These instructions govern work on the engine itself: the code in src/ and the specification in
spec/. They do not govern the consuming product. Product work never needs this document.
Bootstrap
Read spec/ENGINE.md before changing authority, the relationship graph, the
verification lifecycle, fixtures, synchronization, generation, or scaffolds.
Read spec/DIAGNOSTICS.md before adding, renaming, or repurposing a
diagnostic code.
Read spec/PROFILE.md before adding anything the engine needs to know about a
specific repository.
What this is
The engine keeps requirements, verification obligations, prose fixtures, executable bindings,
implementation units, and generated projections synchronized. It enforces relationships and decides
no meaning.
src/engine.zig root namespace and self-test aggregation
src/model.zig graph types, ZON loading, lookups
src/validate.zig every structural gate over the graph
src/fixture.zig fence extraction, generated Zig tests, instrumentation checks
src/scaffold.zig authoring plans and disposable implementations
src/diag.zig subjects, codes, fingerprints, stale-link reports
src/project.zig generated documents, freshness, atomic replacement
src/query.zig single-fact queries and impact reporting
src/codegen.zig generic Zig data projections
src/status.zig derived verification state and coverage reporting
src/sync.zig fingerprint synchronization and source registration
src/text.zig identifier, Markdown, XML, and wrapping primitives
Non-negotiable invariants
No product-domain fact in src/. No repository path, product name, requirement prefix, or suite
meaning. Add it to the profile instead.
No import other than std, sibling engine files, and the profile module.
No third-party dependency.
Generated output stays reproducible from registries alone.
Scaffolds write to standard output only, and unfinished generated code fails with @compileError.
Engine self-tests never count as product verification evidence.
Gates validate; generators, transformations, and reports do not. A command that repairs a
condition must never refuse to run because of that condition.
Diagnostics are the product
The engine's user interface is its failure output. An author who hits a gate must be able to resolve
it without reading any document.
Every failure goes through diag.fail with a subject, or through a dedicated drift reporter. A new
failure path must answer, in the message itself:
what is inconsistent,
which owner holds the disputed fact,
which command shows the fact and its dependents,
which resolutions are permitted,
which command proves the fix.
If an author would need a procedure that no message and no generator supplies, that is an engine
defect. Fix the message or add a generator. Do not write instructions for the consuming repository.
Changing behavior
Add or update engine self-tests for every behavior change; they live beside the code they cover.
Prefer generation over a new maintained link. A new link needs a stated reason why generation
cannot decide it.
A new structural rule needs a diagnostic subject, a test proving the failure is reachable, and a
catalog entry.
A published diagnostic code keeps its meaning. Narrowing one requires a new code.
Widening the profile contract is a breaking change for consumers: update
spec/PROFILE.md in the same change.
Gates
Run from the repository root:
zig build test
zig build check
zig build check covers formatting, compilation, engine self-tests, generated-projection freshness,
and full specification validation. Keep every source within 100 display columns.
# Specification engine instructions
These instructions govern work on the engine itself: the code in `src/` and the specification in
`spec/`. They do not govern the consuming product. Product work never needs this document.
## Bootstrap
Read [`spec/ENGINE.md`](spec/ENGINE.md) before changing authority, the relationship graph, the
verification lifecycle, fixtures, synchronization, generation, or scaffolds.
Read [`spec/DIAGNOSTICS.md`](spec/DIAGNOSTICS.md) before adding, renaming, or repurposing a
diagnostic code.
Read [`spec/PROFILE.md`](spec/PROFILE.md) before adding anything the engine needs to know about a
specific repository.
## What this is
The engine keeps requirements, verification obligations, prose fixtures, executable bindings,
implementation units, and generated projections synchronized. It enforces relationships and decides
no meaning.
```text
src/engine.zig root namespace and self-test aggregation
src/model.zig graph types, ZON loading, lookups
src/validate.zig every structural gate over the graph
src/fixture.zig fence extraction, generated Zig tests, instrumentation checks
src/scaffold.zig authoring plans and disposable implementations
src/diag.zig subjects, codes, fingerprints, stale-link reports
src/project.zig generated documents, freshness, atomic replacement
src/query.zig single-fact queries and impact reporting
src/codegen.zig generic Zig data projections
src/status.zig derived verification state and coverage reporting
src/sync.zig fingerprint synchronization and source registration
src/text.zig identifier, Markdown, XML, and wrapping primitives
```
## Non-negotiable invariants
- No product-domain fact in `src/`. No repository path, product name, requirement prefix, or suite
meaning. Add it to the profile instead.
- No import other than `std`, sibling engine files, and the `profile` module.
- No third-party dependency.
- Generated output stays reproducible from registries alone.
- Scaffolds write to standard output only, and unfinished generated code fails with `@compileError`.
- Engine self-tests never count as product verification evidence.
- Gates validate; generators, transformations, and reports do not. A command that repairs a
condition must never refuse to run because of that condition.
## Diagnostics are the product
The engine's user interface is its failure output. An author who hits a gate must be able to resolve
it without reading any document.
Every failure goes through `diag.fail` with a subject, or through a dedicated drift reporter. A new
failure path must answer, in the message itself:
1. what is inconsistent,
2. which owner holds the disputed fact,
3. which command shows the fact and its dependents,
4. which resolutions are permitted,
5. which command proves the fix.
If an author would need a procedure that no message and no generator supplies, that is an engine
defect. Fix the message or add a generator. Do not write instructions for the consuming repository.
## Changing behavior
- Add or update engine self-tests for every behavior change; they live beside the code they cover.
- Prefer generation over a new maintained link. A new link needs a stated reason why generation
cannot decide it.
- A new structural rule needs a diagnostic subject, a test proving the failure is reachable, and a
catalog entry.
- A published diagnostic code keeps its meaning. Narrowing one requires a new code.
- Widening the profile contract is a breaking change for consumers: update
[`spec/PROFILE.md`](spec/PROFILE.md) in the same change.
## Gates
Run from the repository root:
```text
zig build test
zig build check
```
`zig build check` covers formatting, compilation, engine self-tests, generated-projection freshness,
and full specification validation. Keep every source within 100 display columns.