# D71. The package's languages are the author's choice; a translation not approved goes in with a warning (6 Nov 2026)

Until now a package of every language (D59) held the course's own language and each translation ready and approved, nothing else; the app built it when « Langue » was enabled in the player, and its Aperçu held the course's own language only. The founder found the workflow unnatural: to try a translation in the Aperçu it had to be approved first, and an author could not choose which languages leave. His words: the Aperçu should carry the language switcher whether the translation is validated or not, so that it can be tried; when several languages exist, Publier should let the author pick the languages of the package, with a warning when a translation is not validated, without forbidding it.

Decided:
- **The Aperçu tries every translation.** `elabora preview` (the app's Aperçu) builds the course's own language and every translation it has, as far as each goes (an untranslated text shows in the course's language), with « Langue » shown whatever the player says (`BuildOptions.tryLanguages`). It says nothing of approvals: it is the author's bench, as « Déverrouiller la progression » is. A translation edited rebuilds it.
- **The package's languages are chosen.** `course.json delivery.languages` (schema 0.1.11): a list of language tags (the course's own always in, first), or `"all"` (the course's own and every translation ready and approved, as D59). Absent: the course's own alone, as before. `elabora build --languages en,fr`, MCP `elabora_build` `languages: ["en", "fr"]`, `@elabora/node` `build({ languages })` and `publishCourse({ languages })` take the same for one build; `--languages all` stays. The app's Publier writes the list (« Langues du paquet »), so that the CLI builds what Publier builds. The languages no longer follow « Langue » in the player.
- **A translation not approved is a warning, not a refusal.** A language named goes in as it is. Its translated plan not approved: `W_PACKAGE_LANGUAGE_NOT_APPROVED`; texts still to translate or out of date (they show in the course's language): `W_PACKAGE_LANGUAGE_INCOMPLETE`; a language without a translation is left out, `W_PACKAGE_LANGUAGE_UNKNOWN`. An agent that builds with one tells the author, who approves it (Traduction › Versions, or through the agent with their yes, D70). Only a client delivery (`--release`), which already needs the source plan validated (A5), needs each translation's approved: the warning is an error there.
- **« Langue » shows by itself.** The item is in a new course's top bar, after the spacer, and shows once the package holds two languages (`one language in the package` otherwise). A course whose top bar was set before keeps it as it is; Publier says when the package holds several languages and « Langue » is not in the player, with « Ajouter » at hand.
- **The language learners start in.** First found of: the learner's own choice, kept with their progress (now kept even when it is the course's own); `?lang=`; the learner's preference the LMS gives (SCORM 1.2 `cmi.student_preference.language`, read only by a package of several languages; SCORM 2004's `cmi.learner_preference.language` and cmi5's `cmi5LearnerPreferences` `languagePreference`, a list in order, go through the same `LmsAdapter.preferredLanguages`); the author's default, `delivery.defaultLanguage` (0.1.11; `W_PACKAGE_DEFAULT_LANGUAGE` when the package does not hold it); the course's own. Codes are matched loosely, as LMSs write them as they like: case and `_` aside, then without the region (`fr_FR` asks `fr`, `pt` asks `pt-BR`). The browser's language is still not read (D59).
- **One package per language, for LMSs that keep language versions.** `delivery.languagePackages: "each"` (0.1.11; `elabora build --packages each`, MCP `packages: "each"`, `@elabora/node/language-packages` `buildLanguagePackages`): the course's own package, then one package for each other language of `delivery.languages`, as `elabora translate build` makes it, each said as above. The web publication stays one module of every language.

What LMSs do with the language (checked on 6 Nov 2026, sources in the session's report):
- **The preference is mostly empty.** SCORM 1.2 gives `cmi.student_preference.language` as a free string; SCORM 2004 a `language_type`; cmi5 makes the AU read `languagePreference` (RFC 5646 tags in order) at start. Moodle's `mod_scorm` fills neither from the user's profile (`datamodels/scorm_12lib.php`, `scorm_13lib.php`: an empty string until the SCO writes one); SCORM Cloud uses the browser's language for its own interface only. Hence the author's default: without it, a learner in Moodle gets the course's own language.
- **Several LMSs keep language versions themselves**: Docebo (a folder per language in a multi-language course, one SCORM each, the learner choosing from a list), SuccessFactors (an item's locales), Cornerstone (one learning object per language, or one that holds several and shows a menu in the player). One package per language suits the first two, and gives reports per language; one package of every language suits Cornerstone's second way and LMSs without versions.
- **What the LMS records does not change with the language** (D59): interactions, objectives and the location are the same in every language, so a learner's record reads the same and reports are not split.

Weighed:
- **Approval required, with a « draft » switch.** Rejected: the founder wants to try and deliver a translation before its approval, and a warning that names the way to approve says enough.
- **Absent `delivery.languages` meaning every approved translation.** Rejected for now: every CLI build of a translated module would become a package of several languages, larger, without the author asking. The app shows the choice in Publier, where it is made in a click.
- **The browser's language before the author's default.** Rejected again (D59): in a company's LMS it says little about the learner, and the author's default says what the client wants.
- **Writing the learner's choice to `cmi.student_preference.language`.** Not needed: the choice is kept with the progress, and LMSs that read it back are rare.

*Revisit if:* an LMS reports per language (then write the preference), learners ask to start in their browser's language, or a client wants a package of several languages without the course's own.
