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:

  1. 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-N for the 5 v2 build repos).

  2. Cross-references in cascade-Q files / arch-state §15 / audit-records / memories / per-repo CLAUDE.md / frontmatter companion_files: write [<repo>-step-N] not BUILD-PLAN.md#step-N or tasks.md#task-N. The bracketed-ID form is resolvable via tasks.md grep OR mkdocs-material autorefs plugin OR plain Ctrl-F.

  3. Section references (within plan.md / spec.md): stable-IDs are less load-bearing than step references — path-based references like plan.md §X.Y are acceptable here IF the section structure is mature (i.e. not expected to move). When in doubt, prefer stable-IDs.

  4. Migration tools (update-build-plan-references.py and 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.

  5. 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.

  6. Pre-commit hook integration (future work): when frontmatter v1.4 lands per Phase D” Stage 7, consider extending check-frontmatter-pins.py to validate that any [<repo>-step-N] reference in a document resolves to a real id: 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.