from pathlib import Path import subprocess,json,hashlib,stat root=Path('/home/worsch/key-cape');out=Path('/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/key39-finalization-blocking-reason-r1');backup=out/'consistency-backup';backup.mkdir() def git(*args):return subprocess.check_output(['git','-C',str(root),*args]).decode() head=git('rev-parse','HEAD').strip();assert head==json.loads((out/'commit.json').read_text())['commit'] assert git('diff-tree','--no-commit-id','--name-only','-r',head).splitlines()==['workplans/KEY-WP-0039-openbao-negative-probe-tokens.md'] assert not git('status','--porcelain=v1') paths=sorted({p.relative_to(root).as_posix() for p in (root/'workplans').rglob('*.md')}|{n for n in ('.custodian-brief.md','WORK-RECORDS.md') if (root/n).exists()}) original={} for rel in paths: p=root/rel;assert p.is_file() and not p.is_symlink() dest=backup/rel;dest.parent.mkdir(parents=True,exist_ok=True);dest.write_bytes(p.read_bytes()) original[rel]={'sha256':hashlib.sha256(p.read_bytes()).hexdigest(),'mode':stat.S_IMODE(p.stat().st_mode),'index':git('ls-files','--stage','--',rel)} (backup/'originals.json').write_text(json.dumps(original,indent=2)+'\n') results=[];changed=[] try: for label,argv in [('consistency',['statehub','fix-consistency','--repo','key-cape','--json']),('normal-sync',['/home/worsch/repo-manager/.venv/bin/rmgr','sync','--path',str(root),'--push'])]: cp=subprocess.run(argv,cwd=root,stdout=subprocess.PIPE,stderr=subprocess.PIPE,timeout=240) (out/(label+'.stdout.json')).write_bytes(cp.stdout);(out/(label+'.stderr.txt')).write_bytes(cp.stderr) results.append({'command':argv,'exit_code':cp.returncode,'label':label}) finally: assert git('rev-parse','HEAD').strip()==head,'unexpected commit; stop for review' for rel,b in original.items(): p=root/rel if not p.exists() or hashlib.sha256(p.read_bytes()).hexdigest()!=b['sha256']: changed.append(rel);p.write_bytes((backup/rel).read_bytes());p.chmod(b['mode']) current=git('ls-files','--stage','--',rel) if current!=b['index']: assert b['index'];mode,oid,stage,path=b['index'].split();assert stage=='0' git('update-index','--cacheinfo',mode,oid,path) assert git('ls-files','--stage','--',rel)==b['index'] assert hashlib.sha256(p.read_bytes()).hexdigest()==b['sha256'] assert not git('status','--porcelain=v1'),git('status','--porcelain=v1') receipt={'published_candidate_commit':head,'normal_commands':results,'unrelated_writeback_restored':changed,'all_original_index_worktree_fields_preserved':True,'one_path_commit':True,'normal_hooks':'changed-staged-blobs scanner8.30.1 clean','native_or_credential_actions':0} (out/'normal-publication.json').write_text(json.dumps(receipt,indent=2)+'\n') print(json.dumps(receipt))