code wiki / _hdl_build / nx_memfind.nx

nx_memfind.nx

buildroot/runtime/_hdl_build/nx_memfind.nx

15065 B397 linesdepth 3pulls 3 transitivereach 0 importersview sourcekind tool
docsdependenciesstructsconstsfunctions

about

nx_memfind.nx -- BM25 ranked retrieval over the laptop-local memory corpus. CONVERTED TO nx_memplane_lib 2026-08-06. It now owns only the ranking: term counting, document length, the integer log, the stopword list and query derivation. The walk, name table, read, join and dump list come from the lib. WHY BM25, AND WHAT IT REPLACED (measured -- three rankers, one test) ------------------------------------------------------------------- Test: reconstruct the ORIGINAL description of a memory that duplicates an existing one (the store law, written twice by two sessions three weeks apart) and ask whether the ranker surfaces the file it duplicates. rarity-weighted presence -> TARGET NOT FOUND conjunction (fraction present) -> TARGET RANK 22 of 2173 BM25 -> TARGET RANK 1 of 2173 Both hand-rolled attempts failed for the SAME reason, solved in retrieval decades ago: * RARITY fails because this is a SINGLE-PROJECT corpus -- the words that identify a doctrine are the words the whole project uses (sovereign 1190/2176, data 1138, files 808, store 697, tsv 442). Dropping "common" terms deletes the topic and keeps the incidental. * CONJUNCTION fails because the biggest file contains every word; a 255 KB roadmap won a query about flat-file policy purely by being long. ★★★★★★ BOTH ARE PRESENCE MEASURES, AND PRESENCE IN A LONG DOCUMENT IS NEARLY FREE. BM25 fixes exactly that pair: term-frequency SATURATION (k1) and LENGTH NORMALISATION (b). ★ WHEN A HAND-ROLLED RANKER KEEPS FAILING, THE FIELD'S BASELINE IS THE KNOWN GOOD YOU WERE SUPPOSED TO MATCH FIRST. Integer notes: idf uses log2 rather than ln, which scales every term identically and so leaves the RANKING unchanged; the BM25 idf ratio simplifies to (2N+2)/(2df+1). Fixed point 1/256 for logs. TWO ENTRY POINTS, ONE RANKER: nx_memfind <term> ... -- a human picks the query (interactive retrieval) nx_memfind --file <path> -- the query is DERIVED from a file's own name+description ⚠ per-term df is printed deliberately: a rewrite once dropped it silently and the gate caught it. ★ A REWRITE THAT PRESERVES THE OUTPUT BUT DROPS THE EVIDENCE FOR IT IS A REGRESSION. usage: nx_memfind [--dir D] [--n K] [--quiet] (--file <path> | <term> [<term> ...]) Sovereign: imports nx_memplane_lib. license_tier: ORIGINAL

dependencies 1 imports · 0 importers

nx_memplane_lib.nx nx_memfind.nx

imports: nx_memplane_lib.nx

imported by: nobody (leaf or entry point)

call flow from main pre-order; caps 40 nodes / depth 6 declared; ↻ = already shown

main mp_streq mp_len mp_alnum ms_addterm ms_termptr ms_lower ms_isstop mp_streq ↻ mp_streq ↻ mp_base mp_len ↻ mp_readf sys_openat_rd sys_read sys_close mp_cat mp_say mp_write_all sys_write mp_scan sys_openat_rd ↻ sys_mmap nxa_die sys_write ↻ sys_exit nxa_lock_take nxa_lock_addr sys_write ↻ nxa_lock_give nxa_lock_addr ↻ nxa_report_overrun sys_write ↻ nxa_dump_printable sys_write ↻ nxa_dump_sizes sys_write ↻ mp_is_md mp_len ↻ mp_nameptr

structs

none

consts

41const MS_DIR: *u8 = "/mnt/c/Users/elder/.claude/projects/C--Users-elder/memory"
42const MS_FBUF: i64 = 1048576
43const MS_MSG: i64 = 65536
44const MS_MAXT: i64 = 40
45const MS_TLEN: i64 = 64
46const MS_MINW: i64 = 3
47const MS_DESC: i64 = 120

functions

49func ms_termptr(terms: *u8, i: i64) -> *u8 { return ((terms as i64) + i * MS_TLEN) as *u8 }
called by 2: ms_addtermmain
51func ms_lower(c: u8) -> i64
called by 2: ms_countms_addterm
58func ms_count(buf: *u8, n: i64, pat: *u8) -> i64
called by 1: main calls 3: mp_lenms_lowermp_alnum
82func ms_doclen(buf: *u8, n: i64) -> i64
called by 1: main calls 1: mp_alnum
99func ms_log2fx(v: i64) -> i64
called by 1: main
111func ms_isstop(w: *u8) -> i64
called by 1: ms_addterm calls 1: mp_streq
137func ms_addterm(terms: *u8, nt: i64, src: *u8, s: i64, wl: i64) -> i64
154func main(argc: i64, argv: *i64) -> i64