build and check are your two validation commands. build parses your sources and produces all derived artifacts; check is a read-only gate that confirms everything is consistent and policy-compliant. Run them together as a CI pipeline step: xspec build && xspec check.
xspec build
build parses every source file, validates structure, IDs, tags, and references, resolves all dependencies, generates TypeScript modules, emits Markdown (when enabled in your config), and writes the graph data used by all read commands. On success it produces no output — silence means clean.
A failed build modifies nothing. If any finding is reported (exit 1) or a configuration error occurs (exit 2), your workspace is left exactly as it was.
build does not evaluate policy rules — that is handled exclusively by check.
What build validates
- Structural validity of every source file
- ID uniqueness and well-formedness
- Tag syntax
- Reference resolution (
dattributes,text(...)calls, TypeScript references) - Dependency and import graph acyclicity
What build generates
- TypeScript modules for every spec group
- Markdown output files (if
markdown.emitis enabled) - Graph data consumed by
ids,show,coverage,impact,query, andreview
xspec check
check performs everything build validates and then adds a second layer of checks that are only meaningful on an already-built workspace. Because it writes nothing, it is safe to run in any environment, including read-only CI runners.
Additional checks beyond build
- Staleness — generated files must match sources byte-for-byte; orphaned derived files with no corresponding source are reported
- Reference completeness — all references must resolve and be static
- Cycle detection — no dependency or import cycles
- Journal integrity — journal must be well-formed and fully replayable
- Policy compliance — all configured policy rules must pass
- Review session integrity — all active review sessions must be intact
Validation findings catalog
CI gate pattern
Runbuild first to regenerate all derived artifacts, then check to verify the full constraint set. If either exits non-zero, the pipeline fails.
--json on check to consume findings programmatically: