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
4 changes: 3 additions & 1 deletion .github/scripts/test_execution_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def test_status_is_scoped_to_internal_continuation(self) -> None:
)
self.assertIn("Public `0.3.0` install wording", text)
self.assertIn("GitHub Release artifact upload", text)
self.assertIn("npm publication/alignment", text)
self.assertIn("npm `@docushell/ethos-pdf@0.3.0` is live on npm", text)
self.assertIn("v0.3.0 npm publication closeout", text)
self.assertIn("DocuShell integration remain blocked", text)
self.assertIn(
"npm `@docushell/ethos-pdf@0.2.0` is deprecated because it shipped stale CLI binaries",
Expand Down Expand Up @@ -113,6 +114,7 @@ def test_public_posture_boundary_remains_explicit(self) -> None:
text,
)
self.assertIn("the Python `ethos-pdf` wheel is live on PyPI", text)
self.assertIn("npm `@docushell/ethos-pdf@0.3.0` is live on npm", text)
self.assertIn("v0.2.0 remains the public CLI artifact baseline", text)
self.assertIn("npm remains `@docushell/ethos-pdf@0.2.1`", text)
self.assertIn("GitHub Release `v0.2.0` macOS arm64/Linux x64 artifacts", text)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,16 @@ def test_current_docs_use_current_public_wording(self) -> None:
)
self.assertIn("Public `0.3.0` install wording", execution_status, str(EXECUTION_STATUS))
self.assertIn("GitHub Release artifact upload", execution_status, str(EXECUTION_STATUS))
self.assertIn("npm publication/alignment", execution_status, str(EXECUTION_STATUS))
self.assertIn(
"npm `@docushell/ethos-pdf@0.3.0` is live on npm",
execution_status,
str(EXECUTION_STATUS),
)
self.assertIn(
"v0.3.0 npm publication closeout",
execution_status,
str(EXECUTION_STATUS),
)
self.assertIn("DocuShell integration remain blocked", execution_status, str(EXECUTION_STATUS))
self.assertIn(
"v0.3.0 publication closeout is recorded",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ def test_decision_is_indexed_and_wired_into_status_docs(self) -> None:
text = normalized(path)
self.assertIn(RECORD.name, text)
self.assertIn("v0.3.0 npm publication approval decision", text.lower())
self.assertIn("operator publish remains pending", text)
self.assertIn("v0.3.0 npm publication closeout", text.lower())
self.assertIn("closeout is recorded", text.lower())

changelog = normalized(CHANGELOG)
self.assertIn("approve exact `@docushell/ethos-pdf@0.3.0` npm publication", changelog)
Expand Down
219 changes: 219 additions & 0 deletions .github/scripts/test_v0_3_0_npm_publication_closeout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
#!/usr/bin/env python3
#
# Copyright 2026 The Ethos maintainers
#
# Licensed under the Apache License, Version 2.0 (the "License");
#

from __future__ import annotations

import hashlib
import json
import re
import unittest
from pathlib import Path

from makefile_guard import target_block
from validation_record_source import assert_record_source_binding


ROOT = Path(__file__).resolve().parents[2]
PACKAGE_DIR = ROOT / "packages/npm/ethos-pdf"
PACKAGE_JSON = PACKAGE_DIR / "package.json"
VENDOR_MANIFEST = PACKAGE_DIR / "vendor/manifest.json"
RECORD = ROOT / (
"docs/validation/v0-3-0-npm-publication-closeout-validation-2026-07-02.md"
)
APPROVAL_DECISION = ROOT / (
"docs/validation/v0-3-0-npm-publication-approval-decision-validation-2026-07-02.md"
)
APPROVAL_REQUEST = ROOT / (
"docs/validation/v0-3-0-npm-publication-approval-request-validation-2026-07-02.md"
)
VENDOR_RECORD = ROOT / "docs/validation/v0-3-0-npm-vendor-refresh-validation-2026-07-02.md"
VALIDATION_README = ROOT / "docs/validation/README.md"
EXECUTION_STATUS = ROOT / "docs/execution-status.md"
PUBLIC_RELEASE_CHECKLIST = ROOT / "docs/public-release-checklist.md"
RELEASE_PREP = ROOT / "docs/v0-3-0-release-prep.md"
CHANGELOG = ROOT / "CHANGELOG.md"

SOURCE_SHORT = "bb93a30"
SOURCE_COMMIT = "bb93a30140ba4d3a64faacfb3ac0bed1e4fc59b2"
SOURCE_TREE = "1e562c9604cb8e1105ff51145f8f8a9ff984c0a8"
PACKAGE = "@docushell/ethos-pdf"
VERSION = "0.3.0"
PACKAGE_VERSION = f"{PACKAGE}@{VERSION}"
PRIOR_PUBLISHED = "@docushell/ethos-pdf@0.2.1"
NPM_TARBALL = "docushell-ethos-pdf-0.3.0.tgz"
NPM_SHASUM = "1a90cebd8d52011ea5c41629becdfb37dec73ee7"
INTEGRITY = (
"sha512-ZWoIY5BO7O8tzN88ICGvRasmOt7/RSN/xWFM2ONT8lavQqIOuCY/bQjvxnuK9vGpNeogh8X4UXHLLSRKqqHVOQ=="
)
TARBALL_URL = "https://registry.npmjs.org/@docushell/ethos-pdf/-/ethos-pdf-0.3.0.tgz"
NODE_VERSION = "v23.11.1"
NPM_VERSION = "10.9.2"
PUBLISHED_AT = "2026-07-02T12:01:02.015Z"
SIGNATURE_KEYID = "SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"
SIGNATURE_SIG = (
"MEUCIQDba2Q4kRW068MuweRo5a5Hz+vLTtgV0S02cU3xp5POtwIgWUf5YaUD1fv0dCAcRlijDgNVl+P2AjBPVG36DmZ7WDI="
)
EXPECTED_VENDOR_SHA256 = {
"vendor/ethos-darwin-arm64": "777e1fb243425a46b83b63ed92fbf7cb810f59cfedd81cfe671cf791410c20dc",
"vendor/ethos-linux-x64": "b416993fc38e6f794611b8b71789ed85af18eb6aa63fef380d9ae7738661f154",
"vendor/manifest.json": "e313b42e49b258171611935455fd9e70bad7ce61c409df63ab90aaa2732a46af",
}
PRIVATE_PATH_MARKERS = (
"/" + "Users/",
"/" + "private/tmp",
"/" + "private/var",
"/" + "var/folders",
"saumil" + "diwaker",
"Desktop/" + "Stuff",
"project/repo/" + "ethos",
)
FORBIDDEN = (
"public installation wording approved",
"hosted surfaces approved",
"production-ready",
"public benchmark claims approved",
"windows packaged artifacts approved",
"bundled pdfium approved",
"docushell integration approved",
)


def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()


def read(path: Path) -> str:
return path.read_text(encoding="utf-8")


def normalized(path: Path) -> str:
return re.sub(r"\s+", " ", read(path))


class V030NpmPublicationCloseoutTests(unittest.TestCase):
def test_closeout_record_is_source_bound(self) -> None:
raw = read(RECORD)
record = normalized(RECORD)

assert_record_source_binding(
self,
root=ROOT,
raw_record=raw,
normalized_record=record,
validated_head=SOURCE_SHORT,
source_label="v0.3.0 npm publication closeout",
source_commit=SOURCE_COMMIT,
source_tree=SOURCE_TREE,
)

def test_checked_in_candidate_matches_published_payload(self) -> None:
self.assertEqual(VERSION, json.loads(read(PACKAGE_JSON))["version"])

for relative_path, expected in EXPECTED_VENDOR_SHA256.items():
self.assertEqual(expected, sha256(PACKAGE_DIR / relative_path))

manifest = json.loads(read(VENDOR_MANIFEST))
self.assertEqual(1, manifest["version"])
self.assertEqual(PACKAGE, manifest["package"])
self.assertEqual("ethos-darwin-arm64", manifest["targets"]["darwin:arm64"]["binary"])
self.assertEqual("ethos-linux-x64", manifest["targets"]["linux:x64"]["binary"])

def test_record_captures_publish_and_registry_evidence(self) -> None:
raw = read(RECORD)
record = normalized(RECORD)

for expected in (
PACKAGE_VERSION,
PRIOR_PUBLISHED,
APPROVAL_DECISION.name,
APPROVAL_REQUEST.name,
VENDOR_RECORD.name,
"+ @docushell/ethos-pdf@0.3.0",
"npm auto-corrected",
'"bin[ethos]" script name was cleaned',
NPM_TARBALL,
NPM_SHASUM,
INTEGRITY,
TARBALL_URL,
SOURCE_COMMIT,
f"Node.js: `{NODE_VERSION}`",
f"npm: `{NPM_VERSION}`",
PUBLISHED_AT,
"Registry latest is now `0.3.0`",
'"latest": "0.3.0"',
'"fileCount": 11',
'"unpackedSize": 4005888',
SIGNATURE_KEYID,
SIGNATURE_SIG,
"This closeout supersedes the npm publication blocker only for the exact package and version",
"This closeout does not run `npm pkg fix`",
"ETHOS_PDFIUM_LIBRARY_PATH",
):
self.assertIn(expected, record)

for expected in EXPECTED_VENDOR_SHA256.values():
self.assertIn(expected, record)
for marker in PRIVATE_PATH_MARKERS:
self.assertNotIn(marker, raw)
for phrase in FORBIDDEN:
self.assertNotIn(phrase, record.lower())

def test_closeout_retains_public_surface_blockers(self) -> None:
raw = read(RECORD)

for blocker in (
"Public `0.3.0` install wording remains blocked.",
"package tag creation remains blocked.",
"release tag creation remains blocked.",
"DocuShell integration remains blocked.",
"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.",
):
self.assertIn(blocker, raw)

def test_closeout_is_indexed_and_wired_into_status_docs(self) -> None:
for path in (
VALIDATION_README,
EXECUTION_STATUS,
PUBLIC_RELEASE_CHECKLIST,
RELEASE_PREP,
):
text = normalized(path)
self.assertIn(RECORD.name, text)
self.assertIn("v0.3.0 npm publication closeout", text.lower())
self.assertIn(PACKAGE_VERSION, text)
self.assertIn("Public `0.3.0` install wording", text)
self.assertIn("DocuShell integration remain blocked", text)

changelog = normalized(CHANGELOG)
self.assertIn("close exact `@docushell/ethos-pdf@0.3.0` npm publication", changelog)
self.assertIn("live registry evidence", changelog)
self.assertIn("blocked", changelog.lower())

def test_release_prep_target_runs_closeout_guard_after_decision_guard(self) -> None:
block = target_block("v0-3-release-prep")
decision_guard = (
"$(PYTHON) .github/scripts/test_v0_3_0_npm_publication_approval_decision.py"
)
closeout_guard = "$(PYTHON) .github/scripts/test_v0_3_0_npm_publication_closeout.py"
public_surface_guard = "$(PYTHON) .github/scripts/test_public_surface_posture.py"

self.assertIn(decision_guard, block)
self.assertIn(closeout_guard, block)
self.assertEqual(1, block.count(closeout_guard))
self.assertLess(block.index(decision_guard), block.index(closeout_guard))
self.assertLess(block.index(closeout_guard), block.index(public_surface_guard))


if __name__ == "__main__":
unittest.main()
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- boundary-exception: close exact `@docushell/ethos-pdf@0.3.0` npm publication with live registry
evidence while keeping public install wording, release/package tags, hosted, production,
Windows, bundled PDFium, benchmark, `ethos-doc`, `ethos-rag`, and DocuShell integration blocked
pending separate lanes.
- boundary-exception: approve exact `@docushell/ethos-pdf@0.3.0` npm publication operator action
while keeping actual `npm publish`, public install wording, registry closeout,
release/package tags, hosted, production, Windows, bundled PDFium, benchmark, `ethos-doc`,
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ v0-3-release-prep:
$(PYTHON) .github/scripts/test_v0_3_0_npm_vendor_refresh.py
$(PYTHON) .github/scripts/test_v0_3_0_npm_publication_approval_request.py
$(PYTHON) .github/scripts/test_v0_3_0_npm_publication_approval_decision.py
$(PYTHON) .github/scripts/test_v0_3_0_npm_publication_closeout.py
$(PYTHON) .github/scripts/test_public_surface_posture.py
$(PYTHON) .github/scripts/claims_gate.py
$(PYTHON) .github/scripts/public_boundary_claims_gate.py
Expand Down
16 changes: 12 additions & 4 deletions docs/execution-status.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,23 @@

Date: 2026-07-02
Owner: product / decider
Status: v0.3.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI. GitHub Release `v0.3.0` now contains closed-out macOS arm64/Linux x64 CLI artifacts for evaluation with caller-provided PDFium. The npm source package candidate is refreshed as `@docushell/ethos-pdf@0.3.0`, and the v0.3.0 npm publication approval decision is recorded with operator publish still pending. v0.2.0 remains the public CLI artifact baseline with GitHub Release `v0.2.0` macOS arm64/Linux x64 artifacts, and npm remains `@docushell/ethos-pdf@0.2.1` for public install wording until a later wording closeout; npm `@docushell/ethos-pdf@0.2.0` is deprecated because it shipped stale CLI binaries that reported `ethos 0.1.2`. Public `0.3.0` install wording, npm publication/alignment, registry closeout, package tags, release tags, and DocuShell integration remain blocked pending their separate operator action, registry-smoke, tag, wording, and closeout records. The exact GitHub Release artifact closeout is limited to the approved `v0.3.0` release assets below. PDFium-backed commands use caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`. Hosted surfaces, production positioning, Windows packaged artifacts, bundled project-maintained PDFium builds, public benchmark reports, public benchmark claims, speed, footprint, parser-quality, table-quality, `ethos-doc`, and `ethos-rag` remain blocked.
Status: v0.3.0 Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` are live on crates.io, and the Python `ethos-pdf` wheel is live on PyPI. GitHub Release `v0.3.0` now contains closed-out macOS arm64/Linux x64 CLI artifacts for evaluation with caller-provided PDFium. npm `@docushell/ethos-pdf@0.3.0` is live on npm, and the v0.3.0 npm publication closeout is recorded. v0.2.0 remains the public CLI artifact baseline with GitHub Release `v0.2.0` macOS arm64/Linux x64 artifacts, and npm remains `@docushell/ethos-pdf@0.2.1` for public install wording until a later wording closeout; npm `@docushell/ethos-pdf@0.2.0` is deprecated because it shipped stale CLI binaries that reported `ethos 0.1.2`. Public `0.3.0` install wording, package tags, release tags, and DocuShell integration remain blocked pending their separate tag, wording, and closeout records. The exact GitHub Release artifact closeout is limited to the approved `v0.3.0` release assets below, and the exact npm publication closeout is limited to `@docushell/ethos-pdf@0.3.0`. PDFium-backed commands use caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`. Hosted surfaces, production positioning, Windows packaged artifacts, bundled project-maintained PDFium builds, public benchmark reports, public benchmark claims, speed, footprint, parser-quality, table-quality, `ethos-doc`, and `ethos-rag` remain blocked.

v0.3.0 npm publication closeout is recorded in
`docs/validation/v0-3-0-npm-publication-closeout-validation-2026-07-02.md`. It records live npm
registry evidence for the exact `@docushell/ethos-pdf@0.3.0` package, including registry latest,
dist shasum, integrity, tarball URL, file count, unpacked size, signature metadata, and source
gitHead. It supersedes the npm publication blocker only for that exact package and version. Public
`0.3.0` install wording, package tag creation, release tag creation, and DocuShell integration
remain blocked pending separate evidence and closeout records.

v0.3.0 npm publication approval decision is recorded in
`docs/validation/v0-3-0-npm-publication-approval-decision-validation-2026-07-02.md`. It accepts
the exact `@docushell/ethos-pdf@0.3.0` npm publication request and authorizes only the later
operator `npm publish` action for that bounded candidate after merged-source validation passes.
It does not publish the package; operator publish remains pending. Public `0.3.0` install wording,
registry closeout, package tag creation, release tag creation, and DocuShell integration remain
blocked pending separate evidence and closeout records.
That operator action is now closed out by the npm publication closeout record above. Public
`0.3.0` install wording, package tag creation, release tag creation, and DocuShell integration
remain blocked pending separate evidence and closeout records.

v0.3.0 npm publication approval request is recorded in
`docs/validation/v0-3-0-npm-publication-approval-request-validation-2026-07-02.md`. It requests
Expand Down
Loading
Loading