AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
One routing table, every harness: cross-vendor model dispatch for Claude Code, Codex, Grok Build, Antigravity
Developer toolsPython · ShellGitHub @Seraphim0916Self-installOwner unconfirmed
Paste into Claude or ChatGPT for installation instructions suited to your environment.
Have you tried it? One tap is enough. No sign-in needed.
Loading the full README. The saved excerpt is shown below.
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.Read the full README ↗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 · 繁體中文 · 简体中文 · 日本語 · 한국어
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.
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 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.
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 vendor
A 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. 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.
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.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. --vendor selects 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 |
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) |
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.
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.
consult.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.
high, or xhigh for deeper review), plus long-context fallback. This is an opt-in role, not a new lane or the default hard-judgment route.--vendor codex --effort max when needed. Explicit model/effort always win.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.
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@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:
/route,
/route-jobs commands, and a SessionStart hook that auto-injects the
routing reminder at session open — no CLAUDE.md edit needed), or drop
skills/omnilane into ~/.claude/skills/.skills/omnilane into ~/.codex/skills/.grok plugin install <this repo> --trustagy plugin install <this repo> (check first with
agy 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:
scripts/configure.sh lists 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-vendor consult lane; edit that one by
hand if needed. install.sh offers 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 — set validates the lane and rejects an unsafe or structurally
invalid spec, rolling back on failure.~/.omnilane/routing.local.yaml — hand-edited overrides, same format
as routing.yaml; local lines win. See routing.local.yaml.example.~/.omnilane/local.sh — per-machine binaries, proxies, auth wrappers;
sourced by every runner, never committed. See local.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: 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.
--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.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.
OMNILANE_DEPTH
guard, exit 86): no runaway agent-calls-agent quota chains.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 SECONDS beats a per-lane OMNILANE_TIMEOUT_<LANE> (the lane
upper-cased with -→_, e.g. OMNILANE_TIMEOUT_HARD_JUDGMENT) beats the
global OMNILANE_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 the vote panel (voters ×
rounds) makes several calls, so total wall-clock can be a multiple of this
value.--job-timeout SECONDS caps 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: Codex work outside 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 workers run in their own process
group and survive the caller's exit; killed workers record an exit code, and
jobs.sh status reports dead instead of running forever.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.
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.
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.
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.
omnilane resign because the AA snapshot has changed.aa-v4.3.2-2026-10-27-v1 adds 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.npm i -g [email protected].omnilane native-context --install once from a terminal on each host; when upgrading from 0.56.0, also run omnilane resign once from a GUI terminal because the AA snapshot has changed.omnilane native-context --install records 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.--inherit handoff when a --native-context file states the caller's model; it never guesses an identity.omnilane refusal: summary and is stored as evidence under $OMNILANE_HOME/refusals/.omnilane self-exec record and omnilane stats self-exec track tasks the commander did itself after a stored refusal.codex/gpt-5-4-mini returns to the score table (no lane lists it); routing.yaml is unchanged.omnilane resign no longer reports working Claude selectors as model-mismatch when the advisor tool is enabled, and keeps a held vendor's failed probe output.npm i -g [email protected].omnilane resign --vendor gemini once from a GUI terminal because run-gemini.sh has changed.task.txt retains the full input.omnilane list.npm i -g [email protected].omnilane resign once from a GUI terminal because the AA snapshot has changed.aa-v4.3.2-2026-10-14-v1 was operator-approved on 2026-10-18; each host still needs its own transport proof.which-bin read-only without writing Python bytecode caches.npm i -g [email protected].omnilane resign. This release keeps the 0.53.0 snapshot.omnilane resign --vendor VENDOR. Non-interactive runs wait 20 hours per failed row; interactive runs or --retry-failed retry immediately, without approving signer changes. Conclusive model/effort mismatches never auto-retry.omnilane doctor and omnilane doctor --json list 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 --daily preserves nonzero failures and interrupted runs in private local status visible through omnilane doctor, even without Telegram. No scheduler is installed automatically.npm i -g [email protected]. Upgrading from 0.53.0 does not require re-signing; upgrading from an earlier version still requires one run of omnilane resign from a GUI terminal.omnilane resign on every host once, from a GUI terminal: the registry snapshot is now aa-v4.3.2-2026-10-08-v1. All dispatch is blocked with transport overlay snapshot mismatch until the overlay is re-signed.taste-final now starts with Claude Sonnet 5.5 (xhigh, 52). Haiku 5.5 joins lower-ceiling coding, bulk, triage and taste candidates; it is not promoted to fast-agentic.resign tests 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).jobs close waits the full 11 seconds; a repeated close signal during worker shutdown no longer kills it with exit 158.jobs rm and jobs prune --apply move jobs to a per-run trash directory under ${OMNILANE_TRASH_DIR:-~/.Trash}, with a manifest.tsv of job IDs and original paths. Permanent deletion is left to the operator.npm i -g [email protected], then omnilane resign.omnilane resign on every host once, from a GUI terminal: the registry snapshot is now aa-v4.3.2-2026-10-02-v2 and the runner scripts changed, so dispatch refuses until the overlay is re-signed.gpt-5.4-mini Codex rows (Codex rejects them on a ChatGPT account) and re-scores twelve GPT-6 Sol and Luna rows; fast-agentic puts GPT-6.1 Sol low ahead of GPT-6 Sol low.option.grok-macos-work: unconfined lets single-shot Grok work run on macOS without isolation. It is off by default and every surface discloses it.resign keeps a vendor's verified mappings as pending_recheck when it cannot re-probe them, stops with exit 40 on a broken host configuration, and anchors the binary dispatch runs. doctor fails when dispatch resolves a different executable than the overlay pinned, and compares installed skill copies with the checkout.dead state, jobs close waits up to 11 seconds, a live job closed by the idle cap keeps its result, and runner files are private from the start.npm i -g [email protected], then omnilane resign.omnilane resign on 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.resign treats a configuration that was never probed on this host as drift, even when no executable changed. --check lists those rows and exits 10. A probe that answered and failed is not repeated, and the signer check, --approve and --trust-adhoc are unchanged.npm i -g [email protected], then omnilane resign.omnilane resign once after upgrading. The registry snapshot changes to
aa-v4.3.2-2026-09-30-v1; the old transport overlay no longer loads, and every
dispatch is refused until the re-sign.OMNILANE_AA_CLAUDE_TRANSCRIPT=0
turns it off). A desktop session that changed model or effort mid-session, or a
scheduled task started with --model default, is read correctly.$OMNILANE_HOME/native-rows.json adds the model/effort
pairs the host's sub-agent tool can run; native-context --host-rows FILE /
--no-host-rows.npm i -g [email protected], then omnilane resign.omnilane resign once after upgrading. The registry snapshot changes to
aa-v4.3.2-2026-09-27-v1.scripts/aa_rebaseline.py fill.gpt-6-sol and gpt-6-luna passed
resign once the Codex quota reset.npm i -g [email protected], then omnilane resign.omnilane resign once after upgrading. The registry snapshot changes
to aa-v4.3.2-2026-09-23-v2; until the overlay is rebuilt a model caller is
refused on every lane with transport overlay snapshot mismatch. GPT-6 Sol and
Luna are proven only by a resign that reaches Codex; until then every chain
serves the row behind them.GPT-6 Sol and GPT-6 Luna.hardest-coding, Opus 5.5 medium heads
bulk-mechanical, GPT-6 Luna high heads triage and GPT-6 Sol high heads
fast-agentic. scripts/aa_rebaseline.py value shows the picks behind each
chain.npm i -g [email protected], then omnilane resign.omnilane resign once after upgrading. The registry snapshot changes
to aa-v4.3.2-2026-09-23-v1 and the transport overlay is bound to it; until
the overlay is rebuilt, a model caller is refused on every lane with
transport overlay snapshot mismatch. Until resign has probed Opus 5.5 on a
host, lanes skip its Opus 5.5 rows and serve the next candidate.hardest-coding and ui-draft at xhigh, and hard-judgment and
taste-final at 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 of
hardest-coding, where it scores no higher. It is the Claude row in consult
(xhigh) and the Claude fallback in live-search (medium). An Opus 5.5 medium
controller has a ceiling of 51 and starts below the rows that head those
chains. New alias Opus 5.5; Opus still means Opus 5. The figures are in
docs/model-capabilities-2026-09.md.npm i -g [email protected], then omnilane resign.omnilane resign once 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 with
transport overlay snapshot mismatch.hard-judgment
before now does. scripts/aa_rebaseline.py rebuilds the registry from a saved
AA extract, so the next index revision is a re-run.hardest-coding, expert-level reasoning and
graded analytical quality for hard-judgment, graded document presentation for
taste-final, automation accuracy per minute for fast-agentic, the harder
long-context benchmark for long-context, visual understanding for ui-draft.
Eight lanes change their first choice: Astra (xhigh) leads hardest-coding,
Astra (low) leads bulk-mechanical and fast-agentic, Astra (high) leads
ui-draft, Opus 5 (max) leads taste-final, Opus 5 (high) leads
long-context, and Grok 4.7 leads coding-overflow as well as live-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 in docs/model-capabilities-2026-09.md.resign has probed 4.7. With --vendor grok there is no
fall-through; until then ask for --model grok-4.6.claude claude-sonnet-5 high could never be
dispatched under the old registry; it now resolves once probed.npm i -g [email protected], then omnilane resign. For Grok 4.7 the
CLI must be logged in when you re-sign.--approve.
Run omnilane resign --trust-adhoc VENDOR once per vendor and an adhoc update
in the same install directory now goes through the daily omnilane resign
like 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.Failed to authenticate, OAuth session expired, Invalid API key, Unauthorized and
401 now mark the vendor unprobeable, and the held-vendor message tells you
to log in first.npm i -g [email protected]. If you are coming from 0.42.x, run
omnilane resign --record-signers once 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 [email protected], 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.
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 --approve command for you. Run
omnilane resign --record-signers once, schedule omnilane resign daily, 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.failed_gate, reason, next_command, required_caller_effort, and
eligible_lanes — the lanes that caller can reach right now.omnilane native-context writes the
capability file that used to be hand-made, and omnilane route --inherit plans
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.omnilane whoami; echo $?
cannot be identified, omnilane whoami alone can. The refusal now says so.--approve.
--inherit has not been run inside Grok Build, and Antigravity exposes no
sub-agent tool. Full detail: CHANGELOG.npm i -g [email protected], then once: omnilane resign --record-signers.codex-modified, and 0.42.8
walked past it looking for one named codex, so every dispatch from such a
thread was refused with missing-caller-context. The name is now recognised;
the launcher's sibling codex-code-mode-host is still not treated as a CLI.whoami exited 0 from a
Codex desktop thread running through the launcher, reporting
codex/gpt-5-6-sol-medium (score 46) read from the codex-modified process.npm i -g [email protected].app-server always ignores startup model and
effort defaults. Other Codex launches keep explicit -m / --model or
-c model=... / --config selectors (TOML model overrides require Python 3.11+);
no model, including profile-only launches, uses the rollout path.CODEX_THREAD_ID. The rollout is looked up under $CODEX_HOME/sessions
(default ~/.codex) as rollout-*-<thread>.jsonl and, after a resume,
rollout-*-<thread>_<session>.jsonl; the most recently written match is read
and its session_meta.id must match. Its latest turn_context needs model,
effort and turn id; a later task_complete, turn_complete (read alias) or
turn_aborted carrying 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. whoami reports thread and turn ids.CODEX_SANDBOX=seatbelt, whoami explains that process inspection,
~/.omnilane writes and networking require rerunning outside the sandbox.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.OMNILANE_AA_CALLER_FROM_PROCESS=0 disables
both argv and rollout reading.whoami and
dispatch.sh --dry-run both exited 0 from the Codex desktop app — in a fresh
thread and in a resumed one whose original rollout had stopped the day before,
reporting codex/gpt-6-astra-xhigh (score 54) and "allowed":true.npm i -g [email protected].--caller-context is 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 on missing-caller-context and hand the question back to the operator; three did so on 2026-09-08 and 2026-09-10.omnilane whoami prints 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.high and at max gets ceilings 52 and 54.--caller-context file, the context a worker inherits, and --operator-asserted-human all take precedence. OMNILANE_AA_CALLER_FROM_PROCESS=0 restores the file-only contract.missing-caller-context and the retry refusal now point to omnilane whoami instead of offering a model two options it cannot take.omnilane --version is right again. The 0.42.6 release left VERSION at 0.42.5.npm i -g [email protected]. Existing repo-symlink installations can update their checkout and verify omnilane --version without rerunning installation.evidence_tier: billed-model when the provider named the model it charged for (Claude, grok), client-echo when the CLI recorded the model it asked for (codex, agy), selector-only when the CLI accepted the selector and said nothing more. client-echo is the CLI's copy of your order; billed-model is the provider's receipt.runtime_verified alone, so a weaker tier never refuses a lane that used to run. A test asserts every decision is unchanged under all three tiers.selector-only, and a CLI that begins reporting a billed model is promoted with no code change.omnilane doctor shows the spread and names the vendors worth re-probing.build_overlay.py and drifted out of use silently — the live overlay hashed claude 2.1.263 while every dispatch ran 2.1.266. Core evidence now resolves the executable the runners resolve.gpt-5.4-mini passed 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 to unproven[] with that reason attached, leaving 46 mappings. Snapshot aa-v4.3.2-2026-10-02-v2 now retires all three rows to unknown_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 run omnilane resign because the snapshot id changed; see docs/reports/aa-rebaseline-2026-10-02-v2.md.npm i -g [email protected]. Existing repo-symlink installations can update their checkout and verify omnilane --version without rerunning installation.vendor tag; a tagged entry whose hash drifts or whose file has disappeared degrades only that vendor to unknown-target-runtime. Untagged evidence stays globally fail-closed.omnilane doctor loads the overlay. A new transport-overlay check 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.probe.py judges Claude responses on the billed modelUsage and fails a run where the CLI silently substituted the default effort for an unknown --effort. build_overlay.py refuses to sign a non-passing probe and records it in the overlay's unproven[] instead of dropping it silently.build_overlay.py and probe.py live in scripts/lib/ and take --root.npm i -g [email protected]. Existing repo-symlink installations can update their checkout and verify omnilane --version without rerunning installation.omnilane route needs to know who is asking; the 60-second start omitted that, so a fresh install hit missing-caller-context with no guidance. It now asserts the human operator once with OMNILANE_AA_OPERATOR_ASSERTED_HUMAN=1, and explains what a model caller passes instead.dispatch.sh synopsis shows [--caller-context FILE | --operator-asserted-human].--caller-context is in the quick reference. The dispatch command signature now shows it, and states that a model caller without it is refused with missing-caller-context before a job exists.missing-caller-context means no file was passed; runtime-mapping-unverified means the target lacks a proven host-local selector, which is fixed by a --transport-overlay entry backed by real evidence and never by editing the frozen registry.npm i -g [email protected]. Existing repo-symlink installations can update their checkout and verify omnilane --version without rerunning installation.low, medium, high, and xhigh selections are passed with --reasoning-effort; Grok 4.6 default routes now select high.npm i -g [email protected]. Existing repo-symlink installations can update their checkout and verify omnilane --version without rerunning installation.--model gemini-3.8-flash-high pair. AA coverage remains 78 scored targets, one scored reference-only entry, and 10 unknown configurations.npm i -g [email protected]. For an existing repo-symlink installation, update the checkout and run omnilane --version; do not rerun ./install.sh unless deliberately rewiring integrations. GitHub release and npm publication remain separate.--executor auto uses 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.scripts/completion-wakeup.py binds 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.npm i -g [email protected]. Existing repo-symlink installations only need the checkout updated to the released revision and omnilane --version verified; review ./install.sh only for first installation or required rewiring. A GitHub release alone does not establish npm availability.Astra defaults to xhigh. In hardest-coding and hard-judgment, Astra now defaults to xhigh; explicitly select --vendor codex --effort max when 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 [email protected], or update your checkout and rerun ./install.sh. npm publication is handled separately; a GitHub release does not establish npm availability.
--workdir with agent-tool networking off, and sysops explicitly opts into full access. Grok's full single-shot plain advise path now has real search/fetch and denied-write evidence; macOS work and restricted live remain gated.--background --live enables 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 --live because its ACP surface does not enforce a read-only boundary.npm i -g [email protected], or update your checkout and rerun ./install.sh.--thread NAME continues 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.jobs.sh threads, threads show NAME, and
threads rm NAME list, inspect, or remove local thread state.long-context and can override any lane through routing.local.yaml.budget_jobs and budget_seconds now persist as JSON null and render as unlimited; the previous implicit 8-job and 900-second caps are gone. Use --budget-jobs N or --budget-seconds S to opt in to a hard cap. The repeat-failure fuse remains enabled by default.omnilane goal status now exits 0 when its consumer closes the pipe early instead of raising BrokenPipeError, so | head and | grep -q work under pipefail.omnilane goal open creates a goal ledger with unlimited default budgets; goal dispatch gates each job on caller-supplied job or wall-clock caps and the always-on repeat-failure fuse. goal note preserves the caller's narrative, goal status shows budgets and per-job records, and goal close writes goals/<id>/report.md.omnilane doctor now checks the goal-orchestrator surface.dispatch --live to require a resident session or --single-shot to force a one-shot job. --live fails immediately for incompatible vendors and lists the live-capable choices.agy stream protocol alongside Claude.--idle-timeout N automatically closes an untended live session and preserves the close reason and timeout in meta.json.U+2028/U+2029 are removed, and worker output is
framed as indented data..claude-plugin/marketplace.json uses a
self-referencing source, and the published npm tarball includes hooks/,
skills/, and .claude-plugin/.events.jsonl. For operations, see
📬 Live mailbox; other vendors explicitly fall back to
single-shot mode with a stderr and mode-notice.txt notice, and
jobs.sh wait ends with done exit=N.SessionStart hook binds a Claude
session_id to a PID plus start time, making PID reuse safe. Dispatch walks
its ancestors to stamp foreman_session into meta.json and completion
records; the inbox prefers a session match and falls back to workdir for
legacy records, so two foremen in one repository do not take each other's
notices.codex exec --json now streams JSONL
events into out.txt.progress.log, so a timeout still records its last known
step. out.txt and the Jobs display remain unchanged.rollout-*.jsonl, found from the first progress event's
thread_id, so the interrupted conversation history can be inspected.jobs recommend and MCP
jobs_recommend rank vendors from completed public job metadata, enforce a
minimum sample gate, and never change routing automatically.doctor --probe V and MCP
provider_probe distinguish an installed CLI from a working provider call.
Default doctor remains offline; probe reports never include response bodies.omnilane benchmark ships a fixed
workload suite, defaults to provider-free dry-run, and requires --run for
actual calls. Cost estimates use only explicit --cost-per-call values.omnilane doctor --strict --json, catching incomplete runtime wiring without
contacting providers.long-context is 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.release-audit --require-tag flags tags with no GitHub release. It warns
rather than fails, skips when gh is absent or offline so the audit still
runs in CI, and looks only at recent tags.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-coding drops Sol from max to xhigh — 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-agentic leads 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.routing.yaml now states why each
ordering holds; every score, price and throughput figure lives in
docs/model-capabilities-2026-09.md with its retrieval date, so a stale
figure never requires a routing-table edit.routing.local.yaml.example trades about one
Intelligence Index point for 30-40% off the cost per task.--mode sysops — work without 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.aria-label attributes screen
readers announce are all covered, and <html lang> follows the selection.state- CSS classes keep the raw value so status colours are unchanged, and
the search index holds both spellings, so running and its translation match
the same job.long-context no 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.taste-final has 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.xhigh: it reaches the same index score as max for 30-53% less
per task.xhigh and not
max, what happens when a CLI is missing, can a worker edit files.plugin.json and
.claude-plugin/plugin.json still reported 0.10.0 after the 0.10.1 and
0.10.2 releases, so plugin installs showed the wrong version.routing.local.yaml.example shipped retired models — the starter
profiles still pointed at claude-opus-4-8 and Gemini 3.5 Flash; they now use
Claude Opus 5 (with lane-appropriate effort) and Gemini 3.6 Flash.docs/model-capabilities-2026-09.md against 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.hardest-coding and hard-judgment moved from max to
xhigh, matching Anthropic's documented guidance for Claude Opus 5: start
at xhigh for coding and agentic work, keep high as the floor for other
intelligence-sensitive work, and reserve max for cases where correctness
outweighs cost. Raise it back per lane with
omnilane configure set <lane> "<spec>".v0.10.0 tag
which was never published.claude-opus-5 joins the default table as first choice for
hard-judgment and taste-final, plus a fallback for the hardest coding work.omnilane configure covers 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 through c.fast-agentic,
triage, and bulk-mechanical (and the Gemini Flash alias) now run
Gemini 3.6 Flash: fewer output tokens, a lower output price, and the fastest
output speed measured by Artificial Analysis.configure set no longer deletes hand-written comments from
routing.local.yaml — it rewrites only its own stamp header and the lane
being replaced.deepseek, zai (GLM),
mistral, groq, and cerebras join openrouter as CLI-free lanes (curl +
a <VENDOR>_API_KEY). A one-line lib/common.sh registry entry adds each;
see docs/model-capabilities-2026-09.md.omnilane completion fish | source.omnilane mcp starts 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: tools route,
jobs_status, jobs_result, and list_lanes. route defaults to
read-only advise mode; work mode requires an explicit workdir.openrouter vendor — dispatch straight to the OpenRouter API with
nothing but curl and an OPENROUTER_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, cerebras vendors — the same
CLI-free direct-API path as openrouter, for OpenAI-compatible providers:
DeepSeek, Z.ai GLM, Mistral, Groq, and Cerebras. Each needs only curl and
its <VENDOR>_API_KEY; advise/consult only. A one-line lib/common.sh
registry entry defines each endpoint, key env, and default model. See
docs/model-capabilities-2026-09.md.opencode vendor — headless dispatch through the OpenCode
multi-provider aggregator CLI (opencode run). Advise mode pins OpenCode's
built-in read-only plan agent; work mode uses --auto. Joins the default
coding-overflow chain as its last fallback.SessionStart hook (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. The
install.sh instruction-file reminder still covers the other CLIs.kimi (Moonshot Kimi Code CLI) and qwen
(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.off, so it works with any one of the three
vendors installed. Runners are contract-tested against fake binaries;
real-model reports welcome.--dry-run prints the fully resolved plan
(vendor, model, mode, timeouts, side-effect decision) with no provider call
and no job state.--json envelope for --list,
--explain, --validate, and jobs list|status|result|stats, plus
read-only jobs wait, jobs audit, and an offline omnilane release-audit
gate with a deterministic manifest.jobs tail peeks at live output,
jobs retry re-dispatches a completed job fail-closed,
prune --older-than ages out old jobs, and --help covers every command.install.sh --check/--dry-run report
drift without writing, omnilane completion bash|zsh ships safe tab
completion, and five macOS stock Bash 3.2 crashes are fixed.--explain, or lint the complete effective table with --validate,
without invoking a provider or creating job state.jobs.sh stats aggregates and
omnilane doctor --json make local automation observable without exposing
task or result bodies.git init.VERSION now drives omnilane --version
and 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
| 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 |
grok