You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/scripts/rtl-check.ts

82 lines
3.1 KiB

feat(direction): un guard para el eje logico-fisico, y el <main> que congelaba las 51 demos Cierra la §2.1 del handoff. El guard nacio en rojo con 24 hallazgos y al arreglarlos aparecieron dos defectos mas grandes que el que buscaba. 1) EL GUARD RTL-1. Nada cruzaba un ancla LOGICA con un desplazamiento FISICO en la misma regla CSS: eidos-lint clasifica SELECTORES, no declaraciones, y la fila RTL del contrato de construccion decia "rule (LIVE)" — revision humana. Por eso el defecto del slider llego a produccion y lo cazo el ojo del usuario. Ahora `npm run rtl:check`, con la logica en src/uix/eidos/rtl-lint.ts (14 tests) para que sea testeable, calcando el par lint.ts / scripts/eidos-lint.ts. El test ancla el caso historico: slider.css ANTES de 013ceac57 sale rojo y el arreglo que se commiteo sale verde. Dos desviaciones del enunciado, deliberadas. AMPLIA a la propiedad independiente `translate:`, que se usa MAS que `transform: translate*` (87 frente a 36) y tiene el mismo defecto — ocho de los 24 hallazgos eran de esa forma. RECORTA `padding-inline*`: no mueve la caja contra su ancla, asi que no puede pelear con un translate; solo anadia ruido. 2) LA COSECHA, 24 -> 1. El unico que queda es palabras, auditado y no tocado. Los 23 caen en tres familias: CENTRADO (10) donde el resultado deseado es simetrico y basta dejar de descentrar; DIRECCIONAL (6) donde el signo debe voltear; y FISICO (7) donde lo que sobraba era el ancla logica — handles de brujula del cropper sobre una imagen que no se voltea, y el arco polar del menu-dial. Medido en Chrome el switch: el thumb salia a +24px en un carril de 38px, colgando fuera. Verificados tambien carousel, avatar, cropper, menu-dial y chat-log. 3) :dir() ES LA DOCTRINA, [dir='rtl'] QUEDA PROHIBIDO. Los 12 selectores que habia en eidos estaban TODOS rotos, en los dos sentidos opuestos del mismo error, y ambos medidos en Chrome. Los 5 descendientes se aplican DE MAS: el sidebar tenia direction:ltr de verdad y aun asi matcheaba, porque el selector capta cualquier ancestro RTL e ignora un dir mas cercano que redeclare. Los 7 de mismo-elemento NO se aplican NUNCA: el tree-view era rtl de verdad y no matcheaba, porque desde 013ceac57 el atributo solo se estampa si alguien lo afirmo. :dir() acierta los tres casos porque mira la direccion RESUELTA. Baseline desde 2023. 4) EL PIN DEL <main>. 5469e05df hizo dos cosas que se anulan: puso las demos en `auto` —sin prop dir, o sea el componente no estampa atributo y HEREDA del DOM— y a la vez clavo <main data-uix-canvas dir="ltr"> sobre ellas. Ese <main> era la herencia, asi que el toggle del topbar y el arabe llegaban a <html> y morian ahi: las 51 demos congeladas en LTR. Su comentario afirmaba que "los componentes siguen las prefs, este contenedor no les afecta" — cierto para la LOGICA, falso para el CSS, que lee el direction COMPUTADO. Medido: html dir="rtl" con el panel del sidebar todavia a la izquierda, y quitar ese atributo y nada mas lo movia. Se queda el lang="en". Coste aceptado por el usuario: vuelve la puntuacion desplazada en la prosa inglesa al elegir RTL, que es cosmetico y solo en un modo de inspeccion; demos que no pueden demostrar, no. Si hay que fijar la prosa otra vez, el pin va alrededor de la PROSA. Verificado: check 74 = linea base exacta en las tres pasadas. rtl-lint 14/14. Suite de eidos 375 pasan; el fallo de lint.test.ts por audio-player es PREEXISTENTE, comprobado con stash, y es del hilo del sonido. Los 9 CSS tocados ya fallaban prettier antes de tocarlos, asi que no se formatean. SIN VERIFICAR EN NAVEGADOR, anotado en el handoff: archetypes y proof-of-human (sus reglas viven en @media (pointer: coarse), invisible en escritorio) y sliding-indicator (la demo del radio-group segmented no llegaba a medir). QUEDA: hay wrappers estampando dir="" vacio en vez de omitir el atributo — visto en sidebar y tree-view; no rompe porque un valor invalido hereda, pero contradice la letra del contrato. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
/**
* rtl-check — the mechanical guard of the build contract's RTL row
* (docs/guides/component-guide.md). Until now that row's guard was
* "rule (LIVE)", i.e. human review, and it is how the Slider defect of
* `013ceac57` reached production: three vertical rules paired a logical
* `inset-inline-start` with a physical `translateX`, and nothing in CI looked
* at CSS declarations — `eidos-lint` classifies selectors.
*
* RTL-1 a physical inline-axis displacement (`transform: translateX/
* translate/translate3d`, or the independent `translate` property) in
* a block that also anchors on `inset-inline*` / `margin-inline*`.
* The anchor flips with the writing direction, the displacement does
* not: correct in LTR, a full element-width off-axis in RTL.
*
feat(direction): RTL-2 — el guard del doble volteo, la forma que se me colo dos veces Cierra §10.1, la ultima deuda del eje. `dee2c9e3a` arreglo los dos defectos pero dejo la FORMA sin guard, y es la que sobrevivio a la migracion §6.3 y a que yo diera el eje por cerrado en §9.19. LA FIRMA — dentro de un bloque cuyo prelude tiene `:dir()`, la misma familia logica (`border`/`padding`/`margin`/`inset`-`inline`) declarada en LAS DOS caras, EXACTAMENTE UNA con valor neutro (`0`, `auto`, `none`, `initial`, `unset`, `revert`). Ese desequilibrio ES el espejo cancelado: la propiedad ya se habia volteado cuando la regla matchea, asi que reubicarla la devuelve al punto de partida y la deja en el borde opuesto al de sus hermanas. Es mas estrecha que «bloque `:dir()` con puras logicas» a proposito. Una regla que CAMBIA un valor bajo RTL sin reubicarlo es legitima —asimetrico por diseño existe—, y las dos caras con valor son un autor describiendo dos bordes reales. Lo que delata el defecto es el PAR, una cara apagada. Hay un test negativo por cada uno de esos casos, que son los que evitan que la regla se vuelva ruido. LAS TRES DECISIONES que el handoff dejaba abiertas: - `:dir(ltr)` tambien entra. Igual de sospechosa, y no anade ruido. - Marcador PROPIO, `rtl-mirror: <reason>`. Reutilizar `rtl-physical:` mentiria: aqui no hay nada fisico, y un marcador que miente es peor que ninguno. Mismo mecanismo (`exemptLines` toma ahora el patron por parametro), dos vocabularios. Un test comprueba que el marcador de RTL-1 NO exime a RTL-2. - Regla aparte, `lintRtlMirror()` con su propio `RtlMirrorFinding`. Los 14 tests de RTL-1 quedan intactos y el tipo lleva los campos que importan (`family`/`neutral`/`payload`) en vez de forzar los de RTL-1. VERIFICACION, en este orden: - `rtl-lint.test.ts` 27/27 (14 de RTL-1 intactos + 13 nuevos). - RECALL con el runner COMPLETO contra el arbol pre-arreglo: restaure los dos ficheros de `dee2c9e3a^` sobre el arbol, corri `rtl:check` y los devolvi con `git checkout` en el mismo bloque. **2/2 cazados** (`feed.css:147`, `tree-view.css:211`). Probar la funcion no basta: el runner es lo que corre. - `rtl:check` sobre HEAD: 1 error, el de `palabras`, preexistente y excluido. - `docs:check` 0/0 sobre 564 docs. `check` 77 = linea base. Un defecto de presentacion salio al hacerlo: el `calc()` multilinea de tree-view partia el mensaje por el primer salto. Los campos que RTL-2 emite colapsan el whitespace; con test. Actualizados los textos que el handoff avisaba que quedarian obsoletos: el `enforcement:` y §4 del contrato, la fila RTL del build contract, la fila X-1.6 del checklist, y los docblocks de `rtl-lint.ts` y `rtl-check.ts` — que son doctrina, no adorno. ⚠️ Sigue siendo cierto lo que NINGUNA de las dos reglas ve: leen texto CSS. Un `transform` inline escrito por JS, un preset de motion compartido y la geometria SVG siguen necesitando el ojo en RTL. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
* RTL-2 inside a `:dir()` block, one logical face turned off and the other
* repainted. The property had ALREADY mirrored, so relocating it
* cancels the mirror and parks it opposite the siblings left alone.
* This is the shape that survived the `[dir='rtl']` → `:dir(rtl)`
* migration untouched, because that pass rewrote selectors and never
* read a body — a mechanical migration inherits what it translates.
*
* Both rules, their deliberate exclusions and their escape hatches
* (`rtl-physical:` / `rtl-mirror:`) live in `src/uix/eidos/rtl-lint.ts`.
feat(direction): un guard para el eje logico-fisico, y el <main> que congelaba las 51 demos Cierra la §2.1 del handoff. El guard nacio en rojo con 24 hallazgos y al arreglarlos aparecieron dos defectos mas grandes que el que buscaba. 1) EL GUARD RTL-1. Nada cruzaba un ancla LOGICA con un desplazamiento FISICO en la misma regla CSS: eidos-lint clasifica SELECTORES, no declaraciones, y la fila RTL del contrato de construccion decia "rule (LIVE)" — revision humana. Por eso el defecto del slider llego a produccion y lo cazo el ojo del usuario. Ahora `npm run rtl:check`, con la logica en src/uix/eidos/rtl-lint.ts (14 tests) para que sea testeable, calcando el par lint.ts / scripts/eidos-lint.ts. El test ancla el caso historico: slider.css ANTES de 013ceac57 sale rojo y el arreglo que se commiteo sale verde. Dos desviaciones del enunciado, deliberadas. AMPLIA a la propiedad independiente `translate:`, que se usa MAS que `transform: translate*` (87 frente a 36) y tiene el mismo defecto — ocho de los 24 hallazgos eran de esa forma. RECORTA `padding-inline*`: no mueve la caja contra su ancla, asi que no puede pelear con un translate; solo anadia ruido. 2) LA COSECHA, 24 -> 1. El unico que queda es palabras, auditado y no tocado. Los 23 caen en tres familias: CENTRADO (10) donde el resultado deseado es simetrico y basta dejar de descentrar; DIRECCIONAL (6) donde el signo debe voltear; y FISICO (7) donde lo que sobraba era el ancla logica — handles de brujula del cropper sobre una imagen que no se voltea, y el arco polar del menu-dial. Medido en Chrome el switch: el thumb salia a +24px en un carril de 38px, colgando fuera. Verificados tambien carousel, avatar, cropper, menu-dial y chat-log. 3) :dir() ES LA DOCTRINA, [dir='rtl'] QUEDA PROHIBIDO. Los 12 selectores que habia en eidos estaban TODOS rotos, en los dos sentidos opuestos del mismo error, y ambos medidos en Chrome. Los 5 descendientes se aplican DE MAS: el sidebar tenia direction:ltr de verdad y aun asi matcheaba, porque el selector capta cualquier ancestro RTL e ignora un dir mas cercano que redeclare. Los 7 de mismo-elemento NO se aplican NUNCA: el tree-view era rtl de verdad y no matcheaba, porque desde 013ceac57 el atributo solo se estampa si alguien lo afirmo. :dir() acierta los tres casos porque mira la direccion RESUELTA. Baseline desde 2023. 4) EL PIN DEL <main>. 5469e05df hizo dos cosas que se anulan: puso las demos en `auto` —sin prop dir, o sea el componente no estampa atributo y HEREDA del DOM— y a la vez clavo <main data-uix-canvas dir="ltr"> sobre ellas. Ese <main> era la herencia, asi que el toggle del topbar y el arabe llegaban a <html> y morian ahi: las 51 demos congeladas en LTR. Su comentario afirmaba que "los componentes siguen las prefs, este contenedor no les afecta" — cierto para la LOGICA, falso para el CSS, que lee el direction COMPUTADO. Medido: html dir="rtl" con el panel del sidebar todavia a la izquierda, y quitar ese atributo y nada mas lo movia. Se queda el lang="en". Coste aceptado por el usuario: vuelve la puntuacion desplazada en la prosa inglesa al elegir RTL, que es cosmetico y solo en un modo de inspeccion; demos que no pueden demostrar, no. Si hay que fijar la prosa otra vez, el pin va alrededor de la PROSA. Verificado: check 74 = linea base exacta en las tres pasadas. rtl-lint 14/14. Suite de eidos 375 pasan; el fallo de lint.test.ts por audio-player es PREEXISTENTE, comprobado con stash, y es del hilo del sonido. Los 9 CSS tocados ya fallaban prettier antes de tocarlos, asi que no se formatean. SIN VERIFICAR EN NAVEGADOR, anotado en el handoff: archetypes y proof-of-human (sus reglas viven en @media (pointer: coarse), invisible en escritorio) y sliding-indicator (la demo del radio-group segmented no llegaba a medir). QUEDA: hay wrappers estampando dir="" vacio en vez de omitir el atributo — visto en sidebar y tree-view; no rompe porque un valor invalido hereda, pero contradice la letra del contrato. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
*/
import { readdirSync, readFileSync, statSync } from 'node:fs';
import { join, relative } from 'node:path';
feat(direction): RTL-2 — el guard del doble volteo, la forma que se me colo dos veces Cierra §10.1, la ultima deuda del eje. `dee2c9e3a` arreglo los dos defectos pero dejo la FORMA sin guard, y es la que sobrevivio a la migracion §6.3 y a que yo diera el eje por cerrado en §9.19. LA FIRMA — dentro de un bloque cuyo prelude tiene `:dir()`, la misma familia logica (`border`/`padding`/`margin`/`inset`-`inline`) declarada en LAS DOS caras, EXACTAMENTE UNA con valor neutro (`0`, `auto`, `none`, `initial`, `unset`, `revert`). Ese desequilibrio ES el espejo cancelado: la propiedad ya se habia volteado cuando la regla matchea, asi que reubicarla la devuelve al punto de partida y la deja en el borde opuesto al de sus hermanas. Es mas estrecha que «bloque `:dir()` con puras logicas» a proposito. Una regla que CAMBIA un valor bajo RTL sin reubicarlo es legitima —asimetrico por diseño existe—, y las dos caras con valor son un autor describiendo dos bordes reales. Lo que delata el defecto es el PAR, una cara apagada. Hay un test negativo por cada uno de esos casos, que son los que evitan que la regla se vuelva ruido. LAS TRES DECISIONES que el handoff dejaba abiertas: - `:dir(ltr)` tambien entra. Igual de sospechosa, y no anade ruido. - Marcador PROPIO, `rtl-mirror: <reason>`. Reutilizar `rtl-physical:` mentiria: aqui no hay nada fisico, y un marcador que miente es peor que ninguno. Mismo mecanismo (`exemptLines` toma ahora el patron por parametro), dos vocabularios. Un test comprueba que el marcador de RTL-1 NO exime a RTL-2. - Regla aparte, `lintRtlMirror()` con su propio `RtlMirrorFinding`. Los 14 tests de RTL-1 quedan intactos y el tipo lleva los campos que importan (`family`/`neutral`/`payload`) en vez de forzar los de RTL-1. VERIFICACION, en este orden: - `rtl-lint.test.ts` 27/27 (14 de RTL-1 intactos + 13 nuevos). - RECALL con el runner COMPLETO contra el arbol pre-arreglo: restaure los dos ficheros de `dee2c9e3a^` sobre el arbol, corri `rtl:check` y los devolvi con `git checkout` en el mismo bloque. **2/2 cazados** (`feed.css:147`, `tree-view.css:211`). Probar la funcion no basta: el runner es lo que corre. - `rtl:check` sobre HEAD: 1 error, el de `palabras`, preexistente y excluido. - `docs:check` 0/0 sobre 564 docs. `check` 77 = linea base. Un defecto de presentacion salio al hacerlo: el `calc()` multilinea de tree-view partia el mensaje por el primer salto. Los campos que RTL-2 emite colapsan el whitespace; con test. Actualizados los textos que el handoff avisaba que quedarian obsoletos: el `enforcement:` y §4 del contrato, la fila RTL del build contract, la fila X-1.6 del checklist, y los docblocks de `rtl-lint.ts` y `rtl-check.ts` — que son doctrina, no adorno. ⚠️ Sigue siendo cierto lo que NINGUNA de las dos reglas ve: leen texto CSS. Un `transform` inline escrito por JS, un preset de motion compartido y la geometria SVG siguen necesitando el ojo en RTL. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
import { lintRtlGeometry, lintRtlMirror } from '../src/uix/eidos/rtl-lint';
feat(direction): un guard para el eje logico-fisico, y el <main> que congelaba las 51 demos Cierra la §2.1 del handoff. El guard nacio en rojo con 24 hallazgos y al arreglarlos aparecieron dos defectos mas grandes que el que buscaba. 1) EL GUARD RTL-1. Nada cruzaba un ancla LOGICA con un desplazamiento FISICO en la misma regla CSS: eidos-lint clasifica SELECTORES, no declaraciones, y la fila RTL del contrato de construccion decia "rule (LIVE)" — revision humana. Por eso el defecto del slider llego a produccion y lo cazo el ojo del usuario. Ahora `npm run rtl:check`, con la logica en src/uix/eidos/rtl-lint.ts (14 tests) para que sea testeable, calcando el par lint.ts / scripts/eidos-lint.ts. El test ancla el caso historico: slider.css ANTES de 013ceac57 sale rojo y el arreglo que se commiteo sale verde. Dos desviaciones del enunciado, deliberadas. AMPLIA a la propiedad independiente `translate:`, que se usa MAS que `transform: translate*` (87 frente a 36) y tiene el mismo defecto — ocho de los 24 hallazgos eran de esa forma. RECORTA `padding-inline*`: no mueve la caja contra su ancla, asi que no puede pelear con un translate; solo anadia ruido. 2) LA COSECHA, 24 -> 1. El unico que queda es palabras, auditado y no tocado. Los 23 caen en tres familias: CENTRADO (10) donde el resultado deseado es simetrico y basta dejar de descentrar; DIRECCIONAL (6) donde el signo debe voltear; y FISICO (7) donde lo que sobraba era el ancla logica — handles de brujula del cropper sobre una imagen que no se voltea, y el arco polar del menu-dial. Medido en Chrome el switch: el thumb salia a +24px en un carril de 38px, colgando fuera. Verificados tambien carousel, avatar, cropper, menu-dial y chat-log. 3) :dir() ES LA DOCTRINA, [dir='rtl'] QUEDA PROHIBIDO. Los 12 selectores que habia en eidos estaban TODOS rotos, en los dos sentidos opuestos del mismo error, y ambos medidos en Chrome. Los 5 descendientes se aplican DE MAS: el sidebar tenia direction:ltr de verdad y aun asi matcheaba, porque el selector capta cualquier ancestro RTL e ignora un dir mas cercano que redeclare. Los 7 de mismo-elemento NO se aplican NUNCA: el tree-view era rtl de verdad y no matcheaba, porque desde 013ceac57 el atributo solo se estampa si alguien lo afirmo. :dir() acierta los tres casos porque mira la direccion RESUELTA. Baseline desde 2023. 4) EL PIN DEL <main>. 5469e05df hizo dos cosas que se anulan: puso las demos en `auto` —sin prop dir, o sea el componente no estampa atributo y HEREDA del DOM— y a la vez clavo <main data-uix-canvas dir="ltr"> sobre ellas. Ese <main> era la herencia, asi que el toggle del topbar y el arabe llegaban a <html> y morian ahi: las 51 demos congeladas en LTR. Su comentario afirmaba que "los componentes siguen las prefs, este contenedor no les afecta" — cierto para la LOGICA, falso para el CSS, que lee el direction COMPUTADO. Medido: html dir="rtl" con el panel del sidebar todavia a la izquierda, y quitar ese atributo y nada mas lo movia. Se queda el lang="en". Coste aceptado por el usuario: vuelve la puntuacion desplazada en la prosa inglesa al elegir RTL, que es cosmetico y solo en un modo de inspeccion; demos que no pueden demostrar, no. Si hay que fijar la prosa otra vez, el pin va alrededor de la PROSA. Verificado: check 74 = linea base exacta en las tres pasadas. rtl-lint 14/14. Suite de eidos 375 pasan; el fallo de lint.test.ts por audio-player es PREEXISTENTE, comprobado con stash, y es del hilo del sonido. Los 9 CSS tocados ya fallaban prettier antes de tocarlos, asi que no se formatean. SIN VERIFICAR EN NAVEGADOR, anotado en el handoff: archetypes y proof-of-human (sus reglas viven en @media (pointer: coarse), invisible en escritorio) y sliding-indicator (la demo del radio-group segmented no llegaba a medir). QUEDA: hay wrappers estampando dir="" vacio en vez de omitir el atributo — visto en sidebar y tree-view; no rompe porque un valor invalido hereda, pero contradice la letra del contrato. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
const REPO = process.cwd();
const EIDOS_DIR = join(REPO, 'src', 'uix', 'eidos');
function walk(dir: string, out: string[] = []): string[] {
for (const entry of readdirSync(dir)) {
const path = join(dir, entry);
if (statSync(path).isDirectory()) walk(path, out);
else if (entry.endsWith('.css')) out.push(path);
}
return out;
}
function main(): void {
const files = walk(EIDOS_DIR);
let errors = 0;
for (const file of files) {
const rel = relative(REPO, file).replace(/\\/g, '/');
feat(direction): RTL-2 — el guard del doble volteo, la forma que se me colo dos veces Cierra §10.1, la ultima deuda del eje. `dee2c9e3a` arreglo los dos defectos pero dejo la FORMA sin guard, y es la que sobrevivio a la migracion §6.3 y a que yo diera el eje por cerrado en §9.19. LA FIRMA — dentro de un bloque cuyo prelude tiene `:dir()`, la misma familia logica (`border`/`padding`/`margin`/`inset`-`inline`) declarada en LAS DOS caras, EXACTAMENTE UNA con valor neutro (`0`, `auto`, `none`, `initial`, `unset`, `revert`). Ese desequilibrio ES el espejo cancelado: la propiedad ya se habia volteado cuando la regla matchea, asi que reubicarla la devuelve al punto de partida y la deja en el borde opuesto al de sus hermanas. Es mas estrecha que «bloque `:dir()` con puras logicas» a proposito. Una regla que CAMBIA un valor bajo RTL sin reubicarlo es legitima —asimetrico por diseño existe—, y las dos caras con valor son un autor describiendo dos bordes reales. Lo que delata el defecto es el PAR, una cara apagada. Hay un test negativo por cada uno de esos casos, que son los que evitan que la regla se vuelva ruido. LAS TRES DECISIONES que el handoff dejaba abiertas: - `:dir(ltr)` tambien entra. Igual de sospechosa, y no anade ruido. - Marcador PROPIO, `rtl-mirror: <reason>`. Reutilizar `rtl-physical:` mentiria: aqui no hay nada fisico, y un marcador que miente es peor que ninguno. Mismo mecanismo (`exemptLines` toma ahora el patron por parametro), dos vocabularios. Un test comprueba que el marcador de RTL-1 NO exime a RTL-2. - Regla aparte, `lintRtlMirror()` con su propio `RtlMirrorFinding`. Los 14 tests de RTL-1 quedan intactos y el tipo lleva los campos que importan (`family`/`neutral`/`payload`) en vez de forzar los de RTL-1. VERIFICACION, en este orden: - `rtl-lint.test.ts` 27/27 (14 de RTL-1 intactos + 13 nuevos). - RECALL con el runner COMPLETO contra el arbol pre-arreglo: restaure los dos ficheros de `dee2c9e3a^` sobre el arbol, corri `rtl:check` y los devolvi con `git checkout` en el mismo bloque. **2/2 cazados** (`feed.css:147`, `tree-view.css:211`). Probar la funcion no basta: el runner es lo que corre. - `rtl:check` sobre HEAD: 1 error, el de `palabras`, preexistente y excluido. - `docs:check` 0/0 sobre 564 docs. `check` 77 = linea base. Un defecto de presentacion salio al hacerlo: el `calc()` multilinea de tree-view partia el mensaje por el primer salto. Los campos que RTL-2 emite colapsan el whitespace; con test. Actualizados los textos que el handoff avisaba que quedarian obsoletos: el `enforcement:` y §4 del contrato, la fila RTL del build contract, la fila X-1.6 del checklist, y los docblocks de `rtl-lint.ts` y `rtl-check.ts` — que son doctrina, no adorno. ⚠️ Sigue siendo cierto lo que NINGUNA de las dos reglas ve: leen texto CSS. Un `transform` inline escrito por JS, un preset de motion compartido y la geometria SVG siguen necesitando el ojo en RTL. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
const css = readFileSync(file, 'utf8');
for (const f of lintRtlGeometry(css)) {
feat(direction): un guard para el eje logico-fisico, y el <main> que congelaba las 51 demos Cierra la §2.1 del handoff. El guard nacio en rojo con 24 hallazgos y al arreglarlos aparecieron dos defectos mas grandes que el que buscaba. 1) EL GUARD RTL-1. Nada cruzaba un ancla LOGICA con un desplazamiento FISICO en la misma regla CSS: eidos-lint clasifica SELECTORES, no declaraciones, y la fila RTL del contrato de construccion decia "rule (LIVE)" — revision humana. Por eso el defecto del slider llego a produccion y lo cazo el ojo del usuario. Ahora `npm run rtl:check`, con la logica en src/uix/eidos/rtl-lint.ts (14 tests) para que sea testeable, calcando el par lint.ts / scripts/eidos-lint.ts. El test ancla el caso historico: slider.css ANTES de 013ceac57 sale rojo y el arreglo que se commiteo sale verde. Dos desviaciones del enunciado, deliberadas. AMPLIA a la propiedad independiente `translate:`, que se usa MAS que `transform: translate*` (87 frente a 36) y tiene el mismo defecto — ocho de los 24 hallazgos eran de esa forma. RECORTA `padding-inline*`: no mueve la caja contra su ancla, asi que no puede pelear con un translate; solo anadia ruido. 2) LA COSECHA, 24 -> 1. El unico que queda es palabras, auditado y no tocado. Los 23 caen en tres familias: CENTRADO (10) donde el resultado deseado es simetrico y basta dejar de descentrar; DIRECCIONAL (6) donde el signo debe voltear; y FISICO (7) donde lo que sobraba era el ancla logica — handles de brujula del cropper sobre una imagen que no se voltea, y el arco polar del menu-dial. Medido en Chrome el switch: el thumb salia a +24px en un carril de 38px, colgando fuera. Verificados tambien carousel, avatar, cropper, menu-dial y chat-log. 3) :dir() ES LA DOCTRINA, [dir='rtl'] QUEDA PROHIBIDO. Los 12 selectores que habia en eidos estaban TODOS rotos, en los dos sentidos opuestos del mismo error, y ambos medidos en Chrome. Los 5 descendientes se aplican DE MAS: el sidebar tenia direction:ltr de verdad y aun asi matcheaba, porque el selector capta cualquier ancestro RTL e ignora un dir mas cercano que redeclare. Los 7 de mismo-elemento NO se aplican NUNCA: el tree-view era rtl de verdad y no matcheaba, porque desde 013ceac57 el atributo solo se estampa si alguien lo afirmo. :dir() acierta los tres casos porque mira la direccion RESUELTA. Baseline desde 2023. 4) EL PIN DEL <main>. 5469e05df hizo dos cosas que se anulan: puso las demos en `auto` —sin prop dir, o sea el componente no estampa atributo y HEREDA del DOM— y a la vez clavo <main data-uix-canvas dir="ltr"> sobre ellas. Ese <main> era la herencia, asi que el toggle del topbar y el arabe llegaban a <html> y morian ahi: las 51 demos congeladas en LTR. Su comentario afirmaba que "los componentes siguen las prefs, este contenedor no les afecta" — cierto para la LOGICA, falso para el CSS, que lee el direction COMPUTADO. Medido: html dir="rtl" con el panel del sidebar todavia a la izquierda, y quitar ese atributo y nada mas lo movia. Se queda el lang="en". Coste aceptado por el usuario: vuelve la puntuacion desplazada en la prosa inglesa al elegir RTL, que es cosmetico y solo en un modo de inspeccion; demos que no pueden demostrar, no. Si hay que fijar la prosa otra vez, el pin va alrededor de la PROSA. Verificado: check 74 = linea base exacta en las tres pasadas. rtl-lint 14/14. Suite de eidos 375 pasan; el fallo de lint.test.ts por audio-player es PREEXISTENTE, comprobado con stash, y es del hilo del sonido. Los 9 CSS tocados ya fallaban prettier antes de tocarlos, asi que no se formatean. SIN VERIFICAR EN NAVEGADOR, anotado en el handoff: archetypes y proof-of-human (sus reglas viven en @media (pointer: coarse), invisible en escritorio) y sliding-indicator (la demo del radio-group segmented no llegaba a medir). QUEDA: hay wrappers estampando dir="" vacio en vez de omitir el atributo — visto en sidebar y tree-view; no rompe porque un valor invalido hereda, pero contradice la letra del contrato. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
errors++;
console.error(
`ERROR [RTL-1] ${rel}:${f.line} — physical "${f.translate}" against logical ` +
`${f.anchors.map((a) => `"${a}"`).join(' + ')} in ${f.selector}`
);
}
feat(direction): RTL-2 — el guard del doble volteo, la forma que se me colo dos veces Cierra §10.1, la ultima deuda del eje. `dee2c9e3a` arreglo los dos defectos pero dejo la FORMA sin guard, y es la que sobrevivio a la migracion §6.3 y a que yo diera el eje por cerrado en §9.19. LA FIRMA — dentro de un bloque cuyo prelude tiene `:dir()`, la misma familia logica (`border`/`padding`/`margin`/`inset`-`inline`) declarada en LAS DOS caras, EXACTAMENTE UNA con valor neutro (`0`, `auto`, `none`, `initial`, `unset`, `revert`). Ese desequilibrio ES el espejo cancelado: la propiedad ya se habia volteado cuando la regla matchea, asi que reubicarla la devuelve al punto de partida y la deja en el borde opuesto al de sus hermanas. Es mas estrecha que «bloque `:dir()` con puras logicas» a proposito. Una regla que CAMBIA un valor bajo RTL sin reubicarlo es legitima —asimetrico por diseño existe—, y las dos caras con valor son un autor describiendo dos bordes reales. Lo que delata el defecto es el PAR, una cara apagada. Hay un test negativo por cada uno de esos casos, que son los que evitan que la regla se vuelva ruido. LAS TRES DECISIONES que el handoff dejaba abiertas: - `:dir(ltr)` tambien entra. Igual de sospechosa, y no anade ruido. - Marcador PROPIO, `rtl-mirror: <reason>`. Reutilizar `rtl-physical:` mentiria: aqui no hay nada fisico, y un marcador que miente es peor que ninguno. Mismo mecanismo (`exemptLines` toma ahora el patron por parametro), dos vocabularios. Un test comprueba que el marcador de RTL-1 NO exime a RTL-2. - Regla aparte, `lintRtlMirror()` con su propio `RtlMirrorFinding`. Los 14 tests de RTL-1 quedan intactos y el tipo lleva los campos que importan (`family`/`neutral`/`payload`) en vez de forzar los de RTL-1. VERIFICACION, en este orden: - `rtl-lint.test.ts` 27/27 (14 de RTL-1 intactos + 13 nuevos). - RECALL con el runner COMPLETO contra el arbol pre-arreglo: restaure los dos ficheros de `dee2c9e3a^` sobre el arbol, corri `rtl:check` y los devolvi con `git checkout` en el mismo bloque. **2/2 cazados** (`feed.css:147`, `tree-view.css:211`). Probar la funcion no basta: el runner es lo que corre. - `rtl:check` sobre HEAD: 1 error, el de `palabras`, preexistente y excluido. - `docs:check` 0/0 sobre 564 docs. `check` 77 = linea base. Un defecto de presentacion salio al hacerlo: el `calc()` multilinea de tree-view partia el mensaje por el primer salto. Los campos que RTL-2 emite colapsan el whitespace; con test. Actualizados los textos que el handoff avisaba que quedarian obsoletos: el `enforcement:` y §4 del contrato, la fila RTL del build contract, la fila X-1.6 del checklist, y los docblocks de `rtl-lint.ts` y `rtl-check.ts` — que son doctrina, no adorno. ⚠️ Sigue siendo cierto lo que NINGUNA de las dos reglas ve: leen texto CSS. Un `transform` inline escrito por JS, un preset de motion compartido y la geometria SVG siguen necesitando el ojo en RTL. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
for (const f of lintRtlMirror(css)) {
errors++;
console.error(
`ERROR [RTL-2] ${rel}:${f.line} — double flip: "${f.neutral}" turns a face off and ` +
`"${f.payload}" repaints the other, but ${f.family} had already mirrored ` +
`in ${f.selector}`
);
}
feat(direction): un guard para el eje logico-fisico, y el <main> que congelaba las 51 demos Cierra la §2.1 del handoff. El guard nacio en rojo con 24 hallazgos y al arreglarlos aparecieron dos defectos mas grandes que el que buscaba. 1) EL GUARD RTL-1. Nada cruzaba un ancla LOGICA con un desplazamiento FISICO en la misma regla CSS: eidos-lint clasifica SELECTORES, no declaraciones, y la fila RTL del contrato de construccion decia "rule (LIVE)" — revision humana. Por eso el defecto del slider llego a produccion y lo cazo el ojo del usuario. Ahora `npm run rtl:check`, con la logica en src/uix/eidos/rtl-lint.ts (14 tests) para que sea testeable, calcando el par lint.ts / scripts/eidos-lint.ts. El test ancla el caso historico: slider.css ANTES de 013ceac57 sale rojo y el arreglo que se commiteo sale verde. Dos desviaciones del enunciado, deliberadas. AMPLIA a la propiedad independiente `translate:`, que se usa MAS que `transform: translate*` (87 frente a 36) y tiene el mismo defecto — ocho de los 24 hallazgos eran de esa forma. RECORTA `padding-inline*`: no mueve la caja contra su ancla, asi que no puede pelear con un translate; solo anadia ruido. 2) LA COSECHA, 24 -> 1. El unico que queda es palabras, auditado y no tocado. Los 23 caen en tres familias: CENTRADO (10) donde el resultado deseado es simetrico y basta dejar de descentrar; DIRECCIONAL (6) donde el signo debe voltear; y FISICO (7) donde lo que sobraba era el ancla logica — handles de brujula del cropper sobre una imagen que no se voltea, y el arco polar del menu-dial. Medido en Chrome el switch: el thumb salia a +24px en un carril de 38px, colgando fuera. Verificados tambien carousel, avatar, cropper, menu-dial y chat-log. 3) :dir() ES LA DOCTRINA, [dir='rtl'] QUEDA PROHIBIDO. Los 12 selectores que habia en eidos estaban TODOS rotos, en los dos sentidos opuestos del mismo error, y ambos medidos en Chrome. Los 5 descendientes se aplican DE MAS: el sidebar tenia direction:ltr de verdad y aun asi matcheaba, porque el selector capta cualquier ancestro RTL e ignora un dir mas cercano que redeclare. Los 7 de mismo-elemento NO se aplican NUNCA: el tree-view era rtl de verdad y no matcheaba, porque desde 013ceac57 el atributo solo se estampa si alguien lo afirmo. :dir() acierta los tres casos porque mira la direccion RESUELTA. Baseline desde 2023. 4) EL PIN DEL <main>. 5469e05df hizo dos cosas que se anulan: puso las demos en `auto` —sin prop dir, o sea el componente no estampa atributo y HEREDA del DOM— y a la vez clavo <main data-uix-canvas dir="ltr"> sobre ellas. Ese <main> era la herencia, asi que el toggle del topbar y el arabe llegaban a <html> y morian ahi: las 51 demos congeladas en LTR. Su comentario afirmaba que "los componentes siguen las prefs, este contenedor no les afecta" — cierto para la LOGICA, falso para el CSS, que lee el direction COMPUTADO. Medido: html dir="rtl" con el panel del sidebar todavia a la izquierda, y quitar ese atributo y nada mas lo movia. Se queda el lang="en". Coste aceptado por el usuario: vuelve la puntuacion desplazada en la prosa inglesa al elegir RTL, que es cosmetico y solo en un modo de inspeccion; demos que no pueden demostrar, no. Si hay que fijar la prosa otra vez, el pin va alrededor de la PROSA. Verificado: check 74 = linea base exacta en las tres pasadas. rtl-lint 14/14. Suite de eidos 375 pasan; el fallo de lint.test.ts por audio-player es PREEXISTENTE, comprobado con stash, y es del hilo del sonido. Los 9 CSS tocados ya fallaban prettier antes de tocarlos, asi que no se formatean. SIN VERIFICAR EN NAVEGADOR, anotado en el handoff: archetypes y proof-of-human (sus reglas viven en @media (pointer: coarse), invisible en escritorio) y sliding-indicator (la demo del radio-group segmented no llegaba a medir). QUEDA: hay wrappers estampando dir="" vacio en vez de omitir el atributo — visto en sidebar y tree-view; no rompe porque un valor invalido hereda, pero contradice la letra del contrato. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
}
if (errors > 0) {
console.error(
`\nrtl-check: ${errors} error(s) across ${files.length} files\n` +
feat(direction): RTL-2 — el guard del doble volteo, la forma que se me colo dos veces Cierra §10.1, la ultima deuda del eje. `dee2c9e3a` arreglo los dos defectos pero dejo la FORMA sin guard, y es la que sobrevivio a la migracion §6.3 y a que yo diera el eje por cerrado en §9.19. LA FIRMA — dentro de un bloque cuyo prelude tiene `:dir()`, la misma familia logica (`border`/`padding`/`margin`/`inset`-`inline`) declarada en LAS DOS caras, EXACTAMENTE UNA con valor neutro (`0`, `auto`, `none`, `initial`, `unset`, `revert`). Ese desequilibrio ES el espejo cancelado: la propiedad ya se habia volteado cuando la regla matchea, asi que reubicarla la devuelve al punto de partida y la deja en el borde opuesto al de sus hermanas. Es mas estrecha que «bloque `:dir()` con puras logicas» a proposito. Una regla que CAMBIA un valor bajo RTL sin reubicarlo es legitima —asimetrico por diseño existe—, y las dos caras con valor son un autor describiendo dos bordes reales. Lo que delata el defecto es el PAR, una cara apagada. Hay un test negativo por cada uno de esos casos, que son los que evitan que la regla se vuelva ruido. LAS TRES DECISIONES que el handoff dejaba abiertas: - `:dir(ltr)` tambien entra. Igual de sospechosa, y no anade ruido. - Marcador PROPIO, `rtl-mirror: <reason>`. Reutilizar `rtl-physical:` mentiria: aqui no hay nada fisico, y un marcador que miente es peor que ninguno. Mismo mecanismo (`exemptLines` toma ahora el patron por parametro), dos vocabularios. Un test comprueba que el marcador de RTL-1 NO exime a RTL-2. - Regla aparte, `lintRtlMirror()` con su propio `RtlMirrorFinding`. Los 14 tests de RTL-1 quedan intactos y el tipo lleva los campos que importan (`family`/`neutral`/`payload`) en vez de forzar los de RTL-1. VERIFICACION, en este orden: - `rtl-lint.test.ts` 27/27 (14 de RTL-1 intactos + 13 nuevos). - RECALL con el runner COMPLETO contra el arbol pre-arreglo: restaure los dos ficheros de `dee2c9e3a^` sobre el arbol, corri `rtl:check` y los devolvi con `git checkout` en el mismo bloque. **2/2 cazados** (`feed.css:147`, `tree-view.css:211`). Probar la funcion no basta: el runner es lo que corre. - `rtl:check` sobre HEAD: 1 error, el de `palabras`, preexistente y excluido. - `docs:check` 0/0 sobre 564 docs. `check` 77 = linea base. Un defecto de presentacion salio al hacerlo: el `calc()` multilinea de tree-view partia el mensaje por el primer salto. Los campos que RTL-2 emite colapsan el whitespace; con test. Actualizados los textos que el handoff avisaba que quedarian obsoletos: el `enforcement:` y §4 del contrato, la fila RTL del build contract, la fila X-1.6 del checklist, y los docblocks de `rtl-lint.ts` y `rtl-check.ts` — que son doctrina, no adorno. ⚠️ Sigue siendo cierto lo que NINGUNA de las dos reglas ve: leen texto CSS. Un `transform` inline escrito por JS, un preset de motion compartido y la geometria SVG siguen necesitando el ojo en RTL. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
'RTL-1: express the offset logically (margin-inline-start: calc(…)), go fully\n' +
'physical (left/right), or mark the line /* rtl-physical: <reason> */ if meant.\n' +
'RTL-2: DELETE the rule and check the base declaration — it had already mirrored.'
feat(direction): un guard para el eje logico-fisico, y el <main> que congelaba las 51 demos Cierra la §2.1 del handoff. El guard nacio en rojo con 24 hallazgos y al arreglarlos aparecieron dos defectos mas grandes que el que buscaba. 1) EL GUARD RTL-1. Nada cruzaba un ancla LOGICA con un desplazamiento FISICO en la misma regla CSS: eidos-lint clasifica SELECTORES, no declaraciones, y la fila RTL del contrato de construccion decia "rule (LIVE)" — revision humana. Por eso el defecto del slider llego a produccion y lo cazo el ojo del usuario. Ahora `npm run rtl:check`, con la logica en src/uix/eidos/rtl-lint.ts (14 tests) para que sea testeable, calcando el par lint.ts / scripts/eidos-lint.ts. El test ancla el caso historico: slider.css ANTES de 013ceac57 sale rojo y el arreglo que se commiteo sale verde. Dos desviaciones del enunciado, deliberadas. AMPLIA a la propiedad independiente `translate:`, que se usa MAS que `transform: translate*` (87 frente a 36) y tiene el mismo defecto — ocho de los 24 hallazgos eran de esa forma. RECORTA `padding-inline*`: no mueve la caja contra su ancla, asi que no puede pelear con un translate; solo anadia ruido. 2) LA COSECHA, 24 -> 1. El unico que queda es palabras, auditado y no tocado. Los 23 caen en tres familias: CENTRADO (10) donde el resultado deseado es simetrico y basta dejar de descentrar; DIRECCIONAL (6) donde el signo debe voltear; y FISICO (7) donde lo que sobraba era el ancla logica — handles de brujula del cropper sobre una imagen que no se voltea, y el arco polar del menu-dial. Medido en Chrome el switch: el thumb salia a +24px en un carril de 38px, colgando fuera. Verificados tambien carousel, avatar, cropper, menu-dial y chat-log. 3) :dir() ES LA DOCTRINA, [dir='rtl'] QUEDA PROHIBIDO. Los 12 selectores que habia en eidos estaban TODOS rotos, en los dos sentidos opuestos del mismo error, y ambos medidos en Chrome. Los 5 descendientes se aplican DE MAS: el sidebar tenia direction:ltr de verdad y aun asi matcheaba, porque el selector capta cualquier ancestro RTL e ignora un dir mas cercano que redeclare. Los 7 de mismo-elemento NO se aplican NUNCA: el tree-view era rtl de verdad y no matcheaba, porque desde 013ceac57 el atributo solo se estampa si alguien lo afirmo. :dir() acierta los tres casos porque mira la direccion RESUELTA. Baseline desde 2023. 4) EL PIN DEL <main>. 5469e05df hizo dos cosas que se anulan: puso las demos en `auto` —sin prop dir, o sea el componente no estampa atributo y HEREDA del DOM— y a la vez clavo <main data-uix-canvas dir="ltr"> sobre ellas. Ese <main> era la herencia, asi que el toggle del topbar y el arabe llegaban a <html> y morian ahi: las 51 demos congeladas en LTR. Su comentario afirmaba que "los componentes siguen las prefs, este contenedor no les afecta" — cierto para la LOGICA, falso para el CSS, que lee el direction COMPUTADO. Medido: html dir="rtl" con el panel del sidebar todavia a la izquierda, y quitar ese atributo y nada mas lo movia. Se queda el lang="en". Coste aceptado por el usuario: vuelve la puntuacion desplazada en la prosa inglesa al elegir RTL, que es cosmetico y solo en un modo de inspeccion; demos que no pueden demostrar, no. Si hay que fijar la prosa otra vez, el pin va alrededor de la PROSA. Verificado: check 74 = linea base exacta en las tres pasadas. rtl-lint 14/14. Suite de eidos 375 pasan; el fallo de lint.test.ts por audio-player es PREEXISTENTE, comprobado con stash, y es del hilo del sonido. Los 9 CSS tocados ya fallaban prettier antes de tocarlos, asi que no se formatean. SIN VERIFICAR EN NAVEGADOR, anotado en el handoff: archetypes y proof-of-human (sus reglas viven en @media (pointer: coarse), invisible en escritorio) y sliding-indicator (la demo del radio-group segmented no llegaba a medir). QUEDA: hay wrappers estampando dir="" vacio en vez de omitir el atributo — visto en sidebar y tree-view; no rompe porque un valor invalido hereda, pero contradice la letra del contrato. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2 months ago
);
process.exit(1);
}
console.log(`rtl-check: 0 error(s) across ${files.length} files`);
}
main();

Powered by TurnKey Linux.