Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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

Closed
sohmn wants to merge 12 commits into
garrytan:main from
sohmn:feat/fanout-skill
Closed

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

Conversation

@sohmn

@sohmn sohmn commented May 27, 2026
edited
Loading

Copy link
Copy Markdown

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>

garrytan commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Closing — targets v1.53.0.0, well behind main (now v1.57.0.0), with substantial merge conflicts. If /fanout is still something you want to land, please rebase on current main and reopen. Thanks for the work!

sohmn commented Jun 9, 2026

Copy link
Copy Markdown
Author

Rebased on current main (v1.57.7.0) and reopened as #1949 — fresh branch, three clean commits, no merge history. Also closed all six limitations the adversarial review here documented as v1 work (collision-proof worktree naming, CHANGELOG/VERSION queue tax surfaced, contract ownership through Slab 0 promotion, over-decomposition guard, table-cell escaping, and per-slab prompt files replacing heredocs in the dispatch script). Thanks for the pointer!

sohmn added a commit to sohmn/gstack that referenced this pull request Jun 10, 2026
...closed
Rebuilt fresh on current main per review feedback on the first PR
(garrytan#1763): rebase instead of dragging four generations of merge
conflicts forward.
Carries the first PR's hardening (Step 1 trust boundary, substitution
discipline) and closes all six limitations that PR documented as v1
work:
- L1 worktree/branch names get a doc-path sha8 suffix (collision-proof
 across same-stem design docs)
- L2 CHANGELOG/VERSION named expected-conflict files in Merge order,
 slab prompts, and the wall-clock report
- L3 Slab 0 promotion keeps contract ownership with the owning slab
- L4 over-decomposition guard: draft-contract refusal in heuristic 4 +
 parallelism-confidence check (stop when >1/3 of slabs chain)
- L5 table cells escape pipes, collapse newlines
- L6 per-slab .prompt.md files replace heredocs in the dispatch script
 (kills the EOF-breakout class, prompts editable before dispatch)
test/fanout.test.ts pins all six guardrails. 7/7 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sohmn added a commit to sohmn/gstack that referenced this pull request Jun 10, 2026
...closed
Rebuilt fresh on current main per review feedback on the first PR
(garrytan#1763): rebase instead of dragging four generations of merge
conflicts forward.
Carries the first PR's hardening (Step 1 trust boundary, substitution
discipline) and closes all six limitations that PR documented as v1
work:
- L1 worktree/branch names get a doc-path sha8 suffix (collision-proof
 across same-stem design docs)
- L2 CHANGELOG/VERSION named expected-conflict files in Merge order,
 slab prompts, and the wall-clock report
- L3 Slab 0 promotion keeps contract ownership with the owning slab
- L4 over-decomposition guard: draft-contract refusal in heuristic 4 +
 parallelism-confidence check (stop when >1/3 of slabs chain)
- L5 table cells escape pipes, collapse newlines
- L6 per-slab .prompt.md files replace heredocs in the dispatch script
 (kills the EOF-breakout class, prompts editable before dispatch)
test/fanout.test.ts pins all six guardrails. 7/7 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sohmn added a commit to sohmn/gstack that referenced this pull request Jun 11, 2026
...closed
Rebuilt fresh on current main per review feedback on the first PR
(garrytan#1763): rebase instead of dragging four generations of merge
conflicts forward.
Carries the first PR's hardening (Step 1 trust boundary, substitution
discipline) and closes all six limitations that PR documented as v1
work:
- L1 worktree/branch names get a doc-path sha8 suffix (collision-proof
 across same-stem design docs)
- L2 CHANGELOG/VERSION named expected-conflict files in Merge order,
 slab prompts, and the wall-clock report
- L3 Slab 0 promotion keeps contract ownership with the owning slab
- L4 over-decomposition guard: draft-contract refusal in heuristic 4 +
 parallelism-confidence check (stop when >1/3 of slabs chain)
- L5 table cells escape pipes, collapse newlines
- L6 per-slab .prompt.md files replace heredocs in the dispatch script
 (kills the EOF-breakout class, prompts editable before dispatch)
test/fanout.test.ts pins all six guardrails. 7/7 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sohmn added a commit to sohmn/gstack that referenced this pull request Jun 12, 2026
...closed
Rebuilt fresh on current main per review feedback on the first PR
(garrytan#1763): rebase instead of dragging four generations of merge
conflicts forward.
Carries the first PR's hardening (Step 1 trust boundary, substitution
discipline) and closes all six limitations that PR documented as v1
work:
- L1 worktree/branch names get a doc-path sha8 suffix (collision-proof
 across same-stem design docs)
- L2 CHANGELOG/VERSION named expected-conflict files in Merge order,
 slab prompts, and the wall-clock report
- L3 Slab 0 promotion keeps contract ownership with the owning slab
- L4 over-decomposition guard: draft-contract refusal in heuristic 4 +
 parallelism-confidence check (stop when >1/3 of slabs chain)
- L5 table cells escape pipes, collapse newlines
- L6 per-slab .prompt.md files replace heredocs in the dispatch script
 (kills the EOF-breakout class, prompts editable before dispatch)
test/fanout.test.ts pins all six guardrails. 7/7 pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

AltStyle によって変換されたページ (->オリジナル) /