Multi-Language Support¶
Ways runs in one of two modes, decided by a single switch. English is the
source of truth; localization is adopter-run — a non-English speaker opts in and
the framework translates itself, validated against the English root (ADR-139). This
page is the reference; the lifecycle and rationale live in
the localization explanation pages (01.009.E–01.013.E) and the evidence record
ADR-183.
The two modes¶
The switch is the resolved Config.language:
| Mode | When | What runs |
|---|---|---|
| English (default) | language is en / auto / unset |
English corpus + English (384-dim) matching only. The 127MB multilingual model is never downloaded or loaded. No locale tuning. The intl pipeline is dormant — zero cost. |
| Localized | language is a specific non-English code (e.g. es) |
The multilingual corpus is built with the English root as anchor, the 768-dim multilingual lane runs as a second lane, and ways tune locale --lang audits the localization. |
Both modes match by the same rule (see matching.md and engine-reference.md). The difference is the model, not the method.
Setting the switch — two configs¶
There are two different language settings; conflating them is the common mistake:
| Config | Controls | Set by |
|---|---|---|
language in ~/.config/agent-ways/config.yaml |
the ways intl mode + the output-language directive | ways-localize |
language in Claude Code settings.json (a NAME, e.g. "spanish") |
Claude Code's response language | the operator (or ways-localize) |
The effective switch is the user-scope config.yaml language (default auto;
ways.language in ways settings), the layer ways-localize writes. Setting Claude
Code's settings.json language alone does nothing to ways, and nothing reports the
mismatch. To localize ways, the operator asks for it, which invokes the
ways-localize skill.
Localizing — the ways-localize skill¶
Localization is one operation, run on demand:
It interviews for the language, gets consent (the model download + all-ways pass is
heavy), flips the switch, fetches the multilingual model on demand
(make -C tools/way-embed model-multilingual), translates every way's
description+vocabulary against the English root, rebuilds the corpus, runs
ways tune locale --lang <code> until clean, and sets Claude Code's own language. See the
skill (skills/ways-localize/) and scenario 01.011.E.
The embedding models¶
| Model | File | Size | Role |
|---|---|---|---|
| all-MiniLM-L6-v2 | minilm-l6-v2.gguf |
21MB | English lane (384-dim) — always present |
| paraphrase-multilingual-MiniLM-L12-v2 | multilingual-minilm-l12-v2-q8.gguf |
127MB | Multilingual lane (768-dim, 52 langs) — on-demand, localized mode only |
An install fetches only the English model. The multilingual model is fetched by
ways-localize (or make -C tools/way-embed model-multilingual) when an adopter
localizes — English installs never pay for it.
The English-root anchor¶
In localized mode, each way contributes two kinds of entry to the multilingual corpus:
- the English root — the way's English
description+vocabulary, embedded with the multilingual model. This is the per-way anchor, the source of truth in multilingual space. - the locale aliases — one
.locales.jsonlline per localized language, generated byways-localize.
Every alias is scored against the root, never against sibling translations — which is what keeps a multilingual install from drifting into a free-for-all with no fixed meaning. A localized way matches a native-language prompt via its alias; the way's English body is still injected (the guidance text — Claude reads it in any language).
Locale stub format¶
One .locales.jsonl file per way, co-located with its .md, one line per language:
{"lang":"es","description":"seguridad general, codificación segura","vocabulary":"seguridad vulnerable defensa owasp"}
Just lang, description, vocabulary — no per-stub threshold, and no per-way
threshold anywhere: firing is the global τ_s / τ_k on the calibrated g(s), never a
per-node or per-locale threshold (see engine-reference.md). A full native-language way
can override a stub by existing as security.es.md. New/edited ways are authored
English-only; ways-localize derives the locale layer.
Tuning — the acceptance gate¶
ways tune locale is the localized-mode acceptance gate. Fidelity is alignment to the
English root; discrimination is non-collision with other ways. It is never invoked in
English mode.
ways tune locale # audit the active localized language
ways tune locale --lang es # scope to one language
ways tune locale --way security # scope to one way
ways tune locale --json
Re-author flagged stubs and re-run until clean. See the
meta/knowledge/optimization/tuning way for the failure modes and fixes.
Output language¶
The effective Config.language also drives the output-language directive injected by
core.md: in localized mode the agent writes commit messages, comments, and prose in
that language. Way content stays English (the guidance text); only generated output
changes.
Checking status¶
ways tune language # resolved language, model availability, per-way locale coverage
ways tune language --json # machine-readable (resolved_language, models, locales_found)
Architecture¶
- ADR-139 — adopter-run localization (the two modes, the shelve, root-anchoring)
- ADR-125 — the coordinate-alias model (
description+vocabularyas embedding-space alias) - ADR-107 — original locale support and the dual-model approach (superseded in part)
- ADR-183 — the tuning mechanics (evidence record)