code wiki / (root) / nx_vidclass_adversary_gate.nx

nx_vidclass_adversary_gate.nx source

↩ module page · 76 lines · 5172 B

1// nx_vidclass_adversary_gate.nx -- CRITIC/ADVERSARY red-team of the video-classification ruler (operator method: 2// researcher -> census -> critic -> ADVERSARY -> coach). A classifier is not trusted until it SURVIVES an attack. 3// Precedent: nx_card_adversary_gate 7/7 = LAW. This tries to BREAK ts_rhythm_marks + ts_classify: 4// A1 NOISE-NOT-RHYTHM (the critical one): pseudo-random high-motion (LCG) must NOT be flagged rhythmic -- 5// if chaos reads as "dance", the whole signal is worthless. 6// A2 PERIODIC-SURVIVES-NOISE: a real periodic beat WITH jitter must STILL be detected (real dance isn't clean). 7// A3 QUIET-NOT-ACTIVE: an all-low clip must NOT label active/rhythmic (no false positive). 8// A4 SINGLE-SPIKE-NOT-SCENEHEAVY: one scene cut in a long clip must NOT label scene-heavy (density holds). 9// A5 DISCRIMINATION: a truly-rhythmic clip labels 2 AND a noisy-active clip labels != 2 -- the ruler SEPARATES 10// them (the "distinguishes a good X from the fake" test). A ruler that can't separate is a fake ruler. 11// Deterministic (LCG, fixed seed) so the gate is reproducible. license_tier: ORIGINAL expect_exit: 0 12import "nx_ts_marks.nx" 13 14func gp(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return sys_write(1, s, n) } 15func gn(v: i64) -> i64 { 16 let bb: *u8 = sys_mmap(28); var m: i64 = v 17 if m < 0 { sys_write(1, "-" as *u8, 1); m = 0 - m } 18 let t: *u8 = sys_mmap(28); var k: i64 = 0 19 if m == 0 { t[0] = 48 as u8; k = 1 } 20 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 21 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 } 22 return sys_write(1, bb, k) 23} 24// deterministic LCG pseudo-random in [lo, lo+range) 25func lcg_next(state: *i64) -> i64 { state[0] = (state[0] * 1103515245 + 12345) & 0x7fffffff; return state[0] } 26 27func main(argc: i64, argv: *i64) -> i64 { 28 var pass: i64 = 0 29 let bins: *i64 = sys_mmap(8 * 128) as *i64 30 let mt: *i64 = sys_mmap(8 * 64) as *i64 31 let ms: *i64 = sys_mmap(8 * 64) as *i64 32 let me: *i64 = sys_mmap(8 * 64) as *i64 33 let cl: *i64 = sys_mmap(8 * 8) as *i64 34 let st: *i64 = sys_mmap(8) as *i64 35 var i: i64 = 0 36 37 // A1 NOISE-NOT-RHYTHM: 40 bins of pseudo-random high motion (value 60..260), NON-periodic -> expect 0 rhythm. 38 st[0] = 987654321 39 i = 0; while i < 40 { bins[i] = 60 + (lcg_next(st) % 200); i = i + 1 } 40 var a1: i64 = ts_rhythm_marks(bins, 40, 500, mt, ms, me, 64) 41 if a1 == 0 { pass = pass + 1; gp("A1 noise NOT flagged rhythmic OK\n" as *u8) } else { gp("A1 *** BREAK: noise -> rhythmic nm=" as *u8); gn(a1); gp(" (rhythm detector fires on chaos)\n" as *u8) } 42 43 // A2 PERIODIC-SURVIVES-NOISE: period-4 beat (350 vs 120) + small jitter -> must STILL detect rhythm. 44 st[0] = 424242 45 i = 0; while i < 40 { var base: i64 = 120; if (i % 4) == 0 { base = 350 } bins[i] = base + (lcg_next(st) % 40); i = i + 1 } 46 var a2: i64 = ts_rhythm_marks(bins, 40, 500, mt, ms, me, 64) 47 if a2 >= 1 { pass = pass + 1; gp("A2 jittered beat STILL rhythmic OK\n" as *u8) } else { gp("A2 *** BREAK: real beat missed under jitter\n" as *u8) } 48 49 // A3 QUIET-NOT-ACTIVE: an all-low clip (one big dead-air span) -> classify must NOT be active(1)/rhythmic(2). 50 mt[0] = 1; ms[0] = 0; me[0] = 18000 51 var a3l: i64 = ts_classify(mt, ms, me, 1, 20000, cl) 52 if a3l != 1 { if a3l != 2 { pass = pass + 1; gp("A3 quiet NOT active/rhythmic OK (label=" as *u8); gn(a3l); gp(")\n" as *u8) } } 53 if a3l == 1 { gp("A3 *** BREAK: quiet -> active\n" as *u8) } 54 if a3l == 2 { gp("A3 *** BREAK: quiet -> rhythmic\n" as *u8) } 55 56 // A4 SINGLE-SPIKE-NOT-SCENEHEAVY: ONE scene cut in a 60s clip -> density 1/min < 12 threshold -> NOT label 3. 57 mt[0] = 2; ms[0] = 30000; me[0] = 30500 58 var a4l: i64 = ts_classify(mt, ms, me, 1, 60000, cl) 59 if a4l != 3 { pass = pass + 1; gp("A4 single cut NOT scene-heavy OK (label=" as *u8); gn(a4l); gp(")\n" as *u8) } else { gp("A4 *** BREAK: one cut -> scene-heavy\n" as *u8) } 60 61 // A5 DISCRIMINATION: rhythmic clip -> 2 AND active-noisy clip -> not 2. The ruler must SEPARATE them. 62 // rhythmic: dominated by a type-4 span. active-noisy: dominated by type-3 (motion) span, NO rhythm. 63 mt[0] = 4; ms[0] = 0; me[0] = 12000 64 var r_lbl: i64 = ts_classify(mt, ms, me, 1, 20000, cl) 65 mt[0] = 3; ms[0] = 0; me[0] = 15000 66 var a_lbl: i64 = ts_classify(mt, ms, me, 1, 20000, cl) 67 if r_lbl == 2 { if a_lbl != 2 { pass = pass + 1; gp("A5 ruler SEPARATES rhythmic(2) from active(" as *u8); gn(a_lbl); gp(") OK\n" as *u8) } } 68 if r_lbl != 2 { gp("A5 *** BREAK: rhythmic clip not labeled 2 (=" as *u8); gn(r_lbl); gp(")\n" as *u8) } 69 if r_lbl == 2 { if a_lbl == 2 { gp("A5 *** BREAK: active clip ALSO labeled rhythmic (ruler cannot separate)\n" as *u8) } } 70 71 gp("VIDCLASS-ADVERSARY pass=" as *u8); gn(pass); gp("/5\n" as *u8) 72 if pass == 5 { gp("VIDCLASS-ADVERSARY GREEN 5/5 (ruler survives: noise-reject, jitter-survive, no-false-positive, density-holds, SEPARATES)\n" as *u8); sys_exit(0) } 73 gp("VIDCLASS-ADVERSARY RED (a red-team attack BROKE the ruler -> harden before trusting)\n" as *u8) 74 sys_exit(1) 75 return 0 76}