code wiki / _hdl_build / nx_toolflags.nx
nx_toolflags.nx
buildroot/runtime/_hdl_build/nx_toolflags.nx
about
nx_toolflags.nx -- SAFETY-FLAG DERIVER (2026-08-06). Emits knowledge/tool_flags.conf so tools/list can
stop publishing a FABRICATED safety profile for tools whose flags were never looked up.
THE DEFECT, MEASURED on the live tools/list: 694 of 869 tools (79.9%) carry the identical quad
ro=0 destr=1 idem=0 open=1. That is not a measurement -- it is a hardcoded constant written by
ma_schema_append_row at registration time. It does not merely omit, it LIES: nx_pm_board, a READ-ONLY
dashboard, is published destructiveHint=true, so an agent that honours annotations refuses a safe read.
(The constant errs CONSERVATIVE, so this is an INFORMATION defect, not an unsafe one -- but a fabricated
value ends the enquiry where a blank would have invited a lookup.)
MATCHES THE KNOWN GOOD: the marker sets and the conservatism below are nx_schema_backfill's
sb_derive_flags (shipped 2026-08-06) COPIED DELIBERATELY, not reinvented -- same syscalls, same
"DESTRUCTIVE is narrower than writes" split, same refusal to claim `idempotent` (nothing in the source
declares it, so it stays 0, the conservative direction). Two consumers is not yet a shared lib (rule 15
says three); if a third appears, extract sb_derive_flags to a lib and delete this copy.
THE TWEAK, AND WHY IT IS A SAFETY FIX: sb_derive_flags scans ONE FILE. An organ that writes through an
imported helper reaches sys_openat_wr in the LIB, not in its own source, so a single-file scan calls it
READ-ONLY -- wrong in the UNSAFE direction. This organ scans the organ's own source AND one level of its
`import "x.nx"` closure, and REPORTS `depth0_readonly` vs `depth1_readonly`: the difference IS the count
of tools the single-file scan would have mislabelled read-only. The number is published either way, so
the tweak can never be claimed without evidence.
HONEST: no source, or a read that FILLED the buffer (so a marker past the cap may have been missed),
=> NOT DERIVED, conservative default kept, and COUNTED. Blank beats bad.
nx_toolflags -> writes knowledge/tool_flags.conf, prints a JSON census on stdout
license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
dependencies 2 imports · 0 importers
imports: nx_mgmt_api.nxnx_syscalls.nx
imported by: nobody (leaf or entry point)
call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown
structs
| none |
consts
| 31 | const TF_ALCAP: i64 = 1 << 18 |
| 32 | const TF_SRCCAP: i64 = 262144 |
| 33 | const TF_NAMECAP: i64 = 128 |
| 34 | const TF_PATHCAP: i64 = 512 |
| 36 | const TF_MAXIMP: i64 = 32 |
| 37 | const TF_OUT: *u8 = "knowledge/tool_flags.conf" as *u8 |
functions
| 42 | func tfw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } |
| 43 | func tfn(v: i64) -> i64 |
| 52 | func tf_ends(s: *u8, sl: i64, suf: *u8, fl: i64) -> i64 called by 1: main |
| 66 | func tf_has(buf: *u8, n: i64, needle: *u8) -> i64 called by 1: tf_scan_one |
| 90 | func tf_wflag(fd: i64, v: i64) -> i64 { if v == 1 { ma_write_str(fd, "1" as *u8) } else { ma_write_str(fd, "0" as *u8) } return 0 } called by 1: main |
| 105 | func tf_strip_comments(src: *u8, n: i64, out: *u8) -> i64 called by 1: tf_scan_one |
| 123 | func tf_scan_one(path: *u8, box: *i64) -> i64 |
| 152 | func tf_imports(path: *u8, imps: *u8) -> i64 |
| 192 | func tf_resolve(stem: *u8, stl: i64, out: *u8) -> i64 |
| 208 | func main() -> i64 |