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
189 changes: 189 additions & 0 deletions .github/scripts/test_app_answer_release_release_prep.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#!/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.
#

from __future__ import annotations

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]
RECORD = ROOT / "docs/validation/app-answer-release-contract-release-prep-validation-2026-07-01.md"
VALIDATION_README = ROOT / "docs/validation/README.md"
EXECUTION_STATUS = ROOT / "docs/execution-status.md"
PUBLIC_RELEASE_CHECKLIST = ROOT / "docs/public-release-checklist.md"
README = ROOT / "README.md"
CHANGELOG = ROOT / "CHANGELOG.md"
MAKEFILE = ROOT / "Makefile"
PYTHON_INIT = ROOT / "python/ethos_pdf/__init__.py"
NPM_PACKAGE = ROOT / "packages/npm/ethos-pdf/package.json"
CARGO_TOML = ROOT / "Cargo.toml"

SOURCE_SHORT = "d386568"
SOURCE_COMMIT = "d386568ef680f36f4a395543b21d34d2b17baccb"
SOURCE_TREE = "5891ab9c1e2fb4a9094d3d52c59ec57630aa871f"
CURRENT_BASELINE = "0.2.0"
SUGGESTED_TARGET = "0.3.0"
RECORD_NAME = "app-answer-release-contract-release-prep-validation-2026-07-01.md"

PRIVATE_PATH_MARKERS = (
"/" + "Users/",
"/" + "private/tmp",
"/" + "private/var",
"/" + "var/folders",
"saumil" + "diwaker",
"Desktop/" + "Stuff",
"project/repo/" + "ethos",
)


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 AppAnswerReleaseReleasePrepTests(unittest.TestCase):
def test_record_is_source_bound_and_indexed(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="app-answer-release contract release prep",
source_commit=SOURCE_COMMIT,
source_tree=SOURCE_TREE,
)

for path in (VALIDATION_README, EXECUTION_STATUS, PUBLIC_RELEASE_CHECKLIST):
text = normalized(path)
self.assertIn(RECORD_NAME, text, str(path))
self.assertIn("app-answer-release contract release prep", text.lower(), str(path))
self.assertIn("remain blocked", text, str(path))

def test_packet_names_scope_version_and_public_surfaces(self) -> None:
record = normalized(RECORD)

self.assertIn(
"Status: **app-answer-release contract release-prep packet recorded; version bump, "
"package publication, tag creation, artifact publication, installable `0.3.0` wording, "
"npm publication, and DocuShell integration remain blocked**",
record,
)
self.assertIn(f"Current published baseline: `{CURRENT_BASELINE}` Rust and Python surfaces", record)
self.assertIn(f"Suggested target version for decider review: `{SUGGESTED_TARGET}`", record)
self.assertIn("Target version proposal is not an approval.", record)
for surface in [
"docs/app-answer-release-contract.md",
"schemas/ethos-app-answer-release-decision.schema.json",
"schemas/examples/app-answer-release-decision.example.json",
"examples/app-answer-release/run_python_demo.py",
"examples/app-answer-release/expected-decision.json",
"make app-answer-release-contract PYTHON=python3",
"make app-answer-release-demo PYTHON=python3",
]:
self.assertIn(surface, record)

def test_package_decisions_are_bounded_and_npm_is_out_by_default(self) -> None:
record = normalized(RECORD)

self.assertIn("Rust decision requested", record)
self.assertIn("workspace uses lockstep source versions", record)
self.assertIn("`ethos-doc-core`, `ethos-verify`, and `ethos-pdf` together", record)
self.assertIn("Python decision requested", record)
self.assertIn("`ethos-pdf==0.3.0`", record)
self.assertIn("npm decision requested: keep npm out of scope by default", record)
self.assertIn("not a Node API or Node SDK", record)
self.assertIn("CLI artifact decision requested: keep GitHub Release CLI artifact publication out of scope by default", record)
self.assertIn("release tag `v0.3.0`", record)

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

self.assertIn("Ethos owns citation grounding and derived proof summaries.", record)
self.assertIn("Applications own question relevance labels.", record)
self.assertIn("Applications own source-fact, synthesis, and unsupported-claim labels.", record)
self.assertIn("Ethos verified citation grounding.", record)
self.assertIn("Answer relevance: direct, partial, or off-topic.", record)

for required in [
"This prep record does not approve a version bump.",
"This prep record does not create a release-candidate branch.",
"This prep record does not approve `cargo publish`.",
"This prep record does not approve PyPI upload.",
"This prep record does not approve `npm publish`.",
"This prep record does not create a GitHub Release.",
"This prep record does not approve installable `0.3.0` public wording.",
"This prep record does not approve a Node API, Node SDK, N-API binding, or WASM package.",
"This prep record does not approve DocuShell integration.",
]:
self.assertIn(required, record)

for forbidden in [
"version bump approved",
"cargo publish approved",
"pypi upload approved",
"npm publish approved",
"github release approved",
"tag creation approved",
"installable `0.3.0` public wording approved",
"ethos verified the answer",
]:
self.assertNotIn(forbidden, lower)
for private in PRIVATE_PATH_MARKERS:
self.assertNotIn(private, raw)

def test_current_public_install_surfaces_are_not_bumped(self) -> None:
self.assertIn('version = "0.2.0"', read(CARGO_TOML))
self.assertIn('__version__ = "0.2.0"', read(PYTHON_INIT))
self.assertIn('"version": "0.2.1"', read(NPM_PACKAGE))
self.assertIn("cargo add ethos-doc-core@0.2.0", read(README))
self.assertIn("python3 -m pip install ethos-pdf==0.2.0", read(README))
self.assertIn("npm install -g @docushell/ethos-pdf@0.2.1", read(README))
self.assertNotIn("cargo add ethos-doc-core@0.3.0", read(README))
self.assertNotIn("python3 -m pip install ethos-pdf==0.3.0", read(README))
self.assertNotIn("npm install -g @docushell/ethos-pdf@0.3.0", read(README))

def test_make_target_runs_scoped_release_prep_guard(self) -> None:
block = target_block("app-answer-release-release-prep")
commands = [line.strip() for line in block.splitlines() if line.strip()]

self.assertEqual(
[
"$(MAKE) app-answer-release-contract PYTHON=$(PYTHON)",
"$(PYTHON) .github/scripts/test_app_answer_release_release_prep.py",
"$(PYTHON) .github/scripts/test_public_surface_posture.py",
"$(PYTHON) .github/scripts/test_ci_workflow.py",
"git diff --check",
],
commands,
)
self.assertIn("test_app_answer_release_release_prep.py", read(MAKEFILE))

def test_changelog_records_boundary_exception_without_publication(self) -> None:
text = normalized(CHANGELOG)

self.assertIn("boundary-exception: record app-answer-release contract release-prep packet", text)
self.assertIn("publication, tag creation, artifact publication, installable `0.3.0` wording", text)
self.assertIn("DocuShell integration blocked", text)


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: record app-answer-release contract release-prep packet for decider review
while keeping version bump, package publication, tag creation, artifact publication,
installable `0.3.0` wording, npm publication, hosted, production, Windows, bundled PDFium,
benchmark, `ethos-doc`, `ethos-rag`, and DocuShell integration blocked.
- boundary-exception: record passing `ethos-doc-core 0.2.0` locked cargo publish dry-run evidence
while keeping actual `cargo publish`, dependent-crate dry-runs, PyPI upload, npm publish, GitHub
Release artifact publication, release/package tags, installable `0.2.0` wording, hosted,
Expand Down
9 changes: 8 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ LAYOUT_EVALUATOR_OUT ?= $(ROOT)/target/layout-evaluator-alpha
.PHONY: milestone-d-grounding-source-contract
.PHONY: milestone-d-crop-element-surface-shape-contract
.PHONY: milestone-d-claim-kind-boundary-contract
.PHONY: app-answer-release-contract app-answer-release-demo
.PHONY: app-answer-release-contract app-answer-release-demo app-answer-release-release-prep

$(ETHOS_BIN):
cargo build --locked -p ethos-cli
Expand Down Expand Up @@ -76,6 +76,13 @@ app-answer-release-demo:
$(PYTHON) .github/scripts/test_app_answer_release_demo.py
git diff --check

app-answer-release-release-prep:
$(MAKE) app-answer-release-contract PYTHON=$(PYTHON)
$(PYTHON) .github/scripts/test_app_answer_release_release_prep.py
$(PYTHON) .github/scripts/test_public_surface_posture.py
$(PYTHON) .github/scripts/test_ci_workflow.py
git diff --check

milestone-d-verify-citations-contract:
cargo test --locked -p ethos-cli --test verify
$(PYTHON) schemas/validate_examples.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 @@ -4,6 +4,14 @@ Date: 2026-06-25
Owner: product / decider
Status: v0.2.0 public beta/evaluation surfaces are live for the GitHub source repository; Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` at `0.2.0`; the Python `ethos-pdf` wheel at `0.2.0`; npm `@docushell/ethos-pdf@0.2.1`; and GitHub Release `v0.2.0` macOS arm64/Linux x64 CLI artifacts. npm `@docushell/ethos-pdf@0.2.0` is deprecated because it shipped stale CLI binaries that reported `ethos 0.1.2`; use `0.2.1`. 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.

App-answer-release contract release prep is recorded in
`docs/validation/app-answer-release-contract-release-prep-validation-2026-07-01.md` for decider
review only. It binds the merged app-release source surfaces, proposes `0.3.0` for review, and
keeps version bump, package publication, tag creation, artifact publication, installable `0.3.0`
wording, npm publication, hosted surfaces, production positioning, Windows packaged artifacts,
bundled project-maintained PDFium builds, public benchmark claims, `ethos-doc`, `ethos-rag`, and
DocuShell integration blocked pending explicit approval and later evidence records.

Historical baseline before v0.2.0 closeout: Public beta evaluation was approved for the GitHub source repository; the three bounded Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` at `0.1.2`; the Python `ethos-pdf` wheel at `0.1.2`; the npm `@docushell/ethos-pdf` CLI package at `0.1.2`; and the GitHub Release `v0.1.2` macOS arm64 and Linux x64 CLI artifacts. Internal Milestone D source-only closeout remains complete, with Milestone E prep source-only closeout recorded for the internal prep boundary. Week 0 governance is accepted, WS-ENGINE Phase 1 has a real narrow PDFium path, WS-VERIFY-ALPHA has real deterministic evidence checks over native Ethos JSON and pinned OpenDataLoader output, WS-HARNESS has fail-closed readiness scaffolding, the Gate Zero corpus/hardware manifest and direct competitor lock are frozen/signed, ADR-0005 records an accepted `PROCEED` decision for internal Milestone B continuation, ADR-0006 closes package identifier/trademark validation, ADR-0007 locks the product direction, and patch `0.1.1` plus patch `0.1.2` publication/install wording closeouts are recorded for the approved evaluation surfaces. The exact historical public sentence approved for source, Rust crate, Python wheel, npm package, macOS arm64 CLI artifact, and Linux x64 CLI artifact evaluation surfaces was: "Ethos is a deterministic document evidence layer for source-grounded verification and citation checking across native Ethos JSON and supported foreign parser outputs. The current beta includes the GitHub source repository, Rust library crates `ethos-doc-core`, `ethos-verify`, and `ethos-pdf` at `0.1.2`, the Python `ethos-pdf` wheel at `0.1.2`, the npm `@docushell/ethos-pdf@0.1.2` package, and GitHub Release `v0.1.2` macOS arm64/Linux x64 CLI artifacts. PDFium-backed commands use caller-provided PDFium through `ETHOS_PDFIUM_LIBRARY_PATH`." Milestone C has a source-tree internal artifact-validation closeout for the RAG chunk and security-report trust-loop checks. Milestone D has a source-tree internal source-only closeout recorded in `docs/validation/milestone-d-final-closeout-validation-2026-06-19.md`; the narrow `verify_citations` v1 contract in `docs/milestone-d-verify-citations-contract.md` remains carried by the existing `ethos verify` path and fixture-backed validation. The D `crop_element` v1 contract in `docs/milestone-d-crop-element-contract.md` is carried by the source-bound `ethos crop_element` CLI command plus existing `ethos verify --crop-dir` evidence artifacts; `ethos-core::crop_element` validates request identity, resolves one native document element, and emits descriptor/rendered crop metadata for that source-only contract when caller-provided source PDF bytes are bound. The `sandbox_subprocess` v1 contract in `docs/milestone-d-sandbox-subprocess-contract.md` classifies existing PDF worker-process timeout, memory-limit, stable-error, and diagnostics-gated stderr behavior without adding hardened sandbox rules. The first Milestone E prep boundary is recorded in `docs/milestone-e-prep-scope.md`, the internal fixture-candidate inventory is recorded in `docs/milestone-e-fixture-candidates.json`, internal fixture-promotion criteria are recorded in `docs/milestone-e-fixture-promotion-criteria.json`, the internal trust-loop walkthrough plan is recorded in `docs/milestone-e-internal-trust-loop-walkthrough.json`, the internal trust-loop use protocol is recorded in `docs/milestone-e-internal-trust-loop-use-protocol.json`, the internal trust-loop rehearsal/evidence matrix is recorded in `docs/milestone-e-internal-trust-loop-rehearsal-evidence-matrix.json`, and the internal trust-loop blocker ledger is recorded in `docs/milestone-e-internal-trust-loop-blocker-ledger.json`; these E prep JSON artifacts are schema-validated by `schemas/validate_examples.py` and only identify tracked trust-loop fixture candidates, internal promotion criteria, internal walkthrough sequencing, source-checkout rules for internal use, internal evidence-lane rehearsal planning, blocked-output alignment, evidence-lane alignment, diagnostic-boundary alignment, promotion-status alignment at `not_promoted_beyond_internal_fixture_planning`, source-status alignment at `source-only-pre-alpha-internal-milestone-e-prep`, applies-to binding alignment across current E source artifacts, required-before alignment for current readiness gates including `make milestone-e-prep remains green`, validation-record source-head alignment for each `Validated source HEAD before this record` line, and explicit blocker tracking that does not resolve or soften blockers. The Milestone E prep source-only closeout is recorded in `docs/validation/milestone-e-final-closeout-validation-2026-06-20.md` and does not resolve or soften blockers outside the approved public beta evaluation surfaces. Hosted surfaces, production positioning, Windows packaged artifacts, bundled project-maintained PDFium builds, `ethos-doc`, `ethos-rag`, public benchmark reports, public benchmark claims, and all speed/footprint/parser-quality/table-quality/production claims remain blocked. The controlled-run handoff remains `docs/gate-zero-evidence-runbook.md`; the accepted decision record is `docs/decisions/ADR-0005-gate-zero-decision.md`.

v0.2.0 release-candidate activation is recorded in `docs/v0-2-0-release-prep.md`. The
Expand Down
10 changes: 10 additions & 0 deletions docs/public-release-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ production positioning, Windows packaged artifacts, bundled project-maintained P
public benchmark reports, public benchmark claims, speed, footprint, parser-quality, table-quality,
`ethos-doc`, and `ethos-rag` remain blocked.

App-answer-release contract release prep is recorded in
`docs/validation/app-answer-release-contract-release-prep-validation-2026-07-01.md` for decider
review only. It proposes `0.3.0` for review, lists the merged contract/schema/helper/demo surfaces,
and requests Rust, Python, npm, CLI artifact, and tag decisions. It does not approve version bump,
package publication, tag creation, artifact publication, installable `0.3.0` wording, npm
publication, hosted surfaces, production positioning, Windows packaged artifacts, bundled
project-maintained PDFium builds, public benchmark reports, public benchmark claims, `ethos-doc`,
`ethos-rag`, or DocuShell integration. Those actions remain blocked pending explicit approval and
later evidence records.

v0.2.0 release approval request is recorded in
`docs/validation/v0-2-0-release-approval-request-validation-2026-06-25.md` for decider review
only. It does not approve version bump, release-candidate branch creation, package publication,
Expand Down
8 changes: 8 additions & 0 deletions docs/validation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ in `docs/public-release-checklist.md`.

Records:

App-answer-release contract release prep is recorded in
`app-answer-release-contract-release-prep-validation-2026-07-01.md` for decider review only. It
binds the merged source commit and tree, proposed `0.3.0` target version for review, app-release
source surfaces, package-surface decisions, product boundary wording, non-approvals, retained
blockers, and guard commands. Version bump, package publication, tag creation, artifact
publication, installable `0.3.0` wording, npm publication, and DocuShell integration remain
blocked pending explicit approval and later evidence records.

v0.2.0 publication closeout is recorded in
`v0-2-0-publication-closeout-validation-2026-06-25.md`. It records crates.io publication for
`ethos-doc-core`, `ethos-verify`, and `ethos-pdf` at `0.2.0`; PyPI `ethos-pdf==0.2.0`;
Expand Down
Loading
Loading