code wiki / (root) / nx_learnmine_gate.nx

nx_learnmine_gate.nx source

↩ module page · 194 lines · 14519 B

1// nx_learnmine_gate.nx -- THE LEARNING-MINING GATE (2026-09-06). An archive.org advancedsearch listing is assembled at runtime 2// under /tmp/nx_learnmine_gate/ from bytes the gate writes itself (quotes, escapes, a unicode escape, an array-valued 3// description and subject, a pipe and a newline inside a value, an item with no date and no downloads, a description longer 4// than the announced head) and digested through the lib: the item count, the census by media type, newest and oldest 5// dates, decoded and sanitised fields, the subject table ordered by count, the truncation announcement; then the refusals 6// by name (an unclosed object, a listing without docs, an absent file) and the command through the ladder. 7// usage: nx_learnmine_gate (no args) 8// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0 9import "nx_syscalls.nx" 10import "nx_gate_verdict.nx" 11import "nx_gatekit_lib.nx" 12import "nx_learnmine_lib.nx" 13 14const LG_DIR: *u8 = "/tmp/nx_learnmine_gate" 15const LG_GOOD: *u8 = "/tmp/nx_learnmine_gate/listing.json" 16const LG_BAD: *u8 = "/tmp/nx_learnmine_gate/unclosed.json" 17const LG_NODOCS: *u8 = "/tmp/nx_learnmine_gate/nodocs.json" 18const LG_ABSENT: *u8 = "/tmp/nx_learnmine_gate/absent.json" 19const LG_ELF_LIVE: *u8 = "./nx_learnmine.elf" 20const LG_ELF_STAGE: *u8 = "./nx_learnmine.sov.elf.new" 21const LG_ELF_BUILD: *u8 = "buildroot/_build/nx_learnmine.sov.elf" 22const LG_DIR_MODE: i64 = 493 23const LG_FILE_MODE: i64 = 420 24const LG_CAP: i64 = 65536 25const LG_ITEMS: i64 = 4 26const LG_LONG_DESC: i64 = 300 27const LG_Q: i64 = 34 28const LG_BS: i64 = 92 29const LG_ID1: *u8 = "anime-nyan-mmd-physics-2025" 30 31func lg_write_file(path: *u8, b: *u8, n: i64) -> i64 { 32 let fd: i64 = sys_openat_wr(path, LG_FILE_MODE) 33 if fd < 0 { return 0 - 1 } 34 var done: i64 = 0 35 while done < n { let k: i64 = sys_write(fd, b + done, n - done); if k <= 0 { break } done = done + k } 36 sys_close(fd) 37 return done 38} 39func lg_exists(path: *u8) -> i64 { let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 } sys_close(fd); return 1 } 40// JSON assembly with the quote byte spelled once, so no string literal in this source carries a quote 41func lg_b(buf: *u8, o: i64, c: i64) -> i64 { buf[o] = c as u8; return o + 1 } 42func lg_q(buf: *u8, o: i64, s: *u8) -> i64 { var p: i64 = lg_b(buf, o, LG_Q); p = lm_cat(buf, p, s); return lg_b(buf, p, LG_Q) } 43func lg_k(buf: *u8, o: i64, key: *u8) -> i64 { var p: i64 = lg_q(buf, o, key); return lg_b(buf, p, 58) } 44func lg_kv(buf: *u8, o: i64, key: *u8, val: *u8) -> i64 { var p: i64 = lg_k(buf, o, key); return lg_q(buf, p, val) } 45func lg_comma(buf: *u8, o: i64) -> i64 { return lg_b(buf, o, 44) } 46// the listing: four docs 47func lg_build_listing(buf: *u8, long: i64) -> i64 { 48 var o: i64 = 0 49 o = lg_b(buf, o, 123) 50 o = lg_k(buf, o, "responseHeader" as *u8); o = lg_b(buf, o, 123); o = lg_k(buf, o, "status" as *u8); o = lm_cat(buf, o, "0" as *u8); o = lg_b(buf, o, 125) 51 o = lg_comma(buf, o); o = lg_k(buf, o, "response" as *u8); o = lg_b(buf, o, 123) 52 o = lg_k(buf, o, "numFound" as *u8); o = lm_cat(buf, o, "4" as *u8); o = lg_comma(buf, o) 53 o = lg_k(buf, o, "start" as *u8); o = lm_cat(buf, o, "0" as *u8); o = lg_comma(buf, o) 54 o = lg_k(buf, o, "docs" as *u8); o = lg_b(buf, o, 91) 55 // doc 1: escapes, unicode, arrays 56 o = lg_b(buf, o, 123) 57 o = lg_kv(buf, o, "identifier" as *u8, LG_ID1); o = lg_comma(buf, o) 58 o = lg_k(buf, o, "title" as *u8); o = lg_b(buf, o, LG_Q); o = lm_cat(buf, o, "MMD physics tutorial " as *u8) 59 o = lg_b(buf, o, LG_BS); o = lm_cat(buf, o, "u00e9 " as *u8); o = lg_b(buf, o, LG_BS); o = lg_b(buf, o, LG_Q); o = lm_cat(buf, o, "quoted" as *u8); o = lg_b(buf, o, LG_BS); o = lg_b(buf, o, LG_Q); o = lg_b(buf, o, LG_Q); o = lg_comma(buf, o) 60 o = lg_kv(buf, o, "mediatype" as *u8, "movies" as *u8); o = lg_comma(buf, o) 61 o = lg_kv(buf, o, "date" as *u8, "2025-11-03T00:00:00Z" as *u8); o = lg_comma(buf, o) 62 o = lg_k(buf, o, "description" as *u8); o = lg_b(buf, o, 91); o = lg_q(buf, o, "part one" as *u8); o = lg_comma(buf, o); o = lg_q(buf, o, "part two" as *u8); o = lg_b(buf, o, 93); o = lg_comma(buf, o) 63 o = lg_k(buf, o, "subject" as *u8); o = lg_b(buf, o, 91); o = lg_q(buf, o, "MMD" as *u8); o = lg_comma(buf, o); o = lg_q(buf, o, "hair physics" as *u8); o = lg_comma(buf, o); o = lg_q(buf, o, "Blender" as *u8); o = lg_b(buf, o, 93); o = lg_comma(buf, o) 64 o = lg_k(buf, o, "downloads" as *u8); o = lm_cat(buf, o, "1234" as *u8) 65 o = lg_b(buf, o, 125); o = lg_comma(buf, o) 66 // doc 2: a pipe and a newline escape inside the description, a scalar subject 67 o = lg_b(buf, o, 123) 68 o = lg_kv(buf, o, "identifier" as *u8, "item-two" as *u8); o = lg_comma(buf, o) 69 o = lg_kv(buf, o, "title" as *u8, "Plain" as *u8); o = lg_comma(buf, o) 70 o = lg_kv(buf, o, "mediatype" as *u8, "texts" as *u8); o = lg_comma(buf, o) 71 o = lg_kv(buf, o, "date" as *u8, "2024-01-15T00:00:00Z" as *u8); o = lg_comma(buf, o) 72 o = lg_k(buf, o, "description" as *u8); o = lg_b(buf, o, LG_Q); o = lm_cat(buf, o, "a|b" as *u8); o = lg_b(buf, o, LG_BS); o = lm_cat(buf, o, "nc" as *u8); o = lg_b(buf, o, LG_Q); o = lg_comma(buf, o) 73 o = lg_kv(buf, o, "subject" as *u8, "MMD" as *u8); o = lg_comma(buf, o) 74 o = lg_k(buf, o, "downloads" as *u8); o = lm_cat(buf, o, "5" as *u8) 75 o = lg_b(buf, o, 125); o = lg_comma(buf, o) 76 // doc 3: no date, no downloads, no subject, no description 77 o = lg_b(buf, o, 123) 78 o = lg_kv(buf, o, "identifier" as *u8, "item-three" as *u8); o = lg_comma(buf, o) 79 o = lg_kv(buf, o, "title" as *u8, "No date" as *u8); o = lg_comma(buf, o) 80 o = lg_kv(buf, o, "mediatype" as *u8, "audio" as *u8) 81 o = lg_b(buf, o, 125); o = lg_comma(buf, o) 82 // doc 4: a description longer than the announced head 83 o = lg_b(buf, o, 123) 84 o = lg_kv(buf, o, "identifier" as *u8, "item-four" as *u8); o = lg_comma(buf, o) 85 o = lg_kv(buf, o, "title" as *u8, "Long" as *u8); o = lg_comma(buf, o) 86 o = lg_kv(buf, o, "mediatype" as *u8, "movies" as *u8); o = lg_comma(buf, o) 87 o = lg_kv(buf, o, "date" as *u8, "2026-08-30" as *u8); o = lg_comma(buf, o) 88 o = lg_k(buf, o, "description" as *u8); o = lg_b(buf, o, LG_Q) 89 var k: i64 = 0 90 while k < long { o = lg_b(buf, o, 97 + (k % 26)); k = k + 1 } 91 o = lg_b(buf, o, LG_Q); o = lg_comma(buf, o) 92 o = lg_kv(buf, o, "subject" as *u8, "Blender" as *u8) 93 o = lg_b(buf, o, 125) 94 o = lg_b(buf, o, 93); o = lg_b(buf, o, 125); o = lg_b(buf, o, 125) 95 buf[o] = 0 as u8 96 return o 97} 98 99func main(argc: i64, argv: *i64) -> i64 { 100 let ctr: *i64 = gv_ctr() 101 sys_mkdir(LG_DIR, LG_DIR_MODE) 102 let buf: *u8 = sys_mmap(LG_CAP) 103 let n: i64 = lg_build_listing(buf, LG_LONG_DESC) 104 gv_check("fixture-listing-assembled (>0 bytes)" as *u8, (n > 0) as i64, ctr) 105 gv_check_eq("fixture-listing-written" as *u8, lg_write_file(LG_GOOD, buf, n), n, ctr) 106 // an unclosed object: cut the listing inside doc 2 107 lg_write_file(LG_BAD, buf, n / 2) 108 // a listing with no docs key 109 let nd: *u8 = sys_mmap(256) 110 var q: i64 = 0 111 q = lg_b(nd, q, 123); q = lg_k(nd, q, "response" as *u8); q = lg_b(nd, q, 123); q = lg_k(nd, q, "numFound" as *u8); q = lm_cat(nd, q, "0" as *u8); q = lg_b(nd, q, 125); q = lg_b(nd, q, 125) 112 lg_write_file(LG_NODOCS, nd, q) 113 // ---- 1. parse the listing ---- 114 let items: *i64 = sys_mmap(8 * LM_I_SLOTS * 64) as *i64 115 let lst: *i64 = sys_mmap(8 * LM_L_SLOTS) as *i64 116 gv_check_eq("listing-parses-OK" as *u8, lm_parse_listing(buf, n, items, 64, lst), LM_OK, ctr) 117 gv_check_eq("items-4" as *u8, lst[LM_L_ITEMS], LG_ITEMS, ctr) 118 gv_check_eq("numfound-4" as *u8, lst[LM_L_NUMFOUND], 4, ctr) 119 gv_check_eq("census-movies-2" as *u8, lst[LM_L_MOVIES], 2, ctr) 120 gv_check_eq("census-texts-1" as *u8, lst[LM_L_TEXTS], 1, ctr) 121 gv_check_eq("census-audio-1" as *u8, lst[LM_L_AUDIO], 1, ctr) 122 gv_check_eq("census-other-0" as *u8, lst[LM_L_OTHER], 0, ctr) 123 gv_check_eq("census-partition-sums-to-items" as *u8, lst[LM_L_MOVIES] + lst[LM_L_TEXTS] + lst[LM_L_AUDIO] + lst[LM_L_IMAGE] + lst[LM_L_OTHER], lst[LM_L_ITEMS], ctr) 124 gv_check("newest-is-2026-08-30 (a date without a time part still compares)" as *u8, lm_streq(lst[LM_L_NEWEST] as *u8, "2026-08-30" as *u8), ctr) 125 gv_check("oldest-is-2024-01-15 (the undated item never wins)" as *u8, lm_streq(lst[LM_L_OLDEST] as *u8, "2024-01-15" as *u8), ctr) 126 gv_check_eq("downloads-sum-1239" as *u8, lst[LM_L_DOWNLOADS], 1239, ctr) 127 gv_check_eq("truncated-descs-1 (the long one is announced)" as *u8, lst[LM_L_TRUNCATED_DESCS], 1, ctr) 128 // ---- 2. the decoded fields ---- 129 gv_check("item0-identifier" as *u8, lm_streq(items[LM_I_ID] as *u8, LG_ID1), ctr) 130 gv_check("item0-date-cut-to-YYYY-MM-DD" as *u8, lm_streq(items[LM_I_DATE] as *u8, "2025-11-03" as *u8), ctr) 131 gv_check_eq("item0-downloads-1234" as *u8, items[LM_I_DOWNLOADS], 1234, ctr) 132 let t0: *u8 = items[LM_I_TITLE] as *u8 133 gv_check("item0-title-decodes-the-unicode-escape (e-acute as UTF-8)" as *u8, gk_out_has(t0, lm_len(t0), "tutorial é " as *u8), ctr) 134 gv_check("item0-title-keeps-the-escaped-quotes" as *u8, gk_out_has(t0, lm_len(t0), "quoted" as *u8), ctr) 135 gv_check_eq("item0-title-length-32 (decoded, not the escape length)" as *u8, lm_len(t0), 32, ctr) 136 gv_check("item0-subjects-joined" as *u8, lm_streq(items[LM_I_SUBJECTS] as *u8, "MMD; hair physics; Blender" as *u8), ctr) 137 gv_check("item0-array-description-joined-by-space" as *u8, lm_streq(items[LM_I_DESC] as *u8, "part one part two" as *u8), ctr) 138 let b1: i64 = 1 * LM_I_SLOTS 139 gv_check("item1-description-sanitised (pipe to slash, newline to space)" as *u8, lm_streq(items[b1 + LM_I_DESC] as *u8, "a/b c" as *u8), ctr) 140 gv_check_eq("item1-downloads-5" as *u8, items[b1 + LM_I_DOWNLOADS], 5, ctr) 141 gv_check("item1-scalar-subject" as *u8, lm_streq(items[b1 + LM_I_SUBJECTS] as *u8, "MMD" as *u8), ctr) 142 let b2: i64 = 2 * LM_I_SLOTS 143 gv_check("item2-no-date-is-empty" as *u8, ((items[b2 + LM_I_DATE] as *u8)[0] == (0 as u8)) as i64, ctr) 144 gv_check_eq("item2-no-downloads-is-0" as *u8, items[b2 + LM_I_DOWNLOADS], 0, ctr) 145 gv_check_eq("item2-no-description-len-0" as *u8, items[b2 + LM_I_DESC_LEN], 0, ctr) 146 let b3: i64 = 3 * LM_I_SLOTS 147 gv_check_eq("item3-description-full-length-announced" as *u8, items[b3 + LM_I_DESC_LEN], LG_LONG_DESC, ctr) 148 gv_check_eq("item3-description-head-cut-to-the-announced-head" as *u8, lm_len(items[b3 + LM_I_DESC] as *u8), LM_DESC_HEAD, ctr) 149 // ---- 3. subjects ---- 150 let subj: *i64 = sys_mmap(8 * 64) as *i64 151 let counts: *i64 = sys_mmap(8 * 64) as *i64 152 let full: *i64 = sys_mmap(16) as *i64 153 let d: i64 = lm_subjects(items, lst[LM_L_ITEMS], subj, counts, 64, full) 154 gv_check_eq("subjects-distinct-3" as *u8, d, 3, ctr) 155 gv_check("subjects-top-is-MMD" as *u8, lm_streq(subj[0] as *u8, "MMD" as *u8), ctr) 156 gv_check_eq("subjects-top-count-2" as *u8, counts[0], 2, ctr) 157 gv_check_eq("subjects-second-count-2 (Blender)" as *u8, counts[1], 2, ctr) 158 gv_check_eq("subjects-not-a-floor" as *u8, full[0], 0, ctr) 159 let d2: i64 = lm_subjects(items, lst[LM_L_ITEMS], subj, counts, 2, full) 160 gv_check_eq("neg-control-subject-table-cap-reports-a-floor" as *u8, full[0], 1, ctr) 161 gv_check_eq("neg-control-subject-table-cap-distinct-2" as *u8, d2, 2, ctr) 162 // ---- 4. refusals ---- 163 gv_check_eq("neg-control-unclosed-object-MALFORMED" as *u8, lm_parse_listing(buf, n / 2, items, 64, lst), LM_ERR_MALFORMED, ctr) 164 gv_check_eq("neg-control-no-docs-NO-DOCS" as *u8, lm_parse_listing(nd, q, items, 64, lst), LM_ERR_NO_DOCS, ctr) 165 gv_check_eq("neg-control-capacity-1-CAPACITY" as *u8, lm_parse_listing(buf, n, items, 1, lst), LM_ERR_CAPACITY, ctr) 166 // ---- 5. the command ---- 167 var elf: *u8 = 0 as *u8 168 if lg_exists(LG_ELF_LIVE) == 1 { elf = LG_ELF_LIVE } 169 else { if lg_exists(LG_ELF_STAGE) == 1 { elf = LG_ELF_STAGE } else { if lg_exists(LG_ELF_BUILD) == 1 { elf = LG_ELF_BUILD } } } 170 gv_need("cli-witness-present (live, staged or build fossil of nx_learnmine)" as *u8, ((elf as i64) != 0) as i64, ctr) 171 if (elf as i64) != 0 { 172 let out: *u8 = sys_mmap(LG_CAP) 173 let bl: *i64 = sys_mmap(16) as *i64 174 let rc0: i64 = gk_run_capture(elf, "items" as *u8, 0 as *u8, 0 as *u8, 0 as *u8, out, LG_CAP, bl) 175 gv_check_eq("cli-items-without-a-listing-is-usage-exit-2" as *u8, rc0, 2, ctr) 176 let rc1: i64 = gk_run_capture(elf, "items" as *u8, LG_GOOD, 0 as *u8, 0 as *u8, out, LG_CAP, bl) 177 gv_check_eq("cli-items-exits-0" as *u8, rc1, 0, ctr) 178 gv_check("cli-items-row-0" as *u8, gk_out_has(out, bl[0], "ITEM|0|anime-nyan-mmd-physics-2025|movies|2025-11-03|1234|" as *u8), ctr) 179 gv_check("cli-items-desc-row-announces-the-full-length" as *u8, gk_out_has(out, bl[0], "DESC|item-four|300|" as *u8), ctr) 180 gv_check("cli-items-summary-last" as *u8, gk_out_has(out, bl[0], "LEARNMINE items=4 numfound=4 movies=2 texts=1 audio=1 image=0 other=0 newest=2026-08-30 oldest=2024-01-15 downloads=1239 truncated_descs=1 verdict=GREEN" as *u8), ctr) 181 let rc2: i64 = gk_run_capture(elf, "subjects" as *u8, LG_GOOD, "2" as *u8, 0 as *u8, out, LG_CAP, bl) 182 gv_check_eq("cli-subjects-exits-0" as *u8, rc2, 0, ctr) 183 gv_check("cli-subjects-top-row" as *u8, gk_out_has(out, bl[0], "SUBJECT|1|2|MMD" as *u8), ctr) 184 gv_check("cli-subjects-shown-2-of-3" as *u8, gk_out_has(out, bl[0], "SUBJECTS distinct=3 shown=2 floor=0" as *u8), ctr) 185 let rc3: i64 = gk_run_capture(elf, "census" as *u8, LG_BAD, 0 as *u8, 0 as *u8, out, LG_CAP, bl) 186 gv_check_eq("cli-census-unclosed-exits-3" as *u8, rc3, 3, ctr) 187 gv_check("cli-census-unclosed-names-MALFORMED" as *u8, gk_out_has(out, bl[0], "rule=MALFORMED" as *u8), ctr) 188 let rc4: i64 = gk_run_capture(elf, "census" as *u8, LG_ABSENT, 0 as *u8, 0 as *u8, out, LG_CAP, bl) 189 gv_check_eq("cli-census-absent-file-exits-3" as *u8, rc4, 3, ctr) 190 gv_check("cli-census-absent-file-names-UNREADABLE" as *u8, gk_out_has(out, bl[0], "rule=UNREADABLE" as *u8), ctr) 191 } 192 gv_kv("fixture_bytes" as *u8, n) 193 return gv_verdict("NX-LEARNMINE" as *u8, ctr, "an archive.org listing assembled from its own bytes digests into item rows and a census with decoded, sanitised fields, dated newest and oldest, an announced description head, a subject table with a floor flag; an unclosed object, a listing without docs, a capacity cut and an absent file refuse by name; the command agrees" as *u8) 194}