From 7b0d1a0db4bbc3cefd2b34d056aec84f86b38784 Mon Sep 17 00:00:00 2001 From: Ira Abramov Date: Wed, 12 Aug 2026 10:40:18 +0300 Subject: [PATCH] feat(templates): allocate FR/SC/T/CHK identifiers sparsely and treat them as permanent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Spec Kit identifiers are references, not labels: plans, tasks, checklists (`[Spec §FR-001]`), analyze findings, converge source-refs, the GitHub issues created by /speckit.taskstoissues, commit messages and PR comments all cite them. But the templates allocate them densely and sequentially, so any insert or delete forces a renumber -- and a renumber silently invalidates every one of those citations while burning tokens rewriting lines that did not change. #1497 reported the failure mode concretely: deleting three tasks from a 100-task file renumbered the task lines "more or less correctly" but left the `(T009-T021, T036-T039)` summaries pointing at the wrong work. The repo already has the correct invariant -- converge.md forbids renumbering and reusing IDs -- but it applies only to convergence tasks while the surrounding templates model the opposite behaviour everywhere else. Generalise the invariant and give it room to work: - Each group (FR category, task phase, checklist category) starts at the next multiple of 1000; items step by 10 within the group. - Insert into the gap: an item between T1010 and T1020 becomes T1015. Nothing after it shifts, so document order stays ascending without a renumber. - Append at the next free multiple of 10; open a new group at the next unused multiple of 1000. Editing one group never touches another. - Removal leaves a permanent hole. Gaps are the steady state, not damage to repair, and a retired number is never re-issued. taskstoissues.md matched issue titles with `\bT\d{3}\b` -- exactly three digits -- so a title containing T1000 did not match at all and those tasks were silently neither deduplicated nor created. That is already reachable today via converge.md's `T{M+1:03d}` (a floor, not a cap; see #3866) and unavoidable under phase blocks, so widen it to `\bT\d{3,}\b` and record the contract in converge.md so producer and consumer cannot drift apart again. Existing artifacts are not retroactively renumbered; the rule applies going forward. Refs #4065, #1497, #3866 --- docs/concepts/complex-features.md | 2 +- templates/checklist-template.md | 25 ++++++++--- templates/commands/checklist.md | 27 +++++------ templates/commands/clarify.md | 1 + templates/commands/converge.md | 20 ++++++--- templates/commands/specify.md | 6 +++ templates/commands/tasks.md | 19 +++++--- templates/commands/taskstoissues.md | 6 +-- templates/spec-template.md | 46 ++++++++++++++----- templates/tasks-template.md | 70 +++++++++++++++++------------ 10 files changed, 145 insertions(+), 77 deletions(-) diff --git a/docs/concepts/complex-features.md b/docs/concepts/complex-features.md index 4fe9ae85d1..6c98e9f787 100644 --- a/docs/concepts/complex-features.md +++ b/docs/concepts/complex-features.md @@ -21,7 +21,7 @@ Instead of letting `/speckit.implement` run through every task at once, tell it to stop early: ```text -/speckit.implement only execute tasks T001-T010, then stop and report progress +/speckit.implement only execute tasks T1000-T1090, then stop and report progress ``` or scope by phase: diff --git a/templates/checklist-template.md b/templates/checklist-template.md index 9d1e801c3e..fbbceac39a 100644 --- a/templates/checklist-template.md +++ b/templates/checklist-template.md @@ -22,17 +22,28 @@ ============================================================================ --> + + ## [Category 1] -- [ ] CHK001 First checklist item with clear action -- [ ] CHK002 Second checklist item -- [ ] CHK003 Third checklist item +- [ ] CHK1000 First checklist item with clear action +- [ ] CHK1010 Second checklist item +- [ ] CHK1020 Third checklist item ## [Category 2] -- [ ] CHK004 Another category item -- [ ] CHK005 Item with specific criteria -- [ ] CHK006 Final item in this category +- [ ] CHK2000 Another category item +- [ ] CHK2010 Item with specific criteria +- [ ] CHK2020 Final item in this category ## Notes @@ -42,4 +53,4 @@ - `checklists/requirements.md` has a separate built-in lifecycle maintained by `__SPECKIT_COMMAND_SPECIFY__` and `__SPECKIT_COMMAND_CLARIFY__` - Add comments or findings inline - Link to relevant resources or documentation -- Items are numbered sequentially for easy reference +- Item numbers are stable references — do not renumber them when editing the list diff --git a/templates/commands/checklist.md b/templates/commands/checklist.md index 5ee239d309..811b674e3e 100644 --- a/templates/commands/checklist.md +++ b/templates/commands/checklist.md @@ -142,9 +142,10 @@ You **MUST** consider the user input before proceeding (if not empty). - Use short, descriptive name based on domain (e.g., `ux.md`, `api.md`, `security.md`) - Format: `[domain].md` - File handling behavior: - - If file does NOT exist: Create new file and number items starting from CHK001 - - If file exists: Append new items to existing file, continuing from the last CHK ID (e.g., if last item is CHK015, start new items at CHK016) + - If file does NOT exist: Create new file. The first category starts at `CHK1000`, the second at `CHK2000`, and so on — each category begins at the next multiple of 1000 and its items step by 10 (`CHK1000`, `CHK1010`, `CHK1020`...). + - If file exists: Append new items to existing file. An item joining an existing category takes the next free multiple of 10 in that category's block; an item that belongs between `CHK1010` and `CHK1020` becomes `CHK1015`; a brand-new category starts at the next unused multiple of 1000. - Never delete or replace existing checklist content - always preserve and append + - CHK IDs are permanent references: never renumber an existing item. If an item is ever removed, leave the hole — do not close the gap and never re-issue a retired number - Leave every newly generated item unchecked (`[ ]`); checkbox state belongs to the reviewer **CORE PRINCIPLE - Test the Requirements, Not the Implementation**: @@ -255,7 +256,7 @@ You **MUST** consider the user input before proceeding (if not empty). - ✅ "Are [edge cases/scenarios] addressed in requirements?" - ✅ "Does the spec define [missing aspect]?" -7. **Structure Reference**: Generate the checklist following the canonical template in `templates/checklist-template.md` for title, meta section, category headings, ownership note, notes section, and ID formatting. If template is unavailable, use: H1 title, purpose/created meta lines, an ownership note explaining that `[x]` means reviewer approval of requirements quality, `##` category sections containing `- [ ] CHK### ` lines with globally incrementing IDs starting at CHK001, and notes that `__SPECKIT_COMMAND_IMPLEMENT__` reads checklist state but does not modify markers. +7. **Structure Reference**: Generate the checklist following the canonical template in `templates/checklist-template.md` for title, meta section, category headings, ownership note, notes section, and ID formatting. If template is unavailable, use: H1 title, purpose/created meta lines, an ownership note explaining that `[x]` means reviewer approval of requirements quality, `##` category sections containing `- [ ] CHK#### ` lines whose IDs start each category at the next multiple of 1000 (CHK1000, CHK2000...) and step by 10 within the category, and notes that `__SPECKIT_COMMAND_IMPLEMENT__` reads checklist state but does not modify markers. 8. **Report**: Output full path to checklist file, item count, and summarize whether the run created a new file or appended to an existing one. Summarize: - Focus areas selected @@ -319,21 +320,21 @@ Sample items: **❌ WRONG - These test implementation, not requirements:** ```markdown -- [ ] CHK001 - Verify landing page displays 3 episode cards [Spec §FR-001] -- [ ] CHK002 - Test hover states work correctly on desktop [Spec §FR-003] -- [ ] CHK003 - Confirm logo click navigates to home page [Spec §FR-010] -- [ ] CHK004 - Check that related episodes section shows 3-5 items [Spec §FR-005] +- [ ] CHK1000 - Verify landing page displays 3 episode cards [Spec §FR-1000] +- [ ] CHK1010 - Test hover states work correctly on desktop [Spec §FR-1020] +- [ ] CHK1020 - Confirm logo click navigates to home page [Spec §FR-1090] +- [ ] CHK1030 - Check that related episodes section shows 3-5 items [Spec §FR-1040] ``` **✅ CORRECT - These test requirements quality:** ```markdown -- [ ] CHK001 - Are the number and layout of featured episodes explicitly specified? [Completeness, Spec §FR-001] -- [ ] CHK002 - Are hover state requirements consistently defined for all interactive elements? [Consistency, Spec §FR-003] -- [ ] CHK003 - Are navigation requirements clear for all clickable brand elements? [Clarity, Spec §FR-010] -- [ ] CHK004 - Is the selection criteria for related episodes documented? [Gap, Spec §FR-005] -- [ ] CHK005 - Are loading state requirements defined for asynchronous episode data? [Gap] -- [ ] CHK006 - Can "visual hierarchy" requirements be objectively measured? [Measurability, Spec §FR-001] +- [ ] CHK1000 - Are the number and layout of featured episodes explicitly specified? [Completeness, Spec §FR-1000] +- [ ] CHK1010 - Are hover state requirements consistently defined for all interactive elements? [Consistency, Spec §FR-1020] +- [ ] CHK1020 - Are navigation requirements clear for all clickable brand elements? [Clarity, Spec §FR-1090] +- [ ] CHK1030 - Is the selection criteria for related episodes documented? [Gap, Spec §FR-1040] +- [ ] CHK1040 - Are loading state requirements defined for asynchronous episode data? [Gap] +- [ ] CHK1050 - Can "visual hierarchy" requirements be objectively measured? [Measurability, Spec §FR-1000] ``` **Key Differences:** diff --git a/templates/commands/clarify.md b/templates/commands/clarify.md index ea2f20d519..319768aaf7 100644 --- a/templates/commands/clarify.md +++ b/templates/commands/clarify.md @@ -193,6 +193,7 @@ Execution steps: - Edge case / negative flow → Add a new bullet under Edge Cases / Error Handling (or create such subsection if template provides placeholder for it). - Terminology conflict → Normalize term across spec; retain original only if necessary by adding `(formerly referred to as "X")` once. - If the clarification invalidates an earlier ambiguous statement, replace that statement instead of duplicating; leave no obsolete contradictory text. + - **Never renumber existing identifiers.** Plans, tasks, checklists, and review comments cite FR/SC IDs, so renumbering silently invalidates those references. A requirement that belongs between FR-1010 and FR-1020 is numbered FR-1015 (IDs step by 10 precisely to leave that room); one appended to a category takes the next free multiple of 10. A removed requirement leaves a permanent hole — do not close the gap, do not renumber, and never re-issue a retired number. - Save the spec file AFTER each integration to minimize risk of context loss (atomic overwrite). - Preserve formatting: do not reorder unrelated sections; keep heading hierarchy intact. - Keep each inserted clarification minimal and testable (avoid narrative drift). diff --git a/templates/commands/converge.md b/templates/commands/converge.md index eadb96ee58..8f0e1e2488 100644 --- a/templates/commands/converge.md +++ b/templates/commands/converge.md @@ -183,7 +183,7 @@ Before appending anything, output a compact, severity-graded summary (no file wr | ID | Gap Type | Severity | Source | Evidence | Remaining Work | |----|----------|----------|--------|----------|----------------| -| F1 | missing | HIGH | FR-008 | Example: no append-only guard detected in path/to/module.py when writing tasks.md | Add append-only enforcement | +| F1 | missing | HIGH | FR-1070 | Example: no append-only guard detected in path/to/module.py when writing tasks.md | Add append-only enforcement | **Summary metrics:** @@ -202,22 +202,28 @@ Append to the **end** of `tasks.md`, per the append contract: 1. Scan all existing task IDs; let `M` be the maximum. Determine the next phase number `N` (highest existing phase + 1). 2. Write a single new section header `## Phase N: Convergence`. -3. Emit one checklist item per actionable finding, ordered CRITICAL/HIGH first, assigning - zero-padded IDs `T{M+1:03d}, T{M+2:03d}, …`: +3. Emit one checklist item per actionable finding, ordered CRITICAL/HIGH first. A + Convergence phase is a phase like any other, so it opens its own block: let `B` be the + next unused multiple of 1000 above every existing task ID, and assign `TB, TB+10, + TB+20, …`: ```markdown - - [ ] T042 per () + - [ ] T7000 per () ``` - `` traces the task to its origin: e.g. `FR-003`, `SC-002`, + Task IDs are therefore at least four digits and always a multiple of 10; consumers MUST + match them with `\bT\d{3,}\b` rather than assuming a fixed width. + + `` traces the task to its origin: e.g. `FR-1020`, `SC-1010`, `US1/AC2`, `plan: storage decision`, `Constitution II`. `` is one of `missing`, `partial`, `contradicts`, `unrequested`. Constitution-violation tasks MUST be emitted first and described as `CRITICAL`. -4. Never reuse or renumber existing IDs. If a prior Convergence phase exists, add a new, - separately-numbered one below it — do not touch the old one. +4. Never reuse or renumber existing IDs, and never close a gap left by a removed task. If a + prior Convergence phase exists, add a new one in its own block below it — do not touch + the old one. **If there are no actionable findings** (`converged` outcome): diff --git a/templates/commands/specify.md b/templates/commands/specify.md index 54151e8b42..2658d15b17 100644 --- a/templates/commands/specify.md +++ b/templates/commands/specify.md @@ -132,6 +132,12 @@ Given that feature description, do this: 5. Generate Functional Requirements Each requirement must be testable Use reasonable defaults for unspecified details (document assumptions in Assumptions section) + Group requirements under category headings. Each category starts at the next + multiple of 1000 (FR-1000, FR-2000, FR-3000...) and requirements step by 10 within + it (FR-1000, FR-1010, FR-1020...). SC identifiers use the same scheme. + FR and SC identifiers are permanent references: never renumber an existing one, + insert into the gap instead (FR-1015 between FR-1010 and FR-1020), and when one is + removed leave the hole — do not close the gap or re-issue the retired number. 6. Define Success Criteria Create measurable, technology-agnostic outcomes Include both quantitative metrics (time, performance, volume) and qualitative measures (user satisfaction, task completion) diff --git a/templates/commands/tasks.md b/templates/commands/tasks.md index 64146a35aa..8917697233 100644 --- a/templates/commands/tasks.md +++ b/templates/commands/tasks.md @@ -157,7 +157,10 @@ Every task MUST strictly follow this format: **Format Components**: 1. **Checkbox**: ALWAYS start with `- [ ]` (markdown checkbox) -2. **Task ID**: Sequential number (T001, T002, T003...) in execution order +2. **Task ID**: Sparse, phase-blocked number in execution order. Each phase starts at the next multiple of 1000 (Phase 1: `T1000`; Phase 2: `T2000`; Phase 3: `T3000`...) and tasks step by **10** within the phase (`T1000`, `T1010`, `T1020`...). Task IDs are permanent references cited by dependency lines, checklists, commit messages, and the GitHub issues created by `__SPECKIT_COMMAND_TASKSTOISSUES__`, so: + - **Never renumber an existing task.** Insert into the gap instead — a task belonging between `T1010` and `T1020` becomes `T1015`. + - **Append** at the next free multiple of 10 in that phase; **start a new phase** at the next unused multiple of 1000. Editing one phase never touches another. + - **Removing a task leaves a permanent hole.** Delete the line and stop: do not close the gap, do not renumber anything after it, and never re-issue a retired number to a different task. Gaps are the expected steady state, not damage to repair. 3. **[P] marker**: Include ONLY if task is parallelizable (different files, no dependencies on incomplete tasks) 4. **[Story] label**: REQUIRED for user story phase tasks only - Format: [US1], [US2], [US3], etc. (maps to user stories from spec.md) @@ -169,14 +172,16 @@ Every task MUST strictly follow this format: **Examples**: -- ✅ CORRECT: `- [ ] T001 Create project structure per implementation plan` -- ✅ CORRECT: `- [ ] T005 [P] Implement authentication middleware in src/middleware/auth.py` -- ✅ CORRECT: `- [ ] T012 [P] [US1] Create User model in src/models/user.py` -- ✅ CORRECT: `- [ ] T014 [US1] Implement UserService in src/services/user_service.py` +- ✅ CORRECT: `- [ ] T1000 Create project structure per implementation plan` (first task of Phase 1) +- ✅ CORRECT: `- [ ] T2010 [P] Implement authentication middleware in src/middleware/auth.py` (Phase 2) +- ✅ CORRECT: `- [ ] T3020 [P] [US1] Create User model in src/models/user.py` (Phase 3) +- ✅ CORRECT: `- [ ] T3025 [US1] Implement UserService in src/services/user_service.py` (added later, between T3020 and T3030) - ❌ WRONG: `- [ ] Create User model` (missing ID and Story label) -- ❌ WRONG: `T001 [US1] Create model` (missing checkbox) +- ❌ WRONG: `T1000 [US1] Create model` (missing checkbox) - ❌ WRONG: `- [ ] [US1] Create User model` (missing Task ID) -- ❌ WRONG: `- [ ] T001 [US1] Create model` (missing file path) +- ❌ WRONG: `- [ ] T1000 [US1] Create model` (missing file path) +- ❌ WRONG: `- [ ] T1001, T1002, T1003 ...` (step is 10, not 1 — leaves no room to insert) +- ❌ WRONG: `- [ ] T1030 ...` as the first task of Phase 2 (must start that phase's own block: T2000) ### Task Organization diff --git a/templates/commands/taskstoissues.md b/templates/commands/taskstoissues.md index 6b60e6f6a8..6960d9a732 100644 --- a/templates/commands/taskstoissues.md +++ b/templates/commands/taskstoissues.md @@ -64,9 +64,9 @@ git config --get remote.origin.url > [!CAUTION] > ONLY PROCEED TO NEXT STEPS IF THE REMOTE IS A GITHUB URL -1. **Fetch existing issues for deduplication**: Before creating anything, build the set of task IDs you are about to process from `tasks.md` (each is a `T` followed by three digits, e.g. `T001`). Then use the GitHub MCP server's `list_issues` tool to look for issues that already cover those IDs. Do not pass a `state` value, since omitting it makes the tool return both open and closed issues. Request `perPage: 100` to keep the number of calls down, and since the tool uses cursor-based pagination, request pages with the `after` parameter (using the `endCursor` from the previous response). For each issue title, match it against the task ID pattern `\bT\d{3}\b` (word boundaries so tokens like `ST001` or `T0010` are not matched by mistake; this also recognises titles written as `T001 ...`, `T001: ...` or `[T001] ...`) and, when it matches one of your task IDs, mark that ID as already having an issue. Stop paginating as soon as every task ID has been matched, or when there are no more pages, so you do not keep fetching the whole repository's issue history once all task IDs are accounted for. This bounds the number of calls on repos with large issue histories and still prevents duplicates when the command is re-run after `tasks.md` is regenerated or the skill is re-invoked. -1. For each task in the list, use the GitHub MCP server to create a new issue in the repository that is representative of the Git remote. Task lines in `tasks.md` start with a markdown checkbox, so first strip the leading `- [ ]` (and any `[P]` / `[US#]` markers) to recover the task ID and its description. Create the issue with a single canonical title of the form `T001: `, with the ID written once followed by the task description (for example, the line `- [ ] T001 Create project structure` becomes the title `T001: Create project structure`). - - **Skip** any task whose ID is already present in the set of existing issues from the previous step, and report it (for example, `T001 already has an issue, skipping`). +1. **Fetch existing issues for deduplication**: Before creating anything, build the set of task IDs you are about to process from `tasks.md` (each is a `T` followed by **at least** three digits — phase-blocked IDs such as `T1000` and `T2010` are the norm, and `__SPECKIT_COMMAND_CONVERGE__` can push them higher still, so never assume a fixed width). Then use the GitHub MCP server's `list_issues` tool to look for issues that already cover those IDs. Do not pass a `state` value, since omitting it makes the tool return both open and closed issues. Request `perPage: 100` to keep the number of calls down, and since the tool uses cursor-based pagination, request pages with the `after` parameter (using the `endCursor` from the previous response). For each issue title, match it against the task ID pattern `\bT\d{3,}\b` (the `{3,}` accepts four-digit and longer IDs — with `\d{3}` a title containing `T1000` would not match at all, because the trailing `\b` cannot fall between two digits, and those tasks would be silently neither deduplicated nor created. The word boundaries still stop a token like `ST1000` from matching, and force the whole digit run to be consumed so `T100` can never match inside `T1000`; this also recognises titles written as `T1000 ...`, `T1000: ...` or `[T1000] ...`) and, when it matches one of your task IDs, mark that ID as already having an issue. Stop paginating as soon as every task ID has been matched, or when there are no more pages, so you do not keep fetching the whole repository's issue history once all task IDs are accounted for. This bounds the number of calls on repos with large issue histories and still prevents duplicates when the command is re-run after `tasks.md` is regenerated or the skill is re-invoked. +1. For each task in the list, use the GitHub MCP server to create a new issue in the repository that is representative of the Git remote. Task lines in `tasks.md` start with a markdown checkbox, so first strip the leading `- [ ]` (and any `[P]` / `[US#]` markers) to recover the task ID and its description. Create the issue with a single canonical title of the form `T1000: `, with the ID written once followed by the task description (for example, the line `- [ ] T1000 Create project structure` becomes the title `T1000: Create project structure`). + - **Skip** any task whose ID is already present in the set of existing issues from the previous step, and report it (for example, `T1000 already has an issue, skipping`). - Only create issues for tasks that do not yet have a matching issue. > [!CAUTION] diff --git a/templates/spec-template.md b/templates/spec-template.md index ceb2877621..e4d14cb9bc 100644 --- a/templates/spec-template.md +++ b/templates/spec-template.md @@ -83,20 +83,38 @@ ### Functional Requirements -- **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"] -- **FR-002**: System MUST [specific capability, e.g., "validate email addresses"] -- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"] -- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"] -- **FR-005**: System MUST [behavior, e.g., "log all security events"] +**[Category 1, e.g. Accounts]** + +- **FR-1000**: System MUST [specific capability, e.g., "allow users to create accounts"] +- **FR-1010**: System MUST [specific capability, e.g., "validate email addresses"] +- **FR-1020**: Users MUST be able to [key interaction, e.g., "reset their password"] + +**[Category 2, e.g. Data and audit]** + +- **FR-2000**: System MUST [data requirement, e.g., "persist user preferences"] +- **FR-2010**: System MUST [behavior, e.g., "log all security events"] *Example of marking unclear requirements:* -- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?] -- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified] +- **FR-2020**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?] +- **FR-2030**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified] ### Key Entities *(include if feature involves data)* @@ -108,14 +126,20 @@ ### Measurable Outcomes -- **SC-001**: [Measurable metric, e.g., "Users can complete account creation in under 2 minutes"] -- **SC-002**: [Measurable metric, e.g., "System handles 1000 concurrent users without degradation"] -- **SC-003**: [User satisfaction metric, e.g., "90% of users successfully complete primary task on first attempt"] -- **SC-004**: [Business metric, e.g., "Reduce support tickets related to [X] by 50%"] +- **SC-1000**: [Measurable metric, e.g., "Users can complete account creation in under 2 minutes"] +- **SC-1010**: [Measurable metric, e.g., "System handles 1000 concurrent users without degradation"] +- **SC-1020**: [User satisfaction metric, e.g., "90% of users successfully complete primary task on first attempt"] +- **SC-1030**: [Business metric, e.g., "Reduce support tickets related to [X] by 50%"] ## Assumptions diff --git a/templates/tasks-template.md b/templates/tasks-template.md index 7fff087cc5..5224e3d67b 100644 --- a/templates/tasks-template.md +++ b/templates/tasks-template.md @@ -18,6 +18,20 @@ description: "Task list template for feature implementation" - **[P]**: Can run in parallel (different files, no dependencies) - **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3) - Include exact file paths in descriptions +- **[ID] numbering — sparse and permanent**: each phase starts at the next multiple of + 1000 (Phase 1 → `T1000`, Phase 2 → `T2000`, …) and tasks step by **10** within the phase + (`T1000`, `T1010`, `T1020`, …). Task IDs are permanent references — dependency lines, + checklists, commits, and the GitHub issues created by `__SPECKIT_COMMAND_TASKSTOISSUES__` + all cite them — so **never renumber an existing task**, and retire a removed task's + number rather than reusing it. + - Insert between two tasks using the gap: a task added between `T1010` and `T1020` + becomes `T1015`. Ordering stays readable and no later task shifts. + - Append to a phase at the next free multiple of 10; start a new phase at the next + unused multiple of 1000. Editing one phase never touches another. + - **Removing a task leaves a permanent hole.** Delete the line and stop — do not close + the gap, do not renumber anything after it, and never re-issue the number to a + different task. Gaps are the expected steady state, not damage to repair. Ranges like + `(T1000-T1090)` in summaries MUST NOT be treated as an invariant to restore. ## Path Conventions @@ -49,9 +63,9 @@ description: "Task list template for feature implementation" **Purpose**: Project initialization and basic structure -- [ ] T001 Create project structure per implementation plan -- [ ] T002 Initialize [language] project with [framework] dependencies -- [ ] T003 [P] Configure linting and formatting tools +- [ ] T1000 Create project structure per implementation plan +- [ ] T1010 Initialize [language] project with [framework] dependencies +- [ ] T1020 [P] Configure linting and formatting tools --- @@ -63,12 +77,12 @@ description: "Task list template for feature implementation" Examples of foundational tasks (adjust based on your project): -- [ ] T004 Setup database schema and migrations framework -- [ ] T005 [P] Implement authentication/authorization framework -- [ ] T006 [P] Setup API routing and middleware structure -- [ ] T007 Create base models/entities that all stories depend on -- [ ] T008 Configure error handling and logging infrastructure -- [ ] T009 Setup environment configuration management +- [ ] T2000 Setup database schema and migrations framework +- [ ] T2010 [P] Implement authentication/authorization framework +- [ ] T2020 [P] Setup API routing and middleware structure +- [ ] T2030 Create base models/entities that all stories depend on +- [ ] T2040 Configure error handling and logging infrastructure +- [ ] T2050 Setup environment configuration management **Checkpoint**: Foundation ready - user story implementation can now begin in parallel @@ -84,17 +98,17 @@ Examples of foundational tasks (adjust based on your project): > **NOTE: Write these tests FIRST, ensure they FAIL before implementation** -- [ ] T010 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py -- [ ] T011 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py +- [ ] T3000 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py +- [ ] T3010 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py ### Implementation for User Story 1 -- [ ] T012 [P] [US1] Create [Entity1] model in src/models/[entity1].py -- [ ] T013 [P] [US1] Create [Entity2] model in src/models/[entity2].py -- [ ] T014 [US1] Implement [Service] in src/services/[service].py (depends on T012, T013) -- [ ] T015 [US1] Implement [endpoint/feature] in src/[location]/[file].py -- [ ] T016 [US1] Add validation and error handling -- [ ] T017 [US1] Add logging for user story 1 operations +- [ ] T3020 [P] [US1] Create [Entity1] model in src/models/[entity1].py +- [ ] T3030 [P] [US1] Create [Entity2] model in src/models/[entity2].py +- [ ] T3040 [US1] Implement [Service] in src/services/[service].py (depends on T3020, T3030) +- [ ] T3050 [US1] Implement [endpoint/feature] in src/[location]/[file].py +- [ ] T3060 [US1] Add validation and error handling +- [ ] T3070 [US1] Add logging for user story 1 operations **Checkpoint**: At this point, User Story 1 should be fully functional and testable independently @@ -108,15 +122,15 @@ Examples of foundational tasks (adjust based on your project): ### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️ -- [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py -- [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py +- [ ] T4000 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py +- [ ] T4010 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py ### Implementation for User Story 2 -- [ ] T020 [P] [US2] Create [Entity] model in src/models/[entity].py -- [ ] T021 [US2] Implement [Service] in src/services/[service].py -- [ ] T022 [US2] Implement [endpoint/feature] in src/[location]/[file].py -- [ ] T023 [US2] Integrate with User Story 1 components (if needed) +- [ ] T4020 [P] [US2] Create [Entity] model in src/models/[entity].py +- [ ] T4030 [US2] Implement [Service] in src/services/[service].py +- [ ] T4040 [US2] Implement [endpoint/feature] in src/[location]/[file].py +- [ ] T4050 [US2] Integrate with User Story 1 components (if needed) **Checkpoint**: At this point, User Stories 1 AND 2 should both work independently @@ -130,14 +144,14 @@ Examples of foundational tasks (adjust based on your project): ### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️ -- [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py -- [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py +- [ ] T5000 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py +- [ ] T5010 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py ### Implementation for User Story 3 -- [ ] T026 [P] [US3] Create [Entity] model in src/models/[entity].py -- [ ] T027 [US3] Implement [Service] in src/services/[service].py -- [ ] T028 [US3] Implement [endpoint/feature] in src/[location]/[file].py +- [ ] T5020 [P] [US3] Create [Entity] model in src/models/[entity].py +- [ ] T5030 [US3] Implement [Service] in src/services/[service].py +- [ ] T5040 [US3] Implement [endpoint/feature] in src/[location]/[file].py **Checkpoint**: All user stories should now be independently functional