nx_diskfree.nx source
↩ module page · 66 lines · 3356 B
1// nx_diskfree.nx -- THE DISK AXIS, made callable (2026-08-28).
2//
3// WHY THIS EXISTS. On 2026-08-28 a 100%-FULL DISK truncated a sibling seat's MEMORY.md to 0 bytes:
4// open(path,"w") truncates BEFORE it writes, so a full volume does not refuse a write, it DESTROYS the
5// file. Nothing in the estate saw it coming. nx_resmon is "the resource axis nx_health lacks" -- but only
6// for MEMORY and SWAP; a search for the disk primitive returned matches=0 for BOTH sys_statfs and statvfs
7// with corpus_complete=1, and nx_res_census records the same absence in its own header.
8//
9// THE CAPABILITY WAS DARK, NOT MISSING. nx_system_triage.tr_free_gb has read filesystem space since
10// 2026-06-10 -- inside an _hdl_build organ that is NOT REGISTERED, so nx_job_run refuses it as "not an
11// unpinned GREEN tool" and no caller in the estate can reach it. ★A CAPABILITY THAT EXISTS IN ONE
12// UNREACHABLE ORGAN IS INDISTINGUISHABLE FROM ONE NOBODY BUILT -- and its absence is only discovered by
13// the incident it would have prevented.
14//
15// This organ is the reachable form. The arithmetic lives in nx_syscalls (sys_fs_used_permil /
16// sys_fs_avail_bytes) so nx_resmon can compose the SAME ruler rather than growing a second one.
17//
18// THE THIRD STATE IS LOAD-BEARING. statfs can fail (bad path, unmounted, permission) and a volume can
19// report zero blocks. Both return STATFS_ERR and this organ prints UNMEASURABLE with exit 3 -- it never
20// prints 0 permil used, because "I could not look" and "the disk is empty" must never share a
21// representation, and 0-used is the most flattering possible lie.
22//
23// license_tier: ORIGINAL No hw writes (Rule 26). expect_exit: 0
24import "nx_syscalls.nx"
25
26const DF_EXIT_UNMEASURABLE: i64 = 3
27const DF_EXIT_USAGE: i64 = 2
28
29func df_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
30func df_num(v: i64) -> i64 {
31 var m: i64 = v
32 if m < 0 { df_puts("-" as *u8); m = 0 - m }
33 let t: *u8 = sys_mmap(32)
34 var k: i64 = 0
35 if m == 0 { t[0] = 48 as u8; k = 1 }
36 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
37 let o: *u8 = sys_mmap(32)
38 var i: i64 = 0
39 while i < k { o[i] = t[k - 1 - i]; i = i + 1 }
40 sys_write(1, o, k)
41 return 0
42}
43
44func main(argc: i64, argv: *i64) -> i64 {
45 if argc < 2 {
46 df_puts("usage: nx_diskfree <path> -- prints used_permil + avail_bytes for the filesystem holding <path>\n" as *u8)
47 sys_exit(DF_EXIT_USAGE)
48 return DF_EXIT_USAGE
49 }
50 let path: *u8 = argv[1] as *u8
51 let used: i64 = sys_fs_used_permil(path)
52 let avail: i64 = sys_fs_avail_bytes(path)
53 if used == STATFS_ERR {
54 df_puts("NX-DISKFREE UNMEASURABLE path=" as *u8)
55 df_puts(path)
56 df_puts(" -- statfs refused it or the volume reports zero blocks. This is NOT 'empty': a disk that\n" as *u8)
57 df_puts("cannot be measured and a disk with room must never share a representation.\n" as *u8)
58 sys_exit(DF_EXIT_UNMEASURABLE)
59 return DF_EXIT_UNMEASURABLE
60 }
61 df_puts("NX-DISKFREE path=" as *u8); df_puts(path)
62 df_puts(" used_permil=" as *u8); df_num(used)
63 df_puts(" avail_bytes=" as *u8); df_num(avail)
64 df_puts(" (used counts against f_bavail, which EXCLUDES the root reserve, so this reads fuller than root sees)\n" as *u8)
65 return 0
66}