Summary
.opencode/skills/swarm-implement/SKILL.md:78 (Phase 0b) and the byte-identical instruction at .opencode/skills/codebase-review-swarm/SKILL.md:74 say:
Verify the working tree is clean with git status --porcelain. If uncommitted changes exist, stash them or abort the checkout to prevent data loss.
That is safe for a single agent and destructive under the execution model these same skills mandate. swarm-implement Phase 1 instructs "Launch parallel subagents for disjoint investigation tasks"; those agents share one worktree. git stash is worktree-global, not scoped to the caller's files — so an agent following Phase 0b stashes every sibling agent's in-flight work.
Note the instruction's own framing: it exists "to prevent data loss." Under parallel execution it causes the data loss it was written to prevent.
This is not hypothetical — it fired
During implementation of the PR-workflow lane-output fix (branch claude/swarm-pr-gates-restrictive-vnu6fc), five agents were editing disjoint file scopes concurrently. One ran git stash to take its own clean-tree baseline measurement, followed by a git reset. That stashed all twelve modified files across all five agents — ~451 insertions of completed, unrelated work.
It was caught only because a source grep for a symbol one agent had reported adding came back empty. The agent's completion report was truthful; its work had been silently removed underneath it by a sibling. Recovered in full via git stash pop, but only because it was noticed within the same session — nothing in the protocol would have surfaced it, and a later git stash would have buried the first stash entry deeper.
Failure mode worth stressing: every agent reports success, and the work is gone. There is no error, no failed assertion, and no gate that detects it. The only signal is an independent re-read of the file.
Why the fix is well-defined
The repository already contains the correct pattern in three places:
.opencode/skills/running-tests/SKILL.md:202 — "Use a Git worktree — safer than git stash (stash can drop untracked…)"
.opencode/skills/swarm-pr-review/SKILL.md:211 and .opencode/skills/swarm-pr-feedback/SKILL.md:174 — "Do not issue git stash through shell", with checkout preparation owned by the prepare_pr_workflow_checkout controller tool instead of delegated agents
So the PR workflow already solved exactly this problem: the orchestrator owns worktree state transitions, delegated agents are forbidden from performing them, and there is a dedicated tool for the legitimate case. The generic implementation skills never inherited that lesson.
Proposed change
swarm-implement/SKILL.md Phase 0b and codebase-review-swarm/SKILL.md — restrict worktree state transitions (stash, reset, checkout ., restore) to the orchestrator, before any subagent is dispatched. Delegated agents must never run them. Point at a git worktree (running-tests precedent) or a temporary save branch (commit-pr/SKILL.md:80 already prefers this on Windows) rather than stash.
- Add an explicit prohibition to the delegation contract so it reaches agents that never read Phase 0b. In this session the workaround was putting a hard "NEVER run
git stash/reset/checkout ./restore" rule in every subagent prompt; that worked, and belongs in the skill rather than in ad-hoc prompts.
- Consider a mechanical guard. A
tool.execute.before hook rejecting destructive git verbs from non-orchestrator sessions would make this structurally impossible instead of merely documented — mirroring how the PR-workflow gate already blocks these. Optional, but this is a silent-data-loss class, which the guardrail ladder (docs/engineering-invariants.md) treats as warranting machinery over vigilance.
Acceptance criteria
Notes
Both files are canonical .opencode sources classified in src/config/skill-mirrors.ts; the .claude/.agents copies are thin adapter shims and should not need content edits.
Surfaced while implementing the fix on claude/swarm-pr-gates-restrictive-vnu6fc. Unrelated to that change's subject matter — filed separately rather than folded in.
Summary
.opencode/skills/swarm-implement/SKILL.md:78(Phase 0b) and the byte-identical instruction at.opencode/skills/codebase-review-swarm/SKILL.md:74say:That is safe for a single agent and destructive under the execution model these same skills mandate.
swarm-implementPhase 1 instructs "Launch parallel subagents for disjoint investigation tasks"; those agents share one worktree.git stashis worktree-global, not scoped to the caller's files — so an agent following Phase 0b stashes every sibling agent's in-flight work.Note the instruction's own framing: it exists "to prevent data loss." Under parallel execution it causes the data loss it was written to prevent.
This is not hypothetical — it fired
During implementation of the PR-workflow lane-output fix (branch
claude/swarm-pr-gates-restrictive-vnu6fc), five agents were editing disjoint file scopes concurrently. One rangit stashto take its own clean-tree baseline measurement, followed by agit reset. That stashed all twelve modified files across all five agents — ~451 insertions of completed, unrelated work.It was caught only because a source
grepfor a symbol one agent had reported adding came back empty. The agent's completion report was truthful; its work had been silently removed underneath it by a sibling. Recovered in full viagit stash pop, but only because it was noticed within the same session — nothing in the protocol would have surfaced it, and a latergit stashwould have buried the first stash entry deeper.Failure mode worth stressing: every agent reports success, and the work is gone. There is no error, no failed assertion, and no gate that detects it. The only signal is an independent re-read of the file.
Why the fix is well-defined
The repository already contains the correct pattern in three places:
.opencode/skills/running-tests/SKILL.md:202— "Use a Git worktree — safer thangit stash(stash can drop untracked…)".opencode/skills/swarm-pr-review/SKILL.md:211and.opencode/skills/swarm-pr-feedback/SKILL.md:174— "Do not issuegit stashthrough shell", with checkout preparation owned by theprepare_pr_workflow_checkoutcontroller tool instead of delegated agentsSo the PR workflow already solved exactly this problem: the orchestrator owns worktree state transitions, delegated agents are forbidden from performing them, and there is a dedicated tool for the legitimate case. The generic implementation skills never inherited that lesson.
Proposed change
swarm-implement/SKILL.mdPhase 0b andcodebase-review-swarm/SKILL.md— restrict worktree state transitions (stash,reset,checkout .,restore) to the orchestrator, before any subagent is dispatched. Delegated agents must never run them. Point at a git worktree (running-testsprecedent) or a temporary save branch (commit-pr/SKILL.md:80already prefers this on Windows) rather thanstash.git stash/reset/checkout ./restore" rule in every subagent prompt; that worked, and belongs in the skill rather than in ad-hoc prompts.tool.execute.beforehook rejecting destructive git verbs from non-orchestrator sessions would make this structurally impossible instead of merely documented — mirroring how the PR-workflow gate already blocks these. Optional, but this is a silent-data-loss class, which the guardrail ladder (docs/engineering-invariants.md) treats as warranting machinery over vigilance.Acceptance criteria
swarm-implementnorcodebase-review-swarminstructs a delegated agent to stash; both name the orchestrator-owned alternative.running-tests:202,swarm-pr-review:211,swarm-pr-feedback:174, andcommit-pr:80.bun run drift:checkclean (both files are canonical.opencodesources with.claude/.agentsadapter shims).docs/releases/pending/(AGENTS.md invariant 12).git stash.Notes
Both files are canonical
.opencodesources classified insrc/config/skill-mirrors.ts; the.claude/.agentscopies are thin adapter shims and should not need content edits.Surfaced while implementing the fix on
claude/swarm-pr-gates-restrictive-vnu6fc. Unrelated to that change's subject matter — filed separately rather than folded in.