diff --git a/.metodo/CHECKSUMS b/.metodo/CHECKSUMS index 62f5b19..0c5efd7 100644 --- a/.metodo/CHECKSUMS +++ b/.metodo/CHECKSUMS @@ -1,4 +1,4 @@ -1138db1c676687e838b4c1f510b58f6c877e59be72d001c9aa03482faa619081 metodo.md +ef4606f5ad9421ecd093633696a19035d3dd034c437912a497464425492d3ac6 metodo.md 11bf48ad900c3a8748f229f4938a600ddd2a34897f36ee2284b10b5d44e3a0bf bin/metodo f89b71bdf31028b05075636c1763c964e379bc37a00e0357d1c23a4dd19c09aa workflows/README.md cc241bbecf9647c747b8525b3a6b527455cd50ca0312caa44bc3544342c8ac41 workflows/comunicacion-entre-sesiones.md diff --git a/.metodo/cicatrices.md b/.metodo/cicatrices.md new file mode 100644 index 0000000..369b0ac --- /dev/null +++ b/.metodo/cicatrices.md @@ -0,0 +1,1204 @@ +# Cicatrices del Metodo + +> La EVIDENCIA de cada rail de `metodo.md`, sacada aparte el 2026-09-02 para que el +> documento que se lee SIEMPRE quepa en contexto. Este viaja a los 27 repos igual que +> `metodo.md` -- el disco es gratis y el contexto no -- pero **no se lee por defecto**: +> se abre cuando alguien discute una regla o necesita el dato crudo que la produjo. +> +> ID PLANO Y PARA SIEMPRE: `C-001`, `C-002`... Se asigna UNA VEZ y **no se renumera**, +> igual que las decisiones `D`. Motivo, de Xavier: **es mucho mas resiliente** -- un id +> que codificara la seccion caducaria al primer movimiento, y este documento se +> reestructura constantemente (el 2026-09-02 se fundieron tres familias en un dia). +> Precedente medido: la numeracion de la §9 se rompio exactamente asi. + +### C-001 + +Cutover 2026-08-19: hasta ese día la fuente +> era la copia del árbol de trabajo y esta constitución llevaba los 10 raíles base **en una línea**, +> con un puntero a una ruta que en un clon ajeno no existe. Coste medido: el raíl nuevo de §8 —«un +> fallo benigno solo protege si alguien LEE la línea»— nació el 2026-08-19 y **no estaba en ninguna +> de las 18 copias**. Ahora los raíles viajan COMPLETOS y las adiciones que estaban «pendientes de +> inlinar» viven dentro de su raíl. + +### C-002 + +Familia de `A20`: la colisión de loopbacks era 1,9 % a 50 nodos y **26 % a 200**; lo que a escala + de banco es una anécdota, a escala de flota es el trabajo de una tarde. + +### C-003 + +Xavier, ordenando: «no estoy diciendo +que no valore la captura de un hub — lo pondremos en el backlog por detrás, con su apartado. Ahora +estamos en el apartado de **“y si capturan un edge”**, y para eso hay una CRL y unos procedimientos +que mis equipos de hoy **ni tienen**». + +### C-004 + +Xavier, `D7`, 2026-08-22. Estrenada el mismo día: `I11.11` salió de +su ficha a una épica propia **con su valor declarado — cero, porque no hay nadie esperándola**, que +es justo el dato que una casilla escondida dentro de otra ficha no da. + +### C-005 + +Cicatriz 2026-09-01: un censo de dependencias filtraba **por pod**, y descartaba la línea entera si +el pod tenía **una** imagen ya pineada junto a las móviles ⇒ **dejó fuera el motor de la propia sesión +que lo estaba midiendo**. Lo cazó **sólo porque sabía que ese motor tenía que salir**. El mismo día, +un censo de tags móviles dio **4** y el bueno era **20**. + +### C-006 + +Medido 2026-08-31, y con recurrencia en dos frentes independientes. Un frente censó **sus once +errores del día** y cómo se cazó cada uno: **4** porque otro no estuvo de acuerdo · **2** por una +predicción escrita antes de medir · **2** por una anomalía del instrumento · **1** al re-derivar una +referencia justo antes de commitear · **1** por accidente. ⛔ **Cero releyendo su propio trabajo.** +El mismo día, quien lleva el Método contó **catorce** en su bitácora —un `awk` que no insertó nada, +un `--amend` que reescribió el commit de otra, un aviso falso dado en consola, un gate publicado +roto— y **también cero**: los cazaron **contar la aparición, el `push` rechazado, otra sesión +midiendo y el `--stat` del commit**. Todos externos. + +### C-007 + +F11.13: meter una LAN en la malla «toca el firewall, como en F9.2 que tiró el acceso de +gestión». En vez de ir con cuidado, se **predijo** que el `md5` de `uci show firewall` no cambiaría +—solo `ospfd.conf` gana una línea `network`— y se midió antes y después: idéntico. El miedo pasó a +ser un invariante verificado. + +### C-008 + +Cicatriz +2026-07-27: un segundo hub daba **401 en toda la administración** y parecía protegida. **No lo estaba: +estaba rota.** Su Ingress reclamaba `/api`, que una imagen pre-F1 no sirve, así que el catch-all +autenticado se tragaba también **`/links/pair`** — el mismo accidente que cerraba `/admin/pair` +impedía que **ningún device pudiera emparejarse**. Se vio al medir la cara abierta: `/links/pair` +pasó de `401` a **`422` con cuerpo de la aplicación**. + +### C-009 + +Cicatriz `R10`, 2026-07-28: la orquestadora afirmó «los espacios no chocan» mirando +el enrutador —el panel usa `/`, `/pending`, `/devices/…`; la API `/links/*`— y era cierto **para el +enrutador y falso para el guard**: `POST /devices/enroll` **casa con la plantilla** +`GET /devices/{device_id}`, que es una página del panel. Una lista pública por **prefijo** habría +abierto esa página a internet — el accidente del otro hub, en espejo: allí el catch-all cerró de más, +aquí habría abierto de más. + +### C-010 + +Cicatriz 2026-08-18: la orquestadora puso +como testigo estrella de un despliegue que `GET /crl/afirmar` pasara de **404** a **302/401**, y +escribió que sin esa comprobación *«un “desplegado” no distingue nada»*. Medido antes de usarlo: la +ruta **no daba 404 ni antes** —daba `303 → /login`— y `/zzz-inventada` daba **exactamente lo mismo**. +El testigo habría tomado el mismo valor con la pantalla puesta y sin ella. + +### C-011 + +F11.11b: en vez de +concluir que nadie llamaba al endpoint viejo, se enseñó que **el mismo device**, minutos después de +instalarse la versión nueva, pidió el endpoint nuevo con token y no volvió a tocar el viejo. + +### C-012 + +Cicatriz 2026-07-27: +al ir a borrar el duplicado `/api/admin/*` apareció que las dos copias habían **derivado**, y la +correcta era **la que no llamaba nadie**. Desde el panel —la única puerta que usa un humano— +aprobar un nodo **no lo publicaba** hasta el barrido siguiente, y revocar una sede dejaba +resolviendo sus nombres **hasta 24 h**. Los tests iban por `/api/admin`, así que todo salía verde. + +### C-013 + +Cicatriz `H35`, 2026-08-04, y salió +bien porque el build se puso ROJO: el censo de la superficie pública se escribió en `doc/`, fuera del +contexto `src/api` ⇒ dentro de la imagen **no existía**, `IndexError`, artefacto no pusheado. Se mudó +a `src/api/tests/` y en `doc/` quedó un puntero. + +### C-014 + +Cicatriz 2026-07-28, barrido de la colección MCP: la MISMA clase apareció en los +CUATRO — la rotación del MCP de secretos daba verde por una señal pegajosa + `kv_exists` [el path ya +existía]; el `version_matches` del MCP del edge comparaba el `.ipk` con su propio `control`; el +`mint_token(git)` no probaba que el token AUTENTICARA; el `verified-ok` del MCP de build daba verde con +los pods VIEJOS sirviendo `200`; su gate A3 admitía `ungated` por ausencia de gates. Dos se cazaron +por casualidad mirando otra cosa; el barrido encontró el resto. Dos de cuatro habría sido casualidad; +cuatro de cuatro es un raíl. + +### C-015 + +Cicatriz `I8`, +2026-07-29: la ficha estimaba —leyendo `wg_hub.py`— que un re-alta anónimo dejaba el peer WG en pie +y que la pérdida llegaría «en el siguiente reinicio de `wg-hub`». **Son 36 segundos**: la API +reescribe `wg0.conf` sin ese peer, y `gre-sync` —**un script del chart, en OTRO repo**— borra el +`grehub` y con él la adyacencia OSPF. El peer sí sobrevivía; **moría todo lo construido encima**, y +eso convertía una bomba latente en una denegación de servicio en vivo. + +### C-016 + +Cicatriz Fase 14, 2026-07-28: `transport-spec.md` daba la derivación v2 de la +loopback por «congelado ⏳» y describía la v1 —«la teclea el operador; el hub la asigna por +`peer_index`»— con las **dos mitades falsas**. Su espejo decía lo mismo, así que **leyendo docs era +indetectable**: solo el hardware llevaba la contraria, con `10.100.203.26` en el router de campo y +`10.100.255.154` en el hub. De la misma tirada cayó un problema que **la spec inventaba**: el puerto +WG no es «443 RUTOS / 51820 OpenWrt» sino `51234` de escucha en ambas, así que el conflicto de +despliegues mixtos que describía **no existe**. + +### C-017 + +Cicatriz `P9c`, +2026-07-28: el panel comprobaba si `zebra` corría buscándolo en `ps` — y la contraseña del VTY de +quagga **es `zebra`**, así que **cada sonda dejaba en `ps` un proceso propio que casaba**. El módulo +se veía a sí mismo: cuanto más se miraba el panel, más imposible era que arrancara. + +### C-018 + +Cicatriz `engine`, 2026-07-30, cazada **antes +de armarla**: el `verify` del MCP de build sale por internet y el Ingress de `engine` tiene whitelist de +IP ⇒ devuelve **403 pase lo que pase**. Un `expect_status:200` habría fallado **siempre** → auto- +rollback → re-pin del digest anterior, que daba **404** → `engine` muerto y sin vuelta atrás: el +mecanismo de seguridad era el asesino. Y `expect_status:403` es **peor**: el ingress-controller +devuelve 403 **aunque el pod esté en `ImagePullBackOff`** — verde eterno sobre un servicio caído. + +### C-019 + +Cicatriz `A16`, 2026-08-01: el MCP del edge leía la versión con `head -1` —**por posición**— y +`/api/settings` tenía **dos claves `version`**; se quedaba con la del **install-report, un fichero que +escribe el `postinst` del propio `.ipk`**. Resultado: `installed 2.1.58 · served 2.1.58 · HTTP 200 · +4/4 enabled`, **verde entero, con el panel ejecutando 2.1.57**. El arreglo no fue reintentar: fue +esperar a **la marca de fin del instalador**, que es un observable distinto del que gatea. + +### C-020 + +Cicatriz 2026-08-13, y la cometió la orquestadora: midió el panel + del hub del trabajo con `urllib.request.urlopen` —que sigue los `3xx` por defecto y no lo dice— y + concluyó **«la aplicación no comprueba nada, el panel está abierto dentro del cluster»**. Era + falso: contestaba `303 → /login`. Encima **tumbó un hallazgo correcto** de la sesión de + ejecución —que sí había medido con `wget -S`, que enseña la traza entera— y estuvo a punto de + cambiar el motivo de una decisión por uno inventado. + +### C-021 + +Cicatriz `H12`, + 2026-08-02: `harbor.manabo.org` es **Valhalla** desde el constructor y **Athena** desde los nodos + que tiran. Una sonda de «¿ya está la imagen?» lanzada desde el pod habría preguntado **al registro + que acababa de recibir el push** ⇒ **200 siempre**. Por eso el destino de la sonda tiene que ser un + **endpoint explícito**, no el nombre. + +### C-022 + +Cicatriz evitada el 2026-08-02 +construyendo la poda de `allowed-ips`: el peer `yomi` lo pone `wg-setup` **desde un Secret** y el API +**nunca** lo escribe en la conf. Una poda de «borro todo lo que no reconozco» se lo habría llevado — +que es el error de `H13` con el `lo` del nodo, y por eso hizo falta una lista `PRESERVE_PEERS` +explícita. + +### C-023 + +Cicatriz 2026-08-02: un `kubectl delete ns karmada-system` lanzado con el plano de +control revuelto por los reinicios de esa misma sesión —`connection refused` contra el apiserver a la +misma hora— se llevó el objeto `Namespace` y dejó **vivos los 18 objetos de dentro**, listables y sin +`deletionTimestamp`, en un namespace que ya no existía. El `namespace-controller` **enumera por +discovery** lo que debe borrar; una enumeración vacía se leyó como «no queda nada», retiró el +finalizador y el `Namespace` desapareció antes que su contenido. + +### C-024 + +Cicatriz 2026-08-02, cazada por Xavier antes de +ejecutarse: un aviso describía un `wg0` con **RX 0 y TX 56 MiB** como «un túnel muerto que nadie +usa», y la orquestadora ofreció «levantarlo o quitarlo» como dos opciones equivalentes. Xavier: +**«ese túnel es con el que me conecto yo a casa»** — y estaba **fuera de casa** en ese momento. +Quitarlo le habría cortado el acceso. + +### C-025 + +El mismo +`A16`: se propuso «comprobar que el PID cambió» como prueba de reemplazo — y **el respawn de procd +también estrena PID**, así que habría salido verde sobre el árbol viejo. El testigo bueno era **la +versión que el panel SIRVE**, que es lo único que solo puede decir el árbol que corre. + +### C-026 + +Cicatriz 2026-08-02, cluster `home`: dos reglas +—`etcdMembersDown` y `etcdInsufficientMembers`— contaban **targets de scrape** y los llamaban +«miembros». Llevaban **56 días** en rojo porque los cuatro componentes del plano de control escuchaban +sus métricas en `127.0.0.1`, con los cuatro **perfectamente sanos**. + +### C-027 + +Cicatriz 2026-08-02, y la cometió la orquestadora: dedujo que Vault llevaba «29 días corriendo sin +el `hostAliases`» porque `currentRevision ≠ updateRevision`, y recomendó **revertirlo en git para que +la alerta se apagara sola**. Medido en el aparato: hay **12** ControllerRevisions, el pod corre la +**10**, `currentRevision` apunta a la **4** y el deseado es la **12**. Con `updateStrategy: OnDelete` +ese campo no describe nada real, y el pod **sí** llevaba el `hostAliases` — en su `/etc/hosts`. + +### C-028 + +Cicatriz +2026-08-12: repuesto el token de ESO de `hermes`, **20 de 30 `ExternalSecret` seguían en +`SecretSyncedError`** y la lectura obvia era «no funcionó»; se estuvo a un paso de reiniciar ESO y de +reescribir la política. Lo que lo desmintió fue **la HORA del último error en el log: siete minutos +de silencio**. El campo contaba el ciclo anterior — su `refreshInterval` es de **una hora**. Forzando +el refresco de los treinta: **30/30 verdes**. + +### C-029 + +Cicatriz al revés, 2026-08-01, hecho +BIEN: vaciando de texto las pantallas de dos paneles, el peligro era llevarse **estado** junto con los +comentarios. En vez de capturas —que **no se pueden diffear**— se volcó **el texto de todas las +pantallas antes y después** en los dos aparatos, con un clasificador prosa/medida: **0 medidas +cambiadas**, y los únicos cambios fueron los seis textos que se querían mover. + +### C-030 + +Cicatriz 2026-08-13, y salió BIEN: una +sesión documentó el porqué de una perilla con comentarios `#`… **dentro de `spec:`**, o sea que +salen en el render. El gate de bytes se puso **rojo en los tres hubs vivos sin que cambiara un solo +valor**. Pasaron a `{{/* */}}` y volvieron los bytes exactos. Sus palabras: «el gate se ganó el +sueldo en el cambio que yo habría llamado cosmético». + +### C-031 + +Cicatriz `F12.1`, +2026-08-02: se eligió el `md5` de `ospfd.conf` como testigo de *«esto no ha cambiado»*, y el fichero +lo escribe un bucle sobre `pairs()` de Lua, que **no ordena**. El hash bailaba sin que cambiara una +sola línea ⇒ el testigo habría gritado en cada medida, y a la tercera nadie se lo cree. + +### C-032 + +Cicatriz +`E9`, 2026-08-03, y es la segunda vez en dos días: el `md5` de un `ospfd.conf` se movió, la sesión +pudo demostrar por reconstrucción que no era suya… pero **no pudo diffearlo**, porque había guardado +el hash y no el contenido normalizado. + +### C-033 + +Cicatriz `H24`, 2026-07-31: la ventana +del zombi no era de 10 s fijos, iba de **~0 a ~10 s** según dónde cayera el revoke dentro del +`sleep 10` de `pq-sync`; con la rotación de Rosenpass en 131 s, acertar era un **~8%**. Tres intentos +fallaron por 50 s, 3 s y 1 s. + +### C-034 + +Cicatriz `H16`, 2026-07-30, y es la **tercera** reincidencia de `H6` — +casillas rancias— tras el 26 y el 27 de julio. El modo de fallo nuevo: la casilla no se podía +contradecir **leyendo los docs**; hubo que entrar en el contenedor a comparar `sha256sum` contra +`git show HEAD:`. + +### C-035 + +Cicatriz 2026-08-03, y la cometió la orquestadora: dedujo que una +LAN estaba en la malla porque el fichero de opciones DHCP existía. Cierto con el código de hoy —que +solo lo escribe para las LAN de la malla— y **falso con el que corría cuando lo midió**, que lo +escribía **incondicionalmente y sin consultar el eje**. La existencia del fichero probaba justo lo +contrario: que el eje se ignoraba. + +### C-036 + +Cicatriz + 2026-08-06: `pq-secret.sh` estaba en **CRLF en el worktree** y así ni arranca —`set -uo + pipefail\r`—, o sea que con `core.autocrlf=true` un clon en Windows deja **todos** los bancos + muertos. El censo no lo vio porque medía —bien— sobre un `git archive` en LF: **la receta correcta + tapó el defecto que la rodeaba**. Se cosió con un `.gitattributes`. + +### C-037 + +Cicatriz 2026-09-01. Se destapó porque un `git diff` marcaba **48 líneas cambiadas** donde el cambio +real eran **13**, con líneas idénticas en `-` y `+`. Y el segundo intento también mintió: daba **9733 +CR en 268 líneas**, un número imposible **que sólo se ve si compruebas la aritmética**. + +### C-038 + +Cicatriz `H23`, 2026-07-31: `I1` decidió —bien— que re-admitir a un nodo +revocado es **«una autorización NUEVA del operador»**… y construyó solo la **negativa**. Medido en el +pod que corre: `POST /links/pair` da **403** permanente, `approve_pair` exige `pending`, y **ninguna +pantalla pinta una fila revocada** ⇒ **no hay botón que pulsar**. Hubo que tocar `status` en la base +de datos. Y lo que lo vuelve grave: el procedimiento documentado de `H21` dice **«revoca los edges +antes de renombrar un hub»** — seguirlo en el cliente dejaría sus sedes fuera **sin marcha atrás**. + +### C-039 + +Cicatriz 2026-07-31, cazada antes de +aplicar: `hubName` gobernaba también los **paths de Vault** — con `hermes.hub` el `trimSuffix "-hub"` +no recortaba nada y el hub habría ido a buscar su clave WireGuard y su **clave Rosenpass** —la que +la `D100` del hub prohíbe regenerar; era `F13·D10` hasta que el 2026-08-22 se renumeró al +contador del hub, precisamente porque el id chocaba con el del edge— a rutas inexistentes. La +sesión partió **identidad** de **nombre público** antes de tocar nada. + +### C-040 + +Cicatriz 2026-07-30: +el catálogo del MCP de build llevaba un CAVEAT diciendo que la suite del hub estaba +obsoleta —12/28 en rojo— y que por eso «el deploy se valida con `skip_tests`, bypass **auditado**». +Había dejado de ser cierto el **2026-07-24**: las 12 aserciones se reescribieron y la suite va a +**90 passed**. Seis días en los que la razón ya no existía y el permiso seguía escrito. + +### C-041 + +Cicatriz 2026-08-04: bajo una cabecera marcada ✅ sobrevivía un pendiente sobre una +carrera `revoke + enroll` **que `I1` había vuelto inconstruible** —los dos `db.delete` ya no +existen—, y su arreglo propuesto era *«un SELECT+DELETE atómico»*. Quien lo hubiera cogido de buena +fe habría **reintroducido exactamente lo que `I1` quitó**, que era el borrado de la fila y toda la +vulnerabilidad con él. + +### C-042 + +Cicatriz 2026-08-03, y la cazó la propia sesión al aplicar su propuesta, no la propuesta: al retirar +`BACKLOG-HERMES.md` —826 líneas, con el invariante de ids comprobado y cuadrado— quedaban **cuatro +ítems abiertos de la red del trabajo** que el borrado se habría llevado **en silencio**: excluir una +IP de la pool de MetalLB, identificar físicamente al okupa de un puerto de switch, renombrar un +address-object del firewall y un puerto de destino. Nada de eso tenía id; eran casillas. + +### C-043 + +Cicatriz `A20`, 2026-08-01: la `/32` que un hub se inventó al resolver una colisión no +se quedó ahí — el edge la adoptó (`A17`), la re-declaró al otro hub (`A18`), que la aceptó, y el +nombre del router acabó resolviendo a la dirección equivocada **por los dos caminos**. Cuanto mejor +funcionaba la réplica, más lejos llegaba el error. + +### C-044 + +Cicatriz 2026-08-28, y es la única del día que llegó a mover el orden de trabajo del usuario: un +aviso reclamaba un gesto urgente sobre la BIOS de un servidor —«la carga está armada»— y desplazó +cuatro asuntos. Un frente había medido **la conducta del SERVICIO** —un host declarado se sirve sin +menú, y el arranque por red instala solo a los 30 s— **y era cierto**. Nadie midió la **precondición**, +que es de **otro sujeto**: el orden de arranque de la **MÁQUINA**. Lo refutó el usuario en una frase: +para arrancar por red **hay que pulsar una tecla**; el disco ya era el primero. La conclusión +compuesta había viajado con fecha, contra-medidas y hasta un `User-Agent` —**todos los signos +externos de una medida**— y **tres registros la aceptaron sin pedirle la precondición**. + +### C-045 + +Dos frentes independientes el 2026-08-28, con casos +distintos. Uno: dos sesiones afirmaban cosas **opuestas** sobre «el log del motor» — y no era un +objeto, eran **dos**, uno por stdout **sin `User-Agent`** y otro dentro del mismo pod en formato +combinado; **ninguna se equivocaba sobre su fuente, faltaba nombrarla**, y lo destapó que una +intentara reproducir el testigo de la otra y no pudiera. + +### C-046 + +**(a)** un bloque de 14 líneas insertado +con `sed a\` entró **colapsado en UNA sola línea**; el testigo era `grep -c ` → **1**, +verde, con la forma destruida. El bueno era `git diff --numstat` (15) junto a `grep -c '^+>'` (14). +**(b)** filtrar un diff con `grep "^[+-][^+-]"` **oculta toda línea de lista Markdown** —una viñeta +empieza por `-` y da `+-`/`--`—: salió **diff vacío** sobre un fichero que sí había cambiado. En un +corpus que es casi todo viñetas, ese filtro **borra la mayoría de lo que buscas**. + +### C-047 + +Cuatro mutantes sobre el netplan real de un host. El +`autoinstall_schema` del controlador de red de subiquity pone `ethernets: {properties: {match: +MATCH}}` con `MATCH` llevando `additionalProperties: false`, y de ahí se afirmó que un `match` con +una clave de más sería rechazado. **Falso**: ese `match` cuelga **directamente de `ethernets`**, +profundidad donde netplan **no lo pone jamás**; el de verdad vive en `ethernets..match`, y ahí +el esquema **no mira**, porque `ethernets` no lleva `additionalProperties: false`. + +### C-048 + +`proyectos-3c`, sobre el arranque por red: +predijo **1 rojo** en su mutante y salió **0**. Su comprobación decía medir *«el servidor que ignora +el `Range`»* y en realidad pasaba por **el magic `CD001` ausente en unos bytes de relleno**. La +arregló con un fichero que **parece correcto a la profundidad equivocada** — literalmente `A13` en +otro traje. + +### C-049 + +Cicatriz 2026-09-02: **tres sesiones a la vez** leyeron *«el nodo conserva la ranura de recuperación +de LUKS»* como un agujero de seguridad, lo escalaron y llegó a la mesa de Xavier. Es la **definición +del estado previo**: esa ranura la retira el día 1, y a ese equipo el día 1 no se le ha aplicado. Lo +deshizo él en dos líneas: **«no se puede pretender que esté securizado antes de que se le aplique la +securización»**. Y el caso puro estaba delante: la máquina que la conservaba está **sin bastionar a +propósito**, porque es **la línea base contra la que enrojece la mitad roja de los gates** — pedirle +que no la tenga es pedirle que deje de servir para lo que existe. + +### C-050 + +Cicatriz 2026-09-02: se corrigió la ficha que decía `.50 = ESXi / .51 = iLO` —al revés— y se dio por +cerrado. Quedaba un **tercer** fichero diciéndolo mal **dos veces más**, y la peor **no era una +descripción sino un PROCEDIMIENTO**: «asignar `.50` al VMKNIC y `.51` al iLO». ⇒ ⭐ **Un dato malo en +una descripción se LEE; en un procedimiento se EJECUTA.** Lo cazó una pregunta de otra sesión — +**«¿cuál corregiste?»**—, que es comprobar el **sujeto** de un arreglo, no su existencia. + +### C-051 + +Cicatriz 2026-09-02: el banco de subiquity del motor de `hermes-infra` estaba commiteado con rutas +absolutas al **scratchpad de OTRA sesión** —un directorio con el UUID de una conversación que ya no +existe— más un `/mnt/c/.../sp2` de relleno. **Tenía casa en el repo y no arrancaba.** + +### C-052 + +Cicatriz 2026-09-02: al nodo IA le faltaba la ruta por defecto tras un corte. Se propuso reponerla +apuntando al **firewall nuestro**, que da salida a internet — y **la máquina es de otro equipo**, con +su gateway propia sin internet real. Lo paró Xavier diciendo **por qué** no la quería, y sólo +entonces se leyó el documento que lo explicaba. ⇒ ⭐ **La ausencia era real y la causa también, y aun +así el arreglo habría sido un cambio no autorizado en la máquina de un tercero.** + +### C-053 + +Cicatriz del motor de aprovisionamiento, cosecha 2026-08-15: `day1.mode` — dos modos producían **el mismo +artefacto**; y así llegó `day0.luks` a existir declarado y sin consumir, sin que nada se pusiera +rojo. + +### C-054 + +Cicatriz F11.11b, 2026-07-27: el test de +cableado recorría `app.routes` **en plano**, pero en esa versión de FastAPI los routers incluidos +van **anidados** → el recorrido veía 8 rutas y **ninguna** `/api/…`, así que **pasaba con el +endpoint abierto de par en par**. Se delató porque la mutación dio **1 rojo donde tenían que ser +2**. Ahora las rutas se descubren por el esquema OpenAPI. + +### C-055 + +F11.12, +2026-07-27: tal cual estaban, la primera mutación **reventaba el bloque entero** y escondía cuántas +aserciones habría tumbado — el número dejaba de ser medible justo cuando lo necesitabas. + +### C-056 + +2026-07-27: +una quinta mutación dio 0 donde se esperaban 2 — **el arnés avisó de que el `sed` no había casado**, +así que el cero quedó explicado en vez de pasar por bueno. + +### C-057 + +2026-08-13: una mutación apuntaba a `values-hermes.yaml` para +tocar la clase de Ingress — y esa instancia **no la declara, la toma del default** ⇒ no había nada +que mutar. El arnés dijo «mutación no aplicada» en vez de un `0 rojos` que se habría leído como +«esto no está cubierto», y la mutación se reapuntó al default, donde sí enrojece las tres. + +### C-058 + +2026-07-28, hub `I6`: la +mutación quitaba un `{% if %}` y dejaba su `{% endif %}` → la plantilla no compilaba, la suite moría +en el fixture y salían **31 `errors` y 0 `failed`**; el arnés leía solo `N failed` ⇒ **0 rojos**, +indistinguible de «este test no cubre nada», y por poco se tira una comprobación buena. + +### C-059 + +Misma sesión: la mutación puso `10.99.0.2` a +pelo… que era exactamente el valor contra el que afirmaba el test → **verde por coincidencia**, con +el número de rojos acertado y la identidad equivocada. Con `10.99.0.77` salieron 3. + +### C-060 + +Cicatriz 2026-08-05, construyendo el gate de +`R14`, y lo cazó la mutación —no el gate en verde— que es la única razón por la que se sabe:* +- ***casar por SUBCADENA y no por LÍNEA***: `grep -q 'port: 444'` salía **verde contra + `port: 4440`**, o sea que la guarda del puerto decía que sí a un valor que no era. Es el + `head -1` de `A16` en otra sintaxis: *leer por posición o por trozo, nunca por identidad*. + ⇒ ⭐ **Y su forma PEOR, medida el 2026-08-13: cuando las dos cadenas son valores LEGÍTIMOS del + sistema, la subcadena engaña en las DOS direcciones.** `nginx-inet` **contiene** `nginx`, y las + dos son clases de Ingress reales de instancias distintas ⇒ una guarda sin ancla `$` decía + `ok [hermes] … emiten nginx` **sobre un render que ponía `nginx-inet`**. Aquí el falso positivo no + es ruido: es *el valor de otro hub*. ⇒ Ancla siempre, y si puedes **compara la cadena exacta en + vez de buscarla** — el `pytest` de esa misma sesión aguantó justo por eso. +- ***`cmd | grep -q` bajo `set -o pipefail`***: `grep -q` sale al primer acierto y cierra la + tubería ⇒ **SIGPIPE al productor** ⇒ la tubería devuelve distinto de cero ⇒ **rojos + intermitentes**. Y lo grave no fue el caso nuevo: estaba **latente en cinco comprobaciones + preexistentes cuyo «ok» es la rama `else`** — o sea que llevaban tiempo pudiendo aprobar por el + motivo equivocado.* + +### C-061 + +Misma sesión: un helper `quiere_linea` definido 300 + líneas después de su primer uso ⇒ la cara **positiva** de esas comprobaciones no se ejecutaba y + **nadie se enteraba**. + +### C-062 + +Cicatriz `H19`, 2026-08-05: el banco de `pq-sync.sh` llevaba **ocho +días** con la base en `17 ok / 4 fallos`, porque `62707e1` retiró del chart la semilla PQ legacy +—tocó **cinco ficheros y no tocó el banco**— y cuatro casos quedaron afirmando sobre algo que ya no +existe. Con esa base, los «más rojos de los previstos» **no eran una cascada**: N2 hacía pasar un +rancio y N4 otro. Y el aviso que lo describía prescribía **re-derivar los conteos**, o sea maquillar +la avería — §6, *un pendiente rancio trae el arreglo equivocado*. + +### C-063 + +Misma +cicatriz, y es la mitad que asusta: `N1` era la **única** mutación en verde del banco… y lo era +**por coincidencia**. Sus dos rojos eran dos rancios, y **las dos aserciones que esa mutación existe +para romper salían VERDES** — el aviso colado por stdout subía el conjunto de 1 a 2, justo lo que se +esperaba. El número acertaba y la identidad estaba entera equivocada: no eran 4 de 5 mal, eran +**5 de 5**. + +### C-064 + +Cicatriz 2026-08-06, y salió bien **porque la predicción iba por +nombre**: al coser seis comprobaciones de `guards.sh` se esperaban **6 `ok`** y salieron **37**. Los +31 de sobra eran `quiere_fallo` —otra familia: lee `stderr` y afirma en positivo—. Con la +predicción hecha solo con el número, la conclusión habría sido «me faltan 31» y se habrían +«arreglado» **31 comprobaciones sanas**. + +### C-065 + +Cicatriz 2026-08-06, y apareció **al poner la base en +verde**, no antes: la mutación 4 de `pq-secret.sh` llevaba desde `R14` sin casar, porque `R14` movió +los volúmenes a `_helpers.tpl` y en `deployment.yaml` ya no queda ningún `items:`. Dos días de censo +no la vieron porque los dos rojos de la base la tapaban. + +### C-066 + +Cicatriz +2026-07-26: comprobar si `PUT /api/config/global` pedía credencial con `{"__probe__":1}` **vació la +Global Config** del hub y disparó el `write_zones()` — el hub dejó de servir sus tres estáticos +durante ~45 s. + +### C-067 + +Cicatriz F11.7, 2026-07-26: «Guardar cambios» no guardaba… y sí guardaba. `apply_default` +hacía `ifup lan` incondicional, y la br-lan **es la interfaz por la que se administra el panel** → +el `ifup` se llevaba el socket de **su propia respuesta**. El backend aplicaba y persistía, y se +quedaba sin poder contestar; en el navegador, `r.json()` reventaba y la promesa del handler moría +sin dueño. Silencio absoluto. + +### C-068 + +Cicatriz 2026-09-01: se recomienda **no tocar** el quórum de +almacenamiento esa noche, con números. El usuario decide **tocar**, y da su razón: **«el sitio caído +no depende de mí, no tengo control sobre él»**. ⇒ Eso **desmontó la premisa de la recomendación** —que +trataba la vuelta del sitio como una **certeza**— y **cambió el modelo de riesgo, no la conclusión**. +Sin la razón se habría aplicado lo mismo **creyendo otra cosa**. + +### C-069 + +Ejemplo del mismo día: se decide soltar un filtro de un +control, y la razón es «**puedo responder por mí, no por lo que hagan las demás personas**» ⇒ el sujeto +del control **no son las cuentas de hoy: son las que otro cree mañana**. Sin esa frase, el gesto es +correcto y **apunta a la cosa equivocada**. + +### C-070 + +Cicatriz 2026-09-01: con el quórum de almacenamiento a 2 de 3, se relaja la regla que impide colocar +un tercer testigo. El orquestador, para aplicar la colocación nueva, intenta **parar uno de los dos +que quedan** — y el sistema se lo **deniega** con «no quedarían suficientes». Como actualiza los +existentes **antes** de crear el tercero, **la operación se impide a sí misma**: cuatro reintentos, el +failover parado. Se desatascó reiniciando el orquestador, que al arrancar limpio pudo actualizar +primero **el testigo caído** —que no dispara la guarda porque ya está parado—. + +### C-071 + +Misma noche: la recomendación de **no tocar** se apoyaba en **«mañana se recompone solo»** — que +**presupone como CIERTO que el sitio caído vuelve mañana**. No lo era: **no dependía de quien decidía**, +no había acceso fuera de banda, y dependía de poder desplazarse. Se puso en la balanza un riesgo +improbable contra **algo tratado como certeza sin haberlo comprobado**: la comparación estaba viciada +de origen. Y el otro platillo decía *«de noche y al final de un día largo»* — **cuando el usuario +estaba despierto y delante**. + +### C-072 + +Cicatriz 2026-09-01: un electricista mete un pico de tensión, salta un diferencial y reinicia **un** +servidor. Un motor de base de datos que llevaba **173 días** corriendo su versión vieja **en memoria** +tira la imagen nueva al rearrancar y muere: los datos en disco eran de la **9.6**, la imagen de hoy la +**26.7**. **El defecto se plantó el día que se movió el tag; el corte sólo lo reveló.** + +### C-073 + +Cicatriz 2026-09-01: un cluster con `2+2+árbitro`, el árbitro en un **tercer** emplazamiento con +switch propio ⇒ sobre el papel, impecable. Medido por el `Designated Bridge` del root port: **ese +tercer sitio cuelga físicamente del switch del sitio A**, y su enlace redundante lleva **los dos +puertos caídos y sin transceptor** —diseñado y **nunca completado**—. ⇒ Apagar el sitio A **no se +lleva 2 nodos: se lleva 3**, y el quórum pasa de `3 de 5` a **`2 de 5`: se pierde**, en el plano de +control **y** en el almacenamiento. **No se degrada: se para.** + +### C-074 + +La misma operación se había hecho **una semana antes** y salió bien — +pero sobre el **lado contrario**, que era del que **no** colgaba el árbitro. **La asimetría era +invisible desde el éxito.** + +### C-075 + +Cicatriz 2026-08-30: una sesión de ejecución pregunta si puede quitar un campo de una plantilla +para implantar una decisión. La medida dice que **ese campo es obligatorio en el instalador ⇒ +quitarlo rompe TODAS las instalaciones**, en la validación, antes de tocar el disco. Se le contesta +**a ella y sólo a ella** — pero eso **invalida media decisión**, y la decisión la llevaba su +orquestadora, que **siguió planificando horas sobre una premisa ya sabida falsa**. Salió porque el +usuario preguntó «¿esto se lo reportaste a la orquestadora?». + +### C-076 + +Cicatriz del mismo día: un frente reporta que una plantilla de ejemplo +enseñaba una capa contra una decisión del usuario, y cede el sujeto. Se arregla y se empuja… y no se +avisa. El que lo reportó se queda con su aviso abierto, persiguiendo lo que ya estaba resuelto. + +### C-077 + +Cicatriz 2026-08-30, **dos veces el mismo día y en direcciones opuestas**: un frente avisa al relevo +de que cierta decisión seguía apoyada en una premisa falsa… **y ya estaba corregida y sustituida**, +por él mismo, la víspera. Y la superadmin repite ese mismo aviso al día siguiente **sin volver a +mirar**. Las dos veces lo cazó la sesión nueva, que era la única que **no daba el estado por sabido**. + +### C-078 + +Medido 2026-08-31: en un frente que entrega a un tercero, el entregable tenía medidas de las +familias construidas **hasta el 27-ago y ninguna posterior**. **No eran diez olvidos**: una familia se +daba por cerrada cuando el rol la aplicaba y el auditor la veía verde, y **el entregable no estaba en +ese ciclo** ⇒ cada familia nueva abría un hueco nuevo. Y en el mismo día, otro frente: la mitad de una +tarea **construida** y **su backlog sin saberlo**. + +### C-079 + +Medido el mismo día, en tres frentes y en el propio gobierno del árbol: un aviso decía que un banco +vivía en un scratchpad **del que ya había salido**; un pendiente declaraba certificados RSA que +**llevaban dos días siendo ECDSA**; y cuatro premisas del corpus raíz quedaron falsas **el día que el +árbol pasó a ser un repo git** — las cuatro por una mejora, ninguna por un fallo. + +### C-080 + +Y no es teórico: el propio linter mide **la copia sellada**, no lo que cada repo tiene de +más ⇒ **hoy un incremento es indistinguible de una deriva para el instrumento del árbol**. + +### C-081 + +Cicatriz 2026-08-31: una +orquestadora escribió **cuatro** raíles en su propio corpus creyéndolos suyos; **tres eran generales y +uno no**, y **ella no podía distinguirlos** — sólo ve su frente. Además, de los tres, uno se paró por +un motivo que ella no habría dado: **una ocurrencia no hace un raíl**. Y quien la paró **no fue un +gate: fue el usuario**. + +### C-082 + +Medido 2026-08-31: **tres instancias en una sola jornada**, en el mismo frente y todas ciertas —un +sujeto de prueba documentado en un directorio de evidencias y un script de banco · una deuda escrita +en el mensaje de un commit · una versión de herramienta medida cinco días antes, en un aviso, un +comentario del rol y la cabecera de una comprobación—. **Las tres las destapó otra sesión leyendo por +casualidad. Ninguna la cazó un gate.** Y en las tres, quien decidía llegó a proponer trabajo ya hecho +o a operar con un riesgo que no existía. + +### C-083 + +Cicatriz 2026-08-31: `clevis luks list` **no puede desmentir** la existencia de una ranura de +contraseña — devuelve `1: tpm2` **con una ranura y con dos**. Se comprobaba justamente si esa frase +seguía abriendo el disco. La respuesta la dio otro instrumento, `luksDump`, que **sí enumera todas +las ranuras**. + +### C-084 + +Cicatriz 2026-08-25→31: un aviso decía «el instalador no baja el seed» y nombraba a **subiquity**. +Quien pide las cuatro rutas y **valida la cadena TLS** es **`cloud-init`**; subiquity **consume** lo +que cloud-init ya le entregó. El aviso era **útil y accionable durante seis días** —el síntoma que +describía es el que se ve— y aun así habría mandado a depurar el componente equivocado. Lo escribió +un frente, **lo heredó otro al citarlo**, y lo corrigió el segundo al medirlo. + +### C-085 + +Cicatriz 2026-08-03, y es `A1` en versión nueva: `dns-malla.md` corrigió el 2026-08-01 su +modelo de resolución en un bloque «⛔ CORREGIDO»… y **dejó vivo el diagrama de arriba**, que dibujaba +la cadena vieja. Nadie lee el párrafo de enmienda: se lee **el diagrama**. Dos días después ese +diagrama era lo que Xavier tenía en la cabeza al describir el diseño, lo que la orquestadora escribió +como **premisa autoritativa** de un encargo, y lo que obligó a la sesión receptora a **parar**. El +modelo derogado sobrevivió a su propia derogación y volvió a entrar por la puerta grande. + +### C-086 + +Cicatriz +2026-07-27: dos sesiones concluyeron «esta máquina no tiene credenciales para `git.manabo.org`» y +dejaron un chart de producción sin aterrizar. Era falso — cinco pushes ese mismo día desde ese mismo +PC. El mismo día, un push a `git.c2et.com` falló con `Recv failure: Connection was reset` y **entró +al segundo intento**. + +### C-087 + +Cicatriz cosecha 2026-08-15: «el +camino Rocky» eran **dos** caminos y solo se había medido uno; la frase viajó por tres documentos +antes de que alguien la careara. + +### C-088 + +Cicatriz 2026-08-18: la orquestadora editó así la ficha `I11` +durante toda una sesión y la rompió **dos veces** — un borrado se llevó la línea ⛔ *«que nadie +construya un des-aplicar»* (**el raíl que su propio encargo repetía**) y una inserción metió `I11.9` +**dentro de la viñeta de `I11.8`**, cuya cola quedó leyéndose como suya. Lo cazó la sesión siguiente +al ir a trabajar sobre la ficha; la orquestadora había «verificado» cada edición con un `grep` del +marcador nuevo, que **siempre casa** aunque el resto haya quedado hecho trizas. + +### C-089 + +Censo 2026-09-02: **cinco párrafos partidos en la matriz**. El más viejo llevaba +**tres días** repartido a los **27 repos** —lo partió, con ironía perfecta, el commit que añadía +«**la puerta hay que escribirla de modo que ATE, no que informe**»—; **dos eran de esa misma tarde y +de quien escribe esto**; y uno estaba **en la cabecera del documento**, la primera frase que lee toda +sesión. **Nadie vio ninguno**, porque una cola varada **se lee como el principio de otro párrafo**: +el texto no se rompe, se **recompone mal** y sigue siendo texto. + +### C-090 + +Cicatriz 2026-08-06, censo de los bancos +del chart del hub: `aip-sync.sh` y `lo-reconcile.sh` son **dos drivers del mismo directorio que hacen +lo mismo** —extraer un bloque del render, mandarlo a un host y ejecutarlo como root—. El 2026-08-02 +`aip-sync.sh` se comió una extracción rota y se cosió bien: `awk`, anclas **afirmadas** y una +aserción negativa. A su hermano no lo miró nadie. Cuatro días después, en `mode: loadBalancer` el +ancla de cierre de `lo-reconcile.sh` **ya no existe** —`R14` quitó el reconciliador a propósito— +pero la de apertura sí, así que el rango del `sed` corre hasta el final del render: **893 líneas +donde son 36**, con los `ExternalSecret` dentro. Su única guarda es `[ -s ]`, que 893 líneas pasan +de sobra, y lo siguiente de ese script es `scp` + **`sudo bash`**. + +### C-091 + +Cicatriz Hermes 2026-07-26: el sidecar Rosenpass corriendo en el +chart del hub y el backlog del hub dándolo por pendiente, con un plan que nunca ocurrió; y un fix +del hub —`F13.0-c`— que solo existía en el backlog del edge. + +### C-092 + +Cicatriz 2026-08-30: un frente reporta a otro un testigo falso —correcto, aceptado— y **añade una +solución**: que cierto endpoint publique la fecha además del identificador. La dueña lo mide: el +endpoint devuelve el identificador **pelado**, la comparación del agente es **de cadena completa**, y +una línea de más hace que **no vuelva a coincidir nunca** ⇒ cada nodo **se re-descarga su árbol en +cada disparo, para siempre**. + +### C-093 + +Cicatriz 2026-08-18: la orquestadora documentó cada +hallazgo de dos días en los dos sitios; la ficha `I11` llegó a **464 líneas** y Xavier dijo que +**había dejado de poder leer el backlog**. La bitácora ya lo tenía todo: lo del backlog era una +copia pura. + +### C-094 + +Cicatriz 2026-08-31: un aviso pedía que el testigo de sincronía apareciera **donde mira quien +depura**. La línea se construyó, es correcta, nombra los dos identificadores y no miente… pero la +escribe un script que va a **un fichero de log distinto** del que recibe el resumen de la ejecución. +⇒ **El testigo existe y no viaja pegado a lo que se lee** — o sea, el gesto que el aviso existía para +quitar **sigue ahí**. Y lo destapó **una sola pregunta**: «¿dónde queda lo que imprime?». + +### C-095 + +Mismo caso: la sesión que construyó **ya había medido** que el testigo caía en otro log **y lo dejó +escrito, honesta y explícitamente… en el mensaje del commit**. Una deuda **medida, dicha y aun así +invisible desde el sitio donde se decide**. La encontró su relevo **por casualidad**, mirando el +`git log` para copiar la convención de mensajes. + +### C-096 + +Cicatriz 2026-08-22, `D6` de Xavier: **18 decisiones distintas +llamadas `D1`** en un solo `backlog.md` — y cuatro fallos de una semana que salen de ahí: un +**resumen** que gobernó en lugar de la decisión, un «precio aceptado» que Xavier nunca pensó, dos +ids que colisionaban, y una sustitución con las **dos versiones vivas** a 90 líneas de distancia. +En sus palabras, para qué sirve la capa: «así tienes todo lo peligroso en un único documento». + +### C-097 + +Tres ocurrencias en cuatro días, la misma forma y sitios distintos: un `workflows/metodo.md` que +llevaba **6 días** siendo máster de facto porque el repartidor no alcanzaba ese árbol y nadie era su +dueño; una entrada de buzón escrita **explícitamente** como copia de seguridad *«que se retira +cuando su dueña la coloque»* —y que sólo se retiró porque lo llevaba escrito dentro—; y un borrador +de propuesta que **su propia autora vio convertirse en derivada** en el momento de aprobarse la +entrega, con dos cambios pendientes en la mano. Las tres se vieron; la primera, seis días tarde. + +### C-098 + +Medido 2026-08-29: arrancar una sesión de un frente maduro cuesta **1,40 MB ≈ 400 k +tokens** antes de hacer nada —`CLAUDE.md` raíz + la constitución + su corpus—, o sea **media ventana +de contexto gastada en leer**. Y ahí está la causa de que las sesiones se agoten y haya que +relevarlas: **el coste de arranque se paga en la moneda con la que se trabaja**. + +### C-099 + +Cicatriz 2026-08-30: una sesión metió tres fechas, un `mtime` y **una cita literal del usuario** +dentro de un anexo firmado — **conociendo el principio**, que se lo habían dicho horas antes. Y el +usuario, al verlo: **«me paso el día matando historiales»** ⇒ no es un desliz de una sesión, es la +norma del sitio. + +### C-100 + +Cicatriz 2026-08-29: el `AVISOS.md` de un frente activo tenía **1.905 caracteres de +media por línea** y una de **8.196** — y es **el fichero que se lee primero**. + +### C-101 + +En un solo frente había **cuatro** afirmando bloqueos sobre trabajo cerrado la semana anterior —y +el propio corpus tenía escrito el patrón, aplicado a un fichero ajeno y nunca a sí mismo. + +### C-102 + +Medido el 2026-08-29 sobre el semáforo del árbol: **14 filas no empezaban por marca de cierre y +sólo 3 estaban realmente vivas** ⇒ **11 falsos positivos**; y **dos empezaban en «viva» y acababan en +«CERRADA»**. Un censo por el principio las cuenta vivas para siempre; uno que busque «CERRADA», las +cuenta cerradas. + +### C-103 + +Cicatriz 2026-08-29, verificando 22 filas antes de purgarlas: el primer barrido +por ids —`D12`, `A37`, `A41`…— **las dio las 22 por buenas**. Sólo el careo por **cifra** —`102 s`, +`8 h 14 m`, `suite 1621`— separó las que de verdad tenían su relato fuera. + +### C-104 + +Cicatriz 2026-08-29: una orquestadora leyó el workflow de ordenación **entero**, tomó las medidas y +**empezó a hacerlo ella**. Lo correcto era pedir que se abriera esa sesión y pasarle el encargo. La +paró el usuario: «estaba esperando a ver si me sacabas un mensaje para que te abriera una sesión». + +### C-105 + +Cicatriz 2026-07-27: el multi-hub existe para **sobrevivir a la caída de un +hub** — y hasta v2.1.34, **añadir el segundo tumbaba el túnel del primero ~40 s**, porque el +endpoint del hub nuevo es un **nombre** y, si no resolvía, `netifd` rehacía la interfaz WG entera. +La propiedad que existía para dar resiliencia **te costaba un hub al activarla**. Llevaba ahí desde +que existe el multi-hub, y solo apareció cuando por primera vez hubo **dos hubs vivos en el mismo +edge**. + +### C-106 + +`A18`, 2026-07-31: con la identidad del edge divergiendo entre los dos + hubs, el nombre **seguía respondiendo 3/3** porque el tráfico rodeaba por el otro router de campo. + Con ese aparato apagado, el hub habría perdido al edge **del todo**. + +### C-107 + +`P12`, 2026-08-02: un edge sin binario de Rosenpass se bajaba la + pubkey del hub —**524.160 B**— cada 20 s y por cada hub. En el router grande (6,8 GB) no se nota + **jamás**; en un GL-AR300M eran **1 MB sobre 212 KB libres**. Lo hizo visible el aparato pequeño, + no una búsqueda. + +### C-108 + +Cinco cicatrices en tres días, + 2026-07-27/30: los seis `postconf` del smtp-relay vivían en un contenedor · el + `argocd-image-updater` falla `unauthorized` con una **credencial cacheada**, y lo único que frenaba + que reescribiera un pin bueno era esa avería —**reiniciarlo ARMA el riesgo**— · `kernel-engine` + corre un digest **que ya no está en el registro**: 62 días arriba y un reinicio lo deja en + `ImagePullBackOff`. + +### C-109 + +Cicatriz 2026-07-31: el +MCP de build llevaba **21 h** con el config anterior al renombrado de los hubs; el fix se commiteó a +las 00:49, pero **editar un ConfigMap no rueda el Deployment** ⇒ sondeaba un nombre hoy `NXDOMAIN` ⇒ +el `verify` no respondía ⇒ **auto-rollback que deshizo un pin bueno**. + +### C-110 + +Cicatriz 2026-08-12, y la cadena empieza en +una recomendación de la orquestadora: se propuso **quitar el root permanente de Vault** —correcto +como higiene— y se ejecutó rotándolo con `generate-root` y revocando el viejo. En Vault los tokens +son **hijos de quien los crea**, y `revoke` del padre **borra el árbol**: 14 minutos después el +`ClusterSecretStore` del cluster `hermes` pasaba a `InvalidProviderConfig` y **30 `ExternalSecret` +dejaban de refrescarse** — entre ellos la base de datos, el SMTP y el Twilio de una aplicación en +producción. + +### C-111 + +F11.14: chronyd moría con `CAP_SYS_TIME not present`. Añadir la capacidad era el reflejo —y +le habría dado a un servicio en red la potestad de mover el reloj del NODO, y con ella TLS, +certificados y etcd. La respuesta era `-x`: **un contenedor que SIRVE hora no es uno que PONE +hora**. + +### C-112 + +Cicatriz `E6`, 2026-08-01: el reconciliador +decidía la política de resolución a partir de `lease_rows()` —la proyección **para publicar**, que no +lleva `nat`—. «No viene `nat`» se leyó como «ninguna LAN tiene salida», así que la negativa se +encendía **en cada vuelta, con el NAT puesto**. Y el test propio lo consagraba. + +### C-113 + +Cicatriz F11.14, 2026-07-27, cazada **en el render, antes de existir**: el +`bindaddress` de chrony salía vacío porque `serviceLoopback` lo inyecta el ApplicationSet y no está +en ningún `values`. Un `bindaddress` a secas no da error — chronyd vuelve a su default y escucha en +**todas** las direcciones, IP pública incluida: un **reflector de amplificación NTP** abierto a +internet. + +### C-114 + +Cicatriz del motor de aprovisionamiento, cosecha 2026-08-15: un hueco de identidad rellenado con «lo de +siempre» sirvió un **kickstart destructivo** con un **HTTP 200** impecable. + +### C-115 + +Cicatriz `V11b`: el careo `routes-*.txt` ↔ `superficie.md` del +chart del hub buscaba `repos/infrarouter/…`, carpeta renombrada la +2026-08-15. Se saltó en **todas** las corridas de cuatro días, y no en silencio: llevaba un +`warnings.warn` **además** del `pytest.skip`, puesto a propósito citando este §8, con el comentario +«*esto no se salta en silencio — se salta diciéndolo*». **Y lo decía. Y nadie lo leyó.** Mientras +tanto las cuatro capturas se quedaron atrás de una capa entera —la CRL— sin que el gate pudiera +enrojecer. + +### C-116 + +Cicatriz 2026-08-30: un frente llevaba **16 avisos `C25`** —mensajes de commit— en rojo **varios +días**, y **ninguna de las cuatro sesiones que pasaron por él lo dijo**, teniendo el propio Método +escrito delante: «si sale rojo, no lo apagues: arréglalo o dilo». Lo cazó la quinta, **el día de +llegar**, precisamente porque **no estaba acostumbrada a verlo**. + +### C-117 + +Mismo censo: `probe-guard-hub.js` llevaba los mismos cuatro +días roto —falla ruidoso, `MODULE_NOT_FOUND`— y nadie vio el rojo porque no lo corre ningún gate; +y `pq-sync.sh` lleva escrito de su puño que **su línea base estuvo ocho días en rojo** «porque +este banco no lo corre ningún gate». Un banco mudo y un banco muerto se leen igual desde fuera. + +### C-118 + +Cicatriz 2026-07-26: +la orquestadora de redes escribió toda una racha de prompts sin decirlo — se asumían fríos porque +empezaban con el ritual de lecturas, y nadie lo había hecho explícito. + +### C-119 + +Cicatriz 2026-08-29: se re-estampó el Método en el repo de un frente que trabaja **otra persona**, +sin mirar antes qué había hecho. No rompió nada —la copia quedó íntegra y su trabajo intacto— pero +**se le cambió el ritual de arranque sin decírselo**, y su frente **no tiene sesión en el canal a la +que avisar**. ⇒ **El corpus manda, pero alguien tiene que avisar de que cambió**: un cambio de método +que llega por `git pull` y nadie anuncia es exactamente lo que este mismo raíl dice que no +funciona. + +### C-120 + +Lo procedimental —cómo se abre un mensaje, qué viaja por el canal y qué no, quién avisa a quién al +acabar— es **procedimiento, no principio**: vive en la capa `workflows/`, como el resto de la +estructura de sesión. + +### C-121 + +Cicatriz 2026-08-28, y son **cuatro** el mismo día, en +tres frentes: «`E2.1` está bloqueado esperando un hierro prestado» —falso—; «esas dos filas son de sesiones +muertas» —una era de una sesión **viva y escribiendo en ella**—; «tiene 5 commits sin empujar» —ya +estaban empujados—; y una alarma de hierro que **movió el orden de la cola del usuario**. **Los +cuatro iban en el bloque afirmativo, ninguno marcado como inferencia.** + +### C-122 + +Cicatriz 2026-08-29/30, y va en los dos sentidos, que es lo que la hace raíl: una sesión mandó a +otra dos datos **marcados como medidos** y los dos eran falsos —un recuento de líneas de una sección +del que se afirmó **el contenido**, y un encaje de workflow que la medida desmentía—; la receptora +los comprobó **a pesar de la marca** y los corrigió. Al día siguiente, en sentido contrario, la +receptora entregó un conteo propio que sí era falso —una ruta relativa sin resolver— y lo cazó la +otra **por no reproducirlo**. Un corte entero se habría apoyado en él. + +### C-123 + +Cicatriz 2026-08-28: la superadmin informó todo el día citando nombres de sesión, todos +correctos, hasta que él dijo «yo no veo eso». Es `§1` —**la herramienta de diagnóstico no ve lo +mismo que el consumidor**— aplicada a hablar con quien te dirige: **darle el identificador que TÚ +usas y él no puede resolver es información inútil con aspecto de precisión**, y es peor que +omitirla. + +### C-124 + +Cicatriz 2026-08-28: +la superadmin mandó un encargo, recibió a continuación un «sigo esperando el encargo», concluyó que +no había llegado y lo reenvió. **Sí había llegado**: entró mientras la otra sesión ejecutaba el turno +en el que escribía su aviso. Lo corrigió la propia destinataria, con su transcripción delante, y +**evitó que una hipótesis no demostrada —«una sesión parada no drena su cola»— entrara en esta +constitución**. Esa hipótesis **sigue sin medir y por eso no se escribe aquí**. + +### C-125 + +**(a)** la sesión del incidente midió +«`srvfkvm02`/`03`: no reiniciar ni drenar, **desplegar encima es seguro**»; se retransmitió como +**tres ⛔ tajantes** y otro frente descartó trabajo por ellas. **(b)** dijo de pasada *«un arranque +tras 18 h es cuando esas bombas explotan»*; se retransmitió como «lo más importante del día». +**Medido después: cero.** La alarma la **retiró su propia autora**. + +### C-126 + +Un parte decía «`A10` NO +bloquea, probado» refiriéndose al del motor; el `A10` de `poniente` es **la bomba de la PKI, viva y +🟠**. Quien leyera el parte junto a ese corpus **daría por descartada una bomba abierta** — y el parte +iba a **tres frentes a la vez**. Lo cazó la dueña del otro `A10`, no un gate. + +### C-127 + +Escrita por separado **por las dos partes tras morderla cada una por su lado**, +que es lo que la manda aquí: se difundió un congelado de Ceph, se **corrigió su redacción** y **no se +avisó cuando murió**; la orquestadora que lo recibió construyó encima un plan entero sobre un muro +levantado hacía dos horas. **Corregir la redacción de una restricción no es retirarla cuando +muere.** + +### C-128 + +Cicatriz F11.9, 2026-07-26: la Global Config del hub estaba +muerta río abajo —su payload alimentaba a un agente borrado tres semanas antes— y al ir a +arreglarla apareció que también lo estaba río arriba: el handler `POST` estaba **registrado como +`GET`**, así que el formulario devolvía **405** y «Guardar» no había guardado **nunca**. Cada mitad +tapaba a la otra: nadie echaba en falta un dato que nadie podía introducir. + +### C-129 + +Cicatriz 2026-08-29: una sesión de ordenación reportó como ⛔ una contraseña en claro en tres +documentos, **con razón por lo que veía** — y era del banco de pruebas. Nada que arreglar salvo lo +que el corpus no decía. + +### C-130 + +Los dos casos, el 2026-09-02: un satélite midió que su `pull` no traía + nada porque ya lo tenía; y `MOT` rechazó un `push` porque **un compañero había empujado tres + commits** desde otro sitio. + +### C-131 + +Cicatriz 2026-08-29, y la encontró la sesión de ejecución que + purgaba el semáforo mientras la superadmin le editaba la cabecera: **paró antes de commitear** + porque vio en el `diff` 21 líneas que no eran suyas. + +### C-132 + +Cicatriz 2026-08-30: la orquestadora de un frente corre **exactamente esta puerta**, con el raíl + escrito **el día anterior y citándola a ella**. Le sale `filas tocadas: 3 · ¿mía?: 1` esperando + `1 y 1`… **y sigue adelante**. El commit se lleva dentro la fila de otra sesión, bajo un mensaje + que hablaba de otra cosa. Nada se perdió; la atribución, sí. + +### C-133 + +Cicatriz 2026-09-01: un gate de la matriz corrido **desde otro repo** avisaba «la MATRIZ ha + cambiado» **sin nombrarla**, justo después de listar los incrementos **de ese otro repo**. Una sesión + lo leyó como suyo y **estuvo a punto de revertir trabajo bueno**; se salvó **yendo a leer el código + del gate** para ver qué entra en la huella. + +### C-134 + +Cicatriz 2026-08-30, y con la puerta puesta: una sesión encadena la comprobación y el + `git commit` **en la misma orden**. Sale `4 filas tocadas · 2 de 4 mías` —debía parar— pero para + cuando lee la salida **el commit ya está hecho**, y publica el bloque a medio escribir de otra + sesión bajo un mensaje que hablaba de otra cosa. + +### C-135 + +Caso 2026-08-30, dos prescripciones hermanas y sólo una atable: **«una fila viva lleva bloque + `EN VUELO`»** es puramente sintáctico —está el marcador o no está—, así que **se ata** y pasa de + «acuérdate» a «no puedes empujar sin ponerlo». Su hermana, **«ninguna sesión se cierra con fila + viva»**, **NO se ata a propósito**: el fichero **no puede saber si el dueño respira** —medido: + `ListAgents` pasó de 13 sesiones a 6 en dos minutos, y una de 12 h apareció como recién + arrancada—, así que un gate que lo adivinara daría **rojos crónicos**, o sea la cara (b) de la + familia de arriba. Queda como **criterio humano, deliberadamente**. + +### C-136 + +Corrección de la propia sesión que lo frenó, 2026-08-29, y lo dijo + contra su propio mérito: «no fue virtud, fue orden — medí el fichero dos veces porque los números + de la primera no cuadraban con los de la segunda, y por eso miré el `diff`; no porque tuviera + presente el raíl». + +### C-137 + +Cicatriz 2026-08-29, y la cometió la superadmin **el mismo día que escribió este raíl**: al + re-estampar el Método en nueve repos, uno de los `push` arrastró un commit ajeno que esperaba una + decisión. Tenía **tres avisos delante** —el de otra orquestadora esa mañana, su propia fila del + semáforo, y su palabra dada— y **corrió la puerta en su repo pero no en los ajenos**: aplicó el + control donde no hacía falta y lo omitió donde sí. **Un raíl recién escrito no protege a quien + acaba de escribirlo.** + +### C-138 + +y se escribe + así a propósito: en este árbol ya se borró un workflow por llevar «los commits van siempre, + automáticos, sin confirmar» — **una autorización sin fecha ni motivo es un agujero, no un + permiso** + +### C-139 + +Estaban escritos como «un segundo agujero», «un + cuarto», «un sexto», «un tercer filo»… **numerados por acumulación y contradiciéndose entre sí**; + renumerados el 2026-09-02. Ninguno se ha quitado: cada uno es un modo de fallo distinto con su + cicatriz. + +### C-140 + +2026-08-30: se commitean **dos** ficheros nombrados uno a uno; entran **tres**. El + tercero era el trabajo *staged* de otra sesión, que sobrevivió íntegro pero quedó publicado **bajo + un mensaje que hablaba de otra cosa**, perdiendo la explicación que esa sesión estaba escribiendo. + ⭐ **El asunto de ese commit era, literalmente, «en este árbol git no distingue sesiones».** Lo + cometió mientras lo escribía, con su propia puerta imprimiendo `ficheros=3` habiendo nombrado 2. + +### C-141 + +2026-08-31: una sesión corre la puerta del índice —limpia—, empuja **un fichero suyo** y publica + **tres commits ajenos** que esperaban entre el remoto y `HEAD`. Lo dio por hecho **porque veinte + minutos antes estaba a cero**: un árbol compartido cambia por debajo entre dos pushes tuyos porque + el otro **está trabajando**, que es lo normal y no la excepción. + +### C-142 + +2026-08-31: un `--amend --no-edit` reescribió el commit de otra sesión ya empujado. **Su + único testigo fue un `push` rechazado por no-fast-forward** — o sea **un fallo que puede no llegar a + producirse**; sin él, la reescritura se habría publicado. + +### C-143 + +2026-09-02: la superadmin avisó a un satélite de «haz `pull`, que hay commits de hace minutos». + Eran ciertos y **ya los tenía**. Lo midió el satélite: los tres rangos, vacíos. + +### C-144 + +2026-09-01: una sesión anexó + **168 líneas** de su bitácora **al repo de otro frente**; y el mismo desliz le hizo **leer los + avisos del repo equivocado**, numerando su hallazgo `A12` donde iban por `A5`: **un identificador + inventado que habría quedado escrito**. + +### C-145 + +2026-09-02: **cuatro colisiones sobre el mismo + fichero en un día, LAS CUATRO CON LAS TRES PUERTAS PUESTAS.** Una sesión publicó la fila de otra · + un `awk` por número de línea borró una fila viva **40 minutos** · otra partió una fila en dos · y a + la cuarta, **entre dos comandos consecutivos**, el índice se le llenó de un fichero ajeno **y su + edición del working tree desapareció**; al commitear, «nothing to commit»: **ya lo había publicado + un tercero**. Cero pérdidas y la atribución cruzada cuatro veces. + +### C-146 + +Medido: el gate de los mensajes de commit +selló en el punto de adopción del Método **con historia mala por detrás**, y necesitó **excepciones +nominales**; el del trailer sella **el día que llega** ⇒ **cero excepciones, por construcción**. + +### C-147 + +`securizacion`, 2026-09-02: cinco comprobaciones publicaban un **dictamen correcto** con +`sh: 1: raiz: not found` **dentro del dato crudo**, y ya commiteado. El gate miraba el dictamen; +**el crudo no lo miraba nadie**. El veredicto era cierto y su evidencia estaba rota. + +### C-148 + +`securizacion`, 2026-09-02: la misma sesión que **por la mañana arregló el clasificador de +credenciales** lo **reescribió mal a mano ocho horas después**, al medir otra familia. La función +existía, era correcta y estaba a mano. **El hueco no estaba en el código: estaba en el criterio que +uno lleva en la cabeza.** + +### C-149 + +`proyectos-3c`, 2026-09-02, refutando un raíl escrito ese mismo día: *«se localiza por contenido, +nunca por número de línea»* **no basta**. Su localizador estaba **anclado a contenido** y aun así su +`perl` a medida **casó de más y siguió en silencio**. *(Y otra sesión editó el mismo fichero con un +`awk` anclado y funcionó **por suerte**, no por diseño.)* + +### C-150 + +`hermes-infra`, 2026-09-03, medido en TRES repos a la vez: la orquestadora corre +`git log origin/main..HEAD`, ve un commit **ajeno** sin empujar y **lo declara en su mensaje**, como +manda el raíl. Commitea. Vuelve a mirar: **el commit ajeno ya no está** — alguien lo empujó **entre +sus dos comprobaciones**. Su `push` responde **«Everything up-to-date»** y `ls-remote` confirma que +**sus commits ya estaban publicados sin que ella los subiera**; en un tercer repo el remoto tenía su +commit **PRE-`--amend`**, publicado mientras ella corregía el mensaje. ⇒ Su aviso *«me llevo un +commit ajeno»* **era cierto al escribirlo y falso al publicarse**. Y lo detectó **por un síntoma +raro** —un `push` que no subía nada— **no por un control**: si el push hubiera tenido algo que +subir, no se entera. **Quien empujaba era el bucle de reparto de la superadmin**, que empuja **todo +repo con commits pendientes**, sean suyos o no. + +### C-151 + +`hermes-infra`, 2026-09-03: `systemd-networkd-wait-online` consumía **el timeout entero de 120 s en +cada arranque, para siempre** — seis SFP en el bond y cable en dos. **No deja `failed`, no da error, +el nodo arranca y la red funciona: sólo tarda.** Lo vio **Xavier mirando la consola**, no una sonda. +⚠️ Y ya estaba resuelto **y escrito** —`optional: true`, de su puño, en el netplan de `styx` +(`asgard/doc/styx-integracion.md:126`)—: vivía en **un ejemplo**, no en el mecanismo, así que no +llegó a la plantilla y **se pagó entero otra vez**. + +### C-152 + +`securizacion` (ejecución), 2026-09-03, sobre su propio caso: **`git commit -- ` publica el +contenido del árbol de trabajo EN EL MOMENTO DEL COMMIT, no el que verificaste antes.** Su ventana +fue de **90 segundos**, y **se la fabricó ella misma escribiendo el mensaje del commit** entre la +verificación y el commit. ⇒ El pathspec la protege del **índice**; no la protege del **árbol**. + +### C-153 + +Este PC, medido por `securizacion` (ejecución) el 2026-09-03: **`grep -c $'\r'` miente en las DOS +direcciones** sobre ficheros CRLF, y **el `sed` de Git Bash y el de WSL no dan el mismo resultado** +sobre el mismo fichero — 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**. El árbitro que sí +declara su semántica es **`git ls-files --eol`**. + +### C-154 + +La superadmin, 2026-09-03, y lo destapó la orquestadora de `securizacion` en el barrido de la +mañana: `cicatrices.md` —**el artefacto nuevo más importante del día**— llegó a los 27 repos y +**ninguno lo versionaba**. La causa: el reparto commiteaba con `git commit -m … -- .metodo/`, y **un +commit con pathspec sólo recoge cambios de ficheros YA TRACKEADOS**. El fichero estaba en disco, se +leía, `C40` lo careaba **y salía verde en los 27** — comprobando un fichero que **el repo no tenía**. + diff --git a/.metodo/metodo.md b/.metodo/metodo.md index 1106f13..6401eb9 100644 --- a/.metodo/metodo.md +++ b/.metodo/metodo.md @@ -420,6 +420,12 @@ 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`)* @@ -1803,6 +1809,26 @@ pega tal cual. **`git commit -- `** (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 "…" -- `; ponerlo después lo convierte en pathspec y el commit muere. + ⚠️ **Y `git commit -- ` 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 -- ` 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 ` 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 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.