diff --git a/.github/scripts/test_execution_status.py b/.github/scripts/test_execution_status.py index b422d98b..584e9e36 100644 --- a/.github/scripts/test_execution_status.py +++ b/.github/scripts/test_execution_status.py @@ -17,6 +17,7 @@ from __future__ import annotations +import json import unittest from pathlib import Path @@ -29,23 +30,33 @@ def status_text() -> str: return EXECUTION_STATUS.read_text(encoding="utf-8") +def published_version() -> str: + """The published release, from the ledger the status block is rendered from.""" + return json.loads((ROOT / "docs/release-state.json").read_text(encoding="utf-8"))["release"]["version"] + + class ExecutionStatusTests(unittest.TestCase): def test_status_is_scoped_to_internal_continuation(self) -> None: text = status_text() + # Derived from the ledger. These sentences are RENDERED from docs/release-state.json by + # check_release_state.py, so transcribing the version here made a generated block need a + # hand edit in its own test every release — and the test then asserted the previous + # release's prose against a block that had correctly moved on. + published = published_version() self.assertIn( - "Status: v0.5.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` " - "are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI.", + f"Status: v{published} Rust library crates `ethos-doc-core`, `ethos-verify`, and " + "`ethos-pdf` are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI.", text, ) self.assertIn( - "The exact v0.5.0 public install wording packet is approved and closed out", + f"The exact v{published} public install wording packet is approved and closed out", text, ) self.assertIn("docs/validation/v0-3-0-public-install-wording-approval-decision-validation-2026-07-02.md", text) self.assertIn("docs/validation/v0-3-0-public-install-wording-closeout-validation-2026-07-02.md", text) self.assertIn("GitHub Release `v0.3.0`", text) - self.assertIn("npm `@docushell/ethos-pdf@0.5.0` is live on npm", text) + self.assertIn(f"npm `@docushell/ethos-pdf@{published}` is live on npm", text) self.assertIn("v0.3.0 npm publication closeout", text) self.assertIn("DocuShell integration remain blocked", text) self.assertIn("Internal Milestone D source-only closeout remains complete", text) @@ -89,6 +100,7 @@ def test_internal_check_command_is_documented(self) -> None: def test_public_posture_boundary_remains_explicit(self) -> None: text = status_text() + published = published_version() self.assertIn( "Public language may use this exact approved sentence on the current source, Rust crate, Python wheel, " @@ -106,15 +118,15 @@ def test_public_posture_boundary_remains_explicit(self) -> None: text, ) self.assertIn( - "v0.5.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io", + f"v{published} Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io", text, ) self.assertIn("the Python `ethos-pdf` wheel is live on PyPI", text) - self.assertIn("npm `@docushell/ethos-pdf@0.5.0` is live on npm", text) - self.assertIn("The exact v0.5.0 public install wording packet is approved and closed out", text) - self.assertIn("GitHub Release `v0.5.0`", text) + self.assertIn(f"npm `@docushell/ethos-pdf@{published}` is live on npm", text) + self.assertIn(f"The exact v{published} public install wording packet is approved and closed out", text) + self.assertIn(f"GitHub Release `v{published}`", text) self.assertIn("macOS arm64/Linux x64 CLI artifacts", text) - self.assertIn("`@docushell/ethos-pdf@0.5.0`", text) + self.assertIn(f"`@docushell/ethos-pdf@{published}`", text) self.assertIn("docs/validation/v0-3-0-publication-closeout-validation-2026-07-01.md", text) self.assertIn("ethos-doc-core", text) self.assertIn("ethos-verify", text) diff --git a/.github/scripts/test_npm_binary_package_scaffold.py b/.github/scripts/test_npm_binary_package_scaffold.py index 51caea60..3a95e229 100644 --- a/.github/scripts/test_npm_binary_package_scaffold.py +++ b/.github/scripts/test_npm_binary_package_scaffold.py @@ -165,8 +165,17 @@ def test_package_docs_keep_pdfium_and_publication_boundaries(self) -> None: self.assertIn("does not bundle PDFium", text) 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.6.0`", text) + # Derived: the published npm version comes from the ledger, the vendored CLI version + # from the payload manifest. They differ during a refresh window and transcribing either + # made this gate need a hand edit every release. + published_npm = json.loads( + (ROOT / "docs/release-state.json").read_text(encoding="utf-8") + )["release"]["npm_package"]["version"] + vendored = json.loads(VENDOR_MANIFEST.read_text(encoding="utf-8"))["cli_version"] + self.assertIn( + f"current published npm package is `@docushell/ethos-pdf@{published_npm}`", text + ) + self.assertIn(f"`ethos {vendored}`", 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_public_surface_posture.py b/.github/scripts/test_public_surface_posture.py index c133df42..d81cf9a8 100644 --- a/.github/scripts/test_public_surface_posture.py +++ b/.github/scripts/test_public_surface_posture.py @@ -18,6 +18,7 @@ from __future__ import annotations import json +import re import unittest from pathlib import Path @@ -49,16 +50,31 @@ def test_readme_status_matches_supported_release_scope(self) -> None: self.assertIn("Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf`", normalized) self.assertIn("Python `ethos-pdf` wheel", normalized) self.assertIn("caller-provided PDFium", text) - self.assertIn("cargo add ethos-doc-core@0.5.0", text) - self.assertIn("cargo add ethos-verify@0.5.0", text) - self.assertIn("cargo add ethos-pdf@0.5.0", text) - self.assertIn("python3 -m pip install ethos-pdf==0.5.0", text) - self.assertIn("npm install -g @docushell/ethos-pdf@0.5.0", text) - self.assertIn("GitHub Release `v0.5.0`", text) - self.assertNotIn("cargo add ethos-doc-core@0.2.0", text) - self.assertNotIn("python3 -m pip install ethos-pdf==0.2.0", text) - self.assertNotIn("npm install -g @docushell/ethos-pdf@0.2.1", text) - self.assertNotIn("@docushell/ethos-pdf@0.2.0` is deprecated", text) + # Derived from the ledger, not transcribed. These were hand-pinned literals that needed + # editing every release and were the last version strings in this file anchored to + # nothing. `release.version` is what is published, so an install command naming any + # other version is by definition wrong. + published = json.loads(read(ROOT / "docs/release-state.json"))["release"]["version"] + for command in ( + f"cargo add ethos-doc-core@{published}", + f"cargo add ethos-verify@{published}", + f"cargo add ethos-pdf@{published}", + f"python3 -m pip install ethos-pdf=={published}", + f"npm install -g @docushell/ethos-pdf@{published}", + f"GitHub Release `v{published}`", + ): + self.assertIn(command, text, command) + + # No install command may name any version other than the published one. This replaces + # the negative assertions retired with test_v0_6_0_version_activation.py, which were + # the only guard against a stale install string surviving in README.md. + for pattern, label in ( + (r"cargo add ethos-(?:doc-core|verify|pdf)@([0-9]+\.[0-9]+\.[0-9]+)", "cargo add"), + (r"pip install ethos-pdf==([0-9]+\.[0-9]+\.[0-9]+)", "pip install"), + (r"npm install -g @docushell/ethos-pdf@([0-9]+\.[0-9]+\.[0-9]+)", "npm install"), + ): + found = set(re.findall(pattern, text)) + self.assertEqual({published}, found, f"{label} versions in README.md: {sorted(found)}") self.assertNotIn("not production-ready", text.lower()) self.assertNotIn("not stable production surfaces", text.lower()) self.assertNotIn("contracts phase", text) diff --git a/.github/scripts/test_v0_6_0_version_activation.py b/.github/scripts/test_v0_6_0_version_activation.py deleted file mode 100644 index 0f3af67e..00000000 --- a/.github/scripts/test_v0_6_0_version_activation.py +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2026 The Ethos maintainers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -"""Guard v0.6.0 core activation while v0.5.0 remains the published public baseline. - -The workspace, the Python package, and the internal crate pins move to 0.6.0 together so release -artifacts build at the right version. Nothing about that makes 0.6.0 installable: the advertised -install commands, the claims registry, and the vendored npm payload keep naming the published -0.5.0 until v0.6.0 artifacts actually publish. - -The npm payload deliberately does **not** advance here. That package ships a vendored CLI binary, -and no v0.6.0 binary exists yet, so bumping the package version would advertise a version the -package does not contain. It advances when the payload is refreshed from published v0.6.0 -artifacts, under its own recorded boundary exception. - -Published-baseline assertions live in `test_v0_5_0_version_activation.py`. This module owns -activation only. -""" - -from __future__ import annotations - -import json -import unittest -from pathlib import Path - - -ROOT = Path(__file__).resolve().parents[2] -ACTIVATED = "0.6.0" -PUBLISHED = "0.5.0" -INTERNAL_WORKSPACE_DEPENDENCIES = ("ethos-core", "ethos-layout", "ethos-tables") -INTERNAL_CLI_DEPENDENCIES = ("ethos-pdf", "ethos-verify", "ethos-grounding-opendataloader-json") - - -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") - cli = read("crates/ethos-cli/Cargo.toml") - lock = read("Cargo.lock") - - self.assertIn(f'version = "{ACTIVATED}"', cargo) - for dependency in INTERNAL_WORKSPACE_DEPENDENCIES: - line = next(line for line in cargo.splitlines() if line.startswith(dependency)) - self.assertIn(f'version = "{ACTIVATED}"', line, dependency) - for dependency in INTERNAL_CLI_DEPENDENCIES: - line = next(line for line in cli.splitlines() if line.startswith(dependency)) - self.assertIn(f'version = "{ACTIVATED}"', line, dependency) - - # Every workspace member resolves at the activated version. - self.assertGreaterEqual(lock.count(f'version = "{ACTIVATED}"'), 7) - self.assertIn(f'version = "{ACTIVATED}"', read("pyproject.toml")) - self.assertIn(f'__version__ = "{ACTIVATED}"', read("python/ethos_pdf/__init__.py")) - - def test_public_install_wording_is_not_advanced_to_the_candidate(self) -> None: - claims = read("docs/public-boundary-claims.json") - readme = read("README.md") - active_readme = readme.split("### 60-second `ethos-full` install", 1)[0] - - # Activation is not publication. Until v0.6.0 reaches the registries, advertising it would - # send users to an install command that cannot succeed. Prose about the v0.6.0 plan is - # fine; an install command naming it is not. - for command in ( - f"cargo add ethos-doc-core@{ACTIVATED}", - f"cargo add ethos-verify@{ACTIVATED}", - f"cargo add ethos-pdf@{ACTIVATED}", - f"python3 -m pip install ethos-pdf=={ACTIVATED}", - f"npm install -g @docushell/ethos-pdf@{ACTIVATED}", - f"@docushell/ethos-pdf@{ACTIVATED}", - ): - self.assertNotIn(command, active_readme, command) - self.assertNotIn(command, claims, command) - self.assertIn(f"npm install -g @docushell/ethos-pdf@{PUBLISHED}", active_readme) - - # 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")) - package = json.loads(read("packages/npm/ethos-pdf/package.json")) - lock = json.loads(read("packages/npm/ethos-pdf/package-lock.json")) - versions = { - manifest["cli_version"], - package["version"], - lock["version"], - lock["packages"][""].get("version"), - } - - if versions == {ACTIVATED}: - # A refresh to the activated version is allowed only with its recorded exception, - # mirroring how the v0.5.0 payload refresh was governed. - self.assertIn( - f"boundary-exception: refresh the v{ACTIVATED} npm B payload from frozen core-A", - read("CHANGELOG.md"), - ) - else: - self.assertEqual({PUBLISHED}, versions) - - def test_release_state_still_records_the_published_version(self) -> None: - state = json.loads(read("docs/release-state.json")) - - # The release ledger describes what is live, not what is being prepared. - self.assertEqual(PUBLISHED, state["release"]["version"]) - - -if __name__ == "__main__": - unittest.main() diff --git a/.github/scripts/test_version_activation_lockstep.py b/.github/scripts/test_version_activation_lockstep.py new file mode 100644 index 00000000..f07fcd2f --- /dev/null +++ b/.github/scripts/test_version_activation_lockstep.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# +# Copyright 2026 The Ethos maintainers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""Version lockstep guards, read from the ledger rather than a hard-coded release. + +This replaces `test_v0_6_0_version_activation.py`, the sixth hand-written generation of one +gate. That module hard-coded ACTIVATED and PUBLISHED, so every release needed a new copy and +the old one asserted a premise that had become false. Both constants now come from +`docs/release-state.json`: `release.activated` is what the tree prepares, `release.version` is +what is published. + +Two assertions are worth keeping across releases: + +1. Core release metadata moves in lockstep. A version bump that reaches Cargo.toml but not + pyproject.toml, or the workspace but not the CLI manifest, ships a tree that disagrees with + itself about what it is. + +2. The npm payload's four version fields move as one set. 1d23604 moved three of them and left + `vendor/manifest.json` behind, producing a package labelled 0.6.0 whose vendored CLI reported + `ethos 0.5.0` with the full suite green; 46d9584 had to revert it. The set may sit at the + published version, or at the activated version with its recorded boundary exception, and + nothing else. +""" + +from __future__ import annotations + +import json +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +INTERNAL_WORKSPACE_DEPENDENCIES = ("ethos-core", "ethos-layout", "ethos-tables") +INTERNAL_CLI_DEPENDENCIES = ("ethos-pdf", "ethos-verify", "ethos-grounding-opendataloader-json") + + +def read(relative: str) -> str: + return (ROOT / relative).read_text(encoding="utf-8") + + +def ledger() -> dict: + return json.loads(read("docs/release-state.json"))["release"] + + +class VersionActivationLockstepTests(unittest.TestCase): + def setUp(self) -> None: + release = ledger() + self.activated = release["activated"] + self.published = release["version"] + + def test_core_release_metadata_is_activated_in_lockstep(self) -> None: + activated = self.activated + cargo = read("Cargo.toml") + cli = read("crates/ethos-cli/Cargo.toml") + lock = read("Cargo.lock") + + self.assertIn(f'version = "{activated}"', cargo) + for dependency in INTERNAL_WORKSPACE_DEPENDENCIES: + line = next(line for line in cargo.splitlines() if line.startswith(dependency)) + self.assertIn(f'version = "{activated}"', line, dependency) + for dependency in INTERNAL_CLI_DEPENDENCIES: + line = next(line for line in cli.splitlines() if line.startswith(dependency)) + self.assertIn(f'version = "{activated}"', line, dependency) + + # Every workspace member resolves at the activated version. + self.assertGreaterEqual(lock.count(f'version = "{activated}"'), 7) + self.assertIn(f'version = "{activated}"', read("pyproject.toml")) + self.assertIn(f'__version__ = "{activated}"', read("python/ethos_pdf/__init__.py")) + + def test_npm_payload_versions_move_as_one_set(self) -> None: + manifest = json.loads(read("packages/npm/ethos-pdf/vendor/manifest.json")) + package = json.loads(read("packages/npm/ethos-pdf/package.json")) + lock = json.loads(read("packages/npm/ethos-pdf/package-lock.json")) + versions = { + manifest["cli_version"], + package["version"], + lock["version"], + lock["packages"][""].get("version"), + } + + self.assertEqual(1, len(versions), f"npm payload versions disagree: {sorted(versions)}") + moved = versions.pop() + + if moved != self.published: + # A payload ahead of the published release is a refresh, allowed only with its + # recorded exception — the governance 46d9584 restored after 1d23604 skipped it. + self.assertEqual(self.activated, moved) + self.assertIn( + f"boundary-exception: refresh the v{moved} npm B payload from frozen core-A", + read("CHANGELOG.md"), + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c953257..d7c45296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,62 @@ ## Unreleased +### v0.6.0 publication closeout + +- boundary-exception: `docs/release-state.json` records 0.6.0 as published. `release.version` + moves to `0.6.0`, `published_cli` carries the published archive and binary digests for both + targets, `github_release` describes the live release and its 16 assets, `package_tags` names the + 0.6.0 triple, and every `closed_lanes` entry points at the new closeout record. All six surfaces + were verified against the live registries before this landed, not asserted from the tree. + +- boundary-exception: install pins across `README.md`, `python/README.md`, `python/QUICKSTART.md`, + the two npm surfaces, and `docs/public-boundary-claims.json` move to `0.6.0`. This is the exact + wording packet approved on 2026-07-31, applied at publication, which is the only point at which + it was authorised to land. + +- The live GitHub Release body still read `This release prepares:`, `The intended v0.6.0 release + surfaces are:`, and listed both archive checksums as `pending — recorded here from the approved + archives before publication`. `docs/releases/v0.6.0.md` is the canonical body, so it is corrected + to published tense with the four real digests, and the corrected text is pushed to the release. + This is the same defect this CHANGELOG records for v0.5.0, whose body read `release candidate` + until it was retrofitted; it recurred because the notes were written before publication and + nothing rereads them at publication time. + +- The release notes now state that the eight published `*.inventory.json` sidecars still read + `draft_not_release_ready`. `write_release_artifact_inventory.py` hard-codes that value and cannot + describe an approved artifact, so without the caveat the machine-readable evidence attached to + the release contradicts the release itself. + +- boundary-exception: `test_v0_6_0_version_activation.py` is retired and replaced by + `test_version_activation_lockstep.py`, which reads the activated and published versions from the + ledger instead of hard-coding them. It was the sixth hand-written generation of one gate, and its + premise — that 0.6.0 is activated but unpublished — is now false. Both durable assertions are + preserved: core metadata moving in lockstep, and the npm payload's four version fields moving as + one set with a recorded boundary exception. The second is the guard that forced `1d23604`'s + revert, and retiring it without replacement would have reopened that defect. + +- `test_public_surface_posture.py` derives its install literals from the ledger rather than + transcribing them, and gains exact-set assertions that no install command in `README.md` names + any version other than the published one. The retired module held the only negative assertions + against stale install strings; without a replacement a leftover `0.5.0` pin would have passed + every gate. + +- The published GitHub Action pin follows the ledger to `v0.6.0`. `actions/verify/README.md` said + the Action downloads "the fixed v0.4.0 Linux x64 release archive" — three releases stale, and + asserted by nothing — and is now version-neutral. + +- **The published GitHub Action was broken by v0.6.0 and is fixed here.** `run_verify.py` read + `checks` at the top level of the verification report. Since 0.6.0 every verdict-bearing command + emits an in-toto Statement and that report is its `predicate` — `README.md` says so under + "Upgrading from 0.5" — so the Action failed with `verification report must contain a checks + array` against its own pinned CLI. It now unwraps the statement when present and reads the bare + report otherwise, detected by shape rather than version, so it works against both 0.5.x and + 0.6.x. Surfaced only because the Action pin moved to v0.6.0 in this change and `ci.yml`'s + `released-cli-action-dogfood` actually executes it; no test covered the report shape. + +- `test_npm_binary_package_scaffold.py` derives the published npm version from the ledger and the + vendored CLI version from the payload manifest, rather than transcribing either. + ### 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 diff --git a/Makefile b/Makefile index b4c619ac..c5025de8 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ release-gates: $(PYTHON) .github/scripts/test_readiness_gate.py $(PYTHON) .github/scripts/test_execution_status.py $(PYTHON) .github/scripts/test_validation_record_source.py - $(PYTHON) .github/scripts/test_v0_6_0_version_activation.py + $(PYTHON) .github/scripts/test_version_activation_lockstep.py verify-alpha-tree: cargo check --locked -p ethos-verify diff --git a/README.md b/README.md index 1f7009de..6ce530fd 100644 --- a/README.md +++ b/README.md @@ -222,22 +222,22 @@ ethos --help To add the currently approved Rust library crates to another Rust project: ```bash -cargo add ethos-doc-core@0.5.0 -cargo add ethos-verify@0.5.0 -cargo add ethos-pdf@0.5.0 +cargo add ethos-doc-core@0.6.0 +cargo add ethos-verify@0.6.0 +cargo add ethos-pdf@0.6.0 ``` To install the Python wrapper from PyPI: ```bash -python3 -m pip install ethos-pdf==0.5.0 +python3 -m pip install ethos-pdf==0.6.0 ``` The Python wheel is a thin wrapper around a caller-provided local `ethos` CLI binary. It does not bundle the CLI or PDFium. Install or provide `ethos` separately, and keep `ETHOS_PDFIUM_LIBRARY_PATH` set for PDFium-backed commands. -The v0.5.0 Python wrapper includes JSON verification and evidence anchoring through that +The v0.6.0 Python wrapper includes JSON verification and evidence anchoring through that caller-provided CLI: ```python @@ -262,7 +262,7 @@ behavior. To install the npm CLI package on a supported first-release platform: ```bash -npm install -g @docushell/ethos-pdf@0.5.0 +npm install -g @docushell/ethos-pdf@0.6.0 ethos --version ``` @@ -273,7 +273,7 @@ platforms fail before invoking a binary. PDFium-backed commands fail until Run `ethos doctor` for local setup diagnostics. Run `ethos doctor --require-pdfium` after setting `ETHOS_PDFIUM_LIBRARY_PATH` to check whether the configured PDFium is usable by Ethos. -GitHub Release `v0.5.0` also provides CLI archives for macOS arm64 and Linux x64. +GitHub Release `v0.6.0` also provides CLI archives for macOS arm64 and Linux x64. ## 2-minute PDF parse quickstart diff --git a/actions/verify/README.md b/actions/verify/README.md index bef9ab03..875d8696 100644 --- a/actions/verify/README.md +++ b/actions/verify/README.md @@ -14,7 +14,7 @@ supplied source representation; it does not establish semantic truth. The Action writes `ethos-verification-report.json`, fails on ungrounded citations (CLI exit `1`), and fails on operational errors (CLI exit `>=2`). It supports GitHub-hosted Linux x64 runners; -other platforms fail explicitly. The Action downloads only the fixed v0.4.0 Linux x64 release +other platforms fail explicitly. The Action downloads only the pinned Linux x64 release archive and verifies both its archive and executable SHA256 values before execution. Pin the Action itself to a full Ethos commit SHA. Marketplace publication is deferred; this diff --git a/actions/verify/action.yml b/actions/verify/action.yml index 556a03d9..fbf8a4e0 100644 --- a/actions/verify/action.yml +++ b/actions/verify/action.yml @@ -25,9 +25,9 @@ runs: - name: Install pinned Ethos CLI shell: bash env: - ETHOS_ACTION_ARCHIVE_URL: https://github.com/docushell/ethos/releases/download/v0.5.0/ethos-linux-x64.tar.gz - ETHOS_ACTION_ARCHIVE_SHA256: 592b175c00d147625f2f2ccc8bc5c74fb8a00ee37f178c363757f2c72404876e - ETHOS_ACTION_BINARY_SHA256: 7b6b7cb03c1d16183b6cdd56f6d2ebe593a25ef257baa5b6553a0055c53e8f44 + ETHOS_ACTION_ARCHIVE_URL: https://github.com/docushell/ethos/releases/download/v0.6.0/ethos-linux-x64.tar.gz + ETHOS_ACTION_ARCHIVE_SHA256: c12772255ba8a85b020bd9b6bb8bf77d01eaf11a6928a0d7348536eff7c378f2 + ETHOS_ACTION_BINARY_SHA256: ba9c648edecd3579c4d9acf2b901d9ac9a2e194bd108ae0a4c485a17bf47e7a6 run: | python3 "$GITHUB_ACTION_PATH/install_cli.py" \ --url "$ETHOS_ACTION_ARCHIVE_URL" \ diff --git a/actions/verify/run_verify.py b/actions/verify/run_verify.py index 7bc5879d..c8836dc1 100644 --- a/actions/verify/run_verify.py +++ b/actions/verify/run_verify.py @@ -44,6 +44,17 @@ def load_report(path: Path) -> dict[str, Any]: report = json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError) as error: raise ValueError(f"verification report is missing or invalid: {error}") from error + + # Since 0.6.0 every verdict-bearing command emits an in-toto Statement and the report the + # Action parses is its `predicate`. Unwrap it when present and keep reading the bare report + # otherwise, so the Action works against both the 0.5.x and 0.6.x CLI. Detected by shape + # rather than by version, because the Action only knows the binary it downloaded. + if isinstance(report, dict) and "predicate" in report and "checks" not in report: + predicate = report.get("predicate") + if not isinstance(predicate, dict): + raise ValueError("verification statement predicate must be an object") + report = predicate + if not isinstance(report, dict) or not isinstance(report.get("checks"), list): raise ValueError("verification report must contain a checks array") if not isinstance(report.get("all_evidence_grounded"), bool): diff --git a/docs/execution-status.md b/docs/execution-status.md index 451a9c99..c63f1f44 100644 --- a/docs/execution-status.md +++ b/docs/execution-status.md @@ -3,9 +3,9 @@ Date: 2026-07-20 Owner: product / decider -Status: v0.5.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI. Its released version is `0.5.0`. GitHub Release `v0.5.0` is marked as the repository's latest release and contains closed-out macOS arm64/Linux x64 CLI artifacts built against caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`. npm `@docushell/ethos-pdf@0.5.0` is live on npm. The exact v0.5.0 public install wording packet is approved and closed out. Package-tag creation for `ethos-package-ethos-doc-core-0.5.0`, `ethos-package-ethos-verify-0.5.0`, and `ethos-package-ethos-pdf-0.5.0` is closed out, and the existing release tag is closed out. +Status: v0.6.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI. Its released version is `0.6.0`. GitHub Release `v0.6.0` is marked as the repository's latest release and contains closed-out macOS arm64/Linux x64 CLI artifacts built against caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`. npm `@docushell/ethos-pdf@0.6.0` is live on npm. The exact v0.6.0 public install wording packet is approved and closed out. Package-tag creation for `ethos-package-ethos-doc-core-0.6.0`, `ethos-package-ethos-verify-0.6.0`, and `ethos-package-ethos-pdf-0.6.0` is closed out, and the existing release tag is closed out. -Current closeout records: [rust python publication](validation/v0-5-0-release-closeout-summary.md); [github release artifacts](validation/v0-5-0-release-closeout-summary.md); [npm publication](validation/v0-5-0-release-closeout-summary.md); [public install wording](validation/v0-5-0-release-closeout-summary.md); [package tags](validation/v0-5-0-release-closeout-summary.md); [release tag](validation/v0-5-0-release-closeout-summary.md); [release metadata](validation/v0-5-0-release-closeout-summary.md). +Current closeout records: [rust python publication](validation/v0-6-0-release-closeout-summary.md); [github release artifacts](validation/v0-6-0-release-closeout-summary.md); [npm publication](validation/v0-6-0-release-closeout-summary.md); [public install wording](validation/v0-6-0-release-closeout-summary.md); [package tags](validation/v0-6-0-release-closeout-summary.md); [release tag](validation/v0-6-0-release-closeout-summary.md); [release metadata](validation/v0-6-0-release-closeout-summary.md). Still blocked: hosted surfaces, Windows packaged artifacts, bundled project-maintained PDFium builds, public benchmark reports and claims, speed, footprint, parser-quality, and table-quality claims, ethos-doc, and ethos-rag. @@ -13,7 +13,7 @@ Still blocked: hosted surfaces, Windows packaged artifacts, bundled project-main The generated block above is the sole current public-release authority in this historical ledger. Sections below preserve dated milestone and wording records for auditability; version statements inside them describe their recorded point in time and are not the current release state unless the -generated block explicitly repeats them. The published public baseline is `0.5.0`. +generated block explicitly repeats them. The published public baseline is `0.6.0`. ## v0.6.0 scope expanded to the major format release (2026-08-09) @@ -67,7 +67,7 @@ availability claim, and npm SDK availability wording all remain blocked. Two decider rulings landed on 2026-07-30. The Grounding JSON fingerprint is `representation_sha256`, the hash of the accepted artifact bytes, with `source.sha256` remaining a separate optional PDF binding; `docs/v0-6-0-release-prep.md` §6.4 and §8.1 were corrected to match -ADR-0016. Separately, the public install wording is advanced to the published `0.5.0` baseline +ADR-0016. Separately, the public install wording is advanced to the published `0.6.0` baseline after registry verification, retiring the pre-publication hold in `.github/scripts/test_v0_5_0_version_activation.py`. diff --git a/docs/public-boundary-claims.json b/docs/public-boundary-claims.json index 7dece04d..f142df16 100644 --- a/docs/public-boundary-claims.json +++ b/docs/public-boundary-claims.json @@ -8,17 +8,17 @@ "It does not decide whether an answer is true, relevant, or complete.", "A missing capability produces an explicit limitation, never a silent guess.", "PDF parsing additionally needs caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`.", - "GitHub Release `v0.5.0` also provides CLI archives for macOS arm64 and Linux x64.", + "GitHub Release `v0.6.0` also provides CLI archives for macOS arm64 and Linux x64.", "We publish no speed, footprint, or parser-quality comparisons.", - "cargo add ethos-doc-core@0.5.0", - "cargo add ethos-verify@0.5.0", - "cargo add ethos-pdf@0.5.0", - "python3 -m pip install ethos-pdf==0.5.0", + "cargo add ethos-doc-core@0.6.0", + "cargo add ethos-verify@0.6.0", + "cargo add ethos-pdf@0.6.0", + "python3 -m pip install ethos-pdf==0.6.0", "The Python wheel is a thin wrapper around a caller-provided local `ethos` CLI binary.", "It does not bundle the CLI or PDFium.", "The JSON verification and evidence-anchor wrapper calls use the caller-provided CLI and do not require PDFium unless the chosen command path invokes PDFium-backed parser, crop, or render behavior.", "The npm package vendors only the supported macOS arm64 and Linux x64 CLI binaries.", - "npm install -g @docushell/ethos-pdf@0.5.0", + "npm install -g @docushell/ethos-pdf@0.6.0", "Unsupported platforms fail before invoking a binary.", "Windows packaged artifacts, bundled project-maintained PDFium builds, and hosted surfaces are outside the distribution scope" ] @@ -26,15 +26,15 @@ "python_readme": { "path": "python/README.md", "claims": [ - "python3 -m pip install ethos-pdf==0.5.0", - "`v0.5.0` includes JSON verification and evidence-anchor wrapper calls through a caller-provided `ethos` CLI binary.", + "python3 -m pip install ethos-pdf==0.6.0", + "`v0.6.0` includes JSON verification and evidence-anchor wrapper calls through a caller-provided `ethos` CLI binary.", "The Python wheel does not bundle the CLI or PDFium." ] }, "python_quickstart": { "path": "python/QUICKSTART.md", "claims": [ - "python3 -m pip install ethos-pdf==0.5.0", + "python3 -m pip install ethos-pdf==0.6.0", "The `ethos-pdf` Python package is a thin wrapper around a caller-provided local `ethos` CLI binary.", "It does not bundle Ethos or PDFium." ] @@ -42,7 +42,7 @@ "npm_readme": { "path": "packages/npm/ethos-pdf/README.md", "claims": [ - "The current published npm package is `@docushell/ethos-pdf@0.5.0`.", + "The current published npm package is `@docushell/ethos-pdf@0.6.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`." @@ -51,8 +51,8 @@ "npm_quickstart": { "path": "packages/npm/ethos-pdf/QUICKSTART.md", "claims": [ - "npm install -g @docushell/ethos-pdf@0.5.0", - "The current published npm package is `@docushell/ethos-pdf@0.5.0`.", + "npm install -g @docushell/ethos-pdf@0.6.0", + "The current published npm package is `@docushell/ethos-pdf@0.6.0`.", "Its vendored CLI binaries report `ethos 0.6.0`.", "The package does not bundle PDFium." ] diff --git a/docs/public-release-checklist.md b/docs/public-release-checklist.md index dfc28b82..633e8b22 100644 --- a/docs/public-release-checklist.md +++ b/docs/public-release-checklist.md @@ -6,9 +6,9 @@ announcements. It is intentionally stricter than the day-to-day engineering gate ## Current Status -Status: v0.5.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI. Its released version is `0.5.0`. GitHub Release `v0.5.0` is marked as the repository's latest release and contains closed-out macOS arm64/Linux x64 CLI artifacts built against caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`. npm `@docushell/ethos-pdf@0.5.0` is live on npm. The exact v0.5.0 public install wording packet is approved and closed out. Package-tag creation for `ethos-package-ethos-doc-core-0.5.0`, `ethos-package-ethos-verify-0.5.0`, and `ethos-package-ethos-pdf-0.5.0` is closed out, and the existing release tag is closed out. +Status: v0.6.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI. Its released version is `0.6.0`. GitHub Release `v0.6.0` is marked as the repository's latest release and contains closed-out macOS arm64/Linux x64 CLI artifacts built against caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`. npm `@docushell/ethos-pdf@0.6.0` is live on npm. The exact v0.6.0 public install wording packet is approved and closed out. Package-tag creation for `ethos-package-ethos-doc-core-0.6.0`, `ethos-package-ethos-verify-0.6.0`, and `ethos-package-ethos-pdf-0.6.0` is closed out, and the existing release tag is closed out. -Current closeout records: [rust python publication](validation/v0-5-0-release-closeout-summary.md); [github release artifacts](validation/v0-5-0-release-closeout-summary.md); [npm publication](validation/v0-5-0-release-closeout-summary.md); [public install wording](validation/v0-5-0-release-closeout-summary.md); [package tags](validation/v0-5-0-release-closeout-summary.md); [release tag](validation/v0-5-0-release-closeout-summary.md); [release metadata](validation/v0-5-0-release-closeout-summary.md). +Current closeout records: [rust python publication](validation/v0-6-0-release-closeout-summary.md); [github release artifacts](validation/v0-6-0-release-closeout-summary.md); [npm publication](validation/v0-6-0-release-closeout-summary.md); [public install wording](validation/v0-6-0-release-closeout-summary.md); [package tags](validation/v0-6-0-release-closeout-summary.md); [release tag](validation/v0-6-0-release-closeout-summary.md); [release metadata](validation/v0-6-0-release-closeout-summary.md). Still blocked: hosted surfaces, Windows packaged artifacts, bundled project-maintained PDFium builds, public benchmark reports and claims, speed, footprint, parser-quality, and table-quality claims, ethos-doc, and ethos-rag. diff --git a/docs/release-state.json b/docs/release-state.json index ad6a8421..1e89c054 100644 --- a/docs/release-state.json +++ b/docs/release-state.json @@ -1,8 +1,8 @@ { "schema_version": 2, - "as_of": "2026-07-21", + "as_of": "2026-09-07", "release": { - "version": "0.5.0", + "version": "0.6.0", "activated": "0.6.0", "rust_crates": [ "ethos-doc-core", @@ -11,31 +11,31 @@ ], "python_package": { "name": "ethos-pdf", - "version": "0.5.0" + "version": "0.6.0" }, "npm_package": { "name": "@docushell/ethos-pdf", - "version": "0.5.0" + "version": "0.6.0" }, "github_release": { - "tag": "v0.5.0", - "version": "0.5.0", - "name": "Ethos v0.5.0", + "tag": "v0.6.0", + "version": "0.6.0", + "name": "Ethos v0.6.0", "latest": true, - "notes": "docs/releases/v0.5.0.md", + "notes": "docs/releases/v0.6.0.md", "platforms": [ "macOS arm64", "Linux x64" ], "assets": [ - "ethos-full-0.5.0-linux-x64.inventory.json", - "ethos-full-0.5.0-linux-x64.smoke.json", - "ethos-full-0.5.0-linux-x64.tar.gz", - "ethos-full-0.5.0-linux-x64.tar.gz.sha256", - "ethos-full-0.5.0-macos-arm64.inventory.json", - "ethos-full-0.5.0-macos-arm64.smoke.json", - "ethos-full-0.5.0-macos-arm64.tar.gz", - "ethos-full-0.5.0-macos-arm64.tar.gz.sha256", + "ethos-full-0.6.0-linux-x64.inventory.json", + "ethos-full-0.6.0-linux-x64.smoke.json", + "ethos-full-0.6.0-linux-x64.tar.gz", + "ethos-full-0.6.0-linux-x64.tar.gz.sha256", + "ethos-full-0.6.0-macos-arm64.inventory.json", + "ethos-full-0.6.0-macos-arm64.smoke.json", + "ethos-full-0.6.0-macos-arm64.tar.gz", + "ethos-full-0.6.0-macos-arm64.tar.gz.sha256", "ethos-linux-x64.inventory.json", "ethos-linux-x64.smoke.json", "ethos-linux-x64.tar.gz", @@ -47,32 +47,32 @@ ] }, "package_tags": [ - "ethos-package-ethos-doc-core-0.5.0", - "ethos-package-ethos-verify-0.5.0", - "ethos-package-ethos-pdf-0.5.0" + "ethos-package-ethos-doc-core-0.6.0", + "ethos-package-ethos-verify-0.6.0", + "ethos-package-ethos-pdf-0.6.0" ], "pdfium_environment": "ETHOS_PDFIUM_LIBRARY_PATH", "published_cli": { "linux-x64": { "archive": "ethos-linux-x64.tar.gz", - "archive_sha256": "592b175c00d147625f2f2ccc8bc5c74fb8a00ee37f178c363757f2c72404876e", - "binary_sha256": "7b6b7cb03c1d16183b6cdd56f6d2ebe593a25ef257baa5b6553a0055c53e8f44" + "archive_sha256": "c12772255ba8a85b020bd9b6bb8bf77d01eaf11a6928a0d7348536eff7c378f2", + "binary_sha256": "ba9c648edecd3579c4d9acf2b901d9ac9a2e194bd108ae0a4c485a17bf47e7a6" }, "macos-arm64": { "archive": "ethos-macos-arm64.tar.gz", - "archive_sha256": "30fa34afda745d168e1af39a134e2281f4a409d425765f3dc85c2e312fcbbcc2", - "binary_sha256": "df2d46efb96501b8071cd8665ca525ee5af4787804cd04d07262354199ead913" + "archive_sha256": "c116b3449a3de1f4bddc6217e7717a1307a6ef58c240e5404be0850af81789bb", + "binary_sha256": "038bfd4f4443784c9410278e63709e21d6f40dc4d204a5842a6df73d1b165180" } } }, "closed_lanes": { - "rust_python_publication": "docs/validation/v0-5-0-release-closeout-summary.md", - "github_release_artifacts": "docs/validation/v0-5-0-release-closeout-summary.md", - "npm_publication": "docs/validation/v0-5-0-release-closeout-summary.md", - "public_install_wording": "docs/validation/v0-5-0-release-closeout-summary.md", - "package_tags": "docs/validation/v0-5-0-release-closeout-summary.md", - "release_tag": "docs/validation/v0-5-0-release-closeout-summary.md", - "release_metadata": "docs/validation/v0-5-0-release-closeout-summary.md" + "rust_python_publication": "docs/validation/v0-6-0-release-closeout-summary.md", + "github_release_artifacts": "docs/validation/v0-6-0-release-closeout-summary.md", + "npm_publication": "docs/validation/v0-6-0-release-closeout-summary.md", + "public_install_wording": "docs/validation/v0-6-0-release-closeout-summary.md", + "package_tags": "docs/validation/v0-6-0-release-closeout-summary.md", + "release_tag": "docs/validation/v0-6-0-release-closeout-summary.md", + "release_metadata": "docs/validation/v0-6-0-release-closeout-summary.md" }, "blocked_lanes": [ "hosted surfaces", diff --git a/docs/releases/v0.6.0.md b/docs/releases/v0.6.0.md index e59aa2e4..0b440dda 100644 --- a/docs/releases/v0.6.0.md +++ b/docs/releases/v0.6.0.md @@ -7,7 +7,7 @@ The release turns on capability the verifier already had internally but could no wire, and closes a set of correctness seams where two implementations of one rule had drifted apart. -This release prepares: +This release delivers: - `ethos.grounding.v1` schema `1.1.0`, which admits eight page-less office media types — DOCX, XLSX, PPTX, ODT, ODS, ODP, RTF, EPUB — under a version-gated union. A `1.0.0` artifact is PDF @@ -39,12 +39,13 @@ This release prepares: index once rather than once per line; - proof statements: every verdict-bearing command emits a self-describing, self-attesting report. -The intended v0.6.0 release surfaces are: +The v0.6.0 release surfaces are: - Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` at `0.6.0`; - the Python `ethos-pdf` wheel at `0.6.0`; - the npm `@docushell/ethos-pdf@0.6.0` CLI package; -- macOS arm64 and Linux x64 CLI archives with checksums, inventory sidecars, and smoke evidence. +- macOS arm64 and Linux x64 CLI archives with checksums, inventory sidecars, and smoke evidence; +- optional `ethos-full` archives for macOS arm64 and Linux x64. Ethos verifies citation grounding against supplied source representations. It does not establish semantic truth, and applications remain responsible for relevance, synthesis policy, and final @@ -87,8 +88,13 @@ downstream without affecting any stored artifact. Published archive SHA256 values: -- `ethos-macos-arm64.tar.gz`: pending — recorded here from the approved archives before publication -- `ethos-linux-x64.tar.gz`: pending — recorded here from the approved archives before publication +- `ethos-macos-arm64.tar.gz`: `c116b3449a3de1f4bddc6217e7717a1307a6ef58c240e5404be0850af81789bb` +- `ethos-linux-x64.tar.gz`: `c12772255ba8a85b020bd9b6bb8bf77d01eaf11a6928a0d7348536eff7c378f2` +- `ethos-full-0.6.0-macos-arm64.tar.gz`: `a0fe3df1b572f47c42b8fc4d456d6ce0983277191a8324b889747407bddd2625` +- `ethos-full-0.6.0-linux-x64.tar.gz`: `d8cf121f111ff6ecb73670c79db4fc1c81e05d02b8cd5d8367104f5cbf3b38ac` + +The published `*.inventory.json` sidecars record pre-publication CI provenance and still read +`draft_not_release_ready`; they describe how each archive was produced, not its publication state. Outside the v0.6.0 release boundary: Windows packaged artifacts, bundled/project-maintained PDFium builds, `ethos-mcp`, hosted surfaces, the WASM playground, native OCR or scanned-document diff --git a/docs/validation/README.md b/docs/validation/README.md index 335e2008..1ef6618c 100644 --- a/docs/validation/README.md +++ b/docs/validation/README.md @@ -7,6 +7,7 @@ summary. Completed per-lane historical validation records were retired. - [v0.4.0 release closeout summary](v0-4-0-release-closeout-summary.md) - [v0.5.0 release closeout summary](v0-5-0-release-closeout-summary.md) - [NIP-5.2 ethos-full build evidence](nip-5-2-ethos-full-build-evidence-2026-07-20.md) +- [v0.6.0 release closeout summary](v0-6-0-release-closeout-summary.md) - [v0.6.0 clean-room mapper walkthrough](v0-6-0-clean-room-walkthrough.md) - [v0.6.0 DocuShell consumer acceptance](v0-6-0-docushell-acceptance.md) - [v0.6.0 double-run determinism evidence](v0-6-0-double-run-determinism.md) diff --git a/docs/validation/v0-6-0-release-closeout-summary.md b/docs/validation/v0-6-0-release-closeout-summary.md new file mode 100644 index 00000000..08da207a --- /dev/null +++ b/docs/validation/v0-6-0-release-closeout-summary.md @@ -0,0 +1,101 @@ +# Ethos v0.6.0 Release Closeout Summary + +Status: closed on 2026-09-07. + +## Source commits + +Two commits, not one. The published CLI archives, the three crates, and the Python wheel were +built from `8adda91cd01baae487c9f2b18e4054b58a378a20`, to which the annotated `v0.6.0` tag +dereferences. The npm payload — both vendored binaries, `vendor/manifest.json`, `package.json`, +and both lockfile version fields — moved in `d2423bb189d153ccab037ce734c9b8c275586a4b` (#242), +two commits later, because a payload refresh can only record digests that already exist. + +Recorded as two commits deliberately. The v0.5.0 record bound core-A and npm-B separately for the +same reason, and binding every surface here to a single commit would state a provenance fact that +is false for the npm tarball. + +## GitHub Release + +[v0.6.0](https://github.com/docushell/ethos/releases/tag/v0.6.0) is live, non-draft, +non-prerelease, and marked latest. It carries 16 assets: the macOS arm64 and Linux x64 +caller-PDFium CLI archives and the optional `ethos-full` archives, each with checksum, inventory, +and target-smoke sidecars. No Windows artifact was published; the run produced a verify-only +Windows candidate, which was deliberately withheld because Windows packaged artifacts remain a +blocked lane. + +Published archive SHA-256 values: + +- `ethos-macos-arm64.tar.gz`: `c116b3449a3de1f4bddc6217e7717a1307a6ef58c240e5404be0850af81789bb`; +- `ethos-linux-x64.tar.gz`: `c12772255ba8a85b020bd9b6bb8bf77d01eaf11a6928a0d7348536eff7c378f2`; +- `ethos-full-0.6.0-macos-arm64.tar.gz`: `a0fe3df1b572f47c42b8fc4d456d6ce0983277191a8324b889747407bddd2625`; +- `ethos-full-0.6.0-linux-x64.tar.gz`: `d8cf121f111ff6ecb73670c79db4fc1c81e05d02b8cd5d8367104f5cbf3b38ac`. + +Each was recomputed from the downloaded archive and matched its published `.sha256` sidecar. That +check verifies transport rather than provenance, because the sidecar is generated in the same +workflow step as the archive; provenance rests on the source commit and release run 33325655578 +recorded in [`v0-6-0-release-promotion.md`](v0-6-0-release-promotion.md). + +**The eight published `*.inventory.json` sidecars still read `draft_not_release_ready` and +`publication: blocked`.** `write_release_artifact_inventory.py` hard-codes both and cannot describe +an approved artifact. They record how each archive was produced, not its publication state. Read +this record for publication state, not the sidecars. + +## Registries + +The Rust crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io at +`0.6.0`, none yanked. The Python `ethos-pdf` wheel is live on PyPI at `0.6.0`, its wheel and sdist +byte-identical to the locally built artifacts. `@docushell/ethos-pdf@0.6.0` is live on npm; the +published tarball was downloaded and its vendored binaries verified byte-identical to the release +archives, with the darwin binary executed and confirmed to report `ethos 0.6.0`. + +## Package tags + +The `ethos-package-*-0.6.0` tags are recorded in `docs/release-state.json`. + +**A prior claim is corrected here rather than repeated.** The ledger declared +`ethos-package-*-0.4.0` and `ethos-package-*-0.5.0` closed out against the v0.5.0 closeout record, +which does not mention package tags at all. Those six tags do not exist, locally or on the remote: +only the `0.1.0`, `0.1.2`, and `0.3.0` triples were ever created. `check_release_state.py` +string-matches the declared names against `release.rust_crates` and never consults git, which is +how the gap survived two releases. + +## Public wording + +The exact wording packet approved on 2026-07-31 in +[`v0-6-0-public-wording-request.md`](v0-6-0-public-wording-request.md) is applied at this +publication, which is the only point at which it was authorised to land. The mechanical hold that +approval names — `test_v0_6_0_version_activation.py` — is retired here, its durable lockstep and +npm-payload assertions preserved in a version-neutral module that reads the target version from +the ledger rather than from a hard-coded constant. + +The approval's limits are unchanged and none is widened: no production positioning, no hosted +surfaces, no Windows artifacts, no benchmark claims, no OCR, no parser-quality claim, and no claim +that a source-hash match proves faithful extraction. + +## Gates + +Release-prep, deterministic-build, target-smoke, claims, licence, package, and release-state gates +passed before publication. `release-live-state-check` compares this ledger against the live GitHub +Release rather than against itself. + +**Consumer acceptance is bound to the 0.5.0 CLI, not 0.6.0.** +[`v0-6-0-docushell-acceptance.md`](v0-6-0-docushell-acceptance.md) records DocuShell pinned to +`ethos 0.5.0` with the v0.5.0 archive and binary digests. It evidences that a real consumer reaches +the verifier through public surfaces only; it does not evidence a consumer exercising the 0.6.0 +bytes. Stated rather than inherited from the v0.5.0 record's wording. + +**Release-prep §5.1, the clean-room developer criterion, was removed by decider decision on +2026-08-30** rather than satisfied. The capability claim — any parser reaching the verifier through +one mapper, with no Rust and no PDFium — stays evidenced by the JavaScript, Python, and DocuShell +mappers. Discoverability, which §5.1 protected, is evidenced by nothing and is not claimed. + +## Boundary + +The release retains the caller-provided PDFium boundary for base archives. Public benchmark, speed, +footprint, parser-quality, table-quality, hosted, production, and Windows packaged claims remain +outside the approved release boundary, as do `ethos-doc` and `ethos-rag`. + +## Source binding + +Recorded against Ethos `8adda91cd01baae487c9f2b18e4054b58a378a20` and +`d2423bb189d153ccab037ce734c9b8c275586a4b`. diff --git a/packages/npm/ethos-pdf/QUICKSTART.md b/packages/npm/ethos-pdf/QUICKSTART.md index 7248a444..e8d54afe 100644 --- a/packages/npm/ethos-pdf/QUICKSTART.md +++ b/packages/npm/ethos-pdf/QUICKSTART.md @@ -23,10 +23,10 @@ PDFium dynamic library. Install the current published npm package with: ```sh -npm install -g @docushell/ethos-pdf@0.5.0 +npm install -g @docushell/ethos-pdf@0.6.0 ``` -The current published npm package is `@docushell/ethos-pdf@0.5.0`. Its vendored CLI binaries report +The current published npm package is `@docushell/ethos-pdf@0.6.0`. Its vendored CLI binaries report `ethos 0.6.0`. ## Vendor Binary Assembly diff --git a/packages/npm/ethos-pdf/README.md b/packages/npm/ethos-pdf/README.md index 177464be..69f59831 100644 --- a/packages/npm/ethos-pdf/README.md +++ b/packages/npm/ethos-pdf/README.md @@ -34,5 +34,5 @@ Vendor assembly: - the script extracts the `ethos` executable from each archive and writes `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 +The current published npm package is `@docushell/ethos-pdf@0.6.0`. Its vendored CLI binaries report `ethos 0.6.0`. diff --git a/python/QUICKSTART.md b/python/QUICKSTART.md index 720ce433..366d9e96 100644 --- a/python/QUICKSTART.md +++ b/python/QUICKSTART.md @@ -6,7 +6,7 @@ It does not bundle Ethos or PDFium. Install the published evaluation wheel from PyPI with: ```sh -python3 -m pip install ethos-pdf==0.5.0 +python3 -m pip install ethos-pdf==0.6.0 ``` ## PDFium Setup diff --git a/python/README.md b/python/README.md index 456a0dce..65d508da 100644 --- a/python/README.md +++ b/python/README.md @@ -5,10 +5,10 @@ This directory contains the `ethos-pdf` Python package source for Ethos. Install the published evaluation wheel from PyPI with: ```sh -python3 -m pip install ethos-pdf==0.5.0 +python3 -m pip install ethos-pdf==0.6.0 ``` -`v0.5.0` includes JSON verification and evidence-anchor wrapper calls through a caller-provided +`v0.6.0` includes JSON verification and evidence-anchor wrapper calls through a caller-provided `ethos` CLI binary. The Python wheel does not bundle the CLI or PDFium. The package exposes a public semver API beginning at `0.1.0` for Python `>=3.8`. Patch releases