From e3a2ebfb3cf81ab2ac88006d65a631bd9266fa10 Mon Sep 17 00:00:00 2001 From: Grok Bot agent 14 Date: Wed, 7 Oct 2026 21:07:32 -0500 Subject: [PATCH 1/5] tests: W7j behavioural controls for the math-downstream-gates lane 21 stdlib unittest controls, added inside the two files the required lane already selects (-p test_required_formal_check.py, -p test_downstream_validation.py), so they run in math-downstream-gates with no workflow or selector change. Each refuses a weakening of run_validation.py, required_formal_check.py or git_transition_audit.py that the existing suite admits (W7j REPORT, main#229 comment 6050666099). Test files only. Co-authored-by: Dylan Roy --- tests/test_downstream_validation.py | 204 ++++++++++++++++++++++++++++ tests/test_required_formal_check.py | 39 ++++++ 2 files changed, 243 insertions(+) diff --git a/tests/test_downstream_validation.py b/tests/test_downstream_validation.py index b5d42a9e9..b32bf973c 100644 --- a/tests/test_downstream_validation.py +++ b/tests/test_downstream_validation.py @@ -13,6 +13,14 @@ SPEC = importlib.util.spec_from_file_location('downstream_validation', SCRIPT) M = importlib.util.module_from_spec(SPEC) SPEC.loader.exec_module(M) +PACKET = SCRIPT.parent +sys.path.insert(0, str(PACKET)) # git_transition_audit imports hard_gate from its packet +try: + AUDIT_SPEC = importlib.util.spec_from_file_location('transition_audit', PACKET / 'git_transition_audit.py') + AUDIT = importlib.util.module_from_spec(AUDIT_SPEC) + AUDIT_SPEC.loader.exec_module(AUDIT) +finally: + sys.path.remove(str(PACKET)) class ValidationTimeoutTests(unittest.TestCase): @@ -262,5 +270,201 @@ def short_run(command, **kwargs): self.assertGreater(record['elapsed_seconds'], 0) +class ReplayGateRefusalControls(unittest.TestCase): + """Mutation-gap controls: refusal paths of execute()/main() that the tests above leave unpinned.""" + BASELINE = 'Ran 71 tests\nOK\n' + DETECTED = 'Ran 71 tests\nAssertionError: changed semantics\nFAILED (failures=1)\n' + + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.out = Path(self.temp.name) + self.command = [sys.executable, '-B', '-S', 'test.py'] + self.two = dict(list(M.MUTANTS.items())[:2]) + + def completed(self, code, stderr, stdout=''): + return subprocess.CompletedProcess(self.command, code, stdout, stderr) + + def gate(self, code=0, stdout=None): + return self.completed(code, b'', (M.ROOT / 'RESULTS.json').read_bytes() if stdout is None else stdout) + + def assert_refused(self, code, stderr, mutant): + with mock.patch.object(M.subprocess, 'run', return_value=self.completed(code, stderr)): + with self.assertRaises(RuntimeError): + M.execute(self.command, self.out, self.out, 'run', mutant=mutant, mode='normal', + mutation='allow_green_ci' if mutant else None) + + def main(self, out, responses, mutants): + with mock.patch.object(sys, 'argv', [str(SCRIPT), '--output', str(out)]): + with mock.patch.object(M, 'MUTANTS', mutants): + with mock.patch.object(M.subprocess, 'run', side_effect=responses) as self.run: + with mock.patch.object(M, 'print', create=True): # keep the success JSON out of test logs + M.main() + + def test_test_count_must_match_exactly(self): + self.assert_refused(0, 'Ran 710 tests\nOK\n', False) + self.assert_refused(1, 'Ran 711 tests\nAssertionError\nFAILED (failures=1)\n', True) + + def test_mutant_requires_every_detection_signal(self): + for code, stderr in [(0, self.DETECTED), (1, 'Ran 71 tests\nFAILED (failures=1)\n'), + (1, 'Ran 71 tests\nAssertionError\nFAILED (errors=1)\n')]: + with self.subTest(code=code, stderr=stderr): + self.assert_refused(code, stderr, True) + + def test_signal_killed_baseline_refused(self): + self.assert_refused(-9, self.BASELINE, False) + + def test_success_replays_both_modes_and_every_mutant(self): + out = self.out / 'ok' + self.main(out, [self.completed(0, self.BASELINE), self.gate(), self.completed(1, self.DETECTED), + self.completed(1, self.DETECTED)] * 2, self.two) + self.assertEqual(self.run.call_count, 8) + self.assertIn('-O', self.run.call_args_list[4].args[0]) + report = json.loads((out / 'REPORT.json').read_text()) + self.assertTrue(report['passed']) + self.assertEqual(report['modes'], ['normal', 'optimized']) + for mode in ('normal', 'optimized'): + for name in self.two: + self.assertTrue((out / ('mutation_' + mode + '_' + name + '.stderr')).is_file()) + + def test_source_change_during_replay_refused(self): + out = self.out / 'drift' + responses = [self.completed(0, self.BASELINE), self.gate(), self.completed(1, self.DETECTED)] * 2 + with mock.patch.object(M, 'identities', side_effect=[{'a': 1}, {'a': 2}]): + with self.assertRaisesRegex(RuntimeError, 'source files changed'): + self.main(out, responses, dict(list(self.two.items())[:1])) + self.assertFalse(json.loads((out / 'REPORT.json').read_text())['passed']) + + def test_output_must_be_new_and_outside_source_before_any_command(self): + packet = self.out / 'packet' + packet.mkdir() + existing = self.out / 'existing' + existing.mkdir() + for out in (packet / 'out', existing): + with self.subTest(out=out.name): + with mock.patch.object(M, 'ROOT', packet): + with self.assertRaisesRegex(RuntimeError, 'new output outside source'): + self.main(out, AssertionError('no command may run'), self.two) + self.assertEqual(self.run.call_count, 0) + + def test_gate_entry_must_exit_zero_with_exact_results(self): + for gate in (self.gate(stdout=b'{}'), self.gate(code=1)): + with self.subTest(code=gate.returncode): + out = self.out / ('gate' + str(gate.returncode)) + with self.assertRaisesRegex(RuntimeError, 'entry/result mismatch'): + self.main(out, [self.completed(0, self.BASELINE), gate], self.two) + self.assertFalse(json.loads((out / 'REPORT.json').read_text())['passed']) + + def test_successful_replay_without_report_fails(self): + real_write = Path.write_text + def fail_report(path, data, *args, **kwargs): + if path.name == 'REPORT.json': + raise OSError('report disk unavailable') + return real_write(path, data, *args, **kwargs) + responses = [self.completed(0, self.BASELINE), self.gate(), self.completed(1, self.DETECTED)] * 2 + with mock.patch.object(Path, 'write_text', fail_report): + with self.assertRaises(OSError): + self.main(self.out / 'noreport', responses, dict(list(self.two.items())[:1])) + + def test_identities_cover_every_packet_file(self): + packet = self.out / 'packet' + for name in ('a.py', 'DATA.json', 'sub/b.md', '__pycache__/c.pyc'): + (packet / name).parent.mkdir(parents=True, exist_ok=True) + (packet / name).write_text(name) + with mock.patch.object(M, 'ROOT', packet): + self.assertEqual(set(M.identities()), {'a.py', 'DATA.json', 'sub/b.md'}) + + +class TransitionAuditRefusalControls(unittest.TestCase): + """Mutation-gap controls for git_transition_audit.py, which the lane runs once on a passing transition.""" + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.repo = Path(self.temp.name) / 'repo' + self.repo.mkdir() + self.git('init', '-q') + self.git('config', 'user.name', 'local test') + self.git('config', 'user.email', 'test@example.invalid') + + def git(self, *args): + return subprocess.run(['git', '-C', str(self.repo), *args], check=True, capture_output=True, text=True).stdout.strip() + + def commit(self, graph, *files): + (self.repo / 'GRAPH.json').write_text(json.dumps(graph)) + for name in ('lemma.md', *files): + (self.repo / name).write_text('bytes of ' + name + '\n') + self.git('add', '.') + self.git('commit', '-qm', 'fixture') + return self.git('rev-parse', 'HEAD') + + @staticmethod + def graph(**extra): + nodes = {'L': {'classification': 'PROVED_REVIEWED', 'controlling': False, 'source': 'lemma.md'}, **extra} + return {'schema_version': 1, 'nodes': nodes, 'edges': []} + + def cli(self, base, head, out): + return subprocess.run([sys.executable, '-B', '-S', str(PACKET / 'git_transition_audit.py'), '--repo', str(self.repo), + '--base', base, '--head', head, '--graph', 'GRAPH.json', '--output', str(out)], + capture_output=True, text=True, timeout=120) + + def test_revision_must_be_full_lowercase_commit(self): + rev = self.commit(self.graph()) + for bad in (rev[:12], rev.upper(), 'HEAD'): + with self.subTest(revision=bad), self.assertRaisesRegex(ValueError, 'immutable commit ID'): + AUDIT.read_snapshot(self.repo, bad, 'GRAPH.json') + with self.assertRaisesRegex(ValueError, 'not a commit'): + AUDIT.read_snapshot(self.repo, self.git('rev-parse', rev + '^{tree}'), 'GRAPH.json') + + def test_blank_source_reference_refused(self): + rev = self.commit(self.graph(W={'classification': 'PROVED_REVIEWED', 'controlling': False, 'source': ' '})) + with self.assertRaisesRegex(ValueError, 'nonempty string'): + AUDIT.read_snapshot(self.repo, rev, 'GRAPH.json') + + def test_non_blob_tree_source_object_refused(self): + rev, real = self.commit(self.graph()), AUDIT.git + def fake(repo, *args, missing=False): + if args[:2] == ('cat-file', '-t') and args[2].endswith(':lemma.md'): + return b'commit\n' + return real(repo, *args, missing=missing) + with mock.patch.object(AUDIT, 'git', side_effect=fake): + with self.assertRaisesRegex(ValueError, 'blob or directory tree'): + AUDIT.read_snapshot(self.repo, rev, 'GRAPH.json') + + def test_unresolved_controlling_source_fails(self): + for source in ('absent.md', 'external:paper'): + with self.subTest(source=source): + graph = self.graph(C={'classification': 'PROVED_REVIEWED', 'controlling': True, 'source': source}) + base, head = self.commit(graph), self.commit(graph, 'unrelated-' + source.replace(':', '_')) + r = AUDIT.audit(self.repo, base, head, 'GRAPH.json') + self.assertEqual((r['controlling_impacted'], r['illegal_controlling']), ([], [])) + self.assertEqual(r['unresolved_controlling_sources'], ['C']) + self.assertFalse(r['check_passed']) + + def test_unchanged_illegal_controlling_fails_and_cli_exits_2(self): + graph = self.graph(X={'classification': 'OPEN_ACTIVE', 'controlling': True, 'source': 'lemma.md'}) + base, head = self.commit(graph), self.commit(graph, 'unrelated.md') + r = AUDIT.audit(self.repo, base, head, 'GRAPH.json') + self.assertEqual((r['controlling_impacted'], r['unresolved_controlling_sources']), ([], [])) + self.assertEqual(len(r['illegal_controlling']), 1) + self.assertFalse(r['check_passed']) + out = Path(self.temp.name) / 'audit.json' + run = self.cli(base, head, out) + self.assertEqual(run.returncode, 2, run.stderr) + self.assertFalse(json.loads(out.read_text())['check_passed']) + + def test_cli_refusals_exit_2_without_output(self): + base, head = self.commit(self.graph()), self.commit(self.graph(), 'unrelated.md') + good = Path(self.temp.name) / 'good.json' + self.assertEqual(self.cli(base, head, good).returncode, 0) + existing = Path(self.temp.name) / 'existing.json' + existing.write_text('keep') + for label, b, out in (('mutable', 'main', Path(self.temp.name) / 'x.json'), ('inside', base, self.repo / 'audit.json'), + ('existing', base, existing)): + with self.subTest(label=label): + run = self.cli(b, head, out) + self.assertEqual(run.returncode, 2, run.stderr) + self.assertIn('TRANSITION_CHECK_REFUSED', run.stderr) + self.assertEqual(out.read_text() if out.exists() else None, 'keep' if label == 'existing' else None) + if __name__ == '__main__': unittest.main() diff --git a/tests/test_required_formal_check.py b/tests/test_required_formal_check.py index 6b6b94e59..83a4d68f5 100644 --- a/tests/test_required_formal_check.py +++ b/tests/test_required_formal_check.py @@ -130,6 +130,45 @@ def test_actual_cli_failure(self): self.assertNotEqual(bad.returncode,0) self.assertNotIn('"conclusion": "success"',bad.stdout) + # Mutation-gap controls: each test refuses a weakening that the tests above still admit. + def test_attempt_identity_is_exact(self): + for value in ('0', '01', 'x', '1 ', ''): + with self.subTest(value=value): + self.env['GITHUB_RUN_ATTEMPT']=value;self.needs['formal']['outputs']['run_attempt']=value + with self.assertRaises(ValueError):self.decision() + with self.assertRaises(ValueError):self.binding() + def test_checkout_head_must_be_tested_commit(self): + with self.assertRaises(ValueError):M.bind_receipt(self.receipt,self.manifest,self.env,'c'*40) + def test_symlinked_receipt_or_manifest_refused(self): + for target in ('receipt','manifest'): + with self.subTest(target=target): + path=getattr(self,target);real=self.root/('real-'+target);real.write_bytes(path.read_bytes()) + path.unlink();path.symlink_to(real) + with self.assertRaises(ValueError):self.binding() + path.unlink();path.write_bytes(real.read_bytes()) + def test_every_receipt_identity_field_required_and_compared(self): + for key,value in (('repository','d6g8k5htny-coder/Math-'),('workflow_run_id','122'),('scientific_effect','POSITIVE')): + with self.subTest(key=key,value=value): + prior=self.record[key];self.record[key]=value;self.write_receipt() + with self.assertRaises(ValueError):self.binding() + self.record[key]=prior + for key in ('checked_commit','repository','workflow_run_id','formalization_status','scientific_effect'): + with self.subTest(missing=key): + prior=self.record.pop(key);self.write_receipt() + with self.assertRaises(ValueError):self.binding() + self.record[key]=prior + def test_receipt_digest_is_an_exact_string(self): + for value in ('b'*65,'b'*64+'\n',int('1'*64)): + self.needs['formal']['outputs']['receipt_sha256']=value + with self.subTest(value=value),self.assertRaises(ValueError):self.decision() + def test_cli_needs_refuse_duplicate_keys(self): + failed=json.dumps({**self.needs['formal'],'result':'failure'}) + text='{"checks":%s,"formal":%s,"formal":%s}'%(json.dumps(self.needs['checks']),failed,json.dumps(self.needs['formal'])) + env={**os.environ,**self.env,'REQUIRED_FORMAL_NEEDS':text} + run=subprocess.run([sys.executable,'-B','-S',str(SCRIPT),'aggregate'],env=env,capture_output=True,text=True) + self.assertNotEqual(run.returncode,0) + self.assertIn('duplicate JSON key',run.stderr) + class WiringTests(unittest.TestCase): def setUp(self): self.is_main=(ROOT/'.github/workflows/workspace-landing.yml').exists() From 85b6c20e54a4c7e04919a04c0a65e2b66850baec Mon Sep 17 00:00:00 2001 From: Grok Bot agent 14 Date: Wed, 7 Oct 2026 21:07:32 -0500 Subject: [PATCH 2/5] tests: optional W7j message/contract-pinning controls (droppable) 8 controls for weakenings that still fail closed but change the exception type, message or refusal order: RV32, RV33, RF08, RF17, RF19, RF23, RF29, GT04. Kept in a separate commit so a reader can drop it without touching the 21 behavioural controls. Test files only. Co-authored-by: Dylan Roy --- tests/test_downstream_validation.py | 18 ++++++++++++++++++ tests/test_required_formal_check.py | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/tests/test_downstream_validation.py b/tests/test_downstream_validation.py index b32bf973c..dee677ec2 100644 --- a/tests/test_downstream_validation.py +++ b/tests/test_downstream_validation.py @@ -355,6 +355,18 @@ def test_gate_entry_must_exit_zero_with_exact_results(self): self.main(out, [self.completed(0, self.BASELINE), gate], self.two) self.assertFalse(json.loads((out / 'REPORT.json').read_text())['passed']) + def test_absent_mutation_anchor_refused(self): + with self.assertRaisesRegex(RuntimeError, 'nonunique mutation'): + self.main(self.out / 'anchor', [self.completed(0, self.BASELINE), self.gate()], + {'absent': ('no such anchor text', 'x')}) + + def test_uncompilable_mutation_refused_before_replay(self): + old = next(iter(M.MUTANTS.values()))[0] + with self.assertRaises(SyntaxError): + self.main(self.out / 'syntax', [self.completed(0, self.BASELINE), self.gate()], {'broken': (old, 'if (:')}) + self.assertEqual(self.run.call_count, 2) + self.assertFalse((self.out / 'syntax' / 'mutants').exists()) + def test_successful_replay_without_report_fails(self): real_write = Path.write_text def fail_report(path, data, *args, **kwargs): @@ -415,6 +427,12 @@ def test_revision_must_be_full_lowercase_commit(self): with self.assertRaisesRegex(ValueError, 'not a commit'): AUDIT.read_snapshot(self.repo, self.git('rev-parse', rev + '^{tree}'), 'GRAPH.json') + def test_each_snapshot_graph_is_validated(self): + graph = self.graph() + graph['nodes']['L']['classification'] = 'NOT_A_CLASSIFICATION' + with self.assertRaises(ValueError): + AUDIT.read_snapshot(self.repo, self.commit(graph), 'GRAPH.json') + def test_blank_source_reference_refused(self): rev = self.commit(self.graph(W={'classification': 'PROVED_REVIEWED', 'controlling': False, 'source': ' '})) with self.assertRaisesRegex(ValueError, 'nonempty string'): diff --git a/tests/test_required_formal_check.py b/tests/test_required_formal_check.py index 83a4d68f5..e87b816af 100644 --- a/tests/test_required_formal_check.py +++ b/tests/test_required_formal_check.py @@ -146,6 +146,10 @@ def test_symlinked_receipt_or_manifest_refused(self): path.unlink();path.symlink_to(real) with self.assertRaises(ValueError):self.binding() path.unlink();path.write_bytes(real.read_bytes()) + def test_non_object_receipt_refused(self): + for text in ('[]','"receipt"','1','null'): + self.receipt.write_text(text) + with self.subTest(text=text),self.assertRaises(ValueError):self.binding() def test_every_receipt_identity_field_required_and_compared(self): for key,value in (('repository','d6g8k5htny-coder/Math-'),('workflow_run_id','122'),('scientific_effect','POSITIVE')): with self.subTest(key=key,value=value): @@ -157,6 +161,20 @@ def test_every_receipt_identity_field_required_and_compared(self): prior=self.record.pop(key);self.write_receipt() with self.assertRaises(ValueError):self.binding() self.record[key]=prior + def test_non_object_log_map_refused(self): + for logs in (['build.log'],'build.log'): + self.record['logs']=logs;self.write_receipt() + with self.subTest(logs=logs),self.assertRaises(ValueError):self.binding() + def test_log_digest_shape_checked_before_log_read(self): + self.record['logs']={'absent.log':'not-a-digest'};self.write_receipt() + with self.assertRaisesRegex(ValueError,'log digest'):self.binding() + def test_nonfinite_json_refused(self): + for text in ('{"a":NaN}','{"a":Infinity}','{"a":-Infinity}'): + with self.subTest(text=text),self.assertRaises(ValueError):M.strict_json(text) + def test_non_object_dependency_outputs_refused(self): + for value in (None,[],'x'): + self.needs['checks']['outputs']=value + with self.subTest(value=value),self.assertRaises(ValueError):self.decision() def test_receipt_digest_is_an_exact_string(self): for value in ('b'*65,'b'*64+'\n',int('1'*64)): self.needs['formal']['outputs']['receipt_sha256']=value From 1a3ab2fdc04371f3f474c3aae0603772bdcab098 Mon Sep 17 00:00:00 2001 From: Grok Bot agent 14 Date: Wed, 7 Oct 2026 23:12:06 -0500 Subject: [PATCH 3/5] tests: AMEND1 for C173-R1/R2/R3 (child mode, Git isolation, resolved ROOT) Test-only amendment answering the C173 AMEND at 85b6c20e (Math-#402 comment 6051938277; threads 4214465273, 4214465286, 4214465290). R1: the two new CLI child launchers (test_cli_needs_refuse_duplicate_keys and TransitionAuditRefusalControls.cli) run the child with -E and the outer optimization level (-O x sys.flags.optimize), so ambient PYTHONOPTIMIZE/PYTHONPATH cannot change the child's mode or imports. R2: TransitionAuditRefusalControls isolates Git: GIT_* scrubbed, GIT_CONFIG_GLOBAL=os.devnull, GIT_CONFIG_NOSYSTEM=1 in os.environ for the fixture, the in-process audit and the child CLI; repo-local commit.gpgSign/tag.gpgSign=false, core.hooksPath=os.devnull, empty template. New control pins this against a hostile signing/hooks/GIT_DIR context. R3: the output-location test mocks ROOT with the resolved packet path and runs under canonical and symlinked spellings of one directory; the no-command and preexisting-output assertions are kept. Co-authored-by: Dylan Roy --- tests/test_downstream_validation.py | 90 +++++++++++++++++++++++------ tests/test_required_formal_check.py | 4 +- 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/tests/test_downstream_validation.py b/tests/test_downstream_validation.py index dee677ec2..c221aa138 100644 --- a/tests/test_downstream_validation.py +++ b/tests/test_downstream_validation.py @@ -1,6 +1,7 @@ """Timeout diagnostics must retain evidence without weakening the replay gate.""" import importlib.util import json +import os from pathlib import Path import subprocess import sys @@ -336,16 +337,19 @@ def test_source_change_during_replay_refused(self): self.assertFalse(json.loads((out / 'REPORT.json').read_text())['passed']) def test_output_must_be_new_and_outside_source_before_any_command(self): - packet = self.out / 'packet' - packet.mkdir() - existing = self.out / 'existing' - existing.mkdir() - for out in (packet / 'out', existing): - with self.subTest(out=out.name): - with mock.patch.object(M, 'ROOT', packet): - with self.assertRaisesRegex(RuntimeError, 'new output outside source'): - self.main(out, AssertionError('no command may run'), self.two) - self.assertEqual(self.run.call_count, 0) + base, link = self.out / 'base', self.out / 'link' + (base / 'packet').mkdir(parents=True) + (base / 'existing').mkdir() + link.symlink_to(base, target_is_directory=True) + for where in (base, link): # canonical and symlinked spellings of one directory + # Production ROOT is resolved (Path(__file__).resolve()); keep that invariant in the mock. + packet = (where / 'packet').resolve() + for out in (where / 'packet' / 'out', where / 'existing'): + with self.subTest(where=where.name, out=out.name): + with mock.patch.object(M, 'ROOT', packet): + with self.assertRaisesRegex(RuntimeError, 'new output outside source'): + self.main(out, AssertionError('no command may run'), self.two) + self.assertEqual(self.run.call_count, 0) def test_gate_entry_must_exit_zero_with_exact_results(self): for gate in (self.gate(stdout=b'{}'), self.gate(code=1)): @@ -387,16 +391,39 @@ def test_identities_cover_every_packet_file(self): self.assertEqual(set(M.identities()), {'a.py', 'DATA.json', 'sub/b.md'}) +def isolated_git_env(environ): + """Fixture Git environment: no ambient GIT_* (GIT_DIR, GIT_CONFIG_PARAMETERS, ...), no global/system config.""" + env = {k: v for k, v in environ.items() if not k.startswith('GIT_')} + env.update(GIT_CONFIG_GLOBAL=os.devnull, GIT_CONFIG_NOSYSTEM='1') + return env + + class TransitionAuditRefusalControls(unittest.TestCase): """Mutation-gap controls for git_transition_audit.py, which the lane runs once on a passing transition.""" def setUp(self): self.temp = tempfile.TemporaryDirectory() self.addCleanup(self.temp.cleanup) - self.repo = Path(self.temp.name) / 'repo' - self.repo.mkdir() - self.git('init', '-q') - self.git('config', 'user.name', 'local test') - self.git('config', 'user.email', 'test@example.invalid') + # The fixture, the in-process audit (AUDIT.git) and the child CLI all inherit this isolated environment. + environ = mock.patch.dict(os.environ) + environ.start() + self.addCleanup(environ.stop) + self.isolate_environ() + self.repo = self.init_repo(Path(self.temp.name) / 'repo') + + @staticmethod + def isolate_environ(): + isolated = isolated_git_env(os.environ) + os.environ.clear() + os.environ.update(isolated) + + def init_repo(self, repo): + repo.mkdir() + run = lambda *a: subprocess.run(['git', '-C', str(repo), *a], check=True, capture_output=True) + run('init', '-q', '--template=') # no template hooks + for key, value in (('user.name', 'local test'), ('user.email', 'test@example.invalid'), + ('commit.gpgSign', 'false'), ('tag.gpgSign', 'false'), ('core.hooksPath', os.devnull)): + run('config', key, value) + return repo def git(self, *args): return subprocess.run(['git', '-C', str(self.repo), *args], check=True, capture_output=True, text=True).stdout.strip() @@ -415,9 +442,38 @@ def graph(**extra): return {'schema_version': 1, 'nodes': nodes, 'edges': []} def cli(self, base, head, out): - return subprocess.run([sys.executable, '-B', '-S', str(PACKET / 'git_transition_audit.py'), '--repo', str(self.repo), + # -E plus the outer optimization level: ambient PYTHON* cannot change the child's mode or imports. + return subprocess.run([sys.executable, '-E', '-B', *(['-O'] * sys.flags.optimize), '-S', + str(PACKET / 'git_transition_audit.py'), '--repo', str(self.repo), '--base', base, '--head', head, '--graph', 'GRAPH.json', '--output', str(out)], - capture_output=True, text=True, timeout=120) + env=dict(os.environ), capture_output=True, text=True, timeout=120) + + def test_fixture_and_audit_ignore_hostile_ambient_git_config(self): + tmp = Path(self.temp.name) + hooks = tmp / 'hostile-hooks' + hooks.mkdir() + (hooks / 'pre-commit').write_text('#!/bin/sh\nexit 1\n') + (hooks / 'pre-commit').chmod(0o755) + hostile = tmp / 'hostile.gitconfig' + hostile.write_text('[commit]\n\tgpgSign = true\n[tag]\n\tgpgSign = true\n' + '[gpg]\n\tprogram = %s\n[core]\n\thooksPath = %s\n' % (tmp / 'no-such-gpg', hooks)) + probe = tmp / 'probe' + probe.mkdir() + bare = lambda *a: subprocess.run(['git', '-C', str(probe), *a], capture_output=True, + env={**os.environ, 'GIT_CONFIG_GLOBAL': str(hostile)}) + for args in (('init', '-q'), ('config', 'user.name', 'p'), ('config', 'user.email', 'p@example.invalid')): + self.assertEqual(bare(*args).returncode, 0) + self.assertNotEqual(bare('commit', '-q', '--allow-empty', '-m', 'x').returncode, 0) # the hostile context bites + os.environ.update(GIT_CONFIG_GLOBAL=str(hostile), GIT_DIR=str(tmp / 'elsewhere.git'), + GIT_INDEX_FILE=str(tmp / 'elsewhere.index')) + self.isolate_environ() + self.repo = self.init_repo(tmp / 'isolated') + graph = self.graph() + base, head = self.commit(graph), self.commit(graph, 'unrelated.md') + self.assertTrue(AUDIT.audit(self.repo, base, head, 'GRAPH.json')['check_passed']) + run = self.cli(base, head, tmp / 'hostile-audit.json') + self.assertEqual(run.returncode, 0, run.stderr) + self.assertFalse((tmp / 'elsewhere.git').exists() or (tmp / 'elsewhere.index').exists()) def test_revision_must_be_full_lowercase_commit(self): rev = self.commit(self.graph()) diff --git a/tests/test_required_formal_check.py b/tests/test_required_formal_check.py index e87b816af..accb6aaab 100644 --- a/tests/test_required_formal_check.py +++ b/tests/test_required_formal_check.py @@ -183,7 +183,9 @@ def test_cli_needs_refuse_duplicate_keys(self): failed=json.dumps({**self.needs['formal'],'result':'failure'}) text='{"checks":%s,"formal":%s,"formal":%s}'%(json.dumps(self.needs['checks']),failed,json.dumps(self.needs['formal'])) env={**os.environ,**self.env,'REQUIRED_FORMAL_NEEDS':text} - run=subprocess.run([sys.executable,'-B','-S',str(SCRIPT),'aggregate'],env=env,capture_output=True,text=True) + # -E: ignore ambient PYTHON* (PYTHONOPTIMIZE, PYTHONPATH, ...); the child runs in the outer mode only. + run=subprocess.run([sys.executable,'-E','-B',*(['-O']*sys.flags.optimize),'-S',str(SCRIPT),'aggregate'], + env=env,capture_output=True,text=True) self.assertNotEqual(run.returncode,0) self.assertIn('duplicate JSON key',run.stderr) From e9ba9fb554d3a086406bfe7a235912b151fce69b Mon Sep 17 00:00:00 2001 From: Dylan Roy <249851642+d6g8k5htny-coder@users.noreply.github.com> Date: Thu, 8 Oct 2026 07:33:40 -0700 Subject: [PATCH 4/5] docs: correct Math required-check test inventory Document 57 tests per mode: 30 original, 16 W8c and 11 W7j. Preserve all executable controls and scientific boundaries. Actual author: OpenAI/Codex correct_formal_test_inventory, delegated by Dylan Roy under M402-DOC-R1-20261008T1428Z. Scientific effect NONE. --- docs/FORMAL_REQUIRED_CHECKS.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/FORMAL_REQUIRED_CHECKS.md b/docs/FORMAL_REQUIRED_CHECKS.md index e4b547c58..ed8eef1bb 100644 --- a/docs/FORMAL_REQUIRED_CHECKS.md +++ b/docs/FORMAL_REQUIRED_CHECKS.md @@ -72,8 +72,10 @@ bundle for this repository and main #188 is preserved in main at ## Validation Run python3 -B -S -m unittest discover -s tests -p test_required_formal_check.py -v -and the same command with -O. Each mode runs forty-six tests. Thirty cover real -CLI success/failure, missing/extra dependencies, all non-success states, stale +and the same command with -O. In this Math- repository, each mode runs +fifty-seven tests: thirty original tests, sixteen W8c controls and eleven W7j +controls. The original thirty cover real CLI success/failure, missing/extra +dependencies, all non-success states, stale commit/run/attempt, repository substitution, malformed identity, modified logs/manifests, duplicate JSON keys and reusable-workflow wiring. Sixteen W8c mutation-gap controls cover the three context() identity bindings: the @@ -82,7 +84,11 @@ empty refused), commit identity (40 lowercase hex accepted; short, long, uppercase, non-hex and non-string refused) and run-ID binding (multi-digit and single nonzero digit accepted; zero, leading zero, non-numeric and empty refused). Their CLI children receive -O exactly when the outer run is optimized, -with any inherited PYTHONOPTIMIZE removed. Hosted negative and positive executions +with any inherited PYTHONOPTIMIZE removed. Eleven W7j mutation-gap controls cover +exact run-attempt identity, tested-checkout binding, receipt/manifest symlinks, +receipt object shape and identity fields, log-map shape and log-digest validation, +non-finite JSON and CLI duplicate keys, dependency-output shape and exact +receipt-digest strings. Hosted negative and positive executions are recorded separately; unit tests alone do not establish platform merge refusal. Official references consulted 27 September 2026: From 357986d90a73f1cdff83e4872cfc433b835e90b1 Mon Sep 17 00:00:00 2001 From: Dylan Roy <249851642+d6g8k5htny-coder@users.noreply.github.com> Date: Thu, 8 Oct 2026 08:50:32 -0700 Subject: [PATCH 5/5] fix: bind downstream replay modes and assertion exit status Require exit 1 for detected mutants and isolate both child constructors from ambient Python settings. Add real child mode/status controls, physical replay-timed source drift, and positive attempt/Math binding subcases while preserving the 57-method required-formal inventory. Refresh only the runner identity; RESULTS remains byte-identical. Actual author: OpenAI/Codex repair_downstream_replay_contract, delegated by Dylan Roy under M402-COMBINED-R1-20261008T1532Z. Scientific effect NONE. --- .../SOURCE_FILES.json | 4 +- .../run_validation.py | 6 +- tests/test_downstream_validation.py | 102 ++++++++++++++++-- tests/test_required_formal_check.py | 21 +++- 4 files changed, 117 insertions(+), 16 deletions(-) diff --git a/frontiers/downstream_gate_20260925/SOURCE_FILES.json b/frontiers/downstream_gate_20260925/SOURCE_FILES.json index c42e11304..62c6c137d 100644 --- a/frontiers/downstream_gate_20260925/SOURCE_FILES.json +++ b/frontiers/downstream_gate_20260925/SOURCE_FILES.json @@ -37,8 +37,8 @@ "sha256": "84b7ad724e4da1c5b4b396c90ae03d4ddedc37771a6e45e1082a45fd80d7ff4a" }, "run_validation.py": { - "bytes": 10454, - "sha256": "ec1d3315b0c21f4608ab7b824f45d7d6e1041555f62e77feeec2bacaa8e5a9f5" + "bytes": 10466, + "sha256": "6b5aa2361e8ce75ce4fc2e76a6386ebdc15e18de567471edefdd8a250f05b59a" }, "test_hard_gate.py": { "bytes": 23161, diff --git a/frontiers/downstream_gate_20260925/run_validation.py b/frontiers/downstream_gate_20260925/run_validation.py index fcf648052..937a91a88 100644 --- a/frontiers/downstream_gate_20260925/run_validation.py +++ b/frontiers/downstream_gate_20260925/run_validation.py @@ -118,7 +118,7 @@ def execute(command, cwd, out, name, mutant=False, *, mode, mutation=None): (out/(name+'.stderr')).write_text(result.stderr) require(f'Ran {EXPECTED_TESTS} tests' in result.stderr and 'skipped=' not in result.stderr, 'unexpected test coverage: '+name) if mutant: - require(result.returncode != 0 and 'AssertionError' in result.stderr and 'FAILED (failures=' in result.stderr, + require(result.returncode == 1 and 'AssertionError' in result.stderr and 'FAILED (failures=' in result.stderr, 'mutation was not detected by a test assertion: '+name) require('SyntaxError' not in result.stderr and 'ImportError' not in result.stderr and '\nERROR:' not in result.stderr, 'mutation caused a program error: '+name) @@ -140,9 +140,9 @@ def main(): 'meaning': 'software replay and mutation detection only; not independent analytic acceptance'} try: for mode, flags in [('normal', []), ('optimized', ['-O'])]: - cmd = [sys.executable, '-B', *flags, '-S', '-m', 'unittest', 'discover', '-p', 'test_*.py', '-v'] + cmd = [sys.executable, '-E', '-B', *flags, '-S', '-m', 'unittest', 'discover', '-p', 'test_*.py', '-v'] execute(cmd, ROOT, out, 'tests_'+mode, mode=mode) - result = subprocess.run([sys.executable, '-B', *flags, '-S', 'hard_gate.py'], cwd=ROOT, capture_output=True, timeout=15) + result = subprocess.run([sys.executable, '-E', '-B', *flags, '-S', 'hard_gate.py'], cwd=ROOT, capture_output=True, timeout=15) require(result.returncode == 0 and result.stdout == (ROOT/'RESULTS.json').read_bytes(), 'entry/result mismatch: '+mode) (out/('output_'+mode+'.json')).write_bytes(result.stdout) for name, (old, new) in MUTANTS.items(): diff --git a/tests/test_downstream_validation.py b/tests/test_downstream_validation.py index c221aa138..d828f3d4e 100644 --- a/tests/test_downstream_validation.py +++ b/tests/test_downstream_validation.py @@ -3,6 +3,8 @@ import json import os from pathlib import Path +import shutil +import signal import subprocess import sys import tempfile @@ -307,7 +309,8 @@ def test_test_count_must_match_exactly(self): self.assert_refused(1, 'Ran 711 tests\nAssertionError\nFAILED (failures=1)\n', True) def test_mutant_requires_every_detection_signal(self): - for code, stderr in [(0, self.DETECTED), (1, 'Ran 71 tests\nFAILED (failures=1)\n'), + for code, stderr in [(0, self.DETECTED), (2, self.DETECTED), (-9, self.DETECTED), + (1, 'Ran 71 tests\nFAILED (failures=1)\n'), (1, 'Ran 71 tests\nAssertionError\nFAILED (errors=1)\n')]: with self.subTest(code=code, stderr=stderr): self.assert_refused(code, stderr, True) @@ -320,21 +323,106 @@ def test_success_replays_both_modes_and_every_mutant(self): self.main(out, [self.completed(0, self.BASELINE), self.gate(), self.completed(1, self.DETECTED), self.completed(1, self.DETECTED)] * 2, self.two) self.assertEqual(self.run.call_count, 8) - self.assertIn('-O', self.run.call_args_list[4].args[0]) + for offset, flags in ((0, []), (4, ['-O'])): + prefix = [sys.executable, '-E', '-B', *flags, '-S'] + tests = prefix + ['-m', 'unittest', 'discover', '-p', 'test_*.py', '-v'] + for index in (0, 2, 3): # baseline and every selected mutant + self.assertEqual(self.run.call_args_list[offset + index].args[0], tests) + self.assertEqual(self.run.call_args_list[offset + 1].args[0], prefix + ['hard_gate.py']) report = json.loads((out / 'REPORT.json').read_text()) self.assertTrue(report['passed']) self.assertEqual(report['modes'], ['normal', 'optimized']) + self.assertTrue(report['sources_unchanged']) + self.assertEqual(report['source_files'], M.identities()) for mode in ('normal', 'optimized'): for name in self.two: self.assertTrue((out / ('mutation_' + mode + '_' + name + '.stderr')).is_file()) + def test_actual_child_modes_ignore_ambient_optimization(self): + # Capture both production constructors; replace only their payloads. + # These real diagnostic children do not run the 71-test packet. + out = self.out / 'mode-commands' + responses = [self.completed(0, self.BASELINE), self.gate(), self.completed(1, self.DETECTED)] * 2 + self.main(out, responses, dict(list(self.two.items())[:1])) + calls = self.run.call_args_list + for offset, expected in ((0, 0), (3, 1)): + tests = calls[offset].args[0] + gate = calls[offset + 1].args[0] + prefixes = {'tests_and_mutants': tests[:tests.index('-m')], 'hard_gate': gate[:-1]} + for constructor, prefix in prefixes.items(): + for ambient in (None, '0', '1', '2'): + with self.subTest(expected=expected, constructor=constructor, ambient=ambient): + env = {key: value for key, value in os.environ.items() + if key not in ('PYTHONOPTIMIZE', 'PYTHONHOME', 'PYTHONPATH')} + if ambient is not None: + env['PYTHONOPTIMIZE'] = ambient + child = subprocess.run(prefix + ['-c', 'import sys; print(sys.flags.optimize)'], + env=env, capture_output=True, text=True, timeout=10) + self.assertEqual(child.returncode, 0, child.stderr) + self.assertEqual(child.stderr, '') + self.assertEqual(child.stdout, str(expected) + '\n') + + def test_real_child_exit_status_distinguishes_assertions_from_abnormal_termination(self): + # All mutant children emit identical synthetic unittest-shaped text. + # Their actual exit status, not that text, distinguishes termination. + real_run = subprocess.run + cases = [('zero', 0, True), ('assertion', 1, True), ('abnormal', 2, True), + ('signal', -signal.SIGKILL, True), ('baseline_signal', -signal.SIGKILL, False)] + for label, code, mutant in cases: + with self.subTest(label=label): + end = ('os.kill(os.getpid(), signal.SIGKILL)' if code < 0 else 'sys.exit(' + str(code) + ')') + payload = 'import os, signal, sys; sys.stderr.write(' + repr(self.DETECTED) + '); sys.stderr.flush(); ' + end + command = [sys.executable, '-E', '-B', '-S', '-c', payload] + observed = [] + def run(*args, **kwargs): + child = real_run(*args, **kwargs) + observed.append(child) + return child + accepted = True + with mock.patch.object(M.subprocess, 'run', side_effect=run): + try: + M.execute(command, self.out, self.out, label, mutant=mutant, + mode='normal', mutation='controlled_stderr' if mutant else None) + except RuntimeError: + accepted = False + self.assertEqual(len(observed), 1) + self.assertEqual(observed[0].returncode, code) + self.assertEqual(observed[0].stderr, self.DETECTED) + self.assertEqual((self.out / (label + '.stderr')).read_text(), self.DETECTED) + self.assertEqual(accepted, mutant and code == 1) + def test_source_change_during_replay_refused(self): out = self.out / 'drift' - responses = [self.completed(0, self.BASELINE), self.gate(), self.completed(1, self.DETECTED)] * 2 - with mock.patch.object(M, 'identities', side_effect=[{'a': 1}, {'a': 2}]): - with self.assertRaisesRegex(RuntimeError, 'source files changed'): - self.main(out, responses, dict(list(self.two.items())[:1])) - self.assertFalse(json.loads((out / 'REPORT.json').read_text())['passed']) + packet = self.out / 'packet' + shutil.copytree(M.ROOT, packet, ignore=shutil.ignore_patterns('__pycache__')) + original_identities = M.identities + commands = 0 + snapshots = [] + def identities(): + snapshot = original_identities() + snapshots.append((commands, snapshot)) + return snapshot + with mock.patch.object(M, 'ROOT', packet): + responses = [self.completed(0, self.BASELINE), self.gate(), self.completed(1, self.DETECTED)] * 2 + def replay(*args, **kwargs): + nonlocal commands + commands += 1 + if commands == 1: + source = packet / 'README.md' + source.write_bytes(source.read_bytes() + b'\nPhysical mid-replay drift fixture.\n') + return responses[commands - 1] + with mock.patch.object(M, 'identities', side_effect=identities): + with self.assertRaisesRegex(RuntimeError, 'source files changed'): + self.main(out, replay, dict(list(self.two.items())[:1])) + self.assertEqual(commands, 6) + self.assertEqual([count for count, _ in snapshots], [0, 6]) + self.assertNotEqual(snapshots[0][1]['README.md'], snapshots[1][1]['README.md']) + report = json.loads((out / 'REPORT.json').read_text()) + self.assertFalse(report['passed']) + self.assertNotIn('sources_unchanged', report) + self.assertNotIn('source_files', report) + self.assertFalse(report['promotion_permission']) + self.assertEqual(report['scientific_effect'], 'NONE') def test_output_must_be_new_and_outside_source_before_any_command(self): base, link = self.out / 'base', self.out / 'link' diff --git a/tests/test_required_formal_check.py b/tests/test_required_formal_check.py index 051efa4a6..45b1961e6 100644 --- a/tests/test_required_formal_check.py +++ b/tests/test_required_formal_check.py @@ -94,10 +94,18 @@ def test_bad_digest(self): self.needs['formal']['outputs']['receipt_sha256']=value with self.subTest(value=value),self.assertRaises(ValueError):self.decision() def test_binding_preserves_receipt(self): - before=self.receipt.read_bytes(); result=self.binding() - self.assertEqual(self.receipt.read_bytes(),before) - self.assertEqual(result['receipt_sha256'],hashlib.sha256(before).hexdigest()) - self.assertEqual(result['run_attempt'],'2') + for repository in ('d6g8k5htny-coder/main', 'd6g8k5htny-coder/Math-'): + with self.subTest(repository=repository): + self.env['GITHUB_REPOSITORY']=repository + self.record['repository']=repository + self.needs['formal']['outputs']['repository']=repository + self.write_receipt() + before=self.receipt.read_bytes(); result=self.binding() + self.assertEqual(self.receipt.read_bytes(),before) + self.assertEqual(result['repository'],repository) + self.assertEqual(result['receipt_sha256'],hashlib.sha256(before).hexdigest()) + self.assertEqual(result['run_attempt'],'2') + self.assertEqual(self.decision()['repository'],repository) def test_unproved_receipt_refused(self): self.record['formalization_status']='specified';self.write_receipt() with self.assertRaises(ValueError):self.binding() @@ -132,6 +140,11 @@ def test_actual_cli_failure(self): # Mutation-gap controls: each test refuses a weakening that the tests above still admit. def test_attempt_identity_is_exact(self): + for value in ('2', '10'): + self.env['GITHUB_RUN_ATTEMPT']=value;self.needs['formal']['outputs']['run_attempt']=value + for operation, check in (('aggregate', self.decision), ('bind_receipt', self.binding)): + with self.subTest(accepted_attempt=value, operation=operation): + self.assertEqual(check()['run_attempt'],value) for value in ('0', '01', 'x', '1 ', ''): with self.subTest(value=value): self.env['GITHUB_RUN_ATTEMPT']=value;self.needs['formal']['outputs']['run_attempt']=value