* feat(plan-phase): chunked mode + filesystem fallback for Windows stdio hang (#2310) Addresses the 2026-04-16 Windows incident where gsd-planner wrote all 5 PLAN.md files to disk but Task() never returned, hanging the orchestrator for 30+ minutes. Two mitigations: 1. Filesystem fallback (steps 9a, 11a): when Task() returns with an empty/truncated response but PLAN.md files exist on disk, surface a recoverable prompt (Accept plans / Retry planner / Stop) instead of silently failing. Directly addresses the post-restart recovery path. 2. Chunked mode (--chunked flag / workflow.plan_chunked config): splits the single long-lived planner Task into a short outline Task (~2 min) followed by N short per-plan Tasks (~3-5 min each). Each plan is committed individually for crash resilience. A hang loses one plan, not all of them. Resume detection skips plans already on disk on re-run. RCA confirmed: task state mtime 14:29 vs PLAN.md writes 14:32-14:52 = subagent completed normally, IPC return was dropped by Windows stdio deadlock. Neither mitigation fixes the root cause (requires upstream Task() timeout support); both bound damage and enable recovery. New reference file planner-chunked.md keeps OUTLINE COMPLETE / PLAN COMPLETE return formats out of gsd-planner.md (which sits at 46K near its size limit). Closes #2310 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(plan-phase): address CodeRabbit review comments on #2499 - docs/CONFIGURATION.md: add workflow.plan_chunked to full JSON schema example - plan-phase.md step 8.5.1: validate PLAN-OUTLINE.md with grep for OUTLINE COMPLETE marker before reusing (not just file existence) - plan-phase.md step 8.5.2: validate per-plan PLAN.md has YAML frontmatter (head -1 grep for ---) before skipping in resume path - plan-phase.md: add language tags (text/javascript/bash) to bare fenced code blocks in steps 8.5, 9a, 11a (markdownlint MD040) - Rejected: commit_docs gate on per-plan commits (gsd-sdk query commit already respects commit_docs internally — comment was a false positive) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(plan-phase): route Accept-plans through step 9 PLANNING COMPLETE handling Honors --skip-verify / plan_checker_enabled=false in 9a fallback path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1.5 KiB
Chunked Mode Return Formats
Used when plan-phase spawns gsd-planner with CHUNKED_MODE=true (triggered by --chunked
flag or workflow.plan_chunked: true config). Splits the single long-lived planner Task into
shorter-lived Tasks to bound the blast radius of Windows stdio hangs.
Modes
outline-only
Write only {PHASE_DIR}/{PADDED_PHASE}-PLAN-OUTLINE.md. Do not write any PLAN.md files.
Return:
## OUTLINE COMPLETE
**Phase:** {phase-name}
**Plans:** {N} plan(s) in {M} wave(s)
| Plan ID | Objective | Wave | Depends On | Requirements |
|---------|-----------|------|-----------|-------------|
| {padded_phase}-01 | [brief objective] | 1 | none | REQ-001, REQ-002 |
| {padded_phase}-02 | [brief objective] | 1 | none | REQ-003 |
The orchestrator reads this table, then spawns one single-plan Task per row.
single-plan
Write exactly one {PHASE_DIR}/{plan_id}-PLAN.md. Do not write any other plan files.
Return:
## PLAN COMPLETE
**Plan:** {plan-id}
**Objective:** {brief}
**File:** {PHASE_DIR}/{plan-id}-PLAN.md
**Tasks:** {N}
The orchestrator verifies the file exists on disk after each return, commits it, then moves to the next plan entry from the outline.
Resume Behaviour
If the orchestrator detects that PLAN-OUTLINE.md already exists (from a prior interrupted
run), it skips the outline-only Task and goes directly to single-plan Tasks, skipping any
{plan_id}-PLAN.md files that already exist on disk.