diff --git a/.github/scripts/test_patch_0_1_2_package_tag_approval_decision.py b/.github/scripts/test_patch_0_1_2_package_tag_approval_decision.py new file mode 100644 index 0000000..b466fc5 --- /dev/null +++ b/.github/scripts/test_patch_0_1_2_package_tag_approval_decision.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# +# Copyright 2026 The Ethos maintainers +# +# Licensed under the Apache License, Version 2.0 (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/patch-0-1-2-package-tag-approval-decision-validation-2026-06-25.md" +REQUEST = ROOT / "docs/validation/patch-0-1-2-package-tag-approval-request-validation-2026-06-25.md" +VALIDATION_README = ROOT / "docs/validation/README.md" +EXECUTION_STATUS = ROOT / "docs/execution-status.md" +PUBLIC_RELEASE_CHECKLIST = ROOT / "docs/public-release-checklist.md" +MAKEFILE = ROOT / "Makefile" + +SOURCE_SHORT = "070a5c5" +SOURCE_COMMIT = "070a5c54afe780f95fc6fbe4598558107949695c" +SOURCE_TREE = "93e025c44993c18a42203b7b999d9dd5af94e709" +PACKAGE_SOURCE_COMMIT = "3bc3564e38c1168b2db72f38863d324b6b57bd4d" +PACKAGE_SOURCE_TREE = "eda8c7a605a4eb29c155ae3b9e6e9f0c35798f8c" +TAGS = ( + "ethos-package-ethos-doc-core-0.1.2", + "ethos-package-ethos-verify-0.1.2", + "ethos-package-ethos-pdf-0.1.2", +) +TAG_COMMANDS = ( + f"git tag -a {TAGS[0]} {PACKAGE_SOURCE_COMMIT}", + f"git tag -a {TAGS[1]} {PACKAGE_SOURCE_COMMIT}", + f"git tag -a {TAGS[2]} {PACKAGE_SOURCE_COMMIT}", +) +PUSH_COMMANDS = tuple(f"git push origin refs/tags/{tag}" for tag in TAGS) +FORBIDDEN = ( + "package tags are created by this record", + "tags are pushed by this record", + "hosted surfaces approved", + "production-ready", + "windows packaged artifacts approved", + "bundled pdfium approved", + "ethos-doc approved", + "ethos-rag approved", + "public benchmark claims approved", +) + + +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 Patch012PackageTagApprovalDecisionTests(unittest.TestCase): + def test_record_is_source_bound_and_indexed(self) -> None: + record = normalized(RECORD) + readme = normalized(VALIDATION_README) + + self.assertIn(RECORD.name, readme) + self.assertIn("patch 0.1.2 package tag approval decision", readme.lower()) + self.assertIn(f"Validated source HEAD before this record: `{SOURCE_SHORT}`", read(RECORD)) + self.assertIn(f"Patch 0.1.2 package tag approval decision source commit: `{SOURCE_COMMIT}`", record) + self.assertIn(f"Patch 0.1.2 package tag approval decision 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_decision_accepts_exact_request_packet(self) -> None: + record = normalized(RECORD) + + self.assertIn(REQUEST.name, record) + self.assertIn("Decision: accept exact patch `0.1.2` package tag creation decision packet.", record) + self.assertIn("Decider approval supplied: Yes, I Approve exact patch 0.1.2.", record) + self.assertIn(f"Package tag source commit accepted by this decision: `{PACKAGE_SOURCE_COMMIT}`", record) + self.assertIn(f"Package tag source tree accepted by this decision: `{PACKAGE_SOURCE_TREE}`", record) + self.assertEqual(PACKAGE_SOURCE_TREE, git("rev-parse", f"{PACKAGE_SOURCE_COMMIT}^{{tree}}")) + for tag in TAGS: + self.assertIn(tag, record) + for command in TAG_COMMANDS + PUSH_COMMANDS: + self.assertIn(command, record) + + def test_decision_authorizes_only_later_operator_tag_creation(self) -> None: + raw = read(RECORD) + record = normalized(RECORD) + lower = record.lower() + + for expected in ( + "This decision record does not create package tags.", + "This decision record does not push package tags.", + "Package tag creation remains a separate operator action after this decision is merged and validation passes on merged source.", + "After this decision record is merged and validation passes on merged source, an operator may run only these tag commands:", + "The operator must use annotated tags.", + "The operator must stop if any requested tag already exists locally or on `origin`,", + "Public beta evaluation surfaces remain unchanged.", + "Hosted surfaces remain blocked.", + "Production positioning remains blocked.", + "Windows packaged artifacts remain blocked.", + "Bundled project-maintained PDFium builds remain blocked.", + "`ethos-doc` remains blocked.", + "`ethos-rag` remains blocked.", + "Public benchmark claims remain blocked.", + ): + self.assertIn(expected, record) + for forbidden in FORBIDDEN: + self.assertNotIn(forbidden, lower) + self.assertNotIn("/Users/", raw) + self.assertNotIn("/private/tmp", raw) + self.assertNotIn("/private/var", raw) + self.assertNotIn("/var/folders", raw) + self.assertNotIn("saumildiwaker", raw) + + def test_status_docs_reference_decision_and_keep_operator_action_pending(self) -> None: + for path in (EXECUTION_STATUS, PUBLIC_RELEASE_CHECKLIST): + text = normalized(path) + self.assertIn(RECORD.name, text, str(path)) + self.assertIn("Package tag creation remains a separate operator action", text, str(path)) + self.assertIn("hosted", text.lower(), str(path)) + self.assertIn("production", text.lower(), str(path)) + + def test_release_candidate_prep_runs_after_request_before_artifact_checks(self) -> None: + makefile = read(MAKEFILE) + request_guard = "$(PYTHON) .github/scripts/test_patch_0_1_2_package_tag_approval_request.py" + decision_guard = "$(PYTHON) .github/scripts/test_patch_0_1_2_package_tag_approval_decision.py" + first_public_guard = "$(PYTHON) .github/scripts/test_first_public_release_artifact_evidence.py" + block = target_block("release-candidate-prep") + + self.assertIn(decision_guard, block) + self.assertEqual(1, makefile.count(decision_guard)) + self.assertLess(block.index(request_guard), block.index(decision_guard)) + self.assertLess(block.index(decision_guard), block.index(first_public_guard)) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/scripts/test_release_candidate_prep.py b/.github/scripts/test_release_candidate_prep.py index 8353938..2a9a9ca 100644 --- a/.github/scripts/test_release_candidate_prep.py +++ b/.github/scripts/test_release_candidate_prep.py @@ -78,6 +78,7 @@ "$(PYTHON) .github/scripts/test_patch_0_1_2_python_publication_closeout.py", "$(PYTHON) .github/scripts/test_patch_0_1_2_python_public_install_wording_closeout.py", "$(PYTHON) .github/scripts/test_patch_0_1_2_package_tag_approval_request.py", + "$(PYTHON) .github/scripts/test_patch_0_1_2_package_tag_approval_decision.py", "$(PYTHON) .github/scripts/test_first_public_release_artifact_evidence.py", "$(PYTHON) .github/scripts/test_first_public_release_final_decider.py", "$(PYTHON) .github/scripts/test_first_public_release_linux_x64_artifact_evidence.py", diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c12d4f..f3b3976 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- boundary-exception: record decider approval for exact patch `0.1.2` package tag creation while keeping actual tag creation as a later operator action and retaining hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` blockers. - boundary-exception: request decider review for exact patch `0.1.2` package tag creation while keeping tag creation, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces blocked pending a separate approval decision. - boundary-exception: close patch `0.1.2` Python public install wording for published PyPI wheel `ethos-pdf==0.1.2` while keeping package tag creation, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces blocked. - boundary-exception: close patch `0.1.2` Python PyPI publication with exact registry evidence for `ethos-pdf==0.1.2` while keeping Python public install wording, package tag creation, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces blocked. diff --git a/Makefile b/Makefile index 8378808..cfe092b 100644 --- a/Makefile +++ b/Makefile @@ -329,6 +329,7 @@ release-candidate-prep: $(PYTHON) .github/scripts/test_patch_0_1_2_python_publication_closeout.py $(PYTHON) .github/scripts/test_patch_0_1_2_python_public_install_wording_closeout.py $(PYTHON) .github/scripts/test_patch_0_1_2_package_tag_approval_request.py + $(PYTHON) .github/scripts/test_patch_0_1_2_package_tag_approval_decision.py $(PYTHON) .github/scripts/test_first_public_release_artifact_evidence.py $(PYTHON) .github/scripts/test_first_public_release_final_decider.py $(PYTHON) .github/scripts/test_first_public_release_linux_x64_artifact_evidence.py diff --git a/docs/execution-status.md b/docs/execution-status.md index 4cba1f6..3a4f37e 100644 --- a/docs/execution-status.md +++ b/docs/execution-status.md @@ -112,6 +112,14 @@ decision is recorded, and hosted surfaces, production positioning, Windows packa bundled project-maintained PDFium builds, `ethos-doc`, `ethos-rag`, and public benchmark claims remain blocked. +Patch `0.1.2` package tag approval decision is recorded in +`docs/validation/patch-0-1-2-package-tag-approval-decision-validation-2026-06-25.md`. It accepts +the exact package tag names, source commit, source tree, and later operator commands. Package tag +creation remains a separate operator action after this decision is merged and validation passes on +merged source, and hosted surfaces, production positioning, Windows packaged artifacts, bundled +project-maintained PDFium builds, `ethos-doc`, `ethos-rag`, and public benchmark claims remain +blocked. + Public approval lane blocker prep is recorded in `docs/milestone-e-public-approval-lane-blockers.json` and schema-bound by `schemas/ethos-milestone-e-public-approval-lane-blockers.schema.json`. This public approval lane diff --git a/docs/public-release-checklist.md b/docs/public-release-checklist.md index a1f7cd2..b36a744 100644 --- a/docs/public-release-checklist.md +++ b/docs/public-release-checklist.md @@ -193,6 +193,14 @@ decision is recorded; hosted surfaces, production positioning, Windows packaged project-maintained PDFium builds, `ethos-doc`, `ethos-rag`, and public benchmark claims remain blocked. +Patch `0.1.2` package tag approval decision is recorded in +`docs/validation/patch-0-1-2-package-tag-approval-decision-validation-2026-06-25.md`. It accepts +the exact package tag names, source commit, source tree, and later operator commands. Package tag +creation remains a separate operator action after this decision is merged and validation passes on +merged source; hosted surfaces, production positioning, Windows packaged artifacts, bundled +project-maintained PDFium builds, `ethos-doc`, `ethos-rag`, and public benchmark claims remain +blocked. + ## Required Before Public Push - Package-name and trademark decision is closed by accepted ADR-0006 in diff --git a/docs/validation/README.md b/docs/validation/README.md index 6f23fd6..127cf27 100644 --- a/docs/validation/README.md +++ b/docs/validation/README.md @@ -765,6 +765,11 @@ recording the exact current-main source candidate and required follow-up evidenc tree, and requested later operator commands for decider review; package tag creation, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces remain blocked until a separate approval decision passes. +- `patch-0-1-2-package-tag-approval-decision-validation-2026-06-25.md` - patch 0.1.2 + package tag approval decision validation accepts the exact package tag names, source commit, + source tree, and later operator commands; package tag creation remains a separate operator + action, and hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` + surfaces remain blocked until separate approval or closeout records pass. - `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/patch-0-1-2-package-tag-approval-decision-validation-2026-06-25.md b/docs/validation/patch-0-1-2-package-tag-approval-decision-validation-2026-06-25.md new file mode 100644 index 0000000..c12bc29 --- /dev/null +++ b/docs/validation/patch-0-1-2-package-tag-approval-decision-validation-2026-06-25.md @@ -0,0 +1,134 @@ +# Patch 0.1.2 Package Tag Approval Decision Validation - 2026-06-25 + +Validated source HEAD before this record: `070a5c5`. + +Patch 0.1.2 package tag approval decision source commit: `070a5c54afe780f95fc6fbe4598558107949695c`. + +Patch 0.1.2 package tag approval decision source tree: `93e025c44993c18a42203b7b999d9dd5af94e709`. + +Status: **patch 0.1.2 package tag approval decision recorded; operator tag creation remains pending** + +This record accepts the exact patch `0.1.2` package tag creation request after decider approval. It +approves only bounded later operator creation and push of the three exact annotated package tags +listed below. It does not create package tags, push package tags, move any existing tag, change +package contents, change public wording, approve hosted surfaces, approve production positioning, +approve Windows packaged artifacts, approve bundled project-maintained PDFium builds, approve +`ethos-doc`, approve `ethos-rag`, or approve public benchmark reports or claims. + +## Subject + +- Repository: `docushell/ethos` +- Lane: patch `0.1.2` package tag creation approval decision +- Approval owner: `docushell-admin` +- Approval request record: + `docs/validation/patch-0-1-2-package-tag-approval-request-validation-2026-06-25.md` +- Package tag source commit accepted by this decision: `3bc3564e38c1168b2db72f38863d324b6b57bd4d` +- Package tag source tree accepted by this decision: `eda8c7a605a4eb29c155ae3b9e6e9f0c35798f8c` + +## Exact Decision Fields + +- Decision: accept exact patch `0.1.2` package tag creation decision packet. +- Decider approval supplied: Yes, I Approve exact patch 0.1.2. +- Approver: `docushell-admin` acting as decider. +- Date: 2026-06-25. +- Exact package tag name set accepted by this decision: + - `ethos-package-ethos-doc-core-0.1.2` + - `ethos-package-ethos-verify-0.1.2` + - `ethos-package-ethos-pdf-0.1.2` +- Exact package tag source commit accepted by this decision: + `3bc3564e38c1168b2db72f38863d324b6b57bd4d`. +- Exact package tag source tree accepted by this decision: + `eda8c7a605a4eb29c155ae3b9e6e9f0c35798f8c`. + +## Approved Later Operator Action + +After this decision record is merged and validation passes on merged source, an operator may run +only these tag commands: + +```sh +git tag -a ethos-package-ethos-doc-core-0.1.2 3bc3564e38c1168b2db72f38863d324b6b57bd4d +git tag -a ethos-package-ethos-verify-0.1.2 3bc3564e38c1168b2db72f38863d324b6b57bd4d +git tag -a ethos-package-ethos-pdf-0.1.2 3bc3564e38c1168b2db72f38863d324b6b57bd4d +git push origin refs/tags/ethos-package-ethos-doc-core-0.1.2 +git push origin refs/tags/ethos-package-ethos-verify-0.1.2 +git push origin refs/tags/ethos-package-ethos-pdf-0.1.2 +``` + +The operator must use annotated tags. The operator must stop if any requested tag already exists +locally or on `origin`, if the requested source commit or tree does not match this record, or if +any retained blocker is softened. + +Package tag creation remains a separate operator action after this decision is merged and validation +passes on merged source. This decision record does not create or push any tag. + +## Required Operator Pre-Tag Checks + +Before creating tags, the operator must run: + +```sh +python3 .github/scripts/test_patch_0_1_2_package_tag_approval_decision.py +python3 .github/scripts/test_patch_0_1_2_package_tag_approval_request.py +python3 .github/scripts/test_patch_0_1_2_python_public_install_wording_closeout.py +make release-candidate-prep PYTHON=python3 +git diff --check +``` + +## Evidence Bound To This Decision + +- Decider decision supplied: Yes, I Approve exact patch 0.1.2. +- The package tag approval request recorded the exact tag names and source binding. +- The requested source commit resolves to the requested source tree. +- The crates.io publication closeout records `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` + published at `0.1.2`. +- The current public README and public package installation wording already point all approved + evaluation install surfaces to `0.1.2`. +- Public beta evaluation surfaces remain unchanged. + +## Non-Actions + +- This decision record does not create package tags. +- This decision record does not push package tags. +- This decision record does not move or delete any tag. +- This decision record does not change package contents. +- This decision record does not change public installation wording. +- This decision record does not approve hosted surfaces. +- This decision record does not approve production positioning. +- This decision record does not approve Windows packaged artifacts. +- This decision record does not approve bundled project-maintained PDFium builds. +- This decision record does not approve public benchmark reports. +- This decision record does not approve public benchmark claims. +- This decision record does not approve `ethos-doc`. +- This decision record does not approve `ethos-rag`. + +## Retained Blockers + +- Package tag creation remains a separate operator action after this decision is merged and + validation passes on merged source. +- Hosted surfaces remain blocked. +- Production positioning remains blocked. +- Windows packaged artifacts remain blocked. +- Bundled project-maintained PDFium builds remain blocked. +- Public benchmark reports remain blocked. +- Public benchmark claims remain blocked. +- `ethos-doc` remains blocked. +- `ethos-rag` remains blocked. +- PDFium remains caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`. + +## Commands + +```sh +python3 .github/scripts/test_patch_0_1_2_package_tag_approval_decision.py +python3 .github/scripts/test_patch_0_1_2_package_tag_approval_request.py +python3 .github/scripts/test_patch_0_1_2_crates_publication_closeout.py +python3 .github/scripts/test_patch_0_1_2_python_public_install_wording_closeout.py +make release-candidate-prep PYTHON=python3 +git diff --check +``` + +## Result + +```text +patch 0.1.2 package tag approval decision recorded +Exact package tag names and source binding are accepted for later operator action +No package tags are created or pushed by this record +```