Module approval
Expand description
Out-of-band SOP approval plane (EPIC C; EPIC G broker).
The resolution layer on top of EPIC A (the engine singleton) and EPIC B (the
durable run store + append-only event log). resolve_gate (resolve) is the
ONE gate-clearing entry point, reachable from four principals - the agent
tool, the loopback CLI, the gateway, and the timeout tick - each recorded
into B’s append-only ledger with a transport-derived principal that a client
body can never forge. ApprovalBroker (broker) wraps that chokepoint with
an authorization + quorum layer (EPIC G): required-group membership and
N-distinct-approver quorum, resolved from the engine’s live
[sop.approval] config. With no policy configured the broker is a
pass-through to resolve_gate - unchanged behavior.
Modules§
- broker
- Approval broker (EPIC G, Phase 5).
- channel_
route - Real channel delivery for the approval route adapter (EPIC G follow-up).
- decision
- The decision a principal makes on a SOP gate, and the outcome of resolving it.
- identity
- Approval identity resolution seam.
- ledger
- The append-only approval ledger entry, mapped onto EPIC B’s
SopEventRecord. - principal
- WHO resolved a SOP approval gate, and from WHERE (EPIC C).
- resolve
- The single gate-clearing chokepoint (EPIC C, C3).
- timeout
- Fail-closed SOP approval-timeout behavior (EPIC C, C2). [SEC-FLIP]
Structs§
- Approval
Broker - Authorization + quorum layer over
resolve_gate. Holds NO copy of the approval policy/group config - it resolves every policy and membership decision from the engine’s live[sop.approval]at use-time (single source of truth), so a config reload cannot leave the broker deciding on stale rules. It carries only the identity-resolution seam and the route adapter. - Approval
Principal - WHO resolved a gate and from WHERE. Recorded into the append-only ledger.
- Channel
Route Adapter - A route adapter that delivers approval notices to configured channels.
- Gate
Ledger Entry - One immutable ledger row per gate event. Becomes a
SopEventRecordviainto_event_record, which the store appends (assigning the monotonic seq). - Gate
Notice - Everything a route adapter needs to render a MEANINGFUL gate notice — not just “run X waits at step N” but WHAT is being approved.
- Local
Config Approval Identity Resolver - Config-backed resolver over
[sop.approval].groups.*.members. Stateless: it reads the config handed to it on each call, so there is no second copy of the membership map to go stale. A member entry may be source-qualified (<source>:<identity>, e.g.http:<subject>,agent:<alias>) to grant rights on ONE transport only - so a subject on the gateway and the same string on the agent tool do not collide - or a bare identity to grant it from any source. Channel principals are stricter: they match onlychannel:<channel-key>:<sender>, neverchannel:<sender>or a bare sender, so same-looking platform ids from different channel aliases cannot collide. A principal with no identity (e.g. the system tick) belongs to no group. - Noop
Route Adapter - A no-op route adapter: logs the delivery intent but sends nowhere. The default until real channel delivery is wired (a follow-up); keeps the broker and escalation functional without a channel dependency.
Enums§
- Approval
Decision - Approve or deny a waiting SOP gate.
- Approval
Mode - WHO may clear a SOP approval gate. Layered with execution_mode / priority / requires_confirmation (all of which still apply). Closed set => serde enum.
- Approval
Notice Kind - Why an approval notice is being delivered. Route adapters render this so an on-call escalation cannot be mistaken for the initial request.
- Approval
Route Issue - A route configuration problem reported at daemon startup before a parked gate would otherwise discover it during delivery.
- Approval
Source - The transport a gate resolution arrived on. The agent tool, the loopback CLI, the gateway WebSocket frame, the gateway HTTP route, or the daemon timeout tick.
- Approval
Timeout Action - What happens to a SOP approval gate when it times out. Default is fail-closed: the gate never self-approves. Closed set => serde enum.
- Broker
Outcome - The outcome of a broker-mediated gate resolution.
- Gate
Event Kind - The kind of gate event recorded in the ledger.
- Resolve
Outcome - What
resolve_gatedid. Returned to the caller (tool / CLI / gateway) so it can report, and so the executor/tick can act on a resumed action.
Traits§
- Approval
Identity Resolver - Resolve an approval principal to the approver groups it is a member of, against
the live
[sop.approval]config passed in at use-time (the single source of truth - never a cloned copy that could drift on reload). - Approval
Route Adapter - Deliver an approval notice to a named route (channel). The seam that lets approvals reach approvers beyond the originating channel (the cross-channel HITL gap) and that escalation uses to reach a distinct SECOND route on timeout. Delivery is best-effort: a route error must never clear or block a gate (the gate state is the source of truth; the route is only a notice).
Functions§
- unresolvable_
approval_ routes - The configured approval routes (
request_route+escalation_route) whose channel key is NOT amongchannel_keys- the channels the route adapter can actually deliver to (present in its map ANDsupports_outbound_send). A route names an undeliverable channel when it is absent from the map (e.g. an AMQP SOP-dispatch channel that needs runtime SOP handles the adapter lacks) OR present but inbound-only (itssendis a no-op). The daemon logs these at STARTUP so the drift between “configured route” and “deliverable channel” surfaces at boot, not silently on the first parked gate. A route must have non-emptychannel:recipienthalves; malformed values are also surfaced at startup. Returns oneApprovalRouteIssueper invalid route.