Run the full round-trip

// GUIDE · ROUND-TRIP

Reproduce, fix, verify, open both PRs — in one orchestrated loop.

The Vivarium round-trip skill walks an AI agent and a human through the full path from an upstream bug report to a draft fix PR. Phases 1-5 of the round-trip automation plan ship the underlying tooling; this guide is the human-readable companion to the `round-trip` Claude Code skill.

// 0 · WHAT THIS GUIDE COVERS

End-to-end orchestration of the round-trip loop.

This guide describes the round-trip loop in human-readable form: what happens at each stage, what is automated, and what stays a human decision. The machine-readable orchestration itself lives in .claude/skills/round-trip/SKILL.md — auto-loaded by Claude Code when its triggers match; you usually do not read it directly.

If you only want to scaffold a recipe — without the full fix- and-PR loop — use the Getting started guide instead.

This guide is still under iteration. Concrete examples grow as the maintainer exercises the loop on real upstream issues; expect this page to fill out over time.

// 1 · PREREQUISITES

What you need installed and configured.

01
gh CLI authenticated with repo scope.

Run gh auth login if not already done. The skill calls gh issue view, gh pr create, gh workflow run, and gh run download; repo is the minimum scope.

02
MCP server registered with your client.

See Use from your AI agent. The round-trip skill invokes search_upstream_issues, prepare_new_recipe, verify_and_report_fix, and (Layer 2) create_fork_pr.

03
Sapling (sl) on this side.

Vivarium uses Sapling as its SCM rather than Git directly. The skill drives sl addremove / sl commit / sl amend / sl pr submit for the Vivarium-side PR.

04
Layer 2 only: GHCR PAT.

A classic PAT with write:packages scope, stored per the one-time setup mise run ghcr:login documents. Used by mise run branch-fix:publish at Stage 5.5.

// 2 · THE FLOW AT A GLANCE

Ten stages, with a layer-dependent verdict path.

Stages 0 – 5 are layer-independent; the path branches at Stage 6 depending on whether the recipe is Layer 1 (WASM in-browser) or Layer 2 (Docker). Layer 3 (record-replay) is currently out of scope for the fixed-verdict capture — see the cheat sheet below.

Stage 0    Pre-flight (project activity, issue exists, no linked PR)
Stage 1    Scaffold (prepare_new_recipe + mise run recipes:new)
Stage 2    Implement reproduction (human + AI)
Stage 3    Capture unfixed verdict (verify_and_report_fix)
Stage 4    Open the Vivarium PR (sl pr submit, label ai: generated)
Stage 5    Fork upstream + push fix branch (human)
Stage 5.5  Layer 2 only: build & push branch-fix image
           (mise run branch-fix:publish)
Stage 6    Capture fixed verdict
           - Layer 1: prepare_fix_candidate → CI wheel build →
                      live recipe page (visual confirm by human)
           - Layer 2: verify_and_report_fix with branch_image →
                      branch-fix-verdict.yml + artefact
Stage 7    Update Vivarium PR with fixed verdict
           (Layer 2 only; sl amend + sl pr submit)
Stage 8    Open upstream draft PR
           - Layer 1: commands returned by prepare_fix_candidate
           - Layer 2: create_fork_pr (dry_run: false)
Stage 9    Final Vivarium-side commit
           (Layer 2 only; sl amend + sl pr submit)

// 3 · INVOKING THE SKILL

One sentence, the agent does the rest.

Tell your AI agent (Claude Code, Cursor, Cline) something like:

Run the full round-trip on https://github.com/owner/repo/issues/N. It is a Layer 2 bug; the title is "short title"; base image is node:26-slim.

The agent picks up the round-trip skill (auto-loaded when its trigger conditions match) and walks you through each stage. At every hand-off back to you (Stages 2, 5, sometimes 6 for Layer 1) you confirm and the agent continues. On any failure the skill sets roundtrip.json#/status to "blocked" and stops — see Troubleshooting below.

// 4 · LAYER 1 vs LAYER 2 CHEAT SHEET

The fixed-verdict path differs; everything else lines up.

Layer 1 (WASM)Layer 2 (Docker)
Unfixed verdict source

In-browser Pyodide / Ruby.wasm / php-wasm, captured by Playwright against src/layer1_wasm/<slug>/

Deployed verdict.json snapshot CI captured at recipe-merge time

Fix delivery

Fork branch → CI wheel build (fires on Vivarium PR merge via deploy-docs.yml)

Fork branch → contributor builds the Docker image locally → GHCR push

Fixed verdict source

Live recipe page renders baseline + fix-candidate side-by-side; human confirms visually

branch-fix-verdict.yml workflow artefact (Contract v1 branch-fix-verdict.json)

Upstream PR opening

Commands returned by prepare_fix_candidate, run manually after the Vivarium PR merges

create_fork_pr MCP tool with dry_run: false (draft PR + body footer disclosure)

Layer 3 (record-replay): verify_and_report_fix rejects Layer 3 verify_fixed with an informative error — branch-fix-verdict.yml only handles src/layer2_docker/<slug>/. Workflow extension to handle src/layer3_thirdway/<slug>/ is tracked separately.

// 5 · TROUBLESHOOTING

When the skill bails with status: blocked.

Any stage failure flips roundtrip.json#/status to "blocked" and stops the skill. A subsequent /round-trip invocation on the same slug refuses to resume until the human clears it.

To resume:

  1. Read roundtrip.json#/notes[] for the failure reason and stage number.

  2. Fix the underlying issue (typically: re-run the failed command manually with verbose flags to see what actually went wrong).

  3. Edit roundtrip.json — set status back to its expected value (likely "verifying" or "verified" depending on how far you got) and bump updated_at.

  4. Re-invoke /round-trip. The skill re-reads roundtrip.json and resumes from the appropriate stage (the computeNextAction state machine in verify_and_report_fix picks the resume point).

Found something this guide didn't cover? File an issue against

aletheia-works/vivarium

so we can fold the gap back into this page.

// NEXT

Compare a branch-fix verdict

The round-trip skill orchestrates branch-fix verification, but you can also drive it manually for one-off fix verification.

VIVARIUM IS PART OF ALETHEIA-WORKS · SEE SOURCE ON GITHUB →