From 2ab2cb26864cd1bdc67da69489bceb35fd96bbcc Mon Sep 17 00:00:00 2001 From: docushell-admin Date: Sun, 21 Jun 2026 12:12:20 +0530 Subject: [PATCH] Record package publication pre-approval gap ledger Signed-off-by: docushell-admin --- ...one_e_package_publication_approval_prep.py | 102 +++++++++++ ...age_publication_pre_approval_gap_ledger.py | 173 ++++++++++++++++++ ...t_milestone_e_prep_guard_sequence_index.py | 1 + .../scripts/test_milestone_e_prep_scope.py | 1 + ...est_milestone_e_validation_record_index.py | 13 +- .github/workflows/ci.yml | 2 + Makefile | 1 + ...e-e-package-publication-approval-prep.json | 56 +++++- docs/validation/README.md | 5 + ...proval-gap-ledger-validation-2026-06-21.md | 122 ++++++++++++ ...kage-publication-approval-prep.schema.json | 109 ++++++++++- 11 files changed, 581 insertions(+), 4 deletions(-) create mode 100644 .github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py create mode 100644 docs/validation/milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md 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 e4a288f0..546f7082 100644 --- a/.github/scripts/test_milestone_e_package_publication_approval_prep.py +++ b/.github/scripts/test_milestone_e_package_publication_approval_prep.py @@ -91,6 +91,7 @@ "package_real_version_selection_prep": "docs/validation/milestone-e-package-publication-real-version-selection-prep-validation-2026-06-21.md", "package_tag_creation_prep": "docs/validation/milestone-e-package-publication-tag-creation-prep-validation-2026-06-21.md", "package_decision_bundle_validation": "docs/validation/milestone-e-package-publication-decision-bundle-validation-2026-06-21.md", + "package_pre_approval_gap_ledger": "docs/validation/milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md", } EXPECTED_PUBLICATION_DECISION_INPUTS = { "decision_status": "not_approved_pending_exact_decision", @@ -272,6 +273,59 @@ "real-version cargo publish remains blocked", ], } +EXPECTED_PACKAGE_PUBLICATION_PRE_APPROVAL_GAP_LEDGER = { + "ledger_state": "pre_approval_gaps_recorded_publication_blocked", + "gap_rows": [ + "version map gap: no package publication version is selected; requires exact SemVer package version or per-crate version map", + "tag name gap: no package tag is created; requires exact package tag name", + "tag binding gap: no package_tag_source_commit or source tree is selected; requires exact source commit and tree binding", + "manifest activation gap: current Cargo manifests remain unchanged; requires exact package-name migration and dependency activation diff", + "registry assembly gap: no registry-backed dependent package assembly is activated; requires exact non-public assembly evidence", + "public installation wording gap: no public installation wording is approved; requires exact wording and exclusions", + "posture and claims gate gap: gates must rerun after exact public installation wording changes", + ], + "blocked_actions": [ + "selecting a package publication version remains blocked", + "creating a package tag remains blocked", + "changing Cargo manifests remains blocked", + "activating package dependency manifests remains blocked", + "creating a registry remains blocked", + "activating registry-backed dependent package assembly remains blocked", + "inviting public installation remains blocked", + "approving package publication remains blocked", + ], + "required_resolution_inputs": [ + "exact package publication approval decision record", + "exact candidate crate list", + "exact SemVer package version or per-crate version map", + "exact package tag name", + "exact package_tag_source_commit and package source tree", + "exact package-name migration diff for ethos-doc-core", + "exact dependency manifest activation diff for ethos-verify and ethos-pdf", + "exact registry-backed dependent package assembly evidence", + "exact public installation wording and explicit exclusions", + "posture and claims gates after exact public installation wording changes", + ], + "non_approvals": [ + "this ledger does not select a package publication version", + "this ledger does not create a package tag", + "this ledger does not change Cargo manifests", + "this ledger does not activate package dependency manifests", + "this ledger does not create a registry", + "this ledger does not activate registry-backed dependent package assembly", + "this ledger does not invite public installation", + "this ledger does not approve package publication", + ], + "retained_blockers": [ + "no package publication version is selected", + "no package tag is created", + "no package dependency manifest activation is approved", + "no registry-backed dependent package assembly activation is approved", + "public installation remains blocked", + "package publication remains blocked", + "real-version cargo publish remains blocked", + ], +} FORBIDDEN_PREP_WORDING = [ "public beta is approved", @@ -643,6 +697,38 @@ def test_package_publication_approval_request_packet_keeps_all_actions_blocked(s self.assertIn('name = "ethos-verify"', verify_manifest) self.assertIn('name = "ethos-pdf"', pdf_manifest) + def test_package_publication_pre_approval_gap_ledger_keeps_resolution_inputs_explicit(self) -> None: + ledger = load_json(PREP)["package_publication_pre_approval_gap_ledger"] + cargo = read(ROOT / "Cargo.toml") + 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") + + self.assertEqual(EXPECTED_PACKAGE_PUBLICATION_PRE_APPROVAL_GAP_LEDGER, ledger) + self.assertEqual("pre_approval_gaps_recorded_publication_blocked", ledger["ledger_state"]) + self.assertEqual(7, len(ledger["gap_rows"])) + self.assertEqual(8, len(ledger["blocked_actions"])) + self.assertIn("creating a package tag remains blocked", ledger["blocked_actions"]) + self.assertIn("changing Cargo manifests remains blocked", ledger["blocked_actions"]) + self.assertIn("inviting public installation remains blocked", ledger["blocked_actions"]) + self.assertIn( + "exact package_tag_source_commit and package source tree", + ledger["required_resolution_inputs"], + ) + self.assertIn( + "exact public installation wording and explicit exclusions", + ledger["required_resolution_inputs"], + ) + 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.assertIn('name = "ethos-core"', core_manifest) + self.assertIn('name = "ethos-verify"', verify_manifest) + self.assertIn('name = "ethos-pdf"', pdf_manifest) + self.assertIn('version = "0.1.0"', cargo) + def test_pdfium_boundary_keeps_ethos_pdf_held_until_confirmed(self) -> None: approved = load_json(PREP)["approved_package_publication_prep"] pdfium_boundary = " ".join(approved["pdfium_boundary"]) @@ -708,6 +794,10 @@ def test_schema_validation_covers_package_publication_prep(self) -> None: False, schema["$defs"]["package_publication_approval_request_packet"]["additionalProperties"], ) + self.assertEqual( + False, + schema["$defs"]["package_publication_pre_approval_gap_ledger"]["additionalProperties"], + ) self.assertEqual(9, schema["properties"]["required_evidence"]["minItems"]) self.assertEqual(13, schema["properties"]["explicit_blockers"]["minItems"]) self.assertEqual( @@ -746,6 +836,18 @@ def test_schema_validation_covers_package_publication_prep(self) -> None: "explicit_exclusions" ]["minItems"], ) + self.assertEqual( + 7, + schema["$defs"]["package_publication_pre_approval_gap_ledger"]["properties"][ + "gap_rows" + ]["minItems"], + ) + self.assertEqual( + 10, + schema["$defs"]["package_publication_pre_approval_gap_ledger"]["properties"][ + "required_resolution_inputs" + ]["minItems"], + ) self.assertIn("ethos-milestone-e-package-publication-approval-prep.schema.json", validate_examples) self.assertIn("docs\" / \"milestone-e-package-publication-approval-prep.json", validate_examples) self.assertIn("ethos-milestone-e-package-publication-approval-prep.schema.json", schemas_readme) 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 new file mode 100644 index 00000000..287f52c4 --- /dev/null +++ b/.github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py @@ -0,0 +1,173 @@ +#!/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 json +import re +import unittest +from pathlib import Path + +from makefile_guard import target_block + + +ROOT = Path(__file__).resolve().parents[2] +PREP = ROOT / "docs/milestone-e-package-publication-approval-prep.json" +RECORD = ( + ROOT + / "docs/validation/" + "milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md" +) +VALIDATION_README = ROOT / "docs/validation/README.md" +CI_WORKFLOW = ROOT / ".github/workflows/ci.yml" + +FORBIDDEN_SCOPE_EXPANSION = [ + "public reports are approved", + "public result wording approved", + "release-ready", + "release artifact approved", + "package-ready", + "package publication is approved", + "package publication approved", + "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 load_json(path: Path) -> dict: + return json.loads(path.read_text(encoding="utf-8")) + + +class MilestoneEPackagePublicationPreApprovalGapLedgerTests(unittest.TestCase): + def test_gap_ledger_record_is_indexed(self) -> None: + readme = read(VALIDATION_README) + normalized_readme = re.sub(r"\s+", " ", readme) + + self.assertIn(RECORD.name, readme) + self.assertIn( + "package publication pre-approval gap-ledger validation", + normalized_readme, + ) + + def test_record_names_validation_commands(self) -> None: + text = read(RECORD) + + self.assertIn("Validated source HEAD before this record: `c28704f`", text) + self.assertIn( + "python3 .github/scripts/test_milestone_e_package_publication_approval_prep.py", + text, + ) + self.assertIn( + "python3 .github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py", + text, + ) + self.assertIn("python3 .github/scripts/test_public_surface_posture.py", text) + self.assertIn("python3 .github/scripts/claims_gate.py", text) + self.assertIn("make milestone-e-prep PYTHON=/bin/python", text) + self.assertIn("git diff --check", text) + + def test_record_matches_gap_ledger_without_approving_actions(self) -> None: + prep = load_json(PREP) + ledger = prep["package_publication_pre_approval_gap_ledger"] + record = normalized(RECORD) + + self.assertEqual("pre_approval_gaps_recorded_publication_blocked", ledger["ledger_state"]) + self.assertIn(ledger["ledger_state"], record) + for row in ledger["gap_rows"]: + self.assertIn(row, record) + for action in ledger["blocked_actions"]: + self.assertIn(action, record) + for required in ledger["required_resolution_inputs"]: + self.assertIn(required, record) + for non_approval in ledger["non_approvals"]: + self.assertIn(non_approval, record) + for blocker in ledger["retained_blockers"]: + self.assertIn(blocker, record) + self.assertIn("Package publication remains blocked", record) + self.assertIn("Public installation remains blocked", record) + + def test_current_manifests_stay_non_publishable(self) -> None: + cargo = read(ROOT / "Cargo.toml") + 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") + + 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.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) + + def test_make_and_ci_run_gap_ledger_after_decision_bundle(self) -> None: + make_block = target_block("milestone-e-prep") + ci = read(CI_WORKFLOW) + bundle_guard = "test_milestone_e_package_publication_decision_bundle_validation_record.py" + gap_guard = "test_milestone_e_package_publication_pre_approval_gap_ledger.py" + command_guard = "test_milestone_e_validation_command_index.py" + + for text, prefix in ((make_block, "$(PYTHON) .github/scripts/"), (ci, "python3 .github/scripts/")): + self.assertIn(prefix + gap_guard, text) + self.assertEqual(1, text.count(prefix + gap_guard)) + self.assertLess(text.index(prefix + bundle_guard), text.index(prefix + gap_guard)) + self.assertLess(text.index(prefix + gap_guard), text.index(prefix + command_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 cb510cae..dcffcfe4 100644 --- a/.github/scripts/test_milestone_e_prep_guard_sequence_index.py +++ b/.github/scripts/test_milestone_e_prep_guard_sequence_index.py @@ -105,6 +105,7 @@ "$(PYTHON) .github/scripts/test_milestone_e_package_publication_manifest_activation_prep.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_decision_bundle_validation_record.py", + "$(PYTHON) .github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py", "$(PYTHON) .github/scripts/test_milestone_e_validation_command_index.py", "$(PYTHON) .github/scripts/test_milestone_e_validation_command_index_validation_record.py", "$(PYTHON) .github/scripts/test_milestone_e_validation_record_index.py", diff --git a/.github/scripts/test_milestone_e_prep_scope.py b/.github/scripts/test_milestone_e_prep_scope.py index 12281cc9..8c2632ce 100644 --- a/.github/scripts/test_milestone_e_prep_scope.py +++ b/.github/scripts/test_milestone_e_prep_scope.py @@ -404,6 +404,7 @@ def test_make_target_is_narrow_and_guarded(self) -> None: "$(PYTHON) .github/scripts/test_milestone_e_package_publication_manifest_activation_prep.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py", "$(PYTHON) .github/scripts/test_milestone_e_package_publication_decision_bundle_validation_record.py", + "$(PYTHON) .github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py", "$(PYTHON) .github/scripts/test_milestone_e_validation_command_index.py", "$(PYTHON) .github/scripts/test_milestone_e_validation_command_index_validation_record.py", "$(PYTHON) .github/scripts/test_milestone_e_validation_record_index.py", diff --git a/.github/scripts/test_milestone_e_validation_record_index.py b/.github/scripts/test_milestone_e_validation_record_index.py index 58aae6fd..9d8d894d 100644 --- a/.github/scripts/test_milestone_e_validation_record_index.py +++ b/.github/scripts/test_milestone_e_validation_record_index.py @@ -254,6 +254,10 @@ class RecordCoverage: "milestone-e-package-publication-decision-bundle-validation-2026-06-21.md", "test_milestone_e_package_publication_decision_bundle_validation_record.py", ), + RecordCoverage( + "milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md", + "test_milestone_e_package_publication_pre_approval_gap_ledger.py", + ), RecordCoverage( "milestone-e-validation-command-index-validation-2026-06-20.md", "test_milestone_e_validation_command_index_validation_record.py", @@ -352,6 +356,7 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: package_decision_bundle_guard = ( "test_milestone_e_package_publication_decision_bundle_validation_record.py" ) + package_gap_ledger_guard = "test_milestone_e_package_publication_pre_approval_gap_ledger.py" command_guard = "test_milestone_e_validation_command_index_validation_record.py" index_guard = "test_milestone_e_validation_record_index.py" index_record_guard = "test_milestone_e_validation_record_index_validation_record.py" @@ -404,8 +409,12 @@ def test_index_guards_run_after_row_and_schema_records(self) -> None: text.index(prefix + package_registry_activation_guard), text.index(prefix + package_decision_bundle_guard), ) - self.assertLess(text.index(prefix + package_decision_bundle_guard), text.index(prefix + command_guard)) - self.assertLess(text.index(prefix + package_decision_bundle_guard), text.index(prefix + index_guard)) + self.assertLess( + text.index(prefix + package_decision_bundle_guard), + text.index(prefix + package_gap_ledger_guard), + ) + self.assertLess(text.index(prefix + package_gap_ledger_guard), text.index(prefix + command_guard)) + self.assertLess(text.index(prefix + package_gap_ledger_guard), text.index(prefix + index_guard)) self.assertLess(text.index(prefix + package_manifest_activation_guard), text.index(prefix + command_guard)) self.assertLess(text.index(prefix + package_manifest_activation_guard), text.index(prefix + index_guard)) self.assertLess(text.index(prefix + package_tag_guard), text.index(prefix + command_guard)) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a59dadb7..bd7490d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -224,6 +224,8 @@ jobs: run: python3 .github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py - name: Milestone E package publication decision-bundle validation record tests run: python3 .github/scripts/test_milestone_e_package_publication_decision_bundle_validation_record.py + - name: Milestone E package publication pre-approval gap ledger tests + run: python3 .github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py - name: Milestone E validation-command index tests run: python3 .github/scripts/test_milestone_e_validation_command_index.py - name: Milestone E validation-command index validation record tests diff --git a/Makefile b/Makefile index 5ef8211e..c2758f50 100644 --- a/Makefile +++ b/Makefile @@ -219,6 +219,7 @@ milestone-e-prep: $(PYTHON) .github/scripts/test_milestone_e_package_publication_manifest_activation_prep.py $(PYTHON) .github/scripts/test_milestone_e_package_publication_registry_assembly_activation_prep.py $(PYTHON) .github/scripts/test_milestone_e_package_publication_decision_bundle_validation_record.py + $(PYTHON) .github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py $(PYTHON) .github/scripts/test_milestone_e_validation_command_index.py $(PYTHON) .github/scripts/test_milestone_e_validation_command_index_validation_record.py $(PYTHON) .github/scripts/test_milestone_e_validation_record_index.py diff --git a/docs/milestone-e-package-publication-approval-prep.json b/docs/milestone-e-package-publication-approval-prep.json index 6709ed67..306762c5 100644 --- a/docs/milestone-e-package-publication-approval-prep.json +++ b/docs/milestone-e-package-publication-approval-prep.json @@ -78,7 +78,8 @@ "package_registry_assembly_activation_prep": "docs/validation/milestone-e-package-publication-registry-assembly-activation-prep-validation-2026-06-21.md", "package_real_version_selection_prep": "docs/validation/milestone-e-package-publication-real-version-selection-prep-validation-2026-06-21.md", "package_tag_creation_prep": "docs/validation/milestone-e-package-publication-tag-creation-prep-validation-2026-06-21.md", - "package_decision_bundle_validation": "docs/validation/milestone-e-package-publication-decision-bundle-validation-2026-06-21.md" + "package_decision_bundle_validation": "docs/validation/milestone-e-package-publication-decision-bundle-validation-2026-06-21.md", + "package_pre_approval_gap_ledger": "docs/validation/milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md" }, "publication_approval_decision_inputs": { "decision_status": "not_approved_pending_exact_decision", @@ -260,6 +261,59 @@ "real-version cargo publish remains blocked" ] }, + "package_publication_pre_approval_gap_ledger": { + "ledger_state": "pre_approval_gaps_recorded_publication_blocked", + "gap_rows": [ + "version map gap: no package publication version is selected; requires exact SemVer package version or per-crate version map", + "tag name gap: no package tag is created; requires exact package tag name", + "tag binding gap: no package_tag_source_commit or source tree is selected; requires exact source commit and tree binding", + "manifest activation gap: current Cargo manifests remain unchanged; requires exact package-name migration and dependency activation diff", + "registry assembly gap: no registry-backed dependent package assembly is activated; requires exact non-public assembly evidence", + "public installation wording gap: no public installation wording is approved; requires exact wording and exclusions", + "posture and claims gate gap: gates must rerun after exact public installation wording changes" + ], + "blocked_actions": [ + "selecting a package publication version remains blocked", + "creating a package tag remains blocked", + "changing Cargo manifests remains blocked", + "activating package dependency manifests remains blocked", + "creating a registry remains blocked", + "activating registry-backed dependent package assembly remains blocked", + "inviting public installation remains blocked", + "approving package publication remains blocked" + ], + "required_resolution_inputs": [ + "exact package publication approval decision record", + "exact candidate crate list", + "exact SemVer package version or per-crate version map", + "exact package tag name", + "exact package_tag_source_commit and package source tree", + "exact package-name migration diff for ethos-doc-core", + "exact dependency manifest activation diff for ethos-verify and ethos-pdf", + "exact registry-backed dependent package assembly evidence", + "exact public installation wording and explicit exclusions", + "posture and claims gates after exact public installation wording changes" + ], + "non_approvals": [ + "this ledger does not select a package publication version", + "this ledger does not create a package tag", + "this ledger does not change Cargo manifests", + "this ledger does not activate package dependency manifests", + "this ledger does not create a registry", + "this ledger does not activate registry-backed dependent package assembly", + "this ledger does not invite public installation", + "this ledger does not approve package publication" + ], + "retained_blockers": [ + "no package publication version is selected", + "no package tag is created", + "no package dependency manifest activation is approved", + "no registry-backed dependent package assembly activation is approved", + "public installation remains blocked", + "package publication remains blocked", + "real-version cargo publish remains blocked" + ] + }, "public_boundary": [ "public reports remain blocked", "release artifacts remain blocked", diff --git a/docs/validation/README.md b/docs/validation/README.md index b9baddd9..3af8dfc1 100644 --- a/docs/validation/README.md +++ b/docs/validation/README.md @@ -319,6 +319,11 @@ inventory, metadata/readiness, dry-run planning, version/tag policy, and PDFium package publication and public installation blocked while recording that no package publication version is selected, no package tag is created, no Cargo manifest is changed, no registry is created, no registry-backed assembly is activated, and no public installation is invited. +- `milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md` - package + publication pre-approval gap-ledger validation for the unresolved package publication approval + inputs; the record keeps package publication and public installation blocked while recording the + missing version map, package tag, source binding, manifest activation diff, registry-backed + assembly evidence, public installation wording, and posture/claims rerun requirements. - `milestone-e-validation-command-index-validation-2026-06-20.md` - internal Milestone E validation-command index validation passed through command-alignment checks, schema enum checks, row-record checks, public-surface posture checks, `make milestone-e-prep`, and diff hygiene; the diff --git a/docs/validation/milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md b/docs/validation/milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md new file mode 100644 index 00000000..77bed9cd --- /dev/null +++ b/docs/validation/milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md @@ -0,0 +1,122 @@ +# Milestone E Package Publication Pre-Approval Gap-Ledger Validation - 2026-06-21 + +## Purpose + +Record the package publication pre-approval gap ledger without approving package publication. + +This record consolidates the unresolved package publication approval inputs from the current +decision-prep bundle and approval request packet. It does not select a package publication version, +create a package tag, bind a package tag to a source commit or source tree, change Cargo manifests, +activate package dependency manifests, create a registry, activate registry-backed dependent +package assembly, invite public installation, approve package publication, publish binaries, +publish wheels, publish npm packages, approve hosted surfaces, approve production positioning, +approve public benchmark reports, approve public benchmark claims, or approve public result +wording. + +## Status + +Status: **pass for package publication pre-approval gap-ledger validation with publication +blocked**. + +Ethos remains source-only pre-alpha outside the approved source-only public beta surface and +internal package publication prep boundary. + +Package publication remains blocked. + +Public installation remains blocked. + +## Subject + +- Repository: `docushell/ethos` +- Validated source HEAD before this record: `c28704f` +- Lane: package publication pre-approval gap ledger +- Evidence area: unresolved package publication approval inputs and retained blockers + +## Gap Ledger + +- ledger state: `pre_approval_gaps_recorded_publication_blocked` +- version map gap: no package publication version is selected; requires exact SemVer package + version or per-crate version map +- tag name gap: no package tag is created; requires exact package tag name +- tag binding gap: no package_tag_source_commit or source tree is selected; requires exact source + commit and tree binding +- manifest activation gap: current Cargo manifests remain unchanged; requires exact package-name + migration and dependency activation diff +- registry assembly gap: no registry-backed dependent package assembly is activated; requires exact + non-public assembly evidence +- public installation wording gap: no public installation wording is approved; requires exact + wording and exclusions +- posture and claims gate gap: gates must rerun after exact public installation wording changes + +## Blocked Actions + +- selecting a package publication version remains blocked +- creating a package tag remains blocked +- changing Cargo manifests remains blocked +- activating package dependency manifests remains blocked +- creating a registry remains blocked +- activating registry-backed dependent package assembly remains blocked +- inviting public installation remains blocked +- approving package publication remains blocked + +## Required Resolution Inputs + +- exact package publication approval decision record +- exact candidate crate list +- exact SemVer package version or per-crate version map +- exact package tag name +- exact package_tag_source_commit and package source tree +- exact package-name migration diff for ethos-doc-core +- exact dependency manifest activation diff for ethos-verify and ethos-pdf +- exact registry-backed dependent package assembly evidence +- exact public installation wording and explicit exclusions +- posture and claims gates after exact public installation wording changes + +## Non-Approvals Retained + +- this ledger does not select a package publication version +- this ledger does not create a package tag +- this ledger does not change Cargo manifests +- this ledger does not activate package dependency manifests +- this ledger does not create a registry +- this ledger does not activate registry-backed dependent package assembly +- this ledger does not invite public installation +- this ledger does not approve package publication + +## Blockers Retained + +- no package publication version is selected +- no package tag is created +- no package dependency manifest activation is approved +- no registry-backed dependent package assembly activation is approved +- public installation remains blocked +- package publication remains blocked +- real-version cargo publish remains blocked + +## Commands + +```sh +python3 .github/scripts/test_milestone_e_package_publication_approval_prep.py +python3 .github/scripts/test_milestone_e_package_publication_pre_approval_gap_ledger.py +python3 .github/scripts/test_public_surface_posture.py +python3 .github/scripts/claims_gate.py +make milestone-e-prep PYTHON=/bin/python +git diff --check +``` + +## Explicit Boundaries + +- Public reports remain blocked. +- Public result wording remains blocked. +- Package publication remains blocked. +- Public installation remains blocked. +- Real-version cargo publish remains blocked. +- Release artifacts remain blocked. +- Binaries remain blocked. +- Wheels remain blocked. +- Npm packages 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. diff --git a/schemas/ethos-milestone-e-package-publication-approval-prep.schema.json b/schemas/ethos-milestone-e-package-publication-approval-prep.schema.json index 1db1fed4..536e5686 100644 --- a/schemas/ethos-milestone-e-package-publication-approval-prep.schema.json +++ b/schemas/ethos-milestone-e-package-publication-approval-prep.schema.json @@ -25,6 +25,7 @@ "semver_package_version_decision_prep", "package_publication_decision_prep_bundle", "package_publication_approval_request_packet", + "package_publication_pre_approval_gap_ledger", "public_boundary", "approval_scope", "required_evidence", @@ -72,6 +73,9 @@ "package_publication_approval_request_packet": { "$ref": "#/$defs/package_publication_approval_request_packet" }, + "package_publication_pre_approval_gap_ledger": { + "$ref": "#/$defs/package_publication_pre_approval_gap_ledger" + }, "public_boundary": { "type": "array", "minItems": 10, @@ -278,7 +282,8 @@ "package_registry_assembly_activation_prep", "package_real_version_selection_prep", "package_tag_creation_prep", - "package_decision_bundle_validation" + "package_decision_bundle_validation", + "package_pre_approval_gap_ledger" ], "additionalProperties": false, "properties": { @@ -317,6 +322,9 @@ }, "package_decision_bundle_validation": { "const": "docs/validation/milestone-e-package-publication-decision-bundle-validation-2026-06-21.md" + }, + "package_pre_approval_gap_ledger": { + "const": "docs/validation/milestone-e-package-publication-pre-approval-gap-ledger-validation-2026-06-21.md" } } }, @@ -560,6 +568,56 @@ } } }, + "package_publication_pre_approval_gap_ledger": { + "type": "object", + "required": [ + "ledger_state", + "gap_rows", + "blocked_actions", + "required_resolution_inputs", + "non_approvals", + "retained_blockers" + ], + "additionalProperties": false, + "properties": { + "ledger_state": { "const": "pre_approval_gaps_recorded_publication_blocked" }, + "gap_rows": { + "type": "array", + "minItems": 7, + "maxItems": 7, + "items": { "$ref": "#/$defs/pre_approval_gap_row" }, + "uniqueItems": true + }, + "blocked_actions": { + "type": "array", + "minItems": 8, + "maxItems": 8, + "items": { "$ref": "#/$defs/pre_approval_blocked_action" }, + "uniqueItems": true + }, + "required_resolution_inputs": { + "type": "array", + "minItems": 10, + "maxItems": 10, + "items": { "$ref": "#/$defs/pre_approval_required_resolution_input" }, + "uniqueItems": true + }, + "non_approvals": { + "type": "array", + "minItems": 8, + "maxItems": 8, + "items": { "$ref": "#/$defs/pre_approval_non_approval" }, + "uniqueItems": true + }, + "retained_blockers": { + "type": "array", + "minItems": 7, + "maxItems": 7, + "items": { "$ref": "#/$defs/packet_retained_blocker" }, + "uniqueItems": true + } + } + }, "reserved_identifier": { "enum": [ "ethos-doc-core", @@ -770,6 +828,55 @@ "real-version cargo publish remains blocked" ] }, + "pre_approval_gap_row": { + "enum": [ + "version map gap: no package publication version is selected; requires exact SemVer package version or per-crate version map", + "tag name gap: no package tag is created; requires exact package tag name", + "tag binding gap: no package_tag_source_commit or source tree is selected; requires exact source commit and tree binding", + "manifest activation gap: current Cargo manifests remain unchanged; requires exact package-name migration and dependency activation diff", + "registry assembly gap: no registry-backed dependent package assembly is activated; requires exact non-public assembly evidence", + "public installation wording gap: no public installation wording is approved; requires exact wording and exclusions", + "posture and claims gate gap: gates must rerun after exact public installation wording changes" + ] + }, + "pre_approval_blocked_action": { + "enum": [ + "selecting a package publication version remains blocked", + "creating a package tag remains blocked", + "changing Cargo manifests remains blocked", + "activating package dependency manifests remains blocked", + "creating a registry remains blocked", + "activating registry-backed dependent package assembly remains blocked", + "inviting public installation remains blocked", + "approving package publication remains blocked" + ] + }, + "pre_approval_required_resolution_input": { + "enum": [ + "exact package publication approval decision record", + "exact candidate crate list", + "exact SemVer package version or per-crate version map", + "exact package tag name", + "exact package_tag_source_commit and package source tree", + "exact package-name migration diff for ethos-doc-core", + "exact dependency manifest activation diff for ethos-verify and ethos-pdf", + "exact registry-backed dependent package assembly evidence", + "exact public installation wording and explicit exclusions", + "posture and claims gates after exact public installation wording changes" + ] + }, + "pre_approval_non_approval": { + "enum": [ + "this ledger does not select a package publication version", + "this ledger does not create a package tag", + "this ledger does not change Cargo manifests", + "this ledger does not activate package dependency manifests", + "this ledger does not create a registry", + "this ledger does not activate registry-backed dependent package assembly", + "this ledger does not invite public installation", + "this ledger does not approve package publication" + ] + }, "in_tree_reconciliation": { "enum": [ "ethos-doc-core maps to the in-tree ethos-core crate before any future publish prep can advance",