Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m58s
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3
65 lines
2.8 KiB
Python
65 lines
2.8 KiB
Python
"""Body-resource evidence must bind both source bytes and the prepared pages."""
|
|
|
|
import hashlib
|
|
import importlib.util
|
|
import json
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from tests.test_bubble_visuals import PNG, bundle, visuals
|
|
|
|
SPEC = importlib.util.spec_from_file_location(
|
|
'body_resources',
|
|
Path(__file__).resolve().parents[1] / 'scripts/verify-bubble-body-resources.py')
|
|
resources = importlib.util.module_from_spec(SPEC)
|
|
SPEC.loader.exec_module(resources)
|
|
|
|
|
|
def prepared(tmp_path):
|
|
source, report, _ = bundle(tmp_path)
|
|
raw = json.dumps({'missing': {}}).encode()
|
|
visuals.publish(source, 'source-capture/retained_spaces.json', raw)
|
|
report['source_sha256']['retained_spaces'] = hashlib.sha256(raw).hexdigest()
|
|
(source / 'reconciliation.json').write_text(json.dumps(report))
|
|
out = tmp_path / 'visual'
|
|
visuals.capture(source, out, lambda _: (PNG, 'png'))
|
|
return source, out
|
|
|
|
|
|
def test_resource_proof_preserves_scope_and_never_accepts_productive_fidelity(tmp_path):
|
|
source, out = prepared(tmp_path)
|
|
summary, private = resources.verify(source, out)
|
|
assert summary['captured_articles'] == 3
|
|
assert summary['source_bodies_verified'] == 3
|
|
assert summary['prepared_pages_verified'] == 2
|
|
assert summary['network_requests'] == 0
|
|
assert not summary['productive_fidelity_accepted']
|
|
assert not summary['live_destinations_checked']
|
|
assert not summary['production_imported']
|
|
assert len(private['fresh_space_blockers']) == 2
|
|
|
|
|
|
@pytest.mark.parametrize('defect', ['source-drift', 'sidecar-drift', 'prepared-body-drift',
|
|
'original-report-drift', 'original-draft-drift'])
|
|
def test_resource_proof_refuses_source_or_prepared_drift(tmp_path, defect):
|
|
source, out = prepared(tmp_path)
|
|
if defect == 'source-drift':
|
|
(source / 'source-capture/articles.json').write_text('{}')
|
|
elif defect == 'sidecar-drift':
|
|
next((source / 'source-bodies').glob('*.txt')).write_text('Changed')
|
|
elif defect == 'original-draft-drift':
|
|
next((source / 'review-trees').glob('*/pages/*.md')).write_text('Changed')
|
|
elif defect == 'original-report-drift':
|
|
p = source / 'reconciliation.json'
|
|
p.write_text(p.read_text() + '\n')
|
|
else:
|
|
report = json.loads((out / 'reconciliation.json').read_text())
|
|
name = next(p['file'] for s in report['spaces'] for p in s['articles'] if p['file'])
|
|
changed = (out / name).read_bytes() + b'Changed'
|
|
(out / name).write_bytes(changed)
|
|
# Even a matching prepared-file hash cannot authorize a changed source body.
|
|
report['file_sha256'][name] = hashlib.sha256(changed).hexdigest()
|
|
(out / 'reconciliation.json').write_text(json.dumps(report))
|
|
with pytest.raises(ValueError):
|
|
resources.verify(source, out)
|