Files
msd-core/get-shit-done/workflows/quick.md
Kevin McCarthy 44cf8ccf48 fix: add mandatory canonical_refs section to CONTEXT.md (#1015)
* fix: add mandatory canonical_refs section to CONTEXT.md

CONTEXT.md is the bridge between user decisions and downstream agents
(researcher, planner). When projects have external specs, ADRs, or
design docs, these references were being silently dropped — mentioned
inline as "see ADR-019" but never collected into a section that agents
could find and read. This caused agents to plan and implement without
reading the specs they were supposed to follow.

Changes:
- templates/context.md: Add <canonical_refs> section to file template,
  all 3 examples, and guidelines (marked MANDATORY)
- workflows/discuss-phase.md: Add step 1b (extract canonical refs),
  add section to write_context template, add to success criteria
- workflows/plan-phase.md: Add canonical ref extraction to PRD express
  path and its CONTEXT.md template
- workflows/quick.md: Add lightweight canonical_refs to --discuss mode

The section is mandatory but gracefully handles projects without external
docs ("No external specs — requirements fully captured in decisions above").

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make canonical refs an accumulator across entire discussion

Refs come from 4 sources, not just ROADMAP.md:
1. ROADMAP.md Canonical refs line (initial seed)
2. REQUIREMENTS.md/PROJECT.md referenced specs
3. Codebase scout (code comments citing ADRs)
4. User during discussion ("read adr-014", "check the MCP spec")

Source 4 is often the MOST important — these are docs the user
specifically wants downstream agents to follow. The previous
version only handled source 1 and silently dropped the rest.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:35:39 -06:00

18 KiB

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 --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 --full flag: enables plan-checking (max 2 iterations) and post-execution verification for quality guarantees without full milestone ceremony.

Flags are composable: --discuss --full gives discussion + plan-checking + verification.

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

**Step 1: Parse arguments and get task description**

Parse $ARGUMENTS for:

  • --full flag → store as $FULL_MODE (true/false)
  • --discuss flag → store as $DISCUSS_MODE (true/false)
  • Remaining text → use as $DESCRIPTION if non-empty

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

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 $DISCUSS_MODE and $FULL_MODE:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (DISCUSS + FULL)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Discussion + plan checking + verification enabled

If $DISCUSS_MODE only:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (DISCUSS)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Discussion phase enabled — surfacing gray areas before planning

If $FULL_MODE only:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► QUICK TASK (FULL MODE)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Plan checking + verification enabled

Step 2: Initialize

INIT=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" init quick "$DESCRIPTION")
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi

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

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 3: Create task directory

mkdir -p "${task_dir}"

Step 4: Create quick task directory

Create the directory for this quick task:

QUICK_DIR=".planning/quick/${next_num}-${slug}"
mkdir -p "$QUICK_DIR"

Report to user:

Creating quick task ${next_num}: ${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}/${next_num}-CONTEXT.md using the standard context template structure:

# Quick Task ${next_num}: ${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}/${next_num}-CONTEXT.md


Step 5: Spawn planner (quick mode)

If $FULL_MODE: Use quick-full mode with stricter constraints.

If NOT $FULL_MODE: Use standard quick mode.

Task(
  prompt="
<planning_context>

**Mode:** ${FULL_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 + '/' + next_num + '-CONTEXT.md (User decisions — locked, do not revisit)' : ''}
</files_to_read>

**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
- No research phase
${FULL_MODE ? '- Target ~40% context usage (structured for verification)' : '- Target ~30% context usage (simple, focused)'}
${FULL_MODE ? '- MUST generate `must_haves` in plan frontmatter (truths, artifacts, key_links)' : ''}
${FULL_MODE ? '- Each task MUST have `files`, `action`, `verify`, `done` fields' : ''}
</constraints>

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

After planner returns:

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

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


Step 5.5: Plan-checker loop (only when $FULL_MODE)

Skip this step entirely if NOT $FULL_MODE.

Display banner:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► CHECKING PLAN
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Spawning plan checker...

Checker prompt:

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

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

**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>
Task(
  prompt=checker_prompt,
  subagent_type="gsd-plan-checker",
  model="{checker_model}",
  description="Check quick plan: ${DESCRIPTION}"
)

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:

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

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

**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>
Task(
  prompt=revision_prompt,
  subagent_type="gsd-planner",
  model="{planner_model}",
  description="Revise quick plan: ${DESCRIPTION}"
)

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 6: Spawn executor

Spawn gsd-executor with plan reference:

Task(
  prompt="
Execute quick task ${next_num}.

<files_to_read>
- ${QUICK_DIR}/${next_num}-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>

<constraints>
- Execute all tasks in the plan
- Commit each task atomically
- Create summary at: ${QUICK_DIR}/${next_num}-SUMMARY.md
- Do NOT update ROADMAP.md (quick tasks are separate from planned phases)
</constraints>
",
  subagent_type="gsd-executor",
  model="{executor_model}",
  description="Execute: ${DESCRIPTION}"
)

After executor returns:

  1. Verify summary exists at ${QUICK_DIR}/${next_num}-SUMMARY.md
  2. Extract commit hash from executor output
  3. 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 ${next_num}-SUMMARY.md"

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


Step 6.5: Verification (only when $FULL_MODE)

Skip this step entirely if NOT $FULL_MODE.

Display banner:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 GSD ► VERIFYING RESULTS
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

◆ Spawning verifier...
Task(
  prompt="Verify quick task goal achievement.
Task directory: ${QUICK_DIR}
Task goal: ${DESCRIPTION}

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

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

Read verification status:

grep "^status:" "${QUICK_DIR}/${next_num}-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 $FULL_MODE:

### Quick Tasks Completed

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

If NOT $FULL_MODE:

### Quick Tasks Completed

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

Note: If the table already exists, match its existing column format. If adding --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 $FULL_MODE (or table has Status column):

| ${next_num} | ${DESCRIPTION} | ${date} | ${commit_hash} | ${VERIFICATION_STATUS} | [${next_num}-${slug}](./quick/${next_num}-${slug}/) |

If NOT $FULL_MODE (and table has no Status column):

| ${next_num} | ${DESCRIPTION} | ${date} | ${commit_hash} | [${next_num}-${slug}](./quick/${next_num}-${slug}/) |

7d. Update "Last activity" line:

Use date from init:

Last activity: ${date} - Completed quick task ${next_num}: ${DESCRIPTION}

Use Edit tool to make these changes atomically


Step 8: Final commit and completion

Stage and commit quick task artifacts:

Build file list:

  • ${QUICK_DIR}/${next_num}-PLAN.md
  • ${QUICK_DIR}/${next_num}-SUMMARY.md
  • .planning/STATE.md
  • If $DISCUSS_MODE and context file exists: ${QUICK_DIR}/${next_num}-CONTEXT.md
  • If $FULL_MODE and verification file exists: ${QUICK_DIR}/${next_num}-VERIFICATION.md
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "docs(quick-${next_num}): ${DESCRIPTION}" --files ${file_list}

Get final commit hash:

commit_hash=$(git rev-parse --short HEAD)

Display completion output:

If $FULL_MODE:

---

GSD > QUICK TASK COMPLETE (FULL MODE)

Quick Task ${next_num}: ${DESCRIPTION}

Summary: ${QUICK_DIR}/${next_num}-SUMMARY.md
Verification: ${QUICK_DIR}/${next_num}-VERIFICATION.md (${VERIFICATION_STATUS})
Commit: ${commit_hash}

---

Ready for next task: /gsd:quick

If NOT $FULL_MODE:

---

GSD > QUICK TASK COMPLETE

Quick Task ${next_num}: ${DESCRIPTION}

Summary: ${QUICK_DIR}/${next_num}-SUMMARY.md
Commit: ${commit_hash}

---

Ready for next task: /gsd:quick

<success_criteria>

  • ROADMAP.md validation passes
  • User provides task description
  • --full and --discuss flags parsed from arguments when present
  • Slug generated (lowercase, hyphens, max 40 chars)
  • Next number calculated (001, 002, 003...)
  • Directory created at .planning/quick/NNN-slug/
  • (--discuss) Gray areas identified and presented, decisions captured in ${next_num}-CONTEXT.md
  • ${next_num}-PLAN.md created by planner (honors CONTEXT.md decisions when --discuss)
  • (--full) Plan checker validates plan, revision loop capped at 2
  • ${next_num}-SUMMARY.md created by executor
  • (--full) ${next_num}-VERIFICATION.md created by verifier
  • STATE.md updated with quick task row (Status column when --full)
  • Artifacts committed </success_criteria>