Delegated Authority — humans keep the final say
The second of Witbitz's two guarantees (the first is the double blind). An agent never owns authority — it receives it, limited and revocable, and a human approves anything high-stakes before it happens. The runtime enforces one invariant: no action runs without an approval.
Built + tested (async Spaces M2 Cut 4); runs inside the deployed
/spacerender. Code:agent/delegatedAuthority.mjs.
1. Propose → approve → execute
An effectful action moves through three recorded steps, asynchronously (the human may approve on a later turn, not in-the-moment):
- propose — on its turn, the agent proposes an action; it is recorded pending, not run
(
propose(room, { action, by })). - approve / deny — a human decides on a later turn (
decide(room, { id, approve, by })). A decision on a non-pending proposal is refused; a decided proposal can't be flipped. - execute — only an approved proposal runs, through the injected executor (
execute(room, { id, run })), and only once.
2. The invariant
Enforced and unit-tested: an un-approved proposal never runs, and no proposal double-runs. Approval is a precondition to execution, checked in the runtime — not left to the model's discretion. This is the couples-therapy safety-floor idea raised to the action level: the model reasons, the human authorizes, the runtime gates.
3. Capabilities are just tools
A Space's effectful capabilities are ordinary tools in its config (send_summary, schedule_checkin, …) —
there is no separate "actions" concept. The turn runs the normal brain tool-loop; the only async-specific twist
is that a high-stakes tool call is deferred to a human approval instead of running in-room. makeProposingBrain
wires this: it runs the brain with the Space's tools and turns a tool call into a pending proposal (via
proposeCallTool) rather than an execution. On approve, execute runs the same proposal through the same tool
executor a live call would use, keyed on the tool name — so approval routes to the real implementation.
4. The audit trail
Every step — propose / approve / deny / execute (with result or error) — is appended to a single per-room
authority doc: { proposals, audit }, an append-only log. It is mk-sealed like the ledger, so it is
content-blind at rest (the platform can't read it) and it persists across weeks. A wrong mk yields
nothing — the trail is readable only to a present member, in the decrypt-once render.
5. Code map
| Concern | Where |
|---|---|
| propose / decide / execute + the invariant | agent/delegatedAuthority.mjs (propose, decide, execute) |
| pending list | agent/delegatedAuthority.mjs (pendingProposals) |
| tool-call → proposal glue | agent/delegatedAuthority.mjs (makeProposingBrain, proposeCallTool) |
| the ops that drive it | agent/spaceService.mjs (turn proposes · decide approves→executes · pending) |
| the sealed authority doc | agent/sessionStore.mjs (putDoc/getDoc), sealed via agent/envelope.mjs |
6. Status
Built + tested (the invariant, deny-can't-execute, no-double-run, the ordered audit trail, platform-blindness) and
running inside the deployed /space Lambda. What it does today is the async propose → approve → execute + audit
loop; richer policy (spend caps, per-capability authority tiers, org-level delegation from the vision) builds on
this primitive.
Machine-readable source: delegated-authority.md · every doc in one fetch: llms-full.txt · ← the-live-call · the-companion →