The review.* family (9 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.
Claimreview.claim
| Property | Value |
|---|---|
| Capability | review.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Guarded UPDATE ... WHERE status='OPEN'; rows_affected==0 ⇒ already
claimed (no two reviewers silently double-owning). claimedBy/claimedAt are written.
Input { reviewId } (fields ending in ? are optional)
Call POST /v/review.claim with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool review.claim.
Expirereview.expire
| Property | Value |
|---|---|
| Capability | review.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Terminal-expire a non-terminal item (the SLA-breach teardown): OPEN|CLAIMED to EXPIRED, stamping resolved_at. Terminal + retained (still readable via review.list); a re-expire of an already-terminal row is an idempotent no-op-shaped success.
Input { reviewId } (fields ending in ? are optional)
Call POST /v/review.expire with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Listreview.list
| Property | Value |
|---|---|
| Capability | review.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Admin |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Returns the queue IDOR-scoped to the workspace, with per-row computed age + SLA standing (within|breached - computed-never-stored, INV-6). The regulated payload is NOT returned in the list projection (sensitivity-gated until the item is opened - INV-7); only lane+subject+status+aging.
Input { lane?, status?, claimedBy? } (fields ending in ? are optional)
Call POST /v/review.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool review.list.
Openreview.open
| Property | Value |
|---|---|
| Capability | review.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
{ lane, subject:{type,id}, payload?, confidence?, slaDueInSecs?, matterId? }. WRITE/L1.
Exactly one Review row written status=OPEN with the lane discriminator + subjectRef. A re-fired
open for an already non-terminal (lane, subject) dedups to the existing row (US-REVIEW-01).
Call POST /v/review.open with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool review.open.
Getreview.policy.get
| Property | Value |
|---|---|
| Capability | review.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Admin |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Read the workspace’s per-lane review-policy configuration
(migration 0041 review_policy). Returns one entry per configured lane:
{lane, config:{enabled, threshold, slaMinutes, ttlDays, triageType[], routing, reassignAuthz}}.
The render source for the review-policy config GUI (US-RENDER-29). RLS-scoped (INV-1); reads
config, computes nothing authoritative (INV-14).
Call POST /v/review.policy.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool review.policy.get.
Setreview.policy.set
| Property | Value |
|---|---|
| Capability | review.policy.author |
| Risk class | Destructive - autonomy L3 |
| Min. permission | Owner |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
upsert ONE review-lane’s config in the EXISTING review_policy store (migration 0041;
one row per (workspace, lane)). DESTRUCTIVE/OWNER per [2026] CC-OPBOX 35: it AUTHORS a human-oversight
CONTROL (it can disable a lane, raise a threshold, relax an SLA - weakening what is routed for human
review), so it inherits the file.policy.* control-authoring tier (CC-OPBOX 27 inheritance), NOT config.set
parity. Owner fail-closed gating is enforced at the dispatch authz check; the INV-8 hash-chained AuditEvent
is appended by the dispatch (governed write); INV-3 attribution is recorded here to updated_by. { lane, config } (config = the per-lane jsonb: enabled/threshold/slaMinutes/ttlDays/triageType/routing/reassignAuthz).
Call POST /v/review.policy.set with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool review.policy.set.
Reassignreview.reassign
| Property | Value |
|---|---|
| Capability | review.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Atomic guarded updateMany WHERE status='CLAIMED'
(rows==0 ⇒ no longer CLAIMED - cannot silently re-own a terminal item). Ownership/attribution only;
it runs NO owning-verb dispatch (distinct from review.resolve - INV-1).
Input { reviewId, toReviewerId } (fields ending in ? are optional)
Call POST /v/review.reassign with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Resolvereview.resolve
| Property | Value |
|---|---|
| Capability | review.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
A CLAIMED review → RESOLVED|DISMISSED with resolvedBy/resolution/resolvedAt recorded. The lane→owning-verb dispatch (party.merge / Gate-grant / doc.extract apply) is the caller’s follow-up through the canonical verb (INV-1 - Review never owns the regulated write); a TRIAGE resolve may be record-only. Idempotent on a terminal row.
Input { reviewId, decision, resolution?, note? } (fields ending in ? are optional)
Call POST /v/review.resolve with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool review.resolve.
Unclaimreview.unclaim
| Property | Value |
|---|---|
| Capability | review.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
The reverse of review.claim: release a CLAIMED item back to OPEN so the
queue can re-claim it. Atomic guarded WHERE status='CLAIMED' (a concurrent resolve/expire wins as a
no-op-shaped Conflict). Ownership-only: runs NO owning-verb effect (INV-1).
Input { reviewId } (fields ending in ? are optional)
Call POST /v/review.unclaim with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.