code wiki / _hdl_build / nx_capgraph_derive_gate.nx
nx_capgraph_derive_gate.nx source
↩ module page · 144 lines · 9328 B
1// nx_capgraph_derive_gate.nx -- the gate for nx_capgraph_derive_lib: level thresholds, the journal
2// row parser, and the progress-rail lookup.
3//
4// WHY: the progress rail was proven only by a LIVE neg-control (drop an edge, watch it record). That is
5// real evidence but it is not a standing tooth -- it proves the rail worked ONCE, on one machine, on one
6// day. These teeth are the standing version, and they cover the parts a live run cannot easily reach:
7// threshold BOUNDARIES (off-by-one is invisible in a live run where nothing sits on the boundary),
8// NEGATIVE level parsing (-1 UNMEASURED must survive a round-trip or every unmeasured node silently
9// reads as 1), and PREFIX safety in the lookup.
10// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
11import "nx_capgraph_derive_lib.nx"
12
13func cdg_t(name: *u8, cond: i64, ctr: *i64) {
14 if cond == 1 {
15 cax_puts(" ok " as *u8)
16 ctr[0] = ctr[0] + 1
17 } else {
18 cax_puts(" FAIL " as *u8)
19 }
20 cax_puts(name)
21 cax_puts("\n" as *u8)
22 ctr[1] = ctr[1] + 1
23}
24
25func main(argc: i64, argv: *i64) -> i64 {
26 var ctr: *i64 = sys_mmap(64) as *i64
27 ctr[0] = 0
28 ctr[1] = 0
29 cax_puts("=== nx_capgraph_derive_gate: thresholds, journal parsing, progress lookup ===\n" as *u8)
30
31 // ---- coverage permil -> ordinal level, tested ON THE BOUNDARIES ----
32 cdg_t("T1 cov 199 -> level 0" as *u8, cd2_cov_level(199) == 0, ctr)
33 cdg_t("T1b cov 200 -> level 1 (boundary is inclusive-low)" as *u8, cd2_cov_level(200) == 1, ctr)
34 cdg_t("T1c cov 949 -> level 4" as *u8, cd2_cov_level(949) == 4, ctr)
35 cdg_t("T1d cov 950 -> level 5" as *u8, cd2_cov_level(950) == 5, ctr)
36 cdg_t("T1e UNMEASURED stays UNMEASURED, never becomes 0" as *u8, cd2_cov_level(CG_UNMEASURED) == CG_UNMEASURED, ctr)
37
38 // ---- frontier gaps -> level (more gaps = lower) ----
39 cdg_t("T2 0 gaps -> 5 (no frontier debt)" as *u8, cd2_gap_level(0) == 5, ctr)
40 cdg_t("T2b 3 gaps -> 4" as *u8, cd2_gap_level(3) == 4, ctr)
41 cdg_t("T2c NEG-CONTROL: a huge gap count floors at 0, never negative" as *u8, cd2_gap_level(9999) == 0, ctr)
42 cdg_t("T2d UNMEASURED stays UNMEASURED" as *u8, cd2_gap_level(CG_UNMEASURED) == CG_UNMEASURED, ctr)
43
44 // ---- infra prefix detection ----
45 cdg_t("T3 infra: prefix recognised" as *u8, cd2_is_infra("infra:nx_seg_store.nx" as *u8) == 1, ctr)
46 cdg_t("T3b NEG-CONTROL: a plain domain name is NOT infra" as *u8, cd2_is_infra("search" as *u8) == 0, ctr)
47 cdg_t("T3c NEG-CONTROL: a short name does not over-read its buffer" as *u8, cd2_is_infra("cms" as *u8) == 0, ctr)
48
49 // ---- THE JOURNAL ROW PARSER (the progress rail depends entirely on it) ----
50 cd2_pn = sys_mmap(CD2_MAXPAIR * CD2_PW + 64) as *u8
51 cd2_pv = sys_mmap(CD2_MAXPAIR * 8 + 64) as *i64
52 let row: *u8 = "nodes=38 edges=54 search=0 llm=3 ghost=-1" as *u8
53 var rn: i64 = 0
54 while row[rn] != (0 as u8) { rn = rn + 1 }
55 cd2_parse_row(row, 0, rn)
56 cdg_t("T4 parser finds every key=value pair" as *u8, cd2_np == 5, ctr)
57 cdg_t("T4b a named value parses" as *u8, cd2_prev_lookup("edges" as *u8) == 54, ctr)
58 cdg_t("T4c a level of 0 parses as 0, not as missing" as *u8, cd2_prev_lookup("search" as *u8) == 0, ctr)
59 cdg_t("T4d a nonzero level parses" as *u8, cd2_prev_lookup("llm" as *u8) == 3, ctr)
60 cdg_t("T4e NEGATIVE (-1 UNMEASURED) survives the round-trip" as *u8, cd2_prev_lookup("ghost" as *u8) == (0 - 1), ctr)
61 cdg_t("T5 NEG-CONTROL: an absent key returns the MISSING sentinel, not 0" as *u8, cd2_prev_lookup("nosuchdomain" as *u8) == (0 - 999), ctr)
62 cdg_t("T5b NEG-CONTROL: a PREFIX of a real key does not match it" as *u8, cd2_prev_lookup("sea" as *u8) == (0 - 999), ctr)
63 cdg_t("T5c NEG-CONTROL: a SUPERSTRING of a real key does not match it" as *u8, cd2_prev_lookup("searchx" as *u8) == (0 - 999), ctr)
64
65 // ---- parser must tolerate leading/trailing whitespace and tabs (journal rows are tab-led) ----
66 let row2: *u8 = " a=1\tb=2 c=3 " as *u8
67 var r2n: i64 = 0
68 while row2[r2n] != (0 as u8) { r2n = r2n + 1 }
69 cd2_parse_row(row2, 0, r2n)
70 cdg_t("T6 whitespace- and TAB-separated pairs all parse" as *u8, cd2_np == 3, ctr)
71 cdg_t("T6b values survive the mixed separators" as *u8, cd2_prev_lookup("b" as *u8) == 2, ctr)
72 cdg_t("T6c NEG-CONTROL: a bare token with no '=' is skipped, not stored" as *u8, cd2_prev_lookup(" " as *u8) == (0 - 999), ctr)
73
74 // ---- THE RAIL'S RECORD/SKIP DECISION. If this is wrong, movement is silently dropped or the
75 // journal fills with phantom rows. Every case is a matched pair against the SAME journal buffer.
76 let j1: *u8 = "1700000000\tnodes=38 edges=54 search=0\n" as *u8
77 var j1n: i64 = 0
78 while j1[j1n] != (0 as u8) { j1n = j1n + 1 }
79 let stA: *u8 = "nodes=38 edges=54 search=0" as *u8
80 var stAn: i64 = 0
81 while stA[stAn] != (0 as u8) { stAn = stAn + 1 }
82 cdg_t("T7 identical state matches the last row (=> do NOT append)" as *u8, cd2_last_row_matches(j1, j1n, stA, stAn) == 1, ctr)
83 let stB: *u8 = "nodes=39 edges=54 search=0" as *u8
84 var stBn: i64 = 0
85 while stB[stBn] != (0 as u8) { stBn = stBn + 1 }
86 cdg_t("T7b NEG-CONTROL: a ONE-CHARACTER change does NOT match (=> movement recorded)" as *u8, cd2_last_row_matches(j1, j1n, stB, stBn) == 0, ctr)
87 let stC: *u8 = "nodes=38 edges=54" as *u8
88 var stCn: i64 = 0
89 while stC[stCn] != (0 as u8) { stCn = stCn + 1 }
90 cdg_t("T7c PREFIX SAFETY: a state that is a PREFIX of the row must NOT match" as *u8, cd2_last_row_matches(j1, j1n, stC, stCn) == 0, ctr)
91 let stD: *u8 = "nodes=38 edges=54 search=0 llm=3" as *u8
92 var stDn: i64 = 0
93 while stD[stDn] != (0 as u8) { stDn = stDn + 1 }
94 cdg_t("T7d SUFFIX SAFETY: a state EXTENDING the row must NOT match (a new node is movement)" as *u8, cd2_last_row_matches(j1, j1n, stD, stDn) == 0, ctr)
95 cdg_t("T7e an EMPTY journal never matches -- the first run must always record a baseline" as *u8, cd2_last_row_matches(j1, 0, stA, stAn) == 0, ctr)
96 let j2: *u8 = "no-tab-in-this-row\n" as *u8
97 var j2n: i64 = 0
98 while j2[j2n] != (0 as u8) { j2n = j2n + 1 }
99 cdg_t("T7f a malformed row with no TAB is treated as NO match, never as equal" as *u8, cd2_last_row_matches(j2, j2n, stA, stAn) == 0, ctr)
100 let j3: *u8 = "1600000000\tnodes=1 edges=1\n1700000000\tnodes=38 edges=54 search=0\n" as *u8
101 var j3n: i64 = 0
102 while j3[j3n] != (0 as u8) { j3n = j3n + 1 }
103 cdg_t("T7g compares against the LAST row, not an earlier one" as *u8, cd2_last_row_matches(j3, j3n, stA, stAn) == 1, ctr)
104 let stE: *u8 = "nodes=1 edges=1" as *u8
105 var stEn: i64 = 0
106 while stE[stEn] != (0 as u8) { stEn = stEn + 1 }
107 cdg_t("T7h NEG-CONTROL: matching an EARLIER row's state returns 0 (history is not the present)" as *u8, cd2_last_row_matches(j3, j3n, stE, stEn) == 0, ctr)
108
109 // ---- ROW-BOUNDARY DECISIONS: which two rows does `progress` diff? Off-by-one here silently
110 // reports the WRONG movement, and a live run only ever exercises whatever shape the journal has
111 // that day. Trailing-newline handling is the trap.
112 let r1: *u8 = "aaa\n" as *u8
113 let r2: *u8 = "aaa\nbbb\n" as *u8
114 let r3: *u8 = "aaa\nbbb\nccc\n" as *u8
115 let r2nonl: *u8 = "aaa\nbbb" as *u8
116 cdg_t("T8 ONE row: last starts at 0" as *u8, cd2_last_row_start(r1, 4) == 0, ctr)
117 cdg_t("T8b ONE row has NO previous row (progress must refuse, not diff garbage)" as *u8, cd2_prev_row_start(r1, 4) == (0 - 1), ctr)
118 cdg_t("T8c TWO rows: last starts after the first newline" as *u8, cd2_last_row_start(r2, 8) == 4, ctr)
119 cdg_t("T8d TWO rows: previous is the FIRST row" as *u8, cd2_prev_row_start(r2, 8) == 0, ctr)
120 cdg_t("T8e THREE rows: last is the THIRD, not the second" as *u8, cd2_last_row_start(r3, 12) == 8, ctr)
121 cdg_t("T8f THREE rows: previous is the SECOND, not the first" as *u8, cd2_prev_row_start(r3, 12) == 4, ctr)
122 cdg_t("T8g TRAILING NEWLINE does not create a phantom empty final row" as *u8, cd2_last_row_start(r2, 8) == 4, ctr)
123 cdg_t("T8h NO trailing newline resolves identically (same two rows)" as *u8, cd2_last_row_start(r2nonl, 7) == 4, ctr)
124 cdg_t("T8i EMPTY buffer: no last row at all" as *u8, cd2_last_row_start(r1, 0) == (0 - 1), ctr)
125 cdg_t("T8j EMPTY buffer: no previous row either" as *u8, cd2_prev_row_start(r1, 0) == (0 - 1), ctr)
126
127 // ⚠MUST BE THE LAST STATEMENT BEFORE THE FOOTER. This call sat ABOVE the T7/T8 blocks for two
128 // rounds because each new tooth block was inserted at the footer anchor, silently pushing the
129 // teeth BELOW the record. Effect: the log read 23/23 while the gate really finished 41/41 -- and
130 // far worse, a FAILING late tooth would still have been logged GREEN, because ctr was equal at
131 // write time. ★A RECORD WRITTEN BEFORE THE WORK IT RECORDS IS A FALSE-GREEN GENERATOR (the inverse
132 // of "a guard placed after the act it guards"). Anything appended after this line must go ABOVE it.
133 cg_gate_log("knowledge/status/capgraph_derive_gate.log" as *u8, "CAPGRAPHDERIVEGATE" as *u8, ctr[0], ctr[1])
134 cax_puts("\nCAPGRAPH-DERIVE-GATE " as *u8)
135 cax_puti(ctr[0])
136 cax_puts("/" as *u8)
137 cax_puti(ctr[1])
138 if ctr[0] == ctr[1] {
139 cax_puts(" GREEN\n" as *u8)
140 return 0
141 }
142 cax_puts(" RED\n" as *u8)
143 return 1
144}