Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: Configuration and time

Configuration and time

What the compiler checks of translations

On this page

jadpo check checks every language file against the messages, enums, emails and failures it words. Each problem has its own error, listed at the end of the page.

Mistakes in a language file

  • a member that no message, enum, email or failure declares (translation.member_unknown, with the nearest name);
  • a member written twice (translation.member_duplicate);
  • a member in the wrong shape for what it words, such as a string where a block of values is needed, or the reverse (translation.wording_shape);
  • a wording that isn't a plain string with {field} placeholders (translation.wording_invalid);
  • a variant that isn't a value of the enum, or a plural form the language doesn't use (translation.variant_unknown);
  • a missing variant or plural form (translation.variant_missing);
  • a placeholder that isn't a field (translation.placeholder_unknown);
  • an amount of money or a percentage written without its style, or a style on another field (translation.placeholder_style);
  • a field type a wording can't hold (translation.field_type), or more than one enum or PluralCount field (translation.too_many_selectors);
  • a language file that isn't named for a locale (translation.file_name_invalid), or is for one the application doesn't support (translation.locale_unsupported);
  • a call of no message (translation.message_unknown);
  • a locale: that isn't a supported locale (type.locale_unsupported);
  • translations in a project with no locales { } (translation.locales_required).

Missing wording

Every supported locale must be complete, unless it is listed in in_progress:. A message, a failure a route can answer with, or an enum once any language words it, missing from such a locale is an error: translation.file_missing for a locale with no language file, translation.wording_missing for a file that lacks a member. The error's next: names the file and the member to add, with the placeholders to use, and ends (agent): your coding agent can add it itself.

A field no wording uses

A field that no wording in a language uses is translation.field_unused. One variant leaving a field out is normal. Jadpo has no warnings, so this is an error, but a judgement call: a person can answer it by writing decline translation.field_unused: "<reason>" above the member (Declining a judgement call). That is right for a language that needs no such word.

Locales in progress

in_progress: is how you say a locale isn't finished. A locale it lists falls back where its language file has no wording, with no error: to the same language's regional sibling first (fr_ca tries fr_fr, if supported), then to the default locale. The sentence is written entirely in the language it came from.

Wording the file does give is checked as for any locale, so a mistake in it is still an error. Removing the locale from in_progress: makes the gaps errors again. Quality comes from the review setting below, not from waiting. jadpo translations missing lists what an in-progress locale falls back on.

Stale translations: sources.jadpo_record

A translation is stale when the wording it was translated from has changed since. Jadpo knows from a file it writes in each translations/ folder, sources.jadpo_record, which you commit. It is a record (The record format) headed record translations 1, written by jadpo translations update, listed by jadpo records and merged by git's union merge.

It has one line for each translation outside the default locale, sorted, with a hash of the default wording it was translated from (from) and of its own wording when that was recorded (wording). A hash is the first 12 hex digits of BLAKE3 over the member's whole text, every value and plural form in name order, so reordering a block changes nothing.

A translation whose from no longer matches today's default wording is stale (translation.stale). That is an error until it is translated again and recorded. An in-progress locale's stale translation is listed by jadpo translations missing instead.

A translation with no line yet isn't stale: it was never recorded, so nothing says what it was made from. (With review required, it is new and not accepted.) So a project that never runs jadpo translations update sees no stale error.

A line Jadpo can't read is translation.sources_invalid, which jadpo translations update fixes. A header Jadpo didn't write, or lines out of order, is record.edited, and a newer format is record.format_newer, as for every record (Checking a record).

Review

By default a translation needs no one to accept it. To have a person accept each one, set translations: { review: TranslationReview.required } in application { }; the default is TranslationReview.none. Then every new or changed wording outside the default locale is not accepted until a person runs jadpo translations accept <locale>, which records the acceptance in the same record. A line says a wording is accepted only while the wording is the one the line hashes.

jadpo translations missing lists wording that isn't accepted. It isn't an error, so jadpo check passes with it: your code review is the gate. Jadpo can't tell who wrote a wording, so this means "changed and not yet accepted", not "written by an agent".

A translations: option other than review: is translation.option_unknown, and a review: that isn't a TranslationReview is translation.review_invalid.

example
application {    translations: {        review: TranslationReview.required    }}locales {    default: Locale.en_gb    supported: [Locale.en_gb, Locale.de_de]}

Jadpo's and packages' wording

The root folder's wording of Jadpo's and packages' text is checked too, each problem with its own error:

  • Jadpo's messages. A supported locale that isn't in progress, in which Jadpo ships no wording and the root file words none of the messages of a feature the app has on, is one error for the locale, listing what is missing (translation.jadpo_missing) and pointing at jadpo translations builtin. A message of a feature that is off is translation.feature_off, and a group of the root file that names no owner is translation.group_unknown. Everything else about a group's wording is checked as a folder's is: translation.member_unknown (with the nearest of Jadpo's messages), member_duplicate, wording_shape, wording_invalid, placeholder_unknown, variant_missing and variant_unknown.
  • The root folder's record. The root folder has its own sources.jadpo_record, kept by the same commands, with the owner in the member's name (translation fr_fr.jadpo.invalid_input from ... wording ...), as a package's is postcodes.<message>.
  • A library package's text. Its own language files are checked by themselves, as a domain's are. Its group in the root file is checked against its public messages, enums and failures (translation.member_unknown, with the nearest of them). Each supported locale not in progress must word all of it in the root file or the package's own file (translation.wording_missing with a root file for the locale, translation.file_missing without). A call through the package of a message it doesn't have is translation.message_unknown, and of one it doesn't make public, package.not_public. A root record line is made from the app's default wording or, when the app gives none, the package's, and is stale when that changes (translation.stale).

Markdown for agents: /docs/what-the-compiler-checks-of-translations.md.Built from Jadpo main at a707efb.