AgentStack
SKILL verified MIT Self-run

Multi Llm Convergence

skill-donnfelker-loop-skills-multi-llm-convergence · by donnfelker

Drive any artifact to convergence by alternating two genuinely different LLM reviewers — a Codex reviewer and an independent Claude review subagent — applying each round's findings and looping until BOTH independently agree it clears the bar (default: no critical/high findings). Artifact-agnostic: works on a plan, PRD, design doc, spec, or implementation diff. Use whenever the user says 'have two…

No reviews yet
0 installs
17 views
0.0% view→install

Install

$ agentstack add skill-donnfelker-loop-skills-multi-llm-convergence

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Multi Llm Convergence? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Multi-LLM Convergence

You are the convergence driver. You own an artifact, and your job is to bounce it between two genuinely different LLM reviewers — round after round — until both independently bless it. You apply findings, you commit each round, and you stop only when there is real cross-model consensus (or a principled stall).

Announce at start: "I'm using the multi-llm-convergence skill — let me confirm the artifact and the bar, then I'll alternate two different reviewers until they agree."

Why this skill exists

A single reviewer — even a good one — has blind spots, and a single model has correlated blind spots: ask the same model twice and it tends to miss the same things twice. Genuine convergence comes from alternating different model families (here: a Codex/GPT reviewer and a Claude review subagent) and letting each catch what the other introduced or missed. This is not theater. In the session this skill was distilled from, the second reviewer caught a defect the first reviewer's fix introduced, and the third pass caught a defect the second pass's fix introduced. Each round's value came precisely from the reviewer being a different mind than the one that last touched the artifact.

Three things make or break this loop, and all three are baked into the steps below:

  1. Ground the reviewers in local source-of-truth. Treat the Codex reviewer as offline / network-unreliable (its sandbox runs read-only with approvals off, and may have no outbound network) — it will stall or hallucinate if it has to fetch the libraries/APIs your artifact depends on. Clone them locally first.
  2. Never let a reviewer go silent. A backgrounded reviewer can hang without ever firing a completion signal. A liveness watchdog detects the silence and recovers, instead of waiting forever.
  3. Stop on real consensus, not the first "looks good." Convergence means a full clean round from each model on the same artifact state — not one reviewer's approval.

Inputs to confirm up front

Before looping, get these settled (ask only for what the user didn't already give you):

  • Artifact — what you're converging. A path to a file (plan/PRD/spec/doc) or a code change (branch/diff). Everything downstream is artifact-agnostic; you just need to know what "apply findings" edits and what "review" reads.
  • The bar — what "good enough to stop" means. Default: no findings at critical or high severity from either reviewer. (Severities are critical | high | medium | low — matching the Codex plugin's vocabulary so a real Codex finding classifies cleanly.) The user may raise it ("no medium either") or lower it.
  • Max rounds — a safety cap so the loop can't run forever. Default: 6 reviewer passes (≈3 per model).
  • Source-of-truth paths (optional) — repos/docs the reviewers must check claims against. If the artifact references external libraries/APIs and none are provided, you will clone them in Step 1.

Process flow

0. Preflight         → verify BOTH reviewers are available; HARD STOP if Codex plugin is missing
1. Ground truth      → clone/fetch external deps into gitignored tmp/ so offline reviewers don't stall
2. Baseline          → ensure the artifact exists and is committed (round 0)
3. Review (model A)  → dispatch reviewer, RUN THE LIVENESS WATCHDOG, collect findings
4. Apply + commit    → apply findings above-bar, commit "converge: round N ( review)"
5. Review (model B)  → the OTHER model reviews the updated artifact (watchdog again)
6. Apply + commit
7. Converge check    → two consecutive clean passes (one per model, no edits) → DONE
                       else loop to step 3, alternating models, until clean or cap/oscillation
8. Final output      → converged artifact + round-by-round convergence log + explicit verdict

Step 0 — Preflight: confirm BOTH reviewers exist (HARD STOP)

Do this before any other work — before grounding, before cloning, before the baseline commit. Cross-model convergence is impossible with one model, so there is no point cloning dependencies or committing a round 0 for a loop that can't run. Discovering a missing reviewer mid-loop (after you've already done grounding work) is the failure this step prevents.

Check both reviewers:

  1. Codex reviewer (the one that can be missing). The codex plugin can be installed in more than one place — a local/project install under a .claude/plugins directory at or above the working directory, or a user-level install under the config dir ($CLAUDE_CONFIG_DIR, or ~/.claude when that's unset). Search all of them, nearest-first, and take the first hit:

``bash # Resolve the codex companion across local + user plugin roots. Prints the path, or nothing if absent. roots=(); p="$PWD" while :; do [ -d "$p/.claude/plugins" ] && roots+=("$p/.claude/plugins") # local/project (walk up to root) [ "$p" = "/" ] && break; p="$(dirname "$p")" done roots+=("${CLAUDE_CONFIG_DIR:-$HOME/.claude}/plugins") # user-level (honors CLAUDE_CONFIG_DIR) existing=(); for r in "${roots[@]}"; do [ -d "$r" ] && existing+=("$r"); done [ ${#existing[@]} -gt 0 ] && find "${existing[@]}" -name 'codex-companion.mjs' -path '*codex*' -print -quit 2>/dev/null ``

Do not use $CLAUDE_PLUGIN_ROOT/scripts/codex-companion.mjs: inside this skill CLAUDE_PLUGIN_ROOT points at the multi-llm-convergence plugin, not the codex plugin, so it would look in the wrong place. The companion lives in a different plugin, which is why it must be located by search across the roots above. If the search prints nothing, the Codex plugin is not installed.

  1. Claude review subagent. Confirm the host can dispatch a background subagent (subagent_type: "general-purpose"). In Claude Code this is always available; on another host, verify the equivalent capability exists.

HARD STOP rule: if the Codex companion script does not resolve (or the subagent capability is unavailable), stop immediately. Do not proceed to Step 1. Do not clone dependencies, do not create a baseline commit, do not start a single-model loop. Tell the user exactly what's missing and how to fix it:

> "I can't run multi-LLM convergence: the Codex plugin isn't installed, so I only have one model and cross-model consensus is impossible. Install it from https://github.com/openai/codex-plugin-cc, then run /codex:setup to authenticate, and re-run this skill."

Only continue past this step once both reviewers resolve. If the user, after being told, explicitly asks for a single-model iterate-to-clean loop instead, you may run that — but only as an explicit opt-in, clearly labeled as NOT cross-model consensus. Never default into it silently.

Step 1 — Establish ground truth FIRST

This is step one, not an afterthought. The single biggest failure mode of this loop is a reviewer that stalls trying to reach the network it doesn't have.

  • Identify every external library, framework, SDK, API, or service the artifact makes claims about.
  • For each, get a local copy the reviewers can read: git clone --depth 1 tmp/ into a tmp/ directory, and/or save the relevant docs locally. Add tmp/ to .gitignore so it never lands in a commit.
  • Note the exact version/tag/SHA you cloned. Reviewers must verify claims against that, not against their training memory.
  • Record the absolute paths — you will hand them to both reviewers in every dispatch.

If the artifact is purely internal (no external dependencies to verify), say so and skip the cloning, but still tell each reviewer which in-repo paths are the source of truth.

> Why this matters: a reviewer asked to verify "does library X's function still exist" will curl GitHub, fail (no network → repeated curl exit 6), and go quiet — looking exactly like a hang. Local clones turn "fetch and stall" into "read a file."

Step 2 — Baseline (round 0)

Make sure the artifact exists and is committed before any review, so every later round is a clean diff.

  • If the user is converging an existing file/branch, confirm it's committed (commit it if not).
  • If the artifact doesn't exist yet (e.g. "converge on a PRD for X"), draft an initial version yourself, then commit it as round 0.
  • If the working directory isn't a git repo, git init it — per-round commits are the convergence audit trail and are not optional. (Uncommitted work is fragile: a reset or re-clone erases it entirely.)

Steps 3 & 5 — Dispatch a reviewer (alternating models)

Reviewers alternate every round. The rule is simple: the model that reviews next is never the model that last edited the artifact. Concretely:

  • Reviewer A = Codex (a non-Claude model). Run it read-only through the free-form codex-companion task path — not the review/adversarial-review commands (those are git-diff-bound and don't fit a plan/PRD/doc), and not the codex:codex-rescue agent (it defaults to a write-capable run and only forwards, exposing no job-control for the watchdog). The task path lets you send the review contract and gives you native status/result job-control for liveness. See references/reviewer-dispatch.md for the exact command, flags, and script-path resolution.
  • Reviewer B = an independent Claude review subagent (subagent_type: "general-purpose"), started fresh with no prior context. Same contract, different model family.

Each reviewer gets the same review contract (full template in references/reviewer-dispatch.md): the artifact, the bar, the source-of-truth paths from Step 1, and a required output shape — a JSON list of findings, each with severity (critical | high | medium | low), location, claim, verified_against, and suggested_fix, plus a final verdict (clears_bar: true|false). Demand the structured output so you can mechanically decide convergence instead of parsing prose.

Run reviewers one at a time, not in parallel. Unlike a single-pass multi-reviewer sweep, convergence is inherently sequential: model B must review what model A's findings produced. Parallelizing defeats the point.

Steps 3a & 5a — The liveness watchdog (REQUIRED on every dispatch)

Tool names in this section (ScheduleWakeup, Agent(...), TaskList/TaskGet/TaskOutput) are illustrative capability names — map them to whatever the running host exposes for scheduling a self-wake, dispatching a background subagent, and polling a background task respectively.

> The one rule that prevents babysitting: never end your turn while a background reviewer is in flight unless a ScheduleWakeup is already armed to wake you. The runtime re-invokes you at that scheduled time whether or not the reviewer ever finishes — so a hung, silent reviewer cannot strand the loop. A dispatch that yields the turn with no wake armed is the bug. Arm the wake in the same turn you dispatch, every time.

A backgrounded reviewer — Codex especially — can stall and never fire a completion notification. Passively awaiting that notification is how the loop hangs forever — because the only thing that would wake you is a signal that never comes. The self-armed ScheduleWakeup is what makes the loop autonomous: it fires on a clock, not on the reviewer's cooperation. So every dispatch is supervised. The exact liveness signal depends on the path:

  • Codex (codex-companion task --background): the command returns a job id. Poll node status --json each tick — read the authoritative job.status, whose values are queued | running | completed | failed | cancelled (note done is a phase, not a status), not a guess from file mtime. Fetch the final output with result --json. (status --json reads instantaneous state and returns immediately; it is independent of the companion's own internal --wait timeout, so your tick cadence is yours to choose.)
  • Claude subagent (Agent(run_in_background: true)): capture the returned agent id and poll TaskList/TaskGet/TaskOutput for liveness and output growth.

The supervision loop, either path:

  1. Dispatch in the background, capturing the job/agent id.
  2. Self-pace a poll with ScheduleWakeup, waking about every 270 seconds — under the 5-minute prompt-cache window so each check is cheap and cache-warm. This self-paced heartbeat is what keeps a silent reviewer from hanging the loop; drive it with ScheduleWakeup directly (do not invoke the user-facing /loop command — that's for a human setting up a recurring task, not for pacing inside a running skill). If ScheduleWakeup isn't available in this host, fall back to a foreground task run under a hard time cap (see references) so a hang surfaces as a non-zero exit instead of an infinite wait — you lose "still thinking vs stuck" discrimination but keep the no-hang guarantee. Use a portable cap: GNU timeout is absent on macOS/BSD, so prefer perl -e 'alarm shift; exec @ARGV' … (or gtimeout from coreutils) there.
  3. Each tick, read job state + output growth. Any terminal job.status (completed/failed/cancelled) means proceed (read the result). A still-active job (queued/running) whose output has advanced is healthy — let it keep going.
  4. Stall verdict: job.status is still queued/running AND output unchanged across 2 consecutive ticks with no result → declare it hung. Don't keep waiting; don't blindly re-dispatch the same way (it stalls identically).
  5. Recover by fixing the cause, not retrying blind: confirm the Step-1 tmp/ clones exist and are complete, then re-dispatch with explicit instructions to read those local paths and make no network calls. If it stalls again after grounding, stop and escalate to the user with what you observed.
  6. Fallback wakeup: also set one long ScheduleWakeup (~1200 s) as a backstop, so even if a completion notification never arrives and a poll is missed, the loop still wakes and re-checks rather than dying silently.

> The detection signal that matters is job state plus output advancement, not elapsed time. A reviewer legitimately thinking for four minutes (job running, output still trickling) is fine; a running job whose output hasn't moved across two checks is stuck. Prefer status --json over raw file mtime precisely so a quiet-but-thinking job isn't misjudged as hung.

Steps 4 & 6 — Apply findings and commit the round

Apply findings under the general rules in references/coding-guidelines.md: think before editing, keep the change minimal, stay surgical (touch only what the finding requires), and edit toward a verifiable success criterion. These bind both the driver and the reviewers — see below.

  • Apply every finding at or above the bar. Findings below the bar (e.g. medium/low when the bar is high) are recorded in the log but don't block convergence; apply them only if cheap and clearly correct.
  • When a reviewer's claim touches an external library, verify it against the Step-1 local clone before acting — reviewers (both models) hallucinate APIs. If the clone contradicts the finding, record it as rejected (contradicted by source) in the log and don't apply it.
  • Commit each round on its own: converge: round — apply review. Per-round commits are the auditable trail; they also let you diff to detect oscillation (Step 7).

Step 7 — Convergence, stall, and oscillation

Converged (success): the artifact has reached convergence when two consecutive reviewer passes — one from each model — both return clears_bar: true with no above-bar findings, AND neither pass required an edit. That guarantees both model families independently bless the same artifact state. If a pass produces any above-bar finding, you apply it and the clean streak resets — the other model must then re-bless the edited version.

Stalled (cap reached): if you hit the max-rounds cap without two consecutive clean passe

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.