The garden learns which language a card is in, and read-aloud stops guessing

Phase 28 (c), the last of the phase. A word met inside a Portuguese
document is a Portuguese card: migration 0018 mirrors documents.doc_lang
onto vocab_words, set server-side from the ownership lookup capture was
already making. Every card still reviews — filtering the queue to the
half she is learning would drop the words she actually met.

Read-aloud was the larger surprise. detectLang routed Han/kana to
Chinese and everything else to en-US, so the zh pair was accidentally
right and every Latin pair wrong. doc_lang now reaches the client
read-only on the document JSON, and docLang(text, verdict) answers for a
passage taken out of it — with the script test still winning, because
quoted Chinese must never be spelled out one "Chinese letter" at a time.

Claude-Session: https://claude.ai/code/session_01GJHNvirh7Hzhc9RL3HAvz7
This commit is contained in:
prosolis
2026-07-28 23:45:26 -07:00
parent 29eb2fe1fc
commit 466055020f
15 changed files with 352 additions and 57 deletions
+6 -3
View File
@@ -825,13 +825,13 @@ func (h *Handler) setStatus(w http.ResponseWriter, r *http.Request, status strin
// hands over a reusable chunk, which is the only thing worth reviewing in a week.
func (h *Handler) plant(id, userID string) {
var s db.Suggestion
var contentText string
var contentText, docLang string
err := h.DB.QueryRow(
`SELECT s.type, s.original, s.replacement, s.explanation, s.doc_id, d.content_text
`SELECT s.type, s.original, s.replacement, s.explanation, s.doc_id, d.content_text, d.doc_lang
FROM suggestions s JOIN documents d ON d.id = s.doc_id
WHERE s.id = ? AND d.user_id = ?`,
id, userID,
).Scan(&s.Type, &s.Original, &s.Replacement, &s.Explanation, &s.DocID, &contentText)
).Scan(&s.Type, &s.Original, &s.Replacement, &s.Explanation, &s.DocID, &contentText, &docLang)
if err != nil {
if !errors.Is(err, sql.ErrNoRows) {
log.Printf("suggestions: could not read %s for planting: %v", id, err)
@@ -850,6 +850,9 @@ func (h *Handler) plant(id, userID string) {
Meaning: s.Explanation,
Example: correctedSentence(contentText, s.Original, s.Replacement),
DocID: &docID,
// The chunk is her own sentence, corrected — so it is in the document's
// language, whatever the collocation pass was framed in.
Lang: docLang,
}); err != nil {
log.Printf("suggestions: could not plant %s: %v", id, err)
}