arthai-marketplace

/router

Operate the Arth Router, the live routing decision service: status, usage summary, pool calibration, override reporting.

Synopsis

/router <status|summary|pools|calibrate|outcome DECISION_ID>

When to use it

Quickstart

/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).

Examples

/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

What it does

  1. Reads ARTH_ROUTER_URL from the environment (set by /router-setup).
  2. Calls the corresponding router API (/health, /usage/summary, /policy/pools, /outcome) and presents the JSON as a readable digest.
  3. For calibrate, walks the capacity-estimate correction: rate-limited while the pool showed well under 100% → lower capacity_usd; never limited at 100% → raise it.
  4. If the router is unreachable, says so, the triage hook is falling back to the static routing table, which is the designed behavior, not an outage.
  5. GLM routes (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.

Requirements

Output

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.

Troubleshooting

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.

Feeding the router from your own evals (routing feedback)

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.