code wiki / (root) / nx_acquire_license_lib.nx

nx_acquire_license_lib.nx source

↩ module page · 153 lines · 6093 B

1// nx_acquire_license_lib.nx -- the LICENCE-URL DERIVATION as a LIBRARY. 2// 3// WHY A LIB, and it is the same unblock nx_licgate_lib records: an organ with main() CANNOT be 4// imported (double-main), so a gate over a CLI can only fork the deployed binary. That fork is a 5// boundary the mutation harness is blind across -- every mutant comes back NOT-REACHED and the gate 6// returns a clean GREEN that reads exactly like a proof while proving nothing. Splitting the pure 7// core out is what makes the logic mutation-testable at all. 8// 9// FAIL-CLOSED ON AN UNKNOWN HOST. Guessing a licence location for a host whose layout we have not 10// established would fetch some other file and pin its digest as though it were a licence: a 11// fabricated fact wearing a cryptographic pin, which is worse than no licence at all. Unknown -> -1. 12// 13// DERIVING A URL IS NOT EVIDENCE. This produces CANDIDATES. A row reaches evidence=READ only once 14// those bytes are fetched, stored and pinned. 15// license_tier: ORIGINAL 16import "nx_syscalls.nx" 17 18const AL_URLCAP: i64 = 512 19const AL_SLASH: i64 = 47 20const AL_NUL: i64 = 0 21const AL_CAND_N: i64 = 4 22 23const AL_HOST_UNKNOWN: i64 = 0 24const AL_HOST_GITHUB: i64 = 1 25const AL_HOST_HF: i64 = 2 26const AL_HOST_HF_DATASET: i64 = 3 27 28func al_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 29 30func al_cat(d: *u8, o: i64, s: *u8) -> i64 { 31 var p: i64 = o 32 var i: i64 = 0 33 while s[i] != (0 as u8) { d[p] = s[i]; p = p + 1; i = i + 1 } 34 return p 35} 36 37func al_starts(s: *u8, p: *u8) -> i64 { 38 var i: i64 = 0 39 var ok: i64 = 1 40 while p[i] != (0 as u8) { 41 if s[i] != p[i] { ok = 0 } 42 if s[i] == (0 as u8) { ok = 0 } 43 i = i + 1 44 } 45 return ok 46} 47 48func al_streq(a: *u8, b: *u8) -> i64 { 49 var i: i64 = 0 50 while 1 == 1 { 51 let ca: i64 = a[i] as i64 52 let cb: i64 = b[i] as i64 53 if ca != cb { return 0 } 54 if ca == 0 { return 1 } 55 i = i + 1 56 } 57 return 1 58} 59 60// candidate licence filenames, in the order a repository is conventionally searched. 61func al_cand(i: i64) -> *u8 { 62 if i == 0 { return "LICENSE" as *u8 } 63 if i == 1 { return "LICENSE.md" as *u8 } 64 if i == 2 { return "LICENSE.txt" as *u8 } 65 return "COPYING" as *u8 66} 67 68// ORDER IS LOad-BEARING: the dataset form is a PREFIX-EXTENSION of the plain hub form, so it must be 69// tested FIRST. Reversed, every dataset row classifies as a model row and its licence is fetched from 70// a path that does not exist -- a 404 that would read as "this work has no licence". 71func al_host(url: *u8) -> i64 { 72 if al_starts(url, "https://huggingface.co/datasets/" as *u8) == 1 { return AL_HOST_HF_DATASET } 73 if al_starts(url, "https://huggingface.co/" as *u8) == 1 { return AL_HOST_HF } 74 if al_starts(url, "https://github.com/" as *u8) == 1 { return AL_HOST_GITHUB } 75 return AL_HOST_UNKNOWN 76} 77 78// copy the first `want` path segments following `skip` bytes of url into out. 79// Returns segments actually copied -- the CALLER checks it, because a URL with fewer segments than 80// required is a malformed row, not an owner/repo pair, and must never be silently used. 81func al_seg(url: *u8, skip: i64, want: i64, out: *u8, cap: i64) -> i64 { 82 var i: i64 = skip 83 var o: i64 = 0 84 var seg: i64 = 0 85 var stop: i64 = 0 86 while stop == 0 { 87 let c: i64 = url[i] as i64 88 if c == AL_NUL { stop = 1 } 89 else { 90 if c == AL_SLASH { 91 seg = seg + 1 92 if seg >= want { stop = 1 } 93 else { if o < cap - 1 { out[o] = AL_SLASH as u8; o = o + 1 } } 94 } else { 95 if o < cap - 1 { out[o] = url[i]; o = o + 1 } 96 } 97 if stop == 0 { i = i + 1 } 98 } 99 } 100 out[o] = 0 as u8 101 // a URL ending without a trailing slash closes its last segment at NUL, so count it complete. 102 if o > 0 { if seg < want { seg = seg + 1 } } 103 return seg 104} 105 106// THE PURE CORE. url + candidate index -> raw licence URL, or -1 for a host we cannot address. 107// cand is ignored for both HuggingFace forms: a hub repo carries its licence in the YAML frontmatter 108// of README.md, not in a LICENSE file, so four filename candidates there would be four requests for 109// files that do not exist. HEAD (not main) for github, so a repo on master or one that renames its 110// default branch later still resolves. 111func aq_license_url(url: *u8, cand: i64, out: *u8, cap: i64) -> i64 { 112 let h: i64 = al_host(url) 113 if h == AL_HOST_UNKNOWN { out[0] = 0 as u8; return 0 - 1 } 114 let seg: *u8 = sys_mmap(AL_URLCAP) 115 116 if h == AL_HOST_GITHUB { 117 if cand < 0 { out[0] = 0 as u8; return 0 - 1 } 118 if cand >= AL_CAND_N { out[0] = 0 as u8; return 0 - 1 } 119 let n: i64 = al_seg(url, al_len("https://github.com/" as *u8), 2, seg, AL_URLCAP) 120 if n < 2 { out[0] = 0 as u8; return 0 - 1 } 121 var o: i64 = al_cat(out, 0, "https://raw.githubusercontent.com/" as *u8) 122 o = al_cat(out, o, seg) 123 o = al_cat(out, o, "/HEAD/" as *u8) 124 o = al_cat(out, o, al_cand(cand)) 125 out[o] = 0 as u8 126 return o 127 } 128 129 if h == AL_HOST_HF_DATASET { 130 let n: i64 = al_seg(url, al_len("https://huggingface.co/datasets/" as *u8), 2, seg, AL_URLCAP) 131 if n < 2 { out[0] = 0 as u8; return 0 - 1 } 132 var o: i64 = al_cat(out, 0, "https://huggingface.co/datasets/" as *u8) 133 o = al_cat(out, o, seg) 134 o = al_cat(out, o, "/raw/main/README.md" as *u8) 135 out[o] = 0 as u8 136 return o 137 } 138 139 let n: i64 = al_seg(url, al_len("https://huggingface.co/" as *u8), 2, seg, AL_URLCAP) 140 if n < 2 { out[0] = 0 as u8; return 0 - 1 } 141 var o: i64 = al_cat(out, 0, "https://huggingface.co/" as *u8) 142 o = al_cat(out, o, seg) 143 o = al_cat(out, o, "/raw/main/README.md" as *u8) 144 out[o] = 0 as u8 145 return o 146} 147 148func al_host_name(h: i64) -> *u8 { 149 if h == AL_HOST_GITHUB { return "github" as *u8 } 150 if h == AL_HOST_HF_DATASET { return "huggingface-dataset" as *u8 } 151 if h == AL_HOST_HF { return "huggingface" as *u8 } 152 return "UNKNOWN" as *u8 153}