code wiki / _hdl_build / nx_toolsafety_lib.nx

nx_toolsafety_lib.nx

buildroot/runtime/_hdl_build/nx_toolsafety_lib.nx

27036 B608 linesdepth 2pulls 2 transitivereach 3 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_toolsafety_lib.nx -- THE ONE MCP SAFETY-FLAG DERIVER (2026-08-25). Write reach, destructive reach, network reach and exec reach for an organ, derived from its TRANSITIVE import closure, with line comments AND string literals stripped, and syscall DEFINITIONS skipped. WHY A LIB, AND WHY NOW. Two derivers already shipped and DISAGREED BY CONSTRUCTION. nx_schema_backfill (sb_derive_flags) scans ONE FILE, so an organ that writes through an imported helper reaches the write syscall in the LIB and is published readOnly=1 -- wrong in the UNSAFE direction. nx_toolflags folds ONE level of the import closure and strips comments, and its own header set the condition for this extraction in advance: two consumers is not yet a lib, but if a third appears, extract it and delete the copy. The third consumer arrived (the drift control), so this is that extraction. WHEN TWO ORGANS MUST AGREE, MAKE DISAGREEMENT IMPOSSIBLE BY CONSTRUCTION: THERE IS ONLY ONE OF IT. THREE CHANGES FROM THE INCUMBENTS, EACH FOR A REASON THAT WAS MEASURED, NOT PREFERRED: 1. TRANSITIVE closure, not one level. A helper that reaches a writer through a helper of its own is two hops away and one hop cannot see it. The depth LADDER is published per subject, so the contribution of the extra depth is evidence rather than a claim about what it bought. 2. STRING LITERALS ARE STRIPPED TOO. The incumbent declared this a rare limitation erring conservative. It stops being rare the moment the deriver is a LIB that every consumer imports: a marker table written as literals would put write, destructive and network markers into the closure of every organ that composed it. That is why the table is a CONF and this source names no marker at all -- but stripping literals is what makes the property hold for any OTHER scanner too, including the ones already shipped. 3. sys_read_file, so there is no source-size cap left to be inconclusive about. Both incumbents cap at 256 KiB and honestly refuse past it; the primitive that closes that hole already exists, sizes its buffer from the file and cannot short-read. FAIL-CLOSED EVERYWHERE. Unreadable subject, unreadable marker table, an empty marker class, or a walk that hits its budget all return INCONCLUSIVE. None of them may return "nothing matched", because nothing-matched is byte-identical to "this organ is read-only", which is the permissive direction and the entire defect this ruler exists to stop. license_tier: ORIGINAL No hw writes (Rule 26).

dependencies 1 imports · 3 importers

nx_syscalls.nx nx_toolsafety_lib.nx nx_schema_backfill.nx nx_schemadrift.nx nx_schemadrift_gate.nx

imports: nx_syscalls.nx

imported by: nx_schema_backfill.nxnx_schemadrift.nxnx_schemadrift_gate.nx

structs

none

consts

34const TS_MARKCONF: *u8 = "knowledge/tool_safety_markers.conf" as *u8
37const TS_CLASSES: i64 = 4
38const TS_CW: i64 = 0
39const TS_CD: i64 = 1
40const TS_CN: i64 = 2
41const TS_CX: i64 = 3
44const TS_MAXMARK: i64 = 64
45const TS_MARKCAP: i64 = 64
46const TS_PATHCAP: i64 = 512
50const TS_MEMOSLOTS: i64 = 8192
51const TS_IMPBLK: i64 = 1536
53const TS_MAXWALK: i64 = 1024
54const TS_LF: i64 = 10
55const TS_TAB: i64 = 9
56const TS_HASH_OFF: i64 = 1469598103934665603
57const TS_HASH_PRIME: i64 = 1099511628211
59const TS_HASH_MUL: i64 = 131
60const TS_CH_SLASH: i64 = 47
61const TS_CH_QUOTE: i64 = 34
62const TS_CH_BSLASH: i64 = 92
63const TS_CH_SPACE: i64 = 32
64const TS_CH_HASH: i64 = 35
65const TS_CH_F: i64 = 102
66const TS_CH_U: i64 = 117
67const TS_CH_N: i64 = 110
68const TS_CH_C: i64 = 99
69const TS_CH_I: i64 = 105
70const TS_CH_M: i64 = 109
71const TS_CH_P: i64 = 112
72const TS_CH_O: i64 = 111
73const TS_CH_R: i64 = 114
74const TS_CH_T: i64 = 116
75const TS_FUNCPFX: i64 = 5
76const TS_IMPPFX: i64 = 8
77const TS_ROOT_HDL: *u8 = "buildroot/runtime/_hdl_build/" as *u8
78const TS_ROOT_RT: *u8 = "buildroot/runtime/" as *u8
80const TS_DEPTH_ALL: i64 = 0 - 1

functions

113func ts_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
called by 2: ts_hasts_reach
115func ts_cat(d: *u8, o: i64, s: *u8) -> i64
called by 1: ts_resolve
136func ts_hash(s: *u8) -> i64
called by 2: ts_slotts_reach
150func ts_streq(a: *u8, b: *u8) -> i64
164func ts_load_markers() -> i64
231func ts_marker_count(cls: i64) -> i64
called by 2: maints_scan_buf
237func ts_marker_at(cls: i64, idx: i64) -> *u8
called by 1: ts_scan_buf
249func ts_strip(src: *u8, n: i64, out: *u8) -> i64
called by 2: gs_probets_slot
282func ts_has(buf: *u8, n: i64, needle: *u8) -> i64
called by 2: gs_probets_scan_buf calls 1: ts_slen
307func ts_scan_buf(buf: *u8, n: i64, box: *i64) -> i64
325func ts_imports_buf(buf: *u8, n: i64, out: *u8) -> i64
called by 1: ts_slot
358func ts_resolve(mod: *u8, out: *u8) -> i64
372func ts_memo_init() -> i64
called by 2: ts_slotts_reach calls 1: sys_mmap
392func ts_slot(path: *u8) -> i64
464func ts_reach(path: *u8, maxdepth: i64, box: *i64) -> i64
578func ts_quad(path: *u8, quad: *i64, deep: *i64, own: *i64) -> i64
called by 2: sb_derive_flagsmain calls 1: ts_reach
590func ts_set_trace(v: i64) -> i64 { TS_TRACE = v; return v }
called by 1: main
595func ts_write_src(out: *u8) -> i64
called by 1: main
606func ts_stat_files() -> i64 { return TS_STAT_FILES }
called by 1: main
607func ts_stat_bytes() -> i64 { return TS_STAT_BYTES }
called by 1: main
608func ts_memo_full() -> i64 { return TS_MEMO_FULL }
called by 1: main