What You’re Proving
A guard enforces the transition — it blocks the move when the gate field is unset or false. It does not verify that the underlying work actually happened; the agent self-attests. The goal is to prove the rail fires, not prove the work was done.1. The Static Check
Run the structural lint against your boards and policies without starting a server:from_group equals to_group (a move that can never happen). Warnings are advisory and exit 0.
substrate validate is a structural lint, not a behavioural test. It cannot tell you whether a guard fires on a real move. Always follow up with the live probe.2. The Live Probe
1
Create a probe task
Call
create_task on the new board, placing the task in the stage before the gate. Leave the gate field unset or set it to false.2
Try to cross the gate
Call
update_task to move the task across the guarded transition. Expect a transition_blocked error naming the missing field. If you don’t get one, the guard is not firing — check your from_group / to_group ids and field paths against the DSL.3
Satisfy the gate and retry
Call
update_task with custom_data: { "<field>": true }, then move again. Expect success and inspect the policies_fired envelope to confirm the guard appeared.4
Check your responsibilities
For each
agent_responsibility, write a task that matches its when conditions and confirm the message appears in policies_fired.5
Clean up
Call
archive_task on the probe task. It served its purpose.3. Spot-Check Without a Throwaway Task
check_transition dry-runs “would moving this task to that group be allowed?” against the real guards and writes nothing:
Testing a Human Gate
Ahuman_only field creates an asymmetry that write tools cannot cross. The only way to see both halves is to exercise the full round trip:
1
Probe the block
Call
check_transition → expect allowed: false with the gate field named in blocked_by.2
Approve as the human
Run
substrate approve <task_id> <field> from the command line.3
Confirm the gate lifts
Call
check_transition again → expect allowed: true.4
Reset the probe
Run
substrate unapprove <task_id> <field> to put the probe back to its original state.