nx_licdetect_gate.nx source
↩ module page · 138 lines · 7930 B
1// nx_licdetect_gate.nx -- GATE for nx_licdetect_lib.
2//
3// The load-bearing tooth reads a REAL LICENCE TEXT WE HOLD (the Anny Apache-2.0 file mirrored from
4// raw.githubusercontent.com with its own provenance row and pin), not a synthetic fixture. A detector
5// proven only against text the test author wrote is proven against the author's idea of the licence.
6// If that mirror is missing the tooth reports a MISSING PRECONDITION and the gate SKIPs -- "I could
7// not look" must never arrive in the same word as "I looked and it passed".
8// license_tier: ORIGINAL
9import "nx_syscalls.nx"
10import "nx_gate_verdict.nx"
11import "nx_licdetect_lib.nx"
12
13func ldg_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
14
15// detect over a NUL-terminated literal, and compare the winning id to a wanted string.
16func ldg_is(ctx: *i64, text: *u8, want: *u8) -> i64 {
17 let out: *i64 = sys_mmap(32) as *i64
18 let r: i64 = ld_detect(ctx, text, ldg_len(text), out)
19 if r != LD_DETECTED { return 0 }
20 let buf: *u8 = ctx[0] as *u8
21 let wn: i64 = ldg_len(want)
22 if out[1] != wn { return 0 }
23 var i: i64 = 0
24 while i < wn { if buf[out[0] + i] != want[i] { return 0 } i = i + 1 }
25 return 1
26}
27
28func ldg_code(ctx: *i64, text: *u8) -> i64 {
29 let out: *i64 = sys_mmap(32) as *i64
30 return ld_detect(ctx, text, ldg_len(text), out)
31}
32
33func main(argc: i64, argv: *i64) -> i64 {
34 let ctr: *i64 = gv_ctr()
35 gv_head("=== nx_licdetect_gate: which licence is this TEXT, read from bytes not declarations ===" as *u8)
36
37 let ctx: *i64 = ld_ctx()
38 gv_check("marker-table-loads" as *u8, (ctx[3] > 0) as i64, ctr)
39
40 // ---- THE LOAD-BEARING TOOTH: a real Apache-2.0 licence text from our own library ----
41 let lp: *i64 = sys_mmap(16) as *i64
42 let real: *u8 = sys_read_file("knowledge/fetched/cmp_librarian_anny_LICENSE.txt" as *u8, lp)
43 var have_real: i64 = 0
44 if (real as i64) != 0 { if lp[0] > 0 { have_real = 1 } }
45 gv_need("precondition-real-apache-licence-mirror-is-held" as *u8, have_real, ctr)
46 if have_real == 1 {
47 let out: *i64 = sys_mmap(32) as *i64
48 let r: i64 = ld_detect(ctx, real, lp[0], out)
49 gv_check("REAL-held-apache-licence-text-DETECTS" as *u8, (r == LD_DETECTED) as i64, ctr)
50 let buf: *u8 = ctx[0] as *u8
51 var isap: i64 = 0
52 if r == LD_DETECTED {
53 if out[1] == 10 {
54 if buf[out[0]] == (97 as u8) { isap = 1 }
55 }
56 }
57 gv_check("REAL-held-licence-detects-as-apache-2.0-ten-chars-starting-a" as *u8, isap, ctr)
58 // The mirrored text is 10875 B against the canonical 11358 B -- it adds a NAVER copyright
59 // preamble and omits the APPENDIX. A detector keyed on the file's SIZE or its first line would
60 // miss it; keying on definitional phrases inside the reproduced terms does not.
61 gv_check("detection-survives-a-preamble-and-a-missing-appendix" as *u8, (r == LD_DETECTED) as i64, ctr)
62 }
63
64 // ---- the marker table is held to its own evidence discipline ----
65 // apache-2.0 has a V row naming the held text above; mit does not, and that must READ as unverified
66 // rather than being quietly presented as equally proven.
67 let cbuf: *u8 = ctx[0] as *u8
68 let rows: *i64 = ctx[2] as *i64
69 var ap_lo: i64 = 0 - 1
70 var ap_ll: i64 = 0
71 var mit_lo: i64 = 0 - 1
72 var mit_ll: i64 = 0
73 var i: i64 = 0
74 while i < ctx[3] {
75 let lo: i64 = rows[i * LD_ROW_STRIDE + 0]
76 let ll: i64 = rows[i * LD_ROW_STRIDE + 1]
77 if ll == 10 { if cbuf[lo] == (97 as u8) { ap_lo = lo; ap_ll = ll } }
78 if ll == 3 { if cbuf[lo] == (109 as u8) { mit_lo = lo; mit_ll = ll } }
79 i = i + 1
80 }
81 gv_check("apache-marker-set-is-VERIFIED-against-a-licence-we-hold" as *u8,
82 ld_marker_set_verified(ctx, ap_lo, ap_ll), ctr)
83 gv_check("mit-marker-set-is-honestly-UNVERIFIED-no-held-text-yet" as *u8,
84 (ld_marker_set_verified(ctx, mit_lo, mit_ll) == 0) as i64, ctr)
85
86 // ---- synthetic texts for the paths no held licence covers yet ----
87 gv_check("mit-text-detects-mit" as *u8,
88 ldg_is(ctx, "MIT License. Permission is hereby granted, free of charge, to any person obtaining a copy. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND." as *u8, "mit" as *u8), ctr)
89 gv_check("gpl3-text-detects-gpl-3.0" as *u8,
90 ldg_is(ctx, "GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Everyone is permitted to copy." as *u8, "gpl-3.0" as *u8), ctr)
91
92 // ---- fail-closed: nothing matched is UNKNOWN, never a nearest guess ----
93 gv_check("prose-with-no-licence-markers-is-UNKNOWN" as *u8,
94 (ldg_code(ctx, "This repository contains research code for a 3D human body model and some notes." as *u8) == LD_UNKNOWN) as i64, ctr)
95 gv_check("empty-text-is-UNKNOWN" as *u8, (ldg_code(ctx, "" as *u8) == LD_UNKNOWN) as i64, ctr)
96 // A README that merely NAMES a licence is a DECLARATION, not the licence text. It must not detect.
97 gv_check("a-readme-merely-naming-apache-2.0-does-NOT-detect" as *u8,
98 (ldg_code(ctx, "This project is released under the Apache 2.0 license. See LICENSE for details." as *u8) == LD_UNKNOWN) as i64, ctr)
99
100 // ---- exclusions: the markers that stop one licence being read as another ----
101 // AGPL text contains the words GNU GENERAL PUBLIC LICENSE in its own prose, so without the AFFERO
102 // exclusion every AGPL file would match GPL-3.0 too and the result would be AMBIGUOUS at best.
103 gv_check("agpl-text-detects-agpl-not-gpl3" as *u8,
104 ldg_is(ctx, "GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 based on the GNU GENERAL PUBLIC LICENSE" as *u8, "agpl-3.0" as *u8), ctr)
105
106 // ---- ambiguity is a REFUSAL, not a tie to break ----
107 let amb: *u8 = "Attribution-NonCommercial 4.0 International and also Attribution-ShareAlike 4.0 International" as *u8
108 gv_check("text-matching-two-licences-is-AMBIGUOUS" as *u8, (ldg_code(ctx, amb) == LD_AMBIGUOUS) as i64, ctr)
109 // and the winner is CLEARED, so a caller cannot read an id out of an ambiguous result by ignoring
110 // the return code -- the commonest way a three-state answer degrades into a two-state one.
111 let ambout: *i64 = sys_mmap(32) as *i64
112 ld_detect(ctx, amb, ldg_len(amb), ambout)
113 gv_check("AMBIGUOUS-clears-the-winner-so-it-cannot-be-read-anyway" as *u8, (ambout[0] == (0 - 1)) as i64, ctr)
114
115 // ================= BITE-PROVEN NEGATIVE CONTROLS =================
116 var b1_bad: i64 = 0
117 var b1_good: i64 = 0
118 if have_real == 1 {
119 let o2: *i64 = sys_mmap(32) as *i64
120 if ld_detect(ctx, real, lp[0], o2) == LD_DETECTED { b1_bad = 1 }
121 }
122 if ldg_code(ctx, "This repository contains research code for a 3D human body model and some notes." as *u8) == LD_DETECTED { b1_good = 1 }
123 gv_bite("neg-control-a-real-licence-text-DETECTS-and-ordinary-prose-does-not" as *u8, b1_bad, b1_good, ctr)
124
125 var b2_bad: i64 = 0
126 var b2_good: i64 = 0
127 if ldg_is(ctx, "GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 based on the GNU GENERAL PUBLIC LICENSE" as *u8, "gpl-3.0" as *u8) == 0 { b2_bad = 1 }
128 if ldg_is(ctx, "GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Everyone is permitted to copy." as *u8, "gpl-3.0" as *u8) == 0 { b2_good = 1 }
129 gv_bite("neg-control-affero-exclusion-blocks-gpl3-on-agpl-text-but-not-on-gpl-text" as *u8, b2_bad, b2_good, ctr)
130
131 var b3_bad: i64 = 0
132 var b3_good: i64 = 0
133 if ldg_code(ctx, amb) == LD_AMBIGUOUS { b3_bad = 1 }
134 if ldg_code(ctx, "Attribution-ShareAlike 4.0 International" as *u8) == LD_AMBIGUOUS { b3_good = 1 }
135 gv_bite("neg-control-two-licences-go-AMBIGUOUS-and-a-single-one-does-not" as *u8, b3_bad, b3_good, ctr)
136
137 return gv_verdict("LICDETECT-GATE" as *u8, ctr, "a licence is read from its TEXT, a declaration never detects, and both nothing-matched and two-matched refuse" as *u8)
138}