Approval spec (v1)

This is the recorded decision for epic 76d3e2: how Chatticus reconciles "work continues when the laptop is closed" with "consequential actions are gated" while v1 is a web tab. Device push is "come back, something finished," not "approve this now" (Messaging). iOS is v3.

The live thin-turn slice does not run approvals yet. The kernel and Gherkin below are the contract the worker HTTP loop must honor before overnight work or a browser can reach a consequential sink.

Consequential classes

These action types always gate unless a control below allows them:

Class Meaning
send Message, email, or other outbound communication
publish Make content public or share it beyond the household
purchase Spend money
delete Destroy data the household cannot trivially restore
production_change Change a live production system

Reading workspace files and other non-consequential work may run unattended. Egress that sends household data anywhere is approval-class whether it looks like a message, a form post, a file upload, or a URL the agent navigates to (Threat model).

Unattended (laptop closed)

v1 has no completable approval path while nobody is at a screen. A routine or overnight turn that reaches a consequential class must either stop visibly or run against a control that already binds the exact operation. Silent failure and indefinite blocking without a visible waiting state are both out of scope.

Channel May run unattended? Control
Structured connector (API, MCP, named tool) Only if a human created an always-allow rule that matches this action type and these exact arguments features/overnight_gated_action.feature
Generic authenticated browser Never Unbound send / publish / purchase / delete / production change stop with user_controlled_completion_required. A screenshot or click coordinate is not approval.

Type-only always-allow (action type without argument bindings) does not authorize overnight execution. A bot cannot add or loosen an always-allow rule. Retrying the same unbound or unmatched action while still unattended is forbidden.

When the human is back at the tab, they approve a concrete operation (destination and payload as the target system will receive them), not a model-authored summary. That approval authorizes only that immutable operation (features/exact_consequential_approval.feature). Changing destination or payload requires a new approval. Completion evidence is the target system's result, not the agent's report.

Presence

No v1 approval design depends on a human being present at a screen unless that presence is guaranteed. Presence is guaranteed only for interactive review in the web tab. Overnight work must not assume it. Push notification is not presence.

Human takeover of a browser session is a binding control for authenticated browser actions; it is interactive and therefore not an overnight path.

Kernel vs live

Piece Where it lives Live on ChatticusThinTurn?
Default require-approval / never-allow features/approvals.feature No
Overnight stop or exact human rule features/overnight_gated_action.feature In-process kernel
Immutable structured approval features/exact_consequential_approval.feature In-process kernel
Unbound browser stop features/unsupported_browser_action.feature In-process kernel
Page-content cannot expand authority features/page_content_authority.feature In-process kernel
Task grant, contexts, injection, exclusions Browser authority In-process kernel

The control-plane sink adapters in capability_sinks enforce these kernels before file, credential, egress, connector, and consequential operations run. Full Lambda and HTTP worker wiring remains incremental.

Exclusions (v1)

  • iOS or push as an approval client (v3)
  • Routine scheduling mechanics (v2)
  • Loosening auto-review so unattended work finishes by default
  • Pre-authorizing generic browser clicks overnight
  • Bot-created always-allow rules
  • Binding a generic browser click to an immutable operation (see Browser authority)