Seal Phase 4AP isolated delta interface PASS, not learning
This commit is contained in:
@@ -0,0 +1,290 @@
|
||||
"""CPU-only temporary evidence trees; no real AP/brain execution."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
import publish_phase4ap as P
|
||||
|
||||
|
||||
_candidates = (
|
||||
Path(__file__).resolve().parents[1] / 'pn-recruitment-audit-v1/publication.py',
|
||||
Path(__file__).resolve().parents[2] / P.HELPER_REL,
|
||||
)
|
||||
HELPER = next((path for path in _candidates if path.is_file()), _candidates[0])
|
||||
|
||||
|
||||
def put(path, value):
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
raw = value if isinstance(value, bytes) else (json.dumps(value, sort_keys=True) + '\n').encode()
|
||||
path.write_bytes(raw)
|
||||
return P.digest(path)
|
||||
|
||||
|
||||
def read(path):
|
||||
return json.loads(path.read_text(encoding='utf-8'))
|
||||
|
||||
|
||||
def seal(directory):
|
||||
files = [r for r in P.file_rows(directory) if r['path'] not in ('manifest.json', 'checksums.sha256')]
|
||||
put(directory / 'manifest.json', dict(root=str(directory), files=files))
|
||||
raw = ''.join(row['sha256'] + ' ' + row['path'] + '\n' for row in files)
|
||||
put(directory / 'checksums.sha256', (raw + P.digest(directory / 'manifest.json') + ' manifest.json\n').encode())
|
||||
|
||||
|
||||
class PublicationTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.temp = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self.temp.cleanup)
|
||||
self.root = Path(self.temp.name).resolve()
|
||||
self.exp, self.registry, self.model = (self.root / rel for rel in (P.EXP_REL, P.REGISTRY_REL, P.MODEL_REL))
|
||||
put(self.root / P.HELPER_REL, HELPER.read_bytes())
|
||||
|
||||
def fixture(self, status='PASS-EXACT-PROCESS-ISOLATED-DELTA-INTERFACE-NOT-LEARNING'):
|
||||
sources, prepared = {}, {}
|
||||
for name in P.SOURCE_FILES:
|
||||
raw = ('# synthetic only: ' + name).encode()
|
||||
checksum = put(self.model / name, raw)
|
||||
snapshot = self.exp / P.SNAPSHOT / name
|
||||
put(snapshot, raw)
|
||||
sources[str(self.model / name)] = prepared[str(snapshot)] = checksum
|
||||
slots = []
|
||||
for arm in ('D1', 'D0', 'frozen'):
|
||||
for mode in ('reference', 'light'):
|
||||
for epoch in (0, 1):
|
||||
name = f'{arm}--{mode}--epoch-{epoch:03d}'
|
||||
imported = name == P.FIRST
|
||||
base = self.root / (P.AO_REL if imported else P.EXP_REL)
|
||||
slots.append(dict(row_id=name, steps=1200, origin='imported_sealed_AO_neural_trajectory' if imported else 'new_AP_neural_execution',
|
||||
neural_dir=str(base / 'runs' / name), case_dir=str(base / 'cases' / name),
|
||||
original_case_dir=str(self.root / P.AO_REL / 'cases' / name)))
|
||||
self.reg = dict(schema='phase4ap-process-isolated-interface-v1', source_sha256=sources,
|
||||
prepared_file_sha256=prepared, source_code_commit='5' * 40, slots=slots,
|
||||
covered_slots=12, new_neural_calls=11, covered_ticks=14400, new_neural_ticks=13200, new_sampler_calls=0,
|
||||
imported_slot=P.FIRST, imported_checkpoint_sha256='e' * 64,
|
||||
anchors={str(self.root / P.AO_REL / 'runs' / P.FIRST / 'checkpoint-manifest.json'): 'e' * 64},
|
||||
original_failed_workflow_reclassified=False, original_AO_process_complete=False,
|
||||
inherited_neural_checkpoint_complete=True, full_conditioning=False, learning_success_claimed=False,
|
||||
within_trial_updates=False, retention_transition_supported=False)
|
||||
self.analysis = dict(status=status, covered_slots=12, new_neural_calls=11,
|
||||
imported_neural_trajectories=1, new_sampler_calls=0, original_AO_status=P.AO_STATUS,
|
||||
learned_candidate=False, learning_success_claimed=False, full_conditioning_executed=False)
|
||||
self.analysis_path = P.ANALYSES[1 if status.startswith('FAIL') else 0]
|
||||
self.final = {k: v for k, v in self.analysis.items() if k != 'original_AO_status'}
|
||||
self.final['AO_failure_preserved'] = True
|
||||
put(self.exp / 'logs/first.log', b'complete evidence, not learning\n')
|
||||
put(self.exp / 'runs/new/state.npz', b'bulk remains here')
|
||||
put(self.exp / 'runs/new/hash.jsonl', b'{}\n')
|
||||
put(self.exp / 'extension-build/source.py', b'build source not evidence')
|
||||
put(self.exp / 'large.json', b' ' * (P.MAX_BYTES + 1))
|
||||
put(self.exp / 'protocol/full-trial-plan.json', {'not_exported_even_if_small': True})
|
||||
self.refresh()
|
||||
|
||||
def refresh(self):
|
||||
reg_sha = put(self.exp / P.REGISTRATION, self.reg)
|
||||
self.analysis['registration_sha256'] = reg_sha
|
||||
self.final['registration_sha256'] = reg_sha
|
||||
self.final['analysis_sha256'] = put(self.exp / self.analysis_path, self.analysis)
|
||||
put(self.exp / P.FINAL, self.final)
|
||||
seal(self.exp)
|
||||
self.anchors = (reg_sha, P.digest(self.exp / 'manifest.json'), P.digest(self.exp / P.FINAL))
|
||||
|
||||
def publish(self, anchors=None):
|
||||
return P.publish(*(anchors or self.anchors), root=self.root)
|
||||
|
||||
def test_success_independent_seal_exact_copy_and_omitted_inventory(self):
|
||||
self.fixture()
|
||||
prior = P.file_rows(self.exp)
|
||||
result = self.publish()
|
||||
self.assertTrue(result['publication_complete'])
|
||||
self.assertEqual(result['source_count'], 5)
|
||||
self.assertFalse(result['complete_bulk_backup'])
|
||||
helper = P.load_helper(self.root / P.HELPER_REL)
|
||||
registry_seal = helper.verify_seal(self.registry)
|
||||
self.assertEqual(registry_seal['manifest_sha256'], result['registry_manifest_sha256'])
|
||||
self.assertEqual(result['receipt_sha256'], P.digest(self.registry / 'publication-receipt.json'))
|
||||
receipt = read(self.registry / 'publication-receipt.json')
|
||||
self.assertEqual(receipt['source_origin']['declared_final_counts']['new_neural_calls'], 11)
|
||||
self.assertEqual(receipt['source_origin']['original_AO_status'], P.AO_STATUS)
|
||||
self.assertFalse(receipt['source_origin']['imported_bulk_independently_reverified'])
|
||||
self.assertFalse(receipt['learning_achieved'])
|
||||
for row in receipt['files']:
|
||||
self.assertEqual(P.digest(self.registry / row['path']), row['sha256'])
|
||||
inventory = read(self.registry / 'artifact-inventory.json')['files']
|
||||
self.assertEqual({r['path'] for r in prior}, {r['path'] for r in inventory})
|
||||
for row in inventory:
|
||||
self.assertEqual(row['sha256'], P.digest(self.exp / row['path']))
|
||||
indexed = {r['path']: r for r in inventory}
|
||||
for name in ('runs/new/state.npz', 'runs/new/hash.jsonl', 'extension-build/source.py',
|
||||
'large.json', 'protocol/full-trial-plan.json'):
|
||||
self.assertEqual(indexed[name]['disposition'], 'omitted')
|
||||
self.assertTrue((self.registry / 'source-snapshot/coordinator.py').is_file())
|
||||
self.assertEqual((self.registry / 'evidence/manifest.json').read_bytes(), (self.exp / 'manifest.json').read_bytes())
|
||||
self.assertEqual((self.registry / 'evidence/checksums.sha256').read_bytes(), (self.exp / 'checksums.sha256').read_bytes())
|
||||
self.assertTrue(all(p.stat().st_size <= P.MAX_BYTES for p in self.registry.rglob('*') if p.is_file()))
|
||||
self.assertEqual(prior, P.file_rows(self.exp))
|
||||
|
||||
def test_incomplete_and_failed_status_are_not_upgraded(self):
|
||||
for status in ('INCOMPLETE-NO-NONZERO-UPDATE-COVERAGE', 'FAIL-CHILD-PROCESS'):
|
||||
with self.subTest(status=status):
|
||||
# Separate exclusive trees; no deletion/retry of a publication.
|
||||
with tempfile.TemporaryDirectory() as temp:
|
||||
self.root = Path(temp).resolve()
|
||||
self.exp, self.registry, self.model = (self.root / rel for rel in (P.EXP_REL, P.REGISTRY_REL, P.MODEL_REL))
|
||||
put(self.root / P.HELPER_REL, HELPER.read_bytes())
|
||||
self.fixture(status)
|
||||
if status.startswith('FAIL'):
|
||||
for value in (self.final, self.analysis):
|
||||
value.update(covered_slots=1, new_neural_calls=0)
|
||||
self.refresh()
|
||||
result = self.publish()
|
||||
self.assertEqual(result['declared_audit_status'], status)
|
||||
self.assertFalse(result['scientific_gate_certified_by_publication'])
|
||||
|
||||
def test_three_anchors_are_required_and_rechecked(self):
|
||||
self.fixture()
|
||||
for index in range(3):
|
||||
values = list(self.anchors); values[index] = '0' * 64
|
||||
with self.subTest(index=index), self.assertRaisesRegex(ValueError, 'External anchor mismatch'):
|
||||
self.publish(values)
|
||||
with self.assertRaisesRegex(ValueError, 'mandatory'):
|
||||
self.publish(['', self.anchors[1], self.anchors[2]])
|
||||
self.assertFalse(self.registry.exists())
|
||||
|
||||
def test_missing_final_or_unsealed_tree_refuses_publication(self):
|
||||
self.fixture()
|
||||
(self.exp / P.FINAL).unlink()
|
||||
with self.assertRaises(ValueError):
|
||||
self.publish()
|
||||
put(self.exp / P.FINAL, self.final)
|
||||
(self.exp / 'checksums.sha256').unlink()
|
||||
with self.assertRaises(ValueError):
|
||||
self.publish()
|
||||
self.assertFalse(self.registry.exists())
|
||||
|
||||
def test_existing_registry_is_untouched(self):
|
||||
self.fixture()
|
||||
marker = self.registry / 'keep.txt'; put(marker, b'keep')
|
||||
with self.assertRaisesRegex(ValueError, 'never overwrite'):
|
||||
self.publish()
|
||||
self.assertEqual(marker.read_bytes(), b'keep')
|
||||
self.assertEqual(len(list(self.registry.iterdir())), 1)
|
||||
|
||||
def test_source_mutation_and_extra_or_missing_inventory_fail(self):
|
||||
self.fixture()
|
||||
put(self.model / 'coordinator.py', b'# different')
|
||||
with self.assertRaisesRegex(ValueError, 'differ'):
|
||||
self.publish()
|
||||
put(self.model / 'coordinator.py', (self.exp / P.SNAPSHOT / 'coordinator.py').read_bytes())
|
||||
put(self.exp / P.SNAPSHOT / 'extra.py', b'# extra')
|
||||
seal(self.exp)
|
||||
anchors = (self.anchors[0], P.digest(self.exp / 'manifest.json'), self.anchors[2])
|
||||
with self.assertRaisesRegex(ValueError, 'inventory differs'):
|
||||
self.publish(anchors)
|
||||
|
||||
def test_resealed_snapshot_disagrees_with_registered_source(self):
|
||||
self.fixture()
|
||||
put(self.exp / P.SNAPSHOT / 'coordinator.py', b'# altered snapshot')
|
||||
seal(self.exp)
|
||||
with self.assertRaisesRegex(ValueError, 'differ'):
|
||||
self.publish((self.anchors[0], P.digest(self.exp / 'manifest.json'), self.anchors[2]))
|
||||
|
||||
def test_import_cannot_be_reclassified_as_new_or_AO_success(self):
|
||||
self.fixture()
|
||||
self.reg['slots'][0]['origin'] = 'new_AP_neural_execution'; self.refresh()
|
||||
with self.assertRaisesRegex(ValueError, 'slot provenance'):
|
||||
self.publish()
|
||||
self.reg['slots'][0]['origin'] = 'imported_sealed_AO_neural_trajectory'
|
||||
self.analysis['original_AO_status'] = 'PASS'; self.refresh()
|
||||
with self.assertRaisesRegex(ValueError, 'reclassify AO'):
|
||||
self.publish()
|
||||
|
||||
def test_missing_duplicate_slot_and_source_escape_fail(self):
|
||||
self.fixture()
|
||||
self.reg['slots'][-1] = dict(self.reg['slots'][0]); self.refresh()
|
||||
with self.assertRaisesRegex(ValueError, 'coverage/order'):
|
||||
self.publish()
|
||||
self.reg['slots'][-1]['row_id'] = 'frozen--light--epoch-001'
|
||||
self.reg['slots'][-1]['origin'] = 'new_AP_neural_execution'
|
||||
self.reg['slots'][-1]['neural_dir'] = str(self.exp / 'runs/frozen--light--epoch-001')
|
||||
self.reg['slots'][-1]['case_dir'] = str(self.exp / 'cases/frozen--light--epoch-001')
|
||||
self.reg['slots'][-1]['original_case_dir'] = str(self.root / P.AO_REL / 'cases/frozen--light--epoch-001')
|
||||
key = str(self.model / 'coordinator.py')
|
||||
self.reg['source_sha256'][str(self.root / 'elsewhere/coordinator.py')] = self.reg['source_sha256'].pop(key)
|
||||
self.refresh()
|
||||
with self.assertRaisesRegex(ValueError, 'exactly five'):
|
||||
self.publish()
|
||||
|
||||
def test_learning_claim_or_inconsistent_declared_count_rejected(self):
|
||||
self.fixture()
|
||||
self.analysis['learning_success_claimed'] = True; self.refresh()
|
||||
with self.assertRaisesRegex(ValueError, 'No-learning'):
|
||||
self.publish()
|
||||
self.analysis['learning_success_claimed'] = False
|
||||
self.analysis['new_neural_calls'] = 12; self.refresh()
|
||||
with self.assertRaisesRegex(ValueError, 'declared count'):
|
||||
self.publish()
|
||||
|
||||
def test_final_analysis_link_and_helper_pin_rejected(self):
|
||||
self.fixture()
|
||||
self.final['analysis_sha256'] = '0' * 64
|
||||
put(self.exp / P.FINAL, self.final); seal(self.exp)
|
||||
anchors = (self.anchors[0], P.digest(self.exp / 'manifest.json'), P.digest(self.exp / P.FINAL))
|
||||
with self.assertRaisesRegex(ValueError, 'analysis SHA'):
|
||||
self.publish(anchors)
|
||||
put(self.root / P.HELPER_REL, b'# not the pinned helper')
|
||||
with self.assertRaisesRegex(ValueError, 'helper SHA mismatch'):
|
||||
self.publish(anchors)
|
||||
|
||||
def test_unlisted_payload_or_corrupt_checksums_refused(self):
|
||||
self.fixture()
|
||||
put(self.exp / 'unlisted.txt', b'not registered')
|
||||
with self.assertRaisesRegex(ValueError, 'unlisted'):
|
||||
self.publish()
|
||||
(self.exp / 'unlisted.txt').unlink()
|
||||
with (self.exp / 'checksums.sha256').open('ab') as stream:
|
||||
stream.write(b'bad\n')
|
||||
with self.assertRaisesRegex(ValueError, 'Malformed checksums'):
|
||||
self.publish()
|
||||
|
||||
def test_postcopy_bulk_change_is_caught_without_deleting_partial_registry(self):
|
||||
self.fixture()
|
||||
helper = P.load_helper(self.root / P.HELPER_REL)
|
||||
original = helper._copy_verified
|
||||
changed = False
|
||||
def copy_and_mutate(*args):
|
||||
nonlocal changed
|
||||
original(*args)
|
||||
if not changed:
|
||||
changed = True
|
||||
put(self.exp / 'runs/new/state.npz', b'mutated omitted bulk')
|
||||
with mock.patch.object(helper, '_copy_verified', side_effect=copy_and_mutate), mock.patch.object(P, 'load_helper', return_value=helper):
|
||||
with self.assertRaisesRegex(ValueError, 'Payload byte count|Payload SHA'):
|
||||
self.publish()
|
||||
self.assertTrue(read(self.registry / 'publication-failure.json')['partial_outputs_preserved'])
|
||||
self.assertFalse((self.registry / 'publication-receipt.json').exists())
|
||||
with self.assertRaisesRegex(ValueError, 'never overwrite'):
|
||||
self.publish()
|
||||
|
||||
def test_external_manifest_race_and_registry_mutation_detected(self):
|
||||
self.fixture()
|
||||
helper = P.load_helper(self.root / P.HELPER_REL)
|
||||
original = helper.verify_seal
|
||||
def new_seal(directory):
|
||||
put(self.exp / 'logs/first.log', b'changed before full verification')
|
||||
seal(self.exp)
|
||||
return original(directory)
|
||||
with mock.patch.object(helper, 'verify_seal', side_effect=new_seal), mock.patch.object(P, 'load_helper', return_value=helper):
|
||||
with self.assertRaisesRegex(ValueError, 'differs from external'):
|
||||
self.publish()
|
||||
self.assertFalse(self.registry.exists())
|
||||
self.anchors = (self.anchors[0], P.digest(self.exp / 'manifest.json'), self.anchors[2])
|
||||
self.publish()
|
||||
put(self.registry / 'source-snapshot/coordinator.py', b'changed')
|
||||
with self.assertRaisesRegex(ValueError, 'Payload byte count|Payload SHA'):
|
||||
helper.verify_seal(self.registry)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user