Skip to content

R11 (#4690): no public GitHub release before its assets, clean-room and preflight - #4883

Merged
noahgift merged 7 commits into
mainfrom
build-kaizen/0702-r11-draft-release
Oct 6, 2026
Merged

noahgift merged 7 commits into
mainfrom
build-kaizen/0702-r11-draft-release

Conversation

@noahgift

@noahgift noahgift commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • scripts/release/autopilot.sh keeps the GitHub release a draft. A new publish step makes it public only after assets, the clean-room run and preflight. The step order becomes … tag cleanroom assets preflight publish dryrun ….
  • New check: scripts/release/check_release_draft_gated.sh.
  • Contract update: contracts/tag-step-milestone-gate-v1.yaml.

Commit: 8b2d33e (Agent: aprender-78).

Status

  • Opened by the release cop (aprender-a3) as item 2b of the 0.70.2 one-pass plan. The branch merges into main ec7b511 with no conflicts.
  • Still to come on this branch: the publish dry run (dryrun, still after tag at 8b2d33e) moves ahead of the tag.
  • It changes what a gate accepts. Before it is armed, it needs a quorum sign-off round by a non-author on the final commit, two non-author reviews and green CI. Not armed.

Closes #4690

🤖 Generated with Claude Code

noahgift and others added 2 commits October 4, 2026 13:32
…nd preflight

The autopilot created a public release right after the tag push, ahead of
the cleanroom, assets and preflight steps. binary-release.yml fired on
`release: published`, so the assets could only be built by publishing first:
the order was inverted by design.

Now:
  tag step      gh release create --draft, then binary-release.yml is
                dispatched on the tag (workflow_dispatch, input tag, the tag's
                own workflow file). Every upload step already finds the
                release by listing, which returns drafts.
  assets step   waits for that dispatch run (--event workflow_dispatch).
  preflight     writes "PASS <tag> <commit>" on success, truncated first.
  publish (new step, between preflight and dryrun) publish_release()
                re-reads each fact itself and only then runs
                gh release edit --draft=false:
                  clean-room (aprender) job = success on the recorded run;
                  a preflight PASS naming this tag and commit;
                  check_release_assets.sh <tag> = 0 (1 and 2 both refuse);
                  the release is still a draft.
Publishing then fires `release: published` once more; that run finds every
asset present and rebuilds nothing (#4286). No token is widened and no check
is renamed; binary-release.yml is unchanged.

Case table: scripts/release/check_release_draft_gated.sh extracts the
autopilot's own tag..publish step bodies and runs them against a stub gh
that records the call order (gh api writes, failing edits, a missing
release and --jq filters modelled; rows may resume over shared state),
plus 4 structural rows over the whole file: only publish_release() sets
draft to false, every create is a --draft, publish_release is called once
from the publish step, and publish follows its gates in STEPS and file.
  before (origin/main 316dee2 autopilot.sh):
    bash scripts/release/check_release_draft_gated.sh <main copy>
    17/17 rows WRONG + 3/4 structural WRONG; every run row reads
    public-EARLY (created public at the tag step) or, for publish-alone
    rows, no refusal at all
  after (this commit):
    bash scripts/release/check_release_draft_gated.sh
    17/17 rows + 4/4 structural ok, mutants 19/19 killed, 18 s
It lives in scripts/release/, outside guard_tree's universe: report-only
until three green nights (L31).

Contract: tag-step-milestone-gate-v1 1.0.0 -> 1.1.0, equation
release_is_draft_until_gated, TSMG-INV-004, FALSIFY-TSMG-007.

ont-delta: none (extends an existing pattern contract; no new kind, class or edge)

Agent: aprender-78
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review round 2 found three ways past the table: a publish in a step it does
not run, spelled through a variable (--draft=$F); publish_release called
through a variable; and a clean-room check weakened to `!= failure`, which
only success/failure fixtures could not see.
- structure: outside publish_release(), with `\` continuations joined, any
  draft set by value (--draft=X, -f/-F draft=X, a JSON "draft": X) and any
  `gh api` write to a release (-X/--method/-f/-F/--field/--input) is RED,
  whatever X is; a plain `--draft` stays allowed, as does a notes edit.
- structure: any mention of publish_release, not only a call followed by a
  space, counts toward "called once, from the publish step".
- rows: a cancelled clean-room (full run and publish alone) and an empty
  conclusion (publish alone).
- mutants: draft-by-variable, publish-by-variable, api-field-variable,
  api-input-body, cleanroom-not-failure.
  before (origin/main 316dee2 autopilot.sh):
    bash scripts/release/check_release_draft_gated.sh <main copy>
    20/20 rows WRONG + 3/4 structural WRONG
  after (this commit):
    bash scripts/release/check_release_draft_gated.sh
    20/20 rows + 4/4 structural ok, mutants 24/24 killed

ont-delta: none (prose of FALSIFY-TSMG-007's prediction; no new kind, class or edge)

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

github-actions Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

§13.11 rung 1 — quorum shadow verdict

S13-SHADOW pr=4883 head=637d4aca05c9136377f2d35cce227218a9ce9abb 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 and others added 3 commits October 6, 2026 19:29
Agent: aprender-78
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ity guard can judge release scripts (#4690)

check_release_scripts_derive_identity.sh reads every script under
scripts/release/ and refuses a literal train identity (R2) or a literal
count (R3). check_release_draft_gated.sh builds a fixture train with a
fixed version and a fixed row count, so it was RED there on two lines.

It is a guard, not a release script: it moves to scripts/ beside the
other check_*.sh guards and reads autopilot.sh from scripts/release/.
No rule of the identity guard changes.

Measured on this tree:
  bash scripts/check_release_draft_gated.sh            rc 0, mutants 24/24
  bash scripts/check_release_scripts_derive_identity.sh rc 0 (was R2 + R3 FAIL)

Agent: aprender-78
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
autopilot ran `rc_publish_gate.sh --verify` (every publishable tarball
built against the local overlay, = cargo publish --dry-run for the whole
cascade) in the `dryrun` step, after the tag was pushed and the draft and
asset build existed. A tarball that does not compile was found only after
the irreversible steps.

Now the tag step runs it first, on the worktree at the release commit the
tag will name, and dies on red before cut_tag: no carry, no tag, no draft.
A green run writes publish-dryrun-commit = the release commit. The
`dryrun` step keeps cascade-publish.sh --check and the T-4 receipt, and
requires that receipt to name exactly the release commit; a missing one
or another commit's is red, never a skip. STEPS and their order do not
change, so every anchor that reads them stays put.

Guards:
- rc_publish_gate.sh --self-test: the wiring check now requires --verify
  and its die inside `if run_step tag`, before cut_tag, and a fixture with
  the old order (dry run after the tag) is refused by the same predicate.
- release-ready list: RR-P07 moves to RR-T16 (tag). RR-T17 and RR-P37
  list the asset dispatch in `tag` and the asset check in `publish`, which
  this branch had left unlisted. The header's step list names `publish`.
- check_release_draft_gated.sh: its harness stubs rc_publish_gate.sh and
  sets WT, as it already stubs tag_coverage_gate.sh. No case or mutant
  changes.

Measured on this tree:
  bash scripts/release/rc_publish_gate.sh --self-test  PASS (both wiring rows ok)
  bash scripts/release/release_ready.sh  unlisted=0 orphaned=0 contradictions=1
    (was unlisted=2 contradictions=2; the one left is publish.executor,
    also on origin/main 682dab1)
  bash scripts/check_release_draft_gated.sh  rc 0, mutants 24/24
  bash scripts/check_tag_coverage_gated.sh (+ --self-test)  rc 0
  bash scripts/check_release_scripts_derive_identity.sh  rc 0

Agent: aprender-78
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift and others added 2 commits October 6, 2026 19:39
…new guard

Since it moved to scripts/, guard_tree runs it on every merge, and it had no
report mode: a new check would have blocked from its first night. It now
follows the row-order guard's shape. A wrong row or a surviving mutant prints
a REPORT line and exits 0. RELEASE_DRAFT_GATED_ENFORCE=1 makes it exit 1.
ENV stays rc 2 in both modes. The contract's falsification test runs it
under ENFORCE, so the contract still fails on a broken table. The header no
longer says guard_tree skips it.

Measured on this tree: rc 0 by default and under ENFORCE. The create-public
mutant on a copy of the autopilot gives 8 WRONG rows, rc 0 by default and
rc 1 under ENFORCE. A missing autopilot is rc 2.

Refs #4690

Agent: aprender-78
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The receipt and findings for 951a030: the draft guard green at head under
enforce, the publish gate's self-test green, and the guard's create-public
mutant turning 8 rows wrong. The cross-vendor reviewer could not be consulted
(the budget probe exited 126), so the verdict is DEGRADED, not PASS.

Refs #4690

Agent: aprender-78
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@noahgift
noahgift enabled auto-merge October 6, 2026 18:29
@noahgift
noahgift added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit 0341808 Oct 6, 2026
20 checks passed
@noahgift
noahgift deleted the build-kaizen/0702-r11-draft-release branch October 6, 2026 20:01
noahgift added a commit that referenced this pull request Oct 6, 2026
…ain)

Agent: aprender-wprodmodels
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

0.70.2 T15: BLD-002 R11 no public GitHub release before its assets (autopilot.sh order)

1 participant