Advisory Decisions
Advisory decisions let you embed typed AI judgment into a spell while keeping execution deterministic, auditable, and safe. Every advisory has a schema, a timeout, and a fallback — so the spell always has a path forward even if the model is unavailable.
How It Works
advise → model call → schema validation → bind result
↓ (on failure)
fallback valueThe advisory output is validated against a declared schema. If validation fails (or the model times out), the fallback value is used instead.
Define an Advisor
Add an advisors section to your spell:
spell SmartRebalance {
advisors: {
risk: {
model: "anthropic:claude-haiku-4-5-20251001"
system_prompt: "Return JSON only. No prose."
timeout: 20
fallback: false
}
}
venues: {
aave: @aave_v3
morpho: @morpho_blue
}
params: { amount: 50000 }
on manual: {
decision = advise risk: "Given current rates, should we rebalance USDC from Aave to Morpho?" {
context: {
balance: balance(USDC)
amount: params.amount
}
within: "execution"
output: {
type: object
fields: {
allow: boolean
reason: string
}
}
on_violation: reject
timeout: 20
fallback: { allow: false, reason: "timeout" }
}
if decision.allow {
aave.withdraw(USDC, params.amount)
morpho.lend(USDC, params.amount)
} else {
emit skipped(reason=decision.reason)
}
}
}
Advisory Block Fields
| Field | Required | Description |
|---|---|---|
output | Yes | Declares the expected output type and schema |
timeout | Yes | Seconds before fallback is used |
fallback | Yes | Value used when model is unavailable or times out |
context | Recommended | Named runtime expressions passed to the model |
within | Recommended | Policy scope label for audit |
on_violation | Recommended | reject or clamp on schema mismatch (default: reject) |
clamp_constraints | Conditional | Required when on_violation: clamp |
Output Schema Types
# Boolean
output: boolean
# Number with bounds
output: { type: number, min: 0, max: 100 }
# Enum
output: { type: enum, values: ["buy", "sell", "hold"] }
# Object
output: {
type: object
fields: {
allow: boolean
max_slippage_bps: { type: number, min: 1, max: 500 }
reason: string
}
}
Safe Execution Path
Validate in strict mode
Strict mode turns advisory warnings (missing context, within, on_violation) into failures:
grimoire validate spells/smart-rebalance.spell --strictSimulate to record advisory outputs
grimoire simulate spells/smart-rebalance.spell --chain 1The model runs during simulation. Outputs are recorded in the run ledger.
Dry-run with recorded decisions
grimoire cast spells/smart-rebalance.spell \
--dry-run \
--chain 1 \
--key-env PRIVATE_KEY \
--rpc-url <rpc>Live cast with advisory replay
Replay the exact advisory outputs from the simulation run — no model call needed:
grimoire cast spells/smart-rebalance.spell \
--chain 1 \
--key-env PRIVATE_KEY \
--rpc-url <rpc> \
--advisory-replay <runId>Inspecting Advisory Events
grimoire log spells/smart-rebalance.spell <runId>Look for these events in the ledger:
| Event | Meaning |
|---|---|
advisory_started | Advisory step began |
advisory_model_used | Model call succeeded |
advisory_completed | Output validated and bound |
advisory_failed | Model/schema failure, fallback used |
Troubleshooting
Advisory output violated schema — align the model's output (or fallback) with the declared output schema.
--advisory-replay requires state persistence — remove --no-state from the replay command.
Advisory step enables clamp but has no clamp_constraints — add clamp_constraints: [max_slippage] when using on_violation: clamp.