code wiki / _hdl_build / nx_rom_provenance.nx

nx_rom_provenance.nx source

↩ module page · 117 lines · 5668 B

1// nx_rom_provenance.nx -- R0.2 the LEGAL-CONTAINMENT keystone for the ROM player. Data-driven, deny-by-default, 2// liar-kill provenance policy over knowledge/registry/rom_provenance.tsv. NOTHING is servable unless its row 3// PROVES a license. The whole /play area sits behind the login wall (R0.1); this decides WHICH titles may be 4// served at all. Mirrors nx_evolution_ladder's evidence-or-RED + nx_galx_authz's deny-by-default. license_tier: ORIGINAL 5// 6// rom_provenance.tsv columns (TAB-separated, one title per row, NO header): 7// id <TAB> title <TAB> machine <TAB> license <TAB> source <TAB> ownership <TAB> tier 8// license: pd | cc | freeware | owned | unknown tier: family | owner 9// POLICY (nx_rom_decide_buf): 10// pd/cc/freeware + source present -> ALLOW (free 3rd-party, license PROVEN by a real source) 11// pd/cc/freeware + source "-"/empty -> DENY_NOSRC (LIAR-KILL: a free claim with no evidence) 12// owned + ownership present + lawyer_ok==1 -> ALLOW (you own it AND legal review signed off) 13// owned (no proof OR lawyer_ok==0) -> DENY_OWNED (owned corpus stays DARK until the lawyer flips it) 14// unknown / not-listed -> DENY (deny-by-default, the safe floor) 15import "nx_syscalls.nx" 16 17const ROM_TSV: *u8 = "knowledge/registry/rom_provenance.tsv" 18const ROM_LAWYER_FLAG: *u8 = "knowledge/registry/rom_lawyer_ok.flag" 19 20const RD_ALLOW: i64 = 1 21const RD_DENY: i64 = 0 // unlisted / unknown license 22const RD_DENY_NOSRC: i64 = 2 // free license claimed but no source (liar-kill) 23const RD_DENY_OWNED: i64 = 3 // owned but not lawyer-cleared / no proof 24 25// set fs[0]=field start, fl[0]=field length for field `idx` (0-based) of line [ls,le). 1 if found, 0 if too few. 26func pv_field(buf: *u8, ls: i64, le: i64, idx: i64, fs: *i64, fl: *i64) -> i64 { 27 var cur: i64 = ls 28 var f: i64 = 0 29 while f < idx { 30 while cur < le { if buf[cur] == (9 as u8) { break } cur = cur + 1 } 31 if cur >= le { return 0 } 32 cur = cur + 1 33 f = f + 1 34 } 35 var e: i64 = cur 36 while e < le { if buf[e] == (9 as u8) { break } e = e + 1 } 37 fs[0] = cur 38 fl[0] = e - cur 39 return 1 40} 41 42// does buf[start..start+len) equal NUL-terminated s? 43func pv_streq(buf: *u8, start: i64, len: i64, s: *u8) -> i64 { 44 var slen: i64 = 0 45 while s[slen] != (0 as u8) { slen = slen + 1 } 46 if slen != len { return 0 } 47 var i: i64 = 0 48 while i < len { if buf[start + i] != s[i] { return 0 } i = i + 1 } 49 return 1 50} 51 52// a field is "absent" if empty or a lone "-". 53func pv_absent(buf: *u8, start: i64, len: i64) -> i64 { 54 if len == 0 { return 1 } 55 if len == 1 { if buf[start] == (45 as u8) { return 1 } } 56 return 0 57} 58 59// decide over an in-memory registry buffer. lawyer_ok is supplied by the caller (reads nx_rom_lawyer_ok()). 60func nx_rom_decide_buf(tsv: *u8, tlen: i64, key: *u8, lawyer_ok: i64) -> i64 { 61 let fs: *i64 = sys_mmap(8) as *i64 62 let fl: *i64 = sys_mmap(8) as *i64 63 let gs: *i64 = sys_mmap(8) as *i64 64 let gl: *i64 = sys_mmap(8) as *i64 65 var i: i64 = 0 66 var ls: i64 = 0 67 while i <= tlen { 68 var nl: i64 = 0 69 if i == tlen { nl = 1 } else { if tsv[i] == (10 as u8) { nl = 1 } } 70 if nl == 1 { 71 let le: i64 = i 72 if le > ls { 73 if pv_field(tsv, ls, le, 0, fs, fl) == 1 { 74 if pv_streq(tsv, fs[0], fl[0], key) == 1 { 75 // matched row: license=field3, source=field4, ownership=field5 76 if pv_field(tsv, ls, le, 3, fs, fl) == 0 { return RD_DENY } 77 let lic_s: i64 = fs[0] 78 let lic_l: i64 = fl[0] 79 var src_present: i64 = 0 80 if pv_field(tsv, ls, le, 4, gs, gl) == 1 { if pv_absent(tsv, gs[0], gl[0]) == 0 { src_present = 1 } } 81 var own_present: i64 = 0 82 if pv_field(tsv, ls, le, 5, gs, gl) == 1 { if pv_absent(tsv, gs[0], gl[0]) == 0 { own_present = 1 } } 83 if pv_streq(tsv, lic_s, lic_l, "pd" as *u8) == 1 { if src_present == 1 { return RD_ALLOW } return RD_DENY_NOSRC } 84 if pv_streq(tsv, lic_s, lic_l, "cc" as *u8) == 1 { if src_present == 1 { return RD_ALLOW } return RD_DENY_NOSRC } 85 if pv_streq(tsv, lic_s, lic_l, "freeware" as *u8) == 1 { if src_present == 1 { return RD_ALLOW } return RD_DENY_NOSRC } 86 if pv_streq(tsv, lic_s, lic_l, "owned" as *u8) == 1 { 87 if own_present == 1 { if lawyer_ok == 1 { return RD_ALLOW } } 88 return RD_DENY_OWNED 89 } 90 return RD_DENY 91 } 92 } 93 } 94 ls = i + 1 95 } 96 i = i + 1 97 } 98 return RD_DENY 99} 100 101// is the owned-corpus legal sign-off in place? Reads the flag file (created ONLY by the operator/lawyer review). 102// Absent -> 0 (owned corpus stays dark by default). NEVER created by the build. 103func nx_rom_lawyer_ok() -> i64 { 104 let box: *i64 = sys_mmap(16) as *i64 105 let d: *u8 = sys_read_file(ROM_LAWYER_FLAG, box) 106 if (d as i64) == 0 { return 0 } 107 if box[0] <= 0 { return 0 } 108 return 1 109} 110 111// production entry: read the registry from disk + decide. Fail-closed: no registry -> deny everything. 112func nx_rom_decide(key: *u8, lawyer_ok: i64) -> i64 { 113 let box: *i64 = sys_mmap(16) as *i64 114 let tsv: *u8 = sys_read_file(ROM_TSV, box) 115 if (tsv as i64) == 0 { return RD_DENY } 116 return nx_rom_decide_buf(tsv, box[0], key, lawyer_ok) 117}