2026-08-27 · Updated 2026-08-27 · 8 min read

Switch coding-agent harnesses in YYLO

Move in-flight agent work from one harness to another without losing anything: an evidence-dated switch surface, a four-step procedure that preserves task truth and receipts, and the session commands that keep both sides addressable.

By Juno AI INC · harness-switching · sessions · yylo

Every team that runs coding agents eventually switches harnesses mid-stream: a model gate changes, a pricing tier moves, one agent turns out to be better at the current sub-job, or you simply want a second engine on the same work. In most stacks that moment is expensive, because the session, the history, and the evidence of what the agent did all live inside the harness being replaced — "switching" really means starting over and hoping nothing was lost.

YYLO inverts that arrangement. The harness is a per-run selection under a control plane that keeps task truth and receipts outside any single agent, so a switch changes the engine without moving the work. This guide gives you the two things you need to do it deliberately: the evidence-dated support matrix of what YYLO's switch surface actually documents, and the switching procedure that carries an in-flight task across harnesses without losing sessions or evidence.

What has to survive a switch

Three things are at risk when the agent layer changes underneath in-flight work:

  • Task truth — what the work is and where it stands. The task, its status, its recorded responses, and its commit references must not move when the harness moves. In YYLO this layer is Git-native task truth: files and ledger history in the repository, not state inside an agent product.
  • The thread — the conversation context the current harness holds. This is the only thing that genuinely lives inside the harness. YYLO's contract is not to teleport it, but to keep it recorded and addressable: every run leaves session ids in its run record, so the thread can be resumed or handed off as data.
  • Receipts — the evidence of what the old harness did. Run artifacts, session history, and execution envelopes are files on your disk. They prove provenance after the switch, exactly the artifacts the auditable-workflow guide maps in full.

A switch fails if it loses any one of the three. The layering is what makes two of them harness-independent by construction: only the thread is harness-native, and even the thread is reduced to a recorded session id plus whatever you explicitly hand across. The harness boundary guide owns why the layers separate this way; the rest of this guide is the operational switch.

The switch surface, dated 2026-08-27

This is the support matrix for switching in YYLO, stated as what the committed product documentation records. Every row below is dated to the 2026-08-27 evidence date of this guide; re-verify against the YYLO documentation before relying on it later:

  • Dispatch surface. -s/--subagent documents the selectable services claude, codex, gemini, pi, and cursor, chosen per run — the switch itself is a flag on the next dispatch, not a migration.
  • Model surface. -m/--model selects the model behind a service, resolved in a fixed order: the CLI flag first, then the configured per-service default (set with yylo <service> set-default-model), then the built-in default — so a switch can carry model choice or leave it to configuration.
  • Session surface. Every run records its session ids, and the session commands address them afterwards: yylo session list and yylo session info <id> inspect them, -r/--resume <id> continues a specific session, and yylo continue reuses the last session id plus its runtime settings. Each run also appends an entry to session_history.json under a state root outside the tracked tree — prompt, subagent, model, cost, session ids — so the seam where you switched is itself greppable later.
  • Evidence surface. For audited dispatch, yy pi --execution-envelope emits one juno_execution_envelope.v1 JSON object as the sole stdout payload, with provider, model, session, version, and cost fields taken from marked backend terminal evidence rather than the agent's own prose.
  • Extension surface. A service YYLO does not document is still reachable: custom services are ordinary Python scripts in ~/.yylo/services/ that accept -p/--prompt, -m/--model, and -v/--verbose and emit JSON events to stdout.

One boundary matters for claim safety: this matrix documents what YYLO dispatches and records. It is not a statement about any external product's current capabilities — those belong to their vendors and change on their schedules. The matrix is refreshable precisely because it is dated.

Switch mid-task without losing the thread

The procedure, as four bounded steps. It works because task truth and receipts never depended on the harness in the first place:

  • Land the current run at a boundary. Do not switch mid-mutation. Finish the active step, commit (or checkpoint) the work, and record the result on the task — status, response, commit reference. Once the task record owns the state, the harness is replaceable.
  • Bank the receipts before changing anything. Capture what the current harness leaves: the final response text, the session id from the run record, and the artifact or envelope paths. If the run was audited, the execution envelope already carries provider, model, and session fields — that is your provenance snapshot of the old side.
  • Dispatch the next run on the new service. This is the entire switch as YYLO sees it — the README's own core-commands reference shows the pair side by side:
sh
yy start -b shell -s claude -i 5 -v
yy start -b shell -s codex -m :codex -i 10

Hand context across explicitly. The new harness cannot read the old harness's session, so put the recorded response — or pointers to the artifacts — into the next prompt, or pass a prepared file with -f/--prompt-file. The old conclusion becomes part of the new agent's input, and the run record shows both sides.

  • Leave the old thread addressable. Nothing about the switch deletes the previous session. yylo session list still shows it, --resume <id> still continues it, and its session_history.json entry still names its subagent and model. Returning to the old harness later is the same procedure in the other direction.

What did not move during any of this: the task, its worktree, the ledger, the operational scripts, and the admission gate. Whether one harness or three contributed, the task lands through the same preflight, finish, and serialized merge path — the discipline the multi-agent workflow guide extends to several harnesses working in one run.

Resume is not switching

The two operations get conflated, and the difference decides what survives:

  • Resume is the same harness continuing its own recorded session — yylo --resume <id> for a specific thread, yylo continue for the last one with its settings snapshot. Context carries over natively because the thread never left home.
  • Switch is a different harness starting from recorded evidence. The bridge is the handoff artifact: the response and receipts you banked become the new agent's input. Nothing is silently translated.

The rule of thumb: resume to go deeper in one thread, switch to change tools, and never expect either to substitute for the other. If you catch yourself switching because a thread got tangled, that is usually a bounded-loop problem — the fix is a tighter task boundary, not a new harness. And when a switch turns out to be a mistake, the symmetry is the safety net: the old session was never destroyed, so the recovery path is one --resume away.

Check the receipts after every switch

A switch is only proven safe by what you can still answer afterwards. Run this bounded check once the second harness has produced a run — it is the in-flight counterpart of the exit drills in the portability audit, focused on the switch itself:

  • Task truth held. The task record shows one continuous id, the status transitions from both runs, and each harness's response with its commit references — not two parallel task histories.
  • Session history shows the seam. Both runs appended entries, and the subagent and model fields differ exactly where you switched. Both session ids are present, so both threads remain addressable.
  • Evidence landed in the same shape. The new run's artifacts and envelope occupy the same locations with the same fields as the old run's, with provenance fields naming the new provider and model. If an auditor asked which harness produced a given commit, the answer comes from files, not memory.

When all three hold, the switch cost one flag plus one deliberate handoff. When one fails, you have found the exact layer that still couples your work to a harness — which is the audit's job to then fix.

Run one bounded switch today

The cheapest way to trust this procedure is to run it while nothing depends on it. Install YYLO, start one bounded task on one harness, and switch the very next run:

sh
npm install -g @yylo/cli
yylo init --task "Describe one verifiable outcome" --subagent claude
yy start -b shell -s claude -i 1 -v
yy start -b shell -s codex -m :codex -i 10

Then run the receipt check above on your own machine. The three products are separately installable and separately removable — YYLO and YYLO Benchmark from npm, YYLO Ledger from PyPI, each with its own repository — and the operational reference for every command in this guide, including the full service and model flags, lives in the YYLO documentation. Keep first switches inside the bounds the bounded-loop guide teaches — one verifiable outcome, focused checks on the touched surface — and the harness becomes what it should be: a per-run choice, not a commitment.