diff --git a/.github/scripts/test_v0_3_0_package_publication_approval_request.py b/.github/scripts/test_v0_3_0_package_publication_approval_request.py new file mode 100644 index 0000000..2f2f93a --- /dev/null +++ b/.github/scripts/test_v0_3_0_package_publication_approval_request.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python3 +# +# Copyright 2026 The Ethos maintainers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# + +from __future__ import annotations + +import json +import re +import unittest +from pathlib import Path + +from makefile_guard import target_block +from validation_record_source import assert_record_source_binding + + +ROOT = Path(__file__).resolve().parents[2] +RECORD = ROOT / "docs/validation/v0-3-0-package-publication-approval-request-validation-2026-07-01.md" +EVIDENCE_RECORD = ROOT / "docs/validation/v0-3-0-package-build-evidence-validation-2026-07-01.md" +VALIDATION_README = ROOT / "docs/validation/README.md" +EXECUTION_STATUS = ROOT / "docs/execution-status.md" +PUBLIC_RELEASE_CHECKLIST = ROOT / "docs/public-release-checklist.md" +MAKEFILE = ROOT / "Makefile" +PYPROJECT = ROOT / "pyproject.toml" +PY_INIT = ROOT / "python/ethos_pdf/__init__.py" +NPM_PACKAGE = ROOT / "packages/npm/ethos-pdf/package.json" + +SOURCE_SHORT = "39cb548" +SOURCE_COMMIT = "39cb548cf6cfe20fbcb47ee605ba51f1ebf71f6b" +SOURCE_TREE = "35076461b03ce8476cd8d73077c6f0bcaeae7dc3" +EVIDENCE_SOURCE_COMMIT = "4b6d219df1757b6e4728c16c8023bee5c8cf8962" +VERSION = "0.3.0" +CRATES = ("ethos-doc-core", "ethos-verify", "ethos-pdf") +PACKAGE_TAGS = ( + "ethos-package-ethos-doc-core-0.3.0", + "ethos-package-ethos-verify-0.3.0", + "ethos-package-ethos-pdf-0.3.0", +) +CRATE_HASHES = { + "ethos-doc-core": ( + "ethos-doc-core-0.3.0.crate", + "7ba41a2ae299a53a4677153beaaec5ed486a07b5da08b2ef13974b9a0be141cb", + ), + "ethos-verify": ( + "ethos-verify-0.3.0.crate", + "00f001455ca207e65aaf464551d3ba05945cda0b06e9e1036f49ac587accbb95", + ), + "ethos-pdf": ( + "ethos-pdf-0.3.0.crate", + "c2f4f2ccb6de6e54cd3257597cd28e7f6dec2a6d22befbd230d2c4cf31931cfd", + ), +} +WHEEL = "ethos_pdf-0.3.0-py3-none-any.whl" +WHEEL_SHA256 = "9eb106deafcd1d9717e5e7b67dc9413180421aba25a5257266352d09540b3265" +FORBIDDEN = ( + "cargo publish approved", + "crates.io publication approved", + "pypi upload approved", + "pypi publication approved", + "python public installation wording approved", + "rust crate public installation wording approved", + "installable 0.3.0 wording approved", + "npm publication approved", + "github release publication approved", + "docushell integration approved", + "production-ready", + "hosted surfaces approved", + "windows packaged artifacts approved", + "bundled pdfium approved", + "public benchmark claims approved", +) +PRIVATE_PATH_MARKERS = ( + "/" + "Users/", + "/" + "private/tmp", + "/" + "private/var", + "/" + "var/folders", + "saumil" + "diwaker", + "Desktop/" + "Stuff", + "project/repo/" + "ethos", +) + + +def read(path: Path) -> str: + return path.read_text(encoding="utf-8") + + +def normalized(path: Path) -> str: + return re.sub(r"\s+", " ", read(path)) + + +class V030PackagePublicationApprovalRequestTests(unittest.TestCase): + def test_request_record_is_source_bound_and_indexed(self) -> None: + raw = read(RECORD) + record = normalized(RECORD) + + assert_record_source_binding( + self, + root=ROOT, + raw_record=raw, + normalized_record=record, + validated_head=SOURCE_SHORT, + source_label="v0.3.0 package publication approval request", + source_commit=SOURCE_COMMIT, + source_tree=SOURCE_TREE, + ) + self.assertIn(EVIDENCE_RECORD.name, record) + self.assertIn(EVIDENCE_SOURCE_COMMIT, record) + + for path in (VALIDATION_README, EXECUTION_STATUS, PUBLIC_RELEASE_CHECKLIST): + text = normalized(path) + self.assertIn(RECORD.name, text, str(path)) + self.assertIn("v0.3.0 package publication approval request", text.lower(), str(path)) + self.assertIn("remain blocked", text, str(path)) + + def test_request_names_exact_crates_wheel_hashes_and_order(self) -> None: + record = normalized(RECORD) + + self.assertIn( + "Status: **v0.3.0 package publication approval request recorded; crates.io and PyPI publication remain blocked**", + record, + ) + for crate in CRATES: + crate_file, digest = CRATE_HASHES[crate] + self.assertIn(f"`{crate} = {VERSION}`", record) + self.assertIn(crate_file, record) + self.assertIn(digest, record) + for tag in PACKAGE_TAGS: + self.assertIn(tag, record) + for expected in ( + WHEEL, + WHEEL_SHA256, + "SOURCE_DATE_EPOCH=0", + "app_answer_release_decision", + "proof_summary", + "cargo publish --locked -p ethos-doc-core", + "cargo publish --locked -p ethos-verify", + "cargo publish --locked -p ethos-pdf", + "Publish `ethos-doc-core` first.", + "Publish `ethos-verify` after crates.io reports `ethos-doc-core = 0.3.0`.", + "Publish `ethos-pdf` after crates.io reports `ethos-doc-core = 0.3.0`.", + ): + self.assertIn(expected, record) + + def test_request_does_not_publish_or_approve_public_wording(self) -> None: + raw = read(RECORD) + record = normalized(RECORD) + lower = record.lower() + + for expected in ( + "Manual action is required before any crates.io publication or PyPI upload.", + "This request record does not approve `cargo publish`.", + "This request record does not publish any crate.", + "This request record does not approve PyPI upload.", + "This request record does not upload any Python distribution.", + "This request record does not approve installable `0.3.0` public wording.", + "This request record does not approve `npm publish`.", + "This request record does not approve GitHub Release artifact publication.", + "This request record does not approve DocuShell integration.", + "Actual crates.io publication remains blocked pending explicit decider approval.", + "Actual PyPI upload remains blocked pending explicit decider approval.", + "PDFium remains caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`.", + "`ethos-doc` remains blocked.", + "`ethos-rag` remains blocked.", + ): + self.assertIn(expected, record) + for forbidden in FORBIDDEN: + self.assertNotIn(forbidden, lower) + for marker in PRIVATE_PATH_MARKERS: + self.assertNotIn(marker, raw) + + def test_source_metadata_and_package_scope_remain_bounded(self) -> None: + self.assertIn('version = "0.3.0"', read(PYPROJECT)) + self.assertIn('__version__ = "0.3.0"', read(PY_INIT)) + self.assertEqual("0.2.1", json.loads(read(NPM_PACKAGE))["version"]) + + for manifest in ( + ROOT / "crates/ethos-core/Cargo.toml", + ROOT / "crates/ethos-verify/Cargo.toml", + ROOT / "crates/ethos-pdf/Cargo.toml", + ): + text = read(manifest) + self.assertNotIn("publish = false", text, str(manifest)) + self.assertIn('publication_status = "approved_for_crates_io_publication"', text, str(manifest)) + + for manifest in ( + ROOT / "crates/ethos-cli/Cargo.toml", + ROOT / "crates/ethos-layout/Cargo.toml", + ROOT / "crates/ethos-tables/Cargo.toml", + ): + self.assertIn("publish = false", read(manifest), str(manifest)) + + def test_v0_3_release_prep_runs_request_guard_after_package_evidence(self) -> None: + makefile = read(MAKEFILE) + block = target_block("v0-3-release-prep") + evidence_guard = "$(PYTHON) .github/scripts/test_v0_3_0_package_build_evidence.py" + request_guard = "$(PYTHON) .github/scripts/test_v0_3_0_package_publication_approval_request.py" + public_surface_guard = "$(PYTHON) .github/scripts/test_public_surface_posture.py" + claims_guard = "$(PYTHON) .github/scripts/claims_gate.py" + + self.assertIn(request_guard, block) + self.assertEqual(1, makefile.count(request_guard)) + self.assertLess(block.index(evidence_guard), block.index(request_guard)) + self.assertLess(block.index(request_guard), block.index(public_surface_guard)) + self.assertLess(block.index(public_surface_guard), block.index(claims_guard)) + + +if __name__ == "__main__": + unittest.main() diff --git a/CHANGELOG.md b/CHANGELOG.md index 83c251b..68f7b18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +- boundary-exception: request decider review for exact v0.3.0 Rust crates.io publication inputs + and exact v0.3.0 deterministic PyPI wheel publication inputs while keeping `cargo publish`, + PyPI upload, npm publish, GitHub Release artifact publication, release/package tags, installable + `0.3.0` wording, npm alignment, hosted, production, Windows, bundled PDFium, benchmark, + `ethos-doc`, `ethos-rag`, and DocuShell integration blocked. - boundary-exception: record v0.3.0 Rust package candidate and Python wheel evidence while keeping `cargo publish`, PyPI upload, npm publish, GitHub Release artifact publication, release/package tags, installable `0.3.0` wording, npm alignment, hosted, production, Windows, bundled PDFium, diff --git a/Makefile b/Makefile index d4545ed..5874b21 100644 --- a/Makefile +++ b/Makefile @@ -92,6 +92,7 @@ v0-3-release-prep: $(PYTHON) .github/scripts/test_v0_3_0_version_activation.py $(PYTHON) .github/scripts/test_validation_record_source.py $(PYTHON) .github/scripts/test_v0_3_0_package_build_evidence.py + $(PYTHON) .github/scripts/test_v0_3_0_package_publication_approval_request.py $(PYTHON) .github/scripts/test_public_surface_posture.py $(PYTHON) .github/scripts/claims_gate.py $(PYTHON) .github/scripts/public_boundary_claims_gate.py diff --git a/docs/execution-status.md b/docs/execution-status.md index 4d50130..72c0109 100644 --- a/docs/execution-status.md +++ b/docs/execution-status.md @@ -12,6 +12,15 @@ smoke passed for `ethos-pdf==0.3.0`. Installable `0.3.0` wording remains blocked publish`, PyPI upload, npm publication, GitHub Release artifact publication, tag creation, npm alignment, and DocuShell integration remain blocked. +v0.3.0 package publication approval request is recorded in +`docs/validation/v0-3-0-package-publication-approval-request-validation-2026-07-01.md`. It requests +decider review for the exact `0.3.0` crates.io publication inputs for `ethos-doc-core`, +`ethos-verify`, and `ethos-pdf`, and the exact deterministic PyPI wheel +`ethos_pdf-0.3.0-py3-none-any.whl`. Actual crates.io publication, PyPI upload, package tag +creation, release tag creation, installable `0.3.0` wording, npm alignment, GitHub Release artifact +publication, and DocuShell integration remain blocked pending explicit approval, operator action, +and closeout records. + v0.3.0 release approval decision is recorded in `docs/validation/v0-3-0-release-approval-decision-validation-2026-07-01.md`. It accepts the exact app-answer-release contract release-prep packet and authorizes source activation on diff --git a/docs/public-release-checklist.md b/docs/public-release-checklist.md index 3d096b4..de0aed3 100644 --- a/docs/public-release-checklist.md +++ b/docs/public-release-checklist.md @@ -24,6 +24,15 @@ build/install/helper smoke for `ethos-pdf==0.3.0`. Installable `0.3.0` wording r `cargo publish`, PyPI upload, npm publication, GitHub Release artifact publication, tag creation, npm alignment, or DocuShell integration is approved by that record. +v0.3.0 package publication approval request is recorded in +`docs/validation/v0-3-0-package-publication-approval-request-validation-2026-07-01.md`. It requests +decider review for the exact `0.3.0` crates.io publication inputs for `ethos-doc-core`, +`ethos-verify`, and `ethos-pdf`, plus the exact deterministic PyPI wheel +`ethos_pdf-0.3.0-py3-none-any.whl`. It does not approve `cargo publish`, PyPI upload, public +install wording, package tags, release tags, npm alignment, GitHub Release artifact publication, +or DocuShell integration; those remain blocked until explicit approval, operator action, and +closeout records pass. + v0.3.0 release approval decision is recorded in `docs/validation/v0-3-0-release-approval-decision-validation-2026-07-01.md`. It accepts the exact app-answer-release contract prep packet and authorizes release-candidate source activation on diff --git a/docs/validation/README.md b/docs/validation/README.md index bbce56c..354b241 100644 --- a/docs/validation/README.md +++ b/docs/validation/README.md @@ -10,6 +10,14 @@ in `docs/public-release-checklist.md`. Records: +v0.3.0 package publication approval request is recorded in +`v0-3-0-package-publication-approval-request-validation-2026-07-01.md`. It requests decider review +for the exact `0.3.0` crates.io publication inputs for `ethos-doc-core`, `ethos-verify`, and +`ethos-pdf`, and the exact deterministic PyPI wheel `ethos_pdf-0.3.0-py3-none-any.whl`. +Actual crates.io publication, PyPI upload, package tag creation, release tag creation, installable +`0.3.0` wording, npm alignment, GitHub Release artifact publication, and DocuShell integration +remain blocked pending explicit approval, operator action, and closeout records. + v0.3.0 package/build evidence is recorded in `v0-3-0-package-build-evidence-validation-2026-07-01.md`. It records local Rust candidate package assembly for `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` at `0.3.0`, a passing diff --git a/docs/validation/v0-3-0-package-publication-approval-request-validation-2026-07-01.md b/docs/validation/v0-3-0-package-publication-approval-request-validation-2026-07-01.md new file mode 100644 index 0000000..82d5aaf --- /dev/null +++ b/docs/validation/v0-3-0-package-publication-approval-request-validation-2026-07-01.md @@ -0,0 +1,189 @@ +# v0.3.0 Package Publication Approval Request Validation - 2026-07-01 + +Validated source HEAD before this record: `39cb548`. + +v0.3.0 package publication approval request source commit: +`39cb548cf6cfe20fbcb47ee605ba51f1ebf71f6b`. + +v0.3.0 package publication approval request source tree: +`35076461b03ce8476cd8d73077c6f0bcaeae7dc3`. + +Status: **v0.3.0 package publication approval request recorded; crates.io and PyPI publication remain blocked** + +This record requests decider review for publishing exactly the v0.3.0 Rust library crate set to +crates.io and exactly the deterministic v0.3.0 Python wheel to PyPI. It does not approve or perform +`cargo publish`, PyPI upload, `npm publish`, GitHub Release artifact publication, release tag +creation, package tag creation, installable `0.3.0` public wording, DocuShell integration, hosted +surfaces, production positioning, Windows packaged artifacts, bundled project-maintained PDFium +builds, `ethos-doc`, `ethos-rag`, or public benchmark reports or claims. + +## Subject + +- Repository: `docushell/ethos` +- Lane: v0.3.0 package publication approval request +- Request source commit: `39cb548cf6cfe20fbcb47ee605ba51f1ebf71f6b` +- Request source tree: `35076461b03ce8476cd8d73077c6f0bcaeae7dc3` +- Package evidence record: + `docs/validation/v0-3-0-package-build-evidence-validation-2026-07-01.md` +- Package evidence source commit: `4b6d219df1757b6e4728c16c8023bee5c8cf8962` +- Rust candidate packages: + - `ethos-doc-core = 0.3.0` + - `ethos-verify = 0.3.0` + - `ethos-pdf = 0.3.0` +- Python candidate package: `ethos-pdf==0.3.0` +- Python candidate wheel: `ethos_pdf-0.3.0-py3-none-any.whl` +- npm package metadata remains `@docushell/ethos-pdf@0.2.1` + +## Exact Request Fields + +- Decision requested: approve exact v0.3.0 crates.io publication inputs and exact deterministic + v0.3.0 PyPI wheel publication inputs for later operator execution. +- Approver requested: `docushell-admin` acting as decider. +- Date requested: 2026-07-01. +- Exact Rust crate list requested: `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` only. +- Exact Rust package version map requested: `ethos-doc-core = 0.3.0`, `ethos-verify = 0.3.0`, and + `ethos-pdf = 0.3.0`. +- Exact package tag name set requested for later package-tag approval: `ethos-package-ethos-doc-core-0.3.0`, + `ethos-package-ethos-verify-0.3.0`, and `ethos-package-ethos-pdf-0.3.0`. +- Exact package tag source commit requested: `39cb548cf6cfe20fbcb47ee605ba51f1ebf71f6b`. +- Exact package tag source tree requested: `35076461b03ce8476cd8d73077c6f0bcaeae7dc3`. +- Exact Python package requested: `ethos-pdf==0.3.0`. +- Exact Python distribution requested: `ethos_pdf-0.3.0-py3-none-any.whl` only. +- Exact Python deterministic build input requested: `SOURCE_DATE_EPOCH=0`. +- Exact Python public helper surface requested: `EthosCli`, `proof_summary`, and + `app_answer_release_decision`. + +## Candidate Artifacts Requested + +Rust crate artifacts: + +```text +ethos-doc-core-0.3.0.crate +sha256: 7ba41a2ae299a53a4677153beaaec5ed486a07b5da08b2ef13974b9a0be141cb + +ethos-verify-0.3.0.crate +sha256: 00f001455ca207e65aaf464551d3ba05945cda0b06e9e1036f49ac587accbb95 + +ethos-pdf-0.3.0.crate +sha256: c2f4f2ccb6de6e54cd3257597cd28e7f6dec2a6d22befbd230d2c4cf31931cfd +``` + +Python wheel artifact: + +```text +ethos_pdf-0.3.0-py3-none-any.whl +sha256: 9eb106deafcd1d9717e5e7b67dc9413180421aba25a5257266352d09540b3265 +``` + +## Requested Rust Publication Order + +1. Publish `ethos-doc-core` first. +2. Publish `ethos-verify` after crates.io reports `ethos-doc-core = 0.3.0`. +3. Publish `ethos-pdf` after crates.io reports `ethos-doc-core = 0.3.0`. + +`ethos-verify` and `ethos-pdf` both depend on `ethos-doc-core`; no dependent crate publish should +be attempted until the base crate is visible from crates.io. + +Exact Rust operator commands requested for later approval: + +```sh +cargo publish --locked -p ethos-doc-core +cargo publish --locked -p ethos-verify +cargo publish --locked -p ethos-pdf +``` + +## Evidence Bound To This Request + +- `docs/validation/v0-3-0-package-build-evidence-validation-2026-07-01.md` records local Rust + candidate package assembly for exactly `ethos-doc-core`, `ethos-verify`, and `ethos-pdf`. +- The evidence record reports candidate version `0.3.0`. +- The evidence record reports registry-equivalent Rust consumer check status `pass`. +- The evidence record reports `package_publication_approved: false`. +- The evidence record reports `public_installation_approved: false`. +- The evidence record reports local Python wheel build, install, and helper smoke status `pass`. +- The Python helper smoke imported `EthosCli`, `proof_summary`, and + `app_answer_release_decision` from the installed candidate wheel. +- `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` source manifests carry the current + publication-prep metadata. +- The `ethos-cli`, `ethos-layout`, and `ethos-tables` source packages remain `publish = false`. +- PDFium remains caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`. + +## Manual Decision Gate + +Manual action is required before any crates.io publication or PyPI upload. A decider must accept or +reject this exact request packet. Only after a separate approval decision record is merged and its +validation passes may an operator publish the exact Rust crate set and the exact Python wheel named +above. + +This request does not select an sdist, alternate wheel, additional crate, npm package, CLI artifact, +release artifact, public wording change, DocuShell integration path, or broad package-publication +class. If any artifact filename, version, hash, source commit, source tree, package list, helper +surface, public wording, or blocker set changes, this request must be replaced by a new evidence +record and a new decider review. + +## Non-Approvals + +- This request record does not approve `cargo publish`. +- This request record does not publish any crate. +- This request record does not approve PyPI upload. +- This request record does not upload any Python distribution. +- This request record does not approve the deterministic wheel hash. +- This request record does not approve an sdist. +- This request record does not approve another wheel. +- This request record does not approve `npm publish`. +- This request record does not approve GitHub Release artifact publication. +- This request record does not create a release tag. +- This request record does not create package tags. +- This request record does not approve installable `0.3.0` public wording. +- This request record does not approve DocuShell integration. +- This request record does not approve hosted surfaces. +- This request record does not approve production positioning. +- This request record does not approve Windows packaged artifacts. +- This request record does not approve bundled project-maintained PDFium builds. +- This request record does not approve public benchmark reports. +- This request record does not approve public benchmark claims. +- This request record does not approve `ethos-doc`. +- This request record does not approve `ethos-rag`. + +## Retained Blockers + +- Actual crates.io publication remains blocked pending explicit decider approval. +- Actual PyPI upload remains blocked pending explicit decider approval. +- Rust crate public installation wording remains blocked pending operator publication, registry + availability, smoke evidence, and wording closeout. +- Python public installation wording remains blocked pending PyPI availability, smoke evidence, and + wording closeout. +- Package tag creation remains blocked pending explicit package-tag approval. +- Release tag creation remains blocked pending explicit release-tag approval. +- npm alignment remains blocked. +- `npm publish` remains blocked. +- GitHub Release artifact publication remains blocked. +- CLI artifact evidence remains blocked for v0.3.0. +- DocuShell integration remains blocked. +- Hosted surfaces remain blocked. +- Production positioning remains blocked. +- Public benchmark reports remain blocked. +- Public benchmark claims remain blocked. +- Windows packaged artifacts remain blocked. +- Bundled project-maintained PDFium builds remain blocked. +- `ethos-doc` remains blocked. +- `ethos-rag` remains blocked. + +## Commands + +```sh +python3 .github/scripts/test_v0_3_0_package_publication_approval_request.py +python3 .github/scripts/test_v0_3_0_package_build_evidence.py +make v0-3-release-prep PYTHON=python3 +python3 .github/scripts/check_release_boundary_paths.py +python3 .github/scripts/validation_record_integrity.py +git diff --check +``` + +## Result + +```text +v0.3.0 package publication approval request recorded +Exact Rust crate set, Rust crate hashes, Python wheel hash, helper surface, source binding, publish order, and retained blockers were recorded +crates.io publication and PyPI upload remain blocked pending explicit decider approval and later operator action +```