From 64ca4ed9d85cd48e13b5ea614fd398016abdc50e Mon Sep 17 00:00:00 2001 From: docushell-admin Date: Tue, 16 Jun 2026 21:39:00 +0530 Subject: [PATCH] Add Windows determinism preflight Signed-off-by: docushell-admin --- .github/scripts/test_determinism_workflow.py | 71 ++++++++++++++++++++ .github/workflows/ci.yml | 2 + .github/workflows/determinism.yml | 11 +-- docs/execution-status.md | 2 + 4 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 .github/scripts/test_determinism_workflow.py diff --git a/.github/scripts/test_determinism_workflow.py b/.github/scripts/test_determinism_workflow.py new file mode 100644 index 00000000..5d2b2a5a --- /dev/null +++ b/.github/scripts/test_determinism_workflow.py @@ -0,0 +1,71 @@ +#!/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 unittest +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[2] +WORKFLOW = ROOT / ".github/workflows/determinism.yml" +REQUIRED_MATRIX_OS = {"macos-14", "ubuntu-latest", "windows-latest"} + + +def workflow_text() -> str: + return WORKFLOW.read_text(encoding="utf-8") + + +def matrix_os_values(text: str) -> set[str]: + match = re.search(r"^\s*os:\s*\[([^\]]+)\]\s*$", text, flags=re.MULTILINE) + if match is None: + return set() + return {item.strip() for item in match.group(1).split(",")} + + +class DeterminismWorkflowTests(unittest.TestCase): + def test_matrix_includes_gate_zero_platforms_and_windows_preflight(self) -> None: + self.assertEqual(matrix_os_values(workflow_text()), REQUIRED_MATRIX_OS) + + def test_windows_is_no_longer_left_as_a_todo(self) -> None: + text = workflow_text() + + self.assertIn("Windows x64 runs a Milestone B", text) + self.assertNotIn("TODO", text) + self.assertNotIn("add windows-latest", text) + + def test_contract_vectors_run_on_every_matrix_os(self) -> None: + text = workflow_text() + + self.assertIn("runs-on: ${{ matrix.os }}", text) + self.assertIn("cargo test --locked -p ethos-core --all-features", text) + + def test_pdfium_corpus_step_remains_explicitly_configured(self) -> None: + text = workflow_text() + + self.assertIn("full-corpus fingerprint equality", text) + self.assertIn("shell: bash", text) + self.assertIn("ETHOS_PDFIUM_LIBRARY_PATH", text) + self.assertIn("skipped: pinned PDFium runtime is not configured", text) + + def test_matrix_does_not_fail_fast(self) -> None: + self.assertIn("fail-fast: false", workflow_text()) + + +if __name__ == "__main__": + unittest.main() diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69d936aa..5fe163e5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,6 +52,8 @@ jobs: run: python3 .github/scripts/test_readiness_gate.py - name: Gate Zero evidence preflight tests run: python3 .github/scripts/test_gate_zero_evidence_preflight.py + - name: determinism workflow tests + run: python3 .github/scripts/test_determinism_workflow.py - name: Gate Zero harness tests run: python3 benchmarks/harness/test_run_gate_zero.py - name: same-platform double-parse byte-diff diff --git a/.github/workflows/determinism.yml b/.github/workflows/determinism.yml index 60194ea4..63726efd 100644 --- a/.github/workflows/determinism.yml +++ b/.github/workflows/determinism.yml @@ -1,6 +1,6 @@ # determinism.yml — nightly + contract-change PRs (plan §9). -# Gate Zero platforms first (macOS arm64 + Linux x64); Windows x64 joins no later than -# Milestone B exit (week 8). Unresolved Windows divergence blocks or re-scopes Public Beta. +# Gate Zero platforms first (macOS arm64 + Linux x64); Windows x64 runs a Milestone B +# preflight lane. Unresolved Windows divergence blocks or re-scopes Public Beta. # Determinism failures are NEVER retried into green — a flaky fingerprint IS the bug. name: determinism @@ -19,9 +19,10 @@ jobs: strategy: fail-fast: false matrix: - os: [macos-14, ubuntu-latest] # macOS arm64 + Linux x64 (Gate Zero platforms) - # TODO(week 8 / Milestone B exit): add windows-latest (risk R9; release-blocking - # for Public Beta if divergent) + # macOS arm64 + Linux x64 are the Gate Zero platforms. Windows x64 is a + # Milestone B preflight lane and only runs PDFium-backed corpus work when + # the pinned runtime is explicitly configured on that runner. + os: [macos-14, ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 diff --git a/docs/execution-status.md b/docs/execution-status.md index d94d151c..52ead91b 100644 --- a/docs/execution-status.md +++ b/docs/execution-status.md @@ -13,6 +13,7 @@ The committed implementation now includes: - A real PDFium-backed born-digital PDF extraction path in `ethos-pdf`, loaded only from an explicit `ETHOS_PDFIUM_LIBRARY_PATH`. - A pinned Phase 1 PDFium profile in `docs/pdfium-profile.md` and `profiles/ethos-deterministic-v1.json`: `chromium/7881`, V8/XFA disabled, platform artifact hashes, runtime library hashes, and provenance are recorded. - Runtime checks that reject missing or mismatched PDFium versions, release artifacts, and extracted libraries with stable errors before dynamic loading. +- The determinism workflow includes a Windows x64 preflight lane for core c14n/profile/fingerprint contract tests, while PDFium-backed corpus work remains explicitly skipped unless the pinned runtime is configured on that runner. A static workflow test guards that matrix wiring. - `ethos doc parse` / `ethos fingerprint` PDF execution through a worker process with `max_parse_ms` timeout enforcement, stable error-envelope relay, diagnostics-gated worker stderr, and page-range validation/filtering. - Quantized page/span extraction at the backend boundary, plus a basic deterministic layout pass that assembles paragraph `text_block` elements, fixture-backed alpha heading and flat list-item elements, and simple column reading order for the current born-digital fixtures. Fixture validation binds selected `fixture.json` expectations to committed extraction/layout goldens and binds current alpha text/Markdown exports to committed layout output so current read-order, element-type, heading-export, list-item, and export cases fail closed on drift. - An internal layout evaluator scaffold exists at `fixtures/evaluate_layout_alpha.py` and `make layout-evaluator-alpha`. It reads committed `fixture.json` and `layout.json` files, summarizes alpha element-type and subset coverage, and fails closed on missing layout expectations or drift in fixture-backed reading order / heading / list-item cases. @@ -58,6 +59,7 @@ Milestone A has an accepted internal Gate Zero decision for roadmap control, so | Schema/example validation | Landed: schemas, examples, deterministic profile, referential integrity, and bbox sanity pass the `jsonschema` validation gate | Contract changes still require explicit versioning and compatibility review | | Trust-layer implementation | Landed: `ethos verify` quote/value/presence/table-cell checks, explicit quote-containment labeling, normalized equality for value/table-cell checks, stale and unverifiable fingerprint handling, unsupported claim reporting, structured capability limits, native Ethos JSON path, ODL-style adapter path with synthetic table/cell mapping, pinned real OpenDataLoader 2.4.7 grounded/ungrounded fixtures, foreign fixture manifest hash validation, crop-ref evidence plumbing, stable logical native crop refs, native crop descriptor artifacts, raw BGRA crop rendering in `ethos-pdf`, CLI PNG crop artifact production for bound native source PDFs, same-host rendered crop repeatability check, rendered-crop run comparison helper, strict citation/config input validation, citation input schema, split-quote fixture coverage, explicit unsupported non-v1 claim reporting, OpenDataLoader-style structure diagnostics for malformed bbox and unknown-page references, verify-alpha case inventory checks, and demo fixtures | Still needed: real OpenDataLoader table-cell grounding, additional adapter hardening against broader real output shapes, future claim-kind expansion outside the current v1 alpha policy, and a decision on whether cross-platform rendered crop artifact equality is worth pursuing after the current macOS/Linux bbox drift finding | | WS-HARNESS readiness | Partially landed: readiness path is green for frozen corpus/hardware and pinned competitors, Gate Zero evidence preflight validates the current `ethos-bench` handoff, and gates fail closed if those records regress | Public-safe comparison report flow, release/package approval, claim-wording approval, and future evidence-refresh workflow still need hardening | +| Determinism workflow | Landed: macOS arm64, Linux x64, and Windows x64 matrix entries run core contract tests; PDFium-backed corpus work stays gated on an explicitly configured pinned runtime; static workflow tests guard the matrix | Windows PDFium runtime provisioning and broader cross-platform corpus validation remain future work | ## PM Rule