Rendered from docs/taxonomies/README.md in the Headwater
corpus. Every document on this half of the site is typed by the taxonomy
the descriptor names: corpus.json.
The canonical taxonomy library
This directory holds the canonical taxonomy library: a curated set of taxonomies, each one modeling a named documentation tradition. Every adopter would otherwise rediscover and re-encode their own tradition from nothing. The library is the alternative to that, published on the terms that spec 7 already fixed.
This file settles five things: what an entry is, what admits one, what each entry ships, what admits an assembly, and where each draft lives. It also collects the rulings that a draft works under, so that authoring an entry reopens none of them.
An entry is a bundle
Q3 settled the packaging mechanism before the library needed it. The base package headwater/standard is minimal and derived from the core. Optional content ships as a bundle, which is a publisher overlay that holds add operations and nothing else (spec 7). A library entry is one such overlay, plus the doctrine prose, the templates, and the fixtures that go with it.
The add-only rule comes from the resolver rather than from taste. Add-only overlays over disjoint addresses commute, so the static confluence check proves that every subset of bundles resolves (spec 2). The publisher runs that check once per release. No adopter can then select a combination of entries that fails. One exception is ruled. HW-DR-0095 (Q67) lets an entry write into the keys of an entry that it names in requires. It appends with add_to or adds a key with add. The dependency applies first, so confluence holds over every order that respects the declared dependencies. The resolver refuses a selection that holds the dependent entry and not its dependency, and names both. case group 8 of the diataxis entry runs this form over two real entries.
Admission criteria
Seven criteria. The first five confirm the sketch that the epic proposed, with one correction inside criterion 5. The last two follow from the confluence rule that criterion 3 rests on. A reviewer checks both mechanically once the engine exists.
1. It models a named tradition with citable prior art. A book, a published method, or a convention that many organizations copied. The doctrine prose carries the citations, and it states what the tradition converges on rather than asserting a shape. A structure invented for the library fails here, however neat it is. The test a reviewer applies: somebody who works in the tradition recognizes it, and the citation predates the entry.
2. It ships the whole anatomy. Schema, doctrine, one template for every concrete kind, and a fixture corpus with its run record, in the layout that the next section fixes. A schema with no doctrine is a shape with no reason. Spec 2 refuses that inside a taxonomy, and this file refuses it around one.
3. It is add-only over the base. No override and no remove, and every written address is absent from the base. An entry that needs either one does not fail admission on its own account. It is evidence that the base declared something that it should not have, and that finding goes to 13 — Open obligations. The entry then waits for the base change rather than working around it.
4. It carries a worked instance corpus. At least one external real or realistic corpus, typed by the entry and recorded with its source, revision, paths, and run. A taxonomy that never met a document is a guess about a tradition. The failure mode is symmetry: kinds that balance on the page and that nobody files. The corpus is also what the engine inherits as a fixture the day that it exists.
A facet-only entry has no kind of its own, so its worked corpus borrows one from another entry (HW-OBL-0186). The corpus names the kind it borrows, and it demonstrates the entry's own facet rather than the borrowed kind's purpose. A facet-only overlay such as Diátaxis takes this reading, because it adds no kind for the corpus to type a page as.
5. It declares its relationship to the invariant core. The core requires the state, freshness, and scent facet roles, the rationale and behavior purposes, and a lifecycle-sensitive succession family (spec 2). An entry names which of its facets carry those roles, and which of its kinds serve those purposes.
A full entry that serves neither rationale nor behavior with a kind of its own satisfies this naming obligation in one of two ways (HW-DR-0079). It names the base declaration that serves each purpose, or extends a base kind that already serves the purpose by writing into that kind's facets. Criterion 1 already refuses an invented kind for either purpose, as a structure invented for the library. Spec 2's own resolved-taxonomy language grounds both shapes. After resolution, some kind serves the rationale purpose, and the check runs against the resolved taxonomy rather than one entry's own declarations.
A partial entry states that instead. A facet-only overlay such as Diátaxis composes onto a base that already satisfies the core, and it satisfies nothing by itself. The declaration is what separates a partial entry from an entry with a hole in it.
This criterion was first drafted around rationale alone. That inherited the omission that Q3 corrected in its own leaning. A taxonomy with no behavior-serving kind has nowhere to state what the system does, so a code path resolves to nothing.
6. Its address set is disjoint from every admitted entry. Confluence holds for add-only overlays over disjoint addresses. Two entries that both add kinds.guide collide, and an adopter who selects both gets a kind assembled out of two traditions. The remedy is a rename in the later entry, or a declared dependency on the earlier one where both mean the same thing. HW-DR-0095 rules the one legal overlap. An entry may write into a key of an entry that it names in requires, and the dependency applies first. No other overlap is admitted. The fixture resolves the declared dependency closure beside each compatible entry.
The resolver's own check is narrower than this criterion, and a reviewer runs both. headwater-resolve compares the leaves that two operations write rather than the paths they address, because two overlays reaching into one declaration without meeting do commute and this repository committed such a pair on the day it typed itself (#50). So it refuses two entries that state a purpose for kinds.guide, and it admits two entries that give kinds.guide different members. The second pair resolves, and it is still two traditions sharing a name. Admission refuses the name, and the release check refuses the contradiction.
7. It resolves, and it declares its dependency closure. Every reference in the entry resolves against the base plus the entries that it names in requires, and its fixture proves that root before it proves composition. The meta-schema lists what that means in full, and three of its rules catch most of it. Every concrete kind is reachable from a shelf. Every declared purpose is served by a concrete kind. Every relation endpoint names a declared kind or anchor kind.
The first-run walkthrough measured why this is not free. A new relation is one line. A new kind drags a shelf, a purpose, an identifier scheme, and its edges behind it.
Two consumption forms share one authored entry shape
The library serves two consumers without maintaining two copies of a taxonomy. A composer selects bundles and writes any local connection between them. A batteries-included consumer takes a flattened package that a publisher derives from a named assembly. Spec 7 defines both forms.
An assembly is not a second library entry. The admitted bundles remain the authored sources for their schema, doctrine, templates, and fixtures. The assembly adds one recipe, an optional assembly overlay, assembly doctrine, and an interaction fixture. Its flattened package is generated release output.
The package boundary keeps the two forms apart. A composer takes headwater/standard and its bundles. A batteries-included consumer takes a package such as headwater/starter and selects no bundles. The flattened package can repeat addresses from the source bundles because the two packages never enter one resolution.
Assembly glue does not repair arbitrary bundle composition. A source bundle can declare a connection into an entry that it names in requires (HW-DR-0095). That makes the whole dependency part of every selection of the bundle. The assembly owns only the connection for its named combination, and it costs no dependency.
Assembly admission
An assembly is a distribution choice rather than a documentation tradition. Criterion 1 therefore does not apply to it. Eight criteria keep the assembly set finite and keep the flattened artifact derived.
1. It names an outside adopter or a documented adopter population. The evidence states why explicit bundle selection does not meet that adopter's need.
2. It selects only admitted bundles. The recipe pins one source package version and lists its complete bundle selection. It relies on no implicit reading of requires. Q40 rules it a label, and HW-DR-0095 reads it for one purpose only: it orders a dependent write. It never adds a bundle to a selection, so the recipe lists every bundle itself.
3. Its overlay contains assembly glue only. Each operation connects declarations from two or more selected bundles. It restates no declaration that the base or a selected bundle owns.
4. It carries a worked interaction corpus. The corpus exercises the connections between the selected traditions. The selected bundles retain their own fixture corpora.
5. Its doctrine explains the combination. It links to each selected entry's doctrine and states only the choices that belong to the assembly.
6. Its flattened package is generated. No person maintains a second taxonomy source, a second bundle doctrine, or a second bundle template.
7. Publication proves equivalence. A fresh recipe resolution and the flattened source have the same canonical declarations after package identity and derivation metadata are excluded.
8. A reader can identify the form from the manifest. distribution.form is flattened, and distribution.derived_from names the recipe inputs. The assembly doctrine states that its publisher coordinates upgrades.
These criteria replace the refusal recorded for #391. The refusal treated a flattened package as an independently authored entry. The assembly model admits the consumer experience and refuses the duplicated source.
One rule of the base is not a criterion here
No relation in the base is created_by: author, because the claim under test is that unassisted human capture decays. A tradition that an entry models may genuinely carry an author-declared edge, so the rule does not transfer. The meta-schema already requires a created_by on every relation from a closed set. What an entry owes beyond that is one sentence of doctrine for each author-created edge, stating why nothing mechanical can propose it. taxonomy audit reports edge counts and staleness by creator, so the bet stays measurable rather than hidden.
What an entry ships
One directory per entry, named for the bundle that it will publish as. Four parts, and three of them have a destination in the published package, so promotion is a move rather than a rewrite. The fourth stays here, and the row below says why.
| Part | Path in the draft | Where it lands when the entry is published |
|---|---|---|
| Schema | bundle.yml |
bundles/<name>/bundle.yml (spec 7) |
| Doctrine | doctrine.md |
the doctrine/ path, vendored to consumers |
| Templates | templates/ |
bundles/<name>/templates/, which a publish reads and carries |
| Fixtures | fixtures/ |
nowhere. A publish reads this directory and leaves it out of the artifact, because no consumer verb opens one. It stays here, as the corpus this publisher measures the bundle against (spec 7) |
bundle.yml is the overlay. It names the bundle, the base version that it was written against, its requires closure, and its add operations. The per-file shape of a bundle is not specified anywhere yet, so a draft adopts this one and says so:
bundle: design-spec
extends: headwater/standard@1.0.0
requires: []
add:
purposes.<name>: {...}
kinds.<name>: {...}
shelves.<name>: {...}
doctrine.md is the prose that a consumer vendors. It states the tradition and cites the prior art of criterion 1. It explains the selection rather than restating the schema. It carries the core declaration of criterion 5, the author-edge sentences above, and every reading that the draft assumed where the specification is silent.
templates/ holds one template per concrete kind that the entry adds. Spec 3 owns what a template contains. An entry with a kind that has no template asks an author to derive a document shape from a schema. A facet-only entry that adds no concrete kind ships this directory absent entirely. That reading matches the convention fixtures/ already carries: no directory ships empty (HW-DR-0079). An entry that extends a base kind it did not add, rather than adding a new one, may ship a template fragment for that kind.
fixtures/ holds the worked corpus of criterion 4, and a fixtures/README.md that states what each document exercises and which findings it should raise. Four programs read one of these pages rather than only describing it, and CI runs each as a blocking step. tools/repo/diataxis-facet-fixtures.sh performs the composition run that the diataxis entry records, and judges the difference that run claims rather than the absolute counts that belong to another entry's corpus. tools/repo/diataxis-fixtures.sh requires the page of the diataxis-site entry, and it parses the source table of that page for the mode map and for the SHA-256 digest of every pinned file. tools/taxonomy/drive_n8n.py reads the fixtures/n8n/README.md page of every entry that carries one, takes the commands out of each, and runs them. tools/repo/decision-record-fixtures.sh reads the fixtures/README.md page of the decision-record entry, for its two source tables and its status map, and runs the digest and byte-identity cases against each vendored corpus the page describes: inspect_evals's 10 ADRs, typed at decision, and Sysl's docs/ideas/root.md, typed at obligation_record. A fifth mechanism opens no bytes and is not a reader: engine/crates/cli/tests/publish.rs asserts that the standards-spec page is a file, which holds that a publish leaves the publisher's own reference corpora where they are. Every other page here is prose in a format that nothing executes, which is a guess about a runner, and each one stays prose until a runner gives it a shape.
What an assembly ships
An assembly draft lives at taxonomy-source/headwater-standard/assemblies/<name>/. It holds assembly.yml, an optional overlay.yml, doctrine.md, and fixtures/. The source package manifest names the directory under contents.assemblies.
assembly.yml names the flattened package, its version, the source package version, the complete bundle selection, and the optional overlay. doctrine.md explains the combination and the coordinated upgrade. fixtures/ measures behavior that crosses the selected entries.
The flattened taxonomy, copied entry doctrine, copied templates, package manifest, and release record are publisher output. They do not live in the assembly draft. A publish reads the draft and the selected entries, proves equivalence, and writes the complete package into its output directory.
Where drafts live, and why here
Drafts live at docs/taxonomies/<name>/, and this file is the index. The decision is recorded here because this file is the one that every entry author reads first.
The alternative was docs/evaluations/, on the argument that a draft is evidence. That argument is spent. Q2, Q3, and Q13 each closed on an evaluation of its own, so no draft is needed to settle a decision now.
An evaluation is a point-in-time record of how a question closed, and it is finished when the question is. A draft taxonomy is neither. It is a deliverable that later releases revise, and it is the engine's fixture corpus the day that there is an engine. A deliverable filed as evidence reads as spent the moment that its decision closes. That is wrong for an artifact which has to stay current.
docs/spec/ is not a candidate. The specification states what Headwater is, and a taxonomy is content that runs on it.
The rulings a draft works under
These are settled elsewhere. An entry works under them and reopens none of them.
The format is Headwater's own dialect, in YAML. Q2 closed it. YAML 1.2 core schema is the concrete syntax, and the schema language, the reference sublanguage, the overlay language, and the meta-schema are Headwater's. JSON Schema is an emitted export and never the validator, because spec 2 already carries references that no JSON Schema keyword resolves.
The loader rules bind a draft now. no stays the string no. Duplicate keys are an error. Anchors, aliases, and merge keys are forbidden in taxonomy sources. The $-reference is the sanctioned reuse mechanism, and an alias is a second one that no overlay can address. Scalar types come from the meta-schema and never from the YAML resolver.
No second projection is required. Q13 put LinkML last of six emitters, shipping only when a named external consumer asks, and it ruled that emitters never chain. Its evidence is already collected in the LinkML worked example. A hand-written LinkML or SHACL projection of an entry buys nothing that those two documents do not already hold.
A draft that uses $-references works under a settled grammar. Spec 2 defines the sublanguage, and engine/crates/ref parses it. An entry writes an address as a dotted path of segments, and it writes a reference with a $ and a root from the closed set. One question stays open, and 13 carries it: what optional holds under the package root. An entry that reads optional package content therefore still records the reading that it assumed, in doctrine.md.
Where a finding goes
9 — The decision register is a register of settled decisions, and it accepts no new questions. A finding from library work goes to 13 — Open obligations, or it reopens a closed decision explicitly and argues the change.
An entry never edits the specification, and the finding is a separate change. The two travel in opposite directions. An entry is content that runs on the specification, and a finding is a claim about the specification. To carry both in one pull request lets a library change rewrite the rules that admitted it.
A finding has a tier, and the tier fixes the timing
1. It contradicts a closed decision. Stop, and reopen that decision explicitly before the entry merges. An entry built on a ruling that its own author believes is wrong carries the error into every entry that follows it.
2. It sharpens a decision, or it names a gap that blocks nothing. It goes to 13, in one change per entry, opened as soon as the entry merges.
3. It records an assumption that the specification does not cover. The same change carries it, grouped under one item. Each one is a place where the meta-schema has to speak eventually.
One change per entry, and never one per epic. A finding held to the end of a program of work is written months after the argument that produced it. Whoever writes it then has to reconstruct that argument first. The long form stays in the entry's doctrine, where the reasoning already sits. 13 carries the pointer, which is the form that its own entries already take.
The epic holds the ledger. Each entry posts its findings to the epic as a comment when it merges, with the tier of each one. That is what makes a review at the end of the epic possible. The review checks that every finding landed, and it is not the mechanism that lands them.
One item there is this library seen from the specification's side. The bundle set waits on a first adopter, because it is a guess about how adopters cluster and it is data in a package. Every entry admitted here is a revision of that guess, and the two must not drift.
Admission, and what is admitted
An entry arrives as a pull request that adds one directory under this one. The reviewer checks the seven criteria above, and the entry is admitted when all seven hold. Criteria 3, 6, and 7 become mechanical the day that the resolver exists. Until then a reviewer reads the address list in bundle.yml against the entries already here.
Each admitted entry adds a line below, with its bundle name and the tradition that it models.
| Entry | Bundle | The tradition |
|---|---|---|
design-spec |
design-spec |
The numbered specification series of IETF RFCs, academic papers, and software design documents |
decision-record |
decision-record |
The architecture-decision-record tradition of Nygard, MADR and the tooling around them |
diataxis |
diataxis |
Procida's four documentation modes, as one facet over the kinds a corpus already has |
diataxis-site |
diataxis-site |
Procida's four documentation modes, as a documentation site's concrete kind set |
standards-spec |
standards-spec |
The internal-standard ladder of MIL-STD-498, ISO/IEC/IEEE 29148 and the functional and technical specification convention |
brd-prd |
brd-prd |
The business-analysis and product-management requirements handoff of IIBA's BABOK Guide, the Pragmatic Marketing Framework and the PRD convention |
The bundle the table does not admit: evidence-and-obligation
One bundle of this library is not an admitted entry, and a composer still has to select it. evidence-and-obligation lives under this directory, publishes inside headwater/standard, and declares kinds.evaluation, shelves.evaluations, purposes.evidence, purposes.obligation and regimes.voice.narrative. HW-DR-0044 moved those addresses out of design-spec, and tools/repo/library-index-fixtures.sh holds this list against the bundle rather than against a reader. Both design-spec and decision-record declare requires: [evidence-and-obligation], and the headwater/starter assembly selects it, so a reader who takes either entry takes this bundle with it. The table above has no row for it, and this paragraph is where a composer finds the name.
Two criteria refuse the row, and neither refusal is a matter of wording. Criterion 1 asks for a named tradition with citable prior art. This bundle models no tradition, and its doctrine cites none. It is a capability split of design-spec rather than a practice that somebody else wrote down. The third column of the table above is headed "The tradition", and there is nothing true to put in that cell. Criterion 4 asks for a worked instance corpus, and the bundle's finding 2 records that it carries none of its own. The design-spec and decision-record fixture corpora exercise evaluation from the two entries that require it.
Criterion 5 is now ruled, and this bundle takes neither reading it admits. Its doctrine states that it serves neither rationale nor behavior, and it names no base declaration for either purpose. HW-DR-0079 admits a full entry that serves neither purpose two ways: it names the base declaration that serves the purpose, or it extends a base kind that already serves it. decision-record and brd-prd each take one of those two ways. This bundle takes neither, and its admission does not turn on the reading either way. Criteria 1 and 4 refuse it independently, regardless of how criterion 5 reads. HW-DR-0044 authorized the split and settled nothing about admission. No ruling admits a row for this bundle, and a reviewer who wrote one would waive criterion 1 rather than read it. Two questions still belong to the owner. The first is whether a capability split may be admitted under a criterion it cannot meet. The second is whether an admitted entry may require a bundle that admission refuses. HW-OBL-0185 holds the second one, with what criterion 7 measures below as its evidence, because a reviewer who follows a question to the issue that raised it arrives at the question again.
Criteria 2, 3, 6 and 7 were each read against this bundle, and this paragraph is the reading. A row asserts all seven and this bundle has no row, so a criterion nobody writes down here is a criterion nobody weighed. Criterion 2 asks for the whole anatomy, and the entry ships bundle.yml, doctrine.md and one template for its one concrete kind. It ships no fixture corpus: its fixtures/ directory holds a README that says so and nothing else, and there is no empty corpus directory beside it, because git carries no empty directory. So criterion 2 falls short on the single fact that criterion 4 refuses the entry for, and finding 2 is the one record of it rather than two. Criterion 3 holds: the file carries one add: list, no override and no remove, and each of the five addresses above is absent from the base taxonomy.yml. Criterion 6 holds: those five addresses are disjoint from every address the other six bundles declare, measured over the add: keys of every bundle.yml under this directory rather than against a list.
Criterion 7 is the one that does not hold inside the entry, and the reading is what the ruling above waits on. The entry declares requires: [] and it resolves from the base alone. Two of the three meta-schema rules named above are green: shelves.evaluations is homogeneous on kinds.evaluation, so the one concrete kind is reachable from a shelf, and the entry declares no relation for an endpoint rule to read. The third fails. The entry declares purposes.evidence and purposes.obligation, and kinds.evaluation is its only kind and serves evidence. Nothing here serves obligation. The kinds that do are obligation_register in design-spec and obligation_record in decision-record, and both of those entries declare requires: [evidence-and-obligation]. So every declared purpose is served over the closure of an entry that requires this one, and over no closure this entry can name. requires: [] is not an omission a later change repairs: requiring either entry back cycles against the edge each already carries, which is the argument the bundle's own header comment makes for the split.
Nothing measures that rule, and a reviewer reads it by hand. Purpose completeness is on the engine's own skipped list, headwater_meta::validate::SKIPPED, because it needs a resolved tree, and no verb runs it after resolution. The resolver checks that a core purpose is served by a concrete kind and it checks no other declared purpose. So the sentence above that criteria 3, 6 and 7 become mechanical the day the resolver exists has arrived for 3 and 6 and has not arrived for this rule of 7.
What each admitted entry measured, and what it cost
The design-spec entry carries six findings against the specification, which its doctrine states in full. Two of them are worth reading before another entry is authored. A bundle extends a list of the base only with add_to, and two bundles that extend one list must declare a dependency between them. And the base's specification kind carries a section contract that a tradition with other headings cannot reuse.
The decision-record entry is what tested criterion 6, and criterion 6 is the one that cost. It serves the obligation purpose and declares nothing at that address, because no entry may declare an address that another entry already holds. So it declares requires: [evidence-and-obligation] for the obligation purpose alone, and it takes every address that bundle declares along with it. HW-DR-0044 prices the alternative. A dependency on the whole of design-spec takes every kind and every shelf that bundle declares, and an ADR-keeping team need use none of them. Two more addresses were closed to the entry in the same way: an endpoint list of concrete kinds, and a kind's list of required facets. Its doctrine states the three as one finding. Shared vocabulary belongs to the base, because an entry is the one place where nothing composes.
The decision-record entry also stopped adding what the base already had. The base declares kinds.decision with Nygard's three sections, so the entry adds no decision kind and writes into the base kind at the keys it leaves absent. That is the operation an add was specified for, and it is the remedy that design-spec's second finding asks for, applied from the other side.
The diataxis entry is a partial entry, and it is what criterion 5's partial-entry paragraph was written for. It declares one facet and attaches it to the base's abstract kind, and it declares no kind, no shelf, no purpose and no relation. So it satisfies no clause of the invariant core, it stands on a base that does, and its doctrine states which declaration of the base supplies each one.
Criterion 2 is now ruled for a partial entry, and diataxis's reading is the one it states. The anatomy asks for one template per concrete kind, and an entry that adds no kind has no kind for a template to shape. HW-DR-0079 admits templates/ absent entirely from a facet-only entry that adds no concrete kind. The diataxis entry ships no templates/ directory, and its own doctrine states this derivation.
The standards-spec entry declares a whole tradition and requires nothing. It adds three kinds, a purpose, a facet, two relations, two shelves and three identifier schemes, and it declares requires: []. Criterion 6 cost decision-record a dependency on a sibling entry for one address. standards-spec met no address that design-spec, decision-record or diataxis holds, because the purpose its standard kind serves is one nobody had claimed. A full entry is therefore not condemned to a dependency. Shared vocabulary in the base is what decides which of the two an entry gets.
A rule of the specification also forced standards-spec into a direction. Reading precedence for the governance family makes the source govern. A conforms_to edge from a specification to the standard that binds it would therefore derive the precedence backwards. The entry spells the edge regulates, from the standard, and its doctrine states the derivation. Its second finding is that the specification's own negative edge, does_not_comply_with, is spelled the other way inside the same family.
The standards-spec entry measured something no reading of the schema shows. Its fixture corpus plants a discriminator value that its heterogeneous shelf does not admit. Kind resolution stops, the census carries the row, and no rule instantiates over the document. A run holding that document alone reports 0 findings and a strict run exits 0. That is a property of every heterogeneous shelf in this library, and the fixture README holds the run.
The diataxis entry also measured a wall that was recorded as wider than it is. #6 concluded that a facet-only entry has to reach kinds.<k>.facets.require on another entry's kinds, and therefore that it waits on HW-OBL-0040. The relevance canon that the conclusion rests on reads require and optional together. So an optional listing on the base's abstract kind satisfies it, and the entry writes into no other entry. HW-DR-0095 (Q67) later discharged HW-OBL-0040. A bundle that names design-spec in requires can now require the facet on a design-spec kind with add_to, and case group 8 runs that. The diataxis entry still declines it, so that it stays usable without design-spec.
The brd-prd entry is a full entry that serves neither core purpose. It is also the entry that says criterion 5 has no reading for that. It adds two kinds, a purpose, a voice regime, a facet, a relation, a shelf and two identifier schemes. Every clause of the core is satisfied by the base. Criterion 5 asks an entry to name which of its kinds serve rationale and behavior, and none of this entry's kinds serves either. decision-record stands in the same position and says so plainly, without naming a gap. Its doctrine records that rationale comes from the base decision, and that it declares no behavior-serving kind. So decision-record and brd-prd read the criterion the same way. The brd-prd doctrine states the reading and asks for a ruling on the wording, which is what diataxis did to criterion 2. The refusal is the other half. The issue that asked for the entry offered a dependency on standards-spec. That would let a corpus hold the whole pipeline from a business need to a technical specification. The edge that pipeline needs reaches into another entry's endpoint list. HW-DR-0095 permits that write only from an entry that names the other in requires. So the edge buys a dependency on the whole of a sibling entry. decision-record paid that cost for one address. So decision-record records what a dependency costs and brd-prd records what refusing one costs.
The brd-prd entry declares a voice regime that the base refuses to supply. The base carries voice.declarative, which forbids future_intent. A requirements document states what a product must do before it exists, so the base's regime reports the tradition itself. The entry declares regimes.voice.prospective, which keeps the other two categories, on the precedent that regimes.voice.narrative set. A probe measured the difference rather than asserting it. With declarative bound instead, the same seven fixture documents raise four more findings, in four of them, and the fixture README holds the run.
The diataxis-site entry gives a documentation-site consumer four concrete kinds, and criteria 3, 6 and 7 all read green on it. Criterion 3: the bundle carries one operation, add, and no override and no remove. Criterion 6: its thirteen addresses are disjoint from every other entry of this library, and tools/repo/diataxis-fixtures.sh measures that against the six of them rather than against a list. Criterion 7: it declares requires: [], it resolves in isolation, and its four concrete kinds, four shelves and one purpose satisfy the three meta-schema rules named above — every kind is reachable from a shelf, the purpose it adds is served by its tutorial and how_to kinds, and the entry declares no relation for an endpoint rule to read.
The four collisions its fixture records are with an adopter overlay, and criterion 6 does not read them. This repository's own overlay writes purposes.procedure, identifier_schemes.tutorial_id, kinds.tutorial and shelves.tutorials, so this corpus cannot select this bundle. Criterion 6 binds an entry against the entries already admitted, and the paragraph below on adopters is why: the seven criteria bind no adopter overlay. A consumer selecting this bundle takes those four declarations from the entry instead of declaring them locally, and a consumer that has already declared them locally selects something else.
Criterion 4 is what this entry was held open for, and the recorded run is what settles it. Its fixture README used to say that the entry could not be admitted until a runner recorded its denominators, while the table above already carried its row. The runner exists, the denominators are recorded, and the row stands: four external documents from two projects, each typed at the kind its shelf gives, with 47 findings of which 16 are errors. The criterion asks for a corpus "recorded with its source, revision, paths, and run" and it does not ask for a clean run, which is the reading evidence-and-obligation above is refused under — that bundle carries no corpus of its own at all, and this one carries a corpus that reports against its own entry. What the run reports is finding 1 of the doctrine: 11 of the 16 errors are missing section headings, and Diátaxis constrains a reader's purpose rather than a writer's headings.
Criterion 1 separates the entries from two candidates that do not model their proposed traditions. The operational runbook of the site-reliability tradition is citable and old enough to pass criterion 1 on its own. A corpus of agent skills or setup guides is not made of runbooks. The work-instruction rung of the ISO 9001 document hierarchy would be an addition to standards-spec rather than an entry, and that entry cites neither ISO 9001 nor an operational method. Criterion 4 refuses the second and the third on one ground. A corpus typed against a tradition it does not belong to files every document and describes none of them.
An adopter waits for none of this, and that is the part worth stating plainly. The seven criteria above bind an entry of this library. They bind no adopter overlay, which answers to no confluence check against a bundle that the consumer declaration does not select. This repository declares its own task-oriented purpose, tutorial kind, and tutorial shelf for that reason, and the same route carried probe, interface_contract, requirement, and acceptance_criterion before an entry existed for any of them. The n8n review-rules fixture is the worked instance of it. Two operations in an adopter overlay, a shelf at the path that corpus already uses, and seven real documents typed with no change to any entry. A corpus of stepwise guides is typable today by an overlay that declares its purpose and kind. The library now supplies the Diátaxis documentation-site tradition for an adopter that wants that entry.
The candidate backlog, and what became of it
HW-OBL-0018 calls the bundle set "a guess about how adopters cluster," data in a package that the first real adopter revises at the cost of a release. This subsection is that guess, written down where a future request is a small edit rather than a comment on a closed issue. #7 held the list first, under a milestone that has since closed with the list still a parking lot; folding the list in here is what gave that issue a close condition.
Candidates. Each row names its stress-test, the check that would exercise the tradition hardest, and its disqualifier, the reason it is not an entry yet.
- Operations — runbooks, playbooks, postmortems; the SRE tradition, with the Google SRE book as prior art. Stress-test: freshness obligations, because a stale runbook is worse than none, and blameless-postmortem voice regimes. Disqualifier: freshness is already a required facet role in the base core, so this candidate tests a mechanism the library already has rather than proposing a new one.
- Proposal process — the PEP / IETF Internet-Draft / Rust RFC tradition: a proposal corpus with a state machine, sponsors, and disposition records. Stress-test: the boundary with
design-specanddecision-record, which overlap it. Disqualifier: many proposal corpora read as the Context / Decision / Rationale shape thatdecision-recordalready expects. So the doctrine has to say where the boundary sits, or argue that one entry subsumes the other. Until then this candidate is a restatement rather than a corpus. - Compliance and evidence — the audit-trail tradition: controls, attestations, evidence with collection dates. Stress-test: the evidence register (spec 4) harder than anything admitted so far, and Q15's warrant that an
asserteddocument does not discharge an evidence obligation. Disqualifier:evidence-and-obligation, admitted under HW-DR-0044, already carries theevidenceandobligationpurposes, so this candidate is designed on top of that bundle rather than beside it. - Policy and governance — values statements, registers, decision logs; a corpus shape the specification records Diátaxis distorts. Stress-test: the least prior art of any row here as a named tradition. Disqualifier: it may fail criterion 1 outright and belong as doctrine within another package instead.
- Requirements — IEEE 29148 / EARS-style requirement statements with verification links. Q19 closed the inbound path already, so what a bundle would still add is the requirement kinds, the EARS statement-form doctrine, and the verification relation. Disqualifier, carried here exactly as
.headwater/overlay.ymlrecords it: this repository's own overlay declaresrequirement,acceptance_criterionandverified_byrather than the library, because criterion 6 refuses the addresses a library entry would want — thebrd-prdentry already holdspurposes.requirement,shelves.requirementsatdocs/requirements/**, and a siblingshelves.acceptance_criteria, andbrd-prddeclares that shelf heterogeneous over[brd, prd]with arequirement_tierdiscriminator where this repository's own shelf is homogeneous over one kind, so the two shapes cannot merge. A promotion of this row renames all three addresses, or proposes that this candidate andbrd-prdbecome one entry that rules on the tier question first. Admit only with a worked instance corpus somebody wants. - Procedure — the step-by-step kind that a separate ruling in this milestone was asked to settle, which the n8n
.agents/skills/tradition, a codelab corpus, and a tutorial corpus all need. Listed here so that ruling's outcome has a row to land in.
Not candidates.
- Wiki or notes — no tradition to model, and an untyped shelf is what the surrounding system already tolerates as a starting state. Q12 closed on the stronger version of that argument: adoption is a migration from no taxonomy, and
headwater infercomputes the debt. An untyped shelf is the state a corpus arrives in, not a shape to publish.
How a row moves. A candidate is promoted by a pull request that adds an entry under this directory against the seven criteria above, filed from an issue that names the row, cites the prior art criterion 1 asks for, and names the worked corpus criterion 4 asks for. A request from an adopter, or a new candidate anyone notices, is a pull request that adds a row to this subsection instead, and the review of that pull request is the whole admission of the row. A row that is promoted, or that fails, is not deleted: it moves to the list below with the issue number, so this subsection stays the record HW-OBL-0018 says the first adopter revises.
What became of the list so far. Two candidates arrived by a different route: standards-spec (#359, merged as #376) and brd-prd (#360, merged as #379) were promoted straight to issues on 2026-08-24 rather than parked on this list first, on the review comment that named their prior art: MIL-STD-498's SSS/SRS/SDD ladder, ISO/IEC/IEEE 29148's BRS→StRS→SyRS→SRS family, and Joel Spolsky's "Painless Functional Specifications" convention for standards-spec; IIBA's BABOK classification schema and the Pragmatic Marketing Framework's MRD→PRD lineage for brd-prd. brd-prd is what the Requirements row above collided with.