code wiki / _hdl_build / nx_docportal_admin_daemon_gate.nx
nx_docportal_admin_daemon_gate.nx source
↩ module page · 273 lines · 20338 B
1// nx_docportal_admin_daemon_gate.nx -- SOVEREIGN in-process referee for the admin.<domain> document-portal daemon
2// on the CANONICAL ecosystem Modern Auth (no socket/curl/shell). Arms a realm + registers an admin via the REAL
3// Modern Auth, then feeds crafted HTTP request BYTES into the pure router dad_handle and asserts the response bytes
4// AND the real upload side effect in the sovereign store -- proving the document portal is gated by the SAME auth
5// the rest of the ecosystem uses (not a bespoke scheme):
6// T1 GET /admin -> 200 + the login/upload SPA shell (public)
7// T2 POST /admin/login ok -> 200 + {"token":...} (mint a real no-cookie token)
8// T3 POST /admin/upload +tok -> 200 UPLOADED, the doc is stored, and the owner ai_blog flag took effect
9// T4 POST /admin/upload NOtok -> 401 (deny-by-default at the daemon, before da_handle)
10// T5 POST /admin/upload BADtok-> 401 (forged session rejected)
11// T6 POST /admin/login WRONGpw-> 401
12// R1 POST /admin/register +invite -> 200 + mnemonic, and the new firm admin can then log in
13// R2 POST /admin/register garbage-invite -> 403, and the user is NOT registered (login fails)
14// R3 POST /admin/register replayed (consumed) invite -> 403 (single-use enforced over HTTP)
15// S1 GET /search?q=... (PUBLIC, no session) -> 200 + the seg_store hit rendered (route matched BEFORE the
16// /admin chain; Host header -> dp-<host>-pub- shard; case-folded term match through the daemon)
17// S2 GET /search with an absent-shard Host -> 200 + "0 result(s)" (graceful isolation, never a 500)
18// S3 GET /doc?cid=<cid> (PUBLIC) -> 200 + the doc text (the SERP click-through, -pub- shard only)
19// S4 GET /doc with an absent cid -> branded 404 (never a 500)
20// GREEN iff 20/20 (D001-migrated 2026-09-02 onto nx_gate_verdict; S8..S8c the L2b stream guard, 2026-09-15). Appends knowledge/status/docportal_admin_daemon_gate.log. license_tier: ORIGINAL
21import "nx_docportal_admin_daemon.nx"
22import "hub/nx_modern_auth_flow.nx"
23import "nx_syscalls.nx"
24import "nx_gate_verdict.nx" // D001 (2026-09-02): the verdict is the base class's, so /api/promote, nx_gate_green and harness.jrnl can all read it
25
26func g_w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
27func g_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
28func g_lw(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 }
29func 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 }
30func g_cat_n(d: *u8, o: i64, s: *u8, n: i64) -> i64 { var i: i64 = 0; while i < n { d[o + i] = s[i]; i = i + 1 } return o + n }
31func g_trunc(path: *u8) -> i64 { let fd: i64 = sys_openat_wr(path, 0x180); if fd >= 0 { sys_close(fd) } return 0 }
32func g_starts(buf: *u8, n: i64, s: *u8) -> i64 { let sn: i64 = g_len(s); if n < sn { return 0 } var i: i64 = 0; while i < sn { if (buf[i] as i64) != (s[i] as i64) { return 0 } i = i + 1 } return 1 }
33func g_contains(hay: *u8, n: i64, needle: *u8) -> i64 {
34 let nn: i64 = g_len(needle); var i: i64 = 0
35 while i + nn <= n { var m: i64 = 1; var j: i64 = 0; while j < nn { if (hay[i + j] as i64) != (needle[j] as i64) { m = 0; j = nn } else { j = j + 1 } } if m == 1 { return 1 } i = i + 1 }
36 return 0
37}
38func g_extract_token(resp: *u8, n: i64, out: *u8) -> i64 {
39 let key: *u8 = "{\"token\":\"" as *u8; let kn: i64 = 10
40 var start: i64 = 0 - 1; var i: i64 = 0
41 while i + kn <= n { var m: i64 = 1; var j: i64 = 0; while j < kn { if (resp[i + j] as i64) != (key[j] as i64) { m = 0; j = kn } else { j = j + 1 } } if m == 1 { start = i + kn; i = n } i = i + 1 }
42 if start < 0 { return 0 }
43 var w: i64 = 0; var k: i64 = start; var done: i64 = 0
44 while done == 0 { if k >= n { done = 1 } if done == 0 { if (resp[k] as i64) == 34 { done = 1 } } if done == 0 { out[w] = resp[k]; w = w + 1; k = k + 1 } }
45 return w
46}
47
48func main() -> i64 {
49 g_w("=== DOCPORTAL ADMIN DAEMON GATE (admin.<domain> on the CANONICAL Modern Auth; sovereign in-process) ===\n" as *u8)
50 let store_path: *u8 = "/tmp/nx_dad_gate_store.log" as *u8
51 let keys_path: *u8 = "/tmp/nx_dad_gate_keys.log" as *u8
52 g_trunc(store_path); g_trunc(keys_path)
53
54 let oprf_seed: *u8 = sys_mmap(32); let akp: *u8 = sys_mmap(32); let akb: *u8 = sys_mmap(33)
55 let edp: *u8 = sys_mmap(32); let edb: *u8 = sys_mmap(32)
56 if nx_uas_server_keys_load_or_init(keys_path, oprf_seed, akp, akb, edp, edb) != NX_UAS_OK { g_w("KEYS FAIL\n" as *u8); sys_exit(1) }
57 let realm: *u8 = "nishi_docportal" as *u8
58 let realm_n: i64 = g_len(realm)
59 let ctx: *NxAuthContext = sys_mmap(256) as *NxAuthContext
60 if nx_auth_context_init(ctx, realm, realm_n, realm, realm_n, store_path as i64, oprf_seed, edp, edb, 900, 8192, 1, 1, 5, 1) != NX_MAUTH_OK { g_w("CTX FAIL\n" as *u8); sys_exit(1) }
61 let mn: *u8 = sys_mmap(512); let mn_n: *i64 = sys_mmap(16) as *i64
62 if nx_modern_auth_register(ctx, "elder" as *u8, 5, "correct horse battery staple" as *u8, 28, mn, 512, mn_n) != NX_MAUTH_OK { g_w("REGISTER FAIL\n" as *u8); sys_exit(1) }
63
64 let req: *u8 = sys_mmap(8192)
65 let out: *u8 = sys_mmap(DAD_OUTCAP)
66 var pass: i64 = 0
67 let ctr: *i64 = gv_ctr()
68 gv_subjects("crafted requests through dad_handle" as *u8, 16, ctr)
69
70 // T1: GET /admin -> 200 + shell
71 let n1: i64 = g_cat(req, 0, "GET /admin HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
72 let o1: i64 = dad_handle(ctx, req, n1, out)
73 var t1: i64 = 0
74 if g_starts(out, o1, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, o1, "id=login" as *u8) == 1 { t1 = 1 } }
75 pass = pass + t1; gv_check("T1-GET-admin-to-200-shell" as *u8, t1, ctr)
76
77 // T2: POST /admin/login (correct) -> token
78 let n2: i64 = g_cat(req, 0, "POST /admin/login HTTP/1.1\r\nHost: x\r\n\r\nhandle=elder&passphrase=correct+horse+battery+staple" as *u8)
79 let o2: i64 = dad_handle(ctx, req, n2, out)
80 let tokbuf: *u8 = sys_mmap(256); var tok_n: i64 = 0
81 var t2: i64 = 0
82 if g_starts(out, o2, "HTTP/1.1 200" as *u8) == 1 { tok_n = g_extract_token(out, o2, tokbuf); if tok_n > 0 { t2 = 1 } }
83 pass = pass + t2; gv_check("T2-POST-admin-login-to-token" as *u8, t2, ctr)
84
85 // T3: authed upload (X-Nishi-Session + body) -> 200 UPLOADED + stored + ai_blog flag took effect
86 let body: *u8 = "Daemon-path public estate planning guide cleared for AI blog use." as *u8
87 let blen: i64 = g_len(body)
88 let cid: i64 = dp_cid(body, blen)
89 var n3: i64 = g_cat(req, 0, "POST /admin/upload?domain=ddaemon&visibility=public&pub_search=1&ai_blog=1 HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: " as *u8)
90 n3 = g_cat_n(req, n3, tokbuf, tok_n)
91 n3 = g_cat(req, n3, "\r\n\r\n" as *u8)
92 n3 = g_cat_n(req, n3, body, blen)
93 let o3: i64 = dad_handle(ctx, req, n3, out)
94 let pq: *i64 = sys_mmap(16) as *i64; let lq: *i64 = sys_mmap(16) as *i64
95 var t3: i64 = 0
96 if g_starts(out, o3, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, o3, "UPLOADED" as *u8) == 1 {
97 if dp_read("ddaemon" as *u8, DP_VIS_PUBLIC, cid, pq, lq) == 1 { if dp_may("ddaemon" as *u8, DP_VIS_PUBLIC, cid, DP_USE_AI_BLOG) == 1 { t3 = 1 } }
98 } }
99 pass = pass + t3; gv_check("T3-authed-upload-stored-+-ai-blog-flagged" as *u8, t3, ctr)
100
101 // T4: upload WITHOUT a session -> 401 (deny-by-default at the daemon)
102 let nofake: *u8 = "Should never be stored: no session." as *u8
103 let nflen: i64 = g_len(nofake)
104 let nfcid: i64 = dp_cid(nofake, nflen)
105 var n4: i64 = g_cat(req, 0, "POST /admin/upload?domain=ddaemon&visibility=public HTTP/1.1\r\nHost: x\r\n\r\n" as *u8)
106 n4 = g_cat_n(req, n4, nofake, nflen)
107 let o4: i64 = dad_handle(ctx, req, n4, out)
108 var t4: i64 = 0
109 if g_starts(out, o4, "HTTP/1.1 401" as *u8) == 1 { if dp_read("ddaemon" as *u8, DP_VIS_PUBLIC, nfcid, pq, lq) == 0 { t4 = 1 } }
110 pass = pass + t4; gv_check("T4-no-session-upload-to-401-+-not-stored" as *u8, t4, ctr)
111
112 // T5: upload with a FORGED session -> 401
113 var n5: i64 = g_cat(req, 0, "POST /admin/upload?domain=ddaemon&visibility=public HTTP/1.1\r\nHost: x\r\nX-Nishi-Session: AAAAAAAA\r\n\r\nx" as *u8)
114 let o5: i64 = dad_handle(ctx, req, n5, out)
115 var t5: i64 = 0
116 if g_starts(out, o5, "HTTP/1.1 401" as *u8) == 1 { t5 = 1 }
117 pass = pass + t5; gv_check("T5-forged-session-upload-to-401" as *u8, t5, ctr)
118
119 // T6: wrong-passphrase login -> 401
120 let n6: i64 = g_cat(req, 0, "POST /admin/login HTTP/1.1\r\nHost: x\r\n\r\nhandle=elder&passphrase=wrong+passphrase" as *u8)
121 let o6: i64 = dad_handle(ctx, req, n6, out)
122 var t6: i64 = 0
123 if g_starts(out, o6, "HTTP/1.1 401" as *u8) == 1 { t6 = 1 }
124 pass = pass + t6; gv_check("T6-wrong-pw-login-to-401" as *u8, t6, ctr)
125
126 // ---- INVITE-GATED SELF-REGISTRATION (POST /admin/register) ----
127 // Derive the SAME per-realm invite store the daemon derives (dad_invite_path) and start it clean.
128 let invpath: *u8 = sys_mmap(512)
129 dad_invite_path(ctx, invpath)
130 g_trunc(invpath)
131 let rnow: i64 = sys_now_realtime_sec()
132
133 // R1: mint a real invite -> POST /admin/register (invite+handle+pw) -> 200 + mnemonic, and the
134 // new firm admin can then nx_modern_auth_login (proves the OPAQUE record actually LANDED in the store).
135 let invtok: *u8 = sys_mmap(80)
136 let ri: i64 = inv_issue(invpath, realm, realm_n, 2, 3600, rnow, invtok)
137 var nr1: i64 = g_cat(req, 0, "POST /admin/register HTTP/1.1\r\nHost: x\r\n\r\nhandle=firmadmin&pw=lawfirm+secret+passphrase&invite=" as *u8)
138 nr1 = g_cat_n(req, nr1, invtok, NX_INV_TOKEN_HEX)
139 let or1: i64 = dad_handle(ctx, req, nr1, out)
140 var r1: i64 = 0
141 if ri == NX_INV_OK { if g_starts(out, or1, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, or1, "mnemonic" as *u8) == 1 {
142 let rtk: *u8 = sys_mmap(NX_MAUTH_SESSION_TOKEN_BYTES); let rtn: *i64 = sys_mmap(16) as *i64; rtn[0] = 0
143 if nx_modern_auth_login(ctx, "firmadmin" as *u8, 9, "lawfirm secret passphrase" as *u8, 25, rtk, NX_MAUTH_SESSION_TOKEN_BYTES, rtn) == NX_MAUTH_OK { r1 = 1 }
144 } } }
145 pass = pass + r1; gv_check("R1-invite-register-to-200-+-the-new-admin-can-log-in" as *u8, r1, ctr)
146
147 // R2: NEG garbage invite -> 403, and the intruder is NOT registered (a subsequent login must fail).
148 var nr2: i64 = g_cat(req, 0, "POST /admin/register HTTP/1.1\r\nHost: x\r\n\r\nhandle=intruder&pw=intruder+pw+here&invite=00000000000000000000000000000000000000000000000000000000deadbeef" as *u8)
149 let or2: i64 = dad_handle(ctx, req, nr2, out)
150 var r2: i64 = 0
151 if g_starts(out, or2, "HTTP/1.1 403" as *u8) == 1 {
152 let rtk2: *u8 = sys_mmap(NX_MAUTH_SESSION_TOKEN_BYTES); let rtn2: *i64 = sys_mmap(16) as *i64; rtn2[0] = 0
153 if nx_modern_auth_login(ctx, "intruder" as *u8, 8, "intruder pw here" as *u8, 16, rtk2, NX_MAUTH_SESSION_TOKEN_BYTES, rtn2) != NX_MAUTH_OK { r2 = 1 }
154 }
155 pass = pass + r2; gv_check("R2-NEG-garbage-invite-to-403-+-not-registered" as *u8, r2, ctr)
156
157 // R3: NEG single-use replay. The R1 invite was consumed on success; replaying it must -> 403.
158 var nr3: i64 = g_cat(req, 0, "POST /admin/register HTTP/1.1\r\nHost: x\r\n\r\nhandle=replayer&pw=replayer+pw+ok&invite=" as *u8)
159 nr3 = g_cat_n(req, nr3, invtok, NX_INV_TOKEN_HEX)
160 let or3: i64 = dad_handle(ctx, req, nr3, out)
161 var r3: i64 = 0
162 if g_starts(out, or3, "HTTP/1.1 403" as *u8) == 1 {
163 let rtk3: *u8 = sys_mmap(NX_MAUTH_SESSION_TOKEN_BYTES); let rtn3: *i64 = sys_mmap(16) as *i64; rtn3[0] = 0
164 if nx_modern_auth_login(ctx, "replayer" as *u8, 8, "replayer pw ok" as *u8, 14, rtk3, NX_MAUTH_SESSION_TOKEN_BYTES, rtn3) != NX_MAUTH_OK { r3 = 1 }
165 }
166 pass = pass + r3; gv_check("R3-NEG-single-use-replay-to-403" as *u8, r3, ctr)
167
168 // ---- PUBLIC SOVEREIGN /search THROUGH THE DAEMON (R4b: route + Host->shard, no auth) ----
169 // Write a real PUBLIC doc into the dadsearch shard through the raw sovereign store (same
170 // incantation as nx_docportal_search_seg_gate; content-addressed key -> re-runs are clean).
171 let sdoc: *u8 = "Probate and estate administration guidance for Texas families." as *u8
172 let sw: *i64 = ss_begin()
173 ss_add(sw, 1, "doc:501" as *u8, sdoc, g_len(sdoc))
174 ss_commit("knowledge/store/dp-dadsearch-pub-" as *u8, sw, 1)
175
176 // S1: PUBLIC GET /search (NO session header) routed to dss_serve; Host: dadsearch keys the shard;
177 // capital "Probate" in the doc vs lowercase query proves the case-folded tokenizer alignment E2E.
178 // scope=site EXPLICIT since the 2026-07-24 wiring fix made web the default scope -- site portals
179 // reach their own shard via the same &scope=site every rendered site link carries.
180 let ns1: i64 = g_cat(req, 0, "GET /search?q=probate&scope=site HTTP/1.1\r\nHost: dadsearch\r\n\r\n" as *u8)
181 let os1: i64 = dad_handle(ctx, req, ns1, out)
182 var s1: i64 = 0
183 // the leading "Probate" is <b>-highlighted (R5), so assert the highlighted rendering exactly
184 if g_starts(out, os1, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, os1, "<b>Probate</b> and estate administration" as *u8) == 1 { if g_contains(out, os1, "1 result(s)" as *u8) == 1 { s1 = 1 } } }
185 pass = pass + s1; gv_check("S1-public-search-to-200-+-seg-store-hit" as *u8, s1, ctr)
186
187 // S2 NEG: absent-shard Host -> 200 + zero results (isolation degrades gracefully, never a 500)
188 let ns2: i64 = g_cat(req, 0, "GET /search?q=probate HTTP/1.1\r\nHost: nosuchdomain-xyz\r\n\r\n" as *u8)
189 let os2: i64 = dad_handle(ctx, req, ns2, out)
190 var s2: i64 = 0
191 if g_starts(out, os2, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, os2, "0 result(s)" as *u8) == 1 { s2 = 1 } }
192 pass = pass + s2; gv_check("S2-NEG-absent-shard-search-to-200-+-0-results" as *u8, s2, ctr)
193
194 // S3: PUBLIC /doc click-through routed through the daemon (boundary-guarded route -> dsv_doc_serve)
195 let ns3: i64 = g_cat(req, 0, "GET /doc?cid=501&scope=site HTTP/1.1\r\nHost: dadsearch\r\n\r\n" as *u8)
196 let os3: i64 = dad_handle(ctx, req, ns3, out)
197 var s3: i64 = 0
198 if g_starts(out, os3, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, os3, "Probate and estate administration" as *u8) == 1 { s3 = 1 } }
199 pass = pass + s3; gv_check("S3-public-doc-to-200-+-doc-text" as *u8, s3, ctr)
200
201 // S4 NEG: /doc with an absent cid -> branded 404 through the daemon (never a 500)
202 let ns4: i64 = g_cat(req, 0, "GET /doc?cid=424242 HTTP/1.1\r\nHost: dadsearch\r\n\r\n" as *u8)
203 let os4: i64 = dad_handle(ctx, req, ns4, out)
204 var s4: i64 = 0
205 if g_starts(out, os4, "HTTP/1.1 404" as *u8) == 1 { s4 = 1 }
206 pass = pass + s4; gv_check("S4-NEG-doc-absent-cid-to-404" as *u8, s4, ctr)
207
208 // S5: API-FIRST through the router -- /api/search answers versioned JSON with CORS (public machine contract)
209 let ns5: i64 = g_cat(req, 0, "GET /api/search?q=probate&scope=site HTTP/1.1\r\nHost: dadsearch\r\n\r\n" as *u8)
210 let os5: i64 = dad_handle(ctx, req, ns5, out)
211 var s5: i64 = 0
212 if g_starts(out, os5, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, os5, "\"v\":1" as *u8) == 1 { if g_contains(out, os5, "\"nresults\":1" as *u8) == 1 { if g_contains(out, os5, "application/json" as *u8) == 1 { s5 = 1 } } } }
213 pass = pass + s5; gv_check("S5-api-search-JSON-through-the-router" as *u8, s5, ctr)
214
215 // S6 NEG: /api/doc structured 400 on a malformed cid (machine-readable error contract)
216 let ns6: i64 = g_cat(req, 0, "GET /api/doc?cid=xyz HTTP/1.1\r\nHost: dadsearch\r\n\r\n" as *u8)
217 let os6: i64 = dad_handle(ctx, req, ns6, out)
218 var s6: i64 = 0
219 if g_starts(out, os6, "HTTP/1.1 400" as *u8) == 1 { if g_contains(out, os6, "\"code\":\"bad_cid\"" as *u8) == 1 { s6 = 1 } }
220 pass = pass + s6; gv_check("S6-NEG-api-doc-malformed-to-400-bad-cid" as *u8, s6, ctr)
221
222 // S7: /api/openapi.json machine-readable contract through the router (enterprise API discovery)
223 let ns7: i64 = g_cat(req, 0, "GET /api/openapi.json HTTP/1.1\r\nHost: dadsearch\r\n\r\n" as *u8)
224 let os7: i64 = dad_handle(ctx, req, ns7, out)
225 var s7: i64 = 0
226 if g_starts(out, os7, "HTTP/1.1 200" as *u8) == 1 { if g_contains(out, os7, "\"openapi\":\"3.1.0\"" as *u8) == 1 { if g_contains(out, os7, "\"/api/search\":" as *u8) == 1 { s7 = 1 } } }
227 pass = pass + s7; gv_check("S7-api-openapi-json-spec-through-the-router" as *u8, s7, ctr)
228
229 // S8..S8c (2026-09-15, the L2b guard): the HTML SERP streams early bytes ONLY when the front door's route
230 // table says `stream` for this host's /search row; a `buffered` row, an empty table and a foreign host all
231 // answer whole. The pure form takes the table, so these teeth cannot depend on the CWD's proxy_routes.conf.
232 let rt_s: *u8 = "dadsearch /search 18456 stream timeout=45\n" as *u8
233 let rt_b: *u8 = "dadsearch /search 18456 buffered timeout=45\n" as *u8
234 let hs: *u8 = "dadsearch" as *u8
235 let ho: *u8 = "elsewhere" as *u8
236 let s8: i64 = (dad_early_ok_tab(rt_s, g_len(rt_s), hs) == 1) as i64
237 pass = pass + s8; gv_check("S8-stream-row-streams-early-bytes" as *u8, s8, ctr)
238 let s8a: i64 = (dad_early_ok_tab(rt_b, g_len(rt_b), hs) == 0) as i64
239 pass = pass + s8a; gv_check("S8a-NEG-buffered-row-answers-whole" as *u8, s8a, ctr)
240 let s8b: i64 = (dad_early_ok_tab(rt_s, 0, hs) == 0) as i64
241 pass = pass + s8b; gv_check("S8b-NEG-empty-table-answers-whole" as *u8, s8b, ctr)
242 let s8c: i64 = (dad_early_ok_tab(rt_s, g_len(rt_s), ho) == 0) as i64
243 pass = pass + s8c; gv_check("S8c-NEG-foreign-host-answers-whole" as *u8, s8c, ctr)
244 gv_kv("early_ok_stream_row" as *u8, dad_early_ok_tab(rt_s, g_len(rt_s), hs))
245 gv_kv("early_ok_buffered_row" as *u8, dad_early_ok_tab(rt_b, g_len(rt_b), hs))
246
247 g_w("----\nDOCPORTAL-ADMIN-DAEMON rows=20 pass="); let db: *u8 = sys_mmap(8); var v: i64 = pass; var k: i64 = 0; if v == 0 { db[0] = 48 as u8; k = 1 } else { while v > 0 { db[k] = (48 + (v % 10)) as u8; v = v / 10; k = k + 1 } } let rv: *u8 = sys_mmap(8); var x: i64 = 0; while x < k { rv[x] = db[k - 1 - x]; x = x + 1 } sys_write(1, rv, k); g_w("\n" as *u8)
248 let lg: i64 = sys_openat_append("knowledge/status/docportal_admin_daemon_gate.log" as *u8, 0x1a4)
249 if lg >= 0 {
250 g_lw(lg, "DOCPORTAL-ADMIN-DAEMON auth=modern-opaque shell="); g_lw(lg, "1"); g_lw(lg, " login_token="); if t2 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
251 g_lw(lg, " authed_upload="); if t3 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
252 g_lw(lg, " deny_no_session="); if t4 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
253 g_lw(lg, " deny_forged="); if t5 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
254 g_lw(lg, " deny_wrongpw="); if t6 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
255 g_lw(lg, " self_register="); if r1 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
256 g_lw(lg, " deny_bad_invite="); if r2 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
257 g_lw(lg, " deny_replay_invite="); if r3 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
258 g_lw(lg, " public_search="); if s1 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
259 g_lw(lg, " search_absent_shard_0="); if s2 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
260 g_lw(lg, " public_doc="); if s3 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
261 g_lw(lg, " doc_absent_404="); if s4 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
262 g_lw(lg, " api_search_json="); if s5 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
263 g_lw(lg, " api_doc_400="); if s6 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
264 g_lw(lg, " api_openapi="); if s7 == 1 { g_lw(lg, "1") } else { g_lw(lg, "0") }
265 g_lw(lg, " rows=20 pass="); sys_write(lg, rv, k)
266 if pass == 20 { g_lw(lg, " verdict=GREEN\n" as *u8) } else { g_lw(lg, " verdict=RED\n" as *u8) }
267 sys_close(lg)
268 }
269 // D001 MIGRATION (2026-09-02): the verdict is gv_verdict's -- the exit code carries it, the LAST line is
270 // `verdict=`, and every tooth above is a gv_check the base counter declared-equals-executed. The journal
271 // line above stays as the gate's own domain row; it is not the verdict.
272 return gv_verdict("nx_docportal_admin_daemon_gate" as *u8, ctr, "in-process over dad_handle on the canonical Modern Auth: portal gating, invite registration, public sovereign /search and /doc, API-first JSON" as *u8)
273}