Reframe sweep M7-27 + capstone (AI drives git, lesson=theory, de-slop) (#93)
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:
2026-06-22 21:58:36 -04:00
committed by Claude (agent)
parent a29823f4b3
commit 513d7e7ac8
38 changed files with 1735 additions and 1424 deletions
+49 -37
View File
@@ -1,8 +1,8 @@
# Module 9 — Issues and the Task Layer
> **An issue is how you hand a piece of work to someone else and "someone else" is now a mix of
> **An issue is how you hand a piece of work to someone else, and "someone else" is now a mix of
> humans and agents.** A well-formed issue is the one interface that works for both, which makes
> writing them a higher-leverage skill than it has ever been.
> writing them more valuable than they used to be.
---
@@ -12,7 +12,7 @@
forge, alongside the code, so this module needs the remote you set up there. Everything here is
provider-neutral: issues exist on every forge.
- **Module 5** — you committed your AI instructions file. That file plus a good issue is what gives
an agent enough context to attempt a task; this module is where that pairing starts to pay off.
an agent enough context to attempt a task; this module puts that pairing to work.
- **Module 2** — the repo-as-durable-memory reframe. Issues are the team-scale version of the same
idea: shared memory for the work that *hasn't happened yet*.
- **Module 1** — the `tasks-app` project. The lab writes issues against it.
@@ -77,7 +77,7 @@ human or a machine. Neither depends on anyone remembering anything.
### Anatomy of a well-formed issue
Most issues are written badly because they're written for the author, who already has all the
context. A good issue is written for **a stranger** because increasingly the thing that picks it
context. A good issue is written for **a stranger**, because increasingly the thing that picks it
up *is* one: a teammate you've never met, future-you who's forgotten, or an agent with no memory at
all. Four parts carry the weight:
@@ -128,9 +128,9 @@ small and orthogonal — a handful of axes, not forty decorative tags:
- **Priority** — `p1`/`p2`/`p3` or `high`/`med`/`low`. How much it matters.
- **Area** — `cli`, `storage`, `docs`. Which part of the system, for routing to whoever (or whatever)
owns it.
- **Readiness** — a single label like `ready` meaning "well-formed enough to start." This one earns
its keep in the AI era: it's the signal that an issue has clear acceptance criteria and can be
handed off to a person *or* an agent without more discussion.
- **Readiness** — a single label like `ready` meaning "well-formed enough to start." This one matters
most in the AI era: it's the signal that an issue has clear acceptance criteria and can be handed
off, to a person *or* an agent, without more discussion.
Resist label sprawl. If a label never changes how you filter or who picks up the work, delete it.
Five well-chosen labels beat thirty that no one trusts.
@@ -142,8 +142,8 @@ person (or agent) the rest of the team can assume is handling it. The discipline
*one* owner — an issue assigned to three people is assigned to no one. Unassigned-but-`ready` is a
fine state too; it means "available, anyone can grab this."
This is the mechanic that turns a pile of issues into coordinated work. And it's where the thesis of
this module lands.
This is the mechanic that turns a pile of issues into coordinated work, and it leads straight to the
point this module turns on.
### The roster is mixed now — humans and agents
@@ -165,7 +165,7 @@ for both.
So how do you decide? A useful heuristic, which is really a property of the *issue*, not the model:
**Hand it to an agent when the issue is well-scoped, has concrete acceptance criteria, and follows
a pattern already in the codebase.** An `undone <index>` command the inverse of `done` is a
a pattern already in the codebase.** An `undone <index>` command, the inverse of `done`, is a
strong candidate: it mirrors the existing command almost exactly, "clear the done flag" is
unambiguous, and a human can verify the result in seconds. The bug above is another: contained,
reproducible, testable.
@@ -178,7 +178,7 @@ right call. A human resolves the ambiguity first (often by splitting it into cle
which point the pieces may become agent-ready).
Notice the heuristic doesn't ask how smart the model is. It asks how well-specified the *work* is.
A vague issue degrades gracefully with a human — they ask you a question and catastrophically with
A vague issue degrades gracefully with a human, who asks you a question, and catastrophically with
an agent, which guesses and produces a confident, plausible, wrong PR. Routing is mostly about
matching the clarity of the issue to the autonomy of the assignee.
@@ -199,8 +199,8 @@ You don't need any of that yet. You need issues good enough to feed it. That's t
## The AI angle
The issue tracker itself isn't new. What's changed is that **the issue has quietly become an agent's
task specification**, and that raises the stakes on writing it well in three concrete ways:
The issue tracker itself isn't new. What's changed is that **the issue is now an agent's task
specification**, and that raises the stakes on writing it well in three concrete ways:
- **Acceptance criteria are the agent's definition of done.** A human reads fuzzy criteria and fills
the gaps with judgment. An agent reads them literally and stops when they're satisfied — so vague
@@ -227,9 +227,9 @@ valuable, not less.
**Lab language:** Markdown + shell, against the `tasks-app` repo you pushed to a forge in Module 8.
You'll draft issues as Markdown locally (so you can version and reuse the format), then create them
on your forge and route them. Drafting first keeps the *thinking* — the part that matters — separate
from whichever forge's web form you happen to be filling in.
You'll draft issues as Markdown locally (so you can version and reuse the format), then have your
agent create them on the forge and route them yourself. Drafting first keeps the *thinking*, the
part that matters, separate from the mechanical step of turning a draft into a forge issue.
**You'll need:**
@@ -241,7 +241,9 @@ from whichever forge's web form you happen to be filling in.
- The starter files in this module's `lab/` folder:
- `issue-template.md` — the well-formed-issue skeleton to copy for each issue.
- `example-issues.md` — three worked issues for `tasks-app`, as a reference/answer key.
- Your AI assistant (still in the browser is fine — you're writing issues, not code).
- Claude Code (or your own CLI/in-editor agent from Module 4), pointed at the `tasks-app` repo. It
can read the code directly to ground each issue's context, and create the issues on your forge once
you've drafted them.
### Part A — Find the work
@@ -259,30 +261,40 @@ Good candidates:
### Part B — Draft three well-formed issues
For each, copy `lab/issue-template.md` and fill every section: title, context (with repro steps for
the bug), acceptance criteria, and out-of-scope. Write them for a stranger.
For each, copy `lab/issue-template.md` to its own file (say `issue-bug.md`, `issue-undone.md`,
`issue-due-dates.md`) and fill every section: title, context (with repro steps for the bug),
acceptance criteria, and out-of-scope. Write them for a stranger.
This is a good place to *use* the AI: paste a file and ask it to draft acceptance criteria, then
**edit them down** — the model tends to over-produce, and tightening its draft is exactly the
skill. Check your drafts against `lab/example-issues.md` only after you've written your own.
This is a good place to *use* the AI: point Claude Code at `tasks-app` and ask it to draft acceptance
criteria against the actual code, then **edit them down**. The model tends to over-produce, and
tightening its draft is exactly the skill. Check your drafts against `lab/example-issues.md` only
after you've written your own.
### Part C — Create, label, and route
On your forge:
You've done the thinking; turning three Markdown drafts into real issues with labels is mechanical
forge work, so hand it to the agent and verify the result. From the repo, ask Claude Code (or your
own agent) to do it, for example: *"Create three issues on the forge from `issue-bug.md`,
`issue-undone.md`, and `issue-due-dates.md`. For each, set a type label (`bug`/`feature`), a
priority, and a `ready` label only where the acceptance criteria are solid enough to start."* The
agent uses the forge's CLI or API (`gh issue create` on GitHub, the equivalent elsewhere) to create
and label them.
1. Create the three issues (web UI, or your forge's CLI if you have one installed).
2. Apply a small label set to each: a **type** (`bug`/`feature`), a **priority**, and — for the ones
that qualify — a **`ready`** label meaning the acceptance criteria are solid enough to start.
3. **Route them.** This is the module's core exercise:
- Assign the **judgment-heavy feature (due dates) to a human** — yourself. It has unresolved
design questions; it is not agent-ready as written.
- Earmark the **bug** and the **`undone` feature for an agent.** They're well-scoped, patterned,
and easy to verify. Use whatever your forge offers: an actual agent assignee, an `agent-ready`
label, or just a note in the issue saying "suitable for an issue-to-PR agent (Module 25)." The
mechanism doesn't matter yet; the *decision* does.
Then **verify** on the forge: open the issue list, confirm all three exist, check the bodies match
your drafts, and check the labels are right. This is the Module 4 pattern. You direct, the agent does
the mechanical work, you confirm it landed.
Write one sentence in each issue, or in a scratch note, explaining **why** it went where it went —
in terms of the issue's clarity, not the model's smarts. That sentence is the routing skill.
**Routing is your call, not the agent's.** This is the module's core exercise:
- Assign the **judgment-heavy feature (due dates) to a human**, yourself. It has unresolved design
questions; it is not agent-ready as written.
- Earmark the **bug** and the **`undone` feature for an agent.** They're well-scoped, patterned, and
easy to verify. Use whatever your forge offers: an actual agent assignee, an `agent-ready` label,
or a note in the issue saying "suitable for an issue-to-PR agent (Module 25)." The mechanism
doesn't matter yet; the *decision* does.
Write one sentence in each issue, or a scratch note, explaining **why** it went where it went, in
terms of the issue's clarity rather than the model's smarts. That sentence is the routing skill.
### Part D — Read the backlog cold
@@ -316,8 +328,8 @@ The honest caveats — issues are not the repo, and they don't behave like it:
small and portable so it survives a forge change — don't build a workflow that depends on one
vendor's exact issue fields.
- **Over-tooling a tiny project is its own failure.** A solo throwaway script does not need a labeled,
prioritized backlog. Issues earn their keep when work is shared across people, across agents, or
across enough time that you'd otherwise forget. Below that threshold, a TODO comment is fine.
prioritized backlog. Issues pay off when work is shared: across people, across agents, or across
enough time that you'd otherwise forget. Below that threshold, a TODO comment is fine.
---