Skip to main content
An agent or a UI often needs to know what it may do next before it does anything. Three read-only calls answer that from the thread’s contract and history: None of them grants permission. They describe the thread at the moment you ask. Before an action with consequences, still call waitFor, which is the only call that reserves an attempt. Decisions answer for the caller’s own role, so they need write access to the thread. Observers can’t call them.

can

Pass either action, the exact step name from your contract, or goal, a plain-language description that Threadify maps to one of your steps.
Add context to also check the data you’re about to send against the step’s content rules, for example thread.can({ action: 'refund', context: { amount: 42 } }). Without it, can only checks order, roles and prerequisites. requires_claim means the action needs a fresh grant each time (it uses must succeed before each invocation). Call waitFor before doing it. uncertain means a goal couldn’t be matched confidently to a single step.

should

should gives advice about whether an allowed action fits the current state. It never makes an action allowed or blocked.

next

Each path is a short sequence of steps that could start now. status is allowed or requires_claim. Later steps in a path may depend on what happens first, so check them again when you get there.

Classifier

Mapping a goal to a step, and should, use a classifier configured on your Engine. Without one, can and next still work when you pass exact step names, and should returns unavailable. A classifier can only choose between steps that are in your contract, and a low-confidence answer never makes an action allowed.

Human approval

To require a person’s approval before an agent acts, put it in the contract: a step owned by the reviewer, which the protected action depends on.
  1. Before approval, can({ action: 'delete_record' }) reports delete_approval as missing.
  2. Your application shows the request to a reviewer. Threadify doesn’t show any UI. When the reviewer approves, record a successful delete_approval as the reviewer. Don’t record a refusal as a successful step.
  3. can now returns requires_claim. The agent’s tool calls waitFor('delete_record'), deletes the record, and reports the outcome.
  4. The approval is used up. The next deletion needs a new approval.
For an agent, expose the business action as an ordinary tool. Its code can call can or next to return a helpful reason when the action isn’t allowed yet; the model doesn’t need separate decision tools. Decisions are also available in GraphQL as can, should and next.