guard.bind, so approvals, grants, breakers, and audit apply per
step — not to the compound as a whole.
Use compound tools when a task always spans the same few primitive calls
(fetch, transform, write) and you want the agent to reach for one intent name
instead of chaining several. Extraction never writes this file — you author it.
When to use a compound
Reach for a compound when all three are true:- The steps are stable and belong together as a single user intent.
- Each step is already a
routeoropenapitool in.vendo/tools.json, a connector tool, or a Vendo capability. - You want the agent to see one descriptor instead of several.
The capabilities file
Compounds live in.vendo/capabilities.json. A compound entry inside
tools.json is rejected at load with a pointer to this file.
id values. Each step targets one
existing tool by name. args, if, and forEach are JSONata expressions
evaluated against the root args and prior step results by id.
Steps
Every step runsif → forEach → args → invoke in that order.
if— skip the step when the expression is falsy.forEach— invoke the step once per item, up to 1000 items. The item is available toargsas the step’s context. Non-array values fail loudly.args— the JSON object passed to the target tool after evaluation.
id. Root inputs are available as
args.
Risk
The compound’s declaredrisk must equal the maximum risk of its steps after
overrides apply. Under- or over-declaring risk quarantines the entry.
Overrides
.vendo/overrides.json applies to compounds by name, field by field, the same
way it applies to extracted tools. Use overrides to tighten risk, mark a
compound critical, or disable it without editing the capabilities file.
Per-step approvals
Every step crossesguard.bind on its own descriptor.
- A step that trips policy
askparks the whole compound with that step’s approval card. The user sees the real step name, arguments, and risk. - A standing grant for the step tool runs the walk under
decidedBy: "grant"with the grant id in audit. criticalon a step forces an ask on every run, even under a standing grant.- The
maxWritesPerRunbreaker counts each write step and can trip mid-walk. - Policy
blockon any step halts the compound before that step runs.
actAs only ever receives step grants.
Resume
When a step parks, the compound resumes from that step after the user decides. Completed steps do not re-run — Vendo re-issues the parked step call verbatim so the approval matches the original request. Resume state is in-memory, bounded to 1000 entries per registry with a 60 minute TTL. A process restart re-walks the compound from step 0 on the next call. With per-step approvals, a compound whose own policy decision is “ask” re-asks on each resume.Quarantine
Vendo validates every compound at load. Entries that fail validation are quarantined: the name is reserved, the compound never appears in descriptors or dispatch, and boot succeeds. Common causes:- A step targets an unknown tool, a disabled tool, or another compound.
- A step targets a
fn:or registry-added tool. - The declared
riskis not the maximum of the step risks. - Two capability sources declare the same name — this throws
conflictinstead of quarantining.