uix(palabras): F-A Camino A · esquema del motor (doc.languages = fuente de verdad)

Base del rework de F-A al modelo de estructura COMPARTIDA (aditivo, sin cambio de
comportamiento; el provider aun usa el modelo-mapa hasta el rework):
- Block.i18n: contenido inline de los idiomas INACTIVOS por bloque (el activo en
  `children`); solo hojas de texto. Sobrevive normalize/ops via spread.
- PalabrasDocument.languages: la LISTA de idiomas = FUENTE DE VERDAD de si el doc es
  multilenguaje (el doc se auto-describe; la prop `languages` = override opcional).
- PalabrasDocument.activeLang: qué idioma vive en `children` (round-trip).
- normalize preserva languages + activeLang en la reconstruccion raiz (como scheme).

Handoff corregido: F-A shipeada = modelo-MAPA (permite divergencia, rechazado);
rework Camino A EN CURSO (esquema hecho, provider pendiente = tarea de manana).
0 errores palabras · normalize 5/5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
alpha-0.1-sec-dom
dev 3 months ago
parent 618075d417
commit 9223956a90

@ -11,19 +11,34 @@
## ▶️ CONTINUAR MAÑANA (2026-07-22) — arranque rápido
**Dónde estamos.** El editor `palabras` está sólido. Cerrado hoy y en `gita`
(rama `alpha-0.1-sec-dom`, HEAD `0cd3a037c`):
- **F-A multilenguaje ✅ HECHA + REHECHA** al modelo correcto (Camino A): **UN solo
documento, estructura COMPARTIDA, texto por idioma** (`block.i18n`). Borrar/insertar/
mover aplica a todos los idiomas por construcción; switcher en menubar/migas.
Detalle en la sección «ESTADO 2026-07-21» de abajo. 60/60 provider · 570/570 motor.
**Dónde estamos.** Rama `alpha-0.1-sec-dom` → `gita`.
- **F-A multilenguaje — SHIPEADA como modelo-MAPA** (chunks 1-3: `value:
Record<lang,doc>`, switcher menubar/migas, historia por idioma; funciona, verificado
Playwright, 58/58 provider). ⚠️ **PERO ese modelo permite estructuras DIVERGENTES entre
idiomas** (borrar en `es` no borra en `en`) — el usuario lo RECHAZÓ.
- **REWORK a Camino A FIRMADO y EN CURSO** (⬅️ TAREA PRINCIPAL DE MAÑANA): **UN solo
documento, estructura COMPARTIDA por construcción, texto por idioma en `block.i18n`**.
HECHO hasta ahora = **esquema del motor** (commiteado): `block.i18n` (contenido de
idiomas inactivos por bloque) + **`doc.languages`** (LISTA de idiomas = FUENTE DE VERDAD
de si es multilenguaje; la prop `languages` pasa a override opcional) + `doc.activeLang`
(idioma en `children`); `normalize` los preserva junto a `scheme`; `validate` no rechaza
props extra; `block.i18n` sobrevive las ops vía spread. **PENDIENTE (el grueso)**: rehacer
el PROVIDER — quitar map/langHistories; al cambiar idioma **swap `children↔i18n`** en cada
hoja de texto; helpers `foldPalabrasLanguages(values, primary)` (construir el doc único
desde docs por idioma) y `projectPalabrasLanguage(doc, lang)` (extraer un idioma para
render/export); `langFilled` por proyección; `multilingual`/`resolvedLanguages` desde
`doc.languages` (prop = override); **revertir `value` a `PalabrasDocument`**; reescribir
los 5 tests multilenguaje + el demo (`foldPalabrasLanguages({es,en},'es')`). Árbol: hojas
de texto = párrafo/encabezado/cita/código/list-item (llevan `i18n`); contenedores =
list/table/columns/callout (recursan). Partir=bloque nuevo sin i18n=vacío-a-traducir;
fusionar=concatenar (o limitación declarada). Diseño completo en «ESTADO 2026-07-21».
- Warnings `state_proxy_equality_mismatch` (`81dca0f14`) y ruido de langs (`45543ab95`)
resueltos. FD.1 (`DESIGN.md`) + FD.3 (mood **sobrio-documental**) firmados.
- **FD.4** (firma perceptual sema+motion) POSPUESTA por el usuario («complicado para
un editor»).
resueltos. FD.1 (`DESIGN.md`) + FD.3 (mood **sobrio-documental**) firmados. **FD.4**
(firma perceptual sema+motion) POSPUESTA por el usuario («complicado para un editor»).
**LO SIGUIENTE = F-B · soporte agentivo** («que un agente pueda rellenar el contenido»).
Su FORMA está SIN firmar — hay que decidir con el usuario ANTES de construir (4 ejes):
**LO SIGUIENTE**: (1) **terminar el rework de F-A** (el provider Camino A, arriba); (2)
**F-B · soporte agentivo** («que un agente pueda rellenar el contenido»). La FORMA de F-B
está SIN firmar — decidir con el usuario ANTES de construir (4 ejes):
1. **¿Qué emite el agente?** JSON `PalabrasDocument` nativo · Markdown · un schema
intermedio agent-friendly.
2. **¿One-shot o streaming?** de golpe vs bloque a bloque en vivo.

@ -68,6 +68,7 @@ export function normalizeDocument(
version: PALABRAS_VERSION,
children: nextChildren,
...(doc.scheme !== undefined ? { scheme: doc.scheme } : {}),
...(doc.languages !== undefined ? { languages: doc.languages } : {}),
...(doc.activeLang !== undefined ? { activeLang: doc.activeLang } : {})
},
mutated: true

@ -509,6 +509,14 @@ export interface PalabrasDocument {
* JSON export, never interpreted — the consumer (eidos) owns its shape.
*/
readonly scheme?: Readonly<Record<string, unknown>>;
/**
* Multilingual (F-A): the ordered language codes this document carries — the
* SOURCE OF TRUTH for whether a document is multilingual (present + non-empty →
* multilingual; the first is the default active). The component's `languages`
* prop is only an optional override / seed for NEW documents; an existing doc
* self-describes via this field. `normalize` preserves it like `scheme`.
*/
readonly languages?: readonly string[];
/**
* Multilingual (F-A): the language code whose content currently lives in each
* block's `children` (the rest are in `block.i18n`). Records which language is

Loading…
Cancel
Save

Powered by TurnKey Linux.