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.
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
You, a person at a terminal, can dispatch right away.
1. Install.
npm i -g omnilaneOr 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 language2. 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 resolves3. 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 browserWhy 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.
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.
./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>) |
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 vendorA vendor you are not logged in to is reported unprobeable and simply stays
unverified; the others work.
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.
It will not re-sign just anything. A changed CLI is re-signed unattended only when it carries the same code-signing team as the one on record and sits in the same install location. So tell it once which signers you accept:
omnilane resign --record-signers # once, right after Step 2If you patch a vendor CLI yourself after every update and re-sign it adhoc, tell omnilane that too, once per vendor; an adhoc update in the same install directory is then re-signed unattended as well:
omnilane resign --trust-adhoc claude # only if you re-sign claude adhoc yourselfThen 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</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.plistThis 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 | a vendor needs you: new or missing signer, unsigned or locally patched binary, new install directory, or the provider refused probes that passed last time | read the message. It prints either "retry later" or the exact omnilane resign --vendor V --approve V to run after you have looked |
| 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 |
Two limits to know. Signer checks use macOS code signatures, so on Linux every
changed CLI stops at exit 20 for your --approve. And a binary with no real
signature (a locally patched CLI, for example) always stops for approval: nothing
ties it to its vendor, which is the point of the check.
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.
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 table four harnesses share it |
🪂 Fallback chains degrades to the CLIs you have |
🗳️ Opinion panel multi-model vote for big calls |
| 🔒 Safety rails locks · watchdogs · no nesting |
🌏 Five languages the installer speaks your locale |
↩️ Reversible--uninstall undoes everything |
Defaults below — run scripts/dispatch.sh --list for the table your machine
actually resolves.
| Lane | First choice | Backup | When |
|---|---|---|---|
| 🔥 hardest-coding | GPT-6 Astra (xhigh) | GPT-6.1 Sol (xhigh) → Claude Opus 5.5 (medium) → GPT-6.1 Sol (high) → GPT-6 Astra (medium) → GPT-6.1 Sol (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 Sonnet 5.5 (medium) → Claude Opus 5 (low) → Grok 4.7 → Grok 4.6 → 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) → 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 Sonnet 5.5 (medium) → Claude Sonnet 5.5 (low) → GPT-6 Sol (medium) → Claude Opus 5 (low) → GPT-6 Sol (low) → Gemini 3.8 Flash (High) | Refactors, migrations, tests, review sweeps — mechanical endurance |
| 🧹 triage | GPT-6 Luna (high) | GPT-5.6 Luna (high) → Gemini 3.8 Flash (Low) → Claude Sonnet 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) → 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 Opus 5.5 (xhigh) | Claude Sonnet 5.5 (xhigh) → Claude Opus 5.5 (high) → Claude Sonnet 5.5 (high) → Claude Opus 5.5 (medium) → Grok 4.7 → Grok 4.6 → GPT-6 Astra (xhigh) → 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 → Grok 4.6 → 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) → 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 Sol (medium) → 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 3.8 Flash (High) | Long-document synthesis; context size alone does not prove task quality |
| ⚡ fast-agentic | GPT-6.1 Sol (medium) | GPT-6 Astra (medium) → GPT-6 Sol (low) → GPT-6.1 Sol (low) → GPT-6 Astra (low) → 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 | Grok 4.6 → 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 | Grok 4.6 → Gemini 3.8 Flash (High) → Kimi K3 → Qwen3 Coder Plus → 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 |
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.
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.
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_IDThe 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.
Model-role guidance (delegation still required)
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.
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 cleanlyThe 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.
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.
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@omnilaneUse ./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>)
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.
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
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 check names a stale vendor
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] # 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 # delete one finished/dead job (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
configure.sh # interactive lane menu
configure.sh set|get|unset|list|diff LANE [SPEC] # script/inspect routing.local.yaml, no tty
--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.
- 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 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.
- 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. 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.
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" --backgroundwatch 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.
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.
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.
Do I need all of these subscriptions?
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).
Does omnilane send my code somewhere new?
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.
Why do Fable 5.1 and Astra now lead hard work?
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.
Why does hardest coding use max while other Claude lanes use xhigh?
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.
What happens when a lane's first-choice CLI is missing?
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 callCan a dispatched worker edit my files?
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.
My dispatch was refused. Which refusal is it?
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 reports the count of such configurations and the
overlay's unproven[] records why each one failed. A refusal caused by a
provider quota limit 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.
What does my mapping's evidence tier mean?
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.
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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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).
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.
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.
- 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.
- 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.
- 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.
- 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. - 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.
- 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.
- 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].
- 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.
- 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.
- 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.
- 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.
-
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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
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.
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.
- 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.
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.
- 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.
- 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.
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.
Older releases (v0.10.0 and earlier)
- 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.
- Fix:
configure setno longer deletes hand-written comments fromrouting.local.yaml— it rewrites only its own stamp header and the lane being replaced.
- 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.
- 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.
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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
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

