De-slop: remove every em-dash + banned words across all modules + capstone (#94)
Sync course wiki / sync-wiki (push) Successful in 4s

Co-authored-by: claude <claude@jpaul.io>
Co-committed-by: claude <claude@jpaul.io>
This commit was merged in pull request #94.
This commit is contained in:
2026-06-22 23:21:22 -04:00
committed by Claude (agent)
parent 513d7e7ac8
commit c098933f25
99 changed files with 1324 additions and 1315 deletions
+34 -34
View File
@@ -1,4 +1,4 @@
# Module 3 Version Control for Words, Not Just Code
# Module 3: Version Control for Words, Not Just Code
> **The safest place to practice Git is on words, and it happens to be a genuinely useful skill on
> its own.** Branch an Architecture Decision Record (ADR), let the AI draft it, read the diff, merge
@@ -8,14 +8,14 @@
## Prerequisites
- **Module 1** you have the `tasks-app` project, an editor, and a terminal.
- **Module 2** you can `init`, `commit`, read a `diff`, and `restore`. This module adds two new
- **Module 1:** you have the `tasks-app` project, an editor, and a terminal.
- **Module 2:** you can `init`, `commit`, read a `diff`, and `restore`. This module adds two new
verbs to that vocabulary: `branch` and `merge`. They're introduced here, in the lowest-stakes
setting possible (a markdown file), and picked up again for real code work in
**Module 6 Branches: Sandboxes for Experiments**.
**Module 6 (Branches: Sandboxes for Experiments)**.
You're still working the way you did in Modules 12: **AI in a browser tab, copy-paste into the
file.** Editor-integrated AI is Module 4. That's deliberate practicing branch/merge on documents
file.** Editor-integrated AI is Module 4. That's deliberate; practicing branch/merge on documents
is exactly the low-risk on-ramp that makes the copy-paste friction tolerable one more time.
---
@@ -51,8 +51,8 @@ them in code:
back to the version that was correct an hour ago. `runbook-final-v2-ACTUAL-use-this.docx` is what
"no undo" looks like when it metastasizes.
Git fixes all three for documents the same way it fixes them for code *if* the documents are in a
format Git can actually work with. That "if" is the whole argument.
Git fixes all three for documents the same way it fixes them for code, but only *if* the documents
are in a format Git can actually work with. That "if" is the whole argument.
### Why plain text wins: the diff is line-based
@@ -72,7 +72,7 @@ you exactly that:
That is a perfect change record. A reviewer reads it in two seconds. Two people can edit different
sections and Git merges them automatically, because the changes touch different lines.
Now do the same edit in a `.docx`. A Word document isn't text it's a zipped bundle of XML, styles,
Now do the same edit in a `.docx`. A Word document isn't text; it's a zipped bundle of XML, styles,
and metadata. Git happily tracks it, but it can't diff it meaningfully. Ask for the diff and you get:
```
@@ -80,7 +80,7 @@ Binary files a/runbook.docx and b/runbook.docx differ
```
That's it. That's the entire change record: *something* changed. You can't see *what*, you can't
review it, and you can't merge two people's edits Git will force you to pick one whole file and
review it, and you can't merge two people's edits; Git will force you to pick one whole file and
throw the other away. The version history exists and is **completely useless**. `.pptx` is worse,
because slide decks are even more structure and even less text.
@@ -96,16 +96,16 @@ The honest counterpoint, where binary formats still earn their place, is in *Whe
You don't need to convert everything. These are the high-value targets, all naturally plain text:
- **READMEs** how to run the thing. Already markdown by convention; you saw `tasks-app/README.md`
- **READMEs:** how to run the thing. Already markdown by convention; you saw `tasks-app/README.md`
in Module 1.
- **ADRs (Architecture Decision Records)** short documents that capture *one* decision: the
- **ADRs (Architecture Decision Records):** short documents that capture *one* decision: the
context, the choice, and the consequences. The point is to make the *reasoning* survive the
meeting. An ADR lives next to the code, gets versioned with it, and answers "why is it like this?"
long after everyone's forgotten.
- **Runbooks** the step-by-step for an operational task (deploy, restore, rotate a key, respond to
- **Runbooks:** the step-by-step for an operational task (deploy, restore, rotate a key, respond to
an alert). These get edited under pressure, which is exactly when you want clean history and undo.
- **Changelogs** what changed in each release. A markdown `CHANGELOG.md` is the standard.
- **Specs / PRDs** what you're going to build and why, before you build it.
- **Changelogs:** what changed in each release. A markdown `CHANGELOG.md` is the standard.
- **Specs / PRDs:** what you're going to build and why, before you build it.
For this audience the ADR is the easiest win: small, structured, high-value, and the kind of thing
that *never* gets written because it feels like overhead, right up until the AI drafts it for you in
@@ -136,14 +136,14 @@ Two new-command notes for this audience:
- **`git switch -c <name>`** creates and moves onto a branch. (Older docs and muscle memory use
`git checkout -b <name>`; `switch` is the newer, clearer verb for the same thing. Either works.)
- **`git diff` shows nothing for a brand-new file** until Git is tracking it new files are
- **`git diff` shows nothing for a brand-new file** until Git is tracking it; new files are
"untracked," and `git diff` only compares *tracked* changes. That's why the loop above does
`git add` *then* `git diff --staged` (also spelled `--cached`): staging tells Git "track this," and
`--staged` shows you what's staged. For a new file the diff is all-additions, which is fine you're
`--staged` shows you what's staged. For a new file the diff is all-additions, which is fine; you're
still reading every line before it lands.
Because this is one document on its own branch, the merge is trivial: nothing else touched `main`
while you worked, so Git **fast-forwards** it just slides `main` up to your branch with no
while you worked, so Git **fast-forwards**; it just slides `main` up to your branch with no
conflict. That clean case is the whole reason we practice here first. What happens when two branches
edit the *same lines* (a merge conflict) is a real skill, and it gets its own treatment in
**Module 6**, on code, where the stakes make it worth the depth. Practice the happy path now; the
@@ -155,7 +155,7 @@ Most Git hosts (GitHub, GitLab, Gitea, and others) ship a **wiki** alongside eac
looks like a web app: you click "New Page," type in a box, hit save. It feels like a different kind
of thing from your code.
It isn't. On essentially every one of these hosts, **the wiki is itself a Git repository** a
It isn't. On essentially every one of these hosts, **the wiki is itself a Git repository**, a
separate repo, usually addressable as something like `your-project.wiki.git`, full of markdown files.
Every page is a `.md` file. Every "save" in the web UI is a commit. The web editor is just a
convenience layer over `git commit`.
@@ -174,7 +174,7 @@ wearing a web UI.)
Here's why this module is more than "learn Git on easy mode":
- **LLMs are native markdown writers.** Markdown is arguably the *most* fluent output format these
models have they were trained on oceans of it, and they reach for it by default. Asking an AI to
models have; they were trained on oceans of it, and they reach for it by default. Asking an AI to
"write an ADR for this decision" or "turn these rough notes into a runbook" plays directly to its
strengths. The output is genuinely good and genuinely in the right format, with zero conversion.
- **"Draft it, branch it, diff it, merge it" works today.** You don't need new tools, a new model, or
@@ -209,7 +209,7 @@ zero.
- The ADR template from this module's `lab/adr-template.md` (and `lab/runbook-template.md` if you
want to do the variant at the end).
### Part A Branch for the document
### Part A: Branch for the document
1. Confirm you're starting clean, then create a branch for the ADR:
@@ -222,7 +222,7 @@ zero.
You're now working on a copy. Nothing you do here touches `main` until you merge.
### Part B Let the AI draft the ADR
### Part B: Let the AI draft the ADR
2. Make a home for decision records:
@@ -250,7 +250,7 @@ zero.
stretch before Module 4 removes it.) The file has to exist on disk before the next part can stage
it.
### Part C Review the diff before you accept it
### Part C: Review the diff before you accept it
5. A brand-new file is untracked, so `git diff` shows nothing yet. Stage it, then review:
@@ -272,7 +272,7 @@ zero.
git log --oneline # your new checkpoint, on this branch
```
### Part D Make a one-line edit and see the line-based diff
### Part D: Make a one-line edit and see the line-based diff
7. Edit one sentence in the ADR (tighten a line, fix a claim, whatever). Save, then:
@@ -288,14 +288,14 @@ zero.
git commit -m "Tighten ADR 0001 rationale"
```
### Part E Merge it into main
### Part E: Merge it into main
8. First, switch back to `main` and prove the document isn't there yet. You created the whole
`docs/adr/` directory on the branch, so on `main` it doesn't exist:
```bash
git switch main
ls docs/adr/ # error: "No such file or directory" — it's only on the branch
ls docs/adr/ # error: "No such file or directory", only on the branch
git log --oneline # and your ADR commits aren't here either
```
@@ -317,7 +317,7 @@ zero.
You just ran the complete branch → draft → diff → commit → merge loop on a real document, with the AI
doing the writing and you doing the reviewing. That's the loop the rest of the course runs on.
### Optional do it again as a runbook
### Optional: do it again as a runbook
Repeat the loop on a different branch (`git switch -c docs/runbook-restore`) using
`runbook-template.md` from this module's `lab/` folder: ask the AI to write a runbook for "restore the
@@ -330,7 +330,7 @@ on next run. Same five parts. Doing it twice is what turns the commands into ref
- **Line-based diffs punish reflowed paragraphs.** Git diffs *lines*. If you (or the AI) rewrap a
paragraph so every line shifts, the diff shows the whole paragraph as changed even if you altered
three words the clean diff degrades toward `.docx`-style noise. The fix the technical-writing
three words; the clean diff degrades toward `.docx`-style noise. The fix the technical-writing
world uses is **semantic line breaks**: write one sentence (or one clause) per line, so edits stay
local and diffs stay surgical. Worth knowing the AI will *not* do this by default; you can ask it
to.
@@ -339,8 +339,8 @@ on next run. Same five parts. Doing it twice is what turns the commands into ref
it just can't show you what changed inside them. Diagrams-as-code (text formats that render to
pictures) sidestep this, but that's beyond this module.
- **Word and PowerPoint still exist for reasons.** A pixel-precise client deliverable, a slide deck
with heavy layout, a document a non-technical stakeholder must edit in a tool they already know
these are real constraints. The argument isn't "markdown for everything." It's "anything that needs
with heavy layout, a document a non-technical stakeholder must edit in a tool they already know.
These are real constraints. The argument isn't "markdown for everything." It's "anything that needs
history, review, or multiple authors is paying a steep tax in a binary format." Pick the targets
where that tax actually bites: runbooks, ADRs, specs, changelogs.
- **Merge conflicts are real; you just didn't hit one.** This lab fast-forwarded because nothing else
@@ -348,10 +348,10 @@ on next run. Same five parts. Doing it twice is what turns the commands into ref
That's a genuine skill, deferred to **Module 6** on purpose so you learn it where the stakes make it
matter.
- **The wiki-clone aha needs a remote.** You can *see* that a host's wiki is a Git repo now, but
cloning it, editing locally, and pushing back requires remotes **Module 8**. The realization is
cloning it, editing locally, and pushing back requires remotes, which is **Module 8**. The realization is
yours today; the round trip waits a few modules.
- **The AI writes confident fiction.** It will produce a fluent ADR with a rationale that sounds
exactly like something a senior engineer wrote and is sometimes simply made up. The format makes
exactly like something a senior engineer wrote, and is sometimes simply made up. The format makes
the document reviewable; it does not make the document *true*. Reading the diff is necessary, not
sufficient. You still have to know whether the reasoning is right.
@@ -363,12 +363,12 @@ on next run. Same five parts. Doing it twice is what turns the commands into ref
- Your `tasks-app` repo has an `docs/adr/0001-*.md` on `main`, authored by the AI and reviewed by you,
arrived there via a branch and a merge.
- You created a branch, committed to it, merged it back, and deleted it — and `git log --oneline` on
- You created a branch, committed to it, merged it back, and deleted it; `git log --oneline` on
`main` shows the ADR commits.
- You can explain, to a skeptical colleague, why the team's runbooks shouldn't be `.docx` files on a
shared drive using the line-based-diff argument, not just "markdown is nicer."
shared drive, using the line-based-diff argument, not just "markdown is nicer."
- You know that your Git host's wiki is itself a Git repo, and what that implies.
When branch/diff/commit/merge feels routine on a document, you're ready for **Module 4**, where the AI
finally comes out of the browser and starts editing your files directly a step that's only safe
finally comes out of the browser and starts editing your files directly, a step that's only safe
because you can now branch, diff, and revert exactly what it does.