code wiki / _hdl_build / nx_flap_probe.nx
nx_flap_probe.nx source
↩ module page · 117 lines · 4405 B
1// nx_flap_probe.nx -- TEAM-OWNED repeat-run stability probe (Engineer's
2// verify verb). Runs a target ELF N times via fork/execve/wait4 and
3// judges from the RAW wait status -- never a shell $? (the fake-green
4// channel, see feedback-wsl-exit-code-judging-2026-06-09: $? echoes
5// pre-expand through PS AND Git-Bash into wsl, so every inline RC=$? is
6// the OUTER shell's last status, not the target's).
7//
8// Born 2026-06-10: a P3 KAT "passed" via $?-echo and "failed" in the game
9// gate -- the gate (wait4) was right, the $? channel lied, and the hunt
10// for "same-binary nondeterminism" was chasing a phantom. This organ
11// makes the honest repeat-run judgment a one-call team capability, in
12// pure NishiLang from the syscall layer up (no sh, no py).
13//
14// Usage:
15// nx_flap_probe.elf <target.elf> [n_runs] (default n_runs = 20)
16//
17// Output: one FLAPPROBE line with a status histogram, e.g.
18// FLAPPROBE target=/tmp/ft.elf runs=20 distinct=1 status=4 x20 verdict=STABLE
19// FLAPPROBE ... distinct=2 status=0 x17 status=4 x3 verdict=FLAP
20//
21// Exit: 0 = STABLE (all runs same status; the status itself is REPORTED,
22// not judged -- a stable failure is the caller's evidence, not ours);
23// 2 = FLAP (nondeterminism proven); 3 = usage/exec error.
24// license_tier: ORIGINAL
25import "nx_syscalls.nx"
26
27const FP_DEFAULT_RUNS: i64 = 20
28const FP_MAX_DISTINCT: i64 = 64
29
30func fp_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
31func fp_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m;sys_write(1,"-" as *u8,1)}; let t: *u8 = sys_mmap(28); var k: i64=0; if m==0 {t[0]=48;k=1}; while m>0 {t[k]=48+(m%10); m=m/10; k=k+1}; var i: i64=0; while i<k {bb[i]=t[k-1-i]; i=i+1}; sys_write(1, bb, k); return 0 }
32
33// one run: fork/execve/wait4; returns WEXITSTATUS or 128+signal (signal-
34// aware like nx_sov_build_run -- a segfault must never decode as success).
35func fp_run_once(path: *u8, envp: *i64) -> i64 {
36 let pid: i64 = sys_fork()
37 if pid == 0 {
38 let av: *i64 = sys_mmap(8 * 2) as *i64
39 av[0] = path as i64
40 av[1] = 0
41 sys_execve(path, av, envp)
42 sys_exit(126)
43 }
44 let st: *i64 = sys_mmap(16) as *i64
45 sys_wait4(pid, st, 0)
46 let sig: i64 = st[0] & 0x7f
47 if sig != 0 { return 128 + sig }
48 return (st[0] >> 8) & 0xff
49}
50
51func main(argc: i64, argv: *i64) -> i64 {
52 if argc < 2 {
53 fp_puts("FLAPPROBE usage: nx_flap_probe.elf <target.elf> [n_runs]\n" as *u8)
54 return 3
55 }
56 let target: *u8 = argv[1] as *u8
57 var runs: i64 = FP_DEFAULT_RUNS
58 if argc >= 3 {
59 let a: *u8 = argv[2] as *u8
60 var v: i64 = 0
61 var i: i64 = 0
62 while a[i] >= (48 as u8) {
63 if a[i] > (57 as u8) { i = i + 1 } else {
64 v = v * 10 + ((a[i] as i64) - 48)
65 i = i + 1
66 }
67 }
68 if v > 0 { runs = v }
69 }
70 let envp: *i64 = sys_mmap(8 * 2) as *i64
71 envp[0] = "PATH=/usr/bin:/bin" as *u8 as i64
72 envp[1] = 0
73
74 // status histogram: parallel code/count arrays (distinct statuses are few)
75 let codes: *i64 = sys_mmap(FP_MAX_DISTINCT * 8) as *i64
76 let counts: *i64 = sys_mmap(FP_MAX_DISTINCT * 8) as *i64
77 var n_distinct: i64 = 0
78
79 var r: i64 = 0
80 while r < runs {
81 let code: i64 = fp_run_once(target, envp)
82 if code == 126 { fp_puts("FLAPPROBE exec-failed\n" as *u8); return 3 }
83 var found: i64 = 0 - 1
84 var k: i64 = 0
85 while k < n_distinct {
86 if codes[k] == code { found = k }
87 k = k + 1
88 }
89 if found == 0 - 1 {
90 if n_distinct < FP_MAX_DISTINCT {
91 codes[n_distinct] = code
92 counts[n_distinct] = 1
93 n_distinct = n_distinct + 1
94 }
95 } else {
96 counts[found] = counts[found] + 1
97 }
98 r = r + 1
99 }
100
101 fp_puts("FLAPPROBE target=" as *u8)
102 fp_puts(target)
103 fp_puts(" runs=" as *u8); fp_putn(runs)
104 fp_puts(" distinct=" as *u8); fp_putn(n_distinct)
105 var k2: i64 = 0
106 while k2 < n_distinct {
107 fp_puts(" status=" as *u8); fp_putn(codes[k2])
108 fp_puts(" x" as *u8); fp_putn(counts[k2])
109 k2 = k2 + 1
110 }
111 if n_distinct == 1 {
112 fp_puts(" verdict=STABLE\n" as *u8)
113 return 0
114 }
115 fp_puts(" verdict=FLAP\n" as *u8)
116 return 2
117}