define and consolidate language resolution across DAW modules #6

Open
opened 2026-05-26 04:16:13 +02:00 by michael · 5 comments
Owner

Goal

Define how language resolution works across DAW modules and programs.

Current State

berhtjan-core has resolve_lang(ctx) and resolve_label(label, lang).
Usage is inconsistent -- some places call resolve_label, others access
.de / .en directly. The rules for fallback order and how lang is
determined from context are not formally defined.

Questions to Answer

  • What is the canonical fallback chain? (e.g. ctx.lang -> os env -> "en")
  • Where is lang set and who owns it?
  • What label format is required? ({ en = ..., de = ... } or string?)
  • Are other languages supported or just en/de for now?
  • Should resolve_label live in core or common?

Acceptance Criteria

  • Language resolution documented (standard or ADR)
  • Fallback chain defined and implemented in one place
  • All label access goes through resolve_label (no direct .de/.en)
  • Existing usages in berhtjan-core and berhtjan-cli aligned
## Goal Define how language resolution works across DAW modules and programs. ## Current State `berhtjan-core` has `resolve_lang(ctx)` and `resolve_label(label, lang)`. Usage is inconsistent -- some places call `resolve_label`, others access `.de` / `.en` directly. The rules for fallback order and how `lang` is determined from context are not formally defined. ## Questions to Answer - What is the canonical fallback chain? (e.g. ctx.lang -> os env -> "en") - Where is `lang` set and who owns it? - What label format is required? (`{ en = ..., de = ... }` or string?) - Are other languages supported or just en/de for now? - Should `resolve_label` live in core or common? ## Acceptance Criteria - [ ] Language resolution documented (standard or ADR) - [ ] Fallback chain defined and implemented in one place - [ ] All label access goes through `resolve_label` (no direct `.de`/`.en`) - [ ] Existing usages in berhtjan-core and berhtjan-cli aligned
Author
Owner

Additional finding: prompt.lua confirm()

The confirm() function shows a hardcoded prompt string:
out:write_raw(message .. " [j/n]: ")

The [j/n] suffix is language-specific and must be resolved
via the language system once DAW/daw-modul-berhtjan-cli#6 is resolved.
Also: prompt.lua has the same out module-level and missing
resolve_label issues as render.lua -- covered by DAW/daw-modul-berhtjan-cli#5.

## Additional finding: prompt.lua confirm() The `confirm()` function shows a hardcoded prompt string: `out:write_raw(message .. " [j/n]: ")` The `[j/n]` suffix is language-specific and must be resolved via the language system once DAW/daw-modul-berhtjan-cli#6 is resolved. Also: `prompt.lua` has the same `out` module-level and missing `resolve_label` issues as render.lua -- covered by DAW/daw-modul-berhtjan-cli#5.
Author
Owner

Partially resolved as part of the 2.1 migration (v2.1.0).

Done:

  • Canonical fallback chain defined and implemented in one place:
    lang.lua's resolve_lang(ctx) -- ctx.user_locale -> ctx.lang ->
    daw_error/v1 (no silent 'en' default anymore)
  • resolve_label(label, lang, default_lang) is now the only path to
    label text -- verified no direct .de/.en table access remains
    anywhere in daw-modul-berhtjan-core or daw-modul-berhtjan-cli
  • default_lang is host/adapter-owned (ctx.default_lang), not
    invented by core or cli

Still open:

  • No standalone standard/ADR document -- the behavior lives in
    lang.lua's code comments and the migration docs, not a
    referenceable standard
  • Whether languages beyond en/de are supported is still implicit
    (the label format is an open key set, so technically yes, but
    never stated as a decision)
  • The bigger question -- how translations/languages enter the
    system at all, including for daw_error/v1 messages and
    daw-modul-berhtjan-cli's own hardcoded UI strings (see #5) -- is
    unresolved and needs a dedicated discussion before this issue can
    close.
Partially resolved as part of the 2.1 migration (v2.1.0). Done: - Canonical fallback chain defined and implemented in one place: lang.lua's resolve_lang(ctx) -- ctx.user_locale -> ctx.lang -> daw_error/v1 (no silent 'en' default anymore) - resolve_label(label, lang, default_lang) is now the only path to label text -- verified no direct .de/.en table access remains anywhere in daw-modul-berhtjan-core or daw-modul-berhtjan-cli - default_lang is host/adapter-owned (ctx.default_lang), not invented by core or cli Still open: - No standalone standard/ADR document -- the behavior lives in lang.lua's code comments and the migration docs, not a referenceable standard - Whether languages beyond en/de are supported is still implicit (the label format is an open key set, so technically yes, but never stated as a decision) - The bigger question -- how translations/languages enter the system at all, including for daw_error/v1 messages and daw-modul-berhtjan-cli's own hardcoded UI strings (see #5) -- is unresolved and needs a dedicated discussion before this issue can close.
Author
Owner

Session 2026-08-11 — language work after v2.1.0

The language-resolution mechanics are implemented in v2.1.0, but the broader language-resource problem is intentionally left for a dedicated follow-up session.

Decisions already implemented

  • resolve_lang(ctx) owns language resolution: ctx.user_locale -> ctx.lang -> daw_error/v1; there is no hardcoded language fallback.
  • resolve_label(label, lang, default_lang) is the single label-resolution path.
  • default_lang is supplied from above via context; berhtjan-core and berhtjan-cli do not fetch configuration from the host program.
  • Missing translations in both requested and configured fallback language are real errors, not silent fallbacks.

Remaining work in this existing issue

  • Define how multilingual resources enter the running system and are supplied to adapters without hardcoding language data in modules or UI implementations.
  • Cover berhtjan-cli's own user-facing strings, including command headings, empty-table text and the confirmation suffix.
  • Define how user-facing localized text is produced for daw_error/v1 errors while preserving the error object's language-neutral machine identity (source, code, data, cause).
  • Document the language model as a referenceable standard/ADR, including that label language keys are not limited to German/English.

This work is cross-repository by nature: the eventual model must remain usable by core, CLI and future adapters (web/API/etc.) without modules reaching back into a host program for configuration.

## Session 2026-08-11 — language work after v2.1.0 The language-resolution mechanics are implemented in v2.1.0, but the broader language-resource problem is intentionally left for a dedicated follow-up session. ### Decisions already implemented - `resolve_lang(ctx)` owns language resolution: `ctx.user_locale` -> `ctx.lang` -> `daw_error/v1`; there is no hardcoded language fallback. - `resolve_label(label, lang, default_lang)` is the single label-resolution path. - `default_lang` is supplied from above via context; berhtjan-core and berhtjan-cli do not fetch configuration from the host program. - Missing translations in both requested and configured fallback language are real errors, not silent fallbacks. ### Remaining work in this existing issue - Define how multilingual resources enter the running system and are supplied to adapters without hardcoding language data in modules or UI implementations. - Cover berhtjan-cli's own user-facing strings, including command headings, empty-table text and the confirmation suffix. - Define how user-facing localized text is produced for `daw_error/v1` errors while preserving the error object's language-neutral machine identity (`source`, `code`, `data`, `cause`). - Document the language model as a referenceable standard/ADR, including that label language keys are not limited to German/English. This work is cross-repository by nature: the eventual model must remain usable by core, CLI and future adapters (web/API/etc.) without modules reaching back into a host program for configuration.
Author
Owner

Session 2026-08-12 -- daw_i18n/v1 contract created

The broader language-resource question left open in the previous
session (comment #7309: "how multilingual resources enter the running
system") has been worked through architecturally and resulted in a new
contract:

  • DAW/daw-contracts daw_i18n/v1 (new) -- language-neutral resource
    format for translatable text. UUID resource identity, mandatory
    complete canonical English definition, optional partial
    translations, named placeholders with set-equality across
    languages, source_hash for staleness detection. Discovery, language
    selection, fallback policy, and grammar (plural/gender/case) are
    explicitly out of scope for v1.

While designing it, a related gap surfaced in daw_error/v1 and
daw_event/v1: source only identified a cell's type, not a
concrete running instance (e.g. two concurrent module_worker cells
were indistinguishable). Both contracts were updated accordingly:

  • source clarified: stable cell name/type (as used in mainjan
    hello.from), not instance identity.
  • cell_id (optional) added: concrete producing/responding cell
    instance. Generation/persistence/lifecycle deliberately out of
    scope -- tracked separately, see DAW/daw-contracts#4.
  • resource_id (optional) added: links to a daw_i18n/v1 resource.
    Must not appear without message.
  • daw_event_response/v1 received the same source/cell_id treatment.
  • daw_error_report/v1 needed no change (fully embeds daw_error/v1
    objects).

All four contracts remain status: draft.

This issue's own scope

Not resolved here, still open:

  • The i18n-for-berhtjan-specifically part of this issue --
    whether/how berhtjan-core's existing resolve_lang/resolve_label
    label model relates to daw_i18n/v1, and whether berhtjan-cli's own
    hardcoded UI strings (#5) become daw_i18n/v1 resources -- is now
    tracked in DAW/daw-modul-berhtjan-core#12 and
    DAW/daw-modul-berhtjan-cli#11.
  • Documenting the language model as a referenceable standard/ADD is
    effectively superseded by daw_i18n/v1 itself now being that
    reference for the error/event/resource side of things; whether this
    issue's original acceptance criteria are still meaningful as written
    should be reassessed against #11/#12's outcome.
## Session 2026-08-12 -- daw_i18n/v1 contract created The broader language-resource question left open in the previous session (comment #7309: "how multilingual resources enter the running system") has been worked through architecturally and resulted in a new contract: - **DAW/daw-contracts daw_i18n/v1** (new) -- language-neutral resource format for translatable text. UUID resource identity, mandatory complete canonical English definition, optional partial translations, named placeholders with set-equality across languages, source_hash for staleness detection. Discovery, language selection, fallback policy, and grammar (plural/gender/case) are explicitly out of scope for v1. While designing it, a related gap surfaced in daw_error/v1 and daw_event/v1: `source` only identified a cell's *type*, not a concrete running *instance* (e.g. two concurrent module_worker cells were indistinguishable). Both contracts were updated accordingly: - `source` clarified: stable cell name/type (as used in mainjan hello.from), not instance identity. - `cell_id` (optional) added: concrete producing/responding cell instance. Generation/persistence/lifecycle deliberately out of scope -- tracked separately, see DAW/daw-contracts#4. - `resource_id` (optional) added: links to a daw_i18n/v1 resource. Must not appear without `message`. - daw_event_response/v1 received the same source/cell_id treatment. - daw_error_report/v1 needed no change (fully embeds daw_error/v1 objects). All four contracts remain `status: draft`. ### This issue's own scope Not resolved here, still open: - **The i18n-for-berhtjan-specifically part of this issue** -- whether/how berhtjan-core's existing `resolve_lang`/`resolve_label` label model relates to daw_i18n/v1, and whether berhtjan-cli's own hardcoded UI strings (#5) become daw_i18n/v1 resources -- is now tracked in DAW/daw-modul-berhtjan-core#12 and DAW/daw-modul-berhtjan-cli#11. - Documenting the language model as a referenceable standard/ADD is effectively superseded by daw_i18n/v1 itself now being that reference for the error/event/resource side of things; whether this issue's original acceptance criteria are still meaningful as written should be reassessed against #11/#12's outcome. ### Related follow-up issues - DAW/daw-lua-common#46 - DAW/daw-lua-net#10 - DAW/daw-modul-berhtjan-core#12 - DAW/daw-modul-berhtjan-cli#11 - DAW/daw-contracts#4 (cell identity/lifecycle contract, deferred) - DAW/daw-contracts#5 (Compatibility wording review, deferred)
Author
Owner

Team decision 2026-08-12 — language and i18n architecture

The architecture discussion started by this issue has resulted in a general DAW i18n model rather than a Berhtjan-specific translation mechanism.

Decisions

  • Translation resources are module-owned data artifacts, not Lua/source-code artifacts.
  • Resources use the language-neutral daw_i18n/v1 JSON contract.
  • Each module owns its own language resource files.
  • English is the canonical resource and must be complete.
  • Additional languages may be partial.
  • Which languages are collected/loaded and which fallback chain is allowed is host/runtime configuration, not module policy.
  • English being canonical does not imply an automatic English runtime fallback.
  • Human-readable resources use stable UUID resource_id values.
  • code remains the independent machine-readable semantic classification for errors/events.
  • Complete sentences and named parameters are used; fragment concatenation is not part of the model.
  • Pluralization and other grammar engines are deliberately outside daw_i18n/v1.
  • Translation staleness is tracked through source_hash.
  • daw_error/v1 and daw_event/v1 can reference i18n resources through resource_id.
  • daw_event/v1 may remain purely structured without human-readable text.
  • daw_event_response/v1 remains a structured response and does not gain i18n fields.

Runtime identity clarification

During the same review, source was clarified as the stable cell name/type rather than the identity of a concrete cell instance.

Optional cell_id now identifies the concrete cell instance in:

  • daw_error/v1
  • daw_event/v1
  • daw_event_response/v1

Cell identity generation, persistence, restoration, and lifecycle are intentionally outside these runtime contracts.

Follow-up issues

  • DAW/daw-lua-common#46 — adopt updated daw_error/v1
  • DAW/daw-lua-net#10 — adopt updated daw_error/v1
  • DAW/daw-modul-berhtjan-core#12 — adopt daw_i18n/v1 and updated daw_error/v1
  • DAW/daw-modul-berhtjan-cli#11 — adopt daw_i18n/v1 for CLI-owned UI strings
  • DAW/daw-contracts#4 — define persistent cell identity and lifecycle
  • DAW/daw-contracts#5 — clarify compatibility wording vs. contract status model

The contracts remain draft. They are currently being integrated to test whether the architecture works in practice. Promotion to beta/stable is reserved for actual productive use by a host program.

This issue should remain open until the Berhtjan-specific implementation work has been completed and verified.

## Team decision 2026-08-12 — language and i18n architecture The architecture discussion started by this issue has resulted in a general DAW i18n model rather than a Berhtjan-specific translation mechanism. ### Decisions - Translation resources are module-owned data artifacts, not Lua/source-code artifacts. - Resources use the language-neutral `daw_i18n/v1` JSON contract. - Each module owns its own language resource files. - English is the canonical resource and must be complete. - Additional languages may be partial. - Which languages are collected/loaded and which fallback chain is allowed is host/runtime configuration, not module policy. - English being canonical does not imply an automatic English runtime fallback. - Human-readable resources use stable UUID `resource_id` values. - `code` remains the independent machine-readable semantic classification for errors/events. - Complete sentences and named parameters are used; fragment concatenation is not part of the model. - Pluralization and other grammar engines are deliberately outside `daw_i18n/v1`. - Translation staleness is tracked through `source_hash`. - `daw_error/v1` and `daw_event/v1` can reference i18n resources through `resource_id`. - `daw_event/v1` may remain purely structured without human-readable text. - `daw_event_response/v1` remains a structured response and does not gain i18n fields. ### Runtime identity clarification During the same review, `source` was clarified as the stable cell name/type rather than the identity of a concrete cell instance. Optional `cell_id` now identifies the concrete cell instance in: - `daw_error/v1` - `daw_event/v1` - `daw_event_response/v1` Cell identity generation, persistence, restoration, and lifecycle are intentionally outside these runtime contracts. ### Follow-up issues - `DAW/daw-lua-common#46` — adopt updated `daw_error/v1` - `DAW/daw-lua-net#10` — adopt updated `daw_error/v1` - `DAW/daw-modul-berhtjan-core#12` — adopt `daw_i18n/v1` and updated `daw_error/v1` - `DAW/daw-modul-berhtjan-cli#11` — adopt `daw_i18n/v1` for CLI-owned UI strings - `DAW/daw-contracts#4` — define persistent cell identity and lifecycle - `DAW/daw-contracts#5` — clarify compatibility wording vs. contract status model The contracts remain `draft`. They are currently being integrated to test whether the architecture works in practice. Promotion to `beta`/`stable` is reserved for actual productive use by a host program. This issue should remain open until the Berhtjan-specific implementation work has been completed and verified.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
DAW/daw-modul-berhtjan-cli#6
No description provided.