skill
omnilane
One routing table, every harness: cross-vendor model dispatch for Claude Code, Codex, Grok Build, Antigravity
Set up
Skills are installed by placing their folder where your agent loads skills.
The download comes from github.com/Seraphim0916/omnilane itself, not from our server, so what you get is exactly what its author published.
Install instructions come from the README
README
synced Oct 25, 2026omnilane
One routing table, every harness.
Your main loop stops guessing which model to use. Drive it from Claude Code · Codex · Grok Build · Antigravity, and every subtask goes to the model that is actually best at it — Codex, Claude, Grok, Gemini, Kimi, Qwen, OpenCode, or any hosted model via OpenRouter — on the subscriptions you already pay for, or a single API key.
English · 繁體中文 · 简体中文 · 日本語 · 한국어
Current upgrade and verification
Snapshot-only upgrades now reuse unchanged request-selector proofs automatically: score/date changes use the new ceiling immediately, without omnilane resign, GUI login, network calls, or rewriting the overlay. Only new/changed request contracts or executable identities need omnilane resign --vendor VENDOR; the refusal names the affected row and whether a desktop terminal is needed. Legacy format 1 works for release-pinned source snapshots; unknown older sources need inspection with omnilane resign --check. First-time setup and signer approval are unchanged. Run scheduled verification as omnilane resign --daily (or bash scripts/resign-daily.sh): failures stay nonzero and appear in omnilane doctor from private local status, without Telegram. No scheduler is installed automatically.
Environment failures (API errors, timeouts, login, quota, or connectivity) are eligible for omnilane resign --vendor VENDOR. Non-interactive runs wait 20 hours after each failed row; interactive runs or omnilane resign --retry-failed --vendor VENDOR retry immediately. The retry flag never approves a signer change. Failure evidence and timestamp presence are integrity-protected; changed or deleted records are reported and are not retried.
Expired proofs are refreshed through the same missing-row path, without re-probing healthy rows. A model/effort mismatch is a conclusive finding and will not retry automatically, even with --retry-failed. Run omnilane doctor, inspect the recorded request and CLI/provider routing, and correct the cause before arranging fresh verification. Release notes below describe behavior at the time of each release; current installations follow this section.
🤔 What is omnilane?
The problem. You already drive an AI coding assistant — Claude Code, Codex, Cursor, Gemini CLI. Each one talks to a single model family. So every task you give it runs on that one model, whether or not it is the right tool: a throwaway file rename burns your most expensive model, and a genuinely hard architecture question runs on whatever you happened to open.
What omnilane does. It gives your assistant a routing table. Work gets sorted into lanes — hardest coding, bulk mechanical, triage, hard judgment, final polish — and each lane names the model that is best (and cheapest) for it. The assistant delegates each lane through a compatible caller-owned native agent or the existing vendor CLI, even when the worker uses the same model.
What it is not. Not a proxy, not a new subscription, not another service to
keep alive. It is a table plus a dispatch script that runs behind the tool you
already use. ./install.sh --uninstall removes every trace.
You do not need every vendor. Each lane is a fallback chain. Install one CLI or seven — dispatch picks the first candidate you actually have, and a lane with nothing available simply turns off. The default table works on a single subscription.
⬇ 60-second start · 🤖 Let your AI assistant drive it · ❓ FAQ
⚡ 60-second start
You, a person at a terminal, can dispatch right away.
1. Install.
npm i -g omnilane
Or clone it, which also gives you the routing table and the skill to customise:
git clone https://github.com/Seraphim0916/omnilane && cd omnilane
./install.sh # finds your CLIs, links the skill, speaks your language
2. See what you have. doctor lists which model CLIs and API keys omnilane
can reach, so you know what will actually run. It changes nothing.
omnilane doctor
omnilane list # the routing table this machine resolves
3. Say you are the operator, then dispatch.
export OMNILANE_AA_OPERATOR_ASSERTED_HUMAN=1
omnilane route hardest-coding "fix the flaky auth token refresh"
omnilane ui start # optional: watch jobs live in your browser
Why the export? omnilane checks every delegation against the capability score of whoever is asking, so a dispatch has to say who that is. A human says it once with
OMNILANE_AA_OPERATOR_ASSERTED_HUMAN=1(or--operator-asserted-humanper call). A model cannot say it for itself: its identity is read from the CLI that launched it. With neither, the dispatch is refused withmissing-caller-contextbefore any job exists.
That is all a human needs. The rest of this section is for the more useful setup: your AI assistant dispatching on its own.
🤖 Let your AI assistant drive omnilane
The assistant (Claude Code, Codex, Grok Build or Antigravity) reads a skill file that tells it how to pick a lane and dispatch. Four steps, once per machine.
Step 1 — Give the assistant the skill
./install.sh links it for every CLI it finds. By hand:
| Assistant | How |
|---|---|
| Claude Code | claude plugin marketplace add <this repo> then claude plugin install omnilane@omnilane (also gives /route, /route-jobs and the completion inbox), or link skills/omnilane into ~/.claude/skills/ |
| Codex | link skills/omnilane into ~/.codex/skills/ |
| Grok Build | grok plugin install <this repo> --trust |
| Antigravity | agy plugin install <this repo> (check first with agy plugin validate <this repo>) |
Step 2 — Prove, once, that each CLI selects the model it is asked for
A model caller is only allowed to dispatch to a target this machine has proven:
that codex -m gpt-5.6-sol really runs Sol, and so on. The proof is a local file,
the transport overlay. Nothing ships with one. Without it every lane refuses
a model caller with runtime-mapping-unverified, and omnilane doctor warns
no overlay configured.
Build it from a normal desktop terminal. (An ssh login cannot read the keychain the CLIs log in with, so it would report them all as not logged in.)
cd "$(npm root -g)/omnilane" # or your clone
ROOT=~/.omnilane/transport-evidence/first-sweep
python3 scripts/lib/probe_sweep.py --root "$ROOT" # one tiny prompt per selector, about 55 calls
python3 scripts/lib/build_overlay.py --root "$ROOT"
cp "$ROOT/transport-contracts.local.json" ~/.omnilane/transport-contracts.local.json
echo 'export OMNILANE_AA_TRANSPORT_OVERLAY="$HOME/.omnilane/transport-contracts.local.json"' >> ~/.omnilane/local.sh
omnilane doctor | grep transport-overlay # PASS, with a count per vendor
A vendor you are not logged in to is reported unprobeable and simply stays
unverified; the others work.
Step 3 — Keep the proof current without doing it by hand
The overlay pins each CLI executable by hash, and the CLIs update themselves,
often weekly. After an update that vendor's lanes are refused until the overlay
is re-signed. omnilane resign does the whole job: finds what changed, re-probes
only that vendor, checks the result, swaps it in, sends one real dispatch to
confirm, and restores the old file if that fails. A source channel only permits probing; it never authorizes dispatch by itself.
Record the signers of the unchanged executables from Step 2 once with omnilane resign --record-signers. Existing team records imply a Developer ID channel, now requiring Apple's certificate chain as well as the team, product identifier and resolved installation location. An old adhoc record without explicit operator trust grants no channel.
omnilane resign --record-signers # once, right after Step 2
For a locally patched CLI, omnilane resign --trust-adhoc claude trusts future adhoc updates at the same installation location. On each host separately, also run omnilane resign --trust-origin claude while a verified factory sample is installed. If the installed sample is adhoc, use omnilane resign --trust-origin claude --team TEAMID, replacing TEAMID with the ten-character team you independently confirmed. This command requires a terminal and the exact confirmation shown; there is no confirmation bypass and no default team. A verified factory update and a later local adhoc update each need their own probes. Same-location adhoc trust does not prove who produced the replacement.
omnilane resign --trust-adhoc claude # only if you re-sign claude adhoc yourself
For a pinned script or native non-macOS executable, use omnilane resign --trust-location VENDOR. After reviewing a changed location or a new script, omnilane resign --approve VENDOR permits only this attempt; after successful probing you can trust the new pinned location. It does not create a channel. Revoke with omnilane resign --revoke-origin VENDOR KIND, where KIND is developer-id, adhoc, script, no-platform-signature or location (all location channels). An empty revoked list stays authoritative over old overlay trust.
omnilane resign --check and omnilane doctor show executable kind and approved channels, and observed team/identifier when blocked. Invalid signatures, unavailable signature verification, unsigned macOS native files and damaged or foreign-host policy files always stop; approval cannot repair them. Source failures and login failures have different instructions. Restore a valid installation or local policy backup before retrying. Source blocking applies when the executable changes. An unchanged pinned executable keeps the existing missing-row, retry and evidence-refresh behavior.
Channels live in host-bound, atomic, backed-up, 0600 $OMNILANE_HOME/transport-origins.local.json; do not copy them between hosts. The first-use policy now covers Developer ID plus self-signed, script and no-platform-signature tools at their installation location; it takes effect with the phase-2 first probe, and no production code calls the interface yet. First-use trust is currently per vendor with no recorded identity, path or policy entry, not per host; phase-2 wiring will decide whether other vendors' existing records should block it. Scripts and non-macOS binaries are not silently trusted on upgrade. AI assistants must never run trust, approval, recording or revocation commands themselves.
Then let it run every day. Any scheduler works as long as it runs inside your desktop login session (the CLIs need the keychain). On macOS, a LaunchAgent:
cat > ~/Library/LaunchAgents/dev.omnilane.resign.plist <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>dev.omnilane.resign</string>
<key>ProgramArguments</key><array><string>/bin/zsh</string><string>-lc</string><string>omnilane resign --daily</string></array>
<key>StartCalendarInterval</key><dict><key>Hour</key><integer>9</integer><key>Minute</key><integer>0</integer></dict>
<key>StandardOutPath</key><string>/tmp/omnilane-resign.log</string>
<key>StandardErrorPath</key><string>/tmp/omnilane-resign.log</string>
</dict></plist>
EOF
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.omnilane.resign.plist
This release verified omnilane resign from a desktop terminal session, including
a real unattended re-sign of a Codex self-update; the LaunchAgent wrapper above is
an example and was not itself exercised. Check it on your machine with
launchctl kickstart gui/$(id -u)/dev.omnilane.resign.
What omnilane resign exits with:
| Exit | Meaning | You do |
|---|---|---|
| 0 | nothing had changed, or everything that changed was re-signed | nothing |
| 10 | --check only: something changed | run omnilane resign |
| 20 | source review, login or verification needs attention | follow the source-specific or login-specific message; approval cannot waive invalid, unsigned or unverifiable signatures |
| 30 | the re-signed overlay failed its real dispatch and the previous one was restored | nothing is broken; read the log |
| 2 | no overlay is configured | do Step 2 |
40 (EXIT_HOST_CONFIG) | dispatch's host configuration could not load, or the configured overlay is unreadable or invalid JSON; nothing read/staged/written after a shell failure | fix the path/error on stderr; daily-job owners decide notification policy |
50 (EXIT_BUSY) | another omnilane resign is already running on this host; nothing read or written | let it finish, then run this one |
Exit 2 also covers argparse usage errors; a configured but unreadable overlay is exit 40, not 2.
Step 4 — Try it from inside the assistant
Ask your assistant to run omnilane whoami. It should answer with the model and
effort it is running as, and a score. Then ask it to delegate something small:
"use omnilane to have the triage lane count the TODO comments in this repo".
If it is refused, the refusal says which check failed and what to do:
failed_gate | In plain words | Fix |
|---|---|---|
caller-identity | omnilane could not tell which model is asking | have it run omnilane whoami as the only command in that tool call. Codex in particular is unreadable behind ; echo $?, && or a pipe |
target-transport | this machine has not proven that target, or a CLI updated since | omnilane resign (Step 3) |
downward-ceiling | the target model scores higher than the model asking; a model may only delegate sideways or down | pick one of the eligible_lanes the refusal lists, or start the assistant at a higher effort |
A Codex automation that wakes an existing thread records no effort. omnilane then holds that caller to its model's lowest score instead of refusing it: cheap lanes keep working, expensive ones say which effort would reach them.
🧭 How it works
omnilane lets the main loop of any agentic CLI classify subtasks into
lanes and dispatch each lane to the best vendor — headlessly, using your
existing subscription logins (or, for the openrouter vendor, a direct API
key with no extra CLI at all):
flowchart LR
M["main loop<br/><i>any CLI you drive</i>"] --> T{{"routing.yaml<br/>one shared table"}}
T -->|hardest-coding| C1["Claude — Fable 5.1"]
T -->|bulk-mechanical| C2["Codex — GPT-5.6 Sol"]
T -->|taste-final| C3["Claude — Fable 5.1"]
T -->|long-context| C4["Gemini — 3.7 Flash"]
T -->|live-search| C5["Grok — 4.6"]
T -->|"arbitrate (opt-in)"| C6["vote — 1-4 model panel"]
routing.yaml— lane → vendor + model + effort. One file, read by every harness.- Fallback chains — a lane can list candidates
(
codex … | claude … | off); dispatch picks the first vendor CLI you actually have, so the default table works even with a single subscription. scripts/dispatch.sh [--vendor V] <lane> "<task>"— resolves the lane and shells out to the vendor's CLI headlessly.--vendorselects one named vendor without fallback.skills/omnilane/SKILL.md— a single skill every harness can load: identify the lane's model and delegate through a compatible native agent or CLI.omnilane mcp— the same routing surface as an MCP stdio server, for hosts that integrate via MCP instead of skills.
| 🧭 One tablefour harnesses share it | 🪂 Fallback chainsdegrades to the CLIs you have | 🗳️ Opinion panelmulti-model vote for big calls |
| 🔒 Safety railslocks · watchdogs · no nesting | 🌏 Five languagesthe installer speaks your locale | ↩️ Reversible--uninstall undoes everything |
🛤️ Lanes
Defaults below — run scripts/dispatch.sh --list for the table your machine
actually resolves.
AA aa-v4.3.2-2026-10-27-v1: approved on 2026-10-27 (by the controller, acting on the operator's request that day to add the new model); 130 scored configurations and 9 unknown rows. It adds GPT-6.1 Terra (six rows, max 48) and places it where the value rule picks it in hardest-coding, bulk-mechanical, ui-draft and fast-agentic; every first choice is unchanged. Host transport proof is still required. Evidence. It replaces aa-v4.3.2-2026-10-18-v1 (approved 2026-10-19).
AA aa-v4.3.2-2026-10-08-v1: approved by the operator on 2026-10-08; Haiku 5.5's claude-haiku-5-5 ID and five effort levels were officially confirmed on 2026-10-08; host transport probes are still pending. Evidence.
| Lane | First choice | Backup | When |
|---|---|---|---|
| 🔥 hardest-coding | GPT-6 Astra (xhigh) | Gemini 4 Argon (High) → GPT-6.1 Sol (xhigh) → Claude Opus 5.5 (medium) → GPT-6.1 Sol (high) → GPT-6 Astra (medium) → GPT-6.1 Sol (medium) → GPT-6.1 Terra (xhigh) → GPT-6.1 Terra (high) → GPT-6.1 Terra (medium) → Claude Fable 5.1 (medium) → Claude Opus 5 (high) → Claude Sonnet 5.5 (high) → GPT-6 Astra (low) → Claude Opus 5 (medium) → Claude Opus 5.5 (low) → Claude Haiku 5.5 (xhigh) → Claude Sonnet 5.5 (medium) → Claude Opus 5 (low) → Grok 4.7 (high) → Gemini 3.8 Flash (High) | Hardest implementation, deep root-cause debug, correctness-critical edits |
| 🏗️ bulk-mechanical | GPT-6.1 Sol (medium) | Claude Opus 5.5 (medium) → GPT-6 Astra (medium) → GPT-6.1 Sol (high) → GPT-6.1 Terra (high) → GPT-6.1 Terra (medium) → Claude Sonnet 5.5 (high) → GPT-6.1 Sol (low) → GPT-6 Astra (low) → GPT-6 Sol (high) → GPT-5.6 Sol (high) → Claude Opus 5.5 (low) → Claude Haiku 5.5 (xhigh) → Claude Sonnet 5.5 (medium) → Claude Haiku 5.5 (high) → Claude Haiku 5.5 (medium) → Claude Haiku 5.5 (low) → GPT-6 Sol (medium) → Claude Opus 5 (low) → GPT-6 Sol (low) → Gemini 4 Argon (High) → Gemini 3.8 Flash (High) | Refactors, migrations, tests, review sweeps — mechanical endurance |
| 🧹 triage | GPT-6 Luna (high) | GPT-5.6 Luna (high) → Gemini 4 Argon (High) → Gemini 3.8 Flash (Low) → Claude Haiku 5.5 (medium) → Claude Haiku 5.5 (low) → Claude Sonnet 5 (low) → Claude Haiku 4.5 | High-volume scans, first-pass filtering |
| ⚖️ hard-judgment | Claude Opus 5.5 (xhigh) | Claude Fable 5.1 (xhigh) → Gemini 4 Argon (High) → Claude Opus 5.5 (medium) → Claude Fable 5.1 (medium) → Claude Opus 5 (high) → Claude Opus 5 (medium) → Claude Opus 5.5 (low) → GPT-6.1 Sol (xhigh) → GPT-6 Astra (high) → Grok 4.7 → Gemini 3.8 Flash (High) | Architecture arbitration, deep reasoning, second opinions |
| ✒️ taste-final | Claude Sonnet 5.5 (xhigh) | Claude Opus 5.5 (xhigh) → Claude Opus 5.5 (high) → Claude Sonnet 5.5 (high) → Claude Opus 5.5 (medium) → Grok 4.7 (high) → GPT-6 Astra (xhigh) → Claude Haiku 5.5 (xhigh) → Gemini 4 Argon (High) → Claude Haiku 5.5 (high) → Gemini 3.8 Flash (High) | User-facing prose and style arbitration; benchmarks do not prove visual or editorial taste |
| 💬 consult | GPT-6 Astra (xhigh) | Claude Opus 5.5 (xhigh) → Grok 4.7 → Gemini 4 Argon (High) → Gemini 3.8 Flash (High) | Direct named-model consultation; keep --vendor to prevent fallback |
| 🎨 ui-draft | Claude Opus 5.5 (high) | GPT-6.1 Sol (high) → GPT-6.1 Terra (high) → Claude Opus 5.5 (medium) → GPT-6 Astra (medium) → GPT-6.1 Sol (medium) → GPT-6.1 Sol (low) → Claude Opus 5.5 (low) → GPT-6 Astra (low) → GPT-6.1 Terra (low) → GPT-6 Sol (medium) → Gemini 4 Argon (High) → Gemini 3.8 Flash (High) | UI drafts only with a design system or reference images; no aesthetic benchmark claim |
| 📚 long-context | Claude Opus 5 (high) | Claude Opus 5 (medium) → Claude Opus 5 (low) → GPT-5.6 Terra (xhigh) → Gemini 4 Argon (High) → Gemini 3.8 Flash (High) | Long-document synthesis; context size alone does not prove task quality |
| ⚡ fast-agentic | GPT-6.1 Sol (medium) | GPT-6.1 Terra (medium) → GPT-6.1 Terra (low) → GPT-6 Astra (medium) → GPT-6.1 Sol (low) → GPT-6 Sol (low) → GPT-6 Astra (low) → Gemini 4 Argon (High) → Gemini 3.8 Flash (Medium) → Claude Sonnet 5.5 (medium) → Claude Opus 5.5 (low) | Fast multi-step tool loops and multimodal checks |
| 📡 live-search | Grok 4.7 | Gemini 4 Argon (High) → Gemini 3.8 Flash (High) → Claude Opus 5.5 (low) → off | Realtime X/web search; backups provide generic web search, not equivalent X context |
| 🚰 coding-overflow | Grok 4.7 | Gemini 4 Argon (High) → Gemini 3.8 Flash (High) → Kimi Code K3 → Qwen3.8 Max → OpenCode → off | Explicit Codex-quota relief; provider failure does not auto-retry another vendor |
| 🗳️ arbitrate | off (opt-in vote panel) | — | Built-in opinion panel for big calls — disabled by default; enable it in routing.local.yaml, one call per voter per round |
Argon High is included in every Flash-bearing lane and requires Google AI Ultra plus successful host transport proof. In bulk-mechanical, triage, fast-agentic, live-search and coding-overflow, it sits immediately before Gemini 3.8 Flash while the original value or purpose default stays first. The other six placements are unchanged; UI/long-context access does not imply measured superiority. Grok remains first for realtime X/web search and Codex-quota relief; Argon provides generic web search as a fallback. consult --vendor gemini selects Argon within Gemini only. Medium/Low remain unscored.
The backup is the next candidate in the lane's routing.yaml chain — what
dispatch falls back to when the first-choice vendor CLI is not installed. Every
lane is such a chain; when nothing in it is installed the lane degrades to off.
Fable 5.1 and Astra now lead hard work. See the current same-condition evidence in FAQ.
Natural-language consultation
With the omnilane skill or /route, you can ask normally:
“Ask Opus to challenge this architecture.” The Agent Skill interprets the
request; this is not a free-form shell parser in dispatch.sh.
- A capability-only question recommends the first available model for the matching lane and makes no model call.
- A generic vendor name uses that vendor's configured candidate in
consult. - A canonical alias such as Opus pins its exact model family from the skill table. If an explicit target is absent or unavailable, the command fails clearly instead of falling back to another vendor or family.
Using the assistant's own sub-agents
By default omnilane hands work to a vendor's command-line tool. When the model that should do the work belongs to the assistant's own vendor, going out through a second CLI is a detour: another login, another process, another thing that breaks when that CLI updates. Most assistants can start a sub-agent themselves, and omnilane can plan the work for that instead. Two ways.
A worker that runs exactly what the assistant runs (--inherit). The
assistant starts its sub-agent without choosing a model or an effort, so the
worker is a copy of the caller. A copy cannot be stronger than the original,
which is the only thing omnilane's score check is there to prevent, so this path
needs no vendor CLI and no transport overlay, and it keeps working when the
caller's effort is unknown or an overlay has gone stale.
omnilane native-context --workdir /absolute/repo --inherits-caller-runtime # prints a capability file
omnilane route --inherit --native-context /path/printed/above --workdir /absolute/repo triage "Count the TODO comments"
# -> a PENDING handoff (JSON). The assistant now starts its own sub-agent with no
# model argument, checks the result, and records it:
omnilane jobs --json complete-native JOB_ID /absolute/completion.json
omnilane jobs --json status JOB_ID
The honest part: the handoff is marked satisfies_lane_target: false. The lane
is only a label for the kind of work. A result produced this way was made by
"the assistant's own sub-agent", never by "the hardest-coding model", and a lane
that needs a stronger model than the caller is still refused.
--inherits-caller-runtime is the assistant's own statement that its sub-agent
tool behaves this way; omnilane cannot observe it. What is known per assistant:
| Assistant | Sub-agent without a model argument |
|---|---|
| Claude Code | documented to use the main conversation's model, and the session's effort unless the agent definition sets one. True for the built-in general-purpose agent with CLAUDE_CODE_SUBAGENT_MODEL unset. Run end to end in this release |
| Codex | collaboration.spawn_agent with no model and no effort. Run end to end in this release |
| Grok Build | documented to inherit the parent's model (the bundled general-purpose agent is model: inherit); effort not documented. Not run in this release |
| Antigravity | no sub-agent tool found in agy 1.2.7. Not available |
A specific model the assistant's tool can select. Describe what the tool
really accepts in a capability file (start from omnilane native-context, add a
row per exact model and effort) and pass --native-context FILE to an ordinary
omnilane route. omnilane uses the sub-agent only when a row matches exactly:
model, effort, mode, workdir, tools, isolation and lifecycle. Same vendor is not
same model, and nothing is guessed from the CLIs you have installed.
--executor native fails instead of falling back; --executor cli forces the
external CLI. When a same-vendor target goes out through the CLI only because no
file was given, dispatch now says so.
Either way the sub-agent shares the assistant's tools and filesystem: there is no
operating-system sandbox, and advise/work are intent, not enforcement.
Background, live, named-thread, multi-round, vote and sysops work stays on the
CLI path. Protocol handling needs Python 3.9+. Schemas, the completion file,
agent reuse and cancellation: docs/native-executor.md.
The best model for a lane does not change with the commander. These are role hints, not self-execution exemptions: even a same-model task is delegated. A native agent is eligible only when the caller explicitly confirms the exact model, effort, mode, workdir, tools, isolation and lifecycle. Otherwise use CLI. The commander orchestrates and validates; workers do not delegate again.
- Claude Code · Fable 5.1 — recommended prompt-level controller for quality-sensitive work; this is a role, not a lane or automatic selector. Delegate hardest-coding at max and judgment/taste at xhigh; use Astra for an independent Codex review, Sol for bulk, Gemini 3.8 Flash for long/fast work, and Grok for live search.
- Claude Code · Opus 5 — balanced prompt-level controller and independent reviewer when explicitly selected (
high, orxhighfor deeper review), plus long-context fallback. This is an opt-in role, not a new lane or the default hard-judgment route. - Codex · Sol — delegate bulk-mechanical and constrained ui-draft at high. Escalate hardest coding and judgment to Fable/Astra; route long/fast work to Gemini 3.8 Flash and live search to Grok.
- Codex · Astra — prompt-level controller backup and independent reviewer. Use xhigh by default for hardest coding/judgment and consult/taste; explicitly select
--vendor codex --effort maxwhen needed. Explicit model/effort always win. - Codex · Terra — delegate the Codex long-context fallback at max. Bulk stays on Sol high; escalate hard work to Fable/Astra.
- Grok Build · Grok 4.7 / 4.6 — delegate live-search and coding-overflow, plus fallback duty in hardest-coding, hard-judgment, and taste-final. Dispatch primary hard coding/judgment/taste work to Codex/Claude/Gemini when available; verify API signatures and cited facts.
- Antigravity · Gemini 3.8 Flash — delegate long-context Medium, fast-agentic/triage Low, and bulk/overflow/web fallbacks High. Do not infer visual taste or controller authority from agent/coding benchmarks.
🖥️ Live Board
Every dispatch — foreground or --background — is a job on disk. The Live
Board is an optional, read-only local workbench over that job store: what each
model was asked, what it answered, how it was routed, and whether it is still
running.
omnilane ui start # start or reuse the server and print its authenticated URL
omnilane ui status # inspect the local server
omnilane ui url # print the current authenticated URL
omnilane ui stop # stop it cleanly
The desktop view keeps the job list and detail pane independently scrollable;
mobile uses a list/detail flow with Back and Esc navigation. Server-sent events
stream updates without replacing focused rows, and a short disconnect keeps the
last snapshot while reconnecting. Pin any loaded task as a reference, then
select another task to compare both model paths and public results side by side.
The reference is memory-only and disappears when the page closes. The board
binds only to 127.0.0.1, uses a random token, and is read-only. It shows
task.txt and the public out.txt, but never raw worker or vendor logs.
Search and state filters apply to the latest 50 retained jobs. Export visible downloads only the currently visible public metadata as local JSON; it excludes tokens, task text, result bodies, workdirs, and raw logs.
The board reads in English, Japanese, Korean, Traditional Chinese and Simplified Chinese. It follows the browser language on first load; the switcher in the header overrides that and the choice is remembered locally.
Core routing does not need Python; only this UI requires Python 3.9 or newer.
Foreman completion inbox
Finished dispatches write a private completion record under $OMNILANE_HOME/inbox/. A Claude Code SessionStart hook binds each foreman's hook-provided session ID to its live process ancestry, and the bundled UserPromptSubmit hook atomically delivers up to ten records owned by that session on the foreman's next prompt. Older records without a session ID still use the original dispatch workdir scope; claimed records move to inbox/consumed/. Set OMNILANE_INBOX=0 on a dispatch to disable record creation; the default is enabled.
📦 Install
Requirements: the vendor CLIs you want to route to, logged in (codex,
claude, grok, agy, and optionally kimi, qwen, opencode) and on
PATH — install only the ones you have; the rest of the table degrades
automatically. The openrouter vendor is the exception: it needs no CLI,
only curl and an OPENROUTER_API_KEY in your environment.
Quickest: ./install.sh — symlinks the skill for the CLIs it finds, prints
the plugin commands for the rest, shows your effective routing, and offers the
interactive lane configurator (--uninstall reverses it). The installer
speaks English, 繁體中文, 简体中文, 日本語 and 한국어 (auto-detected from
your locale; force with OMNILANE_LANG=zh-TW etc.). It also offers an
optional per-CLI routing reminder: a marked, reversible block appended to
each CLI's instruction file (~/.claude/CLAUDE.md, ~/.codex/AGENTS.md,
~/.grok/Agents.md, ~/.gemini/GEMINI.md — paths may vary across CLI
versions) so the main loop remembers to consult the table; non-interactive
installs can pass OMNILANE_HOOKS=all|none|claude,codex.
The foreman completion notice requires the Claude Code plugin install; the skill-only symlink path does not deliver completion notices. Install the plugin from this checkout with:
claude plugin marketplace add <path to this repo>
claude plugin install omnilane@omnilane
Use ./install.sh --check for a read-only drift report. Add --dry-run to an
install or --uninstall to preview every checkout-owned file action.
Rollback the installer-owned links and marked reminders with
./install.sh --uninstall.
Manual wiring:
- Claude Code: install as a plugin (ships the skill +
/route,/route-jobscommands, and aSessionStarthook that auto-injects the routing reminder at session open — no CLAUDE.md edit needed), or dropskills/omnilaneinto~/.claude/skills/. - Codex: drop/symlink
skills/omnilaneinto~/.codex/skills/. - Grok Build:
grok plugin install <this repo> --trust - Antigravity:
agy plugin install <this repo>(check first withagy plugin validate <this repo>)
MCP server
omnilane mcp starts a zero-dependency, local MCP stdio server so any
MCP-capable host can discover and call omnilane without installing the skill or
adding a routing reminder. Configure the host to launch the installed CLI:
{
"mcpServers": {
"omnilane": {
"command": "omnilane",
"args": ["mcp"]
}
}
}
The server exposes route plus read-only introspection: list_lanes,
explain, validate, dry_run, jobs_list, jobs_status, jobs_result,
jobs_stats, jobs_recommend, jobs_audit, doctor, and the explicitly opt-in
provider_probe. route defaults to read-only advise mode. Calls that select work must also
provide an explicit workdir.
Node.js is the only runtime requirement (no npm packages). If you prefer
npm, npm install -g omnilane installs the CLI with the MCP server
included.
⚙️ Configure
Three layers, all optional:
- Interactive menu —
scripts/configure.shlists configurable lanes, lets you pick vendor → model → effort per lane from suggestions (or free text for future models), and writes the result to~/.omnilane/routing.local.yaml. It intentionally skips the multi-vendorconsultlane; edit that one by hand if needed.install.shoffers to run the menu at the end of a normal install. For scripting,configure set|get|unset|list|diff LANE [SPEC]edits or inspects the same file without a tty —setvalidates the lane and rejects an unsafe or structurally invalid spec, rolling back on failure. ~/.omnilane/routing.local.yaml— hand-edited overrides, same format asrouting.yaml; local lines win. Seerouting.local.yaml.example.~/.omnilane/local.sh— per-machine binaries, proxies, auth wrappers; sourced by every runner, never committed. Seelocal.sh.example.
Check the result any time:
scripts/dispatch.sh --list # effective table, fallback resolution annotated
📖 Command reference
omnilane list | route … | jobs … | configure # global wrapper, works anywhere
# (install.sh links it into ~/.local/bin)
eval "$(omnilane completion bash)" # enable Bash completion for this shell
source <(omnilane completion zsh) # enable Zsh completion for this shell
omnilane completion fish | source # enable Fish completion for this shell
omnilane mcp # MCP stdio server (needs Node.js)
omnilane release-audit [--target VERSION] [--json] # offline, read-only release gate
omnilane ui start # start/reuse the local Live UI; print its URL
omnilane ui status # report whether the Live UI is running
omnilane ui url # print the current authenticated local URL
omnilane ui stop # stop the Live UI
omnilane doctor [--json] [--strict] [--probe V] [--probe-timeout SEC] # live probe is opt-in
# transport-overlay: path mismatch FAIL; vendor hash or runner drift WARN
omnilane benchmark [--json] [--run] [--vendor V] [--cost-per-call V=USD] # dry-run by default
dispatch.sh [--background] [--dry-run] [--thread NAME] [--mode advise|work|sysops] [--workdir DIR]
[--vendor V] [--model M] [--effort E] [--timeout SEC] [--job-timeout SEC]
[--caller-context FILE | --operator-asserted-human] # who is asking
LANE "TASK" # "-" reads task from stdin
dispatch.sh [--json] --list [--json]
dispatch.sh [--json] --explain LANE [--json] # offline candidate-by-candidate decision trace
dispatch.sh [--json] --validate [--json] # lint effective routing; no provider calls
jobs.sh [--json] {list | status ID | result ID} # JSON result reports metadata, never bodies
jobs.sh [--json] list [--lane L] [--vendor V] [--status running|done|dead|pending|cancelled|expired] # filter the listing
jobs.sh wait ID [--timeout N] # job exit; 124 timeout; 125 dead worker
jobs.sh cancel ID # stop a running job: group SIGTERM, then SIGKILL
jobs.sh rm ID # move one finished/dead job to ~/.Trash (refuses a running job)
jobs.sh [--json] stats [--last N] [--lane L] [--vendor V] # local success and routing aggregates
jobs.sh [--json] recommend [--last N] [--lane L] [--min-samples N] # evidence-gated vendor suggestion
jobs.sh audit [--last N] [--json] # read-only job integrity/privacy check
jobs.sh prune [--keep N] [--apply] # preview by default; completed jobs only; --apply moves them to ~/.Trash
configure.sh # interactive lane menu
configure.sh set|get|unset|list|diff LANE [SPEC] # script/inspect routing.local.yaml, no tty
configure diff keeps the same machine-specific availability settings from local.sh in both views, so its comparison reflects routing overrides rather than missing local binaries. If either inspection fails, it returns that exit status and names the failed stage instead of printing a comparison.
configure get propagates a failed inspection’s status instead of returning partial data or calling the lane unknown. configure list reports presence-check errors; genuinely missing or empty overrides still succeed.
configure set validates a temporary candidate before publishing it and preserves an existing file’s permission mode. Failures reading existing routing content, unexpected validator failures, or structural errors in the target lane leave the previous configuration untouched; availability warnings and unrelated-lane errors retain their existing handling.
configure unset finishes reading and filtering before changing the destination, then retains its existing in-place write behavior. Read/filter errors leave the original content unchanged; write errors are reported without a rollback guarantee.
Bash, Zsh and Fish completion include the documented top-level, goal and job command groups. Choosing a completion only fills command text; it does not run a job action.
Without --vendor, benchmark discovers vendors from the effective routing list and ignores its unavailable display markers. If no benchmark vendor remains, it exits 2 with a no-configured-vendors diagnostic; the default remains a dry-run without provider calls.
Job list and status use the same observed state. dead means the worker PID is invalid or no longer exists and no exit was recorded; it is excluded from --status running and selectable with --status dead. result reports that no exit was recorded instead of calling the dead worker running. A missing PID still uses the existing startup running state; no exit code is invented.
Background jobs require Perl supervision so cancellation can terminate the
supervised process group. Supervision alone adds no whole-job deadline; when
no job timeout applies, metadata remains job_timeout: null. The supervised
per-call watchdog uses the separate scripts/lib/call-timeout.pl supervisor and
returns 142 on expiry; whole-job deadline
expiry returns 124. jobs close waits up to 11 seconds, including group cleanup.
--thread NAME continues named Claude, Codex, Grok, or Gemini conversations across
single-shot dispatches. In 0.33.0 it pins vendor, model, effort, and physical
workdir; use jobs.sh threads, threads show NAME, or threads rm NAME to
manage local state without deleting the vendor session.
jobs recommend reads only validated public metadata and exit codes. It ranks
eligible vendors by success rate, sample count, then name; the default minimum
is three completed jobs. It never reads task/result bodies or changes routing.
doctor --probe V makes one bounded advise-mode provider call and returns only
availability, selected model, timing, and response byte count—not the response
body. Without --probe, doctor remains offline. benchmark uses the fixed TSV
suite in benchmarks/workloads.tsv; its default dry-run resolves every route
without provider calls. --run is the explicit call gate, and cost totals are
estimates based only on values supplied with --cost-per-call.
Big decisions can get a panel, not a person. The arbitrate lane ships
disabled — a panel costs one call per voter per round, so it is opt-in.
Enable it with arbitrate: vote codex,claude,grok - in routing.local.yaml,
or through the configurator, which lets you pick any 1-4 voters from
codex/claude/grok/gemini. The same question then goes to every voter, the
opinions come back side by side, and the calling model chairs the verdict.
Set the effort field to 2 for a debate round — every voter sees the whole
panel and rebuts only the disagreements. Power users can swap in their own
gate via the exec vendor:
arbitrate: exec /path/to/script - — the script receives
MODE WORKDIR EFFORT PROMPT_FILE OUTPUT_FILE and writes its verdict to
OUTPUT_FILE (see scripts/runners/run-exec.sh).
Exit codes: 2 bad usage (including an invalid vendor or a requested vendor
absent from the lane), 3 lane disabled (off), 4 no vendor CLI available in
the chain or the requested vendor is configured but its CLI is unavailable,
5 too few successful Round 1
voters, 6 no Round 2 rebuttal succeeded, 86 nested dispatch refused, 87
lock timeout, 124 whole-job timeout expired; otherwise the worker's own exit
code passes through.
🎭 Modes
- advise (default): read-only local analysis with native web/search tools where the vendor supports them. Model/provider traffic stays available; agent mutation tools are restricted. This is not a promise of identical X/web capabilities across vendors.
- work: local file and command work confined to the explicit
--workdir, with agent-tool network access disabled. This does not disable the model/provider connection. Unsupported enforcement fails before provider startup rather than silently becoming sysops. - sysops: explicit per-dispatch opt-in to unrestricted agent tools and filesystem/network access. It is never a lane default; the task must state the allowed operations.
The CLI defaults --workdir to the caller’s current directory when omitted; task briefs should still specify it explicitly. The MCP route/dry_run work interface separately requires an explicit workdir.
Codex and Claude have distinct policies for all three modes. Agy advise/sysops use isolated per-session native app settings without replacing subscription authentication; Agy 1.1.27 work has bounded new/resume acceptance using four validated tools and the native terminal sandbox: workspace read/write/edit/build and policy-denied outside writes passed. External temp/cache reads are also restricted; settings are explicitly regenerated at each start rather than claimed immutable. A separate real two-turn work live/FIFO check passed readback, outside-write denial and normal close with unchanged sources. Grok advise uses native tool allow/deny rules; its complete single-shot plain path has verified native keyword search, page fetching, and a denied write on Grok 1.0.13. It uses internal web-tool IDs and job-local MCP readiness without disabling hooks. An existing nonempty CONTEXT_MODE_MCP_SENTINEL_DIR conflicts with this advise scope and stops before provider startup rather than being overwritten. Grok work remains gated by default on macOS because native child-network isolation is Linux-only, and Grok live requires explicit sysops; the advise result does not validate these other paths. OpenRouter remains advise-only; other vendors are not implicitly covered by this four-vendor contract. See the dated runtime gate for evidence boundaries.
macOS Grok work: the operator may enable single-shot work without isolation using option.grok-macos-work: unconfined in routing.local.yaml only. Off by default; chains skip Grok for macOS work when off. doctor --strict fails when on. See the option, risks, and required Grok worker brief.
🔒 Safety rails
- No nested dispatch — workers cannot fan out again (
OMNILANE_DEPTHguard, exit 86): no runaway agent-calls-agent quota chains. - Serialized codex — same-target-directory codex dispatches queue behind a lock keyed on the normalized workdir; stale locks from crashed jobs are detected by owner PID and stolen safely.
- Watchdog — every worker runs under
timeout/gtimeout, or a perl-alarm fallback when neither exists (stock macOS), so a hung CLI cannot block forever. The cap applies to each CLI invocation, highest priority first:--timeout SECONDSbeats a per-laneOMNILANE_TIMEOUT_<LANE>(the lane upper-cased with-→_, e.g.OMNILANE_TIMEOUT_HARD_JUDGMENT) beats the globalOMNILANE_TIMEOUT, default 600s. For a live mailbox, it bounds the whole resident CLI session; completing a turn does not stop or reset that clock. It is a per-call hang-guard, not a whole-job budget: a retrying vendor (grok) or thevotepanel (voters × rounds) makes several calls, so total wall-clock can be a multiple of this value. - Whole-job fuse — optional
--job-timeout SECONDScaps lock wait plus all retries, voters, and rounds under one process-group supervisor. Priority is flag >OMNILANE_JOB_TIMEOUT_<LANE>>OMNILANE_JOB_TIMEOUT> disabled, with one automatic exception: Codexworkoutside a Git worktree uses the resolved per-call watchdog as its whole-job fuse when none was configured, capped at the supervisor's 999999999-second maximum. This automatic guard needs the bundled Perl supervisor; if unavailable, dispatch warns and keeps non-Git work running through the existing per-call watchdog path, which emits its own warning if no watchdog tool exists. Expiry cleans the supervised process group and returns 124. For a deep audit of a large repository, start around 2–4 hours (7200–14400s) with a 30-minute per-call watchdog; these are recommendations, not defaults. - Background lifecycle —
--backgroundworkers run in their own process group and survive the caller's exit; killed workers record an exit code, andjobs.sh statusreportsdeadinstead ofrunningforever. - Payload caps — oversized task text is truncated head+tail before it can blow a worker's context.
📬 Live mailbox
The per-call --timeout bounds the whole resident session. Completing a turn
does not stop or reset that clock. For Claude and Gemini, an answered session
that reaches this timeout is classified as success only when every sent turn
has a vendor SUCCESS result and usable output is available. Its output ends
with closed by per-call timeout after Ns; last turn completed. A trailing
Gemini cancellation error does not undo completed turns. An unanswered turn
keeps exit 142, reported as CALL_TIMEOUT; jobs.sh stats includes it in both
failed and the call_timed_out sub-count. Read the answer and use
jobs close ID promptly, or use --single-shot for one-shot background work.
A live mailbox is a resident background dispatch, not a one-shot dispatch. Claude and Gemini retain their existing automatic live behavior with --background. Codex and Grok default to single-shot; opt in with --background --live (Grok additionally requires --mode sysops --workdir DIR). The foreman can send another instruction while it is running and is responsible for closing it with jobs.sh close ID. The idle cap and configured whole-job timeout (--job-timeout) can still end it.
scripts/dispatch.sh --background --vendor claude hard-judgment "Review the timeout failure"
# save the printed job ID as $ID
scripts/jobs.sh send "$ID" "Also inspect the retry path."
scripts/jobs.sh watch "$ID"
scripts/jobs.sh tail "$ID" --lines 20
scripts/jobs.sh close "$ID"
scripts/jobs.sh retry "$ID" --background
Foreground dispatch and foreground jobs retry print the stored public output even when the job fails, then return its nonzero exit code. Background dispatch keeps its job-ID output.
watch follows $JOB_DIR/events.jsonl; tail reads the public out.txt. Live mailbox support covers Claude, Gemini, Codex, and Grok. Automatic selection remains single-shot for Codex/Grok; only explicit --live opts them in. Grok advise rejects --live because ACP does not enforce its read-only boundary; normal advise uses single-shot native tool allow/deny rules. --live fails fast for unsupported vendors. --single-shot forces one-shot execution for every vendor. --idle-timeout SECONDS sets the inactivity cap (default 900; 0 disables it).
An idle mailbox makes no API calls and incurs no API spend. By default it closes after 900 seconds without a new inbox message or result event, while the whole-job timeout remains the outer cap. Close it sooner when its exchange is finished. jobs.sh send to a finished job or a job that is not live fails with a clear error. Do not use this for fire-and-forget work, vendors without live support, or a clean-slate rerun; start a fresh dispatch (or retry a completed job) instead.
🎯 Goal orchestration
omnilane goal is a foreman-driven ledger for exploratory work. The caller—an agent session or a human terminal—owns the loop: dispatch a job, receive its result through the completion inbox or omnilane jobs wait, decide the next job, and repeat. Job and elapsed-time budgets are unlimited by default; --budget-jobs N and --budget-seconds S opt in to each hard cap. omnilane supplies bookkeeping only, enforces any caller-supplied caps plus the always-on repeated-failure fuse before each goal dispatch, then assembles the report when the foreman closes the goal.
GOAL_ID="$(omnilane goal open "Fix the flaky checkout integration" \
--budget-jobs 4 --budget-seconds 900 --workdir /path/to/repo)"
JOB_ID="$(omnilane goal dispatch "$GOAL_ID" --mode work hardest-coding \
"Reproduce the checkout failure and implement the smallest verified fix")"
omnilane jobs wait "$JOB_ID" --timeout 900
omnilane goal note "$GOAL_ID" "Fix verified by the checkout integration test"
omnilane goal close "$GOAL_ID" --summary "Checkout integration is stable"
Goal state lives under $OMNILANE_HOME/goals/<goal-id>/. Use goal status to inspect budget usage, fuse trips, and each recorded job as its metadata and exit status land. goal close writes report.md and prints its path. For one obvious task, dispatch directly. When budget flags are supplied, those caps are hard bounds, not completion promises.
Failure counts are rebuilt from durable job records after an interrupted refresh, without counting a failure twice. goal close seals the goal only after publishing its report; if publication fails, correct the error and retry close.
A busy goal prints read-only lock-owner diagnostics and keeps exit code 75. Locks are never automatically removed; a recorded PID is not proof of ownership, so manual verification is required before recovery.
Goal status and reports preserve dead and missing states instead of calling them running. Unavailable or inconsistent job-status evidence is unknown, with no invented exit or failure count. Per-job seconds remain elapsed time since submission, not measured active runtime; goal budgets are unchanged. Incomplete jobs each require one local status check, bounded to two seconds.
After normal cleanup of completed job artifacts, the goal retains its validated exit, completion time and elapsed-to-finish duration. Status and reports mark artifacts=missing separately. A job with no recorded completion remains missing or unknown; cleanup never creates a terminal result.
Goal dispatch first journals an intent and reserves one job slot. A one-time claim binds that intent to the generated job ID before launch. spent_jobs still counts recorded jobs; reserved_jobs covers unresolved submissions. An unresolved or corrupt journal blocks new dispatch and close. Reconciliation repairs records without launching work; it never invents an exit or retries an ambiguous submission.
For threaded goal dispatch, stdout is the exact job ID; the matching thread notice is shown on stderr after the ID is verified. Direct background dispatch keeps its existing notice-and-ID stdout format.
goal dispatch launches a background job and does not support --dry-run; the option is rejected before goal state changes. To preview routing, use omnilane dispatch --dry-run [options] LANE "TASK" directly. Direct previews do not inherit the goal’s working directory; pass --workdir DIR when needed.
Persisted goal budgets require JSON integers, not booleans or numeric strings. Optional limits remain null or 1..999999999; counters must be nonnegative and fit the supported numeric range. Invalid fields are rejected before ledger updates or dispatch. Workdir paths containing tabs, carriage returns, newlines or NUL are unsupported; ordinary spaces and Unicode remain supported.
If dispatch errors or its result is lost, inspect goal status before submitting again: a fresh identical command creates a new intent, so the guarantee is one launch per intent, not global command deduplication. Valid existing worker PID/exit evidence is needed to reconcile a claim; pruning that evidence before reconciliation leaves the reservation unresolved. Already-reconciled goal history survives pruning. Old goals remain readable. No automatic stale-lock or ambiguous-intent recovery is performed.
Background finalization preserves its chosen exit status when HUP/TERM arrives. Completion hooks skip already-consumed records and deliver at most ten records per prompt, including unreadable-record notices.
Do not use goal orchestration for a single obvious task; dispatch that task directly. The default unlimited budgets let the caller keep exploring without omnilane imposing a cap; pass either budget flag only when that limit is wanted.
❓ FAQ
No. Every lane is a fallback chain, and dispatch picks the first candidate
whose CLI is actually installed. With one subscription the whole table collapses
onto that vendor; lanes with nothing available turn off rather than failing.
omnilane doctor shows exactly what your machine can reach today, and
routing.local.yaml.example ships starter profiles for common situations
(Claude-focused, Codex-heavy, no-Codex).
No new destination. Dispatch shells out to vendor CLIs you already installed
and logged into, so your code reaches exactly the vendors you already use.
Runners strip API-key environment variables before invoking a subscription CLI,
so a stray key cannot silently switch you onto pay-per-token billing. The one
exception is the direct-API vendor family (openrouter, deepseek, zai,
mistral, groq, cerebras), which by definition calls that provider's API
with the key you set — those are advise-only and never edit files.
The 2026-09-05 refresh compares the two on AA v4.2 under matching effort:
Fable/Astra score 57/55 at max and 54/54 at xhigh; AA Briefcase is
1666/1566 at max and 1657/1540 at xhigh. In the native coding-agent comparison,
Fable max completes 70 at $9.18/task in 24 minutes and Astra max completes 67
at $4.72/task in 26.8 minutes. That supports Fable max for
hardest-coding, Fable xhigh for hard-judgment/taste-final, and Astra as
the Codex-family fallback or independent reviewer.
Fable max is the quality-first prompt-level controller. Opus high/xhigh is
the balanced controller and independent-review option; Astra is the existing-
Codex-quota backup/reviewer. These are role recommendations, not a new lane or
automatic controller selector. Opus also remains the Claude long-context
fallback.
Effort is selected per task, not assumed to improve monotonically. The current
same-condition and native coding evidence justifies max for correctness-first
hardest-coding; xhigh remains the quality/cost default for
hard-judgment, taste-final, and named Fable consultation. Explicit
--model and --effort always override these route defaults.
Dispatch walks the chain and uses the first vendor you have. Inspect the decision without spending a call:
scripts/dispatch.sh --explain hardest-coding # candidate-by-candidate trace
scripts/dispatch.sh --list # whole effective table
scripts/dispatch.sh --dry-run hardest-coding "…" # fully resolved plan, no provider call
Only if you ask for it. Dispatch defaults to advise, with per-vendor read-only
sandbox or native tool permissions and supported web search. For bounded edits,
use --mode work with an explicit --workdir; agent-tool networking is disabled
while the model connection remains available. --mode sysops is a separate,
explicit full-access policy for Codex, Claude, Grok, and Agy, not an alias for
work. Use it only when the task explicitly permits operations outside work's
boundary, such as service management. It is never a lane default. Workers
also cannot dispatch again — the depth guard refuses nested fan-out with exit 86,
so one command can never spiral into a chain of agents spending your quota.
Three codes, three different fixes. Run omnilane doctor first — its
transport-overlay check tells you immediately whether the problem is your
machine's configuration or your request.
missing-caller-context — no identity reached the gate. A human adds
OMNILANE_AA_OPERATOR_ASSERTED_HUMAN=1 or --operator-asserted-human. A model
normally needs nothing: dispatch reads its identity from the nearest launching
CLI, using a bound current-turn rollout for Codex app-server/no-model launches.
When that fails, run omnilane whoami — it either prints a
--caller-context FILE to pass, or says exactly why it cannot (a missing
--effort, a model alias, no scored row). A model must not assert the human
exemption for itself.
Every refusal is one JSON line on stderr. Read failed_gate, reason and
next_command first; eligible_lanes lists what you can still dispatch.
runtime-mapping-unverified — your identity is fine, but the target has no
proven host-local request selector. Either it was never probed, or its probe
failed. omnilane doctor and --json show each unproven row as WARN: its ID,
requested and observed model/effort (when recorded), failure class and reason,
last probe time, evidence paths (not contents), and next step. Environment
failures name omnilane resign --retry-failed --vendor VENDOR; conclusive
failures never auto-retry and name the request/CLI/provider mapping to inspect.
Damaged evidence diagnostics name the affected path and explain restoration
from a known-good backup or explicit fresh probing into a new directory.
A provider quota refusal will not clear until that quota does.
invalid-policy-input with "transport contract evidence changed" — neither of
the above. The overlay itself will not load, so every vendor is refused. The
usual cause is a vendor CLI upgrade: the overlay pins each vendor's executable
and runner-script hash, and Codex and Claude evidence paths embed version
directories, so an upgrade removes the file rather than changing its digest.
Tagged evidence degrades only its own vendor; untagged evidence, such as the
probe manifest, still closes the whole gate. Doctor names the file and the
vendor; omnilane resign re-probes and re-signs it, and the dispatch skill
carries the runbook behind that command.
target-above-effective-ceiling — nothing is broken. The target scores above the
caller. required_caller_effort names the effort the calling session would need;
a caller marked caller_degraded was launched by a harness that recorded no
effort (a Codex heartbeat automation does this) and is held to its model's floor.
It says how strongly the probe pinned down who answered. It does not affect whether you can dispatch.
billed-model — the provider named the model it charged for. Claude reports it
in modelUsage; grok reports it the same way under --output-format json. This
is the provider's receipt.
client-echo — the CLI wrote down the model it asked for, and that record
matches your request. Codex keeps it in the session rollout; agy writes it to
cli.log. This is the CLI's copy of your order, not the provider's receipt: it
proves the request left as intended, not who served it.
selector-only — the CLI accepted the selector and reported nothing further.
Every mapping probed before v0.42.6 reads this way. It still dispatches; it is
simply the weakest of the three, and omnilane doctor names the vendors worth
re-probing.
None of the three certifies upstream provider identity, and none of them can refuse a lane. The tier is derived from what a probe produced rather than from the vendor, so a CLI that starts reporting a billed model is promoted on its next sweep with no change to omnilane.
📊 Defaults and provenance
Default lane assignments follow Artificial Analysis coding/intelligence data
(2026-07 snapshot, cross-checked against AA site records and vendor pricing
pages) plus published head-to-head reviews; they are opinions, not laws — the
configurator and routing.local.yaml exist so you can disagree. The full
working notes, including per-benchmark caveats, live in
docs/model-capabilities-2026-09.md.
⚠️ Known limitations
- Antigravity tool calls in print mode are unstable in current CLI builds (tool calls may be denied or rejected with invalid-argument errors). The long-context lane is designed for content-you-paste-in synthesis, which is unaffected; for repo inspection prefer the claude/codex candidates.
- Grok has no reasoning-effort knob; the effort field is accepted for interface parity and ignored.
- Non-Git Codex work is supported. Some Codex CLI builds may stall outside a Git worktree, so the automatic fuse above bounds that case and cleans the supervised process group. Omnilane neither initializes nor requires a repository.
📜 Release history
What's new in v0.58.0
- After upgrading, every host must run
omnilane resignbecause the AA snapshot has changed. - AA snapshot
aa-v4.3.2-2026-10-27-v1adds GPT-6.1 Terra with six scored efforts (130 scored rows in total). Terra joins selected lane fallback chains; existing scores and every lane's first choice stay unchanged. - Fixes in refusal messages, Codex live sessions, caller identity, result normalization and the parsing of status and overlay files; see CHANGELOG for the list.
- Upgrade:
npm i -g omnilane@0.58.0.
What's new in v0.57.0
- After upgrading, run
omnilane native-context --installonce from a terminal on each host; when upgrading from 0.56.0, also runomnilane resignonce from a GUI terminal because the AA snapshot has changed. omnilane native-context --installrecords the model each harness's own configuration starts with, so a caller that dispatch cannot identify (for example a read-only Codex sandbox) falls back to an inherited worker with no extra flags.- A lane dispatch refused only because the caller's identity could not be read now falls back to the
--inherithandoff when a--native-contextfile states the caller's model; it never guesses an identity. - Every lane refusal prints a one-line
omnilane refusal:summary and is stored as evidence under$OMNILANE_HOME/refusals/. omnilane self-exec recordandomnilane stats self-exectrack tasks the commander did itself after a stored refusal.codex/gpt-5-4-minireturns to the score table (no lane lists it);routing.yamlis unchanged.omnilane resignno longer reports working Claude selectors asmodel-mismatchwhen the advisor tool is enabled, and keeps a held vendor's failed probe output.- Upgrade:
npm i -g omnilane@0.57.0.
What's new in v0.56.0
- When upgrading from 0.55.0, run
omnilane resign --vendor geminionce from a GUI terminal becauserun-gemini.shhas changed. - Gemini tasks are no longer silently truncated: inputs over 180,000 bytes on macOS and other non-Linux platforms, or 130,000 bytes on Linux, fail with rc=2 before agy starts while
task.txtretains the full input. - Quota preflight reroutes eligible lane dispatches when fresh Codex weekly usage reaches the default 90% threshold, while preserving explicit targets and existing thread continuations.
- Unknown model names now list registered aliases and suggest
omnilane list. - Live per-call timeouts count as success only after all turns complete, with usable final output and no pending input, later activity or forwarding failure remaining.
- Retire Grok 4.6 from routing and remove Gemini 3.6/3.7 Flash choices from configure.
- Fix live-close deadline handling and make close-deadline tests runnable independently in a clean checkout.
- Gemini advise can now read files outside the dispatch workdir, except private credential and session paths.
- Upgrade:
npm i -g omnilane@0.56.0.
What's new in v0.55.0
- When upgrading from 0.54.0, run
omnilane resignonce from a GUI terminal because the AA snapshot has changed. - Gemini 4 Argon (High) joins the score table and lanes, immediately before Gemini 3.8 Flash; Antigravity-only hosts use it first while existing defaults and other model ordering stay unchanged.
- AA snapshot
aa-v4.3.2-2026-10-14-v1was operator-approved on 2026-10-18; each host still needs its own transport proof. - Fix the race between background-job timeout receipts and process exit; keep
which-binread-only without writing Python bytecode caches. - Upgrade:
npm i -g omnilane@0.55.0.
What's new in v0.54.0
- Future registry snapshot updates automatically reuse verified rows whose request parameters and executable identities are unchanged; only new or changed rows need
omnilane resign. This release keeps the 0.53.0 snapshot. - Environment failures such as API errors, timeouts, login, quota or connectivity can be retried with
omnilane resign --vendor VENDOR. Non-interactive runs wait 20 hours per failed row; interactive runs or--retry-failedretry immediately, without approving signer changes. Conclusive model/effort mismatches never auto-retry. - Blocked dispatch names the vendor and row, gives the exact next command, and explains whether a GUI terminal is required.
omnilane doctorandomnilane doctor --jsonlist every unverified row with requested/observed identity, failure reason, probe time, evidence paths and next steps; damaged evidence includes backup restoration or fresh-probe guidance.omnilane resign --dailypreserves nonzero failures and interrupted runs in private local status visible throughomnilane doctor, even without Telegram. No scheduler is installed automatically.- Upgrade:
npm i -g omnilane@0.54.0. Upgrading from 0.53.0 does not require re-signing; upgrading from an earlier version still requires one run ofomnilane resignfrom a GUI terminal.
What's new in v0.53.0
- After upgrading, run
omnilane resignon every host once, from a GUI terminal: the registry snapshot is nowaa-v4.3.2-2026-10-08-v1. All dispatch is blocked withtransport overlay snapshot mismatchuntil the overlay is re-signed. - Claude Haiku 5.5 adds five scored rows: max 43, xhigh 41, high 38, medium 34 and low 29. Claude Sonnet 5.5 (low) returns at 36, bringing the table to 120 scored configurations. Haiku's model ID and effort levels are confirmed, but host transport remains unprobed.
taste-finalnow starts with Claude Sonnet 5.5 (xhigh, 52). Haiku 5.5 joins lower-ceiling coding, bulk, triage and taste candidates; it is not promoted tofast-agentic.resigntests a fresh three-digit sum instead of a verbatim reply, locks out a concurrent re-sign with exit 50, and leaves no lock file behind on a missing or unreadable overlay (exit 40).- Foreground Claude and Gemini dispatch runs single-shot, so a finished answer no longer waits for a resident session to time out with exit 124. Background dispatch keeps its resident session.
jobs closewaits the full 11 seconds; a repeated close signal during worker shutdown no longer kills it with exit 158.jobs rmandjobs prune --applymove jobs to a per-run trash directory under${OMNILANE_TRASH_DIR:-~/.Trash}, with amanifest.tsvof job IDs and original paths. Permanent deletion is left to the operator.- Upgrade:
npm i -g omnilane@0.53.0, thenomnilane resign.
What's new in v0.52.0
- After upgrading, run
omnilane resignon every host once, from a GUI terminal: the registry snapshot is nowaa-v4.3.2-2026-10-02-v2and the runner scripts changed, so dispatch refuses until the overlay is re-signed. - The snapshot retires the three
gpt-5.4-miniCodex rows (Codex rejects them on a ChatGPT account) and re-scores twelve GPT-6 Sol and Luna rows;fast-agenticputs GPT-6.1 Sol low ahead of GPT-6 Sol low. - Operator-only
option.grok-macos-work: unconfinedlets single-shot Grok work run on macOS without isolation. It is off by default and every surface discloses it. resignkeeps a vendor's verified mappings aspending_recheckwhen it cannot re-probe them, stops with exit 40 on a broken host configuration, and anchors the binary dispatch runs.doctorfails when dispatch resolves a different executable than the overlay pinned, and compares installed skill copies with the checkout.- Jobs gain a
deadstate,jobs closewaits up to 11 seconds, a live job closed by the idle cap keeps its result, and runner files are private from the start. - CI runs the behaviour checks on macOS as well as Linux.
- Upgrade:
npm i -g omnilane@0.52.0, thenomnilane resign.
What's new in v0.51.1
- After upgrading, run
omnilane resignon every host once; a host that skipped probing a new model (for example Sonnet 5.5 after an ssh re-sign) now probes just those rows. Run it from a GUI terminal so the Claude, Gemini and Grok logins are reachable. resigntreats a configuration that was never probed on this host as drift, even when no executable changed.--checklists those rows and exits 10. A probe that answered and failed is not repeated, and the signer check,--approveand--trust-adhocare unchanged.- An install that leaves rows unprobed now warns and names them.
- Upgrade:
npm i -g omnilane@0.51.1, thenomnilane resign.
What's new in v0.51.0
- Run
omnilane resignonce after upgrading. The registry snapshot changes toaa-v4.3.2-2026-09-30-v1; the old transport overlay no longer loads, and every dispatch is refused until the re-sign. - Claude Sonnet 5.5 and GPT-6.1 Sol are scored, and the lanes are re-ordered value-first on the 2026-09-30 AA capture.
- A Claude caller's identity now comes from its session transcript (current model
and effort; the launch flags are the fallback;
OMNILANE_AA_CLAUDE_TRANSCRIPT=0turns it off). A desktop session that changed model or effort mid-session, or a scheduled task started with--model default, is read correctly. - Host-declared native rows:
$OMNILANE_HOME/native-rows.jsonadds the model/effort pairs the host's sub-agent tool can run;native-context --host-rows FILE/--no-host-rows. - Upgrade:
npm i -g omnilane@0.51.0, thenomnilane resign.
What's new in v0.50.0
- Run
omnilane resignonce after upgrading. The registry snapshot changes toaa-v4.3.2-2026-09-27-v1. - A registry refresh on the 2026-09-27 AA capture: every score is unchanged, AA
re-measured speed, and no lane changes. GPT-6 Sol and Luna (medium) keep the speed
figures AA withdrew on 2026-09-26, filled by the new
scripts/aa_rebaseline.py fill. - GPT-6 Sol and Luna are proven: the model ids
gpt-6-solandgpt-6-lunapassedresignonce the Codex quota reset. - The version jumps from 0.47 to 0.50 as a milestone.
- Upgrade:
npm i -g omnilane@0.50.0, thenomnilane resign.
What's new in v0.47.0
- Run
omnilane resignonce after upgrading. The registry snapshot changes toaa-v4.3.2-2026-09-23-v2; until the overlay is rebuilt a model caller is refused on every lane withtransport overlay snapshot mismatch. GPT-6 Sol and Luna are proven only by aresignthat reaches Codex; until then every chain serves the row behind them. - GPT-6 Sol and GPT-6 Luna join the registry (Sol 48 at max down to 34 at
low, Luna 37 down to 21), with configure catalog entries and the aliases
GPT-6 SolandGPT-6 Luna. - Every lane is ordered value-first. For each caller ceiling a chain gives
the cheapest row that is close to the best that ceiling can reach on the lane's
own measurement. The quality-critical lanes trade only on near-ties; the
throughput lanes use a wider band. No chain contains a max row any more.
Astra xhigh now heads
hardest-coding, Opus 5.5 medium headsbulk-mechanical, GPT-6 Luna high headstriageand GPT-6 Sol high headsfast-agentic.scripts/aa_rebaseline.py valueshows the picks behind each chain. - Upgrade:
npm i -g omnilane@0.47.0, thenomnilane resign.
What's new in v0.46.0
- Run
omnilane resignonce after upgrading. The registry snapshot changes toaa-v4.3.2-2026-09-23-v1and the transport overlay is bound to it; until the overlay is rebuilt, a model caller is refused on every lane withtransport overlay snapshot mismatch. Untilresignhas probed Opus 5.5 on a host, lanes skip its Opus 5.5 rows and serve the next candidate. - Claude Opus 5.5 joins the registry and the lanes (58 at max, 56 xhigh, 54
high, 51 medium, 42 low on AA v4.3.2), placed on each lane's own measurements.
It leads
hardest-codingandui-draftat xhigh, andhard-judgmentandtaste-finalat max, followed by its xhigh and high rows; max is in those two chains because it is clearly ahead of xhigh there, and stays out ofhardest-coding, where it scores no higher. It is the Claude row inconsult(xhigh) and the Claude fallback inlive-search(medium). An Opus 5.5 medium controller has a ceiling of 51 and starts below the rows that head those chains. New aliasOpus 5.5;Opusstill means Opus 5. The figures are indocs/model-capabilities-2026-09.md. - Seven more AA rows are scored (gpt-5.3-codex, gpt-5.5-instant, gemini-3.5-flash-lite, gpt-oss-120b and gpt-oss-20b) so that a caller running on one of them has a ceiling. None is placed in a lane.
- Upgrade:
npm i -g omnilane@0.46.0, thenomnilane resign.
What's new in v0.45.0
- Run
omnilane resignonce after upgrading. The score registry moved to a new snapshot and the transport overlay is bound to it; until the overlay is rebuilt, a model caller is refused on every lane withtransport overlay snapshot mismatch. - Scores follow Artificial Analysis Intelligence Index v4.3.2. v4.2 and
v4.3.2 are different scales with uneven gaps (Fable 5.1 max 57 → 53, Grok 4.6
high 51 → 44, Sol high 48 → 42), so every row was re-scored rather than one
added. Ceilings move with it: Fable 5.1 max, Fable 5.1 xhigh and Astra max now
tie at 53, and a mid-effort controller that reached nothing in
hard-judgmentbefore now does.scripts/aa_rebaseline.pyrebuilds the registry from a saved AA extract, so the next index revision is a re-run. - The lane table is rewritten, not patched. Each lane now names the
measurements that match its kind of work and lists candidates best-first on
them: hard terminal coding (Terminal-Bench 4.0, the coding benchmark the
frontier has not saturated) for
hardest-coding, expert-level reasoning and graded analytical quality forhard-judgment, graded document presentation fortaste-final, automation accuracy per minute forfast-agentic, the harder long-context benchmark forlong-context, visual understanding forui-draft. Eight lanes change their first choice: Astra (xhigh) leadshardest-coding, Astra (low) leadsbulk-mechanicalandfast-agentic, Astra (high) leadsui-draft, Opus 5 (max) leadstaste-final, Opus 5 (high) leadslong-context, and Grok 4.7 leadscoding-overflowas well aslive-search. Every chain also steps down through the score range, so whatever a controller's ceiling, the first candidate it can reach is the best one it can reach. Fable max and Astra max are in no chain: xhigh is level or ahead for markedly less. The figures are indocs/model-capabilities-2026-09.md. - Grok 4.7 joins every lane Grok serves, ahead of Grok 4.6, which stays
behind it: a lane skips a candidate this host has not proven, so 4.6 keeps
serving until
resignhas probed 4.7. With--vendor grokthere is no fall-through; until then ask for--model grok-4.6. - A dead fallback fixed.
claude claude-sonnet-5 highcould never be dispatched under the old registry; it now resolves once probed. - Upgrade:
npm i -g omnilane@0.45.0, thenomnilane resign. For Grok 4.7 thegrokCLI must be logged in when you re-sign.
What's new in v0.44.0
- A CLI you patch yourself is re-signed unattended too. If a local step
re-signs a vendor CLI adhoc after every update (a post-update patch, for
instance), the signer check used to hold every such update for
--approve. Runomnilane resign --trust-adhoc VENDORonce per vendor and an adhoc update in the same install directory now goes through the dailyomnilane resignlike a same-signer one. An unsigned executable, an adhoc one in another directory, and every other vendor still stop for you. The trust is recorded on the overlay, survives later re-signs of any vendor, and is an operator action a model never runs. Works for all four vendors. - An expired login says "log in", not "retry later".
Failed to authenticate,OAuth session expired,Invalid API key,Unauthorizedand401now mark the vendor unprobeable, and the held-vendor message tells you to log in first. - Upgrade:
npm i -g omnilane@0.44.0. If you are coming from 0.42.x, runomnilane resign --record-signersonce as well (see the 0.43.0 notes).
What's new in v0.43.1
Install this rather than 0.43.0. In 0.43.0, build_overlay.py and probe.py
failed to import on Python 3.9, which broke the first-install overlay build and
omnilane resign on that version. Nothing else changed; everything in the 0.43.0
notes below applies. Upgrade: npm i -g omnilane@0.43.1, then once:
omnilane resign --record-signers.
What's new in v0.43.0
In ten days 0.42.x refused every model caller four times, each time over a fact omnilane does not control: a renamed launcher, a runner script changed without a re-sign, four vendor CLIs updating themselves in one week, and a Codex automation that records no effort. Each became "nothing can be dispatched". This release turns each into a narrower, explained outcome, and repairs the common one itself.
- Vendor CLI updated?
omnilane resign. It finds what changed, re-probes only that vendor, checks the result, swaps it in, confirms with one real dispatch, and restores the old overlay if that fails. It re-signs unattended only when the new executable carries the same code-signing team and sits in the same place; anything else stops with the exact--approvecommand for you. Runomnilane resign --record-signersonce, scheduleomnilane resigndaily, and updates stop being your problem. Verified on a real Codex self-update (0.155.0 → 0.155.1): no approval, every mapping kept, exit 0. - A refusal tells the model what to do. Every refused dispatch now carries
failed_gate,reason,next_command,required_caller_effort, andeligible_lanes— the lanes that caller can reach right now. - No recorded effort narrows instead of refusing. A Codex heartbeat automation is held to its model's lowest score rather than being refused on every lane. Cheap lanes keep working; expensive ones say which effort is needed.
- The assistant's own sub-agents.
omnilane native-contextwrites the capability file that used to be hand-made, andomnilane route --inheritplans a worker that is a copy of the caller: no external CLI, no overlay, works even when the caller cannot be identified, and is honestly marked as not the lane's target model. Run end to end in Claude Code and Codex desktop. - Codex: one omnilane command per tool call.
omnilane whoami; echo $?cannot be identified,omnilane whoamialone can. The refusal now says so. - Doctor sees a CLI that moved beside its old file, and warns, with the steps, when no overlay exists at all.
- Rewritten skill and tutorial. The skill is now a five-step procedure a model follows; this README walks through letting an assistant drive omnilane.
- Limits. Unattended re-signing relies on macOS code signatures; on Linux, and
for any unsigned or locally patched CLI, every update asks for
--approve.--inherithas not been run inside Grok Build, and Antigravity exposes no sub-agent tool. Full detail: CHANGELOG. - Upgrade.
npm i -g omnilane@0.43.0, then once:omnilane resign --record-signers.
What's new in v0.42.9
- Codex desktop behind a launcher. When ChatGPT.app starts its app-server
through codex-profile-switch, the process is named
codex-modified, and 0.42.8 walked past it looking for one namedcodex, so every dispatch from such a thread was refused withmissing-caller-context. The name is now recognised; the launcher's siblingcodex-code-mode-hostis still not treated as a CLI. - Accepted on a real desktop thread. On 2026-09-13
whoamiexited 0 from a Codex desktop thread running through the launcher, reportingcodex/gpt-5-6-sol-medium (score 46)read from thecodex-modifiedprocess. - Upgrade. Run
npm i -g omnilane@0.42.9.
What's new in v0.42.8
- Codex current-turn identity.
app-serveralways ignores startup model and effort defaults. Other Codex launches keep explicit-m/--modelor-c model=.../--configselectors (TOML model overrides require Python 3.11+); no model, including profile-only launches, uses the rollout path. - Bound, fail-closed evidence. The current process environment and the codex
direct-child initial environment must carry the same UUID-shaped
CODEX_THREAD_ID. The rollout is looked up under$CODEX_HOME/sessions(default~/.codex) asrollout-*-<thread>.jsonland, after a resume,rollout-*-<thread>_<session>.jsonl; the most recently written match is read and itssession_meta.idmust match. Its latestturn_contextneeds model, effort and turn id; a latertask_complete,turn_complete(read alias) orturn_abortedcarrying that same turn id refuses stale identity, and the refusal names both turn ids and how long ago the rollout was written. No config, model-list, archive or other-session fallback; JSONL is streamed and message content is never included in diagnostics.whoamireports thread and turn ids. - Codex sandbox refusal. Ancestor lookup still runs first. If it fails under
CODEX_SANDBOX=seatbelt,whoamiexplains that process inspection,~/.omnilanewrites and networking require rerunning outside the sandbox. - Hermetic tests. The suite no longer inherits
OMNILANE_AA_*from a dispatching worker, where the authorizer identity and the overlay hash pin used to outrank each fixture's own human exemption and fail six tests. - Compatibility. Other vendors, explicit/inherited caller identity and human
assertion precedence are unchanged.
OMNILANE_AA_CALLER_FROM_PROCESS=0disables both argv and rollout reading. - Accepted on a real desktop thread. On 2026-09-12
whoamianddispatch.sh --dry-runboth exited 0 from the Codex desktop app — in a fresh thread and in a resumed one whose original rollout had stopped the day before, reportingcodex/gpt-6-astra-xhigh (score 54)and"allowed":true. - Upgrade. Run
npm i -g omnilane@0.42.8.
What's new in v0.42.7
- A model session no longer needs an identity file to dispatch. When no
--caller-contextis given, dispatch walks up the process tree to the nearest vendor CLI and reads the model and effort it was launched with. Sessions outside the omnilane checkout used to stop onmissing-caller-contextand hand the question back to the operator; three did so on 2026-09-08 and 2026-09-10. omnilane whoamiprints that identity as a caller-context file, or says exactly why it cannot — a missing--effort, a model alias, or a Claude effort whose only scored row is non-reasoning. It never guesses.- Harder to overstate than a hand-written file. The gate checks a caller-context file's shape, not whether it matches the model actually running. Launch flags are set by the harness, not the model, and each session is held to its own: the same model at
highand atmaxgets ceilings 52 and 54. - Explicit still wins. A
--caller-contextfile, the context a worker inherits, and--operator-asserted-humanall take precedence.OMNILANE_AA_CALLER_FROM_PROCESS=0restores the file-only contract. - The refusal names the way out.
missing-caller-contextand the retry refusal now point toomnilane whoamiinstead of offering a model two options it cannot take. omnilane --versionis right again. The 0.42.6 release leftVERSIONat 0.42.5.- Upgrade. After npm publication, run
npm i -g omnilane@0.42.7. Existing repo-symlink installations can update their checkout and verifyomnilane --versionwithout rerunning installation.
What's new in v0.42.6
- A verified mapping now says how it was verified. Each overlay mapping carries an
evidence_tier:billed-modelwhen the provider named the model it charged for (Claude, grok),client-echowhen the CLI recorded the model it asked for (codex, agy),selector-onlywhen the CLI accepted the selector and said nothing more.client-echois the CLI's copy of your order;billed-modelis the provider's receipt. - Reported, never enforced. Dispatch still turns on
runtime_verifiedalone, so a weaker tier never refuses a lane that used to run. A test asserts every decision is unchanged under all three tiers. - The tier follows the evidence, not the vendor. A sweep predating this release re-judges as
selector-only, and a CLI that begins reporting a billed model is promoted with no code change. omnilane doctorshows the spread and names the vendors worth re-probing.- Overlay evidence anchors the binary that runs. Paths were written into
build_overlay.pyand drifted out of use silently — the live overlay hashed claude2.1.263while every dispatch ran2.1.266. Core evidence now resolves the executable the runners resolve. - Three dead lanes found.
gpt-5.4-minipassed its probe on 2026-09-07 and now returns HTTP 400 — "not supported when using Codex with a ChatGPT account". A signed overlay never notices a lane dying upstream; the re-probe did. Those three configurations move tounproven[]with that reason attached, leaving 46 mappings. Snapshotaa-v4.3.2-2026-10-02-v2now retires all three rows tounknown_configs, without authority, and removes the configure alias and probe candidates. Every other score and ordering is unchanged (117 -> 114 scored, Codex 57 -> 54). Every host must runomnilane resignbecause the snapshot id changed; seedocs/reports/aa-rebaseline-2026-10-02-v2.md. - Upgrade. After npm publication, run
npm i -g omnilane@0.42.6. Existing repo-symlink installations can update their checkout and verifyomnilane --versionwithout rerunning installation.
What's new in v0.42.5
- One CLI upgrade no longer refuses every vendor. Overlay evidence entries take a
vendortag; a tagged entry whose hash drifts or whose file has disappeared degrades only that vendor tounknown-target-runtime. Untagged evidence stays globally fail-closed. omnilane doctorloads the overlay. A newtransport-overlaycheck names the offending file and vendor on failure and reports per-vendor verified counts on success — an all-green doctor could previously coexist with a gate refusing every dispatch.- Probes record a verdict.
probe.pyjudges Claude responses on the billedmodelUsageand fails a run where the CLI silently substituted the default effort for an unknown--effort.build_overlay.pyrefuses to sign a non-passing probe and records it in the overlay'sunproven[]instead of dropping it silently. - Rebuild tooling is versioned.
build_overlay.pyandprobe.pylive inscripts/lib/and take--root. - Upgrade. After npm publication, run
npm i -g omnilane@0.42.5. Existing repo-symlink installations can update their checkout and verifyomnilane --versionwithout rerunning installation.
What's new in v0.42.4
- The quickstart actually runs now.
omnilane routeneeds to know who is asking; the 60-second start omitted that, so a fresh install hitmissing-caller-contextwith no guidance. It now asserts the human operator once withOMNILANE_AA_OPERATOR_ASSERTED_HUMAN=1, and explains what a model caller passes instead. - Command reference. The
dispatch.shsynopsis shows[--caller-context FILE | --operator-asserted-human].
What's new in v0.42.3
- Documentation only. No routing, scoring, gate, or runner behaviour changes.
--caller-contextis in the quick reference. The dispatch command signature now shows it, and states that a model caller without it is refused withmissing-caller-contextbefore a job exists.- A worked caller-context example. The frozen exact-AA downward gate section gains a complete JSON example, and says to build the file before the first dispatch rather than after a refusal.
- Find your own effort instead of guessing. When a harness names a model but no effort, read the exact flags from the launching process by walking your own ancestor chain; match the chain rather than the first same-named process on the host. Declaring the lowest-scoring row is the fallback, not the first move, because an unnecessarily low ceiling silently closes lanes.
- Two refusal codes, two fixes.
missing-caller-contextmeans no file was passed;runtime-mapping-unverifiedmeans the target lacks a proven host-local selector, which is fixed by a--transport-overlayentry backed by real evidence and never by editing the frozen registry. - Upgrade. After npm publication, run
npm i -g omnilane@0.42.3. Existing repo-symlink installations can update their checkout and verifyomnilane --versionwithout rerunning installation.
What's new in v0.42.2
- Grok effort reaches the CLI. Explicit
low,medium,high, andxhighselections are passed with--reasoning-effort; Grok 4.6 default routes now selecthigh. - Evidence-backed local mapping. A host-local overlay proves the exact CLI selector contract without changing frozen AA scores or the approved registry SHA. Missing or incorrect mappings still deny dispatch; explicit effort on live ACP remains blocked until that surface is verified.
- Upgrade. After npm publication, run
npm i -g omnilane@0.42.2. Existing repo-symlink installations can update their checkout and verifyomnilane --versionwithout rerunning installation.
What's new in v0.42.1
- CI fixture repair. Full Python discovery now gives legacy routing and Grok-readiness fixtures an explicit synthetic-human caller, while production missing-identity denial, the approved registry SHA, downward score checks, retry lineage, and skip assertions remain unchanged.
- Portable lineage evidence. The encoded-effort Gemini spy uses a portable Python interpreter selector and verifies the exact
--model gemini-3.8-flash-highpair. AA coverage remains 78 scored targets, one scored reference-only entry, and 10 unknown configurations. - Patch upgrade. After npm publication, run
npm i -g omnilane@0.42.1. For an existing repo-symlink installation, update the checkout and runomnilane --version; do not rerun./install.shunless deliberately rewiring integrations. GitHub release and npm publication remain separate.
What's new in v0.42.0
- Native-first execution. Routing and execution are separate:
--executor autouses a caller-owned native agent only when the host supplies an exact compatible capability context, and otherwise keeps the same vendor/model/effort on the CLI path. A native handoff is pending work, not a completed job; the caller executes it and records verified completion separately. - Frozen exact-AA downward delegation. The checked-in AA v4.2 policy gates every provider attempt against the current caller and inherited ceiling, carries an exact child context, and revalidates retries without inheriting a model's earlier human exemption. Its 78 scored configurations are policy inputs, not a claim that all 78 are runnable.
- Explicit native reuse. Reusing an existing Codex agent requires caller-observed idle state, preserved-context consent, and an exact runtime match; capacity exhaustion never silently changes a new-agent request into reuse. Completion is caller-attested evidence, not independent certification of upstream model identity or a cold-start guarantee.
- Codex completion wakeup.
scripts/completion-wakeup.pybinds a run to a controller thread and job allowlist, records scheduler registration, polls terminal events, and separates delivery from acceptance before closing. This is scheduled heartbeat polling, not instant push; without a supported callback the controller keeps waiting directly. - Package and upgrade. The npm tarball now carries the AA policy, native/AA/wakeup helpers, and both public protocol documents. After npm publication, run
npm i -g omnilane@0.42.0. Existing repo-symlink installations only need the checkout updated to the released revision andomnilane --versionverified; review./install.shonly for first installation or required rewiring. A GitHub release alone does not establish npm availability.
What's new in v0.41.1
-
Astra defaults to xhigh. In
hardest-codingandhard-judgment, Astra now defaults toxhigh; explicitly select--vendor codex --effort maxwhen needed. Provider order and other model efforts are unchanged. This is not a claim of measured CLI subscription-quota savings. -
Python 3.9 compatibility. Agy workspace-policy staging and cleanup now use
Path.lstat()without weakening symlink, inode, or concurrent-replacement protections. -
Isolated CI fixture. Strict doctor acceptance now supplies explicit plugin-enabled and directory-marketplace settings; missing, disabled, or mismatched settings still fail.
-
Portable offline CI fixtures. Tests no longer depend on the operator HOME, use portable permission-mode checks, and verify Linux/macOS live restrictions for the actual platform.
-
Gemini threads on Bash 3.2. Empty thread-argument expansion is guarded while preserving
set -u, populated resume arguments, and existing mode and permission policies. -
Bounded Codex live close. FIFO backpressure and partial writes preserve byte ordering and unsent suffixes for the bounded close drain. If the runner exits before forwarding accepted queued input, that input is retained and the failure is reported rather than silently discarded. Other providers keep their existing forwarding paths.
-
Upgrade after npm publication. Run
npm i -g omnilane@0.41.1, or update your checkout and rerun./install.sh. npm publication is handled separately; a GitHub release does not establish npm availability.
What's new in v0.40.0
- Distinct modes and repaired Grok web access. Advise is read-only with supported native search, work confines edits to explicit
--workdirwith agent-tool networking off, and sysops explicitly opts into full access. Grok's full single-shotplainadvise path now has real search/fetch and denied-write evidence; macOS work and restricted live remain gated. - Explicit Codex and Grok live sessions.
--background --liveenables follow-up prompts and explicit close for Codex work jobs and Grok sysops jobs; automatic Codex/Grok dispatch stays single-shot, while Claude/Gemini keep their existing auto-live behavior. Grok advise rejects--livebecause its ACP surface does not enforce a read-only boundary. - Bounded, observable shutdown. EOF-aware capability probes, immutable per-job worker snapshots, interpreter/SHA provenance, close deadlines, and process-group cleanup keep stalled or killed live jobs bounded without claiming OS sandbox isolation.
- Completion and idle fixes. Completion delivery tolerates truncated UTF-8 tails, terminal state comes from durable exit records, and idle tracking advances on completed result events rather than arbitrary stream traffic.
- AA-informed model coverage. The 12-lane defaults now cover Fable 5.1, GPT-6 Astra, and Gemini 3.8 Flash while retaining existing vendors and explicit model overrides. A dated AA v4.2 coverage snapshot documents 643 leaderboard configurations; catalog presence is not a runtime capability guarantee.
- Upgrade. Run
npm i -g omnilane@0.40.0, or update your checkout and rerun./install.sh.
What's new in v0.33.0
- Four-vendor threaded dispatch.
--thread NAMEcontinues pinned Claude, Codex, Grok, or Gemini conversations across foreground or background single-shot jobs; direct-API vendors,exec, live mode, and pin mismatches stop with visible exit-2 notices. - Thread inspection.
jobs.sh threads,threads show NAME, andthreads rm NAMElist, inspect, or remove local thread state.
What's new in v0.32.0
- Full 2026-09 routing re-evaluation. Fable 5.1 and Gemini 3.7 Flash enter the defaults, backed by the dated Artificial Analysis snapshot.
- Catalogs match live CLI surfaces. Fable 5.1 is added and retired Gemini 3.5 Flash rows are removed.
- Opus 5 remains available. It stays in
long-contextand can override any lane throughrouting.local.yaml.
What's new in v0.31.0
- Unlimited goal budgets by default.
budget_jobsandbudget_secondsnow persist as JSONnulland render asunlimited; the previous implicit 8-job and 900-second caps are gone. Use--budget-jobs Nor--budget-seconds Sto opt in to a hard cap. The repeat-failure fuse remains enabled by default. - Pipe-safe goal status.
omnilane goal statusnow exits 0 when its consumer closes the pipe early instead of raisingBrokenPipeError, so| headand| grep -qwork underpipefail.
What's new in v0.30.0
- Goal ledger.
omnilane goal opencreates a goal ledger with unlimited default budgets;goal dispatchgates each job on caller-supplied job or wall-clock caps and the always-on repeat-failure fuse.goal notepreserves the caller's narrative,goal statusshows budgets and per-job records, andgoal closewritesgoals/<id>/report.md. - Caller owns the loop. The session or person that opened the goal chooses, dispatches, reviews, and closes the work; omnilane does not run a built-in planning model.
- Doctor coverage.
omnilane doctornow checks the goal-orchestrator surface.
What's new in v0.21.0
- Explicit session mode. Use
dispatch --liveto require a resident session or--single-shotto force a one-shot job.--livefails immediately for incompatible vendors and lists the live-capable choices. - Gemini joins the live mailbox. Gemini can now run a resident live job through the
agystream protocol alongside Claude. - Idle cap for live jobs.
--idle-timeout Nautomatically closes an untended live session and preserves the close reason and timeout inmeta.json.
What's new in v0.20.0
- Foreman completion inbox. Finished background dispatches write a private
completion record, and the bundled Claude Code plugin delivers matching
records into the foreman's next prompt. The output tail is injection-hardened:
control characters and
U+2028/U+2029are removed, and worker output is framed as indented data. - Installable Claude Code plugin.
.claude-plugin/marketplace.jsonuses a self-referencing source, and the published npm tarball includeshooks/,skills/, and.claude-plugin/. - Claude live mailbox. Resident background Claude jobs can receive messages
while they run and record
events.jsonl. For operations, see 📬 Live mailbox; other vendors explicitly fall back to single-shot mode with astderrandmode-notice.txtnotice, andjobs.sh waitends withdone exit=N. - Foreman session identity. The
SessionStarthook binds a Claudesession_idto a PID plus start time, making PID reuse safe. Dispatch walks its ancestors to stampforeman_sessionintometa.jsonand completion records; the inbox prefers a session match and falls back toworkdirfor legacy records, so two foremen in one repository do not take each other's notices.
What's new in v0.15.0
- Streaming Codex progress evidence —
codex exec --jsonnow streams JSONL events intoout.txt.progress.log, so a timeout still records its last known step.out.txtand the Jobs display remain unchanged. - Evidence-led timeout diagnostics — timeouts now state that they do not identify the cause, list a three-step check, and clarify that an empty progress log does not prove Codex made no progress.
- Direct rollout recovery path — timeout output now prints the absolute path
to the matching
rollout-*.jsonl, found from the first progress event'sthread_id, so the interrupted conversation history can be inspected.
What's new in v0.14.0
- Evidence-based routing recommendations —
jobs recommendand MCPjobs_recommendrank vendors from completed public job metadata, enforce a minimum sample gate, and never change routing automatically. - Opt-in live capability probes —
doctor --probe Vand MCPprovider_probedistinguish an installed CLI from a working provider call. Default doctor remains offline; probe reports never include response bodies. - Search, filter, and export Live Board history — search and state filters cover the latest 50 jobs, while Export visible downloads only filtered public metadata.
- Repeatable quality/cost benchmark —
omnilane benchmarkships a fixed workload suite, defaults to provider-free dry-run, and requires--runfor actual calls. Cost estimates use only explicit--cost-per-callvalues. - Strict installation acceptance — CI runs isolated
omnilane doctor --strict --json, catching incomplete runtime wiring without contacting providers.
What's new in v0.13.0
long-contextis ordered on AA-LCR — Artificial Analysis's long-context reasoning benchmark, which scores exactly this lane's work. Gemini 3.1 Pro leads both fallbacks there, so its first place is now positively justified rather than merely unrevisited.- The lane's old advice was backwards and is gone. It used to send multi-hop synthesis to the Claude candidate on second-hand figures for a prior model generation; on first-party current-generation data Claude is the weakest of the three shipped candidates. The fallbacks swapped, so GPT-5.6 Sol (high) now precedes Claude Opus 5 (high).
release-audit --require-tagflags tags with no GitHub release. It warns rather than fails, skips whenghis absent or offline so the audit still runs in CI, and looks only at recent tags.- Scope note: AA-LCR runs on 10k-100k-token documents, so it settles synthesis across long documents and nothing at a full 1M. GPT-5.6 Luna tops that table far more cheaply and was deliberately not promoted, because this lane exists for the 1M sweep the benchmark does not reach.
What's new in v0.12.0
These are historical release notes. The current three-mode contract is defined in Modes, including the separate full-access sysops policy in 0.40.0.
hardest-codingdrops Sol frommaxtoxhigh— on AA's per-effort Coding Index, Sol at xhigh outscores Sol at max and every Claude tier while costing about a third less. Past xhigh, effort buys overthinking rather than accuracy on this workload.fast-agenticleads with GPT-5.6 Luna, Gemini 3.6 Flash second. Luna leads Flash on AA's Agentic Index by a wide margin and, after OpenAI's 2026-07-30 reprice, costs a fraction as much per task. Flash keeps only a throughput edge — put it back in front locally if your loops are latency-bound.- Lane comments no longer carry numbers.
routing.yamlnow states why each ordering holds; every score, price and throughput figure lives indocs/model-capabilities-2026-09.mdwith its retrieval date, so a stale figure never requires a routing-table edit. - A value profile in
routing.local.yaml.exampletrades about one Intelligence Index point for 30-40% off the cost per task. - New
--mode sysops—workwithout the vendor sandbox, for service operations the sandbox denies. It gives the worker full machine access, so it is a per-dispatch flag only and can never be a lane default. - Refreshed pricing and benchmark data for the 2026-07-30 OpenAI reprice, and documented that AA's Coding Index is not the Coding Agent Index — they share no components and their numbers collide.
What's new in v0.11.0
- The Live Board reads in five languages — English, Japanese, Korean,
Traditional Chinese and Simplified Chinese. It follows the browser languages
on first load, the switcher in the header overrides that, and the choice is
remembered locally. Headings, the search placeholder, filter buttons, empty
and error states, content markers and the
aria-labelattributes screen readers announce are all covered, and<html lang>follows the selection. - Job states are translated without breaking anything that reads them — the
state-CSS classes keep the raw value so status colours are unchanged, and the search index holds both spellings, sorunningand its translation match the same job. - No routing changes. Dispatch behaviour is identical to v0.10.4.
What's new in v0.10.4
long-contextno longer points multi-hop work at the wrong model — the lane called itself long-document synthesis while shipping Gemini first, but published multi-needle scores at 1M favour Claude by roughly threefold while Gemini leads single-needle retrieval. The lane now describes retrieval and volume sweeps and names the Claude candidate for integration work. Ordering is unchanged; the evidence is secondary and covers prior model generations.- The Coding Agent Index is no longer quoted as a number — the same model reads 80, 78 or 67 depending on index version and harness. It is now cited for ordering only, with every observed value and its provenance recorded.
taste-finalhas writing evidence behind it — previously ordered from general and agentic indexes that do not measure prose. Added EQ-Bench Creative Writing v3, EQ-Bench Longform, and the Lech Mazur benchmark, read from the publishers.- Per-effort cost and throughput added to the model notes, showing why the
defaults use
xhigh: it reaches the same index score asmaxfor 30-53% less per task.
What's new in v0.10.3
- Restructured READMEs in all five languages — the reader now meets a plain
"what is this and why would I want it" section first, version history is
consolidated at the bottom instead of interrupting the introduction, and a new
FAQ answers the questions that kept coming up: do I need every subscription,
where does my code go, why is Fable 5 not in the table, why
xhighand notmax, what happens when a CLI is missing, can a worker edit files. - Fixed: plugin manifests advertised a stale version —
plugin.jsonand.claude-plugin/plugin.jsonstill reported0.10.0after the 0.10.1 and 0.10.2 releases, so plugin installs showed the wrong version. - Fixed:
routing.local.yaml.exampleshipped retired models — the starter profiles still pointed atclaude-opus-4-8and Gemini 3.5 Flash; they now use Claude Opus 5 (with lane-appropriate effort) and Gemini 3.6 Flash. - Corrected the Intelligence Index figures in
docs/model-capabilities-2026-09.mdagainst the Artificial Analysis source (index points, not percentages), added the AA-Briefcase / GDPval-AA v2 comparison, and recorded the two results that cut against the defaults: Fable 5's lead on factual knowledge and Sol's lead on presentation quality.
What's new in v0.10.2
- Claude effort on
hardest-codingandhard-judgmentmoved frommaxtoxhigh, matching Anthropic's documented guidance for Claude Opus 5: start atxhighfor coding and agentic work, keephighas the floor for other intelligence-sensitive work, and reservemaxfor cases where correctness outweighs cost. Raise it back per lane withomnilane configure set <lane> "<spec>". - Fixed two dead CHANGELOG compare links that pointed at a
v0.10.0tag which was never published.
What's new in v0.10.1
claude-opus-5joins the default table as first choice forhard-judgmentandtaste-final, plus a fallback for the hardest coding work.omnilane configurecovers all 13 providers with 106 selectable model entries — current native catalogs for Codex, Claude Code, Grok Build and Antigravity, plus verified OpenRouter/OpenCode shortcuts. Custom model IDs remain available throughc.
What's new in v0.10.0
- Gemini 3.6 Flash defaults — the gemini candidates in
fast-agentic,triage, andbulk-mechanical(and theGemini Flashalias) now run Gemini 3.6 Flash: fewer output tokens, a lower output price, and the fastest output speed measured by Artificial Analysis. - Evidence re-audit — routing comments, model capability notes, and the Gemini price table refreshed against official sources.
What's new in v0.9.1
- Fix:
configure setno longer deletes hand-written comments fromrouting.local.yaml— it rewrites only its own stamp header and the lane being replaced.
What's new in v0.9.0
- Five OpenAI-compatible direct-API vendors —
deepseek,zai(GLM),mistral,groq, andcerebrasjoinopenrouteras CLI-free lanes (curl + a<VENDOR>_API_KEY). A one-linelib/common.shregistry entry adds each; seedocs/model-capabilities-2026-09.md. - Fish shell completion —
omnilane completion fish | source.
What's new in v0.8.3
- MCP server —
omnilane mcpstarts a zero-dependency stdio MCP server, so any MCP-capable host (Claude Code, Codex, Gemini CLI, Cursor, OpenCode…) can discover and call omnilane without installing the skill: toolsroute,jobs_status,jobs_result, andlist_lanes.routedefaults to read-only advise mode; work mode requires an explicit workdir.
What's new in v0.8.2
openroutervendor — dispatch straight to the OpenRouter API with nothing butcurland anOPENROUTER_API_KEY: hundreds of hosted models become reachable from any omnilane install, no coding-agent CLI required. Advise/consult only (it cannot edit files; work mode fails with guidance) and the model slug is mandatory, e.g.dispatch.sh --vendor openrouter --model anthropic/claude-sonnet-5 consult "...".deepseek,zai,mistral,groq,cerebrasvendors — the same CLI-free direct-API path asopenrouter, for OpenAI-compatible providers: DeepSeek, Z.ai GLM, Mistral, Groq, and Cerebras. Each needs onlycurland its<VENDOR>_API_KEY; advise/consult only. A one-linelib/common.shregistry entry defines each endpoint, key env, and default model. Seedocs/model-capabilities-2026-09.md.opencodevendor — headless dispatch through the OpenCode multi-provider aggregator CLI (opencode run). Advise mode pins OpenCode's built-in read-onlyplanagent; work mode uses--auto. Joins the defaultcoding-overflowchain as its last fallback.
What's new in v0.8.1
- Claude Code plugin auto-loads the routing reminder — the plugin now
ships a
SessionStarthook (hooks/hooks.json) that injects the routing reminder at session open (startup|resume|clear), so plugin installs get the persistent reminder with no edit to~/.claude/CLAUDE.md. Theinstall.shinstruction-file reminder still covers the other CLIs.
What's new in v0.8.0
- Two new dispatch vendors —
kimi(Moonshot Kimi Code CLI) andqwen(Alibaba Qwen Code CLI) join the vendor set with the uniform runner contract: advise stays read-only, work auto-approves, API-key env is stripped so the CLIs use their own subscription logins, and empty output is a loud failure. Pin them with--vendor kimi|qwen. - coding-overflow grows a chain — the quota relief valve now falls back
grok → kimi → qwen before
off, so it works with any one of the three vendors installed. Runners are contract-tested against fake binaries; real-model reports welcome.
What's new in v0.7.1
- Routing refresh (2026-07 model data) — hardest-coding now dispatches GPT-5.6 Sol at max effort: Artificial Analysis Coding Agent Index v1.1 scores Sol (max) at 80, the current state of the art, retiring the older xhigh-beats-max snapshot.
- Claude backups sharpened — the Claude Opus 4.8 fallback on hardest-coding and hard-judgment moves to xhigh effort, following Anthropic's guidance to use extra effort for difficult tasks and long-running work.
What's new in v0.7.0
- Preview any dispatch first —
--dry-runprints the fully resolved plan (vendor, model, mode, timeouts, side-effect decision) with no provider call and no job state. - Automate with versioned JSON — one
--jsonenvelope for--list,--explain,--validate, andjobs list|status|result|stats, plus read-onlyjobs wait,jobs audit, and an offlineomnilane release-auditgate with a deterministic manifest. - Drive local jobs end to end —
jobs tailpeeks at live output,jobs retryre-dispatches a completed job fail-closed,prune --older-thanages out old jobs, and--helpcovers every command. - Install and complete safely —
install.sh --check/--dry-runreport drift without writing,omnilane completion bash|zshships safe tab completion, and five macOS stock Bash 3.2 crashes are fixed.
What's new in v0.6.0
- Explain and validate routes offline — inspect every fallback candidate
with
--explain, or lint the complete effective table with--validate, without invoking a provider or creating job state. - Inspect local health and outcomes — bounded
jobs.sh statsaggregates andomnilane doctor --jsonmake local automation observable without exposing task or result bodies. - Compare runs in Live Board — pin one loaded job as a memory-only reference and compare its model path and public result with the current selection.
- Keep lock recovery quiet — transient owner-file read races no longer leak misleading missing-file diagnostics.
What's new in v0.5.1
- Use Codex work outside Git — ordinary directories remain supported;
Omnilane never requires or runs
git init. - Stop non-Git hangs cleanly — the resolved per-call watchdog becomes an automatic process-group fuse when no whole-job timeout was configured, while explicit timeout precedence and exit semantics remain intact.
- Trust the displayed version —
VERSIONnow drivesomnilane --versionand both plugin manifests, with CI checking the changelog and all five READMEs.
🌱 Status
omnilane now spans thirteen dispatch vendors — four harness natives (codex,
claude, grok, gemini), three aggregator/overflow CLIs (kimi, qwen, opencode),
and six CLI-free OpenAI-compatible direct-API vendors (openrouter, deepseek,
zai, mistral, groq, cerebras) — on the uniform runner contract with
contract tests, plus the Claude Code SessionStart
auto-reminder and an MCP stdio server surface (omnilane mcp). The direct-API
and aggregator runners are contract-tested against fake binaries;
real-model reports welcome. Grok/Antigravity command-shell behavior may still
vary across CLI versions. Issues and PRs welcome.
Project policies: Contributing · Security · Changelog