Approvals¶
Target
This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.
Ownership (2026-10-09)
ApprovalService appeared under both the Control Plane and the Governance platform, and the Studio Review Center was described as a third owner. The ownership map assigns approval instances and decisions to Run Control (this page), approval policy (routing, separation of duties, expiry rules) to Trust & Operations, and the Review Center to the Experience plane as a projection that submits authorized commands.
Model¶
| Concept | Meaning |
|---|---|
| Approval request | Created by a run when policy requires a human decision before an action proceeds; references run, step, the exact proposed artifact or action hash, the release and snapshot version, the policy revision, the eligible approver rule and an expiry |
| Decision | One valid decision per request: approve, reject, request changes; records actor, time, reason and an optimistic-concurrency version |
| Binding | A decision authorizes exactly the referenced version. If the artifact is regenerated or the inputs change, the prior decision is stale and a new request is required |
| States | Pending → Approved / Rejected / Expired / Stale / Cancelled; the run itself moves WaitingForApproval → Running or Rejected (ADR-0014) |
| Authority | Approver eligibility and separation of duties are evaluated against the current policy revision at decision time; a wrong-tenant, expired, duplicate or stale decision cannot advance the run |
sequenceDiagram
participant UI as Review Center (Experience)
participant RC as Run Control (BC-03)
participant POL as Approval policy (BC-20)
participant DB as Run state + approval + outbox (one transaction)
UI->>RC: Decision + request version + authenticated subject
RC->>POL: Validate approver, scope, expiry, separation of duties
POL-->>RC: Versioned policy outcome
RC->>DB: Compare current state, commit decision + next transition + outbox
DB-->>RC: Committed or conflict
RC-->>UI: Authoritative result (not a toast)
Invariants¶
- Restart during a pending approval preserves the waiting state; the decision resumes the run exactly once.
- Cancellation of the run cancels pending requests; a decision arriving after cancellation is recorded and rejected.
- Bulk decisions, if offered, apply per item with per-item outcomes and eligibility checks.
- The UI never owns the state: an acknowledged command and a persisted outcome are distinct observable events.
What this applies to (decided 2026-10-09, D21)¶
The user fixed the action classes on 2026-10-09 (decision D21). This table is the Factory's default approval policy; it is Target until a policy engine exists.
| Action class | Examples | Default outcome |
|---|---|---|
| Read | repository analysis, source-backed reports, knowledge search, log reading | Autonomous within scope and budget |
| Sandbox work | build, tests, file edits in an isolated worktree, a draft branch that is never pushed | Autonomous within scope and budget; leaving the sandbox is a gate |
| Writes to shared systems | git push, pull-request creation, tracker comments, wiki edits |
Approval, per action, exact version |
| External effects | e-mail, chat messages, third-party API calls with side effects, payments | Approval, per action, exact arguments |
| Production changes | deployment, production configuration, feature flags, infrastructure | Approval, per action, exact manifest |
| Asset publication and memory promotion | publishing an agent, skill, tool or workflow release; promoting learned content into shared memory | Approval, as a reviewed proposal with evaluation evidence |
| Spend | predicted run cost above the threshold | Approval before start; below the threshold the budget is reserved and settled without a human. The threshold is platform policy; a project may only lower it |
- Granularity is one approval request per gated action, bound to the exact object version (artifact hash, diff, deployment manifest, tool invocation with its arguments). A plan-level approval does not substitute for it. Bulk decisions, if offered, apply per item with per-item outcomes.
- Who may decide is fixed by ADR-0015 point 6 (Reviewer or Workspace admin, never the requester of that run; Platform admin break-glass with an audited reason).
- The class of a tool call is declared by the tool's side-effect class in the tool registry and enforced by the executor under tool policies; a project policy may move a class towards stricter outcomes, never towards looser ones.
Current implementation¶
No approval aggregate, decision record, expiry or policy evaluation exists in code. The prototype's review actions display a toast claiming an audit event and workflow resume; nothing is persisted.