Skip to content

ADR-2153: Move the praetor pin to 04cc813ff054 for the documentation lint budget and the tidy coverage gate

  • Status: Accepted
  • Date: 2026-10-06
  • Deciders: lusoris
  • Tags: ci, governance, standards

Context

The Praetor Documentation Governance job failed intermittently on master when a lint child ran past the engine's fixed 120 s budget. Praetor fixed that with a setting (documentation.lint_timeout_seconds, #784, bundle #796) and moved the gate's deadline into the locked script. The same range of commits adds line-ending-neutral digests (#781, fix!), state-sync bounds (#785), a checkpoint re-run fix (#786) and a clang-tidy translation-unit coverage gate that the native-gpu-systems profile enables: it fails when git tracks a C, C++, CUDA, HIP or Objective-C++ unit that no declared lane reads and no declared exception excuses.

Decision

Move PRAETOR_REF in .github/workflows/standards-gate.yml from 0af07a733e65 to 04cc813ff054921cd6fd9f628ce3f3fee39ca69d, under ADR-1351's conditions: the engine-written files are regenerated by the engine in a throwaway copy (adopt --force --lock-source-root <praetor source at the pin>) and copied back where audit reports them stale (tools/markdownlint/verify.mjs, the DevContainer bundle).

  • documentation.lint_timeout_seconds: 240. Measured on this host (32 logical CPUs, load 30 to 50 from parallel lanes) over three runs of the gate, eight lint children each: min 0.63 s, median 2.58 s, p90 7.15 s, max 11.37 s. 240 s is 21 times the measured maximum and half the 480 s ceiling; the whole gate stays under its 480 s deadline whatever the setting.
  • Tidy coverage. The repository already records the facts once, in the baselines' measured_sources and .config/lint-exceptions.d/clang-tidy-coverage.toml (ADR-1762). scripts/ci/praetor_tidy_coverage.py renders praetor's two inputs from them (.config/clang-tidy/measured-sources.txt, and the exceptions: block of .standards.yaml), a pre-commit hook fails on a stale rendering, and clang_tidy.lanes declares the one list file. 770 of 822 tracked units are read; 52 are excused: the 25 files of the existing exception list that praetor counts as units, the 26 exact-twin data fragments that borrow the .hip extension, and the HIP header adm_decouple_inline.hip. Praetor accepts an exception at most 90 days out, so each rendered entry expires on the earlier of its own date and 2027-01-04.
  • The baseline is unchanged: 0 active infractions within the 0 recorded (baseline --verify), so nothing is re-recorded.
  • Not copied from adopt --force, as in ADR-1351 and ADR-1506: the harness AGENTS.md, the hook registrations in .claude/settings.json, .codex/hooks.json, .gemini/settings.json, the editor files and .config/lefthook/python.sh.

Alternatives considered

Option Pros Cons Why not chosen
Hand-write the lane list and exceptions in .standards.yaml No generator A second list that drifts from the baselines and the exception list (HISS-19) One source, two renderings
Move the whole exception list into .standards.yaml One list Praetor caps expiry at 90 days and takes one entry per file; loses the repository's 400-day list and its checks The repository's list stays the authority
Directory or glob exceptions for the exact-twin fragments Three lines A tier, which the exceptions rule forbids One entry per file, generated
Stay at 0af07a733e65 No work The intermittent documentation job failure remains The fix is in the new pin
Move the pin (chosen) Budget setting, coverage gate, digests A rendering to keep in step

Consequences

  • Positive: the documentation job has a budget that is a setting; every tracked translation unit is checked for a lane or an exception by praetor as well as by the repository's own check.
  • Negative: the generated exceptions expire on 2027-01-04 and must be renewed with PRAETOR_EXPIRY_CAP; the lane list counts the five compat/python-vmaf/matlab units (ical_stat.c, ical_std.c, edges-orig.c, edges.c, pointOp.c) as read because the baselines record them, although the hosted compile database lacks them: that defect and its decision belong to the tidy ratchet lane, not to this move.
  • Neutral / follow-ups: every hook engine on a workstation moves with the merge; a branch rebases onto the merged pin first. Praetor's ci tidy-coverage is not yet a CI step of its own: the audit runs the gate in the hooks.

Supply-chain impact

  • Build-time fetches: go install github.com/cordanaLLM/praetor/cmd/standardsctl@04cc813ff054... in the gate jobs, pinned by commit. The locked documentation gate's npm lock is unchanged.
  • CVE surface delta: none (the katex advisory of the lock is cordanaLLM/praetor#793 and moves with a later pin).

References

  • req (paraphrased): move the praetor pin to 04cc813ff054, set the documentation lint budget from a measurement, bring the tidy translation-unit coverage under the gate or declare each exception, and coordinate the five matlab units with the tidy ratchet lane (coordinator brief, 2026-10-06).
  • ADR-1351, ADR-1506: earlier pin moves. ADR-1762: the repository's coverage check.