nx_nofloat_serve_core.nx source
↩ module page · 1382 lines · 69093 B
1// nx_nofloat_serve_core.nx -- the PURE CORE of the no-float LLM serve organ (2026-07-10): model session +
2// greedy generation + HTTP request handler, NO sockets (the daemon shell owns those; the gate exercises this
3// core in-process with synthetic requests -- the proven pure-core+gate+daemon idiom).
4// nsv_init(path) one-time: load GGUF, tokenizer meta, dequant-once i32 (lossless hero) + i8 (fast) caches.
5// nsv_generate(gp) ctx-bundle: sequential CACHED prefill (decode_step per prompt token -- mathematically
6// identical to batch prefill under causal masking) then greedy decode; text out through
7// the byte-level-BPE inverse (nx_nofloat_tokdec) so ' Paris' renders as real text.
8// nsv_handle(...) routes: GET / (app page) GET /health GET /api POST /gen {prompt,max_new,mode}.
9// license_tier: ORIGINAL No hw writes (Rule 26).
10import "nx_syscalls.nx"
11import "nx_tier.nx"
12import "nx_le.nx"
13import "nx_tensor.nx"
14import "nx_gguf.nx"
15import "nx_gguf_load.nx"
16import "nx_gguf_meta.nx"
17import "nx_nofloat_llm.nx"
18import "nx_nofloat_tok.nx"
19import "nx_nofloat_tokdec.nx"
20import "nx_nofloat_arch.nx"
21import "nx_nofloat_q4k.nx" // LM4 resident-Q4_K decode (2026-09-02): the 7B fits because the weights stay in the file map
22
23const NSV_MAXT: i64 = 2048 // final prompt+gen TOKEN cap (KV cache rows). L2 raise 384->2048 (FORGE 2026-07-12)
24 // so a mini-pack (~1300 tok) + task + whole-organ generation fits. Decode buffers +
25 // KV cache scale with this: ~+200MB at 2048 for the 0.5B coder (24L, kvd=128, ne=896)
26 // -- well within WSL 16GB alongside the ~700MB model + i32/i8 caches. Gated L2.
27const NSV_MAXIN: i64 = 16384 // max prompt BYTES for the tokenizer's byte-level pretokenize scratch (tok_ptr/tok_len).
28 // L2 raise 8192->16384 for the full mini-pack (3911B) + task headroom.
29 // ⚠ tk_bpe_encode seeds 1 slot per INPUT BYTE -> those buffers MUST be sized by bytes,
30 // NOT NSV_MAXT (the old NSV_MAXT*8 page-rounded to 512 entries -> SIGSEGV on >512-byte prompts).
31const NSV_MAXNEW: i64 = 512 // per-request generation cap (L2 raise 96->512 for whole small organs)
32const NSV_CHATML_IDS: i64 = 8 // ids the ChatML wrapper adds around the content (two markers plus the user, newline and assistant pieces)
33const NSV_ERR_TOO_LONG: i64 = 3 // meta[5] for a prompt past the byte cap or the token cap: refused at the door, never half-encoded
34const NSV_PREFILL_BATCHED_DEFAULT: i64 = 1 // R0r: the i8 route prefills in blocks through nf_prefill_batched (nx_nofloat_prefill_gate proves it bit-identical); declared here because its first reader is the scratch allocator
35const NSV_EOS1: i64 = 151643
36const NSV_EOS2: i64 = 151645
37
38static g_nsv_buf: *u8
39static g_nsv_hdr: *NxGgufHeader
40static g_nsv_wc32: *i64
41static g_nsv_wc8: *i64
42static g_nsv_wq4: *i64 // LM4: per-layer resident-Q4_K slot tables (nx_nofloat_q4k), built instead of wc8 when g_nsv_q4k
43static g_nsv_q4k: i64 // 1 = resident-Q4_K serve: model file-mapped, no i32/i16 layer caches, decode mode 3
44static g_nsv_q4st: *i64 // NQ_ST_WORDS census of the q4k build (in-place vs fallback tensors and bytes)
45static g_nsv_hcp: *i64
46static g_nsv_sb: *i64
47static g_nsv_kvc: *i64
48static g_nsv_freqs: *i64
49static g_nsv_cfgA: *i64
50static g_nsv_cfgF: *i64
51static g_nsv_tmp: *i64
52static g_nsv_x1: *i64
53static g_nsv_h1: *i64
54static g_nsv_xt: *i64 // R0r: the prompt's dequantised embedding rows (NSV_MAXT x ne)
55static g_nsv_prefill_batched: i64 // R0r: 1 = blocks through nf_prefill_batched on the i8 route, 0 = the sequential control
56static g_nsv_normed: *i64
57static g_nsv_gout: *i64
58static g_nsv_idout: *i64
59static g_nsv_lgout: *i64
60static g_nsv_nmbuf: *u8
61static g_nsv_ids: *i64
62static g_nsv_tokp: *i64
63static g_nsv_tokl: *i64
64static g_nsv_lgv: *i64 // full vocab logits (sampling path)
65static g_nsv_mt: *i64 // [0]=mfirst [1]=nm_c [2]=vfirst [3]=vocab [4]=te_base [5]=te_ty [6]=ready [7]=init_ms
66static g_nsv_mpath: *u8 // the ACTUAL loaded model path (health must not lie about which model serves)
67static g_nsv_dims: *i64 // arch-config (nac_read_config 2026-07-15): [0]=D [1]=n_layers [2]=n_heads [3]=n_kv [4]=head_dim [5]=q_dim [6]=kv_dim [7]=ffn [8]=scale_q16 [9]=rope_base [10]=ok
68static g_nsv_kvsnap: *i64 // PREFIX-KV-CACHE (2026-07-15): snapshot of KV rows 0..P-1 (the fixed prompt prefix) for reuse across requests
69static g_nsv_snap_p: i64 // number of prefix tokens currently snapshotted (0 = none)
70static g_nsv_crib_ids: *i64 // the snapshotted prefix's token ids (for common-prefix safety vs BPE re-tokenization)
71
72func nsv_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
73func nsv_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i }
74func nsv_catb(dst: *u8, off: i64, s: *u8, n: i64) -> i64 { var i: i64=0; while i<n {dst[off+i]=s[i];i=i+1} return off+n }
75func nsv_catn(dst: *u8, off: i64, v: i64) -> i64 {
76 var o: i64=off
77 var m: i64=v
78 if m<0 { dst[o]=45 as u8; o=o+1; m=0-m }
79 let t: *u8=sys_mmap(28)
80 var k: i64=0
81 if m==0 { t[0]=48 as u8; k=1 }
82 while m>0 { t[k]=(48+(m%10)) as u8; m=m/10; k=k+1 }
83 var i: i64=0
84 while i<k { dst[o+i]=t[k-1-i]; i=i+1 }
85 return o+k
86}
87
88func nsv_log(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
89
90// g_nsv_mt layout: [0]=mfirst [1]=nm_c [2]=vfirst [3]=vocab [4]=te_base [5]=te_ty [6]=ready [7]=init_ms
91// [8]=oh_base [9]=oh_ty (head tensor -- passed to nsv_build_caches via statics)
92
93// STAGE 1: read model, parse, resolve tokenizer meta + the 3 tensors, load output-norm. NO pooled calls.
94// Split from nsv_init (single responsibility + lean frame: the fused 150-line init hit an nx_cc large-frame
95// codegen edge -- a GP fault at the first pooled call -- that vanishes when each stage is its own function).
96func nsv_load_meta(path: *u8) -> i64 {
97 let len_out: *i64 = sys_mmap(8) as *i64
98 len_out[0]=0
99 if g_nsv_q4k == 1 {
100 // LM4: the weights are READ IN PLACE, so the model must be a file-backed map (evictable page cache),
101 // never a 4.7 GB anonymous copy. sys_map_file is read-only by construction (Rule 26).
102 nsv_log(" [init] mapping model (file-backed, resident-Q4_K)...\n" as *u8)
103 g_nsv_buf = sys_map_file(path, len_out)
104 } else {
105 nsv_log(" [init] reading model...\n" as *u8)
106 g_nsv_buf = sys_read_file(path, len_out)
107 }
108 if (g_nsv_buf as i64) == 0 { return 1 }
109 g_nsv_hdr = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader
110 nsv_log(" [init] parsing gguf...\n" as *u8)
111 if nx_gguf_parse(g_nsv_buf, len_out[0], g_nsv_hdr) != NX_GGUF_OK { return 2 }
112 // ARCH-CONFIG (2026-07-15): dims from the model's own metadata (nac_read_config, gate-proven 07-10) --
113 // ANY Qwen2/Llama-schema gguf serves; for the 0.5B these are the SAME numbers, now read instead of assumed.
114 g_nsv_dims = sys_mmap(16*8) as *i64
115 let arch_out: *u8 = sys_mmap(48)
116 if nac_read_config(g_nsv_buf, len_out[0], g_nsv_hdr, g_nsv_dims, arch_out) != 0 { return 8 }
117 if g_nsv_dims[10] != 1 { return 8 }
118 // FAIL-FAST TYPE SCAN (2026-07-15 debt-eaten): every tensor's quant type must be supported BEFORE we
119 // serve. Unknown types used to zero/wrong-decode SILENTLY mid-token; now init refuses (error 10) and
120 // the daemon never comes up on a model we cannot faithfully decode. (⚠hsc is a FRESH local -- the
121 // first cut used `hloc` which is declared LATER in this fn; nx_cc accepts use-before-declare of a
122 // local and reads stack garbage -> SEGV. The LOCAL sibling of the fwd-static-ref gotcha.)
123 let hsc: *NxGgufHeader = g_nsv_hdr
124 let vbts: *i64 = sys_mmap(16) as *i64
125 var tscan: i64 = 0
126 while tscan < hsc.tensor_count {
127 let tsi: *NxGgufTensorInfo = nx_gguf_tensor_at(hsc, tscan)
128 if nf_type_stride(tsi.ggml_type, vbts) != 0 { return 10 }
129 tscan = tscan + 1
130 }
131 let ne: i64 = g_nsv_dims[0]
132 // hloc: local copy of the static header pointer. This organ FOUND the static-base member-access
133 // miscompile (g_nsv_hdr.data_off returned the pointer, not the field) -- ROOT-FIXED + BLESSED
134 // 2026-07-10 (nx_parse VK_GLOBAL unwrap, nx_static_field_probe pins it). The local copy stays as
135 // style: one load, then cheap field reads.
136 let hloc: *NxGgufHeader = g_nsv_hdr
137 g_nsv_mt = sys_mmap(16*8) as *i64
138 let voff: *i64=sys_mmap(8) as *i64
139 let vty: *i64=sys_mmap(8) as *i64
140 let km: *u8="tokenizer.ggml.merges" as *u8
141 let kt: *u8="tokenizer.ggml.tokens" as *u8
142 if nx_gguf_meta_find(g_nsv_buf, len_out[0], g_nsv_hdr, km, nsv_slen(km), voff, vty)==NX_GMETA_OK {
143 g_nsv_mt[1]=nx_gguf_meta_array_count(g_nsv_buf, voff[0])
144 g_nsv_mt[0]=nx_gguf_meta_array_first_elt_off(g_nsv_buf, voff[0])
145 } else { return 3 }
146 if nx_gguf_meta_find(g_nsv_buf, len_out[0], g_nsv_hdr, kt, nsv_slen(kt), voff, vty)==NX_GMETA_OK {
147 g_nsv_mt[3]=nx_gguf_meta_array_count(g_nsv_buf, voff[0])
148 g_nsv_mt[2]=nx_gguf_meta_array_first_elt_off(g_nsv_buf, voff[0])
149 } else { return 4 }
150 let nt: *u8="token_embd.weight" as *u8
151 let no: *u8="output.weight" as *u8
152 let nn: *u8="output_norm.weight" as *u8
153 let ie: nx_int=nx_gguf_find_tensor(g_nsv_hdr, nt, 17)
154 var io: nx_int=nx_gguf_find_tensor(g_nsv_hdr, no, 13)
155 let inn: nx_int=nx_gguf_find_tensor(g_nsv_hdr, nn, 18)
156 if ie<0 { return 5 }
157 if io<0 { io = ie } // tied-embeddings fallback: qwen2-0.5b ties lm_head to token_embd; embedding-model GGUFs (jina) omit output.weight entirely
158 if inn<0 { return 5 }
159 let te: *NxGgufTensorInfo=nx_gguf_tensor_at(hloc, ie)
160 g_nsv_mt[4]=hloc.data_off+te.offset
161 g_nsv_mt[5]=te.ggml_type
162 let oh: *NxGgufTensorInfo=nx_gguf_tensor_at(hloc, io)
163 g_nsv_mt[8]=hloc.data_off+oh.offset
164 g_nsv_mt[9]=oh.ggml_type
165 nsv_log(" [init] tensors located; loading output norm...\n" as *u8)
166 g_nsv_gout=sys_mmap(ne*8) as *i64
167 load_named_q16(g_nsv_buf, g_nsv_hdr, nn, 18, g_nsv_gout, ne)
168 return 0
169}
170
171// STAGE 2: allocate all per-request scratch + KV caches (sized to the serve MAXT). NO pooled calls.
172func nsv_alloc_scratch() -> i64 {
173 let ne: i64 = g_nsv_dims[0]
174 let qd: i64 = g_nsv_dims[5]
175 let kvd: i64 = g_nsv_dims[6]
176 let fd: i64 = g_nsv_dims[7]
177 let nl: i64 = g_nsv_dims[1]
178 let hd: i64 = g_nsv_dims[4]
179 nsv_log(" [init] allocating scratch + kv...\n" as *u8)
180 g_nsv_sb=sys_mmap(14*8) as *i64
181 g_nsv_sb[0]=sys_mmap(NSV_MAXT*ne*8) as i64
182 g_nsv_sb[1]=sys_mmap(NSV_MAXT*qd*8) as i64
183 g_nsv_sb[2]=sys_mmap(NSV_MAXT*kvd*8) as i64
184 g_nsv_sb[3]=sys_mmap(NSV_MAXT*kvd*8) as i64
185 g_nsv_sb[4]=sys_mmap(NSV_MAXT*qd*8) as i64
186 g_nsv_sb[5]=sys_mmap(NSV_MAXT*8) as i64
187 g_nsv_sb[6]=sys_mmap(NSV_MAXT*8) as i64
188 g_nsv_sb[7]=sys_mmap(NSV_MAXT*ne*8) as i64
189 g_nsv_sb[8]=sys_mmap(NSV_MAXT*fd*8) as i64
190 g_nsv_sb[9]=sys_mmap(NSV_MAXT*fd*8) as i64
191 g_nsv_sb[10]=sys_mmap(NSV_MAXT*fd*8) as i64
192 g_nsv_sb[11]=sys_mmap(NSV_MAXT*ne*8) as i64
193 g_nsv_sb[12]=sys_mmap(NSV_MAXT*ne*8) as i64
194 g_nsv_sb[13]=sys_mmap(NSV_MAXT*ne*8) as i64
195 g_nsv_kvc=sys_mmap(2*nl*8) as *i64
196 var kl: i64=0
197 while kl<nl { g_nsv_kvc[2*kl]=sys_mmap(NSV_MAXT*kvd*8) as i64; g_nsv_kvc[2*kl+1]=sys_mmap(NSV_MAXT*kvd*8) as i64; kl=kl+1 }
198 g_nsv_nmbuf=sys_mmap(64)
199 g_nsv_freqs=sys_mmap(hd*8) as *i64
200 rope_freqs(g_nsv_freqs, hd)
201 g_nsv_tmp=sys_mmap(64*256*8) as *i64
202 g_nsv_x1=sys_mmap(ne*8) as *i64
203 g_nsv_h1=sys_mmap(ne*8) as *i64
204 g_nsv_xt=sys_mmap(NSV_MAXT*ne*8) as *i64
205 g_nsv_prefill_batched=NSV_PREFILL_BATCHED_DEFAULT
206 g_nsv_normed=sys_mmap(ne*8) as *i64
207 g_nsv_idout=sys_mmap(8) as *i64
208 g_nsv_lgout=sys_mmap(8) as *i64
209 g_nsv_ids=sys_mmap((NSV_MAXIN + NSV_CHATML_IDS)*8) as *i64 // sized by BYTES like tokp/tokl (a token covers >= 1 byte, so ntok <= bytes): the token-cap check below is then always reached instead of an overrun (2026-09-17: a 19222-byte BRIGHT query overran the 2048-entry buffer and the serving engine died in tk_rank_fast)
210 g_nsv_tokp=sys_mmap(NSV_MAXIN*8) as *i64 // 1 slot per INPUT BYTE (byte-level pretokenize) -> size by BYTES
211 g_nsv_tokl=sys_mmap(NSV_MAXIN*8) as *i64
212 let vcl: i64 = g_nsv_mt[3]
213 g_nsv_lgv=sys_mmap(vcl*8) as *i64
214 g_nsv_cfgA=sys_mmap(8*8) as *i64
215 g_nsv_cfgA[1]=ne
216 g_nsv_cfgA[2]=g_nsv_dims[2]
217 g_nsv_cfgA[3]=g_nsv_dims[3]
218 g_nsv_cfgA[4]=hd
219 g_nsv_cfgA[5]=qd
220 g_nsv_cfgA[6]=kvd
221 g_nsv_cfgA[7]=g_nsv_dims[8]
222 g_nsv_cfgF=sys_mmap(4*8) as *i64
223 g_nsv_cfgF[1]=ne
224 g_nsv_cfgF[2]=fd
225 return 0
226}
227
228// ---- one-time session init (fail-fast: any error -> nonzero, organ must not serve). Thin orchestrator
229// over three lean stages -- each its own frame so the pooled STAGE 3 never shares a frame with the big
230// STAGE 1/2 setup (the large-frame codegen edge that GP-faulted the fused version). ----
231// LIGHT INIT (2026-07-16, memory-proportionate loading): i8-only serve skips the i32 weight cache (~4 bytes/param
232// -- the single biggest allocation; ~6GB at 1.5B) so a mode-1-pinned organ fits comfortably inside the WSL VM
233// (host-pressure kills root-caused: 32GB host, dual-cache 1.5B init ~11GB -> intermittent SIGKILL of the tree).
234// Head cache stays (sampling needs full logits). CONTRACT: after nsv_init_i8, callers MUST pin mode=1 (gp[3]=1);
235// mode 0 would read the absent i32 cache.
236static g_nsv_i8only: i64
237static g_nsv_noi8: i64 // 1 = lossless-only init: the i32 cache and NO i8 cache (the quantisation-gap probe on a 16 GB VM)
238func nsv_init_i8(path: *u8) -> i64 {
239 g_nsv_i8only = 1
240 return nsv_init(path)
241}
242// LOSSLESS-ONLY INIT (2026-09-17, the quantisation-gap probe): the i32 cache and NO i8 cache, so a probe that decodes
243// mode 0 only fits beside the running i8 engine on a 16 GB VM. CONTRACT: callers pin mode=0 (gp[3]=0); mode 1 would
244// read the absent i8 cache.
245func nsv_init_i32only(path: *u8) -> i64 {
246 g_nsv_noi8 = 1
247 return nsv_init(path)
248}
249// LM4 RESIDENT-Q4_K INIT (2026-09-02): no i32 layer cache, no i16 layer cache -- every Q4_K projection is dotted
250// in place from the file map (nx_nofloat_q4k); non-Q4_K tensors fall back per tensor to i16 and are counted.
251// Head cache stays i32 (sampling needs full logits). CONTRACT: callers use decode mode 3 (the request parser
252// defaults to it and refuses i32/i8, whose caches were never built).
253func nsv_init_q4k(path: *u8) -> i64 {
254 g_nsv_q4k = 1
255 g_nsv_i8only = 1
256 return nsv_init(path)
257}
258func nsv_init(path: *u8) -> i64 {
259 let t0: i64 = sys_now_ms()
260 g_nsv_mpath = path
261 // Spawn the worker pool at startup (fail-fast: workers ready before the first request, not on first
262 // token). nf_pool is idempotent -> the cache build + every decode reuse this instance.
263 nsv_log(" [init] pre-warming worker pool...\n" as *u8)
264 nf_pool()
265 let rc1: i64 = nsv_load_meta(path)
266 if rc1 != 0 { return rc1 }
267 nsv_alloc_scratch()
268 let brc: i64 = nsv_build_caches()
269 if brc != 0 { return brc }
270 g_nsv_mt[7]=sys_now_ms()-t0
271 g_nsv_mt[6]=1
272 return 0
273}
274
275// STAGE 3: build the dequant-once caches (i32 head + i32 layers + i8 layers). The ONLY pooled stage;
276// reads oh_base/oh_ty from g_nsv_mt[8]/[9]. Lean frame = no GP fault at nf_pool() first-touch.
277func nsv_build_caches() -> i64 {
278 let ne: i64 = g_nsv_dims[0]
279 let qd: i64 = g_nsv_dims[5]
280 let kvd: i64 = g_nsv_dims[6]
281 let fd: i64 = g_nsv_dims[7]
282 let nl: i64 = g_nsv_dims[1]
283 let oh_base: i64 = g_nsv_mt[8]
284 let oh_ty: i64 = g_nsv_mt[9]
285 let vcb: i64 = g_nsv_mt[3]
286 nsv_log(" [init] building i32 head cache...\n" as *u8)
287 let hcache: *i32 = nf_dequant_head_all_i32(g_nsv_buf, oh_base, oh_ty, vcb, ne)
288 if (hcache as i64) <= 0 { return 7 }
289 if g_nsv_i8only == 0 {
290 nsv_log(" [init] building i32 weight cache (dequant-once)...\n" as *u8)
291 g_nsv_wc32=sys_mmap(nl*8) as *i64
292 let ovf: i64=nf_dequant_all_layers_i32(g_nsv_buf, g_nsv_hdr, g_nsv_wc32, nl, ne, qd, kvd, fd)
293 if ovf != 0 { return 6 }
294 } else {
295 nsv_log(" [init] i8-only: skipping i32 weight cache (memory-proportionate)\n" as *u8)
296 }
297 if g_nsv_q4k == 1 {
298 nsv_log(" [init] building resident-Q4_K slot tables (weights stay in the file map)...\n" as *u8)
299 g_nsv_wq4=sys_mmap(nl*8) as *i64
300 g_nsv_q4st=sys_mmap(NQ_ST_WORDS*8) as *i64
301 if nq_build_layers(g_nsv_buf, g_nsv_hdr, g_nsv_wq4, nl, ne, qd, kvd, fd, g_nsv_nmbuf, g_nsv_q4st) != 0 { return 11 }
302 nsv_log(" [init] q4k layers=" as *u8); nsv_logn(g_nsv_q4st[3])
303 nsv_log(" inplace_tensors=" as *u8); nsv_logn(g_nsv_q4st[0])
304 nsv_log(" inplace_file_bytes=" as *u8); nsv_logn(g_nsv_q4st[4])
305 nsv_log(" fallback_i16_tensors=" as *u8); nsv_logn(g_nsv_q4st[1])
306 nsv_log(" fallback_anon_bytes=" as *u8); nsv_logn(g_nsv_q4st[2])
307 nsv_log(" q8_tensors=" as *u8); nsv_logn(g_nsv_q4st[5]); nsv_log(" q8_file_bytes=" as *u8); nsv_logn(g_nsv_q4st[6])
308 nsv_log("\n" as *u8)
309 } else { if g_nsv_noi8 == 1 {
310 nsv_log(" [init] lossless-only: skipping i8 weight cache (this process decodes mode 0 only)\n" as *u8)
311 } else {
312 nsv_log(" [init] building i8 weight cache...\n" as *u8)
313 g_nsv_wc8=sys_mmap(nl*8) as *i64
314 nf_dequant_all_layers_i8(g_nsv_buf, g_nsv_hdr, g_nsv_wc8, nl, ne, qd, kvd, fd)
315 } }
316 nsv_log(" [init] caches ready\n" as *u8)
317 g_nsv_hcp=sys_mmap(6*8) as *i64
318 g_nsv_hcp[0]=hcache as i64
319 g_nsv_hcp[1]=g_nsv_normed as i64
320 g_nsv_hcp[2]=g_nsv_mt[3]
321 g_nsv_hcp[3]=ne
322 g_nsv_hcp[4]=g_nsv_idout as i64
323 g_nsv_hcp[5]=g_nsv_lgout as i64
324 return 0
325}
326
327func nsv_logn(v: i64) -> i64 { let t: *u8 = sys_mmap(32); let n: i64 = nsv_catn(t, 0, v); sys_write(1, t, n); return 0 }
328
329// one cached decode step at pos in the requested mode (0=i32 lossless, 1=i8 SIMD fast, 3=resident-Q4_K in place).
330const NSV_MODE_I32: i64 = 0
331const NSV_MODE_I8: i64 = 1
332const NSV_MODE_Q4K: i64 = 3 // 2 is the GPU embed grading mode (nsv_embed) -- never reuse it for a decode route
333func nsv_step(pos: i64, mode: i64) -> i64 {
334 if mode == NSV_MODE_Q4K {
335 decode_step_kv_q4k(g_nsv_x1, g_nsv_h1, g_nsv_wq4, g_nsv_sb, g_nsv_freqs, g_nsv_kvc, pos, g_nsv_cfgA, g_nsv_cfgF, g_nsv_dims[1])
336 return 0
337 }
338 if mode == 1 {
339 decode_step_kv_cached_i8(g_nsv_buf, g_nsv_hdr, g_nsv_x1, g_nsv_h1, g_nsv_wc8, g_nsv_sb, g_nsv_nmbuf, g_nsv_freqs, g_nsv_kvc, pos, g_nsv_cfgA, g_nsv_cfgF, g_nsv_dims[1])
340 } else {
341 decode_step_kv_cached_i32(g_nsv_buf, g_nsv_hdr, g_nsv_x1, g_nsv_h1, g_nsv_wc32, g_nsv_sb, g_nsv_nmbuf, g_nsv_freqs, g_nsv_kvc, pos, g_nsv_cfgA, g_nsv_cfgF, g_nsv_dims[1])
342 }
343 return 0
344}
345
346// R0r: the sequential prefill (one cached step per prompt token) -- the control nx_nofloat_prefill_gate measures against.
347func nsv_prefill_seq(nprompt: i64, mode: i64) -> i64 {
348 let ne: i64 = g_nsv_cfgA[1]
349 var i: i64 = 0
350 while i < nprompt {
351 dequant_row(g_nsv_buf, g_nsv_mt[4], g_nsv_mt[5], g_nsv_ids[i], ne, g_nsv_x1, g_nsv_tmp)
352 nsv_step(i, mode)
353 i = i + 1
354 }
355 return 0
356}
357// R0r: the prompt's rows through nf_prefill_batched in blocks of NF_PREFILL_M positions (one weight pass per block; the
358// block keeps the activation rows L2-resident). Leaves g_nsv_h1 exactly as the sequential path leaves it. The i8 route
359// only: the i32 and Q4_K routes keep nsv_prefill_seq, and nsv_generate_pfx (the forge's prefix-cache path) stays sequential.
360func nsv_prefill_i8_batched(nprompt: i64) -> i64 {
361 let ne: i64 = g_nsv_cfgA[1]
362 var i: i64 = 0
363 while i < nprompt {
364 dequant_row(g_nsv_buf, g_nsv_mt[4], g_nsv_mt[5], g_nsv_ids[i], ne, ((g_nsv_xt as i64)+i*ne*8) as *i64, g_nsv_tmp)
365 i = i + 1
366 }
367 var b: i64 = 0
368 while b < nprompt {
369 var T: i64 = NF_PREFILL_M
370 if b + T > nprompt { T = nprompt - b }
371 nf_prefill_batched(g_nsv_buf, g_nsv_hdr, ((g_nsv_xt as i64)+b*ne*8) as *i64, g_nsv_h1, g_nsv_wc8, g_nsv_sb, g_nsv_nmbuf, g_nsv_freqs, g_nsv_kvc, b, T, g_nsv_cfgA, g_nsv_cfgF, g_nsv_dims[1])
372 b = b + T
373 }
374 return 0
375}
376
377// xorshift64* PRNG step; state at sp[0] (never 0). Deterministic per seed -- "same in -> same bytes" holds
378// with the seed as part of the in.
379func nsv_rand(sp: *i64) -> i64 {
380 var s: i64 = sp[0]
381 s = s ^ (s >> 12)
382 s = s ^ (s << 25)
383 s = s ^ (s >> 27)
384 sp[0] = s
385 var r: i64 = s * 2685821657736338717
386 if r < 0 { r = 0 - r }
387 if r < 0 { r = 0 }
388 return r
389}
390// temperature/top-k/top-p sampling over the full logit vector -- 100 percent integer (logits are Q16 head
391// convention; fx_exp is the same Q16 exp the attention softmax rides). sp = [lgv, vocab, temp_pm, top_p_pm,
392// top_k, seed_state_ptr]. Returns the sampled token id.
393func nsv_sample(sp: *i64) -> i64 {
394 let lgv: *i64 = sp[0] as *i64
395 let vocab: i64 = sp[1]
396 var temp_pm: i64 = sp[2]
397 var top_p_pm: i64 = sp[3]
398 var k: i64 = sp[4]
399 let sd: *i64 = sp[5] as *i64
400 if temp_pm < 1 { temp_pm = 1 }
401 if temp_pm > 5000 { temp_pm = 5000 }
402 if top_p_pm < 1 { top_p_pm = 1 }
403 if top_p_pm > 1000 { top_p_pm = 1000 }
404 if k < 1 { k = 1 }
405 if k > 256 { k = 256 }
406 // top-k select (insertion into a small descending array; common case = 1 compare reject)
407 let kid: *i64 = sys_mmap(256*8) as *i64
408 let klg: *i64 = sys_mmap(256*8) as *i64
409 var n: i64 = 0
410 var v: i64 = 0
411 while v < vocab {
412 let l: i64 = lgv[v]
413 var take: i64 = 0
414 if n < k { take = 1 } else { if l > klg[n-1] { take = 1 } }
415 if take == 1 {
416 var pos: i64 = n
417 if pos >= k { pos = k - 1 }
418 var j: i64 = pos
419 while j > 0 { if l > klg[j-1] { klg[j]=klg[j-1]; kid[j]=kid[j-1]; j=j-1 } else { j = 0 - j } }
420 if j < 0 { j = 0 - j }
421 klg[j]=l
422 kid[j]=v
423 if n < k { n = n + 1 }
424 }
425 v = v + 1
426 }
427 // temperature -> Q16 exp weights (max-subtracted so fx_exp sees <= 0)
428 let ev: *i64 = sys_mmap(256*8) as *i64
429 let base: i64 = klg[0]
430 var total: i64 = 0
431 var i: i64 = 0
432 while i < n {
433 let x: i64 = ((klg[i] - base) * 1000) / temp_pm
434 let e: i64 = fx_exp(x)
435 ev[i] = e
436 total = total + e
437 i = i + 1
438 }
439 if total <= 0 { return kid[0] }
440 // top-p nucleus: keep the smallest prefix (descending) whose mass >= top_p_pm/1000 of total
441 let cutoff: i64 = (top_p_pm * total) / 1000
442 var m: i64 = 0
443 var cum: i64 = 0
444 var going: i64 = 1
445 while going == 1 {
446 if m >= n { going = 0 } else {
447 cum = cum + ev[m]
448 m = m + 1
449 if cum >= cutoff { going = 0 }
450 }
451 }
452 if m < 1 { m = 1 }
453 var mtotal: i64 = 0
454 i = 0
455 while i < m { mtotal = mtotal + ev[i]; i = i + 1 }
456 if mtotal <= 0 { return kid[0] }
457 // draw
458 let r: i64 = nsv_rand(sd) % mtotal
459 var c2: i64 = 0
460 i = 0
461 while i < m { c2 = c2 + ev[i]; if c2 > r { return kid[i] } i = i + 1 }
462 return kid[m-1]
463}
464// pick the next token from the current normed hidden state. np = [temp_pm, top_p_pm, top_k, seed_state_ptr].
465// temp_pm==0 -> greedy argmax (the bit-exact hero path, unchanged); else full-logits head + seeded sampling.
466func nsv_next_token(np: *i64) -> i64 {
467 if np[0] == 0 { return head_argmax_cached_i32(g_nsv_hcp) }
468 let hlp: *i64 = sys_mmap(6*8) as *i64
469 hlp[0]=g_nsv_hcp[0]
470 hlp[1]=g_nsv_normed as i64
471 hlp[2]=g_nsv_mt[3]
472 hlp[3]=g_nsv_cfgA[1]
473 hlp[4]=g_nsv_lgv as i64
474 head_logits_cached_i32(hlp)
475 let sp: *i64 = sys_mmap(6*8) as *i64
476 sp[0]=g_nsv_lgv as i64
477 sp[1]=g_nsv_mt[3]
478 sp[2]=np[0]
479 sp[3]=np[1]
480 sp[4]=np[2]
481 sp[5]=np[3]
482 return nsv_sample(sp)
483}
484// decode token `tok` to text: append to the out buffer AND (if ep[3]=fd >= 0) emit one SSE frame
485// `data: {"piece":"..."}` to the stream. ep = [out, olen, ocap, fd]. Returns the new olen.
486func nsv_emit_piece(tok: i64, ep: *i64) -> i64 {
487 let out: *u8 = ep[0] as *u8
488 var olen: i64 = ep[1]
489 let ocap: i64 = ep[2]
490 let fd: i64 = ep[3]
491 let off: i64 = tk_decode_off(g_nsv_buf, g_nsv_mt[2], tok)
492 let pl: i64 = nx_gguf_meta_read_string_len(g_nsv_buf, off)
493 if pl < 1 { return olen }
494 let tmp: *u8 = sys_mmap(1024)
495 let tn: i64 = td_piece_decode(nx_gguf_meta_read_string_ptr(g_nsv_buf, off), pl, tmp, 0, 1000)
496 var i: i64 = 0
497 while i < tn { if olen < ocap { out[olen]=tmp[i]; olen=olen+1 } i = i + 1 }
498 if fd >= 0 {
499 let fr: *u8 = sys_mmap(4096)
500 var fo: i64 = nsv_cat(fr, 0, "data: {\"piece\":\"" as *u8)
501 fo = nsv_jesc(fr, fo, tmp, tn)
502 fo = nsv_cat(fr, fo, "\"}\n\n" as *u8)
503 var w: i64 = 0
504 while w < fo { let kw: i64 = sys_write(fd, ((fr as i64)+w) as *u8, fo-w); if kw <= 0 { w = fo } else { w = w + kw } }
505 }
506 return olen
507}
508
509// build a ChatML prompt id sequence into g_nsv_ids:
510// <|im_start|>user\n{content}<|im_end|>\n<|im_start|>assistant\n
511// special ids 151644 (im_start) / 151645 (im_end == NSV_EOS2) are SPLICED directly (tk_bpe_encode
512// is pure byte-BPE and would byte-encode the marker text). Everything INLINE -- no multi-data-arg
513// helper (the documented 3+-arg miscompile class). Returns nprompt (total ids). Lets the INSTRUCT
514// model see turn structure. tmpids: tk_bpe_encode writes from index 0, so encode into it then copy.
515func nsv_chatml_ids(content: *u8, clen: i64) -> i64 {
516 let base: i64 = g_nsv_ids as i64
517 var off: i64 = 0
518 // <|im_start|>
519 g_nsv_ids[off] = 151644
520 off = off + 1
521 // user\n (encode IN-PLACE into g_nsv_ids[off..] -- the proven single-call buffer)
522 let po1: i64 = base + off*8
523 let ip1: *i64 = po1 as *i64
524 let nu: i64 = tk_bpe_encode(g_nsv_buf, g_nsv_mt[0], g_nsv_mt[1], g_nsv_mt[2], g_nsv_mt[3], "user\n" as *u8, 5, g_nsv_tokp, g_nsv_tokl, ip1)
525 off = off + nu
526 // content
527 let po2: i64 = base + off*8
528 let ip2: *i64 = po2 as *i64
529 let nc: i64 = tk_bpe_encode_b(g_nsv_buf, g_nsv_mt[0], g_nsv_mt[1], g_nsv_mt[2], g_nsv_mt[3], content, clen, g_nsv_tokp, g_nsv_tokl, NSV_MAXIN, ip2, NSV_MAXIN + NSV_CHATML_IDS - off)
530 if nc == TK_REFUSED_TOO_LONG { return TK_REFUSED_TOO_LONG }
531 off = off + nc
532 // <|im_end|>
533 g_nsv_ids[off] = 151645
534 off = off + 1
535 // \n
536 let po3: i64 = base + off*8
537 let ip3: *i64 = po3 as *i64
538 let nn: i64 = tk_bpe_encode(g_nsv_buf, g_nsv_mt[0], g_nsv_mt[1], g_nsv_mt[2], g_nsv_mt[3], "\n" as *u8, 1, g_nsv_tokp, g_nsv_tokl, ip3)
539 off = off + nn
540 // <|im_start|>
541 g_nsv_ids[off] = 151644
542 off = off + 1
543 // assistant\n
544 let po4: i64 = base + off*8
545 let ip4: *i64 = po4 as *i64
546 let na: i64 = tk_bpe_encode(g_nsv_buf, g_nsv_mt[0], g_nsv_mt[1], g_nsv_mt[2], g_nsv_mt[3], "assistant\n" as *u8, 10, g_nsv_tokp, g_nsv_tokl, ip4)
547 off = off + na
548 return off
549}
550
551// THE DOOR (2026-09-17): a prompt is admitted by its BYTE length before a byte of it is tokenised. tk_bpe_encode seeds
552// one scratch slot per input byte into g_nsv_tokp and g_nsv_tokl (NSV_MAXIN entries) and writes ids unbounded, so the
553// old order (encode, then check the token count) let a 19222-byte query overrun the scratch and kill the serving
554// engine inside tk_rank_fast (reproduced on a debug build, resolved by nx_addr2line). 0 admitted, NSV_ERR_TOO_LONG refused.
555func nsv_prompt_admit(plen: i64) -> i64 {
556 if plen > NSV_MAXIN { return NSV_ERR_TOO_LONG }
557 return 0
558}
559
560// generation. gp = [prompt, plen, max_new, mode, out_text, otcap, meta, stream_fd(-1=none),
561// temp_pm(0=greedy), top_p_pm, top_k, seed, chatml(1=wrap prompt in ChatML)].
562// meta out: [0]=n_prompt [1]=n_gen [2]=ms_total [3]=ms_per_tok [4]=eos [5]=err. returns text length (-1 on err).
563func nsv_generate(gp: *i64) -> i64 {
564 let prompt: *u8 = gp[0] as *u8
565 let plen: i64 = gp[1]
566 var max_new: i64 = gp[2]
567 let mode: i64 = gp[3]
568 let out: *u8 = gp[4] as *u8
569 let ocap: i64 = gp[5]
570 let meta: *i64 = gp[6] as *i64
571 meta[0]=0
572 meta[1]=0
573 meta[2]=0
574 meta[3]=0
575 meta[4]=0
576 meta[5]=0
577 if g_nsv_mt[6] != 1 { meta[5]=9; return 0-1 }
578 if plen < 1 { meta[5]=1; return 0-1 }
579 if nsv_prompt_admit(plen) != 0 { meta[5]=NSV_ERR_TOO_LONG; return 0-1 }
580 if max_new < 1 { max_new = 24 }
581 if max_new > NSV_MAXNEW { max_new = NSV_MAXNEW }
582 var nprompt: i64 = 0
583 if gp[12] == 1 { nprompt = nsv_chatml_ids(prompt, plen) }
584 else { nprompt = tk_bpe_encode_b(g_nsv_buf, g_nsv_mt[0], g_nsv_mt[1], g_nsv_mt[2], g_nsv_mt[3], prompt, plen, g_nsv_tokp, g_nsv_tokl, NSV_MAXIN, g_nsv_ids, NSV_MAXIN + NSV_CHATML_IDS) }
585 if nprompt == TK_REFUSED_TOO_LONG { meta[5]=NSV_ERR_TOO_LONG; return 0-1 }
586 if nprompt < 1 { meta[5]=2; return 0-1 }
587 if nprompt >= NSV_MAXT - 2 { meta[5]=3; return 0-1 }
588 if nprompt + max_new >= NSV_MAXT { max_new = NSV_MAXT - 1 - nprompt }
589 meta[0]=nprompt
590 let ne: i64 = g_nsv_cfgA[1]
591 // sampling params (gp[8]=temp_pm 0=greedy, gp[9]=top_p_pm, gp[10]=top_k, gp[11]=seed) + stream fd (gp[7])
592 let np: *i64 = sys_mmap(4*8) as *i64
593 let sd: *i64 = sys_mmap(8) as *i64
594 var seed: i64 = gp[11]
595 if seed == 0 { seed = 88172645463325252 }
596 sd[0]=seed
597 np[0]=gp[8]
598 np[1]=gp[9]
599 np[2]=gp[10]
600 np[3]=sd as i64
601 let ep: *i64 = sys_mmap(4*8) as *i64
602 ep[0]=out as i64
603 ep[1]=0
604 ep[2]=ocap
605 ep[3]=gp[7]
606 let t0: i64 = sys_now_ms()
607 // CACHED prefill. R0r (2026-09-17): the i8 route runs the prompt in blocks through nf_prefill_batched (one weight
608 // pass per NF_PREFILL_M positions) unless g_nsv_prefill_batched is 0; every other route runs the sequential
609 // per-token step. Both are bit-identical under causal masking (row t only ever attends 0..t) and both ride the
610 // dequant-once caches, so there is NO per-request re-dequant of the model. meta[6] carries the prefill ms.
611 var seqpre: i64 = 1
612 if mode == NSV_MODE_I8 { if g_nsv_prefill_batched == 1 { seqpre = 0 } }
613 if seqpre == 1 { nsv_prefill_seq(nprompt, mode) } else { nsv_prefill_i8_batched(nprompt) }
614 meta[6] = sys_now_ms() - t0
615 rmsnorm_gamma_row_q24(g_nsv_h1, g_nsv_gout, 0, ne, g_nsv_normed, 0)
616 var next: i64 = nsv_next_token(np)
617 var T: i64 = nprompt
618 g_nsv_ids[T]=next
619 T=T+1
620 var ngen: i64 = 1
621 var stop: i64 = 0
622 if next==NSV_EOS1 { stop=1; meta[4]=1 }
623 if next==NSV_EOS2 { stop=1; meta[4]=1 }
624 if stop == 0 { ep[1] = nsv_emit_piece(next, ep) }
625 while stop == 0 {
626 if ngen >= max_new { stop = 1 } else { if T >= NSV_MAXT { stop = 1 } else {
627 let pos: i64 = T - 1
628 dequant_row(g_nsv_buf, g_nsv_mt[4], g_nsv_mt[5], g_nsv_ids[pos], ne, g_nsv_x1, g_nsv_tmp)
629 nsv_step(pos, mode)
630 rmsnorm_gamma_row_q24(g_nsv_h1, g_nsv_gout, 0, ne, g_nsv_normed, 0)
631 next = nsv_next_token(np)
632 g_nsv_ids[T]=next
633 T=T+1
634 ngen=ngen+1
635 if next==NSV_EOS1 { stop=1; meta[4]=1 }
636 if next==NSV_EOS2 { stop=1; meta[4]=1 }
637 if meta[4] == 0 { ep[1] = nsv_emit_piece(next, ep) }
638 } }
639 }
640 let t1: i64 = sys_now_ms()
641 meta[1]=ngen
642 meta[2]=t1-t0
643 if ngen > 0 { meta[3]=(t1-t0)/(nprompt+ngen) }
644 return ep[1]
645}
646
647// ---- PREFIX-KV-CACHE (2026-07-15): the forge re-prefills a FIXED crib (~130 tok) on every task. Snapshot the
648// crib's KV rows 0..P-1 ONCE, restore them per task -> skip re-prefilling the crib (~P fewer prefill steps/task).
649// BIT-EXACT by causal masking: row t only attends 0..t, so the crib K/V are identical with or without the suffix
650// (the code already relies on this for sequential==batch prefill). Additive: the live nsv_generate is untouched.
651func nsv_kv_snapshot(P: i64) -> i64 {
652 let kvd: i64 = g_nsv_dims[6]
653 let nl: i64 = g_nsv_dims[1]
654 let per: i64 = P * kvd
655 g_nsv_kvsnap = sys_mmap(2 * nl * per * 8) as *i64
656 g_nsv_snap_p = P
657 g_nsv_crib_ids = sys_mmap(P * 8) as *i64
658 var s: i64 = 0
659 while s < P { g_nsv_crib_ids[s] = g_nsv_ids[s]; s = s + 1 }
660 var L: i64 = 0
661 while L < nl {
662 let K: *i64 = g_nsv_kvc[2*L] as *i64
663 let V: *i64 = g_nsv_kvc[2*L+1] as *i64
664 let base: i64 = (2*L) * per
665 var e: i64 = 0
666 while e < per {
667 g_nsv_kvsnap[base + e] = K[e]
668 g_nsv_kvsnap[base + per + e] = V[e]
669 e = e + 1
670 }
671 L = L + 1
672 }
673 return 0
674}
675func nsv_kv_restore() -> i64 {
676 if (g_nsv_kvsnap as i64) == 0 { return 0 - 1 }
677 let kvd: i64 = g_nsv_dims[6]
678 let nl: i64 = g_nsv_dims[1]
679 let P: i64 = g_nsv_snap_p
680 let per: i64 = P * kvd
681 var L: i64 = 0
682 while L < nl {
683 let K: *i64 = g_nsv_kvc[2*L] as *i64
684 let V: *i64 = g_nsv_kvc[2*L+1] as *i64
685 let base: i64 = (2*L) * per
686 var e: i64 = 0
687 while e < per {
688 K[e] = g_nsv_kvsnap[base + e]
689 V[e] = g_nsv_kvsnap[base + per + e]
690 e = e + 1
691 }
692 L = L + 1
693 }
694 return 0
695}
696// DISK-PERSISTED snapshot (2026-07-15): the crib KV survives process restarts -- a fresh process loads the
697// snapshot instead of re-prefilling (the WSL/daemon-restart pattern). Format: [P][nl][kvd] then crib ids
698// (P i64) then per-layer K rows then V rows (P*kvd i64 each). Load fail-safe: any dim mismatch -> -1, caller
699// falls back to full prefill (never a wrong cache).
700func nsv_kv_snapshot_save(path: *u8) -> i64 {
701 if (g_nsv_kvsnap as i64) == 0 { return 0 - 1 }
702 let kvd: i64 = g_nsv_dims[6]
703 let nl: i64 = g_nsv_dims[1]
704 let P: i64 = g_nsv_snap_p
705 let per: i64 = P * kvd
706 let fd: i64 = sys_openat_wr(path, 0x1a4)
707 if fd < 0 { return 0 - 2 }
708 let hdrb: *i64 = sys_mmap(3*8) as *i64
709 hdrb[0] = P
710 hdrb[1] = nl
711 hdrb[2] = kvd
712 sys_write(fd, hdrb as *u8, 24)
713 sys_write(fd, g_nsv_crib_ids as *u8, P*8)
714 sys_write(fd, g_nsv_kvsnap as *u8, 2*nl*per*8)
715 sys_close(fd)
716 return 0
717}
718func nsv_kv_snapshot_load(path: *u8) -> i64 {
719 let kvd: i64 = g_nsv_dims[6]
720 let nl: i64 = g_nsv_dims[1]
721 let fd: i64 = sys_openat_rd(path)
722 if fd < 0 { return 0 - 1 }
723 let hdrb: *i64 = sys_mmap(3*8) as *i64
724 if sys_read(fd, hdrb as *u8, 24) != 24 { sys_close(fd); return 0 - 2 }
725 let P: i64 = hdrb[0]
726 if P < 1 { sys_close(fd); return 0 - 3 }
727 if P >= NSV_MAXT { sys_close(fd); return 0 - 3 }
728 if hdrb[1] != nl { sys_close(fd); return 0 - 4 }
729 if hdrb[2] != kvd { sys_close(fd); return 0 - 4 }
730 let per: i64 = P * kvd
731 g_nsv_crib_ids = sys_mmap(P*8) as *i64
732 g_nsv_kvsnap = sys_mmap(2*nl*per*8) as *i64
733 var need: i64 = P*8
734 var got: i64 = 0
735 var q: *u8 = g_nsv_crib_ids as *u8
736 while got < need { let r: i64 = sys_read(fd, (q as i64 + got) as *u8, need - got); if r <= 0 { sys_close(fd); return 0 - 5 } got = got + r }
737 need = 2*nl*per*8
738 got = 0
739 q = g_nsv_kvsnap as *u8
740 while got < need { let r2: i64 = sys_read(fd, (q as i64 + got) as *u8, need - got); if r2 <= 0 { sys_close(fd); return 0 - 5 } got = got + r2 }
741 sys_close(fd)
742 g_nsv_snap_p = P
743 return P
744}
745
746// nsv_generate with prefix-KV-cache. prefix_len = # prompt tokens shared with the snapshot; use_snap: 0 = prefill
747// all + snapshot rows 0..prefix_len-1; 1 = restore the snapshot + prefill only [prefix_len..nprompt). Requires
748// prefix_len < nprompt when use_snap==1 (a suffix must exist). Everything after prefill is byte-identical to
749// nsv_generate (same decode, sampling, emit) -> the OUTPUT must match nsv_generate exactly (the gate proves it).
750func nsv_generate_pfx(gp: *i64, prefix_len: i64, use_snap: i64) -> i64 {
751 let prompt: *u8 = gp[0] as *u8
752 let plen: i64 = gp[1]
753 var max_new: i64 = gp[2]
754 let mode: i64 = gp[3]
755 let out: *u8 = gp[4] as *u8
756 let ocap: i64 = gp[5]
757 let meta: *i64 = gp[6] as *i64
758 meta[0]=0
759 meta[1]=0
760 meta[2]=0
761 meta[3]=0
762 meta[4]=0
763 meta[5]=0
764 if g_nsv_mt[6] != 1 { meta[5]=9; return 0-1 }
765 if plen < 1 { meta[5]=1; return 0-1 }
766 if nsv_prompt_admit(plen) != 0 { meta[5]=NSV_ERR_TOO_LONG; return 0-1 }
767 if max_new < 1 { max_new = 24 }
768 if max_new > NSV_MAXNEW { max_new = NSV_MAXNEW }
769 var nprompt: i64 = 0
770 if gp[12] == 1 { nprompt = nsv_chatml_ids(prompt, plen) }
771 else { nprompt = tk_bpe_encode_b(g_nsv_buf, g_nsv_mt[0], g_nsv_mt[1], g_nsv_mt[2], g_nsv_mt[3], prompt, plen, g_nsv_tokp, g_nsv_tokl, NSV_MAXIN, g_nsv_ids, NSV_MAXIN + NSV_CHATML_IDS) }
772 if nprompt == TK_REFUSED_TOO_LONG { meta[5]=NSV_ERR_TOO_LONG; return 0-1 }
773 if nprompt < 1 { meta[5]=2; return 0-1 }
774 if nprompt >= NSV_MAXT - 2 { meta[5]=3; return 0-1 }
775 if nprompt + max_new >= NSV_MAXT { max_new = NSV_MAXT - 1 - nprompt }
776 meta[0]=nprompt
777 let ne: i64 = g_nsv_cfgA[1]
778 let np: *i64 = sys_mmap(4*8) as *i64
779 let sd: *i64 = sys_mmap(8) as *i64
780 var seed: i64 = gp[11]
781 if seed == 0 { seed = 88172645463325252 }
782 sd[0]=seed
783 np[0]=gp[8]
784 np[1]=gp[9]
785 np[2]=gp[10]
786 np[3]=sd as i64
787 let ep: *i64 = sys_mmap(4*8) as *i64
788 ep[0]=out as i64
789 ep[1]=0
790 ep[2]=ocap
791 ep[3]=gp[7]
792 let t0: i64 = sys_now_ms()
793 // no-snapshot fallback: use_snap=1 with no prior snapshot degrades to a full prefill (never crashes)
794 var us: i64 = use_snap
795 if us == 1 { if (g_nsv_kvsnap as i64) == 0 { us = 0 } }
796 var i: i64 = 0
797 if us == 1 {
798 nsv_kv_restore()
799 // BOUNDARY-SAFE: only the token rows that ACTUALLY match the snapshotted crib are trusted; the first
800 // divergent token (BPE may re-tokenize the crib/task seam) and everything after is re-prefilled fresh.
801 var cp: i64 = 0
802 var go: i64 = 1
803 while go == 1 {
804 if cp >= g_nsv_snap_p { go = 0 }
805 else { if cp >= nprompt { go = 0 }
806 else { if g_nsv_ids[cp] == g_nsv_crib_ids[cp] { cp = cp + 1 } else { go = 0 } } }
807 }
808 // stale-h1 guard: if the snapshot covers the WHOLE prompt (identical prompt, e.g. best-of-N resample),
809 // still re-run the LAST prompt token so g_nsv_h1 is the state after token nprompt-1, not a stale gen state.
810 // Rewriting KV row nprompt-1 with the same values is harmless; skipping it leaves h1 wrong.
811 if cp >= nprompt { cp = nprompt - 1 }
812 i = cp
813 }
814 while i < nprompt {
815 dequant_row(g_nsv_buf, g_nsv_mt[4], g_nsv_mt[5], g_nsv_ids[i], ne, g_nsv_x1, g_nsv_tmp)
816 nsv_step(i, mode)
817 i = i + 1
818 }
819 if us == 0 {
820 var snl: i64 = prefix_len
821 if snl > nprompt { snl = nprompt }
822 if snl > 0 { nsv_kv_snapshot(snl) }
823 }
824 rmsnorm_gamma_row_q24(g_nsv_h1, g_nsv_gout, 0, ne, g_nsv_normed, 0)
825 var next: i64 = nsv_next_token(np)
826 var T: i64 = nprompt
827 g_nsv_ids[T]=next
828 T=T+1
829 var ngen: i64 = 1
830 var stop: i64 = 0
831 if next==NSV_EOS1 { stop=1; meta[4]=1 }
832 if next==NSV_EOS2 { stop=1; meta[4]=1 }
833 if stop == 0 { ep[1] = nsv_emit_piece(next, ep) }
834 while stop == 0 {
835 if ngen >= max_new { stop = 1 } else { if T >= NSV_MAXT { stop = 1 } else {
836 let pos: i64 = T - 1
837 dequant_row(g_nsv_buf, g_nsv_mt[4], g_nsv_mt[5], g_nsv_ids[pos], ne, g_nsv_x1, g_nsv_tmp)
838 nsv_step(pos, mode)
839 rmsnorm_gamma_row_q24(g_nsv_h1, g_nsv_gout, 0, ne, g_nsv_normed, 0)
840 next = nsv_next_token(np)
841 g_nsv_ids[T]=next
842 T=T+1
843 ngen=ngen+1
844 if next==NSV_EOS1 { stop=1; meta[4]=1 }
845 if next==NSV_EOS2 { stop=1; meta[4]=1 }
846 if meta[4] == 0 { ep[1] = nsv_emit_piece(next, ep) }
847 } }
848 }
849 let t1: i64 = sys_now_ms()
850 meta[1]=ngen
851 meta[2]=t1-t0
852 if ngen > 0 { meta[3]=(t1-t0)/(nprompt+ngen) }
853 return ep[1]
854}
855
856// ---- GPU ORACLE socket client (e4) -- ⚠BENCH LANE ONLY, NEVER THE RUN LANE (operator law
857// 2026-07-15: "sovereign from the hardware first byte up"; C/libcuda = benchmark oracle like
858// WARP/fxc/gcc). mode 2 is invoked ONLY by in-process gates (nx_gpu_embed_gate) to grade the
859// sovereign CPU path against the resident-weight GPU oracle; the daemon HTTP surface cannot
860// select it. The production /embed and /gen paths are 100%-sovereign CPU until the NishiLang
861// GPU driver (#22) exists. Protocol per token: send [pos=-(i+1):i64][x1: ne i64] ->
862// recv [normed: ne i64]. NO silent fallback: absent oracle = a loud error.
863func nsv_gwall(fd: i64, buf: *u8, count: i64) -> i64 {
864 var off: i64 = 0
865 while off < count {
866 let q: *u8 = buf + off
867 let w: i64 = sys_write(fd, q, count - off)
868 if w <= 0 { return 0 - 1 }
869 off = off + w
870 }
871 return 0
872}
873
874func nsv_grall(fd: i64, buf: *u8, count: i64) -> i64 {
875 var off: i64 = 0
876 while off < count {
877 let q: *u8 = buf + off
878 let r: i64 = sys_read(fd, q, count - off)
879 if r <= 0 { return 0 - 1 }
880 off = off + r
881 }
882 return 0
883}
884
885func nsv_gpu_connect() -> i64 {
886 let fd: i64 = sys_socket(1, 1, 0)
887 if fd < 0 { return 0 - 1 }
888 let sa: *u8 = sys_mmap(128) as *u8
889 sa[0] = 1 as u8
890 sa[1] = 0 as u8
891 let path: *u8 = "/home/elderwesto/nx_stage/nx_gpu.sock" as *u8
892 var i: i64 = 0
893 while path[i] != (0 as u8) { sa[2 + i] = path[i]; i = i + 1 }
894 let cr: i64 = sys_connect(fd, sa, 110)
895 if cr < 0 { sys_close(fd); return 0 - 2 }
896 return fd
897}
898
899// EMBEDDING (jina-code-embeddings recipe, arXiv:2508.21290): a code/text embedding is the LAST-TOKEN
900// pooled FINAL-NORM hidden state == exactly g_nsv_normed after the sequential prefill. No ChatML, no
901// generation -- the caller prepends the task instruction prefix (nl2code/qa/code2code/...) to the text.
902// Fresh sequence by construction: prefill restarts at pos=0 (KV rows 0..n-1 overwritten; causal attention
903// never reads beyond pos -> no state leak between embeds; same semantics as the GPU serve pos==0).
904// outvec receives ne i64s (Q24 scale). Returns n_prompt_tokens (>0) or negative error.
905func nsv_embed(text: *u8, tlen: i64, mode: i64, outvec: *i64) -> i64 {
906 if g_nsv_mt[6] != 1 { return 0-9 }
907 if tlen < 1 { return 0-1 }
908 if nsv_prompt_admit(tlen) != 0 { return 0-3 }
909 let nprompt: i64 = tk_bpe_encode_b(g_nsv_buf, g_nsv_mt[0], g_nsv_mt[1], g_nsv_mt[2], g_nsv_mt[3], text, tlen, g_nsv_tokp, g_nsv_tokl, NSV_MAXIN, g_nsv_ids, NSV_MAXIN + NSV_CHATML_IDS)
910 if nprompt == TK_REFUSED_TOO_LONG { return 0-3 }
911 if nprompt < 1 { return 0-2 }
912 if nprompt >= NSV_MAXT - 2 { return 0-3 }
913 let ne: i64 = g_nsv_cfgA[1]
914 if mode == 2 {
915 // GPU backend: forward+norm run on the resident-weight server, bit-exact vs the CPU i8 path
916 // (gate nx_gpu_embed_gate). Reply lands directly in outvec; the last token's reply stays.
917 let gs: i64 = nsv_gpu_connect()
918 if gs < 0 { return 0 - 10 }
919 let posb: *i64 = sys_mmap(8) as *i64
920 var k: i64 = 0
921 while k < nprompt {
922 dequant_row(g_nsv_buf, g_nsv_mt[4], g_nsv_mt[5], g_nsv_ids[k], ne, g_nsv_x1, g_nsv_tmp)
923 posb[0] = 0 - (k + 1)
924 if nsv_gwall(gs, posb as *u8, 8) != 0 { sys_close(gs); return 0 - 11 }
925 if nsv_gwall(gs, g_nsv_x1 as *u8, ne * 8) != 0 { sys_close(gs); return 0 - 11 }
926 if nsv_grall(gs, outvec as *u8, ne * 8) != 0 { sys_close(gs); return 0 - 12 }
927 k = k + 1
928 }
929 sys_close(gs)
930 return nprompt
931 }
932 var i: i64 = 0
933 while i < nprompt {
934 dequant_row(g_nsv_buf, g_nsv_mt[4], g_nsv_mt[5], g_nsv_ids[i], ne, g_nsv_x1, g_nsv_tmp)
935 nsv_step(i, mode)
936 i = i + 1
937 }
938 rmsnorm_gamma_row_q24(g_nsv_h1, g_nsv_gout, 0, ne, g_nsv_normed, 0)
939 var j: i64 = 0
940 while j < ne { outvec[j] = g_nsv_normed[j]; j = j + 1 }
941 return nprompt
942}
943
944// ---- HTTP layer (in-process; the daemon shell only moves bytes) ----
945func nsv_resp(resb: *u8, rescap: i64, code: i64, ctype: *u8, body: *u8, blen: i64) -> i64 {
946 var o: i64 = 0
947 o = nsv_cat(resb, o, "HTTP/1.1 " as *u8)
948 o = nsv_catn(resb, o, code)
949 if code == 200 { o = nsv_cat(resb, o, " OK" as *u8) } else { o = nsv_cat(resb, o, " X" as *u8) }
950 o = nsv_cat(resb, o, "\r\nContent-Type: " as *u8)
951 o = nsv_cat(resb, o, ctype)
952 o = nsv_cat(resb, o, "\r\nContent-Length: " as *u8)
953 o = nsv_catn(resb, o, blen)
954 o = nsv_cat(resb, o, "\r\nConnection: close\r\n\r\n" as *u8)
955 if o + blen < rescap { o = nsv_catb(resb, o, body, blen) }
956 return o
957}
958// JSON-escape ONE byte into dst at o; returns new o (early-return ladder -- no else-chains).
959func nsv_jesc1(dst: *u8, o: i64, c: i64) -> i64 {
960 if c == 34 { dst[o]=92 as u8; dst[o+1]=34 as u8; return o+2 }
961 if c == 92 { dst[o]=92 as u8; dst[o+1]=92 as u8; return o+2 }
962 if c == 10 { dst[o]=92 as u8; dst[o+1]=110 as u8; return o+2 }
963 if c == 13 { dst[o]=92 as u8; dst[o+1]=114 as u8; return o+2 }
964 if c == 9 { dst[o]=92 as u8; dst[o+1]=116 as u8; return o+2 }
965 if c < 32 { dst[o]=32 as u8; return o+1 }
966 dst[o]=c as u8
967 return o+1
968}
969// JSON-escape src[0,n) into dst at off
970func nsv_jesc(dst: *u8, off: i64, src: *u8, n: i64) -> i64 {
971 var o: i64 = off
972 var i: i64 = 0
973 while i < n { o = nsv_jesc1(dst, o, src[i] & 0xff); i = i + 1 }
974 return o
975}
976// find "key": in body[0,n); return index just after the colon, -1 if absent.
977func nsv_jkey(body: *u8, n: i64, key: *u8) -> i64 {
978 let kl: i64 = nsv_slen(key)
979 var i: i64 = 0
980 while i + kl + 3 < n {
981 if body[i] == (34 as u8) {
982 var k: i64 = 0
983 var ok: i64 = 1
984 while k < kl { if body[i+1+k] != key[k] { ok = 0; k = kl } else { k = k + 1 } }
985 if ok == 1 { if body[i+1+kl] == (34 as u8) {
986 var j: i64 = i + 2 + kl
987 while j < n { if body[j] == (58 as u8) { return j + 1 } if body[j] == (34 as u8) { j = n } else { j = j + 1 } }
988 } }
989 }
990 i = i + 1
991 }
992 return 0 - 1
993}
994// extract a JSON string value starting at/after p (skips ws to the opening quote); unescapes into dst; returns len (-1 if absent).
995func nsv_jstr(body: *u8, n: i64, p: i64, dst: *u8, dcap: i64) -> i64 {
996 var i: i64 = p
997 while i < n { if body[i] == (34 as u8) { i = i + 1; var o: i64 = 0
998 while i < n {
999 let c: i64 = body[i] & 0xff
1000 if c == 34 { return o }
1001 if c == 92 { if i + 1 < n {
1002 let e: i64 = body[i+1] & 0xff
1003 var w: i64 = e
1004 if e == 110 { w = 10 }
1005 if e == 116 { w = 9 }
1006 if e == 114 { w = 13 }
1007 if o < dcap { dst[o] = w as u8; o = o + 1 }
1008 i = i + 2
1009 } else { i = i + 1 } } else {
1010 if o < dcap { dst[o] = c as u8; o = o + 1 }
1011 i = i + 1
1012 }
1013 }
1014 return 0 - 1
1015 }
1016 if body[i] == (32 as u8) { i = i + 1 } else { if body[i] == (9 as u8) { i = i + 1 } else { return 0 - 1 } }
1017 }
1018 return 0 - 1
1019}
1020// extract a JSON integer at/after p; returns value (def if absent).
1021func nsv_jint(body: *u8, n: i64, p: i64, def: i64) -> i64 {
1022 if p < 0 { return def }
1023 var i: i64 = p
1024 var skipping: i64 = 1
1025 while skipping == 1 {
1026 if i >= n { skipping = 0 } else {
1027 if body[i] == (32 as u8) { i = i + 1 } else { skipping = 0 }
1028 }
1029 }
1030 var v: i64 = 0
1031 var any: i64 = 0
1032 var going: i64 = 1
1033 while going == 1 {
1034 if i >= n { going = 0 } else {
1035 let c: i64 = body[i] & 0xff
1036 if c >= 48 { if c <= 57 { v = v * 10 + (c - 48); any = 1; i = i + 1 } else { going = 0 } } else { going = 0 }
1037 }
1038 }
1039 if any == 0 { return def }
1040 return v
1041}
1042
1043// the app page: served at GET /. NOTE: NishiLang literals cannot carry the two banned bytes, so the page uses
1044// rgb() colors, class selectors and no doctype -- functional, clean, dark.
1045func nsv_page(dst: *u8, cap: i64) -> i64 {
1046 var o: i64 = 0
1047 o = nsv_cat(dst, o, "<html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>Nishi No-Float LLM</title><style>body{font-family:system-ui,Segoe UI,Roboto,sans-serif;background:rgb(16,17,22);color:rgb(226,228,235);max-width:760px;margin:4vh auto;padding:0 20px;line-height:1.55}h1{font-size:1.4rem;margin-bottom:.2rem}p.sub{color:rgb(150,155,170);font-size:.9rem;margin-top:0}textarea{width:100%;min-height:90px;background:rgb(28,30,38);color:rgb(230,232,240);border:1px solid rgb(60,63,75);border-radius:8px;padding:10px;font-size:1rem;box-sizing:border-box}select,input{background:rgb(28,30,38);color:rgb(230,232,240);border:1px solid rgb(60,63,75);border-radius:6px;padding:6px 8px}button{background:rgb(58,110,235);color:white;border:none;border-radius:8px;padding:9px 18px;font-size:1rem;cursor:pointer}button:disabled{opacity:.5}.row{display:flex;gap:10px;align-items:center;margin:10px 0;flex-wrap:wrap}.out{white-space:pre-wrap;background:rgb(24,26,33);border:1px solid rgb(55,58,70);border-radius:8px;padding:12px;min-height:60px;margin-top:8px;font-size:1.02rem}.st{color:rgb(140,200,150);font-size:.85rem;min-height:1.2em}.ft{margin-top:2rem;color:rgb(120,124,138);font-size:.78rem}</style></head><body><h1>Nishi No-Float LLM</h1><p class=\"sub\">Qwen2.5-0.5B-Instruct on the sovereign 100 percent integer inference stack. Deterministic: same prompt, same bytes.</p><textarea class=\"pr\" placeholder=\"Type a prompt...\">The capital of France is</textarea><div class=\"row\"><label>tokens <input class=\"mn\" type=\"number\" value=\"24\" min=\"1\" max=\"96\" style=\"width:70px\"></label><label>mode <select class=\"md\"><option value=\"i32\">i32 lossless</option><option value=\"i8\">i8 fast</option></select></label><label>temp <select class=\"tp\"><option value=\"0\">0 (greedy, bit-exact)</option><option value=\"700\">0.7</option><option value=\"800\">0.8</option><option value=\"1000\">1.0</option><option value=\"1200\">1.2</option></select></label><label>seed <input class=\"sd\" type=\"number\" value=\"12345\" style=\"width:90px\"></label><button class=\"go\" onclick=\"go()\">Generate</button></div><div class=\"st\"></div><div class=\"out\"></div><div class=\"ft\">endpoints: POST /gen · GET /health · GET /api — served by nx_nofloat_serve (no gcc, no python, no float)</div><script>async function go(){var b=document.querySelector('.go');var st=document.querySelector('.st');var out=document.querySelector('.out');var t=document.querySelector('.pr').value;var mn=parseInt(document.querySelector('.mn').value);var md=document.querySelector('.md').value;var tp=parseInt(document.querySelector('.tp').value);var sd=parseInt(document.querySelector('.sd').value);b.disabled=true;st.textContent='thinking...';out.textContent=t;try{var r=await fetch('/gen',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({prompt:t,max_new:mn,mode:md,temp:tp,seed:sd,stream:1})});var rd=r.body.getReader();var dec=new TextDecoder();var acc='';var SEP=String.fromCharCode(10)+String.fromCharCode(10);var going=true;while(going){var ch=await rd.read();if(ch.done){going=false}else{acc=acc+dec.decode(ch.value,{stream:true});var parts=acc.split(SEP);acc=parts.pop();for(var pi=0;pi<parts.length;pi=pi+1){var ln=parts[pi];if(ln.indexOf('data: ')==0){var j=JSON.parse(ln.slice(6));if(j.piece){out.textContent=out.textContent+j.piece}if(j.done==1){if(j.ok==1){st.textContent=j.gen_tokens+' tokens · '+j.ms_per_token+' ms/token · '+md+(tp>0?' · temp '+(tp/1000)+' seed '+sd:' · greedy')+(j.eos==1?' · eos':'')}else{st.textContent='error '+j.err}}}}}}}catch(e){st.textContent='request failed: '+e}b.disabled=false;}</script></body></html>" as *u8)
1048 return o
1049}
1050
1051// parse a POST /gen request body into gp: [0]=prompt [1]=plen [2]=max_new [3]=mode(0=i32,1=i8)
1052// [8]=temp_pm(0=greedy) [9]=top_p_pm [10]=top_k [11]=seed [12]=stream(0/1). 0 ok, -1 bad.
1053func nsv_parse_gen(req: *u8, rn: i64, gp: *i64) -> i64 {
1054 var hb: i64 = 0 - 1
1055 var i: i64 = 0
1056 while i + 3 < rn {
1057 if req[i]==(13 as u8) { if req[i+1]==(10 as u8) { if req[i+2]==(13 as u8) { if req[i+3]==(10 as u8) { hb = i + 4; i = rn } } } }
1058 i = i + 1
1059 }
1060 if hb < 0 { return 0 - 1 }
1061 let bb: *u8 = ((req as i64) + hb) as *u8
1062 let bn: i64 = rn - hb
1063 let prompt: *u8 = sys_mmap(32768)
1064 let kp: i64 = nsv_jkey(bb, bn, "prompt" as *u8)
1065 var pl2: i64 = 0 - 1
1066 if kp >= 0 { pl2 = nsv_jstr(bb, bn, kp, prompt, 32760) }
1067 if pl2 < 1 { return 0 - 1 }
1068 gp[0]=prompt as i64
1069 gp[1]=pl2
1070 gp[2]=nsv_jint(bb, bn, nsv_jkey(bb, bn, "max_new" as *u8), 24)
1071 // mode: default is the route whose caches this serve actually built -- a resident-Q4_K serve has NO i32/i16
1072 // layer cache, so an explicit i32/i8 there is REFUSED (400) rather than dereferencing an absent cache; and
1073 // "q4k" on a serve that did not build the slot tables is refused the same way.
1074 var mode: i64 = NSV_MODE_I32
1075 if g_nsv_q4k == 1 { mode = NSV_MODE_Q4K }
1076 // an i8-only serve (nsv_init_i8: no i32 cache) defaults to i8 and REFUSES an explicit i32 -- mode 0 there would
1077 // read the absent cache (2026-09-16, the LAN rewrite engine runs i8-only beside other jobs in a 16 GB VM)
1078 if g_nsv_i8only == 1 { if g_nsv_q4k == 0 { mode = NSV_MODE_I8 } }
1079 let kd: i64 = nsv_jkey(bb, bn, "mode" as *u8)
1080 if kd >= 0 {
1081 let ms: *u8 = sys_mmap(16)
1082 let ml: i64 = nsv_jstr(bb, bn, kd, ms, 8)
1083 if ml == 2 { if ms[0]==(105 as u8) { if ms[1]==(56 as u8) { mode = NSV_MODE_I8 } } }
1084 if ml == 3 { if ms[0]==(105 as u8) { if ms[1]==(51 as u8) { if ms[2]==(50 as u8) { mode = NSV_MODE_I32 } } } }
1085 if ml == 3 { if ms[0]==(113 as u8) { if ms[1]==(52 as u8) { if ms[2]==(107 as u8) { mode = NSV_MODE_Q4K } } } }
1086 if ml == 2 { if ms[0]==(113 as u8) { if ms[1]==(56 as u8) { mode = NSV_MODE_Q4K } } } // "q8": the resident lane over a Q8_0 gguf (search R0s)
1087 if g_nsv_q4k == 1 { if mode != NSV_MODE_Q4K { return 0 - 1 } }
1088 if g_nsv_q4k == 0 { if mode == NSV_MODE_Q4K { return 0 - 1 } }
1089 if g_nsv_i8only == 1 { if mode == NSV_MODE_I32 { return 0 - 1 } }
1090 }
1091 gp[3]=mode
1092 gp[8]=nsv_jint(bb, bn, nsv_jkey(bb, bn, "temp" as *u8), 0)
1093 gp[9]=nsv_jint(bb, bn, nsv_jkey(bb, bn, "top_p" as *u8), 950)
1094 gp[10]=nsv_jint(bb, bn, nsv_jkey(bb, bn, "top_k" as *u8), 64)
1095 gp[11]=nsv_jint(bb, bn, nsv_jkey(bb, bn, "seed" as *u8), 12345)
1096 // SLOT-COLLISION FIX (2026-07-15): "stream" used to land in gp[12], but the forge-era nsv_generate
1097 // contract made gp[12] = CHATML -- so every streamed request silently chatml-wrapped (caught by the
1098 // serve gate T6: streamed 'The capital of France is' returned chat-'Paris', 13 prompt tokens, not the
1099 // raw ' Paris' continuation, 5 tokens). Streaming discriminator now gp[13]; gp[12] = the EXPLICIT
1100 // "chat" body key (default 0 = raw) -- both transports get both behaviors, explicitly.
1101 gp[12]=nsv_jint(bb, bn, nsv_jkey(bb, bn, "chat" as *u8), 0)
1102 gp[13]=nsv_jint(bb, bn, nsv_jkey(bb, bn, "stream" as *u8), 0)
1103 return 0
1104}
1105// jina-code-embeddings task instruction prefixes (VERBATIM from the jina-code-embeddings-0.5b model card /
1106// arXiv:2508.21290 -- protocol constants, cited not invented). Task selected by (len, first byte):
1107// qa=2, code2code=9, code2completion=15, code2nl=7+'c', default nl2code. kq=1 -> query prefix, else passage.
1108func nsv_embed_prefix(task: *u8, tl: i64, kq: i64) -> *u8 {
1109 if tl == 2 {
1110 if kq == 1 { return "Find the most relevant answer given the following question:\n" as *u8 }
1111 return "Candidate answer:\n" as *u8
1112 }
1113 if tl == 9 {
1114 if kq == 1 { return "Find an equivalent code snippet given the following code snippet:\n" as *u8 }
1115 return "Candidate code snippet:\n" as *u8
1116 }
1117 if tl == 15 {
1118 if kq == 1 { return "Find the most relevant completion given the following start of code snippet:\n" as *u8 }
1119 return "Candidate completion:\n" as *u8
1120 }
1121 if tl == 7 { if task[0] == (99 as u8) {
1122 if kq == 1 { return "Find the most relevant comment given the following code snippet:\n" as *u8 }
1123 return "Candidate comment:\n" as *u8
1124 } }
1125 if kq == 1 { return "Find the most relevant code snippet given the following query:\n" as *u8 }
1126 return "Candidate code snippet:\n" as *u8
1127}
1128
1129// parse POST /embed body {"text","task","kind","mode"} -> ep: [0]=text ptr [1]=text len [2]=mode(1=i8 default)
1130// [3]=kind_q(1=query default) [4]=task ptr [5]=task len (0 = default nl2code). 0 ok, -1 bad (text required).
1131func nsv_parse_embed(req: *u8, rn: i64, ep: *i64) -> i64 {
1132 var hb: i64 = 0 - 1
1133 var i: i64 = 0
1134 while i + 3 < rn {
1135 if req[i]==(13 as u8) { if req[i+1]==(10 as u8) { if req[i+2]==(13 as u8) { if req[i+3]==(10 as u8) { hb = i + 4; i = rn } } } }
1136 i = i + 1
1137 }
1138 if hb < 0 { return 0 - 1 }
1139 let bb: *u8 = ((req as i64) + hb) as *u8
1140 let bn: i64 = rn - hb
1141 let text: *u8 = sys_mmap(8192)
1142 let kt: i64 = nsv_jkey(bb, bn, "text" as *u8)
1143 var tl: i64 = 0 - 1
1144 if kt >= 0 { tl = nsv_jstr(bb, bn, kt, text, 8100) }
1145 if tl < 1 { return 0 - 1 }
1146 ep[0]=text as i64
1147 ep[1]=tl
1148 var mode: i64 = 1
1149 let kd: i64 = nsv_jkey(bb, bn, "mode" as *u8)
1150 if kd >= 0 {
1151 let ms: *u8 = sys_mmap(16)
1152 let ml: i64 = nsv_jstr(bb, bn, kd, ms, 8)
1153 // NOTE: mode 2 (GPU oracle) is BENCH-ONLY and deliberately NOT reachable from the HTTP
1154 // surface -- the run lane is sovereign CPU end-to-end (operator law 2026-07-15: C/libcuda
1155 // = benchmark oracle, never the run lane). Gates drive mode 2 in-process.
1156 if ml == 3 { mode = 0 }
1157 }
1158 ep[2]=mode
1159 var kq: i64 = 1
1160 let kk: i64 = nsv_jkey(bb, bn, "kind" as *u8)
1161 if kk >= 0 {
1162 let ks: *u8 = sys_mmap(16)
1163 let kl: i64 = nsv_jstr(bb, bn, kk, ks, 12)
1164 if kl > 0 { if ks[0]==(112 as u8) { kq = 0 } }
1165 }
1166 ep[3]=kq
1167 let task: *u8 = sys_mmap(32)
1168 var tkl: i64 = 0
1169 let kta: i64 = nsv_jkey(bb, bn, "task" as *u8)
1170 if kta >= 0 {
1171 let r: i64 = nsv_jstr(bb, bn, kta, task, 24)
1172 if r > 0 { tkl = r }
1173 }
1174 ep[4]=task as i64
1175 ep[5]=tkl
1176 return 0
1177}
1178
1179// STREAMING route: if the request is POST /gen with "stream":1, serve it as Server-Sent Events DIRECTLY on
1180// fd (headers -> start frame -> one data frame per token from nsv_generate -> done frame with meta) and
1181// return 1. Any other request returns 0 (caller falls through to the buffered nsv_handle). The daemon calls
1182// this FIRST; the gate drives it with a file fd -- same bytes either way.
1183func nsv_handle_stream(fd: i64, req: *u8, rn: i64) -> i64 {
1184 var is_post: i64 = 0
1185 if rn > 5 { if req[0]==(80 as u8) { is_post = 1 } }
1186 if is_post == 0 { return 0 }
1187 if req[6] != (103 as u8) { return 0 }
1188 let gp: *i64 = sys_mmap(16*8) as *i64
1189 let prc: i64 = nsv_parse_gen(req, rn, gp)
1190 if prc != 0 { return 0 }
1191 if gp[13] != 1 { return 0 }
1192 let hdrs: *u8 = "HTTP/1.1 200 OK\r\nContent-Type: text/event-stream\r\nCache-Control: no-cache\r\nConnection: close\r\n\r\n" as *u8
1193 var hl: i64 = nsv_slen(hdrs)
1194 var w: i64 = 0
1195 while w < hl { let k1: i64 = sys_write(fd, ((hdrs as i64)+w) as *u8, hl-w); if k1 <= 0 { w = hl } else { w = w + k1 } }
1196 let text: *u8 = sys_mmap(65536)
1197 let meta: *i64 = sys_mmap(8*8) as *i64
1198 gp[4]=text as i64
1199 gp[5]=65000
1200 gp[6]=meta as i64
1201 gp[7]=fd
1202 let tl: i64 = nsv_generate(gp)
1203 let fin: *u8 = sys_mmap(1024)
1204 var fo: i64 = 0
1205 if tl < 0 {
1206 fo = nsv_cat(fin, 0, "data: {\"done\":1,\"ok\":0,\"err\":" as *u8)
1207 fo = nsv_catn(fin, fo, meta[5])
1208 fo = nsv_cat(fin, fo, "}\n\n" as *u8)
1209 } else {
1210 fo = nsv_cat(fin, 0, "data: {\"done\":1,\"ok\":1,\"prompt_tokens\":" as *u8)
1211 fo = nsv_catn(fin, fo, meta[0])
1212 fo = nsv_cat(fin, fo, ",\"gen_tokens\":" as *u8)
1213 fo = nsv_catn(fin, fo, meta[1])
1214 fo = nsv_cat(fin, fo, ",\"ms_per_token\":" as *u8)
1215 fo = nsv_catn(fin, fo, meta[3])
1216 fo = nsv_cat(fin, fo, ",\"prefill_ms\":" as *u8)
1217 fo = nsv_catn(fin, fo, meta[6])
1218 fo = nsv_cat(fin, fo, ",\"eos\":" as *u8)
1219 fo = nsv_catn(fin, fo, meta[4])
1220 fo = nsv_cat(fin, fo, "}\n\n" as *u8)
1221 }
1222 w = 0
1223 while w < fo { let k2: i64 = sys_write(fd, ((fin as i64)+w) as *u8, fo-w); if k2 <= 0 { w = fo } else { w = w + k2 } }
1224 return 1
1225}
1226
1227// route + serve one request. returns response length in resb.
1228func nsv_handle(req: *u8, rn: i64, resb: *u8, rescap: i64) -> i64 {
1229 let body: *u8 = sys_mmap(65536)
1230 var blen: i64 = 0
1231 // method + path
1232 var is_get: i64 = 0
1233 var is_post: i64 = 0
1234 if rn > 4 { if req[0]==(71 as u8) { is_get=1 } }
1235 if rn > 5 { if req[0]==(80 as u8) { is_post=1 } }
1236 var ps: i64 = 4
1237 if is_post == 1 { ps = 5 }
1238 var pe: i64 = ps
1239 var scanning: i64 = 1
1240 while scanning == 1 {
1241 if pe >= rn { scanning = 0 } else {
1242 if req[pe]==(32 as u8) { scanning = 0 } else { pe = pe + 1 }
1243 }
1244 }
1245 let plen: i64 = pe - ps
1246 // GET /
1247 if is_get == 1 { if plen == 1 { if req[ps]==(47 as u8) {
1248 let page: *u8 = sys_mmap(16384)
1249 let pn: i64 = nsv_page(page, 16384)
1250 return nsv_resp(resb, rescap, 200, "text/html; charset=utf-8" as *u8, page, pn)
1251 } } }
1252 // GET /health
1253 if is_get == 1 { if plen == 7 { if req[ps+1]==(104 as u8) {
1254 var o: i64 = 0
1255 o = nsv_cat(body, o, "{\"ok\":" as *u8)
1256 o = nsv_catn(body, o, g_nsv_mt[6])
1257 o = nsv_cat(body, o, ",\"model\":\"" as *u8)
1258 o = nsv_jesc(body, o, g_nsv_mpath, nsv_slen(g_nsv_mpath))
1259 if g_nsv_q4k == 1 { o = nsv_cat(body, o, "\",\"modes\":[\"q4k\"],\"route\":\"q4k-resident\",\"maxt\":" as *u8) } else {
1260 o = nsv_cat(body, o, "\",\"modes\":[\"i32\",\"i8\"],\"route\":\"dequant-once-i32+i8\",\"maxt\":" as *u8) }
1261 o = nsv_catn(body, o, NSV_MAXT)
1262 o = nsv_cat(body, o, ",\"init_ms\":" as *u8)
1263 o = nsv_catn(body, o, g_nsv_mt[7])
1264 if g_nsv_q4k == 1 {
1265 // per-route decode profile (cumulative since init; diff two reads around one generation): where a token's
1266 // time goes is a measurement here, never a guess in a seat
1267 o = nsv_cat(body, o, ",\"prof\":{\"q4k_gemm_ns\":" as *u8); o = nsv_catn(body, o, nq_prof_get(NQ_PROF_Q4K_NS))
1268 o = nsv_cat(body, o, ",\"q4k_gemm_calls\":" as *u8); o = nsv_catn(body, o, nq_prof_get(NQ_PROF_Q4K_CALLS))
1269 o = nsv_cat(body, o, ",\"i16_ns\":" as *u8); o = nsv_catn(body, o, nq_prof_get(NQ_PROF_I16_NS))
1270 o = nsv_cat(body, o, ",\"i16_calls\":" as *u8); o = nsv_catn(body, o, nq_prof_get(NQ_PROF_I16_CALLS))
1271 o = nsv_cat(body, o, ",\"inplace_tensors\":" as *u8); o = nsv_catn(body, o, g_nsv_q4st[0])
1272 o = nsv_cat(body, o, ",\"fallback_i16_tensors\":" as *u8); o = nsv_catn(body, o, g_nsv_q4st[1])
1273 o = nsv_cat(body, o, "}" as *u8)
1274 }
1275 o = nsv_cat(body, o, "}" as *u8)
1276 return nsv_resp(resb, rescap, 200, "application/json" as *u8, body, o)
1277 } } }
1278 // GET /api
1279 if is_get == 1 { if plen == 4 { if req[ps+1]==(97 as u8) {
1280 let o: i64 = nsv_cat(body, 0, "{\"organ\":\"nx_nofloat_serve\",\"endpoints\":[{\"m\":\"POST\",\"p\":\"/gen\",\"body\":{\"prompt\":\"str\",\"max_new\":\"int 1-96 (default 24)\",\"mode\":\"i32|i8|q4k (q4k only on a route=q4k-resident serve; i32/i8 refused there)\",\"stream\":\"0|1 SSE\",\"chat\":\"0|1 ChatML wrap\"}},{\"m\":\"POST\",\"p\":\"/embed\",\"body\":{\"text\":\"str required <=8100B\",\"task\":\"nl2code|qa|code2code|code2nl|code2completion (default nl2code)\",\"kind\":\"query|passage (default query)\",\"mode\":\"i8|i32 (default i8)\"},\"returns\":\"dim=896 q24 int vector (last-token pooled final-norm hidden, arXiv 2508.21290)\"},{\"m\":\"GET\",\"p\":\"/health\"},{\"m\":\"GET\",\"p\":\"/\"}],\"stack\":\"sovereign 100pct-integer Qwen2.5-0.5B, dequant-once i32 lossless + i8 SIMD fast, KV-cached greedy\"}" as *u8)
1281 return nsv_resp(resb, rescap, 200, "application/json" as *u8, body, o)
1282 } } }
1283 // POST /gen
1284 if is_post == 1 { if plen == 4 { if req[ps+1]==(103 as u8) {
1285 let gp: *i64 = sys_mmap(16*8) as *i64
1286 let prc: i64 = nsv_parse_gen(req, rn, gp)
1287 if prc != 0 {
1288 let o: i64 = nsv_cat(body, 0, "{\"ok\":0,\"err\":1}" as *u8)
1289 return nsv_resp(resb, rescap, 400, "application/json" as *u8, body, o)
1290 }
1291 let text: *u8 = sys_mmap(65536)
1292 let meta: *i64 = sys_mmap(8*8) as *i64
1293 gp[4]=text as i64
1294 gp[5]=65000
1295 gp[6]=meta as i64
1296 gp[7]=0-1
1297 let mode: i64 = gp[3]
1298 let tl: i64 = nsv_generate(gp)
1299 if tl < 0 {
1300 var o: i64 = nsv_cat(body, 0, "{\"ok\":0,\"err\":" as *u8)
1301 o = nsv_catn(body, o, meta[5])
1302 o = nsv_cat(body, o, "}" as *u8)
1303 return nsv_resp(resb, rescap, 400, "application/json" as *u8, body, o)
1304 }
1305 var o: i64 = 0
1306 o = nsv_cat(body, o, "{\"ok\":1,\"mode\":\"" as *u8)
1307 if mode == NSV_MODE_Q4K { o = nsv_cat(body, o, "q4k" as *u8) } else {
1308 if mode == 1 { o = nsv_cat(body, o, "i8" as *u8) } else { o = nsv_cat(body, o, "i32" as *u8) } }
1309 o = nsv_cat(body, o, "\",\"prompt_tokens\":" as *u8)
1310 o = nsv_catn(body, o, meta[0])
1311 o = nsv_cat(body, o, ",\"gen_tokens\":" as *u8)
1312 o = nsv_catn(body, o, meta[1])
1313 o = nsv_cat(body, o, ",\"ms_total\":" as *u8)
1314 o = nsv_catn(body, o, meta[2])
1315 o = nsv_cat(body, o, ",\"ms_per_token\":" as *u8)
1316 o = nsv_catn(body, o, meta[3])
1317 o = nsv_cat(body, o, ",\"prefill_ms\":" as *u8)
1318 o = nsv_catn(body, o, meta[6])
1319 o = nsv_cat(body, o, ",\"prefill\":\"" as *u8)
1320 if g_nsv_prefill_batched == 1 { o = nsv_cat(body, o, "batched" as *u8) } else { o = nsv_cat(body, o, "sequential" as *u8) }
1321 o = nsv_cat(body, o, "\",\"eos\":" as *u8)
1322 o = nsv_catn(body, o, meta[4])
1323 o = nsv_cat(body, o, ",\"temp\":" as *u8)
1324 o = nsv_catn(body, o, gp[8])
1325 o = nsv_cat(body, o, ",\"seed\":" as *u8)
1326 o = nsv_catn(body, o, gp[11])
1327 o = nsv_cat(body, o, ",\"text\":\"" as *u8)
1328 o = nsv_jesc(body, o, text, tl)
1329 o = nsv_cat(body, o, "\"}" as *u8)
1330 return nsv_resp(resb, rescap, 200, "application/json" as *u8, body, o)
1331 } } }
1332 // POST /embed (jina-code-embeddings recipe arXiv:2508.21290: the embedding IS the last-token pooled
1333 // final-norm hidden state; instruction prefix prepended server-side). Returns the raw Q24 int vector --
1334 // cosine/ranking is the caller's (or the index organ's) job, integer math end to end.
1335 if is_post == 1 { if plen == 6 { if req[ps+1]==(101 as u8) {
1336 if g_nsv_mt[6] != 1 {
1337 let o: i64 = nsv_cat(body, 0, "{\"ok\":0,\"err\":9}" as *u8)
1338 return nsv_resp(resb, rescap, 503, "application/json" as *u8, body, o)
1339 }
1340 let ep: *i64 = sys_mmap(8*8) as *i64
1341 let erc: i64 = nsv_parse_embed(req, rn, ep)
1342 if erc != 0 {
1343 let o: i64 = nsv_cat(body, 0, "{\"ok\":0,\"err\":1}" as *u8)
1344 return nsv_resp(resb, rescap, 400, "application/json" as *u8, body, o)
1345 }
1346 let pre: *u8 = nsv_embed_prefix(ep[4] as *u8, ep[5], ep[3])
1347 let txt: *u8 = sys_mmap(NSV_MAXIN)
1348 var l: i64 = nsv_cat(txt, 0, pre)
1349 l = nsv_catb(txt, l, ep[0] as *u8, ep[1])
1350 let ne: i64 = g_nsv_cfgA[1]
1351 let vec: *i64 = sys_mmap(ne*8) as *i64
1352 let t0: i64 = sys_now_ms()
1353 let n: i64 = nsv_embed(txt, l, ep[2], vec)
1354 let t1: i64 = sys_now_ms()
1355 if n < 1 {
1356 var o: i64 = nsv_cat(body, 0, "{\"ok\":0,\"err\":" as *u8)
1357 o = nsv_catn(body, o, n)
1358 o = nsv_cat(body, o, "}" as *u8)
1359 return nsv_resp(resb, rescap, 400, "application/json" as *u8, body, o)
1360 }
1361 var o: i64 = 0
1362 o = nsv_cat(body, o, "{\"ok\":1,\"dim\":" as *u8)
1363 o = nsv_catn(body, o, ne)
1364 o = nsv_cat(body, o, ",\"ntok\":" as *u8)
1365 o = nsv_catn(body, o, n)
1366 o = nsv_cat(body, o, ",\"ms\":" as *u8)
1367 o = nsv_catn(body, o, t1 - t0)
1368 o = nsv_cat(body, o, ",\"scale\":\"q24\",\"mode\":\"" as *u8)
1369 if ep[2] == 1 { o = nsv_cat(body, o, "i8" as *u8) } else { o = nsv_cat(body, o, "i32" as *u8) }
1370 o = nsv_cat(body, o, "\",\"vec\":[" as *u8)
1371 var vi: i64 = 0
1372 while vi < ne {
1373 if vi > 0 { o = nsv_cat(body, o, "," as *u8) }
1374 o = nsv_catn(body, o, vec[vi])
1375 vi = vi + 1
1376 }
1377 o = nsv_cat(body, o, "]}" as *u8)
1378 return nsv_resp(resb, rescap, 200, "application/json" as *u8, body, o)
1379 } } }
1380 let o: i64 = nsv_cat(body, 0, "{\"ok\":0,\"err\":404}" as *u8)
1381 return nsv_resp(resb, rescap, 404, "application/json" as *u8, body, o)
1382}