# How to add a language module Use this guide with the existing Swift package and Xcode project. [The architecture explanation](language-architecture.md) describes progress isolation and storage decisions. 1. Add a file in `apps/ios/Core/Languages/`, following `Spanish.swift` or `Norwegian.swift`. Define a `LanguageModule` with a unique, stable language ID, display names, locale, greeting, speech and writing guidance, lemma rules, six teaching stages and a topic placeholder. Include `lookupUnavailableReply`, the spoken fallback when a web lookup is unavailable, in the target language. Include valid regional alternatives in the correction guidance. 2. Override culture-specific themes by their existing IDs. Keep shared IDs stable. New common themes belong in `apps/ios/Core/Themes.swift`. 3. Register the module in `LanguageRegistry.all`. The learning-language picker, shared teaching policy, evidence validation and progress projection use the registry automatically. Keep published IDs stable and retain modules needed to open existing learning records. Run `python3 scripts/export_android_content.py` so the Android client picks up the new module. 4. Add language fixtures in `apps/ios/Tests/LanguageTests.swift`. Check supported versus independent recall, evidence from another language, archive round trips, vocabulary isolation and prompt contamination. Add a UI check for selecting the language and returning to an existing one. 5. Run `swift test --package-path Mural` from the workspace root, then build and run the native UI tests described in the [README](../README.md). Core Swift files are discovered by Swift Package Manager. If you add app files, also run `python3 Mural/scripts/generate_project.py`. 6. Validate a short live conversation on an iPhone with its saved API key: greeting, input in a support language, target-language output, corrections, subtitles, a cultural theme and a sourced topic. Confirm progress remains separate after switching and relaunching. Review pronunciation and correction quality with a competent speaker. For an explicitly authorized audio check in a Debug build, launch with `--verify-audio --verify-language=`. It makes two real API connections, uses temporary learning data, and writes non-content diagnostics to `Documents/audio-verification.json` in the app container. It is excluded from Release builds and ordinary tests. Network and provider failures still need investigation; a successful connection alone does not establish teaching quality.