fix(modules-4,7,14): make the git demos/labs actually do what the prose claims

- M4 Part C now commits the reviewed `delete` change as the checkpoint, so
  Part D's `git restore .` returns to a delete-containing state (was wiping it).
- M7 'watch it break': switch to an existing divergent branch so the
  "would be overwritten by checkout" refusal actually fires (git switch -c never did).
- M7 Part C: demonstrate worktree isolation with existing add/list and distinct
  per-worktree data; move the new clear/count commands to after they exist.
- M14 Part C: recover with `git revert HEAD` (Module 12, which precedes M14) so
  CI legitimately goes green; drop the wrong "Module 2's safety net" attribution.

Closes #2
Closes #3
Closes #4
Closes #12

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:
2026-06-22 14:52:20 -04:00
parent b061a9da14
commit 9835dba566
3 changed files with 98 additions and 39 deletions
@@ -56,22 +56,31 @@ That's fine when *you* are the only one standing on the floor. It falls apart th
two things happening at once. Watch it break:
```bash
# Agent A is mid-change on a feature branch — uncommitted edits in cli.py
# Agent A added a `clear` command and committed it on its own branch:
git switch -c feature/clear
# ...agent A edits cli.py, hasn't committed...
# ...agent A edits the usage line in cli.py to add `clear`...
git commit -am "Add clear command"
# You want Agent B to start a different job, so you try to switch:
# You start Agent B on a fresh branch off main; it begins editing the SAME
# usage line to add `count`, and hasn't committed:
git switch main
git switch -c feature/count
# ...agent B edits cli.py, hasn't committed...
# You try to hop the working directory back to Agent A's branch to check on it:
git switch feature/clear
# error: Your local changes to the following files would be overwritten by checkout:
# cli.py
# Please commit your changes or stash them before you switch branches.
```
Git stops you — correctly. But now you're stuck choosing between bad options:
Git stops you — correctly. Switching to `feature/clear` would overwrite Agent B's uncommitted edits
to `cli.py` with Agent A's committed version of those same lines, so Git refuses rather than silently
destroy the work. But now you're stuck choosing between bad options:
- **Commit half-finished work** just to get it out of the way (pollutes history, and Agent A's job
isn't done).
- **Stash it** (now Agent A's context lives in a stash you have to remember to pop, and Agent A — a
- **Commit half-finished work** just to get it out of the way (pollutes history, and Agent B's
`count` command isn't done).
- **Stash it** (now Agent B's context lives in a stash you have to remember to pop, and Agent B — a
long-running session that thinks its files are right there — is now editing files that silently
changed under it).
- **Run both agents on the same branch in the same folder** — and watch them overwrite each other's
@@ -220,23 +229,40 @@ collide. Then you'll merge both back and clean up.
### Part A — Feel the collision (1 minute)
Before fixing it, reproduce the bottleneck from "Where branches alone run out." In your `tasks-app`:
Before fixing it, reproduce the bottleneck from "Where branches alone run out." The wall only appears
when both branches touch the **same line** of `cli.py` — one committed, one not — so we make each
branch edit the usage line. (The `sed … > tmp && mv` is just a portable, copy-pasteable stand-in for
the edit an agent would make.) In your `tasks-app`:
```bash
cd ~/workflow-course/tasks-app
git switch -c feature/scratch
# make a fake uncommitted edit so the working dir is dirty:
echo "# scratch" >> cli.py
git switch -c feature/other
# Agent A's branch: add `clear` to the usage line and commit it.
git switch -c feature/clear
sed 's/done <index>/done <index> | clear/' cli.py > cli.tmp && mv cli.tmp cli.py
git commit -am "Add clear command (demo)"
# Agent B's branch, off main: start adding `count` to the SAME line — leave it uncommitted.
git switch main
git switch -c feature/count
sed 's/done <index>/done <index> | count/' cli.py > cli.tmp && mv cli.tmp cli.py
# Try to hop the working directory back to Agent A's branch:
git switch feature/clear
# error: Your local changes to the following files would be overwritten by checkout:
# cli.py
# Please commit your changes or stash them before you switch branches.
```
Git refuses — it won't move you to another branch with uncommitted changes in the way. *That* is the
wall. Clean up before continuing:
Git refuses — moving the one working directory to `feature/clear` would overwrite Agent B's
uncommitted edit with `feature/clear`'s committed version of that line. *That* is the wall: one
directory can't hold two agents' in-progress work at once. These two branches existed only to feel
the collision, so clean them up before continuing:
```bash
git restore cli.py
git restore cli.py # drop Agent B's uncommitted edit
git switch main
git branch -D feature/scratch feature/other
git branch -D feature/clear feature/count # throw away the demo branches
```
### Part B — Create two worktrees
@@ -269,16 +295,19 @@ This is the part to actually *do simultaneously*, not one then the other.
`lab/agent-a-prompt.md`*add a `clear` command that removes all tasks.*
2. Open `~/workflow-course/tasks-app-count` in a **second** editor/AI session. Give it the prompt in
`lab/agent-b-prompt.md`*add a `count` command that prints the number of pending tasks.*
3. Let both work at the same time. While they run, prove the isolation from a third terminal:
3. Let both work at the same time. While they run, prove the isolation from a third terminal — but
use commands that **already exist**. (`clear` and `count` don't yet; the agents are still writing
them.) Give each worktree its own task and list it:
```bash
cd ~/workflow-course/tasks-app-clear && python cli.py clear # agent A's feature
cd ~/workflow-course/tasks-app-count && python cli.py count # agent B's feature
cd ~/workflow-course/tasks-app-clear && python cli.py add "from worktree A" && python cli.py list
cd ~/workflow-course/tasks-app-count && python cli.py add "from worktree B" && python cli.py list
```
Each app runs its own command in its own folder. Note that each worktree has its **own**
`tasks.json` (it's gitignored runtime state, not shared history) so the two running apps don't
even share data. Total isolation.
Each `list` shows only its own task — worktree A never sees "from worktree B" and vice versa. Each
worktree has its **own** `tasks.json` (gitignored runtime state, not shared history), so the two
running apps don't even share data. Separate files, separate state, while both agents work. Total
isolation.
4. In each worktree, commit the agent's work on its own branch:
@@ -289,6 +318,16 @@ This is the part to actually *do simultaneously*, not one then the other.
Two agents, two commits, two branches — neither ever saw the other's files.
5. *Now* the new commands exist — run each in its own worktree to watch it work:
```bash
cd ~/workflow-course/tasks-app-clear && python cli.py clear # agent A's new command
cd ~/workflow-course/tasks-app-count && python cli.py count # agent B's new command
```
`count` reports only worktree B's task — the one you added in step 3 — because B's `tasks.json` is
the only state it can see. The isolation, one last time.
### Part D — Merge back and clean up
Bring both features home to `main` in your original worktree:
@@ -354,8 +393,8 @@ Worktrees are sharp tools. The honest caveats:
**You're done when:**
- `git worktree list` showed three entries at once, and you ran a different command of the
`tasks-app` from two different worktree folders.
- `git worktree list` showed three entries at once, and you ran the `tasks-app` from two different
worktree folders — adding a different task in each and watching each keep its own `tasks.json`.
- You ran two AI sessions in parallel — each in its own worktree on its own branch — and confirmed
neither touched the other's files (different folders, different `tasks.json`, different branch).
- You merged both feature branches back into `main` (resolving a conflict if one appeared) and the