Checkpointing
Capture durable session context without growing the always-loaded root
CLAUDE.md. Canonical state and artifacts live under .claude/.
Owned Paths
.claude/checkpoints/: full timestamped checkpoints; never deleted by the
compact phase.
.claude/checkpoints/INDEX.md: generated catalog of every checkpoint.
PROGRESS.md: latest five checkpoint summaries.
.claude/STATE.md: one Progress Tracker link and current working blocks.
.claude/logs/: drafts, previews, work logs, and CLI activity.
.claude/docs/research/: research notes; inactive notes may be archived only
after user approval.
Both scripts write nothing without --apply. Every default run produces preview
files under .claude/logs/ and leaves PROGRESS.md and .claude/STATE.md
untouched.
Full Checkpoint
Determine the time window from the newest checkpoint, or use all available
history when none exists.
Gather the user requests and decisions from the current conversation, git
changes, CLI logs, team work logs, and relevant design changes.
Write a Japanese five-part summary containing:
何をしたのか, どういうやり取りをユーザーと行ったのか, どうやったのか,
途中でどういう課題が起こったのか, and 将来のアクション.
This is the irreducible judgment in the skill and is never generated: a
missing, empty, stale, or incomplete summary aborts the run with exit 2.
Save the summary to .claude/logs/pending-summary.md, then preview:
python3 .claude/skills/checkpointing/checkpoint.py \
--summary-file .claude/logs/pending-summary.md
Exit 0 reports result: preview and four preview files
(checkpoint-preview-*, index-preview-*, progress-preview-*,
state-preview-* under .claude/logs/). Exit 1 is a bad --since /
--now; exit 2 is a summary or shared-state contract violation; exit 3
is a timestamp collision, a concurrent modification, or a write failure.
Add --label <slug> when the session's commit messages would not name it
well; the label becomes the checkpoint's slug in the frontmatter and the
index.
Review the four previews, then write for real:
python3 .claude/skills/checkpointing/checkpoint.py \
--summary-file .claude/logs/pending-summary.md \
--apply --consume-summary --json
--consume-summary deletes the draft on success, so the next session cannot
silently embed this session's summary. --json emits the single payload
{ok, result, checkpoint_path, prompt_path, index_path, slug, tags, progress_path, progress_entries, state_path, state_updated, summary_validated, summary_consumed, commits, files_changed, cli_consultations, agent_teams, work_logs, collector_errors, skipped_records, warnings, artifacts}; without it the same facts are printed
as prose. Quote collector_errors and warnings verbatim when reporting —
a failed collector is not an empty session.
Confirm the shared-state invariant mechanically rather than by reading:
python3 .claude/skills/checkpointing/refresh_guard.py --mode check
Exit 0 means exactly one # Agent State and one ## Progress Tracker
heading; exit 2 means the structure is invalid.
Review whether durable architecture decisions belong in
.claude/docs/DESIGN.md; use /design-tracker when warranted.
Run the Compact Phase below.
Finding a Past Checkpoint
Three layers make retrieval cheap, so a past session is found without reading
the directory file by file:
.claude/checkpoints/INDEX.md — one table, newest first, with the
branch, tags, counts, and headline for every checkpoint. Read this first and
scan the tags and summary columns.
- YAML frontmatter — each checkpoint opens with
id, timestamp,
branch, slug, summary, tags, and the session counts. Reading the
first ~14 lines settles relevance without parsing the document.
PROGRESS.md — the five most recent summaries in full, for the common
case of "what happened lately".
INDEX.md is regenerated from the checkpoints' frontmatter on every --apply,
so a deleted or hand-edited checkpoint is reflected on the next run rather than
advertised forever. Checkpoint filenames stay YYYY-MM-DD-HHMMSS.md: the slug
lives in the metadata, not the path, so PROGRESS.md links and
collect_repo_state.py keep working. Do not hand-edit INDEX.md.
Compact Phase
The compact phase keeps only the newest ## Current Project,
## Current Feature, and ## Current Bug Fix block of each category. Every
other section is preserved verbatim in document order — ## Main Agent,
## Repository Identity, ## Progress Tracker, and any manual notes, which
.claude/rules/agent-state.md explicitly sanctions. A section that would still
be lost is reported in sections_dropped and aborts the run with exit 2.
Inspect the state, the compaction preview, and the suggested archive moves:
python3 .claude/skills/checkpointing/refresh_guard.py --mode plan
Reports blocks_pruned, sections_preserved, sections_dropped,
research_notes, and move_plan. move_plan entries carry
suggested: true: they come from a stem-mention heuristic and are never a
decision.
Write the candidate state to a draft:
python3 .claude/skills/checkpointing/refresh_guard.py --mode compose
Review .claude/logs/composed-state.md and the reported move plan.
Ask for approval before replacing .claude/STATE.md or moving research
notes. Never delete checkpoint files or regenerate PROGRESS.md here.
After approval, apply the compaction with the script — never by hand:
python3 .claude/skills/checkpointing/refresh_guard.py --mode apply
python3 .claude/skills/checkpointing/refresh_guard.py --mode apply --apply
The first call previews to .claude/logs/state-compaction-preview-*.md and
reports state_hash_before. The second writes atomically, refuses if
.claude/STATE.md changed since it was read, and validates the composed
bytes before replacing. Pass --expect-hash <state_hash_before> to pin the
exact revision that was approved.
Confirm the compaction landed:
python3 .claude/skills/checkpointing/refresh_guard.py --mode verify
verify compares the on-disk state against a freshly composed candidate and
reports compaction_applied. Exit 2 means redundant work blocks remain.
Safety Gates
- Root
AGENTS.md and CLAUDE.md are never modified.
INDEX.md is generated, never hand-maintained; it is not a checkpoint and is
never listed in PROGRESS.md.
- State structure must contain exactly one
# Agent State heading and one
## Progress Tracker heading.
- Archive destinations use
.claude/docs/research/archive/; append when a
destination already exists.
- All destructive moves require an explicit preview and user approval.
- Report the checkpoint path, state blocks pruned, sections preserved, research
notes archived, validation result, and remaining risks in Japanese.
1---2name: checkpointing3description: Save session activity, rebuild rolling PROGRESS.md, and compact stale working blocks in .claude/STATE.md.4---56# Checkpointing78Capture durable session context without growing the always-loaded root9`CLAUDE.md`. Canonical state and artifacts live under `.claude/`.1011## Owned Paths1213- `.claude/checkpoints/`: full timestamped checkpoints; never deleted by the14 compact phase.15- `.claude/checkpoints/INDEX.md`: generated catalog of every checkpoint.16- `PROGRESS.md`: latest five checkpoint summaries.17- `.claude/STATE.md`: one Progress Tracker link and current working blocks.18- `.claude/logs/`: drafts, previews, work logs, and CLI activity.19- `.claude/docs/research/`: research notes; inactive notes may be archived only20 after user approval.2122Both scripts write nothing without `--apply`. Every default run produces preview23files under `.claude/logs/` and leaves `PROGRESS.md` and `.claude/STATE.md`24untouched.2526## Full Checkpoint27281. Determine the time window from the newest checkpoint, or use all available29 history when none exists.302. Gather the user requests and decisions from the current conversation, git31 changes, CLI logs, team work logs, and relevant design changes.323. Write a Japanese five-part summary containing:33 `何をしたのか`, `どういうやり取りをユーザーと行ったのか`, `どうやったのか`,34 `途中でどういう課題が起こったのか`, and `将来のアクション`.35 This is the irreducible judgment in the skill and is never generated: a36 missing, empty, stale, or incomplete summary aborts the run with exit `2`.374. Save the summary to `.claude/logs/pending-summary.md`, then preview:3839 ```bash40 python3 .claude/skills/checkpointing/checkpoint.py \41 --summary-file .claude/logs/pending-summary.md42 ```4344 Exit `0` reports `result: preview` and four preview files45 (`checkpoint-preview-*`, `index-preview-*`, `progress-preview-*`,46 `state-preview-*` under `.claude/logs/`). Exit `1` is a bad `--since` /47 `--now`; exit `2` is a summary or shared-state contract violation; exit `3`48 is a timestamp collision, a concurrent modification, or a write failure.4950 Add `--label <slug>` when the session's commit messages would not name it51 well; the label becomes the checkpoint's slug in the frontmatter and the52 index.535. Review the four previews, then write for real:5455 ```bash56 python3 .claude/skills/checkpointing/checkpoint.py \57 --summary-file .claude/logs/pending-summary.md \58 --apply --consume-summary --json59 ```6061 `--consume-summary` deletes the draft on success, so the next session cannot62 silently embed this session's summary. `--json` emits the single payload63 `{ok, result, checkpoint_path, prompt_path, index_path, slug, tags,64 progress_path, progress_entries, state_path, state_updated,65 summary_validated, summary_consumed, commits, files_changed,66 cli_consultations, agent_teams, work_logs, collector_errors,67 skipped_records, warnings, artifacts}`; without it the same facts are printed68 as prose. Quote `collector_errors` and `warnings` verbatim when reporting —69 a failed collector is not an empty session.706. Confirm the shared-state invariant mechanically rather than by reading:7172 ```bash73 python3 .claude/skills/checkpointing/refresh_guard.py --mode check74 ```7576 Exit `0` means exactly one `# Agent State` and one `## Progress Tracker`77 heading; exit `2` means the structure is invalid.787. Review whether durable architecture decisions belong in79 `.claude/docs/DESIGN.md`; use `/design-tracker` when warranted.808. Run the Compact Phase below.8182## Finding a Past Checkpoint8384Three layers make retrieval cheap, so a past session is found without reading85the directory file by file:86871. **`.claude/checkpoints/INDEX.md`** — one table, newest first, with the88 branch, tags, counts, and headline for every checkpoint. Read this first and89 scan the tags and summary columns.902. **YAML frontmatter** — each checkpoint opens with `id`, `timestamp`,91 `branch`, `slug`, `summary`, `tags`, and the session counts. Reading the92 first ~14 lines settles relevance without parsing the document.933. **`PROGRESS.md`** — the five most recent summaries in full, for the common94 case of "what happened lately".9596`INDEX.md` is regenerated from the checkpoints' frontmatter on every `--apply`,97so a deleted or hand-edited checkpoint is reflected on the next run rather than98advertised forever. Checkpoint filenames stay `YYYY-MM-DD-HHMMSS.md`: the slug99lives in the metadata, not the path, so `PROGRESS.md` links and100`collect_repo_state.py` keep working. Do not hand-edit `INDEX.md`.101102## Compact Phase103104The compact phase keeps only the newest `## Current Project`,105`## Current Feature`, and `## Current Bug Fix` block of each category. **Every106other section is preserved verbatim in document order** — `## Main Agent`,107`## Repository Identity`, `## Progress Tracker`, and any manual notes, which108`.claude/rules/agent-state.md` explicitly sanctions. A section that would still109be lost is reported in `sections_dropped` and aborts the run with exit `2`.1101111. Inspect the state, the compaction preview, and the suggested archive moves:112113 ```bash114 python3 .claude/skills/checkpointing/refresh_guard.py --mode plan115 ```116117 Reports `blocks_pruned`, `sections_preserved`, `sections_dropped`,118 `research_notes`, and `move_plan`. `move_plan` entries carry119 `suggested: true`: they come from a stem-mention heuristic and are never a120 decision.1211222. Write the candidate state to a draft:123124 ```bash125 python3 .claude/skills/checkpointing/refresh_guard.py --mode compose126 ```1271283. Review `.claude/logs/composed-state.md` and the reported move plan.1294. Ask for approval before replacing `.claude/STATE.md` or moving research130 notes. Never delete checkpoint files or regenerate `PROGRESS.md` here.1315. After approval, apply the compaction with the script — never by hand:132133 ```bash134 python3 .claude/skills/checkpointing/refresh_guard.py --mode apply135 python3 .claude/skills/checkpointing/refresh_guard.py --mode apply --apply136 ```137138 The first call previews to `.claude/logs/state-compaction-preview-*.md` and139 reports `state_hash_before`. The second writes atomically, refuses if140 `.claude/STATE.md` changed since it was read, and validates the composed141 bytes before replacing. Pass `--expect-hash <state_hash_before>` to pin the142 exact revision that was approved.1431446. Confirm the compaction landed:145146 ```bash147 python3 .claude/skills/checkpointing/refresh_guard.py --mode verify148 ```149150 `verify` compares the on-disk state against a freshly composed candidate and151 reports `compaction_applied`. Exit `2` means redundant work blocks remain.152153## Safety Gates154155- Root `AGENTS.md` and `CLAUDE.md` are never modified.156- `INDEX.md` is generated, never hand-maintained; it is not a checkpoint and is157 never listed in `PROGRESS.md`.158- State structure must contain exactly one `# Agent State` heading and one159 `## Progress Tracker` heading.160- Archive destinations use `.claude/docs/research/archive/`; append when a161 destination already exists.162- All destructive moves require an explicit preview and user approval.163- Report the checkpoint path, state blocks pruned, sections preserved, research164 notes archived, validation result, and remaining risks in Japanese.