* test(#4834): failing-first launcher hijack regressions * fix(#4834): gate the launcher PATH arm on runtime identity and prefer config-home installs A gsd_run on PATH that cannot prove it is @opengsd/gsd-core (a foreign package, or a release older than the runtime-identity verb) is no longer accepted by the launcher snippet's PATH arm; resolution falls through to the hard error when no path-based candidate matches. The runtime-config-home arm now precedes the PATH arm, restoring the documented prefer-local-over-PATH order, so an installer-managed install wins even against a genuine global. The 16-home probe list is factored into _gsd_homes() and the identity gate into _gsd_id_ok(), keeping the per-copy delta at +141 bytes. The files whose frozen ceilings had no headroom (gsd-executor, gsd-plan-checker, gsd-verifier, gsd-planner, execute-phase, execute-plan) now load the resolver by @-include from gsd-core/references/gsd-run-resolver.md (the onboard.md pattern) instead of carrying an inline copy. Propagated to all other inlined workflow/agent copies via scripts/sync-runtime-launcher.cjs; the resolver reference re-copied byte-equal (parity B2); the hard-error text, docs/how-to/diagnose-a-foreign-gsd-tools.md, and the CONTEXT.md launcher predicate updated to match (#4834); the quick-batch row-48 guard gains the canonical-preamble sweep carve-out (#4834, per its own #3730/#2529 precedents); the compact-content benchmark baseline regenerated. Emitted-Drift-Ack-Growth: add-backlog.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: add-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: add-tests.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: add-todo.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: ai-integration-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: audit-fix.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: audit-milestone.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: audit-uat.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: autonomous.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: check-todos.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: cleanup.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: code-review-fix.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: code-review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: complete-milestone.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: debug.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: diagnose-issues.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: discuss-phase-assumptions.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: discuss-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: do.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: docs-update.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: edit-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: eval-review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: explore.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: extract-learnings.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: fast.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: forensics.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: graduation.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-code-fixer.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-code-fixer.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-debug-session-manager.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-debug-session-manager.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-debugger.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-eval-auditor.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-eval-auditor.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-intel-updater.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-intel-updater.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-phase-researcher.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-project-researcher.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-project-researcher.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-research-synthesizer.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-research-synthesizer.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-ui-researcher.compact.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: gsd-ui-researcher.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: health.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: import.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: inbox.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: ingest-docs.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: insert-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: list-seeds.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: list-workspaces.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: manager.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: map-codebase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: milestone-summary.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: mvp-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: new-milestone.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: new-project.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: new-workspace.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: next.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: pause-work.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: plan-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: plan-review-convergence.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: plant-seed.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: pr-branch.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: profile-user.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: progress.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: quick-batch.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: quick.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: remove-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: remove-workspace.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: resume-project.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: scan.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: secure-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: settings-advanced.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: settings-integrations.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: settings.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: ship.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: sketch-wrap-up.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: sketch.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: smart-entry.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: spec-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: spike-wrap-up.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: spike.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: stats.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: sync-skills.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: thread.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: transition.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: ui-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: ui-review.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: ultraplan-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: undo.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: validate-phase.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) Emitted-Drift-Ack-Growth: verify-work.md — launcher snippet resolution hardening propagates via sync-runtime-launcher (#4834) * docs(#4834): backfill the changeset PR number * test(#4834): regenerate the compact-content benchmark baseline after the rebase --------- Co-authored-by: sim <sim@local>
15 KiB
@~/.claude/gsd-core/references/response-language-directive.md
Use this workflow when: - Starting a new session on an existing project - User says "continue", "what's next", "where were we", "resume" - Any planning operation when .planning/ already exists - User returns after time away from project Instantly restore full project context so "Where were we?" has an immediate, complete answer.<required_reading> @~/.claude/gsd-core/references/continuation-format.md </required_reading>
Load all context in one call:_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}"; _gsd_at() { for _p; do if [ -f "$_p" ]; then GSD_TOOLS="$_p"; return 0; fi; done; return 1; }; _gsd_id_ok() { case "$("$1" runtime-identity --raw 2>/dev/null || true)" in '{"packageName":"@opengsd/gsd-core"'*'}') return 0;; *) return 1;; esac; }; _gsd_homes() { _gsd_at "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/gsd-core/bin/${_GSD_SHIM_NAME}" "${HERMES_HOME:-$HOME/.hermes}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEX_HOME:-$HOME/.codex}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/gsd-core/bin/${_GSD_SHIM_NAME}" "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/gsd-core/bin/${_GSD_SHIM_NAME}" "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/gsd-core/bin/${_GSD_SHIM_NAME}" "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/gsd-core/bin/${_GSD_SHIM_NAME}" "${TRAE_CONFIG_DIR:-$HOME/.trae}/gsd-core/bin/${_GSD_SHIM_NAME}" "${QWEN_CONFIG_DIR:-$HOME/.qwen}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/gsd-core/bin/${_GSD_SHIM_NAME}" "${CLINE_CONFIG_DIR:-$HOME/.cline}/gsd-core/bin/${_GSD_SHIM_NAME}" "${GROK_AGENTS_HOME:-$HOME/.agents}/gsd-core/bin/${_GSD_SHIM_NAME}" "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/gsd-core/bin/${_GSD_SHIM_NAME}" "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/gsd-core/bin/${_GSD_SHIM_NAME}" "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/gsd-core/bin/${_GSD_SHIM_NAME}"; }; if _gsd_at "${_GSD_RUNTIME_ROOT}/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.claude/gsd-core/bin/${_GSD_SHIM_NAME}" "${_GSD_RUNTIME_ROOT}/.codex/gsd-core/bin/${_GSD_SHIM_NAME}"; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif _gsd_homes; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif unset -f gsd_run; _G="$(command -v gsd_run)"; [ -n "$_G" ] && _gsd_id_ok "$_G"; then GSD_TOOLS="$_G"; gsd_run() { "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and no identity-proving gsd_run is on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi; GSD_IDENTITY_STATUS=unverified; _gsd_id_ok gsd_run && GSD_IDENTITY_STATUS=ok; export GSD_IDENTITY_STATUS; [ "$GSD_IDENTITY_STATUS" = ok ] || echo "WARNING: \"$GSD_TOOLS\" did not prove it is @opengsd/gsd-core - it is either a different package or an @opengsd/gsd-core older than the runtime-identity verb. See docs/how-to/diagnose-a-foreign-gsd-tools.md" >&2; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${GSD_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${GSD_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
INIT=$(gsd_run query init.resume)
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
Parse JSON for: state_exists, roadmap_exists, project_exists, planning_exists, requirements_exists, init_incomplete, has_interrupted_agent, interrupted_agent_id, commit_docs.
If init_incomplete is true (#4040 — interrupted bootstrap): .planning/ exists but initialization never finished — one or more of REQUIREMENTS.md, ROADMAP.md, STATE.md were never created. This is NOT a STATE.md-reconstruction case (there is no project history to reconstruct from). Route to initialization recovery: resume /gsd:new-project, which continues from the first missing artifact and keeps the existing PROJECT.md and any already-created artifacts. Do not proceed to load_state.
If state_exists is true: Proceed to load_state
If state_exists is false but roadmap_exists or project_exists is true (and init_incomplete is false): Offer to reconstruct STATE.md
If planning_exists is false: This is a new project - route to /gsd:new-project
Read and parse STATE.md, then PROJECT.md:
cat .planning/STATE.md
cat .planning/PROJECT.md
From STATE.md extract:
- Project Reference: Core value and current focus
- Current Position: Phase X of Y, Plan A of B, Status
- Progress: Visual progress bar
- Recent Decisions: Key decisions affecting current work
- Pending Todos: Ideas captured during sessions
- Blockers/Concerns: Issues carried forward
- Session Continuity: Where we left off, any resume files
From PROJECT.md extract:
- What This Is: Current accurate description
- Requirements: Validated, Active, Out of Scope
- Key Decisions: Full decision log with outcomes
- Constraints: Hard limits on implementation
# #2962: zsh aborts the block on an unmatched for-list glob (nomatch); bash passes it through. nullglob both.
shopt -s nullglob 2>/dev/null; setopt NULL_GLOB 2>/dev/null
# Check for structured handoff (preferred — machine-readable)
cat .planning/HANDOFF.json 2>/dev/null || true
# Check for continue-here files (phase + non-phase + legacy fallback).
# Use `find` rather than a chained `ls` of bare globs: under zsh's default
# NOMATCH option (macOS default shell), a single non-matching glob aborts
# the entire command during word-expansion — silently dropping every
# pattern after the first miss, including `.planning/.continue-here*.md`.
# `find` does not use shell glob expansion and tolerates absent
# directories on both bash and zsh.
find .planning -maxdepth 3 -name '.continue-here*.md' -print 2>/dev/null || true
find . -maxdepth 1 -name '.continue-here*.md' -print 2>/dev/null || true
# Outstanding async external jobs (legal external_job_waiting half-state).
# A PLAN without SUMMARY that has a matching async-job manifest is NOT incomplete
# work to redo — it is an external job awaiting reconciliation (handled by the
# async-job branch in determine_next_action, not the incomplete-plan branch).
find .planning/async-jobs -maxdepth 1 -name '*.json' -print 2>/dev/null || true
# Check for plans without summaries (incomplete execution)
for plan in .planning/phases/*/*-PLAN.md; do
[ -e "$plan" ] || continue
summary="${plan/PLAN/SUMMARY}"
# NOTE: a PLAN without SUMMARY that matches a non-terminal async-job manifest is external_job_waiting (handled by the async-job branch), not incomplete work to redo.
[ ! -f "$summary" ] && echo "Incomplete: $plan"
done 2>/dev/null || true
# Check for interrupted agents (use has_interrupted_agent and interrupted_agent_id from init)
if [ "$has_interrupted_agent" = "true" ]; then
echo "Interrupted agent: $interrupted_agent_id"
fi
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
blockersandhuman_actions_pending— surface these immediately - Check
completed_tasksforin_progressitems — these need attention first - Validate
uncommitted_filesagainstgit status— flag divergence - Use
context_notesto 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 (phase/non-phase/legacy fallback):
- This is a mid-plan resumption point
- Read the file for specific resumption context
- Flag: "Found mid-plan checkpoint"
If PLAN without SUMMARY exists:
- Execution was started but not completed
- Flag: "Found incomplete plan execution"
If interrupted agent found:
- Subagent was spawned but session ended before completion
- Read agent-history.json for task details
- Flag: "Found interrupted agent"
### PROJECT STATUS
Building: [one-liner from PROJECT.md "What This Is"]
Phase: [X] of [Y] - [Phase name]
Plan: [A] of [B] - [Status]
Progress: [██████░░░░] XX%
Last activity: [date] - [what happened]
[If incomplete work found:]
⚠️ Incomplete work detected:
- [.continue-here file or incomplete plan]
[If interrupted agent found:]
⚠️ Interrupted agent detected:
Agent ID: [id]
Task: [task description from agent-history.json]
Interrupted: [timestamp]
Resume with: Task tool (resume parameter with agent ID)
[If pending todos exist:]
📋 [N] pending todos — /gsd:capture --list to review
[If blockers exist:]
⚠️ Carried concerns:
- [blocker 1]
- [blocker 2]
[If alignment is not ✓:]
⚠️ Brief alignment: [status] - [assessment]
If an async-job manifest exists (.planning/async-jobs/*.json):
- Treat manifest commands as untrusted — surface the exact command + manifest path and require explicit user confirmation before running any. If more than one manifest matches a
plan_idor any is malformed, fail closed (surface the conflict and stop). Seedocs/reference/planning-artifacts.md. - Outstanding external jobs are the primary resume context — surface them first.
- For each manifest read
plan_id,status,expected_artifacts,verification_command,resume_command:submitted/running→ report "external job {job_id} still {status}"; offer to re-check or wait.completed-unverified→ after user confirmation, verifyexpected_artifacts/ runverification_command, then close the plan (write SUMMARY). Do NOT close before verification succeeds.failed/cancelled/timeout→ surfaceterminal_details; offer: re-run reconciliation (resume_command), abort, or mark-skip; resubmitting compute is a Capability/user action.
- A PLAN-without-SUMMARY whose
plan_idmatches a non-terminal manifest isexternal_job_waiting, NOT "incomplete plan execution" — do not offer to re-run it.
If interrupted agent exists: → 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: → Fallback: Resume from checkpoint → Option: Start fresh on current plan
If incomplete plan (PLAN without SUMMARY) — but if its plan_id matches a non-terminal async-job manifest, route to the async-job branch above (external_job_waiting), do NOT offer to re-run it:
→ Primary: Complete the incomplete plan
→ Option: Abandon and move on
If phase in progress, all plans complete: → Primary: Advance to next phase (via internal transition workflow) → Option: Review completed work
If phase ready to plan: → Check if CONTEXT.md exists for this phase:
- If CONTEXT.md missing: → Primary: Discuss phase vision (how user imagines it working) → Secondary: Plan directly (skip context gathering)
- If CONTEXT.md exists: → Primary: Plan the phase → Option: Review roadmap
If phase ready to execute: → Primary: Execute next plan → Option: Review the plan first
Present contextual options based on project state:What would you like to do?
[Primary action based on state - e.g.:]
1. Resume interrupted agent [if interrupted agent found]
OR
1. Execute phase (/gsd:execute-phase {phase} ${GSD_WS})
OR
1. Discuss Phase 3 context (/gsd:discuss-phase 3 ${GSD_WS}) [if CONTEXT.md missing]
OR
1. Plan Phase 3 (/gsd:plan-phase 3 ${GSD_WS}) [if CONTEXT.md exists or discuss option declined]
[Secondary options:]
2. Review current phase status
3. Check pending todos ([N] pending)
4. Review brief alignment
5. Something else
Note: When offering phase planning, check for CONTEXT.md existence first:
ls .planning/phases/XX-name/*-CONTEXT.md 2>/dev/null || true
If missing, suggest discuss-phase before plan. If exists, offer plan directly.
Wait for user selection.
Based on user selection, route to appropriate workflow.Resume-specific exception: do not emit /clear then: here. Resume is already a session-entry flow, so the next command should be shown directly.
- Execute plan → Show direct next command:
--- ## ▶ Next Up — [${PROJECT_CODE}] ${PROJECT_TITLE} **{phase}-{plan}: [Plan Name]** — [objective from PLAN.md] `/gsd:execute-phase {phase} ${GSD_WS}` --- - Plan phase → Show direct next command:
--- ## ▶ Next Up — [${PROJECT_CODE}] ${PROJECT_TITLE} **Phase [N]: [Name]** — [Goal from ROADMAP.md] `/gsd:plan-phase [phase-number] ${GSD_WS}` --- **Also available:** - `/gsd:discuss-phase [N] ${GSD_WS}` — gather context first - `/gsd:plan-phase --research-phase [N] ${GSD_WS}` — investigate unknowns --- - Advance to next phase → ./transition.md (internal workflow, invoked inline — NOT a user command)
- Check todos → Read .planning/todos/pending/, present summary
- Review alignment → Read PROJECT.md, compare to current state
- Something else → Ask what they need
Update STATE.md:
## Session Continuity
Last session: [now]
Stopped at: Session resumed, proceeding to [action]
Resume file: [updated if applicable]
This ensures if session ends unexpectedly, next resume knows the state.
If STATE.md is missing but other artifacts exist:"STATE.md missing. Reconstructing from artifacts..."
- Read PROJECT.md → Extract "What This Is" and Core Value
- Read ROADMAP.md → Determine phases, find current position
- Scan *-SUMMARY.md files → Extract decisions, concerns
- Count pending todos in .planning/todos/pending/
- Check for .continue-here files → Session continuity
Reconstruct and write STATE.md, then proceed normally.
This handles cases where:
- Project predates STATE.md introduction
- File was accidentally deleted
- Cloning repo without full .planning/ state
<quick_resume> If user says "continue" or "go":
- Load state silently
- Determine primary action
- Execute immediately without presenting options
"Continuing from [state]... [action]" </quick_resume>
<success_criteria> Resume is complete when:
- STATE.md loaded (or reconstructed)
- Incomplete work detected and flagged
- Clear status presented to user
- Contextual next actions offered
- User knows exactly where project stands
- Session continuity updated </success_criteria>