Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#!/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-python-publication-approval-request-validation-2026-06-25.md"
VALIDATION_README = ROOT / "docs/validation/README.md"
PYPROJECT = ROOT / "pyproject.toml"
INIT = ROOT / "python/ethos_pdf/__init__.py"
MAKEFILE = ROOT / "Makefile"

SOURCE_SHORT = "e431982"
SOURCE_COMMIT = "e431982cca2922d4cc59ddc7cacb9e72538b1cd0"
SOURCE_TREE = "f59ddd018d234eeee0ac77292b417f4acb892b4e"
PACKAGE = "ethos-pdf==0.1.2"
WHEEL = "ethos_pdf-0.1.2-py3-none-any.whl"
DETERMINISTIC_SHA256 = "6f17240954f1257ece3c762c820ad771ccb114353bfb699fe87f418a5ceb663c"
WHEEL_FILES = (
"ethos_pdf/__init__.py",
"ethos_pdf/_cli.py",
"ethos_pdf-0.1.2.dist-info/METADATA",
"ethos_pdf-0.1.2.dist-info/RECORD",
"ethos_pdf-0.1.2.dist-info/WHEEL",
"ethos_pdf-0.1.2.dist-info/licenses/LICENSE",
"ethos_pdf-0.1.2.dist-info/licenses/NOTICE",
"ethos_pdf-0.1.2.dist-info/top_level.txt",
)
FORBIDDEN = (
"pypi upload approved",
"pypi publication approved",
"python package is published",
"wheel is published",
"twine upload approved",
"python installation wording approved",
"production-ready",
"hosted surfaces approved",
"windows packaged artifacts approved",
"bundled pdfium approved",
"ethos-doc approved",
"ethos-rag 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 Patch012PythonPublicationApprovalRequestTests(unittest.TestCase):
def test_request_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 Python PyPI publication approval request", readme)
self.assertIn(f"Validated source HEAD before this record: `{SOURCE_SHORT}`", read(RECORD))
self.assertIn(f"Patch 0.1.2 Python publication approval request source commit: `{SOURCE_COMMIT}`", record)
self.assertIn(f"Patch 0.1.2 Python publication approval 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_deterministic_wheel_candidate_and_metadata(self) -> None:
record = normalized(RECORD)

for expected in (
PACKAGE,
WHEEL,
DETERMINISTIC_SHA256,
"SOURCE_DATE_EPOCH=0",
"Name: `ethos-pdf`",
"Version: `0.1.2`",
"License-Expression: `Apache-2.0`",
"Requires-Python: `>=3.8`",
"Wheel-Version: `1.0`",
"Root-Is-Purelib: `true`",
"Tag: `py3-none-any`",
"member timestamps: `1980-01-01 00:00:00`",
"version `0.1.2`",
"EthosCli",
"EthosCommandError",
"Python `3.9.6`",
"build `1.4.4`",
):
self.assertIn(expected, record)
for wheel_file in WHEEL_FILES:
self.assertIn(wheel_file, record)

def test_request_requires_decision_and_keeps_upload_blocked(self) -> None:
raw = read(RECORD)
record = normalized(RECORD)
lower = record.lower()

for expected in (
"Manual action is required before any PyPI upload.",
"A decider must accept or reject this exact deterministic request packet.",
"This request record does not approve PyPI upload.",
"This request record does not upload any Python distribution.",
"This request record does not approve the deterministic wheel hash.",
"Actual PyPI upload remains blocked pending explicit decider approval.",
"Python public installation wording remains blocked pending PyPI availability closeout.",
"PDFium remains caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`.",
):
self.assertIn(expected, record)
for forbidden in FORBIDDEN:
self.assertNotIn(forbidden, lower)
for private in (
"/" + "Users/",
"/" + "tmp",
"/" + "private/tmp",
"/" + "private/var",
"/" + "var/folders",
"saumil" + "diwaker",
"Desktop/" + "Stuff",
"project/repo/" + "ethos",
):
self.assertNotIn(private, raw)

def test_source_metadata_keeps_current_python_surface_shape(self) -> None:
pyproject = read(PYPROJECT)
init = read(INIT)

self.assertIn('name = "ethos-pdf"', pyproject)
self.assertIn('version = "0.1.2"', pyproject)
self.assertIn('requires-python = ">=3.8"', pyproject)
self.assertIn('license = "Apache-2.0"', pyproject)
self.assertIn('readme = "python/README.md"', pyproject)
self.assertIn('__version__ = "0.1.2"', init)
self.assertIn('"EthosCli"', init)
self.assertIn('"EthosCommandError"', init)

def test_release_candidate_prep_runs_request_guard_after_rust_wording(self) -> None:
makefile = read(MAKEFILE)
rust_wording_guard = "$(PYTHON) .github/scripts/test_patch_0_1_2_rust_public_install_wording_closeout.py"
guard = "$(PYTHON) .github/scripts/test_patch_0_1_2_python_publication_approval_request.py"
first_public_guard = "$(PYTHON) .github/scripts/test_first_public_release_artifact_evidence.py"
block = target_block("release-candidate-prep")

self.assertIn(guard, block)
self.assertEqual(1, makefile.count(guard))
self.assertLess(block.index(rust_wording_guard), block.index(guard))
self.assertLess(block.index(guard), block.index(first_public_guard))


if __name__ == "__main__":
unittest.main()
1 change: 1 addition & 0 deletions .github/scripts/test_release_candidate_prep.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"$(PYTHON) .github/scripts/test_patch_0_1_2_crates_publication_approval_decision.py",
"$(PYTHON) .github/scripts/test_patch_0_1_2_crates_publication_closeout.py",
"$(PYTHON) .github/scripts/test_patch_0_1_2_rust_public_install_wording_closeout.py",
"$(PYTHON) .github/scripts/test_patch_0_1_2_python_publication_approval_request.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",
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased

- boundary-exception: request decider review for exact deterministic patch `0.1.2` Python PyPI wheel publication while keeping PyPI upload, Python public install wording, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces blocked.
- boundary-exception: close patch `0.1.2` Rust public install wording for published crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` while keeping PyPI publication, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces blocked.
- boundary-exception: close patch `0.1.2` crates.io publication for Rust crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` while keeping Rust public install wording, PyPI publication, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces blocked.
- boundary-exception: record decider approval for bounded later crates.io publication of patch `0.1.2` Rust crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` while keeping actual operator publication, package tag creation, Rust public install wording, PyPI publication, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces blocked.
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ release-candidate-prep:
$(PYTHON) .github/scripts/test_patch_0_1_2_crates_publication_approval_decision.py
$(PYTHON) .github/scripts/test_patch_0_1_2_crates_publication_closeout.py
$(PYTHON) .github/scripts/test_patch_0_1_2_rust_public_install_wording_closeout.py
$(PYTHON) .github/scripts/test_patch_0_1_2_python_publication_approval_request.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
Expand Down
8 changes: 8 additions & 0 deletions docs/execution-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ The public README and public boundary inventory now point Rust crate installatio
`ethos-pdf==0.1.1` until separate PyPI `0.1.2` approval, operator publication, and closeout
records pass.

Patch `0.1.2` Python PyPI publication approval request is recorded in
`docs/validation/patch-0-1-2-python-publication-approval-request-validation-2026-06-25.md`. It
binds the exact deterministic `ethos-pdf==0.1.2` wheel candidate, source commit, source tree,
metadata, SHA256, and local install/import smoke for decider review only. PyPI upload, Python
public installation wording, package tag creation, 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
Expand Down
8 changes: 8 additions & 0 deletions docs/public-release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ remain blocked, production positioning remains blocked, Windows packaged artifac
bundled project-maintained PDFium builds remain blocked, `ethos-doc` remains blocked, `ethos-rag`
remains blocked, and public benchmark claims remain blocked.

Patch `0.1.2` Python PyPI publication approval request is recorded in
`docs/validation/patch-0-1-2-python-publication-approval-request-validation-2026-06-25.md`. It
requests decider review for the exact deterministic `ethos-pdf==0.1.2` wheel candidate only. PyPI
upload remains blocked, Python public installation wording remains blocked, 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, and public benchmark claims remain blocked.

## Required Before Public Push

- Package-name and trademark decision is closed by accepted ADR-0006 in
Expand Down
5 changes: 5 additions & 0 deletions docs/validation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,11 @@ recording the exact current-main source candidate and required follow-up evidenc
for `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` at `0.1.2`; PyPI publication, hosted,
production, Windows, bundled PDFium, benchmark, `ethos-doc`, and `ethos-rag` surfaces remain
blocked until separate closeout or approval records pass.
- `patch-0-1-2-python-publication-approval-request-validation-2026-06-25.md` - patch 0.1.2
Python PyPI publication approval request validation binds the exact deterministic
`ethos-pdf==0.1.2` wheel candidate, source commit, source tree, metadata, SHA256, and local
install/import smoke for decider review; PyPI upload and Python public installation wording
remain blocked until separate decision, operator, and 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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Patch 0.1.2 Python PyPI Publication Approval Request Validation - 2026-06-25

Validated source HEAD before this record: `e431982`.

Patch 0.1.2 Python publication approval request source commit:
`e431982cca2922d4cc59ddc7cacb9e72538b1cd0`.

Patch 0.1.2 Python publication approval request source tree:
`f59ddd018d234eeee0ac77292b417f4acb892b4e`.

Status: **patch 0.1.2 Python PyPI publication approval request recorded; PyPI upload remains blocked**

This record requests decider review for publishing exactly the deterministic patch `0.1.2` Ethos
Python wheel to PyPI. It does not approve or perform PyPI upload, create package tags, change public
Python installation 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: Python PyPI deterministic wheel publication
- Candidate package: `ethos-pdf==0.1.2`
- Import package: `ethos_pdf`
- Candidate wheel: `ethos_pdf-0.1.2-py3-none-any.whl`
- Deterministic build input: `SOURCE_DATE_EPOCH=0`
- Deterministic candidate wheel SHA256:
`6f17240954f1257ece3c762c820ad771ccb114353bfb699fe87f418a5ceb663c`

## Exact Request Fields

- Decision requested: approve exact deterministic patch `0.1.2` Python PyPI wheel publication
preparation inputs for later operator execution.
- Approver requested: `docushell-admin` acting as decider.
- Date requested: 2026-06-25.
- Exact package requested: `ethos-pdf==0.1.2`.
- Exact distribution requested: `ethos_pdf-0.1.2-py3-none-any.whl` only.
- Exact deterministic build input requested: `SOURCE_DATE_EPOCH=0`.
- Exact source commit requested: `e431982cca2922d4cc59ddc7cacb9e72538b1cd0`.
- Exact source tree requested: `f59ddd018d234eeee0ac77292b417f4acb892b4e`.
- Exact deterministic wheel SHA256 requested:
`6f17240954f1257ece3c762c820ad771ccb114353bfb699fe87f418a5ceb663c`.

## Wheel Metadata Bound To This Request

- Name: `ethos-pdf`
- Version: `0.1.2`
- Summary: `Python wrapper for the Ethos document evidence CLI.`
- License-Expression: `Apache-2.0`
- Requires-Python: `>=3.8`
- Wheel-Version: `1.0`
- Root-Is-Purelib: `true`
- Tag: `py3-none-any`
- Build Python: Python `3.9.6`
- Build frontend: build `1.4.4`
- Wheel member timestamps: `1980-01-01 00:00:00`

Wheel file list:

- `ethos_pdf/__init__.py`
- `ethos_pdf/_cli.py`
- `ethos_pdf-0.1.2.dist-info/METADATA`
- `ethos_pdf-0.1.2.dist-info/RECORD`
- `ethos_pdf-0.1.2.dist-info/WHEEL`
- `ethos_pdf-0.1.2.dist-info/licenses/LICENSE`
- `ethos_pdf-0.1.2.dist-info/licenses/NOTICE`
- `ethos_pdf-0.1.2.dist-info/top_level.txt`

## Local Evidence Bound To This Request

- `SOURCE_DATE_EPOCH=0 python3 -m build --wheel --outdir <candidate-dir>` built
`ethos_pdf-0.1.2-py3-none-any.whl` twice in isolated build environments.
- Both deterministic builds produced SHA256
`6f17240954f1257ece3c762c820ad771ccb114353bfb699fe87f418a5ceb663c`.
- Wheel metadata inspection reported `Name: ethos-pdf`, `Version: 0.1.2`,
`License-Expression: Apache-2.0`, `Requires-Python: >=3.8`, and `Tag: py3-none-any`.
- Wheel ZIP member timestamp inspection reported `1980-01-01 00:00:00` for every member.
- Local install smoke used `python3 -m pip install --no-deps --force-reinstall <candidate-wheel>`.
- Import smoke reported version `0.1.2`.
- Import smoke resolved `EthosCli`.
- Import smoke resolved `EthosCommandError`.

## Manual Decision Gate

Manual action is required before any PyPI upload. A decider must accept or reject this exact
deterministic request packet. Only after that decision record passes may an operator upload the
exact deterministic wheel named above with the exact SHA256 named above.

This request does not select an sdist, alternate wheel, additional package name, additional Python
module, or broad package-publication class. If any artifact filename, version, hash, source commit,
source tree, metadata, build input, public wording, or blocker set changes, this request must be
replaced by a new evidence record and a new decider review.

## Non-Approvals

- This request record does not approve PyPI upload.
- This request record does not upload any Python distribution.
- This request record does not approve the deterministic wheel hash.
- This request record does not approve an sdist.
- This request record does not approve another wheel.
- This request record does not approve package tags.
- This request record does not approve Python public installation wording.
- This request record does not approve hosted surfaces.
- This request record does not approve production positioning.
- This request record does not approve Windows packaged artifacts.
- This request record does not approve bundled project-maintained PDFium builds.
- This request record does not approve public benchmark reports.
- This request record does not approve public benchmark claims.
- This request record does not approve `ethos-doc`.
- This request record does not approve `ethos-rag`.

## Retained Blockers

- Actual PyPI upload remains blocked pending explicit decider approval.
- Python public installation wording remains blocked pending PyPI availability closeout.
- Package tag creation remains blocked pending explicit decider approval.
- Hosted surfaces remain blocked.
- Production positioning remains blocked.
- Public benchmark reports remain blocked.
- Public benchmark claims remain blocked.
- Windows packaged artifacts remain blocked.
- Bundled project-maintained PDFium builds remain blocked.
- `ethos-doc` remains blocked.
- `ethos-rag` remains blocked.
- PDFium remains caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`.

## Commands

```sh
SOURCE_DATE_EPOCH=0 python3 -m build --wheel --outdir <candidate-dir>
shasum -a 256 <candidate-dir>/ethos_pdf-0.1.2-py3-none-any.whl
python3 .github/scripts/test_patch_0_1_2_python_publication_approval_request.py
python3 .github/scripts/test_python_public_api_policy.py
PYTHONPATH=python python3 -m unittest discover -s python/tests
make release-candidate-prep PYTHON=python3
git diff --check
```

## Result

```text
patch 0.1.2 Python PyPI publication approval request recorded
Exact deterministic wheel, build input, source binding, metadata, SHA256, local install/import smoke, and retained blockers were recorded
PyPI upload remains blocked pending explicit decider approval and later operator action
```
Loading