smtp-relay/.metodo/metodo.md
sirxavor 4c4df9a529 docs(metodo): re-estampa el Metodo 2026-08-15 (promocion de la primera cosecha)
7 adiciones promovidas del buzon de la matriz (0 railes nuevos): R3 diff-del-artefacto,
R6 ruta-exacta, R7 consumidor-salta-merge, R8 preferencia-vs-identidad, rail 12 lineas
ejecutables, Entrega/Git representacion en disco, Entrega/Deploy testigo-en-el-registro.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-15 03:04:20 +02:00

141 lines
8.6 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# El Método — constitución
> **Versión 2026-08-15.** Documento **autocontenido**: es lo que se vendoriza, byte a byte, a cada
> repo (no lleva enlaces a rutas de un árbol concreto, para que funcione clonado en solitario).
> Cada regla lleva su **cicatriz** (meta-principio: un raíl se escribe con el incidente que lo
> enseñó, no a priori). Procedencia, fuerza (nº de repos) y partición linter/juicio: fichero
> `constitucion-de-facto.md` de la matriz.
>
> Los 10 raíles base van hoy **en una línea** (su texto completo con cicatrices está pendiente de
> inlinar); lo promovido de las cosechas (2026-08-08 y 2026-08-15) va **completo**. El árbol `redes`
> conserva su copia `redes/workflows/metodo.md` hasta que se desmantele.
## Raíles base (110)
1. Verifica el **RESULTADO**, no la intención (testigo independiente que sabe ponerse rojo).
2. El dato **CRUDO**, no el cocinado (backend mide, consumidor pinta).
3. **Mutation testing**: ataca el CABLEADO, no las funciones puras.
4. Ejercita el **FLUJO REAL** (abre el navegador, toca el device).
5. No inventes estados ni fallos **no medidos** ("sin dato", degrada a gris no a rojo).
6. Verifica la **PREMISA** del prompt (enmendar es SUSTITUIR; premisa falsa = PARAR). **← +C34**
7. **Fuente única** + copias vendidas + red anti-deriva (`--check`).
8. **Fallo benigno EXPLÍCITO**, nunca degradación silenciosa.
9. **Sesiones frescas** por stack; la continuidad la lleva el orquestador.
10. Lo que **"funciona por casualidad"** está roto.
---
## Raíles nuevos (promovidos 2026-08-08)
### 11. El orden de lo irreversible: añadir antes de quitar · *C14 (4 fuentes)*
Todo lo verificable ocurre **antes** del paso que no se deshace. Se **añade antes de quitar**, se
crea antes de borrar; cada paso de una release se revierte por separado y ninguno depende de dos
cosas nuevas a la vez.
- Un tercer nodo de etcd entra **antes** de que salga el que se retira — al revés, el quórum se
queda en uno.
- "Nunca borres el `IPAddressPool` viejo hasta tener el nuevo sirviendo" (MetalLB).
- El cutover de un servicio con nombre: primero responde el nuevo, luego se retira el viejo.
### 12. Exploración solo-lectura, sin autoengaño · *C35 (Solidaria)*
Explorar es **medir sin tocar, y sin creerte tu propia medida**.
- `curl` **con control**: mira `/api/health`/`http_code`, no "parece que responde".
- **"Aquí no hay nada" es un RESULTADO**, no un fracaso — se anota igual que un hallazgo.
- Los **falsos positivos de `grep` son el riesgo nº1**: una lista larga de "roto" delata TU método
(un patrón demasiado amplio), no el sistema. Verifica cada hit contra la fuente antes de declararlo.
- Sobre **texto generado**, el testigo se define sobre las líneas **EJECUTABLES**, no sobre el
fichero: si el generador emite comentarios que documentan las ramas NO tomadas, el grep ingenuo
mide el comentario — verde indistinguible de rojo. *(Cicatriz: banco de render de infraserver,
2026-08-12.)*
- Medir, no opinar. Sondear una escritura **ES** escribir (no es exploración).
---
## Entrega — la parte de "sacar el trabajo" (promovido 2026-08-08)
El método nació de verificación/UI; la cicatriz de **entrega** (git, secretos, naming, deploy) vivía
fuera, repetida en varios repos. Aquí se consolida.
### Naming · *C17, C32*
- **Ids con prefijo por ámbito**, **no se renumeran** (romperían citas cruzadas), y **antes de
añadir uno se corre el grep de colisión** — no basta con mirar.
- El nombre nombra **DESTINOS, no rutas**: ni el host, ni la IP, ni activo/reserva entran en un FQDN.
Se escribe como **regla**, no como observación.
- **Renombrar sin CNAME de cortesía**: que lo viejo rompa a la vista, no en silencio.
### Secretos · *C20, C21, C22*
- **Una frontera de credenciales por dominio**; aislamiento por **ServiceAccount** (ninguno con
acceso a secretos ajenos).
- **Capacidad > credencial**: se **actúa** con el secreto, no se **revela** (revelar lo deja en el
transcript); el estado raro se dice con la URL, nunca con el secreto.
- **Nunca en git**: imperativos / GPG / PushSecret, forzado por `.gitignore`; se documenta **cómo
recrearlos**, no el valor.
### Git · *C24, C25, C38*
- **Git canónico único y MEDIDO**: se empuja a un remoto y solo ahí; un fallo se **mide**
(dry-run/reintento) antes de concluir "no hay credenciales"; el remoto muerto se elimina localmente.
- **Commits Conventional** (`feat/fix/docs/ci` + scope); el `doc:` registra el **porqué**.
- **Working-tree compartido**: `git add` con ruta explícita (**nunca `-A`**), `git pull` antes de
deploy y antes de commitear docs, una tarea = una sesión/worktree.
- La **representación en disco es parte del artefacto**: cuando un hash o un runtime consume el
checkout, se fija con el repo — **eol** por `.gitattributes` y **bit de ejecución** — o el testigo
mide el checkout, no el contenido (una DERIVA falsa en un clone sin tocar entrena a ignorar el
check). *(Cicatrices: copia vendorizada en CRLF, 2026-08-11; `git archive` sale en CRLF.)*
### Deploy · *C12, C13*
- **Un solo flujo de build**, disparado **deliberadamente**, no por `git push`; el legacy es
**lápida** (código muerto conservado hasta MEDIR qué lo ejecuta, no borrado a ciegas).
- Todo cambio **por git → deploy declarativo**; imagen pineada por **DIGEST inmutable commiteado**;
el historial de commits ES el registro de auditoría.
- El testigo de «**puedo entregar**» no es el push a git: es el **artefacto en el registro del que
tira el destino**. Una cadena de entrega tiene tantas credenciales como saltos, y la que no se
ejercita se pudre en silencio — un componente que lleva semanas sin reconstruirse no se sabe si
puede entregar. *(Cicatriz: robot de registro con 401 en tres repos, mudo durante semanas porque
nadie construía, 2026-08-12.)*
- El **orden de lo irreversible** aplica aquí → **raíl 11**.
---
## Adiciones a raíles base (pendientes de inlinar en su raíl)
- **R6 (verifica la premisa) += C34**: las premisas del encargo se **numeran** (`P1`,`P2`…) con
veredicto explícito (verdadera / falsa / matizada + `fichero:línea`); el **ratio de premisas
falsas** es el termómetro de "escribo de memoria"; **"el doc lo dice" = premisa a verificar**.
Y **hacia atrás** *(cosecha 2026-08-15)*: al **escribir** un hallazgo se nombra la **ruta EXACTA
que se midió**, nunca la categoría — una categoría con una sola medición detrás se lee después
como universal y se hereda como premisa falsa. *(Cicatriz: «el camino Rocky» eran dos caminos y
solo se había medido uno; la frase viajó por tres documentos.)*
- **Diseño de herramientas (R1/R8) += C39**: la **ausencia de una capacidad es un guardarraíl**. El
poder peligroso se **retiene estructuralmente** (no se expone porque no se construye): vocabulario
cerrado, sin `exec`/SQL/comando libre.
- **Docs / R7 += C30**: el **docstring/manual ES la interfaz**. Cambia el comportamiento → cambia el
docstring en el **mismo commit**; un doc que miente **ES el bug**.
*(Cosecha 2026-08-15 — cicatrices de infraserver:)*
- **R3 (ataca el cableado) += el diff del artefacto**: cuando un cambio de configuración pretende
cambiar un comportamiento, el testigo es el **artefacto generado, guardado ANTES y comparado
DESPUÉS**; el veredicto es su `diff` por caso. **Un caso cuyo diff sale vacío no está construido,
aunque no dé error: es un campo-señuelo.** *(Cicatriz: `day1.mode` — dos modos producían el mismo
artefacto; y así llegó `day0.luks` a existir declarado y sin consumir.)*
- **R7 (fuente única) += el consumidor que se salta el merge**: un defecto declarado como **dato en
la capa base** solo es fuente única si **TODOS** los consumidores pasan por el merge; el que se lo
salta es una **segunda fuente**, y hay que buscarlo explícitamente al introducir el defecto.
*(Cicatriz: un endpoint construía su vista sin mergear la capa base y devolvía otro valor.)*
- **R8 (fallo explícito) += preferencia vs identidad**: distingue el default de **PREFERENCIA** (qué
valor usar entre varios válidos) del default de **IDENTIDAD** (qué es esto). **El segundo no
existe**: si el dato que identifica al artefacto no está declarado, el artefacto no se puede
construir, y la respuesta es un fallo explícito con motivo — nunca el valor más común. *(Cicatriz:
un hueco de identidad rellenado sirvió un kickstart destructivo con HTTP 200.)*
---
## La estructura de sesión no vive aquí
Los dos ejes **fase × persona** y el **handoff automático** entre fases son **procedimiento**, no
principio → viven en la capa `workflows/`, con la capa **persona opcional** (se activa solo con
interlocutor no-técnico; en infra en solitario, inactiva pero documentada).