mlx-bun 0.2.0 → 0.3.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 (364) hide show
  1. package/README.md +71 -588
  2. package/docs/README.md +91 -0
  3. package/docs/{design → archive/investigations}/audio-input-plan.md +4 -4
  4. package/docs/{design → archive/investigations}/diffusion-gemma-port.md +3 -3
  5. package/docs/{design → archive/investigations}/faithful-l1-consolidation.md +4 -4
  6. package/docs/{design → archive/investigations}/minicpm5-decode-megakernel.md +11 -11
  7. package/docs/{design → archive/investigations}/optimization_plan.md +1 -1
  8. package/docs/{design → archive/investigations}/pre-colibri-stabilization.md +5 -5
  9. package/docs/{design → archive/investigations}/the-dreaming-handoff.md +2 -2
  10. package/docs/design/batching.md +569 -0
  11. package/docs/design/decode-speed-program.md +3178 -169
  12. package/docs/design/dreaming-nightly-pipeline.md +675 -282
  13. package/docs/design/generic-model-support.md +579 -334
  14. package/docs/design/kv-cache.md +680 -0
  15. package/docs/design/orpo-training.md +673 -1239
  16. package/docs/design/speculative-decoding.md +1627 -0
  17. package/docs/design/turboquant.md +2102 -0
  18. package/docs/design/unified-engine-frontier-plan.md +1831 -727
  19. package/docs/design/web-chat-redesign.md +666 -1083
  20. package/docs/planning/PRODUCT_ROADMAP.md +34 -1
  21. package/docs/planning/release-notes-v0.3.0.md +35 -0
  22. package/docs/planning/video-series.md +2 -2
  23. package/docs/reference/benchmarks.md +1162 -0
  24. package/docs/reference/cli.md +394 -159
  25. package/docs/reference/distribution.md +321 -182
  26. package/docs/reference/environment.md +348 -0
  27. package/docs/reference/glossary.md +39 -0
  28. package/docs/reference/library-api.md +566 -168
  29. package/docs/reference/memory.md +227 -64
  30. package/docs/reference/models.md +104 -6
  31. package/docs/reference/server-api.md +886 -425
  32. package/docs/reference/server-config.md +638 -330
  33. package/docs/reference/training.md +393 -254
  34. package/docs/reference/troubleshooting.md +166 -0
  35. package/package.json +9 -4
  36. package/src/audio/decode.ts +2 -2
  37. package/src/audio/features.ts +2 -2
  38. package/src/backends/mlx/autoregressive.ts +108 -0
  39. package/src/backends/mlx/batch-group.ts +1646 -0
  40. package/src/backends/mlx/diffusion.ts +39 -0
  41. package/src/backends/mlx/draft-target.ts +47 -0
  42. package/src/backends/mlx/evaluation.ts +105 -0
  43. package/src/backends/mlx/fill-append.ts +45 -0
  44. package/src/backends/mlx/gateway-binding.ts +71 -0
  45. package/src/backends/mlx/graph.ts +38 -0
  46. package/src/backends/mlx/memory-client.ts +189 -0
  47. package/src/backends/mlx/memory-guard.ts +40 -0
  48. package/src/backends/mlx/methods.ts +90 -0
  49. package/src/backends/mlx/model-prompt.ts +164 -0
  50. package/src/backends/mlx/model-serving.ts +79 -0
  51. package/src/backends/mlx/prefill.ts +33 -0
  52. package/src/backends/mlx/request-policy.ts +20 -0
  53. package/src/backends/mlx/rollback.ts +51 -0
  54. package/src/backends/mlx/serial-executor.ts +273 -0
  55. package/src/backends/mlx/speculative.ts +114 -0
  56. package/src/backends/mlx/state-views.ts +26 -0
  57. package/src/backends/mlx/text-engine.ts +73 -0
  58. package/src/cli.ts +58 -25
  59. package/src/client.ts +66 -0
  60. package/src/config.ts +21 -4
  61. package/src/contracts/completion.ts +16 -0
  62. package/src/contracts/execution.ts +49 -0
  63. package/src/contracts/generation.ts +103 -0
  64. package/src/contracts/host.ts +7 -0
  65. package/src/contracts/jobs.ts +66 -0
  66. package/src/contracts/pi-provider.ts +30 -0
  67. package/src/contracts/pi.ts +259 -0
  68. package/src/contracts/resources.ts +18 -0
  69. package/src/contracts/scheduling.ts +27 -0
  70. package/src/contracts/tsconfig.json +14 -0
  71. package/src/diffusion/diffusion-generate.ts +218 -153
  72. package/src/embed.ts +1 -1
  73. package/src/engine/admission.ts +59 -0
  74. package/src/engine/cancellation.ts +38 -0
  75. package/src/engine/engine.ts +56 -0
  76. package/src/engine/execution-coordinator.ts +70 -0
  77. package/src/engine/execution-plan.ts +51 -0
  78. package/src/engine/resources.ts +42 -0
  79. package/src/engine/scheduler.ts +67 -0
  80. package/src/engine/session.ts +247 -0
  81. package/src/eval/README.md +44 -1
  82. package/src/eval/kl.ts +236 -3
  83. package/src/eval/reference-logits.ts +207 -0
  84. package/src/eval/runner.ts +8 -96
  85. package/src/fill/echo-index.ts +188 -0
  86. package/src/fill/fill-session.ts +452 -0
  87. package/src/fill/proposal.ts +68 -0
  88. package/src/fill/schema-rows.ts +506 -0
  89. package/src/fill/tool-boundary.ts +103 -0
  90. package/src/fit.ts +1 -1
  91. package/src/generate.ts +656 -268
  92. package/src/grammar.ts +12 -7
  93. package/src/harness-pi.ts +14 -33
  94. package/src/hub-rest.ts +4 -4
  95. package/src/index.ts +7 -0
  96. package/src/inference/denoising.ts +17 -0
  97. package/src/inference/graph.ts +33 -0
  98. package/src/inference/prefill.ts +39 -0
  99. package/src/inference/rollback.ts +7 -0
  100. package/src/jobs/db.ts +4 -0
  101. package/src/jobs/index.ts +2 -0
  102. package/src/jobs/job-entry.ts +12 -12
  103. package/src/jobs/runner.ts +98 -13
  104. package/src/jobs/task-client.ts +19 -0
  105. package/src/jobs/types.ts +2 -58
  106. package/src/kv-store.ts +109 -49
  107. package/src/lab/README.md +18 -0
  108. package/src/{assets → lab/curve}/curve-designer.html +2 -2
  109. package/src/{curve-sampler.ts → lab/curve/curve-sampler.ts} +2 -2
  110. package/src/{expert-trace.ts → lab/expert-trace/expert-trace.ts} +5 -5
  111. package/src/{model → lab/paged-kv}/paged-kv.ts +9 -6
  112. package/src/library.ts +40 -0
  113. package/src/lora.ts +18 -0
  114. package/src/media-fetch.ts +1 -1
  115. package/src/memory/article.ts +1 -1
  116. package/src/memory/chunk.ts +1 -1
  117. package/src/memory/model.ts +30 -169
  118. package/src/memory/prompts.ts +1 -1
  119. package/src/memory/rest.ts +1 -1
  120. package/src/memory/schedule.ts +1 -1
  121. package/src/memory/stages.ts +4 -1
  122. package/src/memory/vault.ts +1 -3
  123. package/src/mlx/array.ts +9 -10
  124. package/src/mlx/compile.ts +12 -2
  125. package/src/mlx/ffi.ts +58 -11
  126. package/src/mlx/materialize.ts +23 -0
  127. package/src/mlx/metal-kernel.ts +10 -11
  128. package/src/mlx/ops.ts +33 -13
  129. package/src/mlx/quantized-rows.ts +36 -0
  130. package/src/mlx/token-bitmask.ts +52 -0
  131. package/src/mlx/turboquant-kv-decode.ts +82 -0
  132. package/src/mlx/turboquant-kv-inverse.ts +122 -0
  133. package/src/mlx/turboquant-ops.ts +33 -3
  134. package/src/mlx/turboquant-tables.ts +2 -2
  135. package/src/model/batched-mask.ts +8 -2
  136. package/src/model/batched-quant.ts +1 -1
  137. package/src/model/batched-rotating-quant.ts +2 -2
  138. package/src/model/batched-rotating.ts +1 -1
  139. package/src/model/compiled-decode.ts +1 -1
  140. package/src/model/diffusion-gemma.ts +8 -8
  141. package/src/model/factory.ts +76 -33
  142. package/src/model/fingerprint.ts +1 -1
  143. package/src/model/flash-attention.ts +3 -3
  144. package/src/model/gemma4-base.ts +26 -9
  145. package/src/model/gemma4.ts +6 -6
  146. package/src/model/generated/gemma4-12b.ts +2 -2
  147. package/src/model/generated/gemma4-26b.ts +2 -2
  148. package/src/model/generated/gemma4-e4b.ts +2 -2
  149. package/src/model/glm52-dsa.ts +13 -9
  150. package/src/model/glm52-memory.ts +1 -1
  151. package/src/model/implementation.ts +69 -0
  152. package/src/model/minicpm5.ts +6 -8
  153. package/src/model/profile.ts +12 -2
  154. package/src/model/qwen-append.ts +12 -0
  155. package/src/model/qwen-conv.ts +52 -0
  156. package/src/model/qwen3_5-checkpoint.ts +164 -0
  157. package/src/model/qwen3_5.ts +140 -56
  158. package/src/model/support.ts +1 -1
  159. package/src/model/trellis-balanced-scatter.ts +51 -0
  160. package/src/model/trellis-linear.ts +672 -0
  161. package/src/model/trellis-shared-m.ts +151 -0
  162. package/src/model/trellis-shared-scatter.ts +144 -0
  163. package/src/model/trellis-splitk-prefill.ts +158 -0
  164. package/src/model/trellis-tiled-prefill.ts +136 -0
  165. package/src/model/trellis-vector-expand.ts +62 -0
  166. package/src/model/trellis-wide-prefill.ts +94 -0
  167. package/src/model/universal/dense.ts +1 -1
  168. package/src/model/universal/modules.ts +8 -1
  169. package/src/native-pack.ts +6 -5
  170. package/src/pi-provider.ts +6 -64
  171. package/src/pi-web.ts +8 -315
  172. package/src/prompt-cache.ts +96 -53
  173. package/src/quantize/allocator.ts +1 -1
  174. package/src/quantize/config-writer.ts +10 -3
  175. package/src/quantize/rotate.ts +4 -4
  176. package/src/quantize/trellis.ts +586 -0
  177. package/src/responses.ts +28 -1
  178. package/src/runtime-config.ts +18 -4
  179. package/src/sampler.ts +4 -4
  180. package/src/serve/batch-scheduler.ts +8 -1671
  181. package/src/serve/chat-request.ts +391 -0
  182. package/src/serve/chat-stage.ts +195 -0
  183. package/src/serve/checkpoint-identity.ts +64 -0
  184. package/src/serve/completion-executor.ts +15 -7
  185. package/src/serve/discovery-routes.ts +12 -13
  186. package/src/serve/generation-gateway.ts +154 -193
  187. package/src/serve/http.ts +159 -0
  188. package/src/serve/inference-request.ts +79 -0
  189. package/src/serve/isolate.ts +297 -105
  190. package/src/serve/lab-routes.ts +3 -0
  191. package/src/serve/lane-registry.ts +2 -1
  192. package/src/serve/model-admin-routes.ts +7 -5
  193. package/src/serve/model-binding.ts +43 -0
  194. package/src/serve/model-host.ts +512 -0
  195. package/src/serve/openai-wire.ts +103 -0
  196. package/src/serve/parent-application.ts +56 -0
  197. package/src/serve/pipeline.ts +33 -0
  198. package/src/serve/preparation.ts +33 -0
  199. package/src/serve/request-plan.ts +19 -15
  200. package/src/serve/request-prep.ts +346 -0
  201. package/src/serve/response-lease.ts +24 -0
  202. package/src/serve/responses-client.ts +69 -0
  203. package/src/serve/session-completion-engine.ts +110 -0
  204. package/src/serve/session-search.ts +1 -1
  205. package/src/serve/static-routes.ts +5 -5
  206. package/src/serve/text-completion-stage.ts +104 -0
  207. package/src/serve/token-streams.ts +519 -0
  208. package/src/server.ts +317 -2649
  209. package/src/spec/assistant-source.ts +10 -44
  210. package/src/spec/deepspec-source.ts +6 -6
  211. package/src/spec/dflash-source.ts +8 -8
  212. package/src/spec/dspark/ab-stats.ts +3 -3
  213. package/src/spec/dspark/calibration.ts +2 -2
  214. package/src/spec/dspark/deepspec-module.ts +2 -2
  215. package/src/spec/dspark/generate-dflash.ts +2 -2
  216. package/src/spec/dspark/generate.ts +2 -2
  217. package/src/spec/dspark/loader.ts +1 -1
  218. package/src/spec/dspark/module-dflash.ts +4 -3
  219. package/src/spec/dspark/module.ts +3 -3
  220. package/src/spec/dspark/quantize-drafter.ts +1 -1
  221. package/src/spec/generate.ts +1 -1
  222. package/src/spec/glm52-mtp-source.ts +1 -1
  223. package/src/spec/ngram-source.ts +1 -1
  224. package/src/spec/prefix-state.ts +45 -0
  225. package/src/spec/qwen-mtp-source.ts +166 -69
  226. package/src/spec/serve-loop.ts +154 -156
  227. package/src/spec/source.ts +42 -10
  228. package/src/spec/two-model.ts +1 -1
  229. package/src/ssd-cache.ts +80 -12
  230. package/src/ssd-durability.ts +25 -13
  231. package/src/tool-call.ts +51 -14
  232. package/src/train/flash-cce.ts +2 -2
  233. package/src/train/forward.ts +6 -0
  234. package/src/train/loss.ts +1 -1
  235. package/src/train/prefix-shared.ts +5 -1
  236. package/src/train/segmented.ts +5 -3
  237. package/src/train/trainer.ts +6 -6
  238. package/src/vision/prompt.ts +1 -1
  239. package/src/vision/qwen3vl-tower.ts +52 -10
  240. package/src/web/app.html +1 -1
  241. package/src/web/app.js +5 -3
  242. package/src/web/src/adapters-panel.ts +3 -3
  243. package/src/web/src/assistant.ts +2 -36
  244. package/src/web/src/chat.ts +4 -4
  245. package/src/web/src/composer.ts +4 -4
  246. package/src/web/src/hub.ts +1 -1
  247. package/src/web/src/markdown.ts +0 -0
  248. package/src/web/src/memory-panel.ts +1 -1
  249. package/src/web/src/model-picker.ts +1 -1
  250. package/src/web/src/palette.ts +1 -1
  251. package/src/web/src/protocol.ts +3 -39
  252. package/src/web/src/sessions.ts +1 -1
  253. package/src/web/src/ui-catalog.ts +4 -18
  254. package/src/web-assets.ts +47 -0
  255. package/src/weights.ts +55 -9
  256. package/docs/archive/investigations/curve-runs/bisector-route.json +0 -98
  257. package/docs/archive/investigations/curve-runs/bisector-trace.json +0 -1393
  258. package/docs/archive/investigations/curve-runs/curve-terrain.json +0 -1179
  259. package/docs/archive/investigations/curve-runs/curve-terrain.svg +0 -42
  260. package/docs/archive/investigations/hlg-ab.html +0 -34
  261. package/docs/archive/investigations/hlg-explorer.html +0 -238
  262. package/docs/archive/investigations/hlg-figs/cliff.svg +0 -1
  263. package/docs/archive/investigations/hlg-figs/cross.svg +0 -1
  264. package/docs/archive/investigations/hlg-figs/edges.svg +0 -1
  265. package/docs/archive/investigations/hlg-figs/k20-grids.svg +0 -1
  266. package/docs/archive/investigations/hlg-figs/k20-peaks.svg +0 -1
  267. package/docs/archive/investigations/hlg-figs/lw-curve.svg +0 -1
  268. package/docs/archive/investigations/hlg-figs/terrain.svg +0 -1
  269. package/docs/archive/investigations/hlg-report.html +0 -262
  270. package/docs/archive/investigations/hlg-runs/hlg-ab.json +0 -149
  271. package/docs/archive/investigations/hlg-runs/hlg-blind-prompts.md +0 -87
  272. package/docs/archive/investigations/hlg-runs/hlg-blind.json +0 -107
  273. package/docs/archive/investigations/hlg-runs/hlg-cliff.json +0 -197
  274. package/docs/archive/investigations/hlg-runs/hlg-cross.json +0 -505
  275. package/docs/archive/investigations/hlg-runs/hlg-edge.json +0 -388
  276. package/docs/archive/investigations/hlg-runs/hlg-eval1.json +0 -25
  277. package/docs/archive/investigations/hlg-runs/hlg-frontier.json +0 -86
  278. package/docs/archive/investigations/hlg-runs/hlg-grid.json +0 -242
  279. package/docs/archive/investigations/hlg-runs/hlg-grid2.json +0 -343
  280. package/docs/archive/investigations/hlg-runs/hlg-lw-coarse.json +0 -110
  281. package/docs/archive/investigations/hlg-runs/hlg-map.json +0 -383
  282. package/docs/archive/investigations/hlg-runs/run0-original.log +0 -159
  283. package/docs/archive/investigations/hlg-runs/runA-recommended.log +0 -131
  284. package/docs/archive/investigations/hlg-runs/runAA-cliff-cpm5.log +0 -26
  285. package/docs/archive/investigations/hlg-runs/runAB-grid2-e4b.log +0 -18
  286. package/docs/archive/investigations/hlg-runs/runAC-peak-e4b-partial.log +0 -25
  287. package/docs/archive/investigations/hlg-runs/runAD-ab-samples.log +0 -8
  288. package/docs/archive/investigations/hlg-runs/runAE-edge-e4b.log +0 -51
  289. package/docs/archive/investigations/hlg-runs/runAF-logit-calibration.log +0 -10
  290. package/docs/archive/investigations/hlg-runs/runAG-eval-config2.log +0 -16
  291. package/docs/archive/investigations/hlg-runs/runB-gain-variants.log +0 -192
  292. package/docs/archive/investigations/hlg-runs/runC-pivots.log +0 -162
  293. package/docs/archive/investigations/hlg-runs/runD-oetf.log +0 -132
  294. package/docs/archive/investigations/hlg-runs/runE-eotf.log +0 -162
  295. package/docs/archive/investigations/hlg-runs/runF-shaper-working.log +0 -86
  296. package/docs/archive/investigations/hlg-runs/runG-shaper-sweep.log +0 -101
  297. package/docs/archive/investigations/hlg-runs/runH-wsweep.log +0 -176
  298. package/docs/archive/investigations/hlg-runs/runI-asweep.log +0 -176
  299. package/docs/archive/investigations/hlg-runs/runJ-knobmap.log +0 -49
  300. package/docs/archive/investigations/hlg-runs/runK-frontier.log +0 -19
  301. package/docs/archive/investigations/hlg-runs/runL-widemap.log +0 -65
  302. package/docs/archive/investigations/hlg-runs/runM-frontier-emb.log +0 -15
  303. package/docs/archive/investigations/hlg-runs/runN-verify.log +0 -116
  304. package/docs/archive/investigations/hlg-runs/runO-frontier-seed5000.log +0 -15
  305. package/docs/archive/investigations/hlg-runs/runP-grid-AxSm.log +0 -15
  306. package/docs/archive/investigations/hlg-runs/runQ-grid-tgW.log +0 -15
  307. package/docs/archive/investigations/hlg-runs/runR-blind-transcript.log +0 -79
  308. package/docs/archive/investigations/hlg-runs/runS-cross-coherence.log +0 -33
  309. package/docs/archive/investigations/hlg-runs/runT-cross-cpm5.log +0 -33
  310. package/docs/archive/investigations/hlg-runs/runU-cross-12b.log +0 -33
  311. package/docs/archive/investigations/hlg-runs/runV-lw-e4b.log +0 -22
  312. package/docs/archive/investigations/hlg-runs/runW-lw-12b.log +0 -22
  313. package/docs/archive/investigations/hlg-runs/runX-lw-cpm5.log +0 -22
  314. package/docs/archive/investigations/hlg-runs/runY-cliff-e4b.log +0 -26
  315. package/docs/archive/investigations/hlg-runs/runZ-cliff-12b.log +0 -26
  316. package/docs/archive/mlx-bun-lab-report.html +0 -275
  317. package/docs/archive/wwdc-mlx-bun.html +0 -848
  318. package/docs/design/adapters-end-to-end.md +0 -205
  319. package/docs/design/batching-perf-path.md +0 -255
  320. package/docs/design/batching-v2-plan.md +0 -529
  321. package/docs/design/bucketing-stage.md +0 -197
  322. package/docs/design/compat-cli-surface-design.md +0 -230
  323. package/docs/design/docs-reorg-plan.md +0 -165
  324. package/docs/design/dspark-serving-program.md +0 -371
  325. package/docs/design/dspark-speculative-decoding.md +0 -318
  326. package/docs/design/grammar-spec-batching-integration.md +0 -301
  327. package/docs/design/memory-inference-path.md +0 -422
  328. package/docs/design/memory-synthesis.md +0 -287
  329. package/docs/design/memory-system.md +0 -237
  330. package/docs/design/mlx-lm-serving-execution-seam.md +0 -81
  331. package/docs/design/mlx-lm-tool-parity-plan.md +0 -545
  332. package/docs/design/omlx-adoption-map.md +0 -98
  333. package/docs/design/orpo-dynamic-lambda.md +0 -220
  334. package/docs/design/orpo-future-enhancements.md +0 -340
  335. package/docs/design/paged-kv-cache.md +0 -214
  336. package/docs/design/parallel-slots.md +0 -567
  337. package/docs/design/parity-tier-dag.md +0 -161
  338. package/docs/design/repo-cleanup-plan.md +0 -231
  339. package/docs/design/runtime-isolation.md +0 -263
  340. package/docs/design/segmented-backward-training.md +0 -543
  341. package/docs/design/spec-decode-larger-targets.md +0 -229
  342. package/docs/design/ssd-kv-cold-tier.md +0 -415
  343. package/docs/design/structured-output.md +0 -484
  344. package/docs/design/tauri-desktop-app.md +0 -127
  345. package/docs/design/the-dreaming-master-plan.md +0 -445
  346. package/docs/design/turboquant-kv.md +0 -235
  347. package/docs/design/turboquant-weights.md +0 -467
  348. package/docs/design/w4a16-compute-precision-spike.md +0 -232
  349. package/docs/design/web-chat-beat-matrix.md +0 -315
  350. package/docs/design/write-pipeline-entity.md +0 -468
  351. package/docs/planning/IDEAS.md +0 -69
  352. package/docs/reference/embedding.md +0 -197
  353. package/docs/reference/features-matrix.md +0 -101
  354. package/docs/reference/orpo-quickstart.md +0 -135
  355. package/src/flags.ts +0 -11
  356. /package/docs/{design → archive/investigations}/colibri-glm52-port.md +0 -0
  357. /package/docs/{planning → archive/planning}/chunk-task-roadmap.md +0 -0
  358. /package/docs/{planning → archive/planning}/curve-sampler-research-plan.md +0 -0
  359. /package/docs/{planning → archive/planning}/memory-docs-and-dag-plan.md +0 -0
  360. /package/docs/{planning → archive/planning}/pi-integration-review.md +0 -0
  361. /package/docs/{planning → archive/planning}/release-notes-v0.2.0.md +0 -0
  362. /package/src/{memory-plan.ts → admission-plan.ts} +0 -0
  363. /package/{docs/archive/investigations → src/serve/assets}/curve-terrain.html +0 -0
  364. /package/{docs/dag → src/serve/assets}/training-inference-map.html +0 -0
@@ -1,42 +0,0 @@
1
- <svg viewBox="0 0 980 560" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="t d" font-family="ui-sans-serif,system-ui,sans-serif">
2
- <title id="t">Curve terrain map</title>
3
- <desc id="d">First-pass terrain of custom log-prob curves. X is mid y at one percent, Y is shoulder y at nine percent, Z is rough diversity delta after junk penalty.</desc>
4
- <rect width="980" height="560" fill="#f7f9fc"/>
5
- <text x="38" y="42" font-size="22" font-weight="700" fill="#172033">Curve Terrain Map</text>
6
- <text x="38" y="65" font-size="12.5" fill="#667085">mlx-community/gemma-4-e4b-it-OptiQ-4bit · N=2 · seed=7300 · default diversity 0.803 · score = diversity delta minus junk penalty</text>
7
- <g transform="translate(250 50)"><path d="M130.0 340.0 L187.5 360.5 L245.0 381.0 L302.5 285.2 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M74.6 315.3 L132.1 340.0 L189.6 360.7 L247.1 327.2 L304.6 276.9 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M23.6 322.2 L81.1 342.7 L138.6 418.5 L196.1 364.9 L253.6 397.3 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M-37.1 235.0 L20.4 255.4 L77.9 300.3 L135.4 324.3 L192.9 343.7 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M-100.0 408.8 L-42.5 364.0 L15.0 348.4 L72.5 318.5 L130.0 339.0 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M130.0 340.0 L74.6 315.3 L23.6 322.2 L-37.1 235.0 L-100.0 408.8 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M187.5 360.5 L132.1 340.0 L81.1 342.7 L20.4 255.4 L-42.5 364.0 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M245.0 381.0 L189.6 360.7 L138.6 418.5 L77.9 300.3 L15.0 348.4 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M302.5 285.2 L247.1 327.2 L196.1 364.9 L135.4 324.3 L72.5 318.5 " fill="none" stroke="#cbd5e1" stroke-width="1"/><path d="M304.6 276.9 L253.6 397.3 L192.9 343.7 L130.0 339.0 " fill="none" stroke="#cbd5e1" stroke-width="1"/><circle cx="-37.1" cy="235.0" r="9.0" fill="rgb(8,145,178)" stroke="white" stroke-width="2">
8
- <title>mid=0.5, shoulder=28, diversity=0.999, score=0.196, junk=0.0%</title></circle><circle cx="20.4" cy="255.4" r="9.0" fill="rgb(8,145,178)" stroke="white" stroke-width="2">
9
- <title>mid=1, shoulder=28, diversity=0.999, score=0.196, junk=0.0%</title></circle><circle cx="304.6" cy="276.9" r="9.0" fill="rgb(8,145,178)" stroke="white" stroke-width="2">
10
- <title>mid=8, shoulder=10, diversity=1.000, score=0.197, junk=0.0%</title></circle><circle cx="302.5" cy="285.2" r="7.8" fill="rgb(17,131,195)" stroke="white" stroke-width="2">
11
- <title>mid=4, shoulder=6, diversity=0.922, score=0.119, junk=0.0%</title></circle><circle cx="77.9" cy="300.3" r="8.4" fill="rgb(12,138,187)" stroke="white" stroke-width="2">
12
- <title>mid=2, shoulder=28, diversity=0.960, score=0.157, junk=0.0%</title></circle><circle cx="74.6" cy="315.3" r="6.1" fill="rgb(29,111,220)" stroke="white" stroke-width="2">
13
- <title>mid=0.5, shoulder=10, diversity=0.806, score=0.003, junk=0.0%</title></circle><circle cx="72.5" cy="318.5" r="9.0" fill="rgb(8,145,178)" stroke="white" stroke-width="2">
14
- <title>mid=4, shoulder=50, diversity=1.000, score=0.197, junk=0.0%</title></circle><circle cx="23.6" cy="322.2" r="6.4" fill="rgb(27,115,216)" stroke="white" stroke-width="2">
15
- <title>mid=0.5, shoulder=16, diversity=0.825, score=0.022, junk=0.0%</title></circle><circle cx="135.4" cy="324.3" r="8.3" fill="rgb(13,137,188)" stroke="white" stroke-width="2">
16
- <title>mid=4, shoulder=28, diversity=0.955, score=0.152, junk=0.0%</title></circle><circle cx="247.1" cy="327.2" r="7.3" fill="rgb(20,125,203)" stroke="white" stroke-width="2">
17
- <title>mid=4, shoulder=10, diversity=0.886, score=0.083, junk=0.0%</title></circle><circle cx="130.0" cy="339.0" r="9.0" fill="rgb(8,145,178)" stroke="white" stroke-width="2">
18
- <title>mid=8, shoulder=50, diversity=1.000, score=0.197, junk=0.0%</title></circle><circle cx="130.0" cy="340.0" r="5.0" fill="rgb(37,99,235)" stroke="white" stroke-width="2">
19
- <title>mid=0.5, shoulder=6, diversity=0.735, score=-0.068, junk=0.0%</title></circle><circle cx="132.1" cy="340.0" r="6.0" fill="rgb(30,110,221)" stroke="white" stroke-width="2">
20
- <title>mid=1, shoulder=10, diversity=0.800, score=-0.003, junk=0.0%</title></circle><circle cx="81.1" cy="342.7" r="6.4" fill="rgb(27,115,216)" stroke="white" stroke-width="2">
21
- <title>mid=1, shoulder=16, diversity=0.825, score=0.022, junk=0.0%</title></circle><circle cx="192.9" cy="343.7" r="8.3" fill="rgb(13,137,187)" stroke="white" stroke-width="2">
22
- <title>mid=8, shoulder=28, diversity=0.956, score=0.153, junk=0.0%</title></circle><circle cx="15.0" cy="348.4" r="7.8" fill="rgb(17,131,195)" stroke="white" stroke-width="2">
23
- <title>mid=2, shoulder=50, diversity=0.919, score=0.116, junk=0.0%</title></circle><circle cx="187.5" cy="360.5" r="5.0" fill="rgb(37,99,235)" stroke="white" stroke-width="2">
24
- <title>mid=1, shoulder=6, diversity=0.735, score=-0.068, junk=0.0%</title></circle><circle cx="189.6" cy="360.7" r="6.0" fill="rgb(30,110,221)" stroke="white" stroke-width="2">
25
- <title>mid=2, shoulder=10, diversity=0.799, score=-0.004, junk=0.0%</title></circle><circle cx="-42.5" cy="364.0" r="6.9" fill="rgb(23,121,208)" stroke="white" stroke-width="2">
26
- <title>mid=1, shoulder=50, diversity=0.861, score=0.058, junk=0.0%</title></circle><circle cx="196.1" cy="364.9" r="6.8" fill="rgb(24,120,209)" stroke="white" stroke-width="2">
27
- <title>mid=4, shoulder=16, diversity=0.855, score=0.052, junk=0.0%</title></circle><circle cx="245.0" cy="381.0" r="5.0" fill="rgb(37,99,235)" stroke="white" stroke-width="2">
28
- <title>mid=2, shoulder=6, diversity=0.735, score=-0.068, junk=0.0%</title></circle><circle cx="253.6" cy="397.3" r="6.5" fill="rgb(26,116,213)" stroke="white" stroke-width="2">
29
- <title>mid=8, shoulder=16, diversity=0.836, score=0.033, junk=0.0%</title></circle><circle cx="-100.0" cy="408.8" r="5.3" fill="rgb(35,103,230)" stroke="white" stroke-width="2">
30
- <title>mid=0.5, shoulder=50, diversity=0.767, score=-0.047, junk=0.1%</title></circle><circle cx="138.6" cy="418.5" r="5.0" fill="rgb(37,99,235)" stroke="white" stroke-width="2">
31
- <title>mid=2, shoulder=16, diversity=0.736, score=-0.067, junk=0.0%</title></circle></g>
32
- <g transform="translate(38 420)">
33
- <text x="0" y="0" font-size="14" font-weight="700" fill="#172033">Highest first-pass cells</text><text x="0" y="24" font-size="12.5" fill="#344054">1. mid 8, shoulder 50 · diversity 1.000 · score 0.197 · junk 0.0%</text><text x="0" y="46" font-size="12.5" fill="#344054">2. mid 4, shoulder 50 · diversity 1.000 · score 0.197 · junk 0.0%</text><text x="0" y="68" font-size="12.5" fill="#344054">3. mid 8, shoulder 10 · diversity 1.000 · score 0.197 · junk 0.0%</text><text x="0" y="90" font-size="12.5" fill="#344054">4. mid 1, shoulder 28 · diversity 0.999 · score 0.196 · junk 0.0%</text><text x="0" y="112" font-size="12.5" fill="#344054">5. mid 0.5, shoulder 28 · diversity 0.999 · score 0.196 · junk 0.0%</text></g>
34
- <g transform="translate(742 420)">
35
- <rect x="0" y="-18" width="170" height="12" fill="url(#grad)"/>
36
- <defs><linearGradient id="grad"><stop offset="0" stop-color="#2563eb"/><stop offset="1" stop-color="#0891b2"/></linearGradient></defs>
37
- <text x="0" y="10" font-size="11.5" fill="#667085">low score</text>
38
- <text x="112" y="10" font-size="11.5" fill="#667085">high score</text>
39
- <text x="0" y="34" font-size="11.5" fill="#667085">red points would indicate junk penalty</text>
40
- </g>
41
- <text x="526" y="528" text-anchor="middle" font-size="12" fill="#667085">x: mid y@1% · y: shoulder y@9% · z: rough terrain score</text>
42
- </svg>
@@ -1,34 +0,0 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8">
2
- <meta name="viewport" content="width=device-width,initial-scale=1"><title>HLG A/B samples</title><style>
3
- :root{--text:#1f2937;--text2:#475569;--text3:#94a3b8;--bg:#f7f9fc;--card:#fff;--bd:#e2e8f0;--grid:#f1f5f9}
4
- *{box-sizing:border-box}
5
- body{margin:0;background:var(--bg);color:var(--text);font:15px/1.6 -apple-system,BlinkMacSystemFont,"Segoe UI",ui-sans-serif,system-ui,sans-serif;-webkit-font-smoothing:antialiased}
6
- .wrap{max-width:1240px;margin:0 auto;padding:34px 22px 100px}
7
- h1{font-size:25px;margin:0 0 3px;letter-spacing:-.02em}
8
- .sub{color:var(--text2);font-size:14.5px;max-width:780px;margin:0 0 8px}
9
- .legend{display:flex;flex-wrap:wrap;gap:14px;margin:14px 0 26px;font-size:13px}
10
- .legend .c{display:flex;gap:8px;align-items:baseline;background:var(--card);border:1px solid var(--bd);border-radius:10px;padding:8px 13px}
11
- .legend .dot{width:10px;height:10px;border-radius:3px;flex:none;position:relative;top:1px}
12
- .legend b{font-weight:700}.legend .d{color:var(--text3);font-size:12px}
13
- .card{background:var(--card);border:1px solid var(--bd);border-radius:14px;padding:18px 20px;margin:0 0 20px;box-shadow:0 1px 2px rgba(15,23,42,.04),0 10px 30px -24px rgba(15,23,42,.2)}
14
- .q{font-size:12px;text-transform:uppercase;letter-spacing:.06em;color:var(--text3);font-weight:700}
15
- .qt{font-size:16px;font-weight:600;margin:3px 0 16px}
16
- .cols{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
17
- @media(max-width:900px){.cols{grid-template-columns:1fr}}
18
- .col h3{font-size:13px;margin:0 0 9px;display:flex;align-items:center;gap:8px}
19
- .col h3 .dot{width:9px;height:9px;border-radius:3px}
20
- .col h3 .d{font-weight:400;color:var(--text3);font-size:11.5px}
21
- .samp{font-size:13.5px;color:#0f172a;background:var(--grid);border-radius:9px;padding:9px 11px;margin:0 0 8px;border-left:3px solid transparent}
22
- .samp .n{color:var(--text3);font-weight:700;font-size:11px;margin-right:6px}
23
- .note{font-size:13px;color:var(--text3);margin-top:28px;border-top:1px solid var(--bd);padding-top:14px}
24
- </style></head>
25
- <body><div class="wrap">
26
- <h1>HLG sampling — side-by-side samples</h1>
27
- <p class="sub">The same prompts, sampled three ways on <b>gemma-4-e4b-it-OptiQ-4bit</b> (3 samples each, fixed seeds). Only the
28
- sampling method changes. Read down a column to feel each sampler's character; read across to compare on one prompt.</p>
29
- <div class="legend"><div class="c"><span class="dot" style="background:#64748b"></span><div><b>Default recipe</b> &nbsp;<span class="d">the model's recommended sampler — T=1, top-p=0.95, top-k=64</span></div></div><div class="c"><span class="dot" style="background:#2563eb"></span><div><b>HLG base</b> &nbsp;<span class="d">A=0.35, s_m=0.7, target_gap=15, W=6</span></div></div><div class="c"><span class="dot" style="background:#0891b2"></span><div><b>HLG loose-A</b> &nbsp;<span class="d">A=0.01 (the diversity-leaning shoulder), rest as base</span></div></div></div>
30
- <div class="card"><div class="q">creative</div><div class="qt">Write the first sentence of a short story about a lighthouse keeper who discovers something strange in the fog.</div><div class="cols"><div class="col"><h3><span class="dot" style="background:#64748b"></span>Default recipe<span class="d">A</span></h3><div class="samp" style="border-left-color:#64748b"><span class="n">1</span>The fog, a thick, greasy blanket that clung to the granite tower like a shroud, always held secrets, but this morning, it delivered something far stranger than the usual drift of unseen seabirds.</div><div class="samp" style="border-left-color:#64748b"><span class="n">2</span>The thick, soupy fog that perpetually hugged the granite tower seemed to thicken further that night, muffling the roar of the ocean until it felt less like the sea and more like a vast, wet sigh, and then he saw it—a perfectly smooth, obsidian sphere bobbing just beyond the reach of his lantern beam.</div><div class="samp" style="border-left-color:#64748b"><span class="n">3</span>The fog, a thick, clammy shroud clinging to the granite tower, seemed to pulse with an unnatural life as Silas scanned the churning grey expanse.</div></div><div class="col"><h3><span class="dot" style="background:#2563eb"></span>HLG base<span class="d">B</span></h3><div class="samp" style="border-left-color:#2563eb"><span class="n">1</span>The fog, a thick, clammy blanket that swallowed the beam of the lamp, usually brought with it the familiar scent of salt and damp stone, but tonight, a faint, metallic tang drifted in, something utterly alien against the backdrop of the churning grey.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">2</span>The fog, a thick, clammy blanket that swallowed the beam of the old tower, pressed against Silas’s windowpane, and it was in that suffocating grey that he first saw the impossible.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">3</span>The fog, a thick, clammy shroud that swallowed the horizon whole, seemed to press against the glass of the lantern room, and it was in that oppressive whiteness that Silas first saw the impossible flicker.</div></div><div class="col"><h3><span class="dot" style="background:#0891b2"></span>HLG loose-A<span class="d">C</span></h3><div class="samp" style="border-left-color:#0891b2"><span class="n">1</span>The fog, a thick, milky blanket that clung to the granite cliffs like wet wool, always held secrets, but this evening, something decidedly out of place drifted through its milky shroud.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">2</span>The relentless, clinging fog had been his only constant companion for three lonely weeks, until tonight, when a splash of unnatural emerald light pierced the milky grey swirling just beyond the tower's narrow beam.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">3</span>The thick, soupy fog that clung to the coast had been a familiar, monotonous blanket for Elias for three years, but this morning, something broke through it.</div></div></div></div><div class="card"><div class="q">continuation</div><div class="qt">Complete this thought in a vivid, original way: 'The strangest thing about human memory is'</div><div class="cols"><div class="col"><h3><span class="dot" style="background:#64748b"></span>Default recipe<span class="d">A</span></h3><div class="samp" style="border-left-color:#64748b"><span class="n">1</span>'The strangest thing about human memory is **how it doesn't archive life; it remixes it.** It’s less a library and more a chaotic, brilliant tapestry where the scent of old rain from a childhood picnic might instantly trigger the bittersweet ache of a grief felt last week, seamlessly weaving the textures of two entirely different selves into a single, shimmering, unreliable present.'</div><div class="samp" style="border-left-color:#64748b"><span class="n">2</span>'The strangest thing about human memory is **how it doesn't catalog events, but rather *re-forges* them—a warm, unreliable tapestry woven from the brilliant threads of feeling, the frayed edges of suggestion, and the perfectly smooth, utterly fictional comfort of what we desperately wish had happened.**'</div><div class="samp" style="border-left-color:#64748b"><span class="n">3</span>'The strangest thing about human memory is **how it feels less like a recording and more like an act of tireless, beautiful, and often treacherous reconstruction.** It's not a dusty film reel; it's a restless alchemist's laboratory, where yesterday's sunlight is re-mixed with today's doubt, and the ghosts of forgotten moments shimmer into the present, always slightly rearranged, always colored by the urgent, vibrant necessity</div></div><div class="col"><h3><span class="dot" style="background:#2563eb"></span>HLG base<span class="d">B</span></h3><div class="samp" style="border-left-color:#2563eb"><span class="n">1</span>'The strangest thing about human memory is **how it doesn't archive; it *re-weaves*. It’s not a library where you pull a perfect volume from the shelf, but a loom where every recollection is re-threaded with the anxieties, the triumphs, and the sheer, messy passage of time, making the past less a fixed photograph and more a perpetually shifting, emotionally charged watercolor.**'</div><div class="samp" style="border-left-color:#2563eb"><span class="n">2</span>'The strangest thing about human memory is **how it doesn't archive; it *re-weaves*. It’s not a pristine library of moments, but a tapestry constantly being re-spun by the present, where the sharp edges of yesterday soften, the crucial details bleed into the background noise, and the emotional resonance of a forgotten Tuesday can suddenly bloom with the blinding, illogical clarity of a perfect, remembered sunset.**'</div><div class="samp" style="border-left-color:#2563eb"><span class="n">3</span>'The strangest thing about human memory is **how it doesn't archive events; it *re-weaves* them, a tapestry where the scent of rain from a childhood summer can suddenly bleed into the sharp, metallic tang of a present-day anxiety, making us believe we are recalling a perfect moment when, in reality, we are just listening to the echo of a feeling.**'</div></div><div class="col"><h3><span class="dot" style="background:#0891b2"></span>HLG loose-A<span class="d">C</span></h3><div class="samp" style="border-left-color:#0891b2"><span class="n">1</span>'The strangest thing about human memory is **how it acts like a kaleidoscope of forgotten dreams, capable of reassembling a perfect, polished vista of a past moment—a scent, the slant of light through a childhood window, the exact timbre of a forgotten argument—only to reveal, upon closer inspection, that the very foundation of that flawless image is made of shimmering, ill-fitting glass.**'</div><div class="samp" style="border-left-color:#0891b2"><span class="n">2</span>'The strangest thing about human memory is **how it doesn't catalog the past like a library, but rather re-authors it in the dusty, flickering spotlight of the present, leaving behind echoes of who we were, rather than the immutable blueprint of what actually occurred.**'</div><div class="samp" style="border-left-color:#0891b2"><span class="n">3</span>'The strangest thing about human memory is **how it acts less like a meticulously filed archive, and more like a perpetually haunted attic—a chaotic, dust-mote-filled space where forgotten sunlight sometimes illuminates a moment with such blinding, visceral clarity that you can still smell the rain on the cobblestones of a life you've long since left behind.**'</div></div></div></div><div class="card"><div class="q">factual</div><div class="qt">In one sentence, what causes the seasons on Earth?</div><div class="cols"><div class="col"><h3><span class="dot" style="background:#64748b"></span>Default recipe<span class="d">A</span></h3><div class="samp" style="border-left-color:#64748b"><span class="n">1</span>The seasons on Earth are caused by the tilt of the planet's axis as it revolves around the Sun.</div><div class="samp" style="border-left-color:#64748b"><span class="n">2</span>The Earth's tilt on its axis as it revolves around the Sun is what causes the seasons.</div><div class="samp" style="border-left-color:#64748b"><span class="n">3</span>The Earth's axial tilt of approximately 23.5 degrees as it orbits the sun causes the changing seasons.</div></div><div class="col"><h3><span class="dot" style="background:#2563eb"></span>HLG base<span class="d">B</span></h3><div class="samp" style="border-left-color:#2563eb"><span class="n">1</span>The seasons on Earth are caused by the tilt of the Earth's axis as it revolves around the Sun.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">2</span>The seasons on Earth are caused by the tilt of the planet's axis as it revolves around the Sun.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">3</span>The Earth's axial tilt, combined with its revolution around the Sun, causes the changing seasons.</div></div><div class="col"><h3><span class="dot" style="background:#0891b2"></span>HLG loose-A<span class="d">C</span></h3><div class="samp" style="border-left-color:#0891b2"><span class="n">1</span>The seasons on Earth are caused by the tilt of the planet's axis as it revolves around the Sun.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">2</span>The Earth's tilt on its axis combined with its revolution around the Sun causes the changing seasons.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">3</span>The Earth's axial tilt of approximately 23.5 degrees combined with its orbit around the sun is what causes the seasons.</div></div></div></div><div class="card"><div class="q">explain</div><div class="qt">Explain in two sentences why the sky is blue.</div><div class="cols"><div class="col"><h3><span class="dot" style="background:#64748b"></span>Default recipe<span class="d">A</span></h3><div class="samp" style="border-left-color:#64748b"><span class="n">1</span>The sky appears blue because of a phenomenon called Rayleigh scattering, where the Earth's atmosphere scatters shorter, blue-wavelength sunlight more effectively than longer, red wavelengths. This scattered blue light reaches our eyes from all directions, making the sky look blue.</div><div class="samp" style="border-left-color:#64748b"><span class="n">2</span>The sky appears blue because of a phenomenon called Rayleigh scattering. Sunlight, when entering the Earth's atmosphere, is scattered by nitrogen and oxygen molecules, with the shorter, blue wavelengths being scattered more effectively in all directions.</div><div class="samp" style="border-left-color:#64748b"><span class="n">3</span>The sky appears blue because of a phenomenon called Rayleigh scattering. This causes shorter, blue wavelengths of sunlight to be scattered more effectively by the molecules in the Earth's atmosphere than longer, red wavelengths.</div></div><div class="col"><h3><span class="dot" style="background:#2563eb"></span>HLG base<span class="d">B</span></h3><div class="samp" style="border-left-color:#2563eb"><span class="n">1</span>The sky appears blue because of a phenomenon called Rayleigh scattering. This process causes shorter, blue wavelengths of sunlight to be scattered more effectively by the molecules in the Earth's atmosphere than longer, redder wavelengths.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">2</span>The sky appears blue because of a phenomenon called Rayleigh scattering. This occurs when sunlight enters the Earth's atmosphere and its shorter, blue-wavelength light is scattered more effectively by the tiny molecules of the atmosphere than the longer, redder wavelengths.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">3</span>The sky appears blue because of a phenomenon called Rayleigh scattering. This process causes shorter, blue wavelengths of sunlight to be scattered more effectively by the molecules in the Earth's atmosphere than longer, red wavelengths.</div></div><div class="col"><h3><span class="dot" style="background:#0891b2"></span>HLG loose-A<span class="d">C</span></h3><div class="samp" style="border-left-color:#0891b2"><span class="n">1</span>The sky appears blue because of a phenomenon called Rayleigh scattering, where molecules of oxygen and nitrogen in the atmosphere scatter shorter, higher-energy blue wavelengths of sunlight more effectively than longer wavelengths. This scattering effect spreads the blue light across the entire sky, making it appear blue to our eyes.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">2</span>The sky appears blue because of a phenomenon called Rayleigh scattering. This scattering of sunlight by the Earth's atmosphere preferentially scatters shorter, blue wavelengths of light across the sky in all directions.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">3</span>The sky appears blue because of a phenomenon called Rayleigh scattering. This causes shorter, blue wavelengths of sunlight to be scattered more effectively by the molecules in the Earth's atmosphere than longer, red wavelengths.</div></div></div></div><div class="card"><div class="q">lateral</div><div class="qt">Give one unusual but genuinely plausible use for a paperclip, in a sentence.</div><div class="cols"><div class="col"><h3><span class="dot" style="background:#64748b"></span>Default recipe<span class="d">A</span></h3><div class="samp" style="border-left-color:#64748b"><span class="n">1</span>A tightly rolled paperclip can serve as a surprisingly effective, miniature shim to stabilize a slightly wobbly piece of delicate electronic equipment.</div><div class="samp" style="border-left-color:#64748b"><span class="n">2</span>A sturdy paperclip could be fashioned into a temporary, improvised fishing hook to snag small aquatic life during an emergency outing.</div><div class="samp" style="border-left-color:#64748b"><span class="n">3</span>A paperclip can be bent into a surprisingly effective, miniature fishing hook for retrieving small, lost items from narrow crevices.</div></div><div class="col"><h3><span class="dot" style="background:#2563eb"></span>HLG base<span class="d">B</span></h3><div class="samp" style="border-left-color:#2563eb"><span class="n">1</span>A paperclip could be bent into a makeshift, temporary hook to retrieve a dropped earring from a narrow drain.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">2</span>A paperclip could be meticulously straightened and used as a temporary, fine-gauge shim to level a slightly wobbly antique picture frame.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">3</span>A paperclip could be bent into a makeshift, temporary antenna to boost a weak radio signal during an outdoor emergency.</div></div><div class="col"><h3><span class="dot" style="background:#0891b2"></span>HLG loose-A<span class="d">C</span></h3><div class="samp" style="border-left-color:#0891b2"><span class="n">1</span>A paperclip could be bent into a miniature, temporary hook to retrieve a dropped earring from a tight spot behind a piece of furniture.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">2</span>A paperclip, carefully bent, can serve as a makeshift, temporary shim to level a slightly uneven tripod leg on a camera in a pinch.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">3</span>A paperclip can be bent into a surprisingly effective, albeit makeshift, reset pin for a jammed electronic device.</div></div></div></div><div class="card"><div class="q">voice</div><div class="qt">Describe the feeling of a city at 3am in one vivid sentence.</div><div class="cols"><div class="col"><h3><span class="dot" style="background:#64748b"></span>Default recipe<span class="d">A</span></h3><div class="samp" style="border-left-color:#64748b"><span class="n">1</span>The city at 3 am hums with a spectral energy, a mélange of distant sirens, the rhythmic sigh of cooling concrete, and the isolated echoes of late-night human solitude.</div><div class="samp" style="border-left-color:#64748b"><span class="n">2</span>The city at 3 am hums with a skeletal, phosphorescent energy, a vast, tired beast breathing slowly between the last echoes of the day's clamor and the relentless arrival of dawn.</div><div class="samp" style="border-left-color:#64748b"><span class="n">3</span>The city breathes a ragged, neon-streaked sigh of lonely industry, a vast, half-asleep beast illuminated by the spectral glow of forgotten streetlights.</div></div><div class="col"><h3><span class="dot" style="background:#2563eb"></span>HLG base<span class="d">B</span></h3><div class="samp" style="border-left-color:#2563eb"><span class="n">1</span>The city at 3 am is a vast, hushed beast, exhaling the metallic scent of cooling asphalt under the lonely, sodium-orange glow of forgotten streetlights.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">2</span>The city at 3 am is a vast, humming beast, exhaling the cool, metallic scent of asphalt and the lonely, rhythmic sigh of distant sirens against a backdrop of deep, bruised indigo.</div><div class="samp" style="border-left-color:#2563eb"><span class="n">3</span>The city at 3 am is a vast, breathing beast, its neon veins pulsing with the ghosts of late-night revelers and the low, rhythmic hum of the sleeping concrete.</div></div><div class="col"><h3><span class="dot" style="background:#0891b2"></span>HLG loose-A<span class="d">C</span></h3><div class="samp" style="border-left-color:#0891b2"><span class="n">1</span>The city at 3 am hums with a solitary, neon-drenched exhaustion, a low thrum of secrets and forgotten sirens weaving through the skeletal geometry of sleeping giants.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">2</span>The city at 3 am hums with a skeletal, phosphorescent energy, a vast, hushed beast whose only movements are the lonely sweep of headlights across slick asphalt and the distant, rhythmic sigh of the ventilation units.</div><div class="samp" style="border-left-color:#0891b2"><span class="n">3</span>The city breathes a humid, neon-tinged quiet, a skeletal monument to forgotten daytime revelry under a velvet-black sky.</div></div></div></div>
31
- <p class="note">Generated by <code>scripts/hlg-ab.ts</code> → <code>scripts/hlg-ab-html.ts</code>. Notice how <b>HLG base</b> tends to
32
- converge on a single strong continuation (lower diversity — the tight shoulder concentrates on the high-probability path), while
33
- <b>HLG loose-A</b> spreads out — the same behavior the diversity sweeps measured, here in plain text.</p>
34
- </div></body></html>
@@ -1,238 +0,0 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8">
2
- <meta name="viewport" content="width=device-width,initial-scale=1">
3
- <title>HLG Sampling Explorer — real logits</title>
4
- <style>
5
- :root{--text:#1f2937;--text2:#475569;--text3:#94a3b8;--bg:#f7f9fc;--card:#fff;--bd:#e2e8f0;
6
- --accent:#2563eb;--accent2:#0891b2;--pos:#16a34a;--warn:#d97706;--danger:#dc2626;--grid:#eef2f7;--gray:#94a3b8;}
7
- *{box-sizing:border-box}
8
- html,body{height:100%;margin:0;overflow:hidden}
9
- body{background:var(--bg);color:var(--text);font:13px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI",ui-sans-serif,system-ui,sans-serif;-webkit-font-smoothing:antialiased}
10
- .app{height:100vh;display:grid;grid-template-columns:minmax(380px,42%) 1fr;gap:14px;padding:14px}
11
- .panel{background:var(--card);border:1px solid var(--bd);border-radius:12px;padding:12px 14px;box-shadow:0 1px 2px rgba(15,23,42,.04),0 10px 30px -24px rgba(15,23,42,.2);min-height:0;overflow:auto}
12
- .controls{display:flex;flex-direction:column}
13
- h1{font-size:15px;margin:0;letter-spacing:-.01em}
14
- .topbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:7px}
15
- .presets{display:flex;flex-wrap:wrap;gap:5px;margin-left:auto}
16
- .presets button{font:600 11px/1 inherit;padding:6px 9px;border:1px solid var(--bd);background:var(--card);border-radius:7px;cursor:pointer;color:var(--text2)}
17
- .presets button:hover{border-color:var(--accent);color:var(--accent)}
18
- .presets button.reset{color:var(--danger);border-color:#f3d6d6}
19
- .presets button.copy{background:var(--accent);color:#fff;border-color:var(--accent)}
20
- .distsel{display:flex;gap:5px;margin-bottom:8px;flex-wrap:wrap}
21
- .distsel button{font:600 11px/1 inherit;padding:6px 9px;border:1px solid var(--bd);background:var(--grid);border-radius:7px;cursor:pointer;color:var(--text2)}
22
- .distsel button.on{background:var(--accent);color:#fff;border-color:var(--accent)}
23
- .copyrow{display:flex;gap:6px;align-items:center;margin-bottom:9px}
24
- .copyrow input{flex:1;font:11px/1.3 ui-monospace,SFMono-Regular,Menlo,monospace;border:1px solid var(--bd);border-radius:7px;padding:6px 8px;background:var(--grid);color:#0f172a}
25
- .copyrow .ok{font-size:11px;font-weight:700;color:var(--pos);min-width:46px}
26
- .grid2{display:grid;grid-template-columns:1fr 1fr;gap:6px 16px;align-content:start}
27
- .gh{grid-column:1/-1;font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text3);margin:6px 0 0;border-top:1px solid var(--bd);padding-top:7px}
28
- .gh:first-child{border-top:none;padding-top:0;margin-top:0}
29
- .cell label{display:flex;justify-content:space-between;align-items:baseline;font-size:11.5px;font-weight:600;gap:6px}
30
- .cell label .v{font-weight:700;color:var(--accent);font-variant-numeric:tabular-nums;font-size:12px}
31
- .cell input[type=range]{width:100%;accent-color:var(--accent);height:16px;cursor:pointer;margin:1px 0 0}
32
- .figs{display:flex;flex-direction:column;gap:8px}
33
- .figs .panel{padding:8px 12px}
34
- .fh{font-size:10px;text-transform:uppercase;letter-spacing:.06em;color:var(--text2);font-weight:700;margin:0 0 2px}
35
- .fh small{font-weight:400;text-transform:none;letter-spacing:0;color:var(--text3)}
36
- svg{width:100%;height:auto;display:block}
37
- .legend{display:flex;gap:13px;flex-wrap:wrap;font-size:10.5px;color:var(--text2);margin-top:3px}
38
- .legend span{display:inline-flex;align-items:center;gap:5px}.legend i{width:14px;height:3px;border-radius:2px;display:inline-block}
39
- .readouts{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin-top:6px}
40
- .ro{background:var(--grid);border-radius:7px;padding:5px 8px}
41
- .ro .k{font-size:9px;text-transform:uppercase;letter-spacing:.04em;color:var(--text3)}
42
- .ro .val{font-size:14px;font-weight:700;font-variant-numeric:tabular-nums}
43
- @media(max-width:820px){.app{grid-template-columns:1fr;height:auto;overflow:auto}html,body{overflow:auto}}
44
- </style></head>
45
- <body>
46
- <div class="app">
47
- <div class="panel controls">
48
- <div class="topbar"><h1>HLG Explorer · real logits</h1>
49
- <div class="presets">
50
- <button data-preset="base">Base</button><button data-preset="loose">Loose-A</button>
51
- <button data-preset="sharp">Sharp</button><button data-preset="base" class="reset">Reset</button>
52
- <button id="copyBtn" class="copy">Copy Values</button>
53
- </div>
54
- </div>
55
- <div class="distsel" id="distsel"></div>
56
- <div class="copyrow"><input id="cfgField" readonly spellcheck="false"><span class="ok" id="copyOk"></span></div>
57
- <div class="grid2" id="grid"></div>
58
- </div>
59
- <div class="figs">
60
- <div class="panel">
61
- <div class="fh">Transfer curve <small>· real tokens mapped on by their logits — watch them pile into the toe</small></div>
62
- <div id="curve"></div>
63
- <div class="legend"><span><i style="background:var(--accent)"></i>OETF</span><span><i style="background:var(--accent2)"></i>after γ</span><span><i style="background:var(--text3)"></i>temp (linear)</span><span><i style="background:var(--warn);height:8px;width:8px;border-radius:50%"></i>tokens</span></div>
64
- <div class="readouts" id="readouts"></div>
65
- </div>
66
- <div class="panel">
67
- <div class="fh">Distribution over the full 262k vocab <small>· x = rank (log) · y = probability (log)</small></div>
68
- <div id="dist"></div>
69
- <div class="legend"><span><i style="background:var(--gray)"></i>raw softmax</span><span><i style="background:var(--pos)"></i>default recipe (top-p·top-k)</span><span><i style="background:var(--accent)"></i>HLG</span><span><i style="background:var(--warn);height:9px;width:2px"></i>W reaches here</span></div>
70
- <div class="readouts" id="distro"></div>
71
- </div>
72
- </div>
73
- </div>
74
-
75
- <script src="hlg-figs/hlg-logits.js"></script>
76
- <script>
77
- const DISTS = (window.REAL_LOGITS||[]).map(d=>({...d, sorted:Float64Array.from(d.sorted)}));
78
- let di = DISTS.length? DISTS.findIndex(d=>d.tag==="creative") : -1; if(di<0) di=0;
79
-
80
- const DEF = { window:8, A:0.35, sM:0.7, targetGap:15, refGap:4, lw:1200, xM:0.55, yM:0.5, xFloor:0.2, yFloor:0.18, p:2.0, T:1.0, topP:0.95, topK:64 };
81
- const PRESETS = { base:{...DEF}, loose:{...DEF,A:0.01}, sharp:{...DEF,targetGap:40,sM:2.0,A:0.2} };
82
- const P = {...DEF};
83
-
84
- const GROUPS = [
85
- {h:"HLG — primary", items:[
86
- {k:"window",label:"W — window (nats)",min:1,max:40,step:0.5},
87
- {k:"A",label:"A — shoulder",min:0.01,max:5,step:0.01},
88
- {k:"sM",label:"s_m — mid slope",min:0.05,max:6,step:0.05},
89
- {k:"targetGap",label:"target_gap",min:4,max:50,step:1},
90
- {k:"lw",label:"L_W (γ)",min:0,max:6,step:0.02,log:true},
91
- {k:"refGap",label:"refGap",min:1,max:20,step:0.5},
92
- ]},
93
- {h:"HLG — geometry", items:[
94
- {k:"xM",label:"x_M",min:0.3,max:0.8,step:0.01},{k:"yM",label:"y_M",min:0.3,max:0.7,step:0.01},
95
- {k:"xFloor",label:"x_floor",min:0.05,max:0.45,step:0.01},{k:"yFloor",label:"y_floor",min:0.05,max:0.45,step:0.01},
96
- {k:"p",label:"p — mid power",min:1.2,max:4,step:0.05},
97
- ]},
98
- {h:"Default recipe (the standard sampler)", items:[
99
- {k:"T",label:"temperature",min:0.1,max:2,step:0.05},{k:"topP",label:"top-p",min:0.1,max:1,step:0.01},{k:"topK",label:"top-k",min:1,max:512,step:1},
100
- ]},
101
- ];
102
- const ALL = GROUPS.flatMap(g=>g.items);
103
- const lwToS=lw=>Math.log10(lw), sToLw=s=>Math.pow(10,s);
104
-
105
- function buildGrid(){
106
- const c=document.getElementById("grid"); c.innerHTML="";
107
- for(const g of GROUPS){ const h=document.createElement("div"); h.className="gh"; h.textContent=g.h; c.appendChild(h);
108
- for(const s of g.items){ const d=document.createElement("div"); d.className="cell";
109
- d.innerHTML=`<label>${s.label}<span class="v" id="v_${s.k}"></span></label><input type="range" id="s_${s.k}" min="${s.min}" max="${s.max}" step="${s.step}" value="${s.log?lwToS(P[s.k]):P[s.k]}">`;
110
- c.appendChild(d);
111
- d.querySelector("input").addEventListener("input",e=>{P[s.k]=s.log?sToLw(parseFloat(e.target.value)):parseFloat(e.target.value); render();});
112
- }
113
- }
114
- }
115
- function buildDistSel(){
116
- const c=document.getElementById("distsel"); c.innerHTML="";
117
- if(!DISTS.length){ c.innerHTML='<span style="color:var(--danger);font-size:11px">hlg-logits.js not loaded — run scripts/hlg-capture-logits.ts</span>'; return; }
118
- DISTS.forEach((d,i)=>{ const b=document.createElement("button"); b.textContent=`${d.tag} · ${d.entropyBits}b`; if(i===di)b.className="on";
119
- b.addEventListener("click",()=>{di=i; buildDistSel(); prep(); render();}); c.appendChild(b); });
120
- }
121
-
122
- // ---- shaper ----
123
- function geom(){
124
- const {xM,yM,xFloor,yFloor,p,sM,A,lw,window:W,targetGap,refGap}=P;
125
- const dxf=xM-xFloor, kc=(yM-sM*dxf-yFloor)/Math.pow(dxf,p), sFloor=sM+kc*p*Math.pow(dxf,p-1);
126
- const det=-Math.pow(xFloor,4), ec=(yFloor*2*xFloor-xFloor*xFloor*sFloor)/det, fc=(Math.pow(xFloor,3)*sFloor-yFloor*3*xFloor*xFloor)/det;
127
- const yPeak=yM+A*Math.log(1+(sM/A)*(1-xM)), gamma=1.2+0.42*Math.log10(Math.max(lw,1e-3)/1000);
128
- const oetfS=x=>{let y; if(x>=xM)y=yM+A*Math.log(Math.max(1+(sM/A)*(x-xM),1e-9)); else if(x>=xFloor)y=yM-sM*(xM-x)-kc*Math.pow(Math.max(xM-x,0),p); else y=ec*x*x*x+fc*x*x; return Math.max(y,0);};
129
- const shapeS=x=>Math.pow(Math.max(oetfS(x)/yPeak,1e-9),gamma);
130
- const xRef=Math.max(0,Math.min(1,1-refGap/W)), outScale=targetGap/Math.max(1e-6,1-shapeS(xRef));
131
- return {gamma,yPeak,outScale,xRef,oetfS,shapeS};
132
- }
133
-
134
- // ---- per-distribution prep ----
135
- let D=null;
136
- function logsumexp(arr,n){ let m=-1e30; for(let i=0;i<n;i++) if(arr[i]>m)m=arr[i]; let s=0; for(let i=0;i<n;i++) s+=Math.exp(arr[i]-m); return m+Math.log(s); }
137
- function prep(){
138
- if(!DISTS.length){ D=null; return; }
139
- const d=DISTS[di], s=d.sorted, V=s.length, lmax=s[0];
140
- const rawLse=logsumexp(s,V);
141
- // log-spaced sample ranks for rendering (+ dense head)
142
- const ranks=new Set(); for(let i=0;i<64;i++) ranks.add(i);
143
- const N=360, lV=Math.log10(V); for(let i=0;i<=N;i++) ranks.add(Math.min(V-1,Math.round(Math.pow(10,(i/N)*lV))-0+0));
144
- const sr=[...ranks].filter(r=>r<V).sort((a,b)=>a-b);
145
- D={s,V,lmax,rawLse,sr,tag:d.tag,ent:d.entropyBits};
146
- }
147
-
148
- // ---- distribution computations ----
149
- function probsAt(g){
150
- const {s,V,lmax,rawLse,sr}=D, {shapeS,outScale}=g, W=P.window;
151
- // raw
152
- const raw=sr.map(r=>Math.exp(s[r]-rawLse));
153
- // HLG: only tokens within W of top leave the toe; rest are the constant toe value
154
- let inWin=0; const thr=lmax-W; while(inWin<V && s[inWin]>thr) inWin++;
155
- const toeShaped=outScale*shapeS(0);
156
- const shapedOf=r=>{ if(r>=inWin) return toeShaped; const x=Math.max(0,Math.min(1,(s[r]-lmax)/W+1)); return outScale*shapeS(x); };
157
- let mx=toeShaped; for(let i=0;i<inWin;i++){ const v=shapedOf(i); if(v>mx)mx=v; }
158
- let Z=(V-inWin)*Math.exp(toeShaped-mx); for(let i=0;i<inWin;i++) Z+=Math.exp(shapedOf(i)-mx);
159
- const hlgLse=mx+Math.log(Z);
160
- const hlg=sr.map(r=>Math.exp(shapedOf(r)-hlgLse));
161
- // default recipe: temp → full softmax → keep top-p ∩ top-k → renormalize
162
- const T=P.T; const scaled=new Float64Array(V); for(let i=0;i<V;i++) scaled[i]=s[i]/T;
163
- const sLse=T===1?(rawLse):logsumexp(scaled,V);
164
- let cum=0, mset=V; for(let i=0;i<V;i++){ cum+=Math.exp(scaled[i]-sLse); if(cum>=P.topP){ mset=i+1; break; } }
165
- const keep=Math.max(1,Math.min(Math.round(P.topK),mset));
166
- let dZ=logsumexp(scaled.subarray(0,keep),keep);
167
- const def=sr.map(r=>r<keep?Math.exp(scaled[r]-dZ):0);
168
- return {raw,hlg,def,inWin,keep,hlgTop1:Math.exp(shapedOf(0)-hlgLse)};
169
- }
170
-
171
- // ---- curve panel ----
172
- const CW=560,CH=210,ML=42,MR=14,MT=15,MB=30;
173
- const cx=x=>ML+x*(CW-ML-MR), cy=(y,ym)=>MT+(1-y/ym)*(CH-MT-MB);
174
- const poly=(fn,ym,n=140)=>{let d="";for(let i=0;i<=n;i++){const x=i/n;d+=(i?"L":"M")+cx(x).toFixed(1)+" "+cy(fn(x),ym).toFixed(1)+" ";}return d;};
175
- function drawCurve(g){
176
- const {oetfS,yPeak,shapeS}=g, oetfN=x=>Math.max(0,oetfS(x)/yPeak);
177
- let ym=1; for(let i=0;i<=140;i++){const x=i/140; ym=Math.max(ym,oetfN(x),shapeS(x));} ym=Math.min(ym,8);
178
- let s=`<svg viewBox="0 0 ${CW} ${CH}" font-family="inherit">`;
179
- s+=`<rect x="${cx(0)}" y="${MT}" width="${cx(P.xFloor)-cx(0)}" height="${CH-MT-MB}" fill="#fde2e2" opacity=".5"/><rect x="${cx(P.xFloor)}" y="${MT}" width="${cx(P.xM)-cx(P.xFloor)}" height="${CH-MT-MB}" fill="#fff3d6" opacity=".5"/><rect x="${cx(P.xM)}" y="${MT}" width="${cx(1)-cx(P.xM)}" height="${CH-MT-MB}" fill="#dcfce7" opacity=".5"/>`;
180
- s+=`<text x="${(cx(0)+cx(P.xFloor))/2}" y="${MT+11}" text-anchor="middle" font-size="9" fill="#b91c1c">toe</text><text x="${(cx(P.xFloor)+cx(P.xM))/2}" y="${MT+11}" text-anchor="middle" font-size="9" fill="#92400e">mid</text><text x="${(cx(P.xM)+cx(1))/2}" y="${MT+11}" text-anchor="middle" font-size="9" fill="#166534">shoulder</text>`;
181
- for(let f=0;f<=1.0001;f+=0.25){const yv=f*ym; s+=`<line x1="${ML}" y1="${cy(yv,ym)}" x2="${CW-MR}" y2="${cy(yv,ym)}" stroke="var(--grid)"/>`;}
182
- s+=`<line x1="${cx(0)}" y1="${cy(0,ym)}" x2="${cx(1)}" y2="${cy(1,ym)}" stroke="var(--text3)" stroke-width="1.3" stroke-dasharray="5 4"/>`;
183
- for(const xv of [P.xFloor,P.xM]) s+=`<line x1="${cx(xv)}" y1="${MT}" x2="${cx(xv)}" y2="${CH-MB}" stroke="var(--text3)" stroke-dasharray="2 3" opacity=".6"/>`;
184
- s+=`<path d="${poly(oetfN,ym)}" fill="none" stroke="var(--accent)" stroke-width="2.2"/><path d="${poly(shapeS,ym)}" fill="none" stroke="var(--accent2)" stroke-width="2.2"/>`;
185
- // real tokens: top 80 mapped on by logit
186
- if(D){ const n=Math.min(80,D.V); for(let r=0;r<n;r++){ const x=Math.max(0,Math.min(1,(D.s[r]-D.lmax)/P.window+1)); s+=`<circle cx="${cx(x)}" cy="${cy(shapeS(x),ym)}" r="${r===0?3.4:2.4}" fill="var(--warn)" stroke="#fff" stroke-width="0.8" opacity="${r===0?1:0.7}"/>`; } }
187
- s+=`<text x="${(ML+CW-MR)/2}" y="${CH-3}" text-anchor="middle" font-size="9.5" fill="var(--text2)">signal x (1 = top token · 0 = ≥W nats below)</text>`;
188
- if(g.gamma<0) s+=`<text x="${(ML+CW-MR)/2}" y="${MT+28}" text-anchor="middle" font-size="11" font-weight="700" fill="var(--danger)">γ&lt;0 — ranking inverts (incoherent)</text>`;
189
- s+=`</svg>`; document.getElementById("curve").innerHTML=s;
190
- }
191
-
192
- // ---- distribution panel (log rank × log prob) ----
193
- const DW=560,DH=210,DL=44,DR=12,DT=12,DB=30, PLO=-7;
194
- function dx(r){ return DL+(Math.log10(r+1)/Math.log10(D.V))*(DW-DL-DR); }
195
- function dy(p){ const lp=p>0?Math.log10(p):PLO; return DT+(1-(Math.max(lp,PLO)-PLO)/(0-PLO))*(DH-DT-DB); }
196
- function linePath(arr){ let d="",started=false; for(let i=0;i<D.sr.length;i++){ const r=D.sr[i],p=arr[i]; if(p<=0){started=false;continue;} d+=(started?"L":"M")+dx(r).toFixed(1)+" "+dy(p).toFixed(1)+" "; started=true; } return d; }
197
- function drawDist(pr){
198
- if(!D){ document.getElementById("dist").innerHTML='<div style="padding:30px;text-align:center;color:var(--text3)">no real logits loaded</div>'; document.getElementById("distro").innerHTML=""; return; }
199
- let s=`<svg viewBox="0 0 ${DW} ${DH}" font-family="inherit">`;
200
- for(let e=0;e>=PLO;e--){ const yy=dy(Math.pow(10,e)); s+=`<line x1="${DL}" y1="${yy}" x2="${DW-DR}" y2="${yy}" stroke="var(--grid)"/><text x="${DL-5}" y="${yy+3}" text-anchor="end" font-size="8" fill="var(--text3)">1e${e}</text>`; }
201
- for(let e=0;Math.pow(10,e)<D.V;e++){ const xx=dx(Math.pow(10,e)); s+=`<line x1="${xx}" y1="${DT}" x2="${xx}" y2="${DH-DB}" stroke="var(--grid)"/><text x="${xx}" y="${DH-DB+12}" text-anchor="middle" font-size="8" fill="var(--text3)">${e===0?"1":"1e"+e}</text>`; }
202
- s+=`<text x="${(DL+DW-DR)/2}" y="${DH-2}" text-anchor="middle" font-size="9" fill="var(--text2)">token rank (sorted by logit) →</text>`;
203
- // W reach marker
204
- let inWin=pr.inWin; s+=`<line x1="${dx(inWin)}" y1="${DT}" x2="${dx(inWin)}" y2="${DH-DB}" stroke="var(--warn)" stroke-width="1.6" stroke-dasharray="3 2"/>`;
205
- s+=`<line x1="${dx(pr.keep)}" y1="${DT}" x2="${dx(pr.keep)}" y2="${DH-DB}" stroke="var(--pos)" stroke-width="1.2" stroke-dasharray="2 3" opacity=".7"/>`;
206
- s+=`<path d="${linePath(pr.raw)}" fill="none" stroke="var(--gray)" stroke-width="2"/>`;
207
- s+=`<path d="${linePath(pr.def)}" fill="none" stroke="var(--pos)" stroke-width="2"/>`;
208
- s+=`<path d="${linePath(pr.hlg)}" fill="none" stroke="var(--accent)" stroke-width="2"/>`;
209
- s+=`</svg>`; document.getElementById("dist").innerHTML=s;
210
- }
211
-
212
- function cfgJSON(){ return JSON.stringify({window:P.window,A:P.A,sM:P.sM,targetGap:P.targetGap,refGap:P.refGap,lw:Math.round(P.lw),xM:P.xM,yM:P.yM,xFloor:P.xFloor,yFloor:P.yFloor,p:P.p}); }
213
- function render(){
214
- for(const sl of ALL){ const el=document.getElementById("v_"+sl.k); if(!el)continue;
215
- el.textContent = sl.k==="lw"?Math.round(P.lw).toLocaleString():(Number.isInteger(P[sl.k])?P[sl.k]:P[sl.k].toFixed(2)); }
216
- const g=geom(); drawCurve(g);
217
- const ro=[["γ",g.gamma.toFixed(2)],["out_scale",g.outScale.toFixed(1)],["tokens in W",D?probsAt(g).inWin:"—"],["x_ref",g.xRef.toFixed(2)]];
218
- let pr=null; if(D){ pr=probsAt(g); drawDist(pr);
219
- const dr=[["HLG top-1",(pr.hlg[0]*100).toFixed(1)+"%"],["raw top-1",(pr.raw[0]*100).toFixed(1)+"%"],["default keeps",pr.keep],["W reaches rank",pr.inWin]];
220
- document.getElementById("distro").innerHTML=dr.map(([k,v])=>`<div class="ro"><div class="k">${k}</div><div class="val">${v}</div></div>`).join("");
221
- }
222
- // curve readouts (recompute inWin cheaply)
223
- const ro2=[["γ",g.gamma.toFixed(2)],["out_scale",g.outScale.toFixed(1)],["tokens in W",pr?pr.inWin:"—"],["dist",D?`${D.tag} (${D.ent}b)`:"—"]];
224
- document.getElementById("readouts").innerHTML=ro2.map(([k,v])=>`<div class="ro"><div class="k">${k}</div><div class="val" style="font-size:${String(v).length>8?11:14}px">${v}</div></div>`).join("");
225
- document.getElementById("cfgField").value=cfgJSON();
226
- }
227
- function applyPreset(n){ Object.assign(P,PRESETS[n]); for(const sl of ALL){ const inp=document.getElementById("s_"+sl.k); if(inp) inp.value=sl.log?lwToS(P[sl.k]):P[sl.k]; } render(); }
228
- function copyValues(){ const txt=cfgJSON(), ok=document.getElementById("copyOk"); const done=()=>{ok.textContent="Copied!";setTimeout(()=>ok.textContent="",1600);};
229
- if(navigator.clipboard&&navigator.clipboard.writeText) navigator.clipboard.writeText(txt).then(done,()=>{fb(txt);done();}); else {fb(txt);done();} }
230
- function fb(t){ const f=document.getElementById("cfgField"); f.focus(); f.select(); try{document.execCommand("copy");}catch(e){} }
231
-
232
- buildGrid(); buildDistSel(); prep();
233
- document.querySelectorAll(".presets button[data-preset]").forEach(b=>b.addEventListener("click",()=>applyPreset(b.dataset.preset)));
234
- document.getElementById("copyBtn").addEventListener("click",copyValues);
235
- document.getElementById("cfgField").addEventListener("click",e=>e.target.select());
236
- render();
237
- </script>
238
- </body></html>
@@ -1 +0,0 @@
1
- <svg viewBox="0 0 920 450" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="t d" font-family="ui-sans-serif,system-ui,sans-serif"><title id="t">HLG cliff resolution — two shapes</title><desc id="d">Fine junk% gradient through the target_gap cliff (a graded ramp, position shifts by vocab) and the W lower edge at high A (a sharp model-invariant edge near 7.5), three models.</desc><text x="460" y="30" text-anchor="middle" font-size="16.5" font-weight="700" fill="var(--text-primary,#1f2937)">Fine cliff resolution — the coarse grid jumped over two different shapes</text><text x="460" y="49" text-anchor="middle" font-size="11.5" fill="var(--text-secondary,#6b7280)">unit steps · mean canary junk% (K=5 seeds) · the transition the 8/12 and 5/10 jumps hid</text><text x="244" y="42" text-anchor="middle" font-size="14" font-weight="700" fill="var(--text-primary,#1f2937)">target_gap cliff — a graded ramp</text><text x="244" y="58" text-anchor="middle" font-size="10.5" fill="var(--text-secondary,#6b7280)">base (A=0.35, s_m=0.7, W=6) · position shifts by vocab</text><line x1="44" y1="380" x2="444" y2="380" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="36" y="384" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">0%</text><line x1="44" y1="291.17647058823525" x2="444" y2="291.17647058823525" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="36" y="295.17647058823525" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">10%</text><line x1="44" y1="202.35294117647058" x2="444" y2="202.35294117647058" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="36" y="206.35294117647058" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">20%</text><line x1="44" y1="113.52941176470588" x2="444" y2="113.52941176470588" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="36" y="117.52941176470588" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">30%</text><line x1="44" y1="371.11764705882354" x2="444" y2="371.11764705882354" stroke="var(--positive,#16a34a)" stroke-width="1.2" stroke-dasharray="5 3" stroke-opacity="0.8"/><text x="444" y="367.11764705882354" text-anchor="end" font-size="9.5" fill="var(--positive,#16a34a)">coherent &lt;1%</text><line x1="44" y1="380" x2="44" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="44" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">7</text><line x1="110.66666666666666" y1="380" x2="110.66666666666666" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="110.66666666666666" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">8</text><line x1="177.33333333333331" y1="380" x2="177.33333333333331" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="177.33333333333331" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">9</text><line x1="244" y1="380" x2="244" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="244" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">10</text><line x1="310.66666666666663" y1="380" x2="310.66666666666663" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="310.66666666666663" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">11</text><line x1="377.33333333333337" y1="380" x2="377.33333333333337" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="377.33333333333337" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">12</text><line x1="444" y1="380" x2="444" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="444" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">13</text><text x="244" y="416" text-anchor="middle" font-size="11" fill="var(--text-secondary,#6b7280)">target_gap →</text><path d="M44.0 131.3 L110.7 104.6 L177.3 229.0 L244.0 371.1 L310.7 371.1 L377.3 380.0 L444.0 380.0" fill="none" stroke="#2563eb" stroke-width="2.5" stroke-opacity="0.9"/><circle cx="44" cy="131.29411764705884" r="3" fill="#2563eb"/><circle cx="110.66666666666666" cy="104.64705882352942" r="3" fill="#2563eb"/><circle cx="177.33333333333331" cy="229" r="3" fill="#2563eb"/><circle cx="244" cy="371.11764705882354" r="3" fill="#2563eb"/><circle cx="310.66666666666663" cy="371.11764705882354" r="3" fill="#2563eb"/><circle cx="377.33333333333337" cy="380" r="3" fill="#2563eb"/><circle cx="444" cy="380" r="3" fill="#2563eb"/><path d="M44.0 166.8 L110.7 229.0 L177.3 344.5 L244.0 371.1 L310.7 380.0 L377.3 380.0 L444.0 380.0" fill="none" stroke="#d97706" stroke-width="2.5" stroke-opacity="0.9"/><circle cx="44" cy="166.8235294117647" r="3" fill="#d97706"/><circle cx="110.66666666666666" cy="229" r="3" fill="#d97706"/><circle cx="177.33333333333331" cy="344.4705882352941" r="3" fill="#d97706"/><circle cx="244" cy="371.11764705882354" r="3" fill="#d97706"/><circle cx="310.66666666666663" cy="380" r="3" fill="#d97706"/><circle cx="377.33333333333337" cy="380" r="3" fill="#d97706"/><circle cx="444" cy="380" r="3" fill="#d97706"/><path d="M44.0 300.1 L110.7 371.1 L177.3 371.1 L244.0 362.2 L310.7 380.0 L377.3 380.0 L444.0 380.0" fill="none" stroke="#0891b2" stroke-width="2.5" stroke-opacity="0.9"/><circle cx="44" cy="300.05882352941177" r="3" fill="#0891b2"/><circle cx="110.66666666666666" cy="371.11764705882354" r="3" fill="#0891b2"/><circle cx="177.33333333333331" cy="371.11764705882354" r="3" fill="#0891b2"/><circle cx="244" cy="362.2352941176471" r="3" fill="#0891b2"/><circle cx="310.66666666666663" cy="380" r="3" fill="#0891b2"/><circle cx="377.33333333333337" cy="380" r="3" fill="#0891b2"/><circle cx="444" cy="380" r="3" fill="#0891b2"/><text x="704" y="42" text-anchor="middle" font-size="14" font-weight="700" fill="var(--text-primary,#1f2937)">W edge @ A=100 — a sharp cliff</text><text x="704" y="58" text-anchor="middle" font-size="10.5" fill="var(--text-secondary,#6b7280)">channel closes abruptly 7→8 in all three</text><line x1="504" y1="380" x2="904" y2="380" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="496" y="384" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">0%</text><line x1="504" y1="291.17647058823525" x2="904" y2="291.17647058823525" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="496" y="295.17647058823525" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">10%</text><line x1="504" y1="202.35294117647058" x2="904" y2="202.35294117647058" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="496" y="206.35294117647058" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">20%</text><line x1="504" y1="113.52941176470588" x2="904" y2="113.52941176470588" stroke="var(--border,#e5e7eb)" stroke-opacity="0.6"/><text x="496" y="117.52941176470588" text-anchor="end" font-size="10" fill="var(--text-tertiary,#9ca3af)">30%</text><line x1="504" y1="371.11764705882354" x2="904" y2="371.11764705882354" stroke="var(--positive,#16a34a)" stroke-width="1.2" stroke-dasharray="5 3" stroke-opacity="0.8"/><text x="904" y="367.11764705882354" text-anchor="end" font-size="9.5" fill="var(--positive,#16a34a)">coherent &lt;1%</text><line x1="504" y1="380" x2="504" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="504" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">3</text><line x1="561.1428571428571" y1="380" x2="561.1428571428571" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="561.1428571428571" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">4</text><line x1="618.2857142857142" y1="380" x2="618.2857142857142" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="618.2857142857142" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">5</text><line x1="675.4285714285714" y1="380" x2="675.4285714285714" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="675.4285714285714" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">6</text><line x1="732.5714285714286" y1="380" x2="732.5714285714286" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="732.5714285714286" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">7</text><line x1="789.7142857142858" y1="380" x2="789.7142857142858" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="789.7142857142858" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">8</text><line x1="846.8571428571429" y1="380" x2="846.8571428571429" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="846.8571428571429" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">9</text><line x1="904" y1="380" x2="904" y2="384" stroke="var(--text-tertiary,#9ca3af)"/><text x="904" y="397" text-anchor="middle" font-size="10" fill="var(--text-secondary,#6b7280)">10</text><text x="704" y="416" text-anchor="middle" font-size="11" fill="var(--text-secondary,#6b7280)">window (W) →</text><path d="M504.0 166.8 L561.1 157.9 L618.3 202.4 L675.4 131.3 L732.6 237.9 L789.7 380.0 L846.9 380.0 L904.0 380.0" fill="none" stroke="#2563eb" stroke-width="2.5" stroke-opacity="0.9"/><circle cx="504" cy="166.8235294117647" r="3" fill="#2563eb"/><circle cx="561.1428571428571" cy="157.94117647058823" r="3" fill="#2563eb"/><circle cx="618.2857142857142" cy="202.35294117647058" r="3" fill="#2563eb"/><circle cx="675.4285714285714" cy="131.29411764705884" r="3" fill="#2563eb"/><circle cx="732.5714285714286" cy="237.88235294117646" r="3" fill="#2563eb"/><circle cx="789.7142857142858" cy="380" r="3" fill="#2563eb"/><circle cx="846.8571428571429" cy="380" r="3" fill="#2563eb"/><circle cx="904" cy="380" r="3" fill="#2563eb"/><path d="M504.0 149.1 L561.1 149.1 L618.3 166.8 L675.4 220.1 L732.6 264.5 L789.7 380.0 L846.9 380.0 L904.0 380.0" fill="none" stroke="#d97706" stroke-width="2.5" stroke-opacity="0.9"/><circle cx="504" cy="149.05882352941177" r="3" fill="#d97706"/><circle cx="561.1428571428571" cy="149.05882352941177" r="3" fill="#d97706"/><circle cx="618.2857142857142" cy="166.8235294117647" r="3" fill="#d97706"/><circle cx="675.4285714285714" cy="220.11764705882354" r="3" fill="#d97706"/><circle cx="732.5714285714286" cy="264.52941176470586" r="3" fill="#d97706"/><circle cx="789.7142857142858" cy="380" r="3" fill="#d97706"/><circle cx="846.8571428571429" cy="380" r="3" fill="#d97706"/><circle cx="904" cy="380" r="3" fill="#d97706"/><path d="M504.0 282.3 L561.1 282.3 L618.3 300.1 L675.4 344.5 L732.6 362.2 L789.7 380.0 L846.9 380.0 L904.0 380.0" fill="none" stroke="#0891b2" stroke-width="2.5" stroke-opacity="0.9"/><circle cx="504" cy="282.29411764705884" r="3" fill="#0891b2"/><circle cx="561.1428571428571" cy="282.29411764705884" r="3" fill="#0891b2"/><circle cx="618.2857142857142" cy="300.05882352941177" r="3" fill="#0891b2"/><circle cx="675.4285714285714" cy="344.4705882352941" r="3" fill="#0891b2"/><circle cx="732.5714285714286" cy="362.2352941176471" r="3" fill="#0891b2"/><circle cx="789.7142857142858" cy="380" r="3" fill="#0891b2"/><circle cx="846.8571428571429" cy="380" r="3" fill="#0891b2"/><circle cx="904" cy="380" r="3" fill="#0891b2"/><line x1="310" y1="436" x2="330" y2="436" stroke="#2563eb" stroke-width="2.5"/><circle cx="320" cy="436" r="3" fill="#2563eb"/><text x="336" y="440" font-size="11" fill="var(--text-secondary,#6b7280)">e4b</text><line x1="410" y1="436" x2="430" y2="436" stroke="#d97706" stroke-width="2.5"/><circle cx="420" cy="436" r="3" fill="#d97706"/><text x="436" y="440" font-size="11" fill="var(--text-secondary,#6b7280)">12B</text><line x1="510" y1="436" x2="530" y2="436" stroke="#0891b2" stroke-width="2.5"/><circle cx="520" cy="436" r="3" fill="#0891b2"/><text x="536" y="440" font-size="11" fill="var(--text-secondary,#6b7280)">CPM5</text></svg>
@@ -1 +0,0 @@
1
- <svg viewBox="0 0 960 658" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="t d" font-family="ui-sans-serif,system-ui,sans-serif"><title id="t">HLG coherence geometry across three models</title><desc id="d">Cross-pair coherence grids for e4b, 12B and CPM5. The sharpness cluster (s_m×tg, A×tg) replicates across all three; the window axis (s_m×W, A×W) tracks vocab size — the two Gemmas agree, CPM5 diverges.</desc><text x="480" y="26" text-anchor="middle" font-size="17" font-weight="700" fill="var(--text-primary,#1f2937)">Does the geometry generalize? Cross-pair coherence across 3 models</text><text x="480" y="46" text-anchor="middle" font-size="12" fill="var(--text-secondary,#6b7280)">green = coherent · red ✗ = canary broke · each grid is 4×4 over the break-spanning ranges</text><text x="288" y="78" text-anchor="middle" font-size="13" font-weight="700" fill="var(--text-primary,#1f2937)">e4b</text><text x="288" y="93" text-anchor="middle" font-size="9.5" fill="var(--text-tertiary,#9ca3af)">Gemma · 262k</text><text x="518" y="78" text-anchor="middle" font-size="13" font-weight="700" fill="var(--text-primary,#1f2937)">12B</text><text x="518" y="93" text-anchor="middle" font-size="9.5" fill="var(--text-tertiary,#9ca3af)">Gemma · 262k</text><text x="748" y="78" text-anchor="middle" font-size="13" font-weight="700" fill="var(--text-primary,#1f2937)">CPM5</text><text x="748" y="93" text-anchor="middle" font-size="9.5" fill="var(--text-tertiary,#9ca3af)">Llama · ~73k</text><rect x="14" y="108" width="932" height="244" rx="8" fill="var(--positive,#16a34a)" fill-opacity="0.05" stroke="var(--positive,#16a34a)" stroke-opacity="0.35"/><text x="26" y="124" font-size="12" font-weight="700" fill="var(--positive,#16a34a)">Replicates across all 3 — the sharpness cluster</text><text x="150" y="180" text-anchor="end" font-size="12.5" font-weight="600" fill="var(--text-primary,#1f2937)">s_m × target_gap</text><rect x="262" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="281" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="165" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="177.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="184" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="196.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="184" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="289.75" y="196.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="300" y="184" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="184" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="203" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="215.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="203" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="289.75" y="215.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="300" y="203" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="203" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="256" y="184" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 256 184)">s_m →</text><text x="300" y="233" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">tg →</text><rect x="492" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="511" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="165" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="177.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="184" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="196.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="184" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="519.75" y="196.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="530" y="184" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="184" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="203" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="215.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="203" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="519.75" y="215.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="530" y="203" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="203" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="486" y="184" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 486 184)">s_m →</text><text x="530" y="233" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">tg →</text><rect x="722" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="146" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="165" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="184" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="196.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="184" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="749.75" y="196.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="760" y="184" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="184" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="203" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="215.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="203" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="749.75" y="215.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="760" y="203" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="203" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="716" y="184" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 716 184)">s_m →</text><text x="760" y="233" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">tg →</text><text x="150" y="298" text-anchor="end" font-size="12.5" font-weight="600" fill="var(--text-primary,#1f2937)">A × target_gap</text><rect x="262" y="264" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="276.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="283" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="295.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="283" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="289.75" y="295.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="300" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="302" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="314.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="321" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="333.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="321" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="289.75" y="333.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="300" y="321" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="321" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="256" y="302" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 256 302)">A →</text><text x="300" y="351" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">tg →</text><rect x="492" y="264" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="276.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="283" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="295.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="302" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="314.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="321" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="333.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="321" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="519.75" y="333.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="530" y="321" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="321" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="486" y="302" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 486 302)">A →</text><text x="530" y="351" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">tg →</text><rect x="722" y="264" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="276.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="264" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="283" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="295.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="283" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="302" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="314.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="302" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="321" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="333.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="321" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="749.75" y="333.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="760" y="321" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="321" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="716" y="302" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 716 302)">A →</text><text x="760" y="351" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">tg →</text><rect x="14" y="366" width="932" height="244" rx="8" fill="var(--accent,#2563eb)" fill-opacity="0.05" stroke="var(--accent,#2563eb)" stroke-opacity="0.35"/><text x="26" y="382" font-size="12" font-weight="700" fill="var(--accent,#2563eb)">Vocab-dependent — the window axis (Gemmas agree, CPM5 diverges)</text><text x="150" y="438" text-anchor="end" font-size="12.5" font-weight="600" fill="var(--text-primary,#1f2937)">s_m × W</text><rect x="262" y="404" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="416.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="423" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="435.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="442" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="454.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="442" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="289.75" y="454.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="300" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="461" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="473.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="461" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="289.75" y="473.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="300" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="256" y="442" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 256 442)">s_m →</text><text x="300" y="491" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">W →</text><rect x="492" y="404" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="416.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="423" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="435.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="442" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="454.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="442" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="519.75" y="454.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="530" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="461" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="473.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="461" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="519.75" y="473.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="530" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="486" y="442" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 486 442)">s_m →</text><text x="530" y="491" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">W →</text><rect x="722" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="404" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="423" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="442" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="461" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="716" y="442" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 716 442)">s_m →</text><text x="760" y="491" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">W →</text><text x="150" y="556" text-anchor="end" font-size="12.5" font-weight="600" fill="var(--text-primary,#1f2937)">A × W</text><rect x="262" y="522" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="534.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="541" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="553.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="560" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="572.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="560" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="300" y="560" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="560" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="262" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="270.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="281" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="289.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="300" y="579" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="319" y="579" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="256" y="560" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 256 560)">A →</text><text x="300" y="609" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">W →</text><rect x="492" y="522" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="534.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="541" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="553.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="530" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="560" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="572.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="560" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="519.75" y="572.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="530" y="560" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="560" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="492" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="500.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="511" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="519.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="530" y="579" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="549" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="557.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><text x="486" y="560" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 486 560)">A →</text><text x="530" y="609" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">W →</text><rect x="722" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="522" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="741" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="541" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="722" y="560" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="572.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="560" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="760" y="560" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="560" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="787.75" y="572.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="722" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="730.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="741" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="749.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><rect x="760" y="579" width="17.5" height="17.5" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><rect x="779" y="579" width="17.5" height="17.5" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="787.75" y="591.25" text-anchor="middle" font-size="10" fill="#b91c1c">✗</text><text x="716" y="560" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)" transform="rotate(-90 716 560)">A →</text><text x="760" y="609" text-anchor="middle" font-size="9" fill="var(--text-tertiary,#9ca3af)">W →</text><g transform="translate(26,644)"><rect x="0" y="-11" width="14" height="14" rx="2" fill="var(--positive,#16a34a)" fill-opacity="0.22" stroke="var(--positive,#16a34a)" stroke-opacity="0.4"/><text x="20" y="0" font-size="11" fill="var(--text-secondary,#6b7280)">coherent</text><rect x="100" y="-11" width="14" height="14" rx="2" fill="#ef4444" fill-opacity="0.34" stroke="#ef4444" stroke-opacity="0.4"/><text x="120" y="0" font-size="11" fill="var(--text-secondary,#6b7280)">canary broke</text><text x="240" y="0" font-size="11" font-style="italic" fill="var(--text-tertiary,#9ca3af)">Same red pattern across columns = the curve, not the model.</text></g></svg>