mlx-bun 0.3.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 (150) hide show
  1. package/docs/README.md +4 -1
  2. package/docs/archive/investigations/openjarvis-fit.md +198 -0
  3. package/docs/archive/investigations/qwen38-27b-campaign-log.md +1092 -0
  4. package/docs/design/batching.md +1321 -49
  5. package/docs/design/decode-speed-program.md +331 -1163
  6. package/docs/design/generic-model-support.md +79 -3
  7. package/docs/design/kv-cache.md +198 -54
  8. package/docs/design/speculative-decoding.md +387 -24
  9. package/docs/design/turboquant.md +123 -13
  10. package/docs/design/unified-engine-frontier-plan.md +144 -142
  11. package/docs/planning/PRODUCT_ROADMAP.md +16 -0
  12. package/docs/planning/release-notes-v0.4.0.md +45 -0
  13. package/docs/reference/benchmarks.md +2457 -6
  14. package/docs/reference/cli.md +41 -2
  15. package/docs/reference/distribution.md +16 -9
  16. package/docs/reference/environment.md +55 -5
  17. package/docs/reference/models.md +13 -4
  18. package/docs/reference/server-api.md +79 -25
  19. package/docs/reference/server-config.md +178 -84
  20. package/docs/reference/troubleshooting.md +13 -21
  21. package/package.json +1 -1
  22. package/src/backends/mlx/assistant-target.ts +46 -0
  23. package/src/backends/mlx/autoregressive-draft-rows.ts +120 -0
  24. package/src/backends/mlx/batch-group.ts +368 -224
  25. package/src/backends/mlx/cache-attachment.ts +67 -0
  26. package/src/backends/mlx/cache-layout.ts +31 -0
  27. package/src/backends/mlx/checkpoint-state.ts +53 -0
  28. package/src/backends/mlx/continuation-persistence.ts +106 -0
  29. package/src/backends/mlx/continuation-request.ts +43 -0
  30. package/src/backends/mlx/continuation.ts +77 -0
  31. package/src/backends/mlx/draft-target.ts +7 -22
  32. package/src/backends/mlx/full-kv-row-append.ts +32 -0
  33. package/src/backends/mlx/full-kv-row-donor.ts +54 -0
  34. package/src/backends/mlx/full-transitioning-kv-rows.ts +65 -0
  35. package/src/backends/mlx/gateway-binding.ts +77 -18
  36. package/src/backends/mlx/kv-codec.ts +9 -0
  37. package/src/backends/mlx/kv-maintenance.ts +133 -0
  38. package/src/backends/mlx/kv-tensor-rows.ts +212 -0
  39. package/src/backends/mlx/model-serving.ts +1 -1
  40. package/src/backends/mlx/prefill-cohort.ts +89 -0
  41. package/src/backends/mlx/prefill-rows.ts +200 -0
  42. package/src/backends/mlx/prefill.ts +1 -1
  43. package/src/backends/mlx/projected-context-rows.ts +72 -0
  44. package/src/backends/mlx/request-state-policy.ts +41 -0
  45. package/src/backends/mlx/rollback.ts +41 -3
  46. package/src/backends/mlx/row-sampling.ts +49 -0
  47. package/src/backends/mlx/serial-executor.ts +35 -66
  48. package/src/backends/mlx/speculative-group.ts +359 -0
  49. package/src/backends/mlx/speculative-round.ts +161 -0
  50. package/src/backends/mlx/state-rows.ts +104 -0
  51. package/src/backends/mlx/state-views.ts +21 -1
  52. package/src/backends/mlx/target-layout-capability.ts +35 -0
  53. package/src/backends/mlx/transitioning-kv-rows.ts +165 -0
  54. package/src/cli.ts +11 -36
  55. package/src/contracts/execution.ts +11 -0
  56. package/src/contracts/prefix-cache.ts +23 -0
  57. package/src/contracts/resources.ts +7 -0
  58. package/src/contracts/sampling.ts +23 -0
  59. package/src/contracts/scheduling.ts +18 -0
  60. package/src/engine/execution-plan.ts +18 -16
  61. package/src/engine/resources.ts +12 -1
  62. package/src/engine/scheduler.ts +10 -5
  63. package/src/fit.ts +29 -15
  64. package/src/generate.ts +77 -173
  65. package/src/inference/draft-acceptance.ts +41 -0
  66. package/src/inference/draft-output.ts +49 -0
  67. package/src/inference/rollback.ts +2 -2
  68. package/src/kv-scheme.ts +70 -12
  69. package/src/kv-store.ts +70 -16
  70. package/src/lab/paged-kv/paged-kv-rows.ts +83 -0
  71. package/src/lab/paged-kv/paged-kv.ts +25 -11
  72. package/src/mlx/array.ts +2 -1
  73. package/src/model/artifact-identity.ts +73 -0
  74. package/src/model/batched-kv.ts +235 -0
  75. package/src/model/batched-mask.ts +12 -4
  76. package/src/model/batched-quant.ts +8 -2
  77. package/src/model/batched-quantized-kv.ts +144 -0
  78. package/src/model/batched-rotating-quant.ts +76 -15
  79. package/src/model/batched-rotating-state.ts +76 -0
  80. package/src/model/batched-rotating.ts +64 -22
  81. package/src/model/batched-row-storage.ts +52 -0
  82. package/src/model/batched-ssm.ts +52 -0
  83. package/src/model/batched-turboquant-kv.ts +93 -0
  84. package/src/model/compiled-decode.ts +7 -1
  85. package/src/model/decoded-kv-donor.ts +12 -0
  86. package/src/model/delayed-quantized-kv.ts +72 -0
  87. package/src/model/delayed-rotating-quantized-kv.ts +93 -0
  88. package/src/model/delayed-turboquant-kv.ts +55 -0
  89. package/src/model/full-prefill-padding.ts +56 -0
  90. package/src/model/full-prefill-row.ts +105 -0
  91. package/src/model/gemma4-base.ts +162 -80
  92. package/src/model/gemma4.ts +34 -26
  93. package/src/model/generated/gemma4-12b.ts +4 -1
  94. package/src/model/generated/gemma4-26b.ts +4 -1
  95. package/src/model/generated/gemma4-e4b.ts +4 -1
  96. package/src/model/glm52-cache.ts +80 -4
  97. package/src/model/glm52-mla.ts +12 -6
  98. package/src/model/glm52.ts +19 -40
  99. package/src/model/kv-attention-view.ts +67 -0
  100. package/src/model/minicpm5.ts +11 -7
  101. package/src/model/qwen3-delta-state.ts +74 -0
  102. package/src/model/qwen3-delta.ts +59 -36
  103. package/src/model/qwen3_5.ts +82 -42
  104. package/src/model/rotating-kv-donor.ts +35 -0
  105. package/src/model/rotating-kv-layout.ts +262 -0
  106. package/src/model/rotating-row-transaction.ts +35 -0
  107. package/src/model/speculative-rotating-kv.ts +101 -0
  108. package/src/model/ssm-prefill-padding.ts +39 -0
  109. package/src/model/trellis-linear.ts +2 -2
  110. package/src/model/turboquant-codec.ts +83 -0
  111. package/src/model/universal/dense.ts +14 -13
  112. package/src/preflight.ts +31 -15
  113. package/src/prompt-cache.ts +42 -44
  114. package/src/sampler.ts +36 -25
  115. package/src/serve/chat-stage.ts +2 -2
  116. package/src/serve/generation-gateway.ts +39 -30
  117. package/src/serve/model-host.ts +3 -4
  118. package/src/serve/request-plan.ts +4 -3
  119. package/src/serve/request-prep.ts +2 -4
  120. package/src/serve/text-completion-stage.ts +2 -2
  121. package/src/server.ts +64 -108
  122. package/src/spec/assistant-rows.ts +92 -0
  123. package/src/spec/assistant-source.ts +28 -18
  124. package/src/spec/cache-identity.ts +22 -0
  125. package/src/spec/deepspec-rows.ts +29 -0
  126. package/src/spec/deepspec-source.ts +12 -10
  127. package/src/spec/dflash-source.ts +28 -4
  128. package/src/spec/drafter.ts +153 -142
  129. package/src/spec/dspark/deepspec-module.ts +95 -120
  130. package/src/spec/dspark/module-dflash.ts +126 -170
  131. package/src/spec/glm52-mtp-graph.ts +29 -0
  132. package/src/spec/glm52-mtp-rows.ts +132 -0
  133. package/src/spec/glm52-mtp-source.ts +53 -136
  134. package/src/spec/glm52-mtp-state.ts +33 -0
  135. package/src/spec/ngram-source.ts +92 -20
  136. package/src/spec/projected-draft-rows.ts +73 -0
  137. package/src/spec/qwen-mtp-module.ts +171 -0
  138. package/src/spec/qwen-mtp-rows.ts +219 -0
  139. package/src/spec/qwen-mtp-source.ts +81 -226
  140. package/src/spec/qwen-mtp-state.ts +30 -0
  141. package/src/spec/serve-loop.ts +70 -68
  142. package/src/spec/source.ts +80 -15
  143. package/src/spec/two-model-rows.ts +61 -0
  144. package/src/spec/two-model.ts +43 -101
  145. package/src/ssd-cache.ts +33 -21
  146. package/src/ssd-durability.ts +11 -7
  147. package/src/web/app.js +57 -57
  148. package/src/backends/mlx/memory-guard.ts +0 -40
  149. package/src/spec/prefix-state.ts +0 -45
  150. /package/docs/{planning → archive/planning}/release-notes-v0.3.0.md +0 -0
@@ -177,7 +177,7 @@ refuses otherwise. GLM-5.2's checkpoint-native MTP row mounts by default
177
177
 
178
178
  | kind | source | what fills the draft | target state used | draft sampler | default γ | oracle / gate |
179
179
  |---|---|---|---|---|---|---|
180
- | `two-model` | `src/spec/two-model.ts` | a full second model, autoregressive, own KV | none | request sampler | 3 (mlx_lm.server) | **L1**: mlx_lm.server `--draft-model`, same pair, greedy, token-for-token (spec-vs-spec). Draft-cache rewind `max(d − kAccept − 1, 0)`. Tokenizer-family probe at startup refuses mismatches (upstream silently accepts ~0%). |
180
+ | `two-model` | `src/spec/two-model.ts` | a full second model, autoregressive, own KV | none | request sampler | 3 (mlx_lm.server) | **L1**: mlx_lm.server `--draft-model`, same pair, greedy, token-for-token (spec-vs-spec). Shared B1/B>1 autoregressive draft state retains independent attention/recurrent boundaries and the pending final-token lag; paired RAM/SSD checkpoints use backend cache codecs. Tokenizer-family probe at startup refuses mismatches (upstream silently accepts ~0%). |
181
181
  | `assistant` | `src/spec/assistant-source.ts` (+ `drafter.ts`) | Gemma "-assistant" Q-only 4-layer head | donor K/V (last sliding + last full layer) + anchor hidden, borrowed each step | greedy (own head) | 3 | **L2**: optiq `spec_generate` — e4b γ=2 identical 48-token output AND identical accept/reject trace (drafted 60 / accepted 17 / target calls 31), `scripts/oracle/oracle-spec.py`. Head picked by TENSOR PRESENCE (centroid vs tied-embedding) — optiq's config-based detection loads the 12B/26B unified drafters with zero-init centroids → 0% acceptance; ours 29% on the same artifact. |
182
182
  | `dspark` | `src/spec/dflash-source.ts` (+ `dspark/module-dflash.ts`) | our trained DSpark block drafter (KV injection + Markov + confidence) | multi-layer hidden tap (`tapLayers`, e4b {20,31,41,42}) grown into H_ctx | greedy | pinned to `cfg.gamma` | **Lab** (no external oracle for our checkpoints): CPU smoke, infer-loop bit-identity pins, real-weights serve gate. See §4. |
183
183
  | `deepspec` | `src/spec/deepspec-source.ts` (+ `dspark/deepspec-module.ts`) | DeepSeek's released `Gemma4DSparkModel` drafters (e.g. `dspark_gemma4_12b_block7`, γ=7) | tap `[5,17,29,41,46]` on the 12B, projected into an incremental context-KV cache; accepted rows only | argmax (temp-0 reference) | pinned to `block_size` | **DeepSpec reference** at temperature 0: its leaky rejection sampling degenerates to exact argmax token-match, RNG-free — round-for-round trace fixtures (`scripts/oracle/oracle-dspark-deepspec.py`; the compare script was deleted 2026-08-23, git history). |
@@ -794,23 +794,68 @@ it is separate from the already-fixed target-cache disposal and admission work.
794
794
 
795
795
  ### 4.8 Paired Qwen MTP conversation state
796
796
 
797
- An isolated candidate adds an optional prefix-state interface to `DraftSource`.
798
- The Qwen provider retains one evaluated prefill boundary containing target KV
799
- and recurrent state, draft KV, the preceding target hidden row, and exact token
800
- IDs. Restore transfers ownership only when the incoming prompt extends those
801
- IDs under the same target and adapter namespace. A mismatch releases the old
802
- entry. Reuse never trims recurrent state to an arbitrary common prefix.
797
+ `DraftSource.checkpoint` supplies the method's companion state. Qwen captures
798
+ draft KV and the preceding target hidden row; the executor pairs these with
799
+ target KV/recurrent state and exact processed token IDs in the shared cache.
800
+ Restore requires an exact prefix under the same compatibility namespace.
801
+ RAM hits lend immutable views and preserve the donor. Reuse never trims
802
+ recurrent state to an arbitrary common prefix.
803
803
 
804
804
  The MTP cache is one position behind the target at a prefill boundary. Extending
805
805
  it first pairs the next incoming token with the saved preceding hidden row,
806
806
  then processes the remaining suffix. Future generation cannot alter the retained
807
- prefix. The candidate caps this one snapshot by the configured prompt-cache
808
- budget and disposes it with the provider. It does not yet retain completed
809
- generation state or participate in the ordinary cache's pressure eviction,
810
- SSD persistence, or byte telemetry. It remains experimental and separate from
811
- the default serving path.
812
-
813
- On the M4 Pro, the unit gate passes 18 tests. Native prompts at 128, 513 and
807
+ prefix. The working-tree migration removes the provider's private store and
808
+ separate budget. All tensors use the existing RAM budget, eviction and SSD
809
+ queue. Native bf16/KV4 tests pass on M1 Max and M4 Pro through repeated RAM
810
+ reuse and SSD cache/provider restart. Completed generated-state publication
811
+ and matched performance remain open. Storage and identity details live in
812
+ [kv-cache method companion state](kv-cache.md#method-companion-state).
813
+
814
+ `DraftProvider.grouped` now opens method-owned row state using the same
815
+ companion checkpoint format. Its sampler is injected; the provider retains
816
+ weights while the group owns draft KV and hidden rows. Prepared requests can
817
+ join, retire, reorder, drain and rejoin without exposing tensor layouts to
818
+ scheduling or introducing another cache store. Capture and membership changes
819
+ occur between committed rounds. The request source and group share Qwen's
820
+ attachment encoding and restoration.
821
+
822
+ The provider interface is adopted in the working tree after bf16/KV4/KV8
823
+ full-round controls at B=1/2/4 on both Macs, including rebuilt checkpoints,
824
+ SSD restart continuations and both complete model-free suites. Extraction
825
+ removes padding, so the continuation control also rebuilds its raw state to
826
+ match attention geometry. The initial M4 comparison against retained padding
827
+ changed subsequent draft KV despite matching tokens and target state; that
828
+ result is retained. These are internal refactor controls. Coordinated
829
+ target/draft admission now uses staged state publication, described in
830
+ batching §7. Source
831
+ identity and raw checks are in the composition-baseline reports under
832
+ `mtp-provider-group-manifest.json`.
833
+
834
+
835
+ The isolated serving candidate adds method preparation and advancement to the
836
+ existing execution group. The scheduler retains its queue, execution lease and
837
+ admission policy; the method owns target/draft state, acceptance and sampling.
838
+ The gateway asks the binding for its supported grouped methods and forwards
839
+ output metadata and speculative usage. No second MTP scheduler is introduced.
840
+ Its real KV4 HTTP test passes on M1 Max and M4 Pro: four submitted requests
841
+ reach a target verification graph with shape B=4, each returns seeded samples
842
+ and logprobs, and the group drains. B=1 token and acceptance checks compare
843
+ against the existing request producer. Callback-stop, failure, cancellation,
844
+ EOS and shared RAM-prefix checks are included in the extended native gate.
845
+ Mixed HTTP checks on both Macs compose structured JSON, seeded sampling and
846
+ logprobs with ordinary requests in the same MTP group. Shared-method SSD
847
+ restart preserves target/draft state, tokens and acceptance traces on both.
848
+ An extended M1 native check also admits a shorter-lived request with a different
849
+ prompt length while another request is decoding, then repeats the same schedule
850
+ with matching outputs. Admission now publishes target state, draft state and
851
+ executor membership together before releasing superseded state. A reproduced
852
+ cleanup failure formerly left a rejected row active; the admission failure
853
+ handler now retires that row before another method round. The candidate remains
854
+ isolated pending complete composition and paired performance acceptance.
855
+ Timing results and their limits live in benchmarks.md. Evidence:
856
+ `reports/qwen38-closeout/composition-baseline/mtp-serving-method-manifest.json`.
857
+
858
+ For the original private-cache candidate, the M4 Pro unit gate passed 18 tests. Native prompts at 128, 513 and
814
859
  2,051 tokens pass six restore checks with unchanged state hashes, token IDs
815
860
  and acceptance traces; repeated allocation is stable at each length. The HTTP
816
861
  gate completes eight responses with identical text, token counts and finish
@@ -871,12 +916,18 @@ section 7.7. Raw evidence: `reports/qwen38-rd/mtp-cache-candidate-native.json` a
871
916
 
872
917
  ## 6. Composition rules (as served)
873
918
 
874
- - A mounted draft routes EVERY request to the serial lane (B=1 latency
875
- mode).
876
- - Quantized KV (any axis) wins over spec: drafted requests decode serially
877
- WITHOUT speculation, with a startup warning (spec lane is bf16-KV-only).
919
+ - Method selection precedes placement. Qualified Qwen MTP uses grouped
920
+ target/draft state, sampling and checkpoint interfaces in the shared
921
+ executor. Other draft providers still use the serial verifier.
922
+ - KV policy stays with the request. Shared Qwen MTP supports bf16 and
923
+ start-zero uniform KV4/KV8/TurboQuant. Unsupported compositions select
924
+ ordinary decoding. Current defaults and qualifications live in server-config.md.
878
925
  - Structured output composes (the constrained verify walk).
879
- - Prompt-cache reuse is bypassed on the spec path.
926
+ - Qwen MTP prefill state uses the shared RAM/SSD cache. The source supplies
927
+ draft KV and the pending hidden row through its checkpoint interface;
928
+ the cache owns retention and persistence. Other speculative sources still
929
+ begin with fresh state until they supply a checkpoint codec. Generated-output
930
+ capture remains R17 work.
880
931
  - Native GLM MTP and an explicit `--draft-model`/`--draft-kind` are mutually
881
932
  exclusive; one provider per request so two draft histories never advance
882
933
  target or grammar state twice.
@@ -1009,11 +1060,12 @@ gets assert fills; verify proposals are dropped and counted
1009
1060
  (`usage.fill.verifyUnsupported`). Checkpointing is real work (~48 DeltaNet
1010
1061
  states on Qwen3.8) and is measured: `usage.fill.checkpointMs`.
1011
1062
 
1012
- **Not migrated (deliberate).** The shipped `DraftSource` roster (ngram, MTP,
1013
- two-model, DSpark) keeps its own seam and executor. The adapter — a DraftSource
1014
- wrapped as a verify-policy ProposalSource, so one apply primitive serves both
1015
- lanes — is future work; rewiring it here would have put the spec lane's oracles
1016
- at risk for no new capability.
1063
+ **Remaining fill integration.** Prompt lookup, Qwen MTP and standalone
1064
+ drafting now share the grouped method lifecycle at B1/B>1 for qualified
1065
+ target layouts (see batching.md). DSpark and other provider migrations remain.
1066
+ Unifying fill proposals with draft proposals through one apply primitive is
1067
+ still open; the existing fill implementation retains its cache transaction
1068
+ contract while that method composition is qualified.
1017
1069
 
1018
1070
  ### 7.2 The echo tier (K3c, Lab, `MLX_BUN_FILL=echo`)
1019
1071
 
@@ -1548,6 +1600,317 @@ grammar/KV/batch/logprobs/seed exclusions individually after their own gates.
1548
1600
  The full experimental matrix and completion rule are in
1549
1601
  [decode-speed-program.md](decode-speed-program.md#7-qwen38-27b-research-program).
1550
1602
 
1603
+ ### 7.5 Logical jump-ahead prefill
1604
+
1605
+ Proposal by Josh Rossi, recorded 2026-09-08. Research proposal, not an
1606
+ implemented semantic intervention or a measured task-time improvement.
1607
+ This is the canonical write-up and proposed preprint question. The existing
1608
+ fixed-serialization implementation is described in §7.4. The broader
1609
+ proposal deliberately permits a different continuation.
1610
+
1611
+ The governing [product objective](../planning/PRODUCT_ROADMAP.md#product-north-star),
1612
+ in Josh's words, is "The absolute BEST local AI experience on a mac". It
1613
+ covers the entire project, including simple installation, direct application
1614
+ integration and JavaScript/TypeScript development. A preprint is optional.
1615
+ This research serves that objective by finishing tasks sooner, producing
1616
+ better results, or making a more capable model practical on the same hardware.
1617
+ A hypothetical 30% reduction in task completion time would be a meaningful
1618
+ product improvement, not a measured result of this proposal. Evaluate the
1619
+ complete experience, including quality, reliability, latency and memory,
1620
+ rather than treating a token-rate increase or a publication as the goal.
1621
+
1622
+ The model often spends time deciding what to do, writes relevant content
1623
+ in its reasoning, and then generates that content again inside a tool call.
1624
+ Josh proposes letting the runtime recognize the intended action, construct
1625
+ some or all of its tool-call representation, and append it through prefill.
1626
+ The model continues from the supplied history and actual tool result.
1627
+ The runtime does not ask the target model to verify that it would have
1628
+ sampled each supplied token.
1629
+
1630
+ The research question has two parts:
1631
+
1632
+ 1. With perfect knowledge of an eligible continuation, how much decode time
1633
+ can be replaced by cheaper prefill and construction work?
1634
+ 2. With an imperfect predictor, how often can the model recover from an
1635
+ unsuitable intervention, and what does that recovery cost?
1636
+
1637
+ The deciding quantity is time saved by logical jump-ahead prefill minus time
1638
+ spent on recovery, with intervention overhead included and task quality held
1639
+ to an independently evaluated standard. Prediction errors do not by
1640
+ themselves rule out a useful speedup. Their consequences determine the cost.
1641
+
1642
+ #### Context management is the broader premise
1643
+
1644
+ Josh's framing is that working with LLMs is largely context management.
1645
+ For the local inference system under our control, the runtime owns every
1646
+ token supplied to the model. At each generation step, the abstraction is
1647
+ `token sequence in -> next-token distribution -> sampled token`.
1648
+ The KV and recurrent caches are computed representations of that history,
1649
+ not an independent record of the path the model might have taken.
1650
+
1651
+ The runtime can construct, insert, replace, summarize or remove context.
1652
+ It can choose what the model needs to decide and what software can supply.
1653
+ The full original transcript need not remain the active inference context.
1654
+ It can remain in the audit log while a different sequence drives the next
1655
+ step. The resulting sequence still must be processed consistently by the
1656
+ model and preserve enough information for the task.
1657
+
1658
+ Logical jump-ahead prefill and micro-compaction are two applications of this
1659
+ control. One supplies a continuation before it is redundantly generated.
1660
+ The other retires or rewrites material after its immediate purpose is served.
1661
+ Both should be judged by successful task completion, elapsed time and the
1662
+ cost of recovering from an inadequate context decision.
1663
+
1664
+ #### Mechanism and example
1665
+
1666
+ Suppose the reasoning contains a settled instruction to write `hello.txt`
1667
+ with the contents `hello, world!`. The normal path generates a tool name,
1668
+ argument names, path and escaped contents. The proposed path constructs that
1669
+ representation from the available trace, appends it as assistant tool-call
1670
+ content, and executes the call through the normal tool dispatcher.
1671
+
1672
+ An intervention consists of:
1673
+
1674
+ 1. Detect an eligible boundary using only context available at that moment.
1675
+ 2. Select an action or source span and construct the continuation, including
1676
+ required escaping and protocol delimiters.
1677
+ 3. Append the supplied tokens through the model's state-update path, then
1678
+ resume generation at the next unresolved choice or dispatch a complete call.
1679
+ 4. Return the actual tool outcome and allow the model to continue, including
1680
+ correcting an unsuitable action when needed.
1681
+
1682
+ The state update still runs model forward computation. Attention KV,
1683
+ recurrent state, positions and parser state must describe the new sequence.
1684
+ It saves sequential token decisions and can avoid intermediate vocabulary
1685
+ projections and verification work. Copying text from an earlier position
1686
+ does not generally permit copying that position's KV, because its context
1687
+ and position differ. Editing an existing prefix also requires invalidating
1688
+ and recomputing affected state. Appending at the current boundary is the
1689
+ smallest implementation to study.
1690
+
1691
+ There is no hidden record of the alternate tokens the model would have
1692
+ sampled. Given consistent state for the supplied prefix, subsequent decoding
1693
+ conditions on that prefix. This does not imply that every supplied action is
1694
+ appropriate or that the model always recovers. Those are empirical questions.
1695
+
1696
+ #### Perfect prediction and imperfect recovery
1697
+
1698
+ Perfect prediction supplies an upper-bound experiment. Replacing a known
1699
+ span's serial generation with a cheaper append saves time. Span size,
1700
+ context length, kernel behavior and construction overhead determine the
1701
+ amount. Very short spans can cost more to detect and append than to decode.
1702
+
1703
+ For the oracle experiment, use the saved future continuation to choose the
1704
+ span, while requiring the copied source content to exist before the jump.
1705
+ This deliberately uses hindsight to measure opportunity. It is not evidence
1706
+ that an online detector can identify those opportunities. An online policy
1707
+ must receive only the prefix available at the intervention boundary.
1708
+
1709
+ With an imperfect policy, an action may still satisfy the task even when it
1710
+ differs from the saved continuation. Another action may require correction.
1711
+ For example, the runtime supplies `ls` in an unsuitable working directory.
1712
+ The returned listing fails to answer the model's question, so the model
1713
+ changes directory or asks for a different listing. The extra reasoning,
1714
+ request prefill, tool calls and tool execution count as recovery cost.
1715
+
1716
+ Record errors the model fails to notice, persistent loops and unsuccessful
1717
+ tasks too. Recovery is possible, not guaranteed. A retry alone is not proof
1718
+ of recovery; the task must regain useful progress and ultimately meet its
1719
+ acceptance criteria. Identical sampled tokens are not required for success.
1720
+
1721
+ #### Cost model
1722
+
1723
+ For an intervention, define:
1724
+
1725
+ | Symbol | Cost |
1726
+ |---|---|
1727
+ | `D` | Serial decode time avoided for the replaced span |
1728
+ | `P` | Time to prefill the supplied continuation and resume |
1729
+ | `H` | Detection, selection, serialization and other intervention overhead |
1730
+ | `R` | Additional downstream time caused by correction or other consequences |
1731
+
1732
+ The local accounting model is:
1733
+
1734
+ ```text
1735
+ net saving = D - P - H - R
1736
+ ```
1737
+
1738
+ If a fraction `q` of interventions require recovery, and their mean added
1739
+ cost is `C`, a simplified expectation is:
1740
+
1741
+ ```text
1742
+ expected net saving = E[D - P - H] - q * C
1743
+ break-even recovery frequency = E[D - P - H] / C
1744
+ ```
1745
+
1746
+ The break-even expression assumes positive `C`, successful eventual recovery
1747
+ and no other downstream differences. Here `q` measures harmful interventions
1748
+ requiring recovery, not disagreement with a hypothetical sampled string.
1749
+ Span length, uncertainty and recovery cost may be correlated; measure their
1750
+ joint behavior rather than multiplying unrelated averages.
1751
+
1752
+ This decomposition explains the mechanism. The authoritative measurement is
1753
+ complete task wall time against a paired baseline. A changed trajectory can
1754
+ alter later reasoning, tool latency, cache reuse and compaction. Those effects
1755
+ belong in the result even when they cannot be assigned to one jump. Do not
1756
+ double-count overlapping spans or add savings from dependent interventions
1757
+ as if each occurred in the original unmodified run.
1758
+
1759
+ #### Evidence and first experiment
1760
+
1761
+ The completed Kanban trace supplies a workload and an offline opportunity
1762
+ analysis. Generation-to-generation duplicate coverage and the narrower
1763
+ reasoning-to-tool coverage are recorded in the
1764
+ [completed Kanban benchmark](../reference/benchmarks.md#completed-fresh-pi-kanban-with-bounded-range-cache-m4-pro-2026-09-08).
1765
+ Those counts retain first occurrences, merge overlapping later positions and
1766
+ exclude replayed request history. They use retokenized payloads rather than
1767
+ the original sampled token stream, so they are opportunity estimates.
1768
+ The longest whole-file repeat was a write followed by a read. It does not
1769
+ establish that the model first wrote that whole file in reasoning.
1770
+
1771
+ Start with these experiment arms:
1772
+
1773
+ | Arm | Purpose |
1774
+ |---|---|
1775
+ | Ordinary decoding | Establish task success, timing and natural retry behavior |
1776
+ | Existing strict fill | Isolate savings from fixed serialization already supported |
1777
+ | Oracle content jumps | Estimate savings with hindsight and no selection mistakes |
1778
+ | Online logical jumps | Measure an implementable policy using only the current prefix |
1779
+ | Controlled mistaken jumps | Measure detection, recovery and failure under known perturbations |
1780
+
1781
+ For the online arm, begin with complete literal content already in the trace
1782
+ and a partially generated tool call that identifies the destination. This
1783
+ reduces the decisions the runtime must infer. Then evaluate earlier action
1784
+ selection as a separate policy. Track changes in opportunity coverage and
1785
+ recovery cost as the policy becomes more permissive.
1786
+
1787
+ Use fresh workspaces and matched prompts, models, quantization, tool access,
1788
+ context limits and hardware conditions. Preserve the same cache and decoding
1789
+ configuration across arms where supported. The Kanban configuration and
1790
+ strict fill currently have composition restrictions; establish a supported
1791
+ common control before attributing a difference to logical jumps. Keep the
1792
+ separate MLX-LM comparison as a reference experiment, not a substitute for
1793
+ this within-engine ablation.
1794
+
1795
+ Record supplied and sampled tokens separately, source-span provenance,
1796
+ intervention boundaries, append cost, selection cost, tool outcomes, extra
1797
+ turns, recovery time, compactions and complete task time. Keep raw generated
1798
+ text and supplied text distinguishable in the audit log, while making the
1799
+ model-visible history consistent with the action actually executed.
1800
+
1801
+ Repeat paired runs over multiple tasks and sampling trials. A matching seed
1802
+ does not preserve the trajectory after an intervention. Evaluate artifacts
1803
+ with independent task checks. Report success rate and the distribution of
1804
+ task times, including slow recoveries, timeouts and failures. Fast failed
1805
+ runs must not improve the reported time-to-success result. Where retries
1806
+ are allowed, include their cost under a predefined retry budget.
1807
+
1808
+ #### Micro-compaction after tool execution
1809
+
1810
+ Josh proposes replacing a long reasoning segment after its associated tool
1811
+ calls have completed. For example, the model may spend roughly 50,000 tokens
1812
+ planning and drafting, then write files and inspect the results. At that
1813
+ boundary, the runtime could replace the reasoning with a concise account of
1814
+ decisions, completed actions, observed results and unresolved work.
1815
+
1816
+ This is selective compaction at a task boundary. It need not wait until the
1817
+ whole context window approaches its limit. A candidate procedure is:
1818
+
1819
+ 1. Identify the reasoning segment whose associated actions have completed.
1820
+ 2. Preserve current requirements, decisions that still constrain the work,
1821
+ observed failures and pending questions in a compact replacement.
1822
+ 3. Retain the relevant tool-call/result pairs and references to written
1823
+ artifacts. Keep the original trace available outside the active context.
1824
+ 4. Build the revised token sequence, recompute affected model state, and
1825
+ continue the task from that sequence.
1826
+
1827
+ The replacement may come from a model-generated summary or deterministic
1828
+ extraction of completed actions and results. Compare these methods rather
1829
+ than assuming another long generation is necessary. A successful file write
1830
+ provides an artifact the model can read again; whether that makes the full
1831
+ earlier draft disposable depends on the remaining task. Missing rationale
1832
+ or a discarded constraint can require recovery even when the file survives.
1833
+
1834
+ Removing earlier tokens changes the context for retained later tokens.
1835
+ Ordinary prefix caching can preserve the unchanged prefix, but it cannot
1836
+ generally reuse the old suffix state as if the removed reasoning were still
1837
+ present. Recompute that suffix under the new history. Any method that keeps
1838
+ stale state intentionally is a separate approximation to evaluate.
1839
+
1840
+ Micro-compaction cannot recover the time already spent generating the long
1841
+ reasoning segment. It can reduce later context-processing work and memory
1842
+ use, and may change subsequent generation or avoid a larger compaction.
1843
+ Measure those effects over the remaining task:
1844
+
1845
+ ```text
1846
+ net saving = future context-processing and trajectory savings
1847
+ - summary/extraction cost
1848
+ - state-rebuild and management cost
1849
+ - extra recovery cost
1850
+ ```
1851
+
1852
+ Because a warm prefix cache already avoids much repeated prefill, removed
1853
+ token counts alone do not establish savings. Context length can still affect
1854
+ subsequent attention work and capacity. Record actual cache reuse, rebuild
1855
+ time, memory, later decode time and rereads caused by missing information.
1856
+
1857
+ Compare the existing compaction policy, post-tool micro-compaction,
1858
+ jump-ahead alone, and their combination. Use the same task checks and failure
1859
+ accounting as the jump experiment. Their gains need not add: removing a
1860
+ reasoning segment also removes a potential source for later content copying.
1861
+ An external source store could retain it, with retrieval cost included.
1862
+
1863
+ #### Related work and the proposed preprint
1864
+
1865
+ Josh identified the connection to structured output and grammars at the
1866
+ outset. [XGrammar](https://github.com/mlc-ai/xgrammar) implements efficient
1867
+ grammar-constrained generation. SGLang's
1868
+ [jump-forward decoding](https://www.lmsys.org/blog/2024-02-05-compressed-fsm/)
1869
+ directly prefills strings fixed by a grammar until the next branch. These
1870
+ are established relatives of fixed-serialization fill.
1871
+
1872
+ [Copy-as-Decode](https://arxiv.org/abs/2604.18170), an April 2026 preprint,
1873
+ is direct prior art for unverified content prefill. The model emits an
1874
+ explicit instruction selecting input line ranges, then the runtime prefills
1875
+ their contents without probabilistic verification. It studies an oracle
1876
+ savings bound and span-selection errors. Editing belongs within this
1877
+ proposal's scope, including when edits are tool calls; the application label
1878
+ does not establish a separate invention. The relevant difference to study
1879
+ is runtime inference from reasoning or a partial call versus an explicit
1880
+ model-selected copy instruction, and the cost of subsequent agent recovery.
1881
+ The paper does not establish agentic multi-file coverage.
1882
+
1883
+ Harness intervention is also established. AI SDK supports
1884
+ [custom tool-call repair](https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling#tool-call-repair),
1885
+ Pydantic AI exposes
1886
+ [JSON and argument modification hooks](https://github.com/pydantic/pydantic-ai/blob/main/docs/capabilities/custom.md),
1887
+ and OpenClaw can
1888
+ [insert loop warnings and block repeated calls](https://docs.openclaw.ai/tools/loop-detection).
1889
+ These show that an agent system can alter actions or subsequent context
1890
+ outside the sampler. They do not measure this proposal's speedup.
1891
+
1892
+ Exact [speculative sampling](https://proceedings.mlr.press/v202/leviathan23a.html)
1893
+ preserves the target distribution conditional on a given context and sampling
1894
+ policy. Logical jumps choose supplied context without that requirement.
1895
+ An exact speculative decoder could still accelerate free generation between
1896
+ jumps.
1897
+
1898
+ The search so far has not identified a direct demonstration of runtime
1899
+ inference of a tool continuation from current reasoning, unverified prefill
1900
+ of that continuation, and whole-agent evaluation of savings against recovery
1901
+ cost. This is a bounded search finding, not a priority claim or proof of
1902
+ absence. The broader unverified-copy mechanism already has overlapping work.
1903
+
1904
+ A working preprint title is **Logical jump-ahead prefill: trading redundant
1905
+ agent decoding for recovery cost**. The contribution to pursue is a defined
1906
+ intervention mechanism, an oracle opportunity bound, an online policy, and a
1907
+ measured relationship between saved decode time and recovery cost at retained
1908
+ task quality. A negative or workload-dependent result would still answer the
1909
+ question. The current trace analysis motivates that study; it does not yet
1910
+ establish the paper's performance result. A broader literature review and
1911
+ the controlled experiments above remain necessary before claiming novelty
1912
+ or a practical speedup.
1913
+
1551
1914
  ## 8. Open items
1552
1915
 
1553
1916
  - K3 (fill): the packed 27B positive-fill token-identity fixture passes;
@@ -139,15 +139,16 @@ Code map:
139
139
  single conversion chokepoint (serve serial lane + generate + eval all flow
140
140
  through it); `TurboQuantKVCache.fromKVCache`; `RotatingKVCache` layers stay
141
141
  bf16 with a one-time warning; keeps the `quantizedKvStart` semantics.
142
- - `src/server.ts` — startup refusals: `--batch N` + turbo (serial-only);
143
- head_dim not in `TURBOQUANT_HEAD_DIMS` (fail-fast at `createServer`, not on
144
- first append — 2026-07-07 review); `--draft-model` + any quantized KV warns
145
- and those requests decode serially WITHOUT speculation (spec-eligibility
146
- gate excludes `turboQuant`; the spec loop builds fresh bf16 caches and would
147
- otherwise silently drop the scheme). `turboQuant` and `kvQuant` are
148
- mutually exclusive (turbo wins with a warning).
149
- - `src/serve/generation-gateway.ts` — explicit solo-only refusal in
150
- placement (belt + braces on top of the instanceof exclusion).
142
+ - `src/backends/mlx/kv-codec.ts` and `src/model/turboquant-codec.ts` separate
143
+ encoding and existing fused kernel selection from storage membership.
144
+ - `KvTensorRows` owns arbitrary encoded planes; `BatchedTurboQuantKVCache`
145
+ binds the five TQ planes to shared positions and a rotated-value attention
146
+ port. Gemma owns pre-write row positions across cache appends and releases
147
+ shared positions with the shared attention state.
148
+ - `src/backends/mlx/cache-layout.ts` supplies ordinary and target-transaction
149
+ layouts. The gateway binds start-zero TQ and grouped Qwen MTP capabilities;
150
+ the scheduler only chooses work. Server head-dimension validation remains.
151
+ `turboQuant` and `kvQuant` are mutually exclusive.
151
152
  - `src/kv-store.ts` — `CacheKind "turboquant"`; header carries kBits/vBits
152
153
  + head_dim; snapshot/restore/clone branches.
153
154
  - `src/model/fingerprint.ts` — NOT touched, by symmetry: uniform
@@ -580,18 +581,65 @@ upstream/mlx-0.31.2; the closed research helpers are removed.
580
581
  4. Whole-repo `tsc --noEmit` = 0; fast suite green; turbo requests route
581
582
  serial with a clear reason.
582
583
 
584
+ The Phase 18 composition is integrated in the unreleased working tree;
585
+ `~/.cache/mlx-bun/turboquant-composition-validation` remains a frozen comparison.
586
+ It extracts the existing
587
+ encode/decode operations behind a KV codec interface and applies that codec to
588
+ one owner of five tensor fields with shared row positions. Merge, retirement,
589
+ rollback and extraction operate on encoded bytes. A rotated-value attention
590
+ port lets Gemma and MiniCPM consumers retain the existing deferred inverse
591
+ rotation with either storage layout.
592
+
593
+ On M1 Max and M4 Pro, the focused codec/kernel/row checks pass 29 tests and
594
+ 2,828 assertions. A native Qwen target test passes 2,824 assertions on each
595
+ machine, comparing retained state and subsequent full logits at the same B=2
596
+ shape across unequal accepted prefixes. Existing fused kernel selection is
597
+ preserved. The subsequent MLX cache-layout binding now serves ordinary and
598
+ Qwen MTP groups through those same encoded rows. Scheduling retains its
599
+ method lifecycle; sampling and fused codec selection are unchanged. The
600
+ method key and paired-prefix namespace include the TurboQuant scheme.
601
+ Temporary extracted-state views use the existing lease interface.
602
+
603
+ Fused K8/V3 serving passes on both Macs: MTP2 and MTP4 each prove true B4,
604
+ seeded logprobs, mixed grammar, joins and retirement; ordinary tests prove
605
+ B1/B2/B3 and immutable RAM donor reuse. Paired RAM and SSD restart tests
606
+ preserve target/draft/hidden state and continuations. Full suites pass
607
+ 2,078 tests on M1 and 2,082 on M4, with typechecks clear. MTP3 also passes
608
+ the M1 native/HTTP gate. On M1, all 21 saved-boundary requests match across
609
+ 8 GiB synchronous, 1 GiB synchronous and 1 GiB asynchronous RAM-cache arms,
610
+ including full usage and acceptance. Each arm durably flushes all seven
611
+ snapshots with no missing, pending, dropped or failed writes. The constrained
612
+ arms cause six eviction spills; the async observer confirms 3,264 submissions.
613
+ These sequential shared-server pressure checks cause substantial swapping;
614
+ B4 correctness is a separate native gate, and no speed or memory-reduction
615
+ claim follows. M4 pressure and strict paired performance acceptance remain open.
616
+ The shared integration is now adopted in the unreleased working tree; the
617
+ released v0.3.0 binary retains its earlier placement limits.
618
+ Evidence: `reports/qwen38-closeout/composition-baseline/turboquant-composition-manifest.json`.
619
+ Integration evidence: `reports/qwen38-closeout/composition-baseline/turboquant-serving/`.
620
+ Broader family checks pass MiniCPM seeded/logprob serving but reproduce a
621
+ Gemma e4b/12B failure: attention borrows the row-offset array across a cache
622
+ append that releases it. The adopted ownership fix passes seeded/logprob and
623
+ prefix checks on both Gemma families, MiniCPM/Qwen prefix controls, and the
624
+ complete suites on both Macs. M4 acceptance also passes fused and unfused
625
+ Gemma seeded sampling, affine KV4 controls and Qwen MTP3 B4 serving.
626
+ MiniCPM prefix checks allow the existing policy to supersede trimmable donors
627
+ while proving byte identity and continuation through retirement.
628
+
583
629
  ## KV-leg limits and non-goals (recorded so they don't creep)
584
630
 
585
631
  - Full-attention layers only; rotating/sliding-window layers stay bf16 (warn
586
632
  once, never throw). Head dims outside {64,128,256,512} refused at server
587
633
  start.
588
- - Solo-only: no batched TurboQuant (novel Cache class); paged-KV combos are
589
- refused explicitly.
634
+ - Shared ordinary execution supports row-local delayed TurboQuant; Qwen MTP
635
+ requires start zero. Delayed affine conversion and paged-KV combinations
636
+ remain unsupported.
590
637
  - No fused quantized-SDPA Metal kernel (remaining fetch cost is
591
638
  unpack+gather); no QJL residual stage; no entropy coding (the paper
592
639
  declined it too).
593
- - Speculative lane is bf16-KV-only: turbo + `--draft-model` keeps the KV
594
- scheme and decodes serially without speculation.
640
+ - Strict legacy serial speculation and draft providers without grouped TQ
641
+ support retain their existing exclusions. A shared server with one active
642
+ row is the TQ/MTP B1 path.
595
643
  - No speed claims: v1 dequant-on-fetch is expected slower per step at long
596
644
  context; this ships as a memory/context feature like uniform KV. Admission
597
645
  still bills turbo as bf16 (server-config.md says so).
@@ -2100,3 +2148,65 @@ any use of the larger crossover or equivalent small-chunk span splitting.
2100
2148
  - 2026-09-02 — Q3 full recipe (rot + LDLQ + k-map 3.00) PASSED: KL 0.1553 at
2101
2149
  3.55 bpw, MMLU 88 / tGSM 48 / rawGSM 44; eval-carrier repack tool; LDLQ
2102
2150
  loop-shadow bug fixed.
2151
+
2152
+ ## Delayed row conversion and reusable precision boundaries
2153
+
2154
+ `DelayedTurboQuantKVCache` implements the existing batchable cache and
2155
+ rotated-value attention ports. It keeps serial row caches during a mixed
2156
+ plain/TQ phase and invokes the existing maintenance operation before each
2157
+ row's next append. `KvTensorRows` supplies positions and masks without
2158
+ dummy tensor planes. Once every row converts, `BatchedTurboQuantKVCache`
2159
+ owns the encoded rows. The scheduler invokes a generic preparation hook;
2160
+ it does not implement threshold, codec or inverse-rotation logic.
2161
+
2162
+ The rotated-value port can capture an output transform for its fetched
2163
+ state. Plain value rows pass through unchanged, and TQ rows receive the
2164
+ existing inverse rotation. Gemma carries that transform through its donor
2165
+ KV consumers. Model projections and attention remain at B=N. Start-zero
2166
+ layouts and kernel selection retain their existing paths.
2167
+
2168
+ A cache's `minimumReusableOffset` records an irreversible precision
2169
+ boundary. Delayed maintenance sets it to the actual conversion offset,
2170
+ which can exceed the configured threshold when a prefill chunk crosses it.
2171
+ Clone, row extraction and SSD metadata retain the bound. RAM/SSD selection
2172
+ and ancestor supersession check it independently of physical trimmability.
2173
+ Earlier plain donors remain reusable after a converted descendant appears.
2174
+ Old TQ SSD headers lacking the bound conservatively use their stored offset.
2175
+
2176
+ Focused tests cover exact mixed-row bytes and output transforms through
2177
+ reordering, retirement and re-admission, plus RAM/SSD ancestor retention,
2178
+ restart, continuation and old-header compatibility. Native seeded/logprob
2179
+ and prefix gates accept positive thresholds via their test environment
2180
+ switches. Shared Qwen MTP also uses the delayed layout. Its transaction
2181
+ begins conversion from committed history before verification. A verify block
2182
+ may cross the configured threshold; resolution converts at the retained
2183
+ offset after rollback and before checkpoint publication, so rejected tokens
2184
+ never set the precision boundary.
2185
+ The draft provider retains its existing paired checkpoint format.
2186
+
2187
+ Mixed rollback and final packed promotion preserve each row's physical left
2188
+ padding. Re-aligning it based on another row's accepted count changes SDPA
2189
+ reduction positions even when all live cache bytes match. Same-batch native
2190
+ controls check every target layer and subsequent hidden rows after unequal
2191
+ acceptance. Affine delayed speculation and the legacy serial TQ speculative
2192
+ path remain excluded. This implementation changes no defaults.
2193
+
2194
+ ### Wider split-K verification screen
2195
+
2196
+ The current packed down-projection operation covers five through eight input
2197
+ vectors. An isolated candidate extended that operation through 32 vectors,
2198
+ using 8-, 16- or 32-row tiles while retaining the native split partition and
2199
+ accumulation order. Scheduler and speculation policy were unchanged.
2200
+
2201
+ Actual 2-, 3- and 4-bit artifact projections pass exact expanded-weight
2202
+ controls at every new width and three input seeds on both Macs. Full Qwen
2203
+ logits, recurrent/KV state and continuation match the unchanged eligibility
2204
+ control at B1/B2/B4/B8 on both Macs. Call-count assertions prove the wider
2205
+ kernels ran. Updated unit coverage includes wider partition tails and
2206
+ noncontiguous inputs; both complete suites and typechecks pass.
2207
+
2208
+ The alternating M4 prompt-lookup comparison preserves all requests but loses
2209
+ concurrent throughput. This wider eligibility is not adopted. Future work
2210
+ needs serving dispatch/cost attribution before additional tile tuning.
2211
+ Measurements: benchmarks.md. Evidence and source manifest:
2212
+ `reports/qwen38-closeout/composition-baseline/trellis-batch-width/`.