Rendered from docs/decisions/README.md in the Headwater
corpus. Every document on this half of the site is typed by the taxonomy
the descriptor names: corpus.json.
Decision records
The documents on this shelf, in the reading order this corpus derives.
- Q1 — Implementation language — The language is Rust, with a WebAssembly build of the same crate for editor and browser embedding.
- Q2 — Schema format — YAML 1.2 is the concrete syntax, and Headwater owns the schema language, the reference sublanguage, the overlay language and the meta-schema.
- Q3 — How much of the default taxonomy ships in the box — The base package is minimal and derived from the core, and optional content ships as add-only bundles.
- new writes no far half of a symmetric relation and no state on a supersedes target — A scaffold edits no target of a symmetric relation. A far half in a live target reads as a live document that rests on a draft. It sets no supersedes state, which check --fix writes. (asserted, and no human has accepted it)
- A reciprocal half is owed once its writer leaves its initial state — While a draft holds the only half of a required pair, nothing is owed. The far document owes its half once the draft is promoted. (asserted, and no human has accepted it)
- Q4 — Relation storage — Front matter is authoritative, and a relation instance is an object rather than a pointer.
- Q5 — Voice checking depth — Voice checking stays lexical, with a curated pattern set, a per-category posture and a reasoned escape hatch.
- Q6 — Where the corpus graph lives at rest — The graph never rests. Every run rebuilds it, and no derived artifact is canonical for anything.
- Q7 — Scope of the MCP surface — Three classes of tool, and a landed write never ships.
- Q8 — Probe cost and cadence — A probe is a document with a declared expectation, and cadence follows the purpose of the run.
- A namespace does not keep two corpora apart, and no rule compares identifier schemes across two locks — Two corpora in one tree, or a vendored corpus beside its host, can mint one identifier, because one namespace plus a literal can spell another. The engine loads one root and one lock, so no rule compares schemes across two locks. An adopter picks namespaces that no pattern can spell from another, or resolves a scratch overlay that declares both corpora's schemes. (asserted, and no human has accepted it)
- Q9 — Multi-repository corpora — A repository holds one or more corpora, the tier above harvests pinned exports, and no merged graph exists.
- Q10 — Naming — The name is Headwater, capitalized in prose and lower case as an identifier.
- Q11 — License and distribution posture — Apache-2.0 for the engine, the library, the base package and the bundles, ratified by the owner on 2026-08-11.
- Q12 — Migration path for an existing corpus — Adoption is a migration from no taxonomy, and
headwater infercomputes the adoption payload. - Q13 — LinkML and SHACL as substrate — Headwater owns the language, emitters never chain, and LinkML is the last of six siblings.
- Q14 — Discovery surface — The corpus descriptor is a generated projection at
.headwater/corpus.json, and registration went to Q16. - Q15 — A synthesized content tier — Every document carries a warrant from a closed set of four, and
assertedcontent is admitted with limits. - A recorded terminal demonstration may show a frozen number behind a recorded-on-date marker — The owner relaxed principle 11 for one asset. A front-page recording may show a number a live run does not produce, if a recorded-on-
marker stands beside it. Nothing compares that number against a later run. - Q61 — How a recorded terminal demonstration is held against a run (superseded) — A recorded terminal demonstration is a figure under HW-DR-0039. It may show only the tutorial's scratch corpus, where a blocking step already holds every printed output against a run. (asserted, and no human has accepted it)
- A figure on a hand-built page is measured when the site is published, and the committed page carries none — The pages under site/ commit every data-figure element empty. A CI job on each push to main measures the figures into the assembled copy and deploys it with wrangler. Two pull requests that add documents merge without a conflict on the pages.
- Q39 — How a figure reaches a hand-built page (superseded) — The interpolating form that HW-DR-0037 admits runs before the commit rather than after it, and a script writes every figure on a hand-built page from a run.
- Q50 — Where the visual register of the hand-built pages lives — The hand-built pages read as a specification rather than as a product page, and one file holds the color tokens and type stacks that carry it. A script writes that file into each hand-built page before the commit, because the content policy of those pages admits no linked stylesheet, and the generated half links the same file because its own policy admits one. (asserted, and no human has accepted it)
- Q37 — Which parts of the site are hand-built and which are a projection of this corpus — Everything under
site/is hand-built and the corpus is the generated projection. A hand-built page states no figure a person typed, and nothing checks that. - Q16 — Public presence — Registration needs a channel with an obliged reader, a directory of corpora is refused, and the site is a projection of this corpus.
- Q17 — Governed access and the solution layer — The serving boundary is the export step of each publishing corpus. A profile filters for an audience, and Headwater has no principals.
- Q18 — Recording adjudicated disagreements — The edge does not become a node. An adjudication is a decision document that carries
overrides. - Q19 — Inbound integration: an external system of record — Imported content is
transcribedagainst a committed pin, and an imported edge carries full weight from the first release. - Q20 — Where scent lives — An optional source-owned cue sits on a relation instance, graded against the alternatives in view at the point of decision.
- Q21 — Terminological succession, and validity under merge — A retired-term lexicon sits in the language regime, and a verdict reports the read set that a merge may void.
- The vendor verb may take a location, and the fetch lives only in a crate the checking loop never links —
headwater taxonomy vendormay accept a location, ruled yes with a boundary. The fetch lives in a crate only the CLI links, so the checking loop's crates keep the no-socket property that serves it. - Q22 — The integrity posture of a published package — A package digest checks a fetched artifact against a pin that a person committed, and it is never a signature. The in-house SHA-256 is held against a second implementation rather than replaced by a dependency. (warrant
proposedis not one of the four values, so no acceptance is read from it) - Q23 — The engine lint floor — A published Rust guideline set is not installed as a skill, because a skill carries no rule of its own. Twenty-two lints are declared once in the workspace manifest, and each was chosen by measuring the corpus rather than by adopting a list.
- Q24 — Readability, and what a sweep can be asked about — Readability is not a sweep class and gets no verb, because every class of a sweep names two things that do not fit and a readability finding names one. A source file is not a slice member, because admitting one degrades the membership refusal for every class.
- Q25 — Where the namespace goes in an identifier, and who declares it — The namespace opens every identifier, and a published source declares no namespace at all, because any constant it wrote would be minted by every adopter of it at once.
- Q26 — Whether terminality belongs to a state, or to a state and a regime — Terminality stays a property of a state alone, because the per-regime reading is available at both call sites and costs the deferral that keeps one defect one finding. No published tradition wants the collision, and two that met it minted a second state name.
- Q27 — Whether a decision record is governed prose — A decision record is governed prose, and the overlay binds the house language regime to it. The shelf carries a prose problem rather than a quotation problem, and collapsing all 37 inline quotations moves 64 findings to 63.
- Q28 — Whether an evaluation is governed prose — An evaluation is governed prose, and the overlay binds the house language regime to it. The shelf carries 432 advisory findings, and the measurement that explains them is whether a rule was reading the prose when it was written rather than who wrote it.
- A verification is a kind, and its identity is minted rather than found in the code that cites it — A verification takes a minted document identifier, because a rename must not break the link and one criterion may be proved in several repositories. The anchor option loses that identity, and it would also be blind to the participation expectation until #855 lands.
- A code path anchor is a pattern over the tree, and it binds when the pattern matches at least one entry — A
code_pathanchor is a pattern in the shelf language or a list of them, and a bare path matches one entry. An edge binds when every pattern matches at least one entry, and a query matches a path against the patterns. - A language rule reaches front-door prose outside the corpus root, and no other rule does — A language regime lists the paths outside the corpus root that it binds, and only the three language rules read them. Such a path is not a document, so no facet, voice, link or relation rule reaches a README. (asserted, and no human has accepted it)
- Q29 — Whether a corpus root may contain code, and what an interface contract may reach — The corpus root stays
docs, because a path is corpus content only where a file with no front matter is a defect, and 185 of the 186 Markdown files underengine/exist to be defective. An interface contract lives inside the root and reaches a crate by agovernsedge that binds on existence alone. - Q30 — Whether what an obligation waits on is a state or a property, and how many values it takes — What an obligation waits on is a state and not a property, and the closed set holds four values. A required
waiting_onfacet onobligation_recordtakesruling,build,measurementoradopter, and the decision-record bundle declares it. - Q31 — Whether this repository becomes public, and when — This repository is public. The owner set 2026-09-08 and opened it on 2026-09-06, and the record stops each run from raising the schedule.
- Q32 — Which test the self-audit label states — The
self-auditlabel states the reader test and not the provenance test. How a finding was found is not the test, and the only question is whether a reader outside this repository is better off. - Q33 — Whether the command line is derived, and who a flag belongs to —
clapderives the command line for 17 lock entries, and a flag belongs to the verb that reads it rather than to the binary. - Q34 — Whether acceptance means merged to main, and what an agent may write before that — Acceptance is the merge onto main. A provenance block on an unmerged branch is a proposal, so an agent may write
accepted_bythere, and stop rule 5 binds main rather than the byte. - Q35 — Whether one requirement kind holds an imported requirement and an authored one — The
requirementandacceptance_criterionkinds serve the authored population alone. A transcribed requirement is a marked file that answers no contract, so a separate kind with an empty contract carries the imported case. - Q36 — Which of MkDocs, Docusaurus, or Astro this corpus emits navigation for, and why — MkDocs is the pick. Its
nav:is data and not code, and Astro has no native nav format to emit at all. - Q38 — Which link relation a rendered page carries to the served corpus descriptor — A rendered page points at the served descriptor with
rel="describedby", because the IANA registry carries that token and the Headwater extension address answers 404. - Q40 — Whether extends, bundle, requires and an overlay's taxonomy key are a mechanism or a label — Three keys of the family are a label rather than a mechanism. HW-DR-0095 made
requiresa mechanism for one purpose, which is an add into the keys of the entry it names. - Q41 — Whether Vale becomes a declared regime backend — Vale does not become a declared regime backend, and its findings are not translated into this engine's Finding shape. It stays where spec 00 already puts it, composable alongside, because four structural mismatches answer Q24's reopening condition a second time.
- Q42 — What "one screen" means for the first help screen — "One screen" is retired as a claim about a terminal and replaced by a claim about content. The first screen carries one line per entry, and the ceiling that follows from it is 64 lines.
- Q43 — Whether a refusal under
--jsonis a JSON document — A refusal is an English sentence on standard error and never a JSON document, because--jsonnames the shape of an artifact and moves no stream and no grammar. - Q44 — Whether bundles decompose into capabilities and assemblies compose practices — Design-spec's evaluation kind and its two purposes move to a new evidence-and-obligation bundle, so decision-record stops requiring the whole specification tradition.
- Coloring the CLI, and where the banner goes — Color is sensed per stream and off by default in a pipe, and turned off everywhere by
--no-colororNO_COLOR. A new masthead banner prints on the root help screen alone, off by--no-bannerorHEADWATER_NO_BANNER. - Migrating from-version carries a semver and a release digest, kept as separate fields —
adoption.fromis a pair, a semver and the release digest that was pinned when the migration began, and never a hash of the two. - The served sitemap is derived from the served directory — The sitemap a reader gets is derived from the directory that is served, by one walk that both halves call. Nobody types a page list, and the assembled directory is the only place the union exists. (asserted, and no human has accepted it)
- How the two halves of the site share one host — One directory holds both halves of the site, composed by
tools/site/assemble-site.shwith the hand-built half last. The Cloudflare Workers Builds build command runs that script, which puts a build on the deploy path for the first time. (asserted, and no human has accepted it) - The consumer surface is what an adopter receives, runs and must have installed, and it is a closed and declared list — An adopter needs the binary, a data-only package, Git,
sh,curl,tar, eight POSIX utilities and the four APT programs, and nothing else. Every other program reaches Headwater through a verb that the binary configures on request, and no adopter-facing page instructs this repository's own tooling. - A corpus-wide fold is derived and never stored — A recorded artifact holds one record per entity and derives every total, because two branches that each add one document write the same new total and a merge takes it without a conflict.
- Q51 — What licenses a term into the public glossary, and what licenses a sixteenth — A term reaches the public glossary because it recurs in the visitor-facing pages of the site, and for no other reason. The tutorial and the glossary itself are not sources, and the specification glossary answers to a different reader. (asserted, and no human has accepted it)
- A document is proposed at the state it will hold, and the merge activates it — A settled decision carries the status current, not draft, in its pull request. An author writes the state a document will hold once it merges, and the merge activates it. The state facet answers to the merge, the way HW-DR-0034 made the warrant facet answer to it.
- A package manifest declares no selection, a recipe declares one, and a flattened manifest records provenance — A manifest says what a package carries, a recipe says what a composer selected, and a flattened manifest records where it came from. Three enforcement points already hold the split, and this record names it as a rule rather than as specification prose. (asserted, and no human has accepted it)
- The upper bound of a reconcile-first allocator is the corpus and a claim store — A tree holds no concurrency, so two branches mint one number in silence. A claim store of one file for each identifier makes the two branches meet, and the rule that already reports a duplicate then fires on the branch. (asserted, and no human has accepted it)
- A hook reads a wire format through the engine and not through an interpreter — A harness payload is read by a verb of this engine rather than by an interpreter a session does not otherwise require. The verb answers nothing about a corpus, which is what puts it outside the term that forbids a hook verb. (asserted, and no human has accepted it)
- A language regime reaches prose through a kind, so the starter kit's doctrine carries the writing profile — No kind in the base package or in any bundle binds a language regime. A package that set the default value would change nothing, so the doctrine page of the starter kit carries the promise. (asserted, and no human has accepted it)
- A shelf layout is the second half of what the identifier claim store covers — The claim store covers an identifier where the file name does not determine it: a shelf that declares a layout, or a scheme that reconciles
- A blank facet value is a rule of its own and it reads every string facet — A declared facet that carries no content is a state that neither the required-facet rule nor the enum rule reaches. A new rule reports it, over every facet a taxonomy types as a string, at error severity. (asserted, and no human has accepted it)
- A transform over a harness session log is an observed transcript when the log arrives by a channel the model cannot write to — A filter that keeps the tool calls of a harness session log and drops every block the model wrote is an outside observation, because the type tag it reads is the harness's and not the model's. The condition is the channel the log arrives by, and a file the session can open is not one. (asserted, and no human has accepted it)
- The engine's version stays one number, and a build's exact commit is a separate, unwired fact — A binary's
--versionkeeps naming one number, theCargo.tomlversion arequires_enginerange is read against. Which commit built it is a separate fact a build script now captures, kept out of that comparison and not yet on the command line. - A refused recording is held by the reliance its state claims, and not by promotion — A refused transcript fails the run where its state carries the
liverole. A role that says nobody relies on the document leaves the run green. (asserted, and no human has accepted it) - Every required facet of a generated document is derived, and the emitter composes the summary — Nine required facets went unwritten on two generated documents. The engine derives seven from committed bytes, the emitter composes the summary, and the declaration block stays closed at three scalars. (asserted, and no human has accepted it)
- Q64 — Whether intent-time routing gains an offline embedding path in shadow mode — Routing gains the shadow-mode embedding path, amended in four places. The intent hook is the only writer, and the vectors are a cache rather than a generated artifact. The model is pinned rather than committed, and the recorder gains a join key and a liveness fact. (asserted, and no human has accepted it)
- A relation declares lifecycle_sensitive for itself and a core requirement demands it of a family — The relation-level member and the core requirement are a union: either marks a relation, and the published base marks nothing beyond succession. (asserted, and no human has accepted it)
- A kind narrows the value set of an enumerated facet, and nothing else can — A kind states which values of an enumerated facet it means, under
facets.values. A lifecycle regime, a shelf discriminator andfacets.forbideach narrow a value set. None of the three reaches a facet with no state machine behind it. (asserted, and no human has accepted it) - The vendored package root moves under .headwater and the old root is named in a refusal — The vendored package root is
.headwater/packages/, because the old root bought only the visibility of one explainer, and a tree there meets a named refusal. (asserted, and no human has accepted it) - The front-matter key that carries a minted identifier is id — The front-matter key
idis the fixed, global name for the value a kind'sidentifier: {scheme: …}facet mints. (asserted, and no human has accepted it) - No paragraph limit joins the language rule, because most paragraphs past six sentences hold one topic — The six-sentence paragraph defect is retired before it lands. 50 of 60 sampled paragraphs past six sentences held one topic, so the count misses what rule 6.5 asks, and no word count replaces it.
- A paragraph limit counts sentences under the language rule and never words (superseded) — No word-length rule joins the check layer. The six-sentence limit of the standard the house regime declares lands as a fifth defect of the language rule, advisory permanently. The paragraph that raised the question is a hand-kept index, and a derived list repairs it where no lexical rule reads it.
- The matched purposes take turns at a route budget, and each pointer states what reached it — The purposes a task matches take turns at the route budget, and the kinds of one purpose take turns inside it. Each pointer states the task terms that reached it and its rank in the order by score. No pointer carries a score or a confidence.
- A route offers a document and never a heading inside it — A route does not read headings and offers no anchor inside a document. A measured heading surface never reached spec 02 or spec 03 for the task that raised the question. At every threshold, function words reached wrong anchors.
- The binary is the only interface an adopter must run, and every integration point outside it is declared — An adopter reaches the whole governed loop through the binary. One integration point sits outside it and the list is closed against growth. Git plumbing meets the necessity test, a network fetch left the list under HW-DR-0075, and a verb writes the change manifest.
- A probe budget prices a run identity fixed before the run, and a committed transcript, and a sweep has neither — Rules that a budget prices a run identity a probe has and a sweep does not, and names the sweep outside every tier. States where .headwater/probe.yml lives and why. (asserted, and no human has accepted it)
- Criterion 5 admits naming or extending a core-serving kind, and a facet-only entry ships no templates directory under criterion 2 — A full entry that serves neither core purpose names or extends a core-serving kind, and a facet-only entry ships no templates/ directory. (asserted, and no human has accepted it)
- Q66 — the corpus dashboard ships free and self-hosted, with tenant isolation stated as a data-model constraint from day one — The corpus-staleness dashboard (#505) ships as a free, self-hosted companion tool, with no hosted form now. Its data model carries a corpus identity on every row from day one, so a later hosted form is an addition rather than a rewrite.
- The hand-authored decision register indexes a subset of the shelf, and stops asserting it supersedes the complete one — The hand register keeps a curated selection of headings and drops its
supersedesedge over the generated register, which stays the complete list. (asserted, and no human has accepted it) - The resolved taxonomy is drawn by a verb that prints Mermaid and writes no file —
headwater taxonomy graphprints the resolved taxonomy as a Mermaid flowchart, no projection or export target draws it, and D2 and DOT are equal candidates after it - Governs and traces_to are created by an agent, because a session proposes the line and a person types it — The base package declares
created_by: agentongovernsandtraces_to, because no verb writes either edge and a person types the line a session proposes (asserted, and no human has accepted it) - A live document that rests on a draft one is reported over every relation, because a draft leaves no record to cite — A live document with any relation to a draft is a warning, unless the relation writes a state onto its target (asserted, and no human has accepted it)
- An engine release and a taxonomy release have disjoint tag namespaces and are cut independently — An engine tag matches v and a taxonomy tag matches taxonomy/headwater-standard/v, so neither release waits on the other and requires_engine is the only link. (asserted, and no human has accepted it)
- A taxonomy release publishes the source at the tagged commit and never ships the vendored copy — The taxonomy release runs taxonomy publish on taxonomy-source/ at the tag and never zips .headwater/packages/, so the artifact and the tag make one claim. (asserted, and no human has accepted it)
- Each release states in its notes the release digest that a consumer pins — An engine release and a taxonomy release each print the headwater/standard release.digest in their notes, so an adopter pins it from the tag they downloaded. (asserted, and no human has accepted it)
- The runner image of the engine release build is written in the workflow because it sets the glibc floor — release.yml names each runner image and never reads CI_RUNNER, because the image sets the glibc floor that README.md states. The build is --locked. (asserted, and no human has accepted it)
- The citation comment of spec 5 is for an adopter's corpus, and this repository does not practice it on its own code — The per-identifier citation comment of spec 5 is a convention for an adopter's corpus. By the owner's ruling, the code of this repository carries none. Its comments that name an identifier are prose, and the checker does not read them. (asserted, and no human has accepted it)
- The live account of a domain is its own kind, split on the product and process line, and it draws on the records it cites — explanation and process_explanation state what holds now across one domain, and draws_on reports an account whose source decision ends. (asserted, and no human has accepted it)
- The APT repository is served from headwater.tools and signed by a subkey the owner's offline key certifies — Headwater ships one amd64 Debian package, taxonomy-free, through an APT repository on headwater.tools whose metadata a CI-held signing subkey signs (asserted, and no human has accepted it)
- Q67 — One library entry may address the keys of an entry it names in requires, and confluence holds over the dependency order — An entry that names another in requires may add into its keys, and every other pair of entries still commutes only over disjoint leaves. (asserted, and no human has accepted it)
- Harper does not become part of the engine now, and Q41 stands — harper-core found 0 real errors in 187 hand-read findings on 25 documents of this corpus. So the engine does not link it now, Q41 stands, and a stated precision bar or an adopter request reopens it. (asserted, and no human has accepted it)
- 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 — Each engine subsystem gets one technical spec, a subsystem_spec on a new shelf, and it governs its crates by one pattern each. No crate gets a functional spec, because interface contracts, spec parts and requirements already state behavior.
- A counted tombstone lists a digest of each withheld identifier, and a sealed one lists nothing — Under the counted grain, each tombstone of a filtered export lists the SHA-256 digest of each identifier it withheld. A tier that pins the export then binds an anchor to a withheld document as withheld, and it reports a typo as unresolved. Under sealed the export lists nothing, and both stay unresolved. An export older than version 1.3 lists nothing either. (asserted, and no human has accepted it)
- An editor integration starts headwater mcp for each query and does not embed the library — An editor plugin is a client of headwater mcp: it starts the server for each query, sends one read request and stops it. The library stays embeddable, but no editor host embeds it. (asserted, and no human has accepted it)
- An evidence relation declares which end is the evidence, and discharges declares the source — A relation of the evidence family declares evidence_at, from or to, because the family cannot say which end substantiates the other. Absent is to. discharges declares from, so an evaluation is the evidence for its obligation. (asserted, and no human has accepted it)