nx_measurement_binding_lib.nx source
↩ module page · 342 lines · 14812 B
1// nx_measurement_binding_lib.nx -- read-only projection of authored plan contracts,
2// retained rank snapshots and matrix-to-source declaration observations. No ranking, execution or publication.
3// Consumers retain the input buffers while using returned spans. A declared contract
4// symbol is not verified behavior; an absent rank row is not proof of completion.
5// license_tier: ORIGINAL
6import "nx_ladder_lib.nx"
7import "nx_matrix_sym_lib.nx"
8import "nx_symdecl_lib.nx"
9import "nx_readcap_lib.nx"
10
11// Wire fields from the existing rung| and rank| producers.
12const PB_PLAN_FIELDS: i64 = 8
13const PB_F_SYMBOL: i64 = 3
14const PB_F_DONE_RULE: i64 = 4
15const PB_F_EXECUTOR: i64 = 5
16const PB_F_ESTIMATE: i64 = 6
17const PB_ROW_SLOTS: i64 = 10
18const PB_PLAN_START: i64 = 0
19const PB_PLAN_END: i64 = 1
20const PB_ORDER_START: i64 = 2
21const PB_ORDER_END: i64 = 3
22const PB_FINISH_START: i64 = 4
23const PB_FINISH_END: i64 = 5
24const PB_UNMAPPED_START: i64 = 6
25const PB_UNMAPPED_END: i64 = 7
26const PB_PLAN_FIELD_COUNT: i64 = 8
27const PB_PLAN_SHAPE: i64 = 9
28const PB_PREFIX_FIELDS: i64 = 5
29const PB_SHAPE_RAW: i64 = 0
30const PB_SHAPE_FULL: i64 = 1
31const PB_SHAPE_PREFIX: i64 = 2
32const PB_STATS_SLOTS: i64 = 6
33const PB_S_RUNGS: i64 = 0
34const PB_S_ORDERED: i64 = 1
35const PB_S_FINISH: i64 = 2
36const PB_S_UNMAPPED: i64 = 3
37const PB_S_RANK_ASOF: i64 = 4
38const PB_S_RANK_STATE: i64 = 5
39const PB_OK: i64 = 0
40const PB_RANK_MISSING: i64 = 1
41const PB_E_INPUT: i64 = 0-1
42const PB_E_CAPACITY: i64 = 0-2
43const PB_E_ROW: i64 = 0-3
44const PB_E_DUP_PLAN: i64 = 0-4
45const PB_E_STAMP: i64 = 0-5
46const PB_E_ORPHAN: i64 = 0-6
47const PB_E_SYMBOL: i64 = 0-7
48const PB_E_DUP_RANK: i64 = 0-8
49const PB_I64_MAX: i64 = 9223372036854775807
50
51func pb_input_ok(buf: *u8, n: i64) -> i64 {
52 if n < 0 { return 0 }
53 if n > 0 { if (buf as i64) == 0 { return 0 } }
54 var p: i64 = 0
55 while p < n { if buf[p] == (0 as u8) { return 0 } p = p + 1 }
56 return 1
57}
58func pb_trim_cr(buf: *u8, p: i64, end: i64) -> i64 {
59 if end > p { if buf[end-1] == (13 as u8) { return end-1 } }
60 return end
61}
62func pb_equal(a: *u8, ao: i64, an: i64, b: *u8, bo: i64, bn: i64) -> i64 {
63 if an != bn { return 0 }
64 var i: i64 = 0
65 while i < an { if a[ao+i] != b[bo+i] { return 0 } i = i + 1 }
66 return 1
67}
68func pb_rank_clear(rows: *i64, count: i64, stats: *i64, state: i64) -> i64 {
69 var r: i64 = 0
70 while r < count {
71 var f: i64 = PB_ORDER_START
72 while f <= PB_UNMAPPED_END { rows[r*PB_ROW_SLOTS+f] = BF_NONE; f = f + 1 }
73 r = r + 1
74 }
75 stats[PB_S_ORDERED] = 0; stats[PB_S_FINISH] = 0; stats[PB_S_UNMAPPED] = 0
76 stats[PB_S_RANK_ASOF] = BF_NONE; stats[PB_S_RANK_STATE] = state
77 return state
78}
79// Preserve every authored rung row, including partial and unfamiliar shapes.
80// Shape-specific normalization is separate from census and raw source preservation.
81func pb_field_count(plan: *u8, p: i64, e: i64, scratch: *i64) -> i64 {
82 var fields: i64 = 0
83 while bf_field(plan, p, e, fields, scratch) >= 0 { fields = fields+1 }
84 return fields
85}
86func pb_plan_shape(fields: i64) -> i64 {
87 if fields == PB_PLAN_FIELDS { return PB_SHAPE_FULL }
88 if fields == PB_PREFIX_FIELDS { return PB_SHAPE_PREFIX }
89 return PB_SHAPE_RAW
90}
91func pb_shape_name(shape: i64) -> *u8 {
92 if shape == PB_SHAPE_FULL { return "full_contract_8" as *u8 }
93 if shape == PB_SHAPE_PREFIX { return "contract_prefix_5" as *u8 }
94 return "uninterpreted" as *u8
95}
96// A semantic accessor must not mistake Organ or a done-rule for a contract symbol.
97func pb_plan_field(plan: *u8, rows: *i64, base: i64, field: i64, scratch: *i64) -> i64 {
98 scratch[0] = BF_NONE
99 if field >= PB_F_SYMBOL {
100 if rows[base+PB_PLAN_SHAPE] == PB_SHAPE_RAW { return BF_NONE }
101 if rows[base+PB_PLAN_SHAPE] == PB_SHAPE_PREFIX { if field > PB_F_DONE_RULE { return BF_NONE } }
102 }
103 let n: i64 = bf_field(plan, rows[base+PB_PLAN_START], rows[base+PB_PLAN_END], field, scratch)
104 if n < 0 { scratch[0] = BF_NONE; return BF_NONE }
105 return n
106}
107func pb_plan_scan(plan: *u8, n: i64, rows: *i64, capacity: i64, stats: *i64, scratch: *i64) -> i64 {
108 if (stats as i64) == 0 { return PB_E_INPUT }
109 stats[PB_S_RUNGS] = 0
110 pb_rank_clear(rows, 0, stats, PB_RANK_MISSING)
111 if pb_input_ok(plan, n) == 0 { return PB_E_INPUT }
112 if capacity < 0 { return PB_E_INPUT }
113 if (scratch as i64) == 0 { return PB_E_INPUT }
114 if capacity > 0 { if (rows as i64) == 0 { return PB_E_INPUT } }
115 var count: i64 = 0
116 var p: i64 = 0
117 while p < n {
118 let raw: i64 = bf_line_end(plan, n, p)
119 let e: i64 = pb_trim_cr(plan, p, raw)
120 if bf_line_starts(plan, p, e, LD_RUNG_TAG) == 1 {
121 if count >= capacity { return PB_E_CAPACITY }
122 let base: i64 = count*PB_ROW_SLOTS
123 rows[base+PB_PLAN_START] = p; rows[base+PB_PLAN_END] = e
124 let fields: i64 = pb_field_count(plan, p, e, scratch)
125 rows[base+PB_PLAN_FIELD_COUNT] = fields
126 rows[base+PB_PLAN_SHAPE] = pb_plan_shape(fields)
127 count = count+1
128 }
129 p = raw+1
130 }
131 stats[PB_S_RUNGS] = count
132 pb_rank_clear(rows, count, stats, PB_RANK_MISSING)
133 return count
134}
135// IDs identify declared rows; repeated IDs are preserved but cannot be joined silently.
136func pb_find_rung(plan: *u8, rows: *i64, count: i64, other: *u8, off: i64, len: i64, scratch: *i64) -> i64 {
137 var found: i64 = BF_NONE
138 if len <= 0 { return BF_NONE }
139 var i: i64 = 0
140 while i < count {
141 let base: i64 = i*PB_ROW_SLOTS
142 let n: i64 = pb_plan_field(plan, rows, base, LD_F_R_ID, scratch)
143 if n > 0 {
144 if pb_equal(plan, scratch[0], n, other, off, len) == 1 {
145 if found >= 0 { return PB_E_DUP_PLAN }
146 found = i
147 }
148 }
149 i = i+1
150 }
151 return found
152}
153// Only the FINAL nonempty line can supply the rank snapshot stamp. Domain binding is
154// exact; a preceding stamp or another domain cannot date the current projection.
155func pb_rank_stamp(domain: *u8, rank: *u8, n: i64) -> i64 {
156 var last: i64 = BF_NONE
157 var lastend: i64 = 0
158 var p: i64 = 0
159 while p < n {
160 let raw: i64 = bf_line_end(rank, n, p)
161 let e: i64 = pb_trim_cr(rank, p, raw)
162 if e > p { last = p; lastend = e }
163 p = raw + 1
164 }
165 if last < 0 { return PB_E_STAMP }
166 if rank[last] != (35 as u8) { return PB_E_STAMP }
167 if bf_line_starts(rank, last+1, lastend, " asof=" as *u8) == 0 { return PB_E_STAMP }
168 p = last + 7
169 var epoch: i64 = 0
170 var digits: i64 = 0
171 while p < lastend {
172 let d: i64 = (rank[p] as i64) - 48
173 if d < 0 { break }
174 if d > 9 { break }
175 if epoch > (PB_I64_MAX-d)/10 { return PB_E_STAMP }
176 epoch = epoch*10+d; digits = digits+1; p = p+1
177 }
178 if digits == 0 { return PB_E_STAMP }
179 if epoch <= 0 { return PB_E_STAMP }
180 if bf_line_starts(rank, p, lastend, " domain=" as *u8) == 0 { return PB_E_STAMP }
181 p = p+8
182 let ds: i64 = p
183 while p < lastend { if rank[p] == (32 as u8) { break } p = p+1 }
184 let dl: i64 = bf_slen(domain)
185 if dl == 0 { return PB_E_STAMP }
186 if pb_equal(rank, ds, p-ds, domain, 0, dl) == 0 { return PB_E_STAMP }
187 if p >= lastend { return PB_E_STAMP }
188 return epoch
189}
190// Unmapped diagnostics may coexist with ordered or finish rows. On any conflict,
191// clear ALL rank links so a caller cannot accidentally publish a reconciled prefix.
192func pb_rank_join(domain: *u8, plan: *u8, rank: *u8, n: i64, rows: *i64, count: i64, stats: *i64, scratch: *i64) -> i64 {
193 if (stats as i64) == 0 { return PB_E_INPUT }
194 if count < 0 { return PB_E_INPUT }
195 if count > 0 { if (rows as i64) == 0 { return PB_E_INPUT } }
196 pb_rank_clear(rows, count, stats, PB_RANK_MISSING)
197 if count > 0 { if (plan as i64) == 0 { return pb_rank_clear(rows, count, stats, PB_E_INPUT) } }
198 if pb_input_ok(rank, n) == 0 { return pb_rank_clear(rows, count, stats, PB_E_INPUT) }
199 if (scratch as i64) == 0 { return pb_rank_clear(rows, count, stats, PB_E_INPUT) }
200 if (domain as i64) == 0 { return pb_rank_clear(rows, count, stats, PB_E_INPUT) }
201 if n == 0 { return PB_RANK_MISSING }
202 let asof: i64 = pb_rank_stamp(domain, rank, n)
203 if asof < 0 { return pb_rank_clear(rows, count, stats, PB_E_STAMP) }
204 var p: i64 = 0
205 while p < n {
206 let raw: i64 = bf_line_end(rank, n, p)
207 let e: i64 = pb_trim_cr(rank, p, raw)
208 var slot: i64 = BF_NONE
209 var fields: i64 = 0
210 var idfield: i64 = 0
211 var symfield: i64 = 0
212 var metric: i64 = 0
213 if bf_line_starts(rank, p, e, "rank|" as *u8) == 1 {
214 slot = PB_ORDER_START; fields = 10; idfield = 3; symfield = 9; metric = PB_S_ORDERED
215 }
216 if bf_line_starts(rank, p, e, "finish|" as *u8) == 1 {
217 slot = PB_FINISH_START; fields = 6; idfield = 1; symfield = 3; metric = PB_S_FINISH
218 }
219 if bf_line_starts(rank, p, e, "unmapped|" as *u8) == 1 {
220 slot = PB_UNMAPPED_START; fields = 4; idfield = 1; symfield = 2; metric = PB_S_UNMAPPED
221 }
222 if slot >= 0 {
223 if bf_field(rank, p, e, fields-1, scratch) < 0 { return pb_rank_clear(rows, count, stats, PB_E_ROW) }
224 if bf_field(rank, p, e, fields, scratch) >= 0 { return pb_rank_clear(rows, count, stats, PB_E_ROW) }
225 let il: i64 = bf_field(rank, p, e, idfield, scratch)
226 if il <= 0 { return pb_rank_clear(rows, count, stats, PB_E_ROW) }
227 let ri: i64 = pb_find_rung(plan, rows, count, rank, scratch[0], il, scratch)
228 if ri == PB_E_DUP_PLAN { return pb_rank_clear(rows, count, stats, PB_E_DUP_PLAN) }
229 if ri < 0 { return pb_rank_clear(rows, count, stats, PB_E_ORPHAN) }
230 let sl: i64 = bf_field(rank, p, e, symfield, scratch)
231 let so: i64 = scratch[0]
232 let base: i64 = ri*PB_ROW_SLOTS
233 let pl: i64 = pb_plan_field(plan, rows, base, PB_F_SYMBOL, scratch)
234 if pl <= 0 { return pb_rank_clear(rows, count, stats, PB_E_SYMBOL) }
235 if pb_equal(rank, so, sl, plan, scratch[0], pl) == 0 { return pb_rank_clear(rows, count, stats, PB_E_SYMBOL) }
236 if rows[base+slot] >= 0 { return pb_rank_clear(rows, count, stats, PB_E_DUP_RANK) }
237 rows[base+slot] = p; rows[base+slot+1] = e
238 stats[metric] = stats[metric]+1
239 }
240 p = raw+1
241 }
242 stats[PB_S_RANK_ASOF] = asof
243 stats[PB_S_RANK_STATE] = PB_OK
244 return PB_OK
245}
246
247// Matrix join observations reuse existing row and symbol readers; duplicates remain separate rows.
248func pbm_row_kind(buf: *u8, p: i64, e: i64) -> i64 {
249 if e <= p { return 0 }
250 if buf[p] == (35 as u8) { return 0 }
251 if buf[p] == (64 as u8) { return 0 }
252 return 1
253}
254func pbm_ident(buf: *u8, p: i64, n: i64) -> i64 {
255 if n <= 0 { return 0 }
256 if buf[p] >= (48 as u8) { if buf[p] <= (57 as u8) { return 0 } }
257 var i: i64 = 0
258 while i < n { if sd_ident_char(buf[p+i] as i64) == 0 { return 0 }; i = i+1 }
259 return 1
260}
261// out[0..1] effective symbol bounds; out[2] form: ordinary0, watch1, withheld2, bare3.
262func pbm_symbol(buf: *u8, a: i64, b: i64, out: *i64) -> i64 {
263 out[0] = a; out[1] = b; out[2] = 0
264 if msym_is_bare_absent(buf, a, b) == 1 { out[0] = b; out[2] = 3; return 1 }
265 if msym_has_absent_prefix(buf, a, b) == 1 {
266 if msym_is_watch(buf, a, b) == 0 { return 0 }
267 out[0] = msym_real_start(buf, a, b); out[2] = 1
268 let sep: i64 = msym_withheld_sep(buf, a, b)
269 if sep >= 0 { out[1] = sep; out[2] = 2 }
270 // Malformed trailing/empty precondition cannot masquerade as a normal watch identity.
271 var i: i64 = out[0]
272 while i < out[1] { if buf[i] == (58 as u8) { return 0 }; i = i+1 }
273 }
274 return 1
275}
276func pbm_validate(buf: *u8, n: i64, scratch: *i64, sym: *i64) -> i64 {
277 if n <= 0 { return PB_E_INPUT }
278 if pb_input_ok(buf, n) == 0 { return PB_E_INPUT }
279 var count: i64 = 0; var p: i64 = 0
280 while p < n {
281 let raw: i64 = bf_line_end(buf,n,p); let e: i64 = pb_trim_cr(buf,p,raw)
282 if pbm_row_kind(buf,p,e) == 1 {
283 if bf_field(buf,p,e,0,scratch) <= 0 { return PB_E_ROW }
284 if bf_field(buf,p,e,1,scratch) <= 0 { return PB_E_ROW }
285 let sl: i64 = bf_field(buf,p,e,2,scratch)
286 if sl <= 0 { return PB_E_ROW }
287 if pbm_symbol(buf,scratch[0],scratch[0]+sl,sym) == 0 { return PB_E_SYMBOL }
288 count = count+1
289 }
290 p = raw+1
291 }
292 return count
293}
294func pbm_matches(buf: *u8, p: i64, e: i64, contract: *u8, co: i64, cn: i64, scratch: *i64, sym: *i64) -> i64 {
295 if cn <= 0 { return 0 }
296 let sl: i64 = bf_field(buf,p,e,2,scratch)
297 if sl <= 0 { return 0 }
298 if pbm_symbol(buf,scratch[0],scratch[0]+sl,sym) == 0 { return 0 }
299 if sym[2] == 3 { return 0 }
300 return pb_equal(buf,sym[0],sym[1]-sym[0],contract,co,cn)
301}
302
303// Same descriptor sizing and EOF observation; rc_fill owns the existing read loop.
304// Caller frees a successful result with sys_munmap(buf, outn[0]+1).
305func pbm_read(path: *u8, outn: *i64) -> *u8 {
306 outn[0] = 0-1
307 let fd: i64 = sys_openat_rd(path)
308 if fd < 0 { return 0 as *u8 }
309 let n: i64 = sys_lseek(fd,0,2)
310 if n < 0 { sys_close(fd); return 0 as *u8 }
311 if n >= PB_I64_MAX { sys_close(fd); return 0 as *u8 }
312 if sys_lseek(fd,0,0) != 0 { sys_close(fd); return 0 as *u8 }
313 let buf: *u8 = sys_mmap(n+1); let st: *i64 = sys_mmap(16) as *i64
314 if (buf as i64) <= 0 { sys_close(fd); if (st as i64) > 0 { sys_munmap(st as *u8,16) }; return 0 as *u8 }
315 if (st as i64) <= 0 { sys_close(fd); sys_munmap(buf,n+1); return 0 as *u8 }
316 let got: i64 = rc_fill(fd,buf,n+1,st); sys_close(fd)
317 let complete: i64 = st[0]; sys_munmap(st as *u8,16)
318 if complete != RC_EOF { sys_munmap(buf,n+1); return 0 as *u8 }
319 if got != n { sys_munmap(buf,n+1); return 0 as *u8 }
320 outn[0] = n; return buf
321}
322func pbm_count(buf: *u8, n: i64, contract: *u8, co: i64, cn: i64, scratch: *i64, sym: *i64) -> i64 {
323 var count: i64 = 0; var p: i64 = 0
324 while p < n {
325 let raw: i64 = bf_line_end(buf,n,p); let e: i64 = pb_trim_cr(buf,p,raw)
326 if pbm_row_kind(buf,p,e) == 1 { if pbm_matches(buf,p,e,contract,co,cn,scratch,sym) == 1 { count = count+1 } }
327 p = raw+1
328 }
329 return count
330}
331
332// Reuse matrix symbol syntax for an authored plan field without mutating its bytes.
333// Returns 1 supported, 0 no contract field, -1 unsupported/malformed. out uses pbm_symbol layout.
334func pbm_contract(buf: *u8, p: i64, n: i64, out: *i64) -> i64 {
335 if n <= 0 { return 0 }
336 if p < 0 { return 0-1 }
337 if n > PB_I64_MAX-p { return 0-1 }
338 if pbm_symbol(buf,p,p+n,out) == 0 { return 0-1 }
339 if out[2] == 3 { return 0-1 }
340 if pbm_ident(buf,out[0],out[1]-out[0]) == 0 { return 0-1 }
341 return 1
342}