287 lines
20 KiB
Python
287 lines
20 KiB
Python
"""Prepared, unexecuted S2b audit/archive. Read-only Git; no gates or staging.
|
|
|
|
Future: pinned-python -B archive-analysis-s2b-checkpoint.py --output ABS_NEW_LOCAL_DIR
|
|
--failure-review ABS_REVIEW_MD
|
|
The review must bind both full-log SHA256 values and the corrected source pin.
|
|
"""
|
|
import argparse
|
|
from datetime import datetime, timezone
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import re
|
|
import subprocess
|
|
|
|
BASE = Path(__file__).resolve().parent.parent
|
|
REPO = BASE / '.local/analysis-core-worktree-20260911'
|
|
GATES = BASE / '.local/analysis-source-gates-20260913'
|
|
SOURCE = 'a2a28f8d23a46ba1696b6a8410d4d3b5c1808f49'
|
|
ORIGINAL = '472fe7a4339a23a3339b2b91e8d53d76442f60c4'
|
|
BASELINE = 'b2c970b4673e062e47eadd12906d2316c4b1a7b3'
|
|
PREFIX = ['cargo','test','--locked','-p','oa-core','--lib']
|
|
SCOPES = ['Cargo.toml','Cargo.lock','rust-toolchain.toml','.cargo','build','crates','assets','docs','examples','harness/fixtures']
|
|
LOWER_PREFIX = 'language::analysis_source::lower::tests::'
|
|
NEW_NAMES = {LOWER_PREFIX + name for name in (
|
|
'staged_oa_and_sa_lowering_match_complete_independent_17_uuid_oracles',
|
|
'forward_cross_unit_resolution_keeps_original_offsets_and_shared_work',
|
|
'all_thirteen_expression_variants_lower_to_real_typed_values_and_admit',
|
|
'call_sites_and_parameter_scopes_preserve_distinct_original_occurrences',
|
|
'missing_ids_require_stabilization_without_uuid_or_budget_churn',
|
|
'duplicate_global_aliases_and_ids_fail_before_body_resolution',
|
|
'typed_reference_domains_unknown_names_and_parameter_scope_fail_at_tokens',
|
|
'ordinary_non_element_categories_are_collected_and_never_property_fallbacks',
|
|
'structural_lowering_defers_type_purity_layer_and_argument_sets_to_admission',
|
|
'lowering_phase_bounds_count_ordinary_globals_and_scoped_parameters_together',
|
|
'affine_kinds_optional_fields_list_signatures_and_unused_unbound_definitions_survive',
|
|
'duplicate_file_keys_and_exhausted_shared_budget_cannot_enter_lowering',
|
|
'iterative_lowering_preserves_128_deep_and_1024_wide_accepted_expressions',
|
|
)}
|
|
CORRECTED_NAMES = ['list-a2a28f8','typed-a2a28f8','tokens-a2a28f8','full-a2a28f8','strict-a2a28f8']
|
|
|
|
|
|
def require(value, message):
|
|
if not value:
|
|
raise ValueError(message)
|
|
|
|
|
|
def sha(data):
|
|
return hashlib.sha256(data).hexdigest()
|
|
|
|
|
|
def binding(data):
|
|
return {'bytes': len(data), 'sha256': sha(data)}
|
|
|
|
|
|
def git(*args, data=None, repository=REPO):
|
|
return subprocess.check_output(['git','-C',str(repository),*args], input=data)
|
|
|
|
|
|
class Audit:
|
|
def __init__(self):
|
|
self.originals = {}
|
|
self.commits = {}
|
|
|
|
def raw(self, path):
|
|
path = Path(path).absolute()
|
|
require(path.is_file(), 'Required existing artifact: '+str(path))
|
|
require(all(not p.is_symlink() and not p.is_junction() for p in (path,*path.parents)), 'Ordinary original path')
|
|
data = path.read_bytes()
|
|
require(self.originals.setdefault(path,data)==data, 'Input changed while inspecting: '+str(path))
|
|
return data
|
|
|
|
def read(self, name, suffix):
|
|
require(re.fullmatch(r'[A-Za-z0-9-]+',name), 'Safe original gate name')
|
|
data = self.raw(GATES/(name+suffix))
|
|
return json.loads(data) if suffix.endswith('.json') else data.decode('utf-8')
|
|
|
|
def committed_inputs(self, source, count):
|
|
if source in self.commits:
|
|
return self.commits[source]
|
|
paths = git('ls-tree','-r','--name-only',source,*SCOPES).decode().splitlines()
|
|
require(len(paths)==len(set(paths))==count, 'Exact committed input-scope membership')
|
|
stream = git('cat-file','--batch',data=''.join(source+':'+p+'\n' for p in paths).encode())
|
|
cursor=0; rows=[]
|
|
for path in paths:
|
|
end=stream.index(b'\n',cursor); _,kind,size=stream[cursor:end].split(); size=int(size)
|
|
data=stream[end+1:end+1+size]
|
|
require(kind==b'blob' and len(data)==size and stream[end+size+1:end+size+2]==b'\n', 'Exact raw Git blob framing')
|
|
rows.append({'path':path,**binding(data)})
|
|
cursor=end+size+2
|
|
require(cursor==len(stream), 'Complete Git blob stream')
|
|
self.commits[source]=rows
|
|
return rows
|
|
|
|
def gate(self, name, source, count, command):
|
|
result=self.read(name,'.result.json'); inputs=self.read(name,'.inputs.json'); log=self.read(name,'.log')
|
|
require(result['source']==result['head_after']==source and result['start'] and result['end']
|
|
and type(result['exit']) is int and result['changed_inputs']==[], 'Closed unchanged original gate: '+name)
|
|
require(result['command']==command and result['inputs']==name+'.inputs.json', 'Exact command/manifest filename: '+name)
|
|
require(inputs=={'source':source,'inputs':self.committed_inputs(source,count)}, 'Original inputs equal complete committed scope: '+name)
|
|
if command[1]=='clippy':
|
|
require(result['exit']==0 and result['artifacts']==[] and 'Finished ' in log
|
|
and not re.search(r'(?m)^(?:error|warning)(?:\[|:)',log), 'Successful strict gate required')
|
|
else:
|
|
require(len(result['artifacts'])==1, 'One core-library test executable')
|
|
artifact=result['artifacts'][0]
|
|
require(artifact['bytes']>0 and re.fullmatch(r'[0-9a-f]{64}',artifact['sha256']), 'Recorded executable identity')
|
|
running=re.findall(r'Running unittests [^\r\n]+ \(([^\r\n]+\.exe)\)',log)
|
|
require(len(running)==1, 'Exactly one actual Running section')
|
|
path=Path(running[0]); path=path if path.is_absolute() else REPO/path
|
|
require(path.resolve()==Path(artifact['path']).resolve(), 'Raw Running artifact path')
|
|
return result,log
|
|
|
|
def admission(self, name, result, names, mode, helper):
|
|
rec=self.read(name,'.admission.json')
|
|
require(rec['source']==result['source'] and rec['mode']==mode and rec['names']==names
|
|
and rec['artifact']==result['artifacts'][0], 'Original list/focused admission membership')
|
|
for key,suffix in [('result_sha256','.result.json'),('inputs_sha256','.inputs.json'),('log_sha256','.log')]:
|
|
require(rec[key]==sha(self.raw(GATES/(name+suffix))), 'Admission raw binding: '+name)
|
|
require(rec['admission_helper_sha256']==sha(self.raw(BASE/'.local'/helper)), 'Original admission helper bytes')
|
|
require(rec['verified_inputs']==(524 if result['source']==BASELINE else 531), 'Admitted input count')
|
|
if helper=='admit-analysis-s2b-gate.py':
|
|
require(rec['baseline_source']==BASELINE
|
|
and rec['baseline_result_sha256']==sha(self.raw(GATES/'list-b2c970b.result.json'))
|
|
and rec['baseline_admission_sha256']==sha(self.raw(GATES/'list-b2c970b.admission.json')), 'Exact original b2 admission dependency')
|
|
return rec
|
|
|
|
|
|
def listing(result, log, expected):
|
|
names=re.findall(r'^([^\r\n]+): test\r?$',log,re.M)
|
|
require(result['exit']==0 and names==result['listing_members'] and len(names)==len(set(names))==result['listing_count']
|
|
and set(names)==set(expected), 'Exact unique actual listing membership')
|
|
require(re.findall(r'^(\d+) tests?, (\d+) benchmarks?\s*$',log,re.M)==[(str(len(names)),'0')], 'Exact listing summary')
|
|
return names
|
|
|
|
|
|
def outcomes(result, log, names, total):
|
|
rows=re.findall(r'^test ([^\r\n]+) \.\.\. (ok|FAILED|ignored)(?:, [^\r\n]*)?\s*$',log,re.M)
|
|
require(len(rows)==len({n for n,_ in rows})==len(names) and {n for n,_ in rows}==set(names), 'Every expected runtime outcome exactly once')
|
|
counts={state:sum(s==state for _,s in rows) for state in ('ok','FAILED','ignored')}
|
|
require(counts['ignored']==0, 'No ignored analysis-core library outcomes expected')
|
|
expected=[('FAILED' if counts['FAILED'] else 'ok',str(counts['ok']),str(counts['FAILED']),'0','0',str(total-len(names)))]
|
|
require(re.findall(r'test result: (ok|FAILED)\. (\d+) passed; (\d+) failed; (\d+) ignored; (\d+) measured; (\d+) filtered out;',log)==expected, 'Actual counts match complete individual outcomes')
|
|
require(result['exit']==(101 if counts['FAILED'] else 0), 'Actual test exit matches failures')
|
|
return {'passed':counts['ok'],'failed':counts['FAILED'],'ignored':0,'exit':result['exit'],
|
|
'outcomes':dict(rows),'failed_names':sorted(n for n,s in rows if s=='FAILED')}
|
|
|
|
|
|
def panic_blocks(log, failed):
|
|
markers=list(re.finditer(r'^---- (.+) stdout ----\r?$',log,re.M)); found={}
|
|
for index,marker in enumerate(markers):
|
|
end=markers[index+1].start() if index+1<len(markers) else len(log)
|
|
body=re.split(r'\r?\nfailures:\r?\n',log[marker.end():end],maxsplit=1)[0]
|
|
name=marker[1]
|
|
require(name not in found, 'Unique failure diagnostic section')
|
|
lines=body.strip().splitlines()
|
|
diagnostic=next((line for line in lines if 'Unsupported schema version:' in line), '')
|
|
# This records observed wording only. A matching name/message is not a source-cause review.
|
|
found[name]={'section_start_line':log.count('\n',0,marker.start())+1,'section_sha256':sha(body.encode()),
|
|
'panic_location':next((line for line in lines if 'panicked at ' in line),'')[:500],
|
|
'diagnostic_excerpt':(diagnostic or '\n'.join(lines[:3]))[:1000],
|
|
'observed_unsupported_schema_wording':'Unsupported schema version: expected arcadia 3, 4, 5, 6 or 7.' in diagnostic}
|
|
require(set(found)==set(failed), 'Each failed outcome has one separate actual panic section')
|
|
return found
|
|
|
|
|
|
def main():
|
|
parser=argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument('--output',type=Path,required=True)
|
|
parser.add_argument('--failure-review',type=Path,required=True)
|
|
args=parser.parse_args()
|
|
require(args.output.is_absolute() and not args.output.exists(), 'Exclusive new absolute archive directory required')
|
|
output=args.output.resolve(); local=(BASE/'.local').resolve()
|
|
require(output.parent==local and re.fullmatch(r'analysis-source-s2b-evidence-[A-Za-z0-9-]+',output.name), 'Archive must be a fresh direct .local/analysis-source-s2b-evidence-* child')
|
|
require(not output.is_relative_to(REPO.resolve()) and not output.is_relative_to((local/'as2-20260913').resolve()), 'No source worktree output')
|
|
frozen_head=git('rev-parse','HEAD',repository=BASE)
|
|
frozen_index=git('diff','--cached','--raw',repository=BASE)
|
|
audit=Audit()
|
|
require(git('rev-parse',SOURCE+'^').decode().strip()==ORIGINAL, 'Exact correction parent')
|
|
changed=git('diff','--name-only',ORIGINAL,SOURCE).decode().splitlines()
|
|
require(changed==['crates/oa-core/src/language/analysis_source/lower/tests.rs'], 'Bounded test-only correction')
|
|
lower=git('show',SOURCE+':'+changed[0]).decode()
|
|
require({LOWER_PREFIX+n for n in re.findall(r'#\[test\]\s*fn (\w+)\(',lower)}==NEW_NAMES and len(NEW_NAMES)==13, 'Thirteen fixed authored test names')
|
|
|
|
baseline,b_log=audit.gate('list-b2c970b',BASELINE,524,PREFIX+['--','--list'])
|
|
baseline_names=listing(baseline,b_log,baseline['listing_members'])
|
|
require(len(baseline_names)==129 and not set(baseline_names)&NEW_NAMES, 'Retained admitted129 plus disjoint13')
|
|
audit.admission('list-b2c970b',baseline,baseline_names,'list','admit-analysis-s2a-gate.py')
|
|
expected=set(baseline_names)|NEW_NAMES
|
|
require(len(expected)==142, 'Exact resulting test inventory')
|
|
|
|
current,l_log=audit.gate('list-a2a28f8',SOURCE,531,PREFIX+['--','--list'])
|
|
names=listing(current,l_log,expected)
|
|
audit.admission('list-a2a28f8',current,names,'list','admit-analysis-s2b-gate.py')
|
|
results={'list':{'members':len(names),'exit':current['exit']}}
|
|
for role,selector,count in [('typed','language::analysis_source',34),('tokens','language::raw_tokens',1),('full',None,142)]:
|
|
stem=role+'-a2a28f8'; selected=[n for n in names if selector is None or selector in n]
|
|
require(len(selected)==count, 'Independently bounded selected count')
|
|
result,log=audit.gate(stem,SOURCE,531,PREFIX+([selector] if selector else [])+['--','--test-threads=1'])
|
|
require(result['artifacts']==current['artifacts'], 'Same corrected recorded test executable')
|
|
results[role]=outcomes(result,log,selected,142)
|
|
if selector:
|
|
require(results[role]['failed']==0, 'Required focused gate must pass before checkpoint')
|
|
audit.admission(stem,result,selected,'focused','admit-analysis-s2b-gate.py')
|
|
if role in ('typed','full'):
|
|
require(all(results[role]['outcomes'].get(n)=='ok' for n in NEW_NAMES), 'All fixed13 must actually pass')
|
|
if role=='full': full_log=log
|
|
strict,_=audit.gate('strict-a2a28f8',SOURCE,531,['cargo','clippy','--locked','-p','oa-core','--all-targets','--','-D','warnings'])
|
|
results['strict']={'exit':strict['exit'],'ended':strict['end']}
|
|
|
|
old,old_list=audit.gate('list-472fe7a',ORIGINAL,531,PREFIX+['--','--list'])
|
|
old_names=listing(old,old_list,expected)
|
|
audit.admission('list-472fe7a',old,old_names,'list','admit-analysis-s2b-gate.py')
|
|
old_typed,old_log=audit.gate('typed-472fe7a',ORIGINAL,531,PREFIX+['language::analysis_source','--','--test-threads=1'])
|
|
require(old_typed['artifacts']==old['artifacts'], 'Original failure executable identity')
|
|
old_outcomes=outcomes(old_typed,old_log,[n for n in old_names if 'language::analysis_source' in n],142)
|
|
require(old_outcomes['passed']==33 and old_outcomes['failed_names']==[LOWER_PREFIX+'all_thirteen_expression_variants_lower_to_real_typed_values_and_admit']
|
|
and 'AsKind requires an anonymous matching dimension and a linear target' in old_log, 'Preserved actual472 failure')
|
|
original_map={r['path']:r for r in audit.commits[ORIGINAL]}
|
|
corrected_map={r['path']:r for r in audit.commits[SOURCE]}
|
|
require(set(original_map)==set(corrected_map) and [p for p in original_map if original_map[p]!=corrected_map[p]]==changed, 'All531 source inputs unchanged except corrected test bytes')
|
|
|
|
prior,p_log=audit.gate('full-b2c970b',BASELINE,524,PREFIX+['--','--test-threads=1'])
|
|
require(prior['artifacts']==baseline['artifacts'], 'Original b2 list/full executable identity')
|
|
prior_full=outcomes(prior,p_log,baseline_names,129)
|
|
require(prior_full['passed']==113 and prior_full['failed']==16, 'Actual b2 full113/16 baseline retained')
|
|
full_causes=panic_blocks(full_log,results['full']['failed_names'])
|
|
prior_causes=panic_blocks(p_log,prior_full['failed_names'])
|
|
comparison={'same_failed_name_set':results['full']['failed_names']==prior_full['failed_names'],
|
|
'new_failed_names':sorted(set(results['full']['failed_names'])-set(prior_full['failed_names'])),
|
|
'no_longer_failed_names':sorted(set(prior_full['failed_names'])-set(results['full']['failed_names'])),
|
|
'corrected_failure_sections':full_causes,'b2_failure_sections':prior_causes,
|
|
'boundary':'Names and observed diagnostic wording are compared separately; source-cause conclusions are in the bound human review.'}
|
|
review=audit.raw(args.failure_review).decode('utf-8')
|
|
require(review.strip() and all(value in review for value in (SOURCE,sha(audit.raw(GATES/'full-a2a28f8.log')),sha(audit.raw(GATES/'full-b2c970b.log')))), 'Separate cause review must explicitly bind both actual full logs and corrected source')
|
|
for leaf in ['run-analysis-source-gate.py','admit-analysis-s2a-gate.py','admit-analysis-s2b-gate.py',
|
|
'analysis-source8-s2b-independent-review-20260913.md','analysis-source8-s2b-runtime-correction-review-20260913.md',
|
|
'analysis-source8-s2b-handoff-20260913.md',Path(__file__).name]:
|
|
audit.raw(BASE/'.local'/leaf)
|
|
|
|
summary={'source':SOURCE,'original':ORIGINAL,'baseline':BASELINE,'scope':'Private S2b source/lowering checkpoint; no full-pass admission, public8, native or release claim.',
|
|
'corrected_gates':results,'original_typed_failure':old_outcomes,'baseline_full':prior_full,
|
|
'failure_comparison':comparison,'source_inputs':531,'baseline_members':129,'new_members':sorted(NEW_NAMES),
|
|
'failure_review':{'path':str(args.failure_review.absolute()),**binding(audit.raw(args.failure_review))},
|
|
'artifacts':'Original recorded paths/bytes/hashes retained. Mutable test executables are not reread or copied.',
|
|
'audit_completed_utc':datetime.now(timezone.utc).isoformat()}
|
|
payloads={}; files=[]
|
|
for path,data in sorted(audit.originals.items(),key=lambda item:str(item[0])):
|
|
try: relative=path.relative_to(BASE).as_posix()
|
|
except ValueError: relative='external-review/'+path.name
|
|
destination='evidence/'+relative
|
|
require(destination not in payloads, 'Unique archive member')
|
|
payloads[destination]=data
|
|
files.append({'path':destination,'original_path':path.relative_to(BASE).as_posix() if path.is_relative_to(BASE) else str(path),'bytes':len(data),'sha256':sha(data)})
|
|
generated=(json.dumps(summary,indent=2)+'\n').encode()
|
|
payloads['audit.json']=generated
|
|
full=results['full']
|
|
readme=f'''# S2b corrected gate evidence
|
|
|
|
Source `{SOURCE}`; original failed source `{ORIGINAL}`. This is private source/lowering checkpoint evidence. Public source8 and native/release acceptance are outside scope.
|
|
|
|
Actual corrected outcomes: listing {len(names)}; typed {results['typed']['passed']} passed; raw token {results['tokens']['passed']} passed; full **{full['passed']} passed / {full['failed']} failed / {full['ignored']} ignored, exit {full['exit']}**; strict exit {strict['exit']}. No full-pass admission is emitted. All13 authored lower tests pass in typed and full outputs; all129 prior members remain. Five corrected gates bind531 exact committed input blobs.
|
|
|
|
Original472 listing and **33 passed / 1 failed, exit101** are preserved. The source correction reports explain the AsKind positive-oracle defect and unchanged semantic boundary. Actual b2 full113/16 remains the comparison baseline. Failed-name sets match: {comparison['same_failed_name_set']}. Each actual panic section is separately recorded in audit.json; the bound cause review supplies source-level conclusions. A name-set match alone is not cause equivalence.
|
|
|
|
The historical S2a checkpoint separately retains the production-language **7 passed / 9 failed at b2**. This archive does not claim a corrected-source legacy integration run or transfer that outcome to a2.
|
|
|
|
manifest.json binds {len(files)} raw files and audit.json. All raw originals were read back before and after exclusive archive creation. Binaries/toolchains are omitted; original artifact identities remain in raw receipts. This helper invokes only read-only Git and file inspection; it neither runs gates nor stages/commits files. Root owns the final durable checkpoint.
|
|
'''
|
|
payloads['README.md']=readme.encode()
|
|
manifest={'source':SOURCE,'scope':summary['scope'],'files':files,'generated_files':[{'path':name,**binding(payloads[name])} for name in ('audit.json','README.md')]}
|
|
payloads['manifest.json']=(json.dumps(manifest,indent=2)+'\n').encode()
|
|
for path,data in audit.originals.items(): require(path.read_bytes()==data, 'Original pre-copy readback')
|
|
output.mkdir(parents=True,exist_ok=False)
|
|
for relative,data in payloads.items():
|
|
target=output/relative; target.parent.mkdir(parents=True,exist_ok=True)
|
|
with target.open('xb') as stream: stream.write(data)
|
|
require(target.read_bytes()==data, 'Archive raw copy readback')
|
|
for path,data in audit.originals.items(): require(path.read_bytes()==data, 'Original post-copy readback')
|
|
require(git('rev-parse','HEAD',repository=BASE)==frozen_head and git('diff','--cached','--raw',repository=BASE)==frozen_index, 'Root HEAD/index unchanged')
|
|
print(json.dumps({'archive':str(output),'raw_files':len(files),'raw_bytes':sum(row['bytes'] for row in files),
|
|
'manifest':binding(payloads['manifest.json']),'full_actual':{k:full[k] for k in ('passed','failed','ignored','exit')},
|
|
'git_writes':False,'gate_execution':False}))
|
|
|
|
|
|
if __name__=='__main__':
|
|
main()
|