Skip to main content
Every requirement section in xspec is identified by a dot-path that mirrors the nesting of <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.
In the example above, 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
Use camelCase for segments whenever possible. camelCase segments are valid JavaScript identifiers, which means xspec can expose them via dot notation in TypeScript without requiring bracket notation.
If you have a segment that is not a valid JavaScript identifier — for example a slug like 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:
You use full identities whenever you reference a requirement from outside its own file — in 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:
The root node is the structural parent of every top-level <S> in the file. You do not declare it; xspec creates it automatically. Root nodes are excluded from coverage requirements by default.

Exploring IDs

Use xspec ids to list every requirement ID in the project. The --tree flag renders the hierarchy so you can spot structural problems at a glance:
To inspect a single node in full — including its edges, hashes, and metadata — use xspec show with the full identity: