The matter.* family (45 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.
Advancematter.advance
| Property | Value |
|---|---|
| Capability | matter.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) |
the ONE step-completion entry point (INV-1). { matterId, stepId?, note? }.
Completes the active step (or the named step) and runs the progression engine: gate on the
StepDependency DAG + conditional visibility, activate the next step(s), apply phase onComplete,
update the single-active cursor. SELECT…FOR UPDATE on the matter serialises concurrent advances
(exactly one wins). Terminal matters are immutable (INV-8). Post-effects fire-and-forget (INV-2).
Input
| Field | Type | Required | Description |
|---|---|---|---|
matterId | string | yes |
Call POST /v/matter.advance with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.advance.
Attachmatter.attach
| Property | Value |
|---|---|
| Capability | matter.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) |
RETAINED as a
THIN ALIAS of edge.attach (CC-OPBOX 34 B2 “keep matter.attach as a thin alias”) for caller
compatibility: it maps entityType/entityId -> src and forces the dst to MATTER/matterId, then
delegates to edge_attach (NO second write path, NO second audit event - the one append_event is
edge.attach’s). The legacy output shape (matterId/entityType/entityId/created) is preserved.
Input
| Field | Type | Required | Description |
|---|---|---|---|
matterId | string | yes | |
entityType | string | yes | e.g. PARTY |
entityId | string | yes |
Call POST /v/matter.attach with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.attach.
Awaitmatter.await
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
(handler await_check - await is a reserved keyword) - poll the verdict of an
AWAIT_MATTER step’s cross-matter blocking condition ([2026] CC-OPBOX 36: “matter.await binds the
AWAIT_MATTER step-type semantics”; Sensitive/MEMBER, mirroring matter.spawn). Finds the matter’s
AWAIT_MATTER step (awaitStepId overrides; else the ACTIVE/BLOCKED one, falling back to the latest),
evaluates it via the SAME resolve_await the advance pass + wake_parent_awaits use (INV-1: one
evaluation path, never a second await engine), and returns the verdict WITHOUT applying it - outcome
application stays exclusively on the wake_parent_awaits / advance write path. A READ-style poll:
idempotent, side-effect free. { matterId, awaitStepId? } -> { matterId, stepId, outcome, childMatterId? }.
Call POST /v/matter.await with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.await.
Cancelmatter.cancel
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
terminal CANCELLED (+reason). { matterId, reason? }. ADMIN. Terminal-immutable after.
Call POST /v/matter.cancel with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.cancel.
Creatematter.comment.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Append a comment to a matter (optionally a step). type defaults
COMMENT (COMMENT|NOTE|SYSTEM). user_id = the comment author: the acting frontend user, OR the OPTIONAL
authorUserId when a kind=SYSTEM seat / Admin attributes on behalf of a user (resolve_author_user;
a Member cannot forge another user’s authorship). If stepId is set it must belong to the matter. The
@agent-mention/mention-validation policy stays a frontend pre-check.
Call POST /v/matter.comment.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.comment.create.
Completematter.complete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
explicit terminal COMPLETED ([2026] VJS-CC-OPBOX 54 HEAD 3b). { matterId }.
SENSITIVE/Admin. The explicit + bulk completion path (e.g. stakeholder-approval’s final-decision sweep) that
the natural final-step matter.advance does not cover. Gated FAIL-CLOSED: every REQUIRED step must be
terminal-done (COMPLETED/SKIPPED) - it refuses to mark a matter COMPLETED past an incomplete required step.
A step is required-by-default unless its config carries required:false (the same predicate as
goto_required_guard). Funnels through set_matter_status, the ONE matter-status writer (INV-1), so it also
fires the EPIC-XMATTER parent-wake; terminal-immutable thereafter (INV-8).
Call POST /v/matter.complete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.complete.
Creatematter.create
| Property | Value |
|---|---|
| Capability | matter.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) |
Instantiate a matter from a published board Version.
{ title, prefix?, boardId? }. If boardId is omitted, falls back to the seeded default board
(M0 parity - a boardless {title} create still works). Pins instantiatedFromVersion (R11),
materialises the typed MatterStep rows + StepDependency edges, and activates the initial steps.
Input
| Field | Type | Required | Description |
|---|---|---|---|
title | string | yes | the matter title (required) |
boardId | string | no | the board/template id to instantiate the matter from (omit for the default board) |
prefix | string | no | optional matter-number prefix |
Call POST /v/matter.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.create.
Creatematter.document.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Append a document row. uploaded_by_id = acting user, OR the
OPTIONAL authorUserId under the kind=SYSTEM-seat/Admin attribution guard (resolve_author_user). stepId
(if set) must belong to the matter. The kernel file_record write stays a separate caller step.
Call POST /v/matter.document.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.document.create.
Deletematter.document.delete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
/SENSITIVE/MEMBER. Delete a document by id, fenced to a matter in the caller’s workspace. rows_affected==0 -> BadInput not-found.
Call POST /v/matter.document.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.document.delete.
Duplicatematter.duplicate
| Property | Value |
|---|---|
| Capability | matter.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) |
([2026] VJS-CC-OPBOX 70) - clone an existing matter into a fresh one:
{ sourceMatterId, title? } -> { id, number, title, stepCount, currentStepIndex }. RiskClass
Write / Authz Member (mirrors matter.create/spawn; NOT a fresh trust boundary). Clones the KERNEL
matter scalars (prefix, board_id, instantiated_from_version, visibility, objective) + deep-copies the
matter_step rows (preserving step_index/phase/lane/type/title/config + the dependency DAG) with the
cursor RESET (all steps PENDING, then the entry step activated like a fresh create). The new matter is
status OPEN, owned by the acting actor, with a fresh per-workspace number minted under FOR UPDATE.
RESERVED (CC-OPBOX 70): the line-item clone leg is NOT performed here - matter_line_item is the money
path; a duplicate copies the WORKFLOW (steps), not the billing ledger.
Call POST /v/matter.duplicate with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.duplicate.
Creatematter.entityLink.create
| Property | Value |
|---|---|
| Capability | matter.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) |
Link one or more entities to a matter. ON CONFLICT
(matter_id, entity_ref, entity_ref_type, link_type) DO NOTHING -> idempotent; returns the ids. Single:
{ matterId, linkType, entityRef, entityRefType, cspEntityId?, cspIndividualId?, role? }; batch:
{ matterId, links: [...] }. created_by_id = acting user (nullable).
Call POST /v/matter.entityLink.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.entityLink.create.
Setmatter.ext.set
| Property | Value |
|---|---|
| Capability | matter.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) |
UPSERT the frontend-owned matter_ext row for a matter. Idempotent
(the matter id is the PK). Partial PATCH semantics per field: absent => leave, null => unset, value =>
set. { matterId, priority?, dueDate?, lastReviewedAt?, tags?, assignedToId?, templateId?, submissionId?, metadata?, metadataValues?, linkedRecords?, description?, enquiryDate?, closeDate?, closedLostReason?, amount?, source?, referrer?, clientType?, dealType?, lastContactedAt?, numberPrefix? }. When
lastReviewedAt is set, last_reviewed_by_id is derived from the acting user.
Call POST /v/matter.ext.set with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.ext.set.
Creatematter.follower.create
| Property | Value |
|---|---|
| Capability | matter.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) |
Follow a matter (idempotent). userId defaults to the acting user; a userId different from the acting user is an auto-follow-on-behalf (system/admin seat). ON CONFLICT (matter_id, user_id) DO UPDATE auto_followed.
Call POST /v/matter.follower.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.follower.create.
Deletematter.follower.delete
| Property | Value |
|---|---|
| Capability | matter.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) |
Unfollow a matter. userId defaults to the acting user.
Call POST /v/matter.follower.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.follower.delete.
Getmatter.get
| Property | Value |
|---|---|
| Capability | matter.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| 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 |
a matter: steps + dependencies + cursor. { matterId }.
Input
| Field | Type | Required | Description |
|---|---|---|---|
matterId | string | yes |
Call POST /v/matter.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.get.
Gotomatter.goto
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
jump to a target step (ADMIN free-jump). { matterId, stepId? | stepIndex? }.
Supports both forward and backward jumps with container/lane isolation. Forward jumps skip
intervening steps (with a required-steps guard); backward jumps reset them to PENDING. If the
target carries a terminal config (closedState / doneState), it is COMPLETED and the
progression engine runs (handling phase onComplete + CRM_PIPELINE phase advancement).
Input
| Field | Type | Required | Description |
|---|---|---|---|
matterId | string | yes | |
stepId | string | yes |
Call POST /v/matter.goto with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.goto.
Holdmatter.hold
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
park ON_HOLD (resumable). { matterId }. ADMIN.
Call POST /v/matter.hold with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.hold.
Kanban Gotomatter.kanbanGoto
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
set a KANBAN matter’s current_step_index to a column index WITHOUT firing the step
engine ([2026] CC-OPBOX 84). { matterId, columnIndex }. KANBAN matters carry column definitions and zero
matter_step rows, so matter.goto (which drives the step machine) does not fit. Sensitive/MEMBER.
Call POST /v/matter.kanbanGoto with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.kanbanGoto.
Creatematter.knowledgeLink.create
| Property | Value |
|---|---|
| Capability | matter.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) |
Link one or more documents to a matter. ON CONFLICT
(matter_id, document_id) DO NOTHING -> idempotent. { matterId, documentId? | documentIds?[], authorUserId? }.
added_by_id = acting user, OR the OPTIONAL authorUserId under the kind=SYSTEM-seat/Admin attribution
guard (resolve_author_user).
Call POST /v/matter.knowledgeLink.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.knowledgeLink.create.
Deletematter.knowledgeLink.delete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Delete a knowledge link by id, fenced to a matter in the caller’s workspace. rows_affected==0 -> BadInput not-found.
Call POST /v/matter.knowledgeLink.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.knowledgeLink.delete.
Listmatter.list
| Property | Value |
|---|---|
| Capability | matter.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| 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 |
list matters in the workspace, filtered + paginated. Read/MEMBER.
Input (all optional): { status?, ownerId?, boardId?, q?, createdAfter?, createdBefore?, limit?, offset? }.
q is a case-insensitive title substring (ILIKE, wildcard-escaped - never a SQL error on user text).
createdAfter/createdBefore are ISO-8601 timestamps (half-open [after, before)). Empty input keeps the
historical behaviour (whole readable workspace list, ordered by number). Filter+projection parity for the
frontend’s prisma.matter.findMany reads (the SPINE only - frontend-owned columns stay frontend-side;
opbox-prod/PARITY-LEDGER.md track C, disposed by [2026] CC-OPBOX 24/25/34).
Input
| Field | Type | Required | Description |
|---|---|---|---|
status | string | no | optional status filter, e.g. OPEN |
ownerId | string | no | optional - matters owned by this actor |
boardId | string | no | optional - matters instantiated from this board |
q | string | no | optional - case-insensitive title substring |
createdAfter | string | no | optional ISO-8601 lower bound (inclusive) |
createdBefore | string | no | optional ISO-8601 upper bound (exclusive) |
limit | integer | no | optional page size (default+clamped) |
offset | integer | no | optional page offset |
Call POST /v/matter.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.list.
Creatematter.metadataField.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
workspace_id from ctx. Unique (workspace_id, key) -> Conflict. sortOrder defaults to current MAX+1.
Call POST /v/matter.metadataField.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.metadataField.create.
Updatematter.metadataField.update
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Partial PATCH by id + workspace fence. The DELETE route is a soft-delete = archived
. rows_affected==0 -> BadInput not-found.Call POST /v/matter.metadataField.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.metadataField.update.
Creatematter.relation.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
(kind default ‘RELATED’, upper-cased then NORMALISED).
WRITE(Sensitive)/MEMBER. Relates two matters as a USER edge in the caller’s workspace. FAIL-CLOSED:
both ids must resolve in ctx.workspace_id (else BadInput); a self-edge is REFUSED; minting a ‘SPAWNED’
edge is REFUSED (that is spawn/await’s); ANY kind outside the closed stored set is REFUSED (BadInput).
The input kind is NORMALISED ([2026] VJS-CC-OPBOX 45 B2/C2/C4): an inverse alias
(BLOCKED_BY/CHILD/CHILD_PROCESS) is rewritten to its CANONICAL directional kind AND the pair is SWAPPED,
so the inverse view stores the same fact as its canonical orientation (never a second stored kind,
CC-OPBOX 34). For a SYMMETRIC kind the (parent,child) pair is canonicalised (parent<child via
LEAST/GREATEST) so A↔B dedups against B↔A through uq_relation_symmetric; for a DIRECTIONAL kind the
direction is preserved (parent=source, child=target, or swapped for an inverse alias) and dedups through
uq_relation_directional. parent_step_id stays NULL (a user edge has no owning step). On a unique
violation (23505) against either 0093 partial the verb returns IDEMPOTENT SUCCESS echoing the existing
row (the SEVERED decisive call, CC-OPBOX 45 B3/C5). Emits ONE INV-8 audit event (no new audit verb).
Input { sourceMatterId, targetMatterId, kind? } (fields ending in ? are optional)
Call POST /v/matter.relation.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.relation.create.
Deletematter.relation.delete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
(Sensitive)/MEMBER. Removes a USER edge in the caller’s workspace. REFUSES a SPAWNED row fail-closed (C5: the SPAWNED lineage is spawn/await’s, torn down only by matter teardown CASCADE - never by this verb). A not-found relation is a BadInput. Emits ONE INV-8 audit event.
Input { relationId } (fields ending in ? are optional)
Call POST /v/matter.relation.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.relation.delete.
Listmatter.relation.list
| Property | Value |
|---|---|
| Capability | matter.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
Lists the relations TOUCHING a matter (as parent OR child),
optionally filtered by kind (upper-cased). Includes SPAWNED lineage rows (a read sees the whole
graph; only the WRITE verbs guard SPAWNED). A render-schema descriptor (ADR-0035, MATTER_RELATION_LIST)
drives the inline artefact + the GUI panel. Returns { relations: [...] } (TEAM_LIST shape).
Input { matterId, kind? } (fields ending in ? are optional)
Call POST /v/matter.relation.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.relation.list.
Renamematter.rename
| Property | Value |
|---|---|
| Capability | matter.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) |
set the matter title ([2026] VJS-CC-OPBOX 54 HEAD 3a). { matterId, title }. WRITE/Member.
The ONLY kernel-SoR scalar mutator the matters fold needs: title is kernel-owned, everything else (CRM/UI)
lives in the frontend-owned matter_ext. CAS on a non-terminal status (guard_non_terminal); idempotent on
the title value (re-renaming to the same title is a no-op-equivalent state).
Call POST /v/matter.rename with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.rename.
Resolvematter.resolve
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
close a matter on a FORCED terminal-step pair (the APR lifecycle close, [2026]
CC-OPBOX 84). { matterId, endStepIndex, skippedStepIndex }. Completes the END step (completed_by = the
calling actor), SKIPs the sibling terminal step, and sets the matter COMPLETED at endStepIndex - even past
a lingering BLOCKED required step that matter.complete refuses by design. Sensitive/ADMIN.
Call POST /v/matter.resolve with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.resolve.
Resumematter.resume
| Property | Value |
|---|---|
| Capability | matter.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) |
lift a parked matter ON_HOLD -> OPEN ([2026] VJS-CC-OPBOX 94, the pair-inverse of
matter.hold). { matterId }. WRITE / Member (idempotent). The frontend step.activate manual override
resumes engagement after a hold; step.activate activates the target step + sets the cursor but does NOT
lift the matter status, so this is the ONE lawful writer of the ON_HOLD->OPEN lift (INV-1 - no Prisma
fallback, VJS-DEC 15 regulated-write-via-verb). Idempotent: re-resuming an already-OPEN matter is a no-op
(set_matter_status writes status=OPEN unconditionally; OPEN->OPEN is the same state). Guards non-terminal:
a COMPLETED/CANCELLED matter is immutable (INV-8) and refuses resume - a terminal matter cannot reopen.
Call POST /v/matter.resume with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.resume.
Set Objectivematter.setObjective
| Property | Value |
|---|---|
| Capability | matter.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) |
matter.set_objective - set the matter’s overriding objective (Executive faculty, EX-4).
{ matterId, objective? }. WRITE/Member. The objective is the test by which a candidate task is
judged before admission (agenttask.rankByObjective ranks against it). Mirrors matter.rename: a CAS
on a non-terminal matter (guard_non_terminal - a terminal matter is immutable, INV-8), RLS-scoped.
An absent/empty objective clears it to NULL (a matter with no objective ranks every candidate at 0).
Call POST /v/matter.setObjective with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.setObjective.
Sharematter.share
| Property | Value |
|---|---|
| Capability | acl.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) |
A thin convenience wrapper that
forwards to acl.grant with object_type=‘matter’ (NO second write path - INV-1). All the
no-amplification + anti-enumeration logic lives in grant.
Input { matterId, granteeType, granteeId, level } (fields ending in ? are optional)
Call POST /v/matter.share with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.share.
Spawnmatter.spawn
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | Core - always on (MCP tier 1) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Legal basis | CC-OPBOX 36 |
the top-level dispatcher to spawn_child ([2026] CC-OPBOX 36). Sensitive/MEMBER (inherits
matter.create’s instantiation tier - it authors a matter INSTANCE, not a control). The fail-closed
depth(3)/fan-out(10) guard + the SINGLE matter.create reuse (INV-1) both live inside spawn_child, so a
DIRECT spawn is bounded identically to the step-driven SPAWN_MATTER path. INV-8 audit + budget re-gating
are the dispatch’s generic enforcement. { parentMatterId, spawnStepId, childBoardId|childBoardKey, childTitle? } -> the minted child id. (Agent-INITIATED autonomous spawn is RESERVED to court, CC-OPBOX 36.)
Call POST /v/matter.spawn with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.spawn.
Deletematter.stepDependency.delete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Delete a step-graph edge by (matterId, stepId, dependsOnStepId), fenced to a matter in the workspace. Idempotent: a missing edge -> deleted:0.
Call POST /v/matter.stepDependency.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.stepDependency.delete.
Setmatter.stepExt.set
| Property | Value |
|---|---|
| Capability | matter.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) |
UPSERT the frontend-owned matter_step_ext row for a step (keyed by
step_id). Idempotent. Partial PATCH per field (absent => leave, null => unset, value => set):
{ stepId, data?, name?, submissionId?, workflowRunId?, assignedToId?, dueDate?, agentDispatchStatus?, agentDispatchConfig? }. matter_id + workspace_id seed the create branch (resolved from the step).
Call POST /v/matter.stepExt.set with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.stepExt.set.
Creatematter.subtask.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Create one or more subtasks on a step. The step must resolve in
the workspace. sortOrder defaults to current MAX+1 on the step. Single: { stepId, title, ... }; batch:
{ stepId, subtasks: [...] }.
Call POST /v/matter.subtask.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.subtask.create.
Deletematter.subtask.delete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
/SENSITIVE/MEMBER. Delete a subtask by id (fenced via step->matter).
Call POST /v/matter.subtask.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.subtask.delete.
Updatematter.subtask.update
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Partial PATCH by id (fenced via step->matter->workspace).
Toggle-complete: status=COMPLETED stamps completed_at=now()/acting user (unless supplied); status=PENDING
clears them. { id, title?, status?, assignedToId?, dueDate?, sortOrder?, completedAt?, completedById? }.
Call POST /v/matter.subtask.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.subtask.update.
Creatematter.template.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Mint a matter_template in the caller’s workspace. form_id is UNIQUE (one template per form) -> 23505 maps to Conflict. boardType defaults PROCESS, status DRAFT.
Call POST /v/matter.template.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.template.create.
Deletematter.template.delete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
/SENSITIVE/ADMIN. Cascade guard: if any matter references the template (matter_ext.template_id) soft-ARCHIVE it; only hard-DELETE when no references remain. deleteMany (addon deprovision) loops by id.
Call POST /v/matter.template.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.template.delete.
Updatematter.template.update
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Partial PATCH by id + workspace fence. rows_affected==0 -> BadInput not-found. updateMany sites (addon lifecycle: addonKey
flips) loop this by id.Call POST /v/matter.template.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.template.update.
Creatematter.template.version.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Append an immutable matter_template_versions snapshot
AND bump matter_templates.current_version in the SAME tx (atomic). version auto = MAX+1 unless supplied;
unique (template_id, version) -> Conflict. created_by_id = the acting user, OR the OPTIONAL authorUserId
under the kind=SYSTEM-seat/Admin attribution guard (resolve_author_user).
Call POST /v/matter.template.version.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.template.version.create.
Creatematter.trigger.create
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Dedupe by (template_id, workspace_id, name): an existing trigger returns its id idempotently (mirrors provisioning). enabled defaults true.
Call POST /v/matter.trigger.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.trigger.create.
Deletematter.trigger.delete
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
/SENSITIVE/ADMIN. Hard delete by id + workspace fence. deleteMany (addon deprovision) loops by id. Idempotent: a missing trigger -> deleted:0.
Call POST /v/matter.trigger.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.trigger.delete.
Updatematter.trigger.update
| Property | Value |
|---|---|
| Capability | matter.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | On demand (MCP tier 2) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Partial PATCH by id + workspace fence. lastRunAt is the scheduler touch leg. updateMany (enabled
on deprovision) loops by id.Call POST /v/matter.trigger.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.trigger.update.
Creatematter.view.create
| Property | Value |
|---|---|
| Capability | matter.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) |
Record a view by the acting user. 5-minute throttle: a recent view by the same user skips the insert (recorded
).Call POST /v/matter.view.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool matter.view.create.