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}