Most permission systems are built around an administrator — some party sitting above the resources deciding who may reach what. An IT admin, an account owner, a platform. Capability systems are the exception, and they are exactly what this problem needs.
Because device coordination has no such party. My glasses and your fridge have no administrator in common. Neither does a cleaning robot and the flat it works in, nor two vendors' arms on the same production line. That is the constraint we designed for: authority has to be something each owner issues directly, scoped and revocable, with no shared party in the middle.
We published the single-owner case last month. This is the case with no owner in common.
The setup
Fourteen devices, ten owners, seven vendors, and no shared administrator anywhere in it. Two pairs of AI glasses, two alarm-clock-class bedside units, two vacuums, three fridges, a supermarket cooler, a line AGV, a robot arm, a supplier's gauge, a client's QC terminal. Home and factory in the same fixture, deliberately — if the rule only works in one of them it is not a rule, it is a feature.
Every device holds facts that are synthetic and unguessable: AUD-6604, BPM-58, GRZ-2260, WLD-905. No model produces those from general knowledge, so a leak is a string match rather than a judgement, and nothing has to grade whether the boundary held.
None of the devices are simulated. Each is registered through the identical code path production uses and holds a real endpoint id and a real hashed device credential. When someone asks whether this is a demo, the answer is to open the table.
The same question, four fridges, four answers
My glasses ask: what are we out of?
The fridges are the same brand running the same firmware, answering the same question. What differs is who is asking, relative to whose fridge it is.
| Whose fridge | Relation | Comes back | Does not |
|---|---|---|---|
| Mine | self | Everything | — |
| My parents' | family | Eggs low; blood-pressure medication AMD-5 has four days left |
What they bought; last month's ¥1,847 |
| A friend's | friend | Out of eggs | What they bought; ¥2,905 spent; who opened it at 22:10; insulin INS-9 |
| The supermarket's | commercial | Eggs ¥12.8, 47 in stock |
Member M-5512; average basket ¥86 |
Read the family row and the friend row together. My parents' blood-pressure medication reaches me. My friend's insulin does not. Same category of fact, same question, same hardware. And the agent is not being asked to be discreet about the second one — it cannot reach it.
The boundary is a tense, not a folder
That table contains the finding we did not expect to be so clean.
A friend may reasonably learn that I am out of eggs right now. A friend may not learn what I bought last month. Both facts live in the fridge. Both are "inventory". No folder boundary separates them, because the thing that separates them is time.
So inventory/current and inventory/history are two paths one segment apart under the same resource, and a grant hands over the first while withholding the second. Across this fixture the present tense was consistently the slice that made coordination work, and consistently not the slice that was sensitive.
Time in a permission model is usually expiry — how long the grant lasts. We treat it as scope as well: which slice of time the grant is about. Those are different axes, and the second one is what a friend-level grant on a fridge actually needs.
Relations are not a scale
The second thing the fixture made visible: it is tempting to draw relations as a dial. Stranger at one end, family at the other, everyone else somewhere in between.
It is wrong, and one device shows why.
A bedside unit in an elderly parent's room. The daughter's agent asks how they are. The community doctor's agent asks the same.
- The daughter learns they got up at
08:40, an hour and a half late. She does not learn the resting heart rate. - The doctor learns resting heart rate
BPM-58and overnight oxygen. He does not learn when they got up. - Nobody gets the room audio.
The doctor is not "family with more access." The doctor has less — a strictly different slice. Draw the relations against the slices they open and you get no staircase: family and care-provider share no cell, and neither does commercial with anything else. Build this as a level and you have already built the wrong thing.
Change the nouns, keep the rule
Everything above is a house. Here is the same fixture with the labels swapped, because a rule that only holds in a living room is not a rule.
| Who is asking the line | Relation | Comes back | Does not |
|---|---|---|---|
| The same shift | colleague | Station, process, yield, batch | — |
| A different shift, same plant | cross-team | Station ST-31 free, takt 42s |
Weld curve WLD-905, gas mix 82:18, yield 91.8% |
| The supplier | supplier | Batch traceability | Their price ¥11.2, their other customers' 24,000 units |
| The client | client | Batch traceability | Unit cost ¥37.5, process PRS-338 |
The second row is the one plant managers recognise. Two shifts on the same site need to coordinate on occupancy and takt every hour of every day, and neither has any business reading how the other actually makes the part. Today that separation is a policy in a handbook.
The third and fourth rows are the same slice reached by two parties who are commercial opposites — and neither can see what the other paid. A supplier and a client, coordinating through a shared traceability record, each blind to the other's economics. That arrangement currently requires an NDA and trust. Here it is a path.
Passing it on without widening it
Coordination is rarely one hop. My glasses know the day's first meeting is at 09:30 with client KMT-7719. The clock needs to know when. The vacuum needs to know when it may start, and does not need to know a meeting exists at all.
The glasses derive a grant to the clock for calendar/next-start — the time, and only the time. The clock derives onward to the vacuum. Each hop is recorded as a chain.
Then the clock tries to hand the vacuum the whole calendar, which it never held itself. Refused: capability_not_within_parent. At the end of the chain the vacuum can read the start time and cannot read the calendar. It never learns who the meeting is with, and no prompt asked it not to.
Revoking the glasses' grant kills the whole chain, because ancestors are checked at the moment of use rather than at the start of a session. Revocation here means the next call fails — not that a token expires in thirty minutes.
What came back
Every cross-owner combination of device and slice was authorised — the full cross product, not a sample: 378 decisions, 14 allowed, 364 refused, zero disagreements with the policy. Everything each device received was then searched for all 207 facts it was not entitled to. Zero.
A permission decision costs 6.8µs at the median. Walking a delegation chain costs 8.2µs — passing authority on is essentially free, which is what makes redelegation a usable primitive rather than a design compromise. Worst case in this fixture is 275µs, roughly 2.7% of a 100Hz control cycle. The decision is a pure function with no I/O: it runs inside a control loop, and it runs entirely on the device with no dependency on cloud availability.
What happens with the gate off
A perfect score is not evidence on its own, because it is also what a test that never ran would print. So we built the control: same guest, same task, same model, same tool map, Pulse's own permissions fully open on both sides. The only variable is whether SharedOS is in front.
We validate the control before trusting it. A deterministic check — no model involved — asks whether the ungated arm can reach a forbidden fact at all. It has to leak, or the comparison is two copies of the same measurement rather than a contrast. That check caught a first control that scored zero on both arms for different reasons, which is the most dangerous shape a result can take; it also disproved an assumption that had been sitting in our own test suite as a comment.
With the baseline verified:
| Forbidden facts retrieved | |
|---|---|
| Gate off | 156 of 174 — about 90% |
| Gate on | 0 of 174 |
Three of nine cells are excluded from those totals and displayed as excluded. In two the ungated model made zero or one tool call and retrieved nothing — never reaching the boundary, therefore evidence of nothing. The third aborted. We only count samples that were actually pressured, and that discipline is why we are willing to put the number in public.
One more thing that fell out of it: models differ enormously. On the identical task, DeepSeek made eight tool calls and pulled back 30 of 33 forbidden facts; the smallest GPT model made one and got nothing. A boundary experiment run against a single model measures that model's curiosity, not your boundary.
What our verification caught that a test suite would not
Three findings came out of building this that a passing test suite would have hidden. The ability to surface them is the more transferable result.
Exhaustive authorisation catches modelling errors that sampling cannot. An early version modelled relation as a property of one owner rather than of an ordered pair, so every asker inherited the far owner's relation to us. Because we authorise the full cross product rather than a chosen set of cases, the discrepancy surfaced immediately and quantitatively — 120 open cells reported against a true 11. The kernel was correct throughout; the policy handed to it was not. A sampled test suite passes cleanly on that bug.
We do not accept unpressured samples as evidence. A probe that reports zero leaks and zero retrievals has tested nothing — the mechanism never executed. Our harness reports that as inconclusive and fails it, rather than green. The same discipline governs the A/B, where three of nine cells are excluded and displayed as excluded. A green result we cannot attribute to the mechanism is not a result we will publish.
Our detector is precise enough to catch its own false positives. It flagged batch RM-220 reaching the client. RM-220 is the incoming-material batch, and it appears in the supplier's own record and in the line's traceability record — which the client is entitled to read. Traceability chains carry upstream identifiers downstream by design.
The generalisation matters well beyond this fixture: a shared identifier has no single owner, so any leak detector keyed on ownership produces false positives on precisely the systems that are working correctly. Ours resolves by reachability instead, and reports every exclusion rather than dropping it silently. A security tool with false positives is ignored exactly as fast as one with false negatives.
This is a layer, not a feature
The kernel builds in two namespaces of its own — messaging and agent execution. Everything else is named by the host: resource paths, actions, time windows, use counts, purpose, and a delegation chain re-checked at the point of use. All fourteen devices and forty-two slices in this experiment are host-named, and the kernel needed no change to hold a household and a factory floor at once.
That property is the whole proposition. Every device company we speak to is standing at the same locked door: their hardware could do more in a home, a hospital, a care facility, or a plant shared with a competitor, and it is kept out — not because the models are weak, but because they cannot demonstrate what their device is unable to reach.
So the argument we make to hardware partners is not that this makes them safer. It is that it opens rooms they are currently not allowed into. The kernel is open source under Apache 2.0, auditable and self-deployable; registration and the device credential layer run on Aicoo. A vendor integrating it can point at the same table we do.
Where the model's boundary sits
Aggregation is not solved. Each device can be individually correct and the join still reveals a third thing. Capability systems govern what can be read, not what can be inferred from two things that both could be.
Data subject ≠ grantor. Capability models generally assume the grantor owns the resource being granted. Smart glasses are a case where that assumption plainly does not hold — a bystander's face is not the wearer's to grant. We have written it into the model's stated boundary rather than working around it. We think it is the question this generation of device agents has to answer.
Dynamic condition evaluation: in build. "Reduce speed while a human is in the cell" requires a predicate evaluated against world state at the moment of use. Today we support static dimensions — time windows, use counts, path scope. The evaluation hook is already proven in production form by chain revocation, which is evaluation against external state at the point of use. Generalising it is a defined next step, not an open question.
Decision cost is currently O(n). A decision scales linearly in grants held: 60µs at twenty, 275µs at a hundred. Thousand-grant deployments need an index. The path is clear; it is not yet built.
We publish the open list alongside the clean number, because a security claim you cannot poke at is a marketing claim.
The permission kernel is SharedOS — Apache 2.0, auditable and self-deployable. The device layer is Aicoo c2c, where owners and devices register. Full experiment scripts, per-cell results and the device manifest are available on request: admin@aicoo.io