You invoked /phased-implement add support for https://github.com/QwenLM/qwen-code. That skill loads a coordinator that never writes source code itself — it only writes plans, spawns workers, and verifies their output. Its job is to turn one big task into a DAG of smaller phases that can be parallelized safely.
Recorded START_HEAD=03f07d3, integration branch qwen, verified the working tree was clean. Created history/2026-04-28-phased-qwen-support/ with prompts/, captures/, and a manifest.md tracking each phase's state (pending → working → done-unverified → merging → merged).
history/ is gitignored and symlinked across all worktrees by workmux's setup, so the coordinator and all workers can read/write the same plan, prompts, and result sentinels without committing them.
Research first. I cloned QwenLM/qwen-code to /tmp/qwen-code and read its source directly (per CLAUDE.md's "source is ground truth" rule) to verify:
- Config dir:
~/.qwen/settings.json(mirrors gemini) - Hook event names:
UserPromptSubmit/PostToolUse/Stop/… — Claude-style, NOT gemini'sBeforeAgent/AfterAgent - CLI flags: inherits
--yolo,-i,-p,--continuefrom gemini-cli - Skills dir:
~/.qwen/skills/
Drafted plan.md with a 2-phase DAG (initially): integration + docs.
Plan review via consult-llm. Sent the plan + relevant existing files (gemini.rs, multiplexer/agent.rs, agent_setup/mod.rs) to gpt-5.5 with --task review, asking for Spec Check / Premortem / Plan Findings.
The review caught 4 high-severity issues:
-pis headless; would kill the interactive pane. Must be-i.- Notification matcher is an exact string in qwen, not a regex alternation. So
"permission_prompt"alone, not"permission_prompt|elicitation_dialog". - Missing sandbox surface entirely:
docker/Dockerfile.qwen,KNOWN_AGENTS,DOCKERFILE_QWENdispatch incontainer.rs, lima mount mapping, GitHub Actions matrix. Cargo.tomlpackage include neededresources/qwen/**/*orcargo publishwould ship without the embedded JSON.
Folded all four into a revised plan with 3 phases (core, sandbox, docs) and a Feedback Ledger documenting what was applied vs. deferred.
The DAG:
core ─┐
├──> docs
sandbox ─┘
core and sandbox touch disjoint files, so they run in parallel. docs waits for both.
For each ready phase, the coordinator wrote prompts/<id>.md (a self-contained brief — workers can't see the coordinator's conversation), then ran:
workmux add qwen-core -b --base qwen -P prompts/core.md
workmux add qwen-sandbox -b --base qwen -P prompts/sandbox.md
For each, workmux:
- Created a git worktree at
../qwen-core/checked out to a new branchqwen-corebased on theqwenbranch. - Ran post-create hooks (file copies, symlinks like
history/, dependency setup). - Created a tmux window in the background (
-b) with the configured pane layout. - Started a Claude Code agent in the editor pane and injected the prompt file's contents into the agent's first message via
claude -i "$(cat PROMPT.md)". - Wired up status hooks so the tmux window name shows 🤖 working / 💬 waiting / ✅ done.
Both workers were now running in parallel, each in its own filesystem checkout, each with its own Claude agent that had read its phase prompt and started working autonomously.
The coordinator sat in workmux wait qwen-core qwen-sandbox --any --timeout 300, blocking until any worker's status flipped to done.
The phase prompt instructed each worker to run /implement <description>. That skill is itself an autonomous workflow with these stages:
Worker reads the acceptance criteria from its prompt and rewrites them as testable statements. For core, that meant ~8 specific assertions (enum variant exists with serde tag "qwen", QwenProfile.prompt_argument returns -i ..., Cargo.toml includes resources/qwen/**/*, etc.).
Worker drafts its own implementation plan — file-by-file changes, in what order, what tests to add. This plan lives inside the worker's worktree, not in history/.
Worker fans out to external LLMs via consult-llm for a premortem ("what's most likely to break?") and an independent alternative ("how would you do it differently?"). Findings get filtered through a decision ledger: each one is either applied, deferred-with-reason, or rejected-with-reason. No silent ignoring.
Worker edits files. For core:
- New file
src/agent_setup/qwen.rsmodeled line-by-line ongemini.rsbut with Claude-style hook events. - New file
resources/qwen/settings.jsonwith the 5 hooks. - Edit
src/agent_setup/mod.rsto addAgent::Qwen, wire it intocheck_all,install,name(), and update every test that enumerates the enum. - Edit
src/multiplexer/agent.rsto addQwenProfileand register it inPROFILES. - Edit
src/config.rsfor~/.qwenmapping. - Edit
src/skills.rsto move qwen out of theNonebranch. - Edit
Cargo.tomlfor the package include.
Worker runs just check (cargo check + clippy + fmt + tests). If it fails, it enters a debug loop: re-read the failure, root-cause it, fix the underlying issue, re-run. It does not paper over symptoms with // TODO or --allow flags. For core, validation reported 1015 tests passing.
Worker sends the diff to another LLM with adversarial framing: "find the bug." Must-fix findings go through the decision ledger and get applied; the worker re-validates after.
Single commit on the worker's branch (qwen-core), following the project's commit style from CLAUDE.md (lowercase, imperative, no conventional-commit prefixes, with a body explaining "why").
Final action — the worker writes a one-line file to the shared history/ tree:
PHASE_RESULT id=core status=success commit=c6bd9e1... validation=passed
Then idles, waiting for the coordinator to send /merge --keep.
When workmux wait returned with a worker in done state, the coordinator:
- Read the sentinel from the shared
history/captures/<phase>.result.status=success,validation=passed— green light. - Captured the agent's tail (
workmux capture qwen-core -n 200) intocaptures/<phase>.tailfor the audit trail. Useful for forensics if anything later turns out wrong. - Serialized merges. The coordinator never lets two
/mergecalls run concurrently — they share the integration branch. If another phase was already merging, this one waits. - Sent
/merge --keepinto the worker's tmux session viaworkmux send qwen-core "/merge --keep". The worker received it as if the user had typed it.
The /merge skill, running inside the worker's session:
git fetch originand rebaseqwen-coreonto the latestqwen(the integration branch). This rewrites commit SHAs, which is why the post-rebase tip is what matters for ancestry, not the pre-rebase sha in the sentinel.- Fast-forward merges the rebased branch into
qwen. - Normally
/mergewould also delete the worktree, the local branch, and the tmux window.--keepsuppresses that, leaving the worktree alive for the coordinator to inspect.
The coordinator then ran git rev-parse HEAD inside the (still-alive) worker worktree to get the post-rebase sha, and checked:
git merge-base --is-ancestor <post_tip> qwen
If the post-rebase sha is an ancestor of the integration branch, the merge truly landed. If not, it would mark the phase failed and halt dependents — never trust /merge exit code alone, since a silent rebase abort can look successful.
After verification, workmux remove qwen-core cleaned up the worktree, the local branch, and the tmux window in one shot.
After a merge, the coordinator recomputed the ready set: phases whose status is pending and whose dependencies are all merged.
- After
coremerged:sandboxwas already running (independent),docsstill blocked. - After
sandboxmerged:docsbecame ready. Coordinator wroteprompts/docs.md, spawnedqwen-docsbased on the now-much-newerqwenbranch (which contained both prior commits), and the docs worker ran the same/implementworkflow against acceptance criteria that explicitly forbade touchingsrc/,docker/, etc. - After
docsmerged: ready set empty, nothing working — exit dispatch loop.
8524df1 fix table formatting in open.md reference ← docs phase fixup commit
000c41b document qwen-code support across README, … ← docs phase main commit
e3fd493 add qwen sandbox image and wire through … ← sandbox phase
c6bd9e1 add qwen-code as a first-class agent ← core phase
03f07d3 sidebar: log fd count and watch lifecycle … ← START_HEAD
Three phases. Three logical commits (one phase produced two — a main commit and a doc table fixup found by its own red-team pass). Each phase ran just check independently and the integration branch ran just check again at the end: 1016 tests, all green.
- Parallelism.
coreandsandboxran simultaneously and saved wall-clock time. - File scope isolation. Two parallel agents can't conflict if their
paths:don't overlap. Cross-phase corruption is avoided by the prompt's hard constraints, not by trust. - Smaller context per worker. Each worker only loads files relevant to its phase, leaving more context budget for
/implement's plan + review + red-team passes. - Independent quality gates. Plan-review-redteam runs three times instead of once. The reviewer who would have caught the
-pvs-ibug at the master-plan level is a different LLM than the one doing the per-phase review at implementation time. Bugs that slip past one model often get caught by another. - Hard cleanup boundary. A failed phase fails its own worktree and halts only its dependents. Other parallel phases finish, get merged normally, and the user gets a partial-success summary instead of a half-applied mess on the integration branch.
The whole run was ~15 minutes wall-clock. The coordinator's actual reasoning output was small — most of the tokens were spent inside the three worker agents doing the real engineering, in isolation, with their own review loops.