mlx-bun 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/README.md +71 -588
  2. package/docs/README.md +94 -0
  3. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  4. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  5. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  6. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  7. package/docs/archive/investigations/openjarvis-fit.md +198 -0
  8. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  9. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  10. package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
  11. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  12. package/docs/archive/planning/release-notes-v0.3.0.md +35 -0
  13. package/docs/design/batching.md +1841 -0
  14. package/docs/design/decode-speed-program.md +2346 -169
  15. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  16. package/docs/design/generic-model-support.md +655 -334
  17. package/docs/design/kv-cache.md +824 -0
  18. package/docs/design/orpo-training.md +673 -1239
  19. package/docs/design/speculative-decoding.md +1990 -0
  20. package/docs/design/turboquant.md +2212 -0
  21. package/docs/design/unified-engine-frontier-plan.md +1833 -727
  22. package/docs/design/web-chat-redesign.md +666 -1083
  23. package/docs/planning/PRODUCT_ROADMAP.md +50 -1
  24. package/docs/planning/release-notes-v0.4.0.md +45 -0
  25. package/docs/planning/video-series.md +2 -2
  26. package/docs/reference/benchmarks.md +3613 -0
  27. package/docs/reference/cli.md +434 -160
  28. package/docs/reference/distribution.md +328 -182
  29. package/docs/reference/environment.md +398 -0
  30. package/docs/reference/glossary.md +39 -0
  31. package/docs/reference/library-api.md +566 -168
  32. package/docs/reference/memory.md +227 -64
  33. package/docs/reference/models.md +113 -6
  34. package/docs/reference/server-api.md +944 -429
  35. package/docs/reference/server-config.md +740 -338
  36. package/docs/reference/training.md +393 -254
  37. package/docs/reference/troubleshooting.md +158 -0
  38. package/package.json +9 -4
  39. package/src/audio/decode.ts +2 -2
  40. package/src/audio/features.ts +2 -2
  41. package/src/backends/mlx/assistant-target.ts +46 -0
  42. package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
  43. package/src/backends/mlx/autoregressive.ts +108 -0
  44. package/src/backends/mlx/batch-group.ts +1790 -0
  45. package/src/backends/mlx/cache-attachment.ts +67 -0
  46. package/src/backends/mlx/cache-layout.ts +31 -0
  47. package/src/backends/mlx/checkpoint-state.ts +53 -0
  48. package/src/backends/mlx/continuation-persistence.ts +106 -0
  49. package/src/backends/mlx/continuation-request.ts +43 -0
  50. package/src/backends/mlx/continuation.ts +77 -0
  51. package/src/backends/mlx/diffusion.ts +39 -0
  52. package/src/backends/mlx/draft-target.ts +32 -0
  53. package/src/backends/mlx/evaluation.ts +105 -0
  54. package/src/backends/mlx/fill-append.ts +45 -0
  55. package/src/backends/mlx/full-kv-row-append.ts +32 -0
  56. package/src/backends/mlx/full-kv-row-donor.ts +54 -0
  57. package/src/backends/mlx/full-transitioning-kv-rows.ts +65 -0
  58. package/src/backends/mlx/gateway-binding.ts +130 -0
  59. package/src/backends/mlx/graph.ts +38 -0
  60. package/src/backends/mlx/kv-codec.ts +9 -0
  61. package/src/backends/mlx/kv-maintenance.ts +133 -0
  62. package/src/backends/mlx/kv-tensor-rows.ts +212 -0
  63. package/src/backends/mlx/memory-client.ts +189 -0
  64. package/src/backends/mlx/methods.ts +90 -0
  65. package/src/backends/mlx/model-prompt.ts +164 -0
  66. package/src/backends/mlx/model-serving.ts +79 -0
  67. package/src/backends/mlx/prefill-cohort.ts +89 -0
  68. package/src/backends/mlx/prefill-rows.ts +200 -0
  69. package/src/backends/mlx/prefill.ts +33 -0
  70. package/src/backends/mlx/projected-context-rows.ts +72 -0
  71. package/src/backends/mlx/request-policy.ts +20 -0
  72. package/src/backends/mlx/request-state-policy.ts +41 -0
  73. package/src/backends/mlx/rollback.ts +89 -0
  74. package/src/backends/mlx/row-sampling.ts +49 -0
  75. package/src/backends/mlx/serial-executor.ts +242 -0
  76. package/src/backends/mlx/speculative-group.ts +359 -0
  77. package/src/backends/mlx/speculative-round.ts +161 -0
  78. package/src/backends/mlx/speculative.ts +114 -0
  79. package/src/backends/mlx/state-rows.ts +104 -0
  80. package/src/backends/mlx/state-views.ts +46 -0
  81. package/src/backends/mlx/target-layout-capability.ts +35 -0
  82. package/src/backends/mlx/text-engine.ts +73 -0
  83. package/src/backends/mlx/transitioning-kv-rows.ts +165 -0
  84. package/src/cli.ts +66 -58
  85. package/src/client.ts +66 -0
  86. package/src/config.ts +21 -4
  87. package/src/contracts/completion.ts +16 -0
  88. package/src/contracts/execution.ts +60 -0
  89. package/src/contracts/generation.ts +103 -0
  90. package/src/contracts/host.ts +7 -0
  91. package/src/contracts/jobs.ts +66 -0
  92. package/src/contracts/pi-provider.ts +30 -0
  93. package/src/contracts/pi.ts +259 -0
  94. package/src/contracts/prefix-cache.ts +23 -0
  95. package/src/contracts/resources.ts +25 -0
  96. package/src/contracts/sampling.ts +23 -0
  97. package/src/contracts/scheduling.ts +45 -0
  98. package/src/contracts/tsconfig.json +14 -0
  99. package/src/diffusion/diffusion-generate.ts +218 -153
  100. package/src/embed.ts +1 -1
  101. package/src/engine/admission.ts +59 -0
  102. package/src/engine/cancellation.ts +38 -0
  103. package/src/engine/engine.ts +56 -0
  104. package/src/engine/execution-coordinator.ts +70 -0
  105. package/src/engine/execution-plan.ts +53 -0
  106. package/src/engine/resources.ts +53 -0
  107. package/src/engine/scheduler.ts +72 -0
  108. package/src/engine/session.ts +247 -0
  109. package/src/eval/README.md +44 -1
  110. package/src/eval/kl.ts +236 -3
  111. package/src/eval/reference-logits.ts +207 -0
  112. package/src/eval/runner.ts +8 -96
  113. package/src/fill/echo-index.ts +188 -0
  114. package/src/fill/fill-session.ts +452 -0
  115. package/src/fill/proposal.ts +68 -0
  116. package/src/fill/schema-rows.ts +506 -0
  117. package/src/fill/tool-boundary.ts +103 -0
  118. package/src/fit.ts +30 -16
  119. package/src/generate.ts +709 -417
  120. package/src/grammar.ts +12 -7
  121. package/src/harness-pi.ts +14 -33
  122. package/src/hub-rest.ts +4 -4
  123. package/src/index.ts +7 -0
  124. package/src/inference/denoising.ts +17 -0
  125. package/src/inference/draft-acceptance.ts +41 -0
  126. package/src/inference/draft-output.ts +49 -0
  127. package/src/inference/graph.ts +33 -0
  128. package/src/inference/prefill.ts +39 -0
  129. package/src/inference/rollback.ts +7 -0
  130. package/src/jobs/db.ts +4 -0
  131. package/src/jobs/index.ts +2 -0
  132. package/src/jobs/job-entry.ts +12 -12
  133. package/src/jobs/runner.ts +98 -13
  134. package/src/jobs/task-client.ts +19 -0
  135. package/src/jobs/types.ts +2 -58
  136. package/src/kv-scheme.ts +70 -12
  137. package/src/kv-store.ts +177 -63
  138. package/src/lab/README.md +18 -0
  139. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  140. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  141. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +5 -5
  142. package/src/lab/paged-kv/paged-kv-rows.ts +83 -0
  143. package/src/{model → lab/paged-kv}/paged-kv.ts +32 -15
  144. package/src/library.ts +40 -0
  145. package/src/lora.ts +18 -0
  146. package/src/media-fetch.ts +1 -1
  147. package/src/memory/article.ts +1 -1
  148. package/src/memory/chunk.ts +1 -1
  149. package/src/memory/model.ts +30 -169
  150. package/src/memory/prompts.ts +1 -1
  151. package/src/memory/rest.ts +1 -1
  152. package/src/memory/schedule.ts +1 -1
  153. package/src/memory/stages.ts +4 -1
  154. package/src/memory/vault.ts +1 -3
  155. package/src/mlx/array.ts +11 -11
  156. package/src/mlx/compile.ts +12 -2
  157. package/src/mlx/ffi.ts +58 -11
  158. package/src/mlx/materialize.ts +23 -0
  159. package/src/mlx/metal-kernel.ts +10 -11
  160. package/src/mlx/ops.ts +33 -13
  161. package/src/mlx/quantized-rows.ts +36 -0
  162. package/src/mlx/token-bitmask.ts +52 -0
  163. package/src/mlx/turboquant-kv-decode.ts +82 -0
  164. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  165. package/src/mlx/turboquant-ops.ts +33 -3
  166. package/src/mlx/turboquant-tables.ts +2 -2
  167. package/src/model/artifact-identity.ts +73 -0
  168. package/src/model/batched-kv.ts +235 -0
  169. package/src/model/batched-mask.ts +20 -6
  170. package/src/model/batched-quant.ts +9 -3
  171. package/src/model/batched-quantized-kv.ts +144 -0
  172. package/src/model/batched-rotating-quant.ts +78 -17
  173. package/src/model/batched-rotating-state.ts +76 -0
  174. package/src/model/batched-rotating.ts +65 -23
  175. package/src/model/batched-row-storage.ts +52 -0
  176. package/src/model/batched-ssm.ts +52 -0
  177. package/src/model/batched-turboquant-kv.ts +93 -0
  178. package/src/model/compiled-decode.ts +8 -2
  179. package/src/model/decoded-kv-donor.ts +12 -0
  180. package/src/model/delayed-quantized-kv.ts +72 -0
  181. package/src/model/delayed-rotating-quantized-kv.ts +93 -0
  182. package/src/model/delayed-turboquant-kv.ts +55 -0
  183. package/src/model/diffusion-gemma.ts +8 -8
  184. package/src/model/factory.ts +76 -33
  185. package/src/model/fingerprint.ts +1 -1
  186. package/src/model/flash-attention.ts +3 -3
  187. package/src/model/full-prefill-padding.ts +56 -0
  188. package/src/model/full-prefill-row.ts +105 -0
  189. package/src/model/gemma4-base.ts +179 -80
  190. package/src/model/gemma4.ts +40 -32
  191. package/src/model/generated/gemma4-12b.ts +6 -3
  192. package/src/model/generated/gemma4-26b.ts +6 -3
  193. package/src/model/generated/gemma4-e4b.ts +6 -3
  194. package/src/model/glm52-cache.ts +80 -4
  195. package/src/model/glm52-dsa.ts +13 -9
  196. package/src/model/glm52-memory.ts +1 -1
  197. package/src/model/glm52-mla.ts +12 -6
  198. package/src/model/glm52.ts +19 -40
  199. package/src/model/implementation.ts +69 -0
  200. package/src/model/kv-attention-view.ts +67 -0
  201. package/src/model/minicpm5.ts +17 -15
  202. package/src/model/profile.ts +12 -2
  203. package/src/model/qwen-append.ts +12 -0
  204. package/src/model/qwen-conv.ts +52 -0
  205. package/src/model/qwen3-delta-state.ts +74 -0
  206. package/src/model/qwen3-delta.ts +59 -36
  207. package/src/model/qwen3_5-checkpoint.ts +164 -0
  208. package/src/model/qwen3_5.ts +202 -78
  209. package/src/model/rotating-kv-donor.ts +35 -0
  210. package/src/model/rotating-kv-layout.ts +262 -0
  211. package/src/model/rotating-row-transaction.ts +35 -0
  212. package/src/model/speculative-rotating-kv.ts +101 -0
  213. package/src/model/ssm-prefill-padding.ts +39 -0
  214. package/src/model/support.ts +1 -1
  215. package/src/model/trellis-balanced-scatter.ts +51 -0
  216. package/src/model/trellis-linear.ts +672 -0
  217. package/src/model/trellis-shared-m.ts +151 -0
  218. package/src/model/trellis-shared-scatter.ts +144 -0
  219. package/src/model/trellis-splitk-prefill.ts +158 -0
  220. package/src/model/trellis-tiled-prefill.ts +136 -0
  221. package/src/model/trellis-vector-expand.ts +62 -0
  222. package/src/model/trellis-wide-prefill.ts +94 -0
  223. package/src/model/turboquant-codec.ts +83 -0
  224. package/src/model/universal/dense.ts +15 -14
  225. package/src/model/universal/modules.ts +8 -1
  226. package/src/native-pack.ts +6 -5
  227. package/src/pi-provider.ts +6 -64
  228. package/src/pi-web.ts +8 -315
  229. package/src/preflight.ts +31 -15
  230. package/src/prompt-cache.ts +110 -69
  231. package/src/quantize/allocator.ts +1 -1
  232. package/src/quantize/config-writer.ts +10 -3
  233. package/src/quantize/rotate.ts +4 -4
  234. package/src/quantize/trellis.ts +586 -0
  235. package/src/responses.ts +28 -1
  236. package/src/runtime-config.ts +18 -4
  237. package/src/sampler.ts +40 -29
  238. package/src/serve/batch-scheduler.ts +8 -1671
  239. package/src/serve/chat-request.ts +391 -0
  240. package/src/serve/chat-stage.ts +195 -0
  241. package/src/serve/checkpoint-identity.ts +64 -0
  242. package/src/serve/completion-executor.ts +15 -7
  243. package/src/serve/discovery-routes.ts +12 -13
  244. package/src/serve/generation-gateway.ts +183 -213
  245. package/src/serve/http.ts +159 -0
  246. package/src/serve/inference-request.ts +79 -0
  247. package/src/serve/isolate.ts +297 -105
  248. package/src/serve/lab-routes.ts +3 -0
  249. package/src/serve/lane-registry.ts +2 -1
  250. package/src/serve/model-admin-routes.ts +7 -5
  251. package/src/serve/model-binding.ts +43 -0
  252. package/src/serve/model-host.ts +511 -0
  253. package/src/serve/openai-wire.ts +103 -0
  254. package/src/serve/parent-application.ts +56 -0
  255. package/src/serve/pipeline.ts +33 -0
  256. package/src/serve/preparation.ts +33 -0
  257. package/src/serve/request-plan.ts +23 -18
  258. package/src/serve/request-prep.ts +344 -0
  259. package/src/serve/response-lease.ts +24 -0
  260. package/src/serve/responses-client.ts +69 -0
  261. package/src/serve/session-completion-engine.ts +110 -0
  262. package/src/serve/session-search.ts +1 -1
  263. package/src/serve/static-routes.ts +5 -5
  264. package/src/serve/text-completion-stage.ts +104 -0
  265. package/src/serve/token-streams.ts +519 -0
  266. package/src/server.ts +335 -2711
  267. package/src/spec/assistant-rows.ts +92 -0
  268. package/src/spec/assistant-source.ts +31 -55
  269. package/src/spec/cache-identity.ts +22 -0
  270. package/src/spec/deepspec-rows.ts +29 -0
  271. package/src/spec/deepspec-source.ts +16 -14
  272. package/src/spec/dflash-source.ts +36 -12
  273. package/src/spec/drafter.ts +153 -142
  274. package/src/spec/dspark/ab-stats.ts +3 -3
  275. package/src/spec/dspark/calibration.ts +2 -2
  276. package/src/spec/dspark/deepspec-module.ts +97 -122
  277. package/src/spec/dspark/generate-dflash.ts +2 -2
  278. package/src/spec/dspark/generate.ts +2 -2
  279. package/src/spec/dspark/loader.ts +1 -1
  280. package/src/spec/dspark/module-dflash.ts +129 -172
  281. package/src/spec/dspark/module.ts +3 -3
  282. package/src/spec/dspark/quantize-drafter.ts +1 -1
  283. package/src/spec/generate.ts +1 -1
  284. package/src/spec/glm52-mtp-graph.ts +29 -0
  285. package/src/spec/glm52-mtp-rows.ts +132 -0
  286. package/src/spec/glm52-mtp-source.ts +54 -137
  287. package/src/spec/glm52-mtp-state.ts +33 -0
  288. package/src/spec/ngram-source.ts +93 -21
  289. package/src/spec/projected-draft-rows.ts +73 -0
  290. package/src/spec/qwen-mtp-module.ts +171 -0
  291. package/src/spec/qwen-mtp-rows.ts +219 -0
  292. package/src/spec/qwen-mtp-source.ts +147 -195
  293. package/src/spec/qwen-mtp-state.ts +30 -0
  294. package/src/spec/serve-loop.ts +201 -201
  295. package/src/spec/source.ts +110 -13
  296. package/src/spec/two-model-rows.ts +61 -0
  297. package/src/spec/two-model.ts +44 -102
  298. package/src/ssd-cache.ts +99 -19
  299. package/src/ssd-durability.ts +36 -20
  300. package/src/tool-call.ts +51 -14
  301. package/src/train/flash-cce.ts +2 -2
  302. package/src/train/forward.ts +6 -0
  303. package/src/train/loss.ts +1 -1
  304. package/src/train/prefix-shared.ts +5 -1
  305. package/src/train/segmented.ts +5 -3
  306. package/src/train/trainer.ts +6 -6
  307. package/src/vision/prompt.ts +1 -1
  308. package/src/vision/qwen3vl-tower.ts +52 -10
  309. package/src/web/app.html +1 -1
  310. package/src/web/app.js +62 -60
  311. package/src/web/src/adapters-panel.ts +3 -3
  312. package/src/web/src/assistant.ts +2 -36
  313. package/src/web/src/chat.ts +4 -4
  314. package/src/web/src/composer.ts +4 -4
  315. package/src/web/src/hub.ts +1 -1
  316. package/src/web/src/markdown.ts +0 -0
  317. package/src/web/src/memory-panel.ts +1 -1
  318. package/src/web/src/model-picker.ts +1 -1
  319. package/src/web/src/palette.ts +1 -1
  320. package/src/web/src/protocol.ts +3 -39
  321. package/src/web/src/sessions.ts +1 -1
  322. package/src/web/src/ui-catalog.ts +4 -18
  323. package/src/web-assets.ts +47 -0
  324. package/src/weights.ts +55 -9
  325. package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
  326. package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
  327. package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
  328. package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
  329. package/docs/archive/investigations/hlg-ab.html +0 -34
  330. package/docs/archive/investigations/hlg-explorer.html +0 -238
  331. package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
  332. package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
  333. package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
  334. package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
  335. package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
  336. package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
  337. package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
  338. package/docs/archive/investigations/hlg-report.html +0 -262
  339. package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
  340. package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  341. package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
  342. package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
  343. package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
  344. package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
  345. package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
  346. package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
  347. package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
  348. package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
  349. package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  350. package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
  351. package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
  352. package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
  353. package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  354. package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  355. package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  356. package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  357. package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  358. package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  359. package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  360. package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
  361. package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
  362. package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
  363. package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
  364. package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
  365. package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  366. package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
  367. package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
  368. package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
  369. package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
  370. package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
  371. package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  372. package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
  373. package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  374. package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  375. package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  376. package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  377. package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  378. package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  379. package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
  380. package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  381. package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
  382. package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  383. package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  384. package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  385. package/docs/archive/mlx-bun-lab-report.html +0 -275
  386. package/docs/archive/wwdc-mlx-bun.html +0 -848
  387. package/docs/design/adapters-end-to-end.md +0 -205
  388. package/docs/design/batching-perf-path.md +0 -255
  389. package/docs/design/batching-v2-plan.md +0 -529
  390. package/docs/design/bucketing-stage.md +0 -197
  391. package/docs/design/compat-cli-surface-design.md +0 -230
  392. package/docs/design/docs-reorg-plan.md +0 -165
  393. package/docs/design/dspark-serving-program.md +0 -371
  394. package/docs/design/dspark-speculative-decoding.md +0 -318
  395. package/docs/design/grammar-spec-batching-integration.md +0 -301
  396. package/docs/design/memory-inference-path.md +0 -422
  397. package/docs/design/memory-synthesis.md +0 -287
  398. package/docs/design/memory-system.md +0 -237
  399. package/docs/design/mlx-lm-serving-execution-seam.md +0 -81
  400. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  401. package/docs/design/omlx-adoption-map.md +0 -98
  402. package/docs/design/orpo-dynamic-lambda.md +0 -220
  403. package/docs/design/orpo-future-enhancements.md +0 -340
  404. package/docs/design/paged-kv-cache.md +0 -214
  405. package/docs/design/parallel-slots.md +0 -567
  406. package/docs/design/parity-tier-dag.md +0 -161
  407. package/docs/design/repo-cleanup-plan.md +0 -231
  408. package/docs/design/runtime-isolation.md +0 -263
  409. package/docs/design/segmented-backward-training.md +0 -543
  410. package/docs/design/spec-decode-larger-targets.md +0 -229
  411. package/docs/design/ssd-kv-cold-tier.md +0 -415
  412. package/docs/design/structured-output.md +0 -484
  413. package/docs/design/tauri-desktop-app.md +0 -127
  414. package/docs/design/the-dreaming-master-plan.md +0 -445
  415. package/docs/design/turboquant-kv.md +0 -235
  416. package/docs/design/turboquant-weights.md +0 -467
  417. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  418. package/docs/design/web-chat-beat-matrix.md +0 -315
  419. package/docs/design/write-pipeline-entity.md +0 -468
  420. package/docs/planning/IDEAS.md +0 -69
  421. package/docs/reference/embedding.md +0 -197
  422. package/docs/reference/features-matrix.md +0 -101
  423. package/docs/reference/orpo-quickstart.md +0 -135
  424. package/src/flags.ts +0 -11
  425. /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
  426. /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
  427. /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
  428. /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
  429. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  430. /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
  431. /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
  432. /package/{docs/archive/investigations → src/serve/assets}/curve-terrain.html +0 -0
  433. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -1,422 +0,0 @@
1
- # Memory inference path rework — The Dreaming
2
-
3
- Status: BUILT + VERIFIED (2026-06-28). Templating fix + single-model reuse
4
- land and are ready; batching is implemented but is a measured *loss* for
5
- the real memory workload (see "Verification results" below). Owner: memory
6
- pipeline.
7
-
8
- > ## Verification results (2026-06-28, M-series GPU, e4b OptiQ-4bit)
9
- >
10
- > Ran on `~/.cache/.../chunk-data-le4000/valid.jsonl` (HELD-OUT, not
11
- > training rows) + the live vault (`memory.sqlite`, 2096 convs).
12
- >
13
- > 1. **tsc = 0** (whole repo). Non-GPU suite green:
14
- > `tests/memory-templating.test.ts` → 7/7 pass (4 CPU message-shape, 2
15
- > CPU training-parity, 1 GPU batched-order).
16
- > 2. **Templating matches training — CONFIRMED.** `memoryPromptIds("chunk",
17
- > {system: CHUNK_SYSTEM, user}, …)` is **byte/id-identical** to
18
- > `encodeSftRow`'s prompt region for a real train row (the CPU parity
19
- > test asserts `ids.length` + `ids` equal and the rendered text starts
20
- > `<bos><|turn>system`). `CHUNK_SYSTEM` equals `messages[0].content`
21
- > verbatim. The chunk stage now decodes ON-distribution.
22
- > 3. **Chunk adapter on-distribution — CONFIRMED.** On the 4 held-out
23
- > multi-chunk valid rows (7/10/11/35) the corrected `system+user` path
24
- > produced valid JSON with **all anchors in range** (4/4 each, except
25
- > row 11 which collapsed 2→1 — same as the old path) and faithful
26
- > labels (e.g. "Wonder Valley homestead land size and payment").
27
- > Caveat: the OLD user-only path on the SAME adapter *also* produced
28
- > valid in-range JSON on these rows — the adapter generalizes, so the
29
- > behavioral delta is minor (label phrasing). The load-bearing win is
30
- > the byte-exact training-contract match, not a dramatic quality jump on
31
- > these easy/short held-out rows (the valid set is ~90% single-chunk).
32
- > 4. **Batching — IMPLEMENTED, but NOT a speedup for memory stages.**
33
- > - 8 extract-style prompts (~400-token prefills, maxTokens=96):
34
- > **batched 9345ms vs serial 5001ms = 0.54x (≈1.9x SLOWER)**, 8/8
35
- > exact match.
36
- > - 8 short replies (maxTokens=24): batched 2085ms vs serial 1067ms =
37
- > 0.51x SLOWER, **7/8** match (row 6 "H2O" vs "Water" — the documented
38
- > near-tie decode-path divergence, `runner.ts:104-108`, not an
39
- > ordering/contamination bug).
40
- > - 16 short uniform one-liners (maxTokens=64): serial(width=1) 6168ms
41
- > vs batched 5139ms (width=8) = **~1.2x faster** — batching only wins
42
- > for many short *uniform* prompts where prefill-pad waste is small.
43
- >
44
- > Root cause: the bit-exact serial path prefills each sequence with one
45
- > efficient single-sequence forward; the `BatchScheduler` pads to the
46
- > batch's max prompt length, so heterogeneous long prefills (exactly the
47
- > EXTRACT/chunk shape) waste compute and lose to serial.
48
- >
49
- > **Recommendation:** ship the templating fix + single-model reuse (the
50
- > real wins); **default `MLX_BUN_MEMORY_BATCH=1`** (serial bit-exact) until
51
- > the scheduler grows length-bucketed / ragged prefill — current batching
52
- > regresses the EXTRACT stage AND can diverge on near-ties. Re-segmenting
53
- > the corpus on the corrected on-distribution path is *principled but
54
- > low-urgency* (old output was already valid in-range; delta is modest).
55
-
56
- *(Original design statement below — superseded; the rework is BUILT, see the
57
- banner at the top of this file.)*
58
-
59
- Scope: the local-model call seam used by every Dreaming stage
60
- (`src/memory/*` → `callLocal` → `src/eval/runner.ts generateText`). Two
61
- defects, one rework.
62
-
63
- ## Problem (verified)
64
-
65
- 1. **Off-distribution chunk decode (correctness).** The `memory-chunk`
66
- adapter (`e4b-chunk-300`) was SFT'd on rows shaped
67
- `{messages:[{role:"system",…},{role:"user",…},{role:"assistant",…}]}`
68
- and training renders the *full* message list, system turn included
69
- (`src/train/dataset.ts:86-88`, `:98-101`). The e4b chat template emits
70
- a **distinct** `<|turn>system\n…<turn|>\n` block when
71
- `messages[0].role in ['system','developer']`
72
- (`chat_template.jinja:179-204`) — this is the Gemma-4 `<|turn>…<turn|>`
73
- format that supports a native system role. But live inference renders
74
- the prompt as a **single user turn**:
75
- `tm.template!.render([{ role: "user", content: body }], …)`
76
- (`src/eval/runner.ts:139-141`), so the entire system segment is
77
- dropped. Verified rendered shapes on the real e4b snapshot:
78
- - training: `"<bos><|turn>system\n{SYS}<turn|>\n<|turn>user\n{USER}<turn|>\n<|turn>model\n"`
79
- - live: `"<bos><|turn>user\n{USER}<turn|>\n<|turn>model\n"`
80
-
81
- The chunk adapter is decoded with its trained system prompt missing — a
82
- real distributional gap, not cosmetic.
83
-
84
- 2. **Single-loaded + serial (throughput).** `callLocal`
85
- (`src/memory/model.ts:62-75`) loads its **own** `TaskModel` per
86
- `(stage, adapter-present)` key (`:46-57`) and decodes serially through
87
- `greedyDecodeBitExact` (`runner.ts:109-131`), one forward loop per
88
- call. The hot stages are embarrassingly parallel (EXTRACT: one 128-tok
89
- call per chunk over thousands; ROUTE/SECTION: 4–16-tok binary gates;
90
- SEGMENT: one 2048-tok call per conversation) but run one at a time.
91
-
92
- The server already solves (1): `server.ts:977` renders the **whole**
93
- `normalizeMessages(req.messages)` array (system + user + …) through the
94
- same `ChatTemplate`, so system lands as its distinct block. The fix is to
95
- make the memory path do the same, and to route batchable stages through
96
- the in-process continuous-batching engine.
97
-
98
- ## (a) Routing decision — in-process gateway, NOT the HTTP server
99
-
100
- **Decision: drive an in-process `BatchScheduler` (via a thin
101
- `MemoryExecutor`) over ONE shared `RuntimeModel`.** Not the HTTP server.
102
-
103
- Rationale:
104
- - **No-start-servers rule** (CLAUDE.md): an agent/bootstrap job cannot
105
- `mlx-bun serve`; the HTTP route presupposes an externally-managed
106
- server. Coupling the offline bootstrap to a running server is fragile.
107
- - **The gateway/scheduler are pure objects.** `GenerationGateway`'s
108
- constructor is `new GenerationGateway(model, batch, serialRun)`
109
- (`generation-gateway.ts:77-83`) — no HTTP. `BatchScheduler`'s is
110
- `new BatchScheduler(model, { maxBatch, lock })`
111
- (`batch-scheduler.ts:101`). Both are constructible in-process over a
112
- `loadTaskModel(...).model`.
113
- - **Per-request adapter does not batch on the server anyway.** Any request
114
- with an adapter is forced to the serial lane on the server too
115
- (`willBatch` excludes `hasAdapters`, `generation-gateway.ts:103`;
116
- `server.ts:1570-1577`). So HTTP buys us nothing for the one adapter we
117
- have (chunk) and adds a process boundary.
118
- - **The workload is exactly what continuous batching targets** — a long
119
- offline sweep over all eligible conversations/chunks
120
- (`chunk.ts:220-286`; the extract/route/section hot loops).
121
-
122
- **Fallback:** when only one row is in flight (N==1) or batching is
123
- disabled, `MemoryExecutor` decodes through the **existing bit-exact greedy
124
- path** (`greedyDecodeBitExact`, `runner.ts:109-131`) so single calls keep
125
- token-for-token parity. The in-process scheduler is the throughput lane,
126
- not a hard dependency.
127
-
128
- We construct the executor directly over `BatchScheduler.submit` rather
129
- than `GenerationGateway.run`, because `gateway.willBatch` hard-excludes
130
- adapters (`:103`) — routing the chunk stage through `run()` would silently
131
- fall back to serial. Driving `scheduler.submit()` directly lets us manage
132
- `loraState.active` ourselves for the chunk batch (see (c)).
133
-
134
- ## (b) Templating — system vs user per stage
135
-
136
- The new seam renders a **message array** through the same template path
137
- the server uses, instead of wrapping `body` as a lone user turn.
138
-
139
- Render contract (mirrors `server.ts:977-980`):
140
- ```
141
- const rendered = template.render(messages, { addGenerationPrompt: true });
142
- const ids = tokenizer.encode(rendered, /* addSpecialTokens */ false); // template emits BOS
143
- // BOS-dedupe identical to promptIdsFor (server.ts:979-980)
144
- ```
145
- `messages` is `[{role:"system",content:SYS}, {role:"user",content:USER}]`
146
- (system omitted when a stage has none → user-only, today's shape). This is
147
- byte-identical to how `encodeSftRow` builds the prompt region
148
- (`dataset.ts:98-101`, `render(promptMessages, {addGenerationPrompt:true})`).
149
-
150
- **Per-stage system/user split:**
151
-
152
- | stage string | adapter | system (instruction + policy) | user (content to operate on) | maxTokens |
153
- |---|---|---|---|---|
154
- | `chunk` | `memory-chunk`→e4b-chunk-300 | **exact trained system** (below) | `CHUNK_PROMPT` body + inlined Meta pages + `Here is the conversation:` + `formatConversation(...)` | 2048 |
155
- | `entity` | base | extraction instruction + Entities policy | chunk/text to extract from | 128 |
156
- | `route` | base | `You answer only 'yes' or 'no'.` + Bucketing policy | the disambiguate/engagesAsSubject question | 4 |
157
- | `section` | base | binary / new-section instruction | title/section/gist content | 4 / 16 |
158
- | `synthesis` | base | editorial/synthesis instruction + editorial policy | entity/chunks/article-body | 8–512 |
159
- | `editor` | base | section-editorial instruction + Editorial_Guidelines | section body to edit | 160–512 |
160
-
161
- **Chunk stage system prompt is load-bearing and MUST match training
162
- byte-for-byte.** Add a constant to `src/memory/chunk.ts` reproducing the
163
- trained `messages[0].content` verbatim (from
164
- `~/.cache/mlx-bun/mlx-bun-finetunes/chunk-data-le4000/train.jsonl`):
165
-
166
- ```
167
- export const CHUNK_SYSTEM = `You are a precise conversation-segmentation engine, not a coding assistant and not a chat assistant. You receive ONE conversation transcript and return its topic segmentation.
168
-
169
- Absolute output contract (overrides any conversational instinct):
170
- - Your entire response MUST be a single JSON object, parseable by JSON.parse with no edits.
171
- - No prose, no preamble, no explanation, no follow-up question, no markdown code fences, no tool calls. The first character you emit is "{" and the last is "}".
172
- - Never ask for clarification or more data — the transcript in the message IS the data. If it has no meaningful content, return {"chunks": []}.
173
- - Use only message UUIDs present in the provided transcript; never invent or alter a UUID.
174
-
175
- Follow the segmentation rules and JSON schema in the message exactly.`;
176
- ```
177
-
178
- The chunk SEGMENT call becomes `callLocal("chunk", { system: CHUNK_SYSTEM,
179
- user: promptHead() + formatConversation(...) }, {maxTokens})`.
180
-
181
- **Secondary: chunk USER-turn content drift.** The live `CHUNK_PROMPT`
182
- (`chunk.ts:30-69`) also diverges from the trained user turn on four axes
183
- and these matter for true on-distribution behavior, but are a SEPARATE
184
- fix from the role bug:
185
- - (a) `chunk.ts:32` adds `Use ONLY content from the conversation provided
186
- below; never copy any name…` — absent in training.
187
- - (b) `META_POLICY_PAGES = ["Chunking","Topics_to_Ignore"]` (`chunk.ts:72`)
188
- inlines **2** pages; training inlined **8** (Article_Conventions,
189
- Bucketing, Buckets, Category_Definitions, Chunking,
190
- Editorial_Guidelines, Synthesis_Pipeline, Topics_to_Ignore).
191
- - (c) label guidance rewritten to abstract GOOD/BAD shape vs trained
192
- inline examples (`chunk.ts:55-57`).
193
- - (d) training POLICY line names the vault path `/Users/joshrossi/Dreaming/Meta/`;
194
- live drops it.
195
-
196
- Recommendation: land the **role fix first** (biggest, cheapest win), then
197
- reconcile the user turn to the trained shape *or* retrain `e4b-chunk-300`
198
- against the current `CHUNK_PROMPT`. Pick one; do not leave it
199
- half-aligned. The role fix alone moves the chunk stage substantially
200
- closer to its training distribution.
201
-
202
- For the **base** stages (everything except chunk), the system/user split
203
- is a quality choice for the base instruct model (which was trained to
204
- honor a system turn) — apply it, but there is no trained adapter to match,
205
- so byte-exactness is not required there.
206
-
207
- ## (c) Batching — per-stage homogeneous-adapter batches
208
-
209
- `loraState.active` is a **single global field** on the model, set by
210
- `generate()`'s `adapterScoped` (`generate.ts:235-247`) and applied
211
- uniformly to every row; the scheduler never touches it (it calls
212
- `model.forwardHidden` directly — zero `loraState` refs in
213
- `batch-scheduler.ts`). Therefore **a batch is necessarily single-adapter
214
- (or all-base).** We cannot mix chunk-adapter and base rows in one batch.
215
-
216
- This fits the pipeline naturally because `callLocalBatch` is invoked
217
- **per stage**, and stage→adapter is fixed (`adapterDirFor`,
218
- `model.ts:38-41`; only `memory-chunk` exists on disk):
219
-
220
- - **Base stages (entity / route / section / synthesis / editor):** batch
221
- with **zero** adapter friction — `loraState.active = []`. Submit N rows
222
- to the scheduler. The easy, highest-volume win (EXTRACT first: uniform
223
- 128-tok prompt, one per chunk, no inter-call dependency).
224
- - **Chunk stage:** set `model.loraState.active = ["memory-chunk"]`
225
- **once** for the whole stage batch, submit only chunk rows, reset to
226
- `[]` after. Because `forwardHidden` reads the global `loraState`, all
227
- rows get the adapter uniformly. The executor owns the model exclusively
228
- during the batch (the scheduler holds the lock for its active span), so
229
- there is no concurrent serial generation to clobber `loraState`.
230
-
231
- **Decode-path caveat.** The batched lane samples via `generate()`'s
232
- sampler path (greedy = argmax over `forwardHidden`/`logitsFromHidden`),
233
- NOT the runner's raw-`forward` bit-exact greedy. The runner warns these
234
- diverge on near-ties past ~32 tokens (`runner.ts:104-108`). For chunk's
235
- 2048-tok JSON and the binary gates this is expected to be fine (chunk eval
236
- is well-formedness, per memory notes), but it MUST be validated against
237
- the greedy reference before the chunk batch is trusted (see verification).
238
-
239
- **Batching priority** (from the usage survey, batchable structure):
240
- 1. EXTRACT (`entity`, base, 128 tok, 1/chunk over thousands) — prime win,
241
- uniform prompt, no dependency.
242
- 2. ROUTE + SECTION binaries (`route`/`section`, base, 4–16 tok) — batch
243
- the per-chunk N-section grid and per-candidate gates (the trailing
244
- new-section call depends on all-no — keep it after the batch).
245
- 3. SEGMENT (`chunk`, adapter, 2048 tok, 1/conversation) — batchable across
246
- conversations, but long outputs; the only adapter-bound batch.
247
- 4. SYNTHESIZE/WIKIFY drafts (`synthesis`/`editor`, 96–512 tok) — batch
248
- per-phase within an article (the N independent section drafts), NOT
249
- whole-article (outline→draft and the leak-retry are data-dependent).
250
- 5. RECONCILE — largely serial (`next` mutated in place); leave on the
251
- serial fallback; only the independent binary classifiers batch.
252
-
253
- The hot loops stay where they are; we change *how a set of independent
254
- calls is submitted*. The cleanest refactor: where a stage today does
255
- `for (x of xs) await call(buildPrompt(x))`, collect `xs`, build all
256
- messages, and `await callLocalBatch(stage, messages[])` → results[].
257
- Start with EXTRACT and SEGMENT; leave dependent loops on serial `callLocal`.
258
-
259
- ## (d) API surface
260
-
261
- `src/memory/model.ts` grows a messages-aware seam and a batch seam; the
262
- single-user-turn `generateText` overload is no longer used by the memory
263
- path.
264
-
265
- ```ts
266
- export interface LocalInput {
267
- /** System turn (instruction + policy). Omit for a user-only prompt. */
268
- system?: string;
269
- /** User turn (the content to operate on). */
270
- user: string;
271
- }
272
-
273
- /** One call. N==1 → bit-exact greedy (runner.ts:109-131). */
274
- export async function callLocal(
275
- stage: string,
276
- input: LocalInput,
277
- opts?: { maxTokens?: number },
278
- ): Promise<string>;
279
-
280
- /** N independent calls for one stage (homogeneous adapter). Submitted to
281
- * the shared in-process BatchScheduler when batch>1; otherwise looped on
282
- * the bit-exact greedy path. Order-preserving: out[i] ↔ inputs[i]. */
283
- export async function callLocalBatch(
284
- stage: string,
285
- inputs: LocalInput[],
286
- opts?: { maxTokens?: number },
287
- ): Promise<string[]>;
288
- ```
289
-
290
- Backing implementation — a module-level `MemoryExecutor` (lazy singleton):
291
- - holds ONE `RuntimeModel` (via `loadTaskModel(MODEL_ID)`), ONE
292
- `AdapterManager` with `memory-chunk` mounted once, ONE `BatchScheduler`
293
- (constructed with an in-process `AsyncMutex`-backed lock), and the
294
- tokenizer + template.
295
- - `render(input)` → messages array → `template.render(messages,
296
- {addGenerationPrompt:true})` → `encode(text, false)` → BOS-dedupe →
297
- `promptIds`.
298
- - `callLocalBatch(stage, inputs)`:
299
- 1. `active = adapterDirFor(stage) ? ["memory-chunk"] : []`.
300
- 2. `model.loraState.active = active` for the batch's lifetime.
301
- 3. render all inputs → promptIds; build a per-row token sink (decode via
302
- `tokenizer.decode`); `Promise.all(rows.map(r =>
303
- scheduler.submit({promptIds, maxTokens, eosTokenIds, sample: greedy,
304
- onToken: collect})))`.
305
- 4. reset `model.loraState.active = []`; return decoded strings in order.
306
- - `callLocal` delegates to `callLocalBatch(stage, [input])[0]` when
307
- batching is enabled, else the bit-exact greedy single decode.
308
-
309
- This **consolidates** the per-stage `TaskModel` instances
310
- (`model.ts:46-57`) into one shared model — reuse AND batching in one move.
311
- Stage builders change from passing a `prompt` string to passing
312
- `{system?, user}` (chunk supplies `CHUNK_SYSTEM`).
313
-
314
- `generateText`'s single-user render (`runner.ts:139-141`) is left intact
315
- for the eval suite (its own contract), but the memory path stops calling
316
- it. Optionally add a system-aware overload to `generateText` later to
317
- share the render helper; not required for this rework.
318
-
319
- ## (e) Re-segment the partial import — YES
320
-
321
- The current import (720/2096 conversations segmented) was chunked with the
322
- **old single-user template** (no system role) AND only 2 Meta pages — i.e.
323
- the off-distribution shape this rework fixes. For consistency the whole
324
- corpus should be segmented under one (correct) prompt regime.
325
-
326
- Decision: **re-segment all 720 already-chunked conversations** after the
327
- role fix lands. It is cheap and safe:
328
- - SEGMENT is idempotent — `chunkConversations` deletes prior chunks per
329
- conv and resets `chunked_at` on success (`chunk.ts:262-273`).
330
- - To force a re-run, clear `chunked_at` (set NULL) for the 720 so
331
- `selectEligible` re-admits them; then run the batched SEGMENT.
332
- - Downstream stages key off chunk ids; re-segmentation changes chunk
333
- boundaries/labels, so the dependent EXTRACT/ROUTE/SYNTH state for those
334
- convs must be invalidated too (treat as a fresh segmentation). Sequence
335
- the bootstrap so re-segmentation precedes the downstream sweep.
336
-
337
- Do NOT mix two segmentation regimes in one vault; re-segment for a clean
338
- baseline.
339
-
340
- ## (f) Implementation steps
341
-
342
- 1. **Template seam.** Add `MemoryExecutor` in `src/memory/model.ts`: one
343
- shared `RuntimeModel` + tokenizer + template + `AdapterManager`
344
- (mount `memory-chunk`). Implement `render({system?,user})` →
345
- promptIds (render → encode(false) → BOS-dedupe, matching
346
- `server.ts:979-980`).
347
- 2. **API.** Replace `callLocal(stage, prompt, opts)` with
348
- `callLocal(stage, LocalInput, opts)` + `callLocalBatch`. Single-call
349
- path keeps bit-exact greedy.
350
- 3. **Chunk system.** Add `CHUNK_SYSTEM` (verbatim trained text) to
351
- `chunk.ts`; change the SEGMENT call to pass `{system: CHUNK_SYSTEM,
352
- user: promptHead()+formatConversation(...)}`.
353
- 4. **Per-stage splits.** Update entity/route/section/synthesis/editor
354
- builders to return `{system, user}` (move instruction+policy → system,
355
- content → user). Mechanical; one stage at a time, tsc-green each.
356
- 5. **Batch the hot stages.** Convert EXTRACT first
357
- (`entity.ts`/`stages.ts:333-340`), then SEGMENT
358
- (`chunk.ts:220-286`), to collect inputs and call `callLocalBatch`.
359
- Leave dependent loops (reconcile, outline→draft) on serial `callLocal`.
360
- 6. **loraState management.** In `callLocalBatch`, set/reset
361
- `model.loraState.active` around the chunk batch; assert base stages
362
- submit with `active=[]`.
363
- 7. **Re-segment.** One-off: NULL `chunked_at` for the 720 imported convs,
364
- invalidate downstream state, run batched SEGMENT, then the downstream
365
- sweep.
366
- 8. **tsc 0** across the repo incl. `scripts/experiments` (standing rule).
367
-
368
- ## Verification plan
369
-
370
- - **Templating parity (the correctness gate).** Render the chunk
371
- `{system,user}` through the new seam and assert the token ids equal the
372
- training prompt-region ids for a real `train.jsonl` row: rebuild the row
373
- via `encodeSftRow`'s prompt render (`dataset.ts:98-101`,
374
- `render(messages,{addGenerationPrompt:true})`) and compare. Must be
375
- byte/id-identical (same `<|turn>system…<turn|>` block, single BOS).
376
- This is the foundation — verify it before any generation claim
377
- (standing "verify the foundation" rule).
378
- - **System-present smoke.** Decode one conversation with the new seam and
379
- confirm the rendered prompt contains the system block (not user-only);
380
- diff against the old render to show the gap closed.
381
- - **Batching correctness.** For a base stage (EXTRACT) and the chunk
382
- stage, compare `callLocalBatch([a,b,c])` against three serial
383
- `callLocal` greedy decodes. Base/binary outputs should match; for chunk,
384
- validate the batched (sampler-path) output against the bit-exact greedy
385
- reference and accept divergence only within the documented near-tie
386
- envelope (chunk eval = well-formedness: valid JSON, in-range anchors).
387
- - **Chunk-adapter behavior.** Confirm `loraState.active=["memory-chunk"]`
388
- is set for the chunk batch and `[]` for base batches (assert in test).
389
- Re-run `scripts/chunk-eval.ts` before/after the role fix; expect
390
- well-formedness and boundary/label quality to improve now that decode is
391
- on-distribution.
392
- - **No-leak / single-model.** Confirm the executor loads ONE model (not
393
- per-stage instances) and peak memory does not regress vs the current
394
- per-stage cache; watch for KV/loraState leaks across batches.
395
- - **Re-segment sanity.** After re-segmenting the 720, spot-check chunk
396
- counts/labels vs the old segmentation and confirm downstream stages
397
- re-run cleanly on the new boundaries.
398
-
399
- ## Risks
400
-
401
- - **Decode divergence on the batched lane.** generate()'s sampler path ≠
402
- the runner's raw-forward greedy past ~32 tokens on near-ties
403
- (`runner.ts:104-108`). Mitigation: greedy sampler + well-formedness
404
- validation; keep the bit-exact greedy path for the single-call fallback
405
- and for any stage that proves sensitive.
406
- - **Global `loraState` clobber.** The chunk batch sets a global field; any
407
- concurrent generation would corrupt it. The bootstrap runs one executor
408
- with exclusive model ownership, so this is safe — but the seam must
409
- never be shared with a live server process.
410
- - **User-turn content drift (chunk).** The role fix alone does not close
411
- the 8-vs-2 Meta-pages / examples / vault-path drift. Track as a
412
- follow-up: reconcile `CHUNK_PROMPT` to training or retrain the adapter.
413
- Until then the chunk stage is *closer* to, but not fully on,
414
- distribution.
415
- - **Re-segment blast radius.** Re-segmentation invalidates downstream
416
- state for the 720 convs; sequencing errors could leave orphaned
417
- extract/route rows. Mitigation: invalidate-then-resweep, idempotent
418
- stages, verify counts.
419
- - **Single trained adapter assumption.** Only `memory-chunk` exists. If
420
- future stages gain adapters, `callLocalBatch` already batches per stage
421
- (homogeneous adapter) — but mixing adapters in one batch remains
422
- impossible by construction; keep stages separate.