38 lines
4.0 KiB
Python
38 lines
4.0 KiB
Python
from pathlib import Path
|
|
import hashlib,json,subprocess,datetime
|
|
R=Path(__file__).resolve().parent.parent;S=R/'.local/analysis-checked-save-847b1caa-20260913';D=R/'harness/experiments/analysis-checked-save-windows-20260913'
|
|
def sha(b):return hashlib.sha256(b).hexdigest()
|
|
def new(p,b):
|
|
p.parent.mkdir(parents=True,exist_ok=True)
|
|
with p.open('xb') as f:f.write(b)
|
|
assert not D.exists();D.mkdir()
|
|
result=json.loads((S/'result.json').read_bytes());pre=json.loads((S/'preflight.json').read_bytes())
|
|
assert result['source']=='847b1caa7e75bb82f6ce5193c45bcfc45973ad1a'
|
|
assert result['exit']==101 and not result['changed_inputs'] and result['head_unchanged'] and not result['worktree_status']
|
|
assert result['membership']['exact_one'] and result['membership']['exit']==0 and result['membership']['artifact_unchanged']
|
|
artifact=Path(result['artifact']['path']);assert artifact.stat().st_size==result['artifact']['bytes'] and sha(artifact.read_bytes())==result['artifact']['sha256']
|
|
assert sha((S/'inputs.json').read_bytes())=='80ae7cece89e241bc2d8b53153affa3b16dd94e6dcf7cb8e3ebb9fad36945e02'
|
|
assert len(json.loads((S/'inputs.json').read_bytes())['inputs'])==512
|
|
rows=[]
|
|
def add(p,dest):
|
|
b=p.read_bytes();new(D/dest,b);rows.append({'path':dest,'source':str(p.relative_to(R)).replace('\\','/'),'bytes':len(b),'sha256':sha(b)})
|
|
for p in sorted(S.iterdir()):
|
|
assert p.is_file() and not p.is_symlink();add(p,'run/'+p.name)
|
|
runner=R/'.local/run-analysis-checked-save-20260913.py';assert sha(runner.read_bytes())==pre['runner']['sha256'];add(runner,'tools/'+runner.name)
|
|
add(Path(__file__).resolve(),'tools/'+Path(__file__).name)
|
|
bindings={'scope':'Excluded large artifact and existing source/toolchain paths. Test executable was rehashed at archival; toolchain/other values retain original preflight identity, not new build/module acceptance.','source':result['source'],'source_worktree':pre['cwd'],'retained_target_directory':pre['target_directory'],'executable':result['artifact'],'runtime_path_candidate':pre['runtime_path_candidate'],'runtime_binding_limit':pre['runtime_binding_limit'],'raw_source_input_manifest':'run/inputs.json','test_temp_directory':'Not retained: the unchanged tempfile-owned test dropped it on panic. No saved-model snapshot is claimed.'}
|
|
b=(json.dumps(bindings,indent=2)+'\n').encode();new(D/'external-bindings.json',b);rows.append({'path':'external-bindings.json','source':'generated from verified closed run/preflight receipts','bytes':len(b),'sha256':sha(b)})
|
|
new(D/'archive-manifest.json',(json.dumps({'utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'scope':'Closed one-test public checked-save failure, source identity, actual command/logs/runner and external failed executable binding. No candidate acceptance.','files':rows},indent=2)+'\n').encode())
|
|
# Append only this new rule in the working file, preserving every existing byte.
|
|
attr=R/'.gitattributes';before=attr.read_bytes();rule=b'harness/experiments/analysis-checked-save-windows-20260913/** -text whitespace=-blank-at-eol,-blank-at-eof,cr-at-eol'
|
|
assert rule not in before;nl=b'\r\n' if b'\r\n' in before else b'\n';attr.write_bytes(before+(b'' if before.endswith(b'\n') else nl)+rule+nl)
|
|
# Index-specific patch stages only our row; other staged/unstaged attribute edits remain.
|
|
index=subprocess.check_output(['git','show',':.gitattributes'],cwd=R);assert rule not in index
|
|
old=index.decode().splitlines();context=old[-1]
|
|
patch=f'diff --git a/.gitattributes b/.gitattributes\n--- a/.gitattributes\n+++ b/.gitattributes\n@@ -{len(old)},1 +{len(old)},2 @@\n {context}\n+{rule.decode()}\n'
|
|
subprocess.run(['git','apply','--cached','--check','-'],input=patch.encode(),cwd=R,check=True)
|
|
subprocess.run(['git','apply','--cached','-'],input=patch.encode(),cwd=R,check=True)
|
|
afterindex=subprocess.check_output(['git','show',':.gitattributes'],cwd=R)
|
|
assert afterindex.decode().splitlines()==old+[rule.decode()]
|
|
print(json.dumps({'initial_payloads':len(rows),'external_executable_verified':True,'attribute_staged_only_own_new_row':True},indent=2))
|