|
| 1 | +# fix/101-stale-roadmap-merge-order-note |
| 2 | + |
| 3 | +## Goal |
| 4 | + |
| 5 | +Remove the dead "Merge order & shared-file coupling (2026-07-05)" note from |
| 6 | +`docs/features/ROADMAP.md` — a one-time sequencing instruction for PRs #8, |
| 7 | +#9, #10 (all merged long ago) that now has zero forward-looking value and is |
| 8 | +read on every `workflow-status`/`design-feature` invocation. |
| 9 | + |
| 10 | +## Issue |
| 11 | + |
| 12 | +`#101` — GitHub issue. The PR closes it via `Closes #101` in the body. |
| 13 | + |
| 14 | +## Branch |
| 15 | + |
| 16 | +`fix/101-stale-roadmap-merge-order-note` |
| 17 | + |
| 18 | +## Depends on |
| 19 | + |
| 20 | +— (independent) |
| 21 | + |
| 22 | +## Root cause |
| 23 | + |
| 24 | +The note was added as a one-time sequencing instruction for the initial |
| 25 | +three-feature merge window (2026-07-05, features 01-03 sharing overlapping |
| 26 | +files). It was never cleaned up once the window closed — no mechanism |
| 27 | +enforces removing a one-time note after its triggering PRs merge. |
| 28 | + |
| 29 | +## Detected in |
| 30 | + |
| 31 | +`/product-audit` run on 2026-07-19 (Roadmap coherence dimension). Confirmed |
| 32 | +via `gh pr view 8/9/10 --json state,mergedAt` — all three `MERGED` on |
| 33 | +2026-07-05, closing the file-coupling window the note existed to protect. |
| 34 | + |
| 35 | +## Scope |
| 36 | + |
| 37 | +### In scope |
| 38 | + |
| 39 | +- Remove the "Merge order & shared-file coupling (2026-07-05)" note |
| 40 | + (`docs/features/ROADMAP.md` lines 29-39) in its entirety. |
| 41 | + |
| 42 | +### Out of scope |
| 43 | + |
| 44 | +- `docs/fix/README.md`'s 21 stale merged-PR rows — tracked separately in |
| 45 | + `docs/fix/100-stale-fix-index-rows/`. |
| 46 | +- Any other content in `docs/features/ROADMAP.md` (the Features table, the |
| 47 | + status legend, etc.) — untouched. |
| 48 | + |
| 49 | +## Acceptance |
| 50 | + |
| 51 | +- [x] `docs/features/ROADMAP.md` no longer contains the |
| 52 | + "Merge order & shared-file coupling (2026-07-05)" note. |
| 53 | +- [x] The Features table (rows 01-17) and Status legend are byte-for-byte |
| 54 | + unchanged aside from the removed note. |
| 55 | +- [x] The note remains recoverable from git history (no `--amend`/force-push |
| 56 | + involved in this fix). |
| 57 | + |
| 58 | +## Phases |
| 59 | + |
| 60 | +Execution ledger — `execute-phase --fix` runs **one phase per invocation** |
| 61 | +and ticks tasks here. |
| 62 | + |
| 63 | +### Phase-lint (authoritative copy — keep in sync with `docs/features/_TEMPLATE/SPEC.md` `### Phases`) |
| 64 | + |
| 65 | +Every implementation phase below must pass all 8 boxes before it is emitted |
| 66 | +(planner skills) or executed (`execute-phase` pre-flight). Fail-closed: any |
| 67 | +unticked box blocks emission/execution until the phase is re-cut or split. |
| 68 | + |
| 69 | +- [ ] Title names ONE deliverable — FAIL if it joins nouns with `+`, `,`, |
| 70 | + `&`, `and`/`y`, or `/`. |
| 71 | +- [ ] One declared layer — each phase declares exactly one of the fixed enum |
| 72 | + `schema/db | domain | api | ui | config/infra | docs | hardening | |
| 73 | + close-out`; FAIL if any task's target file belongs to another. Tests |
| 74 | + for the phase's own layer belong to the phase; a test-only phase |
| 75 | + declares `hardening`. |
| 76 | +- [ ] ≤ 8 tasks (close-out phase: ≤ 10, only the literal close-out chain). |
| 77 | +- [ ] One checkbox = one deliverable — FAIL if a task contains a `→` chain |
| 78 | + of implementation steps, enumerates > 3 cases/scenarios, or creates |
| 79 | + > 1 file of distinct concerns. |
| 80 | +- [ ] Zero decision words — FAIL on `Decide`, `choose`, `OR` between |
| 81 | + alternatives, `If … then <change scope>`. |
| 82 | +- [ ] No conditional scope mutation — a task may not move work between |
| 83 | + phases at runtime. |
| 84 | +- [ ] No external/manual gates inside implementation phases — |
| 85 | + human/out-of-repo verifications live in the hardening/close-out phase, |
| 86 | + marked `manual`. |
| 87 | +- [ ] Machine-checkable done-when — every phase ends with one verifiable |
| 88 | + invariant (a command + expected outcome). |
| 89 | + |
| 90 | +### P1 — Remove the stale merge-order note |
| 91 | + |
| 92 | +Layer: `docs`. Done-when: |
| 93 | +`grep -c 'Merge order & shared-file coupling' docs/features/ROADMAP.md` → |
| 94 | +returns `0`. |
| 95 | + |
| 96 | +- [x] Delete the "Merge order & shared-file coupling (2026-07-05)" blockquote |
| 97 | + from `docs/features/ROADMAP.md` (Features table and Status legend |
| 98 | + untouched) — evidence: `grep -c 'Merge order & shared-file coupling' |
| 99 | + docs/features/ROADMAP.md` → `0` |
| 100 | + |
| 101 | +### P2 — Hardening & PR |
| 102 | + |
| 103 | +- [ ] Re-run the project's full verification gate (commands + exit codes pasted) |
| 104 | +- [ ] Pending-docs check: `git status --porcelain -- docs/` → empty |
| 105 | +- [ ] Set the fix-index row status to `done` and commit the flip |
| 106 | +- [ ] `git push` |
| 107 | +- [ ] Open the PR (`gh pr create --body-file <path>` — body written as a |
| 108 | + Markdown file, real backticks, never inline `--body`/heredoc) and |
| 109 | + PRINT THE PR URL in the chat; the body includes `Closes #101` |
| 110 | +- [ ] Update the fix-index row to `done · [#<pr>](<pr-url>)` |
| 111 | +- [ ] Commit `docs: link PR #101` and push |
| 112 | + |
| 113 | +## Testing |
| 114 | + |
| 115 | +Docs-only change; no test layer applies. Verification is the `grep` |
| 116 | +done-when above plus a visual diff review confirming only the note block was |
| 117 | +removed. |
| 118 | + |
| 119 | +## Rollback |
| 120 | + |
| 121 | +Single `git revert` of the PR commit — the note is recoverable from git |
| 122 | +history at any time. No data-side cleanup (documentation-only). |
| 123 | + |
| 124 | +## Status |
| 125 | + |
| 126 | +`done` |
| 127 | + |
| 128 | +## Cross-issue notes |
| 129 | + |
| 130 | +None found blocking, blocked-by, overlapping, or absorbable via |
| 131 | +`gh issue list --state open` / `gh pr list --state open` at drafting time, |
| 132 | +other than sibling fix #100 (different file, different defect class — kept |
| 133 | +separate per the shared-root-cause checklist). |
| 134 | + |
| 135 | +## Effort |
| 136 | + |
| 137 | +XS (1 commit, ≤ 1h) — mechanical deletion of one dead blockquote. |
| 138 | + |
| 139 | +## Decisions made during drafting |
| 140 | + |
| 141 | +- Chose **delete** over **relocate** (the issue's acceptance criteria leaves |
| 142 | + this to the maintainer). The note is a one-time, closed-window instruction |
| 143 | + with zero remaining audience; git history and `git log -p` on this file |
| 144 | + already preserve it verbatim, so relocating it into `CHANGELOG.md` or |
| 145 | + `docs/workflow/MIGRATION.md` would only duplicate that history without |
| 146 | + adding value. If the user disagrees, this is trivially reverted / |
| 147 | + redirected before merge. |
| 148 | +- Did not merge with #100 into one unit: different files |
| 149 | + (`docs/features/ROADMAP.md` vs `docs/fix/README.md`) and different defect |
| 150 | + classes (a stale one-time merge-order note vs. stale merged-PR rows) — |
| 151 | + fails the shared-root-cause checklist's first box. |
0 commit comments