Rendered from docs/decisions/0098-an-engine-subsystem-is-described-by-a-technical-design-spec-on-a-shelf-of-its-own-and-its-behavior-stays-where-it-is-already-written.md in the Headwater corpus. Every document on this half of the site is typed by the taxonomy the descriptor names: corpus.json.

An engine subsystem is described by a technical design spec on a shelf of its own, and its behavior stays where it is already written

Context

#1283 measured the engine source on 2026-09-28. headwater taxonomy audit reports that no governs edge reaches 137 of the 184 files under engine/crates/**/src/**/*.rs. The check crate has 8 of 54 files reached, and resolve has 3 of 17. An edit to one of those files names no document.

The gap is not only missing edges. No document describes the inside of a crate. Spec 6 describes the whole engine in eight sections: the pipeline, the checks, the projections and the performance targets. It is the only place that names the crate structure. Five spec parts are longer than 11,000 words, and spec 7 is about 17,600. Implementation detail and system promises share one document in each of them.

The question was whether each crate needs a functional spec and a technical spec, or a technical spec alone. A reader meets the behavior of the engine through its verbs, and the verbs do not map one to one onto crates. The governs edges of the 25 interface contracts show this. The query crate serves five verbs: explain, mcp, query, route and show. The census crate serves three. The taxonomy verb reaches three crates: audit, compat and resolve.

Behavior already has three homes. A spec part states what the system promises. An interface contract states what one verb does, in the shape of a manual page. A requirement states one testable statement, and an acceptance criterion settles it. Only the third home is thin, with two requirements and two criteria.

The owner ruled on the three questions below in a session on 2026-09-28.

Decision

An engine subsystem gets one technical spec, and no crate gets a functional spec. A functional spec per crate would state the behavior of a verb a second time, cut along crates instead of verbs. That gives one sentence two owners, which HW-PD-0001 forbids for orchestration prose. The same reason applies here, because two copies of one behavior drift apart.

A technical spec states how a subsystem works, and why. It states the data structures, the invariants, the algorithms and the reasons for them. It links to the interface contract, spec part or requirement that states the behavior, with traces_to, and it does not repeat that behavior.

The unit is a subsystem, not a crate. A subsystem is one stage, or a small set of stages, of the pipeline that spec 6 draws. The stages are resolve, parse, graph build, cache, checks, queries, projections, export and explain. The authoring verbs and the measurement layer are two more subsystems that the diagram does not draw. Every crate under engine/crates/ belongs to exactly one subsystem. Six crates hold one source file each, so a spec for each crate would often be one paragraph long.

A technical spec is a subsystem_spec on a new shelf, docs/subsystems/. The numbered parts under docs/spec/ stay at the level of the system. The kind is declared in the overlay beside the shelf, and it requires the title alone. It reuses the spec_id scheme, so a subsystem spec reads as HW-SPEC-<slug>.

This paragraph first named design_spec, on the reading that sequence was a requirement of the spec_series shelf. The design-spec bundle requires sequence on the kind itself, and nothing reads an order among subsystem specs. The owner ruled on 2026-09-28 that a subsystem spec carries no sequence. So the overlay declares a second kind rather than weaken design_spec for every numbered part.

A technical spec governs each crate it owns by one pattern. The anchor is engine/crates/<crate>/src/**, which HW-DR-0074 permits. A new file in the crate is then reached with no new edge. Exactly one technical spec governs the source of each crate. An interface contract can keep its edges onto the files that implement its verb.

Spec 6 keeps the pipeline and the map from each stage to its subsystem spec. The implementation detail in spec 6 moves to the subsystem spec that owns it. Specs 2, 7 and 12 move their implementation detail the same way, when the subsystem spec that owns it exists. A spec part keeps what the system promises.

Consequences

The overlay declares the subsystem_spec kind and the docs/subsystems/** shelf, and it names the shelf for a generated index. That change moved the taxonomy lock. So the fourteen transcripts of the two campaign pilots of 2026-09-28 stand at deprecated, because each one pins the earlier lock. #1288 carries the writing of the subsystem specs.

The crate criterion of #1283 is met by the subsystem specs, not by spec 6. A ** anchor on spec 6 would make one document the rule for every crate. The #956 recount of 2026-09-21 rejected that shape for a subtree that many documents share.

Each subsystem spec is a document to write, and it must read the code it describes. The work is about ten documents, one for each subsystem, and it can land one subsystem at a time. The audit reading for engine/crates/**/src/**/*.rs is the measure of progress.

This decision does not close the gap on the functional side. Two requirements and two acceptance criteria are too few to state the behavior of the engine as testable statements. That gap is separate work.

Where an adopter links a crate as a library, the public API of that crate is a contract with an outside reader. That contract is an interface contract or rustdoc beside the code, not a subsystem spec. This decision is open again if such an adopter appears and a subsystem spec starts to state an API contract.