Consent as a First-Class Primitive
Most software asks for your permission exactly once, at the worst possible moment: at install, before it has done anything, when you have the least information and the most incentive to click through. You grant the camera, the contacts, the location, the microphone - all of it - and then the app carries that grant forever, silently, whether it ever uses it or not. The contract is "allow everything now, trust me later." It is a bad contract, and we all sign it several times a week.
Priostack starts from the opposite assumption. A permission is not a property an app owns after you tap "Allow." It is an event that happens at the moment an app tries to do something you would care about - with a stated reason and an end date attached - and that the engine underneath can refuse. Consent is not a setup screen. It is a primitive the runtime enforces, every time, at the point of use.
This piece is about why that shift matters, and how it actually works: what a Priostack app is made of, why most of it never needs a dangerous permission at all, how the few things that do get requested, granted, and revoked, and where the honest limits are.
Contents
1. The install-time bargain is broken
The install-time permission model fails for a simple structural reason: the moment you decide is disconnected from the moment it matters. You approve the microphone during setup, when the app has no task in front of it and cannot tell you what it wants the microphone for. Six weeks later it records something, and you have no memory of agreeing, no reason attached to the grant, and no expiry that would have ended it on its own.
Three things are missing, and they are the three things that make consent meaningful:
- A reason. "This app can use your camera" is not consent to anything in particular. Consent is to a purpose - "to scan the meter on the wall right now" - not to a capability in the abstract.
- A moment. Permission granted long before use, and carried indefinitely after, is permission you cannot supervise. You need to be asked when the action is about to happen, not once, forever, up front.
- An end. A grant with no expiry is a grant you have to remember to revoke. Almost nobody does. The default outcome of allow-all is permanent access nobody is watching.
2. An app is models, not code
To see why Priostack can enforce consent this precisely, you have to know what a third-party app on the platform actually is. It is not a binary of opaque code that the operating system has to sandbox and hope for the best. A Priostack app ships a bundle of models, and the single engine underneath - Qubit - runs them directly:
- ArchiMate 4.0 for structure - what the app is, its layers, its components, the devices it touches.
- BPMN 2.0 for what it does - processes that run as Petri nets, so the possible states are known, not guessed.
- CMMN 1.1 for cases, DMN 1.3 for decisions, Camel routes for integrations out, IFML for the views you see.
Because the engine runs these models natively, it knows the full shape of what an app can do before the app does anything. A process modeled as a Petri net cannot reach a state the model does not contain. A decision table returns one of its declared outputs and nothing else. This is the important part for consent: most of an app is expressible entirely in models, and models cannot touch your camera, your keys, or your money. They move process state, evaluate decisions, render views, and route messages within declared bounds. That surface needs no dangerous permission because it is structurally incapable of the dangerous thing.
So the permission surface is not the whole app. It is the narrow set of actions that fall outside what a model can express - and those get handled separately, and deliberately.
3. Native features: the escape hatch, on a leash
Some things a model genuinely cannot do. A model cannot open a lens and read a QR code. It cannot hold a cryptographic key and sign with it. It cannot place a phone call. For exactly these, the platform provides native features: capabilities the surrounding "super app" offers that reach past the model into the real device - the camera, keys, placing a call, and their kin.
A native feature is the escape hatch out of the safe, modeled world - which is precisely why it is the thing consent has to govern. And so every native feature is granted the same way: with a purpose and an expiry, and enforced at the moment it is invoked, not at install. The app declares that a step needs the camera and states why. The grant, if you give it, is scoped to that purpose and carries an end date. When the app actually reaches for the lens, the engine checks the grant then, at that instant. No live grant, no camera.
4. What, why, and until when
Every native-feature grant answers three questions, and you see the answers before you decide:
REQUEST camera
WHAT read the utility meter for this reading
WHY the reading step cannot complete without an image
UNTIL this task, expires end of visit
─────────────────────────────────────────────
[ Grant for this task ] [ Not now ]
What is the concrete native feature - not a category, the actual thing. Why is the purpose bound to it, the reason the running step needs it. Until when is the expiry: this task, this session, this window. When the clock runs out or the task ends, the grant is gone. There is nothing left behind for you to remember to switch off.
This is a genuinely stronger contract than "allow-all at install." Allow-all gives an app an open-ended capability with no attached reason. A purposed, expiring grant gives it a narrow one, justified, that closes itself. If the app later wants the camera for something else, that is a different purpose and a different ask - not a silent reuse of a grant you gave for something unrelated.
5. Side effects and the autonomy ladder
Consent is not only about native hardware. It is also about how much an app is allowed to act on your behalf, and how visible its actions are before they happen. Two mechanisms carry this.
First, every capability declares its side-effect class, and you see that class before you grant anything:
read_only- looks, changes nothing.reversible_local- changes something you can undo.external_communication- sends something outward, to someone or some service.financial_commitment- spends or commits money.account_security- touches credentials, keys, access.high_stakes- consequential and hard to walk back.
The class is the honest label on the tin. "This will send a message to someone" and "this will read a value" are not the same request, and the system does not let them look the same.
Second, how far an app may act is set by the autonomy ladder:
| Level | Name | Behaviour |
|---|---|---|
| 0 | Suggest | Proposes only. Does nothing itself. |
| 1 | Prepare | Drafts the action; you send it. |
| 2 | Confirm | Asks before each action. |
| 3 | Delegated | Acts within limits, tells you after. |
| 4 | Continuous | Runs on its own; you can stop it. |
The crucial rule is that effective autonomy is the lower of what the app asks for and what you grant. An app can declare it would like to run Continuously, but if you granted Confirm, it runs at Confirm. The app never gets to overrule you upward. And there is a hard ceiling the app cannot argue past: anything in the financial_commitment or account_security class is capped at Confirm, no matter what level the app declared. Money and the keys to your account always stop and ask. There is no autonomy level that buys past that.
6. Enforced at invocation, not install
The whole design rests on one implementation choice: the check happens when the action fires, not when the app was installed. The engine is the thing running the models and mediating every reach into a native feature, so it is positioned to enforce the grant at the exact point of use.
Concretely, the lifecycle of a native-feature grant looks like this:
DECLARE app model marks a step: needs `camera`, purpose stated
REQUEST step is reached → engine asks you: what / why / until
GRANT you approve → grant is scoped to purpose + expiry
INVOKE app reaches for the camera
CHECK engine verifies a live, matching grant ← here, now
ACT lens opens (or: no live grant → refused)
EXPIRE task ends / clock runs out → grant gone, no residue
Notice where the enforcement point sits: at CHECK, between the app wanting the camera and the camera opening - not weeks earlier at install. An expired or purpose-mismatched grant fails at that line. The app cannot smuggle an old grant into a new purpose, and it cannot hold a capability it is not, right now, actively permitted to use.
This is the same reason the modeled surface is safe by construction. Because Qubit runs BPMN as Petri nets, the states an app can be in are the states its model contains - an unmodeled action is not a permission you forgot to deny, it is a state that does not exist. Enforcement at invocation extends that same principle to the few actions that live outside the models.
7. The same rule at the edge
None of this changes when the app leaves the phone. The same app runs as a native mobile app drawing its IFML views, as a PWA in the browser, and on edge devices through Skopin - Priostack's Linux edge OS - because there is one engine underneath and one meaning for each model on every surface. Consent travels with it.
On an edge device this matters more, not less. Skopin runs an app's models and policies out in the field, on a fast repeating scan cycle - on the order of 120 ms on a control device - and reports the device's real state back. Sensor conditions become read-only guards. Unsafe interlock states are not checked for at runtime and rejected; they are made structurally unreachable by the Petri-net semantics - safety by construction. A device in an ArchiMate model is not a drawing of a device; a technology-layer node can be a real board out there running Skopin, on Reflex-class hardware, anchored in the physical world.
So a native feature invoked on an edge device - actuating something, opening a channel - passes the same purposed, expiring, checked-at-invocation gate as one on your phone. The family framing is: Priostack orchestrates, Skopin executes at the edge, Reflex anchors it in the physical world. The consent primitive is one of the things that stays identical across all three.
8. Honest limits
This model is stronger than install-time allow-all. It is not magic, and it is worth naming what it does not do.
- It does not read your mind about purpose. The "why" attached to a grant is the reason the app declares. The system binds the grant to that purpose and can refuse reuse for a different one, but it cannot audit whether a stated purpose is honest in some deeper sense. What it guarantees is narrowness and expiry, not sincerity.
- Consent fatigue is a real cost. Asking at the moment of use, for a reason, is more prompts than asking once. The design fights this by keeping the dangerous surface small - most of an app is modeled and needs no prompt at all - and by scoping grants to a task so you are not re-asked mid-task. But there is an honest tension between "ask every time" and "do not nag," and we land deliberately on the side of asking for the things that can spend money, send messages, or touch the physical world.
- The geometric memory that gives apps context recalls by similarity, not by key - and today it matches deterministic projections of execution state, not semantic paraphrase. Context is bounded and honest about what it is; it is not a hidden channel that remembers more about you than the grants allow.
- A grant is only as good as its floor. The value of the money-and-security cap is that it is enforced in the engine, below the app. That is a strength, but it also means the guarantee is exactly as strong as the engine's mediation of native features - which is why that mediation, not app-level promises, is where the enforcement lives.
Conclusion
The install-time checkbox asks you to decide everything at the one moment you know the least, and then to trust an app indefinitely with capabilities it may never explain and you will probably never revoke. Priostack replaces that with a smaller, sharper contract. Most of an app is models, which cannot reach your camera or your money at all. The few things that can are native features, and each one is granted with a purpose and an expiry and checked at the instant it is invoked. How far an app may act is the lower of what it asks and what you grant, with a hard floor at Confirm for anything touching money or account security.
"Asked at the moment it matters, for a reason, with an end date" is not a nicer wording of the same permission. It is a different object. It is consent that expires on its own, that is bound to why it was given, and that the engine - not the app - enforces at the point of use. That is what it means to make consent a first-class primitive: not a screen you pass through on the way in, but a rule the system keeps, every time, for as long as it should and no longer.