Claude-agentic-coding-playbook checkpoint
Save all work, update memory, commit, push, and prepare to end the session. Use when user says "save my work", "wrap up", or "I'm done for now". Use at natural breakpoints or when context is getting large.
git clone https://github.com/john-wilmes/claude-agentic-coding-playbook
T=$(mktemp -d) && git clone --depth=1 https://github.com/john-wilmes/claude-agentic-coding-playbook "$T" && mkdir -p ~/.claude/skills && cp -r "$T/profiles/combined/skills/checkpoint" ~/.claude/skills/john-wilmes-claude-agentic-coding-playbook-checkpoint && rm -rf "$T"
profiles/combined/skills/checkpoint/SKILL.mdCheckpoint
Save all session state and prepare for a clean handoff to the next session. Delegates heavy work to a subagent to keep parent context lean.
Steps
0. Persist unsaved findings (parent does this — NOT the subagent)
Before delegating, review the conversation for any research findings, evidence, analysis, or detailed information that was discussed but not yet written to a memory topic file. This is the #1 cause of data loss at checkpoint — the subagent cannot see conversation context, so anything not already in a file will be lost.
For each unsaved finding:
- Write it to an appropriate topic file in the project's memory directory (e.g.
,project_<topic>.md
)feedback_<topic>.md - Include the full detail — do NOT summarize or abbreviate
- Add a pointer in
if the topic file is newMEMORY.md
If all findings are already persisted in topic files, skip this step.
1. Delegate save work to a subagent
Spawn a subagent (model: "sonnet") using the Task tool to perform all the heavy I/O. Pass it the following context:
- The project's memory file path (e.g.
)~/.claude/projects/<project>/memory/MEMORY.md - What was accomplished this session (bullet list of concrete outcomes, not a vague summary)
if provided (use as next-steps summary)$ARGUMENTS- The current working directory
The subagent prompt should instruct it to:
-
Update memory: Read the project's
. Update the "Current Work" section with what was done, current state, and next steps. Replace the previous entry (do not accumulate). Add date stamp. Do NOT attempt to summarize research findings here — detailed findings belong in topic files (written in Step 0), not in MEMORY.md. Current Work should only contain status, outcomes, and next steps. Keep MEMORY.md under 80 lines (hard stop: 120) — it is an index of one-line pointers, not a knowledge base. Clear theMEMORY.md
section entirely if it exists — its content has been incorporated into Current Work.## Recovered from previous session -
Commit and push: Run
. If there are uncommitted changes, stage relevant files (not build artifacts, logs, or secrets), commit with a descriptive message, and push to remote. If no changes or not a git repo, skip.git status -
Sync knowledge repo (if applicable): If
exists and has a~/.claude/knowledge
directory:.gitif [ -f "$HOME/.claude/hooks/knowledge-db.js" ]; then node ~/.claude/hooks/knowledge-db.js export ~/.claude/knowledge/entries.jsonl 2>/dev/null fi bash ~/.claude/scripts/skills/sync-knowledge-repo.sh --knowledge-dir ~/.claude/knowledge -
Verify: Run
to confirm clean working tree.git status -
Clear session state: Delete the session marker and loop detector to indicate a clean exit:
# Derive the project dir from cwd — Claude Code encodes the path with slashes as dashes. PROJECT_SLUG=$(pwd | sed 's|/|-|g') PROJECT_DIR=$(echo "$HOME/.claude/projects/${PROJECT_SLUG}" | sed 's|//|/|g') # Fall back to most-recently-modified project dir if the derived path doesn't exist. if [ ! -d "$PROJECT_DIR" ]; then PROJECT_DIR=$(ls -dt ~/.claude/projects/*/ 2>/dev/null | head -1) fi rm -f "$PROJECT_DIR/session-marker.json" rm -f "$PROJECT_DIR/loop-detector.json" # Only delete session-specific state, not the entire shared recovery directory # (other concurrent sessions may be using it) if [ -n "${CLAUDE_LOOP_PID:-}" ] && [[ "${CLAUDE_LOOP_PID}" =~ ^[0-9]+$ ]]; then rm -f "/tmp/claude-subagent-recovery/recovery-${CLAUDE_LOOP_PID}.json" fi -
Return a one-line summary of what was done (e.g. "Memory updated, committed abc1234, pushed to origin").
2. Exit decision
After the subagent returns, print exactly:
CHECKPOINT COMPLETE
Check if running under claude-loop:
echo "CLAUDE_LOOP=${CLAUDE_LOOP:-0} SENTINEL=${CLAUDE_LOOP_SENTINEL:-}"
If
(headless/task-queue mode): Write the sentinel and exit.CLAUDE_LOOP=1
[[ "${CLAUDE_LOOP_PID}" =~ ^[0-9]+$ ]] || exit 0 SENTINEL="/tmp/claude-checkpoint-exit-${CLAUDE_LOOP_PID}" echo '{"reason":"checkpoint","timestamp":'$(date +%s)'}' > "${SENTINEL}"
Print exactly "Exiting — claude-loop will respawn." Then STOP. Do not make any more tool calls or produce any more output.
If
is set (interactive mode under claude-loop): Write the sentinel.CLAUDE_LOOP_SENTINEL
[[ "${CLAUDE_LOOP_PID}" =~ ^[0-9]+$ ]] || exit 0 SENTINEL="/tmp/claude-checkpoint-exit-${CLAUDE_LOOP_PID}" echo '{"reason":"checkpoint","timestamp":'$(date +%s)'}' > "${SENTINEL}"
Print exactly:
Checkpoint complete. Session will restart with fresh context.
Then STOP. Do not make any more tool calls or produce any more output.
If neither is set (standalone session, no claude-loop): Print exactly:
Checkpoint complete. Exiting session.
Then STOP. Do not make any more tool calls or produce any more output. The session is over.