Language buddy — V0

DRAFT — will change

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 min
Versioning: this milestone — the sticky first conversation — is V0 (it was first drafted as "V1"). The V1 milestone is the teaching layer: the Anki backbone + themed clusters.
Design
  1. The thesis
  2. V0 scope
  3. North-star example (anna)
  4. The six moves
  5. Onboarding objectives
  6. Non-negotiable: always readable
  7. What changes from today
Plan
  1. Definition of done
  2. The changes
  3. Explicitly not in V0
  4. Risks
  5. Build & test sequence
Context
  1. Beyond V0 — the teaching layer
  2. Open questions

Design

The thesis

You 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.

V0 scope

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.

V0 is Japanese-only. There is no language picker and no multi-language plumbing — the entire flow (scripts, kana/kanji, readability, dosage) is built specifically around Japanese. Every reference to "the target language" below means Japanese. Supporting other languages is a deliberate post-V0 concern.

V0 — now

  • Japanese only — no language selection; the whole experience assumes Japanese.
  • A sticky first conversation — onboarding that hooks and gets them producing Japanese naturally.
  • Exposure-first, interactive, calibrated to the person in real time.
  • Quietly capture what they know (seed the memory) — even though we won't resurface it yet.
  • Rewrite the system prompt around the moves below.

Later — retention

  • Proactive texts that resurface their own phrases (the SRS loop).
  • Cadence + anti-annoying logic for agent-initiated messages.
  • Near-miss detection & "say it better" prompts.
  • Long-horizon memory decay / scheduling.
  • Other languages — generalizing past Japanese-only.

North-star example (anna)

The target feel for a V0 first conversation. Not perfect — a reference, not a script.

hi anna
anna
whats up
someone told me you wanna learn a language
which one?
japanese
anna
へえ 本当??
what made you want to learn japanese?
i started learning in middle school because of anime lol and im starting again bc im moving there for 2 months. i also wanna live there in the future
anna
すごいね...
じゃ should we talk in 日本語?
why do you wanna live in 日本?
also just lmk if you dont understand anything
いいよ。まあ子供の時からいつも日本大好きし、日本のボダリングは insanely good

By turn four the user is producing unprompted Japanese — and nobody said "repeat after me." That's the bar.

The six moves

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.

1
Casual named cold-open. "whats up / someone told me you wanna learn a language." Friend-of-a-friend energy — no "I'm your tutor," no app intro.
2
Target language from turn two. へえ 本当?? drops Japanese instantly, no announcing. fixes the all-English onboarding gauntlet
3
Always ends on a question. React warmly → then ask. Statements and questions, so the user keeps producing — not a stream of declarations.
4
Consent-to-ramp + safety net. "should we talk in 日本語? … lmk if you don't understand." Asks permission to level up, gives an escape hatch. fixes the kanji-flood overshoot
5
Ambient info-gathering. Learns anime / middle-school / moving-2-months / wants-to-live-there through real conversation — never a five-question form. (It still works a checklist — ambient ≠ aimless.)
6
It pays off fast. The natural next move becomes answering in the language. Producing without drilling.

Onboarding objectives

Ambient 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:

ObjectiveHow it gets it
Which languageFixed: 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 learningAmbient — falls out of "what's pulling you toward it?"
Experience with the languageActually ask — studied before? how long? where'd you stop? Don't only infer it.
Script knowledge · Japanese-specificDo they read hiragana / katakana / kanji? Probe early — the single biggest dosage input.
Interests / topicsAmbient — 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).

Non-negotiable: always readable

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 yetRomaji (optionally kana with romaji alongside). Latin is always decodable.
Kana, not kanjiKana — and any kanji carries a kana reading (furigana-style, e.g. 日本(にほん)), or just write it in kana.
Kanji tooNormal 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.

What changes from today

TodayV0
Onboarding = a 5-step interrogation; exposure gated to step 5Exposure-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 personaA 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 blobQuietly 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

Plan

The concrete changes to ship V0. Almost entirely a prompt/objective rewrite in one file — no new infra.

Definition of done

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.

The changes

~90% lives in core/agent.mjs. The persona is fine; the onboarding objective is the problem.

1 · Rewrite the onboarding objective core/agent.mjs · currentObjective() core

TODAY

A numbered 5-step gauntlet: ask language → ask reason → gauge level → ask interests → then (step 5) use the language. "Ask ONE thing per message." Exposure gated to the end.

V0

Cold-open as a friend; the moment they name the language, start dropping it. Each turn = react warmly + ask one real question (in-target where natural). Ramp with consent ("should we go in 日本語?") + safety net. Gather reason/interests/level through the chat, saving via 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.

2 · Soften the onboarded gate + share DNA core/agent.mjs core

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.

3 · Calibration: read the room, don't trust the label core/agent.mjs core

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.

4 · Give it a name .env 1 line

Set AGENT_NAME=anna (or your pick). buildSystemPrompt already branches on it — this just turns on the named-friend cold-open.

5 · One small memory addition core/memory.mjs · core/agent.mjs small

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.)

Explicitly not in V0

Any non-Japanese language — V0 is Japanese-only; no language picker or multi-language plumbing. · proactive (agent-initiated) texts · resurfacing & SRS scheduling · Profile/Voice store split · memory-decay. The rest is retention-side — deferred by design. (The Progress / vocab state machine is the Anki backbone — the V1 teaching milestone, the next thing after this V0 onboarding work.)

Risks

RiskMitigation
Model still over-questions or under-switchesIterate the prompt against the test loop; the six moves are explicit targets to grade against.
Less structure → forgets to capture language/levelKeep remember calls baked into the new objective so profile still populates ambiently.
Calibration by prompt alone is weaker than tracked stateAccept for V0 — lean on "consent + back off when asked." The real fix (Progress store) is a later milestone.

Build & test sequence

  1. Set AGENT_NAME in .env.
  2. Rewrite the onboarding objective; align the learning block; soften the gate; update calibration language.
  3. Eyeball the result offline: node -e with the exported buildSystemPrompt({}) to read the new prompt before sending anything.
  4. Test from a fresh number (whitelist is open) — or clear a test handle's entry in core/.memory.json — to get true first-contact behavior.
  5. Run npm run messages + npm start, text in, and grade the thread against the six moves.
  6. Re-test the overshoot case: confirm it ramps with consent and drops to hiragana the moment it's asked.
  7. Iterate the prompt until a cold first thread reads like the anna north-star.

Context

Beyond V0 — the teaching layer

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.

The full tracking spec — a status state machine plus a read-only web view of everything you've picked up — is the Anki backbone, the spine of V1, the teaching milestone that builds on this V0 onboarding work.

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.

Open questions