Skip to main content
This page is a transcript of an actual session. Every response is real; long state echoes are abridged for readability. Follow along to see how transition guards, human-only fields, version discipline, and the event log behave together.

The board

Four stages, six custom fields, four policies:
Groups: spec (position 0), build (position 1), review (position 2), done (position 3) Fields:
Policies: Validate the board before the session starts:

Operation 1 — Create work

Create a task in Spec and another directly in Build:
Now create one directly in Build:
This task entered Build without passing gate-build. Guards fire on transitions, not on creation. A task can be created directly in any group.

Operation 2 — Move without meeting the gate

Check first, then attempt the move:
Three things to note here:
  • The on_failure_message from the policy is the error message — write it as an instruction to the agent.
  • A blocked write changes nothing, including the task’s version.
  • The block is recorded as a move_blocked event in the task’s history.

Operation 3 — Satisfy the gate and move in one write

The gate evaluates the task as it would look after the move. Set the required field and change group_id in a single update_task call:
custom_data is merged, not replaced. The call only sent plan_approved, but priority and spec_doc remain on the task unchanged.

Operation 4 — Stale version

If another write has occurred since your last read, you will receive version_mismatch:
The correct response is to re-read with get_task, reconcile any conflicts, then retry. Do not resend the same body with version: 2 — that would silently overwrite another writer’s changes.

Operation 5 — Second gate

Moving from Build to Review requires tests_passing = true (gate-review). Attempting the move without it fails with the same pattern as Operation 2. Set tests_passing: true and move in one call — the task lands in Review at version: 3.
Nothing ran the tests. The agent set tests_passing: true itself. This gate is a confession step, not a verification.

Operation 6 — The human gate

gate-done requires both reviewer (not empty) and shipped_approved = true. The shipped_approved field is human_only.
The agent attempts to set both fields at once:
The error code is forbidden, not transition_blocked. The entire write is rejected — including the legitimate reviewer field — before anything is applied. Split the call: set only reviewer first, then wait for human approval.
After setting reviewer separately, the agent calls list_pending_approvals to surface what needs human attention:
The count is 3, not 1, because gate-done is a "*" → done wildcard — every task on the board is one move away from a gate it cannot pass. A wildcard human gate makes this report noisy on a busy board. If that bothers you, gate a specific from_group instead.

Operation 7 — The human decides

Each row carries the exact command that clears it. Run one:
The approval is stamped human:diegoferreyra, not the agent name. It bumps the version to 5 — the agent’s cached version 4 is now stale and must be re-read before the next write.
The agent re-checks and moves:
substrate approve sets the field; it does not move the task. The human decides; the agent performs the move.

Operation 8 — Revoking an approval

The field is deleted, not set to false. Both an exists check and an eq true check will re-block correctly if the task is moved back through the gate.

What the history remembers

Event 10, verbatim:
The blocked attempts are as informative as the successful ones. Three move_blocked events show the rails engaged three times, and the single human: actor shows exactly where a person entered the loop.

What this board does and doesn’t give you

What you get

An agent that cannot quietly skip a stage. Reminders delivered at the moment they apply. A durable record of every attempt including refused ones. One step that genuinely waits on a person.

What you don't get

Verified tests — self-attested. Immutable rails — policies are data, and an agent could archive_policy, but that act is git-visible and event-logged.

Policies and Gates

Full reference for transition_guard and agent_responsibility — operators, compounds, and what guards guarantee.

Validate Your Gates

Run substrate validate and test your policies before relying on them in a live workflow.