fix(M1-6): apply AI-drives-git reframe, lesson=theory, de-slop, + issue fixes
Phase 1 of the reframe. M1-3 stay manual-by-hand (browser chat); M4 is the pivot to the AI agent (Claude Code as example); M5-6 are agent-driven. - M1: de-slop (em-dashes), relocate the build-note out of the lab. Seam devices kept. - M2: #78 tell learner how to paste cli.py into chat; #79 commit the delete so the tree ends clean. restore/cold-session devices kept. - M3: #80 define ADR; #81 create-file-before-add; #82 ls before/after merge to prove branch isolation; #83 drop "prose"; M3 now owns the branch-basics intro. - M4: #84 Claude Code as the worked example; #85 AI drives git (arithmetic->calculator); #86 /path/to -> ~/ai-workflow-course; #87 agent does the revert+verify. - M5: #88 ask the agent which config files to commit, then let it stage/commit (CLAUDE.md example; repo still uses AGENTS.md). - M6: #90 stop re-teaching branch basics; rescope to the AI experimenting on a branch; the engineered conflict is now AI-resolved, learner-verified. Closes #78 Closes #79 Closes #80 Closes #81 Closes #82 Closes #84 Closes #85 Closes #87 Closes #88 Closes #90 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfzV5QvtPDz8LJS3Pu5VLT
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Module 2 — Version Control as a Safety Net
|
||||
|
||||
> **Version control is undo for the AI — and it's the AI's memory between sessions.** This is the one
|
||||
> **Version control is undo for the AI, and it's the AI's memory between sessions.** This is the one
|
||||
> module that makes every riskier thing in the rest of the course safe to attempt.
|
||||
|
||||
---
|
||||
@@ -11,7 +11,7 @@
|
||||
felt the three seams where copy-paste breaks. This module installs the fix for the third seam (no
|
||||
undo, no record) and, surprisingly, the second (no memory across time) as well.
|
||||
|
||||
You do **not** need Git installed yet — that's the first step of the lab.
|
||||
You do **not** need Git installed yet; that's the first step of the lab.
|
||||
|
||||
---
|
||||
|
||||
@@ -19,13 +19,13 @@ You do **not** need Git installed yet — that's the first step of the lab.
|
||||
|
||||
By the end of this module you can:
|
||||
|
||||
1. Initialize a repository and capture your work as commits — checkpoints you can always return to.
|
||||
1. Initialize a repository and capture your work as commits: checkpoints you can always return to.
|
||||
2. Read what changed with `git status`, `git diff`, and `git log`, and undo unwanted changes with
|
||||
`git restore`.
|
||||
3. Recover cleanly after an AI confidently makes a mess, without retyping anything.
|
||||
4. Use the repo as **durable memory**: have a fresh AI session reconstruct "where were we?" entirely
|
||||
from Git, with no chat history.
|
||||
5. Explain the one thing Git *can't* see — and why that's the argument for committing often.
|
||||
5. Explain the one thing Git *can't* see, and why that's the argument for committing often.
|
||||
|
||||
---
|
||||
|
||||
@@ -35,10 +35,10 @@ By the end of this module you can:
|
||||
|
||||
Strip away the open-source mythology and Git is one thing: **a tool that records snapshots of your
|
||||
files over time and lets you move between them.** Each snapshot is a *commit*. A commit is a labeled
|
||||
checkpoint — "here is exactly what every file looked like at this moment, and here's a note about
|
||||
checkpoint: "here is exactly what every file looked like at this moment, and here's a note about
|
||||
why." You can compare any two checkpoints, and you can return to any of them.
|
||||
|
||||
That's it. Everything else — branches, remotes, merges — is built on "snapshots you can move
|
||||
That's it. Everything else (branches, remotes, merges) is built on "snapshots you can move
|
||||
between." For now we only need the local core: `init`, `commit`, `diff`, `log`, `restore`.
|
||||
|
||||
### Reframe 1 — Commits are undo for the AI
|
||||
@@ -48,12 +48,12 @@ Module 1's third seam was: when the AI makes a mess, you have no checkpoint to r
|
||||
|
||||
1. Get the project to a working state.
|
||||
2. **Commit it.** Now this exact state is saved forever, with a message.
|
||||
3. Let the AI try something — anything, however risky.
|
||||
3. Let the AI try something, anything, however risky.
|
||||
4. If it worked, commit again. If it didn't, **`git restore` throws away the mess and you're back at
|
||||
step 2's checkpoint, byte for byte.**
|
||||
|
||||
This is the unlock for the whole course. Every later module asks you to let the AI do something
|
||||
bolder — edit real files (Module 4), work on a branch (Module 6), open a PR (Module 10), run
|
||||
This is what the whole course is built on. Every later module asks you to let the AI do something
|
||||
bolder: edit real files (Module 4), work on a branch (Module 6), open a PR (Module 10), run
|
||||
unattended (Unit 5). You can say yes to all of it *because* you can always get back to a known-good
|
||||
checkpoint. Without this, every AI change is a gamble. With it, the downside is "throw away five
|
||||
minutes of work."
|
||||
@@ -72,17 +72,17 @@ git restore <file> # discard uncommitted changes to a file (the undo)
|
||||
|
||||
A note on `restore`: `git restore <file>` throws away **uncommitted** edits and resets the file to
|
||||
the last commit. That's the everyday AI-undo. (Returning to an *older* commit, reverting a merge, and
|
||||
the reflog are recovery topics with their own module — Module 12 — once you've got remotes and PRs to
|
||||
the reflog are recovery topics with their own module (Module 12) once you've got remotes and PRs to
|
||||
make them meaningful. Here we only need "undo back to my last checkpoint.")
|
||||
|
||||
### Reframe 2 — The repo is durable memory the AI can read
|
||||
|
||||
This is the part most people miss, and it directly fixes Module 1's *second* seam.
|
||||
|
||||
An AI session is ephemeral. Close the tab and the agent's working context is gone — it cannot
|
||||
An AI session is ephemeral. Close the tab and the agent's working context is gone. It cannot
|
||||
remember yesterday. But here's the thing: **the changes on disk aren't gone.** And Git turns the
|
||||
disk into a structured, queryable record of exactly what happened and what's in flight. A fresh
|
||||
session — a brand-new chat, or tomorrow's agent that's never seen this project — can answer "where
|
||||
session (a brand-new chat, or tomorrow's agent that's never seen this project) can answer "where
|
||||
were we?" entirely from ground truth by reading Git:
|
||||
|
||||
| Command | What it tells a cold session |
|
||||
@@ -94,7 +94,7 @@ were we?" entirely from ground truth by reading Git:
|
||||
|
||||
Together those cover every state a change can be in: **untracked, uncommitted, committed, and
|
||||
not-yet-pushed.** That's the entire surface area of "what's going on in this project," and a fresh
|
||||
agent can read all of it in one pass — no chat history required, no re-explaining yesterday.
|
||||
agent can read all of it in one pass, with no chat history required and no re-explaining yesterday.
|
||||
|
||||
This reframes the whole point of committing. You're not just saving your work; you're **writing the
|
||||
project's memory in a form the next AI session can read.** The chat forgets. The repo remembers.
|
||||
@@ -103,9 +103,9 @@ project's memory in a form the next AI session can read.** The chat forgets. The
|
||||
|
||||
Put the two reframes together and the discipline falls out on its own:
|
||||
|
||||
- The more granular your commits, the **smaller the blast radius** when the AI makes a mess — you
|
||||
- The more granular your commits, the **smaller the blast radius** when the AI makes a mess: you
|
||||
restore to a checkpoint ten minutes back, not yesterday.
|
||||
- The more granular your commits, the **cleaner the reconstruction** — `git log` reads like a
|
||||
- The more granular your commits, the **cleaner the reconstruction**: `git log` reads like a
|
||||
decision journal instead of one giant "stuff" commit.
|
||||
|
||||
Commit at every working state. Treat it as the autosave you control. "It runs and does what I
|
||||
@@ -118,12 +118,12 @@ expect" is a good enough reason to commit.
|
||||
Everything above is standard Git. What's *specific* to AI-assisted work:
|
||||
|
||||
- **The AI raises the value of undo.** You're making more changes, faster, with more confidence
|
||||
(yours and the model's) — and confidence is exactly what precedes a quiet mistake. The frequency of
|
||||
(yours and the model's), and confidence is exactly what precedes a quiet mistake. The frequency of
|
||||
"wait, undo that" goes *up* with AI, so cheap, reliable undo matters more, not less.
|
||||
- **The AI has no memory; the repo is the memory you give it.** This is the single highest-leverage
|
||||
habit in the course. When you start a session with *"read `git log`, `git status`, and `git diff`,
|
||||
- **The AI has no memory; the repo is the memory you give it.** This is the habit that pays off most
|
||||
across the course. When you start a session with *"read `git log`, `git status`, and `git diff`,
|
||||
then tell me where we are,"* you've replaced "re-explain the project from memory" with "read the
|
||||
ground truth." Agents are *good* at this — reading state is what they're best at.
|
||||
ground truth." Agents are *good* at this; reading state is what they're best at.
|
||||
- **AI changes are reviewable as diffs.** `git diff` turns "the AI rewrote my file" into a precise,
|
||||
line-by-line account of what it actually did. That's the foundation the review skill (Module 10) is
|
||||
built on, and it starts here.
|
||||
@@ -140,12 +140,12 @@ and your AI assistant.
|
||||
|
||||
> **How you work with the AI in this lab — still the browser.** You haven't moved the AI into your
|
||||
> editor yet; that's **Module 4** ("Getting the AI Out of the Browser"), and it comes *after* this
|
||||
> one on purpose. The whole point of this module is to install the safety net **first** — you only
|
||||
> one on purpose. The whole point of this module is to install the safety net **first**: you only
|
||||
> let an AI edit your real files directly once you can see and revert exactly what it did. So for now,
|
||||
> keep doing what you did in Module 1: **ask in your browser chat, then copy the result into the
|
||||
> file yourself.** Every time you read "ask your AI" below, that means: paste the relevant file(s)
|
||||
> into your chat, ask for the change, and paste the result back. Yes, it's the copy-paste loop from
|
||||
> Module 1 — that friction is exactly what Module 4 removes, and you'll appreciate it more for having
|
||||
> Module 1, and that friction is exactly what Module 4 removes. You'll appreciate it more for having
|
||||
> felt it one more time with a net underneath you.
|
||||
|
||||
### Part A — First checkpoint
|
||||
@@ -179,8 +179,10 @@ and your AI assistant.
|
||||
|
||||
### Part B — A change you can see and trust
|
||||
|
||||
3. Ask your AI for a small feature — e.g. *"add a `count` command to `cli.py` that prints how many
|
||||
tasks are pending."* Apply the change to the file.
|
||||
3. Get `cli.py` in front of your AI first. The browser chat can't see your disk, so you have to hand
|
||||
it the file: run `cat cli.py` and copy the output, or copy the contents straight from your editor.
|
||||
Paste that into the chat, then ask for a small feature, e.g. *"add a `count` command to `cli.py`
|
||||
that prints how many tasks are pending."* Paste the AI's version back over `cli.py`.
|
||||
|
||||
4. **Before committing, read the diff:**
|
||||
|
||||
@@ -188,7 +190,7 @@ and your AI assistant.
|
||||
git diff
|
||||
```
|
||||
|
||||
This is the habit that replaces "paste it back and hope." You're reading exactly what changed —
|
||||
This is the habit that replaces "paste it back and hope." You're reading exactly what changed,
|
||||
nothing more, nothing less. Confirm it does what you asked and didn't touch anything it shouldn't.
|
||||
Run it (`python cli.py count`), then commit:
|
||||
|
||||
@@ -200,7 +202,7 @@ and your AI assistant.
|
||||
### Part C — Recover from a mess (the whole point)
|
||||
|
||||
5. Now let the AI make a mess on purpose. Ask it to *"aggressively refactor `tasks.py`"* and paste
|
||||
the result over your file **without reading it**. Run the app — maybe it's broken, maybe it's
|
||||
the result over your file **without reading it**. Run the app. Maybe it's broken, maybe it's
|
||||
subtly wrong, maybe it's fine but unrecognizable. Doesn't matter.
|
||||
|
||||
6. Decide you don't want it. Undo it completely:
|
||||
@@ -213,7 +215,7 @@ and your AI assistant.
|
||||
```
|
||||
|
||||
You just recovered from a bad AI change in one command, with zero retyping and zero guesswork.
|
||||
*This is the safety net.* Internalize how cheap that just was — that cheapness is what lets you say
|
||||
*This is the safety net.* Internalize how cheap that just was; that cheapness is what lets you say
|
||||
yes to riskier AI work for the rest of the course.
|
||||
|
||||
### Part D — The repo as the AI's memory
|
||||
@@ -238,10 +240,22 @@ and your AI assistant.
|
||||
Then ask: *"Based only on this Git output, tell me where this project is: what's settled, what's
|
||||
in progress, and what I should do next."*
|
||||
|
||||
Watch a session that has never seen your project reconstruct its exact state — settled history
|
||||
from `log`, in-flight work from `status`/`diff` — with no chat history at all. **That's durable
|
||||
Watch a session that has never seen your project reconstruct its exact state: settled history
|
||||
from `log`, in-flight work from `status`/`diff`, with no chat history at all. **That's durable
|
||||
memory.** Make this your standard way to start a session on any project.
|
||||
|
||||
9. Close the loop and leave the repo clean. The cold session just told you what's in progress and
|
||||
what to do next: finish the `delete <index>` command. Do that with the AI (paste in `cli.py` the
|
||||
same way as Part B), run it to confirm it works (`python cli.py delete 1`), then commit:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Add delete command"
|
||||
git status # "nothing to commit, working tree clean"
|
||||
```
|
||||
|
||||
No dangling uncommitted work follows you into Module 3.
|
||||
|
||||
---
|
||||
|
||||
## Where it breaks
|
||||
@@ -251,7 +265,7 @@ up again in Module 8 for the *backup* half and Module 12 for the *recovery* half
|
||||
|
||||
- **Git only sees what was written to disk.** This is the one limit to teach yourself hard. If the
|
||||
AI reasoned brilliantly about an approach in the conversation but you never wrote it to a file, it
|
||||
is *gone* with the session — Git can't recover what was never on disk. The repo is ground truth,
|
||||
is *gone* with the session. Git can't recover what was never on disk. The repo is ground truth,
|
||||
but only for things that became files. (This is also the practical argument for committing often:
|
||||
the more you write down, the less lives only in ephemeral context.)
|
||||
- **A single local repo is not a backup.** Everything in this module lives on one disk. Drop the
|
||||
@@ -277,5 +291,5 @@ up again in Module 8 for the *backup* half and Module 12 for the *recovery* half
|
||||
argues for committing often.
|
||||
|
||||
When undo feels free and starting a cold session feels like "just read the repo," you've got the
|
||||
safety net. Module 3 puts it to work on the lowest-risk possible target — documents, not code —
|
||||
safety net. Module 3 puts it to work on the lowest-risk possible target (documents, not code)
|
||||
before Module 4 lets the AI edit your files directly.
|
||||
|
||||
Reference in New Issue
Block a user