De-slop: remove every em-dash + banned words across all modules + capstone (#94)
Sync course wiki / sync-wiki (push) Successful in 4s
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:
@@ -1,4 +1,4 @@
|
||||
# Module 9 — Issues and the Task Layer
|
||||
# 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
|
||||
> humans and agents.** A well-formed issue is the one interface that works for both, which makes
|
||||
@@ -8,14 +8,14 @@
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Module 8** — you have a repo on a remote forge (GitHub or any alternative). Issues live on the
|
||||
- **Module 8**: you have a repo on a remote forge (GitHub or any alternative). Issues live on the
|
||||
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
|
||||
- **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 puts that pairing to work.
|
||||
- **Module 2** — the repo-as-durable-memory reframe. Issues are the team-scale version of the same
|
||||
- **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.
|
||||
- **Module 1**: the `tasks-app` project. The lab writes issues against it.
|
||||
|
||||
You do **not** yet need pull requests (Module 10) or the full collaboration loop (Module 11). This
|
||||
module produces the *input* to that loop. We'll point forward to it, not teach it here.
|
||||
@@ -26,12 +26,12 @@ module produces the *input* to that loop. We'll point forward to it, not teach i
|
||||
|
||||
By the end of this module you can:
|
||||
|
||||
1. Write a well-formed issue — title, context, acceptance criteria, scope — that a human *or* an
|
||||
1. Write a well-formed issue (title, context, acceptance criteria, scope) that a human *or* an
|
||||
agent can pick up and act on without a follow-up conversation.
|
||||
2. Use labels and assignment to route, prioritize, and find work across a backlog.
|
||||
3. Decide which work to route to a human and which to hand to an agent, and articulate the heuristic
|
||||
behind that call.
|
||||
4. Use issues as durable, shared task memory — the part of the project's state that lives outside
|
||||
4. Use issues as durable, shared task memory: the part of the project's state that lives outside
|
||||
the code.
|
||||
|
||||
---
|
||||
@@ -45,19 +45,19 @@ someone's head, a Slack thread, or a chat tab.** The project-management vocabula
|
||||
that core doesn't. It has a title, a body, and metadata (labels, an assignee, a status). It gets a stable number. You
|
||||
can link to it, search it, and close it.
|
||||
|
||||
You already know this shape — it's a ticket. Jira, Linear, ServiceNow, a help-desk queue: same idea.
|
||||
You already know this shape; it's a ticket. Jira, Linear, ServiceNow, a help-desk queue: same idea.
|
||||
What matters for this course is that **every git forge has issues built in**, sitting in the same
|
||||
place as the repo. GitHub Issues, GitLab Issues, Gitea/Forgejo Issues, Bitbucket, Azure Boards —
|
||||
place as the repo. GitHub Issues, GitLab Issues, Gitea/Forgejo Issues, Bitbucket, Azure Boards:
|
||||
the feature set varies, the concept does not. Because they're attached to the repo, an issue can
|
||||
reference a commit, a file, or a line, and the work that resolves it can reference the issue back.
|
||||
That tight coupling is the whole point: the *description* of the work and the *code* that does it
|
||||
live one click apart.
|
||||
|
||||
### Reframe — issues are shared task memory
|
||||
### Reframe: issues are shared task memory
|
||||
|
||||
Module 2 reframed the repo as **durable memory the AI can read**: a fresh session reconstructs
|
||||
"where were we?" from `git log`, `git status`, and `git diff`. But notice what git can only ever
|
||||
tell you — what *happened*. Settled history and in-flight edits. It is silent on the work that
|
||||
tell you: what *happened*. Settled history and in-flight edits. It is silent on the work that
|
||||
*hasn't started yet*: the bug someone reported, the feature you promised, the cleanup you keep
|
||||
deferring.
|
||||
|
||||
@@ -70,7 +70,7 @@ and they divide the timeline cleanly:
|
||||
| The repo (Module 2) | "What happened / what's in flight right now?" | commits, working tree |
|
||||
| The issue tracker (this module) | "What still needs to happen, and who has it?" | issues, labels, assignees |
|
||||
|
||||
A teammate joining tomorrow — or an agent that has never seen the project — reads the repo to learn
|
||||
A teammate joining tomorrow, or an agent that has never seen the project, reads the repo to learn
|
||||
the code and reads the open issues to learn the *work*. Both are ground truth you can hand to a
|
||||
human or a machine. Neither depends on anyone remembering anything.
|
||||
|
||||
@@ -81,18 +81,18 @@ context. A good issue is written for **a stranger**, because increasingly the th
|
||||
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:
|
||||
|
||||
1. **Title** — a specific, scannable summary. Someone reading a list of forty titles should know
|
||||
1. **Title**: a specific, scannable summary. Someone reading a list of forty titles should know
|
||||
what each one is. `done command crashes on a bad index` beats `bug in cli`.
|
||||
2. **Context / problem** — what's wrong or missing, and *why it matters*. Include how to reproduce a
|
||||
2. **Context / problem**: what's wrong or missing, and *why it matters*. Include how to reproduce a
|
||||
bug (the exact command and what happened), or the motivation for a feature. This is the part a
|
||||
vague issue skips and then nobody can act on it.
|
||||
3. **Acceptance criteria** — the checklist that defines *done*. Concrete, verifiable statements:
|
||||
3. **Acceptance criteria**: the checklist that defines *done*. Concrete, verifiable statements:
|
||||
"`done 99` prints an error and exits non-zero instead of a traceback." This is the single most
|
||||
valuable part of the issue, for reasons the AI angle makes sharp.
|
||||
4. **Scope / out of scope** — what this issue does *not* cover, so the work doesn't sprawl. "Not
|
||||
4. **Scope / out of scope**: what this issue does *not* cover, so the work doesn't sprawl. "Not
|
||||
changing the storage format" keeps a one-line fix from becoming a refactor.
|
||||
|
||||
A proposed approach is optional and often helpful, but keep it as a suggestion, not a spec — the
|
||||
A proposed approach is optional and often helpful, but keep it as a suggestion, not a spec; the
|
||||
person or agent doing the work may know a better one.
|
||||
|
||||
Compare. A bad issue:
|
||||
@@ -100,7 +100,7 @@ Compare. A bad issue:
|
||||
> **Title:** fix the done thing
|
||||
> the done command is broken, please fix
|
||||
|
||||
Nobody — human or agent — can act on that without coming back to ask you three questions. A
|
||||
Nobody, human or agent, can act on that without coming back to ask you three questions. A
|
||||
well-formed version of the same bug:
|
||||
|
||||
> **Title:** `done` command crashes on an out-of-range or non-integer index
|
||||
@@ -119,44 +119,44 @@ well-formed version of the same bug:
|
||||
|
||||
That second version is pickup-ready. It is also, not coincidentally, the format an agent needs.
|
||||
|
||||
### Labels — the cross-cutting axes
|
||||
### Labels: the cross-cutting axes
|
||||
|
||||
A title says what one issue is. **Labels** are how you slice the whole backlog. Keep the taxonomy
|
||||
small and orthogonal — a handful of axes, not forty decorative tags:
|
||||
small and orthogonal, a handful of axes, not forty decorative tags:
|
||||
|
||||
- **Type** — `bug`, `feature`, `chore`/`docs`. What kind of work.
|
||||
- **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)
|
||||
- **Type**: `bug`, `feature`, `chore`/`docs`. What kind of work.
|
||||
- **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 matters
|
||||
- **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.
|
||||
|
||||
### Assignment — routing the work to one owner
|
||||
### Assignment: routing the work to one owner
|
||||
|
||||
Labels describe; **assignment routes.** Assigning an issue puts one name on it: the owner, the
|
||||
person (or agent) the rest of the team can assume is handling it. The discipline that matters is
|
||||
*one* owner — an issue assigned to three people is assigned to no one. Unassigned-but-`ready` is a
|
||||
*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 leads straight to the
|
||||
point this module turns on.
|
||||
|
||||
### The roster is mixed now — humans and agents
|
||||
### The roster is mixed now: humans and agents
|
||||
|
||||
Here's the shift. The list of things you can assign an issue to used to be "the people on the team."
|
||||
It increasingly includes **agents**. An issue can be routed to a person, or handed to an
|
||||
issue-to-PR agent that reads the issue, makes the change on a branch, and opens it up for review.
|
||||
(That agent is its own module — **Module 25** — and we are not building it here. The point now is
|
||||
(That agent is its own module, **Module 25**, and we are not building it here. The point now is
|
||||
only that it's a possible *assignee*, which changes how you write the issue.)
|
||||
|
||||
The exact mechanism varies and is still settling across forges: some let you assign an agent like a
|
||||
user, some trigger it with a label, some kick it off from a comment or an external runner. Don't
|
||||
anchor on the plumbing. Anchor on this: **the well-formed issue is the one interface that works for
|
||||
every assignee on the roster.** A human and an agent need the same things from an issue — a clear
|
||||
every assignee on the roster.** A human and an agent need the same things from an issue: a clear
|
||||
title, real context, and acceptance criteria that define done. Write it well and you've written it
|
||||
for both.
|
||||
|
||||
@@ -174,7 +174,7 @@ reproducible, testable.
|
||||
risk.** "Add due dates" sounds small but isn't: what date format does the user type? Does the list
|
||||
re-sort by date? How are overdue tasks shown, and in whose timezone? Those are product decisions an
|
||||
agent will *answer confidently and probably wrongly*, because nothing in the issue tells it the
|
||||
right call. A human resolves the ambiguity first (often by splitting it into clear sub-issues — at
|
||||
right call. A human resolves the ambiguity first (often by splitting it into clear sub-issues, at
|
||||
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.
|
||||
@@ -187,7 +187,7 @@ matching the clarity of the issue to the autonomy of the assignee.
|
||||
This module produces the input to a loop you'll complete later. An issue is the start; the rest is:
|
||||
|
||||
- An assignee (human or agent) takes the issue, branches (Module 6), does the work, and opens it for
|
||||
review as a pull request (**Module 10**), which gets merged and **closes the issue** — the full
|
||||
review as a pull request (**Module 10**), which gets merged and **closes the issue**; the full
|
||||
coordination loop is **Module 11**.
|
||||
- Agents can also work the *intake* side: triaging, labeling, and routing incoming issues with a
|
||||
human still deciding (**Module 24**), or taking an assigned issue all the way to a PR (**Module
|
||||
@@ -203,7 +203,7 @@ The issue tracker itself isn't new. What's changed is that **the issue is now an
|
||||
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
|
||||
the gaps with judgment. An agent reads them literally and stops when they're satisfied, so vague
|
||||
criteria produce work that's technically complete and actually wrong. The same criteria also become
|
||||
the basis for the test you'll write (Module 13) and the thing you check in review (Module 10). One
|
||||
well-written checklist pays out three times.
|
||||
@@ -212,7 +212,7 @@ specification**, and that raises the stakes on writing it well in three concrete
|
||||
confident, plausible, wrong PR that costs more to review than the work would have taken. The cheap
|
||||
insurance is the clarity you put in *before* assigning.
|
||||
- **Your committed config plus the issue is the whole brief.** Module 5's instructions file carries
|
||||
the standing context — conventions, build and test commands, what not to touch. The issue carries
|
||||
the standing context: conventions, build and test commands, what not to touch. The issue carries
|
||||
the specific task. Together they're enough for an agent to attempt the work with no live
|
||||
conversation at all. That's the pairing that makes routing-to-an-agent viable, and it's why both
|
||||
artifacts have to be good.
|
||||
@@ -234,32 +234,32 @@ part that matters, separate from the mechanical step of turning a draft into a f
|
||||
**You'll need:**
|
||||
|
||||
- Your `tasks-app` repo on a forge (Module 8), with its issue tracker enabled. Most forges turn
|
||||
issues on by default, but not all of them do — consistent with the "the feature set varies" caveat
|
||||
issues on by default, but not all of them do, consistent with the "the feature set varies" caveat
|
||||
above. Bitbucket Cloud's tracker is off until you enable it, Azure DevOps uses Boards/Work Items
|
||||
rather than an Issues tab, and SourceHut uses a separately provisioned `todo.sr.ht` tracker. If you
|
||||
took the forge-agnostic path, confirm yours has issues available before Part C.
|
||||
- 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.
|
||||
- `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.
|
||||
- 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
|
||||
### Part A: Find the work
|
||||
|
||||
Look at the `tasks-app` and find three real pieces of work. The app is deliberately thin, so there's
|
||||
plenty it still can't do. Because it's carried forward across modules, skip anything you may have
|
||||
already built (a `delete` command, task priorities) and pick work that's genuinely still missing.
|
||||
Good candidates:
|
||||
|
||||
1. **A bug** — `python cli.py done 99` (an out-of-range index) and `python cli.py done abc` (a
|
||||
1. **A bug**: `python cli.py done 99` (an out-of-range index) and `python cli.py done abc` (a
|
||||
non-integer) both crash with an uncaught traceback. Run them and watch.
|
||||
2. **A small, patterned feature** — an `undone <index>` command that clears a task's done flag,
|
||||
2. **A small, patterned feature**: an `undone <index>` command that clears a task's done flag,
|
||||
mirroring the existing `done` command (it's the inverse).
|
||||
3. **A judgment-heavy feature** — due dates on tasks (date format? sorting? overdue display?
|
||||
3. **A judgment-heavy feature**: due dates on tasks (date format? sorting? overdue display?
|
||||
storage?).
|
||||
|
||||
### Part B — Draft three well-formed issues
|
||||
### Part B: Draft three well-formed issues
|
||||
|
||||
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),
|
||||
@@ -270,7 +270,7 @@ criteria against the actual code, then **edit them down**. The model tends to ov
|
||||
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
|
||||
### Part C: Create, label, and route
|
||||
|
||||
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
|
||||
@@ -296,25 +296,25 @@ the mechanical work, you confirm it landed.
|
||||
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
|
||||
### Part D: Read the backlog cold
|
||||
|
||||
Open your forge's issue list and filter by your `ready` label. You should be looking at exactly the
|
||||
work that's pickable right now, by anyone or anything. That filtered view is the shared task memory
|
||||
from the reframe — the thing a new teammate or a fresh agent reads to learn the work, with no one
|
||||
from the reframe: the thing a new teammate or a fresh agent reads to learn the work, with no one
|
||||
explaining anything.
|
||||
|
||||
---
|
||||
|
||||
## Where it breaks
|
||||
|
||||
The honest caveats — issues are not the repo, and they don't behave like it:
|
||||
The honest caveats: issues are not the repo, and they don't behave like it:
|
||||
|
||||
- **Issues lie when they go stale; git doesn't.** The repo is ground truth by construction — it *is*
|
||||
- **Issues lie when they go stale; git doesn't.** The repo is ground truth by construction; it *is*
|
||||
the code. An issue is a *claim* about work, and a claim rots. A backlog full of issues that were
|
||||
fixed months ago, or describe a version of the app that no longer exists, is worse than no backlog,
|
||||
because people (and agents) trust it. Closing issues is as much a discipline as opening them.
|
||||
- **Acceptance criteria can't capture genuine ambiguity.** The whole "agent-ready vs. human" split
|
||||
assumes you *can* write clear criteria. For real design problems you can't yet — that's not a
|
||||
assumes you *can* write clear criteria. For real design problems you can't yet; that's not a
|
||||
writing failure, it's the nature of the work. Forcing crisp criteria onto an open question just
|
||||
hides the question. Those issues stay with a human until the ambiguity is resolved.
|
||||
- **Routing to an agent is delegation, not abdication.** Handing an issue to an agent doesn't mean
|
||||
@@ -325,7 +325,7 @@ The honest caveats — issues are not the repo, and they don't behave like it:
|
||||
- **Label and assignment models differ across forges.** There's no cross-forge standard. Some allow
|
||||
multiple assignees, some one; label and permission systems vary; "assign an issue to an agent" is
|
||||
an emerging capability implemented differently everywhere it exists at all. Keep your taxonomy
|
||||
small and portable so it survives a forge change — don't build a workflow that depends on one
|
||||
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 pay off when work is shared: across people, across agents, or across
|
||||
@@ -338,23 +338,23 @@ The honest caveats — issues are not the repo, and they don't behave like it:
|
||||
**You're done when:**
|
||||
|
||||
- You have **three well-formed issues** on your forge for `tasks-app`, each with a title, context,
|
||||
and concrete acceptance criteria — not a one-line "fix the thing."
|
||||
and concrete acceptance criteria, not a one-line "fix the thing."
|
||||
- Each issue carries a small, sensible label set, and at least one is marked `ready`.
|
||||
- At least one issue is **routed to a human** and at least one is **earmarked for an agent**, and you
|
||||
can state the routing reason in terms of the issue's clarity and scope — not the model's
|
||||
can state the routing reason in terms of the issue's clarity and scope, not the model's
|
||||
intelligence.
|
||||
- You can explain why issues are *shared task memory* and how that complements (rather than
|
||||
duplicates) the repo-as-memory idea from Module 2.
|
||||
|
||||
When a stranger could pick up any of your `ready` issues and start without asking you a single
|
||||
question, you've written them well — and that's exactly what Module 10 (reviewing the resulting
|
||||
question, you've written them well, and that's exactly what Module 10 (reviewing the resulting
|
||||
change) and Module 11 (closing the loop) are about to build on.
|
||||
|
||||
---
|
||||
|
||||
## Verify-before-publish
|
||||
|
||||
Mostly durable — issues are a stable concept on every forge — but one part of this module sits on
|
||||
Mostly durable (issues are a stable concept on every forge), but one part of this module sits on
|
||||
moving ground:
|
||||
|
||||
- [ ] **Agent-as-assignee mechanics.** How you route an issue to an agent (native agent assignee,
|
||||
@@ -362,5 +362,5 @@ moving ground:
|
||||
that the lab's "earmark for an agent" step still matches what at least one mainstream forge
|
||||
actually offers, and keep the wording mechanism-agnostic if it's still in flux.
|
||||
- [ ] **Forge issue terminology and label/assignee limits** (single vs. multiple assignees, built-in
|
||||
vs. custom labels) — confirm the neutral descriptions still hold across the forges named in
|
||||
vs. custom labels). Confirm the neutral descriptions still hold across the forges named in
|
||||
Module 8.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<!--
|
||||
Worked example issues for the tasks-app — Module 9 of "The Workflow".
|
||||
Worked example issues for the tasks-app, Module 9 of "The Workflow".
|
||||
|
||||
These are a reference / answer key. Write your OWN three issues from issue-template.md FIRST, then
|
||||
compare. Yours don't need to match word for word — check that each has a specific title, real
|
||||
compare. Yours don't need to match word for word; check that each has a specific title, real
|
||||
context (with repro for the bug), concrete acceptance criteria, and a stated scope.
|
||||
|
||||
Note how the routing call is a property of the ISSUE (clear vs. ambiguous), not the model.
|
||||
@@ -12,7 +12,7 @@
|
||||
deliberately target work the app does NOT have yet, so each reads as a genuine open issue.
|
||||
-->
|
||||
|
||||
# Issue 1 — bug — route to AGENT
|
||||
# Issue 1: bug, route to AGENT
|
||||
|
||||
# Title: `done` command crashes on an out-of-range or non-integer index
|
||||
|
||||
@@ -33,8 +33,8 @@ python cli.py done abc # ValueError traceback
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] `done <index>` with an out-of-range index prints a clear message (e.g. `no task at index 99`)
|
||||
and exits non-zero — no traceback.
|
||||
- [ ] `done <non-integer>` prints a clear message and exits non-zero — no traceback.
|
||||
and exits non-zero, with no traceback.
|
||||
- [ ] `done <non-integer>` prints a clear message and exits non-zero, with no traceback.
|
||||
- [ ] A valid `done <index>` still marks the task done exactly as before.
|
||||
|
||||
## Out of scope
|
||||
@@ -45,17 +45,17 @@ Changing how tasks are stored, numbered, or displayed.
|
||||
- **Type:** bug
|
||||
- **Priority:** high
|
||||
- **Ready:** yes
|
||||
- **Route to:** agent — contained, reproducible, and verifiable in seconds; clear acceptance criteria
|
||||
- **Route to:** agent. Contained, reproducible, and verifiable in seconds; clear acceptance criteria
|
||||
mean an agent's first pass is very likely correct.
|
||||
|
||||
|
||||
# Issue 2 — feature — route to AGENT
|
||||
# Issue 2: feature, route to AGENT
|
||||
|
||||
# Title: Add an `undone <index>` command to mark a completed task as not done
|
||||
|
||||
## Context / problem
|
||||
|
||||
You can mark a task `done`, but there's no way to undo it — flag the wrong index by mistake and the
|
||||
You can mark a task `done`, but there's no way to undo it; flag the wrong index by mistake and the
|
||||
only "fix" is to delete the task and re-add it. The command should mirror the existing `done <index>`
|
||||
command, which already takes an index and flips a task's state; this is simply its inverse.
|
||||
|
||||
@@ -73,38 +73,38 @@ A general multi-step undo / command history (separate concern). Changing the sto
|
||||
|
||||
## Proposed approach (optional)
|
||||
|
||||
Add a `reopen(index)` method on `TaskList` in `tasks.py` — the inverse of the existing `complete` —
|
||||
Add a `reopen(index)` method on `TaskList` in `tasks.py` (the inverse of the existing `complete`)
|
||||
and wire an `undone` branch in `cli.py`, parallel to the existing `done` handling.
|
||||
|
||||
---
|
||||
- **Type:** feature
|
||||
- **Priority:** med
|
||||
- **Ready:** yes
|
||||
- **Route to:** agent — well-scoped and patterned directly on existing code (the inverse of `done`);
|
||||
- **Route to:** agent. Well-scoped and patterned directly on existing code (the inverse of `done`);
|
||||
low ambiguity, easy to verify.
|
||||
|
||||
|
||||
# Issue 3 — feature — route to HUMAN
|
||||
# Issue 3: feature, route to HUMAN
|
||||
|
||||
# Title: Support due dates on tasks
|
||||
|
||||
## Context / problem
|
||||
|
||||
Users want to attach a due date to a task so the list can reflect what's coming up, not just what
|
||||
exists. Today a task is only a title and a done flag. This is desirable but underspecified — several
|
||||
exists. Today a task is only a title and a done flag. This is desirable but underspecified; several
|
||||
product decisions have to be made before any code is written.
|
||||
|
||||
Open questions (resolve before this is `ready`):
|
||||
- What date format does the user type, and how forgiving is parsing? (ISO `2026-06-30` only, or
|
||||
relative like `tomorrow` / `friday`?)
|
||||
- Does `list` re-sort by due date, group by it, or just display it inline?
|
||||
- How is a due date set — at `add` time (a flag?) or with a separate command? Can it be cleared?
|
||||
- How are overdue tasks surfaced — highlighted, flagged, sorted to the top — and in whose timezone?
|
||||
- How is a due date set: at `add` time (a flag?) or with a separate command? Can it be cleared?
|
||||
- How are overdue tasks surfaced (highlighted, flagged, sorted to the top), and in whose timezone?
|
||||
- How is it stored, and what's the default for the existing tasks that have none?
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- [ ] (Cannot be written yet — depends on the decisions above. Likely splits into 2–3 smaller,
|
||||
- [ ] (Cannot be written yet; depends on the decisions above. Likely splits into 2-3 smaller,
|
||||
agent-ready issues once the design is settled.)
|
||||
|
||||
## Out of scope
|
||||
@@ -115,6 +115,6 @@ TBD until the design questions are answered.
|
||||
- **Type:** feature
|
||||
- **Priority:** low
|
||||
- **Ready:** no
|
||||
- **Route to:** human — genuine design ambiguity. An agent would answer these questions confidently
|
||||
- **Route to:** human. Genuine design ambiguity. An agent would answer these questions confidently
|
||||
and probably wrongly. A person decides the design, then splits this into clear sub-issues (which
|
||||
may then be agent-ready).
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Well-formed issue skeleton — Module 9 of "The Workflow".
|
||||
Well-formed issue skeleton for Module 9 of "The Workflow".
|
||||
|
||||
Copy this for each issue you draft. Fill every section. Write it for a STRANGER: a teammate you've
|
||||
never met, future-you who's forgotten, or an agent with no memory. Delete these comments as you go.
|
||||
@@ -9,17 +9,17 @@
|
||||
below is what matters and ports anywhere.
|
||||
-->
|
||||
|
||||
# Title: <specific, scannable — someone reading 40 titles should know what this is>
|
||||
# Title: <specific, scannable; someone reading 40 titles should know what this is>
|
||||
|
||||
## Context / problem
|
||||
|
||||
<What is wrong or missing, and WHY it matters.
|
||||
- For a bug: the exact command you ran, what happened, and what you expected.
|
||||
- For a feature: the motivation — what the user can't do today.>
|
||||
- For a feature: the motivation, i.e. what the user can't do today.>
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
<The checklist that defines DONE. Concrete and verifiable. This is the most important section —
|
||||
<The checklist that defines DONE. Concrete and verifiable. This is the most important section:
|
||||
it is the definition of done for a human AND the spec for an agent.>
|
||||
|
||||
- [ ] <verifiable statement, e.g. "`done 99` prints a clear error and exits non-zero">
|
||||
@@ -41,4 +41,4 @@
|
||||
- **Type:** bug | feature | chore
|
||||
- **Priority:** high | med | low
|
||||
- **Ready:** yes/no (acceptance criteria solid enough to start?)
|
||||
- **Route to:** human | agent — and one sentence on WHY (in terms of the issue's clarity/scope)
|
||||
- **Route to:** human | agent, plus one sentence on WHY (in terms of the issue's clarity/scope)
|
||||
|
||||
Reference in New Issue
Block a user