feat: verifier-gated model router (run cheap → verify → escalate)
Draft
AN
2mo ago+2317+2317+0123456789012345678901234567890123456789-38-38-01234567890123456789
What does this PR do?
Adds a verifier-gated model router: run a cheap model first, verify the result deterministically (dbt build), and escalate to a stronger model only when verification fails. Flag-gated via ALTIMATE_ROUTER (default off) — the normal single-model run path is byte-for-byte unchanged.
packages/opencode/src/router/verifier.ts— deterministicVerdictfromdbt build/dbt test. Spoof-proof (parses the last summary + usesexitCodeas backstop, so a model-emitted fakeDone. PASS=… ERROR=0cannot pass the gate). PluggableImpl; honestunverifiablestate when a gate can't run.packages/opencode/src/router/router.ts— the escalation ladder. Runs each tier, verifies, escalates on a failed verdict with the exact failing checks as context, stops at the first pass. Per-tier exception handling (a transient tier error escalates instead of aborting). Ladder overridable viaALTIMATE_ROUTER_LADDER.packages/opencode/src/router/policy.ts— where the ladder comes from: a static default, or a per-context policy fetched from the altimate API whenALTIMATE_API_KEYis set (withAbortSignaltimeouts +sanitizeTiersvalidation/capping; degrades to static on any failure).packages/opencode/src/router/verdict.ts— a machine-checkable verdict envelope (schemaVersion, per-attempt history, checks, evidence hash, optional signature).packages/opencode/src/cli/cmd/run.ts— orchestration when the flag is on. Only routes verifiable (dbt) workspaces; a non-dbt project runs once with the user's own model (no silent downgrade).dbt buildruns with a hard timeout.
The customer routing policy endpoint lives in altimate-backend (separate PR). This PR ships the client + the static default.
Type of change
- New feature (non-breaking change which adds functionality)
Issue for this PR
Closes #853
How did you verify your code works?
- 51 unit tests (
test/router/*.test.ts), including adversarial cases: dbt summary-line injection, ANSI/huge/multi-summary output, endpoint response validation + cost-bomb capping, and per-tier exception escalation. - 3 env-gated E2E suites (
test/router/*.e2e.test.ts) run with real dependencies (no mocks): realdbt buildin a container (incl. a spoof-attack that fails to fool the gate), real OpenRouter model calls with real escalation, and real-network policy fallback + adversarial endpoint responses. tsgo --noEmittypecheck clean on all changed files; marker check clean.- Live CLI smoke (
ALTIMATE_ROUTER=1on a real dbt project): routed to the cheap tier → real agent run → realdbt buildverify → verdict emitted, no escalation needed. - Reviewed via multi-model consensus (
/consensus:code-review); all CRITICAL/MAJOR findings (non-dbt gating, external-call timeouts, per-tier exception handling, honestunverifiableverdict, endpoint hardening) applied before opening.
Checklist
- My code follows the style guidelines of this project
- I have performed a self-review of my own code
- I have commented my code, particularly in hard-to-understand areas
- I have added tests that prove my fix is effective or that my feature works
- New and existing unit tests pass locally with my changes
- Draft —
execute()-level follow-ups (reuse one session across tiers;finallycleanup of per-tier listeners/tracer) tracked for a follow-up before marking ready
Summary by cubic
Adds a verifier‑gated model router: run a cheap model, verify with dbt build, and escalate only on failure. Optional, flag‑gated equivalence verifier compares base↔head compiled SQL and falls back to build/test; escalated tiers reuse the same session; default off.
-
New Features
- Router: decision‑aware escalation (escalate on
FAILED/PROVEN_DIFFERENT, never onUNDECIDABLE); stops at first pass; reuses the initial session across tiers. - Verifier: spoof‑proof dbt parsing (last summary +
exitCodebackstop) with a 300s timeout; verdicts includestrength(UNVERIFIABLE<BUILD<DBT_TEST<EQUIVALENCE) anddecision(OK|PROVEN_DIFFERENT|UNDECIDABLE|FAILED). - Equivalence: behind
ALTIMATE_ROUTER_EQUIVALENCE=1using a git+dbtReferenceResolverto produce base↔head compiled SQL pairs andaltimate_core.equivalence; onUNDECIDABLEor resolver/engine errors, falls back to build/test without silent passes. - Verdict envelope: v2 schema with
strength/decision, attempt history, checks, evidence hash, optional signature. - Policy/CLI: static ladder or Altimate API policy (
ALTIMATE_API_KEY/ALTIMATE_API_URL) with outcome reporting; routes only in verifiable dbt workspaces; non‑dbt runs once; env:ALTIMATE_ROUTER,ALTIMATE_ROUTER_EQUIVALENCE,ALTIMATE_ROUTER_LADDER,ALTIMATE_API_KEY,ALTIMATE_API_URL.
- Router: decision‑aware escalation (escalate on
-
Bug Fixes
- CLI always removes per‑run signal handlers and finalizes the tracer in a
try/finally, preventing leaks when a tier throws. - E2E router tests skip (not fail) when
E2E_IMGorOPENROUTER_API_KEYare missing. - E2E cleanup removes the redundant
sudo rm -rfand relies onrmSync, avoiding unnecessary privileges.
- CLI always removes per‑run signal handlers and finalizes the tracer in a
Summary by CodeRabbit
-
New Features
- Verifier-gated router orchestration in the
runcommand enables multi-tier policy routing with workspace verification. - Integrated dbt-based workspace verification to validate outcomes deterministically.
- Escalation logic threads failure context across tiers to guide subsequent attempts.
- Verdict envelopes capture and report routing outcomes.
- Support for both API-driven and static routing policies.
- Verifier-gated router orchestration in the
-
Documentation
- Added comprehensive router module documentation.
-
Tests
- Added extensive unit and end-to-end test coverage for router components.