diff --git a/.github/ISSUE_TEMPLATE/02-task.yml b/.github/ISSUE_TEMPLATE/02-task.yml index cc3d3f5722d..27d6ddccf37 100644 --- a/.github/ISSUE_TEMPLATE/02-task.yml +++ b/.github/ISSUE_TEMPLATE/02-task.yml @@ -11,7 +11,8 @@ body: 1. This is the DEFAULT type. If you are unsure which template to use, use this one and add the label needs-triage, then say so in Objective. - 2. A Task has NO children. If this needs sub-issues, it is a PRD - use 01-prd.yml. + 2. A Task has NO children. If this needs sub-issues, it is a Feature - use + 07-feature.yml. If it is a problem statement needing evidence, it is a PRD. 3. Fill EVERY required field. Do not add headings that are not in this form. 4. If a field does not apply, write exactly: N/A - 5. Objective must be ONE sentence naming an artifact that will exist when done. @@ -23,7 +24,7 @@ body: --> Bounded, concrete work. One branch, one PR. If it needs child issues, file a - **PRD** instead. + **Feature** instead. - type: input id: parent diff --git a/.github/ISSUE_TEMPLATE/07-feature.yml b/.github/ISSUE_TEMPLATE/07-feature.yml new file mode 100644 index 00000000000..f70e8776077 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/07-feature.yml @@ -0,0 +1,93 @@ +name: Feature +description: One demonstrable capability under a PRD, decomposed into agent-executable tasks +title: "feature: " +labels: ["type:feature"] +body: + - type: markdown + attributes: + value: | + + + One demonstrable capability inside a milestone. Decomposes into Tasks; rolls up + into a PRD. When it closes, the capability exists and the acceptance criteria + are all ticked with evidence. + + - type: input + id: parent + attributes: + label: Parent PRD + description: 'Issue number of the PRD this feature delivers part of, e.g. #290. A feature always has a parent.' + placeholder: "#290" + validations: + required: true + + - type: input + id: milestone + attributes: + label: Milestone + description: 'Exact title of the open milestone this feature ships in, e.g. "Knowledge crate shipped". Attach the actual milestone to the issue as well.' + validations: + required: true + + - type: input + id: outcome + attributes: + label: Outcome + description: One sentence. The capability that exists when this closes, phrased as what someone can do or observe - not the implementation. + validations: + required: true + + - type: textarea + id: acceptance + attributes: + label: Acceptance criteria + description: Markdown checkboxes. Each line an observable check verifiable by someone who did not build it. + value: | + - [ ] + - [ ] + - [ ] + validations: + required: true + + - type: textarea + id: children + attributes: + label: Child issues + description: 'Task-list of the issues that implement this, one per line: "- [ ] #123". Write "N/A - not yet decomposed" if filing ahead of breakdown; fill in before work starts.' + value: | + - [ ] # + validations: + required: true + + - type: textarea + id: outofscope + attributes: + label: Out of scope + description: Adjacent capabilities a reviewer should NOT expect this feature to deliver, and where they live instead. + validations: + required: true diff --git a/.github/workflows/launchpad-issue-check.yml b/.github/workflows/launchpad-issue-check.yml index 995f29478b6..76b92b6b7ac 100644 --- a/.github/workflows/launchpad-issue-check.yml +++ b/.github/workflows/launchpad-issue-check.yml @@ -31,6 +31,8 @@ jobs: REQUIRED = { "type:prd": ["Problem", "Evidence", "Success criteria", "Non-goals", "Impacted components", "Security implications"], + "type:feature": ["Parent PRD", "Milestone", "Outcome", + "Acceptance criteria", "Child issues", "Out of scope"], "type:task": ["Parent PRD", "Objective", "Definition of done", "Impacted components", "Out of scope"], "type:enhancement": ["Current behaviour", "Desired behaviour", "Why now", diff --git a/launchpad/AGENTS.md b/launchpad/AGENTS.md index 179c4d5441d..88125c9efd9 100644 --- a/launchpad/AGENTS.md +++ b/launchpad/AGENTS.md @@ -101,7 +101,7 @@ New workflows go in `.github/workflows/` (GitHub requires it) and **must** be na ## 4. Choosing an issue type -Five types. **Exactly one `type:` label per issue** — a type never modifies another +Six types. **Exactly one `type:` label per issue** — a type never modifies another type. Work down this list. **The first "yes" wins.** Do not reorder it. @@ -111,8 +111,9 @@ Work down this list. **The first "yes" wins.** Do not reorder it. | 1 | Is the output a **decision plus rationale**, with nothing in the repo changing when it closes? | **ADR** | A document records a choice; no code or config moves | | 2 | Does something **exist and behave incorrectly**? | **Bug** | You ran it and observed the failure | | 3 | Does something **exist and work, but insufficiently**? | **Enhancement** | Behaviour is correct, just not good enough | -| 4 | Does it need **child issues** to finish? | **PRD** | It has acceptance criteria and decomposes | -| 5 | Otherwise | **Task** | One agent, one branch, one PR | +| 4 | Is it a **problem statement with evidence**, whose delivery spans more than one capability? | **PRD** | It states why; features deliver it | +| 5 | Does it need **child issues** to finish? | **Feature** | One demonstrable capability; holds acceptance criteria and decomposes into tasks | +| 6 | Otherwise | **Task** | One agent, one branch, one PR | ADR is first on purpose: **decisions masquerade as work.** "Pick a config management tool" looks like a Task until you notice nothing ships when it closes. @@ -120,16 +121,22 @@ tool" looks like a Task until you notice nothing ships when it closes. ### How the types relate ``` -Milestone (M0, M1) -└── PRD the approvable unit; holds acceptance criteria - ├── Task executable child: one branch, one PR - ├── Bug found while building - ├── Enhancement deferred improvement - └── ADR an open question the PRD cannot proceed without +Milestone (a dated, demonstrable outcome) +└── PRD problem, evidence, success criteria — the why + ├── Feature one demonstrable capability; holds acceptance criteria + │ ├── Task executable child: one branch, one PR + │ ├── Bug found while building this feature + │ └── ADR a decision only this feature depends on + ├── ADR an open question the PRD cannot proceed without, + │ or a decision more than one feature depends on + └── Enhancement deferred improvement against shipped work ADR ─────────────────────── standalone only when no PRD raised it ``` +Tasks filed before the Feature level existed parent directly to their PRD; that +remains valid history — do not re-parent closed or in-flight work. + 1. **An ADR is never a work item and never has children.** Work a decision creates is filed separately afterwards and linked back. 2. **A PRD's open questions are raised as ADR issues, parented to that PRD.** Link it @@ -142,7 +149,7 @@ ADR ─────────────────────── stand that closes its issue.** A decision that exists only in a closed issue is lost to the noise. Closing the issue without writing the document is not done. This does not make an ADR a work item — no code or config moves; the decision record is the only artifact. -4. **A Task never has children.** If a Task grows children, it was a PRD — relabel it. +4. **A Task never has children.** If a Task grows children, it was a Feature — relabel it. 5. **Bug and Enhancement** are children of a PRD if found while building it, standalone if found later against shipped work. 6. **An Enhancement against unshipped work is a scope change to its PRD, not an @@ -179,7 +186,7 @@ These are hard constraints, not style preferences. ### Filing an issue -There is one specialised form beyond the five types: **Agent workflow proposal** +There is one specialised form beyond the six types: **Agent workflow proposal** (`06-agent-workflow.yml`). It is an Enhancement with different prompts — it requires the specific access an agent needs and its blast radius. Use it for any proposal that an agent should do something a person does today. Guidance is in #40. diff --git a/launchpad/labels.yml b/launchpad/labels.yml index f02746a9e72..047213e6864 100644 --- a/launchpad/labels.yml +++ b/launchpad/labels.yml @@ -6,7 +6,10 @@ # --- Type: exactly one per issue. A type never modifies another type. ---------- - name: "type:prd" color: "5319e7" - description: "Work with acceptance criteria that needs child tasks" + description: "Problem, evidence and success criteria — delivered through child features and tasks" +- name: "type:feature" + color: "8a63d2" + description: "One demonstrable capability under a PRD — decomposes into tasks" - name: "type:task" color: "1d76db" description: "Bounded work — one branch, one PR. The default type."