A bilingual friend you can't stop texting. You learn by talking; later, the friend drills it in by reusing your own words back at you. V0 nails the sticky first conversation — the design and the build plan in one doc. The teaching layer (tracking your words, drilling them back) is V1.
8 minYou have a bilingual friend. You just talk to them, and you pick up the language from exposure — naturally, never a lesson. Then it gets drilled in, because the friend texts you later and uses the stuff you learned together. It's spaced repetition, but conversation-native: not flashcards, but "here's a thing you actually said — now say it better in Japanese." It repeats your own life, not random vocab. That's the whole edge.
The full product is exposure + retention. V0 is deliberately just the front half: make the very first interaction so good they keep texting. Get that sticky, then build retention on a base that already hooks people.
The target feel for a V0 first conversation. Not perfect — a reference, not a script.
By turn four the user is producing unprompted Japanese — and nobody said "repeat after me." That's the bar.
What anna does that makes it work — each maps to a current failure it fixes. These are the explicit targets the prompt rewrite aims at, and the bar the definition of done grades against.
へえ 本当?? drops Japanese instantly, no announcing. fixes the all-English onboarding gauntletAmbient isn't aimless. The agent holds a checklist of what it needs to learn, weaves it into the chat, and actively draws it out — it never waits passively, and never fires the list in sequence. By the end of the first conversation it should know:
| Objective | How it gets it |
|---|---|
| Which language | Fixed: Japanese. V0 is Japanese-only, so this isn't really a question — assume Japanese. The cold-open can still surface it naturally ("which one?"), but there's no other answer to support. |
| Why they're learning | Ambient — falls out of "what's pulling you toward it?" |
| Experience with the language | Actually ask — studied before? how long? where'd you stop? Don't only infer it. |
| Script knowledge · Japanese-specific | Do they read hiragana / katakana / kanji? Probe early — the single biggest dosage input. |
| Interests / topics | Ambient — to talk through. |
Method: gauge what shows itself — skill leaks through how they reply — but explicitly probe experience and scripts. Those don't surface fast enough and they set the entire calibration. Script knowledge is exactly what the 5109 thread got wrong: conversationally decent, but can't read kanji, so the agent flooded them with it. It gets stored as a small calibration field (change §5).
Exposure only works if the user can actually decode what's on screen. So sitting on top of dosage is a hard rule: never send target text the user can't read. Script knowledge isn't just a calibration input for how much Japanese — it directly sets how every line is written. When in doubt, attach the reading rather than withhold the word.
| If they read… | Render target text as… |
|---|---|
| No kana yet | Romaji (optionally kana with romaji alongside). Latin is always decodable. |
| Kana, not kanji | Kana — and any kanji carries a kana reading (furigana-style, e.g. 日本(にほん)), or just write it in kana. |
| Kanji too | Normal mixed script. |
Kanji is the special case. Which kanji a person knows is wildly individual, so V0 doesn't try to track it per-character — it leans on the universal safety net: any time there's doubt they can read a kanji, gloss it in kana (or romaji for true beginners). Readability is never traded away to look authentic. It's the 5109 failure from the other side — bare kanji nobody could read.
| Today | V0 |
|---|---|
| Onboarding = a 5-step interrogation; exposure gated to step 5 | Exposure-first; info gathered ambiently mid-chat |
Fixed level label drives dosage (over/undershoots) | Consent-to-ramp + read-the-room calibration in the moment |
| No fixed name; generic persona | A named friend (e.g. "anna"), casual cold-open |
| Prompt is broad & "meh" | Rewritten around the six moves as explicit targets |
| Notes are an inert free-text blob | Quietly capture structured "what they know" (the scripts field) |
| Target text written however the model likes (bare kanji) | Every line rendered in a script they can read — romaji / kana / kana-glossed kanji |
The concrete changes to ship V0. Almost entirely a prompt/objective rewrite in one file — no new infra.
A brand-new person texts in and gets a first conversation that hits the six moves:
Measured by eyeballing real threads against the anna north-star — not a metric yet.
~90% lives in core/agent.mjs. The persona is fine; the onboarding objective is the problem.
remember as they surface. No "first win" pressure.
Objectives to land — held as a checklist, gathered ambiently + by gentle probing, never a form: which language (fixed: Japanese — V0 is Japanese-only, so this is an assumption, not a real branch) · why · experience (ask directly) · script knowledge — reads hiragana / katakana / kanji? (the key dosage input) · interests. Gauge skill from how they reply, but explicitly draw out experience and scripts.
The hard onboarding→learning switch reads as a personality change. Flip onboarded as soon as they've named the language and had one real in-target exchange, and make both objective blocks exposure-first + interactive so the seam disappears.
Replace "calibrate to the stored level" with: judge from the thread — reply length, kana vs kanji, how much target they volunteer — and trust that over the label. Ramp by consent; never flood; if they ask for simpler (e.g. hiragana), drop immediately. Keep the level ladder as a guide, demote the fixed label. This is the prompt-only fix for the 5109 kanji overshoot. The hard readability rule above is a constant on top of this: dosage controls how much target language, readability controls how it's written, and the user must be able to read 100% of it.
Set AGENT_NAME=anna (or your pick). buildSystemPrompt already branches on it — this just turns on the named-friend cold-open.
Add a scripts field to the profile — { hiragana, katakana, kanji }, each reads | learning | no — plus a matching param on the remember tool, so the agent records script ability and calibrates its writing to it across turns. This field is what drives the readability rule in §3: it picks the render layer (romaji / kana / kana-glossed kanji) for every target line. That's calibration, not retention, so it's in V0. Otherwise this onboarding rewrite leaves memory as-is: the structured Progress store is V1 — the teaching milestone (the Anki backbone), not this onboarding file — and resurfacing tools are V1 too, not V0. (Optional: drop the exact-match note dedup that hoards duplicate paragraphs.)
| Risk | Mitigation |
|---|---|
| Model still over-questions or under-switches | Iterate the prompt against the test loop; the six moves are explicit targets to grade against. |
| Less structure → forgets to capture language/level | Keep remember calls baked into the new objective so profile still populates ambiently. |
| Calibration by prompt alone is weaker than tracked state | Accept for V0 — lean on "consent + back off when asked." The real fix (Progress store) is a later milestone. |
AGENT_NAME in .env.node -e with the exported buildSystemPrompt({}) to read the new prompt before sending anything.core/.memory.json — to get true first-contact behavior.npm run messages + npm start, text in, and grade the thread against the six moves.Tracking and grading vocab is the V1 teaching layer, not V0 — but the raw material is right there in the very first conversation (phrases used, near-misses like ボダリング → ボルダリング, topics they care about). V0 quietly captures it; V1 turns it into a tracked, resurfaced vocabulary.
Further out: the proactive retention loop (agent texts first, reusing your own phrase — "今日なんか疲れてるっぽい?"), a continuous skill rating that replaces the coarse beginner→native ladder, and other languages beyond Japanese.