diff --git a/.github/scripts/test_npm_binary_package_scaffold.py b/.github/scripts/test_npm_binary_package_scaffold.py index 6f613a29..51caea60 100644 --- a/.github/scripts/test_npm_binary_package_scaffold.py +++ b/.github/scripts/test_npm_binary_package_scaffold.py @@ -40,21 +40,21 @@ NOTICE = PACKAGE_DIR / "NOTICE" LICENSE = PACKAGE_DIR / "LICENSE" VENDOR_MANIFEST = PACKAGE_DIR / "vendor" / "manifest.json" -# Bound to the reviewed v0.5.0 release commit bfb7197 ("prepare npm B from frozen -# v0.5 core"). binary_sha256 is independently re-verified against the vendored bytes -# below; release_asset_sha256 comes from that release closeout. +# Bound to the v0.6.0 release run 33325655578 on tag v0.6.0, source commit 8adda91, recorded in +# docs/validation/v0-6-0-release-promotion.md. binary_sha256 is independently re-verified against +# the vendored bytes below; release_asset_sha256 comes from that run's published sidecars. SUPPORTED_TARGETS = { "darwin:arm64": { "binary": "ethos-darwin-arm64", - "binary_sha256": "df2d46efb96501b8071cd8665ca525ee5af4787804cd04d07262354199ead913", + "binary_sha256": "038bfd4f4443784c9410278e63709e21d6f40dc4d204a5842a6df73d1b165180", "release_asset": "ethos-macos-arm64.tar.gz", - "release_asset_sha256": "30fa34afda745d168e1af39a134e2281f4a409d425765f3dc85c2e312fcbbcc2", + "release_asset_sha256": "c116b3449a3de1f4bddc6217e7717a1307a6ef58c240e5404be0850af81789bb", }, "linux:x64": { "binary": "ethos-linux-x64", - "binary_sha256": "7b6b7cb03c1d16183b6cdd56f6d2ebe593a25ef257baa5b6553a0055c53e8f44", + "binary_sha256": "ba9c648edecd3579c4d9acf2b901d9ac9a2e194bd108ae0a4c485a17bf47e7a6", "release_asset": "ethos-linux-x64.tar.gz", - "release_asset_sha256": "592b175c00d147625f2f2ccc8bc5c74fb8a00ee37f178c363757f2c72404876e", + "release_asset_sha256": "c12772255ba8a85b020bd9b6bb8bf77d01eaf11a6928a0d7348536eff7c378f2", }, } EXPECTED_PACKAGE_FILES = { @@ -133,7 +133,7 @@ def test_vendor_manifest_binds_supported_targets_to_release_assets(self) -> None self.assertEqual(1, manifest["version"]) self.assertEqual("@docushell/ethos-pdf", manifest["package"]) - self.assertEqual("0.5.0", manifest["cli_version"]) + self.assertEqual("0.6.0", manifest["cli_version"]) self.assertEqual(SUPPORTED_TARGETS, manifest["targets"]) for target in manifest["targets"].values(): self.assertRegex(target["release_asset_sha256"], r"^[a-f0-9]{64}$") @@ -166,7 +166,7 @@ def test_package_docs_keep_pdfium_and_publication_boundaries(self) -> None: self.assertIn("ETHOS_PDFIUM_LIBRARY_PATH", text) self.assertIn("QUICKSTART.md", text) self.assertIn("current published npm package is `@docushell/ethos-pdf@0.5.0`", text) - self.assertIn("`ethos 0.5.0`", text) + self.assertIn("`ethos 0.6.0`", text) self.assertIn("release-archive and extracted-executable SHA256 values", text) self.assertIn("does not include public benchmark reports or claims", normalized) diff --git a/.github/scripts/test_package_registry_source_consistency.py b/.github/scripts/test_package_registry_source_consistency.py index 0b5f38ea..cef218c2 100644 --- a/.github/scripts/test_package_registry_source_consistency.py +++ b/.github/scripts/test_package_registry_source_consistency.py @@ -130,7 +130,13 @@ def validate_registry_surfaces(root: Path) -> list[str]: expected_publication = ( f"The current published npm package is `{published_npm_name}@{published_npm_version}`." ) - expected_binary_version = f"Its vendored CLI binaries report `ethos {published_npm_version}`." + # The vendored binaries are whatever the payload currently carries, which during a refresh + # window is the activated version, not the published one. The two sentences describe + # different things and the README must be free to say so: the package on the registry is + # still 0.5.0 while the bytes in the tree are already 0.6.0. Deriving this from the + # published version made the refreshed README state something false about its own payload. + vendored_cli_version = str(cli_version) + expected_binary_version = f"Its vendored CLI binaries report `ethos {vendored_cli_version}`." expected_npm_install = f"npm install -g {published_npm_name}@{published_npm_version}" forbidden_postures = ( re.compile(r"source package candidate", re.IGNORECASE), @@ -154,9 +160,9 @@ def validate_registry_surfaces(root: Path) -> list[str]: f"{path.relative_to(root)} is missing CLI version wording: {expected_binary_version}" ) reported_versions = re.findall(rf"`ethos ({SEMVER})`", text) - if reported_versions != [published_npm_version]: + if reported_versions != [vendored_cli_version]: failures.append( - f"{path.relative_to(root)} must report only CLI version {published_npm_version}; " + f"{path.relative_to(root)} must report only CLI version {vendored_cli_version}; " f"found {reported_versions}" ) for pattern in forbidden_postures: @@ -226,7 +232,7 @@ def write_fixture( ) npm_text = ( f"The current published npm package is `@docushell/ethos-pdf@{published_npm_version}`. " - f"Its vendored CLI binaries report `ethos {published_npm_version}`.\n" + f"Its vendored CLI binaries report `ethos {cli_version}`.\n" ) (root / "python/README.md").write_text(python_text, encoding="utf-8") (root / "python/QUICKSTART.md").write_text(python_text, encoding="utf-8") @@ -277,13 +283,13 @@ def test_rejects_npm_wording_stale_against_release_state(self) -> None: failures = validate_registry_surfaces(root) self.assertTrue(any("missing current-publication wording" in failure for failure in failures)) - def test_rejects_cli_wording_stale_against_published_npm_version(self) -> None: + def test_rejects_cli_wording_stale_against_the_vendored_cli_version(self) -> None: with tempfile.TemporaryDirectory(prefix="ethos-registry-consistency-") as temp: root = Path(temp) write_fixture(root) readme = root / "packages/npm/ethos-pdf/README.md" readme.write_text( - read(readme).replace("`ethos 0.3.1`", "`ethos 0.3.2`"), encoding="utf-8" + read(readme).replace("`ethos 0.3.0`", "`ethos 0.3.2`"), encoding="utf-8" ) failures = validate_registry_surfaces(root) self.assertTrue(any("missing CLI version wording" in failure for failure in failures)) diff --git a/.github/scripts/test_v0_6_0_version_activation.py b/.github/scripts/test_v0_6_0_version_activation.py index 0376243f..0f3af67e 100644 --- a/.github/scripts/test_v0_6_0_version_activation.py +++ b/.github/scripts/test_v0_6_0_version_activation.py @@ -48,6 +48,16 @@ def read(path: str) -> str: return (ROOT / path).read_text(encoding="utf-8") +def _registry_claims(claims_json: str) -> list[str]: + """Every claim string in docs/public-boundary-claims.json, flattened.""" + registry = json.loads(claims_json) + return [ + claim + for surface in registry["surfaces"].values() + for claim in surface["claims"] + ] + + class V060CoreVersionActivationTests(unittest.TestCase): def test_core_release_metadata_is_activated_in_lockstep(self) -> None: cargo = read("Cargo.toml") @@ -86,7 +96,19 @@ def test_public_install_wording_is_not_advanced_to_the_candidate(self) -> None: self.assertNotIn(command, active_readme, command) self.assertNotIn(command, claims, command) self.assertIn(f"npm install -g @docushell/ethos-pdf@{PUBLISHED}", active_readme) - self.assertNotIn(ACTIVATED, claims) + + # The activated version may appear in the registry only where it states a fact about the + # bytes in this tree, never where it advertises something installable. After a payload + # refresh the vendored binaries really do report the activated version, and saying so is + # the honest claim; a blanket ban forced the registry to describe its own payload wrongly. + for claim in _registry_claims(claims): + if ACTIVATED not in claim: + continue + self.assertEqual( + f"Its vendored CLI binaries report `ethos {ACTIVATED}`.", + claim, + f"only the vendored-binary claim may name the activated version: {claim}", + ) def test_npm_payload_stays_on_the_published_release_until_refreshed(self) -> None: manifest = json.loads(read("packages/npm/ethos-pdf/vendor/manifest.json")) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cc2d4e3..1c953257 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,50 @@ ## Unreleased +### The npm payload carries the v0.6.0 CLI + +- boundary-exception: refresh the v0.6.0 npm B payload from frozen core-A. Both vendored + binaries and all four digests in `packages/npm/ethos-pdf/vendor/manifest.json` move to the + v0.6.0 release, together with `cli_version`, `package.json`, and both `package-lock.json` + version fields. `test_v0_6_0_version_activation.py` holds those four as one value, which is + why 1d23604 moved three and was reverted; they move as a set here. + + Bytes come from release run 33325655578 on tag `v0.6.0`, source commit `8adda91`, bound in + `docs/validation/v0-6-0-release-promotion.md` — not from a local build, which + `RELEASE_OPERATOR_RUNBOOK.md` forbids and which would not reproduce these digests anyway, + since `cli-draft-artifacts` builds once and does not compare. + + `prepare:vendor` assembled and verified the darwin binary end to end on macOS arm64: archive + digest, extracted-binary digest, `--help` grounding support, the new `--version` binding, and + the destination digest after copying. It correctly refused the linux binary on this host, + because it executes what it copies. That binary was taken from the same verified archive and + its digest checked against the manifest; its version is evidenced by the release run's own + Linux smoke step, which recorded `version_stdout: ethos 0.6.0` against archive + `c12772255ba8a85b020bd9b6bb8bf77d01eaf11a6928a0d7348536eff7c378f2`. Stated plainly because it + is weaker than the darwin path: the binding ran on CI's Linux runner, not here. + +- The npm README and QUICKSTART said the vendored binaries report `ethos 0.5.0`, and both ship + inside the tarball. `test_package_registry_source_consistency.py` derived that sentence from + the published npm version, so a refreshed payload would have published a README stating + something false about the bytes beside it. The two sentences describe different things: the + package on the registry is still `0.5.0`, and the vendored binaries are already `0.6.0`. The + publication sentence still follows `docs/release-state.json`; the vendored-binary sentence now + follows `vendor/manifest.json`'s `cli_version`. + +- `test_npm_binary_package_scaffold.py`'s `SUPPORTED_TARGETS` is rebound from the v0.5.0 closeout + to the v0.6.0 run, and `test/platform-selection.test.js` follows `cli_version`. + + `docs/release-state.json` is untouched: `version` stays `0.5.0` because nothing is published + yet, and `activated` already reads `0.6.0`. + +- `test_v0_6_0_version_activation.py`'s blanket `assertNotIn(ACTIVATED, claims)` is narrowed. Its + six explicit install-command checks already cover every installable form; the trailing catch-all + additionally forbade the string anywhere in the registry, which forced + `docs/public-boundary-claims.json` to describe its own payload wrongly once that payload moved. + The activated version may now appear only in the vendored-binary claim, which is a fact about + the bytes in this tree rather than an advertisement of something installable. Verified that the + narrowed rule still fails when an install command is advanced to the activated version. + ### The ledger separates what is published from what is being prepared - boundary-exception: `docs/release-state.json` gains `release.activated` and diff --git a/docs/public-boundary-claims.json b/docs/public-boundary-claims.json index e9febbb5..7dece04d 100644 --- a/docs/public-boundary-claims.json +++ b/docs/public-boundary-claims.json @@ -43,7 +43,7 @@ "path": "packages/npm/ethos-pdf/README.md", "claims": [ "The current published npm package is `@docushell/ethos-pdf@0.5.0`.", - "Its vendored CLI binaries report `ethos 0.5.0`.", + "Its vendored CLI binaries report `ethos 0.6.0`.", "The package is prepared as a binary distribution package.", "PDFium-backed commands use caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`." ] @@ -53,7 +53,7 @@ "claims": [ "npm install -g @docushell/ethos-pdf@0.5.0", "The current published npm package is `@docushell/ethos-pdf@0.5.0`.", - "Its vendored CLI binaries report `ethos 0.5.0`.", + "Its vendored CLI binaries report `ethos 0.6.0`.", "The package does not bundle PDFium." ] } diff --git a/packages/npm/ethos-pdf/QUICKSTART.md b/packages/npm/ethos-pdf/QUICKSTART.md index 5c89e3ea..7248a444 100644 --- a/packages/npm/ethos-pdf/QUICKSTART.md +++ b/packages/npm/ethos-pdf/QUICKSTART.md @@ -27,7 +27,7 @@ npm install -g @docushell/ethos-pdf@0.5.0 ``` The current published npm package is `@docushell/ethos-pdf@0.5.0`. Its vendored CLI binaries report -`ethos 0.5.0`. +`ethos 0.6.0`. ## Vendor Binary Assembly diff --git a/packages/npm/ethos-pdf/README.md b/packages/npm/ethos-pdf/README.md index e76e6868..177464be 100644 --- a/packages/npm/ethos-pdf/README.md +++ b/packages/npm/ethos-pdf/README.md @@ -35,4 +35,4 @@ Vendor assembly: `vendor/ethos-darwin-arm64` and `vendor/ethos-linux-x64`. The current published npm package is `@docushell/ethos-pdf@0.5.0`. Its vendored CLI binaries report -`ethos 0.5.0`. +`ethos 0.6.0`. diff --git a/packages/npm/ethos-pdf/package-lock.json b/packages/npm/ethos-pdf/package-lock.json index 1c20b9e6..1efcfdaf 100644 --- a/packages/npm/ethos-pdf/package-lock.json +++ b/packages/npm/ethos-pdf/package-lock.json @@ -1,12 +1,12 @@ { "name": "@docushell/ethos-pdf", - "version": "0.5.0", + "version": "0.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@docushell/ethos-pdf", - "version": "0.5.0", + "version": "0.6.0", "cpu": [ "arm64", "x64" diff --git a/packages/npm/ethos-pdf/package.json b/packages/npm/ethos-pdf/package.json index 037fe12b..6952608b 100644 --- a/packages/npm/ethos-pdf/package.json +++ b/packages/npm/ethos-pdf/package.json @@ -1,6 +1,6 @@ { "name": "@docushell/ethos-pdf", - "version": "0.5.0", + "version": "0.6.0", "description": "Ethos PDF CLI binary package for document evidence workflows.", "license": "Apache-2.0", "main": "./index.js", diff --git a/packages/npm/ethos-pdf/test/platform-selection.test.js b/packages/npm/ethos-pdf/test/platform-selection.test.js index bbf98234..b76c66e3 100644 --- a/packages/npm/ethos-pdf/test/platform-selection.test.js +++ b/packages/npm/ethos-pdf/test/platform-selection.test.js @@ -49,7 +49,7 @@ assert.throws( const manifest = readVendorManifest(); assert.strictEqual(manifest.version, 1); assert.strictEqual(manifest.package, "@docushell/ethos-pdf"); -assert.strictEqual(manifest.cli_version, "0.5.0"); +assert.strictEqual(manifest.cli_version, "0.6.0"); validateVendorManifest(manifest); for (const [key, binaryName] of SUPPORTED_TARGETS.entries()) { assert.strictEqual(manifest.targets[key].binary, binaryName); diff --git a/packages/npm/ethos-pdf/vendor/ethos-darwin-arm64 b/packages/npm/ethos-pdf/vendor/ethos-darwin-arm64 index 05132673..f77a73d5 100755 Binary files a/packages/npm/ethos-pdf/vendor/ethos-darwin-arm64 and b/packages/npm/ethos-pdf/vendor/ethos-darwin-arm64 differ diff --git a/packages/npm/ethos-pdf/vendor/ethos-linux-x64 b/packages/npm/ethos-pdf/vendor/ethos-linux-x64 index cf0ee30c..c2dd49ff 100755 Binary files a/packages/npm/ethos-pdf/vendor/ethos-linux-x64 and b/packages/npm/ethos-pdf/vendor/ethos-linux-x64 differ diff --git a/packages/npm/ethos-pdf/vendor/manifest.json b/packages/npm/ethos-pdf/vendor/manifest.json index b4355cc9..11b1de28 100644 --- a/packages/npm/ethos-pdf/vendor/manifest.json +++ b/packages/npm/ethos-pdf/vendor/manifest.json @@ -1,19 +1,19 @@ { "version": 1, "package": "@docushell/ethos-pdf", - "cli_version": "0.5.0", + "cli_version": "0.6.0", "targets": { "darwin:arm64": { "binary": "ethos-darwin-arm64", - "binary_sha256": "df2d46efb96501b8071cd8665ca525ee5af4787804cd04d07262354199ead913", + "binary_sha256": "038bfd4f4443784c9410278e63709e21d6f40dc4d204a5842a6df73d1b165180", "release_asset": "ethos-macos-arm64.tar.gz", - "release_asset_sha256": "30fa34afda745d168e1af39a134e2281f4a409d425765f3dc85c2e312fcbbcc2" + "release_asset_sha256": "c116b3449a3de1f4bddc6217e7717a1307a6ef58c240e5404be0850af81789bb" }, "linux:x64": { "binary": "ethos-linux-x64", - "binary_sha256": "7b6b7cb03c1d16183b6cdd56f6d2ebe593a25ef257baa5b6553a0055c53e8f44", + "binary_sha256": "ba9c648edecd3579c4d9acf2b901d9ac9a2e194bd108ae0a4c485a17bf47e7a6", "release_asset": "ethos-linux-x64.tar.gz", - "release_asset_sha256": "592b175c00d147625f2f2ccc8bc5c74fb8a00ee37f178c363757f2c72404876e" + "release_asset_sha256": "c12772255ba8a85b020bd9b6bb8bf77d01eaf11a6928a0d7348536eff7c378f2" } } }