# 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.