Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -440,8 +440,10 @@ data budget asks.
| **V27.3 — delivered** | **A `>=` that was quietly an `=`**: retesting the comparison question after V27.2 produced « 0 ligne correspond où fare >= 0 » — impossible on a table where all 891 fares clear zero. Root cause found by reproduction, not by reading: the model emitted `"value": "0"` as a **string**, `asFilter` accepted a string for any operator, and `matchesFilter` took the numeric branch only for `typeof value === 'number'` — so `>=` fell through to the equality branch and tested `fare == "0"` against a column whose zero fares are written `0.0`. Same intent with a real number: 891 rows. The hole is closed on both sides: `asFilter` converts a numeric string and refuses anything else on `<`, `<=`, `>`, `>=` (equality keeps text — that is how categorical filters work), and `matchesFilter` handles the ordering operators apart, throwing the named `filter-not-numeric` rather than passing a bug off as a query with no matches. V6 code, reachable only through the model: the keyword parser always built numbers. **And a limit, recorded rather than papered over**: « est-ce que les femmes payaient plus cher que les hommes ? » is still read wrong — a correlation before V27.2, a vacuous count after. The model finds `fare` every time and the shape never. Two prompt attempts are enough; a third would be sewing the prompt around one sentence, which buys a flattering bench and nothing else. The measured score stands at **5 of 6**, and the sixth is written down as what a 0.6B does not do. 337 unit tests, 57 e2e. | Found by retesting in production (22/08/2026). An arithmetically impossible answer — zero rows for a condition every row satisfies — is worse than a refusal and worse than a wrong reading: it makes the engine itself untrustworthy, which is the one thing LabML sells. |
| **V28 — delivered** | **« Ne nous croyez pas sur parole »** — a `/privacy` route that states the local-only promise once, in full, and then hands the reader the means to check it without trusting a word of it. Four verification steps, ordered by how hard they are to fake: cut the network (DevTools → Network → Offline, or the Wi-Fi switch) and watch the whole lab keep working; watch the Network tab while loading a file and training, and see nothing happen; read `Content-Security-Policy` on the document itself; open Application → IndexedDB and see exactly what was kept. The served policy is **quoted verbatim on the page and pinned to `public/_headers` by a unit test** — a page that claims a protection the site quietly dropped is worse than no page. A schematic of the Network panel is drawn rather than screenshotted (DevTools chrome differs per browser and per locale) and captioned as a diagram, not a capture. A live audit panel counts this page's own resource timings by origin and says, in the same breath, what it cannot see: worker timelines and requests the CSP blocked — a proof that oversells itself is worth less than none. Last section lists what _does_ cross the network (app files, demo datasets on click, vision models on entering Vision, LLM weights on explicit consent) and what never does. FR/EN, prerendered shell, WCAG AA verified by axe including the audit result. 344 unit tests, 60 e2e. | Owner request (22/08/2026): the promise is repeated across the site, but a user has no way to tell a true claim from a comforting one. Verifiability is the product here — anyone can write « your data stays local » in a footer. |
| **V29 — delivered** | **Analytical SQL in the browser (DuckDB-Wasm, MIT)**: the Data Studio gains a real OLAP engine — joins, window functions, aggregations — over the file you just loaded, with no server and no upload. The file is queried **as dropped, before the cleaning recipe**: the recipe belongs to the studio, and a result traceable to nothing the user can reopen would be worse than no SQL at all. Extra CSV / **Parquet** / JSON files can be attached in the same session (Parquet is a new input format for the lab), each exposed as a view named after the file; a result exports to CSV or goes to the ML Lab in one click, through the handoff path V4 already built. Errors show **DuckDB's own message** — it names the line and the token, which no paraphrase of ours would. **The measurement that set the version**: `@duckdb/duckdb-wasm` is pinned to **1.28.0**, not `latest`. From 1.29 the binaries cross Cloudflare Pages' hard 25 MiB per-file limit (eh 34.2 MiB, mvp 39.4 MiB); at 1.28.0 they are **17.3 and 21.1 MiB** and fit. Newer would have meant sharding the wasm and either widening `connect-src` to `blob:` — days after publishing a page that quotes that very directive — or rebuilding the service worker in injectManifest mode. An older engine was the cheaper honest trade, and it is written here so the next upgrade re-measures instead of rediscovering. Self-hosted under `/duckdb/` (the library defaults to jsDelivr, which the CSP refuses), **never precached** — cached on first use like the vision models, so nobody pays 18 MiB before opening the console — and the `coi` threaded build is left out entirely: no COOP/COEP, no SharedArrayBuffer, single-threaded as the assumed mode. Remote S3/HTTP querying stays out, by CSP and by intent. 352 unit tests, 61 e2e. | Owner request (21/08/2026): real analytical SQL on ~100 MB files with zero backend. Delivered after the /privacy page at the owner's request (22/08/2026). |
| V30 | **Chat that reads better, measured before it is made bigger.** The V27.1–V27.3 measurement stands at **5 of 6** reference questions, and the one failure is a _shape_ error, not missing knowledge: the model finds `fare` every time and picks the wrong intent. **First, the numbers that kill the obvious idea** — a « 600 MB model » is not an upgrade: at q4f16, Qwen3-0.6B **non-DQ is 570 MB and the same brain**, only its embeddings unquantised. The real rungs are gemma-3-1b-it **764 MB** (2×), Llama-3.2-1B **1.09 GB**, SmolLM2-1.7B **1.11 GB**, Qwen2.5-1.5B **1.22 GB**, Qwen3-1.7B **1.43 GB** — against 370 MB today. So the plan spends nothing on weights until the cheap levers are exhausted. **(A) A bench worth the name** — 40–60 FR/EN questions including the phrasings that fail, runnable and reported; today's 18 cases cannot run in CI, and without this nothing that follows is measurable. **(B) Constrained decoding** — a hand-written `LogitsProcessor` masking every token outside the grammar _during_ generation: after `{"kind":"` only seven tokens are legal. The shape error becomes unrepresentable rather than caught after the fact, and on this task that can beat a model four times larger. **(C) Examples drawn from the user's own columns** instead of frozen Titanic ones — 0 MB, and it removes the temptation to copy an example column. **(D) Two samples, one vote**, keeping the candidate that validates and invents no column the question never names — 0 MB, 2× the time. **Only then** the bigger model, and as a SECOND announced download (« reinforced model », 764 MB) with Qwen 370 MB staying the default: the V27 sharding infrastructure already handles it (32 parts of 24 MiB). VRAM (~1.2–1.5 GB estimated) and first-token latency to be measured before promising anything. | Owner question (22/08/2026): would a bigger model raise the share of correct answers? The measured failure is structural, so the plan tests that hypothesis for 0 MB before asking a visitor for twice the bandwidth. |
| V31 | **Vision that stops being asked the impossible.** Today's three models weigh **18.6 MB total** (EfficientNet-Lite4 int8 13.6, YOLOX-Nano 3.7, UltraFace 1.3) against 370 MB for the chat model — the headroom is enormous. **The main cause of the mistakes is not the network**: ImageNet-1k has **no « person » class** — 1000 labels, ~120 of them dog breeds, none for a human being — so a photo of someone comes back as « suit » or « jersey ». The model is not wrong; it is being asked a question whose answer is absent from its vocabulary. **(A) Measure first**: 30–50 public-domain images with expected label and expected boxes, replayed in e2e, so « it still makes mistakes » becomes a percentage. **(B) Fix the label space — the real correction**: CLIP ViT-B/32 zero-shot, vision q4f16 **126 MB** + text int8 **64 MB** ≈ **190 MB**, letting the visitor type their own labels (« a cat », « an invoice », « a houseplant »). It repairs the defect and makes a far better demonstration than 1000 frozen classes; open weights, self-hosted, local execution — the doctrine holds. **(C) What costs no download**: check the crop (squashing a 16:9 photo into a square skews everything — `preprocess.ts` is the suspect), average over two crops, recalibrate `OBJECT_THRESHOLD` (0.35) and `FACE_THRESHOLD` (0.9), and above all **refuse below a confidence floor** — « I am not sure » rather than a label picked at random, which is the chat's doctrine applied to pixels. **(D) A better detector**: YOLOX-S (Apache-2.0), ~35 MB, roughly +14 mAP over Nano — with acquisition and licence verified first, as in V23: the YOLOX ONNX files on the Hub are community re-uploads, not official releases. | Owner report (22/08/2026): the vision playground is better than the chat but still makes mistakes. Naming the label-space mismatch is what turns a vague complaint into a fixable defect. |
Comment on lines +443 to +444

**Ordering**: V23 first (owner request); V24 keeps its vocabulary capped —
**Ordering**: V30 and V31 both start with a bench, because neither « a bigger model » nor « it still makes mistakes » is a measurable statement today; no wave starts without an explicit launch command. V23 first (owner request); V24 keeps its vocabulary capped —
V25 (delivered) chose announced sampling and a named memory guard over the
typed-array rewrite, which measurement showed unnecessary; widening the
vocabulary stays possible later. Set aside for now: multiclass thresholds. V12
Expand Down
Loading