diff --git a/contracts/release-ready-v1.yaml b/contracts/release-ready-v1.yaml index 7433188c1c..4ddc166aca 100644 --- a/contracts/release-ready-v1.yaml +++ b/contracts/release-ready-v1.yaml @@ -63,6 +63,11 @@ # `publish` (was RR-P37); the `assets` wait on the binary-release run is its `also`. # Child rows 82 -> 50 (RR-D01..D50); GATEs unchanged at 19 (merge 10, tag 5, publish 5). # The spec's T-4 row now names the executor the `cascade` step runs, so publish.executor agrees. +# #5174 (R5 never went green on a release): under the standing release policy the autopilot does +# not start the T-1 dogfood lane and the preflight does not run R5, the R8 form. release_ready.sh +# reads `[ "$s:$AP_POLICY" != dogfood:1 ]` on the lane loop as that lane off the release path, and +# dogfood.sh's rows with it, so RR-T09 and RR-D01..D50 leave the list (as R8 has no entry). The +# dogfood runs nightly; it comes back only as a GATE the operator rules in. GATEs 19 -> 18. # # A ROW (`parent: `) is part of the GATE it names: checked like any entry, printed # under that GATE by `--gates`, and never counted in its total. @@ -209,12 +214,12 @@ binding_registry: # counted GATE of that stage is STALE, and either fails `release_ready.sh --budget`. Caps 10/5/5. # The checker stays LAB: a stage calls it as a blocking step only after three green nights on main. # Merge 9: the x86-main preflight is listed (RR-M17); RR-M01 is the same gate job as RR-M16 and RR-M14 -# the case table of RR-M13, so each is an `also`. Tag 5: readiness runs nightly (autopilot skips it under -# the standing release policy), and the pre-push tag guard (RR-T21) takes its place. +# the case table of RR-M13, so each is an `also`. Tag 4: readiness and the pre-publish dogfood run nightly +# (autopilot starts neither under the standing release policy, #5174); the pre-push tag guard (RR-T21) is listed. stages: release_entries: merge: RR-M02 RR-M05 RR-M09 RR-M10 RR-M11 RR-M13 RR-M15 RR-M16 RR-M17 - tag: RR-T01 RR-T09 RR-T11 RR-T16 RR-T21 + tag: RR-T01 RR-T11 RR-T16 RR-T21 publish: RR-T01 RR-P01 RR-P03 RR-P14 RR-P38 # THE LIST. One requirement per line (the checker parses this block; keep one flow map per line). @@ -229,62 +234,11 @@ requirements: - {id: RR-M16, applies_to: [merge], anchor: "merge:required-context/gate", also: ["merge:required-context/ci / gate"], checker: ".github/workflows/ci.yml# gate:", provenance: "CLAUDE.md Git Workflow; org ruleset on main (ci/sections.yml: rulesets need the exact name gate)", producer: "ci-main"} - {id: RR-M17, applies_to: [merge], anchor: "merge:ci.yml/gate/needs/x86-main", checker: ".github/workflows/ci.yml# x86-main:", provenance: "the x86-main preflight: the jq pin, the cheap checks, the fat_driver and secret-plumbing case tables run before its sections", producer: "ci-main"} - {id: RR-T01, applies_to: [tag, publish], seven: provenance, anchor: "tag:autopilot/commit/git merge-base --is-ancestor", also: ["tag:autopilot/commit/cargo metadata --no-deps --format-version", "publish:preflight/R1", "publish:preflight/R2", "publish:preflight/R3", "publish:preflight/R4"], checker: "scripts/release/autopilot.sh#git merge-base --is-ancestor", provenance: "APR-RELEASE-001 T-0, #3599 (release commit on origin/main)", producer: "ci-main"} - - {id: RR-T09, applies_to: [tag], anchor: "tag:autopilot/dogfood/bash scripts/dogfood.sh --phase", also: ["publish:preflight/R5"], checker: "scripts/dogfood.sh", provenance: "APR-RELEASE-001 T-1 dogfood GO (#3957)", producer: "dogfood"} - {id: RR-T11, applies_to: [tag], seven: crux-smoke, anchor: "tag:autopilot/models/bash scripts/release/models_t1.sh", also: ["publish:preflight/R7"], checker: "scripts/release/models_t1.sh", provenance: "#3717 #3712 model matrix", producer: "models"} - {id: RR-T16, applies_to: [tag], anchor: "tag:autopilot/tag/bash scripts/release/rc_publish_gate.sh --verify", also: ["publish:autopilot/dryrun/bash scripts/cascade-publish.sh --check"], checker: "scripts/release/rc_publish_gate.sh#--verify", provenance: "#4287 RC-DOGFOOD-001 §4.5 (compile every tarball), moved ahead of the tag (#4690, was RR-P07)", producer: "publish-dryrun"} - {id: RR-T21, applies_to: [tag], anchor: "tag:autopilot/tag/git push origin", checker: "scripts/hooks/pre-push-tags.sh", provenance: "#4943 #4944 the pre-push tag guard refuses a release tag that is not exactly its release branch head", producer: "tag"} - {id: RR-T22, applies_to: [tag], kind: mechanics, anchor: "tag:autopilot/tag/source scripts/lib/release_policy.sh", checker: "scripts/lib/release_policy.sh#rp_known_failures", provenance: "the release notes list each known failure with its ticket; it lists and never stops a release", producer: "tag"} - {id: RR-T23, applies_to: [tag], kind: mechanics, anchor: "tag:autopilot/tag/bash scripts/hooks/pre-push-tags.sh --arm-release", checker: "scripts/hooks/pre-push-tags.sh#--arm-release", provenance: "#4950 G1: the one-shot marker the pre-push tag guard needs to let a release tag out, armed for that one tag after every tag check passed; it arms the push and judges nothing", producer: "tag"} - - {id: RR-D01, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_multiplatform_dogfood", checker: "Cargo.toml#scripts/check_multiplatform_dogfood.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D02, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_model_ladder", checker: "Cargo.toml#scripts/check_model_ladder.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D03, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_ladder_provenance", checker: "Cargo.toml#scripts/check_ladder_provenance.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D04, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_ladder_serve_verdict", checker: "Cargo.toml#scripts/check_ladder_serve_verdict.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D05, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_serve_backend_record", checker: "Cargo.toml#scripts/check_serve_backend_record.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D06, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_ladder_output_judged", checker: "Cargo.toml#scripts/check_ladder_output_judged.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D07, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_dogfood_no_defer", checker: "Cargo.toml#scripts/check_dogfood_no_defer.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D08, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_tokenizer_nonascii_parity", checker: "Cargo.toml#scripts/check_tokenizer_nonascii_parity.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D09, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_verifier_pinning", checker: "Cargo.toml#scripts/check_verifier_pinning.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D10, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_dogfood_shim", checker: "Cargo.toml#scripts/check_dogfood_shim.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D11, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_bench_receipt", checker: "Cargo.toml#scripts/check_bench_receipt.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D12, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_parity_receipt", checker: "Cargo.toml#scripts/check_parity_receipt.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D13, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_no_claim_literals", checker: "Cargo.toml#scripts/check_no_claim_literals.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D14, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:check_perf041_marker", checker: "Cargo.toml#scripts/check_perf041_marker.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D15, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:float16_greedy_parity", checker: "Cargo.toml#scripts/float16_greedy_parity.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D16, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:tokenizer_parity", checker: "Cargo.toml#scripts/tokenizer_parity.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D17, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:surface_audit_bins_gate", checker: "Cargo.toml#scripts/surface_audit_bins_gate.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D18, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:dogfood_comparator_env_tests", checker: "Cargo.toml#scripts/dogfood_comparator_env_tests.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D19, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/declared:package_tarball_build", checker: "Cargo.toml#scripts/package_tarball_build.sh", provenance: "dogfood declared gate, Cargo.toml [package.metadata.dogfood].gates (#3957)", producer: "dogfood"} - - {id: RR-D20, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/git-clean", checker: "scripts/dogfood.sh#mark git-clean FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D21, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/dogfood-gates", checker: "scripts/dogfood.sh#mark dogfood-gates FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D22, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/version-unpublished", checker: "scripts/dogfood.sh#'version-unpublished FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D23, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/coverage", checker: "scripts/dogfood.sh#mark coverage FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D24, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/fmt", checker: "scripts/dogfood.sh#ci_mark fmt ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D25, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/clippy", checker: "scripts/dogfood.sh#gate clippy ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D26, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/security", checker: "scripts/dogfood.sh#gate security ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D27, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/security-2nd-source", checker: "scripts/dogfood.sh#mark security-2nd-source FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D28, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/pmat-pin", checker: "scripts/dogfood.sh#mark pmat-pin FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D29, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/release-binary", checker: "scripts/dogfood.sh#mark release-binary FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D30, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/deterministic-tools", checker: "scripts/dogfood.sh#mark deterministic-tools FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D31, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/pv-contracts", checker: "scripts/dogfood.sh#mark pv-contracts FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D32, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/pv-lint", checker: "scripts/dogfood.sh#mark pv-lint FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D33, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/pv-bindings", checker: "scripts/dogfood.sh#mark pv-bindings FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D34, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/bashrs", checker: "scripts/dogfood.sh#mark bashrs FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D35, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/renacer", checker: "scripts/dogfood.sh#gate renacer ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D36, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/pmat-verify", checker: "scripts/dogfood.sh#gate pmat-verify ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D37, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/pmat-comply", checker: "scripts/dogfood.sh#mark pmat-comply FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D38, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/contracts-exit-integrity", checker: "scripts/dogfood.sh#mark contracts-exit-integrity FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D39, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/contracts", checker: "scripts/dogfood.sh#gate contracts ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D40, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/cli-surface", checker: "scripts/dogfood.sh#mark cli-surface FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D41, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/transport-decl", checker: "scripts/dogfood.sh#mark transport-decl FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D42, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/transport-absence", checker: "scripts/dogfood.sh#mark transport-absence FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D43, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/interface-parity", checker: "scripts/dogfood.sh#mark interface-parity FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D44, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/transport-invariance", checker: "scripts/dogfood.sh#mark transport-invariance FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D45, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/surface-derivation", checker: "scripts/dogfood.sh#mark surface-derivation FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D46, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/probador-suite", checker: "scripts/dogfood.sh#gate probador-suite ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D47, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/dogfood-use", checker: "scripts/dogfood.sh#mark dogfood-use FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D48, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/model-parity-falsifier", checker: "scripts/dogfood.sh#mark model-parity-falsifier FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D49, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/model-parity", checker: "scripts/dogfood.sh#mark model-parity FAIL", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - - {id: RR-D50, applies_to: [tag], parent: RR-T09, anchor: "tag:dogfood/test", checker: "scripts/dogfood.sh#ci_mark test ", provenance: "dogfood pre-publish row (#3957)", producer: "dogfood"} - {id: RR-P01, applies_to: [publish], seven: cleanroom-tag-commit, anchor: "publish:autopilot/cleanroom/gh-workflow clean-room.yml", also: ["publish:cascade/clean_room_gate"], checker: "scripts/release/autopilot.sh#clean-room.yml", provenance: "APR-RELEASE-001 T-3 (infra#621)", producer: "cleanroom-cpu"} - {id: RR-P03, applies_to: [publish], seven: binaries-before-public, anchor: "publish:autopilot/publish/bash scripts/check_release_assets.sh", also: ["publish:autopilot/assets/gh-workflow binary-release.yml", "tag:autopilot/tag/gh-workflow binary-release.yml"], checker: "scripts/check_release_assets.sh", provenance: "#4657 #4659 release binaries; #4690 the draft goes public only with its assets verified (#4688: was RR-P37)", producer: "assets"} - {id: RR-P06, applies_to: [publish], kind: mechanics, anchor: "publish:autopilot/preflight/bash scripts/check_publish_preflight.sh", also: ["publish:cascade/if [ -f .cargo/config.toml ]", "publish:cascade/scripts/check_publish_preflight.sh"], checker: "scripts/check_publish_preflight.sh", provenance: "PMAT-745 publish preflight", producer: "preflight"} diff --git a/docs/roadmaps/entries/PMAT-5174.yaml b/docs/roadmaps/entries/PMAT-5174.yaml new file mode 100644 index 0000000000..3d4e2198e5 --- /dev/null +++ b/docs/roadmaps/entries/PMAT-5174.yaml @@ -0,0 +1,18 @@ +- id: PMAT-5174 + github_issue: 5174 + item_type: task + title: 'Release: decide where the R5 dogfood receipt belongs on the publish path' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T02:43:24Z + updated: 2026-10-12T02:43:24Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 diff --git a/docs/roadmaps/roadmap.yaml b/docs/roadmaps/roadmap.yaml index 57ddce108c..0bd9fdbcec 100644 --- a/docs/roadmaps/roadmap.yaml +++ b/docs/roadmaps/roadmap.yaml @@ -24753,3 +24753,21 @@ Not done, pending the ruling: moving the 31 fixture files to an obviously synthe - kind:code notes: null epic: 3998 +- id: PMAT-5174 + github_issue: 5174 + item_type: task + title: 'Release: decide where the R5 dogfood receipt belongs on the publish path' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T02:43:24Z + updated: 2026-10-12T02:43:24Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 diff --git a/scripts/check_publish_preflight.sh b/scripts/check_publish_preflight.sh index 66de1988d8..1b129b1705 100755 --- a/scripts/check_publish_preflight.sh +++ b/scripts/check_publish_preflight.sh @@ -33,6 +33,9 @@ # R5 the newest dogfood receipt (`.dogfood/receipt-*.json`, written by # scripts/dogfood.sh) says `verdict: GO` for THIS commit and THIS # version. A stale receipt, a NO-GO, or no receipt at all refuses. +# Under the STANDING RELEASE POLICY (as R8 below) R5 is not run (#5174): the pre-publish +# dogfood never went green on a release and takes ~55 min, so it is not a release gate; it is +# a nightly lane, ticketed on red. `--receipt-only` still judges every receipt it is given. # R7 the model matrix (#3717, #3712): the per-host receipts COMMITTED in this tree for this # version (evidence/dogfood/models//, put there by the bump, #3708) are judged by # scripts/check_model_ladder.sh -- the same judge autopilot's T-1 `models` step runs on its @@ -135,6 +138,13 @@ newest_receipt() { # dir -> path of the newest receipt-*.json, or nothing # rule_r5 root head version -> prints its row; 0 accepted, 1 refused rule_r5() { local root="$1" head="$2" version="$3" rdir receipt verdict rcommit rversion rphase rdeferred ropen bad_defer g + # The STANDING RELEASE POLICY covers this version: R5 is not run at all and no receipt is read (#5174). + # The pre-publish dogfood is a nightly lane; it returns here only as a GATE the operator rules in. + if [ "${POL_APPLIES:-0}" = 1 ]; then + echo "ok R5 STANDING RELEASE POLICY covers $version: the pre-publish dogfood was not run and no receipt was read; CRUX smoke (R7) is the release gate" + R5_SCOPED=1 + return 0 + fi rdir="${PUBLISH_PREFLIGHT_RECEIPT_DIR:-$root/.dogfood}" receipt="$(newest_receipt "$rdir")" if [ -z "$receipt" ]; then @@ -447,6 +457,7 @@ gate() { local root="${PUBLISH_PREFLIGHT_ROOT:-}" release_ref r4_ref r4_on local fails=0 status version tags head R8_SCOPED="" + R5_SCOPED="" for t in git cargo python3; do command -v "$t" >/dev/null 2>&1 || die_env "$t is not on PATH" done @@ -482,7 +493,7 @@ gate() { local prc=0 policy_ladder "$root" "$version" || prc=$? case "$prc" in - 0) [ "$POL_APPLIES" != 1 ] || echo "POLICY: crux-smoke -- the standing release policy in contracts/model-capability-ladder-v1.yaml covers $version: CRUX smoke under R7 is the release gate, R8 is not run, the larger ladder rows are nightly" ;; + 0) [ "$POL_APPLIES" != 1 ] || echo "POLICY: crux-smoke -- the standing release policy in contracts/model-capability-ladder-v1.yaml covers $version: CRUX smoke under R7 is the release gate, R5 and R8 are not run, the larger ladder rows are nightly" ;; *) echo "FAIL R7/R8 the standing release policy cannot be applied to $version, so neither the scope nor the full gate can be chosen: $POL_WHY" fails=1; pol_bad=1 ;; esac @@ -565,9 +576,9 @@ gate() { return 1 fi if [ -n "${SCOPE:-}" ]; then - echo "PASS $PROG: clean, versioned, tagged, on $release_ref, dogfood GO, OPERATOR EMERGENCY SCOPE $SCOPE satisfied (the model matrix was NOT the gate${R8_SCOPED:+; release-readiness was NOT the gate})" + echo "PASS $PROG: clean, versioned, tagged, on $release_ref, $([ -n "${R5_SCOPED:-}" ] && echo "the dogfood was NOT the gate" || echo "dogfood GO"), OPERATOR EMERGENCY SCOPE $SCOPE satisfied (the model matrix was NOT the gate${R8_SCOPED:+; release-readiness was NOT the gate})" else - echo "PASS $PROG: clean, versioned, tagged, on $release_ref, dogfood GO, model matrix green" + echo "PASS $PROG: clean, versioned, tagged, on $release_ref, $([ -n "${R5_SCOPED:-}" ] && echo "the dogfood was NOT the gate" || echo "dogfood GO"), model matrix green" fi return 0 } @@ -618,6 +629,9 @@ receipt_gate() { return 1 fi echo "ok R2 version $version (cargo metadata, root manifest)" + # No policy is read here: --receipt-only judges the receipt it is given, whatever the release (the + # nightly negative control asks it to refuse a nightly receipt). + POL_APPLIES=0 if ! rule_r5 "$root" "$head" "$version"; then echo "REFUSE $PROG --receipt-only: the T-4 publish gate would refuse this receipt (R5)." return 1 @@ -1021,11 +1035,19 @@ FXREADY FX_SCOPE_RC=1 row policy_scope_red_refuses 1 "FAIL R7 OPERATOR EMERGENCY SCOPE crux-smoke NOT satisfied" "$d" FX_READINESS_RC=1 row policy_r8_is_not_the_gate 0 "release-readiness was NOT the gate" "$d" FX_READINESS_RC=1 row policy_r8_is_not_run 0 "ok R8 STANDING RELEASE POLICY covers 1.2.3: release-readiness was not run" "$d" + # #5174: under the policy R5 reads no receipt -- a NO-GO one, or none at all, does not refuse -- + # and --receipt-only still refuses the same NO-GO receipt. + write_receipt "$d" NO-GO "$(git -C "$d" rev-parse HEAD)" 1.2.3 + row policy_r5_is_not_run 0 "ok R5 STANDING RELEASE POLICY covers 1.2.3: the pre-publish dogfood was not run" "$d" + row policy_pass_names_dogfood_not_gate 0 "the dogfood was NOT the gate" "$d" + POL_APPLIES=1 row policy_receipt_only_still_judges 1 "FAIL R5 dogfood receipt" "$d" receipt_gate d="$tmp/pol-rc"; build_repo "$d"; record_policy "$d" 1.2.3 row policy_since_equal_covers 0 "POLICY: crux-smoke" "$d" d="$tmp/pol-later"; build_repo "$d"; record_policy "$d" 1.2.4 FX_READINESS_RC=1 row policy_later_r8_enforced 1 "FAIL R8 the release-readiness wrapper exited 1" "$d" FX_LADDER_RC=1 row policy_later_r7_is_matrix 1 "FAIL R7 model matrix NOT green" "$d" + write_receipt "$d" NO-GO "$(git -C "$d" rev-parse HEAD)" 1.2.3 + row policy_later_r5_enforced 1 "FAIL R5 dogfood receipt" "$d" d="$tmp/pol-dup"; build_repo "$d"; record_policy "$d" 1.2.0 1.2.3 row policy_and_record_refuse 1 "one release takes one ruling" "$d" FX_READINESS_RC=1 row policy_and_record_no_scope 1 "FAIL R8 the release-readiness wrapper exited 1" "$d" diff --git a/scripts/check_release_t1_lanes_joined.sh b/scripts/check_release_t1_lanes_joined.sh index d312f6af17..2e0dd7a894 100755 --- a/scripts/check_release_t1_lanes_joined.sh +++ b/scripts/check_release_t1_lanes_joined.sh @@ -16,12 +16,12 @@ # overlap two 3 s lanes -> rc 0 in under 5 s (in series they need 6) # interrupt TERM to the run -> rc 1 within seconds, nothing after the join, dogfood's child gone # self-red models red; dogfood, signalled, exits 1 by itself -> dogfood RED (not STOPPED), both named -# and under the standing release policy (D2, #4930), where dogfood's ladder gate reads models' receipts: -# policy-order both green -> dogfood starts no earlier than models ends -# policy-models-red models red -> rc 1, dogfood NOT-RUN and never started -# policy-solo dogfood alone -> not held, rc 0 -# and, on the autopilot text itself, that t1_dogfood exports MODEL_LADDER_CRUX_DIR and CRUX_CERT under -# the policy (the pair the T-4 preflight reads), that dogfood builds into its own target dir under +# and under the standing release policy, where the pre-publish dogfood is not run (#5174): +# policy-both both selected -> rc 0, models alone runs (one GO row), dogfood never started, +# one NOT-RUN line +# policy-models-red models red -> rc 1, dogfood never started +# policy-solo dogfood alone -> rc 0, no lane started, the NOT-RUN line +# and, on the autopilot text itself, that dogfood builds into its own target dir under # $REPO_ROOT/target while models keeps CARGO_TARGET_DIR (readiness reads the apr models built), and # that scripts/check_model_parity.sh runs every apr parity under the ladder's GPU lock (dogfood's C14 # parity and the ladder now share the GPU). @@ -84,6 +84,7 @@ case_run() { verdict() { awk -F'\t' -v s="$2" '$1==s {print $5}' "$TMP/$1/t1-steps.tsv" 2>/dev/null; } col() { awk -F'\t' -v s="$2" -v c="$3" '$1==s {print $c}' "$TMP/$1/t1-steps.tsv" 2>/dev/null; } ran() { [ -f "$TMP/$1/dogfood-ran" ]; } +notrun() { [ "$(grep -c 'STEP dogfood NOT-RUN: the standing release policy' "$TMP/$1/STATUS" 2>/dev/null)" = 1 ]; } rows() { tail -n +2 "$TMP/$1/t1-steps.tsv" 2>/dev/null | wc -l; } after() { grep -q 'AFTER-JOIN' "$TMP/$1/STATUS" 2>/dev/null; } child_gone() { local c; c=$(cat "$TMP/$1/dogfood-child" 2>/dev/null); [ -n "$c" ] && ! kill -0 "$c" 2>/dev/null; } @@ -122,20 +123,17 @@ table() { DT=1 case_run "$j" "$t-self" "dogfood models" 0 0 1 1 [ "$C_RC" = 1 ] && [ "$(verdict "$t-self" dogfood)" = RED ] && grep -q 'STOP .*models dogfood RED' "$TMP/$t-self/STATUS" \ || { echo "self-red: rc=$C_RC dogfood=$(verdict "$t-self" dogfood) (want dogfood RED: it exited 1 by itself, not by the signal)"; return 1; } - # D2 (P7 WIRE): under the standing release policy the dogfood's ladder gate reads the CRUX receipts - # the models lane writes, so dogfood starts only once models is GO. - AP_POLICY=1 case_run "$j" "$t-p-order" "dogfood models" 1 0 2 0 - [ "$C_RC" = 0 ] && after "$t-p-order" \ - && [ "$(verdict "$t-p-order" dogfood)$(verdict "$t-p-order" models)" = GOGO ] \ - && [ "$(col "$t-p-order" dogfood 2)" -ge "$(col "$t-p-order" models 3)" ] \ - || { echo "policy-order: rc=$C_RC dogfood start=$(col "$t-p-order" dogfood 2) models end=$(col "$t-p-order" models 3) (want rc 0, 2 GO, dogfood started after models ended)"; return 1; } + # #5174: under the standing release policy the pre-publish dogfood is not run -- models runs alone. + AP_POLICY=1 case_run "$j" "$t-p-both" "dogfood models" 1 0 1 0 + [ "$C_RC" = 0 ] && after "$t-p-both" && ! ran "$t-p-both" && [ "$(rows "$t-p-both")" = 1 ] \ + && [ "$(verdict "$t-p-both" models)" = GO ] && notrun "$t-p-both" \ + || { echo "policy-both: rc=$C_RC rows=$(rows "$t-p-both") models=$(verdict "$t-p-both" models) (want rc 0, models GO alone, dogfood never started, one NOT-RUN line)"; return 1; } AP_POLICY=1 case_run "$j" "$t-p-mred" "dogfood models" 1 0 1 1 - [ "$C_RC" = 1 ] && ! after "$t-p-mred" && ! ran "$t-p-mred" && [ "$(verdict "$t-p-mred" dogfood)" = NOT-RUN ] \ - && [ "$(verdict "$t-p-mred" models)" = RED ] \ - || { echo "policy-models-red: rc=$C_RC dogfood=$(verdict "$t-p-mred" dogfood) (want rc 1, models RED, dogfood NOT-RUN and never started)"; return 1; } + [ "$C_RC" = 1 ] && ! after "$t-p-mred" && ! ran "$t-p-mred" && [ "$(verdict "$t-p-mred" models)" = RED ] \ + || { echo "policy-models-red: rc=$C_RC models=$(verdict "$t-p-mred" models) (want rc 1, models RED, dogfood never started)"; return 1; } AP_POLICY=1 case_run "$j" "$t-p-solo" "dogfood" 1 0 0 0 - [ "$C_RC" = 0 ] && ran "$t-p-solo" && [ "$(rows "$t-p-solo")" = 1 ] \ - || { echo "policy-solo: rc=$C_RC rows=$(rows "$t-p-solo") (want rc 0: dogfood alone is not held)"; return 1; } + [ "$C_RC" = 0 ] && after "$t-p-solo" && ! ran "$t-p-solo" && [ "$(rows "$t-p-solo")" = 0 ] && notrun "$t-p-solo" \ + || { echo "policy-solo: rc=$C_RC rows=$(rows "$t-p-solo") (want rc 0, no lane started, the NOT-RUN line)"; return 1; } return 0 } @@ -156,25 +154,25 @@ dirs() { [ -z "$m" ] || { echo "models moved off CARGO_TARGET_DIR, which readiness reads: $m"; return 1; } } -# crux AUTOPILOT -> 0 when t1_dogfood points the ladder gate at models' receipts under the policy -crux() { - local e - e=$(awk '/^t1_dogfood\(\) \{/{p=1} p&&/MODEL_LADDER_CRUX_DIR=/{print; exit} p&&/^\}/{exit}' "$1") - case "$e" in - *'[ "$AP_POLICY" != 1 ] || export MODEL_LADDER_CRUX_DIR="$AP/models-t1" CRUX_CERT="$WT/evidence/crux/$V/prompt-certification.json"'*) ;; - *) echo "t1_dogfood does not export the models lane's CRUX receipts under the policy: '$e'"; return 1 ;; - esac +# nogo AUTOPILOT -> 0 when every line that can print "dogfood GO" swaps it out under the policy (#5174): +# the dogfood is not run then, so a receipt that names a dogfood GO would be a green nothing measured. +# The post-publish dogfood still runs after the publish, so its GO is struck out before the match. +nogo() { + local bad + bad=$(sed 's/post-publish dogfood GO//g' "$1" | grep -n 'dogfood GO' | grep -v '^[0-9]*:[[:space:]]*#' \ + | grep -vF '[ "$AP_POLICY" != 1 ] || { AP_DF_RECEIPT="dogfood not run (policy)"; AP_DF_CLOSE="pre-publish dogfood not run' || true) + [ -z "$bad" ] || { echo "a line prints dogfood GO with no policy swap: $(printf '%s\n' "$bad" | head -n 1 | cut -c1-100)"; return 1; } } # check AUTOPILOT TAG -> 0 when the join and the dirs hold check() { awk '/^# The join\./{p=1} p{print} p&&/^fi$/{exit}' "$1" > "$TMP/$2.join" grep -q 'wait -n' "$TMP/$2.join" || { echo "no join block (\"# The join.\" .. fi with wait -n)"; return 1; } - dirs "$1" && crux "$1" && locked "${3:-$PARITY}" && table "$TMP/$2.join" "$2" + dirs "$1" && nogo "$1" && locked "${3:-$PARITY}" && table "$TMP/$2.join" "$2" } bad=0 -if why=$(check "$AUTOPILOT" real); then echo "ok the join holds (12 cases), dogfood reads models' CRUX receipts under the policy, dogfood's target dir is its own, parity takes the GPU lock" +if why=$(check "$AUTOPILOT" real); then echo "ok the join holds (12 cases), the dogfood lane is not started under the policy and no line claims a dogfood GO then, dogfood's target dir is its own, parity takes the GPU lock" else echo "FAIL the autopilot's T-1 lanes: $why"; bad=1; fi # The mutants run whatever the real tree did, so report mode prints every line before its verdict. @@ -195,9 +193,12 @@ mutant first-red 's/t1_red="\${t1_red:+\$t1_red }\$s"/t1_red=${t1_red:-$s}/' mutant no-trap "/^ trap 'for p in/d" mutant shared-dogfood '/^ export CARGO_TARGET_DIR="\$REPO_ROOT\/target\/t1-dogfood"$/d' mutant stopped-any-rc 's/ \&\& \[ "\$rc" -eq "\$t1_term_rc" \]; then v=STOPPED/; then v=STOPPED/' -mutant no-hold 's/ || t1_held=dogfood ;; esac$/ || : ;; esac/' -mutant held-after-red 's/^ if \[ "\$v" = GO \] && \[ -z "\$t1_red" \]; then$/ if :; then/' -mutant no-crux-env '/export MODEL_LADDER_CRUX_DIR="\$AP\/models-t1"/d' +mutant policy-runs-dogfood 's/ \&\& \[ "\$s:\$AP_POLICY" != dogfood:1 \]//' +mutant policy-drops-every-lane 's/\[ "\$s:\$AP_POLICY" != dogfood:1 \]/[ "$AP_POLICY" != 1 ]/' +mutant no-not-run-line '/^\[ "\$AP_POLICY" != 1 \] || ! run_step dogfood || say /d' +mutant dryrun-claims-go 's/receipts: \$AP_DF_RECEIPT, tag/receipts: dogfood GO, tag/' +mutant close-claims-go 's/Receipts: \$AP_DF_CLOSE, all/Receipts: pre-publish dogfood GO, all/' +mutant no-policy-swap 's/; \[ "\$AP_POLICY" != 1 \] || { AP_DF_RECEIPT="dogfood not run (policy)".*$//' nm=$((nm + 1)) sed -e 's/flock -E 75 -w "\${MODEL_LADDER_LOCK_WAIT:-1800}" "\${MODEL_LADDER_GPU_LOCK:-\/tmp\/apr-gpu.lock}"/env/' "$PARITY" > "$TMP/m-parity.sh" if cmp -s "$PARITY" "$TMP/m-parity.sh"; then echo "FAIL mutant parity-unlocked did not apply (anchor moved)"; fails=$((fails + 1)) @@ -205,5 +206,5 @@ elif why=$(check "$AUTOPILOT" m-parity "$TMP/m-parity.sh"); then echo "FAIL mut else echo "ok mutant parity-unlocked killed ($why)"; fi [ "$fails" -eq 0 ] || { echo "FAIL $fails of $nm mutant(s)"; finish 1; } [ "$bad" = 0 ] || finish 1 -echo "PASS 12 case(s) + CRUX env + target dirs + parity lock, $nm mutant(s) killed: dogfood and models start together (dogfood held for models under the policy), join before readiness, and a red in either stops the pass" +echo "PASS 12 case(s) + target dirs + no dogfood GO under the policy + parity lock, $nm mutant(s) killed: dogfood and models start together (under the policy models runs alone, #5174), join before readiness, and a red in either stops the pass" finish 0 diff --git a/scripts/release/autopilot.sh b/scripts/release/autopilot.sh index 74fe5c17ad..2ec77a77ee 100755 --- a/scripts/release/autopilot.sh +++ b/scripts/release/autopilot.sh @@ -166,7 +166,10 @@ export CARGO_TARGET_DIR="$REPO_ROOT/target" # The standing release policy, judged ONCE from the release commit: it picks the models lane mode and # whether readiness runs. cut_tag re-judges it itself (a log is not the gate). AP_POLICY=$(ap_policy_applies "$V" 2>> "$LOG") || die "the standing release policy cannot be judged for $V (see $LOG): nothing is measured" -[ "$AP_POLICY" != 1 ] || say "POLICY: the standing release policy covers $V -- CRUX smoke on lambda and gx10 is the release gate, readiness (R8) is not run, the larger ladder rows are nightly" +# #5174: under the policy the pre-publish dogfood is not run, so no receipt this run prints may claim a dogfood GO +# (check_release_t1_lanes_joined.sh refuses any line that prints one without this swap). +AP_DF_RECEIPT="dogfood GO"; AP_DF_CLOSE="pre-publish dogfood GO at \`$MC\`"; [ "$AP_POLICY" != 1 ] || { AP_DF_RECEIPT="dogfood not run (policy)"; AP_DF_CLOSE="pre-publish dogfood not run (standing release policy)"; } +[ "$AP_POLICY" != 1 ] || say "POLICY: the standing release policy covers $V -- CRUX smoke on lambda and gx10 is the release gate, the pre-publish dogfood (R5) and readiness (R8) are not run, the larger ladder rows are nightly" # #4950: the cascade publishes to crates.io, which cannot be undone, so it re-proves its own premise # instead of trusting the cleanroom step's files: the tag on origin is MC, the clean-room (aprender) job @@ -227,14 +230,12 @@ cascade_no_secret_green() { # measured at the release version, and R5 at T-4 refused it anyway: v0.69.0 stopped at the publish # preflight 43 min after tagging and ran the real dogfood then, with the tag already public. # Now the real dogfood runs here and writes the receipt in this worktree. R5 is judged once, at T-4 -# (check_publish_preflight.sh R5, an `also` anchor of RR-T09); the T-1 --receipt-only repeat was a duplicate +# (check_publish_preflight.sh R5); the T-1 --receipt-only repeat was a duplicate # stop and left the release path (#4688). +# Under the standing release policy this lane is not started and R5 is not run (#5174): it never went +# green on a release, so it is the nightly's dogfood lane, ticketed on red, until ruled back in. t1_dogfood() { export CARGO_TARGET_DIR="$REPO_ROOT/target/t1-dogfood" - # D2 (#4930): under the standing release policy the declared ladder gate (check_model_ladder.sh) judges - # the CRUX receipts the models lane wrote at $MC and the certification committed in the bump -- the same - # pair the T-4 preflight reads. The join starts this lane only after models is GO. - [ "$AP_POLICY" != 1 ] || export MODEL_LADDER_CRUX_DIR="$AP/models-t1" CRUX_CERT="$WT/evidence/crux/$V/prompt-certification.json" bash scripts/dogfood.sh --phase pre-publish > "$AP/dogfood-pre-publish.log" 2>&1; rc=$? grep -E 'VERDICT' "$AP/dogfood-pre-publish.log" >> "$STATUS" [ $rc -eq 0 ] || die "dogfood pre-publish NO-GO rc=$rc ($AP/dogfood-pre-publish.log)" @@ -293,22 +294,20 @@ t1_models_rehearsal() { # build and ladder running in the release dir the next pass reuses. models runs to its own verdict. # An INT or TERM to the autopilot stops every lane (the lanes no longer share its process group), # models included: the operator chose to stop, and the remote leg may run on to its own end. -# HELD LANE (D2, #4930). Under the standing release policy dogfood's ladder gate judges the CRUX -# receipts models writes to $AP/models-t1, so with both selected dogfood is HELD: it starts when -# models exits GO and no lane is red, else its row reads NOT-RUN and it never starts. -# Dogfood selected alone is not held: it reads whatever an earlier pass left in $AP/models-t1. +# Under the standing release policy dogfood is not a lane at all (#5174; it replaced the D2 hold of +# #4930): models runs alone, and a dogfood selection prints one NOT-RUN line. # scripts/check_release_t1_lanes_joined.sh runs this block against stub lanes, and its mutants. -T1_LANES=(); for s in dogfood models; do run_step "$s" && T1_LANES+=("$s"); done +# Under the standing release policy the dogfood lane is not started (#5174); release_ready.sh reads the +# `[ "$s:$AP_POLICY" != :1 ]` form as that lane being off the release path. +T1_LANES=(); for s in dogfood models; do run_step "$s" && [ "$s:$AP_POLICY" != dogfood:1 ] && T1_LANES+=("$s"); done +[ "$AP_POLICY" != 1 ] || ! run_step dogfood || say "STEP dogfood NOT-RUN: the standing release policy covers this release, so the pre-publish dogfood is not a release gate (R5 is not run at T-4); it is a nightly lane" if [ "${#T1_LANES[@]}" -gt 0 ]; then declare -A T1_STEP=() T1_T0=() T1_STOPPED=() trap 'for p in "${!T1_STEP[@]}"; do kill -TERM -- "-$p" 2> /dev/null; done; die "T-1 lanes interrupted"' INT TERM - t1_held='' - case " ${T1_LANES[*]} " in *" dogfood "*"models "*) [ "$AP_POLICY" != 1 ] || t1_held=dogfood ;; esac - T1_NOW=(); for s in "${T1_LANES[@]}"; do [ "$s" = "$t1_held" ] || T1_NOW+=("$s"); done t1_launch=$SECONDS; set -m - for s in "${T1_NOW[@]}"; do "t1_$s" & T1_STEP[$!]=$s; T1_T0[$s]=$SECONDS; done + for s in "${T1_LANES[@]}"; do "t1_$s" & T1_STEP[$!]=$s; T1_T0[$s]=$SECONDS; done set +m - say "T-1 LANES started together: ${T1_LANES[*]}${t1_held:+ ($t1_held held until models is GO)}" + say "T-1 LANES started together: ${T1_LANES[*]}" [ -f "$AP/t1-steps.tsv" ] || printf 'step\tstart\tend\tseconds\tverdict\n' > "$AP/t1-steps.tsv" t1_red=''; t1_term_rc=$((128 + $(kill -l TERM))) while [ "${#T1_STEP[@]}" -gt 0 ]; do @@ -325,16 +324,6 @@ if [ "${#T1_LANES[@]}" -gt 0 ]; then T1_STOPPED[${T1_STEP[$p]}]=1; kill -TERM -- "-$p" 2> /dev/null done fi - if [ "$s" = models ] && [ -n "$t1_held" ]; then - s=$t1_held; t1_held='' - if [ "$v" = GO ] && [ -z "$t1_red" ]; then - set -m; "t1_$s" & T1_STEP[$!]=$s; T1_T0[$s]=$SECONDS; set +m - say "STEP $s started: models is GO, its CRUX receipts are in $AP/models-t1" - else - printf '%s\t%s\t%s\t0\tNOT-RUN\n' "$s" "$((t1 - t1_launch))" "$((t1 - t1_launch))" >> "$AP/t1-steps.tsv" - say "STEP $s NOT-RUN: held for models' CRUX receipts, and $t1_red went red first" - fi - fi done trap - INT TERM [ -z "$t1_red" ] || die "T-1 lane(s) $t1_red RED: dogfood was stopped, models ran to its verdict, nothing is tagged ($AP/t1-steps.tsv)" @@ -600,7 +589,7 @@ if run_step dryrun; then behind=$(grep -cE "\(want ${V//./\\.}\)" "$AP/cascade-check.log" || true) tail -3 "$AP/cascade-check.log" >> "$STATUS" say "DRYRUN cascade-publish.sh --check rc=$rc crates_behind=$behind ($AP/cascade-check.log)" - say "DRYRUN-RECEIPT T-4 proceeds unattended (standing authorization 2026-09-17, reconfirmed by the operator 2026-09-20 \"never wait for me\"); receipts: dogfood GO, tag $T, clean-room run $(cat "$AP/cleanroom-run-id" 2>/dev/null), assets, preflight, dry-run" + say "DRYRUN-RECEIPT T-4 proceeds unattended (standing authorization 2026-09-17, reconfirmed by the operator 2026-09-20 \"never wait for me\"); receipts: $AP_DF_RECEIPT, tag $T, clean-room run $(cat "$AP/cleanroom-run-id" 2>/dev/null), assets, preflight, dry-run" fi # 6. crates.io cascade: multi-pass drain, then the check is the verdict (pass 1 exiting 1 is normal) @@ -844,7 +833,7 @@ if run_step close; then # SEC010 (bashrs-gate): read the run id with the read builtin, not $(cat "$AP/…") -- AP is derived # now (#3655), so a cat over it inside the message is flagged as a path-traversal risk. cleanroom_run_id=unknown; IFS= read -r cleanroom_run_id < "$AP/cleanroom-run-id" 2>/dev/null || cleanroom_run_id=unknown - gh issue comment "$EPIC" --repo $REPO --body "$T released: $(gh release view "$T" --repo $REPO --json url -q .url). Receipts: pre-publish dogfood GO at \`$MC\`, all release assets verified by \`scripts/check_release_assets.sh $T\`, crates.io cascade complete, the CUDA asset downloaded, verified and run on gx10 and yoga. clean-room (aprender) green on the tag (run ${cleanroom_run_id}), install.sh receipts on intel and gx10, post-publish dogfood GO over the host receipts of every host in the multi-platform matrix. Logs: $AP on $(hostname)." >> "$LOG" 2>&1 || say "WARN epic comment failed" + gh issue comment "$EPIC" --repo $REPO --body "$T released: $(gh release view "$T" --repo $REPO --json url -q .url). Receipts: $AP_DF_CLOSE, all release assets verified by \`scripts/check_release_assets.sh $T\`, crates.io cascade complete, the CUDA asset downloaded, verified and run on gx10 and yoga. clean-room (aprender) green on the tag (run ${cleanroom_run_id}), install.sh receipts on intel and gx10, post-publish dogfood GO over the host receipts of every host in the multi-platform matrix. Logs: $AP on $(hostname)." >> "$LOG" 2>&1 || say "WARN epic comment failed" # The epic is IN the milestone, so "0 open items" could never hold while it was open, and nothing # here closed it: 0.68.2's #3477 was closed by hand (#3708). Every OTHER item must be closed first; # then the epic, then the milestone. Any other open item refuses both. diff --git a/scripts/release/release_ready.sh b/scripts/release/release_ready.sh index 4b2b71e403..7728ee7337 100755 --- a/scripts/release/release_ready.sh +++ b/scripts/release/release_ready.sh @@ -198,13 +198,18 @@ autopilot_found() { } } } - # parallel lanes: `for s in a b c; do run_step "$s"` launched as `"t1_$s" &`; each step is its t1_ body + # parallel lanes: `for s in a b c; do run_step "$s"` launched as `"t1_$s" &`; each step is its t1_ body. + # A lane the loop line names in `[ "$s:$AP_POLICY" != :1 ]` is not started under the standing release + # policy: that lane, and only that lane, is off the release path (#5174) for (i = 1; i <= NR; i++) { if (L[i] !~ /for s in [a-z ]+; [d]o run_step "\$s"/) continue ls = L[i]; sub(/.*for s in /, "", ls); sub(/;.*/, "", ls); nl = split(ls, LN, / +/) + delete LOFF; t = L[i] + while (match(t, /\[ "\$s:\$AP_POLICY" != [a-z]+:1 \]/)) { w = substr(t, RSTART, RLENGTH); t = substr(t, RSTART + RLENGTH); sub(/.*!= /, "", w); sub(/:1 \]$/, "", w); LOFF[w] = 1 } for (j = 1; j <= nl; j++) { st = LN[j]; fn = "t1_" st if (!(st in PH) || !(fn in FS0)) { unk = 1; continue } + if (st in LOFF) continue if (PH[st] == "") continue delete seen for (e = FS0[fn] + 1; e < FE[fn]; e++) { @@ -366,6 +371,15 @@ claims() { printf '%s\n' "$out" } +# dogfood_lane_off AUTOPILOT: rc 0 when the T-1 lane loop names a dogfood lane and takes it off under the standing +# release policy (`[ "$s:$AP_POLICY" != dogfood:1 ]`, #5174). The pre-publish dogfood then does not run, so the rows +# it can mark FAIL are off the release path with it, as R8's are with readiness. +dogfood_lane_off() { + awk '/for s in [a-z ]+; [d]o run_step "\$s"/ { ls = $0; sub(/.*for s in /, "", ls); sub(/;.*/, "", ls) + if ((" " ls " ") ~ / dogfood / && index($0, "[ \"$s:$AP_POLICY\" != dogfood:1 ]")) f = 1 } + END { exit f ? 0 : 1 }' "$1" +} + # found ROOT: every anchor the surfaces state; rc 2 when a surface is missing or unreadable found() { local root=$1 f @@ -377,7 +391,7 @@ found() { autopilot_found "$root/$AUTO_REL" "$AUTO_REL" || { printf 'surface unreadable: %s steps\n' "$AUTO_REL" >&2; return 2; } preflight_found "$root/$PRE_REL" "$PRE_REL" || { printf 'surface unreadable: %s RULES\n' "$PRE_REL" >&2; return 2; } cascade_found "$root/$CAS_REL" "$CAS_REL" || { printf 'surface unreadable: %s gates\n' "$CAS_REL" >&2; return 2; } - dogfood_found "$root/$DF_REL" "$root/$CARGO_REL" "$DF_REL" "$CARGO_REL" || { printf 'surface unreadable: %s rows\n' "$DF_REL" >&2; return 2; } + dogfood_lane_off "$root/$AUTO_REL" || dogfood_found "$root/$DF_REL" "$root/$CARGO_REL" "$DF_REL" "$CARGO_REL" || { printf 'surface unreadable: %s rows\n' "$DF_REL" >&2; return 2; } } # ---------------------------------------------------------------- the list ---------------------------------------- @@ -668,6 +682,14 @@ YML # plant DIR FILE TEXT: append TEXT as a line of FILE (relative to DIR) plant() { printf '%s\n' "$3" >> "$1/$2"; } +# dogfood_lane DIR: a second T-1 lane, dogfood, beside deep (a tag step whose body runs the pre-publish dogfood) +dogfood_lane() { + edit "$1" "$AUTO_REL" 's/^# steps: wait deep tag/# steps: wait deep dogfood tag/' \ + && edit "$1" "$AUTO_REL" 's/^STEPS=(wait deep tag/STEPS=(wait deep dogfood tag/' \ + && edit "$1" "$AUTO_REL" 's/for s in deep; do/for s in deep dogfood; do/' \ + && plant "$1" "$AUTO_REL" 't1_dogfood() {' && plant "$1" "$AUTO_REL" ' bash scripts/dogfood.sh --phase pre-publish || die x' \ + && plant "$1" "$AUTO_REL" '}' +} # edit DIR FILE SED: one sed program on FILE; a program that changes nothing is a broken case, not a pass edit() { local before @@ -737,6 +759,11 @@ mutate() { && plant "$d" "$DF_REL" 'else' && plant "$d" "$DF_REL" ' mark post-row FAIL "x"' && plant "$d" "$DF_REL" 'fi' ;; unlisted-lane-cargo) edit "$d" "$AUTO_REL" '/^ cargo metadata --locked/a\ cargo test --doc --workspace' ;; nm-lane-no-function) edit "$d" "$AUTO_REL" 's/^t1_deep() {/t1_deeep() {/' ;; + orphaned-policy-off-lane) edit "$d" "$AUTO_REL" 's/do run_step "$s" \&\& T1/do run_step "$s" \&\& [ "$s:$AP_POLICY" != deep:1 ] \&\& T1/' ;; + green-policy-off-names-another-lane) edit "$d" "$AUTO_REL" 's/do run_step "$s" \&\& T1/do run_step "$s" \&\& [ "$s:$AP_POLICY" != dogfood:1 ] \&\& T1/' ;; + unlisted-dogfood-lane-ungated) dogfood_lane "$d" ;; + orphaned-policy-off-dogfood-lane) dogfood_lane "$d" \ + && edit "$d" "$AUTO_REL" 's/do run_step "$s" \&\& T1/do run_step "$s" \&\& [ "$s:$AP_POLICY" != dogfood:1 ] \&\& T1/' ;; nm-dogfood-missing) rm -f -- "${d:?}/$DF_REL" ;; nm-dogfood-unbalanced) plant "$d" "$DF_REL" 'if [ -n "$X" ]; then' ;; nm-dogfood-no-declared) edit "$d" "$CARGO_REL" '/check_x.sh/d' ;; @@ -830,6 +857,10 @@ unlisted-sourced-lib 1 UNLISTED tag:autopilot/tag/source scripts/lib/new_lib.sh unlisted-tag-push 1 UNLISTED tag:autopilot/tag/git push origin orphaned-policy-off-step 1 ORPHANED FX-P1 orphaned-policy-off-rule 1 ORPHANED FX-P4 +orphaned-policy-off-lane 1 ORPHANED FX-T3 +green-policy-off-names-another-lane 0 unlisted=0 orphaned=0 contradictions=0 listed=15 stated=16 +unlisted-dogfood-lane-ungated 1 UNLISTED tag:autopilot/dogfood/bash scripts/dogfood.sh +orphaned-policy-off-dogfood-lane 1 unlisted=0 orphaned=3 contradictions=0 green-policy-guard-runs-a-call 0 unlisted=0 orphaned=0' selftest() { @@ -984,7 +1015,11 @@ M59 sourced lib ignored@@out = out "\nsource " w@@out = out M60 tag push ignored@@out = out "\ngit push origin"@@out = out M61 policy-off step read@@if (i in OFF) continue@@if (0) continue M62 policy-off rule read@@if (!(x in OFF)) printf@@if (1) printf -M63 any body is policy-off@@ok = 0 }@@ok = 1 }' +M63 any body is policy-off@@ok = 0 }@@ok = 1 } +M64 policy-off lane read@@if (st in LOFF) continue@@if (0) continue +M65 a policy-off form excuses the whole loop@@if (st in LOFF) continue@@if (length(LOFF)) continue +M66 dogfood rows read with the lane off@@dogfood_lane_off "$root/$AUTO_REL" ||@@false || +M67 dogfood rows dropped by a form on a loop without dogfood@@if ((" " ls " ") ~ / dogfood / && index@@if (index' mutants() { local tmp line id name from to killed=0 total=0 err=0