Skip to content

/gsd undo

/gsd undo rolls back the most recently completed unit. It finds the last unit by scanning the activity log directory, deletes its summary artifact, unchecks its task checkbox in the slice plan (for execute-task units), and attempts to revert the associated git commits.

This is the inverse of a completed dispatch — useful when a unit ran but produced wrong output, when you need to re-execute a task with different context, or when a chain of units needs to be rewound. Run it multiple times to undo multiple units in reverse order.

Because undo reaches into your git history, it requires explicit confirmation. Running /gsd undo without flags shows you exactly what would happen and asks you to re-run with --force to proceed.

/gsd undo
/gsd undo --force
InvocationBehavior
/gsd undoPreview mode — shows what will be undone, no changes made
/gsd undo --forceExecute — deletes artifacts, unchecks PLAN.md, reverts commits

Run /gsd status first if you’re unsure which unit was last completed.

  1. Scan activity logs — Lists .jsonl files in .gsd/activity/, sorted by filename in reverse order (most recent first). If the directory is missing or empty, undo exits with an info notice.
  2. Parse unit from filename — Extracts the unit type and ID from the most recent filename using the pattern <seq>-<unitType>-<unitId>.jsonl (e.g., 0042-execute-task-M001-S01-T01.jsonl). Dashes in the unit ID segment are converted back to slashes (M001-S01-T01M001/S01/T01). If the filename doesn’t match the expected pattern, undo exits with a warning.
  3. Preview (without --force) — Shows the unit type and ID that would be undone, and lists every action that would be taken. No changes are made.
  4. Delete summary artifact — The artifact produced by the unit is deleted from disk. For task-level units (M001/S01/T01), this is the <TID>-SUMMARY.md inside the tasks directory. For slice-level units (M001/S01), GSD looks for files matching <SID>-SUMMARY.md or <SID>-COMPLETE.md in the slice directory.
  5. Uncheck task in PLAN.md — For execute-task units, the corresponding checkbox in the slice’s PLAN.md is flipped from [x] back to [ ]. This keeps the plan file consistent with the reverted state.
  6. Revert git commits — GSD scans activity log files in .gsd/activity/ whose names contain both the unit type and unit ID. It reads the most recent matching file and extracts commit SHAs from tool_result blocks — specifically the [branch sha] tokens that git prints after a successful commit. Duplicate SHAs are deduplicated. Commits are reverted in reverse order using git revert --no-commit (or the libgit2 native equivalent when available). Reverts are staged but not committed — you review the diff and commit or reset yourself. If a revert conflict occurs, the remaining commits are skipped and undo continues.
  7. Re-derive state — All caches are invalidated and deriveState() re-reads the .gsd/ tree so subsequent commands reflect the reverted state. A desktop notification fires on completion.

When undo reverts git commits, it stages the reverse changes but leaves them uncommitted. This gives you a chance to inspect the diff before deciding:

Terminal window
git diff --cached # review what undo staged
git commit # commit the revert permanently
git reset HEAD # unstage if you want to handle it differently

This design avoids creating a “revert commit” you didn’t ask for, and it lets you combine the revert with other changes in a single commit.

GSD records agent activity in .gsd/activity/ as .jsonl files with sequenced names (e.g., 0042-execute-task-M001-S01-T01.jsonl). The sequence prefix is a zero-padded counter that ensures filenames sort chronologically. Each line is a JSON message. Undo finds commit SHAs by scanning tool_result blocks in the most recent matching file — specifically the [branch sha] tokens that git prints after a successful commit. Duplicate SHAs are deduplicated automatically.

If no activity file exists for the unit (e.g., the unit was completed in a previous GSD version or via /gsd skip), the git revert step is skipped silently. Artifact deletion and plan unchecking still happen.

Undo only operates on the last unit in the activity log — it has no --target option. To undo multiple units, run /gsd undo --force repeatedly. Activity log filenames are sequenced by dispatch time, so undo always works backwards through the execution history.

FilePurpose
.gsd/activity/Directory listing to find the most recent activity log
.gsd/activity/<seq>-<type>-<unitId>.jsonlMost recent log file — parsed for unit identity and commit SHAs
FilePurpose
.gsd/milestones/<MID>/slices/<SID>/<SID>-PLAN.mdTask checkbox unchecked (execute-task units only)
FileCondition
.gsd/milestones/<MID>/slices/<SID>/tasks/<TID>-SUMMARY.mdTask-level unit (M001/S01/T01)
.gsd/milestones/<MID>/slices/<SID>/<SID>-SUMMARY.mdSlice-level unit (M001/S01)
.gsd/milestones/<MID>/slices/<SID>/<SID>-COMPLETE.mdSlice-level unit (alternate suffix)

Previewing an undo without committing to it:

> /gsd undo
⚠ Will undo: execute-task (M001/S01/T01)
This will:
- Delete summary artifacts
- Uncheck task in PLAN (if execute-task)
- Attempt to revert associated git commits
Run /gsd undo --force to confirm.

Confirming and executing the undo:

> /gsd undo --force
✓ Undone: execute-task (M001/S01/T01)
- Deleted summary artifact
- Unchecked task in PLAN
- Reverted 2 commit(s) (staged, not committed)
Review with 'git diff --cached' then 'git commit' or 'git reset HEAD'

Undoing a slice-level unit (e.g., a run-uat that was run but produced bad results):

> /gsd undo --force
✓ Undone: run-uat (M001/S02)
- Deleted summary artifact

Nothing to undo:

> /gsd undo
ℹ Nothing to undo — no activity logs found.
  • /gsd skip — Mark a unit as completed without executing it (forward direction)
  • /gsd auto — Resume dispatch after undo; the reverted unit will be re-dispatched
  • /gsd status — Check which unit was last completed before running undo
  • /gsd forensics — Investigate what a unit produced before deciding to undo it
  • /gsd doctor — Repair structural issues without reverting execution history