code wiki / (root) / nx_acquire.nx

nx_acquire.nx source

↩ module page · 190 lines · 8955 B

1// nx_acquire.nx -- THE LIBRARIAN'S SHELF. Reads knowledge/acquire_sources.conf and answers, for every 2// external work we know of, the only question that matters: WHAT MAY WE DO WITH IT? 3// 4// This is the organ that makes the other two live. nx_acquire_lib holds the DOOR (evidence gates 5// rights) and nx_licgate_lib holds the RIGHTS TABLE; until something drove them from real data they 6// were a correct decision nobody asked. A capability with no caller is an adoption gap, not a feature. 7// 8// ONE RIGHTS TABLE. The licence columns come from knowledge/model_license.conf via lg_find_license -- 9// the same table, the same encoding, the same fail-closed semantics the shippability verdict uses. 10// A second table keyed differently for "code" versus "models" is how two answers for one licence get 11// created, and the estate already measured FIVE non-communicating licence taxonomies. 12// 13// FAIL-CLOSED AT EVERY UNKNOWN: a malformed evidence word, an unparseable row, or a licence id absent 14// from the rights table all degrade toward REVIEW and never toward permission. Silence is never 15// permission, and "I could not read the row" must never arrive in the same word as "you may". 16// license_tier: ORIGINAL 17import "nx_syscalls.nx" 18import "nx_licgate_lib.nx" 19import "nx_acquire_lib.nx" 20 21const AQX_FCAP: i64 = 512 22const AQX_TAB: i64 = 9 23const AQX_NL: i64 = 10 24const AQX_HASH: i64 = 35 25const AQX_A: i64 = 65 26const AQX_L: i64 = 76 27const AQX_NUMCAP: i64 = 32 28 29func aqx_puts(s: *u8) -> i64 { sys_write(1, s, lg_len(s)); return 0 } 30 31func aqx_num(v: i64) -> i64 { 32 let t: *u8 = sys_mmap(AQX_NUMCAP) 33 var m: i64 = v 34 var k: i64 = 0 35 if m == 0 { t[0] = 48 as u8; k = 1 } 36 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 37 let o: *u8 = sys_mmap(AQX_NUMCAP) 38 var i: i64 = 0 39 while i < k { o[i] = t[k - 1 - i]; i = i + 1 } 40 sys_write(1, o, k) 41 sys_munmap(t, AQX_NUMCAP) 42 sys_munmap(o, AQX_NUMCAP) 43 return 0 44} 45 46// copy TAB-field idx of the row [s,e) into out, NUL-terminated. Returns its length, or -1 when the row 47// has fewer fields -- which the caller must treat as a MALFORMED ROW and never as an empty value. 48func aqx_fieldz(buf: *u8, s: i64, e: i64, idx: i64, out: *u8, cap: i64) -> i64 { 49 let box: *i64 = sys_mmap(32) as *i64 50 lg_field(buf, s, e, idx, box) 51 let off: i64 = box[0] 52 let ln: i64 = box[1] 53 if ln < 0 { out[0] = 0 as u8; return 0 - 1 } 54 if off < 0 { out[0] = 0 as u8; return 0 - 1 } 55 var i: i64 = 0 56 while i < ln { 57 if i < cap - 1 { out[i] = buf[off + i] } 58 i = i + 1 59 } 60 var w: i64 = ln 61 if w > cap - 1 { w = cap - 1 } 62 out[w] = 0 as u8 63 return w 64} 65 66func aqx_pad(s: *u8, width: i64) -> i64 { 67 aqx_puts(s) 68 var n: i64 = lg_len(s) 69 while n < width { aqx_puts(" " as *u8); n = n + 1 } 70 return 0 71} 72 73func main(argc: i64, argv: *i64) -> i64 { 74 let lp: *i64 = sys_mmap(16) as *i64 75 let buf: *u8 = sys_read_file("knowledge/acquire_sources.conf" as *u8, lp) 76 if (buf as i64) == 0 { 77 aqx_puts("REFUSED cannot-read knowledge/acquire_sources.conf -- no shelf is printed for a registry we do not hold\n" as *u8) 78 return 4 79 } 80 let n: i64 = lp[0] 81 let ctx: *i64 = lg_ctx() 82 if ctx[3] < 0 { 83 aqx_puts("REFUSED rights-table-unreadable (knowledge/model_license.conf) -- every verdict would be a guess\n" as *u8) 84 return 4 85 } 86 87 aqx_puts("=== NX-ACQUIRE SHELF -- what may we do with each external work we hold a record of ===\n" as *u8) 88 aqx_puts(" evidence: NONE no licence seen | DECLARED asserted upstream, unread | READ we hold and read the text\n" as *u8) 89 aqx_puts(" rights: YES granted | REVIEW a human must settle it, NOT a pass | NO refused\n\n" as *u8) 90 91 let fid: *u8 = sys_mmap(AQX_FCAP) 92 let fev: *u8 = sys_mmap(AQX_FCAP) 93 let flic: *u8 = sys_mmap(AQX_FCAP) 94 let res: *i64 = aq_res() 95 96 var rows: i64 = 0 97 var n_clear: i64 = 0 98 var n_review: i64 = 0 99 var n_refuse: i64 = 0 100 var n_malformed: i64 = 0 101 var n_licrows: i64 = 0 102 var n_read: i64 = 0 103 104 var p: i64 = 0 105 while p < n { 106 var q: i64 = p 107 var scan: i64 = 1 108 while scan == 1 { 109 if q >= n { scan = 0 } 110 else { if buf[q] == (AQX_NL as u8) { scan = 0 } else { q = q + 1 } } 111 } 112 // a row is processed only when it starts with the type letter AND a TAB. A '#' comment, a 113 // blank line and a continuation all fall through untouched. 114 if q > p + 1 { 115 if buf[p + 1] == (AQX_TAB as u8) { 116 if buf[p] == (AQX_L as u8) { n_licrows = n_licrows + 1 } 117 if buf[p] == (AQX_A as u8) { 118 rows = rows + 1 119 let lid: i64 = aqx_fieldz(buf, p, q, 1, fid, AQX_FCAP) 120 let lev: i64 = aqx_fieldz(buf, p, q, 3, fev, AQX_FCAP) 121 let llc: i64 = aqx_fieldz(buf, p, q, 4, flic, AQX_FCAP) 122 var bad: i64 = 0 123 if lid < 0 { bad = 1 } 124 if lev < 0 { bad = 1 } 125 if llc < 0 { bad = 1 } 126 var ev: i64 = 0 - 1 127 if bad == 0 { ev = aq_ev_parse(fev) } 128 if ev < 0 { bad = 1 } 129 if bad == 1 { 130 n_malformed = n_malformed + 1 131 aqx_puts(" " as *u8) 132 aqx_pad(fid, 30) 133 aqx_puts("MALFORMED-ROW -- refused, not defaulted\n" as *u8) 134 } else { 135 if ev == AQ_EV_READ { n_read = n_read + 1 } 136 // A LICENCE ID ABSENT FROM THE RIGHTS TABLE CANNOT GRANT. Passing verified=0 137 // caps the verdict at REVIEW by the door's own rule, so an unknown licence and 138 // an unread one land in the same honest place instead of silently granting. 139 var redist: i64 = 0 140 var vfy: i64 = 0 141 var known: i64 = 0 142 let li: i64 = lg_find_license(ctx, flic) 143 if li >= 0 { 144 redist = lg_lic_redist(ctx, li) 145 vfy = lg_lic_verified(ctx, li) 146 known = 1 147 } 148 let rc: i64 = aq_decide(ev, redist, vfy, res) 149 if rc == AQ_RC_OK { n_clear = n_clear + 1 } 150 if rc == AQ_RC_REVIEW { n_review = n_review + 1 } 151 if rc == AQ_RC_REFUSE { n_refuse = n_refuse + 1 } 152 aqx_puts(" " as *u8) 153 aqx_pad(fid, 30) 154 aqx_puts("ev=" as *u8); aqx_pad(aq_ev_name(ev), 9) 155 // 32, not 24: a LicenseRef- id is legitimately long (the SPDX escape for a 156 // licence the List cannot name is prefix + vendor + name), and at 24 the 157 // column ran into the next field. Sized from the longest id the rights table 158 // actually holds, not from what looked tidy on the first row. 159 aqx_puts("lic=" as *u8); aqx_pad(flic, 32) 160 if known == 0 { aqx_puts("[not-in-rights-table] " as *u8) } 161 aqx_puts("mirror=" as *u8); aqx_pad(aq_right_name(res[AQ_R_MIRROR]), 7) 162 aqx_puts("redist=" as *u8); aqx_pad(aq_right_name(res[AQ_R_REDIST]), 7) 163 aqx_puts("learn=" as *u8); aqx_pad(aq_right_name(res[AQ_R_LEARN]), 5) 164 aqx_puts("attrib=" as *u8); aqx_pad(aq_right_name(res[AQ_R_ATTRIB]), 5) 165 aqx_puts("=> " as *u8); aqx_puts(aq_rc_name(rc)) 166 aqx_puts("\n" as *u8) 167 } 168 } 169 } 170 } 171 p = q + 1 172 } 173 174 // THE PARTITION MUST SUM AND THE SUM IS PRINTED. A residual nobody can reconcile is a leak, and a 175 // shelf that quietly drops a row is worse than one that refuses. 176 let sum: i64 = n_clear + n_review + n_refuse + n_malformed 177 aqx_puts("\nrows=" as *u8); aqx_num(rows) 178 aqx_puts(" clear=" as *u8); aqx_num(n_clear) 179 aqx_puts(" review=" as *u8); aqx_num(n_review) 180 aqx_puts(" refuse=" as *u8); aqx_num(n_refuse) 181 aqx_puts(" malformed=" as *u8); aqx_num(n_malformed) 182 aqx_puts(" sum=" as *u8); aqx_num(sum) 183 if sum == rows { aqx_puts(" partition=RECONCILES" as *u8) } else { aqx_puts(" partition=LEAK" as *u8) } 184 aqx_puts("\nlicence-evidence rows held (L)=" as *u8); aqx_num(n_licrows) 185 aqx_puts(" artifacts at evidence=READ=" as *u8); aqx_num(n_read) 186 aqx_puts("\n\nREVIEW IS NOT A PASS. Only YES permits. The work that clears a REVIEW is reading a licence:\n" as *u8) 187 aqx_puts(" nx_acquire_license derive <repo-url> -> fetch it -> pin it -> write an L row.\n" as *u8) 188 if sum != rows { return 1 } 189 return 0 190}