208 lines
21 KiB
Python
208 lines
21 KiB
Python
"""Create a distinct reviewer; this generator launches no application or package helper."""
|
|
from pathlib import Path
|
|
import ast
|
|
import hashlib
|
|
import json
|
|
|
|
OUT = Path(__file__).resolve().parent
|
|
ROOT = OUT.parents[1]
|
|
OLD = ROOT / '.local/contextual-prerelease-review-20260911/review.py'
|
|
PREP = ROOT / '.local/nav-repair-retry-20260911'
|
|
raw = OLD.read_text(encoding='utf-8')
|
|
raw = raw.replace("PREP = ROOT / '.local/contextual-prerelease-20260911'", "PREP = ROOT / '.local/nav-repair-retry-20260911'")
|
|
raw = raw.replace('0.2.0-preview.contextual.20260911', '0.2.0-preview.navigation.20260911')
|
|
raw = raw.replace('b2c3e54001fc19a05423bcd5808ceea78d13ff59', '33c6d83e9ba9a5b1310b1b627d7c40affcbcf15c')
|
|
raw = raw.replace('5657bab5c841939b66f901efe6c0ffb2d7cbbe8cc5f111a0ca3de8073d3846ce', 'b183ef31f16b3986538b3f2aba8435eab45978635c47f99ca01be6e72b168848')
|
|
raw = raw.replace('cwd=ROOT, capture_output=True, check=True).stdout', 'cwd=SOURCE, capture_output=True, check=True).stdout')
|
|
raw = raw.replace('Independent contextual package persistence', 'Independent navigation package persistence')
|
|
raw = raw.replace("def artifact():\n", "def artifact():\n for name, h in FROZEN['producer_records'].items():\n check(sha((PREP / name).read_bytes()) == h, 'frozen producer record: ' + name)\n")
|
|
raw = raw.replace(" actual = file_map(PACKAGE)\n", " actual = file_map(PACKAGE)\n producer = read_json(PREP / 'package-readback.json')\n check(producer['status'] == 'PASS' and {p: v['sha256'] for p, v in producer['files'].items()} == actual, 'independent extraction equals complete frozen producer readback')\n", 1)
|
|
raw = raw.replace(" package = read_json(PACKAGE / 'package.json')\n", " companion = ZIP.with_suffix('.zip.sha256').read_text(encoding='utf-8').split()\n check(companion == [EXPECTED_ZIP, ZIP.name], 'companion checksum binds exact archive')\n package = read_json(PACKAGE / 'package.json')\n", 1)
|
|
start = raw.index('def provenance():')
|
|
end = raw.index('\n\ndef notices(actual):', start)
|
|
old_provenance = raw[start:end]
|
|
lock_checks = old_provenance[old_provenance.index(' old_manifest ='):old_provenance.index(' evidence =')]
|
|
new_provenance = '''def provenance():
|
|
gates = ROOT / '.local/text-repair-save-20260911'
|
|
input_path = gates / 'inputs1.json'
|
|
check(sha(input_path.read_bytes()) == '75a282fd3d4cb2dec6763046ea45d0caa015b998281fbdd6f222d8e3a175b13f', 'original GUI B183 raw input manifest identity')
|
|
inputs = read_json(input_path)
|
|
expected = {i['path']: i['sha256'] for i in inputs['files']}
|
|
sizes = {i['path']: i['bytes'] for i in inputs['files']}
|
|
check(len(expected) == len(inputs['files']) == 500 and sum(sizes.values()) == 9482855, 'measured 500 unique original GUI gate inputs and 9482855 bytes')
|
|
check(inputs['head'] == 'eeeaa1262748800c4c9aaa1eca79a7de96757358', 'original gate captured head retained separately from accepted source base')
|
|
input_zip = gates / 'inputs1.zip'
|
|
check(sha(input_zip.read_bytes()) == inputs['archiveSha256'] == '213fdb39ea7c3601b4baac674c3ab3ecc863ac44db1b092d922d3e24f26887b7', 'frozen GUI source ZIP identity')
|
|
with zipfile.ZipFile(input_zip) as archive:
|
|
names = archive.namelist()
|
|
check(len(names) == len(set(names)) == len(expected) and set(names) == set(expected), 'complete captured source ZIP file set')
|
|
original = {p: archive.read(p) for p in names}
|
|
check(all(sha(original[p]) == h and len(original[p]) == sizes[p] for p, h in expected.items()), 'all 500 original captured input bytes and sizes')
|
|
preparation = read_json(PREP / 'preparation.json')
|
|
check(preparation['base_commit'] == BASE_COMMIT and preparation['reconstruction_commit'] == SOURCE_COMMIT == '802855f7e6f2f00a107a12196b458b267f586b8d', 'exact release base and independent reconstruction')
|
|
check(preparation['gui_inputs'] == expected, 'producer input mapping equals independently pinned gate source mapping')
|
|
derived = git_blobs(SOURCE_COMMIT, list(expected))
|
|
base = git_blobs(BASE_COMMIT, list(expected))
|
|
differences = []
|
|
mixed = []
|
|
for p, h in expected.items():
|
|
current = (SOURCE / p).read_bytes()
|
|
check(original[p] == derived[p] == current == (PREP / 'source-roundtrip' / p).read_bytes(), 'captured input equals Git and both reconstructed checkouts: ' + p)
|
|
if base[p] != current:
|
|
check(base[p].replace(b'\\r\\n', b'\\n') == current.replace(b'\\r\\n', b'\\n'), 'restoration changes only newline bytes: ' + p)
|
|
differences.append(p)
|
|
crlf = current.count(b'\\r\\n')
|
|
if crlf and current.count(b'\\n') > crlf:
|
|
mixed.append(p)
|
|
wanted = {'docs/api.html', 'docs/api.rst', 'docs/language.html', 'docs/openapi.json', 'harness/fixtures/rest-coverage/coverage-probe.json'} | {
|
|
'crates/oa-desktop/src/' + p for p in ('behavior/creation.rs', 'behavior/scenario/workspace.rs', 'behavior/topology/contextual.rs', 'guide.rs', 'semantic_review/artifacts_view.rs', 'semantic_review/attachments_view.rs', 'semantic_review/keyed_rows.rs', 'semantic_review/keyed_tests.rs', 'semantic_review/keyed.rs', 'semantic_review/ordered.rs')}
|
|
check(set(differences) == wanted and len(differences) == 15, 'exact fifteen measured newline restorations')
|
|
check(set(mixed) == {'crates/oa-desktop/src/behavior/creation.rs', 'crates/oa-desktop/src/guide.rs'}, 'both mixed-newline inputs retained byte-exact')
|
|
restored = {i['path']: i for i in preparation['restorations']}
|
|
check(len(restored) == len(preparation['restorations']) == 15 and set(restored) == wanted, 'restoration receipt exact path set')
|
|
for p, r in restored.items():
|
|
check(r['sha256'] == sha(original[p]) and r['base_git_sha256'] == sha(base[p]) and r['bytes'] == len(original[p]) and r['crlf'] == original[p].count(b'\\r\\n') and r['lf'] == original[p].count(b'\\n'), 'independently measured restoration receipt: ' + p)
|
|
delta = subprocess.run(['git', 'diff', '--name-only', BASE_COMMIT, SOURCE_COMMIT], cwd=SOURCE, check=True, capture_output=True).stdout.decode().splitlines()
|
|
check(set(delta) == wanted | {'.gitattributes'}, 'reconstruction changes only fifteen exact inputs and scoped attributes')
|
|
semantic_delta = subprocess.run(['git', 'diff', '--name-only', '--ignore-space-at-eol', BASE_COMMIT, SOURCE_COMMIT], cwd=SOURCE, check=True, capture_output=True).stdout.decode().splitlines()
|
|
check(semantic_delta == ['.gitattributes'], 'no non-newline source change in reconstruction')
|
|
for p, h in preparation['shared_non_cargo_inputs'].items():
|
|
blob = git_blobs(SOURCE_COMMIT, [p])[p]
|
|
check(h == sha(blob) == sha((SOURCE / p).read_bytes()) == sha((PREP / 'source-roundtrip' / p).read_bytes()), 'separate shared input exact Git/checkout bytes: ' + p)
|
|
roundtrip = read_json(PREP / 'committed-roundtrip.json')
|
|
check(roundtrip['checks'] == expected | preparation['shared_non_cargo_inputs'] and roundtrip['clean'] is True, 'complete committed-roundtrip record matches independently checked input union')
|
|
check(preparation['root_before'] == preparation['root_after'] and preparation['root_after']['tracked_status'] == '', 'preparation retained root HEAD/index and clean tracked state')
|
|
check((SOURCE / '.git/objects').is_dir() and not (SOURCE / '.git/objects/info/alternates').exists(), 'reconstruction has separate Git object store without alternates')
|
|
|
|
complete = read_json(gates / 'complete.json')
|
|
commands = ['desktop-tests', 'desktop-clippy', 'scoped-fmt', 'diff-check', 'gui-build']
|
|
check(complete['gates'] == commands and complete['inputsUnchanged'] is True and complete['sourceHead'] == inputs['head'] and complete['archiveSha256'] == inputs['archiveSha256'], 'five terminal gates bind the same captured source')
|
|
gate_records = {}
|
|
for name in commands:
|
|
record = read_json(gates / (name + '-result.json'))
|
|
check(record['exitCode'] == 0 and record['inputsUnchanged'] is True, 'successful terminal gate with unchanged input readback: ' + name)
|
|
for stream in ('stdout', 'stderr'):
|
|
check(sha((gates / (name + '-' + stream + '.log')).read_bytes()) == record[stream + 'Sha256'], 'original gate stream exact hash: ' + name + '/' + stream)
|
|
gate_records[name] = record
|
|
test_text = (gates / 'desktop-tests-stdout.log').read_text(encoding='utf-8')
|
|
summaries = re.findall(r'test result: ok\\. (\\d+) passed; (\\d+) failed; (\\d+) ignored; (\\d+) measured; (\\d+) filtered out;', test_text)
|
|
check(summaries == [('755', '0', '1', '0', '0')], 'actual full desktop terminal summary is 755 passed, zero failed, one ignored')
|
|
gui = gate_records['gui-build']['binary']
|
|
check(gui['sha256'] == BINARIES['arcadia-studio.exe'] and gui['bytes'] == 113206272 and sha((gates / 'gui-repair.exe').read_bytes()) == gui['sha256'], 'original GUI build receipt and preserved binary bind exact shipped B183')
|
|
events = [json.loads(line) for line in (gates / 'gui-build-stdout.log').read_text(encoding='utf-8').splitlines() if line.startswith('{')]
|
|
artifacts = [e for e in events if e.get('reason') == 'compiler-artifact' and e.get('target', {}).get('name') == 'arcadia-studio' and e.get('executable')]
|
|
check(artifacts == [gui['artifact']] and any(e.get('reason') == 'build-finished' and e.get('success') is True for e in events), 'original Cargo stdout contains the exact successful GUI artifact')
|
|
check(gui['artifact']['profile']['opt_level'] == '0' and gui['artifact']['profile']['debug_assertions'] is True and gui['artifact']['profile']['test'] is False, 'shipped GUI is a development executable, not a test or release profile')
|
|
|
|
history = PREP / 'evidence'
|
|
historical_pins = {
|
|
'server-original-gates.json': 'b7fdfc55ed4c964d276f20f1c57c81c1e924b8da315171089740ab8335ac9f0d',
|
|
'server-original-binary-hashes.json': '110a03e323133efb48d50ad065d41414599aa85e0ac420e7d622aa04df4d54f8',
|
|
'server-prior-input-comparisons.json': '3c78dea4e93dae186fd24ab826c6680178a2c7849c270a22deae2ff732f1857b',
|
|
'prior-dependency-notices.json': '98fab15c1a2bb3aa727c6d52d5c69435b15efa56b6668ed717e7a04cf86f9b52',
|
|
'server-source-snapshot.tar.gz': 'cbb371a93a562e1e641d7629fe351e016d63e66fc9112499b3fed6d5cd171f78',
|
|
}
|
|
for p, h in historical_pins.items():
|
|
check(sha((history / p).read_bytes()) == h, 'independent historical server evidence pin: ' + p)
|
|
origin_path = ROOT / 'harness/experiments/textual-authoring-20260911-local/provenance.json'
|
|
origin = read_json(origin_path)
|
|
check(origin['exe_sha256'].lower() == BINARIES['arcadia-server.exe'], 'original independent server record binds unchanged EFEE')
|
|
server_expected = {i['path']: i['snapshot_sha256'].lower() for i in origin['source_comparisons']}
|
|
check(len(server_expected) == len(origin['source_comparisons']) == 120 and server_expected == preparation['historical_server_inputs'], 'measured 120 unique historical server inputs against their original record')
|
|
tar_path = history / 'server-source-snapshot.tar.gz'
|
|
tar_manifest = read_json(ROOT / '.local/linux-qa/runtime/source7-20260907T082753190288Z.tar.manifest.json')
|
|
with tarfile.open(tar_path) as tar:
|
|
regular = [m for m in tar.getmembers() if m.isfile()]
|
|
members = {m.name.removeprefix('./'): m for m in regular}
|
|
check(len(members) == len(regular), 'historical tar contains no duplicate regular path')
|
|
for p, h in server_expected.items():
|
|
check(sha(tar.extractfile(members[p]).read()) == h, 'original server tar exact separately recorded source bytes: ' + p)
|
|
historical_crate_paths = {p for p in members if p.startswith(('crates/oa-core/', 'crates/oa-server/'))}
|
|
check(historical_crate_paths == set(server_expected), 'historical tar complete core/server file set')
|
|
shared = [p for p in members if p in ('Cargo.toml', 'Cargo.lock', 'docs/openapi.json') or p.startswith('build/')]
|
|
old_shared = {p: tar.extractfile(members[p]).read() for p in shared}
|
|
for p, data in old_shared.items():
|
|
check(sha(data) == tar_manifest['files'][p].lower(), 'original server shared input matches original tar manifest: ' + p)
|
|
if p not in ('Cargo.toml', 'Cargo.lock'):
|
|
check(data == (SOURCE / p).read_bytes(), 'unchanged shared server build resource: ' + p)
|
|
current_server = {}
|
|
for crate in ('oa-core', 'oa-server'):
|
|
current_server.update({'crates/' + crate + '/' + p: h for p, h in local_source_map(SOURCE / 'crates' / crate).items()})
|
|
changed = sorted(p for p, h in server_expected.items() if current_server.get(p) != h)
|
|
added = sorted(set(current_server) - set(server_expected))
|
|
check(changed == ['crates/oa-core/src/language.rs'] and added == ['crates/oa-core/src/language_outline_tests.rs'], 'current GUI core differs from historical server only in documented language change/new outline tests')
|
|
check(preparation['historical_server_comparison']['changed_current_inputs'] == changed and preparation['historical_server_comparison']['added_current_files'] == added, 'producer states the same independently measured server/source distinction')
|
|
'''
|
|
new_tail = ''' evidence = read_json(PACKAGE / 'package.json')['build_evidence']['evidence']
|
|
check(evidence == read_json(PREP / 'build-evidence.json'), 'packaged build evidence equals exact frozen producer evidence semantically')
|
|
check(evidence['binary_sha256'] == {k: v for k, v in BINARIES.items() if k.endswith('.exe')}, 'per-binary build evidence binds both exact shipped executables')
|
|
check(SOURCE_COMMIT in evidence['source_identity'] and BASE_COMMIT in evidence['source_identity'] and 'not the original build commit' in evidence['source_identity'], 'GUI reconstruction identified without claiming original build commit')
|
|
check('No current-source server claim' in evidence['source_identity'] and 'historical development artifact, not rebuilt' in evidence['profile'], 'historical server is explicitly not attributed to the new GUI source')
|
|
check('No reproducible build or new server build claimed' in evidence['compiler'] and 'Native/package acceptance remains pending' in evidence['profile'], 'build evidence retains development and native acceptance limitations')
|
|
manifest = read_json(PREP / 'evidence-manifest.json')
|
|
expected_records = {'evidence/' + p: ROOT / '.local/contextual-prerelease-20260911/evidence' / p for p in historical_pins}
|
|
expected_records.update({'evidence/gui-inputs1.json': gates / 'inputs1.json', 'evidence/gui-complete.json': gates / 'complete.json', 'evidence/gui-gate-run.py': gates / 'run.py'})
|
|
for name in commands:
|
|
for suffix in ('-result.json', '-stdout.log', '-stderr.log'):
|
|
expected_records['evidence/gui-' + name + suffix] = gates / (name + suffix)
|
|
records = {r['destination']: r for r in manifest}
|
|
check(len(records) == len(manifest) == len(expected_records) and set(records) == set(expected_records), 'all 23 independently identified per-binary gate/source records are retained')
|
|
for p, source in expected_records.items():
|
|
record = records[p]
|
|
data = (PREP / p).read_bytes()
|
|
check(Path(record['source']).resolve() == source.resolve() and data == source.read_bytes() and sha(data) == record['sha256'] and len(data) == record['bytes'], 'external historical record preserves original exact bytes: ' + p)
|
|
per_binary = evidence['per_binary_provenance']
|
|
check(set(per_binary) == {'arcadia-studio.exe', 'arcadia-server.exe'}, 'two separate executable provenance records')
|
|
check(per_binary['arcadia-studio.exe']['captured_head'] == inputs['head'], 'GUI provenance retains actual precommit captured head')
|
|
for binary, references in per_binary.items():
|
|
for value in references.values():
|
|
if value.startswith('evidence/'):
|
|
check(value in expected_records, 'per-binary provenance resolves to verified external record: ' + binary + '/' + value)
|
|
check('not files inside the ZIP' in evidence['provenance_reference_base'], 'external provenance references are not advertised as bundled payload')
|
|
RESULT['provenance'] = {
|
|
'gui_inputs_sha256': sha(input_path.read_bytes()), 'gui_inputs': len(expected), 'gui_input_bytes': sum(sizes.values()),
|
|
'captured_build_head': inputs['head'], 'source_commit': SOURCE_COMMIT, 'base_commit': BASE_COMMIT,
|
|
'eol_restorations': differences, 'mixed_newline_inputs': mixed, 'gate_counts': [int(n) for n in summaries[0]],
|
|
'server_source_files': len(server_expected), 'changed_current_server_inputs': changed, 'added_current_server_inputs': added,
|
|
'server_origin_sha256': sha(origin_path.read_bytes()), 'shared_input_files': shared,
|
|
'original_lock_packages': len(old_packages), 'additional_local_lock_package': cli,
|
|
'original_server_lock_sha256': sha(old_shared['Cargo.lock']), 'current_gui_lock_sha256': sha((SOURCE / 'Cargo.lock').read_bytes()),
|
|
'tar_sha256': sha(tar_path.read_bytes()), 'preserved_records': len(records),
|
|
'limitations': 'Original build receipts read back; no rebuild, GUI, native acceptance or reproducibility claim by this evaluator.'}
|
|
'''
|
|
raw = raw[:start] + new_provenance + lock_checks + new_tail + raw[end:]
|
|
raw = raw.replace("previous_path = ROOT / '.local/authoring-prerelease-review-20260911/extracted/ArcadiaStudio-0.2.0-preview.authoring.20260911-x86_64-pc-windows-gnullvm/dependency-notices.json'", "previous_path = PREP / 'evidence/prior-dependency-notices.json'")
|
|
raw = raw.replace(" for p, h in notice['workspace_build_inputs_sha256'].items():", " shared_names = {'Cargo.toml', 'Cargo.lock', 'LICENSE', 'docs/openapi.json'} | {'build/' + p for p in local_source_map(SOURCE / 'build')}\n check(set(notice['workspace_build_inputs_sha256']) == shared_names, 'complete ordinary shared build-input inventory')\n for p, h in notice['workspace_build_inputs_sha256'].items():")
|
|
raw = raw.replace(" env = {'SystemRoot': str(windows), 'WINDIR': str(windows), 'PATH': str(windows / 'System32') + ';' + str(windows), 'TEMP': str(temp), 'TMP': str(temp)}", """ profile = runtime / 'profile'
|
|
for sub in ('Desktop', 'AppData/Roaming', 'AppData/Local'):
|
|
(profile / sub).mkdir(parents=True, exist_ok=True)
|
|
program_data = runtime / 'ProgramData'
|
|
program_data.mkdir()
|
|
env = {'SystemDrive': windows.drive, 'SystemRoot': str(windows), 'WINDIR': str(windows),
|
|
'PATH': ';'.join(map(str, (PACKAGE, windows / 'System32', windows))),
|
|
'TEMP': str(temp), 'TMP': str(temp), 'COMSPEC': str(windows / 'System32/cmd.exe'),
|
|
'USERPROFILE': str(profile), 'HOMEDRIVE': profile.drive,
|
|
'HOMEPATH': str(profile)[len(profile.drive):], 'APPDATA': str(profile / 'AppData/Roaming'),
|
|
'LOCALAPPDATA': str(profile / 'AppData/Local'), 'ProgramData': str(program_data),
|
|
'ALLUSERSPROFILE': str(program_data)}""")
|
|
raw = raw.replace(" def start(index):", " owned = []\n def start(index):")
|
|
raw = raw.replace(" out.close()\n err.close()\n RESULT['processes'].append", " owned.append(process)\n out.close()\n err.close()\n RESULT['processes'].append")
|
|
raw = raw.replace(" RESULT['processes'][-1]['exit_after_explicit_terminate'] = code", " next(r for r in RESULT['processes'] if r['pid'] == process.pid)['exit_after_explicit_terminate'] = code")
|
|
raw = raw.replace(" if process is not None and process.poll() is None:\n stop(process)", " for owned_process in owned:\n if owned_process.poll() is None:\n stop(owned_process)\n check(all(p.poll() is not None for p in owned), 'both owned server processes are terminal')")
|
|
raw = raw.replace("'notice identity/checksum occurs in historical lock: '", "'notice identity/checksum occurs in verified current lock: '")
|
|
ast.parse(raw)
|
|
target = OUT / 'review.py'
|
|
with target.open('x', encoding='utf-8', newline='\n') as f:
|
|
f.write(raw)
|
|
sha = lambda p: hashlib.sha256(p.read_bytes()).hexdigest()
|
|
frozen = {'source_commit': '802855f7e6f2f00a107a12196b458b267f586b8d',
|
|
'zip_sha256': 'd7228c542f162663933ea002739a78c722bcca41e437df63b7c868ea2af201f1',
|
|
'zip_bytes': 32971712, 'zip_members': 559,
|
|
'authorization': 'Root explicit artifact/server authorization after producer terminal 2026-09-11T21:13:15Z; no GUI/compiler.',
|
|
'previous_reviewer_sha256': sha(OLD),
|
|
'producer_records': {name: sha(PREP / name) for name in ('preparation.json', 'committed-roundtrip.json', 'evidence-manifest.json', 'build-evidence.json', 'package2-result.json', 'package-readback.json', 'adapter-manifest.json', 'prepare.py', 'package2.ps1', 'readback.py')}}
|
|
with (OUT / 'frozen-inputs.json').open('x', encoding='utf-8', newline='\n') as f:
|
|
json.dump(frozen, f, ensure_ascii=False, indent=2)
|
|
f.write('\n')
|
|
print(json.dumps({'reviewer_sha256': sha(target), 'frozen_inputs_sha256': sha(OUT / 'frozen-inputs.json'), 'syntax': 'AST parsed; no artifact/server execution'}, indent=2))
|