code wiki / (root) / nx_treaty.nx

nx_treaty.nx source

↩ module page · 283 lines · 11879 B

1// nx_treaty.nx -- bilateral cooperative resource agreement. 2// 3// THE PARTNERSHIP PRIMITIVE. Per user 2026-05-19: "partnering with 4// steam to improve things like vram usage, disk space usage." A 5// treaty is a declarative, breachable agreement between two parties 6// to share a contested resource on agreed terms. Parties may be: 7// - native cell + native cell (intra-Nishi negotiation) 8// - native cell + foreign symbiote (Nishi + Steam-hosted NMS) 9// - organism + symbiote (whole-Nishi-ecosystem + foreign-program) 10// 11// The structural EXCEED-axis vs OS-level resource limits (cgroups, 12// Job Objects, RLIMIT_AS): those are UNILATERAL ceilings imposed by 13// the host. A treaty is BILATERAL -- both parties consent to share 14// terms and either can renegotiate when conditions change. This is 15// the only structurally honest way to integrate a foreground game 16// with a foreground background-inference workload on the same RTX 17// 5080: they negotiate VRAM share dynamically, not fight over it. 18// 19// Composes: 20// nx_budget -- party budgets supply the negotiation basis 21// nx_attention_class -- treaty priority cap (treaty can only 22// require yield UP the priority hierarchy, 23// never down -- a foreground party can't 24// agree to yield to a background party) 25// nx_symbiote -- foreign-party state + observed consumption 26// nx_evict_journal -- proposals, acceptances, breaches logged 27// nx_organism -- container that holds N treaties across 28// all member pairs 29// 30// V1 ships pairwise treaties only. Multi-party treaties (e.g., 31// {organism, Steam-NMS, OBS-recorder} all agreeing to share 12 GB 32// VRAM with weights 60/30/10) are decomposable into pairwise treaties 33// for V1; a multi-party primitive is queued. 34// 35// Gap list (V1 honest perf verdict): 36// - bilateral only (multi-party decomposes) 37// - no expiration time (treaties last until breach or release) 38// - no automatic renegotiation when budgets change 39// - breach detection is observation-window only (caller invokes 40// nx_treaty_check_breach; no background monitor in V1) 41// 42// genealogy_id: international_treaty_law + biology_mutualism + 43// cardinal_2026-05-19_partnership_not_throttle 44// lineage_id: substrate_treaty_v1 45// 46// nx_safety_envelope: 47// intended_use: "Bilateral cooperative resource share 48// agreement between two ecosystem members" 49// sil_target: SIL2 50// evidence: [shares_sum_to_unity, breach_observable, 51// priority_axiom_enforced] 52// hazard_register: [bug-tape-treaty-priority-inversion, 53// bug-tape-treaty-stale-after-budget-change] 54// verdict: NOT_YET_EVALUATED 55 56import "nx_syscalls.nx" 57import "nx_tier.nx" 58import "nx_budget.nx" 59import "nx_attention_class.nx" 60import "nx_evict_journal.nx" 61const NX_MAGIC_1024: i64 = 1024 62 63// ===== Sealed enum: NxTreatyState ================================ 64 65const NX_TR_PROPOSED: nx_int = 0 // a proposed; b has not accepted 66const NX_TR_ACTIVE: nx_int = 1 // both parties agreed; in force 67const NX_TR_BREACHED: nx_int = 2 // one party violated; need renegotiate 68const NX_TR_RELEASED: nx_int = 3 // mutually dissolved 69const NX_TR_N_STATES: nx_int = 4 70 71// ===== Sealed enum: NxTreatyVerdict ============================== 72 73const NX_TREATY_OK: nx_int = 0 74const NX_TREATY_ERR_PRIORITY_INVERT: nx_int = 1 // can't agree to yield down-priority 75const NX_TREATY_ERR_NOT_PROPOSED: nx_int = 2 76const NX_TREATY_ERR_NOT_ACTIVE: nx_int = 3 77const NX_TREATY_ERR_SHARES_INVALID: nx_int = 4 // a + b != 1024 (Q10 unity) 78const NX_TREATY_ERR_BREACHED: nx_int = 5 79const NX_TREATY_ERR_RELEASED: nx_int = 6 80 81// ===== Struct: NxTreaty ========================================== 82// 83// a_id / b_id are cell_id or pid (caller-defined, just for forensics). 84// a_class / b_class are NxAttentionClass values. ram_share_a_q10 and 85// vram_share_a_q10 are Q10 fractions; b's shares = 1024 - a's. 86// 87// breach_at_overshoot_q10 is the threshold: if either party's 88// observed consumption exceeds their share by this margin, treaty 89// is BREACHED and arbiter must renegotiate. Q10 1024 = exact share; 90// Q10 1126 = 10% overshoot tolerance. 91 92struct NxTreaty { 93 treaty_id: nx_int, 94 a_id: nx_int, 95 a_class: nx_int, 96 b_id: nx_int, 97 b_class: nx_int, 98 ram_share_a_q10: nx_int, 99 vram_share_a_q10: nx_int, 100 breach_at_overshoot_q10: nx_int, 101 state: nx_int, 102 breach_count: nx_int, 103 last_state_change_us: nx_size, 104} 105 106// Default 10% overshoot tolerance before declaring breach. 107const NX_TREATY_DEFAULT_BREACH_Q10: nx_int = 1126 108 109// ===== nx_tr_state_is_valid ===================================== 110 111func nx_tr_state_is_valid(s: nx_int) -> nx_int { 112 if s < 0 { return 0 } 113 if s >= NX_TR_N_STATES { return 0 } 114 return 1 115} 116 117// ===== nx_treaty_propose ========================================= 118// 119// Party A proposes terms. Returns OK or one of the err verdicts. 120// Priority axiom: A cannot propose to yield priority DOWN the 121// hierarchy -- e.g., foreground game cannot agree to surrender VRAM 122// to a background inference cell. That would be priority inversion. 123// Treaties either share equal-priority resources or yield UP only. 124 125func nx_treaty_propose(treaty_id: nx_int, 126 a_id: nx_int, a_class: nx_int, 127 b_id: nx_int, b_class: nx_int, 128 ram_share_a_q10: nx_int, 129 vram_share_a_q10: nx_int, 130 now_us: nx_size) -> *NxTreaty { 131 // Priority axiom check 132 let a_prio: nx_int = nx_ac_priority(a_class) 133 let b_prio: nx_int = nx_ac_priority(b_class) 134 // a is HIGHER priority (lower numeric) than b -- agreeing to a 135 // share where b gets MORE than a would be priority inversion. 136 // ram_share_a < 512 means a gets less than half. 137 if a_prio < b_prio { 138 if ram_share_a_q10 < 512 { return (0 as i64) as *NxTreaty } 139 if vram_share_a_q10 < 512 { return (0 as i64) as *NxTreaty } 140 } 141 if ram_share_a_q10 < 0 { return (0 as i64) as *NxTreaty } 142 if ram_share_a_q10 > NX_MAGIC_1024 { return (0 as i64) as *NxTreaty } 143 if vram_share_a_q10 < 0 { return (0 as i64) as *NxTreaty } 144 if vram_share_a_q10 > NX_MAGIC_1024 { return (0 as i64) as *NxTreaty } 145 146 let t: *NxTreaty = (sys_mmap(88)) as *NxTreaty 147 t.treaty_id = treaty_id 148 t.a_id = a_id 149 t.a_class = a_class 150 t.b_id = b_id 151 t.b_class = b_class 152 t.ram_share_a_q10 = ram_share_a_q10 153 t.vram_share_a_q10 = vram_share_a_q10 154 t.breach_at_overshoot_q10 = NX_TREATY_DEFAULT_BREACH_Q10 155 t.state = NX_TR_PROPOSED 156 t.breach_count = 0 157 t.last_state_change_us = now_us 158 return t 159} 160 161// ===== nx_treaty_accept ========================================== 162// 163// Party B accepts the proposal. Transitions PROPOSED -> ACTIVE. 164 165func nx_treaty_accept(t: *NxTreaty, now_us: nx_size) -> nx_int { 166 if t.state != NX_TR_PROPOSED { return NX_TREATY_ERR_NOT_PROPOSED } 167 t.state = NX_TR_ACTIVE 168 t.last_state_change_us = now_us 169 return NX_TREATY_OK 170} 171 172// ===== nx_treaty_party_share_q10 ================================= 173// 174// Returns the share fraction owed to the given party_id for the 175// given resource kind. Returns -1 if party_id is not in the treaty. 176 177func nx_treaty_party_share_q10(t: *NxTreaty, party_id: nx_int, kind: nx_int) -> nx_int { 178 if t.state != NX_TR_ACTIVE { return -1 } 179 if party_id == t.a_id { 180 if kind == NX_RES_RAM { return t.ram_share_a_q10 } 181 if kind == NX_RES_VRAM { return t.vram_share_a_q10 } 182 return -1 183 } 184 if party_id == t.b_id { 185 if kind == NX_RES_RAM { return NX_MAGIC_1024 - t.ram_share_a_q10 } 186 if kind == NX_RES_VRAM { return NX_MAGIC_1024 - t.vram_share_a_q10 } 187 return -1 188 } 189 return -1 190} 191 192// ===== nx_treaty_check_breach ==================================== 193// 194// Given the contested pool size and each party's observed consumption, 195// returns 1 if either party has exceeded its share by more than the 196// breach threshold; otherwise 0. State auto-transitions to BREACHED 197// when breach is detected. breach_count increments on each detected 198// breach so the integration layer can spot persistent violators. 199 200func nx_treaty_check_breach(t: *NxTreaty, 201 pool_bytes: nx_size, 202 a_observed: nx_size, 203 b_observed: nx_size, 204 kind: nx_int, 205 now_us: nx_size) -> nx_int { 206 if t.state != NX_TR_ACTIVE { return 0 } 207 if pool_bytes <= 0 { return 0 } 208 209 // Compute each party's quota in bytes. 210 var a_share: nx_int = 0 211 if kind == NX_RES_RAM { a_share = t.ram_share_a_q10 } 212 if kind == NX_RES_VRAM { a_share = t.vram_share_a_q10 } 213 let b_share: nx_int = NX_MAGIC_1024 - a_share 214 let a_quota_bytes: nx_size = ((pool_bytes as i64) * a_share / NX_MAGIC_1024) as nx_size 215 let b_quota_bytes: nx_size = ((pool_bytes as i64) * b_share / NX_MAGIC_1024) as nx_size 216 217 // Compute overshoot Q10 for each party. 218 var a_over: nx_int = 0 219 var b_over: nx_int = 0 220 if a_quota_bytes > 0 { 221 a_over = ((a_observed as i64) * NX_MAGIC_1024) / (a_quota_bytes as i64) 222 } 223 if b_quota_bytes > 0 { 224 b_over = ((b_observed as i64) * NX_MAGIC_1024) / (b_quota_bytes as i64) 225 } 226 if a_over > t.breach_at_overshoot_q10 { 227 t.state = NX_TR_BREACHED 228 t.breach_count = t.breach_count + 1 229 t.last_state_change_us = now_us 230 return 1 231 } 232 if b_over > t.breach_at_overshoot_q10 { 233 t.state = NX_TR_BREACHED 234 t.breach_count = t.breach_count + 1 235 t.last_state_change_us = now_us 236 return 1 237 } 238 return 0 239} 240 241// ===== nx_treaty_release ========================================= 242// 243// Mutual dissolution. Either party may invoke; sets state to RELEASED. 244// A released treaty stays in the journal for forensics but does not 245// govern resource allocation. 246 247func nx_treaty_release(t: *NxTreaty, now_us: nx_size) -> nx_int { 248 if t.state == NX_TR_RELEASED { return NX_TREATY_OK } 249 t.state = NX_TR_RELEASED 250 t.last_state_change_us = now_us 251 return NX_TREATY_OK 252} 253 254// ===== nx_treaty_renegotiate_shares ============================== 255// 256// Caller updates the share Q10 values mid-treaty (e.g., NMS texture 257// quality dropped from Ultra to High so it asks for less VRAM; our 258// inference cell can now have a bigger share). Resets state to 259// PROPOSED so the counterparty must re-accept; the breach_count is 260// preserved so persistent breachers don't escape via renegotiation. 261 262func nx_treaty_renegotiate_shares(t: *NxTreaty, 263 ram_share_a_q10: nx_int, 264 vram_share_a_q10: nx_int, 265 now_us: nx_size) -> nx_int { 266 if t.state == NX_TR_RELEASED { return NX_TREATY_ERR_RELEASED } 267 if ram_share_a_q10 < 0 { return NX_TREATY_ERR_SHARES_INVALID } 268 if ram_share_a_q10 > NX_MAGIC_1024 { return NX_TREATY_ERR_SHARES_INVALID } 269 if vram_share_a_q10 < 0 { return NX_TREATY_ERR_SHARES_INVALID } 270 if vram_share_a_q10 > NX_MAGIC_1024 { return NX_TREATY_ERR_SHARES_INVALID } 271 t.ram_share_a_q10 = ram_share_a_q10 272 t.vram_share_a_q10 = vram_share_a_q10 273 t.state = NX_TR_PROPOSED 274 t.last_state_change_us = now_us 275 return NX_TREATY_OK 276} 277 278// ===== nx_treaty_is_active ======================================= 279 280func nx_treaty_is_active(t: *NxTreaty) -> nx_int { 281 if t.state == NX_TR_ACTIVE { return 1 } 282 return 0 283}