Rule: When designing cross-reference architecture for documentation systems (spec/plan/tasks bundles, schemas, cascading-Q files, audit-records, memories that cite other artefacts), default to stable-IDs over file-paths. Use intuitive IDs (v2-step-1, ik-step-7), NOT UUIDs — preserves grep-ability.
Why: Path-based references break on rename / move / split (single point of failure: the file path string). Stable-ID references survive because the ID is decoupled from the file location. OpenSpec uses Requirement ID: <uuid> markers so cross-capability references and diff visualisations survive moves; Spec-Kit uses T001-style stable task-IDs that survive plan/task regenerations. Both converge on this pattern in 2026 SOTA. Empirical origin: Phase D” D-6 lock 2026-05-24T19:15 BST after WebSearch + ctx_fetch_and_index of OpenSpec docs/concepts.md + docs/migration-guide.md + docs/workflows.md + spec-kit/spec-driven.md + spec-kit-docs + spec-kit discussion #775. Originally proposed path-based 4-way rewrite (effort ~3-5h); research-driven re-ask surfaced stable-ID-first as SOTA alternative (effort ~5-7h; future-rename safety built-in); Rich locked stable-ID-first.
How to apply:
-
Authoring new tasks.md / spec.md / equivalent: every task/requirement gets
id:frontmatter (e.g.id: v2-step-3). Use the repo prefix convention already in TT (v2-step-N/ik-step-N/ias-step-N/www-step-N/test-suite-step-Nfor the 5 v2 build repos). -
Cross-references in cascade-Q files / arch-state §15 / audit-records / memories / per-repo CLAUDE.md / frontmatter
companion_files: write[<repo>-step-N]notBUILD-PLAN.md#step-Nortasks.md#task-N. The bracketed-ID form is resolvable via tasks.md grep OR mkdocs-material autorefs plugin OR plain Ctrl-F. -
Section references (within plan.md / spec.md): stable-IDs are less load-bearing than step references — path-based references like
plan.md §X.Yare acceptable here IF the section structure is mature (i.e. not expected to move). When in doubt, prefer stable-IDs. -
Migration tools (
update-build-plan-references.pyand future equivalents): design as two-pass — Pass 1 introduces stable-IDs in the new artefact + rewrites step-N references to stable-ID form; Pass 2 path-based rewrites for less-load-bearing section refs. This is the Phase D” Stage 3.6 D-6 pattern. -
When to NOT use stable-IDs: ephemeral references (commit messages, conversation, short-lived audit notes). Stable-IDs are for substrate that future-Claude or future-Rich will follow back.
-
Pre-commit hook integration (future work): when frontmatter v1.4 lands per Phase D” Stage 7, consider extending
check-frontmatter-pins.pyto validate that any[<repo>-step-N]reference in a document resolves to a realid:in the target tasks.md. Blocks dangling references at commit-time.
Counter-pattern to avoid: introducing stable-IDs WITHOUT updating cross-references at the same time. The whole point is the references resolve — half-migrating leaves the system worse than before (mix of stable + path-based with no clear convention). Stage 3.6’s two-pass design (introduce IDs + rewrite refs in the same script) is the correct pattern.
Related: feedback_research_artefact_forward_traceability (same forward-safety motivation — research artefacts must signal forward consumers); feedback_frontmatter_policy_sdd_alignment (frontmatter discipline more broadly; v1.4 adds 8 SDD fields including the id: field that this pattern depends on); feedback_methodology_migration_cascade_q_pairing_mandatory (MQ-020 discipline for arch-state ↔ MQ-NNN pairing — analogous stable-ID concept at the meta-layer).
Substrate origin: Phase D” batch-imp-24 launch-prompt v1.3 (commit 371e74f on docs-strategy origin/main 2026-05-24T19:25 BST). The D-6 lock and §1.1 Stage 3.6 + §1.2 tasks.md rubric describe the concrete TT implementation. Phase D” Stage 3.6 is the first place this pattern lands operationally; future Phase E + Phase F work should extend it.