code wiki / (root) / nx_gatherer.nx

nx_gatherer.nx source

↩ module page · 296 lines · 10215 B

1// nx_gatherer.nx -- inward-axis compounding primitive. 2// 3// Per [[feedback-hunter-gatherer-meta-primitives-outward-inward-axes]] 4// CARDINAL: "nx_gatherer (inward — iteratively compound substrate ROI 5// like farmer compounds land/crops/animals/machinery)." 6// 7// THE FARMER PRIMITIVE per user 2026-05-17: "gathering as the 8// iterative process that the farmer does of improving their land 9// and crops and animals and machinery to get a higher and higher 10// roi." Gatherer is the INWARD arm: every session adds yield to 11// substrate fields (new primitive shipped, smoke coverage axis +1, 12// ms saved on a hot path, false-positive eliminated). Yields 13// accumulate across sessions like compound interest on land. 14// 15// Composes: 16// nx_hunter -- outward-axis dual; gatherer+hunter together 17// form the session-audit gate 18// nx_gather_journal -- append-only event log of yields 19// nx_metabolism -- ms-saved yields measured against per-site 20// cycle counts 21// nx_palette -- bytes-shaved yields measured against pre/post 22// packing densities 23// nx_pamp / nx_pamp_meta -- false-positive-eliminated yields 24// measured against pre/post detection rates 25// 26// V1 ships: 27// - sealed enum NxGatherFieldKind (5 from cardinal: 28// PRIMITIVE / ISA / SMOKE / METRIC / COMPOST) 29// - sealed enum NxGatherYieldKind (4 from cardinal: 30// MS_SAVED / BYTES_SHAVED / FALSE_POSITIVE_ELIMINATED / COVERAGE_AXIS_PLUS_ONE) 31// - struct NxGatherField + NxGatherer container 32// - sow_field/harvest_yield verbs 33// - cumulative-yield queries (sum across the fields tilled) 34// 35// Gap list (V1 honest perf verdict): 36// - per-season rotation (weekly/monthly/quarterly fallow review) 37// queued -- V1 is one continuous season 38// - compost recycling (prior-arc knowledge informing current) 39// is a tag/kind in V1; deeper compose with archived hunts 40// is V2 (nx_gather_compost specialized primitive) 41// - no per-field decay model (sown fields don't auto-archive) 42// 43// genealogy_id: cardinal_2026-05-17_hunter_gatherer_meta_primitives + 44// regenerative_agriculture_compound_interest 45// lineage_id: substrate_gatherer_v1 46// 47// nx_safety_envelope: 48// intended_use: "Inward-axis compounding of substrate yield; 49// farmer-discipline ROI accumulation across 50// sessions" 51// sil_target: SIL1 52// evidence: [append_only_field_log, 53// cumulative_yield_observable] 54// verdict: NOT_YET_EVALUATED 55 56import "nx_syscalls.nx" 57import "nx_tier.nx" 58 59// ===== Sealed enum: NxGatherFieldKind ============================= 60 61const NX_GFK_PRIMITIVE: nx_int = 0 // new substrate primitive shipped 62const NX_GFK_ISA: nx_int = 1 // new ISA backend / codegen target 63const NX_GFK_SMOKE: nx_int = 2 // new smoke test added 64const NX_GFK_METRIC: nx_int = 3 // new measurable metric exposed 65const NX_GFK_COMPOST: nx_int = 4 // prior-arc knowledge applied here 66const NX_GFK_N_KINDS: nx_int = 5 67 68// ===== Sealed enum: NxGatherYieldKind ============================= 69 70const NX_GYK_MS_SAVED: nx_int = 0 71const NX_GYK_BYTES_SHAVED: nx_int = 1 72const NX_GYK_FALSE_POSITIVE_ELIMINATED: nx_int = 2 73const NX_GYK_COVERAGE_AXIS_PLUS_ONE: nx_int = 3 74const NX_GYK_N_KINDS: nx_int = 4 75 76// ===== Sealed enum: NxGathererVerdict ============================= 77 78const NX_GATHERER_OK: nx_int = 0 79const NX_GATHERER_ERR_FULL: nx_int = 1 80const NX_GATHERER_ERR_BAD_KIND: nx_int = 2 81const NX_GATHERER_ERR_NOT_FOUND: nx_int = 3 82 83// ===== Struct: NxGatherField ====================================== 84 85struct NxGatherField { 86 field_id: nx_int, 87 kind: nx_int, 88 content_hash: nx_size, 89 yield_ms_saved: nx_size, 90 yield_bytes_shaved: nx_size, 91 yield_fp_eliminated: nx_int, 92 yield_coverage_delta: nx_int, 93 sown_us: nx_size, 94 last_harvest_us: nx_size, 95} 96 97// ===== Struct: NxGatherer ========================================= 98 99struct NxGatherer { 100 fields: *NxGatherField, 101 capacity: nx_size, 102 head: nx_size, 103 count: nx_size, 104} 105 106const NX_GATHER_FIELD_BYTES: nx_size = 72 107 108// ===== Validators ================================================ 109 110func nx_gfk_is_valid(k: nx_int) -> nx_int { 111 if k < 0 { return 0 } 112 if k >= NX_GFK_N_KINDS { return 0 } 113 return 1 114} 115 116func nx_gyk_is_valid(k: nx_int) -> nx_int { 117 if k < 0 { return 0 } 118 if k >= NX_GYK_N_KINDS { return 0 } 119 return 1 120} 121 122// ===== nx_gatherer_new ============================================ 123 124func nx_gatherer_new(capacity: nx_size) -> *NxGatherer { 125 let g: *NxGatherer = (sys_mmap(32)) as *NxGatherer 126 let bytes: nx_size = capacity * NX_GATHER_FIELD_BYTES 127 g.fields = (sys_mmap(bytes)) as *NxGatherField 128 g.capacity = capacity 129 g.head = 0 130 g.count = 0 131 return g 132} 133 134// ===== _gatherer_at =============================================== 135 136func _gatherer_at(g: *NxGatherer, idx: nx_size) -> *NxGatherField { 137 return (g.fields as i64 + (idx as i64) * NX_GATHER_FIELD_BYTES) as *NxGatherField 138} 139 140// ===== _gatherer_find ============================================= 141 142func _gatherer_find(g: *NxGatherer, field_id: nx_int) -> nx_int { 143 var i: nx_size = 0 144 while i < g.count { 145 let f: *NxGatherField = _gatherer_at(g, i) 146 if f.field_id == field_id { return i as i64 } 147 i = i + 1 148 } 149 return -1 150} 151 152// ===== nx_gatherer_sow ============================================ 153// 154// Begin tracking a new field. Returns the index, or -1 if full / 155// bad kind / duplicate. Yields start at zero and accumulate via 156// nx_gatherer_harvest. 157 158func nx_gatherer_sow(g: *NxGatherer, 159 field_id: nx_int, 160 kind: nx_int, 161 content_hash: nx_size, 162 now_us: nx_size) -> nx_int { 163 if nx_gfk_is_valid(kind) == 0 { return -1 } 164 if _gatherer_find(g, field_id) >= 0 { return -1 } 165 if g.count >= g.capacity { return -1 } 166 let f: *NxGatherField = _gatherer_at(g, g.head) 167 f.field_id = field_id 168 f.kind = kind 169 f.content_hash = content_hash 170 f.yield_ms_saved = 0 171 f.yield_bytes_shaved = 0 172 f.yield_fp_eliminated = 0 173 f.yield_coverage_delta = 0 174 f.sown_us = now_us 175 f.last_harvest_us = now_us 176 g.head = g.head + 1 177 if g.head >= g.capacity { g.head = 0 } 178 g.count = g.count + 1 179 return (g.count - 1) as i64 180} 181 182// ===== nx_gatherer_harvest ======================================== 183// 184// Add a yield to an existing field. yield_kind selects which yield 185// counter to bump; value is added (not assigned) so harvests 186// compound across sessions on the same field. 187 188func nx_gatherer_harvest(g: *NxGatherer, 189 field_id: nx_int, 190 yield_kind: nx_int, 191 value: nx_size, 192 now_us: nx_size) -> nx_int { 193 if nx_gyk_is_valid(yield_kind) == 0 { return NX_GATHERER_ERR_BAD_KIND } 194 let idx: nx_int = _gatherer_find(g, field_id) 195 if idx < 0 { return NX_GATHERER_ERR_NOT_FOUND } 196 let f: *NxGatherField = _gatherer_at(g, idx as nx_size) 197 if yield_kind == NX_GYK_MS_SAVED { 198 f.yield_ms_saved = f.yield_ms_saved + value 199 } 200 if yield_kind == NX_GYK_BYTES_SHAVED { 201 f.yield_bytes_shaved = f.yield_bytes_shaved + value 202 } 203 if yield_kind == NX_GYK_FALSE_POSITIVE_ELIMINATED { 204 f.yield_fp_eliminated = f.yield_fp_eliminated + (value as i64) 205 } 206 if yield_kind == NX_GYK_COVERAGE_AXIS_PLUS_ONE { 207 f.yield_coverage_delta = f.yield_coverage_delta + (value as i64) 208 } 209 f.last_harvest_us = now_us 210 return NX_GATHERER_OK 211} 212 213// ===== nx_gatherer_total_ms_saved ================================= 214// 215// Sum yield_ms_saved across all fields. The farmer compound result: 216// total ms saved across the substrate's lifetime. 217 218func nx_gatherer_total_ms_saved(g: *NxGatherer) -> nx_size { 219 var total: nx_size = 0 220 var i: nx_size = 0 221 while i < g.count { 222 let f: *NxGatherField = _gatherer_at(g, i) 223 total = total + f.yield_ms_saved 224 i = i + 1 225 } 226 return total 227} 228 229// ===== nx_gatherer_total_bytes_shaved ============================= 230 231func nx_gatherer_total_bytes_shaved(g: *NxGatherer) -> nx_size { 232 var total: nx_size = 0 233 var i: nx_size = 0 234 while i < g.count { 235 let f: *NxGatherField = _gatherer_at(g, i) 236 total = total + f.yield_bytes_shaved 237 i = i + 1 238 } 239 return total 240} 241 242// ===== nx_gatherer_total_fp_eliminated ============================ 243 244func nx_gatherer_total_fp_eliminated(g: *NxGatherer) -> nx_int { 245 var total: nx_int = 0 246 var i: nx_size = 0 247 while i < g.count { 248 let f: *NxGatherField = _gatherer_at(g, i) 249 total = total + f.yield_fp_eliminated 250 i = i + 1 251 } 252 return total 253} 254 255// ===== nx_gatherer_total_coverage_delta =========================== 256 257func nx_gatherer_total_coverage_delta(g: *NxGatherer) -> nx_int { 258 var total: nx_int = 0 259 var i: nx_size = 0 260 while i < g.count { 261 let f: *NxGatherField = _gatherer_at(g, i) 262 total = total + f.yield_coverage_delta 263 i = i + 1 264 } 265 return total 266} 267 268// ===== nx_gatherer_count_by_kind ================================== 269 270func nx_gatherer_count_by_kind(g: *NxGatherer, kind: nx_int) -> nx_int { 271 var hits: nx_int = 0 272 var i: nx_size = 0 273 while i < g.count { 274 let f: *NxGatherField = _gatherer_at(g, i) 275 if f.kind == kind { hits = hits + 1 } 276 i = i + 1 277 } 278 return hits 279} 280 281// ===== nx_gatherer_count ========================================== 282 283func nx_gatherer_count(g: *NxGatherer) -> nx_size { 284 return g.count 285} 286 287// ===== nx_gatherer_session_emitted ================================ 288// 289// Predicate: did at least one gather event occur in this gatherer? 290// True if any field has been sown. Used by the session-audit gate 291// to confirm gather_count >= 1. 292 293func nx_gatherer_session_emitted(g: *NxGatherer) -> nx_int { 294 if g.count > 0 { return 1 } 295 return 0 296}