You are a coding agent. ADocumentation Index
Fetch the complete documentation index at: https://docs.aethis.ai/llms.txt
Use this file to discover all available pages before exploring further.
/decide call returned something unexpected. Work through this page in order; each step is safe.
Step 1 — Read the envelope, not just the decision
Every/decide response carries an audit envelope:
decision—eligible/not_eligible/undeterminedmissing_fields— which fields the engine wanted but didn’t getfields_providedvsfields_evaluated— if provided > evaluated, the extra fields are either unknown to this ruleset (probably a typo) or not relevant to the active pathslugresolved — if you sent a slug, this confirms what the resolver picked. Different from what you expected? Wrong slug, wrong tenant. (The datedruleset_idis also returned — that’s the immutable version-pin if you need byte-exact replay.)engine_version— same as your local expectation? Mismatched engine versions can change outcomes; pin the version if replay matters
Step 2 — Re-run with include_trace: true
Trace shows per-group status for every criterion group in the ruleset:
/explain output for that group tells you which clause of the source legislation it compiled from.
Via MCP:
include_explanation: true adds a structured explanation object to the response — the gate-level checklist plus the supporting facts that proved each satisfied criterion. Shape:
groups[].statusandcriteria[].statusaresatisfied/not_satisfied/pending— the gate-level checklist.supporting_factslists the answers that proved each satisfied criterion. For anOrbranch, only the satisfied disjunct’s facts appear (no over-reporting alternatives).unused_factslists field names you provided that no criterion in the ruleset references — the typo signal. If you sentchild.school_kindinstead ofchild.school_type, it shows up here.
Step 3 — If decision = not_eligible, use /explain-failure
Step 4 — If you got a 4xx, check the error reason_code
Every error response has areason_code under detail:
| Status | reason_code | What to do |
|---|---|---|
| 401 | (no body) | Missing x-api-key on a scoped endpoint. Check Nomenclature — rulebook lookups need a key. |
| 403 | reserved_namespace | You tried to publish under aethis/* without an internal key. |
| 403 | invalid_scope | Your key doesn’t have the scope the endpoint needs. |
| 404 | (no reason_code) | Ruleset/rulebook not found — check slug spelling and visibility. |
| 409 | slug_conflict | Slug is owned by another tenant. Pick a different namespace. |
| 422 | invalid_slug_format | Slug must be ^[a-z][a-z0-9-]*(/[a-z][a-z0-9-]*)*$. |
| 422 | outcome_logic validation | You sent {"expr": "..."} instead of an Expr AST. See Nomenclature and the Author recipe. |
| 429 | (no body) | Rate limit hit. Retry-After: 86400 on daily-tier exhaustion. |
Step 5 — Still confused? Minimal reproduction
decision_id is the handle — the server logs every decision keyed by that id.
Common gotchas
ruleset_id: "aethis/uk-fsm"— that’s a rulebook slug. Move the value torulebook_idand addx-api-key. See Nomenclature.- Anonymous
/decideon a private ruleset returns 404 — the engine doesn’t leak existence of private rulesets. If you own the ruleset, add your API key. - Slug resolves to an unexpected version — slug pointers transfer on re-publish. Check
ruleset_idin the response envelope to see which ruleset you actually hit. missing_fieldsis empty but decision isundetermined— discretionary clause (see system-wide discretion principle) or a case outside the compiled rules. The ruleset may need regeneration or an explicit rule for your case.
Next steps
- Errors reference — every
reason_codethe API emits - Decision envelope — the audit/replay contract
- Evaluate a case — the happy-path workflow