Reframe sweep M7-27 + capstone (AI drives git, lesson=theory, de-slop) (#93)
Sync course wiki / sync-wiki (push) Successful in 11s
Sync course wiki / sync-wiki (push) Successful in 11s
Co-authored-by: claude <claude@jpaul.io> Co-committed-by: claude <claude@jpaul.io>
This commit was merged in pull request #93.
This commit is contained in:
@@ -1,15 +1,15 @@
|
||||
# Module 26 — Orchestrating Multiple Agents
|
||||
|
||||
> **One agent on its own branch was the experiment. Several agents at once, on their own branches,
|
||||
> integrated back through review — that's the payoff.** This module is where worktrees stop being a
|
||||
> neat trick and become an operating model, and where you meet the bottleneck that replaces compute:
|
||||
> your own attention.
|
||||
> integrated back through review: that's the payoff.** This module turns worktrees from a one-off
|
||||
> convenience into an operating model, and it introduces the bottleneck that replaces compute. That
|
||||
> bottleneck is your own attention.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Module 7 — Worktrees** — the load-bearing primitive. One repo, many working directories, each on
|
||||
- **Module 7 — Worktrees** — the primitive everything here rests on. One repo, many working directories, each on
|
||||
its own branch, each safe for an agent to edit without touching the others. Module 7 proved this on
|
||||
*two* agents and told you the scale-up lived here. This is here. If `git worktree add` /
|
||||
`list` / `remove` aren't muscle memory yet, go back — everything below is that, multiplied.
|
||||
@@ -60,7 +60,7 @@ Module 25 got you to a real milestone: hand an agent an issue, walk away, come b
|
||||
passed CI. The supervision was structural — the agent couldn't merge anything; it could only *propose*
|
||||
a reviewable change. That's one agent.
|
||||
|
||||
The thing nobody tells you about that milestone is how quickly you want a second one. The agent is
|
||||
What that milestone doesn't tell you is how quickly you want a second one. The agent is
|
||||
cheap and it works in wall-clock minutes, so the instant you have one job running you notice three
|
||||
*other* jobs sitting idle. The model isn't the constraint — it never was. The constraint was that
|
||||
all those jobs wanted the same repo, the same files, the same checked-out branch. Module 7 removed
|
||||
@@ -79,7 +79,7 @@ Everything below is one of those four management problems: **split, isolate, coo
|
||||
|
||||
### Problem 1 — Splitting work cleanly (the part everyone gets wrong)
|
||||
|
||||
The seductive failure mode is to look at a pile of work, declare "I'll run five agents on this," and
|
||||
The common failure mode is to look at a pile of work, declare "I'll run five agents on this," and
|
||||
fan it out by gut. It feels like a 5× speedup. It usually isn't, because **most work isn't as
|
||||
independent as it looks**, and the dependencies you ignored at split-time come back as merge
|
||||
conflicts at integrate-time — with interest.
|
||||
@@ -213,8 +213,8 @@ exactly as serial as they were.
|
||||
> bottleneck — and it doesn't fan out.** Orchestration is the discipline of spending that attention on
|
||||
> the two things only you can do (split and review) and letting the agents have everything in between.
|
||||
|
||||
That's not a disappointment; it's the job. The skill of this module is not "launch many agents" — any
|
||||
tool can do that. It's keeping the fan-in narrow enough that one human can still stand at the funnel.
|
||||
The skill of this module is not "launch many agents"; any tool can do that. It's keeping the fan-in
|
||||
narrow enough that one human can still stand at the funnel.
|
||||
|
||||
---
|
||||
|
||||
@@ -235,7 +235,7 @@ That changes the calculus specifically:
|
||||
parallel.** The temptation to fan out is strongest exactly when you're most rushed, which is exactly
|
||||
when you're least careful about the seams. Fanning out non-parallel work doesn't speed it up; it
|
||||
converts a clean sequential job into a conflicted parallel one and *adds* the merge tax.
|
||||
- **Review is the load-bearing wall and agents push on it hardest.** One agent makes you review one
|
||||
- **Review is the wall everything rests on, and agents push on it hardest.** One agent makes you review one
|
||||
diff. Five agents make you review five — and they all finished while you were reviewing the first.
|
||||
This is the concrete reason the whole back half of this course (review, CI, security gates) had to
|
||||
exist *before* this module: those gates are the only things that let one human stay in the loop on
|
||||
@@ -270,14 +270,17 @@ thing you're waiting on.
|
||||
branch and review the diff there." You lose the forge UI, not the lesson.
|
||||
- Worktrees working (Module 7) — `git --version` ≥ 2.5.
|
||||
- **Three** AI edit sessions you can run at once (Module 4): three editor windows, three terminal
|
||||
agent sessions, or — if your agentic tool can spawn parallel sub-agents — one orchestrator driving
|
||||
three. Browser-only still works; treat each worktree as a separate copy-paste context, but you'll
|
||||
feel the coordination cost more sharply (which is fine — that's the lesson).
|
||||
- The starter files in this module's `lab/` folder: `orchestration-plan.md`, `fan-out.sh`,
|
||||
`status.sh`, `cleanup.sh`, and three prompts under `lab/agent-prompts/`. As established back in
|
||||
Module 4, the course's lab scripts live in the course repo while `tasks-app` is a separate folder —
|
||||
so **copy the scripts into `tasks-app` and run them by name** (`bash fan-out.sh`), using your real
|
||||
course path in place of `/path/to/`.
|
||||
agent sessions, or one orchestrator driving three sub-agents if your tool supports it (Claude Code
|
||||
is the worked example here; sub your own agent). Browser-only still works; treat each worktree as a
|
||||
separate copy-paste context, but you'll feel the coordination cost more sharply, which is the lesson.
|
||||
- The starter files in this module's `lab/` folder, at
|
||||
`~/ai-workflow-course/modules/26-orchestrating-multiple-agents/lab/`: `orchestration-plan.md`,
|
||||
`fan-out.sh`, `status.sh`, `cleanup.sh`, and three prompts under `lab/agent-prompts/`. As
|
||||
established back in Module 4, the course's lab scripts live in the course repo while `tasks-app` is a
|
||||
separate folder. Here the worktree git is the **AI's** job (the Module 4 pivot): you direct a
|
||||
coordinating session to create and tear down the worktrees and you verify the result, with the
|
||||
scripts as the tool-agnostic fallback if you'd rather hand the agent a script to run than have it
|
||||
type the commands. `status.sh` stays a read-only dashboard you run yourself.
|
||||
|
||||
### Part A — Plan the split before you launch anything (this is the lab)
|
||||
|
||||
@@ -298,23 +301,26 @@ thing you're waiting on.
|
||||
|
||||
### Part B — Fan out
|
||||
|
||||
3. From inside `tasks-app`, copy this module's lab scripts in and create a worktree per issue:
|
||||
3. Create a worktree per issue. An agent that lives inside a worktree can't create its own worktree,
|
||||
so direct your **coordinating session** (the AI already pointed at `tasks-app` from Module 4 —
|
||||
Claude Code in this example; sub your own agent) to set them up from the plan:
|
||||
|
||||
> *"From the `tasks-app` repo, create one linked worktree per row in `orchestration-plan.md`, each
|
||||
> as a sibling folder on its issue-named branch: `../tasks-app-42-count` on `feature/42-count`,
|
||||
> `../tasks-app-43-docs` on `feature/43-docs`, and `../tasks-app-44-clear` on `feature/44-clear`.
|
||||
> Leave `main` untouched. Then show me `git worktree list`."*
|
||||
|
||||
That's three `git worktree add` calls and a `git worktree list`, run for you. (Prefer a script?
|
||||
Hand the agent `fan-out.sh` from this module's `lab/` and have it run that instead — same result,
|
||||
tool-agnostic.) Then **verify** by hand:
|
||||
|
||||
```bash
|
||||
cp /path/to/modules/26-orchestrating-multiple-agents/lab/*.sh . # fan-out.sh, status.sh, cleanup.sh
|
||||
bash fan-out.sh
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git worktree list # main + the three feature/ worktrees
|
||||
```
|
||||
|
||||
It runs, in effect:
|
||||
|
||||
```bash
|
||||
git worktree add ../tasks-app-42-count -b feature/42-count
|
||||
git worktree add ../tasks-app-43-docs -b feature/43-docs
|
||||
git worktree add ../tasks-app-44-clear -b feature/44-clear
|
||||
git worktree list
|
||||
```
|
||||
|
||||
Four folders, one repo, `main` untouched and reserved for integration.
|
||||
Four folders, one repo, `main` untouched and reserved for integration. You directed, the agent did
|
||||
the git, you confirmed.
|
||||
|
||||
4. Launch the three agents **at the same time**, each pointed at its own worktree and given its own
|
||||
prompt:
|
||||
@@ -323,24 +329,31 @@ thing you're waiting on.
|
||||
- `tasks-app-43-docs` ← `lab/agent-prompts/agent-43-docs.md`
|
||||
- `tasks-app-44-clear` ← `lab/agent-prompts/agent-44-clear.md`
|
||||
|
||||
While they run, watch the fleet from a fourth terminal (run from inside `tasks-app`, where you
|
||||
copied the scripts in step 3):
|
||||
While they run, watch the fleet. Copy the read-only dashboard into `tasks-app` and run it from a
|
||||
fourth terminal:
|
||||
|
||||
```bash
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
cp ~/ai-workflow-course/modules/26-orchestrating-multiple-agents/lab/status.sh .
|
||||
bash status.sh
|
||||
```
|
||||
|
||||
It prints each worktree, its branch, and how many commits/changes are in flight — your fleet
|
||||
It prints each worktree, its branch, and how many commits/changes are in flight: your fleet
|
||||
dashboard. Update the **Status** column in the plan as each finishes.
|
||||
|
||||
5. In each worktree, commit the agent's work on its own branch and push it:
|
||||
5. Have each agent commit and push its own work. Each prompt already ends by telling its agent to
|
||||
commit the change on its branch and push it; to trigger it explicitly, tell each session: *"Commit
|
||||
your work on this branch with a message that references the issue, then push the branch."* Each
|
||||
agent owns its own commit and push, so three branches advance in parallel with no git typed by you.
|
||||
Then **verify** the fleet landed:
|
||||
|
||||
```bash
|
||||
cd ~/ai-workflow-course/tasks-app-42-count && git add . && git commit -m "Add count command (#42)" && git push -u origin feature/42-count
|
||||
cd ~/ai-workflow-course/tasks-app-43-docs && git add . && git commit -m "Document commands, add changelog (#43)" && git push -u origin feature/43-docs
|
||||
cd ~/ai-workflow-course/tasks-app-44-clear && git add . && git commit -m "Add clear command (#44)" && git push -u origin feature/44-clear
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
bash status.sh # each branch should show commits ahead of main and DIRTY? = no
|
||||
```
|
||||
|
||||
(No remote? Drop the push; the branches still exist locally and you'll integrate them in Part C.)
|
||||
|
||||
### Part C — Fan in through the funnel
|
||||
|
||||
6. Open **one PR per branch** on your forge (Module 11), each linked to its issue. You now have three
|
||||
@@ -351,35 +364,46 @@ thing you're waiting on.
|
||||
finished in parallel, and you are reading their diffs in series. Time yourself if you want the
|
||||
point to land.
|
||||
|
||||
8. **Merge in deliberate order, not finish order.** Merge the two clean, independent PRs first:
|
||||
8. **Merge in deliberate order, not finish order.** The order is *your* call, the part only you can
|
||||
make: merge the two clean, independent branches first, then the one you flagged as a collision, so
|
||||
the conflict surfaces against settled code. Direct your coordinating session (in the `tasks-app`
|
||||
main worktree) to do the merges in exactly that order, and to stop on the first conflict instead of
|
||||
resolving it:
|
||||
|
||||
```bash
|
||||
# via the forge UI, or locally:
|
||||
cd ~/ai-workflow-course/tasks-app && git switch main
|
||||
git merge feature/42-count # clean
|
||||
git merge feature/43-docs # clean — different files entirely
|
||||
> *"On `main` in `tasks-app`, merge `feature/42-count`, then `feature/43-docs`, then
|
||||
> `feature/44-clear`, in that order. After each, tell me whether it merged cleanly or conflicted.
|
||||
> If one conflicts, stop and show me the conflict — don't resolve it yet."*
|
||||
|
||||
The first two land clean (disjoint files). The third stops on a conflict:
|
||||
|
||||
```text
|
||||
CONFLICT (content): Merge conflict in cli.py
|
||||
Automatic merge failed; fix conflicts and then commit the result.
|
||||
```
|
||||
|
||||
Now merge the one you flagged as a collision:
|
||||
|
||||
```bash
|
||||
git merge feature/44-clear
|
||||
# CONFLICT (content): cli.py — both #42 and #44 added an elif to the dispatch chain
|
||||
```
|
||||
|
||||
There it is — the conflict you predicted in Part A, exactly where the plan said it would be.
|
||||
Resolve it with the Module 6 skill (keep both the `count` and `clear` branches), then:
|
||||
There it is: the conflict you predicted in Part A, exactly where the plan said it would be — both
|
||||
#42 and #44 added an `elif` to the same dispatch chain. Read the conflict yourself before you let
|
||||
the agent touch it; seeing it land where you called it is the whole point of the prediction you
|
||||
wrote in Part A. Then direct the agent to resolve it the Module 6 way — *keep both the `count` and
|
||||
`clear` branches, then stage and commit the merge* — and **verify** the result by hand:
|
||||
|
||||
```bash
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
python cli.py list && python cli.py count && python cli.py clear # all three features live
|
||||
git add cli.py && git commit
|
||||
```
|
||||
|
||||
If any of those three commands fails, the resolution was wrong. That's why you verify the result
|
||||
instead of trusting the merge.
|
||||
|
||||
9. Close the issues (Module 11 closes them automatically if the PRs referenced them). Then tear the
|
||||
fleet down (from inside `tasks-app`):
|
||||
fleet down: direct your coordinating session to *remove the three worktrees now that their work is
|
||||
merged, then prune and show `git worktree list`*. (Prefer a script? Hand it `cleanup.sh` from this
|
||||
module's `lab/`.) Either way it refuses to remove a worktree that still has uncommitted work —
|
||||
Git's safety — so commit or merge anything stray first. Verify only `main` remains:
|
||||
|
||||
```bash
|
||||
bash cleanup.sh
|
||||
cd ~/ai-workflow-course/tasks-app
|
||||
git worktree list # just main
|
||||
```
|
||||
|
||||
### Part D — Score the orchestration honestly
|
||||
@@ -465,7 +489,7 @@ Re-check at build/publish time:
|
||||
|
||||
- [ ] **Parallel-agent / sub-agent features in agentic tools.** Whether and how current tools launch
|
||||
and manage parallel sessions, background agents, or orchestrator-and-sub-agent patterns — names,
|
||||
limits, and defaults drift fast. Keep the prose describing the *capability* generically; don't
|
||||
limits, and defaults drift fast. Keep the writing describing the *capability* generically; don't
|
||||
pin a vendor's feature name.
|
||||
- [ ] **Native worktree management in agentic tools.** Some tools now create/manage worktrees per
|
||||
session automatically. If that's mainstream at publish time, note it so learners aren't doing by
|
||||
|
||||
@@ -19,4 +19,5 @@ You are working in this worktree only. Do not touch any other folder.
|
||||
- No other files change. (`README.md`, `CHANGELOG.md`, and `tasks.py` are owned by other agents —
|
||||
stay out of them.)
|
||||
|
||||
When done, stop. The human commits, pushes, and opens the PR.
|
||||
When done, commit your work on this branch with a message referencing #42, then push the branch. Stop
|
||||
there; the human opens and reviews the PR.
|
||||
|
||||
@@ -23,4 +23,5 @@ You are working in this worktree only. Do not touch any other folder, and do not
|
||||
- `CHANGELOG.md` exists and is valid markdown.
|
||||
- No code files change.
|
||||
|
||||
When done, stop. The human commits, pushes, and opens the PR.
|
||||
When done, commit your work on this branch with a message referencing #43, then push the branch. Stop
|
||||
there; the human opens and reviews the PR.
|
||||
|
||||
@@ -20,5 +20,6 @@ You are working in this worktree only. Do not touch any other folder.
|
||||
- `python cli.py clear` removes all tasks and prints `cleared`.
|
||||
- `python cli.py list` afterward shows `(no tasks yet)`.
|
||||
|
||||
When done, stop. The human commits, pushes, and opens the PR — and should expect a conflict against
|
||||
`feature/42-count` at merge.
|
||||
When done, commit your work on this branch with a message referencing #44, then push the branch. Stop
|
||||
there; the human opens and reviews the PR, and should expect a conflict against `feature/42-count` at
|
||||
merge.
|
||||
|
||||
Reference in New Issue
Block a user