nx_store_janitor.nx
buildroot/runtime/nx_store_janitor.nx
about
nx_store_janitor.nx -- reclaim SUPERSEDED seg-store segment files. The janitor pass that seq724/RK013
named as reclaimable and nobody had built.
MEASURED 2026-07-30 BEFORE WRITING THIS: knowledge/store holds 63,669 MB across 14,585 segment .docs files,
while all 1,088 manifests TOGETHER reference only 3,031 live segments. debt-manifest.txt lists exactly TWO
segments while 2,055 debt-seg-*.docs exist on disk, ~2.4 GB for one plane. So roughly 79 percent of the
information plane's bytes are segments no reader can ever reach: the seg-store is append-only and every
commit writes a NEW segment, so superseded generations simply accumulate forever.
WHY THIS IS SAFE BY CONSTRUCTION: the manifest IS the definition of live. ss_manifest/ss_scan_seglist read
ONLY segments listed there, so a file whose segid is absent from its own plane's manifest is unreachable BY
DEFINITION, not by inference. That is the whole safety argument and it is why this tool refuses to run when
it cannot read the manifest -- an unknown live set means an unknown safe set.
RULE 13 -- MOVE ASIDE, NEVER DELETE. Superseded files are RENAMED into knowledge/store/retired/ (the
convention already present on the box). Nothing is unlinked, so a mistake is reversible by renaming back.
DRY RUN IS THE DEFAULT: it reports what it WOULD move and touches nothing. Pass 'apply' to actually move.
EXIT: 0 clean/reported - 2 usage - 3 REFUSED (manifest unreadable or empty live set) - 4 nothing superseded
license_tier: ORIGINAL No hw writes (Rule 26).
dependencies 1 imports · 0 importers
imports: nx_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
| 23 | const SJ_MANI: i64 = 262144 |
| 24 | const SJ_DBUF: i64 = 262144 |
| 25 | const SJ_LIVE: i64 = 65536 |
| 26 | const SJ_MAXLIVE: i64 = 8192 |
| 27 | const SJ_PATH: i64 = 1024 |
| 28 | const SJ_MSG: i64 = 8192 |
| 29 | const SJ_STAT: i64 = 256 |
| 30 | const SJ_STAT_SIZE_OFF: i64 = 48 |
| 31 | const SJ_NL: i64 = 10 |
| 32 | const SJ_DOT: i64 = 46 |
| 33 | const SJ_SLASH: i64 = 47 |
| 34 | const SJ_STDOUT: i64 = 1 |
| 35 | const SJ_EXIT_USAGE: i64 = 2 |
| 36 | const SJ_EXIT_REFUSED: i64 = 3 |
| 37 | const SJ_EXIT_NONE: i64 = 4 |
| 38 | const SJ_MB: i64 = 1048576 |
functions
| 40 | func sj_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } called by 1: main |
| 41 | func sj_cat(d: *u8, off: i64, s: *u8) -> i64 called by 1: main |
| 46 | func sj_num(d: *u8, off: i64, v: i64) -> i64 |
| 60 | func sj_size(path: *u8) -> i64 |
| 69 | func main(argc: i64, argv: *i64) -> i64 |