Witbitz docs PlatformTrustAll docs

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 /space render. 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):

  1. propose — on its turn, the agent proposes an action; it is recorded pending, not run (propose(room, { action, by })).
  2. 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.
  3. 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