"""V2 reviewed admission and durable debit. No reset/refund or ledger CLI. WHY: reservation failure is consumed; immutable input SHA and run token bind all later actions. The lock inode remains stable across atomic JSON replaces. OFFLINE_TEST_ONLY ledgers are never accepted as native-run authorizations. """ import fcntl,hashlib,json,os,re,stat,time,uuid from pathlib import Path from plans import RUNS,LIMITS TICKET="SWAYFX_MOSAIC_STEP20C_REBUILD_FROM_GIT_COREC_OOM_GPU_NIGHT_SHIFT_V1" WL_SHA="7edca9a7d65855addda68e29ba5db94d57c803eb5fa7d0f86db3136b90ca9837" def need(v,m): if not v:raise ValueError(m) def sha(p):return hashlib.sha256(Path(p).read_bytes()).hexdigest() def encoded(value):return (json.dumps(value,sort_keys=True,indent=2)+"\n").encode() def digest(value):return hashlib.sha256(encoded(value)).hexdigest() def canonical_lab(lab): p=Path(lab);need(p.is_absolute() and str(p)==str(p.resolve()) and p.parent==Path("/var/tmp"),"canonical direct /var/tmp LAB required") st=p.stat();need(st.st_uid==os.getuid() and stat.S_ISDIR(st.st_mode),"LAB owner/type") return p def clean_environment(lab): lab=canonical_lab(lab) need((lab/"scratch").resolve()==lab/"scratch" and (lab/"scratch").stat().st_uid==os.getuid(),"canonical owned scratch required") # Allowlist avoids inherited loader, backend, activation and desktop authority. e={k:os.environ[k] for k in ("PATH","LANG","LC_ALL","TZ") if k in os.environ} e.update(TMPDIR=str(lab/"scratch"),TMP=str(lab/"scratch"),TEMP=str(lab/"scratch"),SMX_LAB=str(lab),XDG_CACHE_HOME=str(lab/"cache"),XDG_DATA_HOME=str(lab/"data"),PYTHONPYCACHEPREFIX=str(lab/"pycache"),CCACHE_DIR=str(lab/"cache/ccache")) return e def durable(path,value,exclusive=False): p=Path(path);tmp=p.with_name(p.name+".tmp-"+uuid.uuid4().hex) try: with tmp.open("xb") as f:f.write(encoded(value));f.flush();os.fsync(f.fileno()) if exclusive:os.link(tmp,p);tmp.unlink() else:os.replace(tmp,p) fd=os.open(p.parent,os.O_RDONLY|os.O_DIRECTORY) try:os.fsync(fd) finally:os.close(fd) finally: if tmp.exists():tmp.unlink() class Ledger: def __init__(self,lab,path=None,offline=False): self.lab=canonical_lab(lab);self.offline=offline self.path=Path(path) if path else self.lab/"budget.json" need(self.path.parent.resolve().is_relative_to(self.lab),"ledger outside LAB") need(not self.path.is_symlink(),"ledger symlink") if offline:need("OFFLINE_TEST_ONLY" in self.path.parts,"offline fixture namespace required") else:need(self.path==self.lab/"budget.json","real ledger fixed path") self.lock=self.path.with_name(self.path.name+".lock") def transaction(self,fn,initialize=False): fd=os.open(self.lock,os.O_RDWR|os.O_CREAT|os.O_NOFOLLOW,0o600) try: st=os.fstat(fd);need(st.st_uid==os.getuid() and stat.S_ISREG(st.st_mode) and st.st_nlink==1 and not st.st_mode&0o077,"stable lock owner/type/link") fcntl.flock(fd,fcntl.LOCK_EX) need(os.stat(self.lock,follow_symlinks=False).st_ino==st.st_ino,"lock inode changed") if initialize:need(not self.path.exists(),"ledger already initialized");d=None else: s=self.path.lstat();need(s.st_uid==os.getuid() and stat.S_ISREG(s.st_mode) and s.st_nlink==1,"ledger owner/type/link") d=json.loads(self.path.read_text());need(d["ticket"]==TICKET and d["lab"]==str(self.lab) and d["uid"]==os.getuid(),"old ticket/LAB/UID") need(d["namespace"]==("OFFLINE_TEST_ONLY" if self.offline else "REAL") and d["limits"]==LIMITS,"namespace/limits") value,new=fn(d);durable(self.path,new,exclusive=initialize);return value finally:os.close(fd) def initialize(self): return self.transaction(lambda _: (None,dict(ticket=TICKET,lab=str(self.lab),uid=os.getuid(),namespace="OFFLINE_TEST_ONLY" if self.offline else "REAL",limits=LIMITS,runs=[])),True) def admit(self,rid,manifest,review,publication): auth=validate_review(self.lab,manifest,review,publication,rid,offline=self.offline) def reserve(d): spec=RUNS[rid] # WHY/CONTRACT/INVARIANT: O2 is dependent evidence, never a retry after O1 # availability or invariant failure. Missing/unfinished O1 blocks admission. if rid=='O2': prior=[r for r in d['runs'] if r['id']=='O1'] need(len(prior)==1 and prior[0]['status']=='COMPLETED' and prior[0].get('outcome',{}).get('status')=='PARTIALLY_FEASIBLE',"O1 critical/unresolved failure blocks O2") need(not any(r["id"]==rid for r in d["runs"]),"consumed run") need(len(d["runs"])<14 and sum(r["capture_limit"] for r in d["runs"])+spec["capture_limit"]<=180,"global budget") token=uuid.uuid4().hex;r=dict(id=rid,token=token,started_ns=time.monotonic_ns(),capture_limit=spec["capture_limit"],action_limits=spec["action_limits"],actions={},status="RESERVED",bindings=auth) d["runs"].append(r);return dict(auth,token=token,run_id=rid,lab=str(self.lab),offline=self.offline),d return self.transaction(reserve) def action_debit(self,auth,*kinds): # Revalidate all frozen source/review/publication/binary bytes before each action. fresh=validate_review(self.lab,auth["manifest"],auth["review"],auth["publication"],auth["run_id"],offline=self.offline) def update(d): rows=[r for r in d["runs"] if r["id"]==auth["run_id"]];need(len(rows)==1,"missing reservation");r=rows[0] need(r["token"]==auth["token"] and r["bindings"]==fresh and r["status"]=="RESERVED","token/stale bindings/completed") need(time.monotonic_ns()-r["started_ns"]<150_000_000_000,"duration exhausted") actions=dict(r["actions"]) for kind in kinds: limit=r["capture_limit"] if kind=="capture" else r["action_limits"].get(kind,0) need(actions.get(kind,0)