Documentation Standard

Public design docs are human-reviewable contract context. They must make their maturity explicit so agents, reviewers, and signoff gates can distinguish accepted behavior from work in progress.

Design Doc Status Marker

Every HTML file under docs/design must declare data-doc-status on either the root body, main, or another top-level container. Pages should also show the same status in visible text near the title when the status is draft or proposal.

<main data-doc-status="draft" data-doc-stage="proposal" data-doc-domain="pcb">

Status Vocabulary

Status Meaning Release posture
draft Exploratory direction. Implementation may be absent or partial. Allowed, but release signoff must not treat it as accepted contract evidence.
proposal Ready for focused implementation review, but not yet accepted. Allowed, but release signoff must review the open decision explicitly.
accepted Aligned with code, tests, contracts, and any required ADR. May be used as accepted standard or contract evidence.
superseded Retained for history after a newer doc or ADR replaced it. Must link to the replacement before release.

Signoff Behavior

dev-std audit fails when HTML design docs are unmarked or use a status outside the approved vocabulary. It passes but reports draft and proposal pages so L99 signoff can decide whether those pages are acceptable for the release being prepared.

Repositories may add stricter local gates. A package with a public API, serialized contract, or release note that depends on an unfinished design should fail release signoff until the relevant document is promoted to accepted or a clear release exception is recorded.

Plan closeout requires an explicit governance-document intent audit. Agents must review required design docs, ADRs, and requirements against the user's stated intent, the implemented behavior, public contracts, and tests. A data-doc-status="accepted" marker is necessary but not sufficient when the implementation changed during the plan.

Plan And Log Metadata

Active plans and attached work logs use Markdown files with TOML front matter. The minimum plan fields are type, id, status, created, at least one [[steps]] entry, and at least one [[exit_criteria]] entry. The minimum log fields are type, id, plan_id, step_id, and created. Plan documents use type = "plan" and work logs use type = "plan_log". Plans may declare depends_on when one plan must finish before another can proceed.

Markdown filenames with a standalone log token, such as v1_1_log.md, are treated as log-like by the docs audit. Keep them as compliant plan_log files only while they support an active plan. After closeout, delete them or distill useful material into durable history, research, design, requirement, ADR, release, or source documentation.

+++
type = "plan"
id = "pcb-a0-alignment"
status = "active"
created = "2026-06-27"

[[steps]]
id = "work"
title = "Execute plan work"
status = "pending"

[[steps]]
id = "design-doc-intent-audit"
title = "Audit design docs, ADRs, and requirements against implementation"
status = "pending"
depends_on = ["work"]

[[steps]]
id = "external-review"
title = "Obtain independent external review"
status = "pending"
depends_on = ["work", "design-doc-intent-audit", "test-runtime-impact-audit"]

[[steps]]
id = "test-runtime-impact-audit"
title = "Audit new test runtime impact"
status = "pending"
depends_on = ["work"]

[[exit_criteria]]
id = "signoff"
title = "Focused signoff passes"
status = "pending"

[[exit_criteria]]
id = "design-doc-intent-audit"
title = "Design docs, ADRs, and requirements match implementation"
status = "pending"

[[exit_criteria]]
id = "test-runtime-impact-audit"
title = "New tests are listed and runtime impact is reviewed"
status = "pending"

[[exit_criteria]]
id = "external-review"
title = "Independent external review is complete"
status = "pending"
+++

Plan status values are active, pending, and blocked. Completed plans are closed out into durable artifacts and removed from active plan roots rather than left with a complete status. The audit treats attempted closeout statuses such as done, closed, complete, and finished as failures with closeout-process guidance.

Closeout is a process, not a state. Before removing an active plan, agents must finish or intentionally block the work, update durable artifacts such as design docs, ADRs, requirements, release notes, and tests, mark the required closeout criteria as met, obtain the required external review, and rerun dev-std audit . --scope docs.plans. The test-runtime-impact-audit closeout step must list new or changed tests, review docs/test-strategy.html, record observed runtime impact where available, and document reasonable optimization or slower-lane splitting decisions for long-running tests. After the durable artifacts carry the useful history, the temporary plan and attached logs should be deleted from the active plan root.

Plans must declare [[steps]] metadata with id, title, status, and optional depends_on. Structured steps are the canonical current state for active plan work, and logs must reference a step with step_id. The dev-std plan and dev-std log commands can create, read, and update canonical plan, step, and log files when the active plan catalog is already compliant. log create accepts --body for short one-line notes and --body-file for longer Markdown so shell command-line length, newline, and quoting limits do not shape the log content.

Active/pending/blocked plans must include design-doc-intent-audit, test-runtime-impact-audit, and external-review as both step ids and exit-criterion ids. The design-doc-intent-audit id is the required closeout hook for checking design docs, ADRs, and requirements against the completed implementation. The test-runtime-impact-audit id is the required closeout hook for checking new tests against the test strategy and runtime-budget expectations. The matching ids make the work item and closeout condition traceable.

Exit criteria are the canonical answer to "are we done?" Each [[exit_criteria]] entry has an id, title, and status. Valid statuses are pending, met, and blocked. The docs-plan audit fails active plans without exit criteria and reports plans whose criteria are all met while the plan still remains active.

ADR Metadata

Architecture decision records are durable decision artifacts. They use Markdown files with TOML front matter and type = "adr". ADR ids are domain scoped: core-adr-0001, pcb-adr-0007, or another <domain>-adr-<n> form. The filename must start with the ADR id, and the document should live under docs/<domain>/adr/.

+++
type = "adr"
id = "core-adr-0001"
domain = "core"
status = "accepted"
title = "Record Durable Decisions"
created = "2026-07-02"
design_refs = ["docs/core/design/index.html"]
+++

ADR status values are proposed, accepted, deprecated, and superseded. Accepted ADRs should describe the standing decision and its stable context. They must not carry active plan closeout language, open-question sections, or release-specific cleanup instructions that belong in a plan or issue. The docs.adrs audit fails when no ADR inventory exists, and dev-std adr create can create a canonical starting document.

Requirement Metadata

Requirements are durable obligations that should be testable or explicitly tracked as unverified. They use Markdown files with TOML front matter and type = "requirement". Requirement ids are domain scoped: transforms-req-0001, alx-req-0004, or another <domain>-req-<n> form. The filename must start with the requirement id, and the document should live under docs/<domain>/requirements/.

+++
type = "requirement"
id = "transforms-req-0001"
domain = "transforms"
status = "active"
title = "Static Transform Mapping Documentation"
created = "2026-07-02"
adr_refs = ["transforms-adr-0001"]

[[verification_refs]]
kind = "local_pytest"
target = "tests/test_transform_docs.py::test_docs_exist"
+++

Requirement status values are draft, active, implemented, deprecated, and superseded. Active and implemented requirements must either define structured [[verification_refs]] entries or explicitly declare verification_status = "unverified" with an issue ref that tracks the missing verification. The docs.requirements audit validates those verification refs directly: local verification targets must stay inside the audited repo root and must resolve, while external refs must name their owning repository. The docs.requirements audit fails when no requirement inventory exists, and dev-std requirement create can create a canonical draft requirement.

Traceability Refs

ADRs, requirements, and plans may carry typed traceability metadata. Simple relations use string arrays such as issue_refs, plan_refs, adr_refs, requirement_refs, design_refs, and schema_refs. Local path refs must resolve. External issue refs should use owner/repo#number.

Implementation and verification refs use arrays of tables so they can describe local files, local pytest selectors, or external test/source ownership in another repository or language.

[[verification_refs]]
kind = "external_cpp_test"
repo = "owner/example-repo"
target = "tests/cpp/test_format.cpp::FormatBehavior"

[[implementation_refs]]
kind = "external_source"
repo = "owner/example-repo"
target = "src/cpp/example/format.hpp:FormatBehavior"

Generated Governance Pages

TOML-front-matter Markdown remains the source format for ADRs and requirements because it is easy to diff and merge. Repositories may generate HTML browse pages from that source. Generated governance pages should carry data-dev-std-gov-type, data-dev-std-gov-id, and data-dev-std-gov-source attributes so audits can connect the browse page back to the source document.

Human-facing HTML design docs should link to generated governance pages when those pages exist, not to raw ADR or requirement Markdown source. This keeps review paths stable while preserving Markdown as the merge-friendly source of truth.

dev-std governance html --output <dir> generates an index plus per-record pages for compliant plans, logs, ADRs, and requirements. Generated pages include data-dev-std-gov-type, data-dev-std-gov-id, data-dev-std-gov-source, data-dev-std-gov-status, and data-dev-std-gov-domain where the source metadata provides the value. The command accepts repeated --css arguments so consumers can inject project-specific styles without editing generated files.

Generated governance pages cross-link known local metadata refs such as ADR ids, requirement ids, and plan ids to their generated HTML pages. Local file refs under docs/, src/, and tests/ are linked when the target exists. Raw Markdown remains the source of truth; generated HTML is a review and navigation artifact.

dev-std owns governance link resolution. Downstream projects should not need to hardcode relative links to generated ADR, requirement, plan, or log pages inside hand-authored docs. A repo may author stable hooks such as data-dev-std-gov-ref="core-adr-0001" or an equivalent configured marker; dev-std governance resolve builds the id-to-generated-page map from the governance catalogs and the configured generated-output root.

Downstream repositories own only configuration and presentation: source roots, generated governance output location, optional static-site URL base, and CSS hooks. The catalog scan, id lookup, relative href computation, stale raw-Markdown detection, and missing-id failure policy belong in dev-std so the same behavior works for downstream packages and future package templates.

[governance.html]
output = "docs/generated/governance"

The resolver validates every data-dev-std-gov-ref hook against the generated governance id map. In write mode it updates anchor href attributes, and for non-anchor elements it writes data-dev-std-gov-href. The docs.links audit uses the same resolver in check mode and fails missing ids, missing generated hrefs, and stale relative hrefs.

The generator renders the supported Markdown body subset into semantic HTML rather than a literal preformatted block. Headings, paragraphs, strong text, inline code, links, unordered lists, fenced code blocks, and simple pipe tables receive stable dev-std-gov-* classes such as dev-std-gov-h, dev-std-gov-p, dev-std-gov-strong, and dev-std-gov-table so projects can override presentation with their own CSS.

Generated governance pages include a default governance.css copied into the output root. Its visual language follows the standard governance documentation baseline: monospace typography, quiet gray paper surfaces, dark section bars, square corners, and table-first scanability. Projects can still pass repeated --css values to layer additional styles after the default stylesheet.

The page structure is intentionally stable for styling and future behavior: main#dev-std-gov-page, section#dev-std-gov-meta, and section#dev-std-gov-body wrap the main regions. Metadata rows render id and status first when present, then the remaining keys in stable order. Rows carry data-dev-std-gov-field plus field-specific and typed value classes such as dev-std-gov-meta-row-status, dev-std-gov-meta-val-id, dev-std-gov-meta-val-string, and dev-std-gov-status-active. This makes CSS-only customization and later collapsible behavior possible without changing the source Markdown contract.

Generated plan pages include a section#dev-std-gov-plan-steps region when a plan declares structured [[steps]]. Each step is rendered with a stable data-dev-std-gov-step-id hook and a collapsible <details> block containing logs whose metadata links them to that step. This gives reviewers a step-centered view of work history while preserving each log as its own generated page.

Typed table metadata such as verification_refs, implementation_refs, and exception refs renders as dev-std-gov-evidence-table content instead of opaque raw strings. Targets and known ids are linked when the generator can resolve them, giving reviewers a browseable path from requirement or ADR evidence to tests, implementation files, and related governance records.

Domain Registry

Packages declare a domain registry at docs/governance/domain_registry.toml. The registry is inclusion-first: [domain_governance].owned_roots identifies the project roots whose files must be associated with a domain, and ignore removes generated, vendor, transient, or build-output paths from ownership checks.

[domain_governance]
owned_roots = ["src", "tests", "docs"]
ignore = ["docs/generated/**"]

[[domains]]
id = "core"
title = "Core"
status = "active"
purpose = "Own core source, tests, and governance."
html = "docs/domains/core.html"

[[file_groups]]
primary_domain = "core"
supporting_domains = ["api"]
paths = ["src/core/**", "tests/core/**", "docs/core/**"]

Source layout is not required to be domain-first. File groups connect paths to one primary domain plus optional supporting domains. Language and classification metadata may be added by projects but are not strict enumerations in the initial registry contract. Each registered domain must have a browseable HTML page with data-domain, data-domain-status, and a visible reference to the registry source. The docs.domains audit fails when no domain registry exists.

Governed Surface Manifest

Packages may declare governed surfaces at docs/governance/governed_surfaces.toml. A governed surface is a public API, CLI command, workflow, transform, serializer, schema, WASM endpoint, importer/exporter behavior, or other contract surface that must be verified or explicitly excepted. The manifest is committed source text; generated SQLite, JSON, or HTML reports may be derived from it but are not the reviewed source of truth.

[[surfaces]]
id = "core.api.list_core"
domain = "core"
kind = "public_function"
status = "active"
purpose = "List core records."
implementation_refs = ["src/core/api.py#list_core"]

[[surfaces.verification_refs]]
kind = "local_pytest"
target = "tests/test_core.py::test_core"
coverage_mode = "regression"
rationale = "Covers the public surface."

[[surfaces.fixture_refs]]
kind = "fixture_file"
target = "tests/fixtures/core.json"
coverage_mode = "regression"
rationale = "Exercises a stable fixture."

[fixture_governance]
discovery_roots = ["tests/fixtures"]
ignore = ["tests/fixtures/archive/**"]

[[fixtures]]
id = "fixture.core"
kind = "json"
path = "tests/fixtures/core.json"
status = "active"
purpose = "Core API fixture."

[[exceptions]]
id = "core.api.native.deferred"
surface_ref = "core.api.native"
status = "deferred"
rationale = "Tracked until the native lane exists."
issue_refs = ["wavenumber-eng/example#12"]

[[parity_relationships]]
id = "core.api.py_cpp"
source_surface_ref = "core.py.list_core"
target_surface_ref = "core.cpp.list_core"
mode = "semantic_parity"
fixture_coverage = "equal"
status = "active"
rationale = "Python and C++ APIs should cover the same behavior."

Active and implemented surfaces must declare [[surfaces.verification_refs]] or have a matching [[exceptions]] entry. Verification refs and fixture refs must include kind, target, coverage_mode, and rationale. Local refs must resolve. External refs must identify their owning repository. Exceptions with deferred or missing-capability status must include issue refs.

Optional [[parity_relationships]] entries connect two governed surfaces across implementation lanes or runtimes. They must name source and target surface refs, a parity mode, a fixture_coverage relationship, status, and rationale. Accepted divergence in either parity behavior or fixture coverage must point to an exception or issue so reviewers can distinguish intentional differences from missing test coverage.

Optional [fixture_governance] and [[fixtures]] sections let a repository distinguish registered fixtures, physically discovered fixture files, logical case ids, synthetic vectors, oracle artifacts, fixture sets, ignored/generated/archived data, missing backing files, and unused active fixtures. When a fixture catalog is present, surface fixture refs must target a registered fixture id or registered path. Active physical fixtures must have backing files and be referenced by at least one governed surface. Logical fixtures such as fixture_case, synthetic_vector, oracle_artifact, fixture_set, and rack_evidence are registered by id and purpose; they do not need a local file path unless the project chooses to attach one. Archived and ignored fixtures document provenance but do not need to be used by active verification.

Rack Evidence Interface

dev-std owns committed governance contracts. wn-rack owns runtime test execution evidence. Projects may later connect the two through generated Rack evidence artifacts, but those artifacts are derivative reports rather than the authored source of truth.

A Rack evidence export should identify the test id, runtime or implementation lane, concerns, case id, fixture/data ids used, artifacts produced, result status, run id, timestamp, and whether each relationship was declared, statically inferred, or runtime observed. Initial dev-std audits validate committed refs and manifests without requiring Rack runtime evidence. Future strict modes may compare declared verification and fixture refs against Rack evidence from the same signoff run.

Bootstrap Files

New packages should use dev-std.toml as the package marker. Existing packages may keep legacy wn-dev-std.toml until they migrate. Governance adoption can begin with narrow scopes and add files as each ratchet becomes useful: plan roots for temporary execution work, domain registry for ownership coverage, governed-surface manifests for API/workflow verification, ADRs for decisions, requirements for durable obligations, and generated or hand-authored domain HTML for browseable context.

The intended signoff integration is a plain audit invocation from the package root. Repositories should prefer a generic command such as dev-std audit . --scope docs.plans --scope docs.adrs --scope docs.requirements --scope docs.domains --scope docs.build --scope docs.test_strategy --scope docs.surfaces --scope docs.traceability --scope docs.links --scope tests over local bespoke scanners unless they need stricter project-specific policy. Packages with committed artifacts, vendored source, or configured release channels should also add docs.artifacts, docs.vendors, and docs.release.