diff --git a/.github/workflows/frontier741.yml b/.github/workflows/frontier741.yml index 23e56ff27f..5c74d21b28 100644 --- a/.github/workflows/frontier741.yml +++ b/.github/workflows/frontier741.yml @@ -9,6 +9,8 @@ on: - 'research/direct-delivery504-global/**' - 'research/complex-sw4-frame8/**' - 'scripts/verify_frontier741*.py' + - 'scripts/verify_frontier_replay.py' + - 'tests/test_frontier_replay_coverage.py' - 'tests/test_frontier741_bindings.py' - 'scripts/verify_selected_result.py' - 'certificates/selected-result.json' @@ -23,6 +25,8 @@ on: - 'research/direct-delivery504-global/**' - 'research/complex-sw4-frame8/**' - 'scripts/verify_frontier741*.py' + - 'scripts/verify_frontier_replay.py' + - 'tests/test_frontier_replay_coverage.py' - 'tests/test_frontier741_bindings.py' - 'scripts/verify_selected_result.py' - 'certificates/selected-result.json' @@ -53,11 +57,13 @@ jobs: run: | python -B scripts/verify_selected_result.py python -B scripts/verify_pr_reconciliation.py + - name: Receipt coverage regression checks + run: python -B -m unittest discover -s tests -p 'test_frontier_replay_coverage.py' -v - name: Cold finite replay and exact composition binding env: CXX: g++ BOOST_INCLUDE: /usr/include - run: python -B scripts/verify_frontier741.py --work "$RUNNER_TEMP/frontier741" + run: python -B scripts/verify_frontier_replay.py --frontier 741 --work "$RUNNER_TEMP/frontier741" - name: Require committed files unchanged run: git diff --exit-code - uses: actions/upload-artifact@v4 @@ -66,9 +72,9 @@ jobs: name: frontier741-linux-python312 path: | ${{ runner.temp }}/frontier741/RESULT.json - ${{ runner.temp }}/frontier741/STEPS.json - ${{ runner.temp }}/frontier741/*.log - ${{ runner.temp }}/frontier741/complex/RESULT.json - ${{ runner.temp }}/frontier741/complex/RECEIPT.json - ${{ runner.temp }}/frontier741/complex/STAGES.json - ${{ runner.temp }}/frontier741/complex/global-replay/ASSEMBLY.json + ${{ runner.temp }}/frontier741/replay/STEPS.json + ${{ runner.temp }}/frontier741/replay/*.log + ${{ runner.temp }}/frontier741/replay/complex/RESULT.json + ${{ runner.temp }}/frontier741/replay/complex/RECEIPT.json + ${{ runner.temp }}/frontier741/replay/complex/STAGES.json + ${{ runner.temp }}/frontier741/replay/complex/global-replay/ASSEMBLY.json diff --git a/.github/workflows/frontier799.yml b/.github/workflows/frontier799.yml index 58a4a9a1a6..b05a06cdc3 100644 --- a/.github/workflows/frontier799.yml +++ b/.github/workflows/frontier799.yml @@ -9,7 +9,10 @@ on: - 'research/direct-delivery504-global/**' - 'research/complex-sw4-frame8/**' - 'research/gauge44-frames-x/**' + - 'scripts/verify_frontier741*.py' - 'scripts/verify_frontier799*.py' + - 'scripts/verify_frontier_replay.py' + - 'tests/test_frontier_replay_coverage.py' - 'tests/test_frontier799_bindings.py' - 'scripts/verify_selected_result.py' - 'certificates/selected-result.json' @@ -24,7 +27,10 @@ on: - 'research/direct-delivery504-global/**' - 'research/complex-sw4-frame8/**' - 'research/gauge44-frames-x/**' + - 'scripts/verify_frontier741*.py' - 'scripts/verify_frontier799*.py' + - 'scripts/verify_frontier_replay.py' + - 'tests/test_frontier_replay_coverage.py' - 'tests/test_frontier799_bindings.py' - 'scripts/verify_selected_result.py' - 'certificates/selected-result.json' @@ -55,11 +61,13 @@ jobs: run: | python -B scripts/verify_selected_result.py python -B scripts/verify_pr_reconciliation.py + - name: Receipt coverage regression checks + run: python -B -m unittest discover -s tests -p 'test_frontier_replay_coverage.py' -v - name: Cold finite replay and exact composition binding env: CXX: g++ BOOST_INCLUDE: /usr/include - run: python -B scripts/verify_frontier799.py --work "$RUNNER_TEMP/frontier799" + run: python -B scripts/verify_frontier_replay.py --frontier 799 --work "$RUNNER_TEMP/frontier799" - name: Require committed files unchanged run: git diff --exit-code - uses: actions/upload-artifact@v4 @@ -68,10 +76,10 @@ jobs: name: frontier799-linux-python312 path: | ${{ runner.temp }}/frontier799/RESULT.json - ${{ runner.temp }}/frontier799/ANCESTRY.json - ${{ runner.temp }}/frontier799/STEPS.json - ${{ runner.temp }}/frontier799/*.log - ${{ runner.temp }}/frontier799/INDEPENDENT-*.json - ${{ runner.temp }}/frontier799/global/ASSEMBLY.json - ${{ runner.temp }}/frontier799/global/STAGES.json - ${{ runner.temp }}/frontier799/native/STEPS.json + ${{ runner.temp }}/frontier799/replay/ANCESTRY.json + ${{ runner.temp }}/frontier799/replay/STEPS.json + ${{ runner.temp }}/frontier799/replay/*.log + ${{ runner.temp }}/frontier799/replay/INDEPENDENT-*.json + ${{ runner.temp }}/frontier799/replay/global/ASSEMBLY.json + ${{ runner.temp }}/frontier799/replay/global/STAGES.json + ${{ runner.temp }}/frontier799/replay/native/STEPS.json diff --git a/Makefile b/Makefile index d0a21163fb..ea996804e9 100644 --- a/Makefile +++ b/Makefile @@ -582,9 +582,9 @@ frontier626-verify: selected-record-check .PHONY: frontier741-verify frontier741-verify: selected-record-check @work=$$(mktemp -d "$${TMPDIR:-/tmp}/integer-mult-frontier741.XXXXXX"); \ - python3 -B scripts/verify_frontier741.py --work "$$work/replay" + python3 -B scripts/verify_frontier_replay.py --frontier 741 --work "$$work/replay" .PHONY: frontier799-verify frontier799-verify: selected-record-check @work=$$(mktemp -d "$${TMPDIR:-/tmp}/integer-mult-frontier799.XXXXXX"); \ - python3 -B scripts/verify_frontier799.py --work "$$work/replay" + python3 -B scripts/verify_frontier_replay.py --frontier 799 --work "$$work/replay" diff --git a/docs/research/frontier-replay-coverage.md b/docs/research/frontier-replay-coverage.md new file mode 100644 index 0000000000..e2fcaa246b --- /dev/null +++ b/docs/research/frontier-replay-coverage.md @@ -0,0 +1,83 @@ +# Required evidence coverage for public frontier replay + +Tooling integration; no new kappa or mathematical construction. + +[Lucas's PR838](https://github.com/CrocSwap/integer-mult-bounds/pull/838), at +`2a50020bb9564229874cbfbdc112e17b235bacfc`, identified a receipt-coverage gap: +the PR741 composition checker accepts an unrelated successful stage in place +of a required stage, or an omitted artifact when its receipt entry is omitted +too. Its existing checks validate the hashes of listed evidence, but do not +require the producer's complete inventory. PR799 uses that checker for ancestry. + +The public `make frontier741-verify` and `make frontier799-verify` commands and +both frontier CI workflows now use `scripts/verify_frontier_replay.py`. It +requires the frozen PR741 producer's 22 ordered stages, all 44 artifact paths, +and agreement between the receipt and `STAGES.json`, then applies every +historical composition check, including file/log hashes and path containment. +The inventory comes from the producer and retained complete run, not the +candidate receipt. A regression checks agreement with the producer's 34 fixed +outputs and its ten local outputs. + +The entrypoint checks reused ancestry before starting a supplier. After a cold +run it checks ancestry again, before writing the public completion record. +The implementation delegates construction to the existing scripts; it does not +copy or change their mathematics, source packages, selected records or proof +hashes. Existing historical script entrypoints retain their historical checks. + +## Commands and output layout + +```sh +python3 -B -m unittest discover -s tests -p 'test_frontier_replay_coverage.py' -v +make frontier799-verify +``` + +For an explicit output directory, which must be fresh and outside the repository: + +```sh +python3 -B scripts/verify_frontier_replay.py --frontier 799 --work /tmp/frontier-run +``` + +`/tmp/frontier-run/replay/` contains the historical script's logs and output. +Only `/tmp/frontier-run/RESULT.json` marks successful completion of the public +entrypoint. It retains the historical result fields and adds receipt coverage +counts. Expected final output for the base selection: + +```text +PASS_COMPLETE_REPLAY_RECEIPT_COVERAGE 0.001661634653669567 +``` + +To reuse a complete PR741 run, add `--ancestor /path/to/pr741`. That directory +must contain `bit/` and `complex/`; for output from this new entrypoint, use its +`replay/` subdirectory. Incomplete reuse is rejected before creating the output +directory. Construction failure or failed postflight coverage leaves no public +top-level `RESULT.json`; diagnostic files may remain in `replay/`. + +## Scope and attribution + +Base: `f567884aeb8851b6e794af1184119a3bfbe1e631`. The source contract is +`research/complex-sw4-frame8/verify.py` and its retained complete archive +`research/community-queue-20261013/pr741-fresh-replay.tar.gz` at that commit. +Changing that producer's coverage requires reviewing this contract and tests. + +Validation on Linux CPython 3.12.15 in a network-disabled, read-only Docker +container: all 11 new tests pass, the existing PR741/PR799 binding suites pass, +and the selected-record integrity check passes with its original hashes. Tests +physically delete each of the 44 artifacts and reproduce historical acceptance +of representative coherently rehashed omissions. Publication tests substitute +only the expensive subprocess boundary and validate real archived evidence; +they are not fresh native construction runs. A fresh full cold replay and +hosted CI are not claimed as locally completed; the updated workflows perform +the full cold replay when run. + +This closes omission acceptance in the public entrypoint. It does not +authenticate a fabricated log, establish that an arbitrary receipt records +an actual execution, or replace mathematical certificate replay. It does not +audit all PR799 evidence or prove the full multiplication theorem. Inherited +realization, all-size, hosting, precision/tape and analytic assumptions remain. + +Credit Lucas (@ljste) for PR838's finding and supplemental coverage predicate; +Douglas Colkitt for the composition checkers and retained replays; Chafik +Boukhalfa for PR741; and DreamingOfClouds and eumemic for PR589/PR555 and their +retained predecessors. Production integration and regression tests by +Chinmay (@chinmayarvind23), with substantial OpenAI Codex assistance, under +Apache-2.0. This is a follow-up to PR838, not an independent discovery. diff --git a/scripts/verify_frontier_replay.py b/scripts/verify_frontier_replay.py new file mode 100644 index 0000000000..1d23d3ed66 --- /dev/null +++ b/scripts/verify_frontier_replay.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python3 +"""Run the frozen PR741/799 verifiers with mandatory PR741 receipt coverage. + +The historical scripts and their proof-record hashes remain unchanged. A run +is complete only when this entrypoint writes its top-level RESULT.json. +Coverage finding: Lucas (@ljste), PR838. Integration: Chinmay (@chinmayarvind23), with +substantial OpenAI Codex assistance. Apache-2.0. No new mathematical bound. +""" +import argparse +import json +from pathlib import Path +import subprocess +import sys + +from verify_frontier741_bindings import check as check_composition, read, require + +ROOT = Path(__file__).resolve().parents[1] + +# Contract of the frozen complex-sw4-frame8/verify.py producer. Its 34 fixed +# outputs and ten local outputs are deliberately independent of the candidate +# receipt. Tests bind this list to the producer and the retained complete run. +EXPECTED_STAGES = ( + 'ancestral558-fresh', 'gauge44-exact-construction', 'notri56-construction', + 'notri-control-g44', 'layered66-construction', 'p6n-cold72-construction', + 'four-promotions', 'promotion-controls', 'sw4-read-exchanges', + 'eight-B-frame-construction', 'all728-columns-native', 'both-native-ledgers', + 'independent-native-controls', 'residual-wrappers', 'all-native-phase-edges', + 'independent-scalar-frames-cones', 'inherited-cold-controls', + 'eight-frame-controls', 'owner-construction-controls', + 'strict-global-admission', 'independent-literal-map-moment', + 'independent-two-engine-outer47', +) +EXPECTED_ARTIFACTS = frozenset(( + 'RESULT.json', 'ANCESTRAL-LINK.json', 'STAGES.json', + 'INDEPENDENT-LOCAL.json', 'INDEPENDENT-MAP.json', 'INDEPENDENT-PRICE.json', + 'RECONSTRUCTED-OWNERS.json.gz', 'OWNER-CONSTRUCTION-CONTROLS.json', + 'FRAME-CONTROLS.json', 'cold-controls/COLD-END-CONTROLS.json', + 'PROMO-CONTROLS.json', 'promoted/FULL-WORD.json.gz', 'p6n/STEPS.json', + 'p6n/controls/COLD-END-CONTROLS.json', 'p6n/p6n/FULL-WORD.json.gz', + 'sw4/BUILD.json', 'sw4/FULL-WORD.json.gz', 'frames/BUILD.json', + 'frames/FULL-WORD.json.gz', 'gauge44/STEPS.json', 'notri56/STEPS.json', + 'notri56/cold44/CONSTRUCTION.json', 'notri-control/STEPS.json', + 'layered66/STEPS.json', 'layered66/swap/PIVOT-SWAP.json', + 'layered66/controls/COLD-END-CONTROLS.json', 'global-replay/REPLAY.json', + 'global-replay/ASSEMBLY.json', 'global-replay/STAGES.json', + 'global-replay/ADMISSION-CONTROLS.json', 'global-replay/BIT-SUPPLIER-CONTROLS.json', + 'global-replay/global/audit/OWNERS-AND-PROFILE.json', + 'global-replay/global/audit/PREFIX-AND-INVOICE.json', + 'global-replay/global/audit/ASYNC-AUDIT.json', + 'local/CANONICAL-WORD.json.gz', 'local/CLIFFORD-RECIPES.json', + 'local/CLIFFORD-REVIEW.json', 'local/FULL-WORD.json.gz', + 'local/INDEPENDENT-LOCAL-REPLAY.json', 'local/LOCAL-CHECKS.json', + 'local/LOCAL-PROGRAMS.json.gz', 'local/RESIDUAL-ADAPTERS.json', + 'local/SCALAR-FRAME-AUDIT.json', 'local/WRAPPER-CHECKS.json', +)) + + +def check_coverage(complex_dir): + receipt = read(complex_dir / 'RECEIPT.json') + stages = receipt['stages'] + require(tuple(s['name'] for s in stages) == EXPECTED_STAGES and + all(s['exit_code'] == 0 for s in stages), 'Required replay stages differ') + require(set(receipt['artifacts']) == EXPECTED_ARTIFACTS, + 'Required replay artifact inventory differs') + require(read(complex_dir / 'STAGES.json') == stages, + 'Receipt stages differ from recorded execution stages') + + +def check_ancestry(ancestor): + """Enforce coverage, then retain every original source/hash/math check.""" + check_coverage(ancestor / 'complex') + return check_composition(ancestor / 'bit', ancestor / 'complex') + + +def main(argv=None): + p = argparse.ArgumentParser(description=__doc__) + p.add_argument('--frontier', choices=('741', '799'), required=True) + p.add_argument('--work', type=Path, required=True) + p.add_argument('--ancestor', type=Path, + help='PR799 only: reuse a complete historical PR741 output ' + '(or the replay/ directory of this entrypoint)') + a = p.parse_args(argv) + work = a.work.resolve() + if sys.flags.optimize or work.exists() or work.is_relative_to(ROOT): + p.error('Use enabled assertions and a fresh output directory outside the repository') + if a.ancestor is not None and a.frontier != '799': + p.error('--ancestor is only supported for frontier 799') + ancestor = a.ancestor.resolve() if a.ancestor is not None else None + # Reject incomplete reused evidence before starting any supplier work. + if ancestor is not None: + check_ancestry(ancestor) + work.mkdir(parents=True) + replay = work / 'replay' + command = [sys.executable, '-B', str(ROOT / ('scripts/verify_frontier' + a.frontier + '.py')), + '--work', str(replay)] + if ancestor is not None: + command += ['--ancestor', str(ancestor)] + subprocess.run(command, cwd=ROOT, check=True) + if ancestor is None: + ancestor = replay if a.frontier == '741' else replay / 'ancestor' + check_ancestry(ancestor) + result = read(replay / 'RESULT.json') + result['receipt_coverage'] = dict(stages=len(EXPECTED_STAGES), artifacts=len(EXPECTED_ARTIFACTS)) + # Nested files are the historical producer's output. Publish the public + # completion record only after the additional evidence checks succeed. + (work / 'RESULT.json').write_text(json.dumps(result, indent=2) + '\n', encoding='utf-8') + print('PASS_COMPLETE_REPLAY_RECEIPT_COVERAGE', result['decimal'], flush=True) + + +if __name__ == '__main__': + main() diff --git a/tests/test_frontier_replay_coverage.py b/tests/test_frontier_replay_coverage.py new file mode 100644 index 0000000000..22dec0b039 --- /dev/null +++ b/tests/test_frontier_replay_coverage.py @@ -0,0 +1,268 @@ +"""Exercise coverage against real replay bytes, including coherently rehashed omissions.""" +import ast +from contextlib import contextmanager +from copy import deepcopy +from hashlib import sha256 +import json +from pathlib import Path, PurePosixPath +import shutil +import subprocess +import sys +import tarfile +import tempfile +import unittest +from unittest.mock import patch + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / 'scripts')) +import verify_frontier741_bindings as historical +import verify_frontier_replay as coverage + + +class ReplayCoverage(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.tmp = tempfile.TemporaryDirectory() + cls.addClassCleanup(cls.tmp.cleanup) + cls.root = Path(cls.tmp.name).resolve() + cls.ancestor = cls.root / 'ancestor' + cls.complex = cls.ancestor / 'complex' + cls.bit = cls.ancestor / 'bit' + shutil.copytree(ROOT / 'research/community-frontier741-audit/bit', cls.bit) + archive_path = ROOT / 'research/community-queue-20261013/pr741-fresh-replay.tar.gz' + prefix = PurePosixPath('pr741-fresh-replay') + with tarfile.open(archive_path) as archive: + members = {PurePosixPath(m.name): m for m in archive if m.isfile()} + cls.pristine = json.loads(archive.extractfile(members[prefix / 'RECEIPT.json']).read()) + required = {'RECEIPT.json', *cls.pristine['artifacts'], + *(s['name'] + '.log' for s in cls.pristine['stages'])} + cls.archive_local = { + p.relative_to(prefix).as_posix() for p in members + if p.parent == prefix / 'local' + } + # Extract only consumed ordinary files; compiler symlinks are not needed. + for relative in required: + target = (cls.complex / relative).resolve() + if not target.is_relative_to(cls.complex): + raise ValueError('Invalid retained replay path') + target.parent.mkdir(parents=True, exist_ok=True) + target.write_bytes(archive.extractfile(members[prefix / relative]).read()) + cls.receipt = cls.complex / 'RECEIPT.json' + cls.stages = cls.complex / 'STAGES.json' + + @contextmanager + def changed(self, *paths): + saved = {p: p.read_bytes() if p.exists() else None for p in paths} + try: + yield + finally: + for path, content in saved.items(): + if content is None: + path.unlink(missing_ok=True) + else: + path.write_bytes(content) + + def write(self, path, value): + path.write_bytes((json.dumps(value, indent=2) + '\n').encode()) + + def write_receipt_and_stages(self, receipt): + self.write(self.stages, receipt['stages']) + receipt['artifacts']['STAGES.json'] = sha256(self.stages.read_bytes()).hexdigest() + self.write(self.receipt, receipt) + + def test_pristine_retained_replay_passes_both_checks(self): + coverage.check_coverage(self.complex) + self.assertEqual(coverage.check_ancestry(self.ancestor)['decimal'], + '0.001661202643272239') + + def test_contract_matches_frozen_producer_and_retained_local_inventory(self): + # Parse the producer without importing or executing its expensive pipeline. + producer = ROOT / 'research/complex-sw4-frame8/verify.py' + tree = ast.parse(producer.read_text(encoding='utf-8')) + calls = [n.value for n in tree.body if isinstance(n, ast.Expr) + and isinstance(n.value, ast.Call) + and isinstance(n.value.func, ast.Name) and n.value.func.id == 'run'] + names = tuple(ast.literal_eval(call.args[0]) for call in calls) + fixed_lists = [ast.literal_eval(n.value) for n in tree.body + if isinstance(n, ast.Assign) + and any(isinstance(t, ast.Name) and t.id == 'files' for t in n.targets)] + self.assertEqual(len(names), 22) + self.assertEqual(names, coverage.EXPECTED_STAGES) + self.assertEqual(len(fixed_lists), 1) + self.assertEqual(len(fixed_lists[0]), 34) + self.assertEqual(len(self.archive_local), 10) + self.assertEqual(set(fixed_lists[0]) | self.archive_local, coverage.EXPECTED_ARTIFACTS) + self.assertEqual(set(self.pristine['artifacts']), coverage.EXPECTED_ARTIFACTS) + self.assertEqual(len(coverage.EXPECTED_ARTIFACTS), 44) + + def test_replacement_phase_stage_with_matching_index_and_log_is_rejected(self): + receipt = deepcopy(self.pristine) + phase = next(s for s in receipt['stages'] if s['name'] == 'all-native-phase-edges') + old_log = self.complex / (phase['name'] + '.log') + phase['name'] = 'unrelated-successful-stage' + new_log = self.complex / (phase['name'] + '.log') + with self.changed(self.receipt, self.stages, old_log, new_log): + new_log.write_bytes(old_log.read_bytes()) + old_log.unlink() + self.write_receipt_and_stages(receipt) + # This is a real accepted historical input, not a mocked reader. + historical.check(self.bit, self.complex) + with self.assertRaisesRegex(ValueError, 'Required replay stages'): + coverage.check_coverage(self.complex) + + def test_each_artifact_omission_and_file_deletion_is_rejected(self): + for relative in sorted(self.pristine['artifacts']): + with self.subTest(artifact=relative): + path = self.complex / relative + receipt = deepcopy(self.pristine) + del receipt['artifacts'][relative] + with self.changed(self.receipt, path): + path.unlink() + self.write(self.receipt, receipt) + with self.assertRaisesRegex(ValueError, 'Required replay artifact inventory'): + coverage.check_coverage(self.complex) + + def test_omitted_phase_evidence_passes_historical_binding_but_fails_new_cli(self): + relative = 'local/CLIFFORD-REVIEW.json' + receipt = deepcopy(self.pristine) + del receipt['artifacts'][relative] + path = self.complex / relative + work = self.root / 'must-not-start' + with self.changed(self.receipt, path): + path.unlink() + self.write(self.receipt, receipt) + historical.check(self.bit, self.complex) + result = subprocess.run( + [sys.executable, '-B', str(ROOT / 'scripts/verify_frontier_replay.py'), + '--frontier', '799', '--work', str(work), '--ancestor', str(self.ancestor)], + capture_output=True, text=True, timeout=15, + ) + self.assertNotEqual(result.returncode, 0) + self.assertIn('Required replay artifact inventory', result.stderr) + self.assertFalse(work.exists(), 'An incomplete ancestor must fail before work begins') + + def test_stage_order_and_failure_cannot_be_hidden_in_matching_index(self): + for kind in ('reordered', 'failed'): + with self.subTest(kind=kind), self.changed(self.receipt, self.stages): + receipt = deepcopy(self.pristine) + if kind == 'reordered': + receipt['stages'][0], receipt['stages'][1] = receipt['stages'][1], receipt['stages'][0] + else: + receipt['stages'][0]['exit_code'] = 1 + self.write_receipt_and_stages(receipt) + if kind == 'reordered': + historical.check(self.bit, self.complex) + with self.assertRaisesRegex(ValueError, 'Required replay stages'): + coverage.check_coverage(self.complex) + + def test_disagreeing_stage_index_is_rejected_even_with_updated_hash(self): + receipt = deepcopy(self.pristine) + index = deepcopy(receipt['stages']) + index[0]['exit_code'] = 1 + with self.changed(self.receipt, self.stages): + self.write(self.stages, index) + receipt['artifacts']['STAGES.json'] = sha256(self.stages.read_bytes()).hexdigest() + self.write(self.receipt, receipt) + historical.check(self.bit, self.complex) + with self.assertRaisesRegex(ValueError, 'Receipt stages differ'): + coverage.check_coverage(self.complex) + + def test_added_hash_bound_artifact_is_not_part_of_frozen_inventory(self): + receipt = deepcopy(self.pristine) + extra = self.complex / 'unrelated-evidence.json' + with self.changed(self.receipt, extra): + self.write(extra, {'status': 'unrelated'}) + receipt['artifacts'][extra.name] = sha256(extra.read_bytes()).hexdigest() + self.write(self.receipt, receipt) + historical.check(self.bit, self.complex) + with self.assertRaisesRegex(ValueError, 'Required replay artifact inventory'): + coverage.check_coverage(self.complex) + + def test_public_result_is_written_only_after_generated_evidence_passes(self): + # Substitute only native generation; validate actual archived files and hashes. + for omit in (False, True): + work = self.root / ('generated-incomplete' if omit else 'generated-complete') + + def supplier(command, **kwargs): + self.assertEqual(Path(command[2]).name, 'verify_frontier741.py') + replay = Path(command[-1]) + shutil.copytree(self.ancestor, replay) + self.write(replay / 'RESULT.json', historical.check(replay / 'bit', replay / 'complex')) + if omit: + receipt_path = replay / 'complex/RECEIPT.json' + receipt = json.loads(receipt_path.read_bytes()) + relative = 'local/CLIFFORD-REVIEW.json' + del receipt['artifacts'][relative] + (replay / 'complex' / relative).unlink() + self.write(receipt_path, receipt) + return subprocess.CompletedProcess(command, 0) + + with self.subTest(omit=omit), patch.object(coverage.subprocess, 'run', side_effect=supplier) as run: + args = ['--frontier', '741', '--work', str(work)] + if omit: + with self.assertRaisesRegex(ValueError, 'Required replay artifact inventory'): + coverage.main(args) + self.assertFalse((work / 'RESULT.json').exists()) + else: + coverage.main(args) + published = json.loads((work / 'RESULT.json').read_bytes()) + self.assertEqual(published['receipt_coverage'], {'stages': 22, 'artifacts': 44}) + self.assertEqual(published['decimal'], '0.001661202643272239') + self.assertTrue((work / 'replay/RESULT.json').exists()) + run.assert_called_once() + + def test_799_fresh_and_reused_ancestry_are_checked_before_publication(self): + retained_result = ROOT / 'research/community-frontier799-audit/RESULT.json' + for reuse in (False, True): + for omit in (False, True): + work = self.root / f'generated799-{reuse}-{omit}' + supplied = self.root / f'supplied799-{reuse}-{omit}' + if reuse: + shutil.copytree(self.ancestor, supplied) + + def supplier(command, **kwargs): + self.assertEqual(Path(command[2]).name, 'verify_frontier799.py') + replay = Path(command[command.index('--work') + 1]) + replay.mkdir() + if reuse: + self.assertEqual(command[-2:], ['--ancestor', str(supplied)]) + ancestor = supplied + else: + self.assertNotIn('--ancestor', command) + ancestor = replay / 'ancestor' + shutil.copytree(self.ancestor, ancestor) + shutil.copyfile(retained_result, replay / 'RESULT.json') + if omit: + receipt_path = ancestor / 'complex/RECEIPT.json' + receipt = json.loads(receipt_path.read_bytes()) + del receipt['artifacts']['local/CLIFFORD-REVIEW.json'] + self.write(receipt_path, receipt) + return subprocess.CompletedProcess(command, 0) + + args = ['--frontier', '799', '--work', str(work)] + if reuse: + args += ['--ancestor', str(supplied)] + with self.subTest(reuse=reuse, omit=omit), patch.object( + coverage.subprocess, 'run', side_effect=supplier) as run: + if omit: + with self.assertRaisesRegex(ValueError, 'Required replay artifact inventory'): + coverage.main(args) + self.assertFalse((work / 'RESULT.json').exists()) + else: + coverage.main(args) + result = json.loads((work / 'RESULT.json').read_bytes()) + self.assertEqual(result.pop('receipt_coverage'), {'stages': 22, 'artifacts': 44}) + self.assertEqual(result, json.loads(retained_result.read_bytes())) + run.assert_called_once() + + def test_supplier_failure_never_publishes_a_result(self): + work = self.root / 'failed-supplier' + with patch.object(coverage.subprocess, 'run', + side_effect=subprocess.CalledProcessError(1, ['supplier'])): + with self.assertRaises(subprocess.CalledProcessError): + coverage.main(['--frontier', '799', '--work', str(work)]) + self.assertFalse((work / 'RESULT.json').exists()) + + +if __name__ == '__main__': + unittest.main()