CHECKPOINT-BASED DEVELOPMENT WITH LLMs
Working with LLMs accelerates development. It also accelerates mistakes. In a single message, an LLM can rewrite three files, break two functions that were working, and solve the original problem. Net result: one step forward, two steps back. The solution is not to distrust the LLM — it is to have a checkpoint system that makes rollback so trivial it never hurts to do it.
Stack: Git · Python · any project
Reference projects: FocOs · TeliOs
Goal: Turn rollback into a 2-second operation with zero friction
01. THE PROBLEM IT SOLVES
When an LLM modifies multiple files in a single session, it becomes easy to lose track of which state was stable. Without explicit checkpoints, the developer ends up choosing between two equally costly options: push forward with broken code hoping to fix it later, or manually rewrite to get back to the previous state. Checkpoints eliminate that choice entirely.
When rollback does not hurt, the developer accepts more calculated risks. And calculated risks are precisely what produces real breakthroughs.
// Non-technical explanation
Imagine you are building a very complex LEGO castle. Every time you finish an important section — a tower, a bridge, a wall — you take a photo. If you accidentally break something, you do not have to start from scratch. You look at the photo and rebuild only the part that broke. Checkpoints are those photos. Git takes them automatically whenever you say so.
02. THE GOLDEN RULE — ONE CHECKPOINT PER STABLE STATE
A checkpoint is not a commit for every change. It is a commit for every verified functional state. The distinction is fundamental — and it is the difference between a useful history and noise.
git commit -m 'changes'
git commit -m 'more changes'
git commit -m 'fixing something'
git commit -m 'wip'
# Result: useless history. You have no idea which state worked.
# RIGHT — committing verified stable states
# Before handing work to the LLM:
git add .
git commit -m 'CHECKPOINT: LLM panel functional — before adding history'
# After verifying the new state works:
git add .
git commit -m 'CHECKPOINT: conversation history implemented and verified'
# Result: every commit is a reliable restoration point.
03. THE FULL PROTOCOL — BEFORE, DURING AND AFTER
# 1. Verify the current state works
python main.py
# 2. Commit the checkpoint
git add .
git commit -m 'CHECKPOINT: [description of current state]'
# 3. Log what you are about to ask the LLM (SESSION-LOG or comment)
# 'Going to ask it to implement the conversation history'
# DURING work with the LLM:
# 4. Review EVERY change before applying — never apply in bulk unread
# 5. Test after each modified file — do not wait for all changes
# AFTER — if the result works:
git add .
git commit -m 'CHECKPOINT: [description of new state]'
# AFTER — if the result is broken:
git checkout . # discard uncommitted changes
# or
git reset --hard HEAD # revert to last checkpoint
04. NAMING CONVENTION — THE ONE THAT SAVES TIME
A checkpoint name must communicate two things: what state exists at this point and why this moment deserves a checkpoint. If you cannot describe the state in one line, the state is not clear yet — do not checkpoint.
# Real examples from FocOs:
CHECKPOINT: JS<>Python bridge stable — before integrating Monaco
CHECKPOINT: Monaco with model:null — tabs without shared buffer bug
CHECKPOINT: LLM Groq responding — User-Agent fix applied
CHECKPOINT: xterm.js terminal functional — before adding autocomplete
CHECKPOINT: dashboard with real data — before connecting SQLite
# What NEVER belongs in a checkpoint name:
# 'fix' | 'minor changes' | 'wip' | 'updating'
| Name | Valid checkpoint? | Reason |
|---|---|---|
| CHECKPOINT: bridge stable — before Monaco | [ + ] Yes | Clearly describes state and context. |
| fix | [ - ] No | Does not describe what was fixed or the resulting state. |
| wip | [ - ] No | Work in progress is not a verified stable state. |
| minor changes | [ - ] No | Ambiguous. History becomes useless within 48 hours. |
05. GIT STASH — THE TEMPORARY CHECKPOINT
When you want to explore an idea without committing to a checkpoint, git stash saves the current state temporarily without making a commit. Ideal for quick experiments without polluting the history.
git stash push -m 'experiment: testing alternative Monaco approach'
# If the experiment worked — checkpoint and drop the stash
git add .
git commit -m 'CHECKPOINT: alternative Monaco approach works better'
git stash drop
# If the experiment failed — recover previous work
git stash pop
# Inspect stashes
git stash list
git stash show stash@{0} -p
06. BRANCHES FOR MAJOR EXPERIMENTS
For changes that affect the full architecture, use a separate branch — never main. If the experiment fails, main was never touched. Zero drama.
git checkout -b experiment/llm-streaming
# If it works — merge into main
git checkout main
git merge experiment/llm-streaming
git commit -m 'CHECKPOINT: LLM streaming integrated from branch'
# If it fails — delete branch without touching main
git checkout main
git branch -D experiment/llm-streaming
# Branch naming in FocOs:
# feature/onboarding | feature/file-explorer
# experiment/monaco-vim-mode | fix/bridge-timeout
07. SESSION-LOG INTEGRATION
Every checkpoint should have a corresponding entry in the day's SESSION-LOG. This keeps the Git history and the project history synchronized — you can reconstruct exactly what decision you made and with which LLM.
- 10:30 — CHECKPOINT: JS<>Python bridge stable
Commit: a3f9c2b
State before: bridge crashed on cold start
State after: on_start() callback stable
LLM used: Claude Sonnet
- 14:15 — CHECKPOINT: Monaco independent tabs
Commit: d8e4f1a
State before: all tabs shared buffer
State after: model:null + unique URI per tab
LLM used: Groq llama-3.3-70b
## Day rollbacks
- 12:00 — Rollback to stable bridge
Reason: streaming attempt broke the bridge
Time lost: 45 min
Lesson: test streaming on a separate branch
-- CONCLUSION
Checkpoint-based development applied to LLM-driven projects turns rollback from a costly, painful operation into a 2-second routine. The psychological effect is as important as the technical one: when the developer knows they can go back without drama, they accept more experiments. More experiments means more discoveries. The cost of being wrong drops to zero — and that changes build velocity as much as the LLM itself.
> SYSTEM_READY > NODE_ONLINE