Approval
Included from Basic tier
A covered run — a change or a workflow run — enters the approval funnel at
create: every matched approval policy freezes into a line of a per-subject
checklist, the subject holds in pending_approval, and each line must reach
its quorum before release. Trust and transport grant approvals ride the same
checklist (see subject_kind). Served by the v2 ChangeGovernanceService:
ListPendingApprovals (the inbox — the open set), ListApprovalChecklists
(the decision history — the decided set, each row an ApprovalHistoryEntry),
GetApprovalChecklist, ApproveChecklist, RejectChecklist,
BreakGlassRelease and StartApprovedRun.
The decision history lists a checklist to a caller who may read its target,
who decided it (an approval row, a rejection or a break-glass — an
approver always sees what they decided, even after their read on the target
is withdrawn), or who holds the oversight determination — readable on
/governance/change or updatable on /admin, the governance
administrator — which admits every checklist in the estate. The request's
mine narrows it to the caller's own decisions; unset, the server lists
the caller's own decisions unless they hold oversight, in which case the
whole history.
ApprovalRow
ApprovalRow is one recorded approval (who/when/comment), tagged to the line it satisfies and stamped with the fingerprint the approver saw.
| Field | Type | Meaning |
|---|---|---|
approved_by | string | Username of the approving identity. |
comment | string | The approver's optional comment. |
created_at | timestamp | When the record was created. |
fingerprint | string | The content fingerprint the approver saw; the approval binds to it. |
id | string | The record's identity. |
voided_at | timestamp | Set when a validity lapse re-gated the checklist and voided this row. |
ApprovalApprovers
ApprovalApprovers names who may approve a policy's line. kinds carries the resolution families beyond named users/groups — the impacted_asset_owners kind: resolved per change from the frozen target set to each impacted asset's declared subtree owner, one all-of line per resolved owner (every resolved owner approves — distinct from the per-line n-of-m quorum). A covered create whose impacted targets include one no declaration covers refuses loudly at create.
| Field | Type | Meaning |
|---|---|---|
groups | array of string | Approver group names; any known member of a named group may approve. |
kinds | array of string | Resolution families beyond named identities — impacted_asset_owners resolves one all-of line per declared subtree owner of the subject's frozen targets. |
users | array of string | Approver usernames. |
ApprovalChecklist
ApprovalChecklist is one subject's layered checklist.
| Field | Type | Meaning |
|---|---|---|
action | string | The held subject's action name. |
caller_eligibility | string | The caller's standing on the checklist, mirroring ApproveChecklist's verdict: "eligible", "self_approval_excluded", "already_approved" or "not_approver". Affordance honesty while the checklist is open — the server stays the enforcement. |
caller_may_reject | boolean | The caller may reject: a named approver on any line, with the self-approval exclusion applied line-wise. |
completed_at | timestamp | When the checklist completed — every line satisfied. Unset while pending. |
context | ApprovalContext | WHY the subject was raised — the approval context (see below): the requester's kind and rationale, the originating agent with its tier at creation, the correlation chain's hops and the recommendation the subject implements. On a trust raise it names the agent whose trust is being raised (the agent block, by the fleet id the approver-scoped subject read admits), the granter as requester and the grant's note as rationale, with no chain. Served to the checklist's approvers (any line, group membership resolved), its requester and holders of the agent-governance reviewer determination; absent for every other reader, and on transport-grant and release subjects. |
finalise_reason | string | The finaliser's stated reason (mandatory on reject and break-glass). |
finalised_by | string | Who finalised (rejected/released/break-glassed) and why. |
fingerprint | string | The content fingerprint approvals bind to; content drift voids recorded approvals. |
first_run_anywhere | boolean | No prior run of this content anywhere (the first-run-anywhere flag). |
held_reason | string | Why an approved subject is still held (the window refusal), when it is. |
id | string | The record's identity. |
lines | array of ApprovalChecklistLine | The matched policies' lines, frozen at funnel entry; every line must be satisfied. |
prior_runs | array of PriorRun | The prior-run evidence panel. |
quorum_deadline_at | timestamp | The effective quorum TTL deadline — the earliest across the lines; a pending checklist expires into rejected when it lapses. |
release_mode | string | "approved" | "break_glass" for a released subject. |
released_at | timestamp | When the released subject started. |
requested_at | timestamp | When the covered create entered the funnel. |
requested_by | string | Username of the requester — the covered create's author. |
run_id | string | The held subject: a change or workflow run id. |
run_kind | string | The held subject's kind: "change" | "workflow" | "trust_grant" (a trust raise) | "agent_release" (a release promotion) | "agent_rollover" (a release rollover of a lane serving a governed environment) | "transport_grant". For the non-run kinds run_id carries the held subject's own id. |
status | string | "pending" | "approved" | "released" | "rejected" | "expired". |
subject_id | string | The held subject's own id: equals run_id for change and workflow subjects; the grant's id for a trust or transport grant subject. |
subject_kind | string | The held subject itself: "change" and "workflow" echo the run (subject_id = run_id); a trust or transport grant names the grant's own subject, so review surfaces can deep-link it. |
target_path | string | The subject's target node path. |
validity_deadline_at | timestamp | The approval validity deadline, set at completion; a lapse voids the approvals and re-gates the subject. |
window | ApprovalWindowState | Maintenance-window coverage of the target path at read time, set when a line requires a window and the composition serves windows. |
ApprovalChecklistLine
ApprovalChecklistLine is one matched policy's line, frozen at funnel entry.
| Field | Type | Meaning |
|---|---|---|
approvals | array of ApprovalRow | The approvals recorded against this line. Every line carries its own rows: on a multi-line checklist each line names the approver who decided it, in the subject read, the decision history and the export alike. |
approver_kind | string | "named" (the policy's own users/groups) or "impacted_asset_owners" (one line per owner resolved from the frozen target set). |
approvers | ApprovalApprovers | Who may approve the line, frozen from the policy at funnel entry. |
id | string | The record's identity. |
owner_path | string | The resolved owner declaration's subtree root on an impacted_asset_owners line; empty on a named line. |
policy_id | string | The matched policy. |
policy_name | string | The matched policy's display name at funnel entry. |
policy_scope_path | string | The owning policy's delegation scope ('' = global) — with policy_name, quorum and require_window, the line's policy summary. |
quorum | integer | Distinct approving identities this line requires. |
require_change_reference | boolean | Frozen from the policy: a typed external reference must be present before an approval is accepted. |
require_window | boolean | Frozen from the policy: the approved subject releases only inside an open admitting maintenance window. |
satisfied | boolean | The line's quorum is met. |
self_approval | boolean | Frozen from the policy: whether the requester's or the change owner's approval counts toward this line. |
strict | boolean | Frozen from the policy: a strict line is never subsumed by run-level satisfaction. |
waiting_on | array of string | The identities the line still waits on: the named users plus the named groups' known members, minus identities whose approval is already recorded and, on a self_approval: false line, minus the requester and the change owner. Empty on a satisfied line, and when no member of a named group is known to the server (the approvers field still names the groups). |
waiting_on_you | boolean | The calling principal may still approve this line. |
ApprovalHistoryEntry
ApprovalHistoryEntry is one row of the decision history (ListApprovalChecklists): the checklist as GetApprovalChecklist serves it plus the decision summary the history tables print — the outcome, when it was decided, by whom, and the note. The listing is ordered by decided_at, newest first, and cursor-paged.
| Field | Type | Meaning |
|---|---|---|
checklist | ApprovalChecklist | The full checklist — lines, approval rows, clocks, fingerprint, the caller's standing and the approval context. |
decided_at | timestamp | When the decision landed: the release instant for a released subject, the completion instant for an approved-held one, the finalisation instant for a rejection or timeout, the funnel-entry instant while pending. |
decided_by | array of string | The identities whose decision the row records: the live approval rows' approvers across every line (each line's approver on a multi-line checklist, in recording order), plus the rejecter or the break-glass releaser. Empty on a timeout. |
decided_by_you | boolean | The calling principal is among decided_by — "me" in a history table. |
note | string | The decision's note: the rejection or break-glass reason, else the approvers' comments. |
outcome | string | "approved" (quorum complete — held for its window or released by approval) | "rejected" | "timed_out" (the quorum TTL lapsed) | "break_glass" (released without quorum) | "pending". |
ApprovalContext
ApprovalContext is the WHY behind a held change or workflow run — what an approver needs to decide beyond the subject's name: who raised it (a person, or an agent with its trust tier at creation and its owner), the stated rationale, the correlation chain the subject belongs to (the incident or operator request that invoked the agent → its governed reads → the recommendation → this subject) and the recommendation it implements. The platform explains itself: the create lane stamps the provenance under the run's server-owned opschain metadata namespace (requester_kind, rationale, recommendation_id, agent_id, agent_code, agent_project, tier_at_creation, correlation_id — never client-settable), and the inbox reads it back set-based, one read per page. opschain approvals show <run-id> prints it; the GUI inbox opens it per row and shows the rationale above the approve/reject controls. For a trust raise the context names the agent being raised in its agent block (fleet id, code, project, owner, trust-review link) so the inbox can open that agent's detail and trust review under the approver-scoped subject read (opschain docs change-governance, "What an approver may read"); requester_kind is user (the granter), rationale the grant's note.
| Field | Type | Meaning |
|---|---|---|
agent | ApprovalContextAgent | The originating agent, set when requester_kind is "agent". |
chain_summary | array of ChainHop | The chain's hops in order — the most recent 20 — each the chain page's row, RBAC-redacted per viewer exactly as ChainService.ListChainHops redacts it (redacted hops carry kind, depth and timestamp only). |
chain_truncated | boolean | An older remainder exists beyond the summary; the chain page carries it. |
correlation_id | string | The chain the subject belongs to (the run's correlation id). |
metadata_json | string | The subject's own metadata document as JSON text — the operator keys and the server-owned opschain provenance namespace; "" when none. |
rationale | string | The requester's stated reason, verbatim (opschain.rationale): optional for a person, mandatory for an agent. |
recommendation | ApprovalContextRecommendation | The recommendation the subject implements, when it does (stamped opschain.recommendation_id, or the accept flow's approved_from_recommendation). |
requester_display | string | The requester as the inbox shows it: the agent's code for an agent principal, else the requesting username. |
requester_kind | string | "user" or "agent"; a run created before provenance stamping reads as "user". |
transcript_ref | string | The redacted adapter transcript evidencing the agent's reasoning, as the API path of the exchange sealed on the chain (/api/projects/{project}/agents/{code}/adapter_transcripts/{exchange}); empty when none was sealed or the agent's path is outside the viewer's read grant. |
ApprovalContextAgent
ApprovalContextAgent names the agent that raised the subject.
| Field | Type | Meaning |
|---|---|---|
code | string | The agent's code. |
id | string | The agent's identity (its member id). |
owner | string | The agent's owning user or group at read time (owned_by). |
project_path | string | The project the agent is registered under. |
tier_at_creation | string | The effective trust tier the server applied when the subject was created ("supervised", "autonomous"), frozen on the run. |
trust_review_link | string | The agent's trust-review document (/api/agents/{id}/trust_review). |
ApprovalContextRecommendation
ApprovalContextRecommendation summarises the recommendation a subject implements.
| Field | Type | Meaning |
|---|---|---|
created_at | timestamp | When the recommendation was filed. |
id | string | The recommendation's identity. |
status | string | Its lifecycle status (open, accepted, dismissed, expired, superseded). |
summary | string | The recommendation's body, bounded to its opening lines. |
title | string | Its title. |
ApprovalWindowState
ApprovalWindowState names the maintenance-window coverage of a held subject's target path at read time: state is "active" (an active window covers the path), "scheduled" (none active, but one is scheduled) or "none". Coverage informs the reader; the release gate's admission decision stays authoritative.
| Field | Type | Meaning |
|---|---|---|
node_path | string | The target path whose window coverage is reported. |
scheduled_start | timestamp | The next scheduled window's start, when state is "scheduled". |
state | string | "active" | "scheduled" | "none". |
until | timestamp | The active window's end, when state is "active". |
window_id | string | The covering window, when state names one. |
ApprovalFunnel
ApprovalFunnel is the window's checklist flow by terminal state.
| Field | Type | Meaning |
|---|---|---|
approved | integer/string | Checklists created in the dashboard window now approved (completed, awaiting release). |
expired | integer/string | Checklists created in the window now expired (the quorum TTL lapsed). |
pending | integer/string | Checklists created in the window, by their current status. |
rejected | integer/string | Checklists created in the window now rejected. |
released | integer/string | Checklists created in the window now released (the subject started). |
Related pages
opschain docs change-governance— the funnel end to end: matching, freezing, quorum, release and break-glass.opschain docs resources/approval_policy— the matrix rows that become checklist lines.opschain docs resources/asset_owner— the subtree owner declarations theimpacted_asset_ownerskind resolves.opschain docs maintenance-windows— what an admitting window is, forrequire_windowlines.