Skip to content

ADR-2440: Move the praetor pin to 7458a220e1c9 and drop the exceptions for the managed workflows

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

Context

PRAETOR_REF pinned afb739ed81f3 (ADR-2321). Praetor main at 7458a220e1c99d136cda3287d0e57afba7a2668b (2026-10-07) is three commits later (cordanaLLM/praetor#826, #836, #851); #826 and #851 are breaking. The new engine's audit, run on an untouched clean clone of master b075f3a88, fails one gate. The other changes ask nothing of this tree.

Praetor change Finding on master Resolution here
#826 (fix for #815): the emitted praetor-api.yml and praetor-docs.yml push only on the default branch, listen for opened, synchronize, reopened, ready_for_review, and stop a draft with a failing first step; prior renderings are recorded so a copy refreshes without --force .github/workflows/praetor-docs.yml holds an earlier Praetor text both files regenerated by adopt --force in a throwaway copy and copied back
#851, hook gate: audit and adopt fail when core.hooksPath leaves the managed hooks directory none: no core.hooksPath is set here planted core.hooksPath=/dev/null in a throwaway repository: audit fails and names the scope; without it the hook check is the old one
#851, caveman C1 counts only whole-word articles (a token such as A380 is no article) none at the audit; scripts/ci/AGENTS.d/ci-impact.md already failed the page check page reworded, now 1 article
#851, snapshot lock waits; test-only changes (#755, #809, #836) none none

The DevContainer bundle and the agent evasion hook changed with the engine and were regenerated in the same copy.

Decision

Move PRAETOR_REF in .github/workflows/standards-gate.yml to 7458a220e1c99d136cda3287d0e57afba7a2668b, under ADR-1351's conditions: engine-written files come from the engine in a throwaway copy (adopt --force --lock-source-root <praetor clone at the pin>) and only the files audit reports stale are copied back (the two workflows, the DevContainer bundle, .config/agent/hooks/block_evasion.py). .paperclip/ and .standards.yaml are not copied back: in the copy the register block names the skills adopt wrote there, which this repository does not carry (ADR-2321).

Drop the exceptions Q-076 declared for the two managed workflows, as far as the engine now allows:

  • push_branch_exceptions is empty. Both workflows push only on master.
  • ready_for_review exemption removed from test_every_pull_request_workflow_listens_for_ready_for_review.
  • untiered_jobs keeps both entries, with a new reason and expiry 2027-12-31. The engine stops a draft with a failing first step and skips the rest, but the job still starts and reports a red check, and the tier contract expects a draft to start no job but the declared ones. A job-level gate cannot be added to a byte-locked file. test_praetor_managed_jobs_stop_on_a_draft_before_any_work proves the step shape (first step fails closed on a draft, every later step guarded by the opposite condition) and two planted defects show it failing.
  • Proof the old exceptions are gone: the routing contract run against the previous workflow text (CI_ROUTING_WORKFLOWS_DIR) fails 6 cases; against the regenerated files it passes (39 cases). A planted push trigger without the branch filter fails expect_no_other_branch_runs.

The state row T-CI-PRAETOR-LOCKED-WORKFLOWS-PUSH-AND-DRAFT-2026-10-07 moves to Recently closed with the draft caveat.

Alternatives considered

Option Pros Cons Why not chosen
Drop the untiered_jobs entries too and teach the contract that a first-step stop is a draft gate No exception left Weakens a contract that expects a job-level gate; the jobs do start on a draft The entry plus a shape test states exactly what the engine does
Wait for praetor to skip the job on a draft Cleaner Open-ended; the exception expires 2026-12-31 and fails then The push-branch half is fixed now
Edit the two workflows by hand to add a job-level if Meets the contract Audit refuses a hand edit Forbidden by the byte lock
Move the pin (chosen) Branch filter and ready_for_review arrive; the 52 daily push runs per workflow on other branches (measured 2026-10-06) stop One exception stays

Consequences

  • Positive: a push to another branch starts neither workflow; a draft costs seconds, not the full gate.
  • Negative: a draft pull request shows two red managed checks until it is ready; the draft-start gap is filed upstream as cordanaLLM/praetor#857, and the two untiered_jobs entries go when it lands; a throwaway clone made with git clone -c core.hooksPath=... persists the value and fails audit (use the option per command instead).
  • Neutral / follow-ups: every hook engine moves with the merge; a branch rebases onto the merged pin first. Go API Compatibility joins strictMustReport (Q-184): the earlier reason (no ready_for_review) no longer holds. test_required_and_strict fails against the previous aggregator.

Supply-chain impact

  • Build-time fetches: go install github.com/cordanaLLM/praetor/cmd/standardsctl@7458a220e1c9... in the gate jobs, pinned by commit.
  • CVE surface delta: none.

References

  • Q-178 (follow-up of Q-108): move the pin from afb739ed81f3 to 7458a220e1c9 (orchestrator ledger, 2026-10-07).
  • Q-108: the first of the two bumps; a second, small bump follows praetor#826 (ADR-2321).
  • Q-183, Q-184, Q-185: keep the two untiered_jobs entries; move Go API Compatibility into strictMustReport; file the draft-start gap upstream (orchestrator ledger, 2026-10-08).
  • Q-076: the exceptions for the managed workflows, expiry 2026-12-31 (ADR-2169).
  • req (paraphrased): fix every finding in the repository without waivers, regenerate the managed workflows through praetor, and return real choices as questions (coordinator brief, 2026-10-07).
  • ADR-1351, ADR-2153: earlier pin moves.