opbox

The gate.* family (6 verbs). Every verb enters through the one front door: it is capability-checked, permission-checked, scope-checked and audited before it runs (see Security & permissions). Each entry below lists its capability, risk class (which fixes the minimum autonomy level), the minimum caller permission, its availability tier, whether it is idempotent, and any outbound egress.

Applygate.apply

PropertyValue
Capabilitygate.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)

atomic, TOCTOU-safe apply on approval (US-GATE-02, INV-4). { gateId, reviewNote? }.

  1. Lock the gate row FOR UPDATE (routing/authz pre-read - NOT authoritative).
  2. The AUTHORITATIVE guard: UPDATE gate SET status='APPLIED' ... WHERE id=$1 AND status='PENDING'. rows_affected()==0 -> the gate is not PENDING (a concurrent winner already applied, or it was rejected/withdrawn/terminal) -> Conflict, the whole tx aborts before any replay (exactly one winner; re-apply on a terminal gate refused; APPROVED!=APPLIED upheld - only PENDING applies).
  3. Replay the captured change-set through the target’s canonical verb (INV-1, no shadow path) on the SAME tx, and append the replay’s OWN AuditEvent (INV-8).

Input

FieldTypeRequiredDescription
gateIdstringyes
reviewNotestringno

Call POST /v/gate.apply with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool gate.apply.

Getgate.get

PropertyValue
Capabilitygate.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

one gate (the changeset diff + attribution). { gateId }. READ/L0.

Call POST /v/gate.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool gate.get.

Listgate.list

PropertyValue
Capabilitygate.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

list gates in the workspace (optional status/kind filter). { status?, kind? }. READ/L0.

Call POST /v/gate.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool gate.list.

Proposegate.propose

PropertyValue
Capabilitygate.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

capture a proposed mutation as a PENDING gate (US-GATE-01). { kind, targetType, targetId?, changeset, matterId?, restorationData? }.

The change-set is captured atomically with the PENDING insert; the deferred write does NOT happen here - the proposing caller sees {gated:true, gateId} and must not also write the fact (INV-1, no double write). For a data-gate the change-set carries {verb, input} to replay; for an action-gate (ESCALATION) it carries {targetVerb, inputHash}.

Input

FieldTypeRequiredDescription
kindstringyese.g. STEP_ACCEPTANCE
targetTypestringyes
targetIdstringyes
matterIdstringno
changesetobjectyes{verb, input} - the write to replay on apply

Call POST /v/gate.propose with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Rejectgate.reject

PropertyValue
Capabilitygate.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityAdmin only (CLI/HTTP; never advertised over MCP)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)

close a PENDING gate -> REJECTED with a note (US-GATE-04). { gateId, reviewNote? }. Atomic guard same as apply: only a PENDING gate can be rejected (no rejecting a terminal gate).

Call POST /v/gate.reject with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.

Revertgate.revert

PropertyValue
Capabilitygate.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - in-box (pure Postgres, no outbound call)
Legal basisCC-OPBOX 32

the SCOPED-REVERT undo ([2026] CC-OPBOX 32). State-restoring undo of an APPLIED gate: the is-revertible guard (APPLIED + non-null restoration_data ONLY), the atomic terminal restored_at stamp (the status enum STAYS ‘APPLIED’ in a RESTORED-terminal posture, preserving CC-OPBOX 25 immutability), and the restoration replayed through the canonical verb (INV-1, re-gated, own AuditEvent - the SAME mechanism gate.apply uses). The gate-attached restoration_data is the ONLY revertible target (no event.revert - an arbitrary audit event has no before-state). Sensitive/L2/ADMIN, at parity with gate.apply. { gateId, reviewNote? }.

Call POST /v/gate.revert with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool gate.revert.