@@ -50,7 +50,10 @@ configuration later used an explicit `last-release-sha` bridge to establish the
5050recovery alpha as the previous-release boundary. Maintainers enabled the
5151repository variable only to start the stable release sequence, and human
5252finalization removed the bridge. An unset or non-true variable prevents the
53- corresponding gated job from executing.
53+ corresponding gated job from executing. ` RELEASE_RECOVERY_TAG ` and
54+ ` RELEASE_RECOVERY_SHA ` are absent by default and may exist only during an
55+ explicitly authorized recovery of that exact existing immutable release
56+ identity.
5457The release live-model configuration resolves an unset or empty
5558` COMETAPI_LIVE_MODEL ` to ` gpt-5.4 ` .
5659
@@ -191,6 +194,12 @@ violations in one run and still returns non-zero when any violation exists.
191194 the GitHub API until that exact tag and commit are independently reported as
192195 immutable, then invokes the protected publication chain directly;
193196 workflow-token release events do not trigger a second workflow run.
197+ - ` release-recovery.yml ` is the only manual publication path. It requires an
198+ exact immutable tag and commit, the protected default branch, and the
199+ temporary ` RELEASE_RECOVERY_TAG ` and ` RELEASE_RECOVERY_SHA ` identity opt-in
200+ before it calls the same protected publication chain. Delete both variables
201+ immediately after success or failure. The workflow and reusable publication
202+ jobs reject every rerun attempt.
194203- ` publish.yml ` is called only with the independently verified immutable tag,
195204 commit, and default branch. It resolves the tag to the checked-out commit,
196205 fetches the protected default branch, and rejects a commit that is not
@@ -205,9 +214,14 @@ violations in one run and still returns non-zero when any violation exists.
205214Third-party Actions are pinned to full commit SHAs. Workflow permissions are
206215read-only by default. The reusable publication caller and protected publishing
207216job declare ` id-token: write ` ; the caller passes the maximum permission and
208- only the publishing job requests the OIDC token.
217+ only the publishing job requests the OIDC token. Every repository-local caller
218+ of ` publish.yml ` declares ` secrets: inherit ` ; without it, GitHub-hosted runners
219+ can silently resolve the called job's environment secret as empty. The semantic
220+ workflow checker enforces inheritance and the live job checks the credential
221+ before making a request.
209222Publishing uses a protected ` pypi ` environment and concurrency control.
210- Arbitrary-branch and manual publication are forbidden.
223+ Arbitrary-branch publication is forbidden. Manual publication is limited to the
224+ reviewed immutable-release recovery described below.
211225
212226## Alpha release checklist (completed)
213227
@@ -316,3 +330,41 @@ project metadata, lock file, and changelog must remain at the exact generated
316330` 0.1.0 ` version. If GitHub requires approval before checks run on the automated
317331pull request, approve only that reviewed workflow execution and wait for every
318332blocking check.
333+
334+ ## Immutable release publication recovery
335+
336+ Use recovery only when an immutable GitHub release exists, its protected
337+ publication chain stopped before PyPI accepted the version, and a reviewed fix
338+ has already reached ` main ` . Do not create another tag or release, change the
339+ existing release, bypass live smoke, or publish an artifact retained from the
340+ failed run.
341+
342+ Before dispatch, verify that the exact PyPI version is absent, the release is
343+ immutable and non-draft, its tag resolves to the supplied commit, that commit is
344+ reachable from protected ` main ` , and the repository-local caller uses
345+ ` secrets: inherit ` . Then enable only the one-time recovery gate and dispatch the
346+ workflow from ` main ` with the exact immutable identity:
347+
348+ ``` bash
349+ gh variable set RELEASE_RECOVERY_TAG --body ' <exact-tag>'
350+ gh variable set RELEASE_RECOVERY_SHA --body ' <exact-commit>'
351+ gh workflow run release-recovery.yml --ref main \
352+ -f release-tag=' <exact-tag>' \
353+ -f release-sha=' <exact-commit>'
354+ ```
355+
356+ The run must rebuild and verify the exact tag, pass the credential preflight and
357+ bounded four-request live suite, wait for protected ` pypi ` approval, publish by
358+ OIDC, verify provenance and public digests, and pass the registry clean-install
359+ smoke. Delete the gate immediately after the run succeeds or stops:
360+
361+ ``` bash
362+ gh variable delete RELEASE_RECOVERY_TAG
363+ gh variable delete RELEASE_RECOVERY_SHA
364+ ```
365+
366+ A recovery failure stops the sequence. Diagnose and land a separate reviewed
367+ fix before requesting another explicit recovery authorization; do not rerun a
368+ failed job merely to obtain a different result. The workflow enforces this by
369+ allowing only ` github.run_attempt == 1 ` at both the recovery and publication
370+ boundaries.
0 commit comments