@protect alone already covers the node.
The policy
runnable
The code
This is the adapter’s own example. It needspip install ctrlrun-langgraph and a LangGraph
install, which the harness that runs the other recipes does not have; the adapter’s tests run
this shape against a real langgraph in this repository’s CI, and the adapter’s README carries
the conformance results.
What the agent sees
The €2,500 refund interrupts the graph with a payload naming the action and its arguments. Resuming withapproved: True and the arguments the human saw runs it once. Resuming with
different arguments is refused with ApprovalMismatch, the approval is left grantable, and
nothing runs. Resuming with approved: False refuses and records who said no.
The receipt
The receipt is the same shape as one fromctrlrun approve: approve/committed, approver
ada@example.com. The node ran twice, once to ask and once on resume, so the log holds two
action_ids and two approval requests for one refund; the action_hash is continuous, which is
why the binding is about content and never about an id.
When an AMBIGUOUS appears
If Stripe’s reply is lost inside the resumed node, the effect isAMBIGUOUS and the graph’s
retry, or a re-run of the thread, is refused. Resolve it with ctrlrun resolve refund:txn_2 --committed or --failed; the approval was spent on the execution, so a retry after --failed
needs a new interrupt.
Next
- Use the LangGraph adapter: prevention versus attribution, and where LangGraph shows through.
- Approval binding · Get started · Why.