Enhance /gsd:pause-work to write .planning/HANDOFF.json alongside .continue-here.md. The JSON provides machine-readable state that /gsd:resume-work can parse for precise resumption. HANDOFF.json includes: - Task position (phase, plan, task number, status) - Completed and remaining tasks with commit hashes - Blockers with type classification (technical/human_action/external) - Human actions pending (API keys, approvals, manual testing) - Uncommitted files list - Context notes for mental model restoration Resume-work changes: - HANDOFF.json is primary resumption source (highest priority) - Surfaces blockers and human actions immediately on session start - Validates uncommitted files against git status - Deletes HANDOFF.json after successful resumption - Falls back to .continue-here.md if no JSON exists Also checks for placeholder content in SUMMARY.md files to catch false completions (frontmatter claims complete but body has TBD). Fixes #940
This commit is contained in:
@@ -17,6 +17,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
### Fixed
|
||||
- **Requirements `mark-complete` is now idempotent** — Re-marking already-completed requirements returns `already_complete` instead of `not_found` (#948)
|
||||
|
||||
### Improved
|
||||
- **Structured session handoff** — `/gsd:pause-work` now writes `.planning/HANDOFF.json` alongside `.continue-here.md`. JSON provides machine-readable state (task position, blockers, human actions pending, uncommitted files) that `/gsd:resume-work` parses for precise resumption instead of generic "what do you want to do?" (#940)
|
||||
|
||||
## [1.25.0] - 2026-03-16
|
||||
|
||||
### Added
|
||||
|
||||
@@ -513,11 +513,13 @@
|
||||
**Purpose:** Maintain project continuity across context resets and sessions.
|
||||
|
||||
**Requirements:**
|
||||
- REQ-SESSION-01: Pause MUST save current position and next steps to `continue-here.md`
|
||||
- REQ-SESSION-02: Resume MUST restore full project context from state files
|
||||
- REQ-SESSION-01: Pause MUST save current position and next steps to `continue-here.md` and structured `HANDOFF.json`
|
||||
- REQ-SESSION-02: Resume MUST restore full project context from HANDOFF.json (preferred) or state files (fallback)
|
||||
- REQ-SESSION-03: Progress MUST show current position, next action, and overall completion
|
||||
- REQ-SESSION-04: Progress MUST read all state files (STATE.md, ROADMAP.md, phase directories)
|
||||
- REQ-SESSION-05: All session operations MUST work after `/clear` (context reset)
|
||||
- REQ-SESSION-06: HANDOFF.json MUST include blockers, human actions pending, and in-progress task state
|
||||
- REQ-SESSION-07: Resume MUST surface human actions and blockers immediately on session start
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -296,7 +296,7 @@ Controlled by `workflow.ui_safety_gate` config toggle.
|
||||
|---------|---------|-------------|
|
||||
| `/gsd:progress` | Show status and next steps | Anytime -- "where am I?" |
|
||||
| `/gsd:resume-work` | Restore full context from last session | Starting a new session |
|
||||
| `/gsd:pause-work` | Save context handoff | Stopping mid-phase |
|
||||
| `/gsd:pause-work` | Save structured handoff (HANDOFF.json + continue-here.md) | Stopping mid-phase |
|
||||
| `/gsd:help` | Show all commands | Quick reference |
|
||||
| `/gsd:update` | Update GSD with changelog preview | Check for new versions |
|
||||
| `/gsd:join-discord` | Open Discord community invite | Questions or community |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<purpose>
|
||||
Create `.continue-here.md` handoff file to preserve complete work state across sessions. Enables seamless resumption with full context restoration.
|
||||
Create structured `.planning/HANDOFF.json` and `.continue-here.md` handoff files to preserve complete work state across sessions. The JSON provides machine-readable state for `/gsd:resume-work`; the markdown provides human-readable context.
|
||||
</purpose>
|
||||
|
||||
<required_reading>
|
||||
@@ -27,10 +27,61 @@ If no active phase detected, ask user which phase they're pausing work on.
|
||||
3. **Work remaining**: What's left in current plan/phase
|
||||
4. **Decisions made**: Key decisions and rationale
|
||||
5. **Blockers/issues**: Anything stuck
|
||||
6. **Mental context**: The approach, next steps, "vibe"
|
||||
7. **Files modified**: What's changed but not committed
|
||||
6. **Human actions pending**: Things that need manual intervention (MCP setup, API keys, approvals, manual testing)
|
||||
7. **Background processes**: Any running servers/watchers that were part of the workflow
|
||||
8. **Files modified**: What's changed but not committed
|
||||
|
||||
Ask user for clarifications if needed via conversational questions.
|
||||
|
||||
**Also inspect SUMMARY.md files for false completions:**
|
||||
```bash
|
||||
# Check for placeholder content in existing summaries
|
||||
grep -l "To be filled\|placeholder\|TBD" .planning/phases/*/*.md 2>/dev/null
|
||||
```
|
||||
Report any summaries with placeholder content as incomplete items.
|
||||
</step>
|
||||
|
||||
<step name="write_structured">
|
||||
**Write structured handoff to `.planning/HANDOFF.json`:**
|
||||
|
||||
```bash
|
||||
timestamp=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" current-timestamp full --raw)
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"timestamp": "{timestamp}",
|
||||
"phase": "{phase_number}",
|
||||
"phase_name": "{phase_name}",
|
||||
"phase_dir": "{phase_dir}",
|
||||
"plan": {current_plan_number},
|
||||
"task": {current_task_number},
|
||||
"total_tasks": {total_task_count},
|
||||
"status": "paused",
|
||||
"completed_tasks": [
|
||||
{"id": 1, "name": "{task_name}", "status": "done", "commit": "{short_hash}"},
|
||||
{"id": 2, "name": "{task_name}", "status": "done", "commit": "{short_hash}"},
|
||||
{"id": 3, "name": "{task_name}", "status": "in_progress", "progress": "{what_done}"}
|
||||
],
|
||||
"remaining_tasks": [
|
||||
{"id": 4, "name": "{task_name}", "status": "not_started"},
|
||||
{"id": 5, "name": "{task_name}", "status": "not_started"}
|
||||
],
|
||||
"blockers": [
|
||||
{"description": "{blocker}", "type": "technical|human_action|external", "workaround": "{if any}"}
|
||||
],
|
||||
"human_actions_pending": [
|
||||
{"action": "{what needs to be done}", "context": "{why}", "blocking": true}
|
||||
],
|
||||
"decisions": [
|
||||
{"decision": "{what}", "rationale": "{why}", "phase": "{phase_number}"}
|
||||
],
|
||||
"uncommitted_files": [],
|
||||
"next_action": "{specific first action when resuming}",
|
||||
"context_notes": "{mental state, approach, what you were thinking}"
|
||||
}
|
||||
```
|
||||
</step>
|
||||
|
||||
<step name="write">
|
||||
@@ -92,19 +143,22 @@ timestamp=$(node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" current-timesta
|
||||
|
||||
<step name="commit">
|
||||
```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
|
||||
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
|
||||
```
|
||||
</step>
|
||||
|
||||
<step name="confirm">
|
||||
```
|
||||
✓ Handoff created: .planning/phases/[XX-name]/.continue-here.md
|
||||
✓ Handoff created:
|
||||
- .planning/HANDOFF.json (structured, machine-readable)
|
||||
- .planning/phases/[XX-name]/.continue-here.md (human-readable)
|
||||
|
||||
Current state:
|
||||
|
||||
- Phase: [XX-name]
|
||||
- Task: [X] of [Y]
|
||||
- Status: [in_progress/blocked]
|
||||
- Blockers: [count] ({human_actions_pending count} need human action)
|
||||
- Committed as WIP
|
||||
|
||||
To resume: /gsd:resume-work
|
||||
|
||||
@@ -63,6 +63,9 @@ cat .planning/PROJECT.md
|
||||
Look for incomplete work that needs attention:
|
||||
|
||||
```bash
|
||||
# Check for structured handoff (preferred — machine-readable)
|
||||
cat .planning/HANDOFF.json 2>/dev/null
|
||||
|
||||
# Check for continue-here files (mid-plan resumption)
|
||||
ls .planning/phases/*/.continue-here*.md 2>/dev/null
|
||||
|
||||
@@ -78,7 +81,18 @@ if [ "$has_interrupted_agent" = "true" ]; then
|
||||
fi
|
||||
```
|
||||
|
||||
**If .continue-here file exists:**
|
||||
**If HANDOFF.json exists:**
|
||||
|
||||
- This is the primary resumption source — structured data from `/gsd:pause-work`
|
||||
- Parse `status`, `phase`, `plan`, `task`, `total_tasks`, `next_action`
|
||||
- Check `blockers` and `human_actions_pending` — surface these immediately
|
||||
- Check `completed_tasks` for `in_progress` items — these need attention first
|
||||
- Validate `uncommitted_files` against `git status` — flag divergence
|
||||
- Use `context_notes` to restore mental model
|
||||
- Flag: "Found structured handoff — resuming from task {task}/{total_tasks}"
|
||||
- **After successful resumption, delete HANDOFF.json** (it's a one-shot artifact)
|
||||
|
||||
**If .continue-here file exists (fallback):**
|
||||
|
||||
- This is a mid-plan resumption point
|
||||
- Read the file for specific resumption context
|
||||
@@ -145,8 +159,12 @@ Based on project state, determine the most logical next action:
|
||||
→ Primary: Resume interrupted agent (Task tool with resume parameter)
|
||||
→ Option: Start fresh (abandon agent work)
|
||||
|
||||
**If HANDOFF.json exists:**
|
||||
→ Primary: Resume from structured handoff (highest priority — specific task/blocker context)
|
||||
→ Option: Discard handoff and reassess from files
|
||||
|
||||
**If .continue-here file exists:**
|
||||
→ Primary: Resume from checkpoint
|
||||
→ Fallback: Resume from checkpoint
|
||||
→ Option: Start fresh on current plan
|
||||
|
||||
**If incomplete plan (PLAN without SUMMARY):**
|
||||
|
||||
Reference in New Issue
Block a user