Skip to content

v0.7.1 — close the coverage gap, and a full documentation audit

Latest

Choose a tag to compare

@skymanbp skymanbp released this 17 Aug 01:54
· 1 commit to main since this release

Two things v0.7.0 left open.

Coverage: the checks had no tests

A trace showed 17 of validate_plugin.py's 35 functions were never entered by any testmain(), check_manifests, check_crossrefs, check_i18n, and every cross-file sub-check among them. All of them could have been reduced to no-ops with CI still printing OK. The shipped repository passing is evidence that the repository is clean, not that a check works.

tools/tests/test_checks.py now runs all seven check groups against a synthetic repository and mutates it once per rule — 7 clean + 40 rejection cases, each rejection pinning its expected diagnostic so an unrelated failure cannot green a dead check. Coverage is 35/35. It runs in CI as a fifth step.

Writing it found three defects the shipped repository could not surface:

  • Deleting every command wrapper passed the wrapper-parity check. check_commands returned early on not files, so N=0 — the most complete way to violate the rule — was the one case that passed.
  • _check_command_flags ignored its argument. Written def f(repo: Path = REPO), the module global was captured at def time, so the check always scanned the real repository. That is also why it was the one cross-ref sub-check that could not be pointed at a fixture, and therefore the one that could not be tested.
  • v0.7.0's own zero-count tripwire was too strict. It required at least one anchored link; zero anchored links is a legitimate state, and it rejected the validator's own fixture repository. Narrowed to the single count that cannot legitimately be zero — proving each sub-check still fires is a test's job, and now is one.

Documentation: full-corpus audit

Five dimensions, every finding put through an independent refuting pass: 14 confirmed, 26 rejected. Among the rejected was one the maintainer had called confirmed — presets/design.md's (F = 0) is an appositive gloss on "violated hard constraint", so the gate was never inverted.

Confirmed and fixed:

  • Following CONTRIBUTING.md's field-profile recipe broke CI. Field profiles are registered in docs/languages.json one path at a time while presets/ and commands/ use globs, so a new profile was an unregistered canonical document. Reproduced, fixed in both the contributor guide and field-profiles/README.md, and re-verified by following the corrected recipe end to end.
  • The chaining handoff contract called deliverables "line-per-item" and told tree-chain to take "the first K lines". They are ranked ## <id> sections carrying several lines of fields each, so a head-N over lines would slice an item's body in half. Now defined as entries, split on level-2 headings.
  • ENGINE §4's slot table named fields no preset declaresfalsifiability attributed to design, cost_of_change to nothing at all — and had no row for the external-check field §3.X mandates. Every example is now a field a shipped preset really declares.
  • §F7 listed --max-branches as a cap with a cap-trip status that §6.1, §6.2 and §7.4 never define. It raises a per-node ceiling whose floor §3 fixes at 12 and never terminates a run.
  • README double-nested the run directory (an explicit --out is the run directory), miscounted CONTRIBUTING.md, and claimed CI runs on every push when ci.yml restricts push to main.
  • Two physically wrong worked examples in framings.md: relaxing a 5σ cut to 3σ cannot make detections drop out (it triples the sample), and 10¹¹ M_sun is a Milky-Way-scale halo, not the galaxy-cluster regime.

Every Chinese parallel was co-edited and its source digest refreshed.

No interface changes: every flag, preset, command, and output filename is unchanged from v0.7.0.

Full detail: CHANGELOG.md