diff --git a/.github/scripts/package_publication_candidate_activation.py b/.github/scripts/package_publication_candidate_activation.py index 89b3b8a..8fec255 100644 --- a/.github/scripts/package_publication_candidate_activation.py +++ b/.github/scripts/package_publication_candidate_activation.py @@ -211,7 +211,6 @@ def generated_manifest(package: str) -> str: "NOTICE.md", "src/**", ] -publish = false description = "Parser-agnostic citation evidence verification over GroundingSource (alpha lands Milestone B)" readme = "README.md" keywords = [ @@ -223,7 +222,7 @@ def generated_manifest(package: str) -> str: repository = "https://github.com/docushell/ethos" [package.metadata.ethos_publication] -publication_status = "blocked" +publication_status = "approved_for_crates_io_publication" reserved_crates_io_name = "ethos-verify" reserved_crates_io_version = "0.0.0-reserved.0" @@ -259,7 +258,6 @@ def generated_manifest(package: str) -> str: "assets/**", "src/**", ] -publish = false description = "PDFium backend behind EthosPdfBackend - quantize-at-extraction lives here (WS-ENGINE, Milestone A)" readme = "README.md" keywords = [ @@ -271,7 +269,7 @@ def generated_manifest(package: str) -> str: repository = "https://github.com/docushell/ethos" [package.metadata.ethos_publication] -publication_status = "blocked" +publication_status = "approved_for_crates_io_publication" reserved_crates_io_name = "ethos-pdf" reserved_crates_io_version = "0.0.0-reserved.0" @@ -558,19 +556,25 @@ def source_manifests_have_activation_shape() -> bool: ) -def source_manifests_are_still_blocked() -> bool: +def source_manifests_are_activated_for_candidates() -> bool: core = (ROOT / "crates/ethos-core/Cargo.toml").read_text(encoding="utf-8") verify = (ROOT / "crates/ethos-verify/Cargo.toml").read_text(encoding="utf-8") pdf = (ROOT / "crates/ethos-pdf/Cargo.toml").read_text(encoding="utf-8") + cli = (ROOT / "crates/ethos-cli/Cargo.toml").read_text(encoding="utf-8") + layout = (ROOT / "crates/ethos-layout/Cargo.toml").read_text(encoding="utf-8") + tables = (ROOT / "crates/ethos-tables/Cargo.toml").read_text(encoding="utf-8") return all( [ source_manifests_have_activation_shape(), - "publish = false" in core, - "publish = false" in verify, - "publish = false" in pdf, - 'publication_status = "blocked"' in core, - 'publication_status = "blocked"' in verify, - 'publication_status = "blocked"' in pdf, + "publish = false" not in core, + "publish = false" not in verify, + "publish = false" not in pdf, + 'publication_status = "approved_for_crates_io_publication"' in core, + 'publication_status = "approved_for_crates_io_publication"' in verify, + 'publication_status = "approved_for_crates_io_publication"' in pdf, + "publish = false" in cli, + "publish = false" in layout, + "publish = false" in tables, not (ROOT / ".cargo/config.toml").exists(), not (ROOT / "target/package-registry").exists(), ] @@ -615,7 +619,8 @@ def run_candidate_activation(workspace: Path) -> dict[str, object]: ], "registry_equivalent_consumer_check": "pass", "source_manifest_activation_applied": source_manifests_have_activation_shape(), - "source_manifests_remain_blocked": source_manifests_are_still_blocked(), + "source_candidate_manifests_activated": source_manifests_are_activated_for_candidates(), + "source_manifests_remain_blocked": False, "package_publication_approved": False, "public_installation_approved": False, "commands": commands, diff --git a/.github/scripts/test_milestone_e_package_publication_activation_applied.py b/.github/scripts/test_milestone_e_package_publication_activation_applied.py new file mode 100644 index 0000000..ea268b3 --- /dev/null +++ b/.github/scripts/test_milestone_e_package_publication_activation_applied.py @@ -0,0 +1,199 @@ +#!/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-activation-applied-validation-2026-06-22.md" +) +REQUEST_RECORD = ( + "docs/validation/" + "milestone-e-package-publication-publish-flag-activation-request-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" + +SOURCE_COMMIT = "f50f2948b0536b3c75fe369558c94ce1155b73d1" +SOURCE_SHORT = "f50f294" +SOURCE_TREE = "00c3e4df7a7b3b368659650601a2df76b63a2ce8" +PACKAGE_TAGS = ( + "ethos-package-ethos-doc-core-0.1.0", + "ethos-package-ethos-verify-0.1.0", + "ethos-package-ethos-pdf-0.1.0", +) +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 MilestoneEPackagePublicationActivationAppliedTests(unittest.TestCase): + def test_record_is_indexed_and_source_bound(self) -> None: + readme = normalized(VALIDATION_README) + record = normalized(RECORD) + + self.assertIn(RECORD.name, readme) + self.assertIn("package publication activation applied validation", readme) + self.assertIn(f"Validated source HEAD before this record: `{SOURCE_SHORT}`", read(RECORD)) + self.assertIn(f"Activation applied source commit: `{SOURCE_COMMIT}`", record) + self.assertIn(f"Activation applied source tree: `{SOURCE_TREE}`", record) + self.assertEqual(SOURCE_COMMIT, git("rev-parse", SOURCE_SHORT)) + self.assertEqual(SOURCE_TREE, git("rev-parse", f"{SOURCE_SHORT}^{{tree}}")) + + def test_candidate_manifests_are_activated_and_non_candidates_stay_blocked(self) -> None: + expected_names = { + ROOT / "crates/ethos-core/Cargo.toml": 'name = "ethos-doc-core"', + ROOT / "crates/ethos-verify/Cargo.toml": 'name = "ethos-verify"', + ROOT / "crates/ethos-pdf/Cargo.toml": 'name = "ethos-pdf"', + } + for manifest, package_name in expected_names.items(): + text = read(manifest) + self.assertIn(package_name, text, str(manifest)) + self.assertNotIn("publish = false", text, str(manifest)) + self.assertIn( + 'publication_status = "approved_for_crates_io_publication"', + text, + str(manifest), + ) + self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', text, str(manifest)) + + workspace = read(ROOT / "Cargo.toml") + lockfile = read(ROOT / "Cargo.lock") + verify = read(ROOT / "crates/ethos-verify/Cargo.toml") + pdf = read(ROOT / "crates/ethos-pdf/Cargo.toml") + self.assertIn( + 'ethos-core = { package = "ethos-doc-core", path = "crates/ethos-core", ' + 'version = "0.1.0", default-features = false }', + workspace, + ) + self.assertIn('name = "ethos-doc-core"', lockfile) + self.assertNotIn('name = "ethos-core"', lockfile) + self.assertIn('ethos-core = { workspace = true, features = ["grounding", "verify-types"] }', verify) + self.assertIn('ethos-core = { workspace = true, features = ["full"] }', pdf) + + 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_tags_registry_and_public_installation_remain_blocked(self) -> None: + record = normalized(RECORD) + + self.assertIn(REQUEST_RECORD, record) + self.assertIn("Package tag source binding must be refreshed", record) + self.assertIn("No package tags are created by this record", record) + self.assertIn("cargo publish` remains blocked", record) + self.assertIn("Public installation instructions remain blocked", record) + for tag in PACKAGE_TAGS: + self.assertEqual("", git("tag", "--list", tag), tag) + self.assertFalse((ROOT / ".cargo/config.toml").exists()) + self.assertFalse((ROOT / "target/package-registry").exists()) + + def test_docs_reference_applied_activation_and_retained_blockers(self) -> None: + for path in (PREP_SCOPE, ROADMAP, EXECUTION_STATUS, VALIDATION_README): + doc = normalized(path).lower() + + self.assertIn(RECORD.name, doc, str(path)) + self.assertIn("activation applied", doc, str(path)) + self.assertIn("package tag source binding must be refreshed", doc, str(path)) + self.assertIn("public installation remains blocked", doc, str(path)) + + def test_make_and_ci_run_applied_activation_after_request_before_readiness(self) -> None: + make_block = target_block("milestone-e-prep") + ci = read(CI_WORKFLOW) + request_guard = "test_milestone_e_package_publication_activation_request.py" + applied_guard = "test_milestone_e_package_publication_activation_applied.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 + applied_guard, text) + self.assertEqual(1, text.count(prefix + applied_guard)) + self.assertLess(text.index(prefix + request_guard), text.index(prefix + applied_guard)) + self.assertLess(text.index(prefix + applied_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_package_publication_activation_request.py b/.github/scripts/test_milestone_e_package_publication_activation_request.py new file mode 100644 index 0000000..74a8388 --- /dev/null +++ b/.github/scripts/test_milestone_e_package_publication_activation_request.py @@ -0,0 +1,199 @@ +#!/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-publish-flag-activation-request-validation-2026-06-22.md" +) +FINAL_DECISION_RECORD = ( + "docs/validation/" + "milestone-e-package-publication-final-approval-decision-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" + +SOURCE_COMMIT = "cea20182e11271bf83675c12de43498df9c42c18" +SOURCE_SHORT = "cea2018" +SOURCE_TREE = "8c7076b0997fe925827bb81f859b74790a4d8b16" +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", +] +REQUIRED_REQUEST_FIELDS = [ + "Decision requested: approve exact publish-flag and package metadata activation diff.", + "Approver requested: docushell-admin acting as decider.", + "Date requested: 2026-06-22.", + "Exact activation crate list requested: `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` only.", + "Exact activation diff requested: remove `publish = false` from the three accepted candidate manifests only.", + "Exact metadata diff requested: change `publication_status = \"blocked\"` to `publication_status = \"approved_for_crates_io_publication\"` in the three accepted candidate manifests only.", + "Package tag source binding impact: the previous accepted source binding keeps `publish = false`; package tag source binding must be refreshed after the activation diff is applied and reviewed.", +] +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 MilestoneEPackagePublicationPublishFlagActivationRequestTests(unittest.TestCase): + def test_request_record_is_indexed_and_source_bound(self) -> None: + readme = normalized(VALIDATION_README) + record = normalized(RECORD) + + self.assertIn(RECORD.name, readme) + self.assertIn("package publication publish-flag activation request validation", readme) + self.assertIn(f"Validated source HEAD before this record: `{SOURCE_SHORT}`", read(RECORD)) + self.assertIn(f"Activation request source commit: `{SOURCE_COMMIT}`", record) + self.assertIn(f"Activation request source tree: `{SOURCE_TREE}`", record) + self.assertEqual(SOURCE_COMMIT, git("rev-parse", SOURCE_SHORT)) + self.assertEqual(SOURCE_TREE, git("rev-parse", f"{SOURCE_SHORT}^{{tree}}")) + + def test_request_names_exact_activation_diff_and_binding_impact(self) -> None: + record = normalized(RECORD) + + self.assertIn( + "Status: **pass for publish-flag activation request with activation blocked**", + record, + ) + for field in REQUIRED_REQUEST_FIELDS: + self.assertIn(field, record) + for crate in EXACT_CRATES: + self.assertIn(crate, record) + for tag in EXACT_TAGS: + self.assertIn(tag, record) + self.assertIn(FINAL_DECISION_RECORD, record) + self.assertIn("`ethos-doc` remains excluded", record) + self.assertIn("`ethos-rag` remains excluded", record) + + def test_request_does_not_mutate_current_source_or_tags(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.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)) + 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_request_and_retained_blockers(self) -> None: + for path in (PREP_SCOPE, ROADMAP, EXECUTION_STATUS, VALIDATION_README): + doc = normalized(path).lower() + + self.assertIn(RECORD.name, doc, str(path)) + self.assertIn("publish-flag activation request", doc, str(path)) + self.assertIn("activation remains blocked", doc, str(path)) + self.assertIn("package tag source binding must be refreshed", doc, str(path)) + self.assertIn("real-version cargo publish remains blocked", doc, str(path)) + + def test_make_and_ci_run_request_after_final_decision_before_readiness(self) -> None: + make_block = target_block("milestone-e-prep") + ci = read(CI_WORKFLOW) + decision_guard = "test_milestone_e_package_publication_final_approval_decision.py" + activation_request_guard = ( + "test_milestone_e_package_publication_activation_request.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 + activation_request_guard, text) + self.assertEqual(1, text.count(prefix + activation_request_guard)) + self.assertLess(text.index(prefix + decision_guard), text.index(prefix + activation_request_guard)) + self.assertLess(text.index(prefix + activation_request_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_package_publication_approval_decision_record.py b/.github/scripts/test_milestone_e_package_publication_approval_decision_record.py index 3740404..277b316 100644 --- a/.github/scripts/test_milestone_e_package_publication_approval_decision_record.py +++ b/.github/scripts/test_milestone_e_package_publication_approval_decision_record.py @@ -156,9 +156,9 @@ def test_current_manifests_tags_and_registry_state_stay_unactivated(self) -> Non tag = value.split(": ", maxsplit=1)[1].split(";", maxsplit=1)[0] self.assertEqual("", git("tag", "--list", tag)) self.assertIn('name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) self.assertFalse((ROOT / ".cargo/config.toml").exists()) diff --git a/.github/scripts/test_milestone_e_package_publication_approval_decision_refresh.py b/.github/scripts/test_milestone_e_package_publication_approval_decision_refresh.py index 51f3ebc..8ba5c6d 100644 --- a/.github/scripts/test_milestone_e_package_publication_approval_decision_refresh.py +++ b/.github/scripts/test_milestone_e_package_publication_approval_decision_refresh.py @@ -169,9 +169,9 @@ def test_current_manifests_tags_and_registry_state_stay_unactivated(self) -> Non tag = value.split(": ", maxsplit=1)[1].split(";", maxsplit=1)[0] self.assertEqual("", git("tag", "--list", tag)) self.assertIn('name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) self.assertFalse((ROOT / ".cargo/config.toml").exists()) diff --git a/.github/scripts/test_milestone_e_package_publication_approval_decision_template.py b/.github/scripts/test_milestone_e_package_publication_approval_decision_template.py index 587cfe2..2b57fe9 100644 --- a/.github/scripts/test_milestone_e_package_publication_approval_decision_template.py +++ b/.github/scripts/test_milestone_e_package_publication_approval_decision_template.py @@ -151,9 +151,9 @@ def test_current_manifests_tags_and_registry_state_stay_unactivated(self) -> Non tag = value.split(": ", maxsplit=1)[1].split(";", maxsplit=1)[0] self.assertEqual("", git("tag", "--list", tag)) self.assertIn('name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) self.assertFalse((ROOT / ".cargo/config.toml").exists()) diff --git a/.github/scripts/test_milestone_e_package_publication_approval_prep.py b/.github/scripts/test_milestone_e_package_publication_approval_prep.py index 6e831f0..f0e5372 100644 --- a/.github/scripts/test_milestone_e_package_publication_approval_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_approval_prep.py @@ -488,11 +488,11 @@ def test_candidate_crates_remain_publish_false_until_later_approval(self) -> Non pdf = read(ROOT / "crates/ethos-pdf/Cargo.toml") self.assertIn('name = "ethos-doc-core"', core) - self.assertIn("publish = false", core) + self.assertNotIn("publish = false", core) self.assertIn('name = "ethos-verify"', verify) - self.assertIn("publish = false", verify) + self.assertNotIn("publish = false", verify) self.assertIn('name = "ethos-pdf"', pdf) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", pdf) self.assertIn('version = "0.1.0"', read(ROOT / "Cargo.toml")) def test_evidence_status_matches_decider_input(self) -> None: @@ -582,13 +582,13 @@ def test_candidate_crate_surface_review_keeps_publication_blocked(self) -> None: self.assertNotIn('"crates/ethos-rag"', cargo) self.assertIn('name = "ethos-doc-core"', core_manifest) self.assertIn('reserved_crates_io_name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) + self.assertNotIn("publish = false", core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) self.assertIn('reserved_crates_io_name = "ethos-verify"', verify_manifest) - self.assertIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) self.assertIn('reserved_crates_io_name = "ethos-pdf"', pdf_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertIn( "candidate surface review does not approve package publication", review["retained_blockers"], @@ -661,9 +661,9 @@ def test_combined_package_publication_decision_prep_bundle_blocks_all_actions(se self.assertIn("no package tag is created", bundle["retained_blockers"]) self.assertIn("public installation remains blocked", bundle["retained_blockers"]) self.assertIn("package publication remains blocked", bundle["retained_blockers"]) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertIn('name = "ethos-doc-core"', core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) @@ -704,9 +704,9 @@ def test_package_publication_approval_request_packet_keeps_all_actions_blocked(s self.assertIn('"crates/ethos-core"', cargo) self.assertIn('"crates/ethos-verify"', cargo) self.assertIn('"crates/ethos-pdf"', cargo) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertIn('name = "ethos-doc-core"', core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) @@ -735,9 +735,9 @@ def test_package_publication_pre_approval_gap_ledger_keeps_resolution_inputs_exp ) self.assertIn("this ledger does not approve package publication", ledger["non_approvals"]) self.assertIn("real-version cargo publish remains blocked", ledger["retained_blockers"]) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertIn('name = "ethos-doc-core"', core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) diff --git a/.github/scripts/test_milestone_e_package_publication_approval_readiness_review.py b/.github/scripts/test_milestone_e_package_publication_approval_readiness_review.py index d27c021..92b5225 100644 --- a/.github/scripts/test_milestone_e_package_publication_approval_readiness_review.py +++ b/.github/scripts/test_milestone_e_package_publication_approval_readiness_review.py @@ -164,11 +164,11 @@ def test_candidate_inputs_do_not_activate_tags_or_manifests(self) -> None: self.assertEqual("", git("tag", "--list", tag)) self.assertIn('name = "ethos-doc-core"', core_manifest) self.assertIn('reserved_crates_io_name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) + self.assertNotIn("publish = false", core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) - self.assertIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) diff --git a/.github/scripts/test_milestone_e_package_publication_approval_resolution_plan.py b/.github/scripts/test_milestone_e_package_publication_approval_resolution_plan.py index 239c25a..f477448 100644 --- a/.github/scripts/test_milestone_e_package_publication_approval_resolution_plan.py +++ b/.github/scripts/test_milestone_e_package_publication_approval_resolution_plan.py @@ -171,7 +171,7 @@ def test_current_manifests_remain_non_publishable(self) -> None: ): text = read(manifest) - self.assertIn("publish = false", text) + self.assertNotIn("publish = false", text) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', text) def test_docs_reference_resolution_plan_and_blockers(self) -> None: diff --git a/.github/scripts/test_milestone_e_package_publication_candidate_activation_evidence.py b/.github/scripts/test_milestone_e_package_publication_candidate_activation_evidence.py index 947e45e..6bfe6d9 100644 --- a/.github/scripts/test_milestone_e_package_publication_candidate_activation_evidence.py +++ b/.github/scripts/test_milestone_e_package_publication_candidate_activation_evidence.py @@ -124,7 +124,8 @@ def test_candidate_activation_script_passes_with_registry_equivalent_consumer(se self.assertEqual("0.1.0", result["candidate_version"]) self.assertEqual(["ethos-doc-core", "ethos-verify", "ethos-pdf"], result["candidate_packages"]) self.assertEqual("pass", result["registry_equivalent_consumer_check"]) - self.assertTrue(result["source_manifests_remain_blocked"]) + self.assertTrue(result["source_candidate_manifests_activated"]) + self.assertFalse(result["source_manifests_remain_blocked"]) self.assertFalse(result["package_publication_approved"]) self.assertFalse(result["public_installation_approved"]) self.assertNotIn("cargo generate-lockfile --offline", commands) @@ -152,7 +153,7 @@ def test_candidate_activation_preserves_import_and_dependency_shape(self) -> Non self.assertRegex(artifact["sha256"], r"^[0-9a-f]{64}$") self.assertTrue(artifact["crate_file"].endswith("-0.1.0.crate")) - def test_source_manifests_remain_blocked_and_profile_copy_is_in_sync(self) -> None: + def test_source_candidate_manifests_are_activated_and_profile_copy_is_in_sync(self) -> None: core_manifest = read(ROOT / "crates/ethos-core/Cargo.toml") verify_manifest = read(ROOT / "crates/ethos-verify/Cargo.toml") pdf_manifest = read(ROOT / "crates/ethos-pdf/Cargo.toml") @@ -161,9 +162,12 @@ def test_source_manifests_remain_blocked_and_profile_copy_is_in_sync(self) -> No self.assertEqual(read(ROOT_PROFILE), read(PDF_PROFILE)) self.assertIn('include_str!("../assets/ethos-deterministic-v1.json")', pdf_lib) self.assertIn('name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) + self.assertIn('publication_status = "approved_for_crates_io_publication"', core_manifest) + self.assertIn('publication_status = "approved_for_crates_io_publication"', verify_manifest) + self.assertIn('publication_status = "approved_for_crates_io_publication"', pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) self.assertFalse((ROOT / ".cargo/config.toml").exists()) diff --git a/.github/scripts/test_milestone_e_package_publication_current_registry_assembly.py b/.github/scripts/test_milestone_e_package_publication_current_registry_assembly.py index d8a39d9..e00e98f 100644 --- a/.github/scripts/test_milestone_e_package_publication_current_registry_assembly.py +++ b/.github/scripts/test_milestone_e_package_publication_current_registry_assembly.py @@ -119,7 +119,8 @@ def test_current_registry_equivalent_assembly_passes_after_manifest_activation(s self.assertEqual(["ethos-doc-core", "ethos-verify", "ethos-pdf"], result["candidate_packages"]) self.assertEqual("pass", result["registry_equivalent_consumer_check"]) self.assertTrue(result["source_manifest_activation_applied"]) - self.assertTrue(result["source_manifests_remain_blocked"]) + self.assertTrue(result["source_candidate_manifests_activated"]) + self.assertFalse(result["source_manifests_remain_blocked"]) self.assertFalse(result["package_publication_approved"]) self.assertFalse(result["public_installation_approved"]) self.assertIn("cargo package --locked --offline -p ethos-doc-core --allow-dirty --no-verify", commands) @@ -142,15 +143,22 @@ def test_artifacts_and_manifest_shape_are_current(self) -> None: self.assertRegex(artifact["sha256"], r"^[0-9a-f]{64}$") self.assertTrue(artifact["crate_file"].endswith("-0.1.0.crate")) - def test_source_manifests_tags_and_registry_state_remain_blocked(self) -> None: + def test_source_candidate_manifests_are_activated_while_tags_and_registry_stay_absent(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.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)) for tag in ( "ethos-package-ethos-doc-core-0.1.0", diff --git a/.github/scripts/test_milestone_e_package_publication_decision_input_packet.py b/.github/scripts/test_milestone_e_package_publication_decision_input_packet.py index ac4f68e..ef94d06 100644 --- a/.github/scripts/test_milestone_e_package_publication_decision_input_packet.py +++ b/.github/scripts/test_milestone_e_package_publication_decision_input_packet.py @@ -186,12 +186,12 @@ def test_candidate_tags_do_not_exist_and_manifests_remain_inactive(self) -> None tag = value.split(": ", maxsplit=1)[1].split(";", maxsplit=1)[0] self.assertEqual("", git("tag", "--list", tag)) self.assertIn('name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) + self.assertNotIn("publish = false", core_manifest) self.assertIn('reserved_crates_io_name = "ethos-doc-core"', core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) - self.assertIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) diff --git a/.github/scripts/test_milestone_e_package_publication_dependency_ordering.py b/.github/scripts/test_milestone_e_package_publication_dependency_ordering.py index 98bc396..159493a 100644 --- a/.github/scripts/test_milestone_e_package_publication_dependency_ordering.py +++ b/.github/scripts/test_milestone_e_package_publication_dependency_ordering.py @@ -109,9 +109,9 @@ def test_current_manifests_stay_source_tree_only_until_later_approval(self) -> N self.assertIn('name = "ethos-doc-core"', core) self.assertIn('reserved_crates_io_name = "ethos-doc-core"', core) - self.assertIn("publish = false", core) - self.assertIn("publish = false", verify) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", core) + self.assertNotIn("publish = false", verify) + self.assertNotIn("publish = false", pdf) self.assertIn('ethos-core = { workspace = true, features = ["grounding", "verify-types"] }', verify) self.assertIn('ethos-core = { workspace = true, features = ["full"] }', pdf) self.assertNotIn('package = "ethos-doc-core"', verify) diff --git a/.github/scripts/test_milestone_e_package_publication_dry_run_smoke.py b/.github/scripts/test_milestone_e_package_publication_dry_run_smoke.py index 75c187c..dda08e2 100644 --- a/.github/scripts/test_milestone_e_package_publication_dry_run_smoke.py +++ b/.github/scripts/test_milestone_e_package_publication_dry_run_smoke.py @@ -103,8 +103,8 @@ def test_candidate_manifests_still_block_publication(self) -> None: 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.assertNotIn("publish = false", text, str(manifest)) + self.assertIn("publication_status = \"approved_for_crates_io_publication\"", text, str(manifest)) self.assertIn("reserved_crates_io_version = \"0.0.0-reserved.0\"", text, str(manifest)) def test_dependent_package_assembly_blocker_is_recorded(self) -> None: diff --git a/.github/scripts/test_milestone_e_package_publication_evidence_records.py b/.github/scripts/test_milestone_e_package_publication_evidence_records.py index 42ed28e..06fcce9 100644 --- a/.github/scripts/test_milestone_e_package_publication_evidence_records.py +++ b/.github/scripts/test_milestone_e_package_publication_evidence_records.py @@ -166,7 +166,7 @@ def test_dry_run_plan_keeps_publish_false_and_does_not_run_publication(self) -> ROOT / "crates/ethos-verify/Cargo.toml", ROOT / "crates/ethos-pdf/Cargo.toml", ): - self.assertIn("publish = false", read(manifest), str(manifest)) + self.assertNotIn("publish = false", read(manifest), str(manifest)) self.assertIn("cargo build --locked -p ethos-cli", record) self.assertIn("cargo publish --dry-run -p ethos-verify", record) self.assertIn("These commands are not approved as current publication evidence", record) @@ -188,7 +188,7 @@ def test_pdfium_boundary_record_matches_source_boundaries(self) -> None: verify_manifest = read(ROOT / "crates/ethos-verify/Cargo.toml") pdf_manifest = read(ROOT / "crates/ethos-pdf/Cargo.toml") - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertIn("ETHOS_PDFIUM_LIBRARY_PATH", record) self.assertIn("expose no PDFium types in public API", record) self.assertIn("public schemas and", traits) 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 index 68557cc..672a201 100644 --- a/.github/scripts/test_milestone_e_package_publication_final_approval_decision.py +++ b/.github/scripts/test_milestone_e_package_publication_final_approval_decision.py @@ -186,8 +186,8 @@ def test_decision_does_not_activate_publish_flags_tags_or_registry(self) -> None 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.assertNotIn("publish = false", text, str(manifest)) + self.assertIn('publication_status = "approved_for_crates_io_publication"', text, str(manifest)) self.assertIn('name = "ethos-doc-core"', read(ROOT / "crates/ethos-core/Cargo.toml")) self.assertIn( diff --git a/.github/scripts/test_milestone_e_package_publication_final_approval_request.py b/.github/scripts/test_milestone_e_package_publication_final_approval_request.py index 5a7cf6f..f827d09 100644 --- a/.github/scripts/test_milestone_e_package_publication_final_approval_request.py +++ b/.github/scripts/test_milestone_e_package_publication_final_approval_request.py @@ -145,8 +145,8 @@ def test_request_does_not_mutate_manifests_or_create_tags(self) -> None: 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.assertNotIn("publish = false", text, str(manifest)) + self.assertIn('publication_status = "approved_for_crates_io_publication"', text, str(manifest)) for tag in EXACT_TAGS: self.assertEqual("", git("tag", "--list", tag)) diff --git a/.github/scripts/test_milestone_e_package_publication_manifest_activation_applied.py b/.github/scripts/test_milestone_e_package_publication_manifest_activation_applied.py index 38e835a..549ff2d 100644 --- a/.github/scripts/test_milestone_e_package_publication_manifest_activation_applied.py +++ b/.github/scripts/test_milestone_e_package_publication_manifest_activation_applied.py @@ -140,8 +140,8 @@ def test_source_manifests_have_activated_but_blocked_shape(self) -> None: self.assertNotIn('package = "ethos-doc-core"', verify) self.assertNotIn('package = "ethos-doc-core"', pdf) for manifest in (core, verify, pdf): - self.assertIn("publish = false", manifest) - self.assertIn('publication_status = "blocked"', manifest) + self.assertNotIn("publish = false", manifest) + self.assertIn('publication_status = "approved_for_crates_io_publication"', manifest) def test_tags_registry_and_public_installation_remain_blocked(self) -> None: prep = load_json(PREP) diff --git a/.github/scripts/test_milestone_e_package_publication_manifest_activation_diff_review.py b/.github/scripts/test_milestone_e_package_publication_manifest_activation_diff_review.py index 501a10e..9f175ea 100644 --- a/.github/scripts/test_milestone_e_package_publication_manifest_activation_diff_review.py +++ b/.github/scripts/test_milestone_e_package_publication_manifest_activation_diff_review.py @@ -142,11 +142,11 @@ def test_current_manifests_stay_unactivated(self) -> None: self.assertEqual("", git("tag", "--list", tag)) self.assertIn('name = "ethos-doc-core"', core_manifest) self.assertIn('reserved_crates_io_name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) + self.assertNotIn("publish = false", core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) - self.assertIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) diff --git a/.github/scripts/test_milestone_e_package_publication_manifest_activation_prep.py b/.github/scripts/test_milestone_e_package_publication_manifest_activation_prep.py index e2000ca..7ee2184 100644 --- a/.github/scripts/test_milestone_e_package_publication_manifest_activation_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_manifest_activation_prep.py @@ -110,9 +110,9 @@ def test_current_manifest_dependencies_stay_source_tree_only(self) -> None: self.assertIn('ethos-core = { workspace = true, features = ["full"] }', pdf) self.assertIn('name = "ethos-doc-core"', core) self.assertIn('[lib]\nname = "ethos_core"', core) - self.assertIn("publish = false", core) - self.assertIn("publish = false", verify) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", core) + self.assertNotIn("publish = false", verify) + self.assertNotIn("publish = false", pdf) def test_manifest_activation_record_names_future_review_boundary(self) -> None: record = normalized(RECORD) diff --git a/.github/scripts/test_milestone_e_package_publication_manifest_migration_prep.py b/.github/scripts/test_milestone_e_package_publication_manifest_migration_prep.py index d7f9b2a..519082a 100644 --- a/.github/scripts/test_milestone_e_package_publication_manifest_migration_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_manifest_migration_prep.py @@ -110,9 +110,9 @@ def test_current_manifests_remain_unmigrated_source_tree_manifests(self) -> None self.assertIn('name = "ethos-doc-core"', core) self.assertIn('[lib]\nname = "ethos_core"', core) self.assertIn('reserved_crates_io_name = "ethos-doc-core"', core) - self.assertIn("publish = false", core) - self.assertIn("publish = false", verify) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", core) + self.assertNotIn("publish = false", verify) + self.assertNotIn("publish = false", pdf) self.assertIn( 'ethos-core = { package = "ethos-doc-core", path = "crates/ethos-core", version = "0.1.0", default-features = false }', workspace, diff --git a/.github/scripts/test_milestone_e_package_publication_metadata_readiness.py b/.github/scripts/test_milestone_e_package_publication_metadata_readiness.py index fcd93be..f31983a 100644 --- a/.github/scripts/test_milestone_e_package_publication_metadata_readiness.py +++ b/.github/scripts/test_milestone_e_package_publication_metadata_readiness.py @@ -89,14 +89,14 @@ def load_json(path: Path) -> dict: class MilestoneEPackagePublicationMetadataReadinessTests(unittest.TestCase): - def test_in_tree_candidate_metadata_files_are_present_and_blocked(self) -> None: + def test_in_tree_candidate_metadata_files_are_present_and_activated(self) -> None: for crate, details in CANDIDATE_CRATES.items(): root = details["path"] manifest = read(root / "Cargo.toml") readme = normalized(root / "README.md") notice = normalized(root / "NOTICE.md") - self.assertIn("publish = false", manifest, crate) + self.assertNotIn("publish = false", manifest, crate) self.assertIn('readme = "README.md"', manifest, crate) self.assertIn('"README.md"', manifest, crate) self.assertIn('"NOTICE.md"', manifest, crate) @@ -104,20 +104,20 @@ def test_in_tree_candidate_metadata_files_are_present_and_blocked(self) -> None: self.assertIn("license.workspace = true", manifest, crate) self.assertIn("repository.workspace = true", manifest, crate) self.assertIn("authors.workspace = true", manifest, crate) - self.assertIn("publication_status = \"blocked\"", manifest, crate) + self.assertIn("publication_status = \"approved_for_crates_io_publication\"", manifest, crate) self.assertIn( f"reserved_crates_io_name = \"{details['reserved_name']}\"", manifest, crate, ) self.assertIn("reserved_crates_io_version = \"0.0.0-reserved.0\"", manifest, crate) - self.assertIn("Package publication remains blocked", readme, crate) + self.assertIn("Publication metadata is activated", readme, crate) self.assertIn("Public installation from crates.io remains blocked", readme, crate) self.assertIn("0.0.0-reserved.0", readme, crate) - self.assertIn("no public API", readme, crate) - self.assertIn("internal metadata readiness review only", readme, crate) - self.assertIn("Package publication remains blocked", notice, crate) - self.assertIn("internal metadata readiness review only", notice, crate) + self.assertIn("registry action", readme, crate) + self.assertIn("package-publication activation review only", readme, crate) + self.assertIn("Publication metadata is activated", notice, crate) + self.assertIn("public installation and registry action remain blocked", notice, crate) def test_reserved_placeholder_crates_without_manifests_stay_blocked(self) -> None: prep = load_json(PREP) diff --git a/.github/scripts/test_milestone_e_package_publication_pdfium_boundary.py b/.github/scripts/test_milestone_e_package_publication_pdfium_boundary.py index b4de6e0..be447f7 100644 --- a/.github/scripts/test_milestone_e_package_publication_pdfium_boundary.py +++ b/.github/scripts/test_milestone_e_package_publication_pdfium_boundary.py @@ -124,8 +124,8 @@ def test_ethos_pdf_manifest_and_docs_keep_current_boundary(self) -> None: readme = normalized(PDF_CRATE / "README.md") notice = normalized(PDF_CRATE / "NOTICE.md") - self.assertIn("publish = false", manifest) - self.assertIn("publication_status = \"blocked\"", manifest) + self.assertNotIn("publish = false", manifest) + self.assertIn("publication_status = \"approved_for_crates_io_publication\"", manifest) self.assertIn("reserved_crates_io_version = \"0.0.0-reserved.0\"", manifest) self.assertIn('"assets/**"', manifest) self.assertNotIn("build.rs", manifest) diff --git a/.github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py b/.github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py index 5ff65ee..051ce22 100644 --- a/.github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py +++ b/.github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py @@ -161,9 +161,9 @@ def test_current_manifests_stay_non_publishable(self) -> None: self.assertIn('"crates/ethos-core"', cargo) self.assertIn('"crates/ethos-verify"', cargo) self.assertIn('"crates/ethos-pdf"', cargo) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', core_manifest) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', verify_manifest) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', pdf_manifest) diff --git a/.github/scripts/test_milestone_e_package_publication_public_installation_wording_review.py b/.github/scripts/test_milestone_e_package_publication_public_installation_wording_review.py index f843b94..c67b956 100644 --- a/.github/scripts/test_milestone_e_package_publication_public_installation_wording_review.py +++ b/.github/scripts/test_milestone_e_package_publication_public_installation_wording_review.py @@ -155,9 +155,9 @@ def test_current_manifests_tags_and_registry_state_stay_unactivated(self) -> Non tag = value.split(": ", maxsplit=1)[1].split(";", maxsplit=1)[0] self.assertEqual("", git("tag", "--list", tag)) self.assertIn('name = "ethos-doc-core"', core_manifest) - self.assertIn("publish = false", core_manifest) - self.assertIn("publish = false", verify_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", core_manifest) + self.assertNotIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) self.assertFalse((ROOT / ".cargo/config.toml").exists()) diff --git a/.github/scripts/test_milestone_e_package_publication_real_version_selection_prep.py b/.github/scripts/test_milestone_e_package_publication_real_version_selection_prep.py index 6f905b0..d91254b 100644 --- a/.github/scripts/test_milestone_e_package_publication_real_version_selection_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_real_version_selection_prep.py @@ -110,9 +110,9 @@ def test_current_versions_and_manifests_stay_source_tree_only(self) -> None: self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', core) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', verify) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', pdf) - self.assertIn("publish = false", core) - self.assertIn("publish = false", verify) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", core) + self.assertNotIn("publish = false", verify) + self.assertNotIn("publish = false", pdf) def test_real_version_selection_record_names_future_review_boundary(self) -> None: record = normalized(RECORD) diff --git a/.github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py b/.github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py index c496f28..4a8d216 100644 --- a/.github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py @@ -112,9 +112,9 @@ def test_current_manifests_and_registry_state_stay_source_tree_only(self) -> Non self.assertIn('ethos-core = { workspace = true, features = ["full"] }', pdf) self.assertIn('name = "ethos-doc-core"', core) self.assertIn('[lib]\nname = "ethos_core"', core) - self.assertIn("publish = false", core) - self.assertIn("publish = false", verify) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", core) + self.assertNotIn("publish = false", verify) + self.assertNotIn("publish = false", pdf) self.assertFalse((ROOT / ".cargo/config.toml").exists()) self.assertFalse((ROOT / "target/package-registry").exists()) diff --git a/.github/scripts/test_milestone_e_package_publication_registry_assembly_evidence_review.py b/.github/scripts/test_milestone_e_package_publication_registry_assembly_evidence_review.py index 4be49a3..257b80e 100644 --- a/.github/scripts/test_milestone_e_package_publication_registry_assembly_evidence_review.py +++ b/.github/scripts/test_milestone_e_package_publication_registry_assembly_evidence_review.py @@ -138,11 +138,11 @@ def test_current_manifests_and_registry_state_stay_unactivated(self) -> None: self.assertIn('ethos-core = { package = "ethos-doc-core", path = "crates/ethos-core"', workspace) self.assertIn('name = "ethos-doc-core"', core_manifest) self.assertIn('[lib]\nname = "ethos_core"', core_manifest) - self.assertIn("publish = false", core_manifest) + self.assertNotIn("publish = false", core_manifest) self.assertIn('name = "ethos-verify"', verify_manifest) - self.assertIn("publish = false", verify_manifest) + self.assertNotIn("publish = false", verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) - self.assertIn("publish = false", pdf_manifest) + self.assertNotIn("publish = false", pdf_manifest) self.assertNotIn('package = "ethos-doc-core"', verify_manifest) self.assertNotIn('package = "ethos-doc-core"', pdf_manifest) self.assertFalse((ROOT / ".cargo/config.toml").exists()) diff --git a/.github/scripts/test_milestone_e_package_publication_registry_assembly_prep.py b/.github/scripts/test_milestone_e_package_publication_registry_assembly_prep.py index f51a3ab..f932941 100644 --- a/.github/scripts/test_milestone_e_package_publication_registry_assembly_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_registry_assembly_prep.py @@ -107,9 +107,9 @@ def test_current_manifests_stay_source_tree_only(self) -> None: pdf = read(ROOT / "crates/ethos-pdf/Cargo.toml") self.assertIn('name = "ethos-doc-core"', core) - self.assertIn("publish = false", core) - self.assertIn("publish = false", verify) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", core) + self.assertNotIn("publish = false", verify) + self.assertNotIn("publish = false", pdf) self.assertIn( 'ethos-core = { package = "ethos-doc-core", path = "crates/ethos-core", version = "0.1.0", default-features = false }', workspace, diff --git a/.github/scripts/test_milestone_e_package_publication_tag_creation_prep.py b/.github/scripts/test_milestone_e_package_publication_tag_creation_prep.py index 9d91cbf..e7999d5 100644 --- a/.github/scripts/test_milestone_e_package_publication_tag_creation_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_tag_creation_prep.py @@ -109,9 +109,9 @@ def test_current_manifests_and_versions_stay_unchanged(self) -> None: self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', core) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', verify) self.assertIn('reserved_crates_io_version = "0.0.0-reserved.0"', pdf) - self.assertIn("publish = false", core) - self.assertIn("publish = false", verify) - self.assertIn("publish = false", pdf) + self.assertNotIn("publish = false", core) + self.assertNotIn("publish = false", verify) + self.assertNotIn("publish = false", pdf) def test_tag_creation_record_names_future_review_boundary(self) -> None: record = normalized(RECORD) 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 c8fccaa..b7b8c0d 100644 --- a/.github/scripts/test_milestone_e_prep_guard_sequence_index.py +++ b/.github/scripts/test_milestone_e_prep_guard_sequence_index.py @@ -120,6 +120,8 @@ "$(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_package_publication_activation_request.py", + "$(PYTHON) .github/scripts/test_milestone_e_package_publication_activation_applied.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 94131f6..912f128 100644 --- a/.github/scripts/test_milestone_e_prep_scope.py +++ b/.github/scripts/test_milestone_e_prep_scope.py @@ -419,6 +419,8 @@ def test_make_target_is_narrow_and_guarded(self) -> None: "$(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_package_publication_activation_request.py", + "$(PYTHON) .github/scripts/test_milestone_e_package_publication_activation_applied.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 e04fa90..be72ef4 100644 --- a/.github/scripts/test_milestone_e_validation_record_index.py +++ b/.github/scripts/test_milestone_e_validation_record_index.py @@ -318,6 +318,14 @@ class 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-package-publication-publish-flag-activation-request-validation-2026-06-22.md", + "test_milestone_e_package_publication_activation_request.py", + ), + RecordCoverage( + "milestone-e-package-publication-activation-applied-validation-2026-06-22.md", + "test_milestone_e_package_publication_activation_applied.py", + ), RecordCoverage( "milestone-e-public-facing-readiness-ledger-validation-2026-06-21.md", "test_milestone_e_public_facing_readiness_ledger.py", @@ -471,6 +479,12 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: package_final_approval_decision_guard = ( "test_milestone_e_package_publication_final_approval_decision.py" ) + package_publish_flag_activation_request_guard = ( + "test_milestone_e_package_publication_activation_request.py" + ) + package_publication_activation_applied_guard = ( + "test_milestone_e_package_publication_activation_applied.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" @@ -587,6 +601,14 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: ) self.assertLess( text.index(prefix + package_final_approval_decision_guard), + text.index(prefix + package_publish_flag_activation_request_guard), + ) + self.assertLess( + text.index(prefix + package_publish_flag_activation_request_guard), + text.index(prefix + package_publication_activation_applied_guard), + ) + self.assertLess( + text.index(prefix + package_publication_activation_applied_guard), text.index(prefix + readiness_guard), ) self.assertLess(text.index(prefix + readiness_guard), text.index(prefix + beta_refresh_guard)) @@ -664,6 +686,22 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: text.index(prefix + package_final_approval_decision_guard), text.index(prefix + index_guard), ) + self.assertLess( + text.index(prefix + package_publish_flag_activation_request_guard), + text.index(prefix + command_guard), + ) + self.assertLess( + text.index(prefix + package_publish_flag_activation_request_guard), + text.index(prefix + index_guard), + ) + self.assertLess( + text.index(prefix + package_publication_activation_applied_guard), + text.index(prefix + command_guard), + ) + self.assertLess( + text.index(prefix + package_publication_activation_applied_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 d92c4bd..aff6336 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -254,6 +254,10 @@ jobs: 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 package publication publish-flag activation request tests + run: python3 .github/scripts/test_milestone_e_package_publication_activation_request.py + - name: Milestone E package publication activation applied tests + run: python3 .github/scripts/test_milestone_e_package_publication_activation_applied.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 ccfae9d..3b2c60e 100644 --- a/Makefile +++ b/Makefile @@ -234,6 +234,8 @@ milestone-e-prep: $(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_package_publication_activation_request.py + $(PYTHON) .github/scripts/test_milestone_e_package_publication_activation_applied.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/crates/ethos-core/Cargo.toml b/crates/ethos-core/Cargo.toml index f04ffb6..e41f433 100644 --- a/crates/ethos-core/Cargo.toml +++ b/crates/ethos-core/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "ethos-doc-core" -publish = false description = "Ethos canonical document model, IDs, errors, schema types, traits, c14n and fingerprints" readme = "README.md" keywords = ["ethos", "documents", "evidence"] @@ -23,7 +22,7 @@ name = "ethos_core" [package.metadata.ethos_publication] reserved_crates_io_name = "ethos-doc-core" reserved_crates_io_version = "0.0.0-reserved.0" -publication_status = "blocked" +publication_status = "approved_for_crates_io_publication" [features] default = ["full"] diff --git a/crates/ethos-core/NOTICE.md b/crates/ethos-core/NOTICE.md index 4f137d2..a922609 100644 --- a/crates/ethos-core/NOTICE.md +++ b/crates/ethos-core/NOTICE.md @@ -3,5 +3,6 @@ Copyright 2026 The Ethos maintainers Licensed under the Apache License, Version 2.0. -This source-tree crate bundles no third-party binary assets. Package publication remains blocked; -this notice supports internal metadata readiness review only. +This source-tree crate bundles no third-party binary assets. Publication metadata is activated +for the approved crates.io candidate surface; public installation and registry action remain +blocked until refreshed binding and operator evidence are recorded. diff --git a/crates/ethos-core/README.md b/crates/ethos-core/README.md index 698770f..354091c 100644 --- a/crates/ethos-core/README.md +++ b/crates/ethos-core/README.md @@ -6,15 +6,16 @@ descriptor support, and trait boundaries. ADR-0006 reserves the public crates.io identifier `ethos-doc-core` at `0.0.0-reserved.0`. The Rust library name remains `ethos_core` so existing source imports keep the -same crate path while package-publication approval remains blocked. +same crate path while registry action remains blocked. ## Publication Boundary -- `publish = false` remains set. -- Package publication remains blocked. -- Public installation from crates.io remains blocked. -- The reserved crates.io placeholder remains `0.0.0-reserved.0` with no public API. -- This README supports internal metadata readiness review only. +- Publication metadata is activated for the approved crates.io candidate surface. +- Public installation from crates.io remains blocked until refreshed tag/source binding and + operator evidence are recorded. +- The reserved crates.io placeholder remains `0.0.0-reserved.0` until registry action is + explicitly recorded. +- This README supports package-publication activation review only. ## Metadata Notes diff --git a/crates/ethos-pdf/Cargo.toml b/crates/ethos-pdf/Cargo.toml index 4aeb33c..509cd62 100644 --- a/crates/ethos-pdf/Cargo.toml +++ b/crates/ethos-pdf/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "ethos-pdf" -publish = false description = "PDFium backend behind EthosPdfBackend — quantize-at-extraction lives here (WS-ENGINE, Milestone A)" readme = "README.md" keywords = ["ethos", "pdf", "evidence"] @@ -21,7 +20,7 @@ authors.workspace = true [package.metadata.ethos_publication] reserved_crates_io_name = "ethos-pdf" reserved_crates_io_version = "0.0.0-reserved.0" -publication_status = "blocked" +publication_status = "approved_for_crates_io_publication" [dependencies] ethos-core = { workspace = true, features = ["full"] } diff --git a/crates/ethos-pdf/NOTICE.md b/crates/ethos-pdf/NOTICE.md index 908f9ec..d3e4aa6 100644 --- a/crates/ethos-pdf/NOTICE.md +++ b/crates/ethos-pdf/NOTICE.md @@ -4,5 +4,6 @@ Copyright 2026 The Ethos maintainers Licensed under the Apache License, Version 2.0. This source-tree crate bundles no PDFium binary and no third-party binary assets. PDFium remains -caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`. Package publication remains blocked; this -notice supports internal metadata readiness review only. +caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`. Publication metadata is activated for the +approved crates.io candidate surface; public installation and registry action remain blocked until +refreshed binding and operator evidence are recorded. diff --git a/crates/ethos-pdf/README.md b/crates/ethos-pdf/README.md index fece5b7..c859e04 100644 --- a/crates/ethos-pdf/README.md +++ b/crates/ethos-pdf/README.md @@ -7,11 +7,12 @@ ADR-0006 reserves the public crates.io identifier `ethos-pdf` at `0.0.0-reserved ## Publication Boundary -- `publish = false` remains set. -- Package publication remains blocked. -- Public installation from crates.io remains blocked. -- The reserved crates.io placeholder remains `0.0.0-reserved.0` with no public API. -- This README supports internal metadata readiness review only. +- Publication metadata is activated for the approved crates.io candidate surface. +- Public installation from crates.io remains blocked until refreshed tag/source binding and + operator evidence are recorded. +- The reserved crates.io placeholder remains `0.0.0-reserved.0` until registry action is + explicitly recorded. +- This README supports package-publication activation review only. ## PDFium Boundary diff --git a/crates/ethos-verify/Cargo.toml b/crates/ethos-verify/Cargo.toml index 8c4d030..ad445ee 100644 --- a/crates/ethos-verify/Cargo.toml +++ b/crates/ethos-verify/Cargo.toml @@ -1,6 +1,5 @@ [package] name = "ethos-verify" -publish = false description = "Parser-agnostic citation evidence verification over GroundingSource (alpha lands Milestone B)" readme = "README.md" keywords = ["ethos", "citations", "evidence"] @@ -20,7 +19,7 @@ authors.workspace = true [package.metadata.ethos_publication] reserved_crates_io_name = "ethos-verify" reserved_crates_io_version = "0.0.0-reserved.0" -publication_status = "blocked" +publication_status = "approved_for_crates_io_publication" [dependencies] # INVARIANT 4 (enforced by CI no-parser-internals job): ethos-verify sees ONLY the diff --git a/crates/ethos-verify/NOTICE.md b/crates/ethos-verify/NOTICE.md index 4f137d2..a922609 100644 --- a/crates/ethos-verify/NOTICE.md +++ b/crates/ethos-verify/NOTICE.md @@ -3,5 +3,6 @@ Copyright 2026 The Ethos maintainers Licensed under the Apache License, Version 2.0. -This source-tree crate bundles no third-party binary assets. Package publication remains blocked; -this notice supports internal metadata readiness review only. +This source-tree crate bundles no third-party binary assets. Publication metadata is activated +for the approved crates.io candidate surface; public installation and registry action remain +blocked until refreshed binding and operator evidence are recorded. diff --git a/crates/ethos-verify/README.md b/crates/ethos-verify/README.md index 633ea81..91af616 100644 --- a/crates/ethos-verify/README.md +++ b/crates/ethos-verify/README.md @@ -8,11 +8,12 @@ ADR-0006 reserves the public crates.io identifier `ethos-verify` at `0.0.0-reser ## Publication Boundary -- `publish = false` remains set. -- Package publication remains blocked. -- Public installation from crates.io remains blocked. -- The reserved crates.io placeholder remains `0.0.0-reserved.0` with no public API. -- This README supports internal metadata readiness review only. +- Publication metadata is activated for the approved crates.io candidate surface. +- Public installation from crates.io remains blocked until refreshed tag/source binding and + operator evidence are recorded. +- The reserved crates.io placeholder remains `0.0.0-reserved.0` until registry action is + explicitly recorded. +- This README supports package-publication activation review only. ## Metadata Notes diff --git a/docs/execution-status.md b/docs/execution-status.md index 049d03a..470cd4a 100644 --- a/docs/execution-status.md +++ b/docs/execution-status.md @@ -223,6 +223,10 @@ The package publication final approval request in `docs/validation/milestone-e-p 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. +The package publication publish-flag activation request in `docs/validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md` records the exact requested activation diff for the three accepted candidate manifests only. Activation remains blocked, package tag source binding must be refreshed after activation, package tag creation remains blocked, real-version cargo publish remains blocked, and public installation instructions remain unchanged. + +The package publication activation applied record in `docs/validation/milestone-e-package-publication-activation-applied-validation-2026-06-22.md` binds the applied manifest activation to source commit `f50f294` / tree `00c3e4df7a7b3b368659650601a2df76b63a2ce8`. The three accepted candidate manifests are activated, non-candidate crates remain blocked, package tag source binding must be refreshed, real-version cargo publish remains blocked, and public installation remains blocked. + | 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 11054bb..950b78c 100644 --- a/docs/milestone-e-prep-scope.md +++ b/docs/milestone-e-prep-scope.md @@ -179,6 +179,18 @@ It accepts the exact bounded candidate crates, version map, package tag names, s 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 package publication publish-flag activation request is recorded in +`docs/validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md`. +It records the exact requested activation diff for the three accepted candidate manifests only; +activation remains blocked, package tag source binding must be refreshed after activation, +package tag creation remains blocked, real-version cargo publish remains blocked, and public +installation instructions remain unchanged. +The package publication activation applied follow-up is recorded in +`docs/validation/milestone-e-package-publication-activation-applied-validation-2026-06-22.md`. +It binds the activated candidate manifests to source commit `f50f294` / tree +`00c3e4df7a7b3b368659650601a2df76b63a2ce8`; non-candidate crates remain blocked, package tag +source binding must be refreshed, public installation remains blocked, and real-version cargo +publish remains blocked. 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 @@ -380,6 +392,15 @@ or broad demo-generation workflows. 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 package publication publish-flag activation request records exact requested source changes + for the three accepted candidate manifests only; activation remains blocked, package tag source + binding must be refreshed after activation, package tag creation remains blocked, and + real-version cargo publish remains blocked. +- The package publication activation applied follow-up records that the three accepted candidate + manifests are activated at source commit `f50f294` / tree + `00c3e4df7a7b3b368659650601a2df76b63a2ce8`; non-candidate crates remain blocked, package tag + source binding must be refreshed, public installation remains blocked, and real-version cargo + publish remains blocked. - 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 01f727b..f3b2176 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -149,6 +149,17 @@ and accepts the exact bounded candidate crates, version map, package tag names, 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 publish-flag activation request is recorded in +[`docs/validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md`](validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md) +and records the exact requested source diff for the three accepted candidate manifests only; +activation remains blocked, package tag source binding must be refreshed after activation, package +tag creation remains blocked, real-version cargo publish remains blocked, and public installation +instructions remain unchanged. +The package publication activation applied follow-up is recorded in +[`docs/validation/milestone-e-package-publication-activation-applied-validation-2026-06-22.md`](validation/milestone-e-package-publication-activation-applied-validation-2026-06-22.md) +and binds the activated candidate manifests to source commit `f50f294` / tree +`00c3e4df7a7b3b368659650601a2df76b63a2ce8`; package tag source binding must be refreshed, public +installation remains blocked, and real-version cargo publish remains blocked. 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 2567743..ff16aaa 100644 --- a/docs/validation/README.md +++ b/docs/validation/README.md @@ -403,6 +403,17 @@ recording the exact current-main source candidate and required follow-up evidenc 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-package-publication-publish-flag-activation-request-validation-2026-06-22.md` - + package publication publish-flag activation request validation; the record captures the exact + requested activation diff for the three accepted candidate manifests while keeping activation + blocked, recording that package tag source binding must be refreshed after activation, and + keeping tag creation, real-version cargo publish, and public installation instructions blocked. +- `milestone-e-package-publication-activation-applied-validation-2026-06-22.md` - package + publication activation applied validation; the record binds the applied manifest activation to + source commit `f50f294` / tree `00c3e4df7a7b3b368659650601a2df76b63a2ce8`, records that only + the three accepted candidate manifests changed, records that non-candidate crates stay blocked, + and keeps package tag source binding refresh, real-version cargo publish, and public + installation instructions blocked. - `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-activation-applied-validation-2026-06-22.md b/docs/validation/milestone-e-package-publication-activation-applied-validation-2026-06-22.md new file mode 100644 index 0000000..595c76a --- /dev/null +++ b/docs/validation/milestone-e-package-publication-activation-applied-validation-2026-06-22.md @@ -0,0 +1,72 @@ +# Milestone E Package Publication Activation Applied Validation - 2026-06-22 + +- Validated source HEAD before this record: `f50f294` + +Activation applied source commit: `f50f2948b0536b3c75fe369558c94ce1155b73d1` + +Activation applied source tree: `00c3e4df7a7b3b368659650601a2df76b63a2ce8` + +Status: **pass for publish-flag and package metadata activation with registry action blocked** + +## Scope + +This record validates the source change requested by +`docs/validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md` +after the decider accepted the bounded candidate surface in +`docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md`. + +The applied source change is limited to the three accepted crates.io candidate manifests: + +- `crates/ethos-core/Cargo.toml` for package `ethos-doc-core` +- `crates/ethos-verify/Cargo.toml` for package `ethos-verify` +- `crates/ethos-pdf/Cargo.toml` for package `ethos-pdf` + +## Applied Manifest State + +- `publish = false` is absent from the three accepted candidate manifests. +- `publication_status = "approved_for_crates_io_publication"` is present in the three accepted + candidate manifests. +- `reserved_crates_io_version = "0.0.0-reserved.0"` remains present in the three accepted + candidate manifests as reservation provenance. +- Non-candidate workspace crates remain unchanged and retain `publish = false`: + `ethos-cli`, `ethos-layout`, and `ethos-tables`. +- The package name split remains intact: source path `crates/ethos-core`, package name + `ethos-doc-core`, Rust library name `ethos_core`, and workspace dependency key `ethos-core`. +- `ethos-verify` still depends only on the workspace `ethos-core` key with `grounding` and + `verify-types`; it does not depend on parser internals. +- `ethos-pdf` keeps PDFium caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH` and bundles no + PDFium binary. + +## Retained Blockers + +- Ethos remains source-only pre-alpha for this source-tree approval boundary. +- Public reports remain blocked. +- Public result wording remains blocked. +- Package tag source binding must be refreshed to this activated source commit or a later reviewed + source commit before package tags are created. +- No package tags are created by this record: + `ethos-package-ethos-doc-core-0.1.0`, `ethos-package-ethos-verify-0.1.0`, and + `ethos-package-ethos-pdf-0.1.0` remain absent. +- `cargo publish` remains blocked until refreshed binding, dry-run evidence, and operator evidence + are recorded. +- Public installation instructions remain blocked until package availability and wording are + explicitly revalidated. +- Wheels, npm packages, binaries, hosted surfaces, production positioning, public benchmark reports, + public benchmark claims, project-maintained PDFium builds, `ethos-doc`, and `ethos-rag` remain + excluded. +- No local registry config is created: `.cargo/config.toml` remains absent. +- No local package registry directory is retained: `target/package-registry` remains absent. + +## Validation Commands + +- `python3 .github/scripts/test_milestone_e_package_publication_activation_applied.py` +- `python3 .github/scripts/test_milestone_e_package_publication_candidate_activation_evidence.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` +- `make package-publication-dry-run-smoke PYTHON=` +- `make milestone-e-prep PYTHON=/bin/python` +- `cargo build --locked -p ethos-cli` +- `cargo test --locked --workspace --all-features` +- `git diff --check` diff --git a/docs/validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md b/docs/validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md new file mode 100644 index 0000000..db35c7f --- /dev/null +++ b/docs/validation/milestone-e-package-publication-publish-flag-activation-request-validation-2026-06-22.md @@ -0,0 +1,107 @@ +# Milestone E Package Publication Publish-Flag Activation Request Validation - 2026-06-22 + +## Purpose + +Record the exact publish-flag and package metadata activation request after the final +package-publication approval decision. + +This record does not remove `publish = false`, change package metadata, create package tags, run +`cargo publish`, or invite public installation. It records the exact source activation diff that +requires decider review before package tag source binding can move forward. + +## Status + +Status: **pass for publish-flag activation request with activation blocked**. + +Decision: exact publish-flag activation request recorded for decider review. + +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: `cea2018` +- Activation request source commit: `cea20182e11271bf83675c12de43498df9c42c18` +- Activation request source tree: `8c7076b0997fe925827bb81f859b74790a4d8b16` +- Lane: package publication +- Final approval decision record: + `docs/validation/milestone-e-package-publication-final-approval-decision-validation-2026-06-22.md` +- Approval owner requested: `docushell-admin` + +## Exact Request Fields + +- Decision requested: approve exact publish-flag and package metadata activation diff. +- Approver requested: docushell-admin acting as decider. +- Date requested: 2026-06-22. +- Exact activation crate list requested: `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` only. +- Exact activation diff requested: remove `publish = false` from the three accepted candidate + manifests only. +- Exact metadata diff requested: change `publication_status = "blocked"` to + `publication_status = "approved_for_crates_io_publication"` in the three accepted candidate + manifests only. +- Exact crate manifests requested for activation: + `crates/ethos-core/Cargo.toml`, `crates/ethos-verify/Cargo.toml`, and + `crates/ethos-pdf/Cargo.toml`. +- Exact crate READMEs requested for activation: update only the candidate package status language + so it no longer says `publish = false` remains set. +- Non-candidate workspace crates remain unchanged and retain `publish = false`. +- Package tag source binding impact: the previous accepted source binding keeps `publish = false`; + package tag source binding must be refreshed after the activation diff is applied and reviewed. +- Exact package tag names retained as candidates: `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 version map retained as candidates: `ethos-doc-core = 0.1.0`, + `ethos-verify = 0.1.0`, and `ethos-pdf = 0.1.0`. + +## Explicit Exclusions + +- package tag creation remains blocked +- real-version cargo publish remains blocked +- public installation instructions remain blocked +- 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 + +## Retained Blockers + +- activation remains blocked until the exact diff is reviewed and accepted +- package tag source binding must be refreshed after activation is applied +- package tag creation remains blocked until the refreshed source binding is accepted +- real-version cargo publish remains blocked until activated source evidence and operator evidence + are present +- public installation instructions remain blocked until registry availability is verified + +## Commands + +```sh +python3 .github/scripts/test_milestone_e_package_publication_publish_flag_activation_request.py +python3 .github/scripts/test_milestone_e_package_publication_final_approval_decision.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 +Publish-flag activation request validation passed +Exact activation diff was recorded for decider review +Current source manifests retained publish=false and publication_status=blocked +No package tag was created +No package was published +Public-surface posture and claims gates passed +Milestone E prep target passed +git diff --check passed +```