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");
# 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/patch-0-1-1-python-publication-approval-request-validation-2026-06-24.md"
VALIDATION_README = ROOT / "docs/validation/README.md"
PYPROJECT = ROOT / "pyproject.toml"
INIT = ROOT / "python/ethos_pdf/__init__.py"
MAKEFILE = ROOT / "Makefile"

SOURCE_SHORT = "16b2c18"
SOURCE_COMMIT = "16b2c189e1f23962dced921551cf6b4f9af4ba06"
SOURCE_TREE = "c76ba8525faaa63c53ac7f037d349a8ab4803fcb"
PACKAGE = "ethos-pdf==0.1.1"
WHEEL = "ethos_pdf-0.1.1-py3-none-any.whl"
WHEEL_SHA256 = "faa6c4751341b603b986ad3cf65d3c0c2f574e5df1d7232f76c3afd0221dac14"
WHEEL_FILES = (
"ethos_pdf/__init__.py",
"ethos_pdf/_cli.py",
"ethos_pdf-0.1.1.dist-info/METADATA",
"ethos_pdf-0.1.1.dist-info/WHEEL",
"ethos_pdf-0.1.1.dist-info/licenses/LICENSE",
"ethos_pdf-0.1.1.dist-info/licenses/NOTICE",
)
FORBIDDEN = (
"pypi upload approved",
"pypi publication approved",
"python package is published",
"wheel is published",
"twine upload approved",
"production-ready",
"hosted surfaces approved",
"windows packaged artifacts approved",
"bundled pdfium 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 Patch011PythonPublicationApprovalRequestTests(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.1 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.1 Python publication approval request source commit: `{SOURCE_COMMIT}`", record)
self.assertIn(f"Patch 0.1.1 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_wheel_candidate_and_metadata(self) -> None:
record = normalized(RECORD)

for expected in (
PACKAGE,
WHEEL,
WHEEL_SHA256,
"Name: `ethos-pdf`",
"Version: `0.1.1`",
"License-Expression: `Apache-2.0`",
"Requires-Python: `>=3.8`",
"Wheel-Version: `1.0`",
"Root-Is-Purelib: `true`",
"Tag: `py3-none-any`",
"version `0.1.1`",
"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 request packet.",
"This request record does not approve PyPI upload.",
"This request record does not upload any Python distribution.",
"Only after that decision record passes may an operator upload the exact wheel named above",
"Actual PyPI upload remains blocked pending explicit decider approval.",
"Public installation wording remains blocked pending explicit decider approval.",
"PDFium remains caller-provided through `ETHOS_PDFIUM_LIBRARY_PATH`.",
):
self.assertIn(expected, record)
for forbidden in FORBIDDEN:
self.assertNotIn(forbidden, lower)
self.assertNotIn("/Users/", raw)
self.assertNotIn("/tmp", 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)

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

self.assertIn('name = "ethos-pdf"', pyproject)
self.assertIn('version = "0.1.1"', 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.1"', init)
self.assertIn('"EthosCli"', init)
self.assertIn('"EthosCommandError"', init)

def test_release_candidate_prep_runs_request_guard_after_python_surface_tests(self) -> None:
makefile = read(MAKEFILE)
block = target_block("release-candidate-prep")
python_surface = "$(MAKE) python-surface-test PYTHON=$(PYTHON)"
guard = "$(PYTHON) .github/scripts/test_patch_0_1_1_python_publication_approval_request.py"
npm_guard = "$(PYTHON) .github/scripts/test_npm_binary_package_scaffold.py"

self.assertIn(guard, block)
self.assertEqual(1, makefile.count(guard))
self.assertLess(block.index(python_surface), block.index(guard))
self.assertLess(block.index(guard), block.index(npm_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 @@ -30,6 +30,7 @@
"$(PYTHON) .github/scripts/test_first_public_release_scope_decision.py",
"$(PYTHON) .github/scripts/test_python_public_api_policy.py",
"$(MAKE) python-surface-test PYTHON=$(PYTHON)",
"$(PYTHON) .github/scripts/test_patch_0_1_1_python_publication_approval_request.py",
"$(PYTHON) .github/scripts/test_npm_binary_package_scaffold.py",
"npm test --prefix packages/npm/ethos-pdf",
"$(PYTHON) .github/scripts/test_npm_vendor_binary_payload_strategy.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 exact patch `0.1.1` Python PyPI wheel publication approval for decider review; no PyPI upload or support-boundary change.
- boundary-exception: close patch `0.1.1` Rust crates.io publication with exact registry evidence; no public installation wording or support-boundary change.
- boundary-exception: approve exact patch `0.1.1` Rust crates.io publication decision for later operator publish; no `cargo publish` or support-boundary change.
- boundary-exception: request exact patch `0.1.1` Rust crates.io publication approval for decider review; no `cargo publish` or support-boundary change.
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ release-candidate-prep:
$(PYTHON) .github/scripts/test_first_public_release_scope_decision.py
$(PYTHON) .github/scripts/test_python_public_api_policy.py
$(MAKE) python-surface-test PYTHON=$(PYTHON)
$(PYTHON) .github/scripts/test_patch_0_1_1_python_publication_approval_request.py
$(PYTHON) .github/scripts/test_npm_binary_package_scaffold.py
npm test --prefix packages/npm/ethos-pdf
$(PYTHON) .github/scripts/test_npm_vendor_binary_payload_strategy.py
Expand Down
4 changes: 4 additions & 0 deletions docs/validation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,10 @@ recording the exact current-main source candidate and required follow-up evidenc
publication closeout validation records successful crates.io publication and live registry
verification for `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` `0.1.1`, while keeping public
installation wording and unrelated public/support surfaces blocked.
- `patch-0-1-1-python-publication-approval-request-validation-2026-06-24.md` - patch 0.1.1
Python PyPI publication approval request validation binds the exact `ethos-pdf==0.1.1` wheel,
source commit, wheel metadata, wheel SHA256, local install/import smoke, and retained blockers
for decider review; PyPI upload remains blocked.
- `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,141 @@
# Patch 0.1.1 Python PyPI Publication Approval Request Validation - 2026-06-24

Validated source HEAD before this record: `16b2c18`.

Patch 0.1.1 Python publication approval request source commit:
`16b2c189e1f23962dced921551cf6b4f9af4ba06`.

Patch 0.1.1 Python publication approval request source tree:
`c76ba8525faaa63c53ac7f037d349a8ab4803fcb`.

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

This record requests decider review for publishing exactly the patch `0.1.1` Ethos Python wheel to
PyPI. It does not approve or perform PyPI upload, create package tags, 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: Python PyPI wheel publication
- Package source commit: `16b2c189e1f23962dced921551cf6b4f9af4ba06`
- Package source tree: `c76ba8525faaa63c53ac7f037d349a8ab4803fcb`
- Candidate package: `ethos-pdf==0.1.1`
- Import package: `ethos_pdf`
- Candidate wheel: `ethos_pdf-0.1.1-py3-none-any.whl`
- Candidate wheel SHA256: `faa6c4751341b603b986ad3cf65d3c0c2f574e5df1d7232f76c3afd0221dac14`

## Exact Request Fields

- Decision requested: approve exact patch `0.1.1` Python PyPI wheel publication preparation inputs
for later operator execution.
- Approver requested: `docushell-admin` acting as decider.
- Date requested: 2026-06-24.
- Exact package requested: `ethos-pdf==0.1.1`.
- Exact distribution requested: `ethos_pdf-0.1.1-py3-none-any.whl` only.
- Exact source commit requested: `16b2c189e1f23962dced921551cf6b4f9af4ba06`.
- Exact source tree requested: `c76ba8525faaa63c53ac7f037d349a8ab4803fcb`.
- Exact wheel SHA256 requested:
`faa6c4751341b603b986ad3cf65d3c0c2f574e5df1d7232f76c3afd0221dac14`.

## Wheel Metadata Bound To This Request

- Name: `ethos-pdf`
- Version: `0.1.1`
- 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 file list:

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

## Local Evidence Bound To This Request

- `python3 -m build --wheel --outdir <candidate-dir>` built
`ethos_pdf-0.1.1-py3-none-any.whl` in an isolated build environment.
- Wheel SHA256 verification reported
`faa6c4751341b603b986ad3cf65d3c0c2f574e5df1d7232f76c3afd0221dac14`.
- Wheel metadata inspection reported `Name: ethos-pdf`, `Version: 0.1.1`,
`License-Expression: Apache-2.0`, `Requires-Python: >=3.8`, and `Tag: py3-none-any`.
- Local install smoke used `python3 -m pip install --no-deps --force-reinstall <candidate-wheel>`.
- Import smoke reported version `0.1.1`.
- 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 request
packet. Only after that decision record passes may an operator upload the exact 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, 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 an sdist.
- This request record does not approve another wheel.
- This request record does not approve package tags.
- This request record does not approve 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.
- Public installation wording remains blocked pending explicit decider approval.
- 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
python3 -m build --wheel --outdir <candidate-dir>
shasum -a 256 <candidate-dir>/ethos_pdf-0.1.1-py3-none-any.whl
python3 .github/scripts/test_patch_0_1_1_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.1 Python PyPI publication approval request recorded
Exact wheel, 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