Operate the Arth Router, the live routing decision service: status, usage summary, pool calibration, override reporting.
/router <status|summary|pools|calibrate|outcome DECISION_ID>
status, pools)summary)calibrate)outcome)/router-setup/router summary
What you’ll see: decisions/denials/outcomes counts, total spend, each capacity pool’s state (headroom / on_pace / tight / exhausted) with its rationale, and the two kill-test numbers called out, override rate (> 0.5 means the routing rules are wrong) and estimate bias (> 10% means the cost model needs fixing).
/router status # health: version, catalog sizes, pools, auth/audit
/router summary # the weekly validation digest
/router pools # capacity pools with burn state + rationale
/router calibrate # guided window-capacity calibration
/router outcome rd_ab12cd34ef # report actuals for a routed decision
ARTH_ROUTER_URL from the environment (set by /router-setup)./health, /usage/summary,
/policy/pools, /outcome) and presents the JSON as a readable digest.calibrate, walks the capacity-estimate correction: rate-limited while
the pool showed well under 100% → lower capacity_usd; never limited at
100% → raise it.platform: zhipu-api): the triage hook prints the exact spawn
command, the ANTHROPIC_BASE_URL/ANTHROPIC_AUTH_TOKEN pair scoped to one
claude -p process against Z.ai’s Anthropic-compatible endpoint. Never set
those variables globally; if GLM_API_KEY is missing the hook says so and
the task runs on the best Claude alternative (reported as overridden).When the router is configured, /goal and /implement
also consult it automatically at every agent spawn and report per-lane
outcomes on their own, /router outcome remains the manual path for
prompt-level triage decisions you acted on yourself.
/router-setup) and ARTH_ROUTER_URL in the environment.GLM_API_KEY in ~/.arthai/.env (chmod 600),
optional GLM_BASE_URL override.A readable digest of the router’s JSON. For summary: decision/denial/outcome
counts, total spend, per-pool state with rationale, and the kill-test verdict
lines (override rate vs 0.5, estimate bias vs the 10% SLO). For status: a
one-line health summary. For outcome: confirmation with any
metered_equivalent_burn_usd the router applied.
| Symptom | Fix |
|---|---|
| “router unreachable” | Service down: the triage hook is falling back to static routing by design. Restart via /router-setup or the command in ~/.arthai/arth-router/router.log’s directory. |
ARTH_ROUTER_URL unset |
Run /router-setup (writes it to ~/.claude/settings.json); env loads in NEW sessions. |
| Everything routes to cheap models | Pool tight/exhausted or budget ≥ limit: check /router pools; that’s the policy working. Raise limits in ~/.arthai/arth-router/policy.yaml if wrong. |
| 401/403 from the router | Auth is enabled on a shared instance: put ARTH_PLATFORM_TOKEN=<jwt> in ~/.arthai/.env (chmod 600; the single token every Arth service reads). Set ARTH_ROUTER_TOKEN only to override it for the router specifically. |
| “GLM ROUTE NOT EXECUTABLE” | GLM_API_KEY missing: add it to ~/.arthai/.env (chmod 600). The task still runs on a Claude model; the router is told it was overridden. |
After you’ve run /eval studies, scripts/routing-feedback.sh
turns the graded results into routing evidence — no LLM anywhere, and nothing
is ever changed without you:
scripts/routing-feedback.sh propose # aggregates → PROPOSED diff, never applied
scripts/routing-feedback.sh apply <proposal.diff> # the explicit human step
propose aggregates tests/eval/runs.jsonl per (task-family × dated model)
and writes three things: a proposed model-policy.override.yml diff under
~/.arthai/proposals/ with a one-sentence why[] citation per change (e.g.
“deepseek passed 9/10 backend-fix cells at $0.04/passing vs sonnet $0.31 —
proposing execution lane for family backend-fix”), an evidence sidecar, and
the same aggregates as ~/.arthai/eval/router-history.json — the file the
router’s history signal (ARTH_ROUTER_HISTORY_SOURCE=file|http) can be
pointed at or serve, only if you run a router; without one it’s just a
local report.
Guardrails, always on: protected paths (migrations, billing, auth, …) are
never re-routed; families with too little evidence get “insufficient
evidence”, never a guess; cells with cheat markers are excluded from pass
rates with the exclusion counted; a candidate must match the Claude
baseline’s pass rate and be cheaper per passing task; planning stays on
Claude. apply shows the diff, asks for confirmation, validates the result
against the model-policy.yml schema, and records what was applied in
~/.arthai/routing/applied.jsonl. On a central (team) posture, apply
refuses: the proposal file is the deliverable — you propose, your admin
approves.
Task specs opt into aggregation by declaring family: (and optionally
lane: and paths:) — see tests/eval/tasks/smoke-fix-nullguard.yml.
/router-setup, install and wire the router/routing, the static triage rubric (the fallback path)/eval, run the studies whose results feed routing proposalsArthTech-AI/arth-router (usage guide, scalability, enforcement docs)