traducir.py: nginx → caddy, con acta — y validar con el binario real cazó un bug que CAMBIABA el sentido
Cambiar de nginx a caddy es reescribir la configuración. `traducir.py` hace la parte mecánica y dice
CON NÚMERO DE LÍNEA lo que no pudo traducir.
Doctrina heredada de `soltar`/`paskaq` (tawasuyu): su dominio es otro —datos presos en formatos
cautivos— pero sus principios son los que hacían falta. **Elisión honesta**: lo que no se pudo
traducir se reporta con su línea y su motivo, porque un traductor que descarta en silencio te deja un
servidor sin una redirección o sin una regla de auth y el sitio parece funcionar. **No adivinar en
silencio**: cada heurística queda como decisión explícita. **Procedencia**: cada bloque dice de qué
línea salió.
⚠ **Validar con el caddy real destapó dos bugs que leer la salida no mostraba:**
1. `ambiguous site definition` — en nginx dos `server` con el mismo nombre se distinguen por su
`listen`; en Caddy, por el esquema de la dirección.
2. **El grave**: un `if (...) { return 403; }` salía como `respond 403` INCONDICIONAL — el sitio
entero devolviendo 403. La directiva estaba dentro de un bloque declarado intraducible y se
absorbía igual al de afuera. Es peor que la pérdida silenciosa: no pierde, CAMBIA el sentido.
Ahora todo lo que vive en un bloque opaco sale `SIN-TRADUCIR` con su motivo.
Con los dos arreglados: `Valid configuration` según el caddy del propio corpus.
Y es honesto sobre su alcance: traduce el núcleo común y declara el resto. Uno que cubre el 70 % y
dice cuál es el 30 % restante es útil; uno que aparenta cubrir el 100 % es una trampa.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RomoxEGZUhaT4pob1QSX5x
This commit is contained in:
@@ -301,6 +301,57 @@ reconstruyen el servidor desde cero**:
|
||||
Ninguno de los tres es un log de lo que se hizo: los tres son entradas que se vuelven a ejecutar.
|
||||
Ésa es la diferencia entre mudar un servidor y poder mudarlo otra vez.
|
||||
|
||||
### 4.0 quinquies · Traducir la configuración — `traducir.py`
|
||||
|
||||
Cambiar de nginx a caddy no es cambiar un binario: es **reescribir la configuración**. `traducir.py`
|
||||
hace la parte mecánica y —sobre todo— **dice con número de línea lo que NO pudo traducir**.
|
||||
|
||||
#### Doctrina heredada de `soltar`/`paskaq` (tawasuyu)
|
||||
|
||||
`soltar` desencadena datos presos en formatos cautivos (Btrieve, Paradox, `.mdb`). El dominio es otro
|
||||
—datos, no configuración— pero sus principios son exactamente los que hacía falta, y se adoptan tal
|
||||
cual:
|
||||
|
||||
- **Elisión honesta.** «Lo que no se pudo leer se reporta con offset y motivo.» Acá cada directiva no
|
||||
entendida sale con su línea y su texto. **Un traductor que descarta en silencio te deja un servidor
|
||||
sin una redirección o sin una regla de auth, y el sitio parece funcionar.**
|
||||
- **No adivinar en silencio**: toda heurística queda como decisión explícita, no aplicada de tapadillo.
|
||||
- **Procedencia total**: cada bloque del resultado dice de qué línea del original salió.
|
||||
- **Determinista**: mismo fichero, misma salida.
|
||||
|
||||
Y lo que NO es: un traductor completo de nginx. Traduce el núcleo común y **declara todo lo demás**.
|
||||
*Uno honesto que cubre el 70 % y dice cuál es el 30 % restante es útil; uno que aparenta cubrir el
|
||||
100 % es una trampa.*
|
||||
|
||||
#### ⚠ Validar con el binario real encontró dos bugs, y uno cambiaba el sentido
|
||||
|
||||
Leer la salida no alcanzaba. Pasarla por `caddy validate` —con el caddy del propio corpus— destapó:
|
||||
|
||||
1. **`ambiguous site definition`**: en nginx dos `server` con el mismo `server_name` se distinguen por
|
||||
su `listen`; en Caddy, por el **esquema de la dirección**. Sin traducir eso, los bloques colisionan
|
||||
y el fichero ni carga.
|
||||
2. **Y el grave**: un `if (...) { return 403; }` salía como `respond 403` **incondicional** — el sitio
|
||||
entero devolviendo 403. La directiva vivía dentro de un bloque que yo mismo había declarado
|
||||
intraducible, y se absorbía igual al bloque de afuera.
|
||||
|
||||
Eso es peor que la pérdida silenciosa que la doctrina de `soltar` advierte: **no pierde, CAMBIA el
|
||||
sentido**. Ahora todo lo que está dentro de un bloque opaco sale como `SIN-TRADUCIR` con su motivo:
|
||||
*«sacarla de ahí le cambiaría el sentido — dejaría de ser condicional»*.
|
||||
|
||||
Con los dos arreglados, el caddy del corpus contesta **`Valid configuration`**.
|
||||
|
||||
#### Y la receta de caddy, terminada
|
||||
|
||||
El `caddy` del corpus era un **import de nix en crudo**: su cabecera decía «PUNTO DE PARTIDA, no
|
||||
final» y su `commit` era el TAG flotante `v2.11.4` — contra el ADR 0006, porque un tag se mueve y la
|
||||
receta pasa a construir otra cosa sin que el hash lo note. Anclado a `e2eee6a7…` con `takana pin`; el
|
||||
hash se movió a propósito. 77 MB estáticos, **0 intérpretes requeridos**, y un `file-server` de
|
||||
prueba contesta 200.
|
||||
|
||||
Importaba terminarla por una razón medida: **el `caddy` de gioser no tiene dueño** — binario puesto a
|
||||
mano, sin paquete y sin receta — y se pierde con la máquina. Con la receta, el servidor nuevo lo
|
||||
declara y lo reconstruye.
|
||||
|
||||
### 4.1 El aplicador *(implementado: `scripts/mudanza/aplicar.py`)*
|
||||
|
||||
`aplicar.py --plan plan.toml [--dry-run] [--only <clase>] [--paso N] [--hecho N]`
|
||||
|
||||
Reference in New Issue
Block a user