Legacy ID Migration Mapping — Inventory + Proposal
Legacy ID Migration Mapping — Inventory + Proposal
Section titled “Legacy ID Migration Mapping — Inventory + Proposal”Last verified: 20/05/2026 (kh-prod-readiness-S56, OQ-2 ratification — bare-digit storage format applied)
Context. Task ID-15 (docs/reference/task-list.json) ratifies a bulk
migration of all legacy-format item identifiers across the three task surfaces to
the canonical ID-N / ID-N.M shape per docs/plans/phase-0-investigation/s48-feedback.md §B2
(“ID-15 / ID-15.3 used consistently across task list, backlog, roadmap, and
workflow prompts/docs”). This document is the Subtask ID-15.1 RESEARCH
output: a full inventory of legacy IDs across the three surfaces + a proposed
mapping table for Liam ratification at session close. Subtasks ID-15.2..5
(TECH design, script authoring, application + cross-doc sweep, script deletion)
all carry the mapping decided here.
Cross-references.
docs/reference/task-list.json— Task ID-15 (parent), ID-15.1..5 (subtasks).docs/plans/phase-0-investigation/s48-feedback.md§B2 — ratification of the ID-N canonical format requirement.lib/validation/task-list-schema.ts—Task.idregex^\d+$(strict; only string-of-digits accepted).lib/validation/backlog-schema.ts—BacklogItem.idz.string().min(1)(permits any non-empty string; PRODUCT inv 37 says existing IDs must not change without explicit migration — this Task is that migration).lib/validation/roadmap-schema.ts—RoadmapItem.iddocumented as “Dotted-decimal positional ID” (no legacy formats present; out of scope).
§1 — Methodology
Section titled “§1 — Methodology”All inventory queries used jq against the three JSON surface files. Roadmap is
inspected recursively because items live inside sections[].items[] and
sub-section nesting may be present.
# Backlog — flat items[] arrayjq -r '.items[].id' docs/reference/product-backlog.json | sort
# Task-list — Task array with subtasks[]; compound IDs derived in the scriptjq -r '.tasks[].id' docs/reference/task-list.json | sort -njq -r '.tasks[] | .id as $tid | .subtasks[] | "\($tid).\(.id)"' \ docs/reference/task-list.json
# Roadmap — recursive walk; items may nest in sub-sectionsjq -r '[.. | .items? // empty | .[] | select(type=="object") | .id] | unique | .[]' \ docs/reference/product-roadmap.json | sort -V
# Detect non-dotted-decimal IDs in roadmap (legacy-format check)jq -r '[.. | .items? // empty | .[] | select(type=="object") | .id] | unique | .[]' \ docs/reference/product-roadmap.json \ | grep -v -E '^[0-9]+(\.[0-9]+)*$' || echo "(none — all dotted-decimal)"Counts verified against jq '.items | length' (backlog), jq '.tasks | length'
(task-list), jq '[.. | .items? // empty | .[] | select(type=="object")] | length'
(roadmap items recursive).
§2 — Inventory tables
Section titled “§2 — Inventory tables”§2.1 Backlog (docs/reference/product-backlog.json)
Section titled “§2.1 Backlog (docs/reference/product-backlog.json)”Total items: 46. One already canonical (ID-17); 45 legacy.
| Format | Count | IDs | Notes |
|---|---|---|---|
AST-S{N}-O{M} | 7 | AST-S3-O1, AST-S3-O2, AST-S10-O1, AST-S10-O2, AST-S11-O1, AST-S11-O2, AST-S11-O3 | ast-dataflow follow-ons (one per session arc). Single tightly-coupled track. |
C{N}-DT-* / C{N}-T*-* / C{N}-PA* / C{N}-Mobile-* | 16 | C1-DT-Login-1/-2, C1-DT-Settings-2, C1-T3-Settings-3, C2-DT-BidDetail-1/-2, C2-DT-Session-1/-2, C2-PA5, C2-T3-Session-1, C3-DT-Digest-1/-2/-3, C4-DT-Guide-1, C4-DT-ItemDetail-3, C8-Mobile-2 | Design critique audit outputs (per surfaced field). Cluster by track field (onboarding/authentication/bid-management/change-reporting/browse/mobile). |
OPS-* | 17 | OPS-6, OPS-11, OPS-13, OPS-24, OPS-25, OPS-27, OPS-28, OPS-29, OPS-30, OPS-32, OPS-33, OPS-36, OPS-43.1, OPS-47, OPS-59 (main), OPS-62, OPS-63 | Operational tech-debt; standalone items historically. Note OPS-43.1 uses dot-suffix (S37 batch-5 follow-up — was a sub-item of OPS-43). Note OPS-59 (main) parenthetical disambiguator (cross-track conflict). Two paired items: OPS-28 declares dependencies: ["OPS-29"]. |
RLS-P{N} | 2 | RLS-P8, RLS-P9 | RLS-pattern audit follow-ups (P-prefix denotes “Phase”; audit source implementation-readiness-audit-s240.md). |
| Other | 3 | ENG-TAX-SIMPLIFY, EVAL-2, PL-3 | Singleton legacy prefixes. ENG-TAX-SIMPLIFY depends on P0-TX-OPTION-E (a SHIPPED reference no longer in backlog). |
ID-N canonical | 1 | ID-17 | First entry to use the canonical format (S52 WP0 close — RSS auth design review). |
Legacy total: 45 IDs. All 45 require migration.
§2.2 Task-list (docs/reference/task-list.json)
Section titled “§2.2 Task-list (docs/reference/task-list.json)”Total Tasks: 8. Total Subtasks: 22. All IDs already canonical
(Task.id matches ^\d+$; Subtask id is bare integer per schema).
| Task ID | Title | Subtasks |
|---|---|---|
6 | workflow-orchestration skill body | 2 (6.1, 6.2) |
7 | task-executor body rewrite + task-planner agent | 2 (7.1, 7.2) |
8 | implement-subtask skill + spec-driven-implementation EDIT | 2 (8.1, 8.2) |
9 | Astro+Starlight docs + Warp docubot port + decommission /update-docs | 4 (9.1, 9.2, 9.3, 9.4) |
10 | start-session skill self-adaptation + diary shape | 3 (10.1, 10.2, 10.3) |
15 | Bulk ID-N format migration (this Task) | 5 (15.1..15.5) |
16 | ast-dataflow handover review + worktree closure | 3 (16.1, 16.2, 16.3) |
18 | Author skill-routing-map.md | 1 (18.1) |
Highest existing ID: 18. New IDs for backlog migration start at 19.
Task list is NOT in scope for this migration — it is already canonical.
§2.3 Roadmap (docs/reference/product-roadmap.json)
Section titled “§2.3 Roadmap (docs/reference/product-roadmap.json)”Total sections: 16. Total items (recursive): 61. All item IDs match
^[0-9]+(\.[0-9]+)*$ (dotted-decimal positional, e.g. 1.4, 3.8, 11.19,
12.15.3).
jq -r '[.. | .items? // empty | .[] | select(type=="object") | .id] | unique | .[]' \ docs/reference/product-roadmap.json \ | grep -v -E '^[0-9]+(\.[0-9]+)*$'# → (no output — all dotted-decimal)Roadmap is NOT in scope for this migration — its IDs are positional
(section-anchored), not legacy format codes. RoadmapItemSchema.id documents
the dotted-decimal convention explicitly. Roadmap IDs would only change if a
roadmap section restructure happens, which is independent of the legacy-ID
migration.
§2.4 Summary across surfaces
Section titled “§2.4 Summary across surfaces”| Surface | Total IDs | Legacy IDs | Canonical IDs | Migration in scope |
|---|---|---|---|---|
| Backlog | 46 | 45 | 1 | YES — all 45 |
| Task-list | 30 (8 Task + 22 Subtask) | 0 | 30 | No (already canonical) |
| Roadmap | 61 items + 16 sections | 0 (positional) | 77 (positional) | No (positional, not legacy) |
| TOTAL legacy to migrate | 45 |
§3 — Mapping proposal
Section titled “§3 — Mapping proposal”§3.1 Cluster-vs-standalone decision rules (see §4)
Section titled “§3.1 Cluster-vs-standalone decision rules (see §4)”Items are grouped into clusters (contiguous ID-N blocks preserving semantic continuity) when:
- They share a tight semantic theme AND were surfaced from the same source
(e.g. the seven
AST-S*-O*items are all ast-dataflow track follow-ons). - They share a
trackvalue AND would naturally be planned as a single initiative (e.g. the fiveonboarding-track C-cluster items map to a “First-Time-Admin Onboarding” initiative). - Liam’s mental model already treats them as a set (the two
OPS-28/OPS-29paired auth-allowlist items; the twoRLS-P*items).
Items receive standalone IDs when:
- They are isolated tech-debt (e.g.
OPS-11PK rename,OPS-13batch-dedup RPC,OPS-63quality-scan CHECK fix). - Their
trackoverlaps with others but the work is independent (e.g. severalbid-management-track C items are independent feature ideas, not a single initiative). - The item is a one-off (
PL-3portal automation PoC,EVAL-2Jaccard-metric bug,ENG-TAX-SIMPLIFYtaxonomy retirement).
§3.2 Proposed mapping table (45 legacy IDs → 21..65 targets, bare-digit per S56 OQ-2)
Section titled “§3.2 Proposed mapping table (45 legacy IDs → 21..65 targets, bare-digit per S56 OQ-2)”Ratification status (S53 close + S56 revise):
- S53 close (Liam Q4): 3/7 clusters YES (C1 ast-dataflow, C2 Onboarding, C3 Auth-allowlist); 4/7 REVISE (C4, C5, C6, C7) → resolved S56 (below).
- S53 close (Liam OQ-2..OQ-8): all defaults accepted (shared pool, ID-17 as-is, always-rewrite sweep scope, OPS-43.1 lineage in notes, OPS-59 (main) drop parenthetical, BacklogItem.id schema tighten in ID-15.4, no inventory gaps — R-WP-S* confirmed out-of-scope).
- S56 revise (Liam, per-cluster):
- C4 Auth design — KEEP as cluster (ID-35..36).
- C5 Bid-mgmt UX — SPLIT all four to standalone (no shared substrate per §4.3 tie-break).
- C6 Change Reports — KEEP as cluster (ID-37..39) BUT rename rationale: “Digest” → “Change Reports” per CLAUDE.md gotcha (“user-facing label is Change Reports; internal code still uses digest”).
- C7 RLS-audit — KEEP as cluster (ID-40..41). RLS-P8 stays
spec_needed. RLS-P9 audit was completed in S243-era (Liam-confirmed S56, no issues found, findings not filed); ID-15.4 application step flipsstatus: spec_needed → donewith status_note recording the confirmation.
- S56 informational: +2 shift from original ID-19..ID-63 to ID-21..ID-65 (forced by ID-19 + ID-20 occupying task-list since S53 + S55 closes; topology unchanged).
[live snapshot 2026-05-20T22:00:00.000Z]: AST-S3-O1 + AST-S3-O2 absent from live docs/reference/product-backlog.json at HEAD 3e4ee5c2 (closed separately per Liam, status not migrated). Post-migration backlog occupies bare-digit ids 17, 18, 23..65 per OQ-A non-compaction default (43 items, not 45). Drift handled in scripts/migrate-legacy-ids-to-id-n.ts runtime: legacy-format ids absent from inventory emit [WARN] log + populate skipped[] array. Mapping below reflects the original 45-item plan; the script + inventory at scripts/legacy-id-mapping.inventory.json reflect the 43-item live state. ID-15.3 deliverable per TECH §A.0 final paragraph.
[live snapshot ID-15.4 apply 2026-05-21]: Migration applied to docs/reference/product-backlog.json. RLS-P9 removed entirely (audit-confirmed-clean S243+S56, Liam-ratified S58 ID-15.4 — not worth tracking). Final post-migration occupancy: 17, 18, 23..40, 42..65 (44 items; slot 41 vacated — non-compaction per OQ-A). Cross-doc sweep applied across ALWAYS + BEST-EFFORT tiers: 55 files, 412 replacements, 0 misses. Schema tightened: BacklogItem.id → z.string().regex(/^\d+$/). All bare-digit canonical.
Cluster 1 — ast-dataflow follow-ons (7 items → ID-21..ID-27). Tightly coupled (same track, sequential session arcs S3 / S10 / S11). Preserves semantic continuity: ID-21/22 = S3 outputs; ID-23/24 = S10 outputs; ID-25/26/27 = S11 outputs. Reads cleanly in task-list ordering.
| Legacy | Proposed | Rationale |
|---|---|---|
AST-S3-O1 | 21 | S3 follow-on (column-reads heuristic extension) |
AST-S3-O2 | 22 | S3 follow-on (wildcard confidence tier) |
AST-S10-O1 | 23 | S10 follow-on (type-evolution-check skill candidate) |
AST-S10-O2 | 24 | S10 follow-on (enum-member-audit skill candidate) |
AST-S11-O1 | 25 | S11 follow-on (OPS-T1 codemod impl, 16-24h) |
AST-S11-O2 | 26 | S11 follow-on (MCP outputSchema full rollout, 29h) |
AST-S11-O3 | 27 | S11 follow-on (OQ-R9 opaque-Json RPC migration, 7h) |
Cluster 2 — Onboarding initiative (5 items → ID-28..ID-32). Track =
onboarding. All surfaced from the design critique audit. Plausibly a single
“First-Time-Admin + First-Session Onboarding” Task initiative when the work
activates. Sequential block preserves Liam’s mental grouping.
| Legacy | Proposed | Rationale |
|---|---|---|
C1-T3-Settings-3 | 28 | ”Getting Started” / Setup Checklist for first-time admins |
C1-DT-Settings-2 | 29 | Progressive disclosure wizard for admin settings |
C2-PA5 | 30 | First-session onboarding overlay for Bid Session |
C2-T3-Session-1 | 31 | Onboarding overlay for first bid session (3-step prompt) |
C4-DT-Guide-1 | 32 | ”Getting Started” guide type for infrequent users |
Cluster 3 — Auth allowlist paired items (2 items → ID-33..ID-34). Track =
authentication. OPS-28 declares dependencies: ["OPS-29"] — explicit
pair. Sequential block preserves dependency ordering and Liam’s stated
“second-client onboarding” theme.
| Legacy | Proposed | Rationale |
|---|---|---|
OPS-29 | 33 | Multi-client auth domain allowlist (table-driven). Comes first — dep target. |
OPS-28 | 34 | Admin-controlled user provisioning (invite-only). Depends on ID-33. |
Cluster 4 — Authentication design items (2 items → ID-35..ID-36). Track =
authentication. Both C1-DT-Login-* items surfaced from same audit; loose
coupling (session-duration research + branding feature). S56-ratified KEEP
(audit-lineage value outweighs split). Sequential block but note these are
NOT functionally paired the way ID-33/34 are.
| Legacy | Proposed | Rationale |
|---|---|---|
C1-DT-Login-1 | 35 | Session duration vs security research |
C1-DT-Login-2 | 36 | Organisation branding on login (multi-org) |
Cluster 5 — SPLIT (S56-ratified). The four C2-DT-* bid-management items
are independently shippable per §4.3 tie-break (“prefer standalone unless
cluster genuinely tight”); cluster-framing was loose. All four move to the
standalone block below (bid-management track, ID-54..ID-57).
Cluster 6 — Change Reports items (3 items → ID-37..ID-39). Track =
change-reporting. Three C3-DT-Digest-* items from same audit; plausibly a
single “Change Reports evolution” Task when activated. Sequential block
preserves source ordering. Terminology fix per S56 revise — user-facing
label is “Change Reports” (per CLAUDE.md gotcha); legacy item ID strings
still contain “Digest” because that is the historical audit code, but
rationale strings + post-migration backlog description field MUST use
“Change Reports”.
| Legacy | Proposed | Rationale |
|---|---|---|
C3-DT-Digest-1 | 37 | Change Reports comparison view (side-by-side) |
C3-DT-Digest-2 | 38 | Change Reports as governance artefact (immutable records) |
C3-DT-Digest-3 | 39 | Change Reports distribution list |
Cluster 7 — RLS-pattern audit follow-ups (2 items → ID-40..ID-41). Track =
database. Both from implementation-readiness-audit-s240.md (S53 carry-in).
Independent items but same audit source; sequential block preserves audit
lineage. S56-ratified KEEP cluster. RLS-P9 carries a status flip per S56
(audit completed — see status_note column).
| Legacy | Proposed | Rationale | Post-migration status |
|---|---|---|---|
RLS-P8 | 40 | RLS auto-enable trigger gaps (LIKE / PARTITION OF) | spec_needed (unchanged) |
RLS-P9 | 41 | Retroactive RLS audit for pre-migration tables | done (S243-era audit completed, no issues found — Liam-confirmed S56; ID-15.4 applies the status_note) |
Standalone items (24 items → ID-42..ID-65). No tight cluster; ordering within this block is largely arbitrary. Proposed order groups by track for readability (database, ai-integration, bid-management, browse, mobile, ingestion, cloud-run, documentation, testing). Now includes the 4 items from the split C5 (bid-management track expands 1 → 5).
| Legacy | Proposed | Track | Rationale |
|---|---|---|---|
OPS-6 | 42 | database | DB-layer empty-string coercion for classification |
OPS-11 | 43 | database | content_item_workspaces PK constraint rename |
OPS-13 | 44 | database | EP6 batch dedup RPC latency measurement (blocked) |
OPS-43.1 | 45 | database | Remaining SECDEF→INVOKER flips (35/39 shipped; 4 remain) |
OPS-63 | 46 | database | run_quality_scan CHECK constraint bug |
EVAL-2 | 47 | ai-integration | compare-quality.ts Jaccard metric net-gain handling |
OPS-24 | 48 | ai-integration | MCP get_certification_status holder coverage tests |
OPS-27 | 49 | ai-integration | Marketing-persona H2 enhancements for daily-briefing |
OPS-30 | 50 | ai-integration | Classifier tool-schema hygiene (strict: true) |
OPS-33 | 51 | ai-integration | Plugin endpoint parameterisation |
ENG-TAX-SIMPLIFY | 52 | ai-integration | Retire embedded taxonomy in plugin SKILL.md |
PL-3 | 53 | bid-management | Portal automation PoC (re-scoped — Claude Cowork) |
C2-DT-Session-1 | 54 | bid-management | Split-screen vs single-pane on mobile (research) — from split C5 |
C2-DT-Session-2 | 55 | bid-management | Regeneration instruction templates — from split C5 |
C2-DT-BidDetail-1 | 56 | bid-management | Bid overview as morning briefing — from split C5 |
C2-DT-BidDetail-2 | 57 | bid-management | Question-level routing from Overview — from split C5 |
C4-DT-ItemDetail-3 | 58 | browse | Item detail as shareable report (“Share” / “Export to PDF”) |
OPS-25 | 59 | browse | Cert holder dropdown UX placeholder |
C8-Mobile-2 | 60 | mobile | Evaluate bottom-sheet navigator for mobile bid sessions |
OPS-47 | 61 | ingestion | EP3 UI Pattern E retrofit |
OPS-59 (main) | 62 | ingestion | /admin/imports dedicated UI surface |
OPS-62 | 63 | cloud-run | Cloud Run buildpack equivalent of Vercel build cache |
OPS-36 | 64 | documentation | docs/operations/ inventory §2.5 full refresh |
OPS-32 | 65 | testing | WP7 AC4c-B integration test empty-title brittleness flag |
Final tally. 45 legacy IDs → 21..65 (45 contiguous new IDs) per original plan.
Post-apply actual: 42 legacy IDs migrated (AST-S3-O1/O2 absent — §A.0 drift; RLS-P9 removed S58 ID-15.4 Liam-ratified). Combined with existing ID-17 + ID-18 (both now bare-digit 17 + 18 after prefix strip), the post-migration backlog occupies 17, 18, 23..40, 42..65 (44 items; slot 41 vacated).
17, 18, 23..40, 42..65 form a near-contiguous block (gaps at 19/20/21/22/41 — task-list Tasks at 19/20, absent AST-S3 slots at 21/22, vacated RLS-P9 slot at 41). The shared integer pool with task-list per s48-feedback B2 is ratified (Liam S53 OQ-2).
Per-cluster shift summary (S56 revise outcomes):
| Cluster | Pre-S56 IDs | Post-S56 IDs | S56 outcome |
|---|---|---|---|
| C1 ast-dataflow | ID-19..25 | 21..27 | +2 shift |
| C2 Onboarding | ID-26..30 | 28..32 | +2 shift |
| C3 Auth allowlist | ID-31..32 | 33..34 | +2 shift |
| C4 Auth design | ID-33..34 | 35..36 | +2 shift, KEEP cluster |
| C5 Bid-mgmt UX | ID-35..38 | (vacated) | SPLIT → standalone bid-management |
| C6 Change Reports | ID-39..41 | 37..39 | renumber (-4 after C5 vacate), KEEP, terminology fix |
| C7 RLS audit | ID-42..43 | 40..41 | renumber (-4), KEEP, RLS-P9 status → done |
| Standalone | ID-44..63 | 42..65 | renumber +C5 additions (20 → 24 items) |
§3.3 — S56 OQ-2 ratification — bare-digit storage format
Section titled “§3.3 — S56 OQ-2 ratification — bare-digit storage format”S56 ratification (Liam, post-15.6 RESEARCH): BacklogItem.id aligns DOWN to bare digit. Targets in §3.2 are the bare-digit literal strings the migration script writes to product-backlog.json. The “ID-N” prefix remains a PROSE convention only (CLAUDE.md references, agent briefs, journal blocks, this research doc’s cluster headers).
Schema impact (lands in Phase A 15.4 apply step):
BacklogItem.idtightens fromz.string().min(1)toz.string().regex(/^\d+$/)(matchingTask.idschema inlib/validation/task-list-schema.ts).- Shared constant target:
BARE_ID_REGEX = /^\d+$/exported fromlib/validation/schemas.ts(per ID-15.6 research §7.7); bothTask.idandBacklogItem.idimport.
Roadmap unaffected — positional dotted-decimal (1.3, 9.15.2) preserved per OQ-3 ratification.
Cross-doc sweep impact: the sweep regex set in ID-15.2 TECH spec (Phase A re-dispatch pending) rewrites legacy ID matches to bare-digit targets, not ID-N prefixed. Prose “ID-N” references in code/docs OUTSIDE backlog data stay as-is (prose convention).
Why not ID-N prefix everywhere: Task.id has been bare-digit canonical since task-list inception; rewriting "15" → "ID-15" across 10 existing Tasks + dependencies + downstream 20.1 mirror generator would expand scope without semantic benefit. Aligning backlog DOWN preserves the canonical surface unchanged.
§4 — Decision rules (cluster vs standalone)
Section titled “§4 — Decision rules (cluster vs standalone)”The rules below should guide both this initial migration AND future additions to the backlog so the same heuristic stays applied.
§4.1 Cluster (sequential ID-N block) when ANY of:
Section titled “§4.1 Cluster (sequential ID-N block) when ANY of:”- Shared track + shared surface source. Items with the same
trackfield AND surfaced from the same audit / session arc (e.g. fiveonboarding-track C items all from the design critique audit, sevenast-dataflow-toolingitems all from sequential ast-dataflow sessions). - Declared dependency pairing. Items where one declares the other as a
dependencies[]entry (e.g.OPS-28→OPS-29). Sequential IDs in dependency order improve readability. - Theme-driven initiative. Items that would plausibly be planned as a
single initiative Task when activated (e.g. three
change-reportingdigest-evolution items; two RLS audit follow-ups).
§4.2 Standalone ID when ALL of:
Section titled “§4.2 Standalone ID when ALL of:”- Item is functionally independent of every other backlog entry.
- Item’s
trackvalue is shared with others but only loosely (no shared surface source, no dependency pairing, no initiative grouping). - Item could conceivably ship on its own with no coordination.
§4.3 Tie-breaks
Section titled “§4.3 Tie-breaks”When an item could plausibly belong to a cluster OR be standalone, prefer standalone unless the cluster is genuinely tight. Loose clustering produces sequential IDs that fragment when items are activated independently (one cluster member promoted to a Task while siblings remain backlog), creating non-contiguous gaps that confuse the mental model. Tight clusters survive fragmentation because the relationship is doc-recorded (notes field) and the sequential numbering is a soft hint, not a hard contract.
§4.4 Ordering within a cluster
Section titled “§4.4 Ordering within a cluster”- Dependency order first (dep target = lower ID).
- Then session arc / surfaced date (earliest first).
- Then source-ordering within the audit (preserves audit narrative).
§4.5 Roadmap and task-list out of scope
Section titled “§4.5 Roadmap and task-list out of scope”This decision rule applies to the backlog only. Task-list IDs are auto-assigned by the schema (string-of-digits, no semantic content), and roadmap IDs are dotted-decimal positional (anchored to section structure, not work themes).
§5 — Open questions for Liam ratification
Section titled “§5 — Open questions for Liam ratification”The following decisions need explicit YES / NO / REVISE from Liam at session close before ID-15.2 (TECH design) dispatches.
OQ-1. Cluster groupings (per-cluster YES/NO/REVISE)
Section titled “OQ-1. Cluster groupings (per-cluster YES/NO/REVISE)”Confirm each of the seven proposed clusters preserves semantic continuity in a way that matches your mental model:
- Cluster 1 —
AST-S*-O*→ID-19..ID-25(seven items, contiguous block, ordered by session arc S3 / S10 / S11). YES / NO / REVISE? - Cluster 2 — Onboarding (
C1-T3-Settings-3,C1-DT-Settings-2,C2-PA5,C2-T3-Session-1,C4-DT-Guide-1) →ID-26..ID-30. YES / NO / REVISE? - Cluster 3 — Auth allowlist pair (
OPS-29,OPS-28) →ID-31..ID-32(ordered by dep target first). YES / NO / REVISE? - Cluster 4 — Auth design (
C1-DT-Login-1,C1-DT-Login-2) →ID-33..ID-34. Loose coupling — Cluster or standalone? YES / NO / REVISE? - Cluster 5 — Bid-management UX (
C2-DT-Session-1,C2-DT-Session-2,C2-DT-BidDetail-1,C2-DT-BidDetail-2) →ID-35..ID-38. Loose coupling — Cluster or standalone? YES / NO / REVISE? - Cluster 6 — Digest evolution (
C3-DT-Digest-1/-2/-3) →ID-39..ID-41. YES / NO / REVISE? - Cluster 7 — RLS audit follow-ups (
RLS-P8,RLS-P9) →ID-42..ID-43. YES / NO / REVISE?
OQ-2. Shared ID-N integer pool across task-list + backlog?
Section titled “OQ-2. Shared ID-N integer pool across task-list + backlog?”s48-feedback.md §B2 calls for “ID-15 / ID-15.3 used consistently across
task list, backlog, roadmap” but doesn’t explicitly say whether task-list
Tasks and backlog items share a single integer pool (the proposal here) or
whether the backlog restarts its own counter.
The proposal here ASSUMES a shared pool — backlog items become ID-19..ID-63
continuing from task-list’s highest ID-18. Pro: zero collision risk; backlog
graduation to Task is a status-flip, not an ID change. Con: visually mixes
task-list Tasks (high-engagement) with backlog parked items (low-engagement)
in the same integer space.
Alternative: separate counters (backlog gets its own B1, B2, … or
BL-1, BL-2, …). Pro: clean namespace separation. Con: graduation requires
renaming the item; defeats the purpose of unified ID-N.
Liam to ratify. Shared pool (default) / separate counters / something else?
OQ-3. Should canonical ID-17 be renumbered?
Section titled “OQ-3. Should canonical ID-17 be renumbered?”ID-17 (RSS auth design review) was added S52 WP0 as the first
canonical-format backlog item. Under the shared-pool model (OQ-2 = yes), it
sits at ID-17 between task-list ID-16 (closed) and task-list ID-18
(pending). It does NOT collide with anything, but its position in the integer
sequence is anomalous (no Task ID-17 exists).
Options:
- (a) Leave as-is —
ID-17continues to refer to the existing backlog item. No migration cost. Slight visual oddity in task-list ordering (ID-16→ID-18skips 17 in Tasks). - (b) Renumber
ID-17toID-64(after the migration block) — restores visual contiguity in task-list but adds one more renumber to the migration script.
Default proposal: (a) leave as-is. Minimal migration cost. The “skip” is trivial — the canonical convention doesn’t require ID-N to be densely packed.
OQ-4. Cross-doc reference sweep scope
Section titled “OQ-4. Cross-doc reference sweep scope”The ID-15.2 TECH spec will design the cross-doc reference sweep. Confirm the
always-rewrite scope per the migrate-roadmap-section-3.ts precedent (Liam
to confirm wholesale acceptance, or specify exceptions):
- Always-rewrite (live code + tracked refs):
lib/,app/,__tests__/,scripts/,.claude/agents/,.claude/skills/,docs/reference/,docs/runbooks/,docs/operations/. - Best-effort (historical):
docs/continuation-prompts/,docs/plans/,docs/audits/,docs/specs/(legacy spec refs may be intentional historical record),.planning/.archive/(point-in-time snapshots). - Never-rewrite (verbatim historical): Anything inside
.planning/.archive/.*(treated as snapshot).
YES / NO / REVISE?
OQ-5. Handling of OPS-43.1 dot-suffix
Section titled “OQ-5. Handling of OPS-43.1 dot-suffix”OPS-43.1 (the only legacy ID with a sub-decimal suffix) maps to flat ID-47
in the proposal — the sub-decimal semantic (“a follow-up to OPS-43, which is
SHIPPED and removed from backlog”) is preserved in the notes field but
disappears from the ID. Acceptable, or do you want a footnote / status_note
mechanism to flag the lineage?
YES (acceptable) / NO (revise) / ADD-ANNOTATION?
OQ-6. Handling of OPS-59 (main) parenthetical disambiguator
Section titled “OQ-6. Handling of OPS-59 (main) parenthetical disambiguator”OPS-59 (main) is the only ID with a parenthetical. The parenthetical
disambiguates from cross-track conflicts during the S226 era. Post-migration
the ID is just ID-60 — the (main) suffix has no further meaning. Confirm
this can be dropped silently (no need for note field annotation).
YES (drop silently) / NO (note in notes field)?
OQ-7. Schema constraint update (post-migration)
Section titled “OQ-7. Schema constraint update (post-migration)”Once migration applies and all backlog IDs match ^ID-\d+$, should
BacklogItem.id schema in lib/validation/backlog-schema.ts tighten from
z.string().min(1) to z.string().regex(/^ID-\d+$/)? This would block future
non-canonical IDs at the schema layer (forcing function for ongoing
discipline).
Pro: enforces canonical convention going forward. Con: locks in the format choice; any future namespace-separation (OQ-2 revisit) would require schema loosening.
Default proposal: YES — tighten schema in ID-15.4 (apply migration) commit.
OQ-8. Are there legacy IDs in scope that this inventory missed?
Section titled “OQ-8. Are there legacy IDs in scope that this inventory missed?”The Task description (ID-15) lists these legacy formats:
OPS-*✓ (17 found)AST-S{N}-O{M}✓ (7 found)C{N}-T{M}-*/C{N}-DT-*/C{N}-PA{N}✓ (16 found, includesC8-Mobile-2)R-WP-S{N}-{X}— NONE FOUND in any surface. This format appears in task-listcommit_refsandsession_refs(e.g. “R-WP-S11-D” referring to cross-track work-package merge commits) but does NOT appear as an itemidanywhere. Confirm this format is out-of-scope for item-ID migration (it’s a commit/session label, not an item ID).RLS-P{N}✓ (2 found)- “Plus anything else” — surfaced:
ENG-TAX-SIMPLIFY,EVAL-2,PL-3(3 found singletons).
Anything Liam knows about that this inventory missed? Strongly recommend
final review of the jq output in §1 before script authoring.
§6 — Appendix: full jq output capture
Section titled “§6 — Appendix: full jq output capture”For reproducibility (and so the migration script’s input can be cross-checked against this snapshot):
# Verified 20/05/2026 against production-readiness HEAD ecc7ae31# All three commands run from main repo root.
$ jq -r '.items[].id' docs/reference/product-backlog.json | wc -l46
$ jq -r '.tasks | length' docs/reference/task-list.json8
$ jq -r '[.tasks[].subtasks | length] | add' docs/reference/task-list.json22
$ jq -r '[.. | .items? // empty | .[] | select(type=="object")] | length' \ docs/reference/product-roadmap.json61
$ jq -r '.sections | length' docs/reference/product-roadmap.json16End of ID-15.1 RESEARCH output. Ratification gate at session close; ID-15.2 TECH dispatch is gated on Liam’s responses to OQ-1..OQ-8 above.