Membrane — The Dynamic Frontend
The problem with today's frontends
A traditional frontend knows too much.
It knows which buttons to show. Which fields to render. Which operations are available. It knows this because a developer read the API spec, wrote the UI, and has been keeping them in sync ever since.
The frontend is a frozen snapshot of what someone believed the system could do, for a user who may not be that user anymore.
When the system changes, the frontend breaks or lies. When a user's permissions change, the frontend shows options they cannot use, or hides options they now have. When the API evolves, the frontend version falls behind. These are not bugs. They are the structural consequence of the frontend holding knowledge it should not hold.
What the frontend should know
One thing: what can this caller do, right now.
Not in general. Not statically. Right now — given their current authorization, the current intent set, the current state of the membrane.
That is not knowledge that needs to live in the frontend code. It can be asked.
GET /surface
x-caller: lisa
{
"caller": "lisa",
"available": ["get_entries", "get_entry"],
"unavailable": ["add_entry", "share_entry", "revoke_access"]
}
The frontend renders from this. When Lisa's access is revoked, the next surface query returns a different list. The UI reflects it immediately — not because a developer updated it, but because the membrane's state changed.
No deploy. No sync problem. No stale frontend telling a user they can do something they cannot.
Self-adapting
The membrane knows exactly what paths exist for a given caller. That is not incidental knowledge — it is the core of what the membrane is. Routing is what it does. Exposing the live intent space per caller is a surface query over what already exists.
When Marieke shares an entry with Lisa, Lisa's intent space expands. When she revokes that access, it contracts. When the system recalibrates — paths pruned, new routes formed, weights shifted — every frontend that queries the surface gets the new picture.
The interface is always current because the interface is derived, not authored.
The Guardian generates the labels
The intent set does not need human-readable descriptions written by a developer. The Guardian already generated the intents during calibration — from world knowledge, from reading the inner system's capabilities, from understanding what the system is for.
The same process can generate labels, affordances, suggested phrasings — without a developer writing them.
For a diary system, the Guardian knows:
get_entriesis "read your diary" not "fetch the resource collection"share_entryis "let someone see this" not "create a grant record"revoke_accessis "take back access" not "delete an authorization record"
These surface descriptions travel with the intent definitions. The frontend receives them alongside the available intent list. It renders what it is given.
The same is true of the visual character. The Guardian knows what kind of system this is — a diary, a deal tracker, a medical record. It knows the tone, the weight, the intimacy level. A diary is warm, personal, private. A compliance system is precise and institutional. A creative tool is loose and expressive. That character travels with the surface response.
But the frontend interprets it — it does not receive a palette. The server says "personal — warm, intimate, private." The designer decides what that means: parchment and amber, a serif, generous line spacing, borders that barely show. A different designer reading the same character might make different choices. The character is fixed. The expression is designed.
This is the right division. The Guardian describes the kind of system this is. The designer gives it form.
The builder's side
A frontend does not negotiate a connection or parse a described tool-list it then trusts. It receives the capability surface — the exact set of intents it holds a path to. What is available is not a schema handed over on good faith; it is a structural fact of the caller's capabilities and the paths the membrane has. You can reach what you have a path to, and nothing else, because there is no path to anything else. The trust is mathematical — object-capabilities, unforgeable by construction — not a convention two parties agree to describe to each other. A described interface can only ever describe; a capability surface guarantees.
That structural availability is also why the frontend can hold no business logic: it renders the caller's reachable set, and the reachable set is computed, not declared.
This also names a symmetry across the membrane. On the inner side, a domain owner discusses what the system does with System Presence, grounded in the model. On the outer side, a builder discusses how it should look — and that discussion has the same shape: the builder's own intelligence turns "it should look like this" into form, grounded in what the Guardian exposes. The Guardian is to the builder what the model is to System Presence — the ground truth the discussion is held against.
inner domain owner ↔ System Presence ↔ model — what it does
outer builder ↔ builder's own AI ↔ Guardian — how it looks
The pushback is the same, mirrored: System Presence says "that function isn't there"; the builder's intelligence says "the Guardian doesn't expose that." You cannot render a capability the surface never offered — the membrane has no path for it, so there is nothing to draw.
The builder's intelligence stands outside the membrane, on the world's side. It is not a fourth entity in the architecture — it is System Presence's mirror image out in the world, negotiating form the way System Presence negotiates logic. This side stands apart from the current scope; it is named here so the symmetry is on record.
The deeper implication
The frontend is not a separate artifact that talks to the API. It is a rendering of the intent space — and the intent space is owned by the membrane.
The designer defines intent once, at build time. What the system can do, who can do it, under what conditions. The frontend renders whatever that space looks like for the caller standing in front of it.
This has a second consequence: the frontend does not need to understand what any intent does. It does not need to know that share_entry requires an entry ID and a grantee name and produces a grant record. It needs to know that share_entry is available to this caller, and what label to show. The mechanics belong to the membrane and the inner system.
Business logic stays where it belongs. The frontend holds no assumptions about how the system works — only a live picture of what the current user can reach.
When the system changes, the picture updates. The frontend just renders.
A phone you build from modules
Think of a modular phone. The hardware is fixed — the inner system, unchanged, unaware of anything above it. The modules are the intents: self-describing, defined by the membrane, labeled by the Guardian. You snap them together to build your interface.
Different users build different phones from the same hardware. Marieke has write access — her phone has a writing module, a sharing module, a revoke module. Lisa's grant gives her a reading module. The hardware is the same. The phones are not.
The designer does not ship a phone. They define a module catalog. The membrane decides which modules each caller can use. The user assembles what they have.
When access is granted, a new module becomes available. When access is revoked, the module detaches. When the system recalibrates and a new intent emerges, a new module appears in the catalog — ready to be picked up. No developer updated the frontend. The catalog changed and the phones reflect it.
The three layers of control are clean:
what modules exist — membrane (structural, non-negotiable)
what each module means — Guardian (generated, self-describing)
how the phone is assembled — user (personal, rearrangeable)
The user composes the surface. They do not configure the system. They cannot reach past their module set, because the membrane has no path for it. Freedom at the presentation layer, structure at every layer beneath it.
Pim Bongers, Studio Bonkers, June 2026 With Claude