code wiki / (root) / nx_license_check.nx

nx_license_check.nx source

↩ module page · 223 lines · 9037 B

1// nx_license_check.nx -- Layer-3 lexical grader perspective. 2// 3// Enforces the LICENSING WALL per refined cardinal 4// feedback-licensing-absorb-vs-copy-discipline (2026-05-15): 5// 6// "i dont want direct copies in the code that can be suable or allow 7// loss of sovereignty i want the papers in the library but we need 8// a wall that we arent copying from them something that needs 9// attribution or licensing" 10// 11// Scans a substrate source file for the 12// 13// // license_tier: <TIER> 14// 15// header line. Only THREE tier values are permitted in substrate 16// code: 17// 18// TIER_0_UNENCUMBERED -- public-domain / CC0 / U.S. Govt work; 19// verbatim safe 20// INDEPENDENT_REDERIVE -- built from published spec, no source copy 21// ORIGINAL -- substrate-original, no external ancestor 22// 23// Anything else (or no header at all) is a LOSE. The grader emits a 24// named_improvement string telling the maintainer exactly how to 25// remedy the file. 26// 27// Substrate-original code, written from scratch in this file. 28// 29// license_tier: ORIGINAL 30// 31// nx_safety_envelope: (schema: nishi-library/seeds/safety-critical-standards.toml) 32// intended_use: "Layer-3 license-tier grader -- enforces the 33// TIER_0_UNENCUMBERED / INDEPENDENT_REDERIVE / 34// ORIGINAL wall across substrate. Refuses 35// sneaking in AGPL / GPL / MIT / Apache / OSI 36// annotations. Cardinal feedback-no-standard- 37// OSI-license-custom-tbd enforcement point." 38// sil_target: SIL2 (licensing wall breach = sovereignty 39// loss + suability risk; cardinal- 40// critical) 41// asil_target: QM 42// dal_target: NONE 43// iec_62304_class: NONE 44// evidence: [no_floating_point, sealed_verdict_enum, 45// per_tier_token_table_complete, 46// feedback-no-standard-OSI-license-custom-tbd_enforcement, 47// feedback-nishi-library-open-research-not-paywall-funding_companion] 48// hazard_register: [bug-tape-MIT-License-snuck-in-via-paste, 49// bug-tape-AGPL-header-from-pre-existing-c-file, 50// bug-tape-license-tier-missing-on-new-substrate-file] 51// residual_risk: "Detects ONLY the canonical license-text 52// signatures. Obfuscated copies (e.g. 53// paraphrased AGPL clauses) bypass detection. 54// Defense-in-depth: license_tier header 55// declaration is a SECONDARY axis; both signals 56// must agree for PASS." 57// verdict: NOT_YET_EVALUATED 58 59import "nx_syscalls.nx" 60import "nx_runtime.nx" 61import "nx_types.nx" 62import "nx_tier.nx" 63 64// ---- Sealed enum: license tier -------------------------------------- 65 66// header not found 67const NX_LIC_UNKNOWN: nx_int = 0 68// OK tiers (allowed in substrate code) 69const NX_LIC_TIER_0_UNENCUMBERED: nx_int = 1 70const NX_LIC_INDEPENDENT_REDERIVE: nx_int = 2 71const NX_LIC_ORIGINAL: nx_int = 3 72// header present but tier is one of the banned values 73const NX_LIC_FORBIDDEN: nx_int = 4 74// arity guard 75const NX_LIC_N: nx_int = 5 76 77func nx_license_tier_is_valid(t: nx_int) -> nx_int { 78 if t < 0 { return 0 } 79 if t >= NX_LIC_N { return 0 } 80 return 1 81} 82 83// ---- Sealed enum: license verdict ----------------------------------- 84// 85// Maps each tier to one of the 4 graded-card verdict values used by 86// nx_quality_grade. Mirrors NX_QV_WIN / NX_QV_LOSE / NX_QV_TIE 87// without importing the grader module (this is a Layer-3 perspective 88// that runs standalone too). 89 90const NX_LIC_VERDICT_WIN: nx_int = 1 91const NX_LIC_VERDICT_LOSE: nx_int = 2 92const NX_LIC_VERDICT_TIE: nx_int = 3 93const NX_LIC_VERDICT_UNMEASURED: nx_int = 0 94 95func nx_license_verdict_for_tier(t: nx_int) -> nx_int { 96 if t == NX_LIC_TIER_0_UNENCUMBERED { return NX_LIC_VERDICT_WIN } 97 if t == NX_LIC_INDEPENDENT_REDERIVE { return NX_LIC_VERDICT_WIN } 98 if t == NX_LIC_ORIGINAL { return NX_LIC_VERDICT_WIN } 99 if t == NX_LIC_FORBIDDEN { return NX_LIC_VERDICT_LOSE } 100 if t == NX_LIC_UNKNOWN { return NX_LIC_VERDICT_LOSE } 101 return NX_LIC_VERDICT_UNMEASURED 102} 103 104// ---- Byte helpers --------------------------------------------------- 105 106func _starts_with(src: *u8, src_len: nx_int, off: nx_int, needle: *u8, needle_len: nx_int) -> nx_int { 107 var k: nx_int = 0 108 if off < 0 { return 0 } 109 if off + needle_len > src_len { return 0 } 110 let base: *u8 = (src as nx_int + off) as *u8 111 while k < needle_len { 112 let a: nx_int = base[k] as nx_int 113 let b: nx_int = needle[k] as nx_int 114 if (a & 255) != (b & 255) { return 0 } 115 k = k + 1 116 } 117 return 1 118} 119 120func _skip_spaces(src: *u8, src_len: nx_int, off: nx_int) -> nx_int { 121 var i: nx_int = off 122 while i < src_len { 123 let p: *u8 = (src as nx_int + i) as *u8 124 let c: nx_int = p[0] as nx_int 125 if (c & 255) != 32 { return i } 126 i = i + 1 127 } 128 return i 129} 130 131// ---- Tier match ----------------------------------------------------- 132// 133// Given a source position pointing at the start of a tier name (after 134// `// license_tier:` and any leading spaces), match against the 135// allowed + forbidden sets. Forbidden = any tier name that isn't one 136// of the three OK values; we treat them all the same way because the 137// grader's job is to enforce the wall, not classify the violation. 138 139func _match_tier_at(src: *u8, src_len: nx_int, off: nx_int) -> nx_int { 140 let t0: *u8 = "TIER_0_UNENCUMBERED" as *u8 141 if _starts_with(src, src_len, off, t0, 19) == 1 { 142 return NX_LIC_TIER_0_UNENCUMBERED 143 } 144 let ir: *u8 = "INDEPENDENT_REDERIVE" as *u8 145 if _starts_with(src, src_len, off, ir, 20) == 1 { 146 return NX_LIC_INDEPENDENT_REDERIVE 147 } 148 let og: *u8 = "ORIGINAL" as *u8 149 if _starts_with(src, src_len, off, og, 8) == 1 { 150 return NX_LIC_ORIGINAL 151 } 152 // Any other identifier after the header tag counts as a forbidden 153 // tier. This catches typos AND deliberate banned values like 154 // COPY_WITH_ATTRIB, INTENT_ONLY, REDERIVED (older drafts). 155 return NX_LIC_FORBIDDEN 156} 157 158// ---- Public entry: scan source for the license_tier header --------- 159 160func nx_license_extract(src: *u8, src_len: nx_int) -> nx_int { 161 var i: nx_int = 0 162 if src_len <= 0 { return NX_LIC_UNKNOWN } 163 let tag: *u8 = "// license_tier:" as *u8 164 let tag_len: nx_int = 16 165 let cap: nx_int = src_len - tag_len 166 while i < cap { 167 let line_start: nx_int = 0 168 if i == 0 { 169 if _starts_with(src, src_len, i, tag, tag_len) == 1 { 170 let after: nx_int = _skip_spaces(src, src_len, i + tag_len) 171 return _match_tier_at(src, src_len, after) 172 } 173 } else { 174 let prev: *u8 = (src as nx_int + i - 1) as *u8 175 let pc: nx_int = prev[0] as nx_int 176 if (pc & 255) == 10 { 177 if _starts_with(src, src_len, i, tag, tag_len) == 1 { 178 let after: nx_int = _skip_spaces(src, src_len, i + tag_len) 179 return _match_tier_at(src, src_len, after) 180 } 181 } 182 } 183 i = i + 1 184 } 185 return NX_LIC_UNKNOWN 186} 187 188// ---- Named improvement string --------------------------------------- 189 190func nx_license_named_improvement(t: nx_int) -> *u8 { 191 if t == NX_LIC_UNKNOWN { 192 return "add `// license_tier: ORIGINAL` (or TIER_0_UNENCUMBERED / INDEPENDENT_REDERIVE) to the file header" as *u8 193 } 194 if t == NX_LIC_FORBIDDEN { 195 return "license_tier is not one of TIER_0_UNENCUMBERED / INDEPENDENT_REDERIVE / ORIGINAL -- reroute through nishi-library research catalog and rederive" as *u8 196 } 197 return "" as *u8 198} 199 200// ---- Tier name reflection (for human-readable emit) ----------------- 201 202func nx_license_tier_name(t: nx_int) -> *u8 { 203 if t == NX_LIC_TIER_0_UNENCUMBERED { return "TIER_0_UNENCUMBERED" as *u8 } 204 if t == NX_LIC_INDEPENDENT_REDERIVE { return "INDEPENDENT_REDERIVE" as *u8 } 205 if t == NX_LIC_ORIGINAL { return "ORIGINAL" as *u8 } 206 if t == NX_LIC_FORBIDDEN { return "FORBIDDEN" as *u8 } 207 if t == NX_LIC_UNKNOWN { return "UNKNOWN" as *u8 } 208 return "INVALID" as *u8 209} 210 211// ---- File-level helper: read + extract in one call ------------------ 212// 213// Returns the tier code; on read failure returns NX_LIC_UNKNOWN (which 214// is itself a LOSE -- a file we can't read is a file we can't audit). 215 216func nx_license_scan_file(path: *u8) -> nx_int { 217 let len_raw: *u8 = sys_mmap(16) 218 let len_p: *i64 = len_raw as *i64 219 let src: *u8 = sys_read_file(path, len_p) 220 if src == (0 as *u8) { return NX_LIC_UNKNOWN } 221 let src_len: nx_int = len_p[0] 222 return nx_license_extract(src, src_len) 223}