The workflow.* family (13 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.
Createworkflow.create
| Property | Value |
|---|---|
| Capability | workflow.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) |
Mints the workflow + nested workflow_steps. workspace_id from ctx; created_by_id from the acting human (rule 2). trigger is NOT NULL jsonb.
Call POST /v/workflow.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.create.
Claimworkflow.cron.claim
| Property | Value |
|---|---|
| Capability | workflow.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) |
Only (cron). Optimistic-lock CAS: claim a workflow’s cron slot iff last_cron_run_at is unchanged. The CAS is the idempotency (the loser sees claimed=false). BEARERLESS.
Call POST /v/workflow.cron.claim with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Deleteworkflow.delete
| Property | Value |
|---|---|
| Capability | workflow.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
Cascades workflow_steps + workflow_runs (FK onDelete: Cascade).
Call POST /v/workflow.delete with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.delete.
Createworkflow.run.create
| Property | Value |
|---|---|
| Capability | workflow.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) |
workspace_id from ctx (denormalised, NOT NULL); the workflow must resolve in the workspace. status is the required WorkflowRunStatus. Mints + returns runId. (Distinct from workflow.run.project which writes workflow_run_projection.)
Call POST /v/workflow.run.create with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.run.create.
Eventsworkflow.run.events
| Property | Value |
|---|---|
| Capability | automation.run.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
| Legal basis | CC-OPBOX 58 |
The run’s event history (paginated). In M0 the events
are the last_event snapshot (a jsonb array when the writer supplies one); a separate events table is the
production hydration. Workspace-scoped. Cite [2026] VJS-CC-OPBOX 58 C2.
Input { id, limit?, offset? } (fields ending in ? are optional)
Call POST /v/workflow.run.events with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.run.events.
Getworkflow.run.get
| Property | Value |
|---|---|
| Capability | automation.run.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
| Legal basis | CC-OPBOX 58 |
One run’s detail (incl. the latest event snapshot), workspace-scoped. Cite [2026] VJS-CC-OPBOX 58 C2.
Input { id } (fields ending in ? are optional)
Call POST /v/workflow.run.get with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.run.get.
Listworkflow.run.list
| Property | Value |
|---|---|
| Capability | automation.run.read |
| Risk class | Read - autonomy L0 |
| Min. permission | Member |
| Availability | On demand (MCP tier 2) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Render schema | Yes - drives an inline chat artefact and a GUI panel |
| Legal basis | CC-OPBOX 58 |
The workspace’s workflow runs, newest first, paginated. Workspace-scoped (RLS + the explicit predicate). Cite [2026] VJS-CC-OPBOX 58 C2.
Input { workflowId?, status?, limit?, offset? } (fields ending in ? are optional)
Call POST /v/workflow.run.list with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.run.list.
Projectworkflow.run.project
| Property | Value |
|---|---|
| Capability | automation.run.write |
| Risk class | Write - autonomy L1 |
| Min. permission | Admin |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | Yes |
| Egress | None - in-box (pure Postgres, no outbound call) |
| Legal basis | CC-OPBOX 61 |
(UPSERT on id). The INGRESS verb the Hatchet NON-AGENT firm_tier-ADMIN service bearer (Path-E, CC-OPBOX 59) calls to project run-state; the kernel never egresses (INV-1, CC-OPBOX 17/58). Workspace-scoped (RLS + the GUC bound by the dispatch gate). Cite [2026] VJS-CC-OPBOX 58/59.
Input { id, workflowId?, status?, stepCount?, completedSteps?, retries?, startedAt?, finishedAt?, lastEvent? } (fields ending in ? are optional)
Call POST /v/workflow.run.project with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Purgeworkflow.run.purge
| Property | Value |
|---|---|
| Capability | workflow.write |
| Risk class | Sensitive - autonomy L2 |
| Min. permission | Admin |
| Availability | Admin only (CLI/HTTP; never advertised over MCP) |
| Idempotent | No |
| Egress | None - in-box (pure Postgres, no outbound call) |
Only. Retention sweep: delete runs started before olderThan. Workspace-scoped. Returns {count}. BEARERLESS.
Call POST /v/workflow.run.purge with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Sweep Staleworkflow.run.sweepStale
| Property | Value |
|---|---|
| Capability | workflow.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) |
Only. Bulk orphan-sweep: fromStatus runs started before olderThan -> toStatus. Workspace-scoped. Returns {count}. BEARERLESS.
Call POST /v/workflow.run.sweepStale with a JSON body; returns JSON (or { error, code }). Not advertised over MCP (admin-only); reachable via the CLI and HTTP doors.
Transitionworkflow.run.transition
| Property | Value |
|---|---|
| Capability | workflow.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) |
Status-gated CAS (the double-resume / double-consume guard): the run moves only if its status is in fromStatuses (and, optionally, its resume_token matches). The CAS is the concurrency guard - only one claimant wins. Returns {changed}. Present-and-null resumeToken clears it.
Call POST /v/workflow.run.transition with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.run.transition.
Updateworkflow.run.update
| Property | Value |
|---|---|
| Capability | workflow.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 COALESCE update keyed by runId in ctx.workspace_id (last-write-wins on the run-state). Idempotent.
Call POST /v/workflow.run.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.run.update.
Updateworkflow.update
| Property | Value |
|---|---|
| Capability | workflow.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 field set; if steps is present it is a FULL replace
(delete-all-then-insert in-tx). Fenced by workspace_id (direct column).
Call POST /v/workflow.update with a JSON body; returns JSON (or { error, code }). Also exposed as the MCP tool workflow.update.