Skip to content

perf(release-rc-cut): render the RC command blocks as code, one file per outcome - #1604

Merged
potiuk merged 6 commits into
mainfrom
perf/release-mgmt-1-rc-cut
Oct 16, 2026
Merged

potiuk merged 6 commits into
mainfrom
perf/release-mgmt-1-rc-cut

Conversation

@potiuk

@potiuk potiuk commented Oct 12, 2026

Copy link
Copy Markdown
Member

Summary

First of a stack that moves the release-management skills' deterministic work into code, the same deep split #1570–#1585 did for pr-management.

  • New tools/release-management package. It renders everything a release-* skill hands the release manager from what release-config load prints. Each skill is a subpackage the CLI discovers, so later PRs add commands without editing a shared file. It is stdlib-only and runs nothing: no git, gpg, svn, gh, aws or atr call, no key, no network.
  • release-rc-cut renders every block as code. That covers the signed tag, the reproducible source build, convenience artefacts, sign and checksum commands, per-backend staging, the ATR upload, the Step 2b self-check, the Step 2c CI-signed trigger and the Step 4 planning-issue comment with its reproducibility record (parsed from what repro-archive build printed).
  • SKILL.md becomes a router: 9,962 → 6,503 tokens, 696 → 459 lines. Each Step 0 blocker, refused render and self-check failure, plus the ATR staging notes, gets its own file. The prerequisites and references move to siblings. Every Golden rule, Hard rule and JSON contract is unchanged, and so are the headings the evals extract.

Security notes

Two rules the skill only stated in prose are now enforced in code:

  • Golden rule 5, the dist/release/ denylist, had no check anywhere. A svnpubsub staging URL under dist/release/ is now refused ({"ok": false, "refused": …}, exit 2).
  • An MD5 or SHA-1 digest is refused the same way (Golden rule 3).

The exact-match RC tag check (rc1 must not match rc10) is a tag-exists command.

Also in this PR

  • Archive-review step number. rc-cut, the release-config blocker text, release-build.md and reproducibility.md all said "Step 2f". In release-prepare that step composes the PR; the archive review is 2e.
  • test(agent-isolation), a separate commit. test_signing_in_flight_matches_the_whole_process_name failed whenever the workspace pytest hook ran from a commit made under the gpg-touch overlay's wrap: the inherited MAGPIE_GPG_TOUCH_WRAPPED_SIGNER makes the script report a signature in flight. The test helper now drops it. Reproduced before the fix, passing after.

Type of change

  • Skill change — eval fixtures updated below
  • Python package (new tools/release-management)

Test plan

  • prek run --all-files passes
  • tools/release-management: pytest (25) / ruff / mypy. This includes an integration test that renders from a real release-config load, so a renamed field on either side fails.
  • The model-graded suites step-2-tag-build-sign, step-2b-reproducibility and step-3-staging cases 1–2 (9 cases) are now pytest cases named after each former case.
  • release-rc-cut evals after the change: 7/7. That is step-0 6/6, plus the step-3 injection case, now given the real render output. The baseline before the change was 16/16.

Notes for reviewers

  • The body is still a little over the 5k budget, about 5.5k without the pre-flight block. What remains is the Golden and Hard rules, which I left word for word rather than reword without review.
  • The stack's later PRs: verify-rc, then vote-draft + vote-tally, promote + announce-draft, prepare, and audit-report + archive-sweep + keys-sync.

Was generative AI tooling used to co-author this PR?
  • Yes — Claude Code (Opus 5). I reviewed the diff and the test results; commits carry Generated-by:.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GTPsZ5aEE5bUVYqp47Dpvv

@potiuk potiuk added family:tools tools/* capability:resolve Close-out: invalidate, dedupe, CVE allocate, announcement family:release-management release-* skills substrate:release Tool substrate: release-artefact helpers (reproducible archive build, lint, comparison) labels Oct 12, 2026
@github-actions github-actions Bot added family:setup setup-* skills family:docs Docs, MISSION.md, READMEs family:ci .github workflows, prek, validators substrate:sandbox Tool substrate: agent isolation, egress control, settings audit substrate:framework-dev Tool substrate: build / validate / eval the framework itself labels Oct 12, 2026
@potiuk
potiuk force-pushed the perf/release-mgmt-1-rc-cut branch from 52edbe9 to a1e7c62 Compare October 13, 2026 13:11
@potiuk
potiuk added this pull request to stack #1620 October 13, 2026 14:14
@potiuk
potiuk force-pushed the perf/release-mgmt-1-rc-cut branch 8 times, most recently from b8dba99 to f1ba914 Compare October 16, 2026 06:28
…obe tests

A commit made under the gpg-touch overlay's own `wrap` exports
MAGPIE_GPG_TOUCH_WRAPPED_SIGNER to its hooks. With it set,
signing_in_flight reports a signature whatever is running, so
test_signing_in_flight_matches_the_whole_process_name failed whenever
the workspace pytest hook ran from such a commit. _run now drops the
variable, so the probes see only the processes the test starts.

Generated-by: Claude Opus 5
Claude-Session: https://claude.ai/code/session_01GTPsZ5aEE5bUVYqp47Dpvv
…per outcome

release-rc-cut had the agent compose every paste-ready block by hand
from ~10k tokens of prose: the signed tag, the reproducible source build,
one sign and checksum command per artefact and digest, the per-backend
staging sequence, the ATR upload, the self-check and the planning-issue
comment with its reproducibility record. A new tools/release-management
package renders all of it from what `release-config load` prints;
the agent presents the block and keeps the judgement. The tool runs
nothing: no git, gpg, svn, gh, aws or atr call, no key, no network.

Two rules the skill only stated in prose are now enforced in code: a
svnpubsub staging URL under dist/release/ is refused (Golden rule 5 had
no check anywhere), and so is an MD5 or SHA-1 digest. The exact-match
RC tag check (rc1 must not match rc10) is a `tag-exists` command.

SKILL.md becomes a router (9,962 → 6,503 tokens): each Step 0 blocker,
the refused renders, the self-check failures and the ATR staging notes
get their own file, and the prerequisites and references move to
siblings. Every Golden rule, Hard rule, JSON contract and the headings
the evals extract are unchanged.

The model-graded step-2, step-2b and step-3 (cases 1-2) suites become
pytest cases named after each former case; step-0 and the step-3
injection case stay model evals, the latter now given the real render
output. An integration test renders from a real `release-config load`,
so a renamed field on either side fails.

Also fixes the archive-review step number: rc-cut, the release-config
blocker, release-build.md and reproducibility.md said "Step 2f", which
in release-prepare is composing the PR; the review is 2e.

Generated-by: Claude Opus 5
Claude-Session: https://claude.ai/code/session_01GTPsZ5aEE5bUVYqp47Dpvv
… commands

The release manager pastes these blocks into a shell, so a value taken
from configuration (an archive prefix, an artefact name, a staging URL)
must never be able to expand there. A new release_management.shell
module provides dq (a double-quoted word with \\, ", $ and backquote
escaped) and w (a bare word, unchanged when plainly safe or a
<placeholder>, otherwise shell-quoted), and every rc-cut renderer uses
them. Ordinary values render byte-for-byte as before; a hostile one
comes out as inert text, which tests pin through a real shell.

Generated-by: Claude Opus 5
Claude-Session: https://claude.ai/code/session_01GTPsZ5aEE5bUVYqp47Dpvv
…rd could mislead

Review findings on the rc-cut tool:

- svnpubsub staging now requires a normalised path under /repos/dist/dev/,
  so dist//release/ and dev/../release/ no longer slip past Golden rule 5.
- Step 4 takes each convenience artefact's own outcome
  (--convenience-outcome NAME=RESULT) instead of copying --self-check,
  which could record "reproducibility off (identical)".
- --self-check has no default; under ci-automated a missing or skipped
  value is a record gap.
- binary_check_commands stays empty when binary checks are off.
- dq() single-quotes values containing `!`, which interactive shells
  history-expand inside double quotes.
- --upstream and --project are required on render, so a bare
  <project> can no longer become a shell redirect.
- digest_set is an allowlist of sha512 and sha256.
- parse_record keeps the first occurrence and a 128-hex sha512 only.
- tag-exists returns null (a blocker) when the read printed anything
  other than refs/tags/ lines.

Generated-by: Claude Opus 5
…elf-check

Adversarial-review findings on the rc-cut tool:

- svnpubsub staging requires --asf-id instead of emitting a bare
  `--username <asf-id>`, which the shell reads as a redirect; the local
  artefact directory placeholder is quoted, and so is the CI run id.
- Step 2c refuses when ci_release_workflow is unset instead of emitting
  a bare `--workflow <ci_release_workflow>`.
- repro-archive commands carry a real, quoted framework path (--framework,
  defaulting to the tool's own checkout) instead of `<framework>/…`.
- Convenience build, stage and verification commands use the entry's own
  version, not the source release version.
- The self-check runs when an entry sets its own reproducibility mode, even
  with both global defaults off.
- Self-check builds run in a worktree of the RC tag (rebuild/src) and
  compare against what they build there, with a cleanup command.
- release_dist_backend: atr renders the ATR start / upload / check flow
  instead of refusing it as unknown.

Generated-by: Claude Opus 5
Keep comments and heredocs intact and stop when the rebuild checkout is
unavailable. Resolve build placeholders, emit custom archive records only
after successful builds, report effective per-artefact check modes, and
refuse failed reproducibility outcomes before proposing staging.

Generated-by: Codex (GPT-6)
@potiuk
potiuk force-pushed the perf/release-mgmt-1-rc-cut branch from f1ba914 to 3e6d812 Compare October 16, 2026 06:56
@potiuk
potiuk merged commit e44b44a into main Oct 16, 2026
59 checks passed
@potiuk
potiuk deleted the perf/release-mgmt-1-rc-cut branch October 16, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

capability:resolve Close-out: invalidate, dedupe, CVE allocate, announcement family:ci .github workflows, prek, validators family:docs Docs, MISSION.md, READMEs family:release-management release-* skills family:setup setup-* skills family:tools tools/* substrate:framework-dev Tool substrate: build / validate / eval the framework itself substrate:release Tool substrate: release-artefact helpers (reproducible archive build, lint, comparison) substrate:sandbox Tool substrate: agent isolation, egress control, settings audit

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant