nx_cachewatch.nx
buildroot/runtime/nx_cachewatch.nx
about
nx_cachewatch.nx -- IS THE WRITE CACHE ACTUALLY CACHING? The axis nothing in the estate measured.
WHY THIS EXISTS (2026-09-03). The box spent a full day refusing every build with load 13-25 while
`/api/build` correctly reported an I/O storm. The CAUSE was one condition no organ could see:
`md3 : active raid1 nvme1n1p1[1] [2/1] [_U]` -- the NVMe RAID1 behind the write cache lost a device,
so the cache was flushed to completion and set `uncacheable`, and from that moment 100% of writes went
straight to the RAID5 array. Measured on the live plane: `writes +18,366` == `disk_writes +18,366` ==
`uncached_writes +18,366` across two spaced samples, with every SSD-side counter frozen.
MEASURED ABSENCE BEFORE BUILDING: `grep -rl flashcache buildroot/runtime/*.nx` returned ZERO organs.
The estate could see the SYMPTOM (load, D-state, refused builds) and never the CAUSE.
nx_cachewatch check [proc_root] -> one verdict line, exit carries it
nx_cachewatch explain [proc_root] -> every field it read, with its LEVEL/COUNTER class named
IT READS LEVELS AND REFUSES TO READ COUNTERS AS LEVELS. THIS IS THE WHOLE POINT.
`flashcache_stats` carries `dirty_writeback_kb=31543788` and `dirty_write_hits=43493286`. Both are
LIFETIME COUNTERS sitting among reads/writes/hits. Read as levels they say "31.5 GB of dirty data is
stranded on a degraded unmirrored NVMe" -- an alarming, actionable, WRONG conclusion. The estate's
memory recorded exactly that error, and this organ's author was two minutes from publishing it again.
The LEVEL lives in `cache_info` as `dirty_blocks`, and it reads 0.
A FROZEN COUNTER AND A PINNED LEVEL ARE INDISTINGUISHABLE IN ONE SAMPLE, AND THE ALARMING READING IS
THE ONE THAT GETS PUBLISHED. So this organ names the class of every number it prints, and the
verdict is computed ONLY from fields it can justify as levels.
MODE IS NOT THE DISCRIMINATOR. `cache_info` keeps saying `mode=WRITE_BACK` after the cache has been
flushed and disabled -- that field records how the device was CONFIGURED, not whether it is caching
now. The discriminator is `flashcache_progress: status=uncacheable...`. A verdict built on `mode`
alone would have read GREEN through the entire outage. Proven by its gate's T2: two fixtures with
BYTE-IDENTICAL cache_info must return DIFFERENT verdicts.
exit: 0 GREEN (caching, mirror intact) | 1 RED (NOT caching -- every write hits the array)
| 2 AMBER (caching, mirror degraded -- unmirrored dirty data) | 3 UNOBSERVABLE | 4 usage
UNOBSERVABLE IS NOT GREEN. A missing /proc/flashcache means this host has no such cache OR the
reader is wrong; both are "I could not look", and neither acquits.
PROVEN 8/8 GREEN 2026-09-03, bite-proven killed=1, restores byte-identical.
license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
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
| 39 | const CW_BUF: i64 = 65536 |
| 40 | const CW_NAME: i64 = 512 |
| 41 | const CW_PATH: i64 = 1024 |
| 42 | const CW_DIRBUF: i64 = 65536 |
| 43 | const CW_DENT_RECLEN_OFF: i64 = 16 |
| 44 | const CW_DENT_NAME_OFF: i64 = 19 |
| 45 | const CW_GETDENTS: i64 = 217 |
| 46 | const CW_OPENDIR_FLAGS: i64 = 0x10000 |
| 47 | const CW_AT_FDCWD: i64 = 0 - 100 |
| 48 | const CW_DOT: i64 = 46 |
| 50 | const CW_GREEN: i64 = 0 |
| 51 | const CW_RED: i64 = 1 |
| 52 | const CW_AMBER: i64 = 2 |
| 53 | const CW_UNOBS: i64 = 3 |
functions
| 55 | func cw_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } |
| 56 | func cw_out(s: *u8) -> i64 { sys_write(1, s, cw_slen(s)); return 0 } |
| 57 | func cw_num(v: i64) -> i64 |
| 69 | func cw_cat(dst: *u8, a: *u8, b: *u8, c: *u8) -> i64 |
| 80 | func cw_read(path: *u8, buf: *u8, cap: i64) -> i64 |
| 95 | func cw_find(buf: *u8, n: i64, needle: *u8) -> i64 |
| 111 | func cw_int_after(buf: *u8, n: i64, key: *u8) -> i64 |
| 133 | func cw_degraded_count(buf: *u8, n: i64) -> i64 called by 1: main |
| 158 | func cw_first_cache_dir(root: *u8, out: *u8) -> i64 |
| 204 | func cw_streq(a: *u8, b: *u8) -> i64 called by 1: main |
| 211 | func main(argc: i64, argv: *i64) -> i64 |