Skip to content

Separate published from activated in the ledger, unblocking the npm payload refresh - #241

Merged
docushell-dev merged 1 commit into
mainfrom
chore/release-state-activated-published
Aug 30, 2026
Merged

Separate published from activated in the ledger, unblocking the npm payload refresh#241
docushell-dev merged 1 commit into
mainfrom
chore/release-state-activated-published

Conversation

@docushell-dev

Copy link
Copy Markdown
Collaborator

The v0.6.0 npm payload refresh could not be made. The cause is a fault I introduced in #239.

The deadlock

#239 repointed actions/verify/tests/test_action.py at packages/npm/ethos-pdf/vendor/manifest.json, on the reasoning that it is "the record of the published CLI". It is not. A payload refresh moves that manifest to the next release before that release is published, so it tracks the activated version.

Meanwhile the Action's URL followed release-state.json's release.version, which the activation gate holds at the published version until publication.

Once the payload moves, the only state satisfying both assertions is a v0.5.0 URL carrying v0.6.0 digestsinstall_cli.py downloads one archive and checks it against another's digest, failing at install on every run. ci.yml's released-cli-action-dogfood executes the Action twice, so this breaks for real, not just in an assertion.

Reproduced by simulating the refreshed manifest before changing anything, and reproduced as passing afterwards.

The fix

Stop overloading one field.

Field Meaning
release.version what is published (unchanged)
release.activated what the tree is preparing
release.published_cli published archive + binary digests, both targets

The Action's digests now come from published_cli, next to the version its URL already used. Both halves derive from one published record and move together at publication.

check_release_state.py validates the new keys: activated must be semver and not behind version; every digest lowercase 64-hex.

A vendored binary must report the version the manifest claims

prepare-vendor.js now runs the binary with --version and requires ethos <manifest.cli_version>.

Every existing check compared the manifest against itself — digests prove the manifest and the bytes agree with each other, never that the bytes are the version claimed. That is exactly the hole 1d23604 fell into: a package labelled 0.6.0 whose vendored CLI reported ethos 0.5.0, full suite green.

Verified against the real vendored 0.5.0 binary — a 0.6.0 manifest is now rejected.

Verification

light-check, registry-surface-check, release-live-state-check, ethos-verify-action-contract, the npm package suite, and make release-gates all pass.

🤖 Generated with Claude Code

…ng the npm payload refresh

The v0.6.0 npm payload refresh could not be made, and the cause was a fault introduced by the
previous release-flow work.

test_action.py was repointed at packages/npm/ethos-pdf/vendor/manifest.json on the reasoning that
it is "the record of the published CLI". It is not. A payload refresh moves that manifest to the
next release before that release is published, so it tracks the activated version. The Action's
URL meanwhile followed docs/release-state.json's release.version, which the activation gate holds
at the published version until publication.

Once the payload moved, the only state satisfying both assertions was a v0.5.0 URL carrying v0.6.0
digests: install_cli.py downloads the v0.5.0 archive and checks it against the v0.6.0 digest, so
the Action fails on every run. ci.yml's released-cli-action-dogfood executes it twice, so this
was a real break rather than an assertion artifact. Reproduced by simulating the refreshed
manifest before changing anything, and reproduced as passing afterwards.

The fix is to stop overloading one field. docs/release-state.json gains release.activated, and
release.published_cli carrying the published archive and binary digests for both targets. The
Action's digests now come from published_cli, next to the version its URL already used, so both
halves derive from one published record and move together at publication. check_release_state.py
validates the new keys: activated must be semver and not behind version, and every published_cli
digest must be lowercase 64-hex.

Separately, prepare-vendor.js now runs the vendored binary with --version and requires
`ethos <manifest.cli_version>`. Every existing check compared the manifest against itself — the
digests prove the manifest and the bytes agree with each other, never that the bytes are the
version claimed. That is precisely the hole 1d23604 fell into: a package labelled 0.6.0 whose
vendored CLI reported ethos 0.5.0, with the full suite green. Verified against the real vendored
0.5.0 binary, which a 0.6.0 manifest now rejects. The vendor-assembly fixtures answer --version
accordingly, because a fake that cannot report its version does not model a real one.

light-check, registry-surface-check, release-live-state-check, ethos-verify-action-contract, the
npm package suite, and make release-gates all pass.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: docushell-dev <hello@docushell.com>
@docushell-dev
docushell-dev merged commit 6ba8184 into main Aug 30, 2026
19 checks passed
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