code wiki / (root) / nx_hunt_evidence.nx

nx_hunt_evidence.nx source

↩ module page · 117 lines · 3930 B

1// nx_hunt_evidence.nx -- content-addressed kill receipts. 2// 3// Per [[feedback-hunter-gatherer-meta-primitives-outward-inward-axes]]: 4// "nx_hunt_evidence (content-addressed per 5// [[feedback-end-to-end-bit-traceability-architecture]])." When 6// nx_hunter records a KILL, the evidence backing the kill (e.g., 7// the bug-fix commit hash, the EXCEED-axis benchmark output, the 8// threat-hardening test fixture, the cardinal-text absorbed) is 9// captured as a content-addressed receipt so the kill can be audited 10// later. 11// 12// Composes: 13// nx_hunter -- kills point to evidence rows 14// nx_provenance_chain -- evidence rows chain-link 15// nx_methyl -- each evidence row signed 16// nx_pollinate -- evidence shareable with community 17 18import "nx_syscalls.nx" 19import "nx_tier.nx" 20import "nx_hunter.nx" 21 22const NX_HEV_OK: nx_int = 0 23const NX_HEV_ERR_FULL: nx_int = 1 24const NX_HEV_ERR_NOT_FOUND: nx_int = 2 25 26// ===== Sealed enum: NxEvidenceKind ================================= 27 28const NX_EK_COMMIT_HASH: nx_int = 0 // bug-fix commit 29const NX_EK_BENCHMARK_OUTPUT: nx_int = 1 // EXCEED-axis measurement 30const NX_EK_TEST_FIXTURE: nx_int = 2 // threat-hardening test 31const NX_EK_CARDINAL_TEXT: nx_int = 3 // cardinal absorbed 32const NX_EK_FORENSIC_RECORD: nx_int = 4 // signed xenocell observation 33const NX_EK_N_KINDS: nx_int = 5 34 35// ===== Struct: NxHuntEvidence ====================================== 36 37struct NxHuntEvidence { 38 evidence_id: nx_int, 39 target_id: nx_int, // points to NxHuntTarget 40 kind: nx_int, 41 content_hash: nx_size, 42 captured_us: nx_size, 43 kill_pillar: nx_int, // mirrors target.kill_pillar 44} 45 46struct NxHuntEvidenceLog { 47 rows: *NxHuntEvidence, 48 capacity: nx_size, 49 count: nx_size, 50} 51 52const NX_HEV_ROW_BYTES: nx_size = 40 53 54func nx_ek_is_valid(k: nx_int) -> nx_int { 55 if k < 0 { return 0 } 56 if k >= NX_EK_N_KINDS { return 0 } 57 return 1 58} 59 60func nx_hunt_evidence_log_new(capacity: nx_size) -> *NxHuntEvidenceLog { 61 let l: *NxHuntEvidenceLog = (sys_mmap(24)) as *NxHuntEvidenceLog 62 let bytes: nx_size = capacity * NX_HEV_ROW_BYTES 63 l.rows = (sys_mmap(bytes)) as *NxHuntEvidence 64 l.capacity = capacity 65 l.count = 0 66 return l 67} 68 69func _hev_at(l: *NxHuntEvidenceLog, idx: nx_size) -> *NxHuntEvidence { 70 return (l.rows as i64 + (idx as i64) * NX_HEV_ROW_BYTES) as *NxHuntEvidence 71} 72 73func nx_hunt_evidence_record(l: *NxHuntEvidenceLog, 74 evidence_id: nx_int, 75 target_id: nx_int, 76 kind: nx_int, 77 content_hash: nx_size, 78 kill_pillar: nx_int, 79 now_us: nx_size) -> nx_int { 80 if nx_ek_is_valid(kind) == 0 { return NX_HEV_ERR_NOT_FOUND } 81 if l.count >= l.capacity { return NX_HEV_ERR_FULL } 82 let r: *NxHuntEvidence = _hev_at(l, l.count) 83 r.evidence_id = evidence_id 84 r.target_id = target_id 85 r.kind = kind 86 r.content_hash = content_hash 87 r.captured_us = now_us 88 r.kill_pillar = kill_pillar 89 l.count = l.count + 1 90 return NX_HEV_OK 91} 92 93func nx_hunt_evidence_count_for_target(l: *NxHuntEvidenceLog, target_id: nx_int) -> nx_int { 94 var hits: nx_int = 0 95 var i: nx_size = 0 96 while i < l.count { 97 let r: *NxHuntEvidence = _hev_at(l, i) 98 if r.target_id == target_id { hits = hits + 1 } 99 i = i + 1 100 } 101 return hits 102} 103 104func nx_hunt_evidence_count_by_kind(l: *NxHuntEvidenceLog, kind: nx_int) -> nx_int { 105 var hits: nx_int = 0 106 var i: nx_size = 0 107 while i < l.count { 108 let r: *NxHuntEvidence = _hev_at(l, i) 109 if r.kind == kind { hits = hits + 1 } 110 i = i + 1 111 } 112 return hits 113} 114 115func nx_hunt_evidence_count(l: *NxHuntEvidenceLog) -> nx_size { 116 return l.count 117}