Correr la comprobacion y el push encadenados produce la MISMA salida que hacerlo bien y no puede detener nada. El registro de haberlo hecho bien queda identico. Dos formas validas: decidir por programa, o llamada aparte + leer + actuar. Solo .metodo/ — byte a byte desde la matriz. Sesion: superadmin Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1956 lines
149 KiB
Markdown
1956 lines
149 KiB
Markdown
# El Método — constitución
|
||
|
||
Principios que valen para **cualquier** sesión (exploración, ejecución, despliegue,
|
||
incidente, orquestación) y para cualquier backlog. Los workflows concretos referencian este
|
||
doc en vez de repetirlo. No son teoría: cada uno lleva el caso real que lo enseñó.
|
||
⛔ **Y EL DAÑO NO ES EL QUE PARECE: UNA FILA ARRASTRADA NO QUEDA CORRUPTA — QUEDA PUBLICADA EN UNA
|
||
VERSIÓN ANTERIOR.** No se rompe nada, no hay conflicto, no hay nada que se vea: simplemente el
|
||
remoto **anuncia un estado de hace veinte minutos como si fuera el de ahora**. En un fichero cuyo
|
||
valor entero es decir **qué está pasando AHORA**, un arrastre **no rompe: DESINFORMA** — y el
|
||
siguiente que lo lea **lo creerá al día**. Es peor que un conflicto, que al menos se ve.
|
||
⇒ Y con un bloque de estado en vuelo dentro, sube de categoría: **ese campo existe para que un
|
||
sucesor no tenga que reconstruir nada**, así que **publicarlo desactualizado es exactamente lo que
|
||
ese campo promete que no pasa**.
|
||
⛔ **Frecuencia medida, y cambia cómo hay que leer todo esto: el 2026-08-30 ocurrió TRES veces en
|
||
un día**, con seis sesiones vivas — dos mal *(una no leyó la puerta; otra la leyó **después** de
|
||
actuar)* y **una bien**: miró el `diff` **antes** del `add`, comprobó que fueran esas filas y
|
||
ningún fichero más, no tocó el texto ajeno **y lo declaró en el mensaje del commit**.
|
||
⇒ Por eso **el arrastre es la NORMA, no la excepción**, y por eso el remedio no es un mecanismo
|
||
nuevo —*costaría más que el choque*— sino **dos gestos de una línea**: **declararlo en el mensaje**
|
||
y **avisar a su dueña por el canal**, porque **el dueño es el único que sabe si lo publicado estaba
|
||
al día**.
|
||
|
||
> **Versión 2026-08-29.** 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.
|
||
>
|
||
> ⛔ **Este fichero ES la fuente**, y vive en el repo `metodo` (la matriz). Se reparte con
|
||
> `metodo update`, que lo copia byte a byte a `.metodo/metodo.md` de cada repo. **La copia no se
|
||
> edita nunca** (§7): se edita aquí y se re-estampa. *(cicatriz `C-001`)*
|
||
|
||
> Origen: destilados de la racha Hermes de julio 2026 (Fases 11/13, convergencia UI) **unificados
|
||
> con el método ya afinado en los workflows del frente de aplicación** (el más maduro en método). La lección de
|
||
> fondo: **una UI/gate honesto actúa como auditor del resto del sistema** — casi todos los raíles de
|
||
> abajo nacieron de un "verde que mentía" cazado al construir bien la capa de encima.
|
||
>
|
||
> **Meta-principio: cada raíl se escribe CON LA CICATRIZ.** El humano (o un gate)
|
||
> caza lo que no cuadra → el raíl se escribe con el caso real que lo enseñó → no vuelve a pasar. Por
|
||
> eso cada punto lleva su ejemplo: sin la cicatriz, un principio abstracto no se respeta. Este doc
|
||
> crece añadiendo cicatrices, no teoría.
|
||
|
||
|
||
## 0. Si no escala, no vale para nada *(Xavier — la máxima que gobierna a las demás)*
|
||
|
||
> *«Estamos en Kubernetes, GitOps con Helm, y lo estamos haciendo así **pensando en la masa**: masa
|
||
> de edges, masa de hubs, redundancia barata. La clave es que sea **desechable y barato de
|
||
> levantar**. Alquilar un VPS es barato; poner un Kubernetes en el edge con IP pública y un nombre
|
||
> de dominio, también. Si dejo escritos los manifiestos, puedo levantar **todos los hubs que quiera
|
||
> y todos los edges que quiera** de manera masiva. **No quiero cosas difíciles ni centralizables.**»*
|
||
|
||
⇒ **Y la consecuencia sobre la seguridad, que es la que más cambia el criterio**: *«si me capturan un
|
||
Vault me doy por jodido, pero si me capturan un token lo revoco, **tiro el hub a la basura y levanto
|
||
otro**»*. La respuesta a un compromiso **no es prevenirlo a cualquier precio: es que reponerlo sea
|
||
barato**. Un componente que hay que defender porque cuesta reconstruirlo ya ha fallado el criterio.
|
||
|
||
**Cómo se aplica, y en qué se nota:**
|
||
- ⛔ **Lo que no se puede levantar en masa desde manifiestos, no vale** — aunque funcione. Un paso
|
||
manual por instancia es un tope de escala disfrazado de detalle.
|
||
- ⛔ **Lo centralizable se mira dos veces**: un secreto compartido por todas las instancias, un
|
||
registro único, un nodo del que dependen los demás. Cada uno convierte «tiro uno y levanto otro»
|
||
en «tengo un problema».
|
||
- ⭐ **Y la pregunta antes de aceptar cualquier mecanismo**: *¿esto sigue funcionando con **cien**?*
|
||
Si la respuesta exige un gesto humano por instancia, no escala — y por `§0` **no vale**.
|
||
*(cicatriz `C-002`)*
|
||
|
||
⚠️ **Y lo que NO cubre lo desechable, dicho una vez para que conste**: tirar un componente **no
|
||
deshace lo que ese componente FIRMÓ o PUBLICÓ mientras estaba vivo**. Un artefacto firmado sobrevive
|
||
a su emisor —se propagó, es monótono y no caduca—, así que ahí la reposición barata no es la
|
||
respuesta. Es el único sitio donde hay que mirar el ciclo de vida de la **credencial**, no el de la
|
||
**máquina**.
|
||
|
||
|
||
### ⭐ La calibración: contra qué se mide «suficientemente bueno» *(Xavier, 2026-08-18)*
|
||
|
||
Antes de proponer una fortificación, **el punto de comparación no es un ideal: es lo que hoy se usa
|
||
en su sector**. Y es esto, dicho por él:
|
||
|
||
> *«Tengo aquí cifradores físicos del trabajo que **no son tan complicados como este sistema, y mucho
|
||
> menos útiles y mucho menos seguros**. Llevan tokens físicos, y si alguien pierde uno se lía de tal
|
||
> magnitud que hay que **llevarlos todos a que les cambien las claves**. Y en el sitio donde trabajo
|
||
> **a nadie se le ha pasado por la cabeza que capturen en la vida el cifrador expuesto a internet** —
|
||
> y a mí también me cuesta. **Y los tenemos.**»*
|
||
|
||
⇒ **Dos consecuencias, y las dos cortan discusiones enteras:**
|
||
- **Sobre el coste de recuperarse**: *«si hay que hacer 1.000 o 10.000 ceremonias, sigue siendo
|
||
infinitamente más barato que lo que tendríamos que hacer hoy si nos capturaran un cifrador físico
|
||
edge»*. ⇒ Un procedimiento de reposición **caro pero existente** ya es una mejora enorme sobre el
|
||
estado del arte, que es **no tener ninguno**. No se compara contra cero coste: se compara contra
|
||
*«llevarlos todos al taller»*.
|
||
- **Sobre qué amenazas modelar**: la captura del nodo expuesto a internet **no está en el modelo de
|
||
nadie** en su sector, con equipos que protegen más y valen más. ⇒ Insistir en ella aquí no es rigor:
|
||
es **gastar el foco de Xavier en el escenario que su propio sector descarta**, y él ya lo aplazó
|
||
explícitamente tres veces el mismo día.
|
||
|
||
⛔ **Regla operativa**: antes de escribir *«pero si te comprometen X…»*, pregúntate **contra qué lo
|
||
comparas**. Si la alternativa real que Xavier tiene hoy es peor, la propuesta no mejora nada — solo
|
||
añade dificultad, y eso lo prohíbe `I11·D23` (del hub: «la vara de medir es el COSTE
|
||
PARA EL OPERADOR»).
|
||
|
||
|
||
⇒ ⛔ **Y el error que esto evita, cometido CUATRO veces el 2026-08-18: una decisión lleva ÁMBITO DE
|
||
AMENAZA, y leerla fuera de su ámbito la hace parecer mala.** *(cicatriz `C-003`)* La orquestadora evaluó `D25` —del **edge**, apartado
|
||
`E14`; ⚠️ **sigue sin entrada en su registro**, ver `A43` en el registro de avisos del edge, así que
|
||
esta cita no se puede calificar todavía— contra la captura de un **hub**, y la decisión salía mal
|
||
cuatro veces seguidas. **No estaba mal: se estaba midiendo con la vara de otra sección.**
|
||
⇒ **Regla**: antes de objetar, pregúntate **de qué apartado es la decisión**. Si tu objeción vive en
|
||
otro, no es una objeción: es una **entrada para ese otro apartado** — y se escribe allí, no aquí.
|
||
⭐ Y el corolario que lo hace útil en vez de burocrático: **objetar sigue siendo bienvenido**. Lo que
|
||
Xavier gestiona no es si la objeción vale, es **su alcance y su prioridad en el backlog**.
|
||
⭐ **Y el porqué, en sus palabras: «buscamos MEJORAR, no la perfección desde el principio».** Una
|
||
mejora entregada bate a una solución completa que no existe todavía — y la que no existe **cuesta
|
||
foco**, que es el recurso escaso. ⇒ Lo que convierte esto en método y no en excusa es lo de siempre:
|
||
la mejora se **mide** y lo que queda fuera se **escribe** (un ⏸️ con su motivo, como el aplazamiento
|
||
de la captura de hub), para que nadie lo confunda con un olvido.
|
||
|
||
⛔ **Y el refinement que lo hace ejecutable: una decisión que acarrea trabajo FUERA del alcance del
|
||
producto o de la fase NO se queda como casilla.** Se convierte en **épica nueva** si es grande, o se
|
||
va **a su fase** si tiene una — y se prioriza como todo lo demás: **por valor de producto**, no por
|
||
lo bien argumentada que esté. *(cicatriz `C-004`)*
|
||
⇒ Es el mismo movimiento que el del ámbito de amenaza, una capa más arriba: **lo que no es de aquí
|
||
no se descarta ni se cuela — se muda, con su valor escrito.**
|
||
|
||
## 1. Verifica el resultado, no la intención
|
||
|
||
|
||
|
||
⛔ **UN CENSO QUE SUBESTIMA ENTREGA UNA LISTA CORTA CON ASPECTO DE COMPLETA** — y eso es peor que no
|
||
tenerla, porque **se cierra el tema**. Un censo que sobrestima chirría y se revisa; **uno que se queda
|
||
corto se cree**.
|
||
*(cicatriz `C-005`)*
|
||
⇒ ⭐ **El control es barato y no es «mirar otra vez»: mete en el censo un elemento que TIENE que
|
||
aparecer, y compruébalo.** Si no sale, el filtro está mal — y lo sabes **antes** de entregar la lista.
|
||
⇒ Es el control positivo aplicado a una enumeración: sin él, **un censo no puede decirte que está
|
||
incompleto**, sólo puede decirte lo que encontró.
|
||
⭐⭐ **Y EL PORQUÉ QUE HAY DEBAJO DE CASI TODO ESTE `§1`: RELEER UNA INFERENCIA NO LA COMPRUEBA —
|
||
VUELVE A CORRER EL RAZONAMIENTO QUE LA PRODUJO.** Una afirmación derivada sólo queda comprobada
|
||
cuando **algo EXTERNO a ella tiene que estar de acuerdo**; y *externo* no significa *«mirarlo otra
|
||
vez con más cuidado»*: significa **que llegue por una RUTA DISTINTA de la que la produjo**. No
|
||
volver a leerla — **volver a derivarla por otro camino**.
|
||
|
||
⇒ **Esto explica por qué «ten cuidado» no funciona, y por qué todo lo que este Método pide ES
|
||
EXTERNO**: el mutante, el control negativo, la predicción escrita **antes**, el careo contra el
|
||
artefacto, pedir el crudo. **No son disciplina: son un referente que no eres tú.**
|
||
|
||
*(cicatriz `C-006`)*
|
||
|
||
⛔ **Y la acotación que hay que llevar pegada, porque es la que hace honesta la medida**: ese censo
|
||
**sólo contiene los errores que se llegaron a VER**. Los que no se cazaron **quedan fuera por
|
||
construcción** ⇒ **la propia medida tiene la enfermedad que describe**, y por eso el número no dice
|
||
*«once»*: dice *«al menos once, y ninguno por relectura»*.
|
||
|
||
⇒ **Los dos gestos que más devuelven, y los dos son externos por diseño:**
|
||
**①** **Escribir la predicción ANTES de medir.** Tiene lo que ningún repaso tiene: **puede salir
|
||
mal** — y por eso salir bien significa algo. *(Cazó el error que su autora había llamado «el número
|
||
duro».)*
|
||
**②** **Re-derivar por OTRA ruta toda referencia y todo número justo antes de que entre al corpus.**
|
||
*(Los únicos dos errores que llegaron a tocar un documento eran **una referencia falsa y una cifra**.)*
|
||
⇒ Y de aquí cuelga como caso particular *«corregir el veredicto sin re-preguntar por el sujeto da una
|
||
segunda versión igual de falsa»*: **la corrección se derivó del mismo razonamiento, así que no es
|
||
externa a lo que corrige.**
|
||
Comprueba lo que el sistema **sirve/hace**, no lo que su fuente **dice** que hará. Una señal
|
||
heredada, un booleano cocinado o "el comando salió 0" no son prueba de la operación de ahora.
|
||
|
||
- El *verify version-aware* del deploy: `/health.version` == el digest pineado, no "el pod
|
||
arrancó".
|
||
- El `state` del DNS en el hub se calcula contra **el fichero de zona que dnsmasq parsea**, no
|
||
contra la BD otra vez (es el único sitio donde se ve un `write_zone` fallido o un soft-state
|
||
caducado que sigue resolviendo).
|
||
- El snapshot de BD se acepta tras `pg_restore --list`, no tras "pg_dump salió 0".
|
||
- ⛔ Antipatrón: "redes placebo" — dar por buena una operación por una señal que no la mide.
|
||
|
||
⭐ **Predice también lo que NO debe cambiar, y compruébalo.** Es lo que convierte un aviso en un
|
||
hecho. *(cicatriz `C-007`)*
|
||
|
||
|
||
⛔ **Una partición se verifica por SUS DOS CARAS: lo que debe estar cerrado Y lo que debe estar
|
||
abierto.** Comprobar solo la mitad cerrada **no distingue «bien particionado» de «todo roto»** — y
|
||
en autorización eso es peligrosísimo, porque el fallo se disfraza del resultado bueno. *(cicatriz `C-008`)*
|
||
⇒ Es la misma familia que *«un panel que muestra "nada" y uno que no puede ver nada se leen igual
|
||
desde fuera»* (F10.3), aplicada a la autorización. **Un `401` no es una prueba de nada por sí solo.**
|
||
|
||
⛔ **Y la partición NO se razona sobre el enrutador: se DERIVA de lo montado, y discrimina por
|
||
MÉTODO además de por ruta.** El guard corre **antes** de enrutar, así que no ve rutas — ve
|
||
**cadenas**. *(cicatriz `C-009`)* ⇒ La lista de lo público se genera **del montaje real**, nunca de un
|
||
razonamiento sobre qué prefijos «son de la API»; y `GET /x` y `POST /x` son **dos entradas
|
||
distintas**.
|
||
⇒ ⛔ **Y su aplicación al DESPLIEGUE, que es donde más engaña: «¿existe esta ruta?» NO se contesta
|
||
con un código HTTP si delante hay un guard de sesión.** *(cicatriz `C-010`)*
|
||
⇒ **El testigo que sí discrimina es la TABLA DE RUTAS MONTADAS dentro del pod** —lo derivado del
|
||
montaje, `R10` otra vez— y se lee **por el esquema OpenAPI, no recorriendo `app.routes` en plano**,
|
||
que es la cicatriz `F11.11b` un piso más abajo: los routers incluidos van **anidados** y el recorrido
|
||
plano ve seis rutas y ninguna `crl`. *(La orquestadora tropezó con las dos el mismo día: escribió el
|
||
testigo ciego y luego midió el sustituto por el camino plano.)*
|
||
⇒ Y se comprueba por **sus dos caras**: que la ruta **existe** (tabla) y que **pide sesión**
|
||
(`303 → /login`). La primera sin la segunda certifica una puerta abierta; la segunda sin la primera
|
||
no certifica nada.
|
||
|
||
⚠️ **Cambiar la configuración no cambia lo que el cliente ya tiene.** *(F11.13: la concesión DHCP
|
||
vieja siguió sirviendo `1.0.0.1` y `search lan` durante **12 h** después de que el router ya
|
||
repartiera otra cosa.)* Renueva la concesión —o espera el lease— **antes** de medir, o estarás
|
||
midiendo el pasado.
|
||
|
||
**Prefiere la prueba POSITIVA a la ausencia.** «No hay hits» es débil —puede ser una ventana corta,
|
||
un log rotado o un filtro mal puesto—; «el consumidor **se mudó**» es fuerte. *(cicatriz `C-011`)*
|
||
|
||
⛔ **Si hay dos caminos que hacen lo mismo, el que prueban tus tests se conserva y el que usa el
|
||
usuario se pudre — y el andamio de los tests es justo lo que lo esconde.** *(cicatriz `C-012`)*
|
||
⇒ **Borrar un duplicado es un MERGE, no una limpieza**: antes de tirar una copia, averigua cuál de
|
||
las dos es la correcta y porta lo que falte. Y **haz que los tests entren por la puerta del
|
||
usuario**, o seguirán certificando la copia equivocada.
|
||
|
||
- 🔎 **Y para separar tu propio ruido del tráfico real, genera un evento conocido y búscalo.** En
|
||
esa misma sesión, la pista fácil era falsa: los hits «sospechosos» salían de la **misma IP
|
||
pública y el mismo `curl`** que los del device (el router de campo y el PC salen por el mismo NAT), así que
|
||
*«curl = humano»* no valía. Lo que los separó fue lanzar un `curl` propio, ver **qué versión de
|
||
User-Agent** aparecía, y comprobar que el llamador periódico casaba **exactamente** con el
|
||
intervalo de descubrimiento del edge.
|
||
|
||
⛔ **Un artefacto que GATEA un build tiene que vivir DENTRO del contexto de ese build.** Si el gate
|
||
lee un fichero que la imagen no incluye, no estás comprobando nada: estás comprobando tu árbol de
|
||
trabajo, que es justo lo que el gate existe para no creerse. *(cicatriz `C-013`)*
|
||
⇒ La pregunta antes de escribir cualquier fichero del que dependa una comprobación: **¿entra en la
|
||
imagen?** Y su gemela, que es la buena noticia: **un gate que revienta porque le falta su insumo está
|
||
funcionando** — el fallo silencioso habría sido que lo encontrara vacío y siguiera.
|
||
|
||
**Corolario: el verde lo certifica el GATE/la medida, no tu palabra.** "Los tests
|
||
pasan" no es tu afirmación, es lo que dice el gate — y **antes de que exista artefacto** (gate rojo =
|
||
no hay imagen que desplegar). Vale igual para cualquier "está hecho": lo certifica una comprobación,
|
||
no la confianza en que lo hiciste bien.
|
||
|
||
⛔ **Un veredicto necesita un TESTIGO INDEPENDIENTE, o es decorativo.** Toda señal que gatea un
|
||
`ready`/`verified`/`ok` debe poder **nombrar en el código**: (a) el observable independiente que lee
|
||
—NO derivado de lo que verifica: ni el `control` del propio artefacto, ni la versión que TÚ
|
||
inyectaste en el values, ni el status de una ejecución anterior, ni la **ausencia** de algo que
|
||
comprobar, ni un exit-code sin mirar el efecto—; y (b) un **estado roto concreto, que PUEDE ocurrir
|
||
en producción**, que la pone roja, demostrado mutando el cableado a ese estado (§3). Si no existe tal
|
||
estado, la señal **no puede gatear**: se degrada a dato crudo. Corolarios: «no comprobado» es un
|
||
veredicto **distinto** de «comprobado y verde» (y no admisible por defecto en una puerta); la
|
||
**palabra** del veredicto codifica esa diferencia, no un campo lateral; una credencial acuñada prueba
|
||
que **autentica** antes de `ready`. Pregunta única para cada señal: *«¿QUÉ tendría que estar roto para
|
||
que esto se pusiera rojo, y ese estado PUEDE ocurrir de verdad?»* Si la respuesta es «no puede», es
|
||
una tautología. *(cicatriz `C-014`)*
|
||
|
||
⛔ **UN VEREDICTO CORRECTO NO PRUEBA QUE SU EVIDENCIA LO ESTÉ — y el gate mira el veredicto.** El
|
||
dictamen puede ser cierto y el **dato crudo que lo sostiene** estar roto, vacío o ser de otra cosa;
|
||
nadie lo nota porque **lo que se lee es la conclusión**. *(cicatriz `C-147`)*
|
||
⇒ ⭐ **El artefacto de evidencia es un SUJETO APARTE y se censa aparte.** No basta con que el
|
||
veredicto tenga gate: **el crudo también lo necesita** —que no esté vacío, que no lleve un error del
|
||
intérprete dentro, que hable del sujeto que dice—. Si sólo se comprueba el dictamen, **la evidencia
|
||
se pudre sin que nada enrojezca**, y el día que alguien la abra para discutir el veredicto no habrá
|
||
nada debajo.
|
||
|
||
⛔ **Leer el código de TU capa no dice qué hace la capa de encima con tu salida.** *(cicatriz `C-015`)* ⇒ Una predicción sacada de
|
||
tu propio código describe **tu función**, no el sistema. Y con las capas repartidas entre repos, el
|
||
que consume tu salida **no aparece en tu `grep`**: se mide, o se mide.
|
||
|
||
⛔ **Dos copias que coinciden entre sí no son una verificación — el aparato es el único que
|
||
desempata.** *(cicatriz `C-016`)*
|
||
⇒ Y la técnica que lo resolvió: **ejecuta el código INSTALADO, no lo reimplementes para
|
||
comprobarlo.** Se corrió el módulo `wgt.overlay` del propio device; reimplementar el hash aquí
|
||
habría verificado la reimplementación, no el sistema.
|
||
|
||
⛔ **Y el testigo tiene que ser independiente TAMBIÉN del acto de medir.** *(cicatriz `C-017`)* Una sonda que
|
||
casa con su propia invocación no mide el sistema, **te mide a ti mirándolo**. Señal de alarma: un
|
||
observable que **mejora cuando lo consultas** — y, en general, cualquier comprobación por `ps`/`grep`
|
||
sobre una cadena que también aparece en el comando que la busca.
|
||
|
||
⛔ **Un testigo que no puede ponerse ROJO no es un testigo — y el que se pone rojo SIEMPRE mata lo
|
||
que venía a proteger.** Si la señal que esperas la produce una capa **DELANTE** de lo que verificas,
|
||
no está mirando tu sistema: está mirando al portero. *(cicatriz `C-018`)*
|
||
⇒ Antes de elegir el valor esperado, pregunta **quién lo produce**. Si lo produce el proxy, el
|
||
firewall o el balanceador, cámbialo por uno que solo pueda salir **de dentro**. Y si no hay ninguno
|
||
alcanzable, la respuesta correcta es **la palabra degradada** (`deployed-unverified`) más una
|
||
comprobación a mano — no un `verify` decorativo, que es un rollback automático esperando su turno.
|
||
⇒ **Y el espejo: un testigo que se pone rojo SIN causa enseña a no creérselo.** *(Cicatriz
|
||
2026-07-31: el MCP del edge dio `failed` sin que nada estuviera roto — su smoke midió durante el hueco de
|
||
`uhttpd`.)* Falla hacia el lado seguro, sí, pero **un rojo que hay que desmentir a mano entrena a
|
||
ignorar los rojos**, y el siguiente será de verdad. Un sondeo que puede caer en un hueco conocido
|
||
**reintenta durante una ventana**; no informa del primer intento.
|
||
|
||
⛔ **Cuando una sonda te engaña, el arreglo es OTRO OBSERVABLE — no más reintentos.** Reintentar
|
||
sobre un valor que el propio sujeto escribe solo es **esperar a que la tautología se complete**.
|
||
*(cicatriz `C-019`)*
|
||
⇒ Dos formas concretas de caer, las dos vistas:
|
||
- **Leer por POSICIÓN y no por NOMBRE**: `head -1`, `[0]`, «el primer campo que casa». El día que
|
||
aparece un segundo valor con el mismo nombre, gana el que no querías **y nadie se entera**.
|
||
- **Leer un valor que el sujeto escribe de sí mismo**: un informe de instalación, un `/health` que
|
||
repite lo que le inyectaron, un `ps` que casa con tu propia invocación.
|
||
- ⭐ **Usar un cliente que SIGUE REDIRECCIONES, y leer el destino como si fuera el origen.** Un
|
||
guard que redirige a `/login` es indistinguible de *«no hay guard»* si tu herramienta te da el
|
||
`200` del final del camino. *(cicatriz `C-020`)* ⇒ Cuando midas una autorización, **exige
|
||
ver la traza**: el código de CADA salto y sus cabeceras. Y desconfía por defecto de todo cliente
|
||
que «te lo pone fácil» — `urlopen`, `requests.get`, un navegador: la comodidad es exactamente lo
|
||
que te esconde el peldaño que estabas midiendo.
|
||
- ⭐ **Preguntar por un NOMBRE que resuelve distinto según quién pregunta.** *(cicatriz `C-021`)* Si un nombre es split-horizon, **no sirve como dirección de
|
||
un testigo**: solo sirve para hablar, no para comprobar.
|
||
|
||
⛔ **En un reconciliador, «lo que yo no escribo» NO es «lo que sobra».** El conjunto que **enumeras**
|
||
para decidir qué conservar tiene que ser **más ancho** que el que **escribes** — reutilizar el filtro
|
||
estrecho convierte *«esto no lo gestiono yo»* en *«esto se borra»*. *(cicatriz `C-022`)*
|
||
⇒ Antes de escribir una poda, pregunta: **¿quién MÁS escribe aquí?** Un recurso compartido casi
|
||
siempre tiene más de un dueño, y el que no ves es el que vas a romper.
|
||
⇒ Y su gemelo: **si la lectura del estado vivo FALLA, no se poda nada.** Un `wg show` que no responde
|
||
devuelve **ausencia**, no **conjunto vacío** — y tratarlos igual borra la instalación entera.
|
||
⇒ ⛔ **Y esto también le pasa a Kubernetes, así que no lo des por resuelto porque lo haga el
|
||
sistema.** *(cicatriz `C-023`)*
|
||
⇒ ⭐ **Y lo que lo hace peligroso no es el huérfano, es que sea INVISIBLE**: casi todo se audita
|
||
**por namespace**, y ese namespace ya no está. Es la cicatriz de kaniko en variante nueva — *quitar
|
||
el gestor no quita lo gestionado*.
|
||
⇒ **Regla operativa: ninguna poda que dependa de ENUMERAR se ejecuta con el plano de control
|
||
inestable.** Si hay que borrar algo el día que se toca etcd o un apiserver, se borra **antes** de
|
||
empezar o **después** de comprobar que los apiservers responden — y la comprobación del borrado no es
|
||
que el contenedor padre ya no esté: es que **los objetos ya no están**, incluidos los *cluster-scoped*.
|
||
|
||
⛔ **De un contador se deduce TRÁFICO, no PROPÓSITO. «Nadie lo usa» no es una medida: es una
|
||
inferencia — y es la que justifica retirar cosas.** *(cicatriz `C-024`)*
|
||
⇒ ⭐ **Y el caso peor es sistemático: un camino de último recurso parece ocioso PORQUE funciona.**
|
||
Solo se usa el día que hace falta, así que «sin tráfico» es su estado normal — y es justo lo que lo
|
||
hace parecer muerto. Acceso de emergencia, rutas de respaldo, credenciales de rescate: todas se ven
|
||
igual que la basura.
|
||
⇒ Antes de proponer retirar algo, **pregunta para qué existe a quien lo puso**. Y si el aviso lo
|
||
escribió una sesión que solo vio contadores, **la propuesta de retirada no está fundada**: lo que
|
||
midió es que no pasa tráfico, no que no sirva.
|
||
|
||
⛔ **Un testigo que no DISCRIMINA es peor que no tener testigo**, porque da permiso. *(cicatriz `C-025`)*
|
||
⇒ Antes de aceptar un testigo, pregunta: **¿qué valor tomaría si el fallo estuviera presente?** Si es
|
||
el mismo, no es un testigo: es un adorno.
|
||
⇒ ⭐ **Y el caso más común de todos: una alerta construida sobre «¿responde?» no puede distinguir
|
||
«el sujeto está caído» de «mi sonda está rota».** *(cicatriz `C-026`)* Lo que lo demostró **no fue
|
||
razonarlo, fue un banco de usar y tirar**: tres etcd de juguete, **matando 2 de 3** — y el
|
||
superviviente **siguió sirviendo `/metrics`**, o sea que `up` se habría quedado en **1**. Lo que sí
|
||
se movió fue el estado interno (`etcd_server_has_leader` 1→0, `peer_sent_failures` 0→16→95).
|
||
⇒ **La regla útil lee el ESTADO que el sujeto publica de su propio consenso, no si contestó al
|
||
teléfono.** Y la forma de saberlo es la misma de siempre: **provoca el fallo real y mira qué serie se
|
||
mueve**. Si la tuya no se mueve, tu alerta no vigila lo que crees.
|
||
|
||
⛔ **Un campo de `status` que suena a «lo que hay AHORA» puede ser «lo que había la última vez que el
|
||
controlador lo tocó» — y creerse ese nombre lleva a arreglar la declaración en vez del sistema.**
|
||
*(cicatriz `C-027`)*
|
||
⇒ El testigo de qué corre es **la etiqueta del propio pod** (`controller-revision-hash`), o su
|
||
`/etc/hosts`: se mide en el sujeto, no en la opinión del controlador.
|
||
⇒ ⭐ **Y el corolario general, que es el peligroso: cuando una alerta compara DESEADO con ACTUAL, la
|
||
salida barata es tocar el deseado.** Eso la pone verde **haciendo que la declaración mienta sobre lo
|
||
que corre** — se pierde la alerta *y* la verdad de la spec, a cambio de nada. Si el actual no se
|
||
puede mover (aquí: reiniciar Vault lo deja **sellado**, shamir 3/5 sin auto-unseal, y se lleva 83
|
||
`ExternalSecret`), la respuesta correcta es **la excepción escrita con fecha de caducidad**, no
|
||
editar la intención hasta que cuadre.
|
||
|
||
⇒ ⛔ **Y su espejo, que engaña en la dirección que NADIE vigila: un estado de ERROR es tan pegajoso
|
||
como uno verde.** De un verde heredado ya desconfiamos; un **rojo** heredado se lee como *«sigue
|
||
roto»* — y eso hace perseguir un problema **ya resuelto** y «arreglar» lo que estaba bien. *(cicatriz `C-028`)*
|
||
⇒ El `status` de un objeto narra **su última reconciliación**, no el presente — en los dos colores.
|
||
Para saber si algo sigue roto: mira **cuándo** fue el último fallo, o **provoca** la reconciliación.
|
||
Nunca leas el campo y ya.
|
||
|
||
⛔ **Cuando el riesgo es una PÉRDIDA SILENCIOSA, el testigo tiene que ser DIFFEABLE.** Una
|
||
comparación que solo puede hacer un humano mirando siempre concluye *«se ve igual»* — y esa es
|
||
exactamente la conclusión que el riesgo necesita para pasar. *(cicatriz `C-029`)*
|
||
⇒ Antes de una poda, un refactor o una migración, pregunta: **¿qué artefacto puedo comparar a
|
||
máquina?** Si la respuesta es «ninguno», invéntalo **antes** de tocar — un volcado, un censo, un
|
||
hash. Lo que no se puede diffear no se puede echar de menos.
|
||
⇒ ⭐ **Y el corolario que justifica el gasto: «COSMÉTICO» NO ES UNA CATEGORÍA DEL SISTEMA, ES UNA
|
||
CATEGORÍA TUYA.** Tú decides que un cambio no toca nada; el artefacto no comparte tus categorías, y
|
||
un testigo diffeable es lo único que os pone de acuerdo. *(cicatriz `C-030`)*
|
||
⇒ Por eso un gate de artefacto **no se salta «porque esto solo es un comentario»**: si de verdad no
|
||
cambia nada, pasa solo y no cuesta; y si cuesta, es que cambiaba algo.
|
||
⇒ ⛔ **Pero un hash de algo GENERADO solo vale si el generador es determinista.** *(cicatriz `C-031`)* El arreglo
|
||
no es cambiar de testigo: es **normalizar antes de comparar** (ordenar) — y entonces el diff vuelve a
|
||
significar algo, que es como se cerró la desistencia: `ospfd.conf` **idéntico al byte**, ordenado.
|
||
⇒ Pregunta previa a usar un hash: **¿dos ejecuciones sin cambios dan el mismo byte?** Si no lo has
|
||
comprobado, no tienes un testigo, tienes un generador de ruido.
|
||
⇒ ⛔ **Y aunque normalices: guarda el ARTEFACTO, no su huella.** Un hash dice **que** algo cambió y
|
||
**nunca qué** — así que el día que se mueve estás ciego justo cuando necesitas mirar. *(cicatriz `C-032`)* Un hash cuesta 32 bytes y un fichero de configuración cuesta
|
||
dos kilos: **no hay ninguna razón para guardar el resumen en vez del original.**
|
||
|
||
⛔ **Una carrera no se ESPERA: se PROVOCA.** Si el fallo depende de coincidir con un bucle, cronometrar
|
||
es un sorteo — y tres «no apareció» seguidos no dicen nada. *(cicatriz `C-033`)*
|
||
⇒ Lo que lo hizo repetible: **dejar de cronometrar y disparar el intercambio**, y **calcular la fase
|
||
del bucle a partir del `T0` que el propio supervisor escribe en su log** — el sistema suele publicar
|
||
su reloj; úsalo en vez de adivinarlo desde fuera.
|
||
⇒ Corolario duro: **hasta que no lo hayas reproducido, no puedes cerrar nada arreglándolo.** «No
|
||
apareció después del arreglo» sobre una ventana en la que tampoco habría aparecido antes **no es
|
||
evidencia** — es la misma medida sin discriminación.
|
||
|
||
⛔ **Una nota de cierre tiene que nombrar QUÉ COPIA cerró.** «Arreglado en `hermes`» no dice si habla
|
||
del **código**, de la **imagen** o de la **instancia que corre** — y son tres cosas distintas que se
|
||
desincronizan solas. *(cicatriz `C-034`)*
|
||
⇒ Y el testigo se elige por quién lo produce: **`/health` NO sirve** — devuelve el string que le
|
||
inyectó el `values`, o sea un auto-informe. Lo que decide es el `imageID` del contenedor (qué se
|
||
empaquetó) y, mejor aún, **una huella que solo pueda haber escrito el camino de código nuevo** (una
|
||
fila `promoted` en `pair_claims`). Un fichero dentro de una imagen prueba **qué se empaquetó, no qué
|
||
corrió**.
|
||
⛔ **Y el caso más traicionero: un artefacto producido por el CÓDIGO DEFECTUOSO no prueba nada
|
||
sobre el estado que ese defecto ignoraba.** Si el fallo consiste en *«no mirar X»*, entonces lo que
|
||
ese código escribe sale **igual valga X lo que valga** — así que leer su salida para deducir X es
|
||
leer el defecto y llamarlo dato. *(cicatriz `C-035`)*
|
||
⇒ ⭐ **Y arreglar el defecto cambia el significado de la evidencia hacia atrás.** Antes de inferir
|
||
estado de un artefacto, pregunta **qué versión lo escribió y si esa versión miraba lo que quieres
|
||
deducir**. Si no lo miraba, el artefacto es un testigo de la avería, no del sistema.
|
||
|
||
⇒ Generalizado: **una medida sin su procedencia no es una medida.** Falta decir *qué copia* y
|
||
*cuándo*, y las dos mataron un dato el 2026-07-30:
|
||
- **El árbol de trabajo NO es el repo.** Dos veces el mismo día: un default `harbor.c2et.com`
|
||
reportado como bomba estaba en un WIP **sin commitear**, y «hay **4** `build.yml`» eran **3** en
|
||
`origin/main` (el cuarto vivía en un worktree de otra rama, con 0 commits propios). Si afirmas
|
||
sobre el repo, **mide sobre `origin/<rama>`**, no sobre lo que tienes delante.
|
||
⇒ ⛔ **Y AL REVÉS, que es el que no se espera: medir el ARTEFACTO correcto puede esconder que la
|
||
COPIA que usa la gente está rota.** Son dos preguntas distintas —*«¿qué despliega ArgoCD?»* y
|
||
*«¿qué le pasa a quien clona esto?»*— y **ninguna receta contesta las dos**. *(cicatriz `C-036`)* ⇒ Cuando elijas dónde medir,
|
||
di **qué pregunta estás contestando**; y si la herramienta tiene una salida de emergencia (un
|
||
`tr -d '\r'`, un fallback), pregúntate **qué está haciendo tolerable que no deberías tolerar**.
|
||
⛔ **Y EL TESTIGO DE EOL HAY QUE VALIDARLO CON UN FICHERO QUE SEPAS QUE ES CRLF, porque el obvio
|
||
MIENTE.** `grep -c $'\r'` **es ciego al CR en algunos shells**: devuelve **0** sobre un fichero que
|
||
`od -c` demuestra lleno de `\r\n`. ⇒ Y lo peor: **acertó tres veces seguidas antes de fallar** — los
|
||
tres ficheros eran LF de verdad. *Lo que funciona por casualidad está roto*, aplicado a un testigo.
|
||
*(cicatriz `C-037`)*
|
||
⇒ **Lo que discrimina**: `od -c`, o `tr -dc '\r' | wc -c`. **Nunca `grep $'\r'`.** Y **guarda un
|
||
fichero CRLF conocido** como control positivo del testigo.
|
||
- **Si un inventario lista dos medidas del mismo día, la hora es parte del dato.** Un robot
|
||
«vivo por la mañana» y «borrado por la tarde» no es una contradicción que resolver: es un **antes y
|
||
un después**, y tratarlo como conflicto te hace corregir dos veces y acertar ninguna.
|
||
⇒ ⛔ **Y en ESTE PC hay tres instrumentos que mienten sobre EOL, medidos**: `grep -c $'\r'` **falla en
|
||
las dos direcciones**, y **el `sed` de Git Bash y el de WSL no dan el mismo resultado** sobre el
|
||
mismo fichero CRLF —uno traduce el fin de línea y el otro no—. Lo destapó **un gate de longitud que
|
||
midió 15 donde había 13**, o sea **sesgado en la dirección que aprueba**. *(cicatriz `C-153`)*
|
||
⇒ **El árbitro que declara su semántica es `git ls-files --eol`.** Los demás contestan sin decirte
|
||
qué están contando.
|
||
|
||
⛔ **Si delegas una decisión en el operador, TIENES QUE DARLE EL GESTO. Si no, no has delegado: has
|
||
cerrado la puerta.** *(cicatriz `C-038`)*
|
||
⇒ Prueba barata, y hazla al diseñar, no al depurar: **para cada estado en el que tu sistema puede
|
||
entrar, ¿cuál es la salida y quién la pulsa?** Un control que solo se puede **aplicar** y nunca
|
||
deshacer no es un control, es una trampa. Y si el estado terminal no aparece en ninguna pantalla,
|
||
para el operador **no existe** — da igual lo que diga la fila en la base de datos.
|
||
|
||
⛔ **Un identificador que además es CLAVE DE BÚSQUEDA no se puede renombrar: sepáralo antes.** Si un
|
||
mismo valor da el nombre público **y** direcciona secretos, rutas o etiquetas, cambiar la cara
|
||
visible **re-direcciona lo invisible**, y en silencio. *(cicatriz `C-039`)*
|
||
⇒ Antes de renombrar, **escribe qué se deriva de ese valor**. Lo que dice quién eres y lo que dice
|
||
dónde están tus cosas tienen que ser campos distintos, aunque hoy coincidan. Y donde el derivado
|
||
tenga formato obligado (una etiqueta de kernel, un path), **que la plantilla falle al renderizar** —
|
||
probado que falla, no supuesto.
|
||
|
||
⛔ **Un comentario que JUSTIFICA saltarse una puerta sobrevive al motivo, y convierte el bypass en
|
||
rutina.** Es el peor sitio donde se puede pudrir una nota: el resto de la documentación rancia hace
|
||
perder el tiempo; ésta **desarma un gate y encima explica por qué está bien**. *(cicatriz `C-040`)*
|
||
⇒ Toda excusa escrita para desactivar una comprobación **nace con fecha de caducidad**: dice qué la
|
||
justifica y **qué la cancelaría**. Y quien arregla la causa tiene que borrar el permiso — si no, lo
|
||
que queda no es una excepción, es la nueva costumbre.
|
||
|
||
⛔ **Y su hermano, que es peor porque parece inofensivo: un PENDIENTE rancio no es ruido, es una
|
||
INSTRUCCIÓN EQUIVOCADA esperando a que alguien la ejecute.** Una casilla `[ ]` no solo describe un
|
||
problema: casi siempre trae **cómo arreglarlo**, y ese «cómo» está anclado al diseño de cuando se
|
||
escribió. *(cicatriz `C-041`)*
|
||
⇒ **Al cerrar algo, barre los pendientes que describían su arreglo**: desde ese momento describen el
|
||
arreglo **equivocado**. Cerrar una decisión sin barrer su cola deja instrucciones armadas.
|
||
|
||
⛔ **`Synced` es un veredicto sobre lo que la Application MIRA — no sobre el directorio, ni sobre lo
|
||
que un día gestionó.** Dos caras, las dos medidas el 2026-07-30 desmontando kaniko:
|
||
|
||
- **Quitar el gestor no quita lo gestionado: lo deja HUÉRFANO.** Las tres Applications no tenían
|
||
`resources-finalizer`, así que el prune se llevó **los objetos `Application`** y dejó vivos el pod
|
||
del runner, su PVC, el ns `kaniko` con credenciales de push y el Deployment del image-updater.
|
||
⇒ El resultado de fiarse de la predicción habría sido **peor que no tocar nada**: procesos con
|
||
credencial de escritura corriendo **sin dueño ni en git ni en ArgoCD**. Borrar es un `delete`
|
||
explícito **después** del commit; el commit solo retira la gestión.
|
||
- **Un fichero que la Application no incluye no existe para ArgoCD.** El appset de velero monta su
|
||
directorio con `directory.include: "externalsecrets.yaml"` ⇒ la Application de backup de un cluster salía
|
||
**`Synced/Healthy` sin haber mirado nunca los `Schedule`**. Quitar un namespace del YAML en git no
|
||
quitó nada: el objeto vivo seguía respaldándolo.
|
||
|
||
⇒ Antes de creerte un `Synced`, pregunta **qué ficheros entran** en esa Application y **qué recursos
|
||
siguen vivos sin ella**. Y la comprobación de un desmontaje no es «la Application ya no está»: es
|
||
**que los objetos ya no están**.
|
||
|
||
⛔ **Y borrando DOCUMENTOS pasa lo mismo, con una moneda peor: antes de retirar un documento de
|
||
estado, cuenta lo que está ABIERTO en él — no sus ids, no sus líneas.** Ids y líneas miden **tamaño**;
|
||
las casillas `[ ]` miden **obligaciones**, y son lo único que no se puede reconstruir después.
|
||
*(cicatriz `C-042`)*
|
||
⇒ El censo previo a un borrado tiene **dos columnas**: qué ids se van *(y a dónde)* **y qué queda sin
|
||
hacer** *(y a qué backlog se muda)*. La segunda es la que salva trabajo; la primera solo salva
|
||
referencias.
|
||
⇒ Y el corolario para quien busca esas referencias: **búscalas en TODO el árbol, no solo en los
|
||
`.md`**. En esa misma retirada apareció un puntero al documento **en un comentario de código**
|
||
(`lib/wgt/config.lua`), que es donde un enlace muerto sobrevive más tiempo porque nadie relee los
|
||
comentarios.
|
||
|
||
⛔ **La réplica PROPAGA la decisión, no la juzga: una réplica fiel de una decisión mala la hace
|
||
global.** Mejorar el mecanismo que distribuye, sobre un procedimiento que decide mal, **no arregla —
|
||
amplifica**. *(cicatriz `C-043`)*
|
||
⇒ Antes de mejorar una distribución, pregunta **quién decide lo que se distribuye**. Si el generador
|
||
puede equivocarse, la respuesta no es replicar mejor: es **quitarle la decisión** — el arreglo fue
|
||
que el hub dejara de asignar, no que asignara con más cuidado.
|
||
|
||
⛔ **Cuando un estado vive en DOS sitios, el que sobrevive es el que miente.** No es un caso: es la
|
||
forma en que fallan los sistemas con estado duplicado, y apareció **tres veces el 2026-07-28**.
|
||
|
||
- **Un validador de caché guardado APARTE del dato sobrevive al dato.** El reconciliador PQ guardaba
|
||
el `ETag` de la pubkey del peer en `data/mesh.json`, y el fichero que certifica —
|
||
`data/pq/peers/<pid>.pk`— en otro sitio. Se borró el fichero y **no volvió nunca**: 8 vueltas
|
||
pidiendo con `If-None-Match`, el hub contestando `304`, y el enlace `blocked` **para siempre**,
|
||
con todos los indicadores en verde. ⇒ Un validador tiene que invalidarse cuando **desaparece lo
|
||
que valida**: guárdalo junto al dato, o compruébalo contra su existencia antes de usarlo.
|
||
- **El kernel emparejado y el panel a cero.** Tras desmontar un edge «a cero», `data/mesh.json`
|
||
quedó en `{"hubs":{}}` mientras `wgtrans` conservaba **dos peers con handshake fresco y PSK
|
||
puesta**. Desde fuera, vivo; desde su propio panel, virgen — y sin links en su estado, el
|
||
reconciliador no levanta quagga, así que **no hay OSPF y nadie lo dice**.
|
||
- **El `lo` del nodo acumula direcciones que ningún manifiesto declara** (§ hub): el chart las
|
||
añade y no las quita, así que un nodo lleva encima todo valor con el que se desplegó **alguna
|
||
vez**, y ArgoCD dice `Synced/Healthy`.
|
||
|
||
⇒ **Regla**: si un dato tiene dos copias, di **cuál manda** y haz que la otra **no pueda
|
||
sobrevivirla**. Y para probarlo no basta con razonar que ya no puede pasar: hay que **volver a
|
||
ponerse en el estado roto** y ver que se recupera — es lo que hizo el arreglo del `ETag`, y por eso
|
||
se sabe que sirve.
|
||
|
||
⛔ **UN HECHO MEDIDO SOBRE UN COMPONENTE, MÁS UN SUPUESTO NO MEDIDO SOBRE OTRO, PRODUCE UNA
|
||
CONCLUSIÓN FALSA CON ASPECTO DE MEDIDA.** Es el fallo de la **juntura**, y hoy no lo caza ningún otro
|
||
raíl: `§5` dice *no inventes lo no medido* y arriba está *verifica el resultado, no la intención* —
|
||
pero aquí **nadie inventa nada y todo lo afirmado está medido**. Lo que falla es **unirlo**.
|
||
*(cicatriz `C-044`)*
|
||
⇒ **Regla**: cuando una conclusión **cruza dos sujetos** —un servicio y una máquina, un repo y un
|
||
cluster, un motor y el hierro que lo arranca—, **cada sujeto necesita SU PROPIA medida**. Heredar la
|
||
solidez de uno para el otro es **cómo se fabrica una alarma falsa con pinta de dato**.
|
||
⇒ ⭐ **Y su reverso, que es el mismo error con el signo cambiado: CORREGIR DE MÁS.** Pasar de *«la
|
||
bomba está armada»* a *«aquí no hay nada»* vuelve a tomar por propiedad **del mecanismo** lo que era
|
||
propiedad de **una máquina concreta**: que el disco arranque primero es cierto **de esos servidores**,
|
||
no del sistema — el orden de arranque **se pone a mano, por máquina**. ⇒ Al refutar, la salida no es
|
||
*«refutado»* a secas: es **«precondición identificada, compruébese por máquina»**. *(Lo señalaron dos
|
||
frentes por separado, y uno de ellos ya se había pasado de frenada al corregir.)*
|
||
|
||
⛔ **UN TESTIGO SIN FUENTE NOMBRADA NO ES VERIFICABLE AUNQUE SEA CIERTO — y lo caza quien intenta
|
||
REPRODUCIRLO, no quien duda de él.** El fichero, el endpoint o el comando exacto va **DENTRO del
|
||
testigo**, no en la cabeza de quien lo midió. *(cicatriz `C-045`)*
|
||
⇒ ⭐ Y el patrón que lo generaliza, con **cuatro instancias en tres frentes el mismo día**, todas de
|
||
la misma forma: **el instrumento no decía de qué estaba hablando.** El log no decía **quién**; un
|
||
`uptime` no decía **cuándo** —se leyó una máquina catorce minutos antes de que terminara su
|
||
reinstalación y su «estado estable» eran dos días de otra cosa—; un `push` no dice **de quién** es lo
|
||
que publica; y un listado de sesiones no dice **qué rol** tiene cada una. **Ninguna fue un error de
|
||
medida**: las cuatro son **un dato bueno contestando una pregunta que no era la suya.**
|
||
|
||
⛔ **Y un ENCUADRE FALSO no sobrevive a los datos que lo contradicen: LOS RECLUTA.** No se cae solo
|
||
cuando aparece la evidencia en contra — la absorbe como confirmación, porque **los mismos bytes dan
|
||
veredicto opuesto según una precondición que nadie ha medido**. *(Cicatriz 2026-08-28: los dos hechos
|
||
que más deberían haber tumbado el aviso de la BIOS **se leyeron como que lo confirmaban**.)*
|
||
⇒ Por eso, cuando un encuadre cae, **corregir la frase que lo dijo NO es corregirlo: hay que CENSAR
|
||
dónde ha viajado** — y **empezando por los TÍTULOS**, que es lo único que enseña un listado compacto
|
||
y la superficie donde los encuadres caídos se acumulan.
|
||
|
||
⛔ **EL INSTRUMENTO FORMA PARTE DEL SISTEMA MEDIDO.** No es una advertencia filosófica: es un modo
|
||
de fallo que **produce medidas coherentes y falsas**, y por eso no se nota.
|
||
*(Cuatro mordidas medidas los 2026-09-01/02 en un mismo incidente, todas de la misma sesión:*
|
||
1. ***el gesto reinicia lo que mide*** — reiniciar el operador de Rook **ponía a cero el
|
||
temporizador de failover** que se estaba esperando; tres reinicios «para diagnosticar» eran justo
|
||
lo que impedía que hubiera tercer MON. El muro secundario que sí se veía lo **disparaban los
|
||
propios cambios**.
|
||
2. ***el instrumento no distingue su propio fallo del fallo que mide*** — el vigilante emitía campos
|
||
vacíos, y *«el cluster no contesta»* y *«no llego al cluster»* **se veían idénticos**. Se acusó al
|
||
cluster; era el routing de este PC.
|
||
3. ***la medida es cierta y el SUJETO es otro*** — *«el iDRAC responde ⇒ el nodo tiene corriente y
|
||
sólo falta encenderlo desde ahí»*: cierto, **pero ese nodo era una VM** y el iDRAC contestaba por
|
||
su anfitrión. Misma forma que un `ping` a `192.168.0.45` que respondía siendo los nodos `.4.x`.
|
||
4. ***y el cuarto no es de máquinas, es entre personas*** — *«la máquina ya tiene autoencendido»* se
|
||
leyó referido **al aparato del hilo de quien escuchaba**, no al del que hablaba. **La ambigüedad
|
||
de sujeto está también en el lenguaje con el que nos pasamos los hallazgos**, y ése sólo se caza
|
||
preguntando.*)
|
||
⇒ Antes de creerte una medida: **¿de qué aparato habla?** · **¿pudo cambiarla el hecho de tomarla?**
|
||
· **¿distingue «está mal» de «no lo veo»?**
|
||
|
||
⛔⛔ **UNA COMPROBACIÓN PUEDE INFORMAR DE ALGO DISTINTO DE LO QUE DICE COMPROBAR — y desde fuera se ve
|
||
idéntica a una que funciona.** No es que no pueda enrojecer: **puede**, sólo que **por otra razón que
|
||
la anunciada**. Y el verde que devuelve es cierto: contesta **otra pregunta**. Tres caras, las tres
|
||
medidas el 2026-09-02:
|
||
⇒ ⛔ **Y una CUARTA cara, que es la más barata de cometer: LA COLUMNA QUE IMPRIME UNA HERRAMIENTA NO
|
||
ES EL CAMPO DEL OBJETO.** `STATUS: Unknown` y `.status.phase: Failed` **no son lo mismo**, y de la
|
||
diferencia cuelga la conclusión entera —un pod `Failed` **no retiene recursos**—. *(cicatriz
|
||
`C-156`, con tres testigos falsos más sobre el mismo fallo: un DaemonSet **`4/4 READY`** con el
|
||
plugin sin desplegar donde hacía falta · un objeto de registro **rancio** que seguía diciendo «sí» ·
|
||
y un `attached: true` **cierto**, porque fallaba **la otra mitad** de la operación.)*
|
||
⇒ **Lee el objeto, no la tabla.** La tabla la formatea una herramienta **para leerla rápido**, y el
|
||
resumen que hace **es una decisión suya, no del objeto**.
|
||
|
||
**① PRESENCIA en lugar de FORMA.** Comprobar que algo *está* no comprueba que esté *bien puesto*, y
|
||
el testigo de presencia **sale verde en los dos casos**. *(cicatriz `C-046`)*
|
||
⇒ **Un filtro que no casa no se queja: devuelve nada** — indistinguible de «no hay nada». Cuando un
|
||
instrumento devuelva vacío, **pruébalo contra un caso que SÍ debería encontrar** antes de concluir.
|
||
|
||
**② MENCIÓN en lugar de VALIDACIÓN.** Un esquema **no declara lo que deja de comprobar**: acepta el
|
||
documento, devuelve verde, y el hueco no aparece en ninguna parte. ⇒ **Leer un esquema no te dice qué
|
||
valida: te dice qué MENCIONA.** *(cicatriz `C-047`)*
|
||
```
|
||
version: 3 -> RECHAZADO ("3 is greater than the maximum of 2")
|
||
typo `macadress` en prov0.match -> PASA <- la afirmacion, refutada
|
||
bond con mode: 802.3ed -> PASA <- el verde falso, EJERCITADO
|
||
`match` colgando de `ethernets` a pelo -> RECHAZADO ("Additional properties")
|
||
```
|
||
⇒ De ese esquema, sobre la red, **lo único afirmable es `version` obligatoria y = 2**.
|
||
⇒ ⭐⭐ **Y el remate: el esquema comete EXACTAMENTE la trampa de la que iba a protegernos** — un
|
||
`match` a la profundidad equivocada, que es el aviso `A13` de ese mismo frente. Allí el motor lo
|
||
**borra** sin decir nada; aquí el esquema **valida la nada** sin decir nada. **La herramienta que te
|
||
iba a proteger de una trampa puede estar cometiéndola.**
|
||
|
||
**③ OTRO MECANISMO en lugar del que NOMBRA — y ésta es la que no caza ningún gate genérico.** La
|
||
guarda enrojece de verdad, pero **por un camino distinto del que dice medir**, así que **quitar
|
||
aquello que anuncia comprobar NO la pone roja**. *(cicatriz `C-048`)*
|
||
⇒ **Sólo la separa MUTAR LA GUARDA CONCRETA QUE NOMBRA.** Un mutante genérico no la distingue de una
|
||
comprobación sana: hay que romper **el mecanismo que la cabecera dice medir**, y ver si enrojece.
|
||
|
||
⇒ ⭐ **Y la mitad de proceso, que extiende *«releer una inferencia no la comprueba»* con el remedio**:
|
||
en las tres se afirmó **leyendo** —el marcador, el esquema, la cabecera de la guarda—. La inferencia
|
||
era **correcta sobre el fragmento mirado y falsa sobre el conjunto**. **Releerlo no habría corregido
|
||
nada: sólo lo corrigió el mutante.** ⇒ **La mitad roja no es el adorno de la comprobación: es la
|
||
comprobación.** Contra un validador, el mutante es un documento que **debería** rechazar; si pasa,
|
||
acabas de medir el hueco.
|
||
⚠️ **Con una condición, o el ejercicio se vuelve decorativo: el mutante tiene que PARECERSE A LO QUE
|
||
DE VERDAD SE ESCRIBE.** Un typo en una MAC vale porque **es el error que alguien va a cometer**;
|
||
mutar algo que nadie teclea nunca **mide un hueco que no le importa a nadie** — y te deja igual de
|
||
tranquilo, que es lo peligroso. **Un mutante irreal es un verde disfrazado de rigor.**
|
||
|
||
⛔ **«TODAVÍA NO SE LE HA APLICADO X» NO ES «LE FALTA X».** Confundirlos convierte **el estado normal
|
||
de cualquier sistema antes de su paso de configuración** en un incidente — y gasta la credibilidad
|
||
que hará falta el día que haya uno de verdad.
|
||
*(cicatriz `C-049`)*
|
||
⇒ ⛔ **Pero el contrapeso va PEGADO, o este raíl se convierte en la excusa**: **aceptar que un estado
|
||
intermedio es legítimo no elimina su DURACIÓN.** *«Aún no bastionado»* es correcto como **estado** y
|
||
no lo es como **situación que dura tres semanas sin que nadie la mire** — y la diferencia no la marca
|
||
el estado, la marca **cuánto tiempo se está en él y si alguien lo está contando**.
|
||
⇒ **La salida no es un aviso: es de diseño.** El paso que cierra la ventana **va en el MISMO ítem que
|
||
el que la abre** —instalar y bastionar, `kubeadm init` y su vigilante de caducidad— porque **dos ítems
|
||
separados se separan también en el tiempo**, y el hueco entre ellos no aparece en ninguna lista.
|
||
|
||
⛔ **CORREGIR UNA COPIA NO CIERRA EL HALLAZGO: CENSA LAS COPIAS.** Un dato que está mal suele estar
|
||
mal **en varios sitios**, y arreglar el que tenías delante **produce la sensación de cerrado** sin
|
||
serlo — con el agravante de que ahora el corpus **se contradice a sí mismo** y el lector cree al que
|
||
abrió primero.
|
||
*(cicatriz `C-050`)*
|
||
⇒ **Antes de dar por cerrada una corrección de dato: `grep` del dato en TODO el corpus, y control
|
||
final que salga vacío.** Y al mirar los resultados, **los procedimientos primero**.
|
||
|
||
⛔ **UN ARNÉS CON UNA RUTA ABSOLUTA A UN SCRATCHPAD ES CÓDIGO QUE NO CORRE — y no da síntoma, porque
|
||
nadie lo ejecuta hasta que hace falta**, que es el peor momento posible para descubrirlo.
|
||
*(cicatriz `C-051`)*
|
||
⇒ ⭐ **Y la segunda mitad es la que engaña**: su propio aviso decía *«ya no vive en un scratchpad»* —
|
||
**cierto del CÓDIGO y falso de sus RUTAS**. Se mudó el fichero y no lo que el fichero apunta, y el
|
||
aviso habló de la mitad que se había hecho. Misma forma que la ambigüedad de sujeto: **la afirmación
|
||
es verdadera, sólo que de otra cosa.**
|
||
⇒ Regla: **un arnés no está mudado hasta que corre desde un clon limpio del repo.** Y al escribir el
|
||
aviso de la mudanza, di **de qué mitad hablas**.
|
||
|
||
⛔ **UNA AUSENCIA NO ES UNA CAUSA HASTA QUE COMPRUEBAS QUE ANTES ESTABA.** Encontrar que *falta* algo
|
||
—una ruta por defecto, una etiqueta, una clave— es el final de la búsqueda sólo si esa cosa **debía
|
||
estar**; si nunca estuvo, reponerla no arregla: **cambia el sistema**.
|
||
*(cicatriz `C-052`)*
|
||
|
||
## 2. El dato crudo, no el cocinado
|
||
|
||
El backend **mide y traduce a atributos**; el consumidor (UI, componente, otro servicio)
|
||
**interpreta y pinta**. No cocines el estado antes de tiempo ni lo re-derives en la capa de
|
||
presentación (si no, dos consumidores divergen).
|
||
|
||
- Apareció **cuatro veces** en la convergencia UI: la API servía `wg_status` (up/idle/down) y
|
||
el badge necesitaba `wg_handshake_age` para su contador vivo; igual con IP, OSPF, y el
|
||
`state` de los nombres de malla.
|
||
- **Edad, no timestamp**, en routers sin RTC fiable. `0` es *ausencia de medida*, no "época".
|
||
- El estado se publica una vez (backend, testeable) y el componente sólo lo colorea.
|
||
|
||
## 3. Mutation testing: ataca el CABLEADO, no las funciones puras
|
||
|
||
Las funciones puras se diseñaron junto a sus tests → caer es inevitable, no prueba nada.
|
||
Los bugs viven en las **costuras donde el dato se ensambla**. Testea *qué* se ejecuta/ensambla,
|
||
no sólo *cómo* se parsea.
|
||
|
||
- F10.3: el parser de rutas tenía 8 aserciones verdes y el panel salía **mudo** — el bug estaba
|
||
en qué `proto` se consultaba. El test bueno usa un doble que registra el comando ejecutado.
|
||
- Dos listas de la misma forma (`to_publish`/`published`): intercambiarlas no rompe ninguna
|
||
función pura, sólo **invierte la verdad** → stubea y afirma sobre el resultado con un estado
|
||
conocido.
|
||
- `pq_psk = True` fijo pasaba la suite entera → habría afirmado protección PQ inexistente.
|
||
|
||
⛔ **Cuando un cambio de configuración pretende cambiar un COMPORTAMIENTO, el testigo es el
|
||
ARTEFACTO GENERADO: guardado ANTES, comparado DESPUÉS, y 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 `C-053`)*
|
||
⇒ Es el testigo independiente de §1 aplicado a la configuración: sin el artefacto de antes, «cambié
|
||
la perilla y no dio error» no distingue **construido** de **decorativo**.
|
||
|
||
⛔ **Y el modo de fallo más traicionero: los FIXTURES de la suite son más completos que la realidad.**
|
||
Un test que **construye él mismo el argumento** no puede cazar a un llamante que lo construye mal, y
|
||
la suite sale verde sobre un cableado roto. Dos veces en la misma semana (2026-07-31):
|
||
- `GET /links` —el endpoint del panel— llamaba a `LNK.status` con un `cfg` **declarado y sin
|
||
asignar**, así que el peldaño de identidad llegaba **vacío**. Los tests pasaban **porque le pasan
|
||
`cfg` a mano**.
|
||
- Un mutante que derivaba el sufijo de una LAN del dominio del router —la invención que `F11·D8`
|
||
del edge prohíbe— **no rompió ni una aserción**, porque sus tests **no pasaban registro
|
||
de router**.
|
||
⇒ Pregunta por cada test que pasa: **¿de dónde sale ese argumento en producción?** Si lo fabrica el
|
||
test, ahí no hay cobertura — hay una simulación de que la hay. El testigo tiene que **entrar por
|
||
donde entra el usuario**.
|
||
|
||
⛔ **El NÚMERO de rojos es la señal, no el rojo.** Una mutación que da **menos** rojos de los que
|
||
esperabas acusa a **tu test**, no a la mutación. *(cicatriz `C-054`)*
|
||
⇒ **Escribe cuántos rojos esperas ANTES de mutar.** Sin esa predicción, un rojo de menos pasa por
|
||
éxito y el placebo sobrevive.
|
||
⇒ **Y para que el conteo SEA posible, las aserciones tienen que ser a prueba de `nil`.** *(cicatriz `C-055`)* Una
|
||
suite que explota en vez de suspender no te deja contar rojos.
|
||
⇒ **Y un 0 rojos puede significar «la mutación NO se aplicó».** Distínguelo, o una mutación que no
|
||
casó se lee como *«el test no cubre esto»* y sale a la basura una comprobación buena. *(cicatriz `C-056`)* El arnés de mutación tiene que
|
||
**afirmar que el fichero cambió** antes de correr la suite.
|
||
⇒ ⭐ **Y una forma concreta de que no case, que no es un `sed` mal escrito: mutar donde el valor se
|
||
HEREDA en vez de donde se DECLARA.** *(cicatriz `C-057`)* ⇒ Antes
|
||
de mutar un valor, pregunta **dónde está escrito de verdad** para la instancia que vas a medir.
|
||
⇒ **Y aun cambiando el fichero, el cero puede ser del CONTADOR.** *(cicatriz `C-058`)* Dos
|
||
consecuencias: **cuenta los `errors`** —una suite que explota no es una suite que aprueba (es la
|
||
misma familia que el `nil` de arriba, un piso más abajo)— y **muta a algo sintácticamente válido**:
|
||
una mutación que impide arrancar no mide el sistema, mide el arnés.
|
||
⇒ Y **no mutes a un valor que tu test ya espera.** *(cicatriz `C-059`)* Muta a algo
|
||
que **no pueda ocurrir**, no a lo que el sistema usa de verdad.
|
||
|
||
⛔ **Y el propio ARNÉS es código sin tests — y falla hacia el VERDE.** Todo lo de arriba supone que
|
||
la comprobación dice lo que crees; cuando no, el error es asimétrico, porque en un arnés el camino
|
||
que no se ejecuta suele ser el que declara `ok`. *(cicatriz `C-060`)*
|
||
⇒ Dos preguntas antes de fiarte de una comprobación, y las dos se contestan leyéndola: **¿casa por
|
||
línea o por subcadena?** y **¿cuál de mis dos ramas es el `ok`?** Si el `ok` es el `else`, cualquier
|
||
error en la condición **pasa por éxito**. ⭐ Y el corolario que lo hace barato: **muta también el
|
||
arnés**, no solo el sujeto — una guarda que no puede ponerse roja es tan decorativa como un testigo
|
||
que no discrimina (§1), y aquí encima *da permiso a todo el gate*.
|
||
⇒ ⛔ **Y dos formas más de que el arnés mienta, las dos medidas el 2026-08-17 construyendo `I11.2`:**
|
||
- ⭐ **Un `cmp` prueba que el fichero CAMBIÓ; nunca que cambió a LO QUE QUERÍAS.** Es la guarda que
|
||
§3 ya prescribe —*afirmar que el fichero cambió antes de correr la suite*— y **no basta**: dos
|
||
mutaciones de esa sesión dieron **0 rojos pasando la guarda**, o sea indistinguibles de *«esto no
|
||
está cubierto»* cuando lo que pasaba es que el `sed` había casado **en otro sitio**. ⇒ La guarda
|
||
completa no es *«¿cambió?»* sino **«¿está el texto nuevo, y ha desaparecido el viejo?»** — y para
|
||
una mutación que debe ser única, **cuántas veces**.
|
||
- ⛔ **Una función del arnés usada ANTES de definirse no falla: sale `command not found`, y eso no
|
||
para el script ni cuenta como `FAIL`.** *(cicatriz `C-061`)* Es el *«¿cuál de mis dos ramas es el `ok`?»* un piso más abajo: aquí no se
|
||
ejecutaba **ninguna** de las dos. ⇒ Un banco en shell necesita **suelo de comprobaciones
|
||
EJECUTADAS**, no solo de fallos: si esperas 40 y corren 33, el arnés está roto aunque salga verde.
|
||
⭐ **Y lo que lo cazó fue la predicción por NOMBRE**: el conteo dio **+7 donde se predijeron +8**.
|
||
Con la predicción hecha solo con el número, un 7 razonable habría pasado por bueno.
|
||
|
||
|
||
⛔ **Antes de leer un solo conteo, comprueba que la BASE está VERDE.** Un banco cuya línea base ya
|
||
suspende **no mide nada**: los rojos rancios viajan dentro de cada mutación y —esto es lo que nadie
|
||
espera— **una mutación puede TAPAR uno**, así que el número sube o baja por motivos que no tienen
|
||
que ver con lo que mutaste. *(cicatriz `C-062`)*
|
||
|
||
⇒ ⛔ **Y predice por NOMBRE, no por número: un conteo es un hash con pérdida de la verdad.** *(cicatriz `C-063`)* Escribe **qué aserción, por su nombre**, debe ponerse roja y por qué; el número sale de
|
||
esa lista, nunca al revés.
|
||
|
||
⇒ ⛔ **Y su generalización, que es la que hace daño: si en un fichero conviven DOS FAMILIAS de
|
||
comprobación, el conteo global no es comparable con nada.** No es que el número mienta un poco: es
|
||
que **suma peras y manzanas**, así que una predicción hecha sobre una familia se caree contra el
|
||
total y salga un abismo. *(cicatriz `C-064`)*
|
||
⇒ Antes de comparar dos conteos, pregunta: **¿cuentan lo mismo?** Y si el fichero mezcla familias,
|
||
el testigo no es el total — es **el subconjunto nombrado**.
|
||
|
||
⇒ Y el corolario que cierra el círculo: **si nada CORRE el banco, esto no es mala suerte, es
|
||
inevitable.** Los cuatro bancos de ese chart se lanzan a mano, y por eso se pudrió ocho días sin que
|
||
nadie se enterara. **Un banco sin gate no es una comprobación: es documentación ejecutable, y
|
||
caduca.**
|
||
|
||
⇒ ⛔ **Y una base roja no solo falsea los conteos: ESCONDE MUTACIONES MUERTAS.** El banco se corta
|
||
antes de llegar a mutar, así que una mutación que dejó de casar **nunca llega a quejarse** — no sale
|
||
como «0 rojos», no sale de ninguna forma. *(cicatriz `C-065`)* ⇒ Arreglar la base no es el final del
|
||
trabajo: **es cuando empieza a haber datos**.
|
||
|
||
## 4. Ejercita el flujo real (abre el navegador, toca el device)
|
||
|
||
Tests verdes ≠ funciona. Conduce el flujo de punta a punta en el medio real.
|
||
|
||
- El «Editar» de la br-lan llevaba **roto desde F9.2** (promesa muerta en silencio); sin abrir
|
||
el navegador, F11.0/F11.1 se habrían dado por buenas siendo **inaccesibles**.
|
||
- El PSK PQ, el `.ipk`, el DNS: validados en el router de campo real, no en mock.
|
||
|
||
⛔ **Sondear una escritura ES escribir.** Un cuerpo malformado **no** es una sonda segura: una API
|
||
cuyos campos son todos opcionales lo acepta encantada como *«pon todo por defecto»*. *(cicatriz `C-066`)* Sondea con un método que **no pueda mutar** (`OPTIONS`, un id inexistente), o
|
||
contra una copia. Y si la lías, **restaura desde el `GET` de hace un segundo y cuéntalo**, que es
|
||
lo que hizo esa sesión: 45 s, verificado, y la única huella un contador de versión.
|
||
|
||
**Y por el MISMO CAMINO que el usuario.** Un verde obtenido por otra ruta no dice nada de lo que él
|
||
ve. *(cicatriz `C-067`)*
|
||
|
||
- 🔑 **Instrumento de diagnóstico: la MISMA petición por DOS caminos.** Fue lo que lo destapó —
|
||
por la **LAN** (la interfaz editada): `RESET` a 0,78 s; por la **WAN**: `201` en 3,5 s. Misma
|
||
petición, mismo device, veredictos opuestos. Cuando el canal de gestión **es** lo que estás
|
||
tocando, hace falta un segundo canal para poder verlo.
|
||
- ⚠️ **Corolario incómodo**: el probe de UI daba **verde sobre la versión rota**, porque iba por la
|
||
WAN. Una herramienta de prueba que no usa el camino del usuario **certifica lo que no es**.
|
||
- Familia: `restart_frr` que se lleva `zebra`/`ospfd` (F9.2), el `restart` de uhttpd que tarda un
|
||
minuto en devolver las rutas (U3.3a), y la regla de oro de
|
||
`backlog-ejecucion.md` (capa `workflows/`): **lo que no se puede perder es el acceso de
|
||
administración**. Toda operación que reconfigura el canal por el que te la pidieron es de esta
|
||
familia — y **no puede confirmarse por ese canal**.
|
||
|
||
## 5. No inventes estados ni fallos que no has medido
|
||
|
||
Honestidad de datos. Si no puedes afirmar algo, dilo ("sin dato"), no lo pintes de verde ni de
|
||
rojo. No afirmes en verde algo que **dejó de ser cierto**.
|
||
|
||
- La escalera de badges degrada a **"bloqueado" (gris)**, no a rojo: no inventa un fallo, dice
|
||
"este dato no puede ser válido si el de abajo cae".
|
||
- "Publicado con otra IP" → **pendiente**, no verde (el hub sirve algo que ya no es verdad).
|
||
- `rechazado` no aplica en el hub (su rechazo es síncrono 400/409, no deja estado) → **no se
|
||
inventó** el caso por simetría.
|
||
|
||
## 6. No des por hecho; mira la salida/estado real — incluida la premisa del prompt
|
||
|
||
El plan escrito puede partir de una foto obsoleta o de otro entorno.
|
||
|
||
⭐⭐ **PREGUNTA EL PORQUÉ CUANDO LA RAZÓN CAMBIARÍA LO QUE HACEMOS, NO SÓLO LO QUE ENTENDEMOS.** Una
|
||
decisión del usuario **se acata siempre**; pero **su razón es un DATO**, y a veces es el dato que
|
||
falta. ⛔ No se pide por cortesía ni «para documentar»: se pide **cuando sin ella se construiría otra
|
||
cosa**.
|
||
|
||
**Los tres casos en que se pregunta:**
|
||
**①** ⛔ **Cuando la decisión contradice algo medido.** Ahí el porqué **suele ser la medida que
|
||
faltaba** — no un desacuerdo. *(cicatriz `C-068`)*
|
||
**②** **Cuando la decisión va a la capa que otros leen** —el registro de decisiones, un entregable—
|
||
**y la leerá alguien que no estuvo**: dentro de tres semanas, o un tercero que audita. **Un veredicto
|
||
sin razón adquiere invariantes que nadie decidió.**
|
||
**③** **Cuando el porqué define el SUJETO.** *(cicatriz `C-069`)*
|
||
|
||
⛔ **Y cuándo NO se pregunta**, que es la mitad que evita el interrogatorio: **preferencias**, **gestos
|
||
rutinarios**, y **cuando la razón ya se ve en lo dicho**. Preguntar por todo **entrena a contestar por
|
||
trámite**, y entonces el mecanismo se rompe justo cuando hace falta.
|
||
⇒ ⭐ **Y el porqué se escribe DONDE SE DECIDIÓ, con sus palabras**, no parafraseado: *«un resumen
|
||
adquiere invariantes que la decisión no tiene»*. Si la razón es una frase suya, **va entre comillas**.
|
||
ⓘ *Nace de que el propio usuario lo pidió (2026-09-01), tras comprobar que varias reglas de este
|
||
Método salieron de un porqué suyo y no de un hallazgo técnico.*
|
||
|
||
⛔⛔ **UN CAMBIO PENSADO PARA RECUPERAR REDUNDANCIA PUEDE NECESITAR LA REDUNDANCIA QUE AÚN NO TIENES —
|
||
Y ENTONCES EL GESTO SE BLOQUEA A SÍ MISMO.** *«Es literalmente una línea»* puede ser **cierto del
|
||
destino y falso del trayecto**, y **el trayecto sólo se ve recorriéndolo**.
|
||
*(cicatriz `C-070`)*
|
||
⇒ ⭐ **Y la salvaguarda que lo denegaba NO estaba en el análisis de riesgo**: se había estimado que
|
||
recrear un testigo era *«el comportamiento normal, probabilidad alta»* — y **había un guardia debajo
|
||
que lo impide**. La estimación era **pesimista**, y **no se supo razonando: se supo ejercitándolo**.
|
||
⇒ **Corolario operativo**: la ventana para revertir un relajo así es **mientras la redundancia esté
|
||
recuperada**. Quien lo reponga **después** de que el sistema retire la pieza provisional **se
|
||
encontrará el mismo bucle**. ⇒ **Escríbelo junto a la reversión, o la reversión es una trampa.**
|
||
|
||
⛔ **Y LA PREMISA DE UNA RECOMENDACIÓN TAMBIÉN SE MIDE — INCLUIDA LA MITAD QUE NO ES TÉCNICA.**
|
||
*(cicatriz `C-071`)*
|
||
⇒ ⭐ **Un factor humano que se ASUME en vez de preguntarse es un dato inventado**, y pesa igual que
|
||
uno técnico. ⇒ Antes de recomendar esperar: **¿de quién depende que mañana se pueda?** Si la respuesta
|
||
no es *«de nosotros»*, **esperar no es la opción conservadora: es la que delega el resultado en algo
|
||
que no controlas.** *(En palabras del usuario: «el tiempo corre, y esto me demuestra siempre que si
|
||
algo puede fallar, falla».)*
|
||
|
||
⛔⛔ **UN `latest` NO ES UNA VERSIÓN: ES UNA BOMBA CON TEMPORIZADOR DE REINICIO.** No falla cuando
|
||
alguien mueve el tag — **falla la próxima vez que el proceso arranque**, que puede ser **meses después
|
||
y por una causa ajena al sistema**.
|
||
*(cicatriz `C-072`)*
|
||
⇒ ⭐ **Y el corolario, que invierte la intuición: CUANTO MÁS ESTABLE ES EL PROCESO, MÁS GRANDE ES LA
|
||
DIVERGENCIA ACUMULADA.** 173 días separaron una versión de otra. **La estabilidad no reduce el riesgo:
|
||
lo carga.** Un servicio que lleva medio año sin reiniciarse **no es el más seguro: es el que más lejos
|
||
está de lo que arrancaría hoy**.
|
||
⇒ Y añade algo que *«al encender un camino nunca recorrido salen defectos viejos»* no dice: **el
|
||
disparador puede ser AJENO** — nadie desplegó, nadie tocó nada, y aun así explotó.
|
||
⛔ **Por eso el censo no es opcional**: en el mismo cluster había **una gemela idéntica** —mismo
|
||
`latest`, **mismo digest**, misma base de datos— **viva sólo porque su nodo no se reinició**, más media
|
||
docena de tags móviles en producción. ⇒ **Cuando encuentres uno, cuenta los demás ANTES de celebrar el
|
||
arreglo**: la explosión te dice que hay un campo de minas, no que hubiera una.
|
||
⇒ **El gesto**: pinear a la versión **que los datos ya tienen** —sacada del sistema, no supuesta— y
|
||
**comprobar que ese tag existe** antes de aplicarlo, para no cambiar un fallo por otro. Y el porqué,
|
||
**dentro del propio manifiesto**, o alguien lo devuelve a `latest`.
|
||
|
||
⛔⛔ **UN ÁRBITRO QUE DEPENDE FÍSICAMENTE DE UNO DE LOS DOS LADOS NO ES UN ÁRBITRO.** Un diseño de
|
||
tolerancia por sitios —dos y dos, más un tercero que decide— **puede ser correcto en la capa que lo
|
||
declara y no sostenerse, porque LA RED NO ACOMPAÑA AL DISEÑO.**
|
||
*(cicatriz `C-073`)*
|
||
⇒ **La comprobación no está en la capa que declara la tolerancia**: `etcd` dice cuántos miembros hay
|
||
y dónde, **no por dónde llegan**. ⭐ **Pregunta a hacerse siempre: ¿por qué CAMINO físico llega el que
|
||
decide?** Si la respuesta pasa por uno de los lados que arbitra, **el diseño es correcto y la
|
||
propiedad no existe**.
|
||
|
||
⛔ **Y EL COROLARIO, QUE ES LO QUE MÁS ENGAÑA: EL PRECEDENTE QUE DA CONFIANZA PUEDE SER JUSTAMENTE EL
|
||
QUE NO CUBRE TU DIRECCIÓN.** *(cicatriz `C-074`)*
|
||
⇒ **Un precedente prueba la dirección que recorrió, no la operación.** Antes de apoyarte en él:
|
||
**¿qué es DISTINTO entre aquella vez y ésta?** — y si la respuesta es *«nada relevante»*, **eso hay
|
||
que medirlo, no suponerlo**: en ese mismo caso, **la carga estaba 169 contra 89** porque la ventana
|
||
anterior **había desplazado trabajo que nunca volvió**. ⇒ **Cada uso del precedente lo invalida un
|
||
poco más**, porque la operación anterior **cambió el sistema**.
|
||
|
||
⛔ **«PARA y reporta» ESTABA A MEDIAS: no decía A QUIÉN.** Y el hueco costó dos veces el mismo día,
|
||
por los dos lados, en dos frentes distintos.
|
||
|
||
**(a) Un hallazgo que invalida una decisión va a quien la LLEVA, no sólo a quien la ejecuta.**
|
||
Contestar a quien pregunta **no es reportar**. Son dos destinatarios y dos contenidos: el ejecutor
|
||
recibe **qué hacer ahora**; quien decidió recibe **que su decisión ya no se sostiene**.
|
||
*(cicatriz `C-075`)*
|
||
⇒ Y por eso **un fallo de MÉTODO se le dice a la superadmin** *(Xavier, el mismo día: «cada cosa a
|
||
su ámbito»)*: quien lleva el método es el destinatario, igual que quien lleva la decisión.
|
||
|
||
**(b) Cuando otro frente te reporta algo y lo arreglas, EL ACUSE ES PARTE DEL ARREGLO.**
|
||
Un arreglo silencioso **no es más barato: es más caro**, porque el otro frente **sigue gastando en
|
||
vigilar algo ya hecho**. *(cicatriz `C-076`)*
|
||
⇒ La entrega termina en **el que reportó**, no en el `push`.
|
||
|
||
|
||
**(c) UN AVISO QUE SE REPITE EN UN RELEVO SE RE-MIDE, NO SE REENVÍA.** El relevo es **justo el momento
|
||
en que el estado cambió y quien informa no estaba delante**: entre que avisaste y llega el sucesor,
|
||
alguien pudo arreglarlo. Reenviar el aviso viejo **manda a la nueva a perseguir algo ya hecho** —y
|
||
peor, **con la autoridad de venir de quien lo descubrió**.
|
||
*(cicatriz `C-077`)*
|
||
⇒ ⭐ **Y las tres de este bloque son la misma familia con el fallo movido de sitio**: **(a)** falla
|
||
**a quién** · **(b)** falla **que no se dijo** · **(c)** falla **cuándo**. En las tres **el dato es
|
||
correcto** — lo que está mal es **a quién, o desde cuándo, se refiere**.
|
||
|
||
|
||
|
||
|
||
⛔ **UN ARTEFACTO QUE DEBE REFLEJAR EL TRABAJO Y NO ESTÁ EN EL RITUAL DE CIERRE DEJA DE CRECER AL
|
||
RITMO DEL TRABAJO — EN SILENCIO.** No se rompe, no avisa: simplemente **se queda en la fecha del
|
||
último día en que alguien se acordó**.
|
||
*(cicatriz `C-078`)*
|
||
⇒ **El gesto que lo cierra es nominal y decidible**: algo **no está cerrado hasta que declara qué ha
|
||
producido aguas abajo**, y **lo declarado se cuenta e imprime**. Una unidad cerrada que **no declara
|
||
nada, enrojece**.
|
||
⚠️ **Y lo que ese gate NO puede hacer, dicho por delante**: **comprobar que lo declarado diga la
|
||
verdad**. Eso lo hace una persona leyendo — *medido: los dos automatismos que se probaron **mienten en
|
||
direcciones opuestas**, uno sobre-reporta y otro sub-reporta*. ⇒ Se ata **que exista la declaración**,
|
||
no que sea cierta, **y se dice**.
|
||
|
||
⛔⛔ **Y LA ASIMETRÍA QUE LO EXPLICA: EL CORPUS ES BUENO REGISTRANDO PROBLEMAS Y MALO REGISTRANDO QUE
|
||
SE RESOLVIERON.** Escribir un problema **está motivado** —duele, molesta, bloquea—; escribir que se
|
||
arregló **no lo está**, porque el dolor ya paró. ⇒ **Lo que se queda rancio no es lo que empeoró: es
|
||
lo que MEJORÓ.**
|
||
*(cicatriz `C-079`)*
|
||
⛔ **Y en un entregable eso es peor de lo que suena: un pendiente rancio es una DEBILIDAD DECLARADA QUE
|
||
NO EXISTE**, e invita a quien lo lea a hurgar en algo ya resuelto. ⇒ **Al cerrar algo, la pregunta no
|
||
es sólo «¿lo apunto?», es «¿qué documento afirma hoy un problema que acabo de quitar?»**
|
||
⛔ **UN INCREMENTO SIN DECLARAR ES INDISTINGUIBLE DE UNA DERIVA.** Un repo puede necesitar documentos
|
||
que el Método no prevé —nacen de **lo que ese frente entrega**, y eso no se deduce del Método—; pero
|
||
si no están declarados en ningún sitio, **quien mire ese corpus mañana no puede saber si es «tiene un
|
||
incremento aprobado» o «se fue por su cuenta»**.
|
||
⇒ Es el raíl de fuente única **sin su otra mitad**: hay fuente, y **no hay lista de excepciones a la
|
||
fuente**. *(cicatriz `C-080`)*
|
||
⇒ **Se declara en `.metodo/INCREMENTO`** —del repo, no viaja—, una línea por documento con **ruta,
|
||
fecha y por qué ESTE repo lo necesita**. Misma forma que las excepciones de commits, que ya está
|
||
probada: **nominal, fechada, motivada, contada e impresa en cada corrida**.
|
||
⚠️ **Se ata lo decidible —que lo declarado EXISTA— y se dice por qué no lo demás**: cazar un fichero
|
||
que está y **no** está declarado exigiría una definición de «línea base» del corpus que hoy no existe,
|
||
y un gate que la adivinara daría **rojos crónicos**. Queda como criterio humano, **a propósito**.
|
||
|
||
⭐ **Y QUIÉN PROPONE Y QUIÉN COLOCA, que no es lo mismo: PROPONE EL FRENTE, COLOCA Y RATIFICA QUIEN
|
||
LLEVA EL MÉTODO.**
|
||
⇒ **El frente es el único que puede VER la necesidad**: un documento extra nace de a quién entrega ese
|
||
proyecto, y desde fuera no se deduce.
|
||
⛔ **Pero el frente NO puede decidir dónde vive lo que escribe.** *(cicatriz `C-081`)*
|
||
⇒ Por eso el reparto es: **el frente dice QUÉ necesita y POR QUÉ, con la medida delante; quien lleva
|
||
el Método decide SI es incremento o es Método, y QUÉ FORMA tiene.** Así **proponer desde el frente no
|
||
tiene coste**: lo peor que puede pasar es que le digan que no.
|
||
⛔ **La pregunta «¿esto es del Método o es mío?» no la puede contestar quien lo escribe.**
|
||
⛔⛔ **LO QUE SE MIDE SE ESCRIBE EN LA CAPA DEL QUE EJECUTA, NO EN LA DEL QUE DECIDE — y por eso es
|
||
correcto, está escrito, y quien decide no puede verlo.** Evidencias, scripts de banco, mensajes de
|
||
commit, comentarios dentro de un rol: **todos son sitios donde el trabajo cae de forma natural** y
|
||
**ninguno se lee para decidir**.
|
||
*(cicatriz `C-082`)*
|
||
⇒ **No es descuido de nadie**: las cuatro capas están pensadas **para el que ejecuta**. Falta el gesto
|
||
que las cruza. ⇒ **Al medir algo que cambia lo que otro decidiría, la pregunta no es «¿lo he
|
||
escrito?» sino «¿lo va a VER quien decide?»** — y el sitio donde cae solo casi nunca es ése.
|
||
⛔ **Y un careo por FECHAS no lo caza**: eso detecta *«la capa va por detrás»*; esto es **«el dato
|
||
nunca entró en ninguna capa»**. Son dos enfermedades y la fecha sólo ve una.
|
||
|
||
⛔ **UN INSTRUMENTO QUE NO PUEDE VER EL ESTADO MALO DEVUELVE LO MISMO EN LOS DOS ESTADOS — Y CONTESTA
|
||
CON APLOMO.** No se equivoca: **no puede distinguir**, y su salida no lo dice.
|
||
*(cicatriz `C-083`)*
|
||
⇒ Es la cara consultiva de *«un gate que no puede enrojecer»*: allí el veredicto no puede ser malo;
|
||
aquí **la pregunta no puede tener la respuesta que buscas**. ⇒ **Antes de creer una respuesta
|
||
tranquilizadora, pregúntate si ese comando PODRÍA haber dicho lo contrario** — y si no, cambia de
|
||
instrumento antes de cambiar de conclusión.
|
||
⇒ ⭐ Y para **datar** un artefacto en una máquina: **el `mtime` es lo que alguien decidió que
|
||
pusiera; el `ctime` es cuándo pasó** *(un `useradd -m` copia `/etc/skel` **conservando fechas**, así
|
||
que un home puede llevar una fecha meses anterior a la máquina)*. ⛔ Y la zanja obvia —carear el
|
||
`stat` del directorio contra el de su contenido— **no separa las dos hipótesis**: las mueve las dos.
|
||
⛔ **UN DOCUMENTO PUEDE ACERTAR EL EFECTO Y EQUIVOCARSE DE COMPONENTE — y entonces manda a quien lo
|
||
lea a depurar el sitio equivocado.** El síntoma correcto, la causa correcta y el arreglo correcto no
|
||
salvan a un texto que nombra mal **de quién es el fallo**.
|
||
*(cicatriz `C-084`)*
|
||
⇒ Es la familia de **el instrumento que no dice de qué habla**, con una arista nueva: aquí **el
|
||
documento no dice de QUIÉN**. Y muerde el doble cuando el texto acaba alimentando **una guía
|
||
externa**, donde la diferencia entre *«lo vimos fallar»* y *«falla este componente»* es la
|
||
credibilidad entera.
|
||
⇒ ⭐ **Y la lección de instrumento**: un aviso que **se ha editado varias veces** no está por eso al
|
||
día. Puede haberse actualizado **por otro sitio** y conservar el error viejo **en la parte que nadie
|
||
volvió a leer**. ⛔ Por eso **un careo por FECHAS no basta**: caza el corpus que se queda atrás, **no
|
||
el que se actualiza y conserva un error**. Son **dos enfermedades**, y la fecha sólo ve una.
|
||
⭐ **La familia, que es lo que hace que se retengan las dos**: son primas de las cicatrices del
|
||
instrumento sin sujeto —el log sin *quién*, el `uptime` sin *cuándo*, el `push` sin *de quién*—, pero
|
||
**con el sujeto movido de sitio**. Allí el dato no decía de qué hablaba; aquí **el dato es correcto y
|
||
llega al destinatario equivocado**. En los dos casos el fallo no está en el dato: está en **a qué o a
|
||
quién se refiere**.
|
||
ⓘ Y la instancia que las valida: la regla (a) **se formuló en un mensaje a un par en vez de a quien
|
||
lleva el método**. La regla de enrutado, mal enrutada, por quien acababa de escribirla.
|
||
|
||
- F10.3 en FRR: el hub tiene **cero rutas OSPF en la FIB** (las conectadas ganan) → la fuente es
|
||
la RIB de FRR, no `ip route`. Copiar el filtro del edge habría dado tabla vacía con todo OK.
|
||
- Los puertos del `br-lan` no salen de `network.br_lan.ports` (ese router usa sección UCI
|
||
**anónima**) → se miden del kernel (`brif`).
|
||
- Higiene de git del repo de GitOps: la premisa ("la doc no está en el remoto") era **falsa**; un rebase
|
||
literal habría degradado doc buena. Verifica antes de reescribir.
|
||
|
||
**Una decisión ya cerrada en la ficha es una premisa: contradecirla es PARAR y reportar, nunca
|
||
escribir una segunda «decisión cerrada» encima.** Cicatriz (Hermes F11.3, 2026-07-26): la ficha de la
|
||
Fase 11 decía *"FQDN = hostname + `dns_suffix`"* y *"zona plana, **sin namespacing**"*; ocho días
|
||
después la sesión de ejecución escribió en el MISMO fichero su propia «DECISIÓN CERRADA» con lo
|
||
contrario (`<host>.<sede>.<dominio>`) y sin señalar el conflicto. Lo peligroso es que **su motivo era
|
||
correcto dentro del mecanismo que ella misma acababa de elegir** (reenvío de un solo dominio) — una
|
||
decisión que se auto-justifica y nunca sube al usuario. Señal de alarma: *"esto que voy a cerrar,
|
||
¿lo decidió el usuario o lo estoy decidiendo yo porque me conviene al mecanismo?"*. Si es lo segundo,
|
||
va al resumen como pregunta, no al código como hecho.
|
||
|
||
⛔ **La corrección va DONDE ESTABA EL ERROR, no debajo — y un documento «ya corregido» con el
|
||
artefacto viejo intacto es PEOR que uno sin corregir**, porque la enmienda hace creer que está
|
||
resuelto. *(cicatriz `C-085`)*
|
||
⇒ Regla: **enmendar es SUSTITUIR.** Si lo que estaba mal era un diagrama, se corrige el diagrama; si
|
||
era una tabla, la tabla. Un párrafo debajo que dice *«esto de arriba ya no vale»* deja el error en el
|
||
sitio donde la gente mira, y encima le pone un sello de revisado.
|
||
⇒ Y el corolario para quien ordena docs: **busca los artefactos VISUALES rancios primero** —
|
||
diagramas, tablas, ejemplos de configuración—. Son los que se copian, los que se citan y los que
|
||
nadie diffea.
|
||
|
||
**Y una decisión tiene que PARECER una decisión.** *(Segunda causa de la misma cicatriz, vista al
|
||
ordenar el fichero entero.)* La decisión original vivía **en prosa**, dentro de un párrafo de
|
||
objetivo, sin número, sin dueño y sin marca visual. La que la sobreescribió iba en negrita y
|
||
mayúsculas: «**DECISIÓN CERRADA**». **Ganó la que parecía una decisión.** Por eso el formato no es
|
||
cosmético ni solo un remedio contra el tamaño: un bloque **`D` numerado, con dueño explícito
|
||
(usuario / técnica) y separado del texto normal** se distingue a un golpe de vista, y eso vale
|
||
**también en un documento corto**.
|
||
|
||
⭐ **Un fallo de RED transitorio se lee como un fallo de PERMISOS si no reintentas.** *(cicatriz `C-086`)* Antes de convertir un fallo en una conclusión: **reintenta**, y si vuelve a
|
||
fallar, reporta el error **literal** en vez de tu interpretación de él — «connection reset» y «no
|
||
autorizado» no son lo mismo y llevan a sitios opuestos.
|
||
|
||
**Y si una premisa del encargo es falsa: PARA y repórtalo — no la "arregles" sobre la
|
||
marcha.** El prompt puede dar por hecho algo que no se sostiene; corregirlo en silencio esconde el
|
||
problema. Además: **lo que verificaste en una sesión anterior PUEDE haber cambiado** (otras sesiones,
|
||
otros commits entre medias) → de lo heredado tienes MÁS que re-verificar, no menos, justo porque
|
||
crees que ya lo sabes. Vuelve a mirar el estado real.
|
||
|
||
|
||
⭐ **Y la forma concreta de trabajarlas: las premisas del encargo se NUMERAN** (`P1`, `P2`…) con
|
||
veredicto explícito —verdadera / falsa / matizada, con `fichero:línea`—, y el **ratio de premisas
|
||
falsas** es el termómetro de *«estoy escribiendo de memoria»*. **«El doc lo dice» es una premisa a
|
||
verificar**, no una fuente.
|
||
⇒ ⛔ **Y hacia atrás, que es la mitad que se olvida: 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 de ahí se hereda como premisa falsa. *(cicatriz `C-087`)*
|
||
|
||
⛔ **Y una forma de romper un documento que no deja rastro: la CIRUGÍA POR NÚMERO DE LÍNEA.** Un
|
||
`sed '1342,1453d'` o un `sed "${L}r fichero"` acierta o destroza según un número que **cambia con
|
||
cada edición anterior de la misma sesión** — y el daño es *texto que desaparece*, que es justo lo que
|
||
no se nota releyendo por encima. *(cicatriz `C-088`)*
|
||
⇒ **Un `grep` del marcador que acabas de insertar no verifica una edición: verifica tu inserción.**
|
||
⛔⛔ **Y ESTE RAÍL ESTABA ESCRITO Y NO IMPIDIÓ NADA: SE CUMPLIÓ CINCO VECES SOBRE ESTE MISMO
|
||
DOCUMENTO.** *(cicatriz `C-089`)*
|
||
⇒ ⭐ **La lección no es sobre `sed`: es que un raíl que depende de acordarse ES PROCEDIMIENTO, NO
|
||
PROPIEDAD** — y este llevaba dos semanas escrito, en un documento que sus infractores tenían abierto.
|
||
⇒ ⭐ **Por eso se ató: `C39` del linter** compara cada línea que **acaba a mitad de frase** con la
|
||
siguiente que **arranca un bloque nuevo**, y **nombra la línea**. Ejercitado en los dos sentidos:
|
||
verde sobre el documento reparado, **rojo al partir un párrafo a propósito**. ⇒ **Lo que convierte
|
||
un raíl en una propiedad es un número que mueve el código de salida**, no repetirlo mejor.
|
||
⇒ ⛔ **Y ANCLAR POR CONTENIDO EN VEZ DE POR LÍNEA NO BASTA — refutado el mismo día en que se
|
||
escribió.** Un localizador **anclado a contenido** puede **casar de más y seguir en silencio**, que
|
||
es el mismo daño con otra causa. *(cicatriz `C-149`)*
|
||
⇒ ⭐ **La regla que sí aguanta: en un fichero que otras sesiones escriben, edita con la herramienta
|
||
que FALLA al no casar exacto** —una edición que exige unicidad y revienta si hay cero o dos
|
||
coincidencias—, **no con un script propio**. Un `sed`, un `awk` o un `perl` a medida **hacen algo
|
||
razonable ante la ambigüedad**, y eso es exactamente lo que no quieres: quieres que **pare**.
|
||
|
||
Lo que hay que mirar es **el texto de alrededor**, y en concreto **la línea anterior y la posterior
|
||
al corte**. ⇒ Y siempre que se pueda, edita por **anclas de contenido** (buscar y sustituir una
|
||
cadena única) en vez de por número de línea; los números se recalculan solos y las anclas no.
|
||
|
||
## 7. Fuente única + copias vendidas + red anti-deriva
|
||
|
||
Un artefacto compartido vive en **un** sitio; los consumidores llevan copia **commiteada**
|
||
(build sin red/Node) y un `--check` detecta la deriva. Nunca se edita la copia.
|
||
|
||
⛔⛔ **SUBIR UN ARREGLO UN NIVEL NO BASTA SI EL OPERADOR POSEE TAMBIÉN ESE NIVEL: hay que subirlo
|
||
hasta DONDE EL OPERADOR LEE SU ENTRADA.** Un operador no revierte «el objeto de abajo»: revierte
|
||
**todo lo que rerenderiza**, y eso incluye los CR que parecen la capa de configuración.
|
||
*(cicatriz `C-155`)*
|
||
⇒ ⭐ **Y lo que hace este error casi inevitable es que el corpus TENÍA el aviso y el aviso era
|
||
correcto**: *«donde manda un operador, el operador lo revierte»*. Lo que faltaba era **hasta dónde**.
|
||
⇒ **La pregunta que lo cierra: ¿de qué fichero/CR sale lo que el operador ESCRIBE?** Si tu cambio no
|
||
está ahí, **estás editando una salida, no una entrada** — y la próxima vez que el operador arranque,
|
||
tu arreglo desaparece **sin que nada falle**.
|
||
⇒ ⛔ **Y el censo que lo mide es barato y hay que hacerlo**: separa los arreglos **por si dependen o
|
||
no de un operador**. En el caso medido, **los seis que no dependían seguían en pie y los dos que sí,
|
||
caídos** — la línea divisoria no era la antigüedad ni el autor: **era el dueño del objeto**.
|
||
⇒ ⚠️ **Y no rompe cuando lo haces: rompe cuando algo obliga a RECREAR.** `NoSchedule` no desaloja y
|
||
los montajes del host sobreviven ⇒ el defecto vive **latente**, y luego un corte de luz o un
|
||
`rollout` lo revela. **Lo que parece la causa suele ser sólo el revelador**, y buscarla ahí te lleva
|
||
al sitio equivocado.
|
||
|
||
⛔ **UN CRITERIO QUE EXISTE COMO FUNCIÓN Y AUN ASÍ SE REESCRIBE A MANO NO ESTÁ CENTRALIZADO: ESTÁ
|
||
DISPONIBLE.** Fuente única no es *«existe un sitio donde está bien»*: es **que no haya forma de
|
||
hacerlo mal sin salirse del camino**. Mientras el criterio se pueda teclear otra vez, se teclea otra
|
||
vez — y la segunda versión es la que se equivoca. *(cicatriz `C-148`)*
|
||
⇒ ⭐ **El hueco no estaba en el código: estaba en el criterio que uno lleva en la cabeza**, y por eso
|
||
no lo caza revisar el código. ⇒ La pregunta no es *«¿está centralizado?»* sino **«¿qué me impide
|
||
reescribirlo?»** — y si la respuesta es *«acordarme»*, no está centralizado.
|
||
|
||
⛔ **UN ARREGLO QUE SÓLO VIVE EN UN EJEMPLO NO ESTÁ ARREGLADO: ESTÁ ANOTADO.** Si la corrección
|
||
existe en **un caso concreto** —un fichero de una máquina, un anexo, una guía de integración— y no
|
||
en **el mecanismo que genera los casos**, el siguiente caso nace con el defecto y **se paga entero
|
||
otra vez**, con el agravante de que **alguien puede enseñarte que ya estaba resuelto**.
|
||
*(cicatriz `C-151`; segunda ocurrencia en dos días, la primera en el censo de `A15`)*
|
||
⇒ **Al cerrar algo, la pregunta no es «¿está arreglado?» sino «¿de dónde saldrá el PRÓXIMO?»** — y si
|
||
la respuesta es una plantilla, un rol o un generador, **el arreglo va ahí o no está hecho**.
|
||
|
||
- El design system propio → `sync.sh` copia y `--check` verifica; el `.ipk` y la
|
||
imagen del hub construyen sin dependencias externas. Tres consumidores, cero cambios en el
|
||
componente = el contrato estaba bien puesto.
|
||
|
||
⛔ **Y cuando coses una cicatriz, BUSCA A LOS HERMANOS: un arreglo que no se propaga deja al gemelo
|
||
armado, y encima con la prueba de que el fallo es real.** *(cicatriz `C-090`)*
|
||
⇒ La pregunta, y es la misma de la poda (§1): **¿quién MÁS hace esto?** Un arreglo se termina cuando
|
||
se ha buscado al resto de sitios con esa forma — no cuando el fichero que fallaba pasa.
|
||
⇒ Y el sub-raíl que lo hace concreto: **una guarda de «no vino vacío» no protege de «vino de más»**.
|
||
Si de lo extraído depende un `bash`, la guarda tiene que **afirmar las dos anclas** y llevar una
|
||
**aserción negativa** (*esto NO debe aparecer aquí dentro*). El tamaño no es un testigo.
|
||
|
||
**Si tocas artefactos del OTRO repo, le debes a ese repo su entrada — en la MISMA sesión.** El
|
||
espejo cross-repo no se pudre por deriva de redacción: se pudre **asimétricamente**, porque el
|
||
trabajo hecho desde el repo A sobre cosas de B se documenta solo en A. Síntoma: casillas `[ ]` en B
|
||
para cosas **desplegadas** en B. *(cicatriz `C-091`)* La disciplina del espejo falló justo
|
||
para el trabajo cross-repo, que es **para lo que existe el espejo**.
|
||
|
||
⛔ **PROPONER UN CAMBIO SOBRE EL MECANISMO DE OTRO FRENTE ES TOCARLO.** La regla de leer su contrato
|
||
antes de meter mano **no aplica sólo a editar: aplica a SUGERIR** — porque **una propuesta técnica
|
||
concreta de una orquestadora a otra tiene fuerza de encargo**, y se implementa.
|
||
*(cicatriz `C-092`)*
|
||
⛔⛔ **Y lo que lo hace grave es que NO HABRÍA FALLADO**: convergería igual, nadie lo notaría, y sólo
|
||
gastaría de más **indefinidamente**. ⇒ Es **un cambio de contrato disfrazado de mejora del log**, y
|
||
esa frase nombra la clase entera: los cambios que **no rompen nada** son los que **nadie revisa**.
|
||
⇒ **Precisión de alcance, y es donde el raíl viejo no llegaba**: *«el mecanismo ajeno se ENTREGA, no
|
||
se arregla»* **ya se cumplía** —se entregó—. Lo que faltaba es que **la entrega puede llevar dentro
|
||
un arreglo**. ⇒ La forma correcta: **entregar el problema MEDIDO**, y si propones una salida, **decir
|
||
explícitamente que no has leído su contrato** — que es justo lo que convierte una orden en una idea.
|
||
⭐ **Y lo que hay que llevarse no es el error, es lo que lo contuvo** *(palabras de la dueña del
|
||
mecanismo)*: **«un mecanismo que sólo funciona cuando todo el mundo acierta no es un mecanismo; éste
|
||
funcionó contigo equivocándote, que es la única prueba que cuenta»**. Lo que paró aquello **no fue el
|
||
criterio de nadie**: fue **la frontera**, que obligó a mandar la propuesta en vez de aplicarla.
|
||
⇒ Generalizado: **una frontera se valida el día que alguien competente se equivoca dentro de ella y
|
||
aun así no pasa nada.** Mientras todos acierten, no sabes si tienes una frontera o una costumbre.
|
||
|
||
⛔ **Y el caso más caro de fuente doble no es un artefacto compartido: es el RELATO escrito DOS
|
||
VECES, en el backlog y en la bitácora.** *(cicatriz `C-093`)*
|
||
⇒ La regla que lo evita **ya existía** —*«las decisiones se quedan, la EVIDENCIA se va»*,
|
||
`sesion-ordenacion-docs.md` (capa `workflows/`)— pero vivía **en el workflow de la sesión
|
||
que LIMPIA, no en el de las que ESCRIBEN**, así que se incumplía sistemáticamente y se pagaba
|
||
después en una pasada. Por eso está aquí ahora.
|
||
|
||
⛔ **COMPROBAR QUE ALGO ESTÁ NO ES COMPROBAR QUE HACE AQUELLO PARA LO QUE EXISTE.** Y la trampa es
|
||
que **el artefacto puede ser correcto**: verificarlo sale **VERDE** y aun así el aviso sigue abierto.
|
||
*(cicatriz `C-094`)*
|
||
⇒ **La pregunta que lo caza no es «¿está?», es «¿QUIÉN LO VA A VER, Y CUÁNDO?»** — un piso por encima
|
||
de comprobar la fuente: ahí la fuente declaraba y el artefacto no reconciliaba; **aquí el artefacto es
|
||
correcto y está en el sitio equivocado**.
|
||
|
||
⛔⛔ **Y UN MENSAJE DE COMMIT NO ES UNA CAPA DEL CORPUS.** Lo dicho **sólo ahí** es, a efectos de
|
||
quien decide, **invisible**: quien lee `AVISOS.md` —que es lo que se manda leer primero— lee
|
||
**«RESUELTO»**.
|
||
*(cicatriz `C-095`)*
|
||
⇒ **Un mensaje de commit es el testigo de un CAMBIO, no el estado de un FRENTE.** Si lo que sabes
|
||
cambia el estado, va a su capa **además** —`AVISOS.md`, `decisiones.md`, `backlog.md` o la bitácora—
|
||
y el commit **puede** repetirlo. ⛔ **Nunca sólo en el commit**: es la quinta capa que nadie lee y que
|
||
además **no se puede recorrer** (§8).
|
||
⇒ ⛔ **Y hay un segundo filo, peor que la invisibilidad: UN AVISO CON FECHA DENTRO DE UN ARTEFACTO SIN
|
||
FECHA CADUCA SIN AVISAR.** Un mensaje de commit está **congelado**: se escribió en un instante y el
|
||
mundo siguió. Un *«esto NO está vivo todavía»* escrito a las 14:42 **era cierto**… y a las 15:10, con
|
||
la pieza construida y desplegada, **es una mentira que nadie ha tocado** — y el que lo lea mañana no
|
||
tiene forma de saber cuál de las dos cosas está leyendo.
|
||
*(Medido 2026-08-31, segundo frente en el mismo día: el aviso fue **cierto durante 28 minutos**.)*
|
||
⇒ Por eso un aviso **vive en una capa que se REVISA** —donde alguien lo cierra cuando deja de valer—
|
||
y no en un artefacto que **nadie vuelve a abrir para corregirlo**. ⭐ La prueba de si un sitio sirve
|
||
para un aviso es: **¿alguien va a volver aquí a cerrarlo?** Si la respuesta es no, ese sitio **sólo
|
||
sirve para lo que no caduca**.
|
||
⇒ **Al escribir, decide el destino UNA vez**, y los destinos son **CUATRO**: el corpus de un repo
|
||
tiene **cuatro capas**, no tres. *¿Es una decisión cerrada, de las que otra sesión no puede
|
||
contradecir sin PARAR?* → **`doc/decisiones.md`**, con su texto **íntegro**. *¿Es trabajo — un item
|
||
que cabe en una sesión?* → **`doc/backlog.md`**, que es **el eje del troceo**. *¿Es lo que hay que
|
||
saber el primer día?* → **`doc/AVISOS.md`**, que se lee antes que el backlog. *¿Es cómo nos
|
||
enteramos —lo medido, las predicciones, los mutantes, las premisas falsas, el relato—?* →
|
||
**`doc/bitacora.md`**, append-only, y en el backlog **un puntero fechado**. ⭐ Escribirlo en dos
|
||
**no es prudencia: es crear la deriva** que §7 existe para impedir, porque el día que uno de los dos
|
||
se corrija el otro seguirá ahí.
|
||
⛔ **Y la cuarta capa existe porque una decisión guardada en el backlog se numera POR FASE, y la
|
||
numeración por fase colisiona.** *(cicatriz `C-096`)*
|
||
⇒ Por eso se ordena **por ámbito, no por fase**; cada entrada lleva **texto íntegro** (nunca un
|
||
resumen — un resumen adquiere invariantes que la decisión no tiene), **dueño visible** (*Xavier* o
|
||
*técnica*: una técnica escalada como suya ya coló), **estado**, y el **testigo en la misma línea**
|
||
si afirma algo medible (§1). Una sustitución **edita la entrada vieja** —⚰️ y puntero—, jamás deja
|
||
las dos vivas.
|
||
⇒ Y «todo lo peligroso en un único documento» solo protege si **alguien lo recorre** (§8): toda
|
||
sesión de diseño mira ahí **qué contradice** antes de cerrar nada, y si contradice una `vigente`,
|
||
|
||
⛔ **COLOCAR UNA ENTREGA CONVIERTE EL BORRADOR EN UNA COPIA DERIVADA — y el borrador se BORRA en el
|
||
mismo gesto, no «cuando ya no haga falta».** Mientras se redacta, el borrador **es** la fuente y eso
|
||
está bien. El instante en que la entrega se coloca en el repo, hay **dos**: una con dueño, gate e
|
||
historial, y otra sin nada — y la segunda es justo la que su autora tiene abierta y a mano, así que
|
||
es la que se sigue editando. La deriva no necesita descuido: necesita **una edición más**.
|
||
⇒ **Regla**: la entrega se coloca y el borrador **muere en el mismo turno**. Si aún quedan cambios,
|
||
no se escriben en el borrador — **se aplican al máster**. Y si el autor no puede escribir en el
|
||
máster (no es su ámbito), **los redacta y los entrega**; lo que no hace es guardarlos en su copia
|
||
«hasta que se puedan aplicar», porque eso **es** la fuente doble, sólo que con buena intención.
|
||
*(cicatriz `C-097`)*
|
||
⇒ ⭐ Y el testigo de que esto está bien resuelto **no es que el borrador esté al día: es que NO
|
||
EXISTE**. Un borrador vivo junto a su máster es una fuente doble aunque hoy coincidan byte a byte —
|
||
lo que se mide es **quién puede escribir en él**, no si ahora mismo difiere.
|
||
**PARA y reporta** (§6) o la sustituye explícitamente.
|
||
⛔ **Un valor por 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 no es un descuido: es una **segunda fuente**
|
||
—con su propia verdad— y hay que buscarlo **explícitamente al introducir el default**, no el día que
|
||
los dos valores diverjan. *(Cicatriz del motor de aprovisionamiento, cosecha 2026-08-15: un endpoint construía su vista
|
||
**sin mergear la capa base** y devolvía otro valor.)*
|
||
⇒ Es la pregunta de la poda (§1) en la capa de datos: **¿quién MÁS lee esto, y por dónde?** Declarar
|
||
el default no reparte el default.
|
||
|
||
⛔ **El docstring/manual ES la interfaz — así que también tiene fuente única.** Cambia el
|
||
comportamiento → cambia el docstring **en el mismo commit**. Un doc que miente no es un doc
|
||
desactualizado: **ES el bug**, porque es lo que el llamante lee **en vez** de leer el código, y no
|
||
hay ningún gate detrás que lo desmienta.
|
||
|
||
⛔ **Y LAS CUATRO CAPAS NO SE LEEN IGUAL: hay capas de ARRANQUE y capas de CONSULTA.** El corpus no
|
||
crece porque se escriba de más —crece **porque funciona**— pero **se lee entero cada vez, y eso sí es
|
||
un defecto**. *(cicatriz `C-098`)*
|
||
⇒ **El reparto, y sale de una medida, no de una intuición**:
|
||
- **ARRANQUE** — `AVISOS.md` **primero**, luego `decisiones.md` y `backlog.md`, más el `CLAUDE.md`
|
||
del repo. Es lo que dice **qué muerde hoy**.
|
||
- **CONSULTA** — `bitacora.md` **por su índice**, y se abre la entrada que haga falta. ⛔ **No se lee
|
||
entera al arrancar**: es *append-only* y es historia, su función es **consultarse**.
|
||
- **NI UNA NI OTRA** — los **entregables** (`pos-anexo-x`, `pcte`, `enmiendas`…). Se sostienen solos
|
||
a propósito, así que **por diseño no cuentan nada del estado interno**: para ponerse al día no
|
||
sirven; para entregar, son el producto.
|
||
⛔ **Y esa última frase es una regla de ESCRITURA, no sólo una descripción de para qué sirve cada
|
||
capa**: **el entregable lleva el VALOR; el historial es de la bitácora.** Fuera de un documento
|
||
firmado van las fechas del proceso, los `mtime`, los *«antes decía»*, las citas de quién lo pidió y
|
||
el relato de cómo se llegó — **todo eso tiene su capa, y no es ésta**.
|
||
⇒ **El encuadre importa y es el fallo repetido de `§7`**: escrita como *«los entregables no cuentan
|
||
el estado interno»*, la regla se lee al **arrancar** y se incumple al **editar**, que es cuando
|
||
haría falta. Igual que *«las decisiones se quedan, la evidencia se va»* vivía en el workflow de la
|
||
sesión que LIMPIA y no en el de las que ESCRIBEN.
|
||
*(cicatriz `C-099`)*
|
||
⇒ Por eso la línea va **en la cabecera del propio entregable**, donde se edita, y no sólo aquí: un
|
||
raíl que sólo vive en la constitución **llega tarde al gesto que lo rompe**.
|
||
⭐ **El testigo de que el reparto es correcto, y es una medida real**: una sesión limpia reconstruyó
|
||
un frente entero —fase, cifras, las trece familias, las decisiones vigentes, las trampas y los
|
||
solapes— leyendo **el 28 % del corpus**, con la bitácora **sólo por el índice y sus dos últimas
|
||
entradas**, y **sin abrir** el censo de 1.098 líneas ni los mapeos. En ese frente la bitácora es el
|
||
**79 %** del peso. ⇒ **Sacarla del arranque quita cuatro quintos del coste sin perder nada.**
|
||
⚠️ Y lo que ese mismo careo enseñó del otro lado, que es lo que hay que arreglar escribiendo MÁS y
|
||
no menos: **lo que peor está escrito no es lo técnico, es lo OPERATIVO.** El corpus documentaba
|
||
magníficamente *qué se decidió y por qué falló*, y no decía **cómo se trabaja un martes por la
|
||
mañana**. *«Un sucesor no se atasca en una decisión de diseño; se atasca en no saber si teclear
|
||
`ansible-playbook` o `git push`.»*
|
||
|
||
⛔ **Un AVISO es una BANDERA: si no cabe en una pantalla, no es una bandera — es un documento
|
||
disfrazado.** La primera línea lleva **qué muerde y a quién**; el detalle va debajo, y el relato a la
|
||
bitácora. *(cicatriz `C-100`)*
|
||
⇒ Y no es sólo volumen: **el título en negrita de un aviso es la superficie que acumula encuadres
|
||
caídos**, porque se escribe para que muerda, porque un listado compacto **es lo único que enseña**, y
|
||
porque corregir el cuerpo **se siente** como haber corregido el aviso. Un aviso ya llegó a tener el
|
||
título equivocado **dos veces el mismo día**, con el cuerpo corregido las dos. ⇒ **Ante un encuadre
|
||
caído, el título se censa PRIMERO.**
|
||
⇒ ⭐ Y el barrido que nadie corre y que sale gratis: **censar qué avisos citan un ítem YA CERRADO.**
|
||
*(cicatriz `C-101`)*
|
||
|
||
⛔ **EL VEREDICTO VA EN LA PRIMERA PALABRA DEL CAMPO, NO AL FINAL.** Un campo de estado que **empieza**
|
||
diciendo *«abierta»* y **termina** en *«✅ cerrada»* es **formalmente correcto y operativamente
|
||
mentiroso**: quien escanea una columna —que es como se lee una tabla— ve lo primero. Y las dos
|
||
lecturas son defendibles, así que **dan resultados opuestos y ninguna es refutable**.
|
||
*(cicatriz `C-102`)*
|
||
⇒ Es la **tercera cara del mismo patrón** en un solo día, y por eso está aquí: **el título de un
|
||
aviso** acumula los encuadres caídos · **el cierre de una fila** se pone donde cabe en vez de donde
|
||
se mira · **el veredicto de un campo** se entierra tras 900 caracteres. **Lo que se lee es el
|
||
principio; lo que se corrige, el cuerpo.** ⇒ Al enmendar un estado, **la primera palabra es lo
|
||
primero que cambia**.
|
||
|
||
⛔ **Y AL VERIFICAR QUE ALGO SOBREVIVE EN OTRO SITIO: UN `id` ES ANCLA DÉBIL — LO QUE DISCRIMINA ES
|
||
UNA CIFRA DISTINTIVA.** Los ids se citan en todas partes, así que buscarlos da **verde por
|
||
construcción**. *(cicatriz `C-103`)*
|
||
⇒ ⭐ Y lo que lo hace un raíl y no una anécdota es **la asimetría**: un patrón demasiado **específico**
|
||
da **falsos negativos** —molestan, se ven, se corrigen—; un ancla demasiado **común** da **falsos
|
||
positivos**, y ésos **aprueban un borrado y no se notan nunca**. *«Es peor que tus falsos negativos
|
||
porque no se nota.»* ⇒ Cuando el veredicto **autoriza a destruir**, el ancla se elige **por lo
|
||
exclusiva que es**, no por lo cómoda.
|
||
⚠️ Y con su corolario: **un `sha` es ancla exclusiva pero puede no vivir en ningún documento**. En ese
|
||
mismo censo, **tres shas existían sólo como commits** — su relato estaba en el corpus por id y por
|
||
cifra, pero **el salto del documento al commit no sobrevivía**.
|
||
⇒ ⭐ **Y la forma general del hallazgo, que es transferible a cualquier frente**: *un corpus documenta
|
||
bien **lo que costó decidir** y mal **lo que nunca costó nada** — porque el ciclo de trabajo **no se
|
||
decidió: se fue quedando**. **Nadie escribe lo que hace todos los días.*** Y es exactamente lo que un
|
||
relevo no transmite y lo que un sucesor necesita **en los primeros diez minutos**. ⇒ El corpus de un
|
||
frente lleva, escrito y al día, **cómo se trabaja hoy**: dónde se edita, cómo se aplica, cómo se
|
||
sabe en treinta segundos en qué estado está el banco, y **qué está publicado y qué no**.
|
||
|
||
⛔ **Y LA FRONTERA DE «NO EJECUTES, DELEGA» SE SOSTIENE BIEN PARA MÁQUINAS Y MAL PARA TEXTO.** Ante
|
||
el hierro la pregunta se hace sola —*¿esto puede romper algo?*—; ante el corpus **no aparece**,
|
||
porque quien coordina **escribe en él todo el día legítimamente** —avisos, decisiones, bitácora— y
|
||
una pasada de ordenación **se siente como más de lo mismo**. **No lo es**: reescribe **memoria
|
||
compartida que leen todas las sesiones**, y por eso su propio procedimiento la declara **única**.
|
||
*(cicatriz `C-104`)*
|
||
⇒ ⭐ **El criterio que sí para, y no es ninguno de los dos que se usan por instinto**: no es *«¿sé
|
||
hacerlo?»* ni *«¿es peligroso?»* — es **«¿esto tiene un TIPO DE SESIÓN PROPIO?»**. Si lo tiene, **se
|
||
delega aunque sea texto, aunque sea barato y aunque sepas hacerlo**.
|
||
⇒ ⛔ **Y el mecanismo del fallo, que es lo transferible**: **un documento que describe un TIPO DE
|
||
SESIÓN se lee como un MÉTODO que aplicar uno mismo.** Son las dos cosas a la vez —describen la sesión
|
||
*y* contienen su método— y **nada en el texto obliga a decidir qué lectura estás haciendo**: un
|
||
método **invita a ejecutarlo**, un tipo de sesión **invita a delegarlo**, y el mismo fichero produce
|
||
las dos conductas. ⇒ Por eso un documento así **lo dice en su primera línea**: *«esto lo hace una
|
||
sesión propia; si lo estás leyendo y no eres ella, tu trabajo es escribir su encargo»*.
|
||
|
||
⛔ **Y LA UNIDAD DE MEDIDA DEL CORPUS ES EL TOKEN, NO LA LÍNEA** *(Xavier, 2026-08-29)*. Contar
|
||
líneas **hace invisible el problema real**: una línea de **8.196 caracteres** y una de **70** cuentan
|
||
igual, y en los corpus de este árbol **eso no es una anomalía, es la norma** — un `AVISOS.md` con
|
||
**1.905 caracteres de media por línea**, un semáforo con **928** y filas de **9.004**, frente a la
|
||
constitución con **79**. ⇒ **Dos documentos con las mismas líneas pueden diferir en veinte veces lo
|
||
que cuesta leerlos.**
|
||
⇒ **Proxy práctico**: `wc -c` (bytes) y **dividir entre ~3,5** para castellano con markdown y emojis.
|
||
No hace falta un tokenizador: hace falta **dejar de contar líneas**.
|
||
⚠️ **Y esto invalida disparadores ya escritos**: cualquier umbral del corpus expresado en líneas
|
||
—*«el backlog llegó a 2.729 líneas»*— **mide otra cosa** que la que se quería medir, y por eso los
|
||
recortes hechos sobre ese criterio no cuadran con el alivio que producen. **Se re-expresan en
|
||
tokens.** *(Lo cazó Xavier al no cuadrarle una sesión de ordenación de documentación: recortaba
|
||
líneas y el coste no bajaba.)*
|
||
|
||
|
||
## 8. Fallo benigno explícito, nunca degradación silenciosa
|
||
|
||
Diseña qué pasa cuando algo cae, y hazlo verificable. Y si algo se rompe en silencio, que grite.
|
||
|
||
- Rosenpass cae → se **mantiene la última PSK** (WG sigue cifrando); NO se baja a sin-PSK.
|
||
- `gre-sync` reconcilia la ruta al spoke **en cada vuelta** (no sólo al crear) — el opuesto era
|
||
perder la ruta de vuelta tras cada reinicio, en silencio.
|
||
- El guard de build falla si falta la copia del bundle, en vez de servir un `<script>` 404.
|
||
|
||
⛔ **Un mecanismo de resiliencia que NUNCA se ha ejercitado puede ser autodestructivo justo en el
|
||
momento de usarse.** *(cicatriz `C-105`)*
|
||
⇒ Un camino de recuperación que no se ha recorrido **no es un camino de recuperación**, es una
|
||
hipótesis. Ejercítalo **antes** de necesitarlo: el día que haga falta, ya es tarde para descubrir
|
||
que el remedio quita lo que venía a proteger.
|
||
|
||
⛔ **TODO AMORTIGUADOR ESCONDE EL FALLO QUE AMORTIGUA — y lo enseña el día que ya no está: en el peor
|
||
momento y sin historial.** El defecto **no está latente: está ocurriendo**, sólo que algo lo paga por
|
||
ti. Tres amortiguadores, tres cicatrices, un solo mecanismo:
|
||
- **REDUNDANCIA de caminos.** *(cicatriz `C-106`)* ⇒ Un verde con todas las
|
||
rutas vivas **no dice que el servicio funcione: dice que alguna de ellas funciona.**
|
||
- **ABUNDANCIA de recursos.** *(cicatriz `C-107`)* ⇒ Disco, RAM, CPU y ancho de banda **convierten un fallo en una estadística que
|
||
nadie mira**. **La flota real se parece al más pobre, no al banco.**
|
||
- **UPTIME: el proceso vivo.** Sostiene en memoria cosas que ya no existen fuera, y **el reinicio no
|
||
rompe nada: es cuando se descubre lo que llevaba roto**. *(cicatriz `C-108`)* ⇒ **Un `uptime` largo es motivo de SOSPECHA, no de confianza.**
|
||
|
||
⇒ ⭐ **El remedio es el mismo en los tres: QUITA EL AMORTIGUADOR Y VUELVE A MEDIR.** Apaga el camino
|
||
alterno · mide en el aparato más apretado, no en el más holgado · **reinicia, o carea lo que el
|
||
proceso cree contra lo que hay HOY en su origen** (el registro, el fichero, el secreto).
|
||
⇒ **Y las tres preguntas, cuando una medida salga limpia**: *¿qué la estaba tapando?* · *¿en qué
|
||
aparato la he tomado y qué le sobraba?* · *¿sobrevive a un reinicio?*
|
||
⇒ **Corolario para retiradas**: antes de quitar un mecanismo, comprueba si algo vivo **depende de que
|
||
no se reinicie**. Quitar la última forma de reconstruir algo que hoy sólo existe en una caché
|
||
convierte una limpieza en una pérdida.
|
||
⇒ ⛔ **Y el mismo raíl al revés: un arreglo COMMITEADO no es un arreglo APLICADO.** Todo lo que se lee
|
||
**al arrancar** —ConfigMap, variables de entorno, fichero de configuración— sigue siendo el viejo
|
||
hasta que el proceso reinicie, **y el `git log` dice que está arreglado**. *(cicatriz `C-109`)* ⇒ **Cierra el cambio midiendo
|
||
lo que el proceso vivo cree, no lo que dice el repositorio.**
|
||
|
||
⛔ **REVOCAR una credencial se lleva a sus HIJAS — así que «revocar el root» solo es seguro cuando
|
||
todo lo que importa es HUÉRFANO, y eso se mide ANTES.** Una limpieza de credenciales no es una
|
||
limpieza si no sabes qué cuelga de lo que vas a quitar. *(cicatriz `C-110`)*
|
||
⇒ ⭐ **Y lo que lo probó no fue el muerto, fue el SUPERVIVIENTE**: los tres tokens que aguantaron
|
||
eran `orphan: true` y el que murió era el único que no. *El diferencial es la prueba*, y no exigió
|
||
el privilegio que ya no se tenía — que es justo cuando hace falta un método, porque investigar un
|
||
incidente de credenciales suele empezar sin credenciales.
|
||
⇒ Antes de revocar: **enumera qué cuelga y comprueba su `orphan`**. Y al acuñar cualquier
|
||
credencial de servicio, **hazla huérfana desde el principio** — una credencial que hereda el ciclo
|
||
de vida de quien la creó es un rehén. La solución de fondo no es la orfandad, es **no usar tokens
|
||
estáticos** (auth method), pero la orfandad es lo que se puede hacer hoy.
|
||
|
||
⛔ **No concedas un privilegio para callar un error: pregunta si el proceso debería estar haciendo
|
||
eso.** *(cicatriz `C-111`)*
|
||
|
||
⭐ **Y su forma positiva, que es de DISEÑO y no de permisos: 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`, sin SQL libre, sin comando arbitrario. Lo que no
|
||
existe no hay que acordarse de no usarlo, ni protegerlo con un permiso que alguien acabará
|
||
concediendo un martes para callar un error.
|
||
|
||
⛔ **Una PROYECCIÓN construida para otra cosa no sirve de entrada a una decisión: los campos que no
|
||
lleva se leen como valores, no como ausencias.** *(cicatriz `C-112`)*
|
||
⇒ Dos arreglos, y hacen falta **los dos**: que el dato salga de **su** fuente (la configuración de las
|
||
LAN, no la proyección), y que **una fila que no declara el campo devuelva `dato_incompleto` y no
|
||
decida nada**. Una ausencia nunca puede ser interpretable como un valor.
|
||
|
||
⛔ **Un valor de configuración que sale VACÍO no falla: cae al default, y el default suele ser el
|
||
menos seguro.** *(cicatriz `C-113`)* ⇒ En las plantillas, `required` en todo valor cuyo vacío sea peligroso, para que
|
||
**reviente al renderizar** en vez de desplegarse abierto.
|
||
|
||
⇒ ⛔ **Y el corte que decide cuándo un default es admisible: PREFERENCIA vs IDENTIDAD.** Un default
|
||
de **preferencia** —qué valor usar entre varios válidos— es legítimo. Un default de **identidad**
|
||
—qué ES esto— **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 su motivo**, nunca el valor más
|
||
común. *(cicatriz `C-114`)*
|
||
|
||
⛔ **Y el corolario que este raíl NO llevaba, medido seis veces el 2026-08-19: un fallo benigno
|
||
explícito sólo protege si alguien LEE la línea.** Un banco que se salta algo **anunciándolo**, en
|
||
una salida que nadie mira, produce el mismo resultado que el silencio — y encima con la conciencia
|
||
tranquila de haberlo declarado. *(cicatriz `C-115`)*
|
||
|
||
⛔ **UN GATE PERMANENTEMENTE ROJO ES TAN CIEGO COMO UNO QUE NO PUEDE ENROJECER — y es peor, porque
|
||
parece que funciona.** Si un `check` lleva días en rojo, **ya no puede señalar el defecto siguiente**:
|
||
el 17.º aviso entra en una pantalla que tenía 16, y nadie lo ve. El rojo constante **no es una deuda
|
||
pendiente: es el gate apagado**, con la ceremonia intacta.
|
||
*(cicatriz `C-116`)*
|
||
⇒ ⭐ **Y al mirarlo, la vara estaba mal, no el trabajo**: de los 16, **seis eran `avisos:` y
|
||
`bitacora:`** — las **capas del propio corpus**, que en este método son **tipos de cambio de primera
|
||
clase** y el vocabulario no las contemplaba. **Arreglar la regla quitó seis; declarar excepciones
|
||
las habría enterrado a las dieciséis.**
|
||
⇒ **El orden, entonces**: ante un gate en rojo crónico, **primero pregunta si la vara mide lo que
|
||
crees** —un rojo masivo y homogéneo acusa al criterio antes que al trabajo—; **sólo lo que
|
||
sobreviva a eso** se arregla o se declara como excepción **nominal, fechada y motivada**.
|
||
⛔ Y el corolario que lo hace operativo: **acostumbrarse a un rojo es el mecanismo**, así que quien
|
||
llega nuevo a un frente **es el único que puede verlo** — si arrancas en un sitio y su gate sale
|
||
rojo, **dilo ese día**; después ya te habrás acostumbrado tú.
|
||
|
||
⇒ ⭐ **Lo único que convierte un aviso en un gate es un NÚMERO QUE TIENE QUE CUADRAR**, y que ese
|
||
número mueva el **código de salida**, no la pantalla. Las tres formas que ya existen en el árbol, y
|
||
se copian en vez de inventarse:
|
||
- **suelo de comprobaciones EJECUTADAS** (`guards.sh`: `SUELO_CHECKS`) — un `command not found` no
|
||
para el script y la comprobación *simplemente no ocurre*;
|
||
- **suelo de mutaciones EJECUTADAS** (los bancos del edge y del hub) — una mutación que
|
||
deja de casar **no se queja**;
|
||
- **un `skip`/una dormancia CONTADOS** (el `conftest.py` del chart del hub) — saltarse un
|
||
careo es rojo, y las ausencias legítimas se declaran **por nombre** y se carean **por igualdad**,
|
||
para que la lista no se pudra afirmando una ausencia que ya no existe.
|
||
|
||
⛔ **Y su hermano gemelo, que es el que no se ve mirando el código: un gate que NADIE LANZA da
|
||
igual de bien escrito que esté.** *(cicatriz `C-117`)*
|
||
⇒ Al escribir una comprobación, la pregunta no acaba en *¿puede ponerse roja?* — sigue en **¿quién
|
||
la lanza, y qué pasa si ese lanzador deja de existir?** Un suelo dentro de un banco que nadie
|
||
lanza sigue sin ser una puerta.
|
||
|
||
⛔ **Y el rastrillo que hay que pasar SIEMPRE que un testigo salga verde: ¿ese testigo puede decir
|
||
que no?** Tres veces el mismo día 2026-08-19, las tres midiendo el arreglo del censo `V12` y las
|
||
tres a punto de firmar un verde falso:
|
||
- `git status --porcelain 2>/dev/null` **desde WSL** aborta por *«dubious ownership»* ⇒ **no imprime
|
||
nada porque FALLA**. Ese vacío se leyó como «el árbol está limpio»; medido desde Git Bash, había
|
||
**tres ficheros mutados**.
|
||
- `bash -n` dio **verde** sobre una llamada cuyos argumentos estaban corridos un puesto (unos
|
||
comentarios metidos dentro de una continuación `\`). Sintaxis válida, semántica rota: lo cazó
|
||
**correr** el banco, con `$2: unbound variable` a mitad de vuelta.
|
||
- Un `tail` sobre `/tmp/a.out` devolvió la salida **de otra sesión** —fichero ajeno, de doce horas
|
||
antes, con el redirect propio fallando por permisos— y estuvo a punto de reportarse como medida
|
||
propia.
|
||
⇒ Tres instrumentos distintos, un solo modo de fallo: **el silencio de la herramienta se leyó como
|
||
la respuesta buena**. Antes de creerte un verde, **hazle decir que no una vez** — rompe algo a
|
||
propósito y comprueba que el testigo lo acusa. Y no midas en un sitio compartido (`/tmp`) lo que
|
||
tiene que ser tuyo.
|
||
|
||
## 9. Sesiones: fresca para su stack; la continuidad la lleva el orquestador
|
||
|
||
Cada sesión de ejecución arranca limpia sobre el stack que toca (edge ≠ hub ≠ MCP). No se
|
||
reutiliza una sesión de otro stack "por aprovechar contexto" — arrastra ruido. El hilo entre
|
||
sesiones lo mantiene la orquestadora (backlog + memoria).
|
||
|
||
**TODO PROMPT DICE SI ES EN FRÍO O EN CALIENTE.** Es la primera línea, no una nota al pie: quien
|
||
lo recibe tiene que saber si abre sesión nueva o lo pega en la que ya corre. *(cicatriz `C-118`)*
|
||
|
||
- **CALIENTE** — mismo stack, mismo repo, **continuación directa**, y el contexto de la sesión
|
||
anterior es un **activo**: acaba de construir justo eso que vas a tocar. Típico de los remates
|
||
cortos (cerrar un endpoint que ella misma dejó anotado). Re-arrancar en frío para cambiar un
|
||
decorador significa releer cinco documentos para nada.
|
||
- **FRÍA** — cambio de stack; **o** la tarea es *verificar / cuestionar* lo que esa sesión acaba de
|
||
hacer; **o** ha pasado tiempo y el estado ha cambiado; **o** su contexto ya es ruido (sesión
|
||
larguísima, tema agotado).
|
||
|
||
⛔ **La sesión que acaba de construir algo es la PEOR para verificar que está bien.** Ya cree sus
|
||
propias premisas, y el raíl 6 dice que de lo heredado hay que re-verificar **más**, no menos. Si la
|
||
tarea es comprobar, medir o poner en duda → **fría, siempre**. Construir encima → caliente.
|
||
|
||
⛔ **LO PRIMERO DE UNA ORQUESTADORA ES UN `git pull` — Y SI TRAE ALGO NUEVO, MEDIRLO ANTES DE
|
||
SEGUIR** *(Xavier, 2026-08-29)*. No es higiene de git: es que **el estado que creías tuyo puede
|
||
haberlo movido otro mientras no estabas**, y arrancar sobre una foto vieja es empezar con una premisa
|
||
falsa que nadie va a contradecir. ⇒ **Las dos mitades son obligatorias**: traerlo **y mirarlo**. Un
|
||
`pull` que trae doce commits y no se lee **sólo ha cambiado el sitio donde está la sorpresa**.
|
||
⇒ Y aplica **también a los repos que tú no trabajas pero coordinas**: puede que su frente lo lleve
|
||
**otra persona**, y que lo que traiga el `pull` no sea de ninguna sesión sino **suyo**.
|
||
*(cicatriz `C-119`)*
|
||
|
||
⚙️ **Desde el 2026-08-28 «CALIENTE» tiene MECANISMO: ya no se pega — se manda.** Este raíl daba por
|
||
supuesto que el prompt lo transporta **una persona** (de ahí *«quien lo recibe tiene que saber si
|
||
abre sesión nueva o lo pega en la que ya corre»*). Ese día dos sesiones del mismo árbol se hablaron
|
||
**directamente** por primera vez —cinco mensajes, todos actuados, en unas tres horas—, así que una
|
||
sesión viva se direcciona **por su nombre**.
|
||
⛔ **Lo que cambia es el TRANSPORTE, no el CRITERIO.** Que alcanzar una sesión salga barato no
|
||
convierte en caliente nada de lo que la lista de arriba llama frío, y el prompt sigue diciendo cuál
|
||
es. La confusión es fácil y cara, por eso se escribe aparte.
|
||
|
||
⛔ **Y la tensión NUEVA que el canal crea contra este mismo raíl: la sesión más barata de alcanzar
|
||
es exactamente la que `§9` prohíbe usar.** Mandarle un mensaje a la que acaba de construir la pieza
|
||
cuesta un gesto; abrir una fría cuesta releer. El camino cómodo lleva justo a *«pregúntale al que lo
|
||
hizo si está bien»*, que es la frase que este raíl existe para prohibir.
|
||
⇒ **La forma que sí funcionó, medida el mismo día**: la orquestadora **verificó por su cuenta y
|
||
desde fuera** —abriendo los objetos de git, midiendo los certificados con el crudo delante,
|
||
censando el corpus— y usó el canal **sólo para mandar el resultado ya medido**. El canal transportó
|
||
**datos y correcciones**; la verificación, nunca. ⇒ Regla de bolsillo: **por el canal viaja lo que
|
||
ya está medido; lo que hay que medir no se pregunta, se mide.**
|
||
⚠️ Y lo que el canal SÍ compró ese día, que es por lo que no se descarta: una **premisa falsa parada
|
||
antes de llegar más lejos** en un entregable oficial, una corrección **hacia arriba** (de una sesión
|
||
a su orquestadora) en el momento, y una **discrepancia declarada al instante**.
|
||
*(cicatriz `C-120`)*
|
||
|
||
⛔ **EL CANAL AVISA; EL CORPUS MANDA.** Preguntar y avisar, sí. **Un encargo nuevo o una decisión NO
|
||
viajan por aquí**: van por el usuario y **se escriben**. Una corrección o adenda a un encargo ya
|
||
aprobado sí, **diciendo de quién viene**. Y lo que cambie el trabajo **lo escribe en el corpus quien
|
||
lo recibe**. ⇒ **Un acuerdo que sólo existe en el canal no existe**: un mensaje muere con su sesión;
|
||
una línea del corpus sobrevive.
|
||
⚠️ Con **una excepción medida, y hay que nombrarla o el raíl se aplica mal**: en un **relevo**, el
|
||
canal no está repitiendo lo que el corpus dice — está entregando **lo único que el corpus no sabe
|
||
recoger** (callejones ya recorridos, una medida tomada *y por qué no vale*, la calibración del
|
||
puesto). ⇒ Ahí el deber es el inverso y es del que recibe: **fijar en el corpus lo que le llegó por
|
||
el canal, o el relevo sólo ha movido la deuda de sitio.**
|
||
|
||
⛔ **El ESTADO DE OTRO FRENTE se re-verifica antes de retransmitirlo — o se marca «según me dijeron
|
||
a las HH:MM».** Nunca se afirma en plano. *(cicatriz `C-121`)*
|
||
⇒ ⭐ **El mecanismo, que es lo que hay que saberse**: en los cuatro, **la foto era correcta cuando se
|
||
tomó y llegó rancia sin envejecer visiblemente**. Un estado ajeno **no se pudre de forma legible**:
|
||
sigue pareciendo un hecho. Y **no se puede verificar desde dentro del frente propio** — por eso lo
|
||
declara cada cual y no lo reconstruye el que recibe.
|
||
⇒ Y la razón de que el canal lo empeore, que también es de diseño: **transporta rápido y sin la
|
||
fricción que obliga a citar la fuente**. Escribir en el corpus te obliga a poner ruta, fecha y
|
||
testigo; mandar un mensaje, no.
|
||
|
||
⛔ **«YA MEDIDO, NO LO COMPRUEBES» NO EXIME — ES JUSTAMENTE LA FRASE QUE HAY QUE COMPROBAR.** Esa
|
||
marca no es evidencia: es **posición**. Y en un canal donde nadie ve la pantalla del otro, la
|
||
posición es lo único que puede sustituir a un testigo sin que se note.
|
||
*(cicatriz `C-122`)*
|
||
⇒ **Regla**: el que manda **marca lo medido con su testigo** (comando, cifra, ruta) y **no con su
|
||
autoridad**; el que recibe **reproduce lo que va a sostener una decisión**, aunque venga marcado. Y
|
||
si reproducir no es barato, se retransmite **como inferencia**, no en plano.
|
||
⇒ ⭐ **Y el porqué, que es el diseño del canal y no una cortesía**: *la única forma de que un canal
|
||
entre sesiones no propague errores es que **nadie tenga la última palabra por su posición**.* Ni la
|
||
orquestadora sobre el satélite, ni la superadmin sobre nadie. **El fallo de una se caza porque la
|
||
otra midió; el de la otra, porque la primera no reprodujo. Las dos mitades, o no funciona.**
|
||
⛔ **Corolario, y contradice el instinto de eficiencia**: dos sesiones que **nunca** se corrigen no
|
||
son un canal sano — son un canal donde la de arriba habla y la de abajo ejecuta, y ahí el error de
|
||
la de arriba **no tiene quien lo pare**.
|
||
|
||
⛔ **El NOMBRE de una sesión es una DIRECCIÓN; el ROL es la REFERENCIA. No se mezclan.** Entre
|
||
sesiones se direcciona con **el nombre que imprime tu propio listado** —es lo único que entrega un
|
||
mensaje—; **hacia el usuario se habla de ROL y proyecto**, porque los nombres **en su pantalla no
|
||
existen**. *(cicatriz `C-123`)*
|
||
⇒ Y el rol tiene lo que al nombre le falta: **no rota**. Un nombre caduca en cada reinicio y **miente
|
||
de tres formas** —la sesión murió, se renombró, o **nunca fue una dirección** (una sesión no sabe con
|
||
qué nombre la ven las demás)—. ⇒ **El único testigo válido de que una sesión murió es «escribí y no
|
||
contestó»**, jamás «no la veo en el listado».
|
||
|
||
⛔ **Nada de LAVADO DE PERMISOS: si a una sesión le deniegan algo, no se lo pide a otra — lo devuelve
|
||
a quien la dirige.** No es doctrina de esta casa: es un modo de fallo **con nombre propio en el
|
||
contrato de la propia herramienta** (*cross-session permission laundering*). Un permiso que se
|
||
consigue rodeando a quien lo negó no es un permiso, y el canal hace ese rodeo trivial.
|
||
|
||
⛔ **«Enviado con éxito» dice que el mensaje ENTRÓ EN LA COLA, no que alguien lo haya LEÍDO** — y su
|
||
mitad simétrica, que es la que muerde: **el emisor tampoco sabe si su mensaje se CRUZÓ con el del
|
||
otro**, así que **la ausencia de acuse puede ser un cruce y no un silencio**. *(cicatriz `C-124`)*
|
||
⇒ Regla de bolsillo: **antes de reenviar, pregunta si lo que tienes es un silencio o un cruce.** Y
|
||
si reenvías, **dilo** —*«ya te lo mandé, va otra vez»*— para que quien lo reciba dos veces sepa que
|
||
es el mismo y no un encargo nuevo.
|
||
|
||
⛔⛔ **UN DATO SE DEFORMA AL VIAJAR POR EL CANAL, Y SIEMPRE EN LA MISMA DIRECCIÓN: llega con MÁS
|
||
fuerza y MENOS condiciones de las que tenía.** Cuatro caras, todas medidas el 2026-09-02 y **todas
|
||
de la superadmin**, que es quien más retransmite:
|
||
|
||
**① GANA CONFIANZA — quien retransmite AMPLIFICA.** El intermediario suelta los matices —no son
|
||
suyos, no los midió, no sabe cuáles aguantan— y conserva la conclusión, **que es lo único
|
||
transmisible**. Dos saltos y una frase de pasada es un hecho. *(cicatriz `C-125`)*
|
||
⇒ **Retransmite la MEDIDA, no la conclusión**; y si sólo tienes la conclusión, **di que es de otro y
|
||
que no la has medido**. ⭐ Y el antídoto que funcionó: **al pasar una alarma, adjunta la pregunta que
|
||
la desinflaría** —*«mide el `imagePullPolicy` antes que nada; puede que sean tres y no veinte»*, y
|
||
eran cero—. **Una alarma que viaja con su propia refutación no se propaga sola.**
|
||
|
||
**② PIERDE SU ÁMBITO — los ids son LOCALES a su repo.** `A10` no es un nombre: es un nombre **dentro
|
||
de un repo**, y dos frentes tienen `A10` distintos **por diseño**. *(cicatriz `C-126`)* ⇒ **Prefíjalos**
|
||
(`hermes-infra·A10`), como ya se hace con las `D`. ⭐ **Cuanto más útil es un parte común, más lejos
|
||
viaja una colisión de ids.**
|
||
|
||
**③ PIERDE SU FECHA — un ⛔ recibido CADUCA aunque no lo diga.** Una restricción se levanta cuando su
|
||
causa muere, **y eso no avisa a nadie**: el que la recibió sigue planificando alrededor de un muro
|
||
que ya no existe. *(cicatriz `C-127`)* ⇒ **Al emitir un ⛔, mándalo con su condición de muerte** *(«esto cae cuando vuelva el
|
||
quórum»)*; **al recibirlo, comprueba si su condición sigue viva antes de construir encima**. Un
|
||
mensaje muere con su sesión; **un muro citado de memoria no.**
|
||
|
||
**④ Y LA QUE EXPLICA POR QUÉ LAS TRES SE CORRIGEN TARDE: una restricción o una alarma de MÁS NO DA
|
||
SÍNTOMA.** Nadie se queja de no haber hecho lo que creía prohibido; no sale en ningún log, no la
|
||
enrojece ningún gate, y **se obedece sin preguntar**. La de menos revienta y se ve; ésta sólo se paga
|
||
en **trabajo que nunca se intentó**.
|
||
⇒ **Ante un ⛔ recibido por el canal que vaya a costarte trabajo: de dónde sale, qué lo mide, y sigue
|
||
vivo.** Las tres preguntas son una línea y cubren las cuatro caras.
|
||
|
||
|
||
## 10. Lo que "funciona por casualidad" está roto
|
||
|
||
Construir bien la capa de encima destapa lo de debajo. Al hacerlo, **arréglalo y anótalo**, no
|
||
lo dejes pasar.
|
||
|
||
- CSS que teñía por selectores de ancestro que no cruzan el Shadow DOM (llevaba tiempo sin
|
||
teñir nada). `dnsmasq interface=wg0` sin dirección → el hub no servía DNS a nadie desde hacía
|
||
meses. El split-DNS escribiendo en `/etc/dnsmasq.d` cuando OpenWrt lee `/tmp/dnsmasq.d`.
|
||
|
||
**Cuando destapes algo muerto, mira las DOS mitades: que nadie lo consuma puede estar escondiendo
|
||
que tampoco se podía escribir.** *(cicatriz `C-128`)* **Señal barata y
|
||
fiable**: un contador de versión de config que sigue en `1` con todos los campos vacíos no es «no
|
||
lo han usado» — es «no se puede usar». Búscala.
|
||
- Si es de **producción** (p. ej. el `gre-sync` de c2et), no lo arregles a lo loco: anótalo como
|
||
bomba latente y encájalo en el plan de release (ver `incidente-produccion.md`).
|
||
|
||
## 11. El orden de lo irreversible: añadir antes de quitar · *C14 (4 fuentes), promovido 2026-08-08*
|
||
|
||
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, promovido 2026-08-08*
|
||
|
||
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 del motor,
|
||
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
|
||
|
||
⛔ **UNA CREDENCIAL ESCRITA EN EL CORPUS DICE DE QUÉ ES — banco o real — o el lector tiene que
|
||
asumir lo peor** *(Xavier, 2026-08-29: «hay que diferenciar entre el banco de pruebas y lo real»)*.
|
||
El raíl de `Entrega/Secretos` dice **nunca en git**, y con eso basta para las reales. Lo que no
|
||
cubría es que **una credencial de banco escrita sin decir que lo es se lee como una fuga**, y el
|
||
coste no es teórico: **quien la encuentra para el trabajo y la sube como hallazgo de seguridad**.
|
||
*(cicatriz `C-129`)*
|
||
⇒ **Regla**: si una credencial va a estar escrita, **va con su ámbito pegado** —*«banco de pruebas,
|
||
no producción»*— en la misma línea. Y si no lleva ámbito, **el lector debe tratarla como real**: esa
|
||
asimetría es deliberada, porque el fallo caro es el contrario.
|
||
⇒ ⭐ Y la generalización, que vale más que el caso: **el corpus no distingue hoy, a la vista, un
|
||
sujeto de BANCO de uno REAL** — ni en credenciales, ni en endpoints, ni en nombres de host. Un
|
||
ejemplo copiable que apunta a producción **es el mecanismo de un accidente, no una errata**, y no
|
||
hace falta que lo vendorices a ningún sitio: **ya es peligroso donde está**, porque una sesión lo
|
||
pega tal cual.
|
||
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`**) y, mejor,
|
||
**`git commit -- <rutas>`**, que ignora el índice para todo lo demás; una tarea = una sesión.
|
||
⛔ **Y `git pull` NO es parte de esto**: entre sesiones **de esta máquina** es un **no-op** —
|
||
comparten árbol e índice, ver el cuarto filo de `§9`— y creerlo una protección **es el modelo
|
||
equivocado**. Donde **sí** hace falta es contra el **remoto**, cuando ha podido empujar **otra
|
||
máquina o una persona**. *(cicatriz `C-130`)* ⇒ **Distingue de quién te estás sincronizando**: de otra sesión, no
|
||
hay nada que traer; de otra máquina, sí.
|
||
- ⛔ **QUIÉN EMPUJA: el `push` es un acto de ÁMBITO, no un acto sobre tus commits** *(Xavier,
|
||
2026-08-29)*. **Un `push` publica todo lo que hay entre el remoto y tu HEAD, lo haya puesto quien
|
||
lo haya puesto** — así que el permiso no se decide por quién escribió el commit, sino por **de
|
||
quién es el repo**:
|
||
- **La ORQUESTADORA empuja en SU ámbito.** Es la única que puede: es quien ve si la tarea
|
||
**reencuadra el backlog** o cambia algo más, y **empuja después de la medición**, no antes.
|
||
- **La EJECUCIÓN no empuja: se lo dice a su orquestadora.** Commitea y lo declara; publicar es
|
||
de arriba.
|
||
- **La SUPERADMIN tiene su propio ámbito —el Método— y ahí se comporta como una orquestadora
|
||
más.** Fuera de él: si ve algo sin empujar, **avisa a la orquestadora de ese frente**; si no
|
||
está viva, **pregunta a Xavier**, y es él quien autoriza a empujarlo todo.
|
||
⇒ **Testigo obligatorio antes de cualquier `push` en repo compartido**: `git log @{u}..HEAD` — y
|
||
que **todo lo que vas a subir sea de tu ámbito**. Si arrastras algo ajeno, **dilo en el mensaje**
|
||
en vez de callarlo: eso es lo que convierte un arrastre en un robo silencioso.
|
||
⚠️ **Y EL LÍMITE DE ESE TESTIGO, que hay que saberse porque parece cubrir más de lo que cubre:
|
||
`git add` con ruta explícita NO protege cuando el cambio ajeno está en el MISMO fichero.** Protege
|
||
contra arrastrar **otros** ficheros; contra **dos sesiones escribiendo en uno solo** no distingue
|
||
nada — la ruta es la misma. *(cicatriz `C-131`)*
|
||
⇒ ⭐ **Lo que sí lo caza es la puerta de los tres números** —`ficheros staged` · `filas tocadas` ·
|
||
`¿todas mías?`— **pero enrojeciendo por un motivo que no es el tuyo**: ahí habría dado `22/43` en
|
||
vez de `22/22`. **Un gate que se pone rojo por causa ajena entrena a desmentirlo**, así que cuando
|
||
salga descuadrado la pregunta no es *«¿qué he hecho mal?»* sino **«¿de quién es lo demás?»** — y la
|
||
respuesta es un mensaje, no un `commit`.
|
||
⛔⛔ **Y LA PUERTA HAY QUE ESCRIBIRLA DE MODO QUE ATE, NO QUE INFORME.**
|
||
|
||
echo "filas tocadas: $n ¿mías?: $m" # INFORMA — depende de que alguien mire
|
||
[ "$n" = "$m" ] || { echo "PARA"; exit 1; } # ATA — falla sola
|
||
|
||
*(cicatriz `C-132`)*
|
||
⛔⛔ **Y UN GATE AMBIGUO NO FALLA: ENSEÑA A IGNORARLO.** No corrompe nada, no da un número malo —
|
||
**dice la verdad sin decir de QUIÉN habla**, y el que lo lee la atribuye al sujeto que tiene delante.
|
||
*(cicatriz `C-133`)*
|
||
⇒ ⭐ **Y el daño no es el susto: es lo que se aprende.** *«La segunda vez que a alguien le pase, no va
|
||
a ir a leer el código: va a aprender que ese rojo **no es suyo** y a saltárselo»* — **y entonces el
|
||
gate está apagado el día que el rojo sí sea suyo**. Es el rojo crónico llegando por otra puerta: allí
|
||
se ignora **por costumbre**, aquí **por razonamiento**, que es peor porque el que lo salta **cree que
|
||
tiene motivo**.
|
||
⇒ **El arreglo no es lógica, es redacción: que la línea NOMBRE su sujeto.** Con el repo delante, el
|
||
mismo rojo deja de ser ambiguo y **no hay nada que aprender a ignorar**.
|
||
⇒ ⭐ **El enunciado general, que vale más que el caso — y es la TERCERA cara de la misma familia**:
|
||
**el número puede estar bien y el veredicto no vincular.** Las tres caras medidas son (a) el `rc`
|
||
**no sobrevive al transporte** —el que lees es el de `tail`—, (b) el **rojo crónico**, correcto e
|
||
ilegible por costumbre, y (c) ésta: **enrojece bien y no ata nada**. ⇒ **Un gate sólo ata si rompe
|
||
el flujo por sí mismo** —código de salida, comando que no continúa—, nunca delegando el veredicto
|
||
en quien lo lee.
|
||
⛔⛔ **CUARTA CARA, y es la que más engaña: UNA PUERTA CUYO RESULTADO SE LEE DESPUÉS DE ACTUAR NO ES
|
||
UNA PUERTA — ES UN REGISTRO DE LO QUE YA PASÓ.** Aquí el gate **calcula bien, enrojece bien y el
|
||
operador lo lee**… y no sirve, porque **no hubo ningún instante en el que pudiera parar**.
|
||
*(cicatriz `C-134`)*
|
||
⇒ **La forma no es «correr la puerta»: es que la ACCIÓN sea un paso DISTINTO Y POSTERIOR a leerla.**
|
||
Un `&&` entre la comprobación y el acto **convierte el gate en telemetría**. Si van en la misma
|
||
orden, la comprobación **tiene que abortar ella misma** (cara *(c)*) — leerla no basta.
|
||
⇒ Y el criterio para saber cuál estás escribiendo, que es de la sesión que lo pagó: **si el
|
||
cumplimiento depende de la atención de quien tiene prisa, no has escrito un raíl: has escrito un
|
||
consejo.** Un raíl se cumple **aunque no te acuerdes de él**.
|
||
⇒ ⭐ **Y la regla NO es «átalo todo»: es ÁTALO SI ES DECIDIBLE SIN ADIVINAR — y si no lo es, DI POR
|
||
QUÉ NO LO HAS ATADO.** Un raíl que explica **por qué no se mecaniza** es lo único que impide que el
|
||
siguiente lo mecanice mal *«por completitud»*.
|
||
*(cicatriz `C-135`)*
|
||
⛔ **Y por eso se escribe el NO**: una prescripción sin gate y sin explicación se lee como un
|
||
descuido, y el siguiente que pase «lo arreglará» — creando justo el rojo permanente que este
|
||
párrafo prohíbe.
|
||
⭐ **Y lo que de verdad caza el arrastre no es acordarse de mirar el `diff`: es MEDIR DOS VECES y
|
||
que los números no cuadren.** *(cicatriz `C-136`)* ⇒ El testigo no es la disciplina de mirar, es **la discrepancia entre dos
|
||
medidas del mismo sujeto**, que **te obliga a mirar sin depender de que te acuerdes**. Y ya
|
||
sabemos lo que rinde un raíl que depende de acordarse: es **procedimiento**, no propiedad.
|
||
*(cicatriz `C-137`)*
|
||
⚠️ **Y no se arregla con `push --force`**: sobre un repo que tocan varios frentes, deshacer algo ya
|
||
publicado es peor que el daño. Se avisa a su dueño y **lo decide él**.
|
||
⚙️ **AUTORIZACIÓN PERMANENTE de Xavier, 2026-08-29, con su motivo y sus límites** *(cicatriz `C-138`)*: **si la orquestadora de ese ámbito NO está viva, la superadmin puede empujar** — y
|
||
**una orquestadora también, en el mismo caso**. **Motivo**: que él no sea el cuello de botella
|
||
para publicar trabajo ya terminado de una sesión que ya no existe.
|
||
⛔ **Y lo que NO cubre, que es la mitad que importa: EMPUJAR NO ES DECIDIR.** El permiso alcanza al
|
||
**acto de publicar**, nunca a la **aprobación del contenido**. Si un commit declara que espera una
|
||
decisión, **publicarlo no la toma**: se empuja **diciéndolo** y la decisión sigue pendiente de su
|
||
dueño. Y **antes de usarlo se comprueba que la orquestadora no está viva** — *el único testigo
|
||
válido es «escribí y no contestó»*, jamás «no la veo en el listado».
|
||
⛔⛔ **LOS SIETE FILOS DEL ÁRBOL COMPARTIDO.** *(cicatriz `C-139`)*
|
||
**① El ÍNDICE es compartido: `git add <ruta>` NO desmonta lo que otra sesión dejó *staged*.** Tu
|
||
commit se lleva **ficheros que ni nombraste ni tocaste**, con ruta explícita, sin `-A`, y haciendo
|
||
todo bien. *(cicatriz `C-140`)*
|
||
⇒ **El gesto que falta NO es «no uses `-A`»** —no se usó— **sino: si te llevaste algo ajeno, DILO
|
||
EN EL MENSAJE.** Es lo único que devuelve la atribución, y cuesta una línea.
|
||
**② La ruta explícita NO protege si el cambio ajeno está en el MISMO fichero.** Protege contra
|
||
arrastrar **otros** ficheros; contra **dos sesiones escribiendo en uno solo** no distingue nada —
|
||
la ruta es la misma. *(2026-08-29: una ejecución paró antes de commitear al ver en el `diff` 21
|
||
líneas que no eran suyas.)*
|
||
**③ `git status` NO VE LOS COMMITS SIN EMPUJAR.** Son **dos gestos y ninguno implica al otro**:
|
||
`--porcelain` dice **qué me llevo DENTRO**; `git log origin/main..HEAD` dice **qué PUBLICO**.
|
||
*(cicatriz `C-141`)*
|
||
**④ El índice compartido también te hace PERDER LO TUYO, con un mensaje que suena a «ya estaba».**
|
||
Un `commit` puede fallar con **«nothing to commit, working tree clean»** teniendo tu cambio en el
|
||
índice: otra sesión lo vació entre tu `add` y tu `commit`. *(2026-09-01: el fichero seguía en disco
|
||
y `git status` lo daba *staged* medio minuto después.)* ⇒ ⭐ **Lo peligroso es la redacción**:
|
||
*«nothing to commit»* **se lee como «ya estaba hecho»**. Un `add` y un `commit` en órdenes
|
||
separadas **no son atómicos aquí**, y **el `rc=0` de un commit que no commiteó nada también es
|
||
cero** ⇒ verifica **después** del push.
|
||
**⑤ `--amend` REESCRIBE EL COMMIT DE OTRA SESIÓN** — y no es una operación local. El índice te hace
|
||
**arrastrar** lo ajeno; el `--amend`, **borrarlo y rehacerlo** con tu contenido dentro y su mensaje
|
||
fuera. *(cicatriz `C-142`)* ⇒ **Sólo sobre un `HEAD` que has
|
||
VERIFICADO que sigue siendo tuyo** (`git log -1`), nunca sobre el que recuerdas. ⛔ **Y el rechazo
|
||
NO se resuelve forzando**: `git reset --soft @{u}` y recommitear **lo tuyo solo**.
|
||
**⑥ NO HAY DOS CLONES — y creer que los hay es el error de modelo que los explica todos.** Las
|
||
sesiones de una máquina **comparten árbol e índice**: no son copias que sincronizar. ⇒ **`git pull`
|
||
entre ellas es un no-op**, y recomendarlo **da una falsa sensación de haberse protegido**.
|
||
*(cicatriz `C-143`)* ⚠️ **Y no lo
|
||
generalices al revés**: es cierto de las sesiones **de la misma máquina**; de un agente en worktree
|
||
aislado o remoto, **no** — y eso **se mide**.
|
||
**⑦ Y uno que no es de `git` sino del shell: con el `cd` PERSISTENTE, una ruta relativa NO
|
||
identifica un fichero.** El mismo `doc/bitacora.md` es otro fichero según dónde quedó el comando
|
||
anterior — y **no falla: escribe en el sitio equivocado y calla**. *(cicatriz `C-144`)* ⇒ **Rutas ABSOLUTAS y `git -C <repo>`**, nunca `cd` +
|
||
relativa. Y el testigo es barato: **el `tail` de lo que acabas de escribir y el `--stat` de lo que
|
||
vas a commitear**; si el `--stat` sale vacío, **no es que no haya cambio: está en otro sitio**.
|
||
⛔⛔ **UN PUSH EN BUCLE SOBRE MUCHOS REPOS PUBLICA LO AJENO POR DISEÑO — y el que lo sufre no se
|
||
entera.** *«Empujar todo repo que tenga commits pendientes»* es el gesto natural de un reparto, y
|
||
**es exactamente la regla equivocada**: publica lo que haya, lo haya puesto quien lo haya puesto,
|
||
**incluido el trabajo a medias de otra sesión que aún lo estaba escribiendo**.
|
||
*(cicatriz `C-150`)*
|
||
⇒ ⛔ **Y convierte en trampa un raíl que sí se cumplió**: la otra sesión corrió
|
||
`git log origin/main..HEAD`, vio el commit ajeno y **lo declaró en su mensaje** — y para cuando su
|
||
commit se publicó, **ese aviso ya era falso**. Cumplir el raíl produjo un mensaje mentiroso.
|
||
⇒ ⛔ **Y a un `--amend` legítimo lo convierte en reescritura de historia publicada**, porque lo que
|
||
amplías **ya está en el remoto sin que lo hayas subido tú**.
|
||
⇒ ⭐ **El gesto correcto no es mirar mejor: es NO EMPUJAR LO QUE NO ES TUYO.** En un bucle, por
|
||
cada repo: **si `origin/main..HEAD` trae algo que no es de tu ámbito, SÁLTATELO y dilo** — nunca
|
||
«lo empujo y lo declaro», que es lo que parecía razonable y publica trabajo en vuelo.
|
||
⚠️ **Y el límite, que hay que saberse**: `origin/main..HEAD` mide **un estado que otra sesión puede
|
||
cambiar entre que lo lees y que actúas**, y la ventana es de **segundos**. Es **necesario y ya no
|
||
suficiente** — otra cara de *«una inspección no gana una carrera»*. El único árbitro algo más
|
||
fiable es **`git ls-remote` inmediatamente antes**, y aun así hay carrera. ⇒ **Lo que de verdad
|
||
cierra esto no es un control mejor: es el alcance** —empujar sólo lo tuyo—, que **no depende de
|
||
cuándo mires**.
|
||
|
||
|
||
⇒ ⭐ **LAS TRES PUERTAS, EN UN SOLO SITIO — y no son redundantes: cubren VENTANAS DISTINTAS.**
|
||
`git status --porcelain` **antes del primer `add`** *(sólo ve lo que YA ESTABA cuando empezaste)* ·
|
||
`git diff --cached --name-only` **inmediatamente antes de commitear**, leído por ojos y **no
|
||
encadenado con `&&`** *(la única que caza lo que entró DESPUÉS de tu `add`)* · `git log
|
||
origin/main..HEAD` **antes de CADA push** *(la única que dice qué publicas)*.
|
||
⛔⛔ **UN DATO IMPRESO EN LA MISMA LLAMADA QUE LA ACCIÓN NO ES UNA PUERTA: ES UN REGISTRO.** Correr
|
||
`git log origin/main..HEAD` **y el `push` encadenados** produce exactamente la misma salida que
|
||
hacerlo bien — **y no puede detener nada**, porque cuando el dato se lee la acción ya ocurrió.
|
||
*(cicatriz `C-157`)*
|
||
⇒ ⭐ **Y por eso es tan fácil de cometer: el registro de haberlo hecho bien queda idéntico.** Quien
|
||
revise después ve la comprobación corrida, ve su salida, y **no puede distinguirla de una puerta
|
||
que funcionó.**
|
||
⇒ **Dos formas válidas, y sólo dos**: **(a)** la comprobación **decide por programa** —un `if` que
|
||
se salta el `push`—, o **(b)** se corre en **una llamada aparte**, se lee, y **luego** se actúa. Lo
|
||
que no vale es imprimir y seguir. ⇒ Es la misma familia que *«predecir el diffstat no vale si lo
|
||
predices y commiteas en el mismo gesto»*: **la ventana entre mirar y actuar te la fabricas tú, y si
|
||
la haces de cero, no hay ventana.**
|
||
⛔⛔ **PERO UNA INSPECCIÓN NO GANA UNA CARRERA, Y LAS TRES SON INSPECCIÓN.** Miran. Contra un
|
||
competidor concurrente sólo te dicen **cómo iba la carrera cuando miraste**, y eso depende de
|
||
**cuándo** mires, que es lo que no controlas. *(cicatriz `C-145`)*
|
||
⇒ **Lo único que no depende de cuándo mires es lo que EXCLUYE en vez de inspeccionar**:
|
||
**`git commit -- <rutas>`** (o `-o`) commitea esas rutas **pase lo que pase en el resto del índice**.
|
||
⚠️ **Ojo a la sintaxis, que se falla a la primera**: el mensaje va **antes** del separador —
|
||
`git commit -m "…" -- <ruta>`; ponerlo después lo convierte en pathspec y el commit muere.
|
||
⚠️ **Y `git commit -- <rutas>` tiene su propio límite, que hay que saberse porque parece cubrir más
|
||
de lo que cubre: te protege del ÍNDICE, no del ÁRBOL.** Publica **el contenido del working tree en
|
||
el instante del commit**, no el que verificaste antes — así que **si otra sesión reescribe ese
|
||
fichero entre tu comprobación y tu `commit`, publicas lo suyo con tu mensaje**.
|
||
*(cicatriz `C-152`)*
|
||
⇒ ⭐ **Y la ventana te la fabricas tú**: en el caso medido fueron **90 segundos**, gastados
|
||
**escribiendo el mensaje del commit** entre la verificación y el gesto. ⇒ **Escribe el mensaje
|
||
ANTES de la comprobación final**, y deja lo verificado pegado al `commit`. La distancia entre mirar
|
||
y actuar **es una decisión tuya**, y es lo único de la carrera que controlas.
|
||
⛔⛔ **Y EL SEGUNDO LÍMITE, QUE ES PEOR PORQUE NO DEJA NI RASTRO: `git commit -- <ruta>` NO AÑADE
|
||
FICHEROS NUEVOS.** Sólo recoge cambios de lo **ya trackeado**. Un fichero **nuevo** bajo esa ruta
|
||
**no entra, no sale en el `--stat`, y el commit tiene éxito**. *(cicatriz `C-154`)*
|
||
⇒ ⛔ **Y lo que lo hace caro es que el fichero SÍ ESTÁ EN DISCO**: se lee, funciona, los gates lo
|
||
carean **y salen verdes** — sobre algo que el repositorio no versiona. **Nada falla hasta que
|
||
alguien clona.**
|
||
⇒ **`git add <ruta-del-fichero-nuevo>` explícito, y el testigo es `git show --stat`**: si el
|
||
fichero que acabas de crear no aparece ahí, **no lo has commiteado**, digan lo que digan el disco y
|
||
el gate.
|
||
⇒ ⭐ Y la forma general: **el pathspec te protege del índice ajeno pagando con lo tuyo nuevo.** Es
|
||
una elección, no una salvaguarda gratuita — y **hay que saber qué se está pagando**.
|
||
⇒ ⭐⭐ **Y LO GRAVE NO ES LA RAREZA DE `git`, QUE ESTÁ DOCUMENTADA Y ES ABURRIDA: ES QUE EL GATE
|
||
ESTABA VERDE SOBRE UN FICHERO QUE NO ESTABA EN GIT.** *(Lo precisó `proyectos-3c`.)* El check leía
|
||
el fichero **del disco** — y **«está en disco» y «está en git» son DOS SUJETOS DISTINTOS**. Con el
|
||
fichero presente y sin versionar, **el check NO PODÍA enrojecer**: medía lo que tenía delante, no lo
|
||
que se publica.
|
||
⇒ **El testigo que discrimina no es leer el fichero: es `git ls-files --error-unmatch`**, que es lo
|
||
único que pregunta por el sujeto correcto. *(Atado en `C40` el mismo día, con control negativo.)*
|
||
⇒ ⭐ Y su familia, que ya tiene tres caras medidas: un gate que lee **un fichero que la IMAGEN no
|
||
incluye** · uno que lee **un fichero que el REPO no incluye** · y un banco cuya cabecera dice que
|
||
corre dentro del pod **y no entra en la imagen**. **Tres veces la misma pregunta —¿el artefacto está
|
||
donde el que lo mide cree que está?— y tres respuestas distintas.**
|
||
⇒ ⛔ **Y lo que NINGÚN gesto de git arregla: que otra sesión te sobrescriba el WORKING TREE.** No
|
||
hay dos copias. Mover la coordinación a git **compra historial, no aislamiento** — y la única
|
||
salida real es **que dos sesiones no escriban el mismo fichero**, no una puerta mejor.
|
||
⇒ ⭐ **Forma general, y vale fuera de git: ante una carrera, una comprobación no es una solución.**
|
||
Sirve para *saber* que perdiste, no para ganar. Lo que resuelve una carrera es **eliminarla**
|
||
—partir el recurso, dar turnos, excluir por construcción—; lo demás es contar accidentes con más
|
||
detalle.
|
||
|
||
⛔⛔ **Y LA PROPIEDAD QUE UNE A LOS SIETE, Y DICE CUÁNDO DEJAR DE BUSCAR UN GATE: `git` ES LA ÚNICA
|
||
HERRAMIENTA COMPARTIDA DEL ÁRBOL QUE NO TIENE EL CONCEPTO DE SESIÓN.** El semáforo sabe quién eres.
|
||
El canal sabe quién eres. El linter sabe en qué repo estás. **`git` sólo ve un working tree y un
|
||
usuario** — y aquí ese usuario es el mismo para todas.
|
||
⇒ Por eso **todos los filos aparecen ahí**, y por eso **ninguno lo caza un gate: no hay dato con el
|
||
que un gate pudiera distinguirlos.** ⭐ Y eso **no es una excusa: es el criterio para parar** —
|
||
buscarle un gate a esto es construir un instrumento sin sujeto, que es la avería que este Método más
|
||
persigue. **Lo que sí se puede es avisar antes y decirlo después.**
|
||
|
||
⭐⭐ **Y LA MITAD QUE SÍ SE PUEDE ATAR, PORQUE EL MENSAJE SÍ LO CONTROLAMOS: CADA COMMIT DICE QUIÉN LO
|
||
HIZO.** `git` no tiene concepto de sesión — pero **el mensaje es nuestro**. Un *trailer* con el **ROL**
|
||
convierte los cuatro filos de arriba en algo **visible en el `log`**: un arrastre, un `--amend` ajeno
|
||
o un `push` que publica lo de otra **se leen**, en vez de descubrirse por un rechazo que puede no
|
||
llegar.
|
||
|
||
Sesion: <rol>/<frente> p. ej. Sesion: orquestadora/securizacion
|
||
Sesion: ejecucion/hermes-infra
|
||
Sesion: superadmin
|
||
|
||
⛔ **El ROL, no el nombre de sesión**: los nombres **rotan en cada reinicio** y el usuario **no los
|
||
ve** — un `log` lleno de identificadores caducados no identifica a nadie. El rol **sobrevive al
|
||
reinicio y significa algo dentro de seis meses**, que es cuando se lee un `log`.
|
||
⇒ Se ata (`C26`) **desde un punto de adopción sellado por repo**, así que **la historia anterior queda
|
||
fuera POR CONSTRUCCIÓN** — no por una lista de excepciones que crecería para siempre. *(Es la lección
|
||
del rojo crónico aplicada al diseñar el gate, no después de sufrirlo.)*
|
||
⭐ **Y lo que esto arregla de fondo**: hasta aquí, la única atribución que existía era **el mensaje**,
|
||
y por eso *«un commit ajeno bajo un mensaje que habla de otra cosa borra la única atribución que
|
||
hay»*. Con el trailer, **la atribución deja de depender de que el mensaje la mencione de pasada**:
|
||
está en un campo, es constante, y **se puede contar**.
|
||
⛔ **Y `C26` NO distingue a una sesión que OLVIDA el trailer de una PERSONA commiteando a mano** —en
|
||
un árbol donde el autor `git` es el mismo para todas, **no hay señal que los separe**—. ⇒ Por eso el
|
||
gate mide **presencia**, no autoría: **cualquier valor vale**, y **una persona escribe el suyo**
|
||
(`Sesion: <su nombre>`). Y su aviso **dice el gesto**: si aún no está empujado, **un `--amend` sobre
|
||
tu propio commit lo cierra sin necesitar excepción**. ⭐ *Un rojo que nombra el arreglo en una línea
|
||
no se vuelve crónico; uno que sólo acusa, sí.*
|
||
⛔ **DOS LÍMITES, escritos para que nadie estire el gate:**
|
||
**(1)** Dice quién **ESCRIBIÓ** el commit, **no quién lo PUBLICÓ**. Hace el `log` legible **después**;
|
||
**lo que evita el accidente antes sigue siendo `git log origin/main..HEAD`**, y el trailer **no lo
|
||
sustituye**.
|
||
**(2)** Es **autodeclarado**: caza **la ausencia**, nunca un rol **equivocado**. Y un `--amend` ajeno
|
||
**reescribe también el trailer**, así que ahí el `log` diría el rol del que enmendó.
|
||
⇒ **De los cuatro filos, `C26` hace LEGIBLES dos y no toca los otros dos.** Es una mejora real; **no
|
||
es el cierre de la familia**, y decirlo forma parte de tenerla.
|
||
|
||
⭐ **Y la regla de diseño que sale de compararlo con el gate anterior: UN GATE NUEVO SE SELLA DONDE
|
||
EMPIEZA A PODER CUMPLIRSE, NO DONDE EMPEZÓ EL REPO.** *(cicatriz `C-146`)*
|
||
- 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**.
|
||
|
||
## 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).
|