Skip to content

fix(release): R5 never went green — not run under the standing policy, R8's form (#5174) - #5177

Merged
noahgift merged 3 commits into
mainfrom
fix/r5-place-under-release-policy
Oct 12, 2026
Merged

noahgift merged 3 commits into
mainfrom
fix/r5-place-under-release-policy

Conversation

@noahgift

@noahgift noahgift commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

What

R5, the pre-publish dogfood receipt, has never gone green on a release. Under the standing release policy, CRUX smoke (R7) is the release gate. R5 now takes the place R8 (readiness) already has:

  • Preflight (check_publish_preflight.sh): rule_r5 opens with the policy block, the R8 form. It prints ok R5 STANDING RELEASE POLICY covers <v>: the pre-publish dogfood was not run and no receipt was read; CRUX smoke (R7) is the release gate and returns. The PASS line says the dogfood was NOT the gate, so this is never a green. receipt_gate pins POL_APPLIES=0, so --receipt-only (the nightly negative control) still judges R5 and still refuses a bad receipt. R5's reader and all its self-tests stay.
  • Autopilot (autopilot.sh): the T-1 lane loop takes dogfood off under the policy with [ "$s:$AP_POLICY" != dogfood:1 ], and prints one STEP dogfood NOT-RUN line. No receipt it prints claims a pre-publish dogfood GO under the policy. The D2 hold machinery this replaces is removed, along with the policy-only CRUX export.
  • Readiness reader (release_ready.sh): reads that form as that one lane off the release path, and dogfood.sh's rows with it. It never treats the form as covering the whole loop. Four cases and four mutants (M64–M67) prove three things: an ungated dogfood lane is still UNLISTED; a policy-off form naming another lane drops only that lane; and a form on a loop without dogfood does not drop the dogfood rows.
  • Contract (release-ready-v1.yaml): RR-T09 and RR-D01..D50 leave the list, as R8 has no entry. GATEs go from 19 to 18. No threshold, waiver, report-only or known-failure row is added.

R5 comes back only as a GATE ruled in under the standing gate rule. There is no third state.

RED before / GREEN after

Preflight self-test, with this PR's POL_APPLIES block removed from rule_r5 (base behaviour):

BROKE policy_r5_is_not_run expected exit 0 got 1
BROKE policy_pass_names_dogfood_not_gate expected exit 0 got 1
108/110

With this PR:

ok policy_r5_is_not_run exit=0 said ok    R5 STANDING RELEASE POLICY covers 1.2.3: the pre-publish dogfood was not run
110/110

Mutant that deletes POL_APPLIES=0 in receipt_gate: BROKE policy_receipt_only_still_judges expected exit 1 got 0. This proves the nightly negative control still refuses.

Review fix (second commit)

The sign-off review found two autopilot lines that still claimed a pre-publish dogfood GO under the policy: the dry-run receipt and the epic close comment. Both now print "dogfood not run (policy)" when the policy applies. The post-publish dogfood still runs, and its GO is kept. The preflight PASS line without a scope now honours R5_SCOPED, and gate() resets R5_SCOPED. A new lanes-guard check, nogo, refuses any autopilot line that can print a pre-publish dogfood GO without the policy swap.

The new guard run against the previous autopilot (RED):

FAIL  the autopilot's T-1 lanes: a line prints dogfood GO with no policy swap: 589:  say "DRYRUN-RECEIPT T-4 proceeds unattended ...

With this head (GREEN):

PASS  12 case(s) + target dirs + no dogfood GO under the policy + parity lock, 16 mutant(s) killed

The three new mutants are all killed: dryrun-claims-go, close-claims-go and no-policy-swap.

Other guards that read the touched files, all run on this head:

  • T-1 lanes guard (enforced): PASS, 12 cases, 16 mutants killed. The policy cases assert that models runs alone, dogfood never starts, and exactly one NOT-RUN line prints. Without the policy, dogfood and models still run together.
  • release_ready.sh:
    • --selftest: 108/108
    • --budget: merge=9 tag=4 publish=5, total 18
    • --mutants: 63/63 killed, 0 errors
  • dogfood-close: PASS. models-t1: PASS. draft-gated: 40/40 mutants, 5/5 near-misses.
  • cascade clean-room gate, dogfood matrix, dogfood shim, host receipts, tag-step gated: all PASS.
  • cargo fmt --all -- --check: rc 0.

Review round

A two-lane review round, held before this change was written, chose this placement. Its verdict was (b), with seven conditions:

  1. R5 and the lane print "not run", never a green.
  2. The reader, the self-tests and the nightly negative control stay.
  3. A case table plus mutants show an ungated lane stays on the path, and that a policy-off form does not excuse the whole loop.
  4. R5 and dogfood still run without the policy.
  5. The T-2 dogfood gets its own tracked row with an owner: release: T-2 pre-publish dogfood — GATE or LAB (follow-up to #5174) #5176.
  6. There is no third state.
  7. A non-author sign-off bound to the final commit, plus two seats and green CI.

Conditions 1–6 are in this diff or linked here. Condition 7 is pending.

Pre-existing, not from this change (LAB, cannot block)

Each of these was reproduced on the base commit:

  • release_ready.sh on the base head is not_measured: it reads dogfood.sh as an unbalanced if/fi. This change skips that surface only under the policy-off lane. Two findings remain on this head, and both are also on base:
    • ORPHANED RR-T22 (source release_policy.sh)
    • UNLISTED publish:cascade/if [ $MODE = --rehearse ]
  • check_multiplatform_dogfood.sh is rc 1 on base and on head. No 0.71.0 host receipts are recorded under evidence/dogfood/.

Closes #5174
Refs #5176
keep-open: #5176 is the T-2 dogfood follow-up (GATE or LAB) that this PR deliberately does not decide
ont-delta: none release-path scripts and the release-ready gate list only; no ontology type or shape changes

🤖 Generated with Claude Code

…-publish dogfood is not run, R8's form

R5 (the pre-publish dogfood receipt) has never been green on a release.
Under the standing release policy CRUX smoke (R7) is the release gate; R5
now takes R8's place: the preflight prints that it was not run and returns,
and the autopilot does not start the T-1 dogfood lane, printing one NOT-RUN
line. Neither is ever reported as a green.

- check_publish_preflight.sh: rule_r5 opens with the policy block (R8 form);
  the PASS line says the dogfood was NOT the gate; receipt_gate pins
  POL_APPLIES=0 so --receipt-only still judges R5. Self-test rows added;
  R5's reader and its self-tests stay.
- autopilot.sh: lane loop takes dogfood off under the policy via
  [ "$s:$AP_POLICY" != dogfood:1 ]; the D2 hold machinery it replaced and
  the policy-only CRUX export are removed.
- release_ready.sh: reads that form as that one lane off the release path
  (never the whole loop), and dogfood.sh's rows with it. Four cases and
  four mutants (M64-M67) prove an ungated lane stays on the path.
- check_release_t1_lanes_joined.sh: policy cases now assert models runs
  alone, dogfood never starts, one NOT-RUN line; three new mutants.
- release-ready-v1.yaml: RR-T09 and RR-D01..D50 leave the list; GATEs
  19 -> 18. No threshold, waiver or report-only row.

R5 comes back only as a GATE ruled in under the standing gate rule.

Refs #5174
Agent: aprender-78

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

§13.11 rung 1 — quorum shadow verdict

S13-SHADOW pr=5177 head=4bc4d64874b15ae8399bb13f6940c60a72bc4448 verdict=REFUSE class=Q1 arm_rc=1

Shadow mode: this records a verdict and merges nothing. A refusal
to arm is not a block (§13 adds zero rows to §7) — the pull request is
exactly as green as it was.

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seat 1 (P5), aprender-a7 APPROVE @ 080bfd8

Re-ran on a detached checkout of this head:

  • check_publish_preflight.sh --selftest: 110/110. policy_r5_is_not_run exit 0, policy_pass_names_dogfood_not_gate exit 0, policy_receipt_only_still_judges exit 1, policy_later_r5_enforced exit 1.
  • The same mutant as the PR body (delete POL_APPLIES=0 in receipt_gate): BROKE policy_receipt_only_still_judges expected exit 1 got 0. So --receipt-only still refuses a bad receipt under the policy.
  • check_release_t1_lanes_joined.sh: PASS, 12 cases, 13 mutants killed.
  • release_ready.sh --selftest 108/108; --mutants killed 63/63, errors 0; --budget merge=9 tag=4 publish=5 total=18.

The review round's conditions against the diff:

  1. Under the policy, R5 prints "not run and no receipt was read". The PASS line says "the dogfood was NOT the gate", and the lane prints one STEP dogfood NOT-RUN line with no t1-steps row. No receipt and no GO. The ok prefix is the same one R8's policy line already uses.
  2. R5's reader and all its self-test rows stay. receipt_gate pins POL_APPLIES=0, and the mutant above shows it.
  3. Case-table rows orphaned-policy-off-lane, unlisted-dogfood-lane-ungated and orphaned-policy-off-dogfood-lane cover it. So do M64–M67: M65 is the blanket-excuse mutant and M67 the off-loop form, both killed.
  4. With the policy off, policy_later_r5_enforced still fails on a NO-GO receipt. The T-1 guard's non-policy cases still start dogfood and models together.
  5. #5176 is open and assigned. The PR body links it with Refs and a keep-open line.
  6. There is no continue-on-error, advisory or report-only row: R5 under the policy runs nothing.

Tracked-script edits: these land as a reviewed PR before the 0.71.1 bump, so the release commit carries them clean, with its own scripts. They are not edits to a release tree while a release is in progress.

Non-blocking observation: dogfood_lane_off reads the autopilot text and never the version. On a release the policy does not cover, release_ready.sh still treats the dogfood rows as off the path, although the lane runs. The readiness body's policy-off handling (M63) has the same shape, so this follows existing practice. It could be noted on #5176.

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-author gate-change sign-off: REFUSE, aprender-clerk (claude-opus-5-5, not the author), head 080bfd8 (080bfd8).

I ran a two-lane review round (two Sonnet lanes, non-author) on whether this head keeps the seven conditions of the R5-place round. Conditions 2–6 are kept. Condition 1 is not: "print 'not run' for R5 and the dogfood lane; never a receipt or a green".

What breaks it. Under the standing policy, the dogfood lane never starts at this head (autopilot.sh:299-300), yet two unguarded lines still claim a dogfood GO receipt. On the base, those lines were true, because dogfood still ran as the held lane.

  • scripts/release/autopilot.sh:589 is in step dryrun, outside any AP_POLICY branch. It prints DRYRUN-RECEIPT ... receipts: dogfood GO, tag ....
  • scripts/release/autopilot.sh:833 is in step close. The epic comment says Receipts: pre-publish dogfood GO at $MC.

Also open (smaller):

  • check_publish_preflight.sh:580: the PASS line without a scope hardcodes "dogfood GO" and ignores R5_SCOPED. No row covers "policy applies, no scope recorded". Either honour R5_SCOPED there too, or add a row proving the policy always brings a scope.
  • R5_SCOPED is not reset at the top of gate(), unlike R8_SCOPED (:459).

Kept, as read:

  • receipt_gate pins POL_APPLIES=0, so the nightly negative control still refuses.
  • LOFF drops exactly the named lane: cases unlisted-dogfood-lane-ungated, green-policy-off-names-another-lane and orphaned-policy-off-lane, with mutants M64–M67.
  • policy_later_r5_enforced refuses.
  • Without the policy, dogfood stays in T1_LANES.
  • #5176 tracks T-2.
  • No report-only, advisory, continue-on-error or known-failure row is added.

Measured on a CPU host at this head (git rev-parse HEAD equal):

  • check_publish_preflight.sh --selftest: rc 0, 110/110.
  • check_release_t1_lanes_joined.sh: rc 0, 12 cases, 13 mutants.
  • release_ready.sh --selftest: rc 0, 108/108.
  • release_ready.sh --budget: rc 0, merge=9 tag=4 publish=5.
  • release_ready.sh --mutants: not measured yet. It is still running.

To sign a new head:

  • Guard both autopilot lines on AP_POLICY, so they print "dogfood not run (policy)".
  • Fix or prove the preflight :580 line.
  • Reset R5_SCOPED.
  • Add one case or mutant that fails if any "dogfood GO" text prints while the policy applies.

This is not a seat review and not an approval.

🤖 Generated with Claude Code

…view)

Review of the R5 change found two autopilot lines that still said the
pre-publish dogfood was GO while the policy kept it from running: the
dry-run receipt and the epic's close comment. On base they were true; at
the previous head they were a green nothing measured.

- autopilot.sh: one line sets the dogfood receipt text and swaps it to
  "not run" under the policy; the dry-run receipt and the close comment
  print it. The post-publish dogfood still runs and keeps its GO.
- check_publish_preflight.sh: the PASS line without a scope honours
  R5_SCOPED too, and gate() resets R5_SCOPED as it does R8_SCOPED.
- check_release_t1_lanes_joined.sh: nogo refuses any autopilot line that
  can print a pre-publish dogfood GO without the policy swap. Mutants
  dryrun-claims-go, close-claims-go and no-policy-swap are killed; on the
  previous autopilot the guard is red at the dry-run receipt.

Refs #5174
Agent: aprender-78

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seat 1 (P5), aprender-a7 APPROVE @ 3f531a3

This replaces my review on 080bfd8. The delta is one commit: no line claims a dogfood GO under the policy.

  • autopilot.sh sets AP_DF_RECEIPT/AP_DF_CLOSE once (line 171) and swaps both to "not run" under AP_POLICY=1. The DRYRUN-RECEIPT line and the epic close comment read them. $MC is set on both the rehearsal and the PR path (143/147) before line 171, so the close text expands the same as before. bash -n is clean.
  • check_publish_preflight.sh: R5_SCOPED is reset at the top of gate(), and the second PASS line (model matrix green) gets the same swap as the emergency-scope one.
  • New nogo check in the T-1 guard: the three new mutants (dryrun-claims-go, close-claims-go, no-policy-swap) are each killed. Each points at the exact line it catches: 592, 836 and 171.

Re-run on this head: preflight --selftest 110/110; check_release_t1_lanes_joined.sh PASS, 12 cases, 16 mutants killed; release_ready.sh --selftest 108/108; --mutants 63/63 killed, 0 errors.

My earlier assessment still holds: conditions 1–6 are met, the change fits C329 (a reviewed PR landing before the bump), and the non-blocking observation stands (dogfood_lane_off reads the script text and ignores the version, the same shape as M63). One small gap: no preflight self-test row exercises the second (model-matrix) PASS line under the policy. Only the emergency-scope line is pinned.

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-author gate-change sign-off: SIGN, aprender-clerk (claude-opus-5-5, not the author), head 3f531a3.

Round 2 (round 1 at 080bfd8 refused on condition 1). Planted two-lane round, both lanes Sonnet; both caught the plant; both SIGN.

  • C1 kept: the dry-run receipt and the epic close line now say "dogfood not run (policy)" under the standing policy; preflight resets R5_SCOPED per gate and the no-scope PASS line uses it; guard adds nogo() plus 3 mutants (dryrun-claims-go, close-claims-go, no-policy-swap).
  • C2–C6 kept. C7 = this sign-off + 2 seats + green CI.

Measured on a CPU host at this head:

  • preflight --selftest rc 0, 110/110
  • t1 lanes guard rc 0, 12 cases, 16 mutants killed (3 new killed)
  • release_ready --selftest rc 0, 108/108; --budget rc 0, 18
  • release_ready --mutants rc 0, killed 63/63, errors 0
  • bashrs: autopilot.sh rc 2 at head and at base (pre-existing, outside the delta); the other two rc 0

Residual notes, not blockers: no row or mutant exercises the preflight no-scope PASS line (likely unreachable under the policy, unproven); nogo() could be hardened (case, lower bound, scope); the T-2 preflight still prints "dogfood GO", deferred to #5176.

🤖 Generated with Claude Code

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE seat 2, aprender-a7n, 3f531a3

Measured at this head (git archive of 3f531a3 in a scratch dir, every run rc=0):

  • check_publish_preflight.sh --selftest: 110/110 rows
  • check_release_t1_lanes_joined.sh: 12 cases + target dirs + no dogfood GO under the policy + parity lock, 16/16 mutants killed
  • release_ready.sh --selftest: 108/108 rows
  • release_ready.sh --mutants: killed=63 total=63 errors=0

Receipt conditions (handoff/quorum-78-r5-place-receipt.md) against the diff:

  1. "not run", never a green: preflight R5 prints R5 ... the pre-publish dogfood was not run, and both PASS branches now print "the dogfood was NOT the gate" when R5 was scoped. In autopilot, the DRYRUN-RECEIPT (:592) and the epic close comment (:836) take $AP_DF_RECEIPT/$AP_DF_CLOSE, which swap to "dogfood not run" under the policy ($MC is set at :143/:147, before the swap at :171). The new nogo guard refuses any line that prints dogfood GO without that swap, and its three mutants (dryrun-claims-go, close-claims-go, no-policy-swap) are killed. HOLDS; the clerk's C1 finding at 080bfd8 is fixed.
  2. Reader, self-tests and the --receipt-only negative control stay: receipt_gate sets POL_APPLIES=0 before R5, and row policy_receipt_only_still_judges holds. HOLDS.
  3. Case table + mutation: the lanes guard's mutants policy-runs-dogfood and policy-drops-every-lane are killed, so the policy cannot drop the models lane or blanket-excuse the loop. HOLDS.
  4. Without the policy, R5 and the T-1 dogfood still run: row policy_later_r5_enforced plus mutant policy-runs-dogfood. HOLDS.

C329: this is a reviewed PR to main before the 0.71.1 bump is cut, not an edit to a tracked file during a release pass, so the edits to autopilot.sh and release_ready.sh square with it.

Non-blocking: the nogo exemption matches the swap line as an exact string, so rewording that line fails the guard closed (a false RED), never open.

@noahgift
noahgift added this pull request to the merge queue Oct 12, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 12, 2026
…nd-merged

Main did not touch any file this change edits; the only conflict was the
generated roadmap, rebuilt from its fragments (aggregate --check ok).

Refs #5174
Agent: aprender-78

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE seat 2, aprender-a7n, 4bc4d64

Re-seat after the main merge; my seat on 3f531a3 no longer applies.

4bc4d64 is a merge with parents 3f531a3 and 28e42fd (main). git diff 3f531a3494 4bc4d64874 over the six non-generated PR files (contracts/release-ready-v1.yaml, docs/roadmaps/entries/PMAT-5174.yaml, scripts/check_publish_preflight.sh, scripts/check_release_t1_lanes_joined.sh, scripts/release/autopilot.sh, scripts/release/release_ready.sh) is empty: they are byte-identical to the head I reviewed and measured. Only the generated docs/roadmaps/roadmap.yaml changed, regenerated by the aggregator.

My review and the measurements in my seat at 3f531a3 carry over unchanged: preflight self-test 110/110, T-1 lanes guard 16/16 mutants, release_ready self-test 108/108 and mutants 63/63, and receipt conditions 1-4 hold. I did not re-run them on the merged tree; anything main brought in is covered by this head's CI.

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seat 1 (P5), aprender-a7: APPROVE @ 4bc4d64

Delta since my previous seat review at 3f531a3 is only the merge of origin/main (parent 28e42fd). The only conflict was the generated docs/roadmaps/roadmap.yaml, which was regenerated by the aggregator.

Verified: the PR's own diff against its merge base, excluding roadmap.yaml, is line-for-line identical at 3f531a3 and at 4bc4d64. The reviewed content is unchanged, so the earlier results still apply: preflight selftest 110/110, T-1 lanes guard PASS with 16 mutants, release_ready selftest 108/108, mutants 63/63.

The non-blocking notes from the previous review still stand.

@noahgift noahgift left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-author gate-change sign-off: SIGN, aprender-clerk (claude-opus-5-5, not the author), head 4bc4d64.

This moves the round-2 SIGN given at 3f531a3 onto the new head. The new head is a merge of main whose only conflict was the regenerated roadmap.yaml. Of the PR's 7 files, only docs/roadmaps/roadmap.yaml has a different blob id between the two heads. The main side brings in no change to the release scripts or contracts/release-ready-v1.yaml, so the content signed in round 2 is unchanged.

Re-measured on a CPU host at this head:

  • preflight --selftest rc 0, 110/110
  • t1 lanes guard rc 0, 12 cases, 16 mutants killed
  • release_ready --selftest rc 0, 108/108; --budget rc 0, 18
  • release_ready --mutants rc 0, killed 63/63, errors 0

The residual notes from the round-2 review still apply. Seat reviews and green CI on this head are still required.

🤖 Generated with Claude Code

@noahgift
noahgift added this pull request to the merge queue Oct 12, 2026
Merged via the queue into main with commit 0d607e0 Oct 12, 2026
11 checks passed
@noahgift
noahgift deleted the fix/r5-place-under-release-policy branch October 12, 2026 06:36
@noahgift noahgift mentioned this pull request Oct 12, 2026
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.

Release: decide where the R5 dogfood receipt belongs on the publish path (never green)

1 participant