diff --git a/docs/i18n/ADAPTIVE_CURRENT_STATE_REPORT_v3.md b/docs/i18n/ADAPTIVE_CURRENT_STATE_REPORT_v3.md new file mode 100644 index 00000000..3c8ed34a --- /dev/null +++ b/docs/i18n/ADAPTIVE_CURRENT_STATE_REPORT_v3.md @@ -0,0 +1,139 @@ +# Adaptive Current-State Report v3 — i18n hardening + LanguageTool editor integration + +> **Mandatory Phase-0 deliverable** for the "i18n hardening + 5 new locales + real LanguageTool" +> program. This is read-only ground truth captured before any feature code, so the work *extends* the +> existing system rather than reinventing it. Status fields below are accurate as of **2026-06-24**. + +## 1. Locale inventory (SSOT: `i18n/locales.ts`) + +19 locales, each a typed `LocaleDescriptor` in the single source of truth. The `.mjs` +build/check/translate scripts derive their list from the `locales//` folders; the +`tests/unit/i18n/localesRegistry.test.ts` integrity guard asserts the two never drift. + +| Tier | Locales | Notes | +|------|---------|-------| +| **Production** (5) | de, en, es, fr, **it** | full key parity + translated `help.json` (`helpFallback: false`) | +| **Near-Production** (4) | ja, zh, pt, el | ≥96% UI coverage, 0 placeholder issues; `help.json` still English-fallback | +| **Beta** (10) | ar, he (RTL); fi, sv, hu, is, eu; fa (RTL); ru, ko | UI coverage varies; `help.json` English-fallback | + +`status` drives the README badge + `LanguageSelector` β-badge (`isBeta` = the *beta* tier specifically, +so Near-Production is distinguished from Beta). RTL = ar/he/fa. Scripts: latin/arabic/hebrew/cjk/ +greek/cyrillic/hangul (font wiring per script; Korean needs Noto Sans KR via CDN, Cyrillic self-hosts). + +## 2. LanguageTool reality — scaffold only, NOT a working grammar checker + +- **`services/languageToolClient.ts`** is a **gate + connectivity ping**, nothing more: + - `assertLanguageToolAllowed(settings, baseUrl)` — throws if the LT integration is disabled, the URL + is invalid, or `privacy.localStorageOnly` is on **and** the host is not `localhost`/`127.0.0.1` + (privacy-first: remote LT blocked in local-only mode). + - `languageToolPing(baseUrl, sampleText)` — a single `POST /v2/check` with `language=en-US` that + returns `res.ok`. **It does not parse `matches[]`, does not surface issues, and is hardcoded to + English.** No real grammar checking exists anywhere in the editor. +- **The Writer "grammar check" is unrelated** — `hooks/useWriterView.ts` `grammarCheck` is an + **AI/Gemini prompt**, not LanguageTool. +- **Settings surface already exists**: `components/settings/IntegrationsSection.tsx` renders the + LanguageTool card; settings shape is `integrations.languageToolEnabled` (default **false**) + + `integrations.languageToolBaseUrl` (default `http://localhost:8010`). This is the scaffold PR-C + builds on — no new Settings plumbing required for enable/baseURL. + +## 3. Editor seam for inline underlines (`components/manuscript/ManuscriptEditor.tsx`) + +The editor is a **plain `