nx_uxf_decode_gate.nx source
↩ module page · 95 lines · 4744 B
1// nx_uxf_decode_gate.nx -- the D001 MIGRATION of nx_uxf_decode_test onto nx_gate_verdict (2026-09-06).
2//
3// This is the operator's HOUSE-OF-CARDS fix made mechanical: a reader that preserves fields it does not
4// understand, proven by CID EQUALITY after a round-trip rather than by inspection. It is the load-bearing
5// half of law 4 (data and functionality on independent clocks), and it was unpromotable because the original
6// hand-rolls its counters and verdict line, so nothing outside could read its outcome.
7//
8// ALL FOUR TEETH PRESERVED IN ORDER AND PREDICATE. What changes: gv_check owns the counting so declared and
9// executed cannot diverge, the neg-control is NAMED so the gate-law census can find it, and gv_kv emits the
10// three CIDs and the field count so this gate's GREEN can be contradicted by anyone who re-encodes the record.
11// license_tier: ORIGINAL No hw writes (Rule 26).
12import "nx_gate_verdict.nx"
13import "nx_syscalls.nx"
14import "nx_canon_cid.nx"
15import "nx_uxf_cid.nx"
16import "nx_uxf_decode.nx"
17
18const UD_PTRTAB: i64 = 64
19const UD_DECTAB: i64 = 128
20const UD_CANON: i64 = 4096
21const UD_CIDBUF: i64 = 128
22const UD_NFIELDS: i64 = 3
23const UD_KNOWN_FIELDS: i64 = 2 // what an INTOLERANT reader would keep: it does not know 'c'
24const UD_MAXDEC: i64 = 16
25
26func ud_streq(a: *u8, b: *u8) -> i64 {
27 var i: i64 = 0
28 while 1 == 1 {
29 if a[i] != b[i] { return 0 }
30 if a[i] == (0 as u8) { return 1 }
31 i = i + 1
32 }
33 return 1
34}
35
36func main(argc: i64, argv: *i64) -> i64 {
37 let ctr: *i64 = gv_ctr()
38 gv_head("nx_uxf_decode -- the tolerant reader preserves what it does not understand" as *u8)
39
40 // original record {a:1, b:2, c:3}. 'c' is the field a future or older reader may not know about.
41 let keys: *i64 = sys_mmap(UD_PTRTAB) as *i64
42 let vals: *i64 = sys_mmap(UD_PTRTAB) as *i64
43 keys[0] = ("a\x00") as i64; vals[0] = ("1\x00") as i64
44 keys[1] = ("b\x00") as i64; vals[1] = ("2\x00") as i64
45 keys[2] = ("c\x00") as i64; vals[2] = ("3\x00") as i64
46 let orig: *u8 = sys_mmap(UD_CANON)
47 let olen: i64 = canon_encode(keys, vals, UD_NFIELDS, orig)
48 let cid_orig: *u8 = sys_mmap(UD_CIDBUF)
49 cid_of(orig, olen, cid_orig)
50
51 // TOLERANT decode: read EVERY field back, with no known-key filter
52 let dkeys: *i64 = sys_mmap(UD_DECTAB) as *i64
53 let dvals: *i64 = sys_mmap(UD_DECTAB) as *i64
54 let nf: i64 = canon_decode(orig, olen, dkeys, dvals, UD_MAXDEC)
55
56 // re-encode the decoded fields: this must reproduce the identical canonical bytes and CID
57 let round: *u8 = sys_mmap(UD_CANON)
58 let rlen: i64 = canon_encode(dkeys, dvals, nf, round)
59 let cid_round: *u8 = sys_mmap(UD_CIDBUF)
60 cid_of(round, rlen, cid_round)
61
62 // the same round-trip under a PROFILED CID
63 let pcid_orig: *u8 = sys_mmap(UD_CIDBUF)
64 let pcid_round: *u8 = sys_mmap(UD_CIDBUF)
65 uxf_cid_profiled(UXF_DATA, orig, olen, pcid_orig)
66 uxf_cid_profiled(UXF_DATA, round, rlen, pcid_round)
67
68 // the INTOLERANT reader: drops the unknown 'c' by re-encoding only the fields it knows
69 let dropc: *u8 = sys_mmap(UD_CANON)
70 let dlen: i64 = canon_encode(dkeys, dvals, UD_KNOWN_FIELDS, dropc)
71 let cid_drop: *u8 = sys_mmap(UD_CIDBUF)
72 cid_of(dropc, dlen, cid_drop)
73
74 gv_check_eq("T1 the tolerant decode reads ALL fields including the one it does not know" as *u8, nf, UD_NFIELDS, ctr)
75 gv_check("T2 round-trip CID is stable, so the unknown field survived encode-decode-re-encode" as *u8, ud_streq(cid_orig, cid_round), ctr)
76 gv_check("T3 the profiled multicodec CID round-trips the same way" as *u8, ud_streq(pcid_orig, pcid_round), ctr)
77 gv_check("neg-control-dropping-the-unknown-field-CHANGES-the-CID-so-preservation-is-load-bearing" as *u8, 1 - ud_streq(cid_orig, cid_drop), ctr)
78
79 gv_values_head()
80 gv_kv("fields_encoded" as *u8, UD_NFIELDS)
81 gv_kv("fields_decoded" as *u8, nf)
82 gv_kv("canon_len_original" as *u8, olen)
83 gv_kv("canon_len_roundtrip" as *u8, rlen)
84 gv_kv("canon_len_dropped" as *u8, dlen)
85 gv_kv("cid_orig_eq_cid_round" as *u8, ud_streq(cid_orig, cid_round))
86 gv_kv("pcid_orig_eq_pcid_round" as *u8, ud_streq(pcid_orig, pcid_round))
87 gv_kv("cid_orig_eq_cid_drop" as *u8, ud_streq(cid_orig, cid_drop))
88 gv_puts(" cid_orig = " as *u8); gv_puts(cid_orig); gv_puts("\n" as *u8)
89 gv_puts(" cid_round = " as *u8); gv_puts(cid_round); gv_puts("\n" as *u8)
90 gv_puts(" cid_drop = " as *u8); gv_puts(cid_drop); gv_puts("\n" as *u8)
91
92 let rc: i64 = gv_verdict("UXF-TOLERANT-READER-GATE" as *u8, ctr, "an unknown field survives a round-trip with the CID unchanged, and dropping it moves the CID, so preservation is load-bearing rather than incidental" as *u8)
93 sys_exit(rc)
94 return rc
95}