The problem
Everything is in English — every string in the interface, and every answer the assistant gives regardless of the language the question was asked in. For a self-hosted tool an organization runs for its own team, that is a barrier for any team that does not work in English day to day.
Proposed solution
Two halves, separable but usually wanted together.
1. The interface. Every string in the frontend comes from a catalogue rather than a literal, with a switcher and a stored preference — a column on the user row rather than a cookie, so the choice survives a new device.
- The token system in
docs/design.md is unaffected: a colour has no language.
- Every screen is touched.
- The form shells that route field errors must take their messages from the catalogue too, or the interface ends up half-translated at exactly the moment a user is stuck.
This half adds no infrastructure.
2. The answers. The assistant replies in the language the question was asked in, while the code, the identifiers and the citations stay as they are in the repository — translating a symbol name would break the [n] citation contract against the file it points at.
This half adds one real risk, and it fails silently. The index holds source code written in English. A question embedded in another language lands in a different neighbourhood of the vector space than the code that answers it, and recall drops with nothing reporting an error — the same silent-quality failure the embedding-model guard exists to prevent.
The seam is M3's classify node. It already rewrites every question into a standalone search query, so constraining that query to English keeps retrieval working while generation answers in the user's language. Note the node's fallback is deliberately lenient — classify falls back to codebase_question plus the raw question, because a helper node may never be the reason a question goes unanswered (.claude/rules/rag.md). The English constraint must degrade the same way rather than fail the turn.
Decisions the specifier owns:
Docs that move in the same change: docs/PRD.md §2.1/§4.2, docs/langgraph.md (the classify node's contract), docs/rag.md, docs/design.md, frontend/README.md, docs/data.md, CHANGELOG.md.
Alternatives you considered
Do nothing. English-only. Defensible for a tool whose primary content — source code, identifiers, file paths — is English anyway, and it avoids the retrieval risk entirely.
Answers only, no interface translation. Much cheaper, no catalogue, no screens touched. It is also the half that carries the recall risk, so it is the wrong half to ship alone if the goal is to reduce risk rather than effort.
Interface only, English answers. The inverse, and the safer first step: it adds no infrastructure and cannot degrade retrieval. A team gets navigable screens while the assistant keeps answering in the language the code is written in.
Let users prompt for a language per question ("answer in Indonesian"). Already works today with no changes, at the cost of retyping it every turn — and it hits the same recall problem without the classify-node mitigation, since the question itself is still non-English.
Translate the retrieved excerpts instead of constraining the query. Rejected: it would break citations against the real file contents and cost a model call per excerpt.
Area
frontend
Which phase does this belong to?
Phase 2 (per-project RBAC)
Before submitting
The problem
Everything is in English — every string in the interface, and every answer the assistant gives regardless of the language the question was asked in. For a self-hosted tool an organization runs for its own team, that is a barrier for any team that does not work in English day to day.
Proposed solution
Two halves, separable but usually wanted together.
1. The interface. Every string in the frontend comes from a catalogue rather than a literal, with a switcher and a stored preference — a column on the user row rather than a cookie, so the choice survives a new device.
docs/design.mdis unaffected: a colour has no language.This half adds no infrastructure.
2. The answers. The assistant replies in the language the question was asked in, while the code, the identifiers and the citations stay as they are in the repository — translating a symbol name would break the
[n]citation contract against the file it points at.This half adds one real risk, and it fails silently. The index holds source code written in English. A question embedded in another language lands in a different neighbourhood of the vector space than the code that answers it, and recall drops with nothing reporting an error — the same silent-quality failure the embedding-model guard exists to prevent.
The seam is M3's
classifynode. It already rewrites every question into a standalone search query, so constraining that query to English keeps retrieval working while generation answers in the user's language. Note the node's fallback is deliberately lenient —classifyfalls back tocodebase_questionplus the raw question, because a helper node may never be the reason a question goes unanswered (.claude/rules/rag.md). The English constraint must degrade the same way rather than fail the turn.Decisions the specifier owns:
backend/app/rag/grounding.pytranslated? They are user-visible answers, not interface chrome, so they sit outside the frontend catalogue and need their own decision.Docs that move in the same change:
docs/PRD.md§2.1/§4.2,docs/langgraph.md(the classify node's contract),docs/rag.md,docs/design.md,frontend/README.md,docs/data.md,CHANGELOG.md.Alternatives you considered
Do nothing. English-only. Defensible for a tool whose primary content — source code, identifiers, file paths — is English anyway, and it avoids the retrieval risk entirely.
Answers only, no interface translation. Much cheaper, no catalogue, no screens touched. It is also the half that carries the recall risk, so it is the wrong half to ship alone if the goal is to reduce risk rather than effort.
Interface only, English answers. The inverse, and the safer first step: it adds no infrastructure and cannot degrade retrieval. A team gets navigable screens while the assistant keeps answering in the language the code is written in.
Let users prompt for a language per question ("answer in Indonesian"). Already works today with no changes, at the cost of retyping it every turn — and it hits the same recall problem without the
classify-node mitigation, since the question itself is still non-English.Translate the retrieved excerpts instead of constraining the query. Rejected: it would break citations against the real file contents and cost a model call per excerpt.
Area
frontend
Which phase does this belong to?
Phase 2 (per-project RBAC)
Before submitting
docs/PRD.mdand this isn't already planned or listed as a non-goal.