mlx-bun 0.0.12 → 0.2.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 (226) hide show
  1. package/README.md +40 -24
  2. package/bin/mlx-bun.mjs +1 -1
  3. package/docs/{design → archive}/hlg-sampling.md +3 -3
  4. package/docs/{investigations → archive/investigations}/hlg-sampling-investigation.md +1 -1
  5. package/docs/archive/investigations/pareto-specialized-runtime-findings.md +92 -0
  6. package/docs/{planning → archive/planning}/chat-ui-vision.md +1 -1
  7. package/docs/archive/planning/release-notes-v0.0.13.md +77 -0
  8. package/docs/{planning → archive/planning}/release-notes-v0.0.9.md +1 -1
  9. package/docs/{planning → archive/planning}/website-readme-pass-plan.md +1 -1
  10. package/docs/design/colibri-glm52-port.md +8 -1
  11. package/docs/design/compat-cli-surface-design.md +1 -1
  12. package/docs/design/decode-speed-program.md +1 -1
  13. package/docs/design/docs-reorg-plan.md +1 -1
  14. package/docs/design/dspark-serving-program.md +1 -1
  15. package/docs/design/dspark-speculative-decoding.md +53 -3
  16. package/docs/design/grammar-spec-batching-integration.md +1 -1
  17. package/docs/design/mlx-lm-serving-execution-seam.md +81 -0
  18. package/docs/design/orpo-dynamic-lambda.md +1 -1
  19. package/docs/design/orpo-future-enhancements.md +1 -1
  20. package/docs/design/orpo-training.md +2 -2
  21. package/docs/design/parity-tier-dag.md +1 -1
  22. package/docs/design/repo-cleanup-plan.md +46 -4
  23. package/docs/design/segmented-backward-training.md +2 -2
  24. package/docs/design/ssd-kv-cold-tier.md +127 -0
  25. package/docs/design/turboquant-weights.md +467 -0
  26. package/docs/design/w4a16-compute-precision-spike.md +1 -1
  27. package/docs/design/web-chat-redesign.md +5 -5
  28. package/docs/planning/chunk-task-roadmap.md +1 -1
  29. package/docs/planning/curve-sampler-research-plan.md +4 -4
  30. package/docs/planning/memory-docs-and-dag-plan.md +1 -1
  31. package/docs/planning/release-notes-v0.2.0.md +49 -0
  32. package/docs/planning/video-series.md +421 -0
  33. package/docs/reference/cli.md +15 -4
  34. package/docs/reference/distribution.md +1 -0
  35. package/docs/reference/features-matrix.md +3 -1
  36. package/docs/reference/library-api.md +41 -1
  37. package/docs/reference/models.md +33 -0
  38. package/docs/reference/server-api.md +86 -19
  39. package/docs/reference/server-config.md +57 -33
  40. package/package.json +2 -2
  41. package/src/anthropic.ts +92 -3
  42. package/src/chat-template.ts +34 -1
  43. package/src/cli.ts +131 -36
  44. package/src/config.ts +10 -0
  45. package/src/eval/kl.ts +27 -20
  46. package/src/eval/runner.ts +23 -4
  47. package/src/eval/tasks/bfcl.ts +2 -1
  48. package/src/eval/tasks/gsm8k.ts +2 -1
  49. package/src/eval/tasks/hashhop.ts +2 -1
  50. package/src/eval/tasks/humaneval.ts +5 -4
  51. package/src/eval/tasks/ifeval.ts +2 -1
  52. package/src/eval/tasks/mmlu.ts +2 -1
  53. package/src/expert-io.ts +3 -1
  54. package/src/expert-offload.ts +3 -1
  55. package/src/expert-trace.ts +3 -1
  56. package/src/fit.ts +24 -43
  57. package/src/flags.ts +7 -9
  58. package/src/generate.ts +107 -92
  59. package/src/grammar.ts +2 -1
  60. package/src/harness-pi.ts +1 -1
  61. package/src/index.ts +20 -0
  62. package/src/jobs/job-entry.ts +3 -2
  63. package/src/kv-scheme.ts +199 -0
  64. package/src/kv-store.ts +370 -205
  65. package/src/media-fetch.ts +19 -3
  66. package/src/memory/model.ts +2 -1
  67. package/src/memory/vault.ts +2 -1
  68. package/src/memory-plan.ts +18 -0
  69. package/src/mlx/ffi.ts +8 -11
  70. package/src/mlx/ops.ts +31 -6
  71. package/src/model/batched-mask.ts +1 -1
  72. package/src/model/batched-quant.ts +1 -1
  73. package/src/model/batched-rotating-quant.ts +43 -97
  74. package/src/model/batched-rotating-state.ts +73 -0
  75. package/src/model/batched-rotating.ts +56 -105
  76. package/src/model/batched-row-storage.ts +127 -0
  77. package/src/model/compiled-decode.ts +3 -2
  78. package/src/model/factory.ts +44 -49
  79. package/src/model/gemma4-base.ts +163 -10
  80. package/src/model/generated/gemma4-12b.ts +50 -146
  81. package/src/model/generated/gemma4-26b.ts +32 -92
  82. package/src/model/generated/gemma4-e4b.ts +26 -74
  83. package/src/model/glm52-cache.ts +19 -9
  84. package/src/model/glm52-memory.ts +28 -1
  85. package/src/model/minicpm5.ts +2 -1
  86. package/src/model/profile.ts +433 -0
  87. package/src/model/qwen3-delta.ts +98 -2
  88. package/src/model/qwen3-mrope.ts +252 -0
  89. package/src/model/qwen3_5.ts +217 -25
  90. package/src/native/frame_extract.swift +140 -0
  91. package/src/native-pack.ts +13 -6
  92. package/src/pi-web.ts +6 -5
  93. package/src/prompt-cache.ts +2 -2
  94. package/src/quantize/atomic-output.ts +38 -0
  95. package/src/quantize/calibration.ts +2 -1
  96. package/src/quantize/config-writer.ts +6 -0
  97. package/src/quantize/index.ts +28 -1
  98. package/src/quantize/job.ts +11 -0
  99. package/src/quantize/quantizer.ts +265 -100
  100. package/src/quantize/rotate.ts +603 -0
  101. package/src/quantize/safetensors-writer.ts +79 -1
  102. package/src/quantize/sensitivity.ts +41 -59
  103. package/src/quantize/weight-transform.ts +292 -0
  104. package/src/responses.ts +102 -2
  105. package/src/runtime-config.ts +67 -0
  106. package/src/sampler.ts +272 -0
  107. package/src/serve/admin-routes.ts +184 -0
  108. package/src/serve/aux-routes.ts +132 -0
  109. package/src/serve/batch-scheduler.ts +200 -87
  110. package/src/serve/completion-executor.ts +346 -0
  111. package/src/serve/completion-sink.ts +157 -0
  112. package/src/serve/discovery-routes.ts +205 -0
  113. package/src/serve/generation-gateway.ts +116 -109
  114. package/src/serve/kv-budget.ts +14 -0
  115. package/src/serve/lab-routes.ts +338 -0
  116. package/src/serve/model-admin-routes.ts +153 -0
  117. package/src/serve/prompt-response-trace.ts +147 -0
  118. package/src/serve/request-plan.ts +158 -0
  119. package/src/serve/static-routes.ts +101 -0
  120. package/src/server.ts +768 -1367
  121. package/src/spec/dflash-source.ts +2 -1
  122. package/src/spec/dspark/module-dflash.ts +1 -1
  123. package/src/spec/glm52-mtp-source.ts +8 -0
  124. package/src/spec/qwen-mtp-source.ts +431 -0
  125. package/src/spec/serve-loop.ts +36 -68
  126. package/src/ssd-cache.ts +17 -14
  127. package/src/ssd-durability.ts +195 -0
  128. package/src/train/flash-cce.ts +12 -11
  129. package/src/train/forward.ts +32 -1
  130. package/src/train/loss.ts +2 -1
  131. package/src/train/segmented.ts +4 -3
  132. package/src/train/trainer.ts +3 -2
  133. package/src/vision/preprocess.ts +1 -1
  134. package/src/vision/prompt.ts +47 -1
  135. package/src/vision/qwen3vl-preprocess.ts +409 -0
  136. package/src/vision/qwen3vl-prompt.ts +196 -0
  137. package/src/vision/qwen3vl-tower.ts +513 -0
  138. package/src/vision/video-frames.ts +148 -0
  139. package/src/web/app.js +10 -3
  140. package/src/web/src/chat.ts +12 -5
  141. package/src/weights.ts +81 -26
  142. /package/docs/{investigations → archive/investigations}/chunk-finetune-experiment.md +0 -0
  143. /package/docs/{investigations → archive/investigations}/colibri-oracle-pin.md +0 -0
  144. /package/docs/{investigations → archive/investigations}/curve-bisector-routing.md +0 -0
  145. /package/docs/{investigations → archive/investigations}/curve-runs/bisector-route.json +0 -0
  146. /package/docs/{investigations → archive/investigations}/curve-runs/bisector-trace.json +0 -0
  147. /package/docs/{investigations → archive/investigations}/curve-runs/curve-terrain.json +0 -0
  148. /package/docs/{investigations → archive/investigations}/curve-runs/curve-terrain.svg +0 -0
  149. /package/docs/{investigations → archive/investigations}/curve-terrain.html +0 -0
  150. /package/docs/{investigations → archive/investigations}/decode-roofline-lookagain.md +0 -0
  151. /package/docs/{investigations → archive/investigations}/dspark-handoff.md +0 -0
  152. /package/docs/{investigations → archive/investigations}/expert-offload-single-user-moe.md +0 -0
  153. /package/docs/{investigations → archive/investigations}/hlg-ab.html +0 -0
  154. /package/docs/{investigations → archive/investigations}/hlg-explorer.html +0 -0
  155. /package/docs/{investigations → archive/investigations}/hlg-figs/cliff.svg +0 -0
  156. /package/docs/{investigations → archive/investigations}/hlg-figs/cross.svg +0 -0
  157. /package/docs/{investigations → archive/investigations}/hlg-figs/edges.svg +0 -0
  158. /package/docs/{investigations → archive/investigations}/hlg-figs/k20-grids.svg +0 -0
  159. /package/docs/{investigations → archive/investigations}/hlg-figs/k20-peaks.svg +0 -0
  160. /package/docs/{investigations → archive/investigations}/hlg-figs/lw-curve.svg +0 -0
  161. /package/docs/{investigations → archive/investigations}/hlg-figs/terrain.svg +0 -0
  162. /package/docs/{investigations → archive/investigations}/hlg-report.html +0 -0
  163. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-ab.json +0 -0
  164. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-blind-prompts.md +0 -0
  165. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-blind.json +0 -0
  166. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-cliff.json +0 -0
  167. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-cross.json +0 -0
  168. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-edge.json +0 -0
  169. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-eval1.json +0 -0
  170. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-frontier.json +0 -0
  171. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-grid.json +0 -0
  172. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-grid2.json +0 -0
  173. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-lw-coarse.json +0 -0
  174. /package/docs/{investigations → archive/investigations}/hlg-runs/hlg-map.json +0 -0
  175. /package/docs/{investigations → archive/investigations}/hlg-runs/run0-original.log +0 -0
  176. /package/docs/{investigations → archive/investigations}/hlg-runs/runA-recommended.log +0 -0
  177. /package/docs/{investigations → archive/investigations}/hlg-runs/runAA-cliff-cpm5.log +0 -0
  178. /package/docs/{investigations → archive/investigations}/hlg-runs/runAB-grid2-e4b.log +0 -0
  179. /package/docs/{investigations → archive/investigations}/hlg-runs/runAC-peak-e4b-partial.log +0 -0
  180. /package/docs/{investigations → archive/investigations}/hlg-runs/runAD-ab-samples.log +0 -0
  181. /package/docs/{investigations → archive/investigations}/hlg-runs/runAE-edge-e4b.log +0 -0
  182. /package/docs/{investigations → archive/investigations}/hlg-runs/runAF-logit-calibration.log +0 -0
  183. /package/docs/{investigations → archive/investigations}/hlg-runs/runAG-eval-config2.log +0 -0
  184. /package/docs/{investigations → archive/investigations}/hlg-runs/runB-gain-variants.log +0 -0
  185. /package/docs/{investigations → archive/investigations}/hlg-runs/runC-pivots.log +0 -0
  186. /package/docs/{investigations → archive/investigations}/hlg-runs/runD-oetf.log +0 -0
  187. /package/docs/{investigations → archive/investigations}/hlg-runs/runE-eotf.log +0 -0
  188. /package/docs/{investigations → archive/investigations}/hlg-runs/runF-shaper-working.log +0 -0
  189. /package/docs/{investigations → archive/investigations}/hlg-runs/runG-shaper-sweep.log +0 -0
  190. /package/docs/{investigations → archive/investigations}/hlg-runs/runH-wsweep.log +0 -0
  191. /package/docs/{investigations → archive/investigations}/hlg-runs/runI-asweep.log +0 -0
  192. /package/docs/{investigations → archive/investigations}/hlg-runs/runJ-knobmap.log +0 -0
  193. /package/docs/{investigations → archive/investigations}/hlg-runs/runK-frontier.log +0 -0
  194. /package/docs/{investigations → archive/investigations}/hlg-runs/runL-widemap.log +0 -0
  195. /package/docs/{investigations → archive/investigations}/hlg-runs/runM-frontier-emb.log +0 -0
  196. /package/docs/{investigations → archive/investigations}/hlg-runs/runN-verify.log +0 -0
  197. /package/docs/{investigations → archive/investigations}/hlg-runs/runO-frontier-seed5000.log +0 -0
  198. /package/docs/{investigations → archive/investigations}/hlg-runs/runP-grid-AxSm.log +0 -0
  199. /package/docs/{investigations → archive/investigations}/hlg-runs/runQ-grid-tgW.log +0 -0
  200. /package/docs/{investigations → archive/investigations}/hlg-runs/runR-blind-transcript.log +0 -0
  201. /package/docs/{investigations → archive/investigations}/hlg-runs/runS-cross-coherence.log +0 -0
  202. /package/docs/{investigations → archive/investigations}/hlg-runs/runT-cross-cpm5.log +0 -0
  203. /package/docs/{investigations → archive/investigations}/hlg-runs/runU-cross-12b.log +0 -0
  204. /package/docs/{investigations → archive/investigations}/hlg-runs/runV-lw-e4b.log +0 -0
  205. /package/docs/{investigations → archive/investigations}/hlg-runs/runW-lw-12b.log +0 -0
  206. /package/docs/{investigations → archive/investigations}/hlg-runs/runX-lw-cpm5.log +0 -0
  207. /package/docs/{investigations → archive/investigations}/hlg-runs/runY-cliff-e4b.log +0 -0
  208. /package/docs/{investigations → archive/investigations}/hlg-runs/runZ-cliff-12b.log +0 -0
  209. /package/docs/{investigations → archive/investigations}/indexshare-performance-spike.md +0 -0
  210. /package/docs/{investigations → archive/investigations}/kernel-perf-review-2026-07.md +0 -0
  211. /package/docs/{investigations → archive/investigations}/lab-build-journal.md +0 -0
  212. /package/docs/{investigations → archive/investigations}/openwiki-evaluation.md +0 -0
  213. /package/docs/{investigations → archive/investigations}/orpo-base-uf-experiment-and-directions.md +0 -0
  214. /package/docs/{investigations → archive/investigations}/orpo-flash-cce-pin-leak.md +0 -0
  215. /package/docs/{investigations → archive/investigations}/orpo-uf-testing-handoff.md +0 -0
  216. /package/docs/{investigations → archive/investigations}/pi-builtin-investigation.md +0 -0
  217. /package/docs/{investigations → archive/investigations}/segmented-backward-handoff.md +0 -0
  218. /package/docs/{investigations → archive/investigations}/starter-model-port-handoff.md +0 -0
  219. /package/docs/{investigations → archive/investigations}/steel-flash-cce-handoff.md +0 -0
  220. /package/docs/{investigations → archive/investigations}/trainer-validation-experiment.md +0 -0
  221. /package/docs/{planning → archive/planning}/chat-ui-vision-memory-first.md +0 -0
  222. /package/docs/{planning → archive/planning}/journal.md +0 -0
  223. /package/docs/{planning → archive/planning}/release-notes-v0.0.10.md +0 -0
  224. /package/docs/{planning → archive/planning}/release-notes-v0.0.11.md +0 -0
  225. /package/docs/{planning → archive/planning}/release-notes-v0.0.12.md +0 -0
  226. /package/docs/{planning → archive/planning}/web-ui-pass-plan.md +0 -0
package/README.md CHANGED
@@ -83,7 +83,7 @@ runtime, so the only thing the first run fetches is the model.
83
83
 
84
84
  ### bunx (no install)
85
85
 
86
- Already have [Bun](https://bun.sh) ≥ 1.3.14? Run it straight from npm,
86
+ Already have [Bun](https://bun.sh) ≥ 1.4.0? Run it straight from npm,
87
87
  nothing to install:
88
88
 
89
89
  ```sh
@@ -97,7 +97,7 @@ mlx-bun` under Node exits with a
97
97
 
98
98
  ### From source
99
99
 
100
- Needs [Bun](https://bun.sh) ≥ 1.3.14 — no Python, no native library to
100
+ Needs [Bun](https://bun.sh) ≥ 1.4.0 — no Python, no native library to
101
101
  install by hand:
102
102
 
103
103
  ```sh
@@ -212,12 +212,12 @@ runtime that serves them:
212
212
  [quickstart](./docs/reference/orpo-quickstart.md)).
213
213
  - **The curve designer** — HLG tone-curve sampling with an interactive
214
214
  designer in the server UI at `/curves`
215
- ([design](./docs/design/hlg-sampling.md)).
215
+ ([design](./docs/archive/hlg-sampling.md)).
216
216
  - **Speculative decoding research (DSpark)** — a KV-injection drafter
217
217
  ([design](./docs/design/dspark-speculative-decoding.md)).
218
218
  - The full research trail — including dead ends — is tracked in
219
219
  [docs/design/](./docs/design/) and
220
- [docs/investigations/](./docs/investigations/).
220
+ [docs/archive/investigations/](./docs/archive/investigations/).
221
221
 
222
222
  On the site: [The lab](https://mlx-bun.dev/about/lab/).
223
223
 
@@ -225,7 +225,7 @@ On the site: [The lab](https://mlx-bun.dev/about/lab/).
225
225
 
226
226
  Scope is deliberate: a few model families held to explicit oracle contracts,
227
227
  rather than dozens held to none. Currently MiniCPM5, the Gemma-4 OptiQ quants,
228
- Qwen3.5-4B, and the direct-container GLM-5.2 path:
228
+ the Qwen 3.x family, and the direct-container GLM-5.2 path:
229
229
 
230
230
  | Model | Download | Fits on | Vision | Notes |
231
231
  |---|---|---|---|---|
@@ -234,14 +234,13 @@ Qwen3.5-4B, and the direct-container GLM-5.2 path:
234
234
  | [`mlx-community/gemma-4-e4b-it-OptiQ-4bit`](https://huggingface.co/mlx-community/gemma-4-e4b-it-OptiQ-4bit) | 7.0 GB | 16 GB | ✓ | **Recommended starter** (16 GB+); ~56 tok/s |
235
235
  | [`mlx-community/gemma-4-12B-it-OptiQ-4bit`](https://huggingface.co/mlx-community/gemma-4-12B-it-OptiQ-4bit) | 8.4 GB | 16 GB | ✓ | Vision + tool calling, both verified end-to-end |
236
236
  | [`mlx-community/gemma-4-26B-A4B-it-OptiQ-4bit`](https://huggingface.co/mlx-community/gemma-4-26B-A4B-it-OptiQ-4bit) | 18 GB | 24 GB | — | MoE (top-8 of 128 experts); ~54 tok/s |
237
+ | [`mlx-community/Qwen3.8-27B-OptiQ-4bit`](https://huggingface.co/mlx-community/Qwen3.8-27B-OptiQ-4bit) | 20.4 GB | 32 GB (24 GB with `--memory-budget`) | image + video | Current-gen Qwen; bf16-KV bit-exact parity (vs mlx-lm); thinking with `reasoning_effort` (xhigh/medium/low) + `preserve_thinking` + tool calling; native MTP head mounts as a `--draft-model` (lossless-by-verify, recurrent-cache rollback built in); **image AND video input serve** (`image_url` / `video_url` content parts — dedicated vision tower + mRoPE; video decodes via macOS-native AVFoundation, 2 fps ≤768 frames) |
237
238
  | [`mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp`](https://huggingface.co/mateogrgic/GLM-5.2-colibri-int4-with-int8-mtp) | ~384 GB / 357 GiB | 32 GB + fast disk | — | Direct streamed Colibri container; true top-8, native MTP, bounded 25 GiB process plan; warm single-stream performance is disk-bound and below the aspirational 2 tok/s target |
238
239
 
239
240
  Not sure what fits your machine? `bun src/cli.ts fit <model> --ctx 8192`
240
- gives a deterministic answer (see below). The larger
241
- `Qwen3.6-27B-OptiQ-4bit` is still in bring-up — parity and serving polish
242
- remain (see [PLAN.md](./PLAN.md)). Downloading, cache layout, and reclaiming
243
- disk: [docs/reference/models.md](./docs/reference/models.md); on the site:
244
- [Choosing a model](https://mlx-bun.dev/getting-started/models/).
241
+ gives a deterministic answer (see below). Downloading, cache layout, and
242
+ reclaiming disk: [docs/reference/models.md](./docs/reference/models.md);
243
+ on the site: [Choosing a model](https://mlx-bun.dev/getting-started/models/).
245
244
 
246
245
  ### GLM-5.2: 32 GB quickstart
247
246
 
@@ -342,8 +341,10 @@ agent CLIs like pi/OpenClaw via their provider config.
342
341
  `temperature`, `top_p`, `top_k`, `max_tokens`, `seed`,
343
342
  `repetition_penalty`, `stop` (string or array, matched on decoded
344
343
  text with streaming hold-back), `reasoning_effort` (thinking on/off for
345
- Qwen3.5 / MiniCPM5 — `none` disables, any level enables), and an `hlg`
346
- tone-curve sampling override;
344
+ Qwen3.5/3.8 / MiniCPM5 — `none` disables, any level enables; on Qwen3.8
345
+ the level also sets reasoning depth: `low`/`medium`/`xhigh`), a Qwen3.8
346
+ `chat_template_kwargs.preserve_thinking` toggle (keep think blocks from
347
+ history; default on), and an `hlg` tone-curve sampling override;
347
348
  omitted sampling fields default to the model's own
348
349
  `generation_config.json` recipe; usage includes `cached_tokens`.
349
350
  Full schemas in
@@ -380,7 +381,9 @@ agent CLIs like pi/OpenClaw via their provider config.
380
381
  - **Prompt caching** — a byte-capped LRU KV cache reuses the longest
381
382
  common token prefix across requests (multi-turn conversations
382
383
  re-prefill only the new turn) — automatic, no client changes.
383
- Entries are adapter-specific when LoRA adapters are in play.
384
+ Entries are adapter-specific when LoRA adapters are in play. With
385
+ `--ssd-cache`, pending snapshots are flushed durably on `SIGINT`/`SIGTERM`;
386
+ `POST /admin/cache/flush` exposes the same boundary for automation.
384
387
  - **LoRA hot-swap** — mount adapters at runtime (`POST /v1/adapters`)
385
388
  and discover on-disk ones (`GET /v1/adapters/available`), select per
386
389
  request with the `adapter` body field (`"id"`, stacked `"a+b"`, or
@@ -415,8 +418,10 @@ agent CLIs like pi/OpenClaw via their provider config.
415
418
  targets, not small fast models. Serial lane only — with `--batch N` a
416
419
  mounted draft routes every request serial, like mlx_lm.server.
417
420
  - **Memory admission control** — `--memory-budget <GB>` refuses to load
418
- a model that can't serve within the budget and rejects requests whose
419
- `prompt + max_tokens` exceed the budget's max safe context with a 400
421
+ a model that can't serve within the budget. For requests, `max_tokens`
422
+ is a ceiling, not a promise: a broad client value is capped to the room
423
+ remaining under the safe context, and only a prompt that leaves no
424
+ generation slot at all is rejected with a 400
420
425
  (`type: "memory_admission"`) *before* generating. The GPU
421
426
  out-of-memory crash it prevents is uncatchable by design — rejection
422
427
  up front is the only defense. Ceiling visible at `GET /stats`.
@@ -474,6 +479,13 @@ for await (const t of gen) process.stdout.write(tok.decode([t.token], true));
474
479
  console.log(gen.stats); // prompt/decode tok/s, cached tokens, ...
475
480
  ```
476
481
 
482
+ `openModel()` first resolves a declared model profile: exact immutable artifact
483
+ profiles outrank dedicated family paths, which outrank the generic fallback.
484
+ Profiles select the loader/model graph/generation loop and carry their fidelity
485
+ contract; they never rewrite explicit or default-resolved KV, MTP, adapter,
486
+ grammar, or sampling choices. `loadContext()` exposes the resolved declaration
487
+ as `ctx.profile`, and direct library users can call `resolveModelProfile()`.
488
+
477
489
  KV caches can be persisted to disk (page-aligned files that reload as
478
490
  zero-copy GPU-safe mmaps — see `src/kv-store.ts`) so a standard agent
479
491
  preamble prefills once, ever.
@@ -562,7 +574,7 @@ On the site: [Correctness](https://mlx-bun.dev/about/correctness/) and
562
574
  - **Slow decode on a model near your RAM ceiling** — close memory-heavy
563
575
  apps; a model that doesn't fit the wired-memory budget pages weights
564
576
  every token (check with `fit`).
565
- - **Bun version** — requires ≥ 1.3.14 (`bun upgrade`); pinned for
577
+ - **Bun version** — requires ≥ 1.4.0 (`bun upgrade`); pinned for
566
578
  `Bun.Image` and verified FFI behavior.
567
579
 
568
580
  ## Status
@@ -571,7 +583,7 @@ Pre-alpha, moving fast. See [PLAN.md](./PLAN.md) for phases, exit
571
583
  criteria, measured numbers, and the findings log.
572
584
 
573
585
  **Complete** — load path; bit-exact model port (MiniCPM5, Qwen3.5-4B,
574
- e4b per-layer-input, 12B dense, 26B MoE); sampling + serving (tools, vision,
586
+ Qwen3.8-27B, e4b per-layer-input, 12B dense, 26B MoE); sampling + serving (tools, vision,
575
587
  prompt cache); registry / fit / KV persistence; quantized +
576
588
  mixed-precision KV serving (rotating-cache KV-quant, Phase 9) with fused
577
589
  quantized prefill (Phase 10); LoRA hot-swap with per-request selection;
@@ -586,17 +598,21 @@ head-to-head benchmark harness; the decode-gap root-cause fix
586
598
  (commit 4625fe5); the embeddable single-binary build (signed +
587
599
  notarized — Homebrew, direct-download, and npm/bunx).
588
600
 
589
- **In progress** — `Qwen3.6-27B` bring-up (Phase 14f): same architecture
590
- as the verified 4B (untied + larger geometry); parity and serving polish
591
- remain. MTP speculation and Qwen3-VL vision deferred.
601
+ **In progress** — `Qwen3.8-27B` full support (Phase 14 retarget): text
602
+ parity is bit-exact, thinking controls (`reasoning_effort` depths,
603
+ `preserve_thinking`) + tool calling are wired, and native MTP speculation
604
+ (the Qwen-trained head as a `--draft-model`) mounts through the serve
605
+ loop's recurrent-cache rollback contract; vision and video input are in
606
+ bring-up.
592
607
 
593
608
  **Experimental** — opt-in, default-off, still being hardened: transparent
594
609
  expert offload for MoE models (`serve --expert-offload`, Phase 20:
595
610
  page-aligned mmap-backed experts, bit-exact — 26B-A4B 17.1→4.2 GB
596
- resident, decode unregressed); batched serving (`--batch N`, default 8
597
- since 2026-07-05 — a lone request runs the exact serial engine, so the cap
598
- engages only under real concurrency, e.g. coding sub-agents; `--batch 1`
599
- pins strict serial; Phase 18: continuous-batching bf16 decode at mlx-lm B=N parity,
611
+ resident, decode unregressed); continuous serving (`--batch N`, default 8
612
+ since 2026-07-05 — the scheduler's B=1 fast path uses serial-class caches and
613
+ the parity-gated single-row graph, while the cap permits B=N under real
614
+ concurrency such as coding sub-agents; `--batch 1` pins the preserved strict
615
+ serial executor; Phase 18: bf16 decode at mlx-lm B=N parity,
600
616
  B=2 bit-parity verified for MiniCPM5/12B/e4b/26B; sampler extras,
601
617
  repetition penalty, and grammar-constrained requests batch; Qwen3.5's
602
618
  SSM caches batch, as do plain full-attention Tier-0 archs (e.g. Llama) —
package/bin/mlx-bun.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  // (a guard inside cli.ts would never run under Node — its static imports
5
5
  // hoist and fail on the bun: scheme first).
6
6
 
7
- const MIN_BUN = "1.3.14"; // Bun.Image + verified FFI behavior (see README)
7
+ const MIN_BUN = "1.4.0"; // fixed macOS arm64 FFI stack layout (see README)
8
8
 
9
9
  if (typeof Bun === "undefined") {
10
10
  console.error(
@@ -1,6 +1,6 @@
1
1
  # HLG sampling — a piecewise tone curve on the logits
2
2
 
3
- Status: **implemented, found neutral, superseded by Curve Designer** — `applyHlg` shipped in `src/sampler.ts`; investigation found HLG a wash vs plain temperature; the Curve Designer (`src/curve-sampler.ts`) is its v2 replacement. See [docs/investigations/hlg-sampling-investigation.md](../investigations/hlg-sampling-investigation.md) for findings. This doc remains as the design rationale.
3
+ Status: **implemented, found neutral, superseded by Curve Designer** — `applyHlg` shipped in `src/sampler.ts`; investigation found HLG a wash vs plain temperature; the Curve Designer (`src/curve-sampler.ts`) is its v2 replacement. See [docs/archive/investigations/hlg-sampling-investigation.md](investigations/hlg-sampling-investigation.md) for findings. This doc remains as the design rationale.
4
4
  Owner: sampling layer (`src/sampler.ts`)
5
5
  Default: **off** (`--hlg-sampling off` = today's temperature sampler, untouched)
6
6
 
@@ -12,7 +12,7 @@ Default: **off** (`--hlg-sampling off` = today's temperature sampler, untouched)
12
12
 
13
13
  ## Outcome / Retrospective
14
14
 
15
- HLG was implemented through **Piece 2** (pure curve + neutrality tests + serial wiring, `applyHlg` live in `src/sampler.ts`). Evaluation found it **neutral vs plain temperature** — no measurable gain in diversity or quality at matched output entropy. As a result, HLG is **superseded by the Curve Designer** (`src/curve-sampler.ts`), which generalizes the same region-shaping idea with an editable control-point interface and cleaner UX. Full empirical findings are in [docs/investigations/hlg-sampling-investigation.md](../investigations/hlg-sampling-investigation.md).
15
+ HLG was implemented through **Piece 2** (pure curve + neutrality tests + serial wiring, `applyHlg` live in `src/sampler.ts`). Evaluation found it **neutral vs plain temperature** — no measurable gain in diversity or quality at matched output entropy. As a result, HLG is **superseded by the Curve Designer** (`src/curve-sampler.ts`), which generalizes the same region-shaping idea with an editable control-point interface and cleaner UX. Full empirical findings are in [docs/archive/investigations/hlg-sampling-investigation.md](investigations/hlg-sampling-investigation.md).
16
16
 
17
17
  The sections below (Goal through Correctness) remain as design rationale. Pieces 3–6 of Phasing and the Open Questions were never executed; see the [Phasing](#phasing-the-piece-n-increments) and [Open Questions](#open-questions--risks) sections for historical context.
18
18
 
@@ -347,4 +347,4 @@ for it. That a transfer function is standard practice in another domain says
347
347
  nothing about whether it helps token sampling — that is decided only by
348
348
  measurement (the KL characterization, the capability guardrail, and the
349
349
  diversity lens in [Correctness](#correctness--evaluation)). The full empirical
350
- write-up is in [docs/investigations/hlg-sampling-investigation.md](../investigations/hlg-sampling-investigation.md).
350
+ write-up is in [docs/archive/investigations/hlg-sampling-investigation.md](investigations/hlg-sampling-investigation.md).
@@ -3,7 +3,7 @@
3
3
  *2026-06-14. Question: can the structure of a piecewise nonlinear transfer
4
4
  function (HLG, the HDR transfer function) be transplanted onto a logit
5
5
  distribution as a sampling method, and if so, where do you place its pivot
6
- (middle grey)? Design contract: [docs/design/hlg-sampling.md](../design/hlg-sampling.md).
6
+ (middle grey)? Design contract: [docs/archive/hlg-sampling.md](../design/hlg-sampling.md).
7
7
  Code: `src/sampler.ts` (`applyHlg`, `makeSampler`). Harness:
8
8
  `scripts/hlg-compare.ts`. Model under test: `gemma-4-e4b-it-OptiQ-4bit` on the
9
9
  M4 Pro.*
@@ -0,0 +1,92 @@
1
+ # Pareto-specialized runtime findings
2
+
3
+ ## Question
4
+
5
+ Which parts of mlx-bun should converge on shared infrastructure, and which parts should remain deliberately specialized so cleanup does not turn the runtime into a lowest-common-denominator model host?
6
+
7
+ This note compares three mature specialization clusters: the Colibri/GLM-5.2 runtime, the Qwen3.8 27B TurboQuant and MTP work, and ORPO training. The evidence says the same thing in all three places: share lifecycle and composition policy, but keep artifact layout and numerical work close to the model or method that owns them.
8
+
9
+ ## Shared control-plane infrastructure
10
+
11
+ The shared layer decides what runs, owns resources, and records what happened. It does not rewrite the selected computation.
12
+
13
+ - **Model construction.** `openModel()` recognizes the direct Colibri artifact before ordinary safetensors loading. `createModel()` prefers dedicated and fingerprint-generated model classes before the universal fallback, and explicitly says the generic path must not shadow a dedicated port. This is shared dispatch with specialized implementations, not one universal graph. [Factory dispatch](../../../src/model/factory.ts#L30-L150)
14
+ - **Concurrency and request composition.** The target is one concurrency-driven engine. One active request uses the B=1 pipelined or compiled fast path; concurrent requests use the general step up to `--batch N`. B=1 is an internal specialization, not a permanent public lane. Features are stackable layers, and scheduling must not replace the selected KV scheme, adapter, draft method, grammar, or sampler. [Unified engine decision](../../design/unified-engine-frontier-plan.md#L333-L403) [Composition matrix](../../design/unified-engine-frontier-plan.md#L405-L424)
15
+ - **Cache lifecycle and capability.** `Cache` owns update, masks, state, rollback, accounting, and disposal. `BatchableCache` adds row merge, extraction, filtering, and byte projection. The scheduler can depend on those capabilities without knowing whether a row contains ordinary KV, recurrent state, TurboQuant tensors, or compressed GLM state. [Cache interface](../../../src/model/gemma4-base.ts#L264-L303) [Batchable cache interface](../../../src/model/gemma4-base.ts#L347-L357)
16
+ - **Resolved KV policy.** `KvScheme` preserves bf16, uniform affine, per-layer affine, and TurboQuant as distinct immutable schemes. It centralizes names, accounting, and current batch capability checks without pretending the schemes have identical storage or kernels. [KV scheme](../../../src/kv-scheme.ts#L84-L169)
17
+ - **Draft lifecycle.** `DraftProvider` owns server-lifetime machinery and opens a request-scoped `DraftSource`. The source interface carries prompt mode, target taps, draft, commit, rollback-related cache state, and disposal. Assistant, DSpark, Qwen MTP, and native GLM MTP can share speculative orchestration while retaining different state transitions. [Draft source](../../../src/spec/source.ts#L31-L101) [Draft provider](../../../src/spec/source.ts#L103-L118)
18
+ - **Expert residency policy.** The budget equation, stable expert union, lease state, backend contract, telemetry, and pressure correction are reusable. GLM supplies artifact geometry and byte segments to that policy. [Residency planning and union](../../../src/expert-residency.ts#L17-L155) [Residency backend](../../../src/expert-residency.ts#L157-L170)
19
+ - **Offline transform orchestration.** `WeightTransform` separates name/config planning from lazy tensor application. Llama, the Qwen3.5 trunk, and Qwen MTP are real adapters over the same conversion seam. [Weight transform interface](../../../src/quantize/weight-transform.ts#L40-L51) [Qwen transform adapters](../../../src/quantize/weight-transform.ts#L244-L268)
20
+ - **Training orchestration.** `TrainConfig` names independent techniques such as segmented backward, fused or flash CCE, prefix sharing, regularization, and ORPO semantics. `orpoLoop()` composes the selected techniques and chooses the model-specific backward implementation. [Training configuration](../../../src/train/trainer.ts#L42-L150) [ORPO composition](../../../src/train/trainer.ts#L821-L948)
21
+
22
+ ## Deliberately specialized data-plane code
23
+
24
+ ### Colibri and GLM-5.2
25
+
26
+ GLM-5.2 is not a descriptor-table variation of a dense transformer. Its graph has MLA, DSA, shared plus routed MoE, native MTP, and compressed cache state. Its public artifact also has a dedicated container and streamed expert layout. The design therefore calls for a dedicated `Glm52Model`, direct artifact support, and a one-read routed-expert kernel rather than repacking into generic projection-major tensors. [Dedicated graph and artifact contract](../../design/colibri-glm52-port.md#L323-L357)
27
+
28
+ The memory contract is also model and artifact specific. A header-only preflight reads the container, derives expert slot layouts, counts DSA and MTP state, and refuses startup when the exact resident weights, expert slabs, compressed KV, verification transients, allocator reserve, Bun reserve, and safety margin exceed the process limit. [GLM geometry and preflight](../../../src/model/glm52-memory.ts#L340-L500) The runtime then maps Colibri segments into generic residency leases, but retains GLM-specific slot layouts, MTP slabs, signed-int8 requirements, and routed-SwiGLU executors. [GLM residency binding](../../../src/model/glm52-residency.ts#L138-L230) [GLM executor construction](../../../src/model/glm52-residency.ts#L300-L459)
29
+
30
+ That split is intentional. Bun owns residency policy and observability; the native helper owns aligned slabs, `pread`, wiring, and completion fences; the GLM model owns tensor semantics and kernels. [Ownership map](../../design/colibri-glm52-port.md#L580-L600)
31
+
32
+ ### Qwen3.8 27B, TurboQuant, and MTP
33
+
34
+ Qwen3.5/3.8 keeps a dedicated graph because gated DeltaNet recurrence, full attention, MRoPE, output gates, and recurrent speculative rollback are numerical behavior, not configuration decoration. [Qwen graph](../../../src/model/qwen3_5.ts#L128-L322) [Qwen model interface](../../../src/model/qwen3_5.ts#L512-L673)
35
+
36
+ Qwen MTP preserves its own artifact and state machine behind `DraftProvider` and `DraftSource`. The provider rejects a non-Qwen target or a hidden-size mismatch. The request source uses tapped pre-final-norm target state, maintains its own KV, samples through the target sampler, and rebuilds accepted rows from verified target hiddens. Those rules must not move into generic speculative orchestration. [Qwen MTP provider](../../../src/spec/qwen-mtp-source.ts#L193-L235) [Qwen MTP state machine](../../../src/spec/qwen-mtp-source.ts#L237-L430)
37
+
38
+ TurboQuant KV demonstrates the right form of specialization. `TurboQuantKVCache` implements the shared `Cache` lifecycle, while keeping packed indices, scales, zero points, FWHT-domain values, supported head dimensions, and conversion rules inside the class. [TurboQuant cache](../../../src/model/gemma4-base.ts#L1539-L1800) The weight pipeline follows the same rule. `WeightTransform` is shared, but the Qwen corridor map preserves the output gate, recurrent internals, vision-to-residual seam, untied 27B head, and companion MTP basis. [Qwen transform seam](../../design/turboquant-weights.md#L80-L87) [Qwen corridor map](../../design/turboquant-weights.md#L125-L174)
39
+
40
+ ### ORPO training
41
+
42
+ ORPO benefits from composition, not one generic backward. The trainer combines prefix sharing, segmented recomputation, fused or flash CCE, LoRA regularization, and objective semantics. The data plane remains specialized where the model topology demands it. Gemma4 segmented ORPO threads per-layer inputs and cross-segment donor KV cotangents; MiniCPM5 uses a simpler segment graph. [Composed ORPO paths](../../design/orpo-training.md#L178-L218) [Gemma4 segmented backward](../../../src/train/segmented.ts#L1137-L1471)
43
+
44
+ Flash CCE is a shared quantized-head interface with specialized Metal kernels and explicit shape guards. Its implementation selects Steel, simdgroup, or scalar kernels from actual hidden, vocabulary, group, and tile geometry, and exposes exact-gradient escape hatches. Flattening this into a generic matrix-loss helper would lose the memory and watchdog constraints that justify it. [Flash CCE head](../../../src/train/flash-cce.ts#L42-L64) [Forward dispatch](../../../src/train/flash-cce.ts#L1033-L1132) [Backward dispatch](../../../src/train/flash-cce.ts#L1134-L1234)
45
+
46
+ Dynamic lambda is not implemented. Its design belongs in the ORPO control plane: validation metrics update a live lambda source in `orpoLoop()`, while every monolithic and segmented loss reads the same value. It should not create another family of backward classes. [Dynamic-lambda status and signals](../../design/orpo-dynamic-lambda.md#L1-L27) [Proposed wiring](../../design/orpo-dynamic-lambda.md#L163-L180)
47
+
48
+ ## Interfaces that already preserve specialization
49
+
50
+ | Interface | Shared invariant | Specialization retained behind it |
51
+ |---|---|---|
52
+ | `RuntimeModel` plus factory dispatch | Construction and serving can hold one model type | Dedicated GLM, Qwen, Gemma, diffusion, MoE, and generated graphs |
53
+ | `Cache` / `BatchableCache` | Lifecycle, rollback, row operations, byte projection | Plain, rotating, quantized, TurboQuant, SSM, MLA, and DSA storage |
54
+ | `KvScheme` | One resolved KV choice and stable identity | Per-scheme accounting, conversion, persistence, and kernels |
55
+ | `DraftProvider` / `DraftSource` | Request lifecycle, target taps, draft and commit | Assistant, DSpark, Qwen MTP, and GLM MTP state machines |
56
+ | `ExpertResidencyBackend` | Lease and I/O lifecycle | Colibri container offsets, slot packing, expert kernels, and prediction policy inputs |
57
+ | `WeightTransform` | Plan first, apply lazily, record identity | Family-specific exact fold corridors and companion artifacts |
58
+ | ORPO trainer configuration | One run composes selected techniques | Model-specific masks, donor topology, VJPs, and Metal kernels |
59
+
60
+ ## Declared profile seam (S2, 2026-08-21)
61
+
62
+ Model construction now resolves one `ResolvedModelProfile` before opening
63
+ weights. An exact artifact declaration binds an immutable external fingerprint,
64
+ config fingerprint, fidelity contract, required engine capabilities, and a
65
+ loader/graph/loop composition. Exact Qwen3.8 OptiQ and GLM-5.2 Colibri revisions
66
+ are pinned; other supported artifacts retain dedicated family resolution and
67
+ then the universal dense fallback.
68
+
69
+ The factory consumes the resolved composition, and the serving context retains
70
+ it for library callers. A matched exact declaration with a config or capability
71
+ mismatch refuses rather than taking another route. The profile seam does not
72
+ own request methods: MTP, KV schemes, adapters, grammar, and sampling remain
73
+ independently resolved inputs to completion execution. This keeps the control
74
+ plane declarative without turning a model profile into a feature preset.
75
+
76
+ These interfaces preserve specialization because they describe lifecycle or capability, not tensor algebra. They also have multiple real implementations. That is the useful test for whether an abstraction belongs.
77
+
78
+ ## Rules for steady-state cleanup
79
+
80
+ 1. **Unify control, not math.** Centralize admission, concurrency, cancellation, ownership, accounting, persistence, telemetry, and technique composition. Keep tensor layout, recurrence, cache encoding, model topology, and kernel selection with their owning model, artifact, or method.
81
+ 2. **Keep one concurrency-driven engine.** B=1 and B>1 are internal step specializations in one engine. `--batch N` is a concurrency cap. Observed placement may be reported, but serial versus batch must not become a permanent public mode or feature-selection interface. Current feature-specific serial routing is capability debt.
82
+ 3. **Never weaken a resolved composition to fit a path.** If batching lacks TurboQuant, MTP, adapters, grammar, or another selected method, close that capability gap or reject the unsupported composition. Do not silently substitute bf16 KV, disable drafting, or change sampling.
83
+ 4. **Prefer capability interfaces over family checks.** Scheduling should ask caches whether they can merge or project bytes and draft sources what target state they require. Factory dispatch is the proper place for model identity checks.
84
+ 5. **Let dedicated ports outrank generic fallbacks.** The universal model path is valuable for ordinary architectures. It must not absorb GLM MLA/DSA, Qwen recurrence, artifact-specific MTP, or another optimized graph merely to reduce class count.
85
+ 6. **Treat artifacts as executable contracts.** Validate manifests, tensor families, layouts, quantization metadata, companion seeds, and memory equations before allocation. Keep artifact-specific loaders and transforms when repacking would add copies, lose reproducibility, or change arithmetic.
86
+ 7. **Generalize only after the invariant is visible in two implementations.** Extract lifecycle and capability seams such as `DraftSource` or `WeightTransform`. Do not extract a common tensor algorithm from code that only looks similar but has different masks, state, accumulation order, or oracle.
87
+ 8. **Compose optimizations at the orchestrator, then test the cross-product.** ORPO proves that prefix sharing, flash CCE, segmented backward, and regularization can stack while model-specific backward code remains intact. Serving needs the same discipline for model graph, KV scheme, MTP, adapters, grammar, sampling, and concurrency.
88
+ 9. **Bind every specialized path to its own oracle and measured purpose.** A specialized module earns its place through parity, memory, quality, or throughput gates on the artifact and hardware it targets. If the benefit disappears, delete the specialization instead of preserving it as architecture folklore.
89
+
90
+ ## Strongest conclusion
91
+
92
+ The steady state is not a generic engine with scattered exceptions. It is a shared control plane that carries authoritative compositions through one concurrency-driven engine, plus specialized data planes selected by model, artifact, and numerical method. That structure preserves the project's Pareto advantage: common serving and training behavior where sameness is real, and unapologetically specific code where the result depends on it.
@@ -1,6 +1,6 @@
1
1
  # The mlx-bun chat surface: a vision
2
2
 
3
- *Draft vision, product/design lead pass — 2026-07-06. Bold stance: reimagine the chat surface from scratch. Companion to the market research and current-state audit that produced it; see `docs/planning/web-ui-pass-plan.md` for the tactical bug list and `docs/design/adapters-end-to-end.md` / `docs/design/memory-system.md` for the backend contracts this vision assumes.*
3
+ *Draft vision, product/design lead pass — 2026-07-06. Bold stance: reimagine the chat surface from scratch. Companion to the market research and current-state audit that produced it; see `docs/archive/planning/web-ui-pass-plan.md` for the tactical bug list and `docs/design/adapters-end-to-end.md` / `docs/design/memory-system.md` for the backend contracts this vision assumes.*
4
4
 
5
5
  ## The feeling
6
6
 
@@ -0,0 +1,77 @@
1
+ # v0.0.13 release notes
2
+
3
+ Everything since v0.0.12. One theme: **Qwen 3.8**. The current-generation
4
+ Qwen (released August 2026) is brought up on the published OptiQ
5
+ artifact at the repo's standard bar — bit-exact logit parity with
6
+ mlx-lm — with its thinking controls served faithfully. Vision, video,
7
+ and native Qwen MTP remain separately gated follow-ups.
8
+
9
+ ## Qwen3.8-27B (text, bit-exact)
10
+
11
+ - `mlx-community/Qwen3.8-27B-OptiQ-4bit` serves on the existing
12
+ qwen3_5 hybrid graph (gated DeltaNet + gated attention) — the
13
+ architecture audit found byte-identical geometry to the verified
14
+ port, and parity confirmed it: **every logit at every prompt
15
+ position plus 32 greedy decode steps, bit-exact vs stock mlx-lm**
16
+ (the parity harness grew a full prefill-grid golden and
17
+ manifest-driven step counts in the process).
18
+ - The config's new `output_gate_type: "swish"` field is inert in every
19
+ implementation (transformers ground truth included) — a load-time
20
+ guard now fails loudly if a future checkpoint carries a value we
21
+ haven't verified.
22
+ - Fit reality: the artifact is 20.35 GB of shards. 32 GB machines
23
+ serve it comfortably; 24 GB machines need `--memory-budget` and
24
+ should prefer the uniform 4-bit conversion until the planned
25
+ ~4 bpw TurboQuant×weights artifact lands (PLAN 14z).
26
+
27
+ ## Thinking controls (Qwen 3.8's serving surface)
28
+
29
+ - Thinking is on by default and streams as OpenAI `reasoning` deltas;
30
+ `chat_template_kwargs.enable_thinking: false` selects instruct mode.
31
+ - `reasoning_effort` is now a real depth control on templates that read
32
+ it: OpenAI levels map onto Qwen's `low`/`medium`/`xhigh` (with
33
+ `xhigh` accepted as a first-class request value), and the variable is
34
+ only passed to templates that declare it — the Qwen 3.8 template
35
+ raises on unknown level names, so the server never forwards unmapped
36
+ strings.
37
+ - `preserve_thinking` (new in Qwen 3.8, default on) is forwarded:
38
+ history keeps its think blocks, which also improves prompt-cache
39
+ reuse in agent loops.
40
+ - Tool calling: Qwen 3.8's XML call format
41
+ (`<tool_call><function=name><parameter=…>`) parses through the
42
+ existing Qwen-style parser into OpenAI `tool_calls`, multiline
43
+ parameters included.
44
+
45
+ ## Qwen native MTP is deliberately not shipped yet
46
+
47
+ - Qwen 3.8 ships a multi-step MTP head trained alongside the model;
48
+ mlx-community publishes it split out
49
+ (`mlx-community/Qwen3.8-27B-MTP-bf16`). Review found that the target's
50
+ 48 recurrent DeltaNet caches cannot roll back rejected verify rows,
51
+ while the shared speculative loop requires exactly that operation.
52
+ The initial implementation therefore never reached a draft round.
53
+ - MTP artifacts are detected and refused at startup with the exact reason,
54
+ before the 20 GB target is opened. Shipping a switch that silently disables
55
+ itself—or corrupts recurrent state when forced—would be worse than a clear
56
+ deferral. The follow-up needs recurrent-state snapshot/restore or a verify
57
+ schedule that never advances state beyond the accepted prefix.
58
+
59
+ ## GLM-5.2 client compatibility
60
+
61
+ - Fixed-context GLM serving now treats request `max_tokens` as an upper bound:
62
+ when a client sends a family-wide value larger than the planned remaining
63
+ context, the server caps it instead of rejecting an otherwise valid first
64
+ prompt. The reported 2,788-prompt + 8,192-cap failure now admits a 1,308-token
65
+ completion ceiling within the 4,096-token plan. Prompts that consume the
66
+ whole context remain rejected before generation.
67
+
68
+ ## Also in this release
69
+
70
+ - The parity harness's step-0 check now covers the full prefill logit
71
+ grid for all Qwen targets — masking/position bugs can no longer hide
72
+ behind a last-position comparison.
73
+ - A GPU command-buffer failure mode on memory-saturated machines was
74
+ root-caused (Metal completion-thread exception, uncatchable by
75
+ design) and documented in PLAN 14g, along with the finding that some
76
+ mlx-c paths surface C++ errors as process panics instead of
77
+ catchable errors (hardening item).
@@ -117,6 +117,6 @@ overturning a load-bearing performance assumption.
117
117
  "failures" were M4-Pro fixtures; all code exonerated — mlx-lm reproduces
118
118
  mlx-bun token-for-token per machine); CI gate (typecheck + model-free tests).
119
119
  - **Research (the lab):** decode-roofline re-measurement overturned the "at
120
- the floor" assumption (docs/investigations/decode-roofline-lookagain.md);
120
+ the floor" assumption (docs/archive/investigations/decode-roofline-lookagain.md);
121
121
  curve-sampler distinctness theorem + witness numbers + preregistered
122
122
  protocol (docs/planning/curve-sampler-research-plan.md).
@@ -20,7 +20,7 @@ Two coherent options:
20
20
 
21
21
  - **(A) Recommended: cut v0.0.9, then deploy the site.** All docs become
22
22
  true simultaneously; nothing below needs version annotations. The
23
- release-notes draft already exists (`docs/planning/release-notes-v0.0.9.md`).
23
+ release-notes draft already exists (`docs/archive/planning/release-notes-v0.0.9.md`).
24
24
  - **(B)** If v0.0.9 is not imminent: hold site deploys, and treat every
25
25
  item marked *v0.0.9* below as blocked. (Reverting docs to 8090 is churn
26
26
  for nothing — don't.)
@@ -692,7 +692,7 @@ batch.
692
692
 
693
693
  G0 inventory note (2026-07-21): the exact pin, artifact/layout contract, and
694
694
  manual checklist are recorded in
695
- [`../investigations/colibri-oracle-pin.md`](../investigations/colibri-oracle-pin.md).
695
+ [`../archive/investigations/colibri-oracle-pin.md`](../archive/investigations/colibri-oracle-pin.md).
696
696
  Because the pinned Makefile writes ignored build artifacts and even creates a
697
697
  configuration stamp while parsing, model-free oracle targets must run from a
698
698
  temporary `git archive` extraction, not in the read-only checkout. The pinned
@@ -1425,6 +1425,13 @@ advertised false, not emulated.
1425
1425
  `native-v0.2.0` GitHub release. Both assets are uploaded; anonymous HTTP
1426
1426
  resolution and an empty-cache default-URL download/checksum/extraction
1427
1427
  passed with all five required files. G8 is closed.
1428
+ - [x] Published mlx-bun v0.0.12 itself: the signed/notarized GitHub release
1429
+ and stable asset, npm package, and Homebrew tap are live and independently
1430
+ verified. Both 80,420,638-byte binary assets carry SHA-256
1431
+ `64c4d697faba65789c2af7c1344ee39024f8a03bd6839d2c8df4ec7dce872a74`;
1432
+ npm reports shasum `0dcc5c200fa81dbea1f8be854e21a0efbbdebbfa`.
1433
+ The final full gate passed 1,936 tests / 28,378 assertions with 71 skips
1434
+ and zero failures.
1428
1435
  - Update README plus `docs/reference/{models,memory,cli,server-config,
1429
1436
  server-api,library-api,features-matrix}.md` in the same feature changes that
1430
1437
  add the corresponding flags, fields, routes, defaults, and limitations.
@@ -85,7 +85,7 @@ mlx-lm" half.
85
85
 
86
86
  ### pi — the built-in agentic coding CLI
87
87
 
88
- (Phase 16; full plan in **docs/investigations/pi-builtin-investigation.md**.) pi is an
88
+ (Phase 16; full plan in **docs/archive/investigations/pi-builtin-investigation.md**.) pi is an
89
89
  MIT, Bun-native (`bun build --compile`) coding agent — the "CLI
90
90
  experience inside our package" that neither Python package has. Two
91
91
  commands, one for each audience:
@@ -66,7 +66,7 @@ grammar composition, and `usage.speculation` telemetry ALL landed
66
66
  serve wiring: 27B/12B retarget (regen+train, Josh's shell), data scale
67
67
  (thousands of on-distribution generations vs 160), draft-loop
68
68
  tightening. At τ≈3 on the 27B agent workload: **~15 → ~35–45 tok/s**
69
- (docs/investigations/dspark-handoff.md). Slots in as `DflashSource`,
69
+ (docs/archive/investigations/dspark-handoff.md). Slots in as `DflashSource`,
70
70
  no-oracle/KL-gated (a Lab item).
71
71
 
72
72
  ### 2. mlx bump — narrow 26B / spec-decode wins, NOT a general decode lever [main-only, from-source]
@@ -140,7 +140,7 @@ files, not benchmark output. Leave entirely alone.
140
140
  | 5 | Add `STATUS.md` (or a pinned top section in PLAN.md) holding only live handoff: current state + next action + blockers. Move PLAN.md's `NEXT UP` / `NEXT SESSION PICKUP` / `SESSION SWEEP` blocks into it. | Separates transient "do this next" from 2,475 lines of durable phase history; gives agents one entry point. |
141
141
  | 6 | Create `docs/planning/` and move `PRODUCT_ROADMAP.md`, `IDEAS.md`, `ResearchTopics.md`, `journal.md` under it. Leave only README + PLAN.md (+ STATUS.md) at root. Add a ~6-line "doc map" to README. | Root is currently a 6-file planning thicket; extends the taxonomy that already works in `docs/`. |
142
142
  | 7 | Pick one home for the optimization plan: fold `docs/design/optimization_plan.md` into PLAN.md Phase A–E, or have PLAN.md link out to it as canonical. | Two homes for the same plan = drift. |
143
- | 8 | Resolve the archive overlap: `archive/pi-builtin-investigation.html` duplicates [docs/investigations/pi-builtin-investigation.md](../investigations/pi-builtin-investigation.md). Decide whether `archive/` (tracked; 2 HTML files: `mlx-bun-lab-report.html` + `wwdc-mlx-bun.html`) should be tracked at all, or moved to an ignored location. Keep the `.md`, drop the duplicate. | Stops committing heavyweight generated HTML; one source per investigation. |
143
+ | 8 | Resolve the archive overlap: `archive/pi-builtin-investigation.html` duplicates [docs/archive/investigations/pi-builtin-investigation.md](../archive/investigations/pi-builtin-investigation.md). Decide whether `archive/` (tracked; 2 HTML files: `mlx-bun-lab-report.html` + `wwdc-mlx-bun.html`) should be tracked at all, or moved to an ignored location. Keep the `.md`, drop the duplicate. | Stops committing heavyweight generated HTML; one source per investigation. |
144
144
 
145
145
  ## P2 — Polish (optional)
146
146
 
@@ -4,7 +4,7 @@ Status: **PLANNED** (2026-07-07). Trigger for Josh's pickup: TurboQuant merge
4
4
  but only Phase 5 actually depends on it; Phases 0–4 are start-anytime.
5
5
  Owner: decode / spec. Predecessors: PR #19 (DSpark paper code-complete +
6
6
  serve-integrated + DeepSpec oracle), the first-live-run findings in
7
- [dspark-handoff.md](../investigations/dspark-handoff.md) "FIRST LIVE RUN".
7
+ [dspark-handoff.md](../archive/investigations/dspark-handoff.md) "FIRST LIVE RUN".
8
8
 
9
9
  ## The problem, in numbers (2026-07-07 first live run, loaded machine)
10
10
 
@@ -247,6 +247,56 @@ regenerated by the target, 10 epochs, batch 512, lr 6e-4, position decay
247
247
  exp(−pos/4), ~38 TB cached hiddens — i.e. our "thousands of generations" data
248
248
  estimate was directionally right and their scale is far beyond a laptop run.
249
249
 
250
+ ## 27B program (2026-08-19): the TQ quant unlocks the real target
251
+
252
+ The turboquant-weights campaign shipped rot-sens48 Qwen3.8-27B at 17 GB
253
+ (docs/design/turboquant-weights.md) — and it changes both DSpark blockers
254
+ this doc recorded:
255
+
256
+ - **Target speed:** measured ~11.8 tok/s decode. This is the slow-target
257
+ regime where the doc's own analysis says τ≈3 nets 2–3× (≈25–35 tok/s) —
258
+ "the ideal target and the real motivation," now actually runnable.
259
+ - **Training feasibility:** "27B memory-infeasible to train on 24 GB" (open
260
+ items below) assumed the bf16 trunk (54 GB). With the quantized trunk
261
+ FROZEN (inference-only: hidden taps + teacher logits) and only the small
262
+ drafter (~5 layers) holding grads/optimizer state in bf16, 27B-target
263
+ drafter training fits a 32 GB machine. The premise is dead; the line in
264
+ the gated item is superseded by this section.
265
+ - **Rollback risk retired:** the stock Qwen-MTP spec path already serves
266
+ this model losslessly (68% per-token acceptance), so verify/rollback
267
+ across the 48 DeltaNet recurrent-state layers is proven engine behavior,
268
+ not new work.
269
+
270
+ Two tracks, cheap-first:
271
+
272
+ - **Track A — confidence-scheduled verification on the stock MTP head (no
273
+ drafter training).** Dynamic per-step block length instead of fixed
274
+ `--num-draft-tokens`: v0 confidence = the draft's own token probability
275
+ (no trained head), mapped through STS calibration
276
+ (`scripts/dspark-calibrate.ts` pattern) to expected acceptance; the
277
+ scheduler stops drafting when marginal expected-accept drops below the
278
+ verify amortization point. Calibration needs thousands of
279
+ (confidence, accepted?) pairs from served traffic — hours, not weeks.
280
+ Gate: paired A/B decode tok/s vs fixed-γ MTP on the same prompts;
281
+ lossless by construction (verify unchanged).
282
+ - **Track B — true DSpark drafter for the 27B (multi-token single-pass).**
283
+ The faithful v2 (KV injection, Markov head) retargeted: `hiddenTap` added
284
+ to `qwen3_5.ts` forwardLayers (gemma4 has it; parity-safe no-op when
285
+ off), tap-layer selection for the 64-layer trunk (bias toward the 16
286
+ full-attention layers + post-finalNorm), data generated by TEACHER-FORCED
287
+ passes over corpus text with the frozen quantized trunk (every position
288
+ of a forward yields a sample — data scale is forward-passes over tokens,
289
+ not generate calls). Open idea: distill from / initialize against the
290
+ shipped MTP head to shortcut the acceptance floor. Gate: generalizing
291
+ per-position acceptance must beat the MTP head's 0.68 or Track B loses to
292
+ Track A + MTP and gets dropped.
293
+
294
+ Sequencing: after the benchmark campaign closes (GPU is owned by the
295
+ certification suite). Track A first — it's measurable in a day and its
296
+ calibration data collection is also Track B's baseline instrumentation.
297
+ Adapters/DSpark drafts trained on the TQ artifact are married to its
298
+ rotation basis (fine for our bundle; note on the card if published).
299
+
250
300
  ## Open items / next
251
301
 
252
302
  - [x] Serve integration (Phase 1) · [x] Alg-1-shaped scheduler (matches the
@@ -258,11 +308,11 @@ estimate was directionally right and their scale is far beyond a laptop run.
258
308
  oracle scripts — the no-training path to the 12B speedup (in progress).
259
309
  - [ ] **Josh-gated GPU (the payoff):** real data scale (thousands of
260
310
  on-distribution generations) + **retarget to 12B** (`--model` +
261
- `--tap-layers 5,17,29,41,46` (DeepSeek's trained taps); 27B memory-infeasible to train on 24 GB, kept
311
+ `--tap-layers 5,17,29,41,46` (DeepSeek's trained taps); ~~27B memory-infeasible to train on 24 GB~~ (superseded — the 17 GB TQ trunk makes it feasible; see "27B program" above), kept
262
312
  dim-generic) + train (`--seq-head` A/B optional) + **calibrate**
263
313
  (`scripts/dspark-calibrate.ts`) + live-τ measure. Recipe:
264
- [docs/investigations/dspark-handoff.md](../investigations/dspark-handoff.md).
314
+ [docs/archive/investigations/dspark-handoff.md](../archive/investigations/dspark-handoff.md).
265
315
  - [ ] Verify the Eq 6 / §3.2.1 shapes against the actual paper when the PDF
266
316
  is available (both flagged in code).
267
317
 
268
- Full session handoff: `docs/investigations/dspark-handoff.md`.
318
+ Full session handoff: `docs/archive/investigations/dspark-handoff.md`.
@@ -15,7 +15,7 @@ three workstreams so they compose deliberately instead of colliding:
15
15
  (docs/design/batching-perf-path.md).
16
16
  - **Speculative decoding** — research proven (assistant drafter bit-exact
17
17
  vs optiq, 12B γ=1 ≈ 1.09× win, docs/design/spec-decode-larger-targets.md;
18
- DSpark architecture verified, docs/investigations/dspark-handoff.md) but
18
+ DSpark architecture verified, docs/archive/investigations/dspark-handoff.md) but
19
19
  **not served**: no `--draft-model`. Build plan already written:
20
20
  docs/design/mlx-lm-tool-parity-plan.md §7 (the `DraftSource` interface,
21
21
  two-model L1 source, serve loop, admission, prompt-cache composition).