nx_session_audit_compose_test.nx source
↩ module page · 133 lines · 6024 B
1// nx_session_audit_compose_test.nx -- meta-cardinal session loop.
2//
3// Per [[feedback-hunter-gatherer-meta-primitives-outward-inward-axes]]:
4// "every session emits both a hunt-log AND a gather-log entry or it's
5// a non-session." This demo simulates a valid session: 3 hunts + 3
6// gathers, all logged to journals, session-audit predicate fires
7// VALID, imbalance check passes. Bit-traceability composed in:
8// provenance chain captured + dumped to trace_log + merkle root
9// computed and verified.
10
11import "nx_syscalls.nx"
12import "nx_tier.nx"
13import "nx_methyl.nx"
14import "nx_hunter.nx"
15import "nx_gatherer.nx"
16import "nx_hunt_journal.nx"
17import "nx_gather_journal.nx"
18import "nx_provenance_chain.nx"
19import "nx_trace_log.nx"
20import "nx_trace_merkle.nx"
21
22func main() -> i64 {
23 let sig: *u8 = (sys_mmap(96)) as *u8
24 sig[0] = 7 as u8
25 let mark: *NxMethylMark = nx_methyl_new(7, 0xcafe, 1000, sig, 96)
26
27 // ===== Hunter side: 3 targets, 3 kills =========================
28 let h: *NxHunter = nx_hunter_new(16)
29 let hj: *NxHuntJournalRing = nx_hunt_journal_new(32)
30
31 // Hunt 1: bug fixed
32 nx_hunter_scout(h, 100, NX_HK_BUG_CLASS, 0xb01, 1000)
33 nx_hunt_journal_log(hj, 1000, 100, NX_HEV_SCOUTED,
34 NX_HK_BUG_CLASS, NX_KP_NONE)
35 nx_hunter_engage(h, 100, 1100)
36 nx_hunter_kill(h, 100, NX_KP_BUG_FIXED, 1200)
37 nx_hunt_journal_log(hj, 1200, 100, NX_HEV_KILLED,
38 NX_HK_BUG_CLASS, NX_KP_BUG_FIXED)
39
40 // Hunt 2: EXCEED axis shipped
41 nx_hunter_scout(h, 200, NX_HK_COMPETITOR_PRODUCT, 0xc02, 2000)
42 nx_hunter_kill(h, 200, NX_KP_EXCEED_AXIS_SHIPPED, 2100)
43 nx_hunt_journal_log(hj, 2100, 200, NX_HEV_KILLED,
44 NX_HK_COMPETITOR_PRODUCT, NX_KP_EXCEED_AXIS_SHIPPED)
45
46 // Hunt 3: cardinal absorbed
47 nx_hunter_scout(h, 300, NX_HK_USER_FEEDBACK, 0xf03, 3000)
48 nx_hunter_kill(h, 300, NX_KP_CARDINAL_ABSORBED, 3100)
49 nx_hunt_journal_log(hj, 3100, 300, NX_HEV_KILLED,
50 NX_HK_USER_FEEDBACK, NX_KP_CARDINAL_ABSORBED)
51
52 if nx_hunter_total_kills(h) != 3 { return 1 }
53 if nx_hunter_count_kills_by_pillar(h, NX_KP_BUG_FIXED) != 1 { return 2 }
54 if nx_hunter_count_kills_by_pillar(h, NX_KP_EXCEED_AXIS_SHIPPED) != 1 { return 3 }
55 if nx_hunter_count_kills_by_pillar(h, NX_KP_CARDINAL_ABSORBED) != 1 { return 4 }
56
57 // ===== Gatherer side: 3 fields, 3 yields =======================
58 let g: *NxGatherer = nx_gatherer_new(16)
59 let gj: *NxGatherJournalRing = nx_gather_journal_new(32)
60
61 // Gather 1: primitive shipped + 150ms saved
62 nx_gatherer_sow(g, 10, NX_GFK_PRIMITIVE, 0xa10, 1500)
63 nx_gather_journal_log(gj, 1500, 10, NX_GEV_SOWN,
64 NX_GFK_PRIMITIVE, NX_GYK_N_KINDS, 0)
65 nx_gatherer_harvest(g, 10, NX_GYK_MS_SAVED, 150, 1600)
66 nx_gather_journal_log(gj, 1600, 10, NX_GEV_HARVESTED,
67 NX_GFK_PRIMITIVE, NX_GYK_MS_SAVED, 150)
68
69 // Gather 2: smoke added + coverage +1
70 nx_gatherer_sow(g, 20, NX_GFK_SMOKE, 0xa20, 2500)
71 nx_gatherer_harvest(g, 20, NX_GYK_COVERAGE_AXIS_PLUS_ONE, 1, 2600)
72 nx_gather_journal_log(gj, 2600, 20, NX_GEV_HARVESTED,
73 NX_GFK_SMOKE, NX_GYK_COVERAGE_AXIS_PLUS_ONE, 1)
74
75 // Gather 3: metric exposed + 2048 bytes shaved
76 nx_gatherer_sow(g, 30, NX_GFK_METRIC, 0xa30, 3500)
77 nx_gatherer_harvest(g, 30, NX_GYK_BYTES_SHAVED, 2048, 3600)
78 nx_gather_journal_log(gj, 3600, 30, NX_GEV_HARVESTED,
79 NX_GFK_METRIC, NX_GYK_BYTES_SHAVED, 2048)
80
81 if nx_gatherer_total_ms_saved(g) != 150 { return 5 }
82 if nx_gatherer_total_bytes_shaved(g) != 2048 { return 6 }
83 if nx_gatherer_total_coverage_delta(g) != 1 { return 7 }
84
85 // ===== Session-audit gate fires VALID ==========================
86 if nx_session_audit_valid(hj, gj) != 1 { return 8 }
87
88 // ===== Imbalance check: ~balanced session ======================
89 // hunt journal events: 4 (1 scout + 1 kill for hunt 1, plus 1 kill each for 2,3)
90 // gather journal events: 4 (1 sown + 1 harvest for gather 1, plus 1 harvest each for 2, 3)
91 // ratio ~ 0.5 = Q10 512
92 let q10: nx_int = nx_session_imbalance_q10(hj, gj)
93 if q10 < 400 { return 9 }
94 if q10 > 600 { return 10 }
95 if nx_session_is_imbalanced(hj, gj) != 0 { return 11 }
96
97 // ===== Bit-traceability: provenance chain + log + merkle =======
98 let chain: *NxProvenanceChain = nx_provenance_chain_new(16)
99 nx_provenance_append(chain, NX_TX_CAPTURE, 0x100, 0xa01, 1000, 7, mark)
100 nx_provenance_append(chain, NX_TX_PREPROCESS, 0x200, 0xa02, 1100, 7, mark)
101 nx_provenance_append(chain, NX_TX_ENCODE, 0x300, 0xa03, 1200, 7, mark)
102 nx_provenance_append(chain, NX_TX_ENCRYPT, 0x400, 0xa04, 1300, 7, mark)
103 if chain.count != 4 { return 12 }
104 if nx_provenance_verify_continuity(chain) != NX_PV_OK { return 13 }
105
106 // Dump to persistent log
107 let log: *NxTraceLog = nx_trace_log_new(32)
108 nx_trace_log_append_from_chain(log, chain, 555)
109 if nx_trace_log_count_for_call(log, 555) != 4 { return 14 }
110
111 // Build merkle tree summarizing the trace range
112 let tree: *NxMerkleTree = nx_trace_merkle_build(log, 555, 0, 4)
113 if (tree as i64) == 0 { return 15 }
114 if nx_trace_merkle_root(tree) == 0 { return 16 }
115
116 // Verify all four output hashes are members
117 if nx_trace_merkle_verify_member(tree, 0xa01) != NX_MK_MEMBER { return 17 }
118 if nx_trace_merkle_verify_member(tree, 0xa02) != NX_MK_MEMBER { return 18 }
119 if nx_trace_merkle_verify_member(tree, 0xa03) != NX_MK_MEMBER { return 19 }
120 if nx_trace_merkle_verify_member(tree, 0xa04) != NX_MK_MEMBER { return 20 }
121 if nx_trace_merkle_verify_member(tree, 0xdead) != NX_MK_NOT_MEMBER { return 21 }
122
123 // Cross-host equivalent: same range -> same root
124 let tree2: *NxMerkleTree = nx_trace_merkle_build(log, 555, 0, 4)
125 if nx_trace_merkle_roots_equal(tree, tree2) != 1 { return 22 }
126
127 // ===== Forensic asserts: this was a valid + balanced session ===
128 if nx_hunter_session_emitted(h) != 1 { return 23 }
129 if nx_gatherer_session_emitted(g) != 1 { return 24 }
130 if nx_session_audit_valid(hj, gj) != 1 { return 25 }
131
132 return 0
133}