diff --git a/.github/scripts/test_milestone_e_package_publication_final_approval_decision.py b/.github/scripts/test_milestone_e_package_publication_final_approval_decision.py new file mode 100644 index 00000000..68557ccd --- /dev/null +++ b/.github/scripts/test_milestone_e_package_publication_final_approval_decision.py @@ -0,0 +1,243 @@ +#!/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. +# + +from __future__ import annotations + +import re +import subprocess +import unittest +from pathlib import Path + +from makefile_guard import target_block + + +ROOT = Path(__file__).resolve().parents[2] +RECORD = ( + ROOT + / "docs/validation/" + "milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md" +) +REQUEST_RECORD = ( + "docs/validation/" + "milestone-e-package-publication-final-approval-request-validation-2026-06-22.md" +) +REGISTRY_ASSEMBLY_RECORD = ( + "docs/validation/" + "milestone-e-package-publication-current-registry-assembly-validation-2026-06-22.md" +) +DRY_RUN_RECORD = ( + "docs/validation/" + "milestone-e-package-publication-current-dry-run-smoke-validation-2026-06-22.md" +) +MANIFEST_ACTIVATION_RECORD = ( + "docs/validation/" + "milestone-e-package-publication-manifest-activation-applied-validation-2026-06-22.md" +) +VALIDATION_README = ROOT / "docs/validation/README.md" +PREP_SCOPE = ROOT / "docs/milestone-e-prep-scope.md" +ROADMAP = ROOT / "docs/roadmap.md" +EXECUTION_STATUS = ROOT / "docs/execution-status.md" +CI_WORKFLOW = ROOT / ".github/workflows/ci.yml" + +DECISION_SOURCE_COMMIT = "4fee88f005a9573de3c2f310ff824861768249c1" +DECISION_SOURCE_SHORT = "4fee88f" +DECISION_SOURCE_TREE = "7f801f0b5aeb51c7f79ecaac1ca19847f0cd1b61" +APPROVED_PACKAGE_SOURCE_COMMIT = "b48e2f2c7ff6f3507bbf84c6d603cf4a385b9875" +APPROVED_PACKAGE_SOURCE_TREE = "4d660bd7c1de69259d0f8c59e6ac8d1c2cb6a3a3" +EXACT_CRATES = ["ethos-doc-core", "ethos-verify", "ethos-pdf"] +EXACT_TAGS = [ + "ethos-package-ethos-doc-core-0.1.0", + "ethos-package-ethos-verify-0.1.0", + "ethos-package-ethos-pdf-0.1.0", +] +EXACT_PUBLIC_WORDING = ( + "Ethos Rust crates ethos-doc-core, ethos-verify, and ethos-pdf version 0.1.0 are proposed " + "for crates.io installation only after explicit package-publication approval and package-tag " + "creation. ethos-pdf requires caller-provided PDFium through ETHOS_PDFIUM_LIBRARY_PATH. " + "Wheels, npm packages, binaries, hosted surfaces, production positioning, public benchmark " + "reports, public benchmark claims, project-maintained PDFium builds, ethos-doc, and ethos-rag " + "remain blocked." +) +REQUIRED_DECISION_FIELDS = [ + "Decision: accept exact package-publication decision packet for the bounded crates.io candidate surface.", + "Approver: docushell-admin acting as decider.", + "Date: 2026-06-22.", + "Exact candidate crate list accepted by this decision: `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` only.", + "Exact package version map accepted by this decision: `ethos-doc-core = 0.1.0`, `ethos-verify = 0.1.0`, and `ethos-pdf = 0.1.0`.", + "Exact package tag source commit accepted by this decision: `b48e2f2c7ff6f3507bbf84c6d603cf4a385b9875`.", + "Exact package tag source tree accepted by this decision: `4d660bd7c1de69259d0f8c59e6ac8d1c2cb6a3a3`.", + "Exact public installation wording accepted by this decision:", + "Publish-flag activation status: still pending a later activation change; `publish = false` remains in all three source manifests.", + "Package tag creation status: still pending a later tag operation; no package tag is created by this decision record.", +] +FORBIDDEN_SCOPE_EXPANSION = [ + "public reports are approved", + "public result wording approved", + "release-ready", + "release artifact approved", + "package-ready", + "packages are published", + "published packages", + "production-ready", + "production positioning approved", + "benchmark-validated", + "public benchmark pass", + "speed validated", + "fastest", + "launch-ready", + "hosted surface approved", + "hosted demo approved", + "demo-ready", + "performance validated", + "quality validated", + "footprint validated", + "table-quality validated", + "parser-quality validated", +] + + +def read(path: Path) -> str: + return path.read_text(encoding="utf-8") + + +def normalized(path: Path) -> str: + return re.sub(r"\s+", " ", read(path)) + + +def git(*args: str) -> str: + return subprocess.check_output( + ["git", *args], + cwd=ROOT, + encoding="utf-8", + stderr=subprocess.DEVNULL, + ).strip() + + +class MilestoneEPackagePublicationFinalApprovalDecisionTests(unittest.TestCase): + def test_decision_record_is_indexed_and_source_bound(self) -> None: + readme = normalized(VALIDATION_README) + record = normalized(RECORD) + + self.assertIn(RECORD.name, readme) + self.assertIn("package publication final approval decision validation", readme) + self.assertIn( + f"Validated source HEAD before this record: `{DECISION_SOURCE_SHORT}`", + read(RECORD), + ) + self.assertIn(f"Approval decision record source commit: `{DECISION_SOURCE_COMMIT}`", record) + self.assertIn(f"Approval decision record source tree: `{DECISION_SOURCE_TREE}`", record) + self.assertEqual(DECISION_SOURCE_COMMIT, git("rev-parse", DECISION_SOURCE_SHORT)) + self.assertEqual(DECISION_SOURCE_TREE, git("rev-parse", f"{DECISION_SOURCE_SHORT}^{{tree}}")) + + def test_decision_accepts_exact_packet_fields(self) -> None: + record = normalized(RECORD) + + self.assertIn( + "Status: **pass for final package-publication approval decision with activation pending**", + record, + ) + for field in REQUIRED_DECISION_FIELDS: + self.assertIn(field, record) + for crate in EXACT_CRATES: + self.assertIn(crate, record) + self.assertIn(f"{crate} = 0.1.0", record) + for tag in EXACT_TAGS: + self.assertIn(tag, record) + self.assertIn(EXACT_PUBLIC_WORDING, record) + self.assertIn("`ethos-doc` remains excluded", record) + self.assertIn("`ethos-rag` remains excluded", record) + self.assertIn(REQUEST_RECORD, record) + self.assertIn(REGISTRY_ASSEMBLY_RECORD, record) + self.assertIn(DRY_RUN_RECORD, record) + self.assertIn(MANIFEST_ACTIVATION_RECORD, record) + + def test_package_source_binding_is_real_and_unchanged(self) -> None: + record = normalized(RECORD) + + self.assertIn( + f"Approved package tag source commit: `{APPROVED_PACKAGE_SOURCE_COMMIT}`", + record, + ) + self.assertIn( + f"Approved package tag source tree: `{APPROVED_PACKAGE_SOURCE_TREE}`", + record, + ) + self.assertEqual(APPROVED_PACKAGE_SOURCE_COMMIT, git("rev-parse", "b48e2f2")) + self.assertEqual(APPROVED_PACKAGE_SOURCE_TREE, git("rev-parse", "b48e2f2^{tree}")) + + def test_decision_does_not_activate_publish_flags_tags_or_registry(self) -> None: + 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.assertIn("publish = false", text, str(manifest)) + self.assertIn('publication_status = "blocked"', text, str(manifest)) + + self.assertIn('name = "ethos-doc-core"', read(ROOT / "crates/ethos-core/Cargo.toml")) + self.assertIn( + 'ethos-core = { package = "ethos-doc-core"', + read(ROOT / "Cargo.toml"), + ) + for tag in EXACT_TAGS: + self.assertEqual("", git("tag", "--list", tag)) + self.assertFalse((ROOT / ".cargo/config.toml").exists()) + self.assertFalse((ROOT / "target/package-registry").exists()) + + def test_docs_reference_decision_and_retained_activation_blockers(self) -> None: + for path in (PREP_SCOPE, ROADMAP, EXECUTION_STATUS, VALIDATION_README): + doc = normalized(path) + + self.assertIn(RECORD.name, doc, str(path)) + self.assertIn("final approval decision", doc.lower(), str(path)) + self.assertIn("publish-flag activation remains blocked", doc.lower(), str(path)) + self.assertIn("package tag creation remains blocked", doc.lower(), str(path)) + self.assertIn("real-version cargo publish remains blocked", doc.lower(), str(path)) + + def test_make_and_ci_run_decision_after_request_before_readiness(self) -> None: + make_block = target_block("milestone-e-prep") + ci = read(CI_WORKFLOW) + request_guard = "test_milestone_e_package_publication_final_approval_request.py" + decision_guard = "test_milestone_e_package_publication_final_approval_decision.py" + readiness_guard = "test_milestone_e_public_facing_readiness_ledger.py" + + for text, prefix in ((make_block, "$(PYTHON) .github/scripts/"), (ci, "python3 .github/scripts/")): + self.assertIn(prefix + decision_guard, text) + self.assertEqual(1, text.count(prefix + decision_guard)) + self.assertLess(text.index(prefix + request_guard), text.index(prefix + decision_guard)) + self.assertLess(text.index(prefix + decision_guard), text.index(prefix + readiness_guard)) + + def test_record_avoids_scope_expansion_language_or_private_paths(self) -> None: + lower = normalized(RECORD).lower() + raw = read(RECORD) + + for phrase in FORBIDDEN_SCOPE_EXPANSION: + self.assertNotIn(phrase, lower) + self.assertNotIn("/Users/", raw) + self.assertNotIn("/private/tmp", raw) + self.assertNotIn("/private/var", raw) + self.assertNotIn("/var/folders", raw) + self.assertNotIn("saumildiwaker", raw) + self.assertNotIn("Desktop/Stuff", raw) + self.assertNotIn("project/repo/ethos", raw) + self.assertNotIn("docs/.roadmap.md.swp", raw) + self.assertNotIn("web/", raw) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/scripts/test_milestone_e_prep_guard_sequence_index.py b/.github/scripts/test_milestone_e_prep_guard_sequence_index.py index 93aa7802..c8fccaaa 100644 --- a/.github/scripts/test_milestone_e_prep_guard_sequence_index.py +++ b/.github/scripts/test_milestone_e_prep_guard_sequence_index.py @@ -119,6 +119,7 @@ "$(PYTHON) .github/scripts/test_milestone_e_package_publication_manifest_activation_applied.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_current_registry_assembly.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_final_approval_request.py", + "$(PYTHON) .github/scripts/test_milestone_e_package_publication_final_approval_decision.py", "$(PYTHON) .github/scripts/test_milestone_e_public_facing_readiness_ledger.py", "$(PYTHON) .github/scripts/test_milestone_e_public_beta_current_main_refresh_prep.py", "$(PYTHON) .github/scripts/test_milestone_e_public_beta_current_main_source_only_approval.py", diff --git a/.github/scripts/test_milestone_e_prep_scope.py b/.github/scripts/test_milestone_e_prep_scope.py index e173ab37..94131f68 100644 --- a/.github/scripts/test_milestone_e_prep_scope.py +++ b/.github/scripts/test_milestone_e_prep_scope.py @@ -418,6 +418,7 @@ def test_make_target_is_narrow_and_guarded(self) -> None: "$(PYTHON) .github/scripts/test_milestone_e_package_publication_manifest_activation_applied.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_current_registry_assembly.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_final_approval_request.py", + "$(PYTHON) .github/scripts/test_milestone_e_package_publication_final_approval_decision.py", "$(PYTHON) .github/scripts/test_milestone_e_public_facing_readiness_ledger.py", "$(PYTHON) .github/scripts/test_milestone_e_public_beta_current_main_refresh_prep.py", "$(PYTHON) .github/scripts/test_milestone_e_public_beta_current_main_source_only_approval.py", diff --git a/.github/scripts/test_milestone_e_validation_record_index.py b/.github/scripts/test_milestone_e_validation_record_index.py index 9ec2bb4d..e04fa90b 100644 --- a/.github/scripts/test_milestone_e_validation_record_index.py +++ b/.github/scripts/test_milestone_e_validation_record_index.py @@ -314,6 +314,10 @@ class RecordCoverage: "milestone-e-package-publication-final-approval-request-validation-2026-06-22.md", "test_milestone_e_package_publication_final_approval_request.py", ), + RecordCoverage( + "milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md", + "test_milestone_e_package_publication_final_approval_decision.py", + ), RecordCoverage( "milestone-e-public-facing-readiness-ledger-validation-2026-06-21.md", "test_milestone_e_public_facing_readiness_ledger.py", @@ -464,6 +468,9 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: package_final_approval_request_guard = ( "test_milestone_e_package_publication_final_approval_request.py" ) + package_final_approval_decision_guard = ( + "test_milestone_e_package_publication_final_approval_decision.py" + ) readiness_guard = "test_milestone_e_public_facing_readiness_ledger.py" beta_refresh_guard = "test_milestone_e_public_beta_current_main_refresh_prep.py" command_guard = "test_milestone_e_validation_command_index_validation_record.py" @@ -576,6 +583,10 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: ) self.assertLess( text.index(prefix + package_final_approval_request_guard), + text.index(prefix + package_final_approval_decision_guard), + ) + self.assertLess( + text.index(prefix + package_final_approval_decision_guard), text.index(prefix + readiness_guard), ) self.assertLess(text.index(prefix + readiness_guard), text.index(prefix + beta_refresh_guard)) @@ -645,6 +656,14 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: text.index(prefix + package_final_approval_request_guard), text.index(prefix + index_guard), ) + self.assertLess( + text.index(prefix + package_final_approval_decision_guard), + text.index(prefix + command_guard), + ) + self.assertLess( + text.index(prefix + package_final_approval_decision_guard), + text.index(prefix + index_guard), + ) self.assertLess( text.index(prefix + package_registry_evidence_review_guard), text.index(prefix + command_guard), diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b88f3cd7..d92c4bda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -252,6 +252,8 @@ jobs: run: python3 .github/scripts/test_milestone_e_package_publication_current_registry_assembly.py - name: Milestone E package publication final approval request tests run: python3 .github/scripts/test_milestone_e_package_publication_final_approval_request.py + - name: Milestone E package publication final approval decision tests + run: python3 .github/scripts/test_milestone_e_package_publication_final_approval_decision.py - name: Milestone E public-facing readiness ledger tests run: python3 .github/scripts/test_milestone_e_public_facing_readiness_ledger.py - name: Milestone E public beta current-main refresh prep tests diff --git a/Makefile b/Makefile index 18b56003..ccfae9de 100644 --- a/Makefile +++ b/Makefile @@ -233,6 +233,7 @@ milestone-e-prep: $(PYTHON) .github/scripts/test_milestone_e_package_publication_manifest_activation_applied.py $(PYTHON) .github/scripts/test_milestone_e_package_publication_current_registry_assembly.py $(PYTHON) .github/scripts/test_milestone_e_package_publication_final_approval_request.py + $(PYTHON) .github/scripts/test_milestone_e_package_publication_final_approval_decision.py $(PYTHON) .github/scripts/test_milestone_e_public_facing_readiness_ledger.py $(PYTHON) .github/scripts/test_milestone_e_public_beta_current_main_refresh_prep.py $(PYTHON) .github/scripts/test_milestone_e_public_beta_current_main_source_only_approval.py diff --git a/docs/execution-status.md b/docs/execution-status.md index a8f24540..049d03a4 100644 --- a/docs/execution-status.md +++ b/docs/execution-status.md @@ -221,6 +221,8 @@ The package publication current registry-equivalent assembly record in `docs/val The package publication final approval request in `docs/validation/milestone-e-package-publication-final-approval-request-validation-2026-06-22.md` records exact candidate crates, version map, package tag names, source binding, proposed public installation wording, and explicit exclusions for decider review. Package publication remains blocked, and public installation remains blocked. +The package publication final approval decision in `docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md` records decider acceptance of the exact bounded candidate crates, version map, package tag names, source binding, wording, and explicit exclusions. Publish-flag activation remains blocked, package tag creation remains blocked, real-version cargo publish remains blocked, and public installation instructions remain unchanged until later gated activation. + | Work item | Current status | Remaining blocker | | --- | --- | --- | | PDFium Phase 1 profile | Landed: pinned profile, V8/XFA-disabled state, platform hashes, runtime library hashes, and provenance are recorded | Phase 2 project-maintained builds still block Public Beta | diff --git a/docs/milestone-e-prep-scope.md b/docs/milestone-e-prep-scope.md index 6667e60b..11054bb2 100644 --- a/docs/milestone-e-prep-scope.md +++ b/docs/milestone-e-prep-scope.md @@ -173,6 +173,12 @@ The package publication final approval request is recorded in It records exact candidate crates, version map, package tag names, source binding, proposed public installation wording, and explicit exclusions for decider review; public installation and package publication remain blocked. +The package publication final approval decision is recorded in +`docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md`. +It accepts the exact bounded candidate crates, version map, package tag names, source binding, +wording, and exclusions; publish-flag activation remains blocked, package tag creation remains +blocked, real-version cargo publish remains blocked, and public installation instructions remain +unchanged until later gated activation. The metadata-readiness follow-up record under `docs/validation/` covers README, NOTICE, manifest metadata, and include-list readiness for `ethos-core`, `ethos-verify`, and `ethos-pdf` only. `ethos-doc` and `ethos-rag` remain reserved placeholders without in-tree package manifests, and @@ -370,6 +376,10 @@ or broad demo-generation workflows. - The package publication final approval request records exact candidate crates, version map, package tag names, source binding, proposed public installation wording, and explicit exclusions for decider review; public installation and package publication remain blocked. +- The package publication final approval decision records exact decider acceptance of the bounded + candidate crates, version map, package tag names, source binding, wording, and exclusions; + publish-flag activation remains blocked, package tag creation remains blocked, and real-version + cargo publish remains blocked until later gated activation. - The public-facing readiness ledger records the current-main source-only public beta source binding and package-publication gap retention; it does not approve package publication, approve public installation, or soften any current diff --git a/docs/roadmap.md b/docs/roadmap.md index 3a476ab1..01f727b7 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -143,6 +143,12 @@ The final approval request is recorded in and records exact candidate crates, version map, package tag names, source binding, proposed public installation wording, and explicit exclusions for decider review; public installation and package publication remain blocked. +The final approval decision is recorded in +[`docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md`](validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md) +and accepts the exact bounded candidate crates, version map, package tag names, source binding, +wording, and explicit exclusions; publish-flag activation remains blocked, package tag creation +remains blocked, real-version cargo publish remains blocked, and public installation instructions +remain unchanged until later gated activation. The registry-assembly prep follow-up records future non-public dependent candidate assembly rehearsal while no registry is created and current Cargo manifests remain unchanged; registry-backed dependent package assembly activation, package dependency manifest activation, diff --git a/docs/validation/README.md b/docs/validation/README.md index 5b47fd4c..25677430 100644 --- a/docs/validation/README.md +++ b/docs/validation/README.md @@ -398,6 +398,11 @@ recording the exact current-main source candidate and required follow-up evidenc publication final approval request validation; the record keeps package publication and public installation blocked while recording exact candidate crates, version map, package tag names, source binding, proposed public installation wording, and explicit exclusions for decider review. +- `milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md` - package + publication final approval decision validation; the record accepts the exact bounded candidate + crates, version map, tag names, source binding, wording, and exclusions while recording that + publish-flag activation remains blocked, package tag creation remains blocked, real-version + cargo publish remains blocked, and public installation instructions remain a later gated action. - `milestone-e-public-facing-readiness-ledger-validation-2026-06-21.md` - public-facing readiness ledger validation recorded `docs/milestone-e-public-facing-readiness-ledger.json` as a current-main refresh candidate and package-publication gap-retention artifact; current main diff --git a/docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md b/docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md new file mode 100644 index 00000000..ed599f49 --- /dev/null +++ b/docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md @@ -0,0 +1,139 @@ +# Milestone E Package Publication Final Approval Decision Validation - 2026-06-22 + +## Purpose + +Record the decider acceptance of the exact package-publication decision packet after the final +approval request, current dry-run smoke evidence, current registry-equivalent assembly evidence, +and source manifest activation review are present. + +This record accepts the exact bounded crates.io candidate surface, version map, tag names, source +binding, public installation wording, and exclusions supplied by `docushell-admin`. It does not +create package tags, remove `publish = false`, activate package metadata, run `cargo publish`, or +publish any package. + +## Status + +Status: **pass for final package-publication approval decision with activation pending**. + +Decision: accept exact package-publication decision packet for the bounded crates.io candidate +surface. + +Ethos remains source-only pre-alpha outside the approved GitHub source-repository public beta +surface. Public reports remain blocked. Public result wording remains blocked. + +## Subject + +- Repository: `docushell/ethos` +- Validated source HEAD before this record: `4fee88f` +- Approval decision record source commit: `4fee88f005a9573de3c2f310ff824861768249c1` +- Approval decision record source tree: `7f801f0b5aeb51c7f79ecaac1ca19847f0cd1b61` +- Lane: package publication +- Final approval request record: + `docs/validation/milestone-e-package-publication-final-approval-request-validation-2026-06-22.md` +- Current dry-run smoke record: + `docs/validation/milestone-e-package-publication-current-dry-run-smoke-validation-2026-06-22.md` +- Current registry-equivalent assembly record: + `docs/validation/milestone-e-package-publication-current-registry-assembly-validation-2026-06-22.md` +- Manifest activation applied record: + `docs/validation/milestone-e-package-publication-manifest-activation-applied-validation-2026-06-22.md` +- Approval owner: `docushell-admin` + +## Exact Decision Fields + +- Decision: accept exact package-publication decision packet for the bounded crates.io candidate + surface. +- Approver: docushell-admin acting as decider. +- Date: 2026-06-22. +- Exact candidate crate list accepted by this decision: `ethos-doc-core`, `ethos-verify`, and + `ethos-pdf` only. +- Exact package version map accepted by this decision: `ethos-doc-core = 0.1.0`, + `ethos-verify = 0.1.0`, and `ethos-pdf = 0.1.0`. +- Exact package tag name set accepted by this decision: `ethos-package-ethos-doc-core-0.1.0`, + `ethos-package-ethos-verify-0.1.0`, and `ethos-package-ethos-pdf-0.1.0`. +- Exact package tag source commit accepted by this decision: + `b48e2f2c7ff6f3507bbf84c6d603cf4a385b9875`. +- Exact package tag source tree accepted by this decision: + `4d660bd7c1de69259d0f8c59e6ac8d1c2cb6a3a3`. +- Exact public installation wording accepted by this decision: Ethos Rust crates ethos-doc-core, + ethos-verify, and ethos-pdf version 0.1.0 are proposed for crates.io installation only after + explicit package-publication approval and package-tag creation. ethos-pdf requires + caller-provided PDFium through ETHOS_PDFIUM_LIBRARY_PATH. Wheels, npm packages, binaries, hosted + surfaces, production positioning, public benchmark reports, public benchmark claims, + project-maintained PDFium builds, ethos-doc, and ethos-rag remain blocked. +- Exact manifest activation reviewed by this decision: source package name `ethos-doc-core`, + Rust library name `ethos_core`, and workspace dependency key `ethos-core` resolving package + `ethos-doc-core`. +- Publish-flag activation status: still pending a later activation change; `publish = false` + remains in all three source manifests. +- Package tag creation status: still pending a later tag operation; no package tag is created by + this decision record. +- Real-version cargo publish status: still blocked pending later activation and operator evidence. +- Public-surface posture check result after this decision: passed against unchanged public surfaces + and this accepted wording record. +- Claims gate result after this decision: passed against unchanged public surfaces and this + accepted wording record. +- Milestone E prep result after this decision record: required for this record branch. + +## Approved Package Source Binding + +- Approved package tag source commit: `b48e2f2c7ff6f3507bbf84c6d603cf4a385b9875`. +- Approved package tag source tree: `4d660bd7c1de69259d0f8c59e6ac8d1c2cb6a3a3`. +- The approval record itself is documentation-only and is intentionally not the package tag source + commit. + +## Explicit Exclusions + +- wheels remain blocked +- npm packages remain blocked +- binaries remain blocked +- hosted surfaces remain blocked +- production positioning remains blocked +- public benchmark reports remain blocked +- public benchmark claims remain blocked +- project-maintained PDFium builds remain blocked +- `ethos-doc` remains excluded +- `ethos-rag` remains excluded +- broader public wording remains blocked +- Public reports remain blocked +- Public result wording remains blocked + +## Activation Blockers Retained After This Decision + +- publish-flag activation remains blocked until a later source change removes `publish = false` + from the three accepted candidate manifests only +- package metadata activation remains blocked until a later source change updates the accepted + candidate metadata only +- package tag creation remains blocked until a later tag operation binds the accepted names to the + accepted source commit +- real-version cargo publish remains blocked until the later activation state and operator evidence + are present +- public README or installation instructions remain unchanged until the accepted package surface is + actually available through the registry + +## Commands + +```sh +python3 .github/scripts/test_milestone_e_package_publication_final_approval_decision.py +python3 .github/scripts/test_milestone_e_package_publication_final_approval_request.py +python3 .github/scripts/test_milestone_e_package_publication_current_registry_assembly.py +python3 .github/scripts/test_milestone_e_package_publication_dry_run_smoke.py +python3 .github/scripts/test_public_surface_posture.py +python3 .github/scripts/claims_gate.py +cargo build --locked -p ethos-cli +make milestone-e-prep PYTHON=/bin/python +git diff --check +``` + +## Result + +```text +Final approval decision validation passed +Exact candidate crate list, version map, tag names, source binding, wording, and exclusions were accepted +No package tag was created +No publish flag was changed +No package metadata was activated +No package was published +Public-surface posture and claims gates passed +Milestone E prep target passed +git diff --check passed +```