Checkpoint 1 · v4 Refactor Plan

One Engine, Ready for Any Language

This is the plan to rebuild the machine that writes definitions, examples, and hints for every word — on a stronger foundation that can plug in any AI company's model and switch its teaching language without a rewrite. Three separate reviews this week, done independently, landed on the same answer: keep building on the new system, don't start over. Here's the plan, and six decisions that shape the foundation everything else gets built on.

Build-on, not replan 3 audits agree 6 foundation decisions Gemini sunset: Oct 16
Checkpoints Latest →
The goal

What "done" actually looks like

The north star for this rebuild, in five parts
The design

One engine, and four abilities fall out of it for free

The core idea the whole plan hangs on

Instead of building four separate systems for four separate asks, the plan builds one thing — a job-runner that takes a to-do list and works through it, writing only the exact pieces it was aimed at — and four of the requirements above come along for free once that one thing exists.

Build once
The job-runner
Takes a list of tasks, works through them, writes only the fields it's aimed at.
Four abilities fall out of it
Scheduled runs
A recurring job with a standing list.
Parallel processing
Many words worked on at once.
Re-audit
Re-run old work through a better model.
French-on-a-whim
A targeted re-run of just the learner-facing text.
Plus, on its own clock: a universal AI-model adapter — one shared connector that lets any step plug into any AI company's model. This is the piece racing the October deadline, and it's being built in parallel with everything else, starting now.
The catch

The data is ready for French. The code isn't — yet.

What the deep, field-by-field audit found
The problem

English is hard-wired in, in five places

Every piece of code that writes an explanation, a translation, or a hint currently assumes the answer belongs in English. There's no "which language" setting anywhere yet:

  • Word definitions are written directly in English — not translated from anything.
  • Several separate translator scripts each independently hard-code "English" as the target.
  • The tracker that records "has this been translated yet" only has one slot: English.
  • The settings sheet that drives each generation run has no field at all for which language to explain in.
  • Even the Indonesian example sentences carry small English hints stitched right inside them — see Decision 1 below.
The good news

The database is already French-ready

The way content is stored already keeps "the language being taught" (Indonesian) separate from "the language explaining it" (English today). Adding French is just adding a new label inside records that already exist — no new database tables, no restructuring how anything is stored.

So this isn't a data problem. It's a code problem, and a naming-convention problem — and the plan fixes both in the foundation phase, once the six decisions below settle exactly which shape it takes.

The plan

Four phases, in order

What gets built, and when
0
Decide. Settle the six foundation decisions below (this checkpoint). They shape the exact database fields everything else gets built on, so they come first.
1
Build the foundation — the one piece everything else is waiting on. Nothing in the new system actually saves a finished card to the database yet — that one missing piece blocks the entire chain downstream. Build it, plus the job-runner from above. At the same time, on a separate clock, finish the universal AI-model adapter — it's needed for the October deadline no matter how these decisions land.
2
Build each content step onto that foundation. Splitting words into distinct meanings → filling in definitions → building word forms (plurals, tenses, etc.) → hints → pronunciation → tags — each one built using whichever language approach Decision 2 picks. Example sentences and translation already work and just plug in unchanged.
3
Prove it. Turn on French for real — add it, run one command, check a full French edition comes out correctly. That's the acceptance test. Turn on parallel runs. Fix one small remaining plumbing issue along the way (linking a word's individual meanings to their IDs correctly).
Timing

The AI-model swap doesn't wait on these decisions

Everything already built — the example-sentence work, the reliable connection layer that talks to AI models — stays useful no matter which way the six decisions below land. The one real deadline is Google retiring the Gemini 2.5 model on October 16, 2026. The universal adapter that lets the pipeline swap in any AI company's model is already being built to beat that date, and it runs in parallel with everything else starting now.

Decide

Six decisions that shape the foundation

These decide the exact shape of the database fields everything else gets built on, so they need answers before Phase 1 starts. About ten smaller inconsistencies turned up in the same audit — those are lower-stakes and will get decided one at a time as each build phase actually reaches them, not bundled in here.
Decision 1 of 6

The English hints stitched inside Indonesian sentences — do they switch to French?

Naming convention · the highest-leverage call in this batch
🏷️
What this is: Every Indonesian example sentence has a small English hint physically stitched inside the Indonesian text itself — like a sticky note glued onto the sentence so a beginner can see a tricky word's translation right where it appears. Because that hint lives inside the "Indonesian" content, that side of the system isn't actually language-free — it secretly assumes the learner reads English. When French support gets added, should that stitched-in hint switch to French for French learners, or always stay in English no matter what language the learner is being taught in?
A — Switch to French. The hint always matches whatever language the learner is being taught in. Makes the Indonesian content genuinely reusable for any future language, not just English and French.
B — Freeze to English. The hint stays in English forever, even inside a French learner's material. Simpler to leave alone today, but "language-free Indonesian content" stops being actually true — English stays baked in permanently.
AI recommendation: A. This is the one place the audit found actively fighting the stated goal of a truly language-swappable system — freezing it to English leaves a permanent asterisk on "French-ready."
Decision 2 of 6

How should switching the explanation language actually work, under the hood?

Core design fork · no single obviously-right answer
🔧
What this is: Right now, every explanation, definition, and hint in the system is written in English by default — there's no concept of "which language should this be in" anywhere in the code. To offer French, one of three different underlying approaches has to be picked for how content gets generated in a new language. This is a genuine fork: reasonable engineers could pick any of the three, so there's no single recommended answer here.
A — A built-in language dial. Every content-writing step checks a setting: "what language am I supposed to explain in?" Turning the dial to French re-runs the whole pipeline's explanation-writing steps aimed at French. Cleanest and most thorough long-term, but touches nearly every piece of the machine — the most work up front.
B — An on-demand "translate to French" pass. After English content already exists, a separate step fills in a French copy, reusing a translation tool that's already built and proven. Smaller and faster to build, but the English hints stitched inside the Indonesian text (Decision 1) need separate handling — a blanket translation step doesn't reach inside them.
C — A separate French add-on layer. The smallest change to the existing code — French becomes its own bolt-on layer rather than a built-in setting. Cheapest to build today, but it recreates a separate French-only storage area — the exact kind of separate storage this rebuild deliberately removed earlier.
Decision 3 of 6

Grammar explanations are stored three incompatible ways — pick one shape

Frank flagged this one himself
📏
What this is: Grammar explanations currently live in three different, incompatible formats depending on where they show up: a short plain-text note attached to individual words, a much richer and more detailed format attached to dedicated grammar-rule cards, and yet a third note format attached to word-form entries (like a verb's different tenses). None of the three can be swapped for each other or reused. There's also one leftover database column meant for grammar content that nothing has ever actually used.
A — One structured format everywhere. Take the richest existing format (from the grammar-rule cards) and use it for grammar content everywhere, including the simple word-level notes. One renderer, one translator, everything connects. Costs the most migration work, and may be more structure than the simple notes actually need.
B — Keep the simple note where it already works; give the rich grammar-rule content its own proper, separate home instead of squeezing it into a shared column. Cleaner separation, smaller change for most existing content — but two grammar systems still get maintained, just tidier ones.
C — Leave the three formats as they are; only delete the one dead, unused column. Cheapest option, no migration — but the three-way inconsistency stays, and every future translation into French (or any other language) has to be built three separate times instead of once.
Decision 4 of 6

A word's related forms are stored two ways at once — pick one

Frank flagged this one himself · 123 exact duplicate entries found
🌳
What this is: A word's "family" — its related and derived forms, like plurals, tenses, or compound words built from it — is currently stored in two places at once: once as its own standalone entries, and again as a duplicated list attached back onto the main word's entry. This double-storage has already produced 123 exact duplicate copies of the same word, plus a cleanup that was started and never finished, leaving some entries orphaned mid-move.
A — Always separate entries. Every related form gets its own standalone record; nothing gets duplicated onto the parent word.
B — Always a list on the parent word. Drop the separate entries; a word's family always lives as a list attached to its main entry.
C — Split by rule. Forms of the exact same word (run / running / ran) stay separate entries; distinct compound words built from two separate words (like "ice cream" from "ice" + "cream") live as a list on the parent instead.
D — The parent's list becomes a pointer, not a copy. Instead of duplicating a form's details onto the parent word, the parent just links to the real entry. Cleanest option on paper — it also happens to fix a second problem (the same pronunciation audio file getting duplicated in multiple places) — but it's the biggest change for anything that reads this data.
Decision 5 of 6

Is the Buddhist-study card deck part of this rebuild, or a separate product?

Scope question · 105 cards
🙏
What this is: Tucked inside the same database table as all the Indonesian vocabulary content is a separate, 105-card deck of English-taught Buddhist vows and concepts — a different kind of study material, built by a different process, at a different time. It sits in the same technical home as everything else being rebuilt, and several of the small inconsistencies in the audit exist specifically because this deck doesn't quite match the shape everything else uses. Is it part of what this rebuild should touch, or a separate product that should just be left alone?
A — In scope. Fold it into this rebuild's rules and cleanups along with everything else.
B — Separate product — leave it alone. Treat it as its own thing outside this rebuild; don't let its quirks drive decisions about the main vocabulary content.
Decision 6 of 6

Ratify the real set of card types — which are first-class, which get built, which retire

Open-ended · no clean multiple choice
📁
What this is: The database currently holds six different kinds of study cards. But the code that builds and manages them doesn't treat all six the same way — one type has cards sitting in the database that the code doesn't even recognize exists, and another has cards with no code that knows how to build or update them at all.
Card typeRoughly how manyStatus today
Vocabulary (words)~2,100Fully supported — this rebuild's main focus
Grammar rules~194Built by the old system; not yet carried into the new one
Script / alphabet~32Built by the old system; not yet carried into the new one
Phrases~28Built by the old system; not yet carried into the new one
Concept (mostly the Buddhist-study deck)~120Content exists, but no code path even recognizes this type
Reading passages12Cards exist, but no code has ever been written to build or manage them; most are flagged incomplete
Tell us which of these should be first-class (fully rebuilt and supported), which should get a builder eventually but aren't urgent, and which should just retire.
Recommended starting point Keep this rebuild's main effort on Vocabulary, exactly as planned. Formally retire the 12 reading-passage cards — no one has ever built anything for them, and there's no plan to. Leave the call on Grammar rules, Script, Phrases, and Concept for a later checkpoint, once Decision 5 (the Buddhist-deck scope question) is settled — Concept's fate is tied to it.
FYI

Everything else found stays catalogued, not bundled in here

About ten smaller inconsistencies turned up in the same field-by-field audit — things like how register labels are named, where source-tracking info lives, pronunciation audio being saved in three different places, and how tags are stored. None of them block the foundation. They'll surface as their own quick decisions when each build phase actually reaches that specific field — not bundled into this checkpoint.
Worth your eye

Three things worth double-checking as you read

🧹
One missing piece blocks everything downstream. Nothing in the new system writes a finished card to the database yet. Until that one piece is built (first thing in Phase 1), nothing else can land, no matter how these six decisions go — which is exactly why it's first in line.
Only two steps are proven and working today. Writing example sentences, and translating them to English, are the only two steps tested end-to-end in the new system right now. Everything else in the plan exists as a design spec, not working code, yet.
🔁
Nothing built so far gets thrown away. The example-sentence work already dug the groundwork the rest of the pipeline rides on — once the upstream steps (definitions, forms, etc.) land, examples plug in unchanged. That holds true no matter which way the six decisions above land.