opbox

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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

FieldTypeRequiredDescription
matterIdstringyes

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

Attachmatter.attach

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentYes
EgressNone - 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

FieldTypeRequiredDescription
matterIdstringyes
entityTypestringyese.g. PARTY
entityIdstringyes

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

Awaitmatter.await

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

FieldTypeRequiredDescription
titlestringyesthe matter title (required)
boardIdstringnothe board/template id to instantiate the matter from (omit for the default board)
prefixstringnooptional 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - drives an inline chat artefact and a GUI panel

a matter: steps + dependencies + cursor. { matterId }.

Input

FieldTypeRequiredDescription
matterIdstringyes

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

Gotomatter.goto

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

FieldTypeRequiredDescription
matterIdstringyes
stepIdstringyes

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

Holdmatter.hold

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.read
Risk classRead - autonomy L0
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Render schemaYes - 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

FieldTypeRequiredDescription
statusstringnooptional status filter, e.g. OPEN
ownerIdstringnooptional - matters owned by this actor
boardIdstringnooptional - matters instantiated from this board
qstringnooptional - case-insensitive title substring
createdAfterstringnooptional ISO-8601 lower bound (inclusive)
createdBeforestringnooptional ISO-8601 upper bound (exclusive)
limitintegernooptional page size (default+clamped)
offsetintegernooptional 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.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

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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilityacl.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityCore - always on (MCP tier 1)
IdempotentNo
EgressNone - in-box (pure Postgres, no outbound call)
Legal basisCC-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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classSensitive - autonomy L2
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionAdmin
AvailabilityOn demand (MCP tier 2)
IdempotentNo
EgressNone - 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

PropertyValue
Capabilitymatter.write
Risk classWrite - autonomy L1
Min. permissionMember
AvailabilityOn demand (MCP tier 2)
IdempotentYes
EgressNone - 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.