Skip to content

docs(harness): record the fixture-vacuity case in the anti-vacuous doctrine - #292

Merged
beyondnetPeru merged 1 commit into
mainfrom
docs/anti-vacuous-fixture-doctrine
Jul 30, 2026
Merged

docs(harness): record the fixture-vacuity case in the anti-vacuous doctrine#292
beyondnetPeru merged 1 commit into
mainfrom
docs/anti-vacuous-fixture-doctrine

Conversation

@beyondnetPeru

Copy link
Copy Markdown
Contributor

Pull Request Summary

coverage.mjs states the rule for guards: zero scanned is a failure, because a check that scanned nothing did not run. Nothing stated it for the guard's test, and the failure has the same shape one level up — a test whose fixture never reaches the branch under test passes, and reads as proof.

25 lines of doctrine, no behaviour change.

The case it records

Observed 2026-07-30 (GT-633) while fixing two parser defects in 41-validate-evidence-commands. Six tests were written for the fix. Three of them passed against the unfixed parser too — they asserted that a command is not reported dead, and the branch that reports it dead is guarded by pkg?.scripts, while the fixture's root package.json declared no scripts at all. The assertions were true, the fix was real, and those tests proved nothing about it.

The rule, now written next to its sibling:

When a test is written to pin a fix, run it against the unfixed code and watch it fail. A test that passes before the fix is the vacuous pass this file already describes, wearing a green tick from the test runner instead of from a guard.

And the half that usually gets skipped

Making the fixture live took those six from 3-of-6 red to 5-of-6 red against the old parser. The sixth passes either way — it is kept and labelled a regression guard, not counted as proof. When a test cannot be made to fail, say so in the test rather than letting the count imply coverage it does not have.

Why here and not on the board

GT-633 is already registered on main (c3221276) and this lesson is not really about that gap — it is doctrine for whoever writes the next guard. A gap row is read once; this file is read by everyone who reaches for assertScanned.

Verification

  • coverage.test.mjs12/12
  • module still loads and exports ZeroCoverageError, assertScanned, assertScannedPerSource, scanned
  • 42-validate-guard-denominators.mjs — green over 60 guards
  • 01-validate-docs.mjs — green, 1491 files

Evolith Core Quality Gates

  • Bilingual Parity: no .md touched — the change is a comment block in a .mjs module.
  • Validation Scripts: 01-validate-docs.mjs run and green.
  • Bilingual Validation: n/a for this change.
  • Agnosticism: documentation only; no dependency introduced.

Linked ADRs / Issues

  • Link to ADR: n/a
  • Link to Issue: extends GT-557's anti-vacuous rule, enforced by GT-578; the case comes from GT-633.

Conventional Commits

  • docs:

🤖 Generated with Claude Code

…ctrine

`coverage.mjs` states the rule for guards: zero scanned is a failure, because a
check that scanned nothing did not run. Nothing states it for the guard's TEST,
and the failure has the same shape one level up — a test whose fixture never
reaches the branch under test passes, and reads as proof.

Observed on 2026-07-30 (GT-633) while fixing two parser defects in
`41-validate-evidence-commands`. Six tests were written for the fix; three of
them asserted that a command is NOT reported dead, and passed against the
UNFIXED parser too, because the branch that reports it dead is guarded by
`pkg?.scripts` and the fixture's root package.json declared no `scripts`. The
assertions were true, the fix was real, and those tests proved nothing about it.

The rule now written down next to its sibling: when a test is written to pin a
fix, RUN IT AGAINST THE UNFIXED CODE AND WATCH IT FAIL. A test that passes before
the fix is the vacuous pass this file already describes, wearing a green tick
from the test runner instead of from a guard.

Its other half is recorded too, because it is the part that gets skipped: making
the fixture live took those six from 3-of-6 red to 5-of-6 red, and the sixth
passes either way. That one is kept and LABELLED a regression guard rather than
counted as proof — when a test cannot be made to fail, say so in the test instead
of letting the count imply coverage it does not have.

This is doctrine for whoever writes the next guard, which is why it lives here
rather than in the GT-633 board entry: a gap row is read once, this file is read
by everyone who reaches for `assertScanned`.

Verified: coverage.test.mjs 12/12; the module still loads and exports
ZeroCoverageError, assertScanned, assertScannedPerSource, scanned;
42-validate-guard-denominators green over 60 guards; 01-validate-docs green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@beyondnetPeru
beyondnetPeru requested a review from a team as a code owner July 30, 2026 14:00
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions

Copy link
Copy Markdown

📊 Bilingual Coverage Impact

PR Changes

  • Paired EN/ES files modified: 0
  • New EN files needing ES translation: 0

Repository Coverage

Metric Value
Total EN files 524
Total ES files 498
Paired files 0
Coverage 0%

Good: All EN changes have ES counterparts.


Generated by GitHub Actions

@beyondnetPeru
beyondnetPeru merged commit ad09d71 into main Jul 30, 2026
31 of 34 checks passed
@beyondnetPeru
beyondnetPeru deleted the docs/anti-vacuous-fixture-doctrine branch July 30, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant