*Part 9 of An OS Where the AI Is Never a Principal.*
For eight posts I have been talking about AI. This one isn't, and that's the point.
The whole first two acts of this series argued that you confine an agent by handing it capabilities instead of credentials, and by tracking what it knows instead of trusting it to forget. The previous post climbed the isolation ladder all the way to seL4 — the rung where confinement stops being strong and becomes *proven*. That was the last brick of the build. Now Act III collects the payoff, and the payoff is that none of this was ever really *about* AI.
The capability model is a model of authority. AI is one urgent application. But the moment you look at any system that has to decide "who can see this, who can do that, who can pass it on" through capability glasses, you find the same machinery hiding under different clothes. So let me take the most ordinary thing I can think of — a microblog, the Twitter/Mastodon/Bluesky shape — and show you that it was a capability-and-information-flow system the whole time, badly disguised as access-control lists.
The worked exposition is examples/moimoi in the Aegis repo (pnpm demo:microblog). It is not a product. It is a lens.
The god-token you carry right now
Here is how every microblog you have ever used works. You log in, and the server hands you a session or OAuth bearer token. From that moment, every request you make rides that one token, and the server checks an ACL: *is the user behind this token allowed to do the thing they just asked for?*
That token can do everything the account can. Post, delete, DM, follow, unfollow, change your password, read every private list. It is ambient authority in exactly the sense of post one — it hangs in the air around your session, available to be grabbed by naming a target. It is a god-token.
Now hand it to an agent. People do this constantly — "here's my API token, go schedule my posts." The agent does not get *part* of you. The agent is you. Every authority the account has is now an authority the agent has, and the only thing standing between a prompt injection in some quoted post and your DMs going out to a stranger is the model's good behavior. We already know how that ends.
OAuth scopes are the industry's apology for this. They are coarse, server-trusted strings — write:tweets, read:dms — and they are checked by the same ACL machinery against the same ambient identity. They blunt the god-token; they do not abolish it.
What Aegis hands you instead
Under Aegis you never hold a god-token. You hold a set of capabilities, each an unforgeable reference to specific authority over specific objects:
readthis home timeline,compose(draft-only, rate-limited)as me,replyto this thread — not "reply to anything."
Each one is separate, attenuable, delegable, revocable. And the key move is at the object level: "reply to post #123" is a *different capability* than "reply to #456." Authority is per-object, not per-verb.
So hand an agent a draft-only compose cap and a home-timeline read cap, and nothing else. It is structurally incapable of DMing, deleting, or following — not "not allowed," *incapable*, because it was never handed the reference. No injection can conjure authority that isn't in the context. This is the whole thesis of the series, now applied to a product you use every day.
Three identities that change everything
The reframe gets interesting when you notice that three things you think of as microblog *features* are actually capability and information-flow primitives in disguise. moimoi calls these the three identities.
Sharing is capability propagation. When you boost a post, you create an object holding a reference to that post and introduce your followers to it. That's it — that's the whole mechanism. The Miller line from the older Endo and Agoric series is exactly right here: *only connectivity begets connectivity.* Holding a share-cap is not propagation. Exercising it is. Your followers can reach the post because you actively introduced them, not because the post sat in a globally-readable table.
Visibility is an IFC secrecy compartment. public, followers-only, circle-X are not ACL flags. They are confidentiality labels. A post carries its audience as a secrecy label; a stream is a sink cleared for an audience. Putting a followers-only post into a public stream is therefore an *information-flow violation* — it is computed by a flow check, not looked up in a permission table. The difference matters: an ACL asks "is this allowed?" and can be tricked by naming things cleverly. A flow check asks "does this label clear this sink?" and there is no clever naming that makes a private label clear a public sink.
The social graph is the capability graph. To follow someone is to hold a read-cap to their stream. To follow a private account is a powerbox request the owner approves. Your feed is a membrane over the union of streams you hold caps to. And block is revocation — you drop the cap, and because revocation cascades through the membrane (post six), their boosts of you go inert too. The permission model and the social graph are not two systems that have to be kept in sync. They are *one graph*.
That last sentence is the one to keep. The follow button and the access-control table were always the same data structure. Microblogs just stored them twice and prayed they agreed.
Alice, Bob, and Eve
Here is the scenario pnpm demo:microblog runs, and it is worth walking because the whole model is visible in it. Alice posts. Bob holds a share-cap to that post. Eve follows Bob, not Alice.
- Before Bob shares: the post is in no stream Eve can reach. Eve can't see it — not "is denied," *cannot reach*. There is no Alice-stream for her to name.
- Bob boosts: he introduces his followers to the post, so Eve reaches it through Bob's stream. She gets one post — not Alice's whole timeline. Eve never became Alice's follower. Connectivity begat connectivity, and only that one edge.
- Can Eve re-share? Only if the facet Bob propagated was delegable. The author sets the *maximum* delegability; each hop may narrow it but never widen it (
child ⊑ parent). A delegable facet → Eve re-shares onward, virality, but governed. A terminal facet → Eve reads but gets a dead-end reference, and the spread stops at Bob's followers. Reach is a property of the references handed out, not a server policy applied after the fact. - IFC sits on top of all that. A
followers-onlypost boosted into a *public* stream is blocked — the audience label doesn't clear the sink — *unless* the placer holds adeclassify(followers-only)privilege. And declassification is itself a capability that only Alice, the author, can grant. The author keeps the lever on her own secrets.
So "can Eve see it?" is a conjunction, not a lookup: authority must say yes (Bob exercised a share that reaches Eve as at least read), and information-flow must say yes (the post's label clears the stream Bob placed it in). Both, independently, computed. An injected agent holding only a read-cap simply cannot share — there's no third condition to check; the reference to share with was never in its hand.
And it scales to the hard parts without a new mechanism
The honest worry with any clean model is that it's clean because it's a toy — that the moment you add the messy real-world complications, you start bolting on special cases until the elegance is gone.
So moimoi built the messy parts too. pnpm demo:social asserts 21 guarantees across the full complication roadmap, and the thing I want you to take from it is not the number but this: *nothing in it needed a new mechanism.* Every hard case fell out of capabilities plus IFC.
- Revocation mid-spread — Alice deletes the post or blocks Bob *after* Eve re-shared — is just dropping the original facet; the whole reachable subgraph goes inert at once, because every onward reference was attenuated transitively through it. Cascading revocation is the deletion semantics, for free.
- Custom circles / close-friends are the multi-tag secrecy lattice. A stream cleared for
{circle-A, circle-B}accepts acircle-Apost; acircle-B-only viewer's does not. Overlapping audiences are just set membership. - Quote-with-commentary is the label *join*: quote a private post, add public commentary, and the whole quote inherits the private label — you can't launder a secret into the open by wrapping it in your own words.
- Mentions are deliberate, narrow capability grants — @-mentioning someone in a
followers-onlypost hands them a read-cap they otherwise wouldn't have, so it has to be explicit and attenuable. - Federation is cap-passing across machines over CapTP; subscriptions are leased read-caps that expire; moderation is a
takedowncap scoped to one community, least authority for moderators too.
Each of those is a known-hard microblog problem, and each one is one sentence of existing primitive. That is the tell that the model is real and not a metaphor. You don't get to add fourteen genuinely hard cases and have them all reduce to "attenuate a facet" or "join two labels" unless the underlying structure was right.
I'll say it once plainly: moimoi is a worked *exposition*, not a product. It deliberately skips everything hard-but-not-illustrative — millions of caps, real federation consensus, spam at volume, the screenshot attack. Those are engineering, not exposition. The point was never to ship a microblog. It was to watch the whole Aegis stack interlock on one problem you already understand, and to confirm that the AI confinement story and the ordinary-software permission story are the same story.
There's one piece I've held back, because it's the deepest. Sharing is *copy* — when you hand someone a cap, you keep yours. That's perfect for sharing and exactly wrong for *selling.* What does it mean to *own* a post, to transfer it so the seller no longer has it? That turns out to be money, mints, and exclusive transfer — and it's where an AI agent gets to own property by precisely the same mechanism a human does. That's the next post.
End of Transmission.