open-standards/aac/aac-rs/tools/speech/review.json
Transaction Science 9e97fc422b feat(aac-web): a symbol in every cell; OBF with licences and languages; 45-language spoken forms
Symbols (grid_cell.rs, symbol_settings.rs): every cell draws its concept's
symbol above the label (aac_core:🔣:lookup_for_cell), from the set the
person picks in Settings — Mulberry (default), OpenMoji, Blissymbolics or
off — with the label still the accessible name. "Symbols and licences" gives
each set's attribution and CC BY-SA 4.0 link, and says the symbols are free
and will never be charged for. The prerender draws the default set; a saved
choice is restored after hydration. Navigation arrows mirror on right-to-left
boards (Blissymbols never do: a mirrored Bliss character is another one);
Bliss lines stay visible on dark cells and in forced colours. Both service
workers precache every sprite the first page draws and LICENSES.md, and
serve anything under symbols/ before the app-shell rule.

The grid now fills its board area: it was sized by its content (cells about
30 px tall on desktop, and any content change moved every cell). Cells are
now about 120 px on desktop, and identical with symbols on, off or any set.

Right-to-left boards: board_area.rs passed a full locale ("ar-SA") to
language_by_code, so Arabic, Hebrew, Persian and Urdu boards never turned
right to left. Fixed, together with eye-gaze hit-testing (gaze_to_cell),
which now mirrors columns on those boards so gaze lands on the cell it looks at.

OBF (obf.rs, import_export.rs): export carries the person's locale, per-button
translations, licence objects (each symbol set's), images for each symbol
(inline SVG in the browser export, so the file is portable), and
ext_aurasense_locked / word_class / provenance / spoken; import round-trips
them. Other apps' pictures are not stored yet (a warning says so); re-importing
a board asks whether to replace it.

Spoken forms: speech_lexicon.json covers all 45 languages (empty where the
board glosses need none), checked against macOS voices with Whisper
(tools/speech/results.json); tools/speech/review.json lists gloss problems
for native speakers (Hebrew ה, Amharic ው and Zulu i glossed as "the";
Japanese nouns in kana; bound suffixes glossed as words).

tools/symbols/bbox: a small usvg tool reporting symbols' stroke bounding boxes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 01:47:08 -04:00

254 lines
14 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"date": "2026-09-29",
"about": "The review behind crates/aac-core/src/speech_lexicon.json. For each site language: the board glosses (translations_data.json) and default-board words an engine could misread when said alone — single letters, single kana, lone particles, prepositions and conjunctions, abbreviations, bound forms — and what was decided. 'left_alone' words were checked and need no spoken form; 'unresolved' words are misread by at least one engine but no spelling was found that fixes them, or the engines cannot be heard well enough to tell; 'gloss_problems' are glosses a spoken form cannot fix, listed for native review (the glosses themselves are not changed here). check_pronunciation.py speaks every lexicon entry and every 'left_alone' and 'unresolved' word. Model-reviewed only: no native speaker has checked any of this.",
"all_languages": {
"gloss_problems": [
{ "gloss": "the", "problem": "Languages with no definite article gloss 'the' as a demonstrative or third-person pronoun (ur وہ, fa آن, mr तो, gu તે, pa ਉਹ, ta அந்த, te ఆ, ml ആ, kn ಆ, th นั้น, id/ms itu, sw ile, yo náà, fi se, pl/cs ten, uk цей, vi cái). Engines say these correctly, but the cell then means 'that' or 'he'. A native reviewer should decide whether the 'the' cell belongs on these boards." },
{ "gloss": "default-board words with no gloss", "problem": "These default-board words have no entry in translations_data.json, so every language speaks them in English with its own voice: is, for, ball, hug, blanket, question, rest, shoe, silly, student, helper, house, better, worse, worried, hurting, emergency, OK, how many, why not, what's that, my turn, your turn, and the board names Actions, Core, Describing, Nouns, People, Places, Questions, Verbs, Speak, Clear." }
]
},
"languages": {
"en": {
"left_alone": {
"a": "Lower-case, so not announced as a capital; engines give the article's citation form /eɪ/.",
"TV": "Said as the letters T V, which is how the word is said.",
"OK": "Apple voices say 'okay'."
}
},
"es": {
"left_alone": { "a": "The letter's name /a/ is the preposition." }
},
"fr": {
"left_alone": {
"où": "Said /u/ without naming the accent (Apple, eSpeak).",
"là": "Said /la/ without naming the accent."
}
},
"de": {
"gloss_problems": [
{ "gloss": "favorite", "written": "Lieblings-", "problem": "A bound prefix (Lieblings-essen); it cannot stand alone. Engines drop the hyphen and say 'Lieblings'." }
]
},
"pt": {
"left_alone": { "TV": "Said as the letters 'tevê', which is the word." },
"unresolved": {
"é": "The verb 'is' (not a board gloss, but a common one-word reply). Apple voices say /ɛ/; eSpeak says 'é agudo'. No spelling fixes eSpeak without changing the vowel ('eh' gives /e/)."
}
},
"it": {
"left_alone": {
"a": "The letter's name /a/ is the preposition.",
"TV": "Said as the letters 'tivù', which is the word."
}
},
"nl": {
"left_alone": { "TV": "Said as the letters 'tee-vee', which is the word." }
},
"zh": {
"unresolved": {
"教": "'teach' is jiāo; Whisper heard 叫 (jiào) from Tingting, but Whisper does not hear tone reliably. Needs a native ear.",
"干": "'dry' is gān; gàn ('to do') is the other reading. Whisper output was unusable.",
"数": "'count' is shǔ; shù ('number') is the other reading. Whisper heard 书 (shū).",
"量": "'measure' is liáng; liàng ('amount') is the other reading.",
"空": "'empty' is kōng; kòng ('free time') is the other reading.",
"累": "'tired' is lèi; Whisper heard 雷 (léi).",
"切": "'cut' is qiē; qiè is the other reading."
},
"left_alone": {
"长": "'long' is cháng; Whisper heard 'Chang' (cháng), not zhǎng.",
"还": "'still' is hái; Whisper heard hāi, not huán."
}
},
"ja": {
"left_alone": {
"と": "The particle is read 'to', as written.",
"ひ": "Read 'hi'.",
"て": "Read 'te'.",
"め": "Read 'me'.",
"は": "Read 'ha' (not the topic particle 'wa') when alone; correct for 'teeth'.",
"き": "Read 'ki'.",
"え": "Read 'e'.",
"も": "Read 'mo'.",
"に": "Read 'ni'; Whisper heard the number 2.",
"ご": "Read 'go'; Whisper heard the number 5."
},
"gloss_problems": [
{ "gloss": "four", "written": "し", "problem": "Said alone, four is よん (yon); し is the counting-sequence reading. Whisper heard 4, so engines say shi." },
{ "gloss": "nouns, verbs and adjectives", "written": "hiragana", "problem": "Almost every gloss is in hiragana where Japanese writes kanji (手 目 歯 木 日 絵 本 家 水 山 川 雨 紙 …). Kanji tell the engine the reading and pitch accent; kana leave it to guess between homophones (あめ 雨/飴, かみ 紙/髪/神, はし 箸/橋)." },
{ "gloss": "nose, flower", "written": "はな", "problem": "Both glosses are はな (鼻, 花); written in kanji they would differ." },
{ "gloss": "need, be, stay", "written": "いる", "problem": "'need' is 要る, 'be/stay' is 居る; they differ in pitch accent and are indistinguishable in kana." }
]
},
"ko": {
"left_alone": {
"에": "Hangul syllables are read as sounds; letter names apply only to lone jamo (ㅇ is read '이응'), which no gloss uses.",
"TV": "Koreans say the letters (티비); Whisper heard 'TV'."
}
},
"ar": {
"gloss_problems": [
{ "gloss": "the", "written": "ال", "problem": "The article is a prefix and cannot stand alone; engines say 'al'." },
{ "gloss": "promise, count", "written": "أعد", "problem": "Same letters, different words (أَعِدُ 'I promise', أَعُدُّ 'I count'); bare, the engine picks one for both cells. Vowel marks on the glosses would separate them." }
]
},
"he": {
"gloss_problems": [
{ "gloss": "the", "written": "ה", "problem": "The article is a prefix and cannot stand alone. Apple (Whisper heard 'hey') and eSpeak (/he/) both say the letter's name. A spoken form 'הַ' gives 'ha', but a lone ה is more often a spelled letter, so it is not in the lexicon." },
{ "gloss": "to, don't", "written": "אל", "problem": "'to' is אֶל (el), 'don't' is אַל (al); both cells show אל and engines say 'al'. The lexicon maps a written word to one spoken form, so this needs vowel points on the 'to' gloss, or another gloss." },
{ "gloss": "there, name", "written": "שם", "problem": "'there' is שָׁם (sham), 'name' is שֵׁם (shem); engines say 'sham' for both." },
{ "gloss": "here, mouth", "written": "פה", "problem": "'here' is פֹּה (po), 'mouth' is פֶּה (pe); both cells show פה." }
]
},
"ur": {
"gloss_problems": [
{ "gloss": "will", "written": "گا", "problem": "The future suffix (-gā) cannot stand alone." },
{ "gloss": "I, in", "written": "میں", "problem": "'I' is مَیں (main), 'in' is مِیں (mẽ); both cells show میں." }
]
},
"fa": {
"left_alone": {
"کی": "'when' (key); eSpeak says /kej/.",
"پر": "'full' (por); eSpeak says /por/, not 'par'.",
"کت": "'jacket' (kot); eSpeak says /kot/."
}
},
"hi": {
"left_alone": {
"से": "A Devanagari syllable is read as its sound, never as a letter name.",
"को": "Read as the postposition 'ko'.",
"में": "Read 'mẽ'.",
"पर": "Read 'par'.",
"भी": "Read 'bhī'."
}
},
"bn": {
"left_alone": { "ও": "The letter's sound /o/ is the word 'too'." },
"gloss_problems": [
{ "gloss": "the", "written": "টা", "problem": "The classifier -টা is a suffix and cannot stand alone." },
{ "gloss": "to", "written": "কে", "problem": "The case ending -কে is written joined to its noun; alone it is read as কে 'who'." }
]
},
"ta": {
"gloss_problems": [
{ "gloss": "to", "written": "க்கு", "problem": "The dative case ending is a suffix and cannot stand alone; eSpeak says 'kku'." }
]
},
"te": {
"gloss_problems": [
{ "gloss": "to", "written": "కు", "problem": "The dative case ending is a suffix and cannot stand alone." },
{ "gloss": "with", "written": "తో", "problem": "The instrumental/comitative case ending is a suffix and cannot stand alone." }
]
},
"ml": {
"gloss_problems": [
{ "gloss": "to", "written": "ക്കു", "problem": "The dative case ending is a suffix and cannot stand alone." }
]
},
"mr": {
"gloss_problems": [
{ "gloss": "to", "written": "ला", "problem": "The dative postposition is written joined to its noun and does not stand alone." },
{ "gloss": "toward", "written": "कडे", "problem": "Written joined to its noun (घराकडे)." }
]
},
"kn": {
"gloss_problems": [
{ "gloss": "to", "written": "ಗೆ", "problem": "The dative case ending is a suffix and cannot stand alone." },
{ "gloss": "since", "written": "ನಿಂದ", "problem": "The ablative case ending is a suffix and cannot stand alone." }
]
},
"gu": {
"gloss_problems": [
{ "gloss": "to", "written": "ને", "problem": "The postposition is written joined to its noun and does not stand alone." },
{ "gloss": "since", "written": "થી", "problem": "Written joined to its noun." }
]
},
"vi": {
"left_alone": {
"to": "A Vietnamese syllable ('big'); Latin letters in Vietnamese are read as syllables, not named.",
"no": "A Vietnamese syllable ('full')."
}
},
"ru": {
"left_alone": {
"о": "The letter's name /o/ is the preposition.",
"я": "The letter's name /ja/ is the pronoun."
}
},
"pl": {
"left_alone": { "o": "The letter's name /ɔ/ is the preposition." }
},
"uk": {
"left_alone": { "я": "The letter's name /ja/ is the pronoun." }
},
"cs": {
"left_alone": { "o": "The letter's name /o/ is the preposition." }
},
"sv": {
"left_alone": {
"i": "The letter's name /iː/ is the preposition.",
"yr": "eSpeak says /yːr/; Whisper could not hear Apple's reading (inconclusive).",
"TV": "Said as the letters 'teve', which is the word."
}
},
"da": {
"left_alone": {
"i": "The letter's name /iː/ is the preposition.",
"tv": "Said as the letters 'te-ve', which is the word."
}
},
"nb": {
"left_alone": {
"i": "The letter's name /iː/ is the preposition.",
"tv": "Said as the letters 'te-ve', which is the word."
}
},
"am": {
"gloss_problems": [
{ "gloss": "the", "written": "ው", "problem": "The definite ending -u/-w is a suffix and cannot stand alone; eSpeak says 'wɨ'." },
{ "gloss": "before, after, during, since", "written": "ከ...በፊት, ከ...በኋላ, በ...ጊዜ, ከ...ጀምሮ", "problem": "Circumpositions written with an ellipsis for the missing noun; a cell speaks the two halves with nothing between." }
]
},
"ha": {
"left_alone": { "i": "Hausa 'yes' is /iː/, the letter's own sound; lower-case, so no 'capital'." },
"gloss_problems": [
{ "gloss": "the", "written": "-n", "problem": "The definite ending is a suffix and cannot stand alone." }
]
},
"yo": {
"left_alone": { "ó": "The third-person pronoun is the vowel with a high tone." }
},
"zu": {
"gloss_problems": [
{ "gloss": "the", "written": "i", "problem": "Zulu has no article; i- is a noun-class prefix and cannot stand alone." },
{ "gloss": "with", "written": "no", "problem": "na- fused with a noun's initial vowel (no- before u-); it does not stand alone." },
{ "gloss": "to", "written": "ku", "problem": "A locative/class prefix; it does not stand alone." },
{ "gloss": "have", "written": "na", "problem": "The associative 'have' needs a subject concord (ngina-, una-); na alone is not a verb." },
{ "gloss": "be", "written": "ba", "problem": "The verb stem -ba needs a subject concord (ngiba …)." },
{ "gloss": "tall, long", "written": "de", "problem": "The adjective stem -de needs a class prefix (-de → mude, lide …)." }
]
},
"tr": {
"left_alone": {
"o": "Lower-case 'o' is read /o/, the pronoun; only the capital is announced ('büyük o'), and the lower-case rule handles that.",
"TV": "Said as the letters 'te-ve'."
},
"gloss_problems": [
{ "gloss": "to", "written": "-e/-a", "problem": "The dative case suffix in two harmony forms; it cannot stand alone, and the cell reads 'e a'." }
]
},
"el": {
"unresolved": {
"ο": "The masculine article /o/. Every engine names the lone letter (Apple 'μικρό όμικρον', eSpeak 'όμικρον', also with a full stop); ω is named too, and 'ω!' changes the word. Not a board gloss on its own."
},
"gloss_problems": [
{ "gloss": "the", "written": "ο/η/το", "problem": "Three articles joined by slashes; eSpeak reads the slash aloud in English ('o slash i slash to'). A cell should hold one word." }
]
},
"hu": {
"gloss_problems": [
{ "gloss": "the", "written": "a/az", "problem": "Two forms joined by a slash; eSpeak reads it 'a per az'." },
{ "gloss": "in, on, with, to", "written": "-ban/-ben, -on/-en/-ön, -val/-vel, -hoz/-hez/-höz", "problem": "Case suffixes in their harmony forms; they cannot stand alone, and eSpeak reads the slash as 'per' ('ban per ben')." }
]
}
}
}