Skip to content

release(rc): cut rc on green, promote rc bytes to final, publish gate at the rc — batch #4285 #4275 #4286 #4287 - #4314

Closed
noahgift wants to merge 22 commits into
mainfrom
PMAT-4285-rc-cut
Closed

noahgift wants to merge 22 commits into
mainfrom
PMAT-4285-rc-cut

Conversation

@noahgift

@noahgift noahgift commented Sep 24, 2026 •

Copy link
Copy Markdown
Member

One batch PR, one commit per issue (operator, relayed verbatim by the cop: "individual PR is too costly for release canidates and even epics, we should actively batch like PRs together"). It touches .github/workflows/, so it needs a 3/3 quorum plus green CI, and the cop merges it. Auto-merge is NOT armed.

commit issue what
096ff9f #4285 rc-cut.yml + rc_cut.sh: when CI goes green on the tip of release/X.Y.Z, cut vX.Y.Z-rc.N as a prerelease and dispatch binary-release.yml (a GITHUB_TOKEN release fires no release: published)
8d2cbe2 #4275 asset_version_check.sh: the smoke strips -rc.N, compares the version whole (the old glob accepted 0.69.30 for v0.69.3), and binds the asset to the tag's commit by sha
804e81d #4286 promote_rc.sh: the final is the rc's bytes. Verify, rename, draft, upload, read back, then publish. The assets gate job keeps release: published from rebuilding over them
b1ea2a1 #4287 rc_publish_gate.sh, run by rc-cut before the tag is written: R6 graph + the path-only dev-dep rule + a cargo package --no-verify walk of all 71 publishable crates

Evidence

Findings (fixed here)

  1. Release binaries carried no commit. The published v0.69.3-rc.1 asset says apr 0.69.3 (v0.69.3+no-git). Fixed: both apr docker builds now get APR_GIT_SHA_OVERRIDE.
  2. A promoted tarball keeps its rc inner directory (apr-v0.69.3-rc.1-…/apr). install.sh, the binary-release smoke and autopilot.sh all assumed ${asset}/apr, so a byte-identical promotion broke installs. A hermetic fake-curl test went RED, then GREEN after the fix; a tarball with two apr-* dirs is refused.
  3. The path-only guard's own baseline masked fix(publish): lib tests in aprender-core and aprender-test-showcase named path-only dev-deps that cargo publish deletes — clean-room B2 red on v0.68.0 #3425 at v0.68.0. So --rc-gate judges the rc tree against the default branch's triage, not the rc tree's.
  4. cargo package --workspace cannot be the walk. It includes publish=false aprender-qa-runner/qa-gen, which cannot resolve each other.

Needs a ruling / follow-up

Closes #4275
Closes #4287
Refs #4285 #4286

#4327 / #4328 C2 and C4: an rc is a draft until every fleet host runs it (90b070f)

  • rc_cut.sh creates the rc as a draft. binary-release.yml looks the release up by listing, because releases/tags/ hides drafts.
  • A fifth apr asset, aarch64-apple-darwin-cpu, is built on the mini runner, stamped and verified. There are now 18 assets.
  • New scripts/release/rc_fleet_stage.sh TAG [--publish] stages the rc on lambda, gx10, yoga, intel and mini. It installs with fleet-bins install or an atomic fallback. Each host then passes only if PATH resolves apr X.Y.Z-rc.N (<tag sha>) and pv reports the tag's version.
  • It publishes only when every host passes. An unreachable host holds the rc unless a dated waiver covers it. It prints a per-host receipt table and appends it to the release notes.
    • Self-test: 8 verdict rows and 2 verdict mutants.
    • It also runs a fake 3-host fleet over stub ssh/scp/gh. A host whose installer claims success but whose PATH still serves the old apr is not published, and a mutant with the verify deleted does publish.
  • New scripts/release/fleet_cells_gate.sh, wired into rc_cut.sh before the tag is written, refuses the cut while any fleet cell is RED without a dated waiver in scripts/release/fleet-waivers.tsv. Missing or stale cells also refuse, because no data is not green data.
    • Self-test: 14 rows, 2 mutants and a wiring row.
  • Dependency: the cells come from infra-64's C3 monitor at fleet/cells.tsv on the fleet-state branch. Until C3 publishes there, a cut refuses unless someone records a dated *\t* waiver.

ont-delta: none — release scripts and workflows only; no ontology type, shape or anchor changes.

🤖 Generated with Claude Code

noahgift and others added 4 commits September 24, 2026 16:14
…se/X.Y.Z (#4285)

rc-cut.yml fires on CI workflow_run completion for release/** and hands the
run id to scripts/release/rc_cut.sh, which decides and writes:

- refuse fork head repos, non release/X.Y.Z branches, a missing or non-success
  `ci / gate` / `workspace-test`, a head that is no longer the tip, or a head
  that already carries an rc tag
- otherwise N = max existing rc + 1 (never reuses a deleted name); create the
  tag, a prerelease (make_latest=false), and dispatch binary-release.yml with
  inputs.tag (GITHUB_TOKEN releases do not fire release: published)

The decision is pure and ships a 17-row case table plus a built-in mutant
(check loop deleted must cut on a red gate), run as the job's first step.
Dry-run against real runs: cancelled release run -> skip; main -> skip; green
run rewritten onto release/0.69.3 -> "cut v0.69.3-rc.2" (rc.1 dereferenced).

Refs #4285

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mit (#4275)

The smoke tested `case "$v" in *"${TAG#v}"*)`, a substring match. It refused
every rc (an rc asset reports 0.69.3, which does not contain 0.69.3-rc.1:
Cargo stays X.Y.Z, cop ruling 2026-09-24) and it accepted 0.69.30 for v0.69.3.

scripts/release/asset_version_check.sh TAG COMMIT "VERSION_LINE" compares the
version whole, with the tag's -rc.N stripped, and requires the asset's sha to
be a prefix of the tag's commit. That is what binds an rc asset to ITS commit.
Case table: 14 rows (the issue's 4 plus 0.69.30, no-git, short/empty sha, a
-rc Cargo version, a non-full commit, a pv line). Six mutants, all killed.

The sha had to be made real first. The published v0.69.3-rc.1 cpu asset
reports `apr 0.69.3 (v0.69.3+no-git)`: the bullseye container sees no usable
git, so no release binary has ever carried its commit. Both apr build lanes
now pass APR_GIT_SHA_OVERRIDE=$(git rev-parse --short=9 HEAD) (build.rs's
first source; it is rerun-if-env-changed, so the cached target rebuilds).

Closes #4275

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rebuild (#4286)

scripts/release/promote_rc.sh vX.Y.Z-rc.N [--dry-run] | --self-test
- refuses unless the rc is a prerelease, the final does not exist (nor a draft),
  and check_release_assets.sh says the rc's asset set is complete
- downloads every rc tarball, verifies it against its .sha256, renames it to the
  final name (the -rc.N label must occur exactly once), writes a same-hash .sha256,
  creates a DRAFT final at the rc's commit, uploads, reads every asset back and
  compares hashes, and only then publishes it
- live --dry-run on v0.69.3-rc.1: 8 tarballs staged, cmp byte-equal, final
  .sha256 hash == rc hash

Findings fixed on the way:
- a promoted tarball keeps its rc inner directory (apr-v0.69.3-rc.1-.../apr).
  install.sh, the binary-release smoke and autopilot.sh assumed ${asset}/apr, so
  a byte-identical promotion broke installs (hermetic fake-curl test: RED
  "Binary 'apr' not found in archive" before, installs apr 0.69.3 after; an
  archive with two apr-* dirs is refused). All three now take the single apr-* dir.
- publishing the promoted final fires `release: published`, whose uploads would
  clobber the rc bytes with a rebuild. binary-release.yml gains an `assets` gate
  job: builds run only when check_release_assets.sh says assets are missing; an
  ENV error fails the gate, so the builds skip (fail closed). Smokes run on
  !cancelled() && verify success, so they still check promoted assets.

Refs #4286 — "released apr --version names the rc" needs #4110 provenance;
identical bytes cannot carry a new label, so the release body records the rc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t blocks the rc, never the final (#4287)

scripts/release/rc_publish_gate.sh ROOT | --self-test, run by rc-cut.yml on a
checkout of the rc commit BEFORE the tag is written (decide --dry-run -> gate ->
cut). Red fails the job and no rc exists. Three checks, each the tool that owns
its rule, from the default-branch checkout so a release branch cannot weaken it:
- graph:    check_publish_preflight.sh --graph-only (new): R2 + R6; R6 is now one
            function, rule_r6, shared with the T-4 gate. Selftest 31/31, incl. a
            cycle refusal and an untagged off-main pass with a full-gate control.
- pathonly: check_pathonly_devdeps_unused_in_src.sh --rc-gate ROOT (new): NEW pairs
            against the DEFAULT BRANCH's triage, never the rc tree's baseline — v0.68.0's
            own baseline listed aprender-core|entrenar, which is how #3425 shipped
            green. A missing TOML reader is ENV 2 here, never fleet state.
- package:  cargo package --no-verify --locked over all 71 publishable members in one
            invocation (the local overlay resolves unpublished siblings); every one
            must print Packaged. `--workspace` fails: it includes publish=false
            aprender-qa-runner/qa-gen, which cannot resolve each other.

Acceptance replay, v0.68.0 (c91e065, git archive): rc=1 in 65 s, graph=0
pathonly=1 package=0 -> red, naming aprender-core|entrenar and
aprender-test-showcase|jugar-probar, exactly #3425's two crates. The package walk
alone is GREEN there (71/71): --no-verify compiles no tests, which is why the
path-only rule is in the gate. Verdict table mutants: 4/4 killed.

Closes #4287

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@noahgift noahgift added this to the 0.70.0 milestone Sep 24, 2026
noahgift and others added 3 commits September 24, 2026 16:54
…#4286 #4287)

Refs #4287

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rtial (#4286)

The assets gate skips every build when the release already holds all its
assets, so needs.build.result is skipped and the summary printed
'partial (status=skipped)' on every promoted release. Say it was not rebuilt.
Quorum finding (sonnet lane, PR #4314).

Refs #4286

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sibly stops it (#4287)

GitHub already ANDs success() into an if: with no status function, so a
red gate never reached the cut; a quorum lane read it the other way. Say
it in the file so no reader has to know the default.

Refs #4287

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@noahgift
noahgift enabled auto-merge September 24, 2026 15:40
@github-actions

github-actions Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

§13.11 rung 1 — quorum shadow verdict

S13-SHADOW pr=4314 head=d2b185d376b3fce944c4d9f3075050fbb4c1377a 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 2 commits September 24, 2026 19:49
…+no-git (#4110)

The 0.69.1 crates.io install AND the release binaries both printed
`apr 0.69.1 (v0.69.1+no-git)` (0.68.1 did too). There were two causes.

(a) crates.io: the tarball carries `.cargo_vcs_info.json` (git.sha1 =
d8a6df5…), which `cargo package` writes, but build.rs never read it. It
is now rung 2, AHEAD of `git rev-parse`, because an unpacked crate can sit
inside an unrelated repository whose HEAD is not ours. The value is short
9-hex, with -dirty when cargo recorded a dirty tree; anything that is not
40 hex is ignored.

(b) release binaries: binary-release.yml builds as root in a container
over the runner-owned checkout, and git refuses it as "dubious ownership".
Reproduced in rust:1.93.0-bookworm: main's build script prints
v0.69.1+no-git and this one prints the HEAD. The git rung now retries with
ONLY the enclosing checkout marked safe.directory, via a private
GIT_CONFIG_GLOBAL under OUT_DIR. `-c safe.directory` is ignored by git
before 2.39 (measured on 2.34.1). This needs no workflow edit.

Must-RED: crates/apr-cli/src/build_rs_vcs_sha_tests.rs compiles the
SHIPPED build.rs with rustc and runs it as cargo does. Rows: packaged
(byte-exact 0.69.1 vcs file), foreign-repo, dirty, malformed, no-vcs,
override, dev-checkout, and foreign-owner (via git's
GIT_TEST_ASSUME_DIFFERENT_OWNER, with a precondition that plain git really
refuses). Three plants must each go RED: vcs rung removed, vcs rung behind
git, retry removed. The tests run in workspace-test (apr-cli --lib).
Contract apr-version-traceability-v1 goes to 1.2.0 with FALSIFY-VERSION-005.

Also: Cargo.lock chacha20 0.10.0 (yanked) -> 0.10.2. It is lock-only; no
default-graph package builds it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
noahgift and others added 8 commits September 24, 2026 19:58
…ted exactly (#4110, #4256, #4290)

The v0.69.3-rc.2 asset prints `apr 0.69.3 (v0.69.3+no-git)`: no rc, no commit.
Operator 2026-09-24: "we need actual version numbers", "version number needs
release canidate info in it".

- scripts/release/stamp_rc_version.sh: binary-release.yml stamps the checked-out
  rc tag tree to X.Y.Z-rc.N (workspace version, every path pin incl. partial
  "0.69" ones, workspace Cargo.lock entries) before `cargo build --locked`, so
  CARGO_PKG_VERSION itself carries the rc. Final tags are a no-op; a tag whose
  X.Y.Z is not the workspace version is refused. Self-test: cargo metadata
  --locked is the oracle, 4 mutants (lock / path-first pins / version-first
  pins / partial pins dropped) each make cargo refuse. Real tree: the
  v0.69.3-rc.2 archive stamps and resolves --locked, 79/79 members at rc.2.
- asset_version_check.sh: the printed version must equal the tag EXACTLY,
  -rc.N included; bare 0.69.3 on an rc tag is refused. Against the real rc.2
  asset: "bad asset reports 0.69.3; tag v0.69.3-rc.2 wants 0.69.3-rc.2".
- #4290: the F2 receipt key is the build, not the version: version plus the
  running executable's sha256 (catches rc.N, dev and dirty rebuilds); an
  unreadable executable gets a key no receipt can hold.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t while a fleet cell is RED (#4327, #4328)

Operator, 2026-09-24: "THE INSTANT we do a release candidate it needs to be on all
hardware either before or same time. change process".

C2 (#4327):
- rc_cut.sh creates the rc as a DRAFT prerelease. Drafts are invisible to install.sh
  and to the fleet poller.
- binary-release.yml reads the release by listing it, because releases/tags/ never
  returns a draft.
- binary-release.yml builds a fifth apr asset, aarch64-apple-darwin-cpu, on the mini
  runner. It is stamped and verified like the others, so mini can install an rc at
  all. check_release_assets now expects 18 assets.
- rc_fleet_stage.sh (new) stages the rc on every host: lambda, gx10, yoga, intel and
  mini (jetson is retired). For each host it copies the assets and installs them,
  with `fleet-bins install` or an atomic built-in installer. It then verifies what
  PATH serves with asset_version_check (apr X.Y.Z-rc.N (<sha>) of the tag commit)
  and checks pv's version.
- It publishes only when every host passes. An unreachable host holds the rc unless
  a dated waiver covers it. It prints a per-host receipt.
- Self-test:
  - a verdict table;
  - two verdict mutants;
  - a fake three-host fleet in which one lying installer holds the publish;
  - a mutant with the verify deleted, which publishes past that host.

C4 (#4328): fleet_cells_gate.sh (new) refuses the cut while any fleet cell is RED
without a dated, recorded waiver (scripts/release/fleet-waivers.tsv).
- It also refuses missing or stale cells.
- rc_cut.sh runs it before writing the tag.
- The cells come from infra-64's C3 monitor, at fleet/cells.tsv on the fleet-state
  branch.
- Self-test: a 14-row table, 2 mutants, and a wiring row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ame (#4327)

releases/tags/ never returns a draft. A promote run before rc_fleet_stage.sh
published the rc therefore reported "cannot read release" as an ENV error, when
the real state was that the rc was not on the fleet yet. It now finds the rc by
tag_name and refuses a draft with the staging command to run. Found by the
sonnet review lane on 90b070f.

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

Two conflicts, both resolved as the union:
- scripts/check_publish_preflight.sh: this branch's R6 publish-graph rule
  and `--graph-only` (#4287), plus main's R7 emergency scope `--scope` and
  `--cut-commit`. They are independent functions. selftest 50/50.
- docs/roadmaps/roadmap.yaml: disjoint item ids on each side. The union
  holds 1074 items, no duplicates, and every id from both sides. Also
  quotes the PMAT-4328 title: its bare `: ` made this branch's roadmap
  unparseable YAML before the merge.

Unblocks #4328's aprender cells: apr/pv print `+no-git` on every fleet host
until the identity fix (2b3cb55) reaches a release.

Refs #4328 #4314

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e over the ceiling of 74 (#4327 line, surfaced on #4314)

grep -qx now reads a process substitution. Self-test 12/12; the planted
darwin-name mutant turns row 12 RED (11/12). check_no_pipe_into_grep_q 74/74.

Pmat-Ticket: PMAT-4275

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n_pinned read it as a bare apr call (guard-cargo red on #4314)

The mutant deletes the asset_version_check.sh call, so the label now names
that. check_apr_bin_pinned OK (357 files); rc_fleet_stage --self-test 14 ok, rc 0.

Pmat-Ticket: PMAT-4275

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ed — cuda-unit did not compile

OwnedQuantizedLayer gained post_attn_norm_weight/post_ffw_norm_weight and
GGUFConfig gained query_pre_attn_scalar; this cuda-only test target was never
updated, so cuda-unit failed E0063 x10. Same file is red on origin/main.

Pmat-Ticket: PMAT-4275

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift and others added 3 commits September 25, 2026 11:41
…te goes RED without them (#4353)

Operator 2026-09-25: "ensure these gaps never occur again as mac is critical
and also wgpu enabled binary for intel".

- build-pv-darwin: native pv build on the mini runner, pv-<tag>-aarch64-apple-darwin.
- build-apr-cpu gains a flavour axis; the x86_64 wgpu row builds with --features wgpu
  (apr-<tag>-x86_64-unknown-linux-gnu-wgpu). Flavour is proven by BEHAVIOUR: a cpu
  build refuses `apr run --gpu` (exit 9), a GPU build does not (exit 3 on the missing
  model). A byte grep for wgpu cannot tell them apart (125-127 hits in every build).
  Both polarities are asserted, so each lane is the other's positive control.
- check_release_assets.sh expects 22 assets (6 apr + 6 sha + 10 pv); new must-fail
  rows for darwin pv and the wgpu apr. There is no waiver path.
- Fix: `printf | grep -qxF` under pipefail read a PRESENT asset as MISSING when
  grep -q closed the pipe early (SIGPIPE 141) — 5/30 self-test runs red at 22 lines.
- tests/check_release_assets_test.sh: its hand-written complete set lacked the
  darwin apr (#4327), so row 3 was red on the base; now carries all 22 + mutants.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ck_runner_labels.sh requires (#4353)

[self-hosted, macOS, ARM64, mini] has none of apple-silicon|m4, so guard-tree
failed on build-apr-darwin and build-pv-darwin. Same selector as ci.yml mac-check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…stops fetching a check it never runs (#4353 quorum nits)

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

apr-cli's `wgpu` feature enabled only `inference`, but the finetune wgpu path
uses entrenar items gated behind entrenar's own `gpu` feature. `wgpu` now
enables `entrenar?/gpu` (weak: only when `training` brings entrenar in, which is
exactly when commands::finetune compiles).

Compiling that surface for the first time exposed 10 clippy findings in
aprender-train's gpu code, which no gate had ever linted:
- 3 unnecessary parens, 1 redundant field name, 1 unused var, 1 needless mut
- await_holding_refcell_ref in transformer/wgpu_block: the PipelineCache is
  now moved out of the RefCell for the await and put back before `?`
- dead code (keep-alive GPU buffers, an unread eps, an uncalled
  dispatch_lora_addmm): #[allow(dead_code)] with a reason, like vram_guard

Measured on lambda, base batch/0.70.0@5a70d9195:
  cargo clippy -p apr-cli --lib --features wgpu -- -D warnings   rc=0 (was 5 E0432/E0433/E0425, then 10 lints)
  cargo clippy -p apr-cli --lib -- -D warnings                   rc=0
  cargo test -p aprender-train --lib --features gpu --no-run     rc=0
  cargo fmt --all -- --check                                     rc=0
Not run: the wgpu_block GPU tests (gpu-q queue 6 deep, timed out waiting).

Follow-up for the fold: scripts/check_clippy_feature_matrix.sh (fold/4310-b4)
excludes `wgpu=#4056`; once both land, drop the exclusion and add a wgpu axis.

Refs #4056

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

Copy link
Copy Markdown
Member Author

Closed as superseded (cop-approved D). The rc-cut-on-release-branch design was superseded by the 2026-09-25 16:58 operator ruling: rc = tag on a queue-green main, cut by the rc tagger. The still-wanted commits were re-homed with cherry-pick -x onto batch/release-tooling-4314-salvage @ 0edc34a (off main): #4275 smoke binding, #4286 promote rc bytes, #4110 version names its commit, #4327 draft until fleet runs it, darwin pv + x86_64 wgpu assets (#4353), guard fixes, driver_cuda_gguf. ed970f9 (#4056) is on #4318. fleet_cells_gate is RED (UNWIRED) until the rc tagger calls it. Branch PMAT-4285-rc-cut is kept as the source.

@noahgift noahgift closed this Sep 25, 2026
auto-merge was automatically disabled September 25, 2026 19:25

Pull request was closed

noahgift added a commit that referenced this pull request Sep 25, 2026
…mments stop citing rc_cut.sh (#4314 salvage, quorum r1)

Gemini lane r1 (conv 2da40e08): with rc_cut.sh gone nothing creates the draft,
so the listing lookup raised StopIteration. main's releases/tags/ lookup 404s
the same way on a bare tag, so this is not a regression; the rc tagger owns
draft creation now. All 7 lookups exit naming the tag and that contract.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift added a commit that referenced this pull request Sep 25, 2026
#4314 salvage, quorum r2)

Haiku lane r2: the two download-side asset lookups kept a bare next(). A miss
already failed the step; now it names the missing asset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift added a commit that referenced this pull request Sep 25, 2026
…ound 3, not degraded

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift added a commit that referenced this pull request Sep 25, 2026
…g hardcoded in prose (#4314 salvage, quorum r4)

agy lane r4 (conv 8ba6854b): smoke-cpu fetched only -cpu, so #4353's wgpu
asset never got #4275's tag/commit binding. The smoke matrix now carries a
flavour and a clean-room wgpu row. The '16'/'18' asset counts in comments
(22 now) are replaced by a pointer to check_release_assets.sh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift added a commit that referenced this pull request Sep 25, 2026
…s fail by name (#4314 salvage, quorum r5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift added a commit that referenced this pull request Sep 25, 2026
…r drafts, then dispatches (#4314 salvage, quorum r6)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
noahgift added a commit that referenced this pull request Sep 25, 2026
6f83d92

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@noahgift
noahgift deleted the PMAT-4285-rc-cut branch October 9, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant