Concepts
Workflows
Per-document-type state machines. Transitions, role gates, confirm prompts, AI bindings.
Workflows
A workflow is a per-document-type state machine that an organisation defines once and the platform enforces on every transition. Workflows say:
- which statuses a document can be in,
- which transitions between them are allowed,
- who is allowed to take each transition,
- when a transition produces a signed snapshot,
- when a transition triggers an AI operation,
- when an extra confirmation prompt should appear before the transition lands.
This page is the conceptual reference. For the JSON shape of a workflow document see Document formats; for the public API see API reference.
Workflows are documents
A workflow is itself a document of type core/workflow, stored in the
tenant. That means workflows have versions, history, and a lifecycle:
| Status | Editable? | Bindable to documents? |
|---|---|---|
draft |
yes | no |
usable |
no | yes |
cancelled |
no | no |
You design workflows in the Workflows admin view (system-admin
role required). A workflow has to reach usable before it can govern
real documents. Editing a usable workflow means cancelling and
re-drafting.
Reserved statuses
Four status names carry platform-wide meaning. Every workflow may use them; custom statuses cannot shadow them.
| Status | Read-only | Snapshotted | Meaning |
|---|---|---|---|
draft |
no | no | Entry status. Required in every workflow. |
usable |
yes | yes | "Publish this." A signed snapshot is produced. |
withheld |
yes | yes | "Publish later." A signed snapshot is produced. |
cancelled |
yes | no | Soft delete. The document is recoverable but considered gone. |
Custom statuses are allowed at any non-reserved point in the
workflow. They behave like an editable intermediate state unless the
transition is marked bumpsVersion.
Anatomy of a transition
A transition declares where a document can move from, where it can move to, and which roles may take it.
{
"from": "draft",
"to": "usable",
"title": "Publish",
"requiredRoles": ["editor"],
"bumpsVersion": false,
"ai": null,
"confirm": null
}
from/to— the status pair. Both must be declared in the same workflow.title— the action label that appears in the transitions menu on a document. Use a verb (Publish,Send back to draft).requiredRoles— list of roles. The transition is allowed when the user holds any listed role. An empty list means anyone with document access can take the transition.bumpsVersion— whentrue, the document'smeta.versionincrements on the transition. Required when the transition leaves a read-only status and the target is notcancelled(re-opening a published document creates a new editable iteration).ai— optional. Wires the transition to an AI operation. See AI integrations.confirm— optional. Shows a confirmation dialog before the transition lands. Useful for destructive moves like cancellation.
Default workflows
A tenant can have multiple workflows for the same document type. The
one marked meta.isDefault: true is the one new documents bind to
when no workflow is specified explicitly. There must be at most one
default per (document type) at a time.
When no usable workflow exists for a document type, a built-in
default ships with the platform (draft → usable → cancelled). It's
enough to get started; replace it as soon as the organisation has
real status requirements.
Workflow binding is frozen at creation
A document carries the workflow id and workflow version it was created against. Editing a workflow later does not change the rules for documents already in flight. This is intentional — operators should never see a document's transitions change underneath them mid-edit.
Re-opening a published document (transition out of usable /
withheld / cancelled) creates a new version but keeps the same
workflow binding.
Snapshots and signing
When a document transitions into usable or withheld, the platform
produces a signed snapshot of the document's content as JSON. The
signature is over a domain-separated byte string using Ed25519. See
Signing and signatures for the verification
recipe, key rotation, and the public-key endpoint.
Snapshots are immutable. The full snapshot bytes ride inside outbound webhook payloads alongside the signature, so a receiver can verify authenticity without round-tripping. See Receiving webhooks.
Status appearance
Each status carries optional icon and color tokens used in the
list views, the workflow chip, and the timeline. The pickers in the
workflow editor show the available tokens. Custom statuses default to
a neutral outline if no pair is set.
The four reserved statuses ship with sensible defaults
(draft → circle-dot/neutral, usable → circle-check/sky,
withheld → clock/sky, cancelled → circle-x/danger); override per
workflow when the organisation's terminology differs (e.g. an
"Approved" status using the usable colour).
Roles
Roles come from the identity provider as realm roles on the
authenticated user. The platform applies them to transitions with
OR semantics: a transition listing ["editor", "lead-editor"] is
allowed for either role.
Roles are capability tags, not tenant scopes. Tenant isolation is enforced separately — see Security.
When a workflow can be edited
A workflow document is editable while it is in draft. Promoting
to usable locks it. To change a usable workflow:
- Cancel the existing workflow (transition
usable → cancelled). - Re-open it (
cancelled → draft, version bump). - Edit.
- Promote to
usableagain.
The platform refuses to cancel a workflow that any active document is still bound to. You'll see a count of bound documents in the cancel dialog so you know what's affected.
AI-bound transitions
A transition carrying an ai block fires an AI operation when an
operator triggers it. Until the AI returns, the document is locked
into a pending state and displays a banner. On success the operation
applies its outputs and the document arrives at the transition's
target status; on permanent failure the document either lands at the
declared onFailure status or stays put with the error visible. See
AI integrations for the full lifecycle.
Practical recipes
A minimal editorial flow
Three statuses, two roles:
draft --(submit, "writer")--> ready
ready --(publish, "editor")--> usable
usable --(unpublish, "editor")--> cancelled
cancelled --(reopen, "editor", bumpsVersion: true)--> draft
Adding an embargo step
draft --(submit, "writer")--> ready
ready --(schedule, "editor")--> withheld
withheld --(release, "editor")--> usable
withheld --(pull, "editor")--> cancelled
The release from withheld to usable does not need
bumpsVersion because the document hasn't been editable in between.
Adding AI translation
Add a custom translated status, an AI operation with the desired
prompt and output targets, and an AI-bound transition. See AI
integrations for the operation shape.
Related pages
- AI integrations — how to wire AI into a transition.
- Document formats — the JSON shape of a workflow document.
- Webhooks — how status transitions reach downstream systems.
- Signing and signatures — how to verify the snapshot a transition produces.