code wiki / _hdl_build / nx_connect_appd.nx
nx_connect_appd.nx source
↩ module page · 486 lines · 25509 B
1// nx_connect_appd.nx -- the DEPLOYABLE CONNECT app daemon (ops shell around the pure core
2// nx_connect_serve). Binds 0.0.0.0:8032 (LAN: http://192.168.8.227:8032/). Route /connect -> this port
3// on the sovereign edge. Build with --build-only; run deliberately. license_tier: ORIGINAL
4//
5// 2026-07-10 PERSISTENCE + PER-SESSION: anonymous nxc_sess cookie -> an isolated persistent world.
6// 2026-07-25 SHARED CONTENT-BLIND PLANE (E2E): daemon-owned pubkey directory + routed ciphertext, replayed
7// from the append-only connect/shared.cbl at boot.
8// 2026-07-25 REAL LOGIN (the accounts rung -- gates everything): full OPAQUE aPAKE (RFC 9807) via the shared
9// nx_opaque_login seam, in CONNECT's OWN realm (nishi_connect, self-provisioned keys+store). The server
10// stores only an OPAQUE envelope -- NO password-equivalent at rest. A signed session token rides the
11// nxc_auth cookie; each request resolves it via olg_whoami to a stable 32-byte user-id -> the world binds
12// to identity, not to an anonymous cookie. The display handle is resolved from a per-account file the
13// daemon writes at register/login. Crypto lives HERE (the shell); the pure core only renders from the
14// auth slots stamped into ctx. Unifying with one family-wide realm (nishi_site_admin) is the next rung.
15import "nx_connect_accounts.nx"
16import "nx_connect_album.nx"
17import "nx_opaque_login.nx" // olg_ctx_setup_ttl / olg_register / olg_login / olg_whoami + NxAuthContext + NX_MAUTH_OK
18
19const CD_MAGIC_262144: i64 = 262144
20const CD_MAGIC_1048576: i64 = 1048576
21const CD_MAGIC_1024: i64 = 1024 // shared-plane delta-append emit buffer (one row max ~350B)
22
23const CD_PORT: i64 = 0x1f60 // 8032 (8031 = survey lane)
24
25// OPAQUE realm config (data-driven; own realm keeps CONNECT accounts isolated from the family primary store).
26const CD_REALM: *u8 = "nishi_connect"
27const CD_REALM_N: i64 = 13
28const CD_DISP: *u8 = "Nishi Connect"
29const CD_DISP_N: i64 = 13
30const CD_AUTH_KEYS: *u8 = "connect_auth_keys.bin\x00"
31const CD_AUTH_STORE: *u8 = "connect_auth_store.log\x00"
32const CD_SESS_TTL: i64 = 86400 // 24h == NX_MAUTH_HARD_MAX_TTL_S (the modauth hard cap; a longer TTL is
33 // rejected by nx_auth_context_init). Sessions renew on the next sign-in;
34 // a sliding refresh (olg_refresh) past 24h is a follow-on.
35const CD_ARGON_M: i64 = 19456 // 19 MiB argon2id (OWASP 2026 alt profile) -- real KSF, snappy on the NAS
36const CD_ARGON_T: i64 = 2
37const CD_ARGON_P: i64 = 1
38const CD_PW_MIN: i64 = 8 // minimum passphrase length
39const CD_COMPACT_EVERY: i64 = 16 // after this many delete-on-delivery acks, physically compact shared.cbl
40
41func cd_p(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
42func cd_addr(out: *u8, port: i64) -> i64 {
43 out[0]=2 as u8
44 out[1]=0 as u8
45 out[2]=((port>>8)&0xff) as u8
46 out[3]=(port&0xff) as u8
47 var i: i64=4
48 while i<16 { out[i]=0 as u8; i=i+1 }
49 return 0
50}
51func cd_is_post(req: *u8) -> i64 {
52 if req[0]==(80 as u8) { if req[1]==(79 as u8) { if req[2]==(83 as u8) { if req[3]==(84 as u8) { return 1 } } } } // "POST"
53 return 0
54}
55
56// generic cookie value extractor: find <key> (e.g. "nxc_auth=") in the raw request, copy its value (ends at
57// ';', whitespace, CR or LF) into out (nul-terminated). Returns the value length, 0 if absent.
58func cd_cookie_val(req: *u8, reqlen: i64, key: *u8, keylen: i64, out: *u8, cap: i64) -> i64 {
59 var i: i64=0
60 while i+keylen<=reqlen {
61 var m: i64=1
62 var j: i64=0
63 while j<keylen { if req[i+j]!=key[j] { m=0; j=keylen } else { j=j+1 } }
64 if m==1 {
65 var q: i64=i+keylen
66 var t: i64=0
67 var go: i64=1
68 while go==1 {
69 if q>=reqlen { go=0 } else {
70 let c: i64 = req[q] as i64 & 0xff
71 if c==59 { go=0 } else { if c==32 { go=0 } else { if c==13 { go=0 } else { if c==10 { go=0 } else {
72 if t<cap-1 { out[t]=c as u8; t=t+1 }
73 q=q+1
74 } } } }
75 }
76 }
77 out[t]=0 as u8
78 return t
79 }
80 i=i+1
81 }
82 out[0]=0 as u8
83 return 0
84}
85// extract the request path token (after the method, up to the next space) into out (nul-terminated).
86func cd_req_path(req: *u8, reqlen: i64, out: *u8, cap: i64) -> i64 {
87 var i: i64=0
88 var seen: i64=0
89 while seen==0 { if i>=reqlen { seen=1 } else { if req[i]==(32 as u8) { i=i+1; seen=1 } else { i=i+1 } } }
90 var t: i64=0
91 var go: i64=1
92 while go==1 {
93 if i>=reqlen { go=0 } else {
94 if req[i]==(32 as u8) { go=0 } else { if t<cap-1 { out[t]=req[i]; t=t+1 } i=i+1 }
95 }
96 }
97 out[t]=0 as u8
98 return t
99}
100// lowercase A-Z in place (a form handle may arrive capitalised; the directory is canonical-lowercase).
101func cd_lower(buf: *u8, n: i64) -> i64 {
102 var i: i64=0
103 while i<n { let c: i64 = buf[i] as i64 & 0xff; if c>=65 { if c<=90 { buf[i]=(c+32) as u8 } } i=i+1 }
104 return 0
105}
106// per-account display-handle file: connect/h<acct>.txt (acct = the identity-derived i64; the file just
107// resolves uid->handle for DISPLAY -- identity/authz never trust it).
108func cd_handle_path(acct: i64, out: *u8) -> i64 {
109 var o: i64 = 0
110 let pfx: *u8 = "connect/h" as *u8
111 while pfx[o]!=(0 as u8) { out[o]=pfx[o]; o=o+1 }
112 let t: *u8 = sys_mmap(28)
113 var m: i64 = acct
114 if m<0 { m=0-m }
115 var k: i64=0
116 if m==0 { out[o]=48 as u8; o=o+1 } else { while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } var jj: i64=0; while jj<k { out[o]=t[k-1-jj]; o=o+1; jj=jj+1 } }
117 let ext: *u8 = ".txt\x00" as *u8
118 var e: i64=0
119 while ext[e]!=(0 as u8) { out[o]=ext[e]; o=o+1; e=e+1 }
120 out[o]=0 as u8
121 return o
122}
123func cd_write_handle(acct: i64, handle: *u8, hn: i64) -> i64 {
124 let path: *u8 = sys_mmap(64)
125 cd_handle_path(acct, path)
126 let fd: i64 = sys_openat_wr(path, 0x1a4)
127 if fd<0 { return 0-1 }
128 sys_write(fd, handle, hn)
129 sys_close(fd)
130 return hn
131}
132func cd_read_handle(acct: i64, out: *u8, cap: i64) -> i64 {
133 let path: *u8 = sys_mmap(64)
134 cd_handle_path(acct, path)
135 let fd: i64 = sys_openat_rd(path)
136 if fd<0 { out[0]=0 as u8; return 0 }
137 var t: i64=0
138 var go: i64=1
139 while go==1 {
140 if t>=cap-1 { go=0 } else {
141 let r: i64 = sys_read(fd, (out as i64 + t) as *u8, cap-1-t)
142 if r<=0 { go=0 } else { t=t+r }
143 }
144 }
145 sys_close(fd)
146 // trim trailing whitespace/newlines (defensive; cd_write_handle writes no trailer), then nul-terminate.
147 var trimming: i64=1
148 while trimming==1 {
149 if t<=0 { trimming=0 } else {
150 let c: i64 = out[t-1] as i64 & 0xff
151 if c==10 { t=t-1 } else { if c==13 { t=t-1 } else { if c==32 { t=t-1 } else { trimming=0 } } }
152 }
153 }
154 out[t]=0 as u8
155 return t
156}
157// insert one header line (nul-terminated, already ending in CRLF) right after the response status line.
158func cd_inject_line(resp: *u8, resp_len: i64, line: *u8, out: *u8, cap: i64) -> i64 {
159 var eol: i64 = 0-1
160 var i: i64=0
161 while i+1<resp_len { if resp[i]==(13 as u8) { if resp[i+1]==(10 as u8) { eol=i+2; i=resp_len } } i=i+1 }
162 if eol<0 { var k: i64=0; while k<resp_len { if k<cap { out[k]=resp[k] } k=k+1 } return resp_len }
163 var o: i64=0
164 var a: i64=0
165 while a<eol { if o<cap { out[o]=resp[a] } o=o+1; a=a+1 }
166 var li: i64=0
167 while line[li]!=(0 as u8) { if o<cap { out[o]=line[li] } o=o+1; li=li+1 }
168 var b: i64=eol
169 while b<resp_len { if o<cap { out[o]=resp[b] } o=o+1; b=b+1 }
170 return o
171}
172// build "Set-Cookie: nxc_auth=<val>; Path=/; HttpOnly; SameSite=Lax; Max-Age=<maxage>\r\n" into out(z-term).
173func cd_setcookie(val: *u8, val_len: i64, maxage: i64, out: *u8) -> i64 {
174 var o: i64=0
175 let pre: *u8 = "Set-Cookie: nxc_auth=" as *u8
176 var i: i64=0
177 while pre[i]!=(0 as u8) { out[o]=pre[i]; o=o+1; i=i+1 }
178 var v: i64=0
179 while v<val_len { out[o]=val[v]; o=o+1; v=v+1 }
180 let mid: *u8 = "; Path=/; HttpOnly; SameSite=Lax; Max-Age=" as *u8
181 i=0
182 while mid[i]!=(0 as u8) { out[o]=mid[i]; o=o+1; i=i+1 }
183 let t: *u8 = sys_mmap(28)
184 var m: i64=maxage
185 var k: i64=0
186 if m==0 { out[o]=48 as u8; o=o+1 } else { while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 } var jj: i64=0; while jj<k { out[o]=t[k-1-jj]; o=o+1; jj=jj+1 } }
187 out[o]=13 as u8; o=o+1; out[o]=10 as u8; o=o+1
188 out[o]=0 as u8
189 return o
190}
191
192// digits only, bounded by n -- a form field is untrusted input (rule 12) and must not run off its length
193func cd_atoi_n(s: *u8, n: i64) -> i64 {
194 var v: i64=0; var i: i64=0
195 while i<n { let c: i64 = s[i] as i64; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 }
196 return v
197}
198// wrap a JSON body in a minimal HTTP/1.1 response; returns total bytes, 0 if it will not fit
199func cd_json_resp(body: *u8, bn: i64, out: *u8, cap: i64) -> i64 {
200 if bn<=0 { return 0 }
201 var o: i64=0
202 o = cs_cat(out, o, "HTTP/1.1 200 OK
203Content-Type: application/json
204Cache-Control: no-store
205Content-Length: " as *u8)
206 o = cs_catn(out, o, bn)
207 o = cs_cat(out, o, "
208Connection: close
209
210" as *u8)
211 if o+bn >= cap { return 0 }
212 var i: i64=0
213 while i<bn { out[o+i]=body[i]; i=i+1 }
214 return o+bn
215}
216func main() -> i64 {
217 let ctx: *i64 = cs_world_new()
218 let dir: *u8 = "connect\x00" as *u8
219 sys_mkdir(dir, 0x1ff)
220 // ---- OPAQUE auth context: fail-CLOSED if the realm keys cannot be provisioned (never serve unauthed-broken) ----
221 let actx: *NxAuthContext = sys_mmap(256) as *NxAuthContext
222 if olg_ctx_setup_ttl(actx, CD_AUTH_KEYS, CD_AUTH_STORE, CD_REALM, CD_REALM_N, CD_DISP, CD_DISP_N, CD_SESS_TTL, CD_ARGON_M, CD_ARGON_T, CD_ARGON_P) != 0 {
223 cd_p("NX-CONNECT-APPD OPAQUE auth ctx FAILED (connect_auth_keys.bin unwritable?) -- fail closed, fail loud\n" as *u8)
224 return 1
225 }
226 // ---- shared content-blind plane: boot = replay the append-only log ----
227 let sh: *i64 = cs_shared_new()
228 let shlog: *u8 = "connect/shared.cbl\x00" as *u8
229 let shlenp: *i64 = sys_mmap(16) as *i64
230 let shboot: *u8 = sys_read_file(shlog, shlenp)
231 if (shboot as i64)!=0 { cs_sh_replay(sh, shboot, shlenp[0]) }
232 let shline: *u8 = sys_mmap(CD_MAGIC_1024)
233 let shcompact: *u8 = sys_mmap(CD_MAGIC_262144) // compaction rewrite buffer (whole minimal log)
234 let shtmp: *u8 = "connect/shared.cbl.tmp\x00" as *u8
235 var acks_since_compact: i64 = 0
236 let addr: *u8 = sys_mmap(16)
237 cd_addr(addr, CD_PORT)
238 let lfd: i64 = sys_socket(AF_INET, SOCK_STREAM, 0)
239 if lfd<0 { cd_p("NX-CONNECT-APPD socket FAILED\n" as *u8); return 1 }
240 let one: *i64 = (sys_mmap(8)) as *i64
241 one[0]=1
242 sys_setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, one as *u8, 4)
243 if sys_bind(lfd, addr, 16)<0 { cd_p("NX-CONNECT-APPD bind 0.0.0.0:8032 FAILED (port busy?)\n" as *u8); return 1 }
244 if sys_listen(lfd, 16)<0 { cd_p("NX-CONNECT-APPD listen FAILED\n" as *u8); return 1 }
245 cd_p("NX-CONNECT-APPD serving http://0.0.0.0:8032/ (OPAQUE login + per-account worlds + content-blind plane)\n" as *u8)
246 let reqb: *u8 = sys_mmap(CD_MAGIC_262144)
247 let resb: *u8 = sys_mmap(CD_MAGIC_1048576)
248 let resb2: *u8 = sys_mmap(CD_MAGIC_1048576)
249 let cookiebuf: *u8 = sys_mmap(256)
250 let sessbuf: *u8 = sys_mmap(64)
251 // auth per-request scratch (hoisted -- no per-request mmap)
252 let pathbuf: *u8 = sys_mmap(320)
253 let authtok: *u8 = sys_mmap(600) // nxc_auth cookie value (b64 token)
254 let uidbuf: *u8 = sys_mmap(64) // 32-byte user-id from whoami
255 let uidn: *i64 = sys_mmap(16) as *i64
256 let handlebuf: *u8 = sys_mmap(64) // display handle (from form or the per-account file)
257 let fhandle: *u8 = sys_mmap(64) // form handle
258 let fpw: *u8 = sys_mmap(300) // form passphrase
259 let newtok: *u8 = sys_mmap(600) // freshly minted session token (b64)
260 let newtokn: *i64 = sys_mmap(16) as *i64
261 let mnbuf: *u8 = sys_mmap(600) // recovery mnemonic (shown once)
262 let mnn: *i64 = sys_mmap(16) as *i64
263 let ckline: *u8 = sys_mmap(768) // Set-Cookie line
264 var salt: i64 = 0
265 var go: i64=1
266 while go==1 {
267 let cfd: i64 = sys_accept(lfd) // 1-arg accept (the opaque_login syscall set; peer addr not needed)
268 if cfd>=0 {
269 let rn: i64 = cs_read_req(cfd, reqb, CD_MAGIC_262144)
270 if rn>0 {
271 let now: i64 = sys_now_realtime_sec()
272 let is_post: i64 = cd_is_post(reqb)
273 // ---- parse path, strip the /connect edge prefix ----
274 cd_req_path(reqb, rn, pathbuf, 320)
275 var pp: *u8 = pathbuf
276 if cs_starts(pp, "/connect" as *u8)==1 { pp = (pathbuf as i64 + 8) as *u8 }
277 if pp[0]==(0 as u8) { pp = "/" as *u8 }
278 // strip any query string from pp (so /account?x still matches /account)
279 var qi: i64=0
280 while pp[qi]!=(0 as u8) { if pp[qi]==(63 as u8) { pp[qi]=0 as u8 } qi=qi+1 }
281
282 // ---- resolve current identity from the nxc_auth cookie ----
283 var authed: i64 = 0
284 handlebuf[0]=0 as u8
285 var acct: i64 = 0
286 var auth_event: i64 = CS_AE_NONE
287 var cookie_action: i64 = 0 // 0 none, 1 set token, 2 clear token
288 var mn_show: i64 = 0
289 let al: i64 = cd_cookie_val(reqb, rn, "nxc_auth=" as *u8, 9, authtok, 600)
290 if al > 0 {
291 if olg_whoami(actx, authtok, al, now, uidbuf, 64, uidn) == NX_MAUTH_OK {
292 authed = 1
293 acct = acc_id_from_range(uidbuf, uidn[0])
294 cd_read_handle(acct, handlebuf, 64)
295 }
296 }
297
298 // ---- auth POST actions (crypto in the shell) ----
299 // body = after CRLFCRLF (cs_form_get needs the field at a boundary: body-start or after '&').
300 var aboff: i64 = rn
301 var aj: i64=0
302 while aj+3<rn { if reqb[aj]==(13 as u8) { if reqb[aj+1]==(10 as u8) { if reqb[aj+2]==(13 as u8) { if reqb[aj+3]==(10 as u8) { aboff=aj+4; aj=rn } } } } aj=aj+1 }
303 let abody: *u8 = (reqb as i64 + aboff) as *u8
304 let ablen: i64 = rn - aboff
305 if is_post==1 {
306 if cs_seq(pp, "/login" as *u8)==1 {
307 let hn: i64 = cs_form_get(abody, ablen, "handle" as *u8, fhandle, 32)
308 let pn: i64 = cs_form_get(abody, ablen, "pw" as *u8, fpw, 256)
309 cd_lower(fhandle, hn)
310 var lhn: i64 = 0; while fhandle[lhn]!=(0 as u8) { lhn=lhn+1 }
311 if olg_login(actx, fhandle, lhn, fpw, pn, newtok, 600, newtokn) == NX_MAUTH_OK {
312 if olg_whoami(actx, newtok, newtokn[0], now, uidbuf, 64, uidn) == NX_MAUTH_OK {
313 authed = 1
314 acct = acc_id_from_range(uidbuf, uidn[0])
315 cd_write_handle(acct, fhandle, lhn)
316 var w: i64=0; while fhandle[w]!=(0 as u8) { handlebuf[w]=fhandle[w]; w=w+1 } handlebuf[w]=0 as u8
317 cookie_action = 1
318 auth_event = CS_AE_SIGNED_IN
319 }
320 } else { auth_event = CS_AE_LOGIN_FAIL }
321 }
322 else { if cs_seq(pp, "/register" as *u8)==1 {
323 let hn: i64 = cs_form_get(abody, ablen, "handle" as *u8, fhandle, 32)
324 let pn: i64 = cs_form_get(abody, ablen, "pw" as *u8, fpw, 256)
325 cd_lower(fhandle, hn)
326 var lhn: i64 = 0; while fhandle[lhn]!=(0 as u8) { lhn=lhn+1 }
327 if cs_name_ok(fhandle)==0 { auth_event = CS_AE_REG_BAD }
328 else { if pn < CD_PW_MIN { auth_event = CS_AE_REG_BAD }
329 else {
330 let rrc: i64 = olg_register(actx, fhandle, lhn, fpw, pn, mnbuf, 600, mnn)
331 if rrc == NX_MAUTH_OK {
332 if olg_login(actx, fhandle, lhn, fpw, pn, newtok, 600, newtokn) == NX_MAUTH_OK {
333 if olg_whoami(actx, newtok, newtokn[0], now, uidbuf, 64, uidn) == NX_MAUTH_OK {
334 authed = 1
335 acct = acc_id_from_range(uidbuf, uidn[0])
336 cd_write_handle(acct, fhandle, lhn)
337 var w2: i64=0; while fhandle[w2]!=(0 as u8) { handlebuf[w2]=fhandle[w2]; w2=w2+1 } handlebuf[w2]=0 as u8
338 mnbuf[mnn[0]]=0 as u8
339 mn_show = 1
340 cookie_action = 1
341 auth_event = CS_AE_REGISTERED
342 }
343 }
344 } else { auth_event = CS_AE_REG_TAKEN }
345 } }
346 }
347 else { if cs_seq(pp, "/logout" as *u8)==1 {
348 authed = 0
349 handlebuf[0]=0 as u8
350 cookie_action = 2
351 auth_event = CS_AE_SIGNED_OUT
352 } } }
353 }
354
355 // ---- account_id: authenticated identity, else anonymous nxc_sess ----
356 var new_sess: i64 = 0
357 var slen: i64 = 0
358 if authed==1 {
359 // acct already set from the uid above
360 cs_world_reset(ctx)
361 acc_load(ctx, acct, dir)
362 } else {
363 let vl: i64 = acc_cookie_get(reqb, rn, cookiebuf, 256)
364 if vl > 0 { acct = acc_id_from_range(cookiebuf, vl) }
365 else { salt = salt + 1; slen = acc_session_mint(salt, sessbuf); acct = acc_id_from_range(sessbuf, slen); new_sess = 1 }
366 cs_world_reset(ctx)
367 acc_load(ctx, acct, dir)
368 }
369
370 // ---- stamp identity into ctx for rendering (survives world_reset because set AFTER it) ----
371 ctx[CS_AUTH] = authed
372 // stamp the authenticated 32-byte user-id so the /pubkey route can BIND the key to identity
373 // (kills trust-on-first-use). uidbuf holds the whoami hash; 0 for anonymous requests.
374 if authed==1 { ctx[CS_UID] = uidbuf as i64 } else { ctx[CS_UID] = 0 }
375 if authed==1 { ctx[CS_HANDLE] = handlebuf as i64 } else { ctx[CS_HANDLE] = 0 }
376 ctx[CS_AUTH_EVENT] = auth_event
377 if mn_show==1 { ctx[CS_MNEMONIC] = mnbuf as i64 } else { ctx[CS_MNEMONIC] = 0 }
378 ctx[CS_SH] = sh as i64 // the contacts page checks the shared pubkey directory for each contact
379
380 // ---- ALBUM / SHARING API (JSON) -- /connect/album/<verb> ----
381 // The crypto-and-syscall half lives here in the shell, exactly like auth: nx_connect_serve
382 // is a pure emitter and cannot touch seg_store. `acct` is the OPAQUE-derived account id and
383 // is passed straight through as the actor -- the caller never names themselves, so there is
384 // no identity to forge in the request. Signed-out is actor 0, which every mutating verb in
385 // al_do refuses (album gate T3/T3b).
386 var album_n: i64 = 0
387 let aitem: *u8 = sys_mmap(128)
388 if cs_starts(pp, "/album/" as *u8)==1 {
389 let averb: *u8 = ((pp as i64) + 7) as *u8
390 var asubj: i64 = 0
391 var arid: i64 = 0
392 if is_post==1 {
393 let sn: i64 = cs_form_get(abody, ablen, "subject" as *u8, fhandle, 32)
394 if sn > 0 { asubj = cd_atoi_n(fhandle, sn) }
395 let idn: i64 = cs_form_get(abody, ablen, "id" as *u8, fpw, 32)
396 if idn > 0 { arid = cd_atoi_n(fpw, idn) }
397 // item id for the containment verbs. Untrusted input: bounded, and left EMPTY when
398 // absent so al_do refuses rather than acting on a blank.
399 let itn: i64 = cs_form_get(abody, ablen, "item" as *u8, aitem, 96)
400 if itn <= 0 { aitem[0] = 0 as u8 }
401 } else { aitem[0] = 0 as u8 }
402 var aactor: i64 = 0
403 if authed==1 { aactor = acct }
404 let ajson: *u8 = sys_mmap(CD_MAGIC_1024*8)
405 let ajn: i64 = al_do(CD_SHARE_PREFIX, averb, aactor, asubj, "album" as *u8, arid, aitem, ajson, CD_MAGIC_1024*8)
406 album_n = cd_json_resp(ajson, ajn, resb, CD_MAGIC_1048576)
407 }
408
409 // ---- handle (session plane + shared plane) ----
410 let np0: i64 = sh[0]
411 let nm0: i64 = sh[1]
412 let pg0: i64 = sh[3]
413 let ag0: i64 = sh[4]
414 var on: i64 = 0
415 if album_n==0 { on = cs_handle2(ctx, sh, reqb, rn, resb, CD_MAGIC_1048576) }
416 if is_post == 1 {
417 if authed==1 { acc_save(ctx, acct, dir) }
418 else { if cookie_action==0 { acc_save(ctx, acct, dir) } } // anon POST persists too (unless logout)
419 // shared plane deltas (append-only)
420 if sh[3]!=pg0 {
421 let af: i64 = sys_openat_append(shlog, 0x1a4)
422 if af>=0 {
423 if sh[0]>np0 {
424 var ai: i64=np0
425 while ai<sh[0] { let an: i64 = cs_sh_emit_pub(sh, ai, shline, 0); sys_write(af, shline, an); ai=ai+1 }
426 } else {
427 if sh[2]>=0 { let au: i64 = cs_sh_emit_pub(sh, sh[2], shline, 0); sys_write(af, shline, au) }
428 }
429 sys_close(af)
430 }
431 }
432 if sh[1]>nm0 {
433 let af2: i64 = sys_openat_append(shlog, 0x1a4)
434 if af2>=0 {
435 var mi: i64=nm0
436 while mi<sh[1] { let mn2: i64 = cs_sh_emit_msg(sh, mi, shline, 0); sys_write(af2, shline, mn2); mi=mi+1 }
437 sys_close(af2)
438 }
439 }
440 // delete-on-delivery: an ack tombstoned a message -> persist a D row so it stays delivered.
441 if sh[4]!=ag0 {
442 if sh[5]>=0 {
443 let af3: i64 = sys_openat_append(shlog, 0x1a4)
444 if af3>=0 { let tn: i64 = cs_sh_emit_tomb(sh, sh[5], shline, 0); sys_write(af3, shline, tn); sys_close(af3) }
445 }
446 // COMPACTION: after enough deliveries, PHYSICALLY rewrite shared.cbl to a minimal log
447 // that drops every tombstoned message -- delivered ciphertext + metadata bytes are then
448 // GONE FROM DISK (delete-on-delivery becomes physical), and the log can't grow unbounded.
449 // Atomic (tmp + rename) so a crash never leaves a torn log; on next boot the compacted
450 // file replays into a clean plane. Runs between requests (single-process accept loop).
451 acks_since_compact = acks_since_compact + 1
452 if acks_since_compact >= CD_COMPACT_EVERY {
453 let cn: i64 = cs_sh_compact_emit(sh, shcompact)
454 let cf: i64 = sys_openat_wr(shtmp, 0x1a4)
455 if cf>=0 {
456 cs_write_all(cf, shcompact, cn)
457 sys_fsync(cf)
458 sys_close(cf)
459 if sys_renameat(shtmp, shlog) >= 0 { acks_since_compact = 0 }
460 }
461 }
462 }
463 }
464
465 // ---- respond (inject the right cookie) ----
466 if album_n>0 { cs_write_all(cfd, resb, album_n) } else {
467 if cookie_action==1 {
468 cd_setcookie(newtok, newtokn[0], CD_SESS_TTL, ckline)
469 let onx: i64 = cd_inject_line(resb, on, ckline, resb2, CD_MAGIC_1048576)
470 if onx > 0 { cs_write_all(cfd, resb2, onx) }
471 } else { if cookie_action==2 {
472 cd_setcookie("" as *u8, 0, 0, ckline)
473 let onx2: i64 = cd_inject_line(resb, on, ckline, resb2, CD_MAGIC_1048576)
474 if onx2 > 0 { cs_write_all(cfd, resb2, onx2) }
475 } else { if new_sess == 1 {
476 let on2: i64 = acc_inject_cookie(resb, on, sessbuf, slen, resb2, CD_MAGIC_1048576)
477 if on2 > 0 { cs_write_all(cfd, resb2, on2) }
478 } else {
479 if on > 0 { cs_write_all(cfd, resb, on) }
480 } } } }
481 }
482 sys_close(cfd)
483 }
484 }
485 return 0
486}