Skip to content

fix(publish): widen the registry-verification bound that failed live 0.4.0 - #30

Merged
hseshadr merged 1 commit into
mainfrom
fix/publish-verify-propagation-bound
Aug 3, 2026
Merged

fix(publish): widen the registry-verification bound that failed live 0.4.0#30
hseshadr merged 1 commit into
mainfrom
fix/publish-verify-propagation-bound

Conversation

@hseshadr

@hseshadr hseshadr commented Aug 3, 2026

Copy link
Copy Markdown
Owner

The claim this touches

A green publish run means PyPI actually serves the version.

0.4.0 is live on PyPI — the wheel contains conformance.py — and
run 30842985605 is red
because this step gave PyPI only ~60s to start serving it. The check was measuring
the right property with the wrong constant.

The design is unchanged and stays. Ask the registry, never trust the uploader, and a
timeout is a FAILURE — never a pass, never a warning, no continue-on-error.

Why 60s was wrong

Measured 2026-08-03, time from a green upload until the registry served the version:

publish served after
PyPI edgeproc-core 0.4.0 >60s — failed this check while genuinely live
PyPI edge-proc 0.3.0 ~120s
npm @edgeproc/errors 0.1.0 (first publish of a new name) ~200s
npm @edgeproc/avow 0.3.0 ~60s

A release recorded as failed while it succeeded is not harmless. It teaches the reader to
wave off red publish runs — which is exactly how the six-green-runs-while-the-package-404'd
defect that this step exists to prevent comes back.

The new bound

14 attempts, backoff 5 / 10 / 15 / 30 then 60s — 600s of sleep, exactly. That is 3x the
slowest case measured. The slow case is the first publish of a brand-new package name,
which is also the case a genuine trusted-publisher misconfiguration is indistinguishable
from, so the budget must clear propagation by a wide margin before it accuses. Backoff keeps
the normal publish verifying in ~15s; only a real problem pays the ten minutes.

The failure message now separates "STILL PROPAGATING" from "THE RELEASE NEVER
HAPPENED"
, and says not to re-run the job merely to make it green. The old text listed
only the misconfiguration causes, which misleads now that a timeout is more often
propagation.

Kept identical to the Lego

This job is an inline copy of hseshadr/ci's python-publish.yml verify step, kept inline
on purpose. A divergence between the Lego and its copy is its own defect, so the comment,
the retry loop and the error message here are byte-identical to
hseshadr/ci#16. The only differences in the whole
step are the pre-existing structural ones — the reusable workflow takes packages-dir as
an input and must validate it; this copy hardcodes dist.

Proof the guard still has teeth

A guard that can no longer fail would be worse than the false negative. The harness pulls
this step's committed run: body out of the workflow YAML and executes it verbatim
under GitHub Actions' own shell flags (bash -e -o pipefail), so these exit codes are the
exit codes the job would produce.

case expected exit code
edgeproc-core==99.99.99 (PyPI does not serve it) fail after the full budget 1
edgeproc-core==0.4.0 (PyPI serves it) pass 0, well under 1s

The positive control is there on purpose: a harness that can only produce failures proves
nothing about the failures it produces. It also exercises the PEP 503 path — the fixture is
named edgeproc_core-*.tar.gz and the step correctly normalises it to edgeproc-core.

Does 0.4.0 need anything else?

No. PyPI versions are immutable and 0.4.0 is already served, so there is nothing to
re-publish. Once this merges, re-running the failed publish job on the v0.4.0 tag makes
the record match reality — the upload will no-op as already-published and the verify step
will confirm in one attempt.

Gate

check exit
uv run poe gate 0 — 296 passed, 99.22% total / 100% branch, README coverage claims match, all 6 documented imports resolve in the built wheel

🤖 Generated with Claude Code

https://claude.ai/code/session_015o7tjWLFZvzRv4KyNfDukx

…0.4.0

0.4.0 is live on PyPI and run 30842985605 is red, because this step gave
PyPI only ~60s to start serving it. Measured propagation is ~120s for a
normal PyPI release and ~200s for the first publish of a brand-new name,
so the bound was simply too tight.

A red run on a live release is worse than noise: it teaches the reader to
wave off red publish runs, which is how the six-green-runs-while-404
defect comes back.

Design unchanged — ask the registry, never trust the uploader, a timeout
is still a FAILURE. Only the bound moves: 14 attempts with backoff (5, 10,
15, 30, then 60s) = 600s of sleep, 3x the slowest measured case. The
failure message now separates "still propagating" from "the release never
happened".

Text kept byte-identical to hseshadr/ci's python-publish.yml verify step,
which this inline job is a copy of. A divergence between the Lego and its
inline copy is its own defect.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015o7tjWLFZvzRv4KyNfDukx
@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@hseshadr
hseshadr merged commit 2afe859 into main Aug 3, 2026
3 checks passed
@hseshadr
hseshadr deleted the fix/publish-verify-propagation-bound branch August 3, 2026 19:17
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