style(no-slop): remove every em-dash + banned words across all modules + capstone

Apply the no-ai-slop standard (now binding in AGENTS.md): the em-dash character is
banned outright (restructured, not blind-replaced), plus the banned word/phrase
list (delve, leverage, robust, seamless, truly, unlock, etc.). 0 em-dashes remain
in modules + capstone; the only "robust" left is the planted M10 ai-change.patch
trap. Module H1 titles use a colon separator.

All deliberate teaching devices preserved; labs compile/parse (py/sh/yaml/json);
no junk. AGENTS.md updated with the hard no-slop rules.

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 23:21:09 -04:00
parent 513d7e7ac8
commit 389ac2e460
99 changed files with 1324 additions and 1315 deletions
@@ -1,4 +1,4 @@
# Module 11 Collaboration: Humans and Agents on One Repo
# Module 11: Collaboration: Humans and Agents on One Repo
> **You now have every piece: issues, branches, PRs, review. This module wires them into one loop,
> and points out that half your "teammates" might not be human.** Once the loop runs the same way no
@@ -10,14 +10,14 @@
This is the synthesis module for Unit 2's collaboration arc. It assumes the whole chain up to here:
- **Module 2** commits as checkpoints, and `git diff`/`git log` as the record everyone reads.
- **Module 6** branches as isolated sandboxes; you make changes off `main`, not on it.
- **Module 7** worktrees, so more than one branch (and more than one agent) can be live at once
- **Module 2:** commits as checkpoints, and `git diff`/`git log` as the record everyone reads.
- **Module 6:** branches as isolated sandboxes; you make changes off `main`, not on it.
- **Module 7:** worktrees, so more than one branch (and more than one agent) can be live at once
without stepping on each other.
- **Module 8** a remote on a git host (GitHub the default; a self-hosted forge if you took that
- **Module 8:** a remote on a git host (GitHub the default; a self-hosted forge if you took that
track), so there's a shared copy to collaborate around.
- **Module 9** issues: the task layer that says *what* needs doing and *who* (human or agent) owns it.
- **Module 10** pull/merge requests and the skill of reviewing a diff you didn't write.
- **Module 9:** issues: the task layer that says *what* needs doing and *who* (human or agent) owns it.
- **Module 10:** pull/merge requests and the skill of reviewing a diff you didn't write.
Each of those taught one move. This module is the assembled motion. If you're missing one, the loop
still works, but a step will feel like a black box, so go back and fill it in.
@@ -28,15 +28,15 @@ still works, but a step will feel like a black box, so go back and fill it in.
By the end of this module you can:
1. Run the full collaboration loop end to end issue → branch → implementation → PR → review →
merge → issue auto-closed and explain why each step exists.
1. Run the full collaboration loop end to end (issue → branch → implementation → PR → review →
merge → issue auto-closed) and explain why each step exists.
2. Link a PR to an issue so the merge closes the issue automatically, and explain when that does and
doesn't fire.
3. Decide correctly between a **branch** and a **fork** based on whether you have push access.
4. Reason about **who's allowed to push**: roles, protected branches, and why "never commit to
`main`" stops being a personal habit and becomes an enforced rule.
5. Treat an agent as a contributor give it a branch, route an issue to it, review its PR on the
same gate you'd use for a human and know where a human has to stay in the loop.
5. Treat an agent as a contributor (give it a branch, route an issue to it, review its PR on the
same gate you'd use for a human) and know where a human has to stay in the loop.
---
@@ -47,7 +47,7 @@ By the end of this module you can:
Module 2 gave you the **inner loop**: edit, `git diff`, commit, repeat. That loop lives on your disk
and is yours alone. It's how *you* (or your agent) make progress in a working session.
This module is the **outer loop** the one the *team* sees:
This module is the **outer loop**, the one the *team* sees:
```
issue → branch → implementation → pull request → review → merge → issue closed
@@ -68,13 +68,13 @@ the module, and we'll come back to it.
### The loop, step by step
**1 The issue (Module 9) is the contract.** Before any code, there's a statement of intent: a
**1. The issue (Module 9) is the contract.** Before any code, there's a statement of intent: a
title, a description of the desired behavior, maybe acceptance criteria. It has a number (`#42`) that
the rest of the loop will reference. The issue exists so that "what we're doing and why" lives
somewhere durable and shared, not in one person's head or one chat session that'll evaporate
(Module 1, Seam 2). Assign it to whoever's taking it: a person, or an agent.
**2 The branch (Module 6) is the workspace.** You never implement on `main`. You cut a branch
**2. The branch (Module 6) is the workspace.** You never implement on `main`. You cut a branch
named for the work. Convention is something traceable like `42-clear-done-command` (the issue
number plus a slug). The name matters more than it looks: months later, `git branch` and the host's
branch list become a map of "what's in flight," and the issue number ties each branch back to its
@@ -85,7 +85,7 @@ git switch -c 42-clear-done-command # branch off main and switch to it
# Switched to a new branch '42-clear-done-command'
```
**3 Implementation is the inner loop (Module 2).** This is where the actual editing happens
**3. Implementation is the inner loop (Module 2).** This is where the actual editing happens:
you, or an agent, making commits on the branch. Nothing here is new; it's the edit/diff/commit
rhythm you already have. The branch keeps it isolated, so however bold the change, `main` is
untouched until the loop says otherwise.
@@ -95,22 +95,22 @@ git push -u origin 42-clear-done-command # publish the branch so others (and t
# branch '42-clear-done-command' set up to track 'origin/42-clear-done-command'.
```
**4 The pull request (Module 10) makes it reviewable.** Opening a PR says "this branch is ready
**4. The pull request (Module 10) makes it reviewable.** Opening a PR says "this branch is ready
to be considered for `main`." It bundles the diff, a description, and a discussion thread into one
reviewable unit. Crucially, **this is where you link back to the issue** (next section) so the loop
can close itself.
**5 Review (Module 10) is the judgment gate.** Someone who isn't the author reads the diff for
**5. Review (Module 10) is the judgment gate.** Someone who isn't the author reads the diff for
correctness *and plausibility*, the skill Module 10 is built around. They approve, request changes,
or comment. For AI-generated diffs this gate is doing more work than it used to: the code compiles,
reads cleanly, and is still wrong in a way only review catches.
**6 Merge is the commitment.** Approved, the PR merges into `main`. Hosts offer a couple of merge
**6. Merge is the commitment.** Approved, the PR merges into `main`. Hosts offer a couple of merge
styles, a squash or a merge commit; your team picks one and the effect is the same: the branch's work
is now part of the shared trunk. (You'll also see a *rebase-merge* option; it rewrites history and is
out of scope here.) Delete the branch after; its job is done and its name lives on in the merge.
**7 The issue closes ideally by itself.** If you linked the PR correctly, merging closes the
**7. The issue closes, ideally by itself.** If you linked the PR correctly, merging closes the
issue automatically. The receipt is written without anyone touching the issue. That's the satisfying
*click* of the whole loop landing, and it's the concrete thing the lab makes you feel.
@@ -123,7 +123,7 @@ The mechanic that makes step 7 free: put a **closing keyword** in the PR descrip
Closes #42
```
`Closes`, `Fixes`, and `Resolves` (and their variants `close/closed`, `fix/fixed`,
`Closes`, `Fixes`, and `Resolves` (and their variants `close/closed`, `fix/fixed`,
`resolve/resolved`) all work on the major hosts. When the PR merges **into the default branch**, the
host closes the referenced issue and cross-links the two so each shows the other. One line in the PR
body buys you a self-closing loop and a permanent trail from "why we did this" (issue) to "what we
@@ -179,9 +179,9 @@ have for production systems.
branch) as protected, and the host then *refuses* direct pushes to it. The only way in is a PR. You
can layer rules on top:
- **Require a pull request** no direct pushes, full stop. The loop is mandatory, not optional.
- **Require a review approval** at least one non-author approval before merge is allowed.
- **Restrict who can merge** only certain roles can click the button.
- **Require a pull request:** no direct pushes, full stop. The loop is mandatory, not optional.
- **Require a review approval:** at least one non-author approval before merge is allowed.
- **Restrict who can merge:** only certain roles can click the button.
Turning these on converts "we agreed not to push to `main`" into "the server won't let you." For a
solo learner this can feel like bureaucracy, but it's exactly the guardrail that makes it safe to add
@@ -280,7 +280,7 @@ loop, not the code, is what you're practicing.
Starter artifacts are in this module's `lab/`: `issue.md` (the issue to file) and `pr-body.md` (the
PR description, including the load-bearing closing keyword).
### Part A Set the guardrail (one-time)
### Part A: Set the guardrail (one-time)
Before the loop, make `main` enforce what you've been doing by hand. In your host's web UI, open the
repo's branch-protection settings and protect `main` with **"require a pull request before merging."**
@@ -304,7 +304,7 @@ was a throwaway to test the guardrail. Its full treatment and its real dangers a
If the push went through instead of bouncing, protection isn't on; fix that before continuing. Feeling
the server say *no* is the point: "never commit to `main`" is now a rule, not a resolution.
### Part B Issue → branch
### Part B: Issue → branch
1. **File the issue.** Create a new issue from `lab/issue.md` (title and body). Note its number; say
it's `#42`. This is the contract.
@@ -325,7 +325,7 @@ the server say *no* is the point: "never commit to `main`" is now a rule, not a
The branch-naming convention (issue number plus a short slug) is the thing to get right here, not
the keystrokes.
### Part C Implementation (with AI)
### Part C: Implementation (with AI)
3. Point Claude Code at `~/ai-workflow-course/tasks-app` and ask for the feature:
@@ -345,7 +345,7 @@ the server say *no* is the point: "never commit to `main`" is now a rule, not a
```bash
python cli.py add "keeper" ; python cli.py add "trash"
python cli.py list # note the index shown next to "trash"
python cli.py done <trash-index> # use the index "list" just printed NOT a fixed 1
python cli.py done <trash-index> # use the index "list" just printed, NOT a fixed 1
python cli.py clear-done # expect it to remove the completed one
python cli.py list # "keeper" remains, "trash" is gone
```
@@ -366,7 +366,7 @@ the server say *no* is the point: "never commit to `main`" is now a rule, not a
git show --stat HEAD # only tasks.py and cli.py listed; subject ends "(closes #42)"
```
### Part D PR → review → merge → auto-close
### Part D: PR → review → merge → auto-close
6. **Open the PR** from your branch into `main`, using `lab/pr-body.md` as the description. Make sure
the body contains the closing line with **your** issue number:
@@ -376,7 +376,7 @@ the server say *no* is the point: "never commit to `main`" is now a rule, not a
```
7. **Review it.** Open the PR's "Files changed" tab and read the diff *as a reviewer*, not as the
author the Module 10 move. For the full effect, pretend an agent wrote it (in a moment, one
author, the Module 10 move. For the full effect, pretend an agent wrote it (in a moment, one
will): is the logic where it belongs? Any edge case missed (empty list, nothing done yet)?
Approve it.
@@ -398,10 +398,10 @@ the server say *no* is the point: "never commit to `main`" is now a rule, not a
git branch # 42-clear-done-command no longer listed; you're on main
```
### Part E Now make the contributor an agent
### Part E: Now make the contributor an agent
Run the loop one more time, but this time **let an agent be the contributor for steps 26.** File a
second issue (e.g. "Add a `pending` command that lists only incomplete tasks" the `TaskList.pending()`
second issue (e.g. "Add a `pending` command that lists only incomplete tasks"; the `TaskList.pending()`
method already exists, so this is wiring only).
**First, a reality check the rest of the lab let you skip.** Two of those steps cross the forge