| name | gse-resume |
| description | Reload checkpoint, verify worktrees, brief user. Triggered by /gse:resume. |
GSE-One Resume — Session Resume
Arguments: $ARGUMENTS
Options
| Flag / Sub-command | Description |
|---|
| (no args) | Resume from the latest checkpoint |
--checkpoint FILE | Resume from a specific checkpoint file |
--list | List all available checkpoints |
--help | Show this command's usage summary |
Prerequisites
Before executing, read (in priority order — load essential state first, defer the rest):
.gse/status.yaml — current state (highest priority)
.gse/plan.yaml — living sprint plan (if it exists) — source of workflow trajectory
.gse/profile.yaml — user profile and preferences
.gse/config.yaml — project configuration
.gse/backlog.yaml — sprint tasks only (current sprint filter)
- Remaining files loaded on demand during workflow
Workflow
Step 0 — Verify Pause State
Read status.yaml → session_paused and status.yaml → pause_checkpoint to confirm the project is in a coherent paused state before searching for a checkpoint to load. This step closes the read-side gap of the pause.md ↔ resume.md state symmetry: pause Step 3 writes session_paused: true + pause_checkpoint: checkpoint-{...}.yaml and resume Step 6 clears them, but until v0.62.2 these two fields were write-only — never consulted to drive resume behavior.
Skip conditions:
- If
--list is specified, skip this step entirely (read-only listing has no state to validate).
- If
--checkpoint FILE is specified, this step still runs but only emits an informational note on inconsistency — it does not block the explicit override.
Three coherence cases:
-
Coherent paused state — session_paused: true AND pause_checkpoint is non-empty AND the file .gse/checkpoints/{pause_checkpoint} exists on disk.
- Use
pause_checkpoint as the default checkpoint for Step 1 (overrides the "latest by filename" search).
- Proceed silently.
-
Inconsistent paused state — session_paused: true BUT pause_checkpoint is empty OR the named file is missing on disk.
-
Not paused — session_paused: false (or absent for pre-v0.47.8 projects).
Step 1 — Load Checkpoint
-
If --list is specified:
- List all files in
.gse/checkpoints/ sorted by date (newest first)
- Display: timestamp, status_snapshot.current_sprint, status_snapshot.current_phase, note (if any)
- Exit
-
If --checkpoint FILE is specified:
- Load the specified checkpoint file
-
Otherwise:
- Use the
pause_checkpoint confirmed by Step 0 case 1 if a coherent paused state was detected.
- Otherwise (Step 0 case 2 "Use latest" or case 3 "Force resume from latest"), find the latest checkpoint in
.gse/checkpoints/ (sorted by filename, newest first).
- If no checkpoints exist: report "No checkpoint found. Use
/gse:go to start." and exit.
-
Read the checkpoint YAML and extract: git_state.worktrees, status_snapshot, backlog_sprint_snapshot, last_task, note
Step 2 — Verify Worktrees
Run git worktree list to get the current worktree state on disk.
For each worktree recorded in the checkpoint:
Worktree is present
-
Check for external changes since the checkpoint:
git log {saved_last_commit}..HEAD --oneline
(executed within the worktree directory)
-
If new commits exist: mark as [CHANGED] — someone (or another session) modified this branch
-
If no new commits: mark as [OK] — unchanged since pause
-
Check for uncommitted changes: mark as [DIRTY] if any
Worktree is missing
- Mark as
[MISSING]
- Check if the branch still exists:
git branch --list {branch_name}
- If branch exists: propose recreation:
git worktree add {original_path} {branch_name}
- If branch is also missing, consult the class-2 backup tags before declaring anything lost (DELIVER Step 0 tags every branch it deletes — spec §10.6 — Safety and Recovery):
git tag -l "gse-backup/sprint-{NN}-{type}-{name}-deleted"
- Tag exists and its commit is in main (
git merge-base --is-ancestor <tag> main): report as [DELIVERED] — the work was merged and the branch cleaned up; the checkpoint is simply stale. Informational, no action needed.
- Tag exists but its commit is NOT in main: report as
[LOST] with recovery available — the Step 3 Gate offers Recover from backup tag.
- No tag: report as
[LOST] — manual intervention needed (spec §10.6 — Safety and Recovery).
No worktrees in the checkpoint (branch-only / none strategy)
If git_state.worktrees[] is empty, verify the current branch instead, with the same grid:
- Compare
git branch --show-current with git_state.current_branch — if different, note the branch switch in the report.
- New commits since pause:
git log {git_state.head}..HEAD --oneline → any output → [CHANGED], else [OK]. (If git_state.head is absent — checkpoint predating this field — skip this comparison with an Inform note.)
- Uncommitted changes:
git status --porcelain → any output → additionally [DIRTY] (this catches changes left uncommitted by the Pause Commit Gate option 3 or --no-commit, as well as edits made outside GSE between sessions).
- Include the branch line in the Step 3 report with the same symbols as worktrees.
Step 3 — Report Worktree State
Display worktree verification results with symbols:
WORKTREES
[OK] .worktrees/sprint-02-feat-api — TASK-003 (unchanged)
[CHANGED] .worktrees/sprint-02-feat-auth — TASK-004 (2 new commits since pause)
[DIRTY] .worktrees/sprint-02-doc-readme — TASK-005 (uncommitted changes)
[MISSING] .worktrees/sprint-02-test-unit — TASK-006 (branch exists, propose recreate)
[DELIVERED] .worktrees/sprint-01-feat-done — TASK-001 (merged to main, cleaned up — stale checkpoint)
[LOST] .worktrees/sprint-01-feat-old — TASK-002 (branch deleted, backup tag found)
If any worktrees are [MISSING] or [LOST], present Gate:
- Recreate — Recreate missing worktrees from their branches
- Recover from backup tag — for
[LOST] entries with a backup tag (spec §10.6 — Safety and Recovery): git branch {branch_name} gse-backup/sprint-{NN}-{type}-{name}-deleted, then recreate the worktree
- Skip — Continue without them
- Discuss — Investigate what happened
[DELIVERED] entries need no Gate — mention them in the Step 4 briefing as already merged (stale checkpoint, nothing to recover).
Step 4 — Context Briefing
Present a summary of where the user left off:
SESSION RESUMED
Paused: {checkpoint_timestamp} ({relative time, e.g., "2 days ago"})
Sprint: S{NN} ({current_phase})
Last activity: {last_activity}
Last task: TASK-{ID} ({task_title})
Open the briefing with the session context: "You paused while working on {last_task}." (skip if last_task is empty).
If a note was attached to the checkpoint:
Note: "{note text}"
Sprint progress:
Tasks: {done}/{total} complete
Budget: {used}/{total} complexity points
Health: {health.score}/10
If .gse/plan.yaml exists with status: active, append a workflow trajectory block:
Next in plan: {workflow.active}
Pending: {workflow.pending}
Completed: {count} of {expected_count}
{if coherence.alerts is non-empty}:
⚠ Alerts: {list of active alerts}
This is more precise than status.yaml.last_activity alone (which says "where we were" but not "where we're going"). For beginners, translate the activity names per P9 Adaptive Communication (e.g., reqs → "writing down what the app should do", produce → "building").
Step 5 — Propose Next Action
Determine the next action using, in priority order:
- Primary —
.gse/plan.yaml.workflow.active if plan.yaml exists with status: active. The workflow's active field is the declarative source of truth for "what comes next" (see orchestrator Decision Tree). This is more reliable than inferring from last_activity.
- Fallback —
status_snapshot.last_activity if plan.yaml is absent (Micro mode or pre-v0.20 projects). Use the table below.
| Checkpoint State | Proposed Action |
|---|
last_activity: /gse:produce, task in-progress | "Continue producing TASK-{ID}: {title}" → /gse:produce --task {ID} |
last_activity: /gse:produce, task done | "All production done. Ready for review." → /gse:review |
last_activity: /gse:review, fixes pending | "Review complete, fixes needed." → /gse:fix |
last_activity: /gse:fix | "Fixes applied. Ready for delivery." → /gse:deliver |
last_activity: /gse:deliver | "Sprint delivered. Time to capitalize." → /gse:compound |
last_activity: /gse:compound | "Capitalization done. Ready to integrate." → /gse:integrate |
last_activity: /gse:pause (nested) | Unwrap to the activity before the pause |
Present the proposal and wait for user confirmation.
Step 6 — Finalize
- Update
status.yaml session state only:
session_paused: false
- Reset
pause_checkpoint: "" (empty string — preserves schema stability vs dropping the field; readers get a well-defined absence representation)
- Update
sessions_without_progress — compare current backlog.yaml TASK statuses against status.yaml → task_status_snapshot (map TASK-id → status written at the end of this step; treat an absent or empty snapshot as "first session" → reset to 0). If no TASK status has changed since the last session → increment sessions_without_progress by 1; if at least one has changed → reset to 0. Then refresh the snapshot: write the current map of {TASK-id: status} to status.yaml → task_status_snapshot. This drives the stale-sprint Gate (see /gse:go Step 4 — Stale Sprint Detection) and the coach mid_sprint_stall event trigger (feeds axes 3-4 — sprint velocity, workflow health; activates at >= 2).
- Integrity-counter backstop — run
python3 "$([ -s .gse/registry ] && cat .gse/registry || cat ~/.gse-one)/tools/counters.py" health; if "stale": true, emit the same Inform note as /gse:go Step 4 — Stale Sprint Detection (P16 integrity counters unmoved across ≥ 5 transitions — re-check spec §P16 counting obligations).
- (Cursor fields
last_activity, last_activity_timestamp are maintained centrally by the orchestrator after the activity closes — see plugin/agents/gse-orchestrator.md — section "Sprint Plan Maintenance", and gse-one-implementation-design.md §10.1 — Sprint Plan Lifecycle (v0.53.0). RESUME writes no cursor fields directly.)
- The session is now active. Proceed with the accepted action or wait for user command.