From e684948efebf4698aa84701268c537b203964da6 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 14 Aug 2026 15:39:50 -0700 Subject: [PATCH] fix(review,autoplan): require explicit run_in_background: false on specialist agents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Claude Code v2.1.198 made subagents run in the background by default, which inverted the old "do not use the flag" guidance: review-army specialists and autoplan dual voices silently launched in the background and the merge step could proceed before they completed — regressing the #497 fix. The generated guidance now instructs an explicit run_in_background: false, and a static tripwire fails the free suite if the inert inverted phrasing ever returns to any generated SKILL.md. Fixes #2440. Co-Authored-By: Claude Fable 5 --- autoplan/SKILL.md | 7 ++- autoplan/SKILL.md.tmpl | 7 ++- review/SKILL.md | 2 +- scripts/resolvers/review-army.ts | 2 +- ship/sections/review-army.md | 2 +- test/fixtures/golden/factory-ship-SKILL.md | 2 +- test/run-in-background-guidance.test.ts | 66 ++++++++++++++++++++++ 7 files changed, 78 insertions(+), 10 deletions(-) create mode 100644 test/run-in-background-guidance.test.ts diff --git a/autoplan/SKILL.md b/autoplan/SKILL.md index 41a108582..29c588290 100644 --- a/autoplan/SKILL.md +++ b/autoplan/SKILL.md @@ -1154,9 +1154,10 @@ Override: every AskUserQuestion → auto-decide using the 6 principles. Duplicates → reject (P4). Borderline (3-5 files) → mark TASTE DECISION. - All 10 review sections: run fully, auto-decide each issue, log every decision. - Dual voices: always run BOTH Claude subagent AND Codex if available (P6). - Run them sequentially in foreground. First the Claude subagent (Agent tool, - foreground — do NOT use run_in_background), then Codex (Bash). Both must - complete before building the consensus table. + Run them sequentially in foreground. First the Claude subagent (Agent tool + with run_in_background: false — subagents default to BACKGROUND since + Claude Code v2.1.198, so the flag must be explicitly false), then Codex + (Bash). Both must complete before building the consensus table. **Codex CEO voice** (via Bash): ```bash diff --git a/autoplan/SKILL.md.tmpl b/autoplan/SKILL.md.tmpl index 0f054dacf..011bbacdd 100644 --- a/autoplan/SKILL.md.tmpl +++ b/autoplan/SKILL.md.tmpl @@ -290,9 +290,10 @@ Override: every AskUserQuestion → auto-decide using the 6 principles. Duplicates → reject (P4). Borderline (3-5 files) → mark TASTE DECISION. - All 10 review sections: run fully, auto-decide each issue, log every decision. - Dual voices: always run BOTH Claude subagent AND Codex if available (P6). - Run them sequentially in foreground. First the Claude subagent (Agent tool, - foreground — do NOT use run_in_background), then Codex (Bash). Both must - complete before building the consensus table. + Run them sequentially in foreground. First the Claude subagent (Agent tool + with run_in_background: false — subagents default to BACKGROUND since + Claude Code v2.1.198, so the flag must be explicitly false), then Codex + (Bash). Both must complete before building the consensus table. **Codex CEO voice** (via Bash): ```bash diff --git a/review/SKILL.md b/review/SKILL.md index 456d98d51..9d070c536 100644 --- a/review/SKILL.md +++ b/review/SKILL.md @@ -1395,7 +1395,7 @@ CHECKLIST: **Subagent configuration:** - Use `subagent_type: "general-purpose"` -- Do NOT use `run_in_background` — all specialists must complete before merge +- Pass `run_in_background: false` on every specialist Agent call — subagents run in the BACKGROUND by default since Claude Code v2.1.198, and all specialists must complete before merge. (Merely omitting the flag no longer produces a foreground run; it must be explicitly false.) - If any specialist subagent fails or times out, log the failure and continue with results from successful specialists. Specialists are additive — partial results are better than no results. --- diff --git a/scripts/resolvers/review-army.ts b/scripts/resolvers/review-army.ts index 5c8766e30..029367deb 100644 --- a/scripts/resolvers/review-army.ts +++ b/scripts/resolvers/review-army.ts @@ -129,7 +129,7 @@ CHECKLIST: **Subagent configuration:** - Use \`subagent_type: "general-purpose"\` -- Do NOT use \`run_in_background\` — all specialists must complete before merge +- Pass \`run_in_background: false\` on every specialist Agent call — subagents run in the BACKGROUND by default since Claude Code v2.1.198, and all specialists must complete before merge. (Merely omitting the flag no longer produces a foreground run; it must be explicitly false.) - If any specialist subagent fails or times out, log the failure and continue with results from successful specialists. Specialists are additive — partial results are better than no results.`; } diff --git a/ship/sections/review-army.md b/ship/sections/review-army.md index f7943d295..c1c934c39 100644 --- a/ship/sections/review-army.md +++ b/ship/sections/review-army.md @@ -245,7 +245,7 @@ CHECKLIST: **Subagent configuration:** - Use `subagent_type: "general-purpose"` -- Do NOT use `run_in_background` — all specialists must complete before merge +- Pass `run_in_background: false` on every specialist Agent call — subagents run in the BACKGROUND by default since Claude Code v2.1.198, and all specialists must complete before merge. (Merely omitting the flag no longer produces a foreground run; it must be explicitly false.) - If any specialist subagent fails or times out, log the failure and continue with results from successful specialists. Specialists are additive — partial results are better than no results. --- diff --git a/test/fixtures/golden/factory-ship-SKILL.md b/test/fixtures/golden/factory-ship-SKILL.md index a5539b750..cb96693bb 100644 --- a/test/fixtures/golden/factory-ship-SKILL.md +++ b/test/fixtures/golden/factory-ship-SKILL.md @@ -2177,7 +2177,7 @@ CHECKLIST: **Subagent configuration:** - Use `subagent_type: "general-purpose"` -- Do NOT use `run_in_background` — all specialists must complete before merge +- Pass `run_in_background: false` on every specialist Agent call — subagents run in the BACKGROUND by default since Claude Code v2.1.198, and all specialists must complete before merge. (Merely omitting the flag no longer produces a foreground run; it must be explicitly false.) - If any specialist subagent fails or times out, log the failure and continue with results from successful specialists. Specialists are additive — partial results are better than no results. --- diff --git a/test/run-in-background-guidance.test.ts b/test/run-in-background-guidance.test.ts new file mode 100644 index 000000000..91283ef55 --- /dev/null +++ b/test/run-in-background-guidance.test.ts @@ -0,0 +1,66 @@ +import { describe, test, expect } from 'bun:test'; +import * as fs from 'fs'; +import * as path from 'path'; + +// Regression guard for #2440 (which itself regressed the #497 fix). +// +// Claude Code v2.1.198 made subagents run in the BACKGROUND by default. +// Guidance written before that ("do NOT use run_in_background") stopped +// producing a foreground run — the review army and autoplan dual-voice +// steps silently launched specialists in the background and merged before +// they completed. The only guidance that works post-2.1.198 is an explicit +// `run_in_background: false` on the Agent call. +// +// This tripwire pins the corrected phrasing in the generated skill output +// and fails if the inverted form ever comes back through a template or +// resolver edit. + +const ROOT = path.resolve(import.meta.dir, '..'); + +const GENERATED_WITH_GUIDANCE = ['review/SKILL.md', 'autoplan/SKILL.md']; + +// The inverted, post-2.1.198-inert phrasings. Checked across every generated +// SKILL.md so the regression can't migrate to another skill unnoticed. +const INVERTED = /do not use\s+`?run_in_background`?/i; + +function allGeneratedSkillFiles(): string[] { + const out: string[] = []; + for (const entry of fs.readdirSync(ROOT, { withFileTypes: true })) { + if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === 'node_modules') continue; + const p = path.join(ROOT, entry.name, 'SKILL.md'); + if (fs.existsSync(p)) out.push(p); + // Generated on-demand section files (e.g. ship/sections/review-army.md) + // carry the same resolver output as SKILL.md bodies — scan them too. + const sections = path.join(ROOT, entry.name, 'sections'); + if (fs.existsSync(sections)) { + for (const f of fs.readdirSync(sections)) { + if (f.endsWith('.md')) out.push(path.join(sections, f)); + } + } + } + const rootSkill = path.join(ROOT, 'SKILL.md'); + if (fs.existsSync(rootSkill)) out.push(rootSkill); + return out; +} + +describe('run_in_background guidance (#2440)', () => { + test('foreground-required skills instruct run_in_background: false explicitly', () => { + for (const rel of GENERATED_WITH_GUIDANCE) { + const content = fs.readFileSync(path.join(ROOT, rel), 'utf-8'); + expect(content).toContain('run_in_background: false'); + } + }); + + test('the inverted "do NOT use run_in_background" phrasing never comes back', () => { + for (const file of allGeneratedSkillFiles()) { + const content = fs.readFileSync(file, 'utf-8'); + if (INVERTED.test(content)) { + throw new Error( + `${path.relative(ROOT, file)} contains the inverted run_in_background guidance — ` + + 'since Claude Code v2.1.198 subagents default to background, so "do not use" is inert; ' + + 'instruct `run_in_background: false` instead (see #2440).', + ); + } + } + }); +});