Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Built with SwiftUI and Liquid Glass on iPhone, and Jetpack Compose on Android. L

## Android

A native Android client is available in [`apps/android/`](apps/android/README.md), with voice and written conversation, the same eight language modules, local learning records and iPhone-compatible JSON backups. Its interface is English, and Spanish on a phone set to Spanish. It runs on Android 8.0 or later and uses your own OpenAI API key stored with Android Keystore. The iPhone client remains available below.
A native Android client is available in [`apps/android/`](apps/android/README.md), with voice and written conversation, the same nine language modules, local learning records and iPhone-compatible JSON backups. Its interface is English, and Spanish on a phone set to Spanish. It runs on Android 8.0 or later and uses your own OpenAI API key stored with Android Keystore. The iPhone client remains available below.

See the [Android installation/build guide](docs/run-on-android.md) and [Android verification record](verification/android-validation.md). Build a personal-install APK with Java 17 and Android SDK 36:

Expand Down Expand Up @@ -83,7 +83,9 @@ A free Personal Team can run the app on your own phone; TestFlight and App Store
- **A fresh start:** the Talk screen returns to its greeting 15 seconds after a conversation ends. Tap **New conversation** to reset immediately. Your saved conversations and learning remain.
- **Local records:** export or import a JSON learning backup, delete a conversation, or delete all learning data from Settings.

The modules teach Norwegian Bokmål with an Eastern Norwegian voice target, Spanish from Spain, international English, French from France, German from Germany, Italian from Italy, Brazilian Portuguese and Standard Mandarin with Simplified Chinese. Each language has its own conversation themes, teaching guidance and progress. Valid regional alternatives are accepted.
The modules teach Norwegian Bokmål with an Eastern Norwegian voice target, Spanish from Spain, international English, French from France, German from Germany, Italian from Italy, Brazilian Portuguese, Standard Mandarin with Simplified Chinese, and Tagalog (Filipino) from the Philippines. Each language has its own conversation themes, teaching guidance and progress. Valid regional alternatives are accepted.

Tagalog includes six teaching stages, Philippine conversation settings and vocabulary guidance that preserves verb focus. It uses the same meanings, word lookup and independent progress flows. [Teaching choices and references](docs/tagalog.md) explain the `tl` identity and the limits of automatic language detection.

On iPhone, Mandarin includes optional pinyin in Talk, transcripts and word details. Chinese word lookup uses word boundaries, and the original characters remain available for copying from transcripts. Pinyin uses system dictionary readings; names, ambiguous words and tone changes in connected speech still need listening checks. Voice accent and teaching guidance are model instructions, and fluent-speaker review is still needed before making pronunciation or learning-effectiveness claims.

Expand Down Expand Up @@ -115,12 +117,14 @@ xcodebuild -project apps/ios/Mural.xcodeproj -scheme Mural \
CODE_SIGNING_ALLOWED=NO ARCHS=arm64 ONLY_ACTIVE_ARCH=YES build
```

For UI tests, create or select an iPhone 17 simulator in Xcode, then run **Product → Test**. The tests use in-memory fixtures and do not require an API key. More commands and preview options are in [the build guide](docs/build-and-test.md).
For UI tests, create a dedicated iPhone 17 simulator in Xcode, then run **Product → Test**. Most tests use in-memory fixtures; the relaunch test also writes language preferences to that simulator's local store. No API key is required. More commands and preview options are in [the build guide](docs/build-and-test.md).

The iPhone language release recorded on 13 September 2026 passed **70 core tests and 20 native UI tests**, including Mandarin pinyin, all four new onboarding choices and the largest accessibility text size. **79 backend tests** passed with an isolated PostgreSQL database and no skips. German, Italian, Brazilian Portuguese and Mandarin each passed a live iPhone check using synthetic typed replies and real voice output, meanings and word lookup. These checks do not establish human speech-recognition, pronunciation or correction quality. [Verification record](verification/validation.md)
On 13 September 2026, the nine-language build passed **90 core tests, 25 native UI tests and 80 backend tests**, with no failures or skipped backend tests. Debug simulator and unsigned Release iPhone builds passed. Tagalog checks include the largest accessibility text size, transcript retention, language isolation and normal relaunch persistence. Tagalog real-device and proficient-speaker review remain pending. Earlier German, Italian, Brazilian Portuguese and Mandarin live checks used synthetic typed replies and real voice output; those checks do not establish human speech-recognition, pronunciation or correction quality. [Verification record](verification/validation.md)

The Android release branch is being prepared separately. See [release progress](verification/android-release-progress.md) for its checks and remaining gates.

After integration with the native-app monorepo on 14 September 2026, the Tagalog branch passed **93 Swift core tests, 25 iOS UI tests, 258 Android JVM tests, 304 API tests and 45 repository-tool tests**. Android lint and Debug APK assembly, cross-platform content checks, and the unsigned Release iPhone build passed. Tagalog is included in Android's generated catalog; physical-device and live-provider review remain pending. [Integration verification](verification/validation.md#14-september-2026--tagalog-integration-with-the-native-app-monorepo)

## Code map

| Directory | Contents |
Expand Down
87 changes: 87 additions & 0 deletions TAGALOG-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Tagalog (Filipino) — Philippines implementation record

This completes the repository plan prepared on 13 September 2026 against `4aef373d85d5d64aee5d6adbf43092dae83c1f55`. Implementation and automated verification are the delivery scope. Real-device conversation and proficient-speaker review remain explicitly pending.

## Feature contract

| Field | Value |
| --- | --- |
| Module | `LanguageModule.tagalog` in `apps/ios/Core/Languages/Tagalog.swift` |
| Stable learning/storage ID | `tl` |
| Display name and native name | `Tagalog (Filipino)` |
| Variety / picker label | `Philippines` / `Tagalog (Filipino) · Philippines` |
| Locale | `tl-PH` |
| Greeting / lookup word | `Kumusta!` / `kumusta` |
| Writing system | Contemporary Latin-script Tagalog |

Filipino is a learner-facing alias, with a single Tagalog progress namespace. The target uses the same onboarding, Settings, voice, typed reply, help, meaning, lookup, theme, topic, vocabulary and backup paths as existing languages. It does not add a second Filipino module or new subtitle/interface localization. The original eight IDs and Norwegian default stay unchanged.

## Implementation map

| Planned work | Implementation |
| --- | --- |
| Complete compiled language module | `apps/ios/Core/Languages/Tagalog.swift`: regional speech, writing, lemma rules, six challenge stages, topic placeholder and target-language lookup fallback. |
| Register the ninth target | `apps/ios/Core/Languages/LanguageModule.swift`: append `.tagalog`; both pickers derive their options and labels automatically. |
| Philippine themes | Override the existing `coffee`, `groceries`, `travel`, `cabin` and `traditions` IDs; inherit the other 19 themes. |
| All prompt paths | Existing `TeachingPolicy` functions interpolate the module, including its display alias; language-specific guidance keeps the target explicit. |
| Prevent false speech redirects | `TeachingPolicy.supportsSpeechLanguageDetection` declines automatic detection for `tl`; the coordinator avoids that unreliable check. Other targets retain their previous behavior. |
| Honest live-check diagnostics | `apps/ios/App/LanguageVerification.swift`: Tagalog reply/lookup fixtures, actual detector label/confidence, separate mechanical `flowPassed`, detection-dependent `passed` and pending language-quality review. |
| Native previews | `ConversationCoordinator.prepareConversationPreview`: matched Tagalog caption/meaning; Debug active-state fixture for the language-switch lock. |
| Experimental hosted locale | `services/api/src/live-provider.ts`: `tl-PH` regional target; negative aliases remain unsupported before any reservation/provider call. |
| Core regressions | `apps/ios/Tests/TagalogTests.swift`, expanded catalog fixtures, cross-language meaning and final-assessment cases. |
| Native regressions | `apps/ios/UITests/MuralUITests.swift`: onboarding, largest accessibility text, subtitle choice, Settings/themes/Words, transcript retention, switching lock and normal relaunch persistence. |
| Hosted regressions | Locale/provider request test plus PostgreSQL-backed Tagalog credit/minute reservation, settlement and invalid-alias coverage. |
| Android integration | Regenerated `apps/android/app/src/main/java/chat/mural/core/Languages.kt` from the Swift catalog; registry, English-support and archive-isolation regression tests. |
| Documentation | README, architecture, add-language/build guides, server contract, store metadata, [Tagalog references](docs/tagalog.md) and [verification record](verification/validation.md). |

## Research and teaching decisions

[Tagalog teaching choices and references](docs/tagalog.md) records the sources, including Tagalog.com dictionary entries and the University of Hawai‘i's aspect/focus grammar notes. The code contains original guidance, not a scraped dictionary or lesson corpus.

- Use everyday Tagalog and context-appropriate polite address; accept valid regional usage and learner support languages.
- Teach aspect in context, with voice/focus and participant markers, rather than mechanically copying English tense categories.
- Group aspect variants under a consistent citation form while retaining meaningful affixes and distinct senses. For example, `kumain` and `kainin` stay separate.
- Preserve source spelling, diacritics, apostrophes, hyphens and exact quotations. Generated pronunciation annotations do not become learning evidence.
- Keep Philippine settings specific without treating all communities as culturally or linguistically identical.

## Detector finding and chosen tradeoff

The local `NLLanguageRecognizer` probe (Xcode 26.6 / Swift 6.3.3) returned the following results on both macOS and an iOS 26.5 simulator:

| Input | Leading result |
| --- | --- |
| `Kumusta! Gusto kong matutong magsalita ng Tagalog. Maaari ba tayong mag-usap tungkol sa pagkain at paglalakbay sa Pilipinas?` | Indonesian (`id`), 0.99247 confidence |
| `Kung magbubukas ka ng kapihan, paano mo mapapanatiling abot-kaya ang mga presyo habang gumagamit ng mga lokal na sangkap?` | Indonesian (`id`), 0.99974 confidence |
| `Gusto ko ng kape.` | Croatian (`hr`), 0.38728 confidence |

The long samples exceed the coordinator's 70-character threshold and the policy's 0.88-confidence threshold. A catalog-only addition would redirect valid speech. The fix disables this detector-based guard for Tagalog while retaining explicit target-language prompts. It does not alias Indonesian to Tagalog or force a positive detector result. Actual English drift also cannot be corrected through this detector, so live review must check for it.

The verification helper records this limit: `flowPassed` can succeed independently, while `passed` requires reliable target-language detection. Neither outcome certifies pronunciation, recognition of a human learner, correction accuracy or teaching effectiveness.

## Test coverage and acceptance

- [x] One stable ID, correct locale and display alias; original language identities retained.
- [x] Every prompt path, all six stages and stable cultural-theme IDs covered.
- [x] Unaided recall, typed/subtitle-assisted practice, imitation, foreign/mixed/alias proposals and invalid provenance covered.
- [x] Aspect-family storage, separate focus/sense keys, hidden cognates, punctuation and exact archive text covered.
- [x] Archive v2 selection/topics/import and rejection of unsupported IDs tested; existing v1 migration retained.
- [x] Late meaning results/errors and final assessments cannot cross into another target.
- [x] Detector regressions cover high-confidence wrong labels, unsupported observations and unchanged behavior for previous targets.
- [x] Native onboarding, Settings, theme and vocabulary labels, large text, transcript retention, active switching lock and normal relaunch tests implemented.
- [x] Server accepts `tl-PH`, rejects unsupported aliases without credit reservation, and settles the fake-provider session correctly.

See [the verification record](verification/validation.md) for executed checks, totals and build results. Simulator previews and the test database contain temporary synthetic data; they make no real provider calls.

## Compatibility and limits

No archive-version change, SwiftData migration, new package dependency or project regeneration is required. Older app versions without the module reject `tl` archives; upgrade before importing. Retain `tl` in future releases so saved records remain readable. The server addition does not enable hosted accounts/billing or require server deployment for the current native BYOK path.

`LearningEngine.validate` checks proposal labels and transcript provenance, not the actual linguistic identity of the text. Tests using supplied lemmas validate storage and evidence behavior; they cannot establish that a model always produces correct lemmas or assessments. No inference of independent learning quality is made from synthetic typed fixtures.

Remaining release review:

- Real iPhone voice conversation with the saved API key, speaker/headphones, interruption, mute and closure.
- Human speech recognition, generated translations, sourced-topic behavior and correction/lemma quality in actual provider output.
- Proficient-speaker review of pronunciation, register, naturalness and cultural examples.

Run the Debug helper with `--verify-audio --verify-language-flow --verify-language=tl` when real-device testing is available. It uses temporary learning records and incurs API usage. The full manual checklist is in [the build guide](docs/build-and-test.md) and [verification record](verification/validation.md).
4 changes: 2 additions & 2 deletions apps/android/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Mural for Android

Native Kotlin and Jetpack Compose client for Android 8.0 or later. It offers voice and written conversation, eight learning languages, 24 themes, meanings, vocabulary and local history, using the owner's OpenAI API key. Mandarin captions link each word and show optional pinyin on Android 10 or later; Android 8 and 9 keep word links without pinyin.
Native Kotlin and Jetpack Compose client for Android 8.0 or later. It offers voice and written conversation, nine learning languages including Tagalog (Filipino) from the Philippines, 24 themes, meanings, vocabulary and local history, using the owner's OpenAI API key. Mandarin captions link each word and show optional pinyin on Android 10 or later; Android 8 and 9 keep word links without pinyin.

Word taps in all eight languages open a contextual meaning sheet, matching the iOS flow. Mandarin uses a bundled offline phrase dictionary with an ICU fallback; unresolved common ambiguous readings retain their source characters.
Word taps in all nine languages open a contextual meaning sheet, matching the iOS flow. Mandarin uses a bundled offline phrase dictionary with an ICU fallback; unresolved common ambiguous readings retain their source characters.

Interface copy lives in `res/values` (English) and `res/values-es` (Spanish); Android picks the translation from the phone's language.

Expand Down
Loading