<S> tags in your MDX file. Because the ID encodes structure, the graph can validate parent-child relationships at build time and give you stable, human-readable addresses for every requirement — from the top-level domain all the way down to an individual acceptance criterion.
Structural Dot-Paths
A child’s ID must equal its parent’s ID followed by a. and one new segment. This rule is enforced at build time; a mismatch is a build error.
auth.login.valid is valid because it extends auth.login, which extends auth. Skipping a level — writing auth.valid as a child of auth.login — is a structural violation.
Every non-root section must declare an
id. Sections without an id are a build error.Segment Rules
Each dot-separated segment must satisfy all of the following:- Non-empty — a segment cannot be a blank string
- No special characters — segments may not contain
.,#, whitespace, or ASCII control characters - Not a reserved word — the following identifiers are reserved and cannot be used as segments:
$,__proto__,prototype,constructor,then - No duplicates — two sibling sections sharing the same full ID is a build error
login-v2 — you can still use it, but you will need bracket notation when accessing it programmatically:
Full Identity: path#id
A requirement ID alone is scoped to a file. The globally unique address of a node combines the file path and the ID with a # separator:
d props, {text(...)} expressions, xspec show arguments, and TypeScript markers.
Root Nodes
Each spec file has an implicit root node identified by its file path alone, with no#id suffix:
<S> in the file. You do not declare it; xspec creates it automatically. Root nodes are excluded from coverage requirements by default.
Exploring IDs
Usexspec ids to list every requirement ID in the project. The --tree flag renders the hierarchy so you can spot structural problems at a glance:
xspec show with the full identity: