code wiki / _hdl_build / nx_legal_portal_gate.nx
nx_legal_portal_gate.nx source
↩ module page · 235 lines · 11219 B
1// nx_legal_portal_gate.nx -- GATE for LEGAL D6 (nx_legal_portal).
2//
3// SOVEREIGN in-process referee (the nx_status_daemon_gate pattern): NO socket,
4// NO curl, NO shell. It builds one tenant's real workflow stores (a SENT contract
5// with 1-of-2 signed via a REAL Ed25519 seal, a Will refused into REQUIRES_WET, a
6// vault doc, a pending checklist), then feeds crafted HTTP request BYTES straight
7// into lp_handle and asserts the response bytes -- proving the portal composes
8// D0/D1/D2/D3/D4 + nx_authz + tenant isolation. Each test has a negative control:
9// T1 GET /portal/envelopes -> 200 + both envelopes + their statuses
10// T2 GET /portal/status?env=C -> 200 + SENT + UETA_GENERAL + "1 of 2"
11// T3 GET /portal/doc?id=V -> 200 + application/pdf + BYTE-EXACT body (D3)
12// T4 GET /portal/doc?id=bogus -> 404 (tenant vault does not own it)
13// T5 GET /staff/matters -> 403 as client(lvl1) / 200 as lawyer(lvl2)
14// T6 GET /portal/status?env=W -> 200 + REQUIRES_WET + "wet signature required"
15// (never-void SURFACED, not silently signable)
16// T7 GET /portal/checklist?doc=V-> 200 + "remaining 1 NOT_READY"; /portal/bogus -> 404
17//
18// Evidence -> knowledge/status/legal_portal.log
19// license_tier: ORIGINAL
20import "nx_legal_portal.nx"
21import "nx_doc_envelope.nx"
22import "nx_doc_serve.nx"
23import "nx_doc_annotate.nx"
24import "nx_doc_vault.nx"
25import "nx_doc_seal.nx"
26import "nx_legal_compliance.nx"
27import "nx_syscalls.nx"
28
29const LP_LOG: *u8 = "knowledge/status/legal_portal.log"
30
31func ew(fd: i64, s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(fd, s, n); return 0 }
32func ewn(fd: i64, v: i64) -> i64 {
33 let bb: *u8 = sys_mmap(28); var m: i64 = v
34 if m < 0 { m = 0 - m; sys_write(fd, "-" as *u8, 1) }
35 let t: *u8 = sys_mmap(28); var k: i64 = 0
36 if m == 0 { t[0] = 48; k = 1 }
37 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
38 var i: i64 = 0; while i < k { bb[i] = t[k - 1 - i]; i = i + 1 }
39 sys_write(fd, bb, k); return 0
40}
41func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
42func g_cat(d: *u8, o: i64, s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { d[o + i] = s[i]; i = i + 1 } return o + i }
43func g_starts(buf: *u8, n: i64, s: *u8) -> i64 {
44 let sn: i64 = slen(s)
45 if n < sn { return 0 }
46 var i: i64 = 0
47 while i < sn { if buf[i] != s[i] { return 0 } i = i + 1 }
48 return 1
49}
50func g_contains(hay: *u8, n: i64, needle: *u8) -> i64 {
51 let nn: i64 = slen(needle)
52 if nn == 0 { return 1 }
53 var i: i64 = 0
54 while i + nn <= n {
55 var m: i64 = 1
56 var j: i64 = 0
57 while j < nn { if hay[i + j] != needle[j] { m = 0; break } j = j + 1 }
58 if m == 1 { return 1 }
59 i = i + 1
60 }
61 return 0
62}
63func mk_seal(s: *NxSeal, dt: i64, ewills: i64, signer: *u8, ts: i64,
64 intent: i64, consent: i64, attribution: i64, retainable: i64,
65 witnesses: i64, notarized: i64) -> i64 {
66 s.doc_type = dt; s.e_wills_allowed = ewills
67 s.intent = intent; s.consent = consent; s.attribution = attribution
68 s.retainable = retainable; s.witnesses = witnesses; s.notarized = notarized
69 s.signer_id = signer; s.signer_id_len = slen(signer); s.ts = ts
70 return nx_seal_create(s)
71}
72
73func main() -> i64 {
74 var ok: i64 = 1
75
76 // ---- RFC 8032 test-1 keypair ----
77 let priv: *u8 = sys_mmap(64)
78 priv[0]=0x9d; priv[1]=0x61; priv[2]=0xb1; priv[3]=0x9d; priv[4]=0xef; priv[5]=0xfd; priv[6]=0x5a; priv[7]=0x60
79 priv[8]=0xba; priv[9]=0x84; priv[10]=0x4a; priv[11]=0xf4; priv[12]=0x92; priv[13]=0xec; priv[14]=0x2c; priv[15]=0xc4
80 priv[16]=0x44; priv[17]=0x49; priv[18]=0xc5; priv[19]=0x69; priv[20]=0x7b; priv[21]=0x32; priv[22]=0x69; priv[23]=0x19
81 priv[24]=0x70; priv[25]=0x3b; priv[26]=0xac; priv[27]=0x03; priv[28]=0x1c; priv[29]=0xae; priv[30]=0x7f; priv[31]=0x60
82 let pub: *u8 = sys_mmap(64)
83 pub[0]=0xd7; pub[1]=0x5a; pub[2]=0x98; pub[3]=0x01; pub[4]=0x82; pub[5]=0xb1; pub[6]=0x0a; pub[7]=0xb7
84 pub[8]=0xd5; pub[9]=0x4b; pub[10]=0xfe; pub[11]=0xd3; pub[12]=0xc9; pub[13]=0x64; pub[14]=0x07; pub[15]=0x3a
85 pub[16]=0x0e; pub[17]=0xe1; pub[18]=0x72; pub[19]=0xf3; pub[20]=0xda; pub[21]=0xa6; pub[22]=0x23; pub[23]=0x25
86 pub[24]=0xaf; pub[25]=0x02; pub[26]=0x1a; pub[27]=0x68; pub[28]=0xf7; pub[29]=0x07; pub[30]=0x51; pub[31]=0x1a
87 let dh: *u8 = sys_mmap(64)
88 var di: i64 = 0
89 while di < 32 { dh[di] = ((di * 7 + 3) & 0xff) as u8; di = di + 1 }
90 let s: *NxSeal = sys_mmap(256) as *NxSeal
91 s.doc_hash = dh; s.doc_hash_len = 32; s.priv = priv; s.canon = sys_mmap(512); s.sig = sys_mmap(128)
92
93 // ---- one tenant's stores ----
94 let ecap: i64 = 8
95 let rcap: i64 = 16
96 let ncap: i64 = 16
97 let vcap: i64 = 8
98 let eflat: *i64 = sys_mmap(ecap * EF_STRIDE * 8) as *i64
99 let rflat: *i64 = sys_mmap(rcap * RF_STRIDE * 8) as *i64
100 let anflat: *i64 = sys_mmap(ncap * NF_STRIDE * 8) as *i64
101 let vflat: *i64 = sys_mmap(vcap * VF_STRIDE * 8) as *i64
102 var ne: i64 = 0
103 var nr: i64 = 0
104 var na: i64 = 0
105 var vc: i64 = 0
106
107 // ENV_C 9601: contract, SENT, 1-of-2 signed (real Ed25519 seal)
108 ne = nx_env_create(eflat, ne, ecap, 9601, 8601, "Services Agreement" as *u8, 1, 1000)
109 nr = nx_env_add_recipient(rflat, nr, rcap, 9601, 101, ROLE_SIGNER, 1)
110 nr = nx_env_add_recipient(rflat, nr, rcap, 9601, 102, ROLE_SIGNER, 2)
111 if nx_env_send(eflat, ne, rflat, nr, 9601) != ENV_SEND_OK { ok = 0 }
112 let cseal: i64 = mk_seal(s, DT_CONTRACT, 1, "client1@andelinwest.com" as *u8, 1100, 1, 1, 1, 1, 0, 0)
113 if cseal != SEAL_OK { ok = 0 }
114 if nx_env_sign(eflat, ne, rflat, nr, 9601, 101, s, pub) != ENV_SIGN_OK { ok = 0 }
115
116 // ENV_W 9602: Will in a non-e-wills jurisdiction -> REQUIRES_WET, refused into DRAFT
117 ne = nx_env_create(eflat, ne, ecap, 9602, 8602, "Last Will and Testament" as *u8, 0, 2000)
118 nr = nx_env_add_recipient(rflat, nr, rcap, 9602, 201, ROLE_SIGNER, 1)
119 if nx_env_send(eflat, ne, rflat, nr, 9602) != ENV_SEND_REFUSED_VOID { ok = 0 }
120
121 // vault doc 8601 (v1) + a pending required checklist item on it
122 vc = nx_vault_add(vflat, vc, vcap, 8601, 5001, 64, 1000)
123 na = nx_ann_add(anflat, na, ncap, 0, 1, 8601, 1, AN_CHECK, 0, 700, ANF_REQUIRED, 1000)
124
125 // the doc bytes to serve (a tiny PDF-ish blob with adversarial bytes)
126 let docb: *u8 = sys_mmap(64)
127 docb[0]=37; docb[1]=80; docb[2]=68; docb[3]=70; docb[4]=13; docb[5]=10; docb[6]=0; docb[7]=88
128 let doclen: i64 = 8
129
130 let eidbuf: *i64 = sys_mmap(32) as *i64
131 eidbuf[0] = 9601; eidbuf[1] = 9602
132
133 let ctx: *NxPortalCtx = sys_mmap(256) as *NxPortalCtx
134 ctx.user_level = 1
135 ctx.eflat = eflat; ctx.ne = ne
136 ctx.rflat = rflat; ctx.nr = nr
137 ctx.anflat = anflat; ctx.na = na
138 ctx.vflat = vflat; ctx.vc = vc
139 ctx.doc_id = 8601; ctx.doc_bytes = docb; ctx.doc_len = doclen; ctx.doc_fmt = DF_PDF
140 ctx.env_ids = eidbuf; ctx.env_count = 2
141
142 let req: *u8 = sys_mmap(4096)
143 let out: *u8 = sys_mmap(16384)
144
145 // ---- T1: list envelopes ----
146 var t1: i64 = 1
147 var rn: i64 = g_cat(req, 0, "GET /portal/envelopes HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
148 var on: i64 = lp_handle(ctx, req, rn, out)
149 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t1 = 0 }
150 if g_contains(out, on, "env 9601 status SENT" as *u8) != 1 { t1 = 0 }
151 if g_contains(out, on, "env 9602 status DRAFT" as *u8) != 1 { t1 = 0 }
152 if g_contains(out, on, "of 2" as *u8) != 1 { t1 = 0 }
153 if t1 != 1 { ok = 0 }
154
155 // ---- T2: contract status ----
156 var t2: i64 = 1
157 rn = g_cat(req, 0, "GET /portal/status?env=9601 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
158 on = lp_handle(ctx, req, rn, out)
159 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t2 = 0 }
160 if g_contains(out, on, "status SENT" as *u8) != 1 { t2 = 0 }
161 if g_contains(out, on, "regime UETA_GENERAL" as *u8) != 1 { t2 = 0 }
162 if g_contains(out, on, "signed 1 of 2" as *u8) != 1 { t2 = 0 }
163 if t2 != 1 { ok = 0 }
164
165 // ---- T3: serve doc byte-exact (D3) ----
166 var t3: i64 = 1
167 rn = g_cat(req, 0, "GET /portal/doc?id=8601 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
168 on = lp_handle(ctx, req, rn, out)
169 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t3 = 0 }
170 if g_contains(out, on, "Content-Type: application/pdf" as *u8) != 1 { t3 = 0 }
171 if nx_doc_serve_roundtrip_ok(out, on, docb, doclen) != 1 { t3 = 0 }
172 if t3 != 1 { ok = 0 }
173
174 // ---- T4: unknown doc id -> 404 (tenant vault does not own it) ----
175 var t4: i64 = 1
176 rn = g_cat(req, 0, "GET /portal/doc?id=9999 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
177 on = lp_handle(ctx, req, rn, out)
178 if g_starts(out, on, "HTTP/1.1 404" as *u8) != 1 { t4 = 0 }
179 if t4 != 1 { ok = 0 }
180
181 // ---- T5: /staff/matters denied to client(lvl1), allowed to lawyer(lvl2) ----
182 var t5: i64 = 1
183 ctx.user_level = 1
184 rn = g_cat(req, 0, "GET /staff/matters HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
185 on = lp_handle(ctx, req, rn, out)
186 if g_starts(out, on, "HTTP/1.1 403" as *u8) != 1 { t5 = 0 }
187 ctx.user_level = 2
188 on = lp_handle(ctx, req, rn, out)
189 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t5 = 0 }
190 if g_contains(out, on, "lawyer view" as *u8) != 1 { t5 = 0 }
191 ctx.user_level = 1
192 if t5 != 1 { ok = 0 }
193
194 // ---- T6: never-void SURFACED for the Will (REQUIRES_WET) ----
195 var t6: i64 = 1
196 rn = g_cat(req, 0, "GET /portal/status?env=9602 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
197 on = lp_handle(ctx, req, rn, out)
198 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t6 = 0 }
199 if g_contains(out, on, "regime REQUIRES_WET" as *u8) != 1 { t6 = 0 }
200 if g_contains(out, on, "wet signature required" as *u8) != 1 { t6 = 0 }
201 if t6 != 1 { ok = 0 }
202
203 // ---- T7: checklist readiness + unknown path -> 404 ----
204 var t7: i64 = 1
205 rn = g_cat(req, 0, "GET /portal/checklist?doc=8601 HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
206 on = lp_handle(ctx, req, rn, out)
207 if g_starts(out, on, "HTTP/1.1 200" as *u8) != 1 { t7 = 0 }
208 if g_contains(out, on, "remaining 1 NOT_READY" as *u8) != 1 { t7 = 0 }
209 rn = g_cat(req, 0, "GET /portal/bogus HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
210 on = lp_handle(ctx, req, rn, out)
211 if g_starts(out, on, "HTTP/1.1 404" as *u8) != 1 { t7 = 0 }
212 if t7 != 1 { ok = 0 }
213
214 // ---- evidence ----
215 var fd: i64 = 1
216 while fd >= 1 {
217 ew(fd, "LEGALPORTALGATE authored=organ composes=D0+D1+D2+D3+D4+authz list_envelopes=" as *u8); ewn(fd, t1)
218 ew(fd, " envelope_status=" as *u8); ewn(fd, t2)
219 ew(fd, " serve_doc_byteexact=" as *u8); ewn(fd, t3)
220 ew(fd, " unknown_doc_404=" as *u8); ewn(fd, t4)
221 ew(fd, " authz_client_vs_lawyer=" as *u8); ewn(fd, t5)
222 ew(fd, " never_void_surfaced=" as *u8); ewn(fd, t6)
223 ew(fd, " checklist_and_404=" as *u8); ewn(fd, t7)
224 if ok == 1 { ew(fd, " verdict=GREEN\n" as *u8) } else { ew(fd, " verdict=RED\n" as *u8) }
225 if fd == 1 {
226 let lf: i64 = sys_openat_append(LP_LOG, 420)
227 if lf >= 1 { fd = lf } else { fd = 0 }
228 } else {
229 sys_close(fd); fd = 0
230 }
231 }
232
233 if ok == 1 { return 0 }
234 return 1
235}