reader.py
python · 82 lines · Sanitized derivative
Sanitized derivative: private paths or personal test identities use explicit placeholders. Original line count is preserved.
Version & provenance · theory-cm7
Recorded SHA-256 cc4526c37e0576007a1519813f165fe129310da0c8a95a878eface31ba77bb00Rendered SHA-256 8f60e18e0c7e35f936fa32e9d033e154d09d885daa247bf0bf4a7eba044a27a1
Apache-2.0 original project code; dependencies retain their own licenses. License notes. Line links are stable within this snapshot. CM-7 completed implementation source; original and public rendered hashes recorded. Host-specific paths use /work placeholders; inspect reproduction instructions before running. Separate Rust helper retains its GPL license.
1"""Three sealed sources and an explicit pair schedule; no PGN work in training."""
2import sys,json,hashlib
3from pathlib import Path
4import numpy as np
5H=Path(__file__).resolve().parent;P=H.parent;BUILDER=Path('/work/source/2026-10-29/task')
6sys.path[1:1]=[str(BUILDER),str(P/'state-v2')]
7from book_pair_loader import BookPairs
8from records import DTYPE,sha,Records as SmallRecords
9from runtime_records import Records
10sys.path.insert(0,str(H))
11PAIR=np.dtype([('source','u1'),('row','<u4'),('choice','<u2')])
12SD=np.dtype([('kind','u1'),('index','<u4')])
13class Data:
14 def __init__(self,manifest,verify=True):
15 self.manifest=json.loads(Path(manifest).read_text());m=self.manifest
16 for path,h in m['bindings'].items():
17 if sha(path)!=h:raise ValueError('followup input changed: '+path)
18 self.schedule=np.memmap(m['schedule'],dtype=SD,mode='r')
19 if sha(m['schedule'])!=m['schedule_sha256'] or len(self.schedule)!=m['decisions']:raise ValueError('schedule integrity')
20 self.book=BookPairs(m['book'],verify=verify)
21 self.exact_pairs=np.memmap(Path(m['replay'])/'exact-pairs.bin',dtype=PAIR,mode='r')
22 self.exact={s:SmallRecords(m['exact'],s,0,verify=verify) for s in (0,1)}
23 self.metadata=[json.loads(x) for x in (Path(m['exact'])/'metadata.jsonl').read_text().splitlines()]
24 self.elite=Records(m['ordinary'],1,0,verify=verify)
25 self.sources={('book',2):self.book.records,('exact',0):self.exact[0],('exact',1):self.exact[1],('elite',1):self.elite}
26 def take(self,ids):
27 ids=np.asarray(ids,dtype=np.int64)
28 if ids.ndim!=1 or np.any(ids<0) or np.any(ids>=len(self.schedule)):raise IndexError('schedule index')
29 e=self.schedule[ids];out=np.empty(len(ids),dtype=DTYPE)
30 if np.any(e['kind']>2):raise ValueError('unknown source kind')
31 for kind in (0,1,2):
32 mask=e['kind']==kind
33 if not mask.any():continue
34 indices=e['index'][mask]
35 if kind==0:out[mask]=self.book.take(indices)
36 elif kind==2:out[mask]=self.elite.take(indices)
37 else:
38 if np.any(indices>=len(self.exact_pairs)):raise IndexError('exact pair')
39 pairs=self.exact_pairs[indices];rows=np.empty(len(pairs),dtype=DTYPE)
40 if np.any(pairs['source']>1):raise ValueError('exact source')
41 for s in (0,1):
42 selected=pairs['source']==s
43 if selected.any():rows[selected]=self.exact[s].take(pairs['row'][selected])
44 for i,pair in enumerate(pairs):
45 target=self.metadata[int(rows[i]['game'])]['tied_target_triples'][int(pair['choice'])]
46 rows[i]['y']=target;rows[i]['x'][-2:]=target[:2]
47 out[mask]=rows
48 return out
49 def close(self):
50 self.book.records.close();self.elite.close()
51
52class Ledger:
53 def __init__(self,data):
54 self.data=data;self.book_states=len(data.book.records);self.exact0=len(data.exact[0]);self.exactn=self.exact0+len(data.exact[1])
55 self.pair_offsets=(0,len(data.book),len(data.book)+len(data.exact_pairs))
56 self.pair_n=self.pair_offsets[2]+len(data.elite)
57 self.state_n=self.book_states+self.exactn+len(data.elite)
58 def snapshot(self,cursor):
59 import torch
60 if not 0<=cursor<=len(self.data.schedule):raise ValueError('cursor')
61 pairs=np.zeros(self.pair_n,dtype=np.uint32);states=np.zeros(self.state_n,dtype=np.uint32)
62 for start in range(0,cursor,65536):
63 e=self.data.schedule[start:min(cursor,start+65536)]
64 if np.any(e['kind']>2):raise ValueError('schedule kind')
65 for kind in (0,1,2):
66 ids=e['index'][e['kind']==kind].astype(np.int64)
67 np.add.at(pairs,ids+self.pair_offsets[kind],1)
68 if kind==0:state=self.data.book.pairs[ids]['row'].astype(np.int64)
69 elif kind==1:
70 p=self.data.exact_pairs[ids];state=self.book_states+p['row'].astype(np.int64)+p['source'].astype(np.int64)*self.exact0
71 else:state=self.book_states+self.exactn+ids
72 np.add.at(states,state,1)
73 if np.any(pairs[:self.pair_offsets[1]]>3) or np.any(pairs[self.pair_offsets[2]:]>1) or np.any(states[:self.book_states]>33) or np.any(states[self.book_states:self.book_states+self.exactn]>90):raise ValueError('exposure ceiling')
74 return {'cursor':cursor,'pair_counts':torch.from_numpy(pairs),'state_counts':torch.from_numpy(states),
75 'sha256':hashlib.sha256(pairs.tobytes()+states.tobytes()).hexdigest(),'exposures':int(pairs.astype(np.uint64).sum()),
76 'unique_pairs':int(np.count_nonzero(pairs)),'unique_states':int(np.count_nonzero(states))}
77 def verify(self,value):
78 import torch
79 actual=self.snapshot(value['cursor'])
80 if any(value[k]!=actual[k] for k in ('sha256','exposures','unique_pairs','unique_states')) or any(not torch.equal(value[k],actual[k]) for k in ('pair_counts','state_counts')):raise ValueError('exposure ledger mismatch')
81 return actual['cursor']
82