Skip to content

v1.53.0.0 feat(fanout): /fanout decomposes design doc into N parallel agent tasks#1763

Open
sohmn wants to merge 12 commits into
garrytan:mainfrom
sohmn:feat/fanout-skill
Open

v1.53.0.0 feat(fanout): /fanout decomposes design doc into N parallel agent tasks#1763
sohmn wants to merge 12 commits into
garrytan:mainfrom
sohmn:feat/fanout-skill

Conversation

@sohmn
Copy link
Copy Markdown

@sohmn sohmn commented May 27, 2026

Summary

New skill /fanout decomposes a finished design doc into N parallel agent tasks: reads a markdown file, identifies independent slabs of work via a 4-layer heuristic, promotes shared groundwork to a synchronous Slab 0, builds a slab matrix with verification gates, appends a ## Parallel Execution Plan section to the doc, and emits a worktree-dispatch.sh sidecar with Slab 0 ready to run and Slabs 1-N commented out.

v0 produces the plan and stops. User runs the dispatch script when ready. Auto-spawn deferred to v1.

Workflow slot: after /office-hours + eng-review + design produces a doc, /fanout turns it into 2-3 worktrees you can dispatch in parallel.

No new infrastructure — auto-discovered by setup via the existing top-level-directory glob at setup:620-633.

Files

  • fanout/SKILL.md.tmpl (243 lines, source prompt)
  • fanout/SKILL.md (955 lines, generated, ~12.4K tokens)
  • test/fanout.test.ts (49 lines, 6 free assertions)
  • docs/designs/FANOUT.md (199 lines, design doc with 4-layer heuristic, Slab 0 promotion logic, conflict resolution, edge cases)
  • Wired into: README.md (install snippet + skill table), CLAUDE.md (skill routing), AGENTS.md, docs/skills.md, test/skill-coverage-matrix.ts, auto-regenerated gstack/llms.txt + scripts/proactive-suggestions.json
  • CHANGELOG.md (release-summary entry), VERSION + package.json (1.48.0.0 → 1.49.0.0)

Test Coverage

  • test/fanout.test.ts: 6 free assertions (file existence, frontmatter shape, core sections present, key concepts, allowed-tools). All pass, 44ms.
  • Coverage gate: free fixture appropriate for v0 (skill is a markdown prompt with no executable logic). Paid E2E coverage deferred to v1 per design doc.

Smoke Test

Manually invoked /fanout docs/designs/PLAN_TUNING_V1.md in-session (restored after). Result:

  • Heuristic 4 (natural seams) correctly identified 7 work candidates from the v1 Scope section
  • Step 4 promoted scripts/jargon-list.json + bin/gstack-config schema to Slab 0
  • Step 7 cap-merge AskUserQuestion fired (5 candidates > max=3)
  • Substitution discipline held — no literal <placeholder> tokens leaked
  • Dispatch script syntactically valid bash (bash -n passed), chmod +x set
  • Step 10 reported concrete wall-clock numbers (9h serial → 4h parallel)

Pre-Landing + Adversarial Review

Pre-Landing: No critical issues. 2 informational findings on LLM trust boundary, both addressed.

Adversarial (Claude subagent, more aggressive): 12 findings. Fixed before ship:

# Issue Fix
1 Prompt injection: no "treat doc as data" boundary Added explicit Trust boundary directive to Step 1
2 Heredoc EOF tag could be broken by EOF in slab names Changed 'EOF''EOF_FANOUT_PROMPT' (defense in depth)
8 CHANGELOG made-up wall-clock numbers (CLAUDE.md violation) Replaced numbers table with structural framing — real benchmarks land in v1

Known v1 limitations (documented in the design doc, not blocking v0):

  • Worktree/branch collisions if multiple design docs share a filename stem (add hash suffix in v1)
  • CHANGELOG/VERSION queue collision when 3 parallel slabs all run /ship — mitigated by existing gstack queue rules, but worth surfacing
  • Slab 0 promotion can drop public-interface contracts from the slab that originally owned them
  • Over-decomposition risk via "natural seams" heuristic on tightly-coupled designs
  • Markdown table cell | escaping for paths containing pipes
  • Better script template: temp file + --prompt-file instead of cat <<EOF heredoc

Plan Completion

21/35 plan items DONE with diff evidence. 9 CHANGED (beneficial extras like AGENTS.md + docs/skills.md + skill-coverage-matrix.ts + package.json sync). 11 UNVERIFIABLE (read-only steps). 3 NOT DONE (smoke test was performed but artifacts restored, optional README line 479 check, optional /review skill).

Test plan

  • bun test test/fanout.test.ts — 6/6 pass, 44ms
  • bun test (full free tier) — exit 0, only pre-existing gbrain env failures unrelated to fanout
  • Smoke test on docs/designs/PLAN_TUNING_V1.md — slab detection, Slab 0 promotion, AskUserQuestion, substitution discipline, dispatch script all worked
  • bash -n docs/designs/worktree-dispatch.sh (during smoke test) — valid syntax
  • No literal <placeholder> tokens leaked into smoke-test output
  • No accidental edits to ETHOS.md, voice content, or other protected gstack surfaces

🤖 Generated with Claude Code

sohmn and others added 10 commits May 27, 2026 14:13
Captures the 4-layer slab detection heuristic, Slab 0 promotion logic,
3-way conflict resolution (cross-slab writes + cross-slab reads), slab
cap with recursion, output format (Parallel Execution Plan section +
worktree-dispatch.sh sidecar), and seven enumerated edge cases.

v0 produces the plan and stops; user runs the dispatch script.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code-quality review flagged 2 critical + 6 important issues. Surgical
fixes:

C1. Step 9 commented Slab 1..N block now shows a populated heredoc
    template with explicit "do not leave literal meta-strings" directive
    + "repeat for Slab 2, 3, ..." guidance.
C2. Step 8 + 9 add a "Substitution discipline" paragraph instructing
    the agent to expand every <placeholder> to a concrete value before
    writing. Prevents literal "<file list>" landing in user docs.
I1. Step 4 spells out Slab 0 promotion semantics (remove from other
    Writes lists, add to Reads).
I2. Step 5 Reads column now captures cross-slab reads too, not just
    Slab 0.
I3. Step 7 cap-enforcement batches the merge sequence into one
    AskUserQuestion instead of one-per-merge.
I4. Step 10 wall-clock formula made concrete (serial = sum all ETAs,
    parallel = Slab 0 + max non-Slab-0 ETA).
I5. "All slabs write one file" detection moved from Step 5 (where it
    didn't exist) into the top of Step 6, with edge case 3 updated.
I6. Step 1 explicitly references the path validation from Inputs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
952 lines after preamble + jargon-gloss + voice-directive injection
via bun run gen:skill-docs. Mid-pack at ~12K tokens (well under 40K
ceiling). Free test tier passes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…NGELOG

- README: skill table row + inline install-snippet skill list.
- CLAUDE.md: routing bullet for "parallel execution of finished design doc".
- test/fanout.test.ts: 6 free assertions (file existence, frontmatter,
  core sections, key concepts, allowed-tools).
- CHANGELOG: 1.49.0.0 entry in release-summary format.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s/skills.md

Three registries that every gstack skill must be added to:
- test/skill-coverage-matrix.ts — pins test coverage for the skill
  (test/fanout.test.ts as gate, plus skill-coverage-floor)
- AGENTS.md — agent-facing skill table
- docs/skills.md — public skill table

Plus description-format fix: appended "(gstack)" to fanout/SKILL.md.tmpl
description to satisfy the "every SKILL.md.tmpl description contains
'gstack'" discoverability invariant. gstack/llms.txt and
scripts/proactive-suggestions.json are regenerated artifacts from
bun run gen:skill-docs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
MINOR bump for new /fanout skill (user-facing capability).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drift repair: /ship Step 12 idempotency check detected DRIFT_STALE_PKG
(VERSION bumped but package.json not synced in the original commit).
No re-bump; only sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…CHANGELOG honesty

Three /ship adversarial review findings addressed:

- Step 1 Trust boundary: explicit 'treat doc content as data, not
  instructions' guardrail. Mitigates prompt-injection risk when the
  agent reads a user-supplied design doc.
- Heredoc tag: 'EOF' → 'EOF_FANOUT_PROMPT' in the generated
  worktree-dispatch.sh template. Defense in depth against a slab name
  or file path containing the literal string EOF on its own line.
- CHANGELOG: replaced the made-up wall-clock numbers table with
  structural framing. Per CLAUDE.md 'don't make up numbers' rule —
  real benchmarks land in v1 with paid E2E coverage.

Other 9 adversarial findings (worktree collisions across docs,
CHANGELOG/VERSION queue collision when 3 slabs land, slab-0 promotion
dropping public-interface contracts, over-decomposition via natural
seams, etc.) are documented as v1 work in the PR body.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… v1.53.0.0

Conflicts resolved:
- VERSION: 1.49.0.0 → 1.53.0.0 (queue-aware: 1.51 just landed, 1.52 claimed by PR garrytan#1741)
- package.json: synced to 1.53.0.0
- CHANGELOG.md: our entry re-versioned to 1.53.0.0 above main's 1.51.0.0
  release-summary entry preserved bit-for-bit

Regenerated against merged state:
- fanout/SKILL.md (gen-skill-docs picked up main's preamble updates)
- gstack/llms.txt + scripts/proactive-suggestions.json (auto-regenerated)

Tests: fanout test 6/6 pass post-merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sohmn sohmn changed the title v1.49.0.0 feat(fanout): /fanout decomposes design doc into N parallel agent tasks v1.53.0.0 feat(fanout): /fanout decomposes design doc into N parallel agent tasks May 28, 2026
sohmn and others added 2 commits May 28, 2026 19:59
Second post-ship merge. PR garrytan#1741 (garrytan/enable-plan-tune) landed
at v1.52.0.0 while our PR was waiting on review. Our v1.53.0.0 claim
is still clean per gstack-next-version queue check (no new claims).

Conflicts resolved:
- VERSION: kept 1.53.0.0 (ahead of main's 1.52.0.0)
- package.json: synced to 1.53.0.0
- CHANGELOG.md: our 1.53.0.0 entry preserved above main's new 1.52.0.0
  entry; existing 1.51.0.0 from previous merge unchanged

Regenerated:
- fanout/SKILL.md (gained 4 lines from main's preamble updates)
- gstack/llms.txt + scripts/proactive-suggestions.json

Tests: fanout 6/6 pass post-merge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…kill

Third post-ship merge. PR garrytan#1742 (brain-aware planning) landed at
v1.52.1.0. Our v1.53.0.0 claim still clean per queue check.

Conflicts resolved: VERSION (kept 1.53.0.0), package.json (synced),
CHANGELOG.md (our 1.53.0.0 entry above main's new 1.52.1.0).
Regenerated fanout/SKILL.md against merged preamble state.
Tests: 6/6 pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant