code wiki / _hdl_build / nx_queue_load.nx
nx_queue_load.nx source
↩ module page · 267 lines · 11515 B
1// nx_queue_load.nx -- IM-Q1: the PROGRAM'S OWN COORDINATION DATA becomes
2// first-class records on the sovereign store (operator 2026-06-11: "own our
3// information management -- a tsv file is not nishi; bottom up hardware rung
4// and each rung nishi"). The seg-store substrate is already hardware-up
5// (rungs 1-9, beats FTS5); this rung puts the QUEUE on it:
6// assignment_queue.tsv rows -> key "aq:"+<row-id>, value = canonical record
7// {kind: queue-row, id, row}. SAME key, NEW VERSION on every change --
8// `nx_store_query hist aq:X-Q-003` is the row's full status time-travel,
9// something the bare TSV can never answer. Idempotent: unchanged row =
10// identical canonical bytes = dup_instore, never re-added.
11// sponsor_decisions.tsv / planning_prefs.tsv / callouts.tsv lines ->
12// content-CID line records (sd:/pp:/co: prefixes, nx_log_load pattern) --
13// the sponsor's decisions + the training corpus gain provenance lineage.
14// The TSV files stay as the WRITE surface this rung (API stability); IM-Q2
15// (filed) moves writers store-first and derives the TSV as a render.
16// argv[1]=store prefix override, argv[2]=queue path override (gates).
17// Evidence: QUEUE-STORE row -> stdout + knowledge/status/infomgmt_store.log.
18// license_tier: ORIGINAL
19
20import "nx_syscalls.nx"
21import "nx_canon_cid.nx"
22import "nx_seg_store.nx"
23// Field 0 of a queue row is a short id like "X-Q-003". This bounds the SCAN for
24// the first tab and is a SEMANTIC rule, not a buffer capacity -- it is the only
25// bound left in this organ. Every buffer below is sized from its own input
26// (canon_encode_size for records, the line length for a row, the file length for
27// the reused line buffer), so no capacity constant has to be kept in sync with
28// anything, and nothing can be dropped because a guessed ceiling was too low.
29const QL_MAX_ID_LEN: i64 = 40
30
31func ql_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
32func ql_fp(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd,s,n); return 0 }
33func ql_fn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 }
34
35func ql_memeq(a: *u8, b: *u8, n: i64) -> i64 {
36 var i: i64 = 0
37 while i < n {
38 if a[i] != b[i] { return 0 }
39 i = i + 1
40 }
41 return 1
42}
43
44// st: st[0]=writer st[1]=wdocs st[2]=segs st[3]=added st[4]=dup st[5]=scanned
45// st[6]=abort-rc st[7]=open handle
46const QL_CHUNK: i64 = 64
47
48func ql_flush(prefix: *u8, st: *i64) -> i64 {
49 if st[1] == 0 { return 0 }
50 let rc: i64 = ss_commit(prefix, st[0] as *i64, sys_now_us())
51 if rc != 0 { st[6] = rc; return rc }
52 st[0] = ss_begin() as i64
53 st[1] = 0
54 st[2] = st[2] + 1
55 return 0
56}
57
58// add record if the store's latest version differs (or key absent); 0/neg
59func ql_put(prefix: *u8, st: *i64, kbuf: *u8, enc: *u8, el: i64) -> i64 {
60 let pp: *i64 = sys_mmap(16) as *i64
61 let ll: *i64 = sys_mmap(16) as *i64
62 var have: i64 = 0
63 let g: i64 = ss_hget(st[7] as *i64, kbuf, pp, ll)
64 if g == 1 { if ll[0] == el { if ql_memeq(pp[0] as *u8, enc, el) == 1 { have = 1 } } }
65 if have == 1 { st[4] = st[4] + 1; return 0 }
66 if ss_add(st[0] as *i64, 1, kbuf, enc, el) != 0 { st[6] = 0 - 98; return 0 - 3 }
67 st[3] = st[3] + 1
68 st[1] = st[1] + 1
69 if st[1] >= QL_CHUNK { if ql_flush(prefix, st) != 0 { return 0 - 4 } }
70 return 0
71}
72
73// one queue row line [i,lend) -> aq:<id> versioned record
74func ql_row(prefix: *u8, st: *i64, b: *u8, i: i64, lend: i64) -> i64 {
75 let llen: i64 = lend - i
76 if llen <= 0 { return 0 }
77 if b[i] == (35 as u8) { return 0 }
78 // There is deliberately no length ceiling here. The buffers below are sized
79 // from llen, so a cap would have nothing to protect. The 3800-byte guard this
80 // replaces returned SUCCESS and fired BEFORE st[5] incremented, so an
81 // over-long queue row was absent from the numerator AND the denominator --
82 // nothing in this organ's output could ever reveal that a row was lost.
83 // id = field 0 (to first tab); no tab = not a row
84 var idl: i64 = 0
85 var go: i64 = 1
86 while go == 1 {
87 if i + idl >= lend { return 0 } else {
88 if b[i + idl] == (9 as u8) { go = 0 } else {
89 idl = idl + 1
90 // Semantic rejection, and it ANNOUNCES: a rejected line must never
91 // be indistinguishable from a line that was not there.
92 if idl > QL_MAX_ID_LEN { st[8] = st[8] + 1; return 0 }
93 }
94 }
95 }
96 if idl == 0 { return 0 }
97 st[5] = st[5] + 1
98 let idb: *u8 = sys_mmap(idl + 1)
99 var t: i64 = 0
100 while t < idl { idb[t] = b[i + t]; t = t + 1 }
101 idb[idl] = 0 as u8
102 let lbuf: *u8 = sys_mmap(llen + 1)
103 t = 0
104 while t < llen { lbuf[t] = b[i + t]; t = t + 1 }
105 lbuf[llen] = 0 as u8
106 let keys: *i64 = sys_mmap(8 * 4) as *i64
107 let vals: *i64 = sys_mmap(8 * 4) as *i64
108 keys[0] = "kind" as *u8 as i64
109 keys[1] = "id" as *u8 as i64
110 keys[2] = "row" as *u8 as i64
111 vals[0] = "queue-row" as *u8 as i64
112 vals[1] = idb as i64
113 vals[2] = lbuf as i64
114 // EXACT, from the encoder's own arithmetic -- not a cap, not headroom.
115 let enc: *u8 = sys_mmap(canon_encode_size(keys, vals, 3))
116 let el: i64 = canon_encode(keys, vals, 3, enc)
117 let kbuf: *u8 = sys_mmap(128)
118 var ko: i64 = 0
119 ko = ss_cat(kbuf, ko, "aq:" as *u8)
120 ko = ss_cat(kbuf, ko, idb)
121 kbuf[ko] = 0 as u8
122 return ql_put(prefix, st, kbuf, enc, el)
123}
124
125func ql_load_queue(prefix: *u8, path: *u8, st: *i64) -> i64 {
126 let szp: *i64 = sys_mmap(16) as *i64
127 let b: *u8 = ss_readall(path, szp)
128 let sz: i64 = szp[0]
129 if sz <= 0 { return 0 - 1 }
130 var i: i64 = 0
131 while i < sz {
132 var e: i64 = i
133 var go: i64 = 1
134 while go == 1 {
135 if e >= sz { go = 0 } else {
136 if b[e] == (10 as u8) { go = 0 } else { e = e + 1 }
137 }
138 }
139 if ql_row(prefix, st, b, i, e) < 0 { return 0 - 2 }
140 i = e + 1
141 }
142 return 0
143}
144
145// line-CID records for a sponsor-surface file (nx_log_load pattern)
146func ql_load_lines(prefix: *u8, path: *u8, tag: *u8, st: *i64) -> i64 {
147 let szp: *i64 = sys_mmap(16) as *i64
148 let b: *u8 = ss_readall(path, szp)
149 let sz: i64 = szp[0]
150 if sz <= 0 { return 0 }
151 let keys: *i64 = sys_mmap(8 * 4) as *i64
152 let vals: *i64 = sys_mmap(8 * 4) as *i64
153 keys[0] = "kind" as *u8 as i64
154 keys[1] = "log" as *u8 as i64
155 keys[2] = "line" as *u8 as i64
156 vals[0] = "sponsor-surface-line" as *u8 as i64
157 vals[1] = tag as i64
158 // Allocated ONCE and reused for every line -- sizing per line would allocate
159 // inside the hot loop. No line can be longer than the file that contains it,
160 // so sz is a proven-sufficient bound rather than a guessed one.
161 let lbuf: *u8 = sys_mmap(sz + 1)
162 lbuf[0] = 0 as u8
163 vals[2] = lbuf as i64
164 // canon_encode_size over an empty line yields the exact fixed cost of this
165 // record's keys and values; the only quantity the encoder cannot know is the
166 // longest line, and the file length bounds that exactly.
167 let enc: *u8 = sys_mmap(canon_encode_size(keys, vals, 3) + sz)
168 let cid: *u8 = sys_mmap(96)
169 let kbuf: *u8 = sys_mmap(160)
170 var i: i64 = 0
171 while i < sz {
172 var e: i64 = i
173 var go: i64 = 1
174 while go == 1 {
175 if e >= sz { go = 0 } else {
176 if b[e] == (10 as u8) { go = 0 } else { e = e + 1 }
177 }
178 }
179 let llen: i64 = e - i
180 var use: i64 = 1
181 if llen <= 0 { use = 0 }
182 // no length test: lbuf is sized from the file, so every line fits
183 if use == 1 { if b[i] == (35 as u8) { use = 0 } }
184 if use == 1 {
185 // Sponsor-surface lines are counted SEPARATELY from queue rows. One
186 // counter serving two populations cannot be checked against either:
187 // a fixture of 3 queue rows read 131 because this pass shared st[5],
188 // so the number could not confirm or refute anything about the queue.
189 st[9] = st[9] + 1
190 var t: i64 = 0
191 while t < llen { lbuf[t] = b[i + t]; t = t + 1 }
192 lbuf[llen] = 0 as u8
193 vals[2] = lbuf as i64
194 let el: i64 = canon_encode(keys, vals, 3, enc)
195 cid_of(enc, el, cid)
196 var ko: i64 = 0
197 ko = ss_cat(kbuf, ko, tag)
198 ko = ss_cat(kbuf, ko, ":" as *u8)
199 ko = ss_cat(kbuf, ko, cid)
200 kbuf[ko] = 0 as u8
201 if ql_put(prefix, st, kbuf, enc, el) < 0 { return 0 - 2 }
202 }
203 i = e + 1
204 }
205 return 0
206}
207
208func main(argc: i64, argv: *i64) -> i64 {
209 var prefix: *u8 = "knowledge/store/im-" as *u8
210 var qpath: *u8 = "knowledge/registry/assignment_queue.tsv" as *u8
211 if argc >= 2 { prefix = argv[1] as *u8 }
212 if argc >= 3 { qpath = argv[2] as *u8 }
213 let logfd: i64 = sys_openat_append("knowledge/status/infomgmt_store.log" as *u8, MODE_0644)
214
215 let st: *i64 = sys_mmap(8 * 16) as *i64
216 st[0] = ss_begin() as i64
217 st[7] = ss_open(prefix) as i64
218
219 if ql_load_queue(prefix, qpath, st) != 0 {
220 ql_p("QUEUE-STORE FAILED rc-inner=" as *u8); ql_fn(1, st[6]); ql_p(" -- fail loud\n" as *u8)
221 sys_exit(1)
222 }
223 // sponsor surfaces ride the same pass (real paths only; scratch gates
224 // pass a scratch prefix so these dedup against it harmlessly)
225 ql_load_lines(prefix, "knowledge/registry/sponsor_decisions.tsv" as *u8, "sd" as *u8, st)
226 ql_load_lines(prefix, "knowledge/registry/planning_prefs.tsv" as *u8, "pp" as *u8, st)
227 ql_load_lines(prefix, "knowledge/registry/callouts.tsv" as *u8, "co" as *u8, st)
228 if st[6] != 0 {
229 ql_p("QUEUE-STORE FAILED late rc=" as *u8); ql_fn(1, st[6]); ql_p("\n" as *u8)
230 sys_exit(1)
231 }
232 if ql_flush(prefix, st) != 0 {
233 ql_p("QUEUE-STORE final commit FAILED -- fail loud\n" as *u8)
234 sys_exit(1)
235 }
236
237 // probe: the queue is QUERYABLE on the team's own substrate
238 let h2: *i64 = ss_open(prefix)
239 let pp2: *i64 = sys_mmap(16) as *i64
240 let ll2: *i64 = sys_mmap(16) as *i64
241 let probe: i64 = ss_hget(h2, "aq:X-Q-003" as *u8, pp2, ll2)
242
243 var fdi: i64 = 0
244 while fdi < 2 {
245 var fd: i64 = 1
246 if fdi == 1 { fd = logfd }
247 if fd > 0 {
248 ql_fp(fd, "QUEUE-STORE queue_rows=" as *u8); ql_fn(fd, st[5])
249 ql_fp(fd, " sponsor_lines=" as *u8); ql_fn(fd, st[9])
250 ql_fp(fd, " added=" as *u8); ql_fn(fd, st[3])
251 ql_fp(fd, " dup_instore=" as *u8); ql_fn(fd, st[4])
252 // Lines whose field 0 was too long to be a queue id. These are
253 // expected (prose, banners) -- but they are REPORTED, because a line
254 // this organ declined to ingest must never look like a line that was
255 // never in the file.
256 ql_fp(fd, " rejected_long_id=" as *u8); ql_fn(fd, st[8])
257 ql_fp(fd, " segments=" as *u8); ql_fn(fd, st[2])
258 ql_fp(fd, " probe_aq=" as *u8); ql_fn(fd, probe)
259 ql_fp(fd, " epoch=" as *u8); ql_fn(fd, sys_now_realtime_sec())
260 ql_fp(fd, " verdict=GREEN\n" as *u8)
261 }
262 fdi = fdi + 1
263 }
264 if logfd > 0 { sys_close(logfd) }
265 sys_exit(0)
266 return 0
267}