Record lifecycle and palette native acceptance and runtime provenance
This commit is contained in:
+37
@@ -0,0 +1,37 @@
|
||||
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))
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
from pathlib import Path
|
||||
from datetime import datetime,timezone
|
||||
import hashlib,json,subprocess,os,time,shutil,re,sys
|
||||
ROOT=Path(__file__).resolve().parent.parent
|
||||
WORK=ROOT/'.local/analysis-core-worktree-20260911'
|
||||
TARGET=ROOT/'.local/analysis-checked-save-target-20260913'
|
||||
OUT=ROOT/'.local/analysis-checked-save-847b1caa-20260913'
|
||||
SOURCE='847b1caa7e75bb82f6ce5193c45bcfc45973ad1a'
|
||||
TEST='checked_save_returns_exact_bytes_and_accepts_unchanged_external_content'
|
||||
def sha(b):return hashlib.sha256(b).hexdigest()
|
||||
def identity(p):
|
||||
p=Path(p);b=p.read_bytes();return {'path':str(p),'bytes':len(b),'sha256':sha(b)}
|
||||
def new(name,obj):
|
||||
with (OUT/name).open('x',encoding='utf-8',newline='\n') as f:json.dump(obj,f,indent=2);f.write('\n')
|
||||
def git(*args):return subprocess.check_output(['git',*args],cwd=WORK)
|
||||
assert git('rev-parse','HEAD').decode().strip()==SOURCE
|
||||
assert not git('status','--porcelain').strip()
|
||||
assert not TARGET.exists();assert not OUT.exists();OUT.mkdir();TARGET.mkdir()
|
||||
paths=git('ls-tree','-r','--name-only',SOURCE,'Cargo.toml','Cargo.lock','rust-toolchain.toml','.cargo','build','crates','assets','docs','examples','harness/fixtures').decode().splitlines()
|
||||
data=subprocess.check_output(['git','cat-file','--batch'],cwd=WORK,input=''.join(f'{SOURCE}:{p}\n' for p in paths).encode())
|
||||
offset=0;inputs=[]
|
||||
for path in paths:
|
||||
end=data.index(b'\n',offset);_,kind,size=data[offset:end].split();assert kind==b'blob';size=int(size)
|
||||
blob=data[end+1:end+1+size];assert (WORK/path).read_bytes()==blob,path
|
||||
inputs.append({'path':path,'bytes':size,'sha256':sha(blob)});offset=end+size+2
|
||||
assert offset==len(data)
|
||||
new('inputs.json',{'source':SOURCE,'scope':'All tracked Cargo/config/shared build/crates/assets/docs/examples/harness fixture paths; exact raw committed blobs compared with current disk bytes before build.','inputs':inputs})
|
||||
env=os.environ.copy();env['CARGO_TARGET_DIR']=str(TARGET);env['CARGO_BUILD_JOBS']='1'
|
||||
assert Path(env['CARGO_HOME']).resolve()==ROOT/'.local/toolchain/cargo'
|
||||
assert Path(env['RUSTUP_HOME']).resolve()==ROOT/'.local/toolchain/rustup'
|
||||
versions={}
|
||||
for name,args in [('rustc',['rustc','-Vv']),('cargo',['cargo','-V']),('linker',['clang.exe','--version'])]:
|
||||
versions[name]=subprocess.check_output(args,cwd=WORK,env=env,stderr=subprocess.STDOUT).decode()
|
||||
tools={n:identity(shutil.which(n,path=env['PATH'])) for n in ['cargo','rustc','clang.exe']}
|
||||
toolchain_bin=ROOT/'.local/toolchain/rustup/toolchains/stable-x86_64-pc-windows-gnullvm/bin'
|
||||
for n in ['cargo.exe','rustc.exe']:tools['actual_'+n]=identity(toolchain_bin/n)
|
||||
runtime=ROOT/'.local/toolchain/llvm-mingw-20260908-ucrt-x86_64/bin/libunwind.dll'
|
||||
metadata={'source':SOURCE,'cwd':str(WORK),'target_directory':str(TARGET),'profile':'Cargo test default development/test profile; workspace profile.dev debug=0. No release optimization claimed.','versions':versions,'tools':tools,'env_script':identity(ROOT/'.local/toolchain/env.ps1'),'selected_environment':{k:env.get(k) for k in ['CARGO_HOME','RUSTUP_HOME','CARGO_TARGET_DIR','CARGO_BUILD_JOBS','CARGO_TARGET_X86_64_PC_WINDOWS_GNULLVM_LINKER','RUSTFLAGS','CARGO_ENCODED_RUSTFLAGS','PATH']},'runtime_path_candidate':identity(runtime),'runtime_binding_limit':'Hashed selected PATH candidate, not an observed loaded-module record.','runner':identity(__file__),'input_manifest':identity(OUT/'inputs.json')}
|
||||
new('preflight.json',metadata)
|
||||
command=['cargo','test','--locked','-p','oa-core','--test','review_regressions',TEST,'--','--exact','--test-threads=1','--nocapture']
|
||||
start=datetime.now(timezone.utc).isoformat();clock=time.monotonic()
|
||||
print(json.dumps({'start':start,'source':SOURCE,'input_count':len(inputs),'command':command,'target_directory':str(TARGET)}),flush=True)
|
||||
with (OUT/'cargo.log').open('xb') as log:
|
||||
p=subprocess.run(command,cwd=WORK,env=env,stdout=log,stderr=subprocess.STDOUT)
|
||||
elapsed=time.monotonic()-clock
|
||||
changed=[x['path'] for x in inputs if sha((WORK/x['path']).read_bytes())!=x['sha256']]
|
||||
executables=list((TARGET/'debug/deps').glob('review_regressions-*.exe'))
|
||||
listing=None;artifact=None
|
||||
if len(executables)==1:
|
||||
exe=executables[0];artifact=identity(exe)
|
||||
lc=[str(exe),TEST,'--exact','--list']
|
||||
with (OUT/'membership.stdout.log').open('xb') as out,(OUT/'membership.stderr.log').open('xb') as err:q=subprocess.run(lc,cwd=WORK,env=env,stdout=out,stderr=err)
|
||||
lines=(OUT/'membership.stdout.log').read_text().splitlines()
|
||||
selected=[line for line in lines if line.endswith(': test')]
|
||||
listing={'command':lc,'exit':q.returncode,'selected':selected,'exact_one':q.returncode==0 and selected==[TEST+': test'],'artifact_unchanged':artifact==identity(exe)}
|
||||
log=(OUT/'cargo.log').read_text(errors='replace')
|
||||
result={'source':SOURCE,'start':start,'end':datetime.now(timezone.utc).isoformat(),'elapsed_seconds':elapsed,'command':command,'exit':p.returncode,'changed_inputs':changed,'head_unchanged':git('rev-parse','HEAD').decode().strip()==SOURCE,'worktree_status':git('status','--porcelain').decode(),'log':identity(OUT/'cargo.log'),'artifact':artifact,'membership':listing,'log_running_one':bool(re.search(r'(?m)^running 1 test\s*$',log)),'log_test_failed':TEST+' ... FAILED' in log,'runtime_candidate_unchanged':metadata['runtime_path_candidate']==identity(runtime),'classification':'Result requires source/log diagnosis; no candidate acceptance inferred.'}
|
||||
new('result.json',result)
|
||||
print(log[-12000:]);print(json.dumps(result,indent=2))
|
||||
assert not changed and result['head_unchanged'] and not result['worktree_status']
|
||||
assert listing is not None and listing['exact_one'] and listing['artifact_unchanged'] and result['log_running_one']
|
||||
sys.exit(p.returncode)
|
||||
Reference in New Issue
Block a user