Project 26: “The Checkpoint Time Machine” — Safety Systems
| Attribute | Value |
|---|---|
| File | KIRO_CLI_LEARNING_PROJECTS.md |
| Main Programming Language | Git / Kiro |
| Coolness Level | Level 3: Genuinely Clever |
| Difficulty | Level 2: Intermediate |
| Knowledge Area | Safety Systems |
What you’ll build: Snapshot, perform risky edits, and restore instantly.
Why it teaches Fearless Coding: You can let the agent be aggressive without fear.
Success criteria:
- A restore returns the repo to a known good state.
Real World Outcome
You’ll create a checkpoint system that snapshots your entire codebase before Kiro makes risky changes, allowing you to instantly roll back if things go wrong. This enables fearless experimentation with aggressive refactoring, large-scale changes, and exploratory edits.
Example Workflow:
# Before risky refactoring
$ kiro checkpoint create "before-refactor-user-service"
✓ Checkpoint created: cp_20240115_143022_before-refactor-user-service
Files: 156 tracked, 12 untracked
Git ref: refs/checkpoints/cp_20240115_143022
# Let Kiro make aggressive changes
$ kiro "refactor the entire user service to use dependency injection"
[Kiro makes extensive changes across 23 files...]
[Tests start failing...]
# Oh no, restore the checkpoint
$ kiro checkpoint restore cp_20240115_143022_before-refactor-user-service
Restoring checkpoint: cp_20240115_143022_before-refactor-user-service
✓ Git worktree reset to refs/checkpoints/cp_20240115_143022
✓ Untracked files restored from .kiro/checkpoints/cp_20240115_143022/
✓ 23 files reverted, 12 untracked files restored
Took 0.8s
# Codebase is back to exactly how it was before
$ git status
# On branch main
# nothing to commit, working tree clean
Checkpoint workflow:
# 1. Create checkpoint before experiment
$ kiro checkpoint create "experiment-async-await"
# 2. Try risky changes
$ kiro "convert all promise chains to async/await"
$ npm test
# Tests fail...
# 3. Restore (instant rollback)
$ kiro checkpoint restore experiment-async-await
# 4. List all checkpoints
$ kiro checkpoint list
cp_20240115_143022_before-refactor-user-service
cp_20240115_150431_experiment-async-await
cp_20240115_152103_before-schema-migration
# 5. Delete old checkpoints
$ kiro checkpoint delete cp_20240115_143022_before-refactor-user-service
What makes this different from git stash or git commit:
| Feature | Checkpoint | Git Stash | Git Commit |
|---|---|---|---|
| Speed | Instant (<1s) | Fast (~2s) | Slow (>5s with hooks) |
| Untracked files | ✓ Included | ✗ Not included | ✗ Not included |
| Easy restore | checkpoint restore |
stash apply (conflicts) |
git reset --hard (dangerous) |
| Named | ✓ Descriptive | ✗ “WIP on main” | ✓ Commit message |
| No git history pollution | ✓ Clean | ✓ Clean | ✗ Creates commits |
You’re building the same safety net that professional game developers use (“checkpoint before boss fight”).
The Core Question You’re Answering
“How do you experiment fearlessly with an AI agent making large-scale code changes when you know you might need to revert everything instantly?”
Before you build any checkpoint system, understand this: The fear of breaking the codebase is the #1 reason developers are conservative with AI agents. If you can’t easily undo changes, you’ll never let the agent be truly creative or aggressive.
Checkpoints remove that fear. You can say “try a radical refactoring” knowing you have a one-command rollback.
Concepts You Must Understand First
Stop and research these before coding:
- Git Worktree and Index
- What is the difference between the working tree, the index (staging area), and HEAD?
- How does
git reset --hardwork (and why is it dangerous)? - What are git refs (references like refs/heads/main, refs/tags/v1.0)?
- Book Reference: “Pro Git” by Scott Chacon - Ch. 10 (Git Internals)
- Untracked Files and .gitignore
- Why don’t
git stashandgit commitsave untracked files? - How do you capture untracked files (tar, rsync, cp -r)?
- What happens to .gitignored files during checkpoint/restore?
- Book Reference: “Version Control with Git” by Loeliger - Ch. 5 (Working Trees)
- Why don’t
- Atomic Operations and Race Conditions
- How do you ensure checkpoint creation is atomic (all-or-nothing)?
- What happens if Kiro creates a checkpoint while you’re editing files?
- How do you handle concurrent checkpoint operations (locking)?
- Book Reference: “The Linux Programming Interface” by Kerrisk - Ch. 30 (File Locking)
- Filesystem Snapshots vs. Git-Based Snapshots
- What are filesystem snapshots (ZFS snapshots, Btrfs snapshots, LVM snapshots)?
- Why use git refs instead of full filesystem snapshots (storage efficiency)?
- How do you handle binary files and large assets (Git LFS)?
- Book Reference: “Understanding the Linux Kernel” by Bovet - Ch. 16 (File Systems)
- Restoration Strategies (Full vs. Partial)
- Should you restore the entire working tree or just specific files?
- How do you handle merge conflicts during restore (overwrite vs. merge)?
- What happens to local changes made after checkpoint creation?
- Book Reference: “Git Pocket Guide” by Silverman - Ch. 3 (Undoing Changes)
- Checkpoint Lifecycle Management
- When should checkpoints be automatically cleaned up (after N days, after restore)?
- How much disk space do checkpoints consume (ref + untracked files)?
- Should checkpoints survive
git clean -fdx(store outside .git/)? - Book Reference: “Designing Data-Intensive Applications” by Kleppmann - Ch. 3 (Storage)
Questions to Guide Your Design
Before implementing, think through these:
- Snapshot Granularity
- Should checkpoints capture the entire repo or just specific directories?
- Do you include node_modules, build artifacts, and .env files?
- Should checkpoints be branch-specific or global across all branches?
- How do you handle submodules and nested git repositories?
- Storage Strategy
- Where do you store checkpoints (.kiro/checkpoints/, .git/refs/checkpoints/)?
- Do you use git refs (lightweight) or full tar archives (heavyweight)?
- How do you compress untracked files (tar.gz, zip, rsync)?
- Should checkpoints be shareable across team members (git remote)?
- Restoration Safety
- Should restore require confirmation (interactive prompt)?
- Do you warn if there are uncommitted changes before restore?
- Should restore create a “pre-restore” checkpoint automatically?
- How do you handle file deletions (restore deleted files)?
- Naming and Discovery
- How do you auto-generate checkpoint names (timestamp + description)?
- Should checkpoints be tagged with metadata (author, timestamp, git commit)?
- How do you search for checkpoints (by name, date, commit range)?
- Can you compare two checkpoints (diff cp1 cp2)?
- Integration with Kiro
- Should Kiro automatically create checkpoints before risky operations?
- Can Kiro suggest when to create a checkpoint (heuristic: changing > 10 files)?
- Should restore be a recoverable operation (keep restore history)?
- How do you visualize checkpoint history (timeline, tree view)?
Thinking Exercise
Trace a Checkpoint and Restore Cycle
Before coding, manually simulate creating and restoring a checkpoint using git:
Scenario: Risky refactoring with checkpoint safety net
# Initial state
$ git status
# On branch main
# nothing to commit, working tree clean
# Create checkpoint (manual simulation)
$ git update-ref refs/checkpoints/cp_001 HEAD
$ tar -czf .kiro/checkpoints/cp_001_untracked.tar.gz \
$(git ls-files --others --exclude-standard)
# Checkpoint created (stored: git ref + untracked files archive)
# Risky changes
$ kiro "refactor all database queries to use TypeORM instead of raw SQL"
[Kiro modifies 30 files, creates 12 new files]
# Tests fail
$ npm test
# 23 tests failed
# Restore checkpoint (manual simulation)
$ git reset --hard refs/checkpoints/cp_001 # Reset tracked files
Unstaged changes after reset:
M src/db/queries.ts (modified but not committed after checkpoint)
$ tar -xzf .kiro/checkpoints/cp_001_untracked.tar.gz # Restore untracked
$ git clean -fd # Remove new untracked files created after checkpoint
# Verify restoration
$ git status
# On branch main
# nothing to commit, working tree clean
$ npm test
# All tests passing (back to checkpoint state)
Questions while tracing:
- What happens to files that existed at checkpoint time but were deleted during the risky changes?
- How do you handle files that were modified both before and after checkpoint creation?
- What if the user has uncommitted changes when they try to restore?
- Should restore delete new files created after the checkpoint (git clean -fd)?
- How do you restore files that are in .gitignore (they’re untracked but intentionally ignored)?
Edge cases to consider:
# Edge Case 1: Checkpoint with dirty working tree
$ git status
# On branch main
# Changes not staged for commit:
# modified: src/app.ts
$ kiro checkpoint create "dirty-state"
# Should this be allowed? Or require a clean working tree?
# Edge Case 2: Restore with uncommitted changes
$ kiro checkpoint restore cp_001
# Warning: You have uncommitted changes. Restore will overwrite them.
# Continue? (y/N)
# Edge Case 3: Checkpoint on non-main branch
$ git checkout feature-branch
$ kiro checkpoint create "feature-experiment"
# Should this checkpoint be branch-specific or global?
# Edge Case 4: Restore after git commit
$ kiro checkpoint create cp_001
$ kiro "refactor code"
$ git add . && git commit -m "refactor"
$ kiro checkpoint restore cp_001
# Restores working tree, but leaves commit in history?
The Interview Questions They’ll Ask
Prepare to answer these:
-
“What is the difference between
git stash,git commit, and a custom checkpoint system for saving codebase state?” -
“How would you implement a checkpoint system that captures both tracked files (in git) and untracked files (not in git)?”
-
“A developer creates a checkpoint, makes changes, commits those changes, then restores the checkpoint. What happens to the git commit history?”
-
“What are the trade-offs between storing checkpoints as git refs vs. full tar archives of the working directory?”
-
“How do you handle checkpoint restoration when there are merge conflicts (files modified both at checkpoint time and after)?”
-
“Why might a checkpoint system fail to restore a repository to its exact prior state, even with all files backed up?”
Hints in Layers
Hint 1: Start with Git Refs
Use git update-ref refs/checkpoints/<name> HEAD to create a lightweight git reference to the current commit. This is fast and doesn’t duplicate the entire repository.
Hint 2: Capture Untracked Files Separately
Git refs only track committed files. Use git ls-files --others --exclude-standard to find untracked files and tar them:
tar -czf .kiro/checkpoints/<name>_untracked.tar.gz $(git ls-files --others)
Hint 3: Restore in Two Steps
First reset tracked files: git reset --hard refs/checkpoints/<name>
Then restore untracked files: tar -xzf .kiro/checkpoints/<name>_untracked.tar.gz
Hint 4: Add Safety Checks Before restore, check for uncommitted changes:
if ! git diff-index --quiet HEAD --; then
echo "Warning: You have uncommitted changes."
read -p "Continue? (y/N) " -n 1 -r
fi
Books That Will Help
| Topic | Book | Chapter |
|---|---|---|
| Git Internals | “Pro Git” by Scott Chacon | Ch. 10 (Git Internals) |
| Working Trees | “Version Control with Git” by Loeliger | Ch. 5 (Working Trees) |
| File Locking | “The Linux Programming Interface” by Kerrisk | Ch. 30 (File Locking) |
| Filesystems | “Understanding the Linux Kernel” by Bovet | Ch. 16 (File Systems) |
| Undoing Changes | “Git Pocket Guide” by Silverman | Ch. 3 (Undoing Changes) |
| Storage Engines | “Designing Data-Intensive Applications” by Kleppmann | Ch. 3 (Storage) |
Common Pitfalls & Debugging
Problem 1: “Restore doesn’t bring back deleted files”
- Why:
git reset --hardonly resets files tracked by git, not untracked files. - Fix: Also restore untracked files from the checkpoint’s tar archive.
- Quick test: Create checkpoint, delete a file, restore, verify file exists.
Problem 2: “Checkpoint failed mid-creation (partial checkpoint)”
- Why: tar command failed due to disk space or permission issues.
- Fix: Make checkpoint creation atomic: write to temp location, then move.
- Quick test: Fill disk during checkpoint creation, verify no partial checkpoints exist.
Problem 3: “Restore leaves new files created after checkpoint”
- Why: Restore doesn’t delete files that didn’t exist at checkpoint time.
- Fix: Run
git clean -fdafter restore to remove untracked files. - Quick test: Create checkpoint, add new file, restore, verify new file is gone.
Problem 4: “Checkpoints consume too much disk space (> 1GB each)”
- Why: Untracked files include node_modules, build artifacts, or large assets.
- Fix: Exclude large directories from checkpoint:
tar --exclude='node_modules' ... - Quick test:
du -sh .kiro/checkpoints/(should be < 100MB per checkpoint)
Problem 5: “Restore fails with ‘ref not found’ error”
- Why: The git ref was deleted (manual cleanup or git gc).
- Fix: Store checkpoints as actual commits (or tags) instead of refs.
- Quick test:
git show-ref refs/checkpoints/(list all checkpoint refs)
Problem 6: “Checkpoints don’t survive git clean -fdx”
- Why:
.kiro/checkpoints/was deleted bygit clean. - Fix: Add
.kiro/to.gitignoresogit cleanskips it. - Quick test:
git clean -fdx && ls .kiro/checkpoints/(should still exist)
Definition of Done
- Can create a checkpoint with a descriptive name
- Checkpoint captures all tracked files (via git ref)
- Checkpoint captures all untracked files (via tar archive)
- Restore brings back the exact working tree state (all files match)
- Restore removes files created after checkpoint (clean working tree)
- Checkpoint creation is atomic (no partial checkpoints on failure)
- Can list all checkpoints with timestamps and descriptions
- Can delete old checkpoints to free disk space
- Restore warns if there are uncommitted changes
- Checkpoint system survives git clean -fdx
- Tested with risky refactoring (create checkpoint, break code, restore successfully)
- Documentation explains when to create checkpoints and how to restore