Bind Agent releases to the release App - #34
Draft
abrichr wants to merge 10 commits into
Draft
Conversation
abrichr
force-pushed
the
codex/release-app-contract
branch
from
August 27, 2026 17:03
0cd1d73 to
6ee887a
Compare
abrichr
force-pushed
the
codex/release-app-contract
branch
from
August 27, 2026 18:19
6ee887a to
69b0e94
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Agent 2.0.2 needs one recoverable release path for exact admitted bytes. A failed upload must resume from the App-authored draft. It must never rebuild the package or accept a different archive.
This PR supersedes #29. The shared commits have identical stable patch IDs, and #33 already merged its lifecycle-language cleanup.
What changed
Release preparation now builds the wheel and source archive once. A separate staging workflow verifies that candidate, creates or resumes one draft GitHub Release, uploads the two exact files, downloads them again, and records the closed qualification input.
The staging record binds App
4730708, installation156835568, bot user321543906, the draft and asset IDs, the immutable-release response, and both tag rulesets. It proves thatrefs/tags/v2.0.2is absent before draft creation and after every staged asset is complete. The centralqualification-releaseadmission binds that record and the same artifact inventory.Publication starts from the durable draft. It re-uploads the same bytes in the publication run for the central reusable verifier. Each protected effect job checks the signed, expiring, revocable admission again after its environment opens. Those checks run immediately before tag creation, artifact attestation, PyPI publication, MCP publication, and final GitHub Release publication.
The release App creates one annotated tag. Its canonical message binds the compact admission reference and artifact inventory digest. Two tag rulesets let that App create the tag once and prevent every actor, including the App, from changing or deleting it.
Recovery checks current public state before another effect. It accepts an exact partial PyPI upload and fills only the missing file. It accepts an exact existing MCP record, annotated tag, or published Release. Any conflicting name, byte, digest, uploader, author, tag object, or registry record stops the run.
The Production inventory contains only the wheel and source archive. The MCPB remains an optional local package. The MCP descriptor stays in the publication flow because it is part of Agent's public registry contract.
Hatchling is pinned to
1.31.0. Version1.32.0emits Core Metadata 2.5, which Twine 6.2 refuses. The pinned builder emits Metadata 2.4, and both archives pass Twine.Required cutover
The code will refuse a release until these target-state settings exist:
CENTRAL_VERIFIER_SHAplaceholder with that exact commit;Administration: read, keepContents: writeandMetadata: read, and set the frozen App, installation, bot, and dispatcher variables;release-identityandmcp-registryenvironments, then add protection to the existingpypienvironment;docs/DISTRIBUTION.md.The live repository doesn't have this configuration yet. This draft keeps the central placeholder on purpose, so its two action-pin tests fail until the verifier commit is safe to pin.
Checks
server.jsonschema check passed.2.0.2missing from PyPI and the MCP registry. Immutable releases are disabled, and no Agent tag ruleset exists.This PR changed no repository setting. It published no package, tag, MCP record, GitHub Release, or Production admission.