Skip to content

test: name every enforced behaviour in a ledger, and the test that proves it - #71

Merged
ExtraToast merged 2 commits into
mainfrom
test/67-behaviour-ledger
Sep 14, 2026
Merged

ExtraToast merged 2 commits into
mainfrom
test/67-behaviour-ledger

Conversation

@ExtraToast

Copy link
Copy Markdown
Contributor

Closes #67 (parent #21)

What this branch does

docs/requirements.md names every behaviour this repository guarantees, and for each one the test that fails when it stops being true. Ten rows, REQ-001 to REQ-010: the ADR contract, the link contract, the manifest gate, the boundary gate, the pull request title check, the em-dash ban, the test harness guards, the coverage ratchet's integrity, the package-contents gate, and the script-to-workflow wiring check.

A behaviour could previously lose its proof without anything saying so. The coverage ratchet notices a line that stops running, but not a test file renamed, emptied or deleted while the code it covered stayed in place, and nothing tied a sentence in the documentation to the test that makes it true.

  • scripts/lint-requirements.ts holds the ledger honest: every row parses, every named file exists and holds at least one test, ids are unique, the stated row count matches the rows, and every id cited anywhere in the tree resolves to a row. Library first, with a one-line CLI guard, the shape the other gates use.
  • Each proving test carries a comment citing its id, so an id resolves from the test as well as from the ledger.
  • The gate runs in the Contracts job beside the ADR, link and manifest contracts, and in npm run verify. It is a document contract of the same kind as its neighbours, not a code-against-graph check like boundaries. ADR 0102 asks for the script and its job in one pull request, and test/pipeline-wiring.test.ts is what would otherwise have failed.
  • This is the companion of the rule ledger in Give every enforced rule an ID, a ledger row and a fixture that proves it fires #29 and deliberately not the same thing: that one lists the rules a tool enforces, this one lists the behaviours a person depends on. The document says so in its opening paragraph.

Decisions

docs/adr/architecture/0103-a-behaviour-ledger-names-what-a-test-proves.md, citing 0102 for the wiring rule.

Two branches came out of scripts/lint-requirements.ts rather than being covered by a contrived test: a ?? "" fallback on a key that comes from the same object being iterated, and an id-shape check already guaranteed by the row pattern, whose capture group is REQ-\d{3}. Neither could fire.

The ratchet rises: statements 97.17 to 97.5, branches 87.5 to 88.79, functions 100, lines 96.88 to 97.26.

Verification

Each acceptance criterion was broken on the rebased tree and restored, not just run:

  • Renaming test/adr-contract.test.ts: REQ-001: names 'test/adr-contract.test.ts', which does not exist
  • Emptying test/link-contract.test.ts: REQ-002: 'test/link-contract.test.ts' holds no test
  • Citing an unknown id: test/link-contract.test.ts cites REQ-999, which no row carries
  • Stating nine rows while holding ten: docs/requirements.md: states 9 rows, holds 10

npm run verify clean, 189 tests. actionlint 1.7.7, the version CI pins, clean.

Follow-up

The coverage numbers in README.md now lag these thresholds. #69 owns that file and holds it to the configuration with a test, so the refresh lands there.

…oves it

Adds docs/requirements.md, one row per behaviour this repository enforces
today (the ADR, link, manifest and boundary gates, the PR title check, the
em-dash ban, the test harness guards and the coverage ratchet), each citing
the test file that proves it. scripts/lint-requirements.ts is the meta test
that holds the ledger honest: every row parses, every named file exists, is
a test file and holds a test, ids are unique, the stated row count matches,
and every id cited anywhere in the tracked tree resolves to a row.

Records the decision as docs/adr/architecture/0103, next free number after
0102 (reserved on another in-flight branch), and adds its register row.
REQ-009 and REQ-010 cover the package-contents gate and the pipeline-wiring
test that issue #23 brought; lint:requirements now runs in the Contracts
job and in npm run verify; ADR 0103 cites the now-landed ADR 0102; coverage
thresholds are raised to what the suite reaches with the new gate covered.
@ExtraToast ExtraToast added type: test Test coverage, fixtures, or validation changes. area: tooling Reusable workflows, Gradle, templates, Renovate, and API tooling. component: tests Unit, integration, system, or contract test concern. labels Sep 14, 2026
@ExtraToast
ExtraToast merged commit 6c5c2bc into main Sep 14, 2026
16 checks passed
@ExtraToast
ExtraToast deleted the test/67-behaviour-ledger branch September 14, 2026 07:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: tooling Reusable workflows, Gradle, templates, Renovate, and API tooling. component: tests Unit, integration, system, or contract test concern. type: test Test coverage, fixtures, or validation changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Name every behaviour in a ledger, and the test that proves it

1 participant