Skip to content

ADR-2321: Move the praetor pin to afb739ed81f3 and meet its nested-context, supply-chain and harness checks

  • Status: Accepted
  • Date: 2026-10-07
  • Deciders: lusoris
  • Tags: ci, governance, standards, supply-chain

Context

PRAETOR_REF pinned 04cc813ff054 (ADR-2153). Praetor main at afb739ed81f3f1ca5342635dca5d7726e3fa009b (2026-10-07) is twelve commits later, seven of them breaking. The new engine's audit, run on an untouched clean clone of master 18b04cf8b with the hooks installed, stops at the first failing gate. Fixing each failure in a throwaway copy and re-running gave the full list:

Praetor change Finding on master Resolution here
4c7d0694b katex override in the Markdown gate lock tools/markdownlint/package.json holds an earlier praetor text the three locked files regenerated by the engine
afb739ed8 register skills (praetor#235) the AGENTS.md register block names social-text and caveman, which this repository does not carry, so it is out of sync compile-context re-spliced the block without skill names
f588ca7b3 caveman lint of every tracked nested AGENTS.md (praetor#311) 19 of 72 files fail, all on article density but one rewritten (Decision)
4c7d0694b DevContainer pins hardening bootstrap Dockerfile identity differs from its inputs bundle regenerated (six parts)
0e6a00f5a HISS-11 declared SLSA level against the measured one (praetor#330) Level 3 declared, .github/workflows/docker-publish-operator-node.yml reaches Level 2 gap declared (Decision)
26ac9f960 harness rows of the declared forge (praetor#321) .paperclip/harness.json is earlier praetor output; rules.md names a push form for another forge and stale complexity limits both regenerated by adopt, with the new register.sources digest

The other breaking changes ask nothing of this tree. 06bae6671 accepts only a pre-commit hook a known runner wrote: lefthook's hook passes, and CI skips the installed-hook check. The Go vulnerability gate of 4c7d0694b passes with the OpenVEX document already in security/vex/go.openvex.json (one advisory, GO-2026-5932, covered). f7dde58da compares live branch protection only when the ruleset is not declined, and adoption.decline lists branch-ruleset. The credits list of 19d884081 is checked by praetor's own tests on praetor's own docs/credits.yaml; an adopter has no credits gate. compile-context --verify, hiss coverage --verify, dedupe scan . and baseline --verify pass on the final tree, and the baseline stays at 0.

Decision

Move PRAETOR_REF in .github/workflows/standards-gate.yml to afb739ed81f3f1ca5342635dca5d7726e3fa009b under ADR-1351's conditions: the engine-written files come from the engine in a throwaway copy (adopt --force --lock-source-root <praetor clone at the pin> for the locked Markdown gate files, the DevContainer bundle and .config/agent/hooks/block_evasion.py; a plain adopt for .paperclip/), copied back where audit reports them stale.

  • Nested context. Every nested AGENTS.md that fails praetorctl caveman check --kind=context, and every AGENTS.d/ topic page that fails the same command, is rewritten in the internal register: 19 files and 195 pages (65,837 prose words, 3,761 articles before). The articles are removed by a script that leaves headings, front matter other than invariant:, fenced and inline code, link targets, URLs, HTML comments and quoted strings untouched. Twenty sentences over 30 prose words are split at a ; or :, and seven hedge or filler words are reworded. A token check found no code span, path, identifier, number or ADR reference lost. The generated index header of scripts/docs/agents_index.py loses its two articles. The pages are not gated by praetor, but they render into the gated indexes and are read in their place.
  • Supply chain. Praetor lets a repository tighten supply_chain and never lower it, and the pinned profile and facet both declare Level 3. The measured Level 2 is declared as a HISS-11 gap in the repository's exception list, .config/lint-exceptions.d/HISS-11.toml, which scripts/ci/praetor_tidy_coverage.py copies into the one exceptions: block of .standards.yaml with the existing expiry cap (2027-01-04). The gap stays open in docs/state.md as T-SLSA-RELEASE-PROVENANCE-LEVEL-2-2026-10-07.
  • Not taken from adopt, as in ADR-1351 and ADR-2153: the generic AGENTS.md harness, the praetorctl hook registrations in .claude/settings.json, .codex/hooks.json and .gemini/settings.json, the editor files, .config/lefthook/python.sh, and the three register skills, whose install would need .agents/skills/ tracked.

Alternatives considered

Option Pros Cons Why not chosen
Install praetor's social-text, caveman and adhd-format skills The register block keeps naming them .agents/skills/ is ignored here as a mirror of .claude/skills/; tracking it changes that layout Kept out of the pin move; returned to the maintainer as a question
Wrap the nested prose in caveman:off regions No rewrite Hides 65,000 words from the gate it exists for A gate that reads nothing is not a gate
Hand-rewrite every page Best prose Days of work for 214 files on the critical path Mechanical article removal plus hand fixes for the rest
Move the release provenance into a reusable workflow that builds and attests (Level 3) Closes the gap CI restructuring of every publish workflow, only verifiable on a release run Tracked as its own row
Drop the security:high facet No gap to declare The native-gpu-systems profile declares Level 3 as well; it weakens every other control of the facet Declares less than the repository wants
Move the pin (chosen) Every check of the new engine runs 214 rewritten agent files, one declared gap

Consequences

  • Positive: agent context below the root is held to the register by the gate, not by hand; the supply-chain claim is stated as measured, with an expiry.
  • Negative: the HISS-11 entry expires on 2027-01-04 and fails the audit then, unless the release workflows reach Level 3 or the entry is renewed with a reason; caveman pages read terser than before.
  • Neutral / follow-ups: every hook engine moves with the merge; a branch rebases onto the merged pin first, and a branch that edits a nested AGENTS.md or an AGENTS.d/ page must pass the caveman check. Praetor's checker counts a model name such as A380 as the article "a" (cordanaLLM/praetor#838); one page reworded a quote to stay under the limit.

Supply-chain impact

  • Build-time fetches: go install github.com/cordanaLLM/praetor/cmd/standardsctl@afb739ed81f3... in the gate jobs, pinned by commit. The locked Markdown gate's npm lock now resolves katex 0.19.0 through an override (praetor#793).
  • CVE surface delta: the katex advisory GHSA-238p-pmpm-9mq7 of the old lock is gone.

References

  • Q-108 (supersedes Q-084): move the pin now from 04cc813ff054 to afb739ed81f3, 12 commits; a second, small bump follows when cordanaLLM/praetor#826 lands (orchestrator ledger, 2026-10-07).
  • Q-084: the pin bump waits for praetor #815 (orchestrator ledger, 2026-10-06; superseded by Q-108).
  • req (paraphrased): fix every finding of the new engine in the repository without waivers, declare the measured SLSA level rather than claim one that cannot be proven, and return real choices as questions (coordinator brief, 2026-10-07).
  • ADR-1351, ADR-2153: earlier pin moves. ADR-1454: the AGENTS.d/ pages.