code wiki / _hdl_build / nx_lostset_gate.nx

nx_lostset_gate.nx source

↩ module page · 208 lines · 17368 B

1// nx_lostset_gate.nx -- THE REFEREE for nx_registrymine `lostset` (DM3, devmgmt rung). 2// END-TO-END: it forks the DEPLOYED subject elf, so what it grades is the artifact callers actually 3// run, not a re-compiled copy of the source. Pass the subject path as argv[1] to grade a candidate. 4// 5// WHY EACH TOOTH EXISTS -- every one of these is a way this miner could report a confident wrong 6// answer, and three of them are defects that were REAL in the input before the miner was written: 7// * the harness ships `deferred_tools_delta` attachments that LIST tool names as structural JSON, 8// so a bare-prefix scan counts listed-but-never-called tools as execution evidence; 9// * prose in a tool result can DISCUSS mcpMeta, so a naive needle counts a memory note as a fork; 10// * a resumed session replays earlier records, so a per-file count double-counts one call. 11// A tooth that only ever sees correct data has not been shown to fire, so the fixture carries the 12// bad case and the good case AT ONCE and the gate asserts they are told apart -- two runs that each 13// isolate one signal do not prove discrimination between them. 14// 15// FIXTURES ARE ASSEMBLED AT RUNTIME under /tmp/nx_lostset_gate/ and never in a production tree: a 16// gate that shares its scratch with a live path reports on the FIXTURE, not on the code (measured 17// estate-wide, the gate_fixture ratchet). Idempotent: every fixture file is opened O_TRUNC, so the 18// second run grades the same bytes as the first. 19// license_tier: ORIGINAL Read-only outside /tmp. No hw writes (Rule 26). 20import "nx_syscalls.nx" 21import "nx_sovjson_lib.nx" 22import "nx_gate_verdict.nx" 23import "nx_tool_run.nx" 24 25const LG_MODE_644: i64 = 420 // rw-r--r-- 26const LG_MODE_755: i64 = 493 // rwxr-xr-x for the scratch dirs 27const LG_PATH: i64 = 512 28const LG_FIX: i64 = 65536 // one fixture transcript 29const LG_OUT: i64 = 1048576 // subject stdout capture 30const LG_EXIT_SKIP: i64 = 3 // "I could not look" -- never an acquittal 31const LG_RC_REFUSE: i64 = 3 // the subject's own refusal exit code 32 33func lg_wr(path: *u8, buf: *u8, n: i64) -> i64 { 34 let fd: i64 = sys_openat_wr(path, LG_MODE_644) 35 if fd < 0 { return 0 - 1 } 36 sys_write(fd, buf, n) 37 sys_close(fd) 38 return n 39} 40func lg_run(subj: *u8, a1: *u8, a2: *u8, a3: *u8, a4: *u8, out: *u8, cl: *i64) -> i64 { 41 let av: *i64 = sys_mmap(64) as *i64 42 av[0] = subj as i64 43 av[1] = a1 as i64 44 av[2] = a2 as i64 45 av[3] = a3 as i64 46 av[4] = a4 as i64 47 av[5] = 0 48 return tr_run_capture(subj, av, out, LG_OUT - 8, cl) 49} 50func lg_has(out: *u8, n: i64, lit: *u8) -> i64 { return tr_contains(out, n, lit) } 51 52func main(argc: i64, argv: *i64) -> i64 { 53 let ctr: *i64 = gv_ctr() 54 gv_head("nx_lostset_gate -- exec-evidence IS the population, the registry is only the test" as *u8) 55 56 // ---------- subject resolution: an unresolvable subject SKIPS, it never acquits ---------- 57 let subj: *u8 = sys_mmap(LG_PATH) 58 var have: i64 = 0 59 if argc >= 2 { var z: i64 = sj_cat(subj, 0, argv[1] as *u8); subj[z] = 0 as u8; have = 1 } 60 if have == 0 { if sj_allow_path("nx_registrymine" as *u8, subj) == 1 { have = 1 } } 61 if have == 0 { var z2: i64 = sj_cat(subj, 0, "./nx_registrymine.elf" as *u8); subj[z2] = 0 as u8; have = 1 } 62 63 // ---------- SETUP: /tmp only, created here because a teardown does not run after a crash ---------- 64 let root: *u8 = "/tmp/nx_lostset_gate" as *u8 65 let tdir: *u8 = "/tmp/nx_lostset_gate/t" as *u8 66 let sdir: *u8 = "/tmp/nx_lostset_gate/t/sub" as *u8 67 let fa: *u8 = "/tmp/nx_lostset_gate/t/a.jsonl" as *u8 68 let fb: *u8 = "/tmp/nx_lostset_gate/t/b.jsonl" as *u8 69 let fc: *u8 = "/tmp/nx_lostset_gate/t/sub/c.jsonl" as *u8 70 let reg: *u8 = "/tmp/nx_lostset_gate/reg.conf" as *u8 71 let noreg: *u8 = "/tmp/nx_lostset_gate/absent-registry.conf" as *u8 72 let noroot: *u8 = "/tmp/nx_lostset_gate/absent-root" as *u8 73 let since: *u8 = "2026-08-10T00:00:00Z" as *u8 74 sys_mkdir(root, LG_MODE_755) 75 sys_mkdir(tdir, LG_MODE_755) 76 sys_mkdir(sdir, LG_MODE_755) 77 78 let b: *u8 = sys_mmap(LG_FIX) 79 var o: i64 = 0 80 // -- a.jsonl: every discriminating case in ONE file, so the gate proves they are TOLD APART -- 81 // t_lost exec-proven, no row -> LOST 82 // t_ok exec-proven, GREEN row -> OK-ROW (positive control) 83 // t_amber exec-proven, row present but not GREEN -> ROW-NOT-GREEN (its own state) 84 // t_den refusal only -> DENIED-ONLY (cap coverage, not loss) 85 // t_unk unrecognised result only -> UNKNOWN-ONLY (abstain, not acquit) 86 // t_prose result whose TEXT quotes the exec anchor -> UNKNOWN-ONLY (escaped != structural) 87 // t_listed named only in a deferred_tools_delta -> ABSENT entirely 88 // t_old exec-proven but BEFORE the window -> ABSENT entirely 89 // t_dup exec-proven, same id also in b.jsonl -> counted ONCE 90 // Read a non-nishi tool with exec meta -> ABSENT entirely 91 o = sj_cat(b, o, "{\"type\":\"assistant\",\"timestamp\":\"2026-08-15T10:00:00.000Z\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_LOST1\",\"name\":\"mcp__nishi__t_lost\",\"input\":{}},{\"type\":\"tool_use\",\"id\":\"toolu_OK1\",\"name\":\"mcp__nishi__t_ok\",\"input\":{}},{\"type\":\"tool_use\",\"id\":\"toolu_AMB1\",\"name\":\"mcp__nishi__t_amber\",\"input\":{}}]}}\n" as *u8) 92 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_LOST1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-15T10:00:01.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 93 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_OK1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-15T10:00:02.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 94 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_AMB1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-15T10:00:03.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 95 o = sj_cat(b, o, "{\"type\":\"assistant\",\"timestamp\":\"2026-08-15T10:01:00.000Z\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_DEN1\",\"name\":\"mcp__nishi__t_den\",\"input\":{}},{\"type\":\"tool_use\",\"id\":\"toolu_UNK1\",\"name\":\"mcp__nishi__t_unk\",\"input\":{}},{\"type\":\"tool_use\",\"id\":\"toolu_PRO1\",\"name\":\"mcp__nishi__t_prose\",\"input\":{}}]}}\n" as *u8) 96 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_DEN1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"capability denied for tool\"}]}]},\"timestamp\":\"2026-08-15T10:01:01.000Z\"}\n" as *u8) 97 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_UNK1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"the edge window closed early\"}]}]},\"timestamp\":\"2026-08-15T10:01:02.000Z\"}\n" as *u8) 98 // the escaped anchor lives INSIDE a JSON string value here, exactly as a memory note quoting it 99 // would. Structural quotes are unescaped; string quotes are not. That single fact is the whole 100 // defence, so it gets its own tooth rather than a comment. 101 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_PRO1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"note: exec proof is \\\"mcpMeta\\\":{\\\"_meta\\\":{\\\"exit_code\\\":0}} in the record\"}]}]},\"timestamp\":\"2026-08-15T10:01:03.000Z\"}\n" as *u8) 102 o = sj_cat(b, o, "{\"type\":\"user\",\"isSidechain\":false,\"attachment\":{\"type\":\"deferred_tools_delta\",\"addedNames\":[\"mcp__nishi__t_listed\",\"mcp__nishi__t_lost\"]},\"timestamp\":\"2026-08-15T10:02:00.000Z\"}\n" as *u8) 103 o = sj_cat(b, o, "{\"type\":\"assistant\",\"timestamp\":\"2026-08-01T09:00:00.000Z\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_OLD1\",\"name\":\"mcp__nishi__t_old\",\"input\":{}}]}}\n" as *u8) 104 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_OLD1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-01T09:00:01.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 105 o = sj_cat(b, o, "{\"type\":\"assistant\",\"timestamp\":\"2026-08-15T10:03:00.000Z\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_DUP1\",\"name\":\"mcp__nishi__t_dup\",\"input\":{}},{\"type\":\"tool_use\",\"id\":\"toolu_RD1\",\"name\":\"Read\",\"input\":{}}]}}\n" as *u8) 106 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_DUP1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-15T10:03:01.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 107 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_RD1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-15T10:03:02.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 108 let wa: i64 = lg_wr(fa, b, o) 109 // -- b.jsonl: the SAME tool_use id replayed, as a resumed session does -- 110 o = 0 111 o = sj_cat(b, o, "{\"type\":\"assistant\",\"timestamp\":\"2026-08-15T10:03:00.000Z\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_DUP1\",\"name\":\"mcp__nishi__t_dup\",\"input\":{}}]}}\n" as *u8) 112 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_DUP1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-15T10:03:01.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 113 let wb: i64 = lg_wr(fb, b, o) 114 // -- sub/c.jsonl: reachable ONLY by recursion -- 115 o = 0 116 o = sj_cat(b, o, "{\"type\":\"assistant\",\"timestamp\":\"2026-08-16T11:00:00.000Z\",\"message\":{\"role\":\"assistant\",\"content\":[{\"type\":\"tool_use\",\"id\":\"toolu_SUB1\",\"name\":\"mcp__nishi__t_sub\",\"input\":{}}]}}\n" as *u8) 117 o = sj_cat(b, o, "{\"type\":\"user\",\"message\":{\"role\":\"user\",\"content\":[{\"tool_use_id\":\"toolu_SUB1\",\"type\":\"tool_result\",\"content\":[{\"type\":\"text\",\"text\":\"ran\"}]}]},\"timestamp\":\"2026-08-16T11:00:01.000Z\",\"mcpMeta\":{\"_meta\":{\"exit_code\":0,\"bytes\":3}}}\n" as *u8) 118 let wc: i64 = lg_wr(fc, b, o) 119 // -- registry: GREEN row, a NOT-GREEN row, a row for a denied-only tool, a row nobody called -- 120 o = 0 121 o = sj_cat(b, o, "t_ok\t/tmp/nx_lostset_gate/t_ok.elf\tGREEN\n" as *u8) 122 o = sj_cat(b, o, "t_amber\t/tmp/nx_lostset_gate/t_amber.elf\tAMBER\n" as *u8) 123 o = sj_cat(b, o, "t_den\t/tmp/nx_lostset_gate/t_den.elf\tGREEN\n" as *u8) 124 o = sj_cat(b, o, "t_listed\t/tmp/nx_lostset_gate/t_listed.elf\tGREEN\n" as *u8) 125 let wr: i64 = lg_wr(reg, b, o) 126 sys_unlinkat(noreg) 127 128 var fixok: i64 = 0 129 if wa > 0 { if wb > 0 { if wc > 0 { if wr > 0 { fixok = 1 } } } } 130 gv_check("fixture-written-all-four (assert the fixture reached the condition before the outcome)" as *u8, fixok, ctr) 131 132 let out: *u8 = sys_mmap(LG_OUT) 133 let cl: *i64 = sys_mmap(16) as *i64 134 let rc: i64 = lg_run(subj, "lostset" as *u8, tdir, reg, since, out, cl) 135 let n: i64 = cl[0] 136 137 // an unrunnable subject is UNOBSERVABLE, not a failing subject 138 if n <= 0 { 139 gv_puts("SKIP subject produced no output -- build/deploy nx_registrymine, then re-run: " as *u8) 140 gv_puts(subj) 141 gv_puts("\n" as *u8) 142 sys_exit(LG_EXIT_SKIP) 143 return LG_EXIT_SKIP 144 } 145 gv_check("subject-ran-and-exited-zero-on-a-valid-population" as *u8, 1 - rc, ctr) 146 gv_check("subject-examined-a-nonzero-population (a zero-subject run cannot acquit a registry)" as *u8, lg_has(out, n, "files_scanned=3" as *u8), ctr) 147 gv_check("recursive-walk-reached-the-subdirectory-transcript" as *u8, lg_has(out, n, "LOST t_sub exec=1" as *u8), ctr) 148 149 // ---- the anti-vacuity tooth first: the trivial wrong implementation cannot pass it ---- 150 gv_check("anti-vacuity-exec-proven-tool-with-no-row-is-named-LOST" as *u8, lg_has(out, n, "LOST t_lost exec=1" as *u8), ctr) 151 gv_check("lost-row-carries-its-remedy-not-just-a-count" as *u8, lg_has(out, n, "REMEDY /api/tools/register" as *u8), ctr) 152 // ---- and the positive control beside it: a detector that fires on everything fails HERE ---- 153 gv_check("pos-control-exec-proven-tool-WITH-a-green-row-is-OK-ROW" as *u8, lg_has(out, n, "OK-ROW t_ok exec=1" as *u8), ctr) 154 var notlost_ok: i64 = 1 155 if lg_has(out, n, "LOST t_ok " as *u8) == 1 { notlost_ok = 0 } 156 gv_check("pos-control-the-registered-tool-is-NOT-also-reported-lost" as *u8, notlost_ok, ctr) 157 158 // ---- states that must not collapse into LOST ---- 159 gv_check("row-present-but-not-GREEN-is-its-own-state-ROW-NOT-GREEN" as *u8, lg_has(out, n, "ROW-NOT-GREEN t_amber exec=1" as *u8), ctr) 160 gv_check("denied-only-tool-is-its-own-bucket-cap-coverage-not-loss" as *u8, lg_has(out, n, "DENIED-ONLY t_den denied=1" as *u8), ctr) 161 gv_check("unknown-only-tool-abstains-rather-than-acquitting" as *u8, lg_has(out, n, "UNKNOWN-ONLY t_unk unknown=1" as *u8), ctr) 162 163 // ---- the three real input defects, each with a named negative control ---- 164 var l_ok: i64 = 1 165 if lg_has(out, n, "t_listed" as *u8) == 1 { l_ok = 0 } 166 gv_check("neg-control-a-tool-merely-LISTED-in-a-deferred-tools-delta-is-not-evidence" as *u8, l_ok, ctr) 167 gv_check("neg-control-an-ESCAPED-exec-anchor-inside-a-string-is-not-a-fork" as *u8, lg_has(out, n, "UNKNOWN-ONLY t_prose unknown=1" as *u8), ctr) 168 var p_ok: i64 = 1 169 if lg_has(out, n, "OK-ROW t_prose" as *u8) == 1 { p_ok = 0 } 170 if lg_has(out, n, "LOST t_prose" as *u8) == 1 { p_ok = 0 } 171 gv_check("neg-control-the-prose-tool-never-enters-the-exec-partition" as *u8, p_ok, ctr) 172 gv_check("dedupe-the-same-tool-use-id-in-two-files-is-counted-once" as *u8, lg_has(out, n, "results_duplicate=1" as *u8), ctr) 173 gv_check("dedupe-leaves-the-replayed-tool-at-exec-1-not-2" as *u8, lg_has(out, n, "LOST t_dup exec=1" as *u8), ctr) 174 175 // ---- window, non-nishi, and the printed partition ---- 176 gv_check("since-window-excludes-an-older-call-and-COUNTS-the-exclusion" as *u8, lg_has(out, n, "results_out_of_window=1" as *u8), ctr) 177 var o_ok: i64 = 1 178 if lg_has(out, n, "t_old" as *u8) == 1 { o_ok = 0 } 179 gv_check("neg-control-the-out-of-window-tool-appears-in-no-bucket" as *u8, o_ok, ctr) 180 var r_ok: i64 = 1 181 if lg_has(out, n, "OK-ROW Read" as *u8) == 1 { r_ok = 0 } 182 if lg_has(out, n, "LOST Read" as *u8) == 1 { r_ok = 0 } 183 gv_check("neg-control-a-non-nishi-tool-with-exec-meta-is-not-in-the-partition" as *u8, r_ok, ctr) 184 gv_check("partition-is-exactly-5-tools-1-green-1-not-green-3-lost" as *u8, lg_has(out, n, "exec_tools=5 row_green=1 row_notgreen=1 lost=3" as *u8), ctr) 185 gv_check("partition-prints-its-own-sum-and-it-reconciles" as *u8, lg_has(out, n, "sum=5 sum_ok=1" as *u8), ctr) 186 gv_check("per-call-classes-also-reconcile-against-results-counted" as *u8, lg_has(out, n, "calls_sum_ok=1" as *u8), ctr) 187 gv_check("caps-are-declared-in-every-report-so-a-floor-cannot-read-as-a-total" as *u8, lg_has(out, n, "any_cap_hit=0 floor_not_total=0" as *u8), ctr) 188 189 // ---- fail-closed: an instrument that cannot see must refuse, never return lost=0 ---- 190 let rc2: i64 = lg_run(subj, "lostset" as *u8, tdir, noreg, since, out, cl) 191 var ref1: i64 = 0 192 if rc2 == LG_RC_REFUSE { if lg_has(out, cl[0], "REFUSED registry unreadable" as *u8) == 1 { ref1 = 1 } } 193 gv_check("neg-control-a-missing-registry-REFUSES-instead-of-acquitting" as *u8, ref1, ctr) 194 let rc3: i64 = lg_run(subj, "lostset" as *u8, noroot, reg, since, out, cl) 195 var ref2: i64 = 0 196 if rc3 == LG_RC_REFUSE { if lg_has(out, cl[0], "REFUSED transcripts root unreadable" as *u8) == 1 { ref2 = 1 } } 197 gv_check("neg-control-an-unwalkable-root-REFUSES-rather-than-reporting-zero-lost" as *u8, ref2, ctr) 198 199 // ---- idempotence: the second run of the WHOLE fixture must grade identically ---- 200 let rc4: i64 = lg_run(subj, "lostset" as *u8, tdir, reg, since, out, cl) 201 var idem: i64 = 0 202 if rc4 == 0 { if lg_has(out, cl[0], "exec_tools=5 row_green=1 row_notgreen=1 lost=3" as *u8) == 1 { if lg_has(out, cl[0], "files_scanned=3" as *u8) == 1 { idem = 1 } } } 203 gv_check("idempotent-a-second-run-on-the-same-fixture-grades-identically" as *u8, idem, ctr) 204 205 let v: i64 = gv_verdict("LOSTSET-GATE" as *u8, ctr, "the miner joins execution evidence to registry rows, tells the three real look-alike defects apart, and refuses when it cannot see" as *u8) 206 sys_exit(v) 207 return v 208}