diff --git a/harness/STATE.md b/harness/STATE.md index 5d03a8c9..6aef787f 100644 --- a/harness/STATE.md +++ b/harness/STATE.md @@ -137,6 +137,15 @@ dirty diagnostic/probe results are retained. No current full-core pass is claimed. Public source8 parser, writer, source-update and persistence composition remain incomplete; these branches are not integrated production analysis. +Published private source **10d7f3340d5cd61a656dc0bcf7c143f8897c5551** adds +complete borrowed original-span export for later edit composition. Its +[Windows evidence](experiments/analysis-original-span-20260923/README.md) records +173 listed tests (all prior 167 retained), 65 typed passes including all 11 +updater cases, and strict core all-target Clippy on the same 538 committed +inputs. Review caught and corrected an intermediate standalone budget +regression. Complete mixed-bundle ownership, combined output compilation and +public source8 remain unimplemented; this is an isolated export adapter. + The [reviewed S1/S7 assessment](issue28-s1-s7-assessment-956atf-20260923.md) distinguishes static analysis/case overlays from contextual inheritance, fixed/default bindings and executable trade studies with durable result diff --git a/harness/experiments/analysis-original-span-20260923/.gitattributes b/harness/experiments/analysis-original-span-20260923/.gitattributes new file mode 100644 index 00000000..c04700c8 --- /dev/null +++ b/harness/experiments/analysis-original-span-20260923/.gitattributes @@ -0,0 +1,4 @@ +*.py text eol=lf +*.md text eol=lf +*.json text eol=lf +*.zip binary diff --git a/harness/experiments/analysis-original-span-20260923/README.md b/harness/experiments/analysis-original-span-20260923/README.md new file mode 100644 index 00000000..a7696dd2 --- /dev/null +++ b/harness/experiments/analysis-original-span-20260923/README.md @@ -0,0 +1,61 @@ +# Private original-span export: Windows verification + +Tested source **10d7f3340d5cd61a656dc0bcf7c143f8897c5551**, based on +**1b1c3e3abb6fc3d0934c9dbfbd21fddc8ae4f594**. This is a private typed rename +adapter, not public source8 support or a mixed-file compositor. + +The adapter exposes a complete borrowed batch of original spans and qualified +identities after validating source ownership, complete edit membership, names +and budget bounds. It creates no replacement source files. Standalone rename +output retains its original size checks; composition defers hypothetical +typed-only output size to the future combined emitter. A review caught an +intermediate standalone budget regression; the final source fixes it and adds +a test that distinguishes the corrected behavior. + +Windows x86_64-pc-windows-gnullvm, Rust/Cargo 1.98.1, one compiler job: + +- Actual library listing: 173 unique tests, all previous 167 retained plus six. +- Actual typed-source execution: 65 passed, zero failed or ignored, including + all 11 updater tests and the existing stack-safety cases. +- Strict `oa-core` all-target Clippy with `-D warnings`: passed. +- All three gates bind the same 538 committed inputs before and after execution. + +Commands are preserved exactly in the raw receipts. Tests use +`cargo test --locked --offline -p oa-core --lib language::analysis_source -- --test-threads=1`; +lint uses `cargo clippy --locked --offline -p oa-core --all-targets -- -D warnings`. +The library listing and typed run used the same 39,222,784-byte executable, +SHA256 `eed1520856679ecbea6ab2c3a202339775b7791cbfb2c24d74984cbde706305d`. +The executable is not included in this evidence package. + +## Inspect and verify + +Run `python -B PATH/verify.py --repo PATH/TO/REPOSITORY`. The repository must +contain the source commit above. The verifier checks the 13 archived payloads, +manifest hashes, exact commands, actual listing/runtime membership, successful +receipts and all 538 inputs against immutable Git blobs. It neither runs the +archived helpers nor depends on the current checkout. ZIP and JSON payloads +retain original bytes. The 117,078-byte ZIP has SHA256 +`abd480826c62326b0d553add85e24daa722ce6da2ec4213e34ff1052895e87bc`. +The archived prior-list receipt is historical inventory; +its wider provenance is in the separately published +[S3 evidence](../analysis-source-s3-windows-20260922/README.md). + +The source review and handoff inside the archive retain their original +pre-compilation status. This README and raw completed receipts supersede that +status only for the named gates. Binary identity is receipt-bound; verification +does not rehash an absent executable. An integrity check verifies recorded +evidence, not the truth of every semantic claim or a fresh runtime execution. + +## Remaining boundaries + +The caller-supplied Budget remains borrowed throughout composition, but the +private Index does not prove it came from the same parse. Production integration +must establish a complete bundle/entry/path/profile/model/index witness, merge +ordinary and typed edits with precise collision rules, enforce combined output +bounds, recompile the actual output, and compare the whole intended Project. +Subtree and scoped-parameter changes, deletion repair, movement, reidentity, +migration, save and history remain separate work. + +No full-core run was performed for this checkpoint. Earlier unsupported public +source8 failures remain disclosed in the S2c evidence; this targeted success +does not resolve them. No GUI, release or Linux acceptance is claimed. diff --git a/harness/experiments/analysis-original-span-20260923/evidence.zip b/harness/experiments/analysis-original-span-20260923/evidence.zip new file mode 100644 index 00000000..8e9f3a07 Binary files /dev/null and b/harness/experiments/analysis-original-span-20260923/evidence.zip differ diff --git a/harness/experiments/analysis-original-span-20260923/manifest.json b/harness/experiments/analysis-original-span-20260923/manifest.json new file mode 100644 index 00000000..3f618cc3 --- /dev/null +++ b/harness/experiments/analysis-original-span-20260923/manifest.json @@ -0,0 +1,54 @@ +{ + "clippy-10d7f33.inputs.json": { + "bytes": 100256, + "sha256": "a8310981b743069f6e6abf0ef11857ec03c16562dc7e8264030c1d9d82517e46" + }, + "clippy-10d7f33.log": { + "bytes": 165, + "sha256": "afbbc80761dfa446c74cc3df188db7c1ff5cf3edf6b809846e46c5a291208f43" + }, + "clippy-10d7f33.result.json": { + "bytes": 1097, + "sha256": "9478e486e803355f5d69382ea31c3dc42d79d8e6f4789226873e4accce29cd92" + }, + "list-10d7f33.inputs.json": { + "bytes": 100256, + "sha256": "a8310981b743069f6e6abf0ef11857ec03c16562dc7e8264030c1d9d82517e46" + }, + "list-10d7f33.log": { + "bytes": 18213, + "sha256": "76b9e9ebc0c0d3d8794020dd222cfc94f7dd8cda9deedd0e74e0cd0c3aa5900c" + }, + "list-10d7f33.result.json": { + "bytes": 19385, + "sha256": "4baf130b68e2c044ad3e43d6e8a2e13c611008192a271d3dfa75ee5a7c1503c1" + }, + "prior-list-1b1c3e3.result.json": { + "bytes": 18669, + "sha256": "23135f0c5739c2f40b703e603f38f4e95e1fb473d0ed799c291f83e08ad6844c" + }, + "runner.py": { + "bytes": 4034, + "sha256": "31e5a645d5983c60cff79fc1bbc08e71c1b7047fd21b343a5cad6c4ad07d97b2" + }, + "source-handoff.md": { + "bytes": 8402, + "sha256": "d4c6aa72679b3dd36c8554def9d224005d896a965c3ab1fd43022e890da66700" + }, + "source-review.md": { + "bytes": 10175, + "sha256": "afe471a04d852c507a35be3da6d5cef116a271dd532662041057d5eb07ed5666" + }, + "typed-10d7f33.inputs.json": { + "bytes": 100256, + "sha256": "a8310981b743069f6e6abf0ef11857ec03c16562dc7e8264030c1d9d82517e46" + }, + "typed-10d7f33.log": { + "bytes": 8188, + "sha256": "db8664ecf777821cb95a7b495a90a1ca80ddcdfd2f6c098ab4d5b0c842ddb95b" + }, + "typed-10d7f33.result.json": { + "bytes": 1395, + "sha256": "1dc4d030206e396cc97d29298880059642336deb36e00c07656e3812a65a71de" + } +} diff --git a/harness/experiments/analysis-original-span-20260923/verify.py b/harness/experiments/analysis-original-span-20260923/verify.py new file mode 100644 index 00000000..88df8be3 --- /dev/null +++ b/harness/experiments/analysis-original-span-20260923/verify.py @@ -0,0 +1,83 @@ +"""Verify published receipts and immutable Git inputs; never run archived code.""" +from pathlib import Path +import argparse +import hashlib +import json +import re +import subprocess +import sys +import zipfile + +if sys.flags.optimize: + raise SystemExit('Optimized Python is unsupported') +parser = argparse.ArgumentParser() +parser.add_argument('--repo', type=Path, required=True) +args = parser.parse_args() +base = Path(__file__).resolve().parent +source = '10d7f3340d5cd61a656dc0bcf7c143f8897c5551' +manifest = json.loads((base / 'manifest.json').read_text()) +with zipfile.ZipFile(base / 'evidence.zip') as archive: + assert len(archive.namelist()) == len(set(archive.namelist())) == 13 + assert set(archive.namelist()) == set(manifest) + payload = {name: archive.read(name) for name in manifest} +for name, data in payload.items(): + assert manifest[name] == {'bytes':len(data), 'sha256':hashlib.sha256(data).hexdigest()}, name + +receipts = {kind:json.loads(payload[f'{kind}-10d7f33.result.json']) for kind in ('list', 'typed', 'clippy')} +commands = { + 'list':['cargo','test','--locked','--offline','-p','oa-core','--lib','--','--list'], + 'typed':['cargo','test','--locked','--offline','-p','oa-core','--lib','language::analysis_source','--','--test-threads=1'], + 'clippy':['cargo','clippy','--locked','--offline','-p','oa-core','--all-targets','--','-D','warnings'], +} +inputs = None +for kind, receipt in receipts.items(): + assert receipt['source'] == receipt['head_after'] == source + assert receipt['exit'] == 0 and receipt['changed_inputs'] == [] + assert receipt['command'] == commands[kind] + assert receipt['start'] < receipt['end'] + assert receipt['environment']['CARGO_BUILD_JOBS'] == '1' + assert receipt['launcher_sha256'] == hashlib.sha256(payload['runner.py']).hexdigest() + current = json.loads(payload[receipt['inputs']]) + assert current['source'] == source and len(current['inputs']) == 538 + if inputs is None: + inputs = current['inputs'] + assert current['inputs'] == inputs + +listed = re.findall(r'^([^\r\n]+): test\r?$', payload['list-10d7f33.log'].decode(), re.M) +assert listed == receipts['list']['listing_members'] +assert len(listed) == len(set(listed)) == receipts['list']['listing_count'] == 173 +prior = json.loads(payload['prior-list-1b1c3e3.result.json']) +assert prior['source'] == '1b1c3e3abb6fc3d0934c9dbfbd21fddc8ae4f594' and prior['exit'] == 0 +assert len(prior['listing_members']) == 167 and set(prior['listing_members']) <= set(listed) +new = { + 'composition_checks_edit_record_ceiling_before_duplicate_membership', + 'composition_defers_only_typed_output_size_with_independent_shrink_arithmetic', + 'composition_exports_complete_borrowed_swap_witnesses_and_empty_noops', + 'composition_keeps_name_storage_and_rename_record_limits_before_allocation', + 'composition_rejects_stale_or_damaged_complete_batches_before_export', + 'standalone_noop_apply_keeps_tighter_file_only_budget_and_output_boundary', +} +assert set(listed)-set(prior['listing_members']) == {'language::analysis_source::update::tests::'+name for name in new} +selected = {name for name in listed if name.startswith('language::analysis_source::')} +log = payload['typed-10d7f33.log'].decode() +passed = re.findall(r'^test ([^\r\n]+) \.\.\. ok\r?$', log, re.M) +assert len(passed) == len(set(passed)) == len(selected) == 65 and set(passed) == selected +assert '65 passed; 0 failed; 0 ignored; 0 measured; 108 filtered out' in log +assert receipts['list']['artifacts'] == receipts['typed']['artifacts'] +assert len(receipts['typed']['artifacts']) == 1 +assert receipts['typed']['artifacts'][0]['sha256'] == 'eed1520856679ecbea6ab2c3a202339775b7791cbfb2c24d74984cbde706305d' +assert 'Finished' in payload['clippy-10d7f33.log'].decode() + +paths = subprocess.check_output(['git','ls-tree','-r','--name-only',source,'Cargo.toml','Cargo.lock','rust-toolchain.toml','.cargo','build','crates','assets','docs','examples','harness/fixtures','vendor'],cwd=args.repo).decode().splitlines() +assert paths == [item['path'] for item in inputs] +blobs = subprocess.check_output(['git','cat-file','--batch'],cwd=args.repo,input=''.join(f'{source}:{path}\n' for path in paths).encode()) +offset = 0 +for item in inputs: + end = blobs.index(b'\n',offset) + _,kind,size = blobs[offset:end].split() + size = int(size) + data = blobs[end+1:end+1+size] + assert kind == b'blob' and size == item['bytes'] and hashlib.sha256(data).hexdigest() == item['sha256'],item['path'] + offset = end+size+2 +assert offset == len(blobs) +print('PASS: 13 payloads; 538 immutable Git inputs; 173 listed, 167 retained + 6 new; exact 65 typed passes; strict core Clippy.')