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}