Use a Dedicated stories: Field for Spec-to-Story Traceability (Not relationships:)
Context and Problem Statement
SR-11 requires that StatementSpec carry back-references to the user stories
that motivated each requirement, enabling bidirectional traceability between
the spec corpus and docs/reference/user_stories/. Two natural attachment
points exist in the schema. Which one should carry story IDs?
Decision Drivers
- Story IDs (
story_YYYY_NNN) are not spec IDs — they do not live in the spec registry and should not be validated as if they do. - The existing
relationships:field'sspec_idsub-field is validated byvalidate_cross_references()against the registry index; a mismatch causes a hard lint error. - Story references must be suppressible per-spec without disabling the broader cross-reference graph check.
Considered Options
- Reuse
relationships:— add story IDs asRelationshipitems whosespec_idvalues carry thestory_YYYY_NNNpattern - Dedicated
stories: list[StoryIdStr]— a first-class optional field onStatementSpecwith its own constrained type, separate fromrelationships:
Decision Outcome
Chosen option: dedicated stories: field, because reusing relationships:
would produce a hard lint error on every story back-reference: the cross-
reference validator would reject story_2022_001 as an unknown spec ID, since
story IDs are not in the registry index. A dedicated field bypasses the
cross-reference graph entirely without polluting it.
Consequences
- Good, because story back-references are type-safe via
StoryIdStrpattern validation without requiring story IDs to enter the spec registry. - Good, because the
_nonempty_if_presentvalidator andlint_suppressmechanism apply uniformly tostories:alongside other list fields. - Good, because the SR-11-003 hard-error gate and SR-11-004 advisory gate
can target
stories:specifically without touchingrelationships:. - Neutral, because
stories:andrelationships:are now two distinct back-reference mechanisms — implementors must know which to use for which kind of reference.
Validation
StoryIdStr pattern enforcement is tested in test/metadata/specs/test_schema.py.
The SR-11-003/004 lint gates are tested in test/metadata/specs/test_lint.py.
uv run spec-lint exits 0 on the live registry.
More Information
- Issue: #2585 (implementation)
- PR: #2589
- Follow-up: #2605 (this ADR)
- See also:
notes/specs-vs-adrs.mdfor the decision-tree that prompted writing this record.
Generated spec requirements: specs/spec-registry.yaml SR-11-001, SR-11-002