The translate card, pointed the other way, and a call that no longer happens
Phase 28's step (b): both remaining items are about direction, and both had
a wrong answer that looked right.
isTranslation could not simply be read backwards. readsAsEnglish is a
deliberately low bar — Latin letters, not swamped by another script — which
every Portuguese sentence clears as easily as English does, so swapping its
two halves would have called every genuine Portuguese correction inside a
Portuguese document a translation. The flipped direction uses sentenceLang
from doclang.go instead, where English has its own curated marker list and
has to out-evidence the pair language to win. The English-document path is
untouched; reconcilePending carries the verdict to ask the question the
right way round.
The tap-through's whole observable change is a model call that stops
happening. /suggestions/{id}/translate now recovers the explanation's
language by re-running targetFor rather than assuming the pair, which gives
today's answer everywhere except the case that was broken: the Portuguese
writer whose explanation already arrived in Portuguese, previously
round-tripped through the model into Portuguese again. It answers "" there,
and the client's existing `res.translation.trim() || explanation` fallback
seeds the bubble with the explanation itself — no frontend change at all.
It deliberately does not render that explanation into English on the
grounds that English is technically the other half: an unasked-for
rendering into the language she is practising is noise, not a seed.
Tests pin both directions of the detector, with Portuguese-in-Portuguese as
the case the file exists for, plus four handler tests through the real
/check and /translate paths — including the skipped seed asserting the
model was never called, and the learning_pair zh learner whose English
explanation still renders into Chinese.
Left of the phase: (c) the garden's language tagging and read-aloud.
Claude-Session: https://claude.ai/code/session_01GJHNvirh7Hzhc9RL3HAvz7
This commit is contained in:
@@ -28,16 +28,35 @@ import (
|
||||
// common words a sentence in that language can hardly avoid and an English
|
||||
// sentence has no reason to contain.
|
||||
|
||||
// isTranslation reports whether this edit is her own language rendered into
|
||||
// English, rather than a correction to her English. Both halves must hold: the
|
||||
// quoted span reads as the pair language, and what Petal offers back reads as
|
||||
// English. The second half matters — a Chinese span rewritten into different
|
||||
// Chinese is something else entirely, and Petal has no business calling it a
|
||||
// translation.
|
||||
func isTranslation(original, replacement, pairLang string) bool {
|
||||
// isTranslation reports whether this edit is a rendering of one language into
|
||||
// the other, rather than a correction. Both halves must hold: the quoted span
|
||||
// reads as one language, and what Petal offers back reads as the other. The
|
||||
// second half matters — a Chinese span rewritten into different Chinese is
|
||||
// something else entirely, and Petal has no business calling it a translation.
|
||||
//
|
||||
// Which way it points follows the document (Phase 28). In an English document
|
||||
// the translate card is her language rendered into English — she reached for a
|
||||
// sentence she couldn't say yet, and Petal said it for her. In a document she
|
||||
// wrote in her own language the useful card is the mirror image: an English
|
||||
// sentence she dropped into her Portuguese, rendered into Portuguese. Asking the
|
||||
// English-document question there would label nothing, and the card would file
|
||||
// as a correction to prose that was never wrong.
|
||||
//
|
||||
// The flipped direction cannot be the same test read backwards. `readsAsEnglish`
|
||||
// is a low bar on purpose — Latin letters, not swamped by another script — which
|
||||
// every Portuguese sentence also clears, so using it on the *original* would
|
||||
// call every genuine Portuguese correction a translation. The flipped test
|
||||
// instead uses the sentence-level vote from doclang.go, where English has its
|
||||
// own marker list and has to out-evidence the pair language to win.
|
||||
func isTranslation(original, replacement, pairLang, docLang string) bool {
|
||||
if strings.TrimSpace(original) == "" || strings.TrimSpace(replacement) == "" {
|
||||
return false
|
||||
}
|
||||
if normalizeDocLang(docLang) == docLangPair {
|
||||
p := normalizePairLang(pairLang)
|
||||
return sentenceLang(original, p) == docLangEnglish &&
|
||||
sentenceLang(replacement, p) == docLangPair
|
||||
}
|
||||
return readsAsPairLang(original, pairLang) && readsAsEnglish(replacement)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user