diff --git a/get-shit-done/workflows/pause-work.md b/get-shit-done/workflows/pause-work.md index 5e60ad998..7857e49d0 100644 --- a/get-shit-done/workflows/pause-work.md +++ b/get-shit-done/workflows/pause-work.md @@ -9,14 +9,28 @@ Read all files referenced by the invoking prompt's execution_context before star -Find current phase directory from most recently modified files: +## Context Detection + +Determine what kind of work is being paused and set the handoff destination accordingly: ```bash -# Find most recent phase directory with work -(ls -lt .planning/phases/*/PLAN.md 2>/dev/null || true) | head -1 | grep -oP 'phases/\K[^/]+' || true +# Check for active phase +phase=$(( ls -lt .planning/phases/*/PLAN.md 2>/dev/null || true ) | head -1 | grep -oP 'phases/\K[^/]+' || true) + +# Check for active spike +spike=$(( ls -lt .planning/spikes/*/SPIKE.md .planning/spikes/*/DESIGN.md 2>/dev/null || true ) | head -1 | grep -oP 'spikes/\K[^/]+' || true) + +# Check for active deliberation +deliberation=$(ls .planning/deliberations/*.md 2>/dev/null | head -1 || true) ``` -If no active phase detected, ask user which phase they're pausing work on. +- **Phase work**: active phase directory → handoff to `.planning/phases/XX-name/.continue-here.md` +- **Spike work**: active spike directory or spike-related files (no active phase) → handoff to `.planning/spikes/SPIKE-NNN/.continue-here.md` (create directory if needed) +- **Deliberation work**: active deliberation file (no phase/spike) → handoff to `.planning/deliberations/.continue-here.md` +- **Research work**: research notes exist but no phase/spike/deliberation → handoff to `.planning/.continue-here.md` +- **Default**: no detectable context → handoff to `.planning/.continue-here.md`, note the ambiguity in `` + +If phase is detected, proceed with phase handoff path. Otherwise use the first matching non-phase path above. @@ -85,10 +99,11 @@ timestamp=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" current-timesta -**Write handoff to `.planning/phases/XX-name/.continue-here.md`:** +**Write handoff to the path determined in the detect step** (e.g. `.planning/phases/XX-name/.continue-here.md`, `.planning/spikes/SPIKE-NNN/.continue-here.md`, or `.planning/.continue-here.md`): ```markdown --- +context: [phase|spike|deliberation|research|default] phase: XX-name task: 3 total_tasks: 7 @@ -124,6 +139,24 @@ last_updated: [timestamp from current-timestamp] - [Blocker 1]: [status/workaround] +## Required Reading (in order) + +1. [document] — [why it matters] + +## Critical Anti-Patterns (do NOT repeat these) + +- [ANTI-PATTERN]: [what it is] → [structural mitigation] + +## Infrastructure State + +- [service/env]: [current state] + +## Pre-Execution Critique Required + +- Design artifact: [path] +- Critique focus: [key questions the critic should probe] +- Gate: Do NOT begin execution until critique is complete and design is revised + [Mental state, what were you thinking, the plan] @@ -143,7 +176,7 @@ timestamp=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" current-timesta ```bash -node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "wip: [phase-name] paused at task [X]/[Y]" --files .planning/phases/*/.continue-here.md .planning/HANDOFF.json +node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "wip: [context-name] paused at [X]/[Y]" --files [handoff-path] .planning/HANDOFF.json ``` @@ -151,11 +184,12 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" commit "wip: [phase-name] p ``` ✓ Handoff created: - .planning/HANDOFF.json (structured, machine-readable) - - .planning/phases/[XX-name]/.continue-here.md (human-readable) + - [handoff-path] (human-readable) Current state: -- Phase: [XX-name] +- Context: [phase|spike|deliberation|research] +- Location: [XX-name or SPIKE-NNN] - Task: [X] of [Y] - Status: [in_progress/blocked] - Blockers: [count] ({human_actions_pending count} need human action) @@ -169,8 +203,10 @@ To resume: /gsd:resume-work -- [ ] .continue-here.md created in correct phase directory -- [ ] All sections filled with specific content +- [ ] Context detected (phase/spike/deliberation/research/default) +- [ ] .continue-here.md created at correct path for detected context +- [ ] Required Reading, Anti-Patterns, and Infrastructure State sections filled +- [ ] Pre-Execution Critique section filled if pausing between design and execution - [ ] Committed as WIP - [ ] User knows location and how to resume diff --git a/tests/pause-work-improvements.test.cjs b/tests/pause-work-improvements.test.cjs new file mode 100644 index 000000000..847f299fa --- /dev/null +++ b/tests/pause-work-improvements.test.cjs @@ -0,0 +1,70 @@ +const { test, describe } = require('node:test'); +const assert = require('node:assert'); +const fs = require('fs'); +const path = require('path'); + +describe('pause-work improvements', () => { + let pauseContent; + + test('pause-work.md exists', () => { + const p = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'); + assert.ok(fs.existsSync(p)); + pauseContent = fs.readFileSync(p, 'utf-8'); + }); + + test('#1489: pause-work detects non-phase contexts (spike, deliberation, research)', () => { + pauseContent = pauseContent || fs.readFileSync( + path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'), 'utf-8' + ); + assert.ok(pauseContent.includes('spike') || pauseContent.includes('Spike'), + 'pause-work should handle spike context'); + assert.ok(pauseContent.includes('deliberation') || pauseContent.includes('research'), + 'pause-work should handle deliberation/research context'); + }); + + test('#1489: pause-work writes to non-phase paths when appropriate', () => { + pauseContent = pauseContent || fs.readFileSync( + path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'), 'utf-8' + ); + assert.ok(pauseContent.includes('.planning/.continue-here') || + pauseContent.includes('.planning/spikes') || + pauseContent.includes('non-phase'), + 'pause-work should write to root .planning/ when not in a phase'); + }); + + test('#1490: continue-here template includes required-reading section', () => { + pauseContent = pauseContent || fs.readFileSync( + path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'), 'utf-8' + ); + assert.ok(pauseContent.includes('Required Reading') || pauseContent.includes('required-reading'), + 'Template should include Required Reading section'); + }); + + test('#1490: continue-here template includes anti-patterns section', () => { + pauseContent = pauseContent || fs.readFileSync( + path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'), 'utf-8' + ); + assert.ok(pauseContent.includes('Anti-Pattern') || pauseContent.includes('anti-pattern') || + pauseContent.includes('do NOT repeat'), + 'Template should include Anti-Patterns section'); + }); + + test('#1490: continue-here template includes infrastructure-state section', () => { + pauseContent = pauseContent || fs.readFileSync( + path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'), 'utf-8' + ); + assert.ok(pauseContent.includes('Infrastructure') || pauseContent.includes('infrastructure'), + 'Template should include Infrastructure State section'); + }); + + test('#1487: pause-work documents pre-execution critique gate', () => { + pauseContent = pauseContent || fs.readFileSync( + path.join(__dirname, '..', 'get-shit-done', 'workflows', 'pause-work.md'), 'utf-8' + ); + assert.ok( + pauseContent.includes('critique') || pauseContent.includes('design gate') || + pauseContent.includes('Pre-Execution'), + 'pause-work should document design critique gate for design→execution transitions' + ); + }); +});