Skip to content
Merged
Show file tree
Hide file tree
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
49 changes: 41 additions & 8 deletions PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,12 @@ comfort, /ml 0.77 → 0.86 measured), V10 (replayable recipes, forced types,
derived dates) — delivered and verified in production. 16 PRs merged,
177 unit tests, 36 e2e.

| Wave | Content | Why |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| **V11 — delivered** | **Data drift** in the Data Studio: a reference file, a file to compare → schema differences (columns added/removed/retyped), **PSI per column** (quantile bins from the reference, thresholds 0.1/0.25), new/vanished categories, missing-rate gaps, overall verdict — with a deliberately drifted demo (`cafe-sales-june.csv`) | The MLOps gesture par excellence: checking that a new batch looks like what the model learned on |
| V12 — pending | **Consented generative chat**: a Cloudflare Pages Function (same repo) proxying the Anthropic API — the key lives in a Cloudflare secret, never in the browser; the LLM translates the question into an intent executed **locally** by the V6 engine (only the question and the column schema leave, never the data); explicit consent screen; clean degradation if the secret is not configured | Owner's product decision (21/08/2026): postponed for now |
| **V13 — delivered** | **Complete runs**: tuning, latest Shapley explanation, exploration and forecast attached to the run record — IndexedDB history (with chips), stored-run page, HTML report and v2 share links (subsampled scatter plots in the URL; v1 links remain decodable) | The V5–V8 artifacts did not survive the run |
| **V14 — delivered** | **Generalized prerendering**: static shells for all six sections (the V9 approach extended — inlined CSS, Latin fonts as data:, per-route preloaded façade, header template), Lighthouse /ml 0.86 → 0.99 and /data 1.0 under real throttling (3-run medians); the root stays the SPA fallback (accepted) | The last Lighthouse gap |
| Wave | Content | Why |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| **V11 — delivered** | **Data drift** in the Data Studio: a reference file, a file to compare → schema differences (columns added/removed/retyped), **PSI per column** (quantile bins from the reference, thresholds 0.1/0.25), new/vanished categories, missing-rate gaps, overall verdict — with a deliberately drifted demo (`cafe-sales-june.csv`) | The MLOps gesture par excellence: checking that a new batch looks like what the model learned on |
| V12 — pending | **Consented generative chat**: a Cloudflare Pages Function (same repo) proxying the Anthropic API — the key lives in a Cloudflare secret, never in the browser; the LLM translates the question into an intent executed **locally** by the V6 engine (only the question and the column schema leave, never the data); explicit consent screen; clean degradation if the secret is not configured | Owner's product decision (21/08/2026): postponed for now. Confirmed 09/10/2026, after Cap 7: not scheduled. |
| **V13 — delivered** | **Complete runs**: tuning, latest Shapley explanation, exploration and forecast attached to the run record — IndexedDB history (with chips), stored-run page, HTML report and v2 share links (subsampled scatter plots in the URL; v1 links remain decodable) | The V5–V8 artifacts did not survive the run |
| **V14 — delivered** | **Generalized prerendering**: static shells for all six sections (the V9 approach extended — inlined CSS, Latin fonts as data:, per-route preloaded façade, header template), Lighthouse /ml 0.86 → 0.99 and /data 1.0 under real throttling (3-run medians); the root stays the SPA fallback (accepted) | The last Lighthouse gap |

---

Expand Down Expand Up @@ -624,5 +624,38 @@ before features, and the one that produces wrong data comes first of all.

**Cap 7 closed (09/10/2026)**: V47 to V52 delivered. What the lab already did now holds when the user does two things at once (V47), when a link is damaged (V48), when CI runs on a branch nobody checked (V49), when a class is rare or absent (V50); the store fits on a screen (V51), and the three majors were taken one at a time, one of them deferred on a measurement rather than forced (V52).

V12 (consented generative chat) remains pending a product decision. No wave
starts without an explicit launch command.
V12 (consented generative chat) is not scheduled: the owner confirmed on
09/10/2026, once Cap 7 closed, that it stays postponed. The row keeps its
« pending » status because nothing was built or refused; it is a decision not to
start, not a measurement. No wave starts without an explicit launch command.

## P. Future directions (not scheduled, 09/10/2026)

Written at the close of Cap 7 so the next session starts from a list rather
than from a fresh audit. None of these is a wave: each has the condition that
would justify starting it, and none starts without an explicit launch command.

- **Adopt TypeScript 7.** Condition: typescript-eslint supports it (V52.3). The
code already typechecks with 0 errors; the work is a version bump, removing
the Dependabot ignore, and re-measuring the typecheck time in CI.
- **Re-measure DuckDB-Wasm above 1.28.0.** Condition: a release whose eh and
mvp binaries fit under Cloudflare Pages' 25 MiB per-file limit, or a reason
to shard them (V29). The Dependabot ignore keeps the question closed until
someone re-measures; it should be re-opened at least once a year.
- **Raise the coverage floors where they are lowest.** Functions (54 %) and
branches (53 %) trail statements and lines. Condition: none, it is
maintenance; the method is V51's, tests on the modules with the lowest
function coverage, then the floor moves up and never down.
- **A lint with zero warnings.** `badge.tsx` and `button.tsx` export their
variant helpers next to the component, which `react-refresh` flags. Moving
the helpers to their own file and adding `--max-warnings 0` makes the next
warning a failure instead of a line nobody reads.
- **A run id in the ML worker protocol.** Condition: the day two requests can
be in flight at once (for example, an analysis that runs during training).
Until then V47's fence is enough, and the limits page says so.
- **Widen the text vocabulary.** V24 capped it; V25 measured that the memory
guard made the typed-array rewrite unnecessary. Condition: a real dataset
where the cap visibly costs accuracy, measured before and after.
- **V12, consented generative chat.** Postponed by the owner (09/10/2026).
Condition: a product decision, plus a fresh read of the provider's data
policy, since the consent screen would have to quote it.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -341,12 +341,14 @@ CI builds, tests and deploys on every push: pull requests get a Cloudflare Pages

## Roadmap

Development proceeds in planned "caps" of feature waves; six caps have shipped (MVP
through the lab meeting the real world: real photos, real text, real file sizes). Cap 7 (closed)
Development proceeds in planned "caps" of feature waves; seven caps have shipped (MVP
through the lab meeting the real world: real photos, real text, real file sizes). The last, Cap 7,
made what already ships hold up under pressure: worker lifecycle, damaged share links,
CI hardening, metric edge cases, a store refactor, and major upgrades taken one at a time
(Vitest 5 and vite-plugin-pwa 2 shipped; TypeScript 7 typechecks this code with no error
in 1.5 s instead of about 11, and waits for typescript-eslint to support it). The full plan, delivery log and design decisions live in
in 1.5 s instead of about 11, and waits for typescript-eslint to support it). No wave is scheduled: the consented
generative chat (V12) stays postponed by product decision, and the candidates for a next
cap are listed, each with the condition that would start it. The full plan, delivery log and design decisions live in
[PLAN.md](PLAN.md); [CHANGELOG.md](CHANGELOG.md) is extracted from it — one entry per
wave, newest first — by `npm run changelog`, and a test fails when the two disagree.

Expand Down
37 changes: 19 additions & 18 deletions src/content/docs/en/limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,25 @@ They are not equivalent, and mixing them would be dishonest:

## Set aside by choice

| Set aside | Why |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| An AutoML « we handle everything » mode | The exact opposite of a lab that shows its decisions |
| A tenth model family | Nine is plenty; a tenth improves neither honesty nor understanding |
| Tabular deep learning | High cost, no gain at this scale, and no longer hand-written |
| A spreadsheet-style cell editor | Hand edits break reproducibility — the recipe is the only record |
| Fuzzy deduplication | Guaranteed false positives on names and addresses: silently merging two real people |
| Model-based imputation | Opaque, and it fabricates plausible values — refused twice, in V39 and V40 |
| Caching models across runs | The cache key would be the whole configuration plus the data; a stale hit is a wrong leaderboard with no warning |
| Guessing a file's locale | The browser has no relationship to the file dropped into it |
| Making the absence indicator mandatory | It would add columns to every existing recipe: imposing is not announcing |
| Translating the changelog and prerendering the French docs | The changelog is an engineering log, not editorial content; without per-language routes, hreflang alternates would lie |
| Catching async errors and shipping crash reports | React boundaries cannot see callbacks or event handlers — claiming otherwise would be false; and nothing leaves the browser, telemetry included |
| A daily Dependabot and `npm audit fix --force` | A daily cadence drowns the signal; `--force` moves majors without reading the break. The remaining advisories sit in build tooling, and we say so instead of hiding it |
| Picking multiclass thresholds automatically | The lab shows its decisions instead of making them for you; and abstention is neither uncertainty calibration nor a conformal guarantee |
| A run id in every worker message | The worker answers in the order it is written to, so the training status is enough to recognise a stale answer. The id becomes necessary the day requests can overlap |
| A « rare class » warning in the interface | A one-row class stays in training, and a target where every class has one row is refused by name; a banner would flag a problem the split already handles |
| Splitting the ML Lab store into independent slices | Every action shares one worker: slicing would have moved code without separating anything |
| Set aside | Why |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| An AutoML « we handle everything » mode | The exact opposite of a lab that shows its decisions |
| A tenth model family | Nine is plenty; a tenth improves neither honesty nor understanding |
| Tabular deep learning | High cost, no gain at this scale, and no longer hand-written |
| A spreadsheet-style cell editor | Hand edits break reproducibility — the recipe is the only record |
| Fuzzy deduplication | Guaranteed false positives on names and addresses: silently merging two real people |
| Model-based imputation | Opaque, and it fabricates plausible values — refused twice, in V39 and V40 |
| Caching models across runs | The cache key would be the whole configuration plus the data; a stale hit is a wrong leaderboard with no warning |
| Guessing a file's locale | The browser has no relationship to the file dropped into it |
| Making the absence indicator mandatory | It would add columns to every existing recipe: imposing is not announcing |
| Translating the changelog and prerendering the French docs | The changelog is an engineering log, not editorial content; without per-language routes, hreflang alternates would lie |
| Catching async errors and shipping crash reports | React boundaries cannot see callbacks or event handlers — claiming otherwise would be false; and nothing leaves the browser, telemetry included |
| A daily Dependabot and `npm audit fix --force` | A daily cadence drowns the signal; `--force` moves majors without reading the break. The remaining advisories sit in build tooling, and we say so instead of hiding it |
| Picking multiclass thresholds automatically | The lab shows its decisions instead of making them for you; and abstention is neither uncertainty calibration nor a conformal guarantee |
| A run id in every worker message | The worker answers in the order it is written to, so the training status is enough to recognise a stale answer. The id becomes necessary the day requests can overlap |
| A « rare class » warning in the interface | A one-row class stays in training, and a target where every class has one row is refused by name; a banner would flag a problem the split already handles |
| Splitting the ML Lab store into independent slices | Every action shares one worker: slicing would have moved code without separating anything |
| A generative chat backed by a remote API (V12) | Postponed by product decision (confirmed 09/10/2026). Today's chat runs entirely in the browser; a remote API would send out the question and the column schema, never the data, and would require a consent screen |

## Dropped after measurement

Expand Down
Loading
Loading