The Autonomous Layer (M4)
The opt-in background executor and the discipline that makes unattended agency acceptable: its design lineage, the five-phase walk, the single chokepoint, the brakes, the honest caveats, and what shipped.
Single-chokepoint security model
Every external action the executor can take flows through one function:
guarded_tool_call (api/app/autonomous/guard.py). There is no other
path to a tool. The closed set of operations is the ToolIntent
enum (api/app/autonomous/enums.py):
retrieve_chunks, run_skill, run_playbook, propose_memory,
propose_precedent, emit_finding, notify.
guarded_tool_call enforces the three brakes in this order — R5 →
R6 → R4 — before dispatching, then records cost + outcome:
- R5 (temporal): re-read
halt_statefrom the DB (db.refresh) so an external signal that arrived after the executor started is honored at the next tool boundary. Ifhalt_requested, transition tohalted, write ahaltedaudit row (reason='external_halt'), and raiseSessionHalted. - R6 (contextual): if the requested
intentis not inPHASE_GRANTS[current_phase], write atool_callaudit row withoutcome='tool_not_granted'and raiseToolNotGranted. - R4 (economic): estimate the call's USD cost once
(
estimate_tool_cost); ifmax_cost_usdis set and the projected total would exceed it, latchcost_cap_reached, transition tohalted, write acost_cap_reachedaudit row, and raiseCostCapReached.
Only after all three pass does the chokepoint dispatch (_dispatch)
and then add the dispatched cost to cost_total_usd, stamp
last_activity_at (which feeds the R5 idle watchdog), and write the
final tool_call audit row.
Commit boundary. The chokepoint flushes audit rows and state
mutations but never commits — the caller (the executor's terminal
handler) owns the commit. This is load-bearing: when a brake raises, it
has already mutated the session (halt_state / cost_cap_reached) and
flushed an audit row; a caller that caught the brake and returned
without committing would silently drop both. The A3.3b nodes therefore
let brakes propagate to the executor's terminal handler, which commits.
The single R4 cost estimate is reused: the same Decimal value the cap
check computed is forwarded into _dispatch, so inference handlers
charge exactly what R4 approved — no double-charge, no divergence
between what was checked and what was billed.
Dispatch detail. Local intents (emit_finding, propose_memory,
propose_precedent, notify) and retrieve_chunks are zero-cost.
propose_precedent upserts race-safely via INSERT ... ON CONFLICT
against a partial unique index, incrementing observed_count on
recurrence — it never touches the projects table (promotion into
a Project's context is a separate, user-authorized proposal lifecycle).
run_skill / run_playbook route through the gateway with
anonymize=True by default (the autonomous flow may carry privileged
context).