1	<purpose>
2	Execute small, ad-hoc tasks with GSD guarantees (atomic commits, STATE.md tracking). Quick mode spawns gsd-planner (quick mode) + gsd-executor(s), tracks tasks in `.planning/quick/`, and updates STATE.md's "Quick Tasks Completed" table.
3
4	With `--full` flag: enables the complete quality pipeline — discussion + research + plan-checking + verification. One flag for everything.
5
6	With `--validate` flag: enables plan-checking (max 2 iterations) and post-execution verification only. Use when you want quality guarantees without discussion or research.
7
8	With `--discuss` flag: lightweight discussion phase before planning. Surfaces assumptions, clarifies gray areas, captures decisions in CONTEXT.md so the planner treats them as locked.
9
10	With `--research` flag: spawns a focused research agent before planning. Investigates implementation approaches, library options, and pitfalls. Use when you're unsure how to approach a task.
11
12	Granular flags are composable: `--discuss --research --validate` gives the same result as `--full`.
13	</purpose>
14
15	<required_reading>
16	Read all files referenced by the invoking prompt's execution_context before starting.
17	</required_reading>
18
19	<available_agent_types>
20	Valid GSD subagent types (use exact names — do not fall back to 'general-purpose'):
21	- gsd-phase-researcher — Researches technical approaches for a phase
22	- gsd-planner — Creates detailed plans from phase scope
23	- gsd-plan-checker — Reviews plan quality before execution
24	- gsd-executor — Executes plan tasks, commits, creates SUMMARY.md
25	- gsd-verifier — Verifies phase completion, checks quality gates
26	- gsd-code-reviewer — Reviews source files for bugs, security issues, and code quality
27	</available_agent_types>
28
29	<process>
30	**Step 1: Parse arguments and get task description**
31
32	Parse `$ARGUMENTS` for:
33	- `--full` flag → store `$FULL_MODE=true`, `$DISCUSS_MODE=true`, `$RESEARCH_MODE=true`, `$VALIDATE_MODE=true`
34	- `--validate` flag → store `$VALIDATE_MODE=true`
35	- `--discuss` flag → store `$DISCUSS_MODE=true`
36	- `--research` flag → store `$RESEARCH_MODE=true`
37	- Remaining text → use as `$DESCRIPTION` if non-empty
38
39	After parsing, normalize: if `$DISCUSS_MODE` and `$RESEARCH_MODE` and `$VALIDATE_MODE` are all true, set `$FULL_MODE=true`. This ensures `--discuss --research --validate` is treated identically to `--full`.
40
41	If `$DESCRIPTION` is empty after parsing, prompt user interactively:
42
43
44	**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
45
46	```
47	AskUserQuestion(
48	  header: "Quick Task",
49	  question: "What do you want to do?",
50	  followUp: null
51	)
52	```
53
54	Store response as `$DESCRIPTION`.
55
56	If still empty, re-prompt: "Please provide a task description."
57
58	Display banner based on active flags:
59
60	If `$FULL_MODE` (all phases enabled — `--full` or all granular flags):
61	```
62	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
63	 GSD ► QUICK TASK (FULL)
64	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
65
66	◆ Discussion + research + plan checking + verification enabled
67	```
68
69	If `$DISCUSS_MODE` and `$VALIDATE_MODE` (no research):
70	```
71	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
72	 GSD ► QUICK TASK (DISCUSS + VALIDATE)
73	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
74
75	◆ Discussion + plan checking + verification enabled
76	```
77
78	If `$DISCUSS_MODE` and `$RESEARCH_MODE` (no validate):
79	```
80	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
81	 GSD ► QUICK TASK (DISCUSS + RESEARCH)
82	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
83
84	◆ Discussion + research enabled
85	```
86
87	If `$RESEARCH_MODE` and `$VALIDATE_MODE` (no discuss):
88	```
89	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
90	 GSD ► QUICK TASK (RESEARCH + VALIDATE)
91	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
92
93	◆ Research + plan checking + verification enabled
94	```
95
96	If `$DISCUSS_MODE` only:
97	```
98	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
99	 GSD ► QUICK TASK (DISCUSS)
100	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
101
102	◆ Discussion phase enabled — surfacing gray areas before planning
103	```
104
105	If `$RESEARCH_MODE` only:
106	```
107	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
108	 GSD ► QUICK TASK (RESEARCH)
109	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
110
111	◆ Research phase enabled — investigating approaches before planning
112	```
113
114	If `$VALIDATE_MODE` only:
115	```
116	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
117	 GSD ► QUICK TASK (VALIDATE)
118	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
119
120	◆ Plan checking + verification enabled
121	```
122
123	---
124
125	**Step 2: Initialize**
126
127	```bash
128	if ! command -v gsd-sdk &>/dev/null; then
129	  echo "⚠ gsd-sdk not found in PATH — /gsd:quick requires it."
130	  echo ""
131	  echo "Install the query-capable GSD SDK CLI:"
132	  echo "  npm install -g get-shit-done-cc"
133	  echo ""
134	  echo "Or update GSD to get the latest packages:"
135	  echo "  /gsd:update"
136	  exit 1
137	fi
138	```
139
140	```bash
141	INIT=$(gsd-sdk query init.quick "$DESCRIPTION")
142	if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
143	AGENT_SKILLS_PLANNER=$(gsd-sdk query agent-skills gsd-planner)
144	AGENT_SKILLS_EXECUTOR=$(gsd-sdk query agent-skills gsd-executor)
145	AGENT_SKILLS_CHECKER=$(gsd-sdk query agent-skills gsd-plan-checker)
146	AGENT_SKILLS_VERIFIER=$(gsd-sdk query agent-skills gsd-verifier)
147	```
148
149	Parse JSON for: `planner_model`, `executor_model`, `checker_model`, `verifier_model`, `commit_docs`, `branch_name`, `quick_id`, `slug`, `date`, `timestamp`, `quick_dir`, `task_dir`, `roadmap_exists`, `planning_exists`.
150
151	```bash
152	USE_WORKTREES=$(gsd-sdk query config-get workflow.use_worktrees 2>/dev/null || echo "true")
153	```
154
155	If the project uses git submodules, worktree isolation is unsafe **only when the quick task touches a submodule path**. The previous behavior unconditionally disabled worktree isolation whenever `.gitmodules` existed, which penalised every quick task in a submodule project even when the task was nowhere near a submodule. Parse submodule paths from `.gitmodules` so the executor can act on actual submodule paths rather than the mere file's existence:
156
157	```bash
158	# Parse submodule paths from .gitmodules once (empty if no .gitmodules).
159	# SUBMODULE_PATHS is a newline-separated list of repo-relative paths used as
160	# a fail-loud commit-time guard inside the quick-task executor — if the
161	# executor stages any path that falls inside SUBMODULE_PATHS, it must abort
162	# the commit and surface the conflict rather than silently corrupting the
163	# submodule state.
164	if [ -f .gitmodules ]; then
165	  SUBMODULE_PATHS=$(git config --file .gitmodules --get-regexp '^submodule\..*\.path$' 2>/dev/null | awk '{print $2}')
166	else
167	  SUBMODULE_PATHS=""
168	fi
169	```
170
171	Quick mode does not have a pre-declared `files_modified` list (the task is freeform), so use a fail-loud guard at commit time: when the executor stages files for the quick-task commit, if any staged path falls inside a `SUBMODULE_PATHS` entry, abort with a clear error explaining that worktree-isolated commits cannot safely span submodule boundaries — the user can re-run with `workflow.use_worktrees=false` to fall back to sequential execution on the main tree. If `SUBMODULE_PATHS` is empty (no `.gitmodules` in the repo), worktree isolation proceeds normally.
172
173	**If `roadmap_exists` is false:** Error — Quick mode requires an active project with ROADMAP.md. Run `/gsd:new-project` first.
174
175	Quick tasks can run mid-phase - validation only checks ROADMAP.md exists, not phase status.
176
177	---
178
179	**Step 2.5: Handle quick-task branching**
180
181	**If `branch_name` is empty/null:** Skip and continue on the current branch.
182
183	**If `branch_name` is set:** Check out the quick-task branch before any planning commits.
184
185	The new branch must fork off the project's default branch (`origin/HEAD`), not
186	off whatever HEAD happens to be checked out — otherwise consecutive quick tasks
187	compound on top of each other and stay unpushed (#2916). If `$branch_name`
188	already exists locally, reuse it as-is so resumed work is not rebased.
189
190	```bash
191	DEFAULT_BRANCH=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')
192	DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}
193
194	if git show-ref --verify --quiet "refs/heads/$branch_name"; then
195	  git switch "$branch_name" \
196	    || { echo "ERROR: Could not switch to existing quick-task branch '$branch_name'." >&2; exit 1; }
197	else
198	  # Fetch the default branch so origin/$DEFAULT_BRANCH is current. If the fetch
199	  # fails (offline, no remote, auth failure) AND we have no local copy of
200	  # origin/$DEFAULT_BRANCH to fall back on, abort — creating the branch off
201	  # arbitrary HEAD is exactly the bug #2916 fixed.
202	  if ! git fetch --quiet origin "$DEFAULT_BRANCH"; then
203	    if ! git show-ref --verify --quiet "refs/remotes/origin/$DEFAULT_BRANCH"; then
204	      echo "ERROR: Could not fetch origin/$DEFAULT_BRANCH and no local copy exists. Refusing to create '$branch_name' off the current HEAD (#2916). Resolve the remote/network issue and retry." >&2
205	      exit 1
206	    fi
207	    echo "WARNING: git fetch origin $DEFAULT_BRANCH failed; using the local copy of origin/$DEFAULT_BRANCH as base." >&2
208	  fi
209
210	  if [ -n "$(git status --porcelain)" ]; then
211	    echo "WARNING: Uncommitted changes present. Carrying them onto the new quick-task branch — they will be branched off origin/$DEFAULT_BRANCH (not the previous-task HEAD)."
212	  else
213	    # Best-effort: fast-forward the local default branch so subsequent local
214	    # work sees the latest tip. Failure here is non-fatal because we always
215	    # create the new branch directly from origin/$DEFAULT_BRANCH below.
216	    git switch --quiet "$DEFAULT_BRANCH" 2>/dev/null \
217	      && git merge --ff-only --quiet "origin/$DEFAULT_BRANCH" 2>/dev/null \
218	      || true
219	  fi
220
221	  # Pin the new branch to origin/$DEFAULT_BRANCH so the start point is
222	  # deterministic regardless of which branch we are currently on (#2916).
223	  # On success HEAD is exactly at origin/$DEFAULT_BRANCH, so a post-creation
224	  # merge-base / "ahead-of" guard would be unreachable — the explicit base
225	  # argument here is the single source of correctness for #2916.
226	  git checkout -b "$branch_name" "origin/$DEFAULT_BRANCH" \
227	    || { echo "ERROR: Could not create '$branch_name' from origin/$DEFAULT_BRANCH (#2916)." >&2; exit 1; }
228	fi
229	```
230
231	All quick-task commits for this run stay on that branch. User handles merge/rebase afterward.
232
233	---
234
235	**Step 3: Create task directory**
236
237	```bash
238	mkdir -p "${task_dir}"
239	```
240
241	---
242
243	**Step 4: Create quick task directory**
244
245	Create the directory for this quick task:
246
247	```bash
248	QUICK_DIR=".planning/quick/${quick_id}-${slug}"
249	mkdir -p "$QUICK_DIR"
250	```
251
252	Report to user:
253	```
254	Creating quick task ${quick_id}: ${DESCRIPTION}
255	Directory: ${QUICK_DIR}
256	```
257
258	Store `$QUICK_DIR` for use in orchestration.
259
260	---
261
262	**Step 4.5: Discussion phase (only when `$DISCUSS_MODE`)**
263
264	Skip this step entirely if NOT `$DISCUSS_MODE`.
265
266	Display banner:
267	```
268	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
269	 GSD ► DISCUSSING QUICK TASK
270	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
271
272	◆ Surfacing gray areas for: ${DESCRIPTION}
273	```
274
275	**4.5a. Identify gray areas**
276
277	Analyze `$DESCRIPTION` to identify 2-4 gray areas — implementation decisions that would change the outcome and that the user should weigh in on.
278
279	Use the domain-aware heuristic to generate phase-specific (not generic) gray areas:
280	- Something users **SEE** → layout, density, interactions, states
281	- Something users **CALL** → responses, errors, auth, versioning
282	- Something users **RUN** → output format, flags, modes, error handling
283	- Something users **READ** → structure, tone, depth, flow
284	- Something being **ORGANIZED** → criteria, grouping, naming, exceptions
285
286	Each gray area should be a concrete decision point, not a vague category. Example: "Loading behavior" not "UX".
287
288	**4.5b. Present gray areas**
289
290	```
291	AskUserQuestion(
292	  header: "Gray Areas",
293	  question: "Which areas need clarification before planning?",
294	  options: [
295	    { label: "${area_1}", description: "${why_it_matters_1}" },
296	    { label: "${area_2}", description: "${why_it_matters_2}" },
297	    { label: "${area_3}", description: "${why_it_matters_3}" },
298	    { label: "All clear", description: "Skip discussion — I know what I want" }
299	  ],
300	  multiSelect: true
301	)
302	```
303
304	If user selects "All clear" → skip to Step 5 (no CONTEXT.md written).
305
306	**4.5c. Discuss selected areas**
307
308	For each selected area, ask 1-2 focused questions via AskUserQuestion:
309
310	```
311	AskUserQuestion(
312	  header: "${area_name}",
313	  question: "${specific_question_about_this_area}",
314	  options: [
315	    { label: "${concrete_choice_1}", description: "${what_this_means}" },
316	    { label: "${concrete_choice_2}", description: "${what_this_means}" },
317	    { label: "${concrete_choice_3}", description: "${what_this_means}" },
318	    { label: "You decide", description: "Claude's discretion" }
319	  ],
320	  multiSelect: false
321	)
322	```
323
324	Rules:
325	- Options must be concrete choices, not abstract categories
326	- Highlight recommended choice where you have a clear opinion
327	- If user selects "Other" with freeform text, switch to plain text follow-up (per questioning.md freeform rule)
328	- If user selects "You decide", capture as Claude's Discretion in CONTEXT.md
329	- Max 2 questions per area — this is lightweight, not a deep dive
330
331	Collect all decisions into `$DECISIONS`.
332
333	**4.5d. Write CONTEXT.md**
334
335	Write `${QUICK_DIR}/${quick_id}-CONTEXT.md` using the standard context template structure:
336
337	```markdown
338	# Quick Task ${quick_id}: ${DESCRIPTION} - Context
339
340	**Gathered:** ${date}
341	**Status:** Ready for planning
342
343	<domain>
344	## Task Boundary
345
346	${DESCRIPTION}
347
348	</domain>
349
350	<decisions>
351	## Implementation Decisions
352
353	### ${area_1_name}
354	- ${decision_from_discussion}
355
356	### ${area_2_name}
357	- ${decision_from_discussion}
358
359	### Claude's Discretion
360	${areas_where_user_said_you_decide_or_areas_not_discussed}
361
362	</decisions>
363
364	<specifics>
365	## Specific Ideas
366
367	${any_specific_references_or_examples_from_discussion}
368
369	[If none: "No specific requirements — open to standard approaches"]
370
371	</specifics>
372
373	<canonical_refs>
374	## Canonical References
375
376	${any_specs_adrs_or_docs_referenced_during_discussion}
377
378	[If none: "No external specs — requirements fully captured in decisions above"]
379
380	</canonical_refs>
381	```
382
383	Note: Quick task CONTEXT.md omits `<code_context>` and `<deferred>` sections (no codebase scouting, no phase scope to defer to). Keep it lean. The `<canonical_refs>` section is included when external docs were referenced — omit it only if no external docs apply.
384
385	Report: `Context captured: ${QUICK_DIR}/${quick_id}-CONTEXT.md`
386
387	---
388
389	**Step 4.75: Research phase (only when `$RESEARCH_MODE`)**
390
391	Skip this step entirely if NOT `$RESEARCH_MODE`.
392
393	Display banner:
394	```
395	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
396	 GSD ► RESEARCHING QUICK TASK
397	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
398
399	◆ Investigating approaches for: ${DESCRIPTION}
400	```
401
402	Spawn a single focused researcher (not 4 parallel researchers like full phases — quick tasks need targeted research, not broad domain surveys):
403
404	```
405	Agent(
406	  prompt="
407	<research_context>
408
409	**Mode:** quick-task
410	**Task:** ${DESCRIPTION}
411	**Output:** ${QUICK_DIR}/${quick_id}-RESEARCH.md
412
413	<files_to_read>
414	- .planning/STATE.md (Project state — what's already built)
415	- .planning/PROJECT.md (Project context)
416	- ./CLAUDE.md (if exists — project-specific guidelines)
417	${DISCUSS_MODE ? '- ' + QUICK_DIR + '/' + quick_id + '-CONTEXT.md (User decisions — research should align with these)' : ''}
418	</files_to_read>
419
420	${AGENT_SKILLS_PLANNER}
421
422	</research_context>
423
424	<focus>
425	This is a quick task, not a full phase. Research should be concise and targeted:
426	1. Best libraries/patterns for this specific task
427	2. Common pitfalls and how to avoid them
428	3. Integration points with existing codebase
429	4. Any constraints or gotchas worth knowing before planning
430
431	Do NOT produce a full domain survey. Target 1-2 pages of actionable findings.
432	</focus>
433
434	<output>
435	Write research to: ${QUICK_DIR}/${quick_id}-RESEARCH.md
436	Use standard research format but keep it lean — skip sections that don't apply.
437	Return: ## RESEARCH COMPLETE with file path
438	</output>
439	",
440	  subagent_type="gsd-phase-researcher",
441	  model="{planner_model}",
442	  description="Research: ${DESCRIPTION}"
443	)
444	```
445
446	> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
447
448	After researcher returns:
449	1. Verify research exists at `${QUICK_DIR}/${quick_id}-RESEARCH.md`
450	2. Report: "Research complete: ${QUICK_DIR}/${quick_id}-RESEARCH.md"
451
452	If research file not found, warn but continue: "Research agent did not produce output — proceeding to planning without research."
453
454	---
455
456	**Step 5: Spawn planner (quick mode)**
457
458	**If `$VALIDATE_MODE`:** Use `quick-full` mode with stricter constraints.
459
460	**If NOT `$VALIDATE_MODE`:** Use standard `quick` mode.
461
462	```
463	Agent(
464	  prompt="
465	<planning_context>
466
467	**Mode:** ${VALIDATE_MODE ? 'quick-full' : 'quick'}
468	**Directory:** ${QUICK_DIR}
469	**Description:** ${DESCRIPTION}
470
471	<files_to_read>
472	- .planning/STATE.md (Project State)
473	- ./CLAUDE.md (if exists — follow project-specific guidelines)
474	${DISCUSS_MODE ? '- ' + QUICK_DIR + '/' + quick_id + '-CONTEXT.md (User decisions — locked, do not revisit)' : ''}
475	${RESEARCH_MODE ? '- ' + QUICK_DIR + '/' + quick_id + '-RESEARCH.md (Research findings — use to inform implementation choices)' : ''}
476	</files_to_read>
477
478	${AGENT_SKILLS_PLANNER}
479
480	**Project skills:** Check .claude/skills/ or .agents/skills/ directory (if either exists) — read SKILL.md files, plans should account for project skill rules
481
482	</planning_context>
483
484	<constraints>
485	- Create a SINGLE plan with 1-3 focused tasks
486	- Quick tasks should be atomic and self-contained
487	${RESEARCH_MODE ? '- Research findings are available — use them to inform library/pattern choices' : '- No research phase'}
488	${VALIDATE_MODE ? '- Target ~40% context usage (structured for verification)' : '- Target ~30% context usage (simple, focused)'}
489	${VALIDATE_MODE ? '- MUST generate `must_haves` in plan frontmatter (truths, artifacts, key_links)' : ''}
490	${VALIDATE_MODE ? '- Each task MUST have `files`, `action`, `verify`, `done` fields' : ''}
491	</constraints>
492
493	<output>
494	Write plan to: ${QUICK_DIR}/${quick_id}-PLAN.md
495	Return: ## PLANNING COMPLETE with plan path
496	</output>
497	",
498	  subagent_type="gsd-planner",
499	  model="{planner_model}",
500	  description="Quick plan: ${DESCRIPTION}"
501	)
502	```
503
504	> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
505
506	After planner returns:
507	1. Verify plan exists at `${QUICK_DIR}/${quick_id}-PLAN.md`
508	2. Extract plan count (typically 1 for quick tasks)
509	3. Report: "Plan created: ${QUICK_DIR}/${quick_id}-PLAN.md"
510
511	If plan not found, error: "Planner failed to create ${quick_id}-PLAN.md"
512
513	---
514
515	**Step 5.5: Plan-checker loop (only when `$VALIDATE_MODE`)**
516
517	Skip this step entirely if NOT `$VALIDATE_MODE`.
518
519	Display banner:
520	```
521	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
522	 GSD ► CHECKING PLAN
523	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
524
525	◆ Spawning plan checker...
526	```
527
528	Checker prompt:
529
530	```markdown
531	<verification_context>
532	**Mode:** quick-full
533	**Task Description:** ${DESCRIPTION}
534
535	<files_to_read>
536	- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan to verify)
537	</files_to_read>
538
539	${AGENT_SKILLS_CHECKER}
540
541	**Scope:** This is a quick task, not a full phase. Skip checks that require a ROADMAP phase goal.
542	</verification_context>
543
544	<check_dimensions>
545	- Requirement coverage: Does the plan address the task description?
546	- Task completeness: Do tasks have files, action, verify, done fields?
547	- Key links: Are referenced files real?
548	- Scope sanity: Is this appropriately sized for a quick task (1-3 tasks)?
549	- must_haves derivation: Are must_haves traceable to the task description?
550
551	Skip: cross-plan deps (single plan), ROADMAP alignment
552	${DISCUSS_MODE ? '- Context compliance: Does the plan honor locked decisions from CONTEXT.md?' : '- Skip: context compliance (no CONTEXT.md)'}
553	</check_dimensions>
554
555	<expected_output>
556	- ## VERIFICATION PASSED — all checks pass
557	- ## ISSUES FOUND — structured issue list
558	</expected_output>
559	```
560
561	```
562	Agent(
563	  prompt=checker_prompt,
564	  subagent_type="gsd-plan-checker",
565	  model="{checker_model}",
566	  description="Check quick plan: ${DESCRIPTION}"
567	)
568	```
569
570	> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
571
572	**Handle checker return:**
573
574	- **`## VERIFICATION PASSED`:** Display confirmation, proceed to step 6.
575	- **`## ISSUES FOUND`:** Display issues, check iteration count, enter revision loop.
576
577	**Revision loop (max 2 iterations):**
578
579	Track `iteration_count` (starts at 1 after initial plan + check).
580
581	**If iteration_count < 2:**
582
583	Display: `Sending back to planner for revision... (iteration ${N}/2)`
584
585	Revision prompt:
586
587	```markdown
588	<revision_context>
589	**Mode:** quick-full (revision)
590
591	<files_to_read>
592	- ${QUICK_DIR}/${quick_id}-PLAN.md (Existing plan)
593	</files_to_read>
594
595	${AGENT_SKILLS_PLANNER}
596
597	**Checker issues:** ${structured_issues_from_checker}
598
599	</revision_context>
600
601	<instructions>
602	Make targeted updates to address checker issues.
603	Do NOT replan from scratch unless issues are fundamental.
604	Return what changed.
605	</instructions>
606	```
607
608	```
609	Agent(
610	  prompt=revision_prompt,
611	  subagent_type="gsd-planner",
612	  model="{planner_model}",
613	  description="Revise quick plan: ${DESCRIPTION}"
614	)
615	```
616
617	> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
618
619	After planner returns → spawn checker again, increment iteration_count.
620
621	**If iteration_count >= 2:**
622
623	Display: `Max iterations reached. ${N} issues remain:` + issue list
624
625	Offer: 1) Force proceed, 2) Abort
626
627	---
628
629	**Step 5.6: Pre-dispatch plan commit (worktree mode only)**
630
631	When `USE_WORKTREES !== "false"`, commit PLAN.md to the current branch **before** spawning the executor. This ensures the worktree inherits PLAN.md at its branch HEAD so the executor can read it via a worktree-rooted path — avoiding the main-repo path priming that triggers CC #36182 path-resolution drift.
632
633	Skip this step entirely if `USE_WORKTREES === "false"` (non-worktree mode: PLAN.md is committed in Step 8 as usual).
634
635	```bash
636	if [ "${USE_WORKTREES}" != "false" ]; then
637	  COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
638	  if [ "$COMMIT_DOCS" != "false" ]; then
639	    git add "${QUICK_DIR}/${quick_id}-PLAN.md"
640	    # No-op skip if nothing actually staged (idempotent re-runs).
641	    if git diff --cached --quiet -- "${QUICK_DIR}/${quick_id}-PLAN.md"; then
642	      echo "ℹ Pre-dispatch PLAN.md commit skipped (no staged changes)"
643	    else
644	      # Run hooks normally (#2924). If a project opts out via
645	      # workflow.worktree_skip_hooks=true, honor that opt-in only.
646	      SKIP_HOOKS=$(gsd-sdk query config-get workflow.worktree_skip_hooks 2>/dev/null || echo "false")
647	      if [ "$SKIP_HOOKS" = "true" ]; then
648	        git commit --no-verify -m "docs(${quick_id}): pre-dispatch plan for ${DESCRIPTION}" -- "${QUICK_DIR}/${quick_id}-PLAN.md" \
649	          || { echo "ERROR: pre-dispatch PLAN.md commit failed (--no-verify path). Aborting before executor dispatch." >&2; exit 1; }
650	      else
651	        git commit -m "docs(${quick_id}): pre-dispatch plan for ${DESCRIPTION}" -- "${QUICK_DIR}/${quick_id}-PLAN.md" \
652	          || { echo "ERROR: pre-dispatch PLAN.md commit failed — likely a pre-commit hook failure. Fix the hook output above (or set workflow.worktree_skip_hooks=true to bypass) and re-run." >&2; exit 1; }
653	      fi
654	    fi
655	  fi
656	fi
657	```
658
659	---
660
661	**Step 6: Spawn executor**
662
663	Capture current HEAD before spawning (used for worktree branch check):
664	```bash
665	EXPECTED_BASE=$(git rev-parse HEAD)
666	if [ "${USE_WORKTREES:-true}" != "false" ]; then
667	  QUICK_WORKTREE_MANIFEST=$(mktemp "${TMPDIR:-/tmp}/gsd-quick-worktree-XXXXXX.json")
668	  printf '{"worktrees":[]}\n' > "$QUICK_WORKTREE_MANIFEST"
669	  export QUICK_WORKTREE_MANIFEST
670	fi
671	```
672
673	Spawn gsd-executor with plan reference:
674
675	```
676	Agent(
677	  prompt="
678	Execute quick task ${quick_id}.
679
680	${USE_WORKTREES !== "false" ? `
681	<worktree_branch_check>
682	FIRST ACTION before any other work: verify this worktree's HEAD is bound to a per-agent
683	branch and that the branch is based on the correct commit.
684
685	Step 1 — HEAD attachment assertion (MANDATORY, runs before any reset/commit):
686	  HEAD_REF=$(git symbolic-ref --quiet HEAD || echo "DETACHED")
687	  ACTUAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
688	  if [ "$HEAD_REF" = "DETACHED" ] || echo "$ACTUAL_BRANCH" | grep -Eq '^(main|master|develop|trunk|release/.*)$'; then
689	    echo "FATAL: worktree HEAD is on '$ACTUAL_BRANCH' (expected per-agent branch like worktree-agent-*)." >&2
690	    echo "Refusing to commit/reset on a protected ref. DO NOT self-recover via 'git update-ref refs/heads/$ACTUAL_BRANCH' — that destroys concurrent work (#2924)." >&2
691	    echo "Aborting before any commits. Surface as a blocker for human review." >&2
692	    exit 1
693	  fi
694	  if ! echo "$ACTUAL_BRANCH" | grep -Eq '^worktree-agent-[A-Za-z0-9._/-]+$'; then
695	    echo "FATAL: worktree HEAD '$ACTUAL_BRANCH' is not in the worktree-agent-* namespace (Claude Code's per-agent worktree branch namespace)." >&2
696	    echo "Refusing to commit; surface as blocker (#2924)." >&2
697	    exit 1
698	  fi
699
700	Step 2 — Base correctness (only after Step 1 passes):
701	  Run: git merge-base HEAD ${EXPECTED_BASE}
702	  If the result differs from ${EXPECTED_BASE}, hard-reset to the correct base (safe — Step 1 confirmed HEAD is on a per-agent branch and the worktree is fresh):
703	    git reset --hard ${EXPECTED_BASE}
704	  Then verify: if [ "$(git rev-parse HEAD)" != "${EXPECTED_BASE}" ]; then echo "ERROR: Could not correct worktree base"; exit 1; fi
705
706	This corrects a known issue where EnterWorktree creates branches from main instead of the feature branch HEAD (#2015) and prevents the destructive HEAD-on-master self-recovery path (#2924).
707	</worktree_branch_check>
708	` : ''}
709
710	<files_to_read>
711	- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan)
712	- .planning/STATE.md (Project state)
713	- ./CLAUDE.md (Project instructions, if exists)
714	- .claude/skills/ or .agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation)
715	</files_to_read>
716
717	${AGENT_SKILLS_EXECUTOR}
718
719	<submodule_commit_guard>
720	SUBMODULE_PATHS for this project: ${SUBMODULE_PATHS}
721
722	If SUBMODULE_PATHS is non-empty, you MUST run this fail-loud guard immediately
723	before EVERY git commit you create during this quick task (after \`git add\`,
724	before \`git commit\`). Quick mode does not have a pre-declared files_modified
725	list, so the guard runs at commit time:
726
727	\`\`\`bash
728	SUBMODULE_PATHS=\"${SUBMODULE_PATHS}\"
729	if [ -n \"\$SUBMODULE_PATHS\" ]; then
730	  STAGED=\$(git diff --cached --name-only)
731	  for sm_raw in \$SUBMODULE_PATHS; do
732	    sm=\"\${sm_raw#./}\"
733	    sm=\"\${sm%/}\"
734	    [ -z \"\$sm\" ] && continue
735	    for f_raw in \$STAGED; do
736	      f=\"\${f_raw#./}\"
737	      f=\"\${f%/}\"
738	      case \"\$f\" in
739	        \"\$sm\"|\"\$sm\"/*)
740	          echo \"ABORT: staged path \$f_raw falls inside submodule \$sm — worktree-isolated commits cannot safely span submodule boundaries. Re-run with workflow.use_worktrees=false.\" >&2
741	          exit 1 ;;
742	      esac
743	    done
744	  done
745	fi
746	\`\`\`
747
748	If the guard aborts, do NOT attempt the commit, do NOT remove the staged files,
749	and do NOT continue subsequent tasks. Surface the abort message in your
750	SUMMARY.md and stop — the user must rerun with worktrees disabled.
751	</submodule_commit_guard>
752
753	<constraints>
754	- Execute all tasks in the plan
755	- Commit each task atomically (code changes only)
756	- Run the <submodule_commit_guard> bash block before every \`git commit\` if SUBMODULE_PATHS is non-empty
757	- Create summary at: ${QUICK_DIR}/${quick_id}-SUMMARY.md
758	- Do NOT commit docs artifacts (SUMMARY.md, STATE.md, PLAN.md) — the orchestrator handles the docs commit in Step 8
759	- Do NOT update ROADMAP.md (quick tasks are separate from planned phases)
760	</constraints>
761	",
762	  subagent_type="gsd-executor",
763	  model="{executor_model}",
764	  ${USE_WORKTREES !== "false" ? 'isolation="worktree",' : ''}
765	  description="Execute: ${DESCRIPTION}"
766	)
767	```
768
769	> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
770
771	If the executor ran with `isolation="worktree"`, append its returned `{agent_id, worktree_path, branch, expected_base}` metadata to `QUICK_WORKTREE_MANIFEST` before cleanup. If any field is unavailable, stop and ask for recovery; do not discover global worktrees.
772
773	After executor returns:
774	1. **Worktree cleanup:** If the executor ran with `isolation="worktree"`, merge the worktree branch back and clean up:
775	   ```bash
776	   QUICK_WORKTREE_MANIFEST=${QUICK_WORKTREE_MANIFEST:-$WAVE_WORKTREE_MANIFEST}
777	   [ -n "${QUICK_WORKTREE_MANIFEST:-}" ] && [ -f "$QUICK_WORKTREE_MANIFEST" ] || {
778	     echo "BLOCKED: missing QUICK_WORKTREE_MANIFEST; refusing broad worktree cleanup (#3384)." >&2
779	     exit 1
780	   }
781
782	   # Prefer the bounded cleanup helper. It verifies branch identity, expected
783	   # base, deletion diffs, merge result, and worktree removal before branch
784	   # deletion. If it blocks, resolve the reported manifest entry and rerun.
785	   if command -v gsd-sdk >/dev/null 2>&1; then
786	     gsd-sdk query worktree.cleanup-wave --manifest "$QUICK_WORKTREE_MANIFEST" || exit 1
787	   else
788	     echo "WARN: gsd-sdk unavailable; using manifest-scoped shell fallback (#3384)." >&2
789
790	   # Find worktrees recorded by the executor manifest only.
791	   # Inclusion-based filter (#2774): match ONLY agent-spawned worktrees under
792	   # `.claude/worktrees/agent-` (the namespace Claude Code's `isolation="worktree"`
793	   # uses). The previous exclusion filter (`grep -v "$(pwd)$"`) destroyed the parent
794	   # workspace's `.git` whenever the workspace itself was a worktree (multi-workspace
795	   # setups, and the cross-drive Windows case where `git worktree list` reports the
796	   # registry path on a different drive than `$(pwd)`).
797	   # Read line-by-line so worktree paths containing whitespace are preserved (#2774).
798	   WT_PATHS_FILE=$(mktemp "${TMPDIR:-/tmp}/gsd-worktree-paths-XXXXXX")
799	   node -e 'const fs=require("fs");const p=process.env.QUICK_WORKTREE_MANIFEST||process.env.WAVE_WORKTREE_MANIFEST;try{if(!p)throw new Error("QUICK_WORKTREE_MANIFEST is unset");if(!fs.existsSync(p))throw new Error("manifest does not exist");const s=fs.readFileSync(p,"utf8");if(!s.trim())throw new Error("manifest is empty");const j=JSON.parse(s);for(const w of j.worktrees||[])if(w.worktree_path)console.log(w.worktree_path)}catch(e){console.error(`ERROR: cannot read worktree manifest ${p||"(unset)"}: ${e.message}`);process.exit(1)}' > "$WT_PATHS_FILE" || { echo "BLOCKED: cannot read QUICK_WORKTREE_MANIFEST; refusing cleanup (#3384)." >&2; exit 1; }
800	   while IFS= read -r WT; do
801	     [ -z "$WT" ] && continue
802	     # Pin CWD to project root before any bare git command (#3521).
803	     # An LLM orchestrator may leak CWD into a worktree across tool calls; without
804	     # this pin the merge command resolves against the worktree branch itself and
805	     # silently no-ops the main-branch merge.
806	     PROJECT_ROOT=$(git -C "$WT" rev-parse --git-common-dir 2>/dev/null)
807	     # git rev-parse --git-common-dir returns the .git dir, not the working tree root.
808	     # Strip the trailing /.git (or bare .git) to get the working tree root.
809	     PROJECT_ROOT=$(echo "$PROJECT_ROOT" | sed 's|/\.git$||; s|/\.git/.*||')
810	     if [ -z "$PROJECT_ROOT" ] || [ ! -d "$PROJECT_ROOT" ]; then
811	       echo "WARN: cannot resolve project root from worktree $WT — skipping cleanup for this entry (#3521)" >&2
812	       continue
813	     fi
814	     cd "$PROJECT_ROOT" || { echo "WARN: cannot cd to project root $PROJECT_ROOT — skipping cleanup for worktree $WT (#3521)" >&2; continue; }
815	     WT_BRANCH=$(git -C "$WT" rev-parse --abbrev-ref HEAD 2>/dev/null)
816	     if [ -n "$WT_BRANCH" ] && [ "$WT_BRANCH" != "HEAD" ]; then
817	       # --- Orchestrator file protection (#1756) ---
818	       # Backup STATE.md and ROADMAP.md before merge (main always wins)
819	       STATE_BACKUP=$(mktemp)
820	       ROADMAP_BACKUP=$(mktemp)
821	       [ -f .planning/STATE.md ] && cp .planning/STATE.md "$STATE_BACKUP" || true
822	       [ -f .planning/ROADMAP.md ] && cp .planning/ROADMAP.md "$ROADMAP_BACKUP" || true
823
824	       # Pre-merge deletion guard: block merges that delete tracked .planning/ files
825	       DELETIONS=$(git diff --diff-filter=D --name-only HEAD..."$WT_BRANCH" 2>/dev/null || true)
826	       if [ -n "$DELETIONS" ]; then
827	         echo "BLOCKED: Worktree branch $WT_BRANCH contains file deletions: $DELETIONS"
828	         echo "Review these deletions before merging. If intentional, remove this guard and re-run."
829	         rm -f "$STATE_BACKUP" "$ROADMAP_BACKUP"
830	         continue
831	       fi
832
833	       git merge "$WT_BRANCH" --no-ff --no-edit -m "chore: merge quick task worktree ($WT_BRANCH)" 2>&1 || {
834	         echo "⚠ Merge conflict from worktree $WT_BRANCH — resolve manually"
835	         echo "  STATE.md backup:   $STATE_BACKUP"
836	         echo "  ROADMAP.md backup: $ROADMAP_BACKUP"
837	         echo "  Restore with: cp \$STATE_BACKUP .planning/STATE.md && cp \$ROADMAP_BACKUP .planning/ROADMAP.md"
838	         break
839	       }
840
841	       # Restore orchestrator-owned files
842	       if [ -s "$STATE_BACKUP" ]; then cp "$STATE_BACKUP" .planning/STATE.md; fi
843	       if [ -s "$ROADMAP_BACKUP" ]; then cp "$ROADMAP_BACKUP" .planning/ROADMAP.md; fi
844	       rm -f "$STATE_BACKUP" "$ROADMAP_BACKUP"
845
846	       # Detect files deleted on main but re-added by worktree merge
847	       # (e.g., archived phase directories that were intentionally removed)
848	       # A "resurrected" file must have a deletion event in main's ancestry —
849	       # brand-new files (e.g. SUMMARY.md just created by the agent) have no
850	       # such history and must NOT be removed (#2501, #3195).
851	       DELETED_FILES=$(git diff --diff-filter=A --name-only HEAD~1 -- .planning/ 2>/dev/null || true)
852	       for RESURRECTED in $DELETED_FILES; do
853	         # Only delete if this file was previously tracked on main and then
854	         # deliberately removed (has a deletion event in git history).
855	         WAS_DELETED=$(git log --follow --diff-filter=D --name-only --format="" HEAD~1 -- "$RESURRECTED" 2>/dev/null | grep -c . || true)
856	         if [ "${WAS_DELETED:-0}" -gt 0 ]; then
857	           git rm -f "$RESURRECTED" 2>/dev/null || true
858	         fi
859	       done
860
861	       if ! git diff --quiet .planning/STATE.md .planning/ROADMAP.md 2>/dev/null || \
862	          [ -n "$DELETED_FILES" ]; then
863	         COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
864	         if [ "$COMMIT_DOCS" != "false" ]; then
865	           git add .planning/STATE.md .planning/ROADMAP.md 2>/dev/null || true
866	           git commit --amend --no-edit 2>/dev/null || true
867	         fi
868	       fi
869
870	       # Safety net: rescue uncommitted SUMMARY.md before worktree removal (#2296, mirrors #2070, #2838).
871	       # Filesystem-level (find + cp) bypasses git's --exclude-standard filter, which silently
872	       # drops .planning/SUMMARY.md when projects gitignore .planning/ — the rescue's prior
873	       # `git ls-files --exclude-standard` form returned empty in that case and the SUMMARY
874	       # was lost on `git worktree remove --force`.
875	       while IFS= read -r SUMMARY; do
876	         [ -z "$SUMMARY" ] && continue
877	         REL_PATH="${SUMMARY#$WT/}"
878	         if [ ! -f "$REL_PATH" ] || ! cmp -s "$SUMMARY" "$REL_PATH"; then
879	           mkdir -p "$(dirname "$REL_PATH")"
880	           cp "$SUMMARY" "$REL_PATH"
881	           echo "⚠ Rescued $REL_PATH from worktree before removal"
882	         fi
883	       done < <(find "$WT/.planning" -name "*SUMMARY.md" 2>/dev/null)
884
885	       # Remove the worktree before deleting the branch. If removal fails,
886	       # leave the branch in place so the worktree remains recoverable (#3384).
887	       REMOVE_OK=false
888	       if git worktree remove "$WT" --force; then
889	         REMOVE_OK=true
890	       else
891	         WT_NAME=$(basename "$WT")
892	         if [ -f ".git/worktrees/${WT_NAME}/locked" ]; then
893	           echo "⚠ Worktree $WT is locked — attempting to unlock and retry"
894	           git worktree unlock "$WT" 2>/dev/null || true
895	           if git worktree remove "$WT" --force; then
896	             REMOVE_OK=true
897	           else
898	             echo "⚠ Residual worktree at $WT — manual cleanup required after session exits:"
899	             echo "    git worktree unlock \"$WT\" && git worktree remove \"$WT\" --force && git branch -D \"$WT_BRANCH\""
900	           fi
901	         else
902	           echo "⚠ Residual worktree at $WT (remove failed) — investigate manually"
903	         fi
904	       fi
905	       if [ "$REMOVE_OK" = "true" ]; then
906	         git branch -D "$WT_BRANCH" 2>/dev/null || true
907	       else
908	         echo "⚠ Keeping branch $WT_BRANCH because worktree removal failed (#3384)"
909	       fi
910	     fi
911	   done < "$WT_PATHS_FILE"
912	   fi
913	   ```
914	   If `workflow.use_worktrees` is `false`, skip this step.
915	2. Verify summary exists at `${QUICK_DIR}/${quick_id}-SUMMARY.md`
916	3. Extract commit hash from executor output
917	4. Report completion status
918
919	**Known Claude Code bug (classifyHandoffIfNeeded):** If executor reports "failed" with error `classifyHandoffIfNeeded is not defined`, this is a Claude Code runtime bug — not a real failure. Check if summary file exists and git log shows commits. If so, treat as successful.
920
921	If summary not found, error: "Executor failed to create ${quick_id}-SUMMARY.md"
922
923	Note: For quick tasks producing multiple plans (rare), spawn executors in parallel waves per execute-phase patterns.
924
925	---
926
927	**Step 6.25: Code review (auto)**
928
929	Skip this step entirely if `$FULL_MODE` is false.
930
931	**Config gate:**
932	```bash
933	CODE_REVIEW_ENABLED=$(gsd-sdk query config-get workflow.code_review 2>/dev/null || echo "true")
934	```
935	If `"false"`, skip with message "Code review skipped (workflow.code_review=false)".
936
937	**Scope files from executor's commits:**
938	```bash
939	# Find the diff base: last commit before quick task started
940	# Use git log to find commits referencing the quick task id, then take the parent of the oldest
941	QUICK_COMMITS=$(git log --oneline --format="%H" --grep="${quick_id}" 2>/dev/null)
942	if [ -n "$QUICK_COMMITS" ]; then
943	  DIFF_BASE=$(echo "$QUICK_COMMITS" | tail -1)^
944	  # Verify parent exists (guard against first commit in repo)
945	  git rev-parse "${DIFF_BASE}" >/dev/null 2>&1 || DIFF_BASE=$(echo "$QUICK_COMMITS" | tail -1)
946	else
947	  # No commits found for this quick task — skip review
948	  DIFF_BASE=""
949	fi
950
951	if [ -n "$DIFF_BASE" ]; then
952	  CHANGED_FILES=$(git diff --name-only "${DIFF_BASE}..HEAD" -- . ':!.planning' 2>/dev/null | tr '\n' ' ')
953	else
954	  CHANGED_FILES=""
955	fi
956	```
957
958	If `CHANGED_FILES` is empty, skip with "No source files changed — skipping code review."
959
960	**Invoke review:**
961	```
962	Agent(
963	  prompt="Review these files for bugs, security issues, and code quality.
964	  Files: ${CHANGED_FILES}
965	  Output: ${QUICK_DIR}/${quick_id}-REVIEW.md
966	  Depth: quick",
967	  subagent_type="gsd-code-reviewer",
968	  model="{executor_model}"
969	)
970	```
971
972	> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
973
974	If review produces findings, display advisory message. **Error handling:** Failures are non-blocking — catch and proceed.
975
976	---
977
978	**Step 6.5: Verification (only when `$VALIDATE_MODE`)**
979
980	Skip this step entirely if NOT `$VALIDATE_MODE`.
981
982	Display banner:
983	```
984	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
985	 GSD ► VERIFYING RESULTS
986	━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
987
988	◆ Spawning verifier...
989	```
990
991	```
992	Agent(
993	  prompt="Verify quick task goal achievement.
994	Task directory: ${QUICK_DIR}
995	Task goal: ${DESCRIPTION}
996
997	<files_to_read>
998	- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan)
999	</files_to_read>
1000
1001	${AGENT_SKILLS_VERIFIER}
1002
1003	Check must_haves against actual codebase. Create VERIFICATION.md at ${QUICK_DIR}/${quick_id}-VERIFICATION.md.",
1004	  subagent_type="gsd-verifier",
1005	  model="{verifier_model}",
1006	  description="Verify: ${DESCRIPTION}"
1007	)
1008	```
1009
1010	> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
1011
1012	Read verification status:
1013	```bash
1014	grep "^status:" "${QUICK_DIR}/${quick_id}-VERIFICATION.md" | cut -d: -f2 | tr -d ' '
1015	```
1016
1017	Store as `$VERIFICATION_STATUS`.
1018
1019	| Status | Action |
1020	|--------|--------|
1021	| `passed` | Store `$VERIFICATION_STATUS = "Verified"`, continue to step 7 |
1022	| `human_needed` | Display items needing manual check, store `$VERIFICATION_STATUS = "Needs Review"`, continue |
1023	| `gaps_found` | Display gap summary, offer: 1) Re-run executor to fix gaps, 2) Accept as-is. Store `$VERIFICATION_STATUS = "Gaps"` |
1024
1025	---
1026
1027	**Step 7: Update STATE.md**
1028
1029	Update STATE.md with quick task completion record.
1030
1031	**7a. Check if "Quick Tasks Completed" section exists:**
1032
1033	Read STATE.md and check for `### Quick Tasks Completed` section.
1034
1035	**7b. If section doesn't exist, create it:**
1036
1037	Insert after `### Blockers/Concerns` section:
1038
1039	**If `$VALIDATE_MODE`:**
1040	```markdown
1041	### Quick Tasks Completed
1042
1043	| # | Description | Date | Commit | Status | Directory |
1044	|---|-------------|------|--------|--------|-----------|
1045	```
1046
1047	**If NOT `$VALIDATE_MODE`:**
1048	```markdown
1049	### Quick Tasks Completed
1050
1051	| # | Description | Date | Commit | Directory |
1052	|---|-------------|------|--------|-----------|
1053	```
1054
1055	**Note:** If the table already exists, match its existing column format. If adding `--validate` (or `--full`) to a project that already has quick tasks without a Status column, add the Status column to the header and separator rows, and leave Status empty for the new row's predecessors.
1056
1057	**7c. Append new row to table:**
1058
1059	Use `date` from init:
1060
1061	**If `$VALIDATE_MODE` (or table has Status column):**
1062	```markdown
1063	| ${quick_id} | ${DESCRIPTION} | ${date} | ${commit_hash} | ${VERIFICATION_STATUS} | [${quick_id}-${slug}](./quick/${quick_id}-${slug}/) |
1064	```
1065
1066	**If NOT `$VALIDATE_MODE` (and table has no Status column):**
1067	```markdown
1068	| ${quick_id} | ${DESCRIPTION} | ${date} | ${commit_hash} | [${quick_id}-${slug}](./quick/${quick_id}-${slug}/) |
1069	```
1070
1071	**7d. Update "Last activity" line:**
1072
1073	Use `date` from init:
1074	```
1075	Last activity: ${date} - Completed quick task ${quick_id}: ${DESCRIPTION}
1076	```
1077
1078	Use Edit tool to make these changes atomically
1079
1080	---
1081
1082	**Step 8: Final commit and completion**
1083
1084	Stage and commit quick task artifacts. This step MUST always run — even if the executor already committed some files (e.g. when running without worktree isolation). The `gsd-sdk query commit` command (or legacy `gsd-tools.cjs` commit) handles already-committed files gracefully.
1085
1086	Build file list:
1087	- `${QUICK_DIR}/${quick_id}-PLAN.md`
1088	- `${QUICK_DIR}/${quick_id}-SUMMARY.md`
1089	- `.planning/STATE.md`
1090	- If `$DISCUSS_MODE` and context file exists: `${QUICK_DIR}/${quick_id}-CONTEXT.md`
1091	- If `$RESEARCH_MODE` and research file exists: `${QUICK_DIR}/${quick_id}-RESEARCH.md`
1092	- If `$VALIDATE_MODE` and verification file exists: `${QUICK_DIR}/${quick_id}-VERIFICATION.md`
1093	- If `${QUICK_DIR}/${quick_id}-deferred-items.md` exists: `${QUICK_DIR}/${quick_id}-deferred-items.md`
1094
1095	```bash
1096	# Explicitly stage all artifacts before commit — PLAN.md may be untracked
1097	# if the executor ran without worktree isolation and committed docs early
1098	# Filter .planning/ files from staging if commit_docs is disabled (#1783)
1099	COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
1100	if [ "$COMMIT_DOCS" = "false" ]; then
1101	  file_list_filtered=$(echo "${file_list}" | tr ' ' '\n' | grep -v '^\.planning/' | tr '\n' ' ')
1102	  git add ${file_list_filtered} 2>/dev/null
1103	else
1104	  git add ${file_list} 2>/dev/null
1105	fi
1106	gsd-sdk query commit "docs(quick-${quick_id}): ${DESCRIPTION}" --files ${file_list}
1107	```
1108
1109	Get final commit hash:
1110	```bash
1111	commit_hash=$(git rev-parse --short HEAD)
1112	```
1113
1114	Display completion output:
1115
1116	**If `$VALIDATE_MODE`:**
1117	```
1118	---
1119
1120	GSD > QUICK TASK COMPLETE (VALIDATED)
1121
1122	Quick Task ${quick_id}: ${DESCRIPTION}
1123
1124	${RESEARCH_MODE ? 'Research: ' + QUICK_DIR + '/' + quick_id + '-RESEARCH.md' : ''}
1125	Summary: ${QUICK_DIR}/${quick_id}-SUMMARY.md
1126	Verification: ${QUICK_DIR}/${quick_id}-VERIFICATION.md (${VERIFICATION_STATUS})
1127	Commit: ${commit_hash}
1128
1129	---
1130
1131	Ready for next task: /gsd:quick ${GSD_WS}
1132	```
1133
1134	**If NOT `$VALIDATE_MODE`:**
1135	```
1136	---
1137
1138	GSD > QUICK TASK COMPLETE
1139
1140	Quick Task ${quick_id}: ${DESCRIPTION}
1141
1142	${RESEARCH_MODE ? 'Research: ' + QUICK_DIR + '/' + quick_id + '-RESEARCH.md' : ''}
1143	Summary: ${QUICK_DIR}/${quick_id}-SUMMARY.md
1144	Commit: ${commit_hash}
1145
1146	---
1147
1148	Ready for next task: /gsd:quick ${GSD_WS}
1149	```
1150
1151	</process>
1152
1153	<success_criteria>
1154	- [ ] ROADMAP.md validation passes
1155	- [ ] User provides task description
1156	- [ ] `--full`, `--validate`, `--discuss`, and `--research` flags parsed from arguments when present
1157	- [ ] `--full` sets all booleans (`$FULL_MODE`, `$DISCUSS_MODE`, `$RESEARCH_MODE`, `$VALIDATE_MODE`)
1158	- [ ] Slug generated (lowercase, hyphens, max 40 chars)
1159	- [ ] Quick ID generated (YYMMDD-xxx format, 2s Base36 precision)
1160	- [ ] Directory created at `.planning/quick/YYMMDD-xxx-slug/`
1161	- [ ] (--discuss) Gray areas identified and presented, decisions captured in `${quick_id}-CONTEXT.md`
1162	- [ ] (--research) Research agent spawned, `${quick_id}-RESEARCH.md` created
1163	- [ ] `${quick_id}-PLAN.md` created by planner (honors CONTEXT.md decisions when --discuss, uses RESEARCH.md findings when --research)
1164	- [ ] (--validate) Plan checker validates plan, revision loop capped at 2
1165	- [ ] `${quick_id}-SUMMARY.md` created by executor
1166	- [ ] (--validate) `${quick_id}-VERIFICATION.md` created by verifier
1167	- [ ] STATE.md updated with quick task row (Status column when --validate)
1168	- [ ] Artifacts committed
1169	</success_criteria>
1170

<purpose>
Execute small, ad-hoc tasks with GSD guarantees (atomic commits, STATE.md tracking). Quick mode spawns gsd-planner (quick mode) + gsd-executor(s), tracks tasks in `.planning/quick/`, and updates STATE.md's "Quick Tasks Completed" table.

With `--full` flag: enables the complete quality pipeline — discussion + research + plan-checking + verification. One flag for everything.

With `--validate` flag: enables plan-checking (max 2 iterations) and post-execution verification only. Use when you want quality guarantees without discussion or research.

With `--discuss` flag: lightweight discussion phase before planning. Surfaces assumptions, clarifies gray areas, captures decisions in CONTEXT.md so the planner treats them as locked.

With `--research` flag: spawns a focused research agent before planning. Investigates implementation approaches, library options, and pitfalls. Use when you're unsure how to approach a task.

Granular flags are composable: `--discuss --research --validate` gives the same result as `--full`.
</purpose>

<required_reading>
Read all files referenced by the invoking prompt's execution_context before starting.
</required_reading>

<available_agent_types>
Valid GSD subagent types (use exact names — do not fall back to 'general-purpose'):
- gsd-phase-researcher — Researches technical approaches for a phase
- gsd-planner — Creates detailed plans from phase scope
- gsd-plan-checker — Reviews plan quality before execution
- gsd-executor — Executes plan tasks, commits, creates SUMMARY.md
- gsd-verifier — Verifies phase completion, checks quality gates
- gsd-code-reviewer — Reviews source files for bugs, security issues, and code quality
</available_agent_types>

<process>
**Step 1: Parse arguments and get task description**

Parse `$ARGUMENTS` for:
- `--full` flag → store `$FULL_MODE=true`, `$DISCUSS_MODE=true`, `$RESEARCH_MODE=true`, `$VALIDATE_MODE=true`
- `--validate` flag → store `$VALIDATE_MODE=true`
- `--discuss` flag → store `$DISCUSS_MODE=true`
- `--research` flag → store `$RESEARCH_MODE=true`
- Remaining text → use as `$DESCRIPTION` if non-empty

After parsing, normalize: if `$DISCUSS_MODE` and `$RESEARCH_MODE` and `$VALIDATE_MODE` are all true, set `$FULL_MODE=true`. This ensures `--discuss --research --validate` is treated identically to `--full`.

If `$DESCRIPTION` is empty after parsing, prompt user interactively:

**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.

```
AskUserQuestion(
  header: "Quick Task",
  question: "What do you want to do?",
  followUp: null
)
```

Store response as `$DESCRIPTION`.

If still empty, re-prompt: "Please provide a task description."

Display banner based on active flags:

If `$FULL_MODE` (all phases enabled — `--full` or all granular flags):
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (FULL)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Discussion + research + plan checking + verification enabled
```

If `$DISCUSS_MODE` and `$VALIDATE_MODE` (no research):
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (DISCUSS + VALIDATE)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Discussion + plan checking + verification enabled
```

If `$DISCUSS_MODE` and `$RESEARCH_MODE` (no validate):
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (DISCUSS + RESEARCH)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Discussion + research enabled
```

If `$RESEARCH_MODE` and `$VALIDATE_MODE` (no discuss):
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (RESEARCH + VALIDATE)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Research + plan checking + verification enabled
```

If `$DISCUSS_MODE` only:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (DISCUSS)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Discussion phase enabled — surfacing gray areas before planning
```

If `$RESEARCH_MODE` only:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (RESEARCH)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Research phase enabled — investigating approaches before planning
```

If `$VALIDATE_MODE` only:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (VALIDATE)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Plan checking + verification enabled
```

---

**Step 2: Initialize**

```bash
if ! command -v gsd-sdk &>/dev/null; then
  echo "⚠ gsd-sdk not found in PATH — /gsd:quick requires it."
  echo ""
  echo "Install the query-capable GSD SDK CLI:"
  echo "  npm install -g get-shit-done-cc"
  echo ""
  echo "Or update GSD to get the latest packages:"
  echo "  /gsd:update"
  exit 1
fi
```

```bash
INIT=$(gsd-sdk query init.quick "$DESCRIPTION")
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
AGENT_SKILLS_PLANNER=$(gsd-sdk query agent-skills gsd-planner)
AGENT_SKILLS_EXECUTOR=$(gsd-sdk query agent-skills gsd-executor)
AGENT_SKILLS_CHECKER=$(gsd-sdk query agent-skills gsd-plan-checker)
AGENT_SKILLS_VERIFIER=$(gsd-sdk query agent-skills gsd-verifier)
```

Parse JSON for: `planner_model`, `executor_model`, `checker_model`, `verifier_model`, `commit_docs`, `branch_name`, `quick_id`, `slug`, `date`, `timestamp`, `quick_dir`, `task_dir`, `roadmap_exists`, `planning_exists`.

```bash
USE_WORKTREES=$(gsd-sdk query config-get workflow.use_worktrees 2>/dev/null || echo "true")
```

If the project uses git submodules, worktree isolation is unsafe **only when the quick task touches a submodule path**. The previous behavior unconditionally disabled worktree isolation whenever `.gitmodules` existed, which penalised every quick task in a submodule project even when the task was nowhere near a submodule. Parse submodule paths from `.gitmodules` so the executor can act on actual submodule paths rather than the mere file's existence:

```bash
# Parse submodule paths from .gitmodules once (empty if no .gitmodules).
# SUBMODULE_PATHS is a newline-separated list of repo-relative paths used as
# a fail-loud commit-time guard inside the quick-task executor — if the
# executor stages any path that falls inside SUBMODULE_PATHS, it must abort
# the commit and surface the conflict rather than silently corrupting the
# submodule state.
if [ -f .gitmodules ]; then
  SUBMODULE_PATHS=$(git config --file .gitmodules --get-regexp '^submodule\..*\.path$' 2>/dev/null | awk '{print $2}')
else
  SUBMODULE_PATHS=""
fi
```

Quick mode does not have a pre-declared `files_modified` list (the task is freeform), so use a fail-loud guard at commit time: when the executor stages files for the quick-task commit, if any staged path falls inside a `SUBMODULE_PATHS` entry, abort with a clear error explaining that worktree-isolated commits cannot safely span submodule boundaries — the user can re-run with `workflow.use_worktrees=false` to fall back to sequential execution on the main tree. If `SUBMODULE_PATHS` is empty (no `.gitmodules` in the repo), worktree isolation proceeds normally.

**If `roadmap_exists` is false:** Error — Quick mode requires an active project with ROADMAP.md. Run `/gsd:new-project` first.

Quick tasks can run mid-phase - validation only checks ROADMAP.md exists, not phase status.

---

**Step 2.5: Handle quick-task branching**

**If `branch_name` is empty/null:** Skip and continue on the current branch.

**If `branch_name` is set:** Check out the quick-task branch before any planning commits.

The new branch must fork off the project's default branch (`origin/HEAD`), not
off whatever HEAD happens to be checked out — otherwise consecutive quick tasks
compound on top of each other and stay unpushed (#2916). If `$branch_name`
already exists locally, reuse it as-is so resumed work is not rebased.

```bash
DEFAULT_BRANCH=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')
DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}

if git show-ref --verify --quiet "refs/heads/$branch_name"; then
  git switch "$branch_name" \
    || { echo "ERROR: Could not switch to existing quick-task branch '$branch_name'." >&2; exit 1; }
else
  # Fetch the default branch so origin/$DEFAULT_BRANCH is current. If the fetch
  # fails (offline, no remote, auth failure) AND we have no local copy of
  # origin/$DEFAULT_BRANCH to fall back on, abort — creating the branch off
  # arbitrary HEAD is exactly the bug #2916 fixed.
  if ! git fetch --quiet origin "$DEFAULT_BRANCH"; then
    if ! git show-ref --verify --quiet "refs/remotes/origin/$DEFAULT_BRANCH"; then
      echo "ERROR: Could not fetch origin/$DEFAULT_BRANCH and no local copy exists. Refusing to create '$branch_name' off the current HEAD (#2916). Resolve the remote/network issue and retry." >&2
      exit 1
    fi
    echo "WARNING: git fetch origin $DEFAULT_BRANCH failed; using the local copy of origin/$DEFAULT_BRANCH as base." >&2
  fi

  if [ -n "$(git status --porcelain)" ]; then
    echo "WARNING: Uncommitted changes present. Carrying them onto the new quick-task branch — they will be branched off origin/$DEFAULT_BRANCH (not the previous-task HEAD)."
  else
    # Best-effort: fast-forward the local default branch so subsequent local
    # work sees the latest tip. Failure here is non-fatal because we always
    # create the new branch directly from origin/$DEFAULT_BRANCH below.
    git switch --quiet "$DEFAULT_BRANCH" 2>/dev/null \
      && git merge --ff-only --quiet "origin/$DEFAULT_BRANCH" 2>/dev/null \
      || true
  fi

  # Pin the new branch to origin/$DEFAULT_BRANCH so the start point is
  # deterministic regardless of which branch we are currently on (#2916).
  # On success HEAD is exactly at origin/$DEFAULT_BRANCH, so a post-creation
  # merge-base / "ahead-of" guard would be unreachable — the explicit base
  # argument here is the single source of correctness for #2916.
  git checkout -b "$branch_name" "origin/$DEFAULT_BRANCH" \
    || { echo "ERROR: Could not create '$branch_name' from origin/$DEFAULT_BRANCH (#2916)." >&2; exit 1; }
fi
```

All quick-task commits for this run stay on that branch. User handles merge/rebase afterward.

---

**Step 3: Create task directory**

```bash
mkdir -p "${task_dir}"
```

---

**Step 4: Create quick task directory**

Create the directory for this quick task:

```bash
QUICK_DIR=".planning/quick/${quick_id}-${slug}"
mkdir -p "$QUICK_DIR"
```

Report to user:
```
Creating quick task ${quick_id}: ${DESCRIPTION}
Directory: ${QUICK_DIR}
```

Store `$QUICK_DIR` for use in orchestration.

---

**Step 4.5: Discussion phase (only when `$DISCUSS_MODE`)**

Skip this step entirely if NOT `$DISCUSS_MODE`.

Display banner:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► DISCUSSING QUICK TASK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Surfacing gray areas for: ${DESCRIPTION}
```

**4.5a. Identify gray areas**

Analyze `$DESCRIPTION` to identify 2-4 gray areas — implementation decisions that would change the outcome and that the user should weigh in on.

Use the domain-aware heuristic to generate phase-specific (not generic) gray areas:
- Something users **SEE** → layout, density, interactions, states
- Something users **CALL** → responses, errors, auth, versioning
- Something users **RUN** → output format, flags, modes, error handling
- Something users **READ** → structure, tone, depth, flow
- Something being **ORGANIZED** → criteria, grouping, naming, exceptions

Each gray area should be a concrete decision point, not a vague category. Example: "Loading behavior" not "UX".

**4.5b. Present gray areas**

```
AskUserQuestion(
  header: "Gray Areas",
  question: "Which areas need clarification before planning?",
  options: [
    { label: "${area_1}", description: "${why_it_matters_1}" },
    { label: "${area_2}", description: "${why_it_matters_2}" },
    { label: "${area_3}", description: "${why_it_matters_3}" },
    { label: "All clear", description: "Skip discussion — I know what I want" }
  ],
  multiSelect: true
)
```

If user selects "All clear" → skip to Step 5 (no CONTEXT.md written).

**4.5c. Discuss selected areas**

For each selected area, ask 1-2 focused questions via AskUserQuestion:

```
AskUserQuestion(
  header: "${area_name}",
  question: "${specific_question_about_this_area}",
  options: [
    { label: "${concrete_choice_1}", description: "${what_this_means}" },
    { label: "${concrete_choice_2}", description: "${what_this_means}" },
    { label: "${concrete_choice_3}", description: "${what_this_means}" },
    { label: "You decide", description: "Claude's discretion" }
  ],
  multiSelect: false
)
```

Rules:
- Options must be concrete choices, not abstract categories
- Highlight recommended choice where you have a clear opinion
- If user selects "Other" with freeform text, switch to plain text follow-up (per questioning.md freeform rule)
- If user selects "You decide", capture as Claude's Discretion in CONTEXT.md
- Max 2 questions per area — this is lightweight, not a deep dive

Collect all decisions into `$DECISIONS`.

**4.5d. Write CONTEXT.md**

Write `${QUICK_DIR}/${quick_id}-CONTEXT.md` using the standard context template structure:

```markdown
# Quick Task ${quick_id}: ${DESCRIPTION} - Context

**Gathered:** ${date}
**Status:** Ready for planning

<domain>
## Task Boundary

${DESCRIPTION}

</domain>

<decisions>
## Implementation Decisions

### ${area_1_name}
- ${decision_from_discussion}

### ${area_2_name}
- ${decision_from_discussion}

### Claude's Discretion
${areas_where_user_said_you_decide_or_areas_not_discussed}

</decisions>

<specifics>
## Specific Ideas

${any_specific_references_or_examples_from_discussion}

[If none: "No specific requirements — open to standard approaches"]

</specifics>

<canonical_refs>
## Canonical References

${any_specs_adrs_or_docs_referenced_during_discussion}

[If none: "No external specs — requirements fully captured in decisions above"]

</canonical_refs>
```

Note: Quick task CONTEXT.md omits `<code_context>` and `<deferred>` sections (no codebase scouting, no phase scope to defer to). Keep it lean. The `<canonical_refs>` section is included when external docs were referenced — omit it only if no external docs apply.

Report: `Context captured: ${QUICK_DIR}/${quick_id}-CONTEXT.md`

---

**Step 4.75: Research phase (only when `$RESEARCH_MODE`)**

Skip this step entirely if NOT `$RESEARCH_MODE`.

Display banner:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► RESEARCHING QUICK TASK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Investigating approaches for: ${DESCRIPTION}
```

Spawn a single focused researcher (not 4 parallel researchers like full phases — quick tasks need targeted research, not broad domain surveys):

```
Agent(
  prompt="
<research_context>

**Mode:** quick-task
**Task:** ${DESCRIPTION}
**Output:** ${QUICK_DIR}/${quick_id}-RESEARCH.md

<files_to_read>
- .planning/STATE.md (Project state — what's already built)
- .planning/PROJECT.md (Project context)
- ./CLAUDE.md (if exists — project-specific guidelines)
${DISCUSS_MODE ? '- ' + QUICK_DIR + '/' + quick_id + '-CONTEXT.md (User decisions — research should align with these)' : ''}
</files_to_read>

${AGENT_SKILLS_PLANNER}

</research_context>

<focus>
This is a quick task, not a full phase. Research should be concise and targeted:
1. Best libraries/patterns for this specific task
2. Common pitfalls and how to avoid them
3. Integration points with existing codebase
4. Any constraints or gotchas worth knowing before planning

Do NOT produce a full domain survey. Target 1-2 pages of actionable findings.
</focus>

<output>
Write research to: ${QUICK_DIR}/${quick_id}-RESEARCH.md
Use standard research format but keep it lean — skip sections that don't apply.
Return: ## RESEARCH COMPLETE with file path
</output>
",
  subagent_type="gsd-phase-researcher",
  model="{planner_model}",
  description="Research: ${DESCRIPTION}"
)
```

> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.

After researcher returns:
1. Verify research exists at `${QUICK_DIR}/${quick_id}-RESEARCH.md`
2. Report: "Research complete: ${QUICK_DIR}/${quick_id}-RESEARCH.md"

If research file not found, warn but continue: "Research agent did not produce output — proceeding to planning without research."

---

**Step 5: Spawn planner (quick mode)**

**If `$VALIDATE_MODE`:** Use `quick-full` mode with stricter constraints.

**If NOT `$VALIDATE_MODE`:** Use standard `quick` mode.

```
Agent(
  prompt="
<planning_context>

**Mode:** ${VALIDATE_MODE ? 'quick-full' : 'quick'}
**Directory:** ${QUICK_DIR}
**Description:** ${DESCRIPTION}

<files_to_read>
- .planning/STATE.md (Project State)
- ./CLAUDE.md (if exists — follow project-specific guidelines)
${DISCUSS_MODE ? '- ' + QUICK_DIR + '/' + quick_id + '-CONTEXT.md (User decisions — locked, do not revisit)' : ''}
${RESEARCH_MODE ? '- ' + QUICK_DIR + '/' + quick_id + '-RESEARCH.md (Research findings — use to inform implementation choices)' : ''}
</files_to_read>

${AGENT_SKILLS_PLANNER}

**Project skills:** Check .claude/skills/ or .agents/skills/ directory (if either exists) — read SKILL.md files, plans should account for project skill rules

</planning_context>

<constraints>
- Create a SINGLE plan with 1-3 focused tasks
- Quick tasks should be atomic and self-contained
${RESEARCH_MODE ? '- Research findings are available — use them to inform library/pattern choices' : '- No research phase'}
${VALIDATE_MODE ? '- Target ~40% context usage (structured for verification)' : '- Target ~30% context usage (simple, focused)'}
${VALIDATE_MODE ? '- MUST generate `must_haves` in plan frontmatter (truths, artifacts, key_links)' : ''}
${VALIDATE_MODE ? '- Each task MUST have `files`, `action`, `verify`, `done` fields' : ''}
</constraints>

<output>
Write plan to: ${QUICK_DIR}/${quick_id}-PLAN.md
Return: ## PLANNING COMPLETE with plan path
</output>
",
  subagent_type="gsd-planner",
  model="{planner_model}",
  description="Quick plan: ${DESCRIPTION}"
)
```

> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.

After planner returns:
1. Verify plan exists at `${QUICK_DIR}/${quick_id}-PLAN.md`
2. Extract plan count (typically 1 for quick tasks)
3. Report: "Plan created: ${QUICK_DIR}/${quick_id}-PLAN.md"

If plan not found, error: "Planner failed to create ${quick_id}-PLAN.md"

---

**Step 5.5: Plan-checker loop (only when `$VALIDATE_MODE`)**

Skip this step entirely if NOT `$VALIDATE_MODE`.

Display banner:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► CHECKING PLAN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Spawning plan checker...
```

Checker prompt:

```markdown
<verification_context>
**Mode:** quick-full
**Task Description:** ${DESCRIPTION}

<files_to_read>
- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan to verify)
</files_to_read>

${AGENT_SKILLS_CHECKER}

**Scope:** This is a quick task, not a full phase. Skip checks that require a ROADMAP phase goal.
</verification_context>

<check_dimensions>
- Requirement coverage: Does the plan address the task description?
- Task completeness: Do tasks have files, action, verify, done fields?
- Key links: Are referenced files real?
- Scope sanity: Is this appropriately sized for a quick task (1-3 tasks)?
- must_haves derivation: Are must_haves traceable to the task description?

Skip: cross-plan deps (single plan), ROADMAP alignment
${DISCUSS_MODE ? '- Context compliance: Does the plan honor locked decisions from CONTEXT.md?' : '- Skip: context compliance (no CONTEXT.md)'}
</check_dimensions>

<expected_output>
- ## VERIFICATION PASSED — all checks pass
- ## ISSUES FOUND — structured issue list
</expected_output>
```

```
Agent(
  prompt=checker_prompt,
  subagent_type="gsd-plan-checker",
  model="{checker_model}",
  description="Check quick plan: ${DESCRIPTION}"
)
```

> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.

**Handle checker return:**

- **`## VERIFICATION PASSED`:** Display confirmation, proceed to step 6.
- **`## ISSUES FOUND`:** Display issues, check iteration count, enter revision loop.

**Revision loop (max 2 iterations):**

Track `iteration_count` (starts at 1 after initial plan + check).

**If iteration_count < 2:**

Display: `Sending back to planner for revision... (iteration ${N}/2)`

Revision prompt:

```markdown
<revision_context>
**Mode:** quick-full (revision)

<files_to_read>
- ${QUICK_DIR}/${quick_id}-PLAN.md (Existing plan)
</files_to_read>

${AGENT_SKILLS_PLANNER}

**Checker issues:** ${structured_issues_from_checker}

</revision_context>

<instructions>
Make targeted updates to address checker issues.
Do NOT replan from scratch unless issues are fundamental.
Return what changed.
</instructions>
```

```
Agent(
  prompt=revision_prompt,
  subagent_type="gsd-planner",
  model="{planner_model}",
  description="Revise quick plan: ${DESCRIPTION}"
)
```

> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.

After planner returns → spawn checker again, increment iteration_count.

**If iteration_count >= 2:**

Display: `Max iterations reached. ${N} issues remain:` + issue list

Offer: 1) Force proceed, 2) Abort

---

**Step 5.6: Pre-dispatch plan commit (worktree mode only)**

When `USE_WORKTREES !== "false"`, commit PLAN.md to the current branch **before** spawning the executor. This ensures the worktree inherits PLAN.md at its branch HEAD so the executor can read it via a worktree-rooted path — avoiding the main-repo path priming that triggers CC #36182 path-resolution drift.

Skip this step entirely if `USE_WORKTREES === "false"` (non-worktree mode: PLAN.md is committed in Step 8 as usual).

```bash
if [ "${USE_WORKTREES}" != "false" ]; then
  COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
  if [ "$COMMIT_DOCS" != "false" ]; then
    git add "${QUICK_DIR}/${quick_id}-PLAN.md"
    # No-op skip if nothing actually staged (idempotent re-runs).
    if git diff --cached --quiet -- "${QUICK_DIR}/${quick_id}-PLAN.md"; then
      echo "ℹ Pre-dispatch PLAN.md commit skipped (no staged changes)"
    else
      # Run hooks normally (#2924). If a project opts out via
      # workflow.worktree_skip_hooks=true, honor that opt-in only.
      SKIP_HOOKS=$(gsd-sdk query config-get workflow.worktree_skip_hooks 2>/dev/null || echo "false")
      if [ "$SKIP_HOOKS" = "true" ]; then
        git commit --no-verify -m "docs(${quick_id}): pre-dispatch plan for ${DESCRIPTION}" -- "${QUICK_DIR}/${quick_id}-PLAN.md" \
          || { echo "ERROR: pre-dispatch PLAN.md commit failed (--no-verify path). Aborting before executor dispatch." >&2; exit 1; }
      else
        git commit -m "docs(${quick_id}): pre-dispatch plan for ${DESCRIPTION}" -- "${QUICK_DIR}/${quick_id}-PLAN.md" \
          || { echo "ERROR: pre-dispatch PLAN.md commit failed — likely a pre-commit hook failure. Fix the hook output above (or set workflow.worktree_skip_hooks=true to bypass) and re-run." >&2; exit 1; }
      fi
    fi
  fi
fi
```

---

**Step 6: Spawn executor**

Capture current HEAD before spawning (used for worktree branch check):
```bash
EXPECTED_BASE=$(git rev-parse HEAD)
if [ "${USE_WORKTREES:-true}" != "false" ]; then
  QUICK_WORKTREE_MANIFEST=$(mktemp "${TMPDIR:-/tmp}/gsd-quick-worktree-XXXXXX.json")
  printf '{"worktrees":[]}\n' > "$QUICK_WORKTREE_MANIFEST"
  export QUICK_WORKTREE_MANIFEST
fi
```

Spawn gsd-executor with plan reference:

```
Agent(
  prompt="
Execute quick task ${quick_id}.

${USE_WORKTREES !== "false" ? `
<worktree_branch_check>
FIRST ACTION before any other work: verify this worktree's HEAD is bound to a per-agent
branch and that the branch is based on the correct commit.

Step 1 — HEAD attachment assertion (MANDATORY, runs before any reset/commit):
  HEAD_REF=$(git symbolic-ref --quiet HEAD || echo "DETACHED")
  ACTUAL_BRANCH=$(git rev-parse --abbrev-ref HEAD)
  if [ "$HEAD_REF" = "DETACHED" ] || echo "$ACTUAL_BRANCH" | grep -Eq '^(main|master|develop|trunk|release/.*)$'; then
    echo "FATAL: worktree HEAD is on '$ACTUAL_BRANCH' (expected per-agent branch like worktree-agent-*)." >&2
    echo "Refusing to commit/reset on a protected ref. DO NOT self-recover via 'git update-ref refs/heads/$ACTUAL_BRANCH' — that destroys concurrent work (#2924)." >&2
    echo "Aborting before any commits. Surface as a blocker for human review." >&2
    exit 1
  fi
  if ! echo "$ACTUAL_BRANCH" | grep -Eq '^worktree-agent-[A-Za-z0-9._/-]+$'; then
    echo "FATAL: worktree HEAD '$ACTUAL_BRANCH' is not in the worktree-agent-* namespace (Claude Code's per-agent worktree branch namespace)." >&2
    echo "Refusing to commit; surface as blocker (#2924)." >&2
    exit 1
  fi

Step 2 — Base correctness (only after Step 1 passes):
  Run: git merge-base HEAD ${EXPECTED_BASE}
  If the result differs from ${EXPECTED_BASE}, hard-reset to the correct base (safe — Step 1 confirmed HEAD is on a per-agent branch and the worktree is fresh):
    git reset --hard ${EXPECTED_BASE}
  Then verify: if [ "$(git rev-parse HEAD)" != "${EXPECTED_BASE}" ]; then echo "ERROR: Could not correct worktree base"; exit 1; fi

This corrects a known issue where EnterWorktree creates branches from main instead of the feature branch HEAD (#2015) and prevents the destructive HEAD-on-master self-recovery path (#2924).
</worktree_branch_check>
` : ''}

<files_to_read>
- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan)
- .planning/STATE.md (Project state)
- ./CLAUDE.md (Project instructions, if exists)
- .claude/skills/ or .agents/skills/ (Project skills, if either exists — list skills, read SKILL.md for each, follow relevant rules during implementation)
</files_to_read>

${AGENT_SKILLS_EXECUTOR}

<submodule_commit_guard>
SUBMODULE_PATHS for this project: ${SUBMODULE_PATHS}

If SUBMODULE_PATHS is non-empty, you MUST run this fail-loud guard immediately
before EVERY git commit you create during this quick task (after \`git add\`,
before \`git commit\`). Quick mode does not have a pre-declared files_modified
list, so the guard runs at commit time:

\`\`\`bash
SUBMODULE_PATHS=\"${SUBMODULE_PATHS}\"
if [ -n \"\$SUBMODULE_PATHS\" ]; then
  STAGED=\$(git diff --cached --name-only)
  for sm_raw in \$SUBMODULE_PATHS; do
    sm=\"\${sm_raw#./}\"
    sm=\"\${sm%/}\"
    [ -z \"\$sm\" ] && continue
    for f_raw in \$STAGED; do
      f=\"\${f_raw#./}\"
      f=\"\${f%/}\"
      case \"\$f\" in
        \"\$sm\"|\"\$sm\"/*)
          echo \"ABORT: staged path \$f_raw falls inside submodule \$sm — worktree-isolated commits cannot safely span submodule boundaries. Re-run with workflow.use_worktrees=false.\" >&2
          exit 1 ;;
      esac
    done
  done
fi
\`\`\`

If the guard aborts, do NOT attempt the commit, do NOT remove the staged files,
and do NOT continue subsequent tasks. Surface the abort message in your
SUMMARY.md and stop — the user must rerun with worktrees disabled.
</submodule_commit_guard>

<constraints>
- Execute all tasks in the plan
- Commit each task atomically (code changes only)
- Run the <submodule_commit_guard> bash block before every \`git commit\` if SUBMODULE_PATHS is non-empty
- Create summary at: ${QUICK_DIR}/${quick_id}-SUMMARY.md
- Do NOT commit docs artifacts (SUMMARY.md, STATE.md, PLAN.md) — the orchestrator handles the docs commit in Step 8
- Do NOT update ROADMAP.md (quick tasks are separate from planned phases)
</constraints>
",
  subagent_type="gsd-executor",
  model="{executor_model}",
  ${USE_WORKTREES !== "false" ? 'isolation="worktree",' : ''}
  description="Execute: ${DESCRIPTION}"
)
```

> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.

If the executor ran with `isolation="worktree"`, append its returned `{agent_id, worktree_path, branch, expected_base}` metadata to `QUICK_WORKTREE_MANIFEST` before cleanup. If any field is unavailable, stop and ask for recovery; do not discover global worktrees.

After executor returns:
1. **Worktree cleanup:** If the executor ran with `isolation="worktree"`, merge the worktree branch back and clean up:
   ```bash
   QUICK_WORKTREE_MANIFEST=${QUICK_WORKTREE_MANIFEST:-$WAVE_WORKTREE_MANIFEST}
   [ -n "${QUICK_WORKTREE_MANIFEST:-}" ] && [ -f "$QUICK_WORKTREE_MANIFEST" ] || {
     echo "BLOCKED: missing QUICK_WORKTREE_MANIFEST; refusing broad worktree cleanup (#3384)." >&2
     exit 1
   }

   # Prefer the bounded cleanup helper. It verifies branch identity, expected
   # base, deletion diffs, merge result, and worktree removal before branch
   # deletion. If it blocks, resolve the reported manifest entry and rerun.
   if command -v gsd-sdk >/dev/null 2>&1; then
     gsd-sdk query worktree.cleanup-wave --manifest "$QUICK_WORKTREE_MANIFEST" || exit 1
   else
     echo "WARN: gsd-sdk unavailable; using manifest-scoped shell fallback (#3384)." >&2

   # Find worktrees recorded by the executor manifest only.
   # Inclusion-based filter (#2774): match ONLY agent-spawned worktrees under
   # `.claude/worktrees/agent-` (the namespace Claude Code's `isolation="worktree"`
   # uses). The previous exclusion filter (`grep -v "$(pwd)$"`) destroyed the parent
   # workspace's `.git` whenever the workspace itself was a worktree (multi-workspace
   # setups, and the cross-drive Windows case where `git worktree list` reports the
   # registry path on a different drive than `$(pwd)`).
   # Read line-by-line so worktree paths containing whitespace are preserved (#2774).
   WT_PATHS_FILE=$(mktemp "${TMPDIR:-/tmp}/gsd-worktree-paths-XXXXXX")
   node -e 'const fs=require("fs");const p=process.env.QUICK_WORKTREE_MANIFEST||process.env.WAVE_WORKTREE_MANIFEST;try{if(!p)throw new Error("QUICK_WORKTREE_MANIFEST is unset");if(!fs.existsSync(p))throw new Error("manifest does not exist");const s=fs.readFileSync(p,"utf8");if(!s.trim())throw new Error("manifest is empty");const j=JSON.parse(s);for(const w of j.worktrees||[])if(w.worktree_path)console.log(w.worktree_path)}catch(e){console.error(`ERROR: cannot read worktree manifest ${p||"(unset)"}: ${e.message}`);process.exit(1)}' > "$WT_PATHS_FILE" || { echo "BLOCKED: cannot read QUICK_WORKTREE_MANIFEST; refusing cleanup (#3384)." >&2; exit 1; }
   while IFS= read -r WT; do
     [ -z "$WT" ] && continue
     # Pin CWD to project root before any bare git command (#3521).
     # An LLM orchestrator may leak CWD into a worktree across tool calls; without
     # this pin the merge command resolves against the worktree branch itself and
     # silently no-ops the main-branch merge.
     PROJECT_ROOT=$(git -C "$WT" rev-parse --git-common-dir 2>/dev/null)
     # git rev-parse --git-common-dir returns the .git dir, not the working tree root.
     # Strip the trailing /.git (or bare .git) to get the working tree root.
     PROJECT_ROOT=$(echo "$PROJECT_ROOT" | sed 's|/\.git$||; s|/\.git/.*||')
     if [ -z "$PROJECT_ROOT" ] || [ ! -d "$PROJECT_ROOT" ]; then
       echo "WARN: cannot resolve project root from worktree $WT — skipping cleanup for this entry (#3521)" >&2
       continue
     fi
     cd "$PROJECT_ROOT" || { echo "WARN: cannot cd to project root $PROJECT_ROOT — skipping cleanup for worktree $WT (#3521)" >&2; continue; }
     WT_BRANCH=$(git -C "$WT" rev-parse --abbrev-ref HEAD 2>/dev/null)
     if [ -n "$WT_BRANCH" ] && [ "$WT_BRANCH" != "HEAD" ]; then
       # --- Orchestrator file protection (#1756) ---
       # Backup STATE.md and ROADMAP.md before merge (main always wins)
       STATE_BACKUP=$(mktemp)
       ROADMAP_BACKUP=$(mktemp)
       [ -f .planning/STATE.md ] && cp .planning/STATE.md "$STATE_BACKUP" || true
       [ -f .planning/ROADMAP.md ] && cp .planning/ROADMAP.md "$ROADMAP_BACKUP" || true

       # Pre-merge deletion guard: block merges that delete tracked .planning/ files
       DELETIONS=$(git diff --diff-filter=D --name-only HEAD..."$WT_BRANCH" 2>/dev/null || true)
       if [ -n "$DELETIONS" ]; then
         echo "BLOCKED: Worktree branch $WT_BRANCH contains file deletions: $DELETIONS"
         echo "Review these deletions before merging. If intentional, remove this guard and re-run."
         rm -f "$STATE_BACKUP" "$ROADMAP_BACKUP"
         continue
       fi

       git merge "$WT_BRANCH" --no-ff --no-edit -m "chore: merge quick task worktree ($WT_BRANCH)" 2>&1 || {
         echo "⚠ Merge conflict from worktree $WT_BRANCH — resolve manually"
         echo "  STATE.md backup:   $STATE_BACKUP"
         echo "  ROADMAP.md backup: $ROADMAP_BACKUP"
         echo "  Restore with: cp \$STATE_BACKUP .planning/STATE.md && cp \$ROADMAP_BACKUP .planning/ROADMAP.md"
         break
       }

       # Restore orchestrator-owned files
       if [ -s "$STATE_BACKUP" ]; then cp "$STATE_BACKUP" .planning/STATE.md; fi
       if [ -s "$ROADMAP_BACKUP" ]; then cp "$ROADMAP_BACKUP" .planning/ROADMAP.md; fi
       rm -f "$STATE_BACKUP" "$ROADMAP_BACKUP"

       # Detect files deleted on main but re-added by worktree merge
       # (e.g., archived phase directories that were intentionally removed)
       # A "resurrected" file must have a deletion event in main's ancestry —
       # brand-new files (e.g. SUMMARY.md just created by the agent) have no
       # such history and must NOT be removed (#2501, #3195).
       DELETED_FILES=$(git diff --diff-filter=A --name-only HEAD~1 -- .planning/ 2>/dev/null || true)
       for RESURRECTED in $DELETED_FILES; do
         # Only delete if this file was previously tracked on main and then
         # deliberately removed (has a deletion event in git history).
         WAS_DELETED=$(git log --follow --diff-filter=D --name-only --format="" HEAD~1 -- "$RESURRECTED" 2>/dev/null | grep -c . || true)
         if [ "${WAS_DELETED:-0}" -gt 0 ]; then
           git rm -f "$RESURRECTED" 2>/dev/null || true
         fi
       done

       if ! git diff --quiet .planning/STATE.md .planning/ROADMAP.md 2>/dev/null || \
          [ -n "$DELETED_FILES" ]; then
         COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
         if [ "$COMMIT_DOCS" != "false" ]; then
           git add .planning/STATE.md .planning/ROADMAP.md 2>/dev/null || true
           git commit --amend --no-edit 2>/dev/null || true
         fi
       fi

       # Safety net: rescue uncommitted SUMMARY.md before worktree removal (#2296, mirrors #2070, #2838).
       # Filesystem-level (find + cp) bypasses git's --exclude-standard filter, which silently
       # drops .planning/SUMMARY.md when projects gitignore .planning/ — the rescue's prior
       # `git ls-files --exclude-standard` form returned empty in that case and the SUMMARY
       # was lost on `git worktree remove --force`.
       while IFS= read -r SUMMARY; do
         [ -z "$SUMMARY" ] && continue
         REL_PATH="${SUMMARY#$WT/}"
         if [ ! -f "$REL_PATH" ] || ! cmp -s "$SUMMARY" "$REL_PATH"; then
           mkdir -p "$(dirname "$REL_PATH")"
           cp "$SUMMARY" "$REL_PATH"
           echo "⚠ Rescued $REL_PATH from worktree before removal"
         fi
       done < <(find "$WT/.planning" -name "*SUMMARY.md" 2>/dev/null)

       # Remove the worktree before deleting the branch. If removal fails,
       # leave the branch in place so the worktree remains recoverable (#3384).
       REMOVE_OK=false
       if git worktree remove "$WT" --force; then
         REMOVE_OK=true
       else
         WT_NAME=$(basename "$WT")
         if [ -f ".git/worktrees/${WT_NAME}/locked" ]; then
           echo "⚠ Worktree $WT is locked — attempting to unlock and retry"
           git worktree unlock "$WT" 2>/dev/null || true
           if git worktree remove "$WT" --force; then
             REMOVE_OK=true
           else
             echo "⚠ Residual worktree at $WT — manual cleanup required after session exits:"
             echo "    git worktree unlock \"$WT\" && git worktree remove \"$WT\" --force && git branch -D \"$WT_BRANCH\""
           fi
         else
           echo "⚠ Residual worktree at $WT (remove failed) — investigate manually"
         fi
       fi
       if [ "$REMOVE_OK" = "true" ]; then
         git branch -D "$WT_BRANCH" 2>/dev/null || true
       else
         echo "⚠ Keeping branch $WT_BRANCH because worktree removal failed (#3384)"
       fi
     fi
   done < "$WT_PATHS_FILE"
   fi
   ```
   If `workflow.use_worktrees` is `false`, skip this step.
2. Verify summary exists at `${QUICK_DIR}/${quick_id}-SUMMARY.md`
3. Extract commit hash from executor output
4. Report completion status

**Known Claude Code bug (classifyHandoffIfNeeded):** If executor reports "failed" with error `classifyHandoffIfNeeded is not defined`, this is a Claude Code runtime bug — not a real failure. Check if summary file exists and git log shows commits. If so, treat as successful.

If summary not found, error: "Executor failed to create ${quick_id}-SUMMARY.md"

Note: For quick tasks producing multiple plans (rare), spawn executors in parallel waves per execute-phase patterns.

---

**Step 6.25: Code review (auto)**

Skip this step entirely if `$FULL_MODE` is false.

**Config gate:**
```bash
CODE_REVIEW_ENABLED=$(gsd-sdk query config-get workflow.code_review 2>/dev/null || echo "true")
```
If `"false"`, skip with message "Code review skipped (workflow.code_review=false)".

**Scope files from executor's commits:**
```bash
# Find the diff base: last commit before quick task started
# Use git log to find commits referencing the quick task id, then take the parent of the oldest
QUICK_COMMITS=$(git log --oneline --format="%H" --grep="${quick_id}" 2>/dev/null)
if [ -n "$QUICK_COMMITS" ]; then
  DIFF_BASE=$(echo "$QUICK_COMMITS" | tail -1)^
  # Verify parent exists (guard against first commit in repo)
  git rev-parse "${DIFF_BASE}" >/dev/null 2>&1 || DIFF_BASE=$(echo "$QUICK_COMMITS" | tail -1)
else
  # No commits found for this quick task — skip review
  DIFF_BASE=""
fi

if [ -n "$DIFF_BASE" ]; then
  CHANGED_FILES=$(git diff --name-only "${DIFF_BASE}..HEAD" -- . ':!.planning' 2>/dev/null | tr '\n' ' ')
else
  CHANGED_FILES=""
fi
```

If `CHANGED_FILES` is empty, skip with "No source files changed — skipping code review."

**Invoke review:**
```
Agent(
  prompt="Review these files for bugs, security issues, and code quality.
  Files: ${CHANGED_FILES}
  Output: ${QUICK_DIR}/${quick_id}-REVIEW.md
  Depth: quick",
  subagent_type="gsd-code-reviewer",
  model="{executor_model}"
)
```

> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.

If review produces findings, display advisory message. **Error handling:** Failures are non-blocking — catch and proceed.

---

**Step 6.5: Verification (only when `$VALIDATE_MODE`)**

Skip this step entirely if NOT `$VALIDATE_MODE`.

Display banner:
```
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► VERIFYING RESULTS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Spawning verifier...
```

```
Agent(
  prompt="Verify quick task goal achievement.
Task directory: ${QUICK_DIR}
Task goal: ${DESCRIPTION}

<files_to_read>
- ${QUICK_DIR}/${quick_id}-PLAN.md (Plan)
</files_to_read>

${AGENT_SKILLS_VERIFIER}

Check must_haves against actual codebase. Create VERIFICATION.md at ${QUICK_DIR}/${quick_id}-VERIFICATION.md.",
  subagent_type="gsd-verifier",
  model="{verifier_model}",
  description="Verify: ${DESCRIPTION}"
)
```

> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.

Read verification status:
```bash
grep "^status:" "${QUICK_DIR}/${quick_id}-VERIFICATION.md" | cut -d: -f2 | tr -d ' '
```

Store as `$VERIFICATION_STATUS`.

| Status | Action |
|--------|--------|
| `passed` | Store `$VERIFICATION_STATUS = "Verified"`, continue to step 7 |
| `human_needed` | Display items needing manual check, store `$VERIFICATION_STATUS = "Needs Review"`, continue |
| `gaps_found` | Display gap summary, offer: 1) Re-run executor to fix gaps, 2) Accept as-is. Store `$VERIFICATION_STATUS = "Gaps"` |

---

**Step 7: Update STATE.md**

Update STATE.md with quick task completion record.

**7a. Check if "Quick Tasks Completed" section exists:**

Read STATE.md and check for `### Quick Tasks Completed` section.

**7b. If section doesn't exist, create it:**

Insert after `### Blockers/Concerns` section:

**If `$VALIDATE_MODE`:**
```markdown
### Quick Tasks Completed

| # | Description | Date | Commit | Status | Directory |
|---|-------------|------|--------|--------|-----------|
```

**If NOT `$VALIDATE_MODE`:**
```markdown
### Quick Tasks Completed

| # | Description | Date | Commit | Directory |
|---|-------------|------|--------|-----------|
```

**Note:** If the table already exists, match its existing column format. If adding `--validate` (or `--full`) to a project that already has quick tasks without a Status column, add the Status column to the header and separator rows, and leave Status empty for the new row's predecessors.

**7c. Append new row to table:**

Use `date` from init:

**If `$VALIDATE_MODE` (or table has Status column):**
```markdown
| ${quick_id} | ${DESCRIPTION} | ${date} | ${commit_hash} | ${VERIFICATION_STATUS} | [${quick_id}-${slug}](./quick/${quick_id}-${slug}/) |
```

**If NOT `$VALIDATE_MODE` (and table has no Status column):**
```markdown
| ${quick_id} | ${DESCRIPTION} | ${date} | ${commit_hash} | [${quick_id}-${slug}](./quick/${quick_id}-${slug}/) |
```

**7d. Update "Last activity" line:**

Use `date` from init:
```
Last activity: ${date} - Completed quick task ${quick_id}: ${DESCRIPTION}
```

Use Edit tool to make these changes atomically

---

**Step 8: Final commit and completion**

Stage and commit quick task artifacts. This step MUST always run — even if the executor already committed some files (e.g. when running without worktree isolation). The `gsd-sdk query commit` command (or legacy `gsd-tools.cjs` commit) handles already-committed files gracefully.

Build file list:
- `${QUICK_DIR}/${quick_id}-PLAN.md`
- `${QUICK_DIR}/${quick_id}-SUMMARY.md`
- `.planning/STATE.md`
- If `$DISCUSS_MODE` and context file exists: `${QUICK_DIR}/${quick_id}-CONTEXT.md`
- If `$RESEARCH_MODE` and research file exists: `${QUICK_DIR}/${quick_id}-RESEARCH.md`
- If `$VALIDATE_MODE` and verification file exists: `${QUICK_DIR}/${quick_id}-VERIFICATION.md`
- If `${QUICK_DIR}/${quick_id}-deferred-items.md` exists: `${QUICK_DIR}/${quick_id}-deferred-items.md`

```bash
# Explicitly stage all artifacts before commit — PLAN.md may be untracked
# if the executor ran without worktree isolation and committed docs early
# Filter .planning/ files from staging if commit_docs is disabled (#1783)
COMMIT_DOCS=$(gsd-sdk query config-get commit_docs 2>/dev/null || echo "true")
if [ "$COMMIT_DOCS" = "false" ]; then
  file_list_filtered=$(echo "${file_list}" | tr ' ' '\n' | grep -v '^\.planning/' | tr '\n' ' ')
  git add ${file_list_filtered} 2>/dev/null
else
  git add ${file_list} 2>/dev/null
fi
gsd-sdk query commit "docs(quick-${quick_id}): ${DESCRIPTION}" --files ${file_list}
```

Get final commit hash:
```bash
commit_hash=$(git rev-parse --short HEAD)
```

Display completion output:

**If `$VALIDATE_MODE`:**
```
---

GSD > QUICK TASK COMPLETE (VALIDATED)

Quick Task ${quick_id}: ${DESCRIPTION}

${RESEARCH_MODE ? 'Research: ' + QUICK_DIR + '/' + quick_id + '-RESEARCH.md' : ''}
Summary: ${QUICK_DIR}/${quick_id}-SUMMARY.md
Verification: ${QUICK_DIR}/${quick_id}-VERIFICATION.md (${VERIFICATION_STATUS})
Commit: ${commit_hash}

---

Ready for next task: /gsd:quick ${GSD_WS}
```

**If NOT `$VALIDATE_MODE`:**
```
---

GSD > QUICK TASK COMPLETE

Quick Task ${quick_id}: ${DESCRIPTION}

${RESEARCH_MODE ? 'Research: ' + QUICK_DIR + '/' + quick_id + '-RESEARCH.md' : ''}
Summary: ${QUICK_DIR}/${quick_id}-SUMMARY.md
Commit: ${commit_hash}

---

Ready for next task: /gsd:quick ${GSD_WS}
```

</process>

<success_criteria>
- [ ] ROADMAP.md validation passes
- [ ] User provides task description
- [ ] `--full`, `--validate`, `--discuss`, and `--research` flags parsed from arguments when present
- [ ] `--full` sets all booleans (`$FULL_MODE`, `$DISCUSS_MODE`, `$RESEARCH_MODE`, `$VALIDATE_MODE`)
- [ ] Slug generated (lowercase, hyphens, max 40 chars)
- [ ] Quick ID generated (YYMMDD-xxx format, 2s Base36 precision)
- [ ] Directory created at `.planning/quick/YYMMDD-xxx-slug/`
- [ ] (--discuss) Gray areas identified and presented, decisions captured in `${quick_id}-CONTEXT.md`
- [ ] (--research) Research agent spawned, `${quick_id}-RESEARCH.md` created
- [ ] `${quick_id}-PLAN.md` created by planner (honors CONTEXT.md decisions when --discuss, uses RESEARCH.md findings when --research)
- [ ] (--validate) Plan checker validates plan, revision loop capped at 2
- [ ] `${quick_id}-SUMMARY.md` created by executor
- [ ] (--validate) `${quick_id}-VERIFICATION.md` created by verifier
- [ ] STATE.md updated with quick task row (Status column when --validate)
- [ ] Artifacts committed
</success_criteria>


please switch cwd to `claude_skill_owl` and /gsd-quick make communes and signoffs delete the .more-done sentinel in the same step where FILE-DROP consumes the commune/signoff file.


Remove sentinel file in FILE-DROP processing step


Repo has `.planning/ROADMAP.md` — gsd-quick valid. Before driving heavy orchestration, scout actual code + check gsd-sdk. Parallel.


Bash

command -v gsd-sdk && gsd-sdk --version 2>/dev/null; echo "---PLANNING---"; cd /c/Users/decid/Documents/projects/claude_skill_owl && git -C . rev-parse --abbrev-ref HEAD && echo "ROADMAP exists:" && test -f .planning/ROADMAP.md && echo yes

Check gsd-sdk + repo branch state


/c/nvm4w/nodejs/gsd-sdk
gsd-sdk v1.42.3
---PLANNING---
main
ROADMAP exists:
yes
Shell cwd was reset to C:\Users\decid\Documents\projects\spt-core