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
@@ -1,4 +1,4 @@
# Module 21 Skills: Teaching the AI Your Playbook
# Module 21: Skills: Teaching the AI Your Playbook
> **Stop re-explaining your own procedures.** A skill is a repeatable workflow written down once,
> committed, and invoked on demand, so the AI does the thing *your* way, the same way, every time,
@@ -14,7 +14,7 @@
writes to.
- **Module 4:** the AI lives in your editor/CLI and reads your files directly. A skill is a file it
loads; a browser chat can't pick one up automatically.
- **Module 5 the one this builds on directly.** You committed an always-on instructions file that
- **Module 5, the one this builds on directly.** You committed an always-on instructions file that
tells the AI how the project works in general. This module is its **structured big sibling**: the
same write-it-down-and-commit instinct, but for *specific repeatable procedures* invoked on demand.
- **Module 13:** what a real test is (and why "it didn't crash" isn't one). The lab's procedure
@@ -82,7 +82,7 @@ This is the distinction to lock in, because the two are siblings and easy to con
| | **Committed instructions file (Module 5)** | **Skill (this module)** |
|---|---|---|
| Scope | How the project works, *in general* | How to do *one specific procedure* |
| When it loads | **Always on** read every session | **On demand** invoked when relevant |
| When it loads | **Always on**: read every session | **On demand**: invoked when relevant |
| Shape | Ambient briefing: conventions, commands, don't-touch list | A playbook: when-to-use, inputs, ordered steps, done-criteria |
| Analogy | The standing house rules posted on the wall | A labeled recipe card you pull out when you cook that dish |
@@ -154,7 +154,7 @@ On paper this is just "write a runbook." The AI-specific twist is what changes t
is how you make *complete* the default instead of a thing you have to keep catching.
- **The skill outlives the model.** Swap models next quarter and the playbook carries over unchanged.
You encoded the *procedure*, not the prompt that happened to coax it out of this month's model. The
workflow is the durable skill; the model is the swappable part here, literally.
workflow is the durable skill; the model is the swappable part; here, literally.
---
@@ -177,7 +177,7 @@ seen, producing all four parts without you listing the steps.
ask Claude Code (`claude` in the project; sub your own agent) to initialize it and commit a
baseline, then confirm with `git log` that the first commit landed.
### Part A Install the skill
### Part A: Install the skill
1. Copy this module's starter skill, `lab/add-command-skill.md`, into your `tasks-app` repo wherever
your tool expects procedures. If your tool auto-discovers a folder, put it there under a clear name
@@ -200,7 +200,7 @@ seen, producing all four parts without you listing the steps.
git log --oneline -1 # the skill commit, by name
```
### Part B Invoke it
### Part B: Invoke it
4. Start a **fresh** AI session in your editor and invoke the skill the way your tool does it: its
slash command / skill name, or plainly: *"Follow `add-command.md` to add a `clear` command that
@@ -215,14 +215,14 @@ seen, producing all four parts without you listing the steps.
- add a `CHANGELOG.md` line;
- stage code + test + changelog into one commit, **without** `tasks.json`.
### Part C Verify it followed the playbook
### Part C: Verify it followed the playbook
6. Don't take the AI's word for it. Check against the skill's own done-criteria:
```bash
python -m unittest # green, and a clear-related test is present
python cli.py add "x" && python cli.py clear && python cli.py list # -> (no tasks yet)
git show --stat HEAD # one commit: tasks.py, cli.py, test_tasks.py, CHANGELOG.md no tasks.json
git show --stat HEAD # one commit: tasks.py, cli.py, test_tasks.py, CHANGELOG.md; no tasks.json
```
If a step was skipped, that's the lab working: it shows you exactly where your wording was too soft.
@@ -230,7 +230,7 @@ seen, producing all four parts without you listing the steps.
diff, and run it again on a second command (`high <index>` to flag a task, say). **A skill you
improve once and reuse forever is the deliverable**, not the one `clear` command.
### Part D See it as a reviewable, reusable asset
### Part D: See it as a reviewable, reusable asset
7. Look at what you built:
@@ -239,7 +239,7 @@ seen, producing all four parts without you listing the steps.
git log -p -- add-command.md # full patch history: the file's creation, plus the Part C tighten if you made one
```
(`git log -p` surfaces the skill's own patches no matter what you committed *after* tightening it
(`git log -p` surfaces the skill's own patches no matter what you committed *after* tightening it,
unlike `git diff HEAD~1`, which would be empty here because the most recent commit added the second
*command*, not a change to the skill.) Each entry in that history *is* a change to how your team adds
commands: readable, attributable, revertable. In a
@@ -250,10 +250,10 @@ seen, producing all four parts without you listing the steps.
## Where it breaks
- **A skill is guidance, not enforcement same caveat as Module 5.** It strongly biases the AI; it
- **A skill is guidance, not enforcement; same caveat as Module 5.** It strongly biases the AI; it
doesn't bind it. The agent can still skip a step, especially a soft one, especially late in a long
session. The steps that *can't* be skipped are the ones backed by **CI (Module 14)**: the test the
skill tells it to write only truly gates anything once a pipeline runs it on every push. Write the
skill tells it to write only gates anything once a pipeline runs it on every push. Write the
done-criteria as hard checks, and let CI be the backstop.
- **Skills rot.** A playbook that says "tests run with X" after you've moved to Y will confidently
march the AI off a cliff. Skills are code-adjacent: review them, update them, delete the ones you no
@@ -1,14 +1,14 @@
# Skill: Add a new tasks-app command, end to end
> A reusable playbook. Don't paste this whole file into a chat and hope. Point your agentic tool at
> it by name "follow `add-command.md` to add a `clear` command" or drop it wherever your tool
> it by name ("follow `add-command.md` to add a `clear` command"), or drop it wherever your tool
> auto-discovers procedures (a skills/commands folder). The steps are the same either way.
## When to use this
Invoke this whenever the task is **"add a new subcommand to the `tasks-app` CLI."** It exists so a
new command lands the *same* way every time: real code, a real test, a changelog line, and a clean
commit never just the code with the rest forgotten.
commit; never just the code with the rest forgotten.
If the task is *not* "add a CLI command" (a bug fix, a refactor, a docs change), this skill does not
apply. Don't force it.
@@ -17,18 +17,18 @@ apply. Don't force it.
Ask for these if they weren't given:
- `COMMAND_NAME` the subcommand word, e.g. `clear`.
- `WHAT_IT_DOES` one sentence of intended behavior, e.g. "remove all tasks."
- `COMMAND_NAME`: the subcommand word, e.g. `clear`.
- `WHAT_IT_DOES`: one sentence of intended behavior, e.g. "remove all tasks."
## Project facts (so you don't have to rediscover them)
- Core logic lives in `tasks.py` (the `TaskList` class). The CLI front end is `cli.py`. State
persists to `tasks.json` **never edit `tasks.json` by hand; it's generated.**
- Tests live in `test_tasks.py` and run with `python -m unittest`. Standard library only no
persists to `tasks.json`. **Never edit `tasks.json` by hand; it's generated.**
- Tests live in `test_tasks.py` and run with `python -m unittest`. Standard library only; no
third-party packages, no new dependencies.
- The human-facing change log is `CHANGELOG.md`, newest entry on top.
## Procedure do these in order, do not skip
## Procedure: do these in order, do not skip
1. **Core logic in `tasks.py`.** If the command needs new behavior on the task list, add a small
method to `TaskList` (e.g. `clear()`). Keep it minimal; match the existing style. If the command
@@ -43,7 +43,7 @@ Ask for these if they weren't given:
A test that passes against a broken implementation is worse than no test.
4. **Run the tests.** `python -m unittest` from the project root. Do not claim success until it's
green. If it fails, fix the code not the test and run again.
green. If it fails, fix the code, not the test, and run again.
5. **Smoke-test the CLI.** Actually run it: `python cli.py COMMAND_NAME`, then `python cli.py list`
to confirm the visible result. Paste what you ran and what it printed.
@@ -60,8 +60,8 @@ Ask for these if they weren't given:
- `python -m unittest` is green and includes a new test that actually exercises `COMMAND_NAME`.
- `python cli.py COMMAND_NAME` does `WHAT_IT_DOES` and you've shown the output.
- `CHANGELOG.md` has a new top line for the command.
- One commit contains the code, the test, and the changelog line and nothing else (no
- One commit contains the code, the test, and the changelog line, and nothing else (no
`tasks.json`, no unrelated reformatting).
If any of those is missing, the skill isn't finished. Report which step failed and stop don't
If any of those is missing, the skill isn't finished. Report which step failed and stop; don't
paper over it.
@@ -5,7 +5,7 @@ Run it:
python cli.py list
python cli.py count
State is kept in tasks.json next to this file. The same minimal app from Module 1 onward the
State is kept in tasks.json next to this file. The same minimal app from Module 1 onward; the
target your "add a command" skill extends.
"""