Skip to content

Bind Agent releases to the release App - #34

Draft
abrichr wants to merge 10 commits into
mainfrom
codex/release-app-contract
Draft

Bind Agent releases to the release App#34
abrichr wants to merge 10 commits into
mainfrom
codex/release-app-contract

Conversation

@abrichr

@abrichr abrichr commented Aug 26, 2026

Copy link
Copy Markdown
Member

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, installation 156835568, bot user 321543906, the draft and asset IDs, the immutable-release response, and both tag rulesets. It proves that refs/tags/v2.0.2 is absent before draft creation and after every staged asset is complete. The central qualification-release admission 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. Version 1.32.0 emits 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:

  • merge the central Production trust v2 verifier and replace every CENTRAL_VERIFIER_SHA placeholder with that exact commit;
  • grant the release App Administration: read, keep Contents: write and Metadata: read, and set the frozen App, installation, bot, and dispatcher variables;
  • create protected release-identity and mcp-registry environments, then add protection to the existing pypi environment;
  • enable immutable releases and create the two exact active tag rulesets described in 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

  • 128 tests passed; the two exact central-pin tests were deliberately excluded while the placeholder remains.
  • Ruff and Actionlint passed.
  • The wheel and source archive passed the code-only, distribution, source-boundary, inventory, and Twine checks.
  • The MCP manifest, packed MCPB boundary, and pinned official server.json schema check passed.
  • Live preflight reports Agent 2.0.2 missing 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.

@abrichr
abrichr force-pushed the codex/release-app-contract branch from 6ee887a to 69b0e94 Compare August 27, 2026 18:19
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.

1 participant