diff --git a/.metodo/CHECKSUMS b/.metodo/CHECKSUMS index a8f86eb..c5a1fcf 100644 --- a/.metodo/CHECKSUMS +++ b/.metodo/CHECKSUMS @@ -1,4 +1,4 @@ 71298d7ef2ab107ca52e288ae425b040abeb81777dcf96926b363e911a97ebcd metodo.md -31c2f9df46cfb73d1413c65428cbca5356fbcb04cbd319fac8a3a71e8fd00576 bin/metodo +896a92488d149cd16be26cf126e32db58591f640c463ef25a7badd56d71ee25d bin/metodo f89b71bdf31028b05075636c1763c964e379bc37a00e0357d1c23a4dd19c09aa workflows/README.md -2470f7013f209c8c1f34eaea9368e9fa25f256eedd08eeb06b6c5358d12131d6 workflows/comunicacion-entre-sesiones.md +6871c5f29642ccec3e60109324de1e5bab8fa5ee73792360d85277bde3323aea workflows/comunicacion-entre-sesiones.md diff --git a/.metodo/bin/metodo b/.metodo/bin/metodo index 58563ea..7b58ff8 100644 --- a/.metodo/bin/metodo +++ b/.metodo/bin/metodo @@ -34,6 +34,16 @@ _hash() { # ⛔ EXCEPCIÓN, y es de fondo: `sesiones-activas.md` **NO se vendoriza**. No es un documento: es un # objeto VIVO y compartido —el semáforo del árbol—, y 27 copias de un semáforo son exactamente lo # contrario de un semáforo. Vive sólo en la matriz, con su historial. +# ⛔ UNA SOLA LISTA. Antes había dos —el censo excluía dos ficheros y los bucles de copia +# sólo uno— y no fallaba: simplemente `sesion-ordenacion-docs.md` VIAJABA a los 27 repos +# contra su propio comentario, y encima FUERA de CHECKSUMS, así que su deriva no la medía +# nadie. La colisión de nombre que la exclusión existe para evitar llegó a estar VIVA. +# (Medido 2026-08-30 por una sesión de ejecución. Dos listas que dicen lo mismo son una +# fuente doble: §7 aplicado a la propia herramienta.) +_wf_no_viaja() { # ¿este workflow NO se vendoriza? — la ÚNICA lista + case "$1" in sesiones-activas.md|sesion-ordenacion-docs.md) return 0;; esac + return 1 +} _vendored_files() { printf '%s\n' "metodo.md" "bin/metodo" local f b @@ -46,7 +56,7 @@ _vendored_files() { # en el mismo repo, que es el riesgo que el árbol tiene escrito: «una sesión puede abrir el que # no era y creer que su ritual de arranque es ése». Exclusión TEMPORAL: cae cuando el duplicado # se resuelva (fusionar es un MERGE, no una limpieza — sus versiones han derivado). - case "$b" in sesiones-activas.md|sesion-ordenacion-docs.md) continue;; esac + _wf_no_viaja "$b" && continue printf 'workflows/%s\n' "$b" done } @@ -258,7 +268,10 @@ check_ids() { check_headings() { hdr "encabezados sin marca de estado (C16)" local f hits=0 line - for f in "$ROOT"/*.md "$ROOT"/doc/*.md; do + # ⛔ `workflows/` entró el 2026-08-30: sus enlaces NO los miraba nadie, y por eso + # `comunicacion-entre-sesiones.md` llevaba 2 enlaces ROTOS en la matriz Y en los 27 repos. + # Un fichero cuyo único trabajo es LLEVAR al Método apuntaba a un sitio que no existe. + for f in "$ROOT"/*.md "$ROOT"/doc/*.md "$ROOT"/workflows/*.md; do [ -f "$f" ] || continue # Un encabezado ## no lleva emoji de ESTADO (el estado vive en las casillas). # ⚠️ se excluye a propósito: en un título es "bandera/aviso", no estado de sección. @@ -274,7 +287,10 @@ check_headings() { check_links() { hdr "enlaces locales resuelven (integridad)" local f dir tgt found=0 broken=0 - for f in "$ROOT"/*.md "$ROOT"/doc/*.md; do + # ⛔ `workflows/` entró el 2026-08-30: sus enlaces NO los miraba nadie, y por eso + # `comunicacion-entre-sesiones.md` llevaba 2 enlaces ROTOS en la matriz Y en los 27 repos. + # Un fichero cuyo único trabajo es LLEVAR al Método apuntaba a un sitio que no existe. + for f in "$ROOT"/*.md "$ROOT"/doc/*.md "$ROOT"/workflows/*.md; do [ -f "$f" ] || continue dir=$(dirname "$f") # process substitution (< <(...)) para que el while corra en ESTE shell y bad() cuente @@ -776,9 +792,15 @@ cmd_init() { mkdir -p "$md/workflows" for _wf in "$SELF_ROOT"/workflows/*.md; do [ -e "$_wf" ] || continue - [ "$(basename "$_wf")" = "sesiones-activas.md" ] && continue + _wf_no_viaja "$(basename "$_wf")" && continue cp "$_wf" "$md/workflows/$(basename "$_wf")" done + # Y RETIRA lo que ya no debe estar: una exclusión que sólo deja de copiar no limpia lo + # que un bucle anterior ya depositó. Sin esto, el fichero mal vendorizado sobrevive. + for _old in "$md"/workflows/*.md; do + [ -e "$_old" ] || continue + _wf_no_viaja "$(basename "$_old")" && rm -f "$_old" + done local mver adopt mver=$(grep -E '^version:' "$SELF_ROOT/.metodo/VERSION" 2>/dev/null | sed 's/version:[[:space:]]*//') adopt=$(git -C "$tgt" rev-parse HEAD 2>/dev/null || echo "") # marca de adopción brownfield @@ -816,9 +838,15 @@ cmd_update() { mkdir -p "$md/workflows" for _wf in "$SELF_ROOT"/workflows/*.md; do [ -e "$_wf" ] || continue - [ "$(basename "$_wf")" = "sesiones-activas.md" ] && continue + _wf_no_viaja "$(basename "$_wf")" && continue cp "$_wf" "$md/workflows/$(basename "$_wf")" done + # Y RETIRA lo que ya no debe estar: una exclusión que sólo deja de copiar no limpia lo + # que un bucle anterior ya depositó. Sin esto, el fichero mal vendorizado sobrevive. + for _old in "$md"/workflows/*.md; do + [ -e "$_old" ] || continue + _wf_no_viaja "$(basename "$_old")" && rm -f "$_old" + done local mver adopt mver=$(grep -E '^version:' "$SELF_ROOT/.metodo/VERSION" 2>/dev/null | sed 's/version:[[:space:]]*//') adopt=$(grep -E '^adopted_commit:' "$md/VERSION" 2>/dev/null | sed 's/adopted_commit:[[:space:]]*//') # se preserva diff --git a/.metodo/workflows/comunicacion-entre-sesiones.md b/.metodo/workflows/comunicacion-entre-sesiones.md index 8554e46..be7c39d 100644 --- a/.metodo/workflows/comunicacion-entre-sesiones.md +++ b/.metodo/workflows/comunicacion-entre-sesiones.md @@ -199,7 +199,7 @@ el corpus, no. ### 3. El semáforo pasa de pasivo a activo — y NO se sustituye Antes de un commit que toque ficheros de una **fila viva ajena** de -[`repos/metodo/workflows/sesiones-activas.md`](../repos/metodo/workflows/sesiones-activas.md), se **pregunta por el canal** en vez de esperar o +`repos/metodo/workflows/sesiones-activas.md` *(ruta del árbol: el semáforo NO viaja, así que en un repo clonado solo no existe — y eso es correcto)*, se **pregunta por el canal** en vez de esperar o pisar. ⛔ **El fichero sigue siendo la fuente**: un mensaje muere con su sesión, una fila sobrevive. El canal acelera el arbitraje; no lo reemplaza. @@ -347,7 +347,9 @@ al subagente **le escribe el prompt la orquestadora y lo dispara en el mismo tur hacer que se presente sola** —`R0`, el saludo invertido— y **sale mejor, porque conserva las dos puertas en vez de quitar una**. -### 🟠 Sigue ABIERTA: `ListAgents` no publica **rol ni proyecto** +### `ListAgents` no publica **rol ni proyecto** +**Estado: 🟠 abierta** *(el estado va aquí y no en el título — un encabezado con estado caduca y nadie +lo actualiza; `C16`)*. Sólo **nombre, modo y hora de arranque**, y el nombre **lo pone el sistema**. Mientras siga así, **`R0` y la puerta de `R1` son lo único que hay** para saber con quién estás hablando. @@ -355,7 +357,7 @@ Sólo **nombre, modo y hora de arranque**, y el nombre **lo pone el sistema**. M ## Dónde vive cada mitad - El **principio** (frío/caliente, quién verifica) → `§9` del Método - ([`repos/metodo/metodo.md`](../repos/metodo/metodo.md), la matriz — ⚰️ la copia de esta carpeta se + ([`repos/metodo/metodo.md`](../metodo.md), la matriz — ⚰️ la copia de esta carpeta se retiró el 2026-08-28; si trabajas dentro de un repo, la tuya es su `.metodo/metodo.md`). - El **procedimiento** (esta página) → aquí, y **a prueba**. -- El **semáforo** → [`repos/metodo/workflows/sesiones-activas.md`](../repos/metodo/workflows/sesiones-activas.md), que sigue siendo la fuente. +- El **semáforo** → `repos/metodo/workflows/sesiones-activas.md` *(ruta del árbol: el semáforo NO viaja, así que en un repo clonado solo no existe — y eso es correcto)*, que sigue siendo la fuente. diff --git a/.metodo/workflows/sesion-ordenacion-docs.md b/.metodo/workflows/sesion-ordenacion-docs.md deleted file mode 100644 index 13dae1f..0000000 --- a/.metodo/workflows/sesion-ordenacion-docs.md +++ /dev/null @@ -1,558 +0,0 @@ -# Workflow — sesión de ORDENACIÓN DE DOCS - -## ⭐ Las CUATRO técnicas que hacen esto auditable *(1-3 destiladas de la pasada del 2026-07-29; la 4 del 2026-08-18)* - -**1. El invariante de identificadores — cuéntalos ANTES y DESPUÉS.** - -```bash -grep -oE '\b(F[0-9]+\.-?[0-9]+[a-z]?|P[0-9]+|I[0-9]+|Q[0-9]+|R[0-9]+|G[0-9]+|H[0-9]+|A[0-9]+|D[0-9]+)\b' \ - | sort -u | wc -l -``` - -No es burocracia: en esa pasada **cazó nueve pérdidas reales** en tres barridos distintos, dos de -ellas (`F11·D10`/`F11·D11` de `hermes-hub`) cuya ausencia habría dejado un salto de numeración inexplicable en la Fase 11. -⛔ **Contarlos solo al final no sirve**: no distingue *«no estaba»* de *«lo he tirado»*. Si falta -alguno se dice **cuál y por qué**, uno a uno — puede ser legítimo, pero se justifica en singular. -⚠️ El `-?` del patrón es obligatorio, o **deja fuera los `F12.-1`/`F12.-2`**: ítems reales, y uno de -ellos bloqueado por una decisión del usuario. - -**2. Comprueba el DESTINO antes de vaciar el origen.** El relato se mueve a la bitácora **con su -fecha real**, nunca con la de hoy — una bitácora es cronológica y meter un hallazgo del 25 bajo el -29 la rompe. ⭐ Y casi siempre **ya está allí**, porque las sesiones escriben en los dos sitios: -saberlo antes convierte la pasada en *«borrar y dejar puntero»*, que es el caso barato — así se -quitaron **1.767 líneas sin que temblara la mano**. - -> ⛔ **Y el instrumento con el que compruebas el destino te va a mentir si es LITERAL.** *(1ª -> ocurrencia en `securizacion`, 2026-08-29.)* El careo por huella literal de los avisos cerrados -> contra las otras capas dio **0 de 172 presentes**. El número era cierto y **su lectura ancha era -> falsa**: buscando por **concepto**, los sujetos estaban todos (`troceo` ×8, `proxy-body-size` ×4, -> `Cumplimiento.sh` ×15). **Un `grep -F` mide coincidencia de REDACCIÓN, no presencia del hecho** — -> y quien escribió la bitácora no copió: contó con sus palabras. -> ⇒ **El instrumento bueno para *«¿tiene destino?»* es otro**: *¿la otra capa NOMBRA este id?* Ahí -> salió **38 de 40**, que es el caso barato («borrar y dejar puntero»); sólo los **2** sin destino -> hubo que mover. ⭐ El literal **sí** vale para lo contrario —**verificar que el museo quedó -> verbatim**—: tras mover, el mismo careo dio **76/76** y un segundo instrumento independiente -> (tokens duros entre backticks) **287/287**. Ahí la coincidencia literal es exactamente lo que se -> quiere probar. -> ⚠️ **Un 0 absoluto o un 100 % absoluto son señal de defecto del instrumento hasta demostrar lo -> contrario.** Antes de creerte cualquiera de los dos: **control positivo** —saca una huella del -> propio destino y búscala— y comprueba **tres a mano, por concepto**. - -**3. Comprueba el balance de `
`** — `grep -c ''`. -*(Cicatriz: el `AVISOS.md` del hub tenía uno abierto y nunca cerrado, así que **todo lo que venía -detrás quedaba colapsado** en cualquier visor que respete el HTML. Invisible, y en el fichero cuyo -trabajo es leerse el primero. No es un fallo de contenido: es contenido que **no se muestra**.)* - -⛔ **Y cuéntalos POR FICHERO ADEMÁS DE POR CORPUS: son dos preguntas distintas y ninguna cubre a la -otra.** *(1ª ocurrencia en `securizacion`, 2026-08-29 — lo cazó la orquestadora verificando por su -cuenta, no la sesión que hizo la pasada.)* El invariante sobre el **corpus entero** dio -`C.x.y-nn` **164 → 164, cero perdidos** — cierto, y era lo que había que probar. Contado sólo sobre -`AVISOS`+`backlog`+`decisiones` sale **54 → 53**: `C.2.1-59` deja de aparecer ahí *(benigno: sobrevive -en el censo, que es su casa, y lo que se fue era una **cita de patrón** —«con la forma de -`C.2.1-59`»—, no un requisito)*. ⇒ **Un invariante de corpus es CIEGO a que un documento concreto -deje de nombrar algo**; el de fichero no prueba que no se haya perdido nada. **Cuesta lo mismo -sacar las dos**, y sólo juntas responden *«no se perdió nada»* **y** *«este documento ya no dice X»*. - -⇒ Y el corolario de las tres: **una pasada de ordenación se entrega con NÚMEROS**, no con «he -reordenado». El lector tiene que poder creerse que no se ha perdido nada sin releer 3.000 líneas. - -⛔ **ANTES QUE NADA, LA UNIDAD: se mide en TOKENS, no en LÍNEAS** *(Xavier, 2026-08-29 — y lo cazó -porque los recortes de este workflow **no le cuadraban con el alivio que producían**)*. -Una línea de **8.196 caracteres** y una de **70** cuentan igual al contar líneas, y en estos corpus -eso **no es una anomalía: es la norma** —un `AVISOS.md` real tiene **1.905 caracteres de media por -línea**, el semáforo **928** con filas de **9.004**, y la constitución **79**—. ⇒ **Dos documentos con -las mismas líneas pueden costar veinte veces distinto**, y por eso un recorte medido en líneas -puede no bajar el coste de leerlo. -⇒ **Proxy práctico**: `wc -c` y dividir entre **~3,5**. No hace falta un tokenizador; hace falta -**dejar de contar líneas**. -⚠️ **Todos los números de este documento están en LÍNEAS** —se escribieron antes de esta corrección— -así que **se leen como historia, no como umbral**. Lo que NO cambia es el criterio de abajo: **la -distribución sigue mandando sobre el promedio**; sólo cambia qué se distribuye. - -**4. Mide la DISTRIBUCIÓN de líneas por ítem, nunca el promedio.** *(Añadido 2026-08-18.)* - -```bash -awk '/^- \[.\] \*\*`|^- \*\*`D[0-9]+`/{if(n)print len; n=1; len=0} {len++}' \ - | sort -n | awk '{a[NR]=$1} END{print "mediana:",a[int(NR/2)], "p90:",a[int(NR*0.9)], "máx:",a[NR]}' -``` - -⭐ **Por qué el promedio engaña, medido en el backlog del hub ese día**: promedio **21** líneas por -ítem —que suena uniforme y llevó a la orquestadora a proponer *«ordenarlo entero, son 3.319 -líneas»*— pero **mediana 6**, p90 **49** y cola por encima de **100**. ⇒ *La mayoría del documento -estaba sano.* El trabajo no era ordenar 3.319 líneas: era **sacarle el relato a la docena de ítems -que lo llevaban pegado**, que es exactamente lo que ya manda §*«las DECISIONES se quedan, la -EVIDENCIA se va»*. La distribución **localiza** dónde aplicar esa regla; no la sustituye. - -⛔ **Y la cicatriz de ese mismo día, que es sobre el método y no sobre el documento**: la -orquestadora afirmó que la regla de proporcionalidad *«no estaba escrita en ningún sitio»* tras un -`grep` con sus propios términos (`proporci|ratio|por decisi`). **Estaba, desde el 2026-08-01**, bajo -*«El SUELO de una ficha no es un número de líneas: es su número de decisiones»*. ⇒ **Un `grep` que no -encuentra algo prueba que tus palabras no casan, no que el contenido falte** — y es la tercera vez -en dos días que la misma forma (medir estrecho, afirmar ancho) produce una conclusión falsa. Antes de -escribir *«esto no está»*, busca por el **concepto** en el índice de secciones, no por tu redacción. - -> ⛔ **ESTE fichero es el MÁSTER transversal, y vive en el repo `metodo`** *(movido aquí el -> 2026-08-29: hasta ese día estaba en el árbol de trabajo, que **no es un repo git** — sin -> historial, sin dueño y sin gate. Es el mismo agujero por el que la copia del Método pasó seis días -> derivada, y por el que **55 líneas de método escritas ese mismo día estuvieron sin versionar**.)* -> -> ⚠️ **Y la etiqueta anterior estaba INVERTIDA — se corrige aquí, no debajo.** Decía *«adaptado de -> `Solidaria`, allí es **canónico**»*, y **era cierto cuando se escribió** el 2026-07-26: allí nació, -> con 3 ocurrencias. **Dejó de serlo sin que nadie lo releyera**: este fichero acumuló cinco -> ocurrencias más y pasó a **540 líneas**, mientras mandaba al lector a uno de **89**. *Una anotación -> con fecha de caducidad implícita se vuelve falsa y nadie la relee* — con el agravante de que -> **el que declaraba canónico al otro era el que no tenía marcha atrás**. -> ⇒ **Qué es cada uno, que es lo que faltaba**: **aquí** vive la práctica transversal (8 principios, -> 4 técnicas, las cicatrices de **ocho** ocurrencias). En -> [`repos/Solidaria/workflows/`](../../Solidaria/workflows/sesion-ordenacion-docs.md) vive **el suyo** -> —el **origen**, y hoy una versión corta adaptada a su contexto—, que **sigue siendo el que manda -> en ese repo** y viaja con él. **No son copias que hayan derivado: son dos documentos con ámbitos -> distintos**… y **el mismo nombre**, que es un riesgo por sí solo: *una sesión puede abrir el que no -> era*. Por eso este **NO se vendoriza** hasta que ese duplicado se resuelva, y resolverlo es un -> **MERGE**, no una limpieza. -> -> **Estado: ADOPTADO 2026-07-26.** Los 8 principios de abajo nacieron allí, con -> sus cicatrices. **Lo que cambia aquí está en §"El CORTE A ESQUEMA"** y no es un detalle: -> en estos proyectos se conserva la **ESTRUCTURA** de fases, y su contenido CERRADO colapsa a una línea. - -Aplica a cualquier backlog de este árbol: Hermes (edge + hub), migración del cluster, MOT. - - -## Qué es (y qué no) - -**Mantenimiento del CORPUS de docs — no producción.** Es el *refactor* periódico de la -documentación: la producción es transversal (cada sesión documenta), esto es su poda. **No toca -código, no despliega, no configura infraestructura.** Entrega una **PROPUESTA para REVISIÓN** del -lector (Xavier): es su corpus, no es un deploy. - -⚠️ **Sesión ÚNICA sobre el árbol.** Reescribe memoria compartida que todas las sesiones leen → que -no corra otra tocando docs del mismo repo a la vez. **Comprobar antes** qué otras sesiones están -vivas y en qué repo escriben (p. ej. una sesión de mcp-edge escribiendo en -`Panel-Teltonika/doc/mcp-edge-contrato.md`). - -> ⚠️ **Son documentos VIVOS → optimiza para REHACERSE fácil, no para la perfección.** Un backlog se -> reescribe a menudo; uno bueno y fácil de reescribir vale más que uno perfecto y frágil. **No -> sobre-pulir**: si te descubres en la 5ª iteración de un matiz, has pasado el punto útil. - -## La cicatriz que la trae aquí (2026-07-26) - -`Panel-Teltonika/doc/backlog.md` = **2.729 líneas**, de las cuales **584 son cabecera**: 11 bloques -«Última actualización» **apilados por PREPEND**, creciendo hacia arriba. Efecto medido: la decisión -cerrada de la Fase 11 (*"FQDN = hostname + `dns_suffix`", "zona plana, sin namespacing"*, línea -1805) quedó enterrada, y ocho días después una sesión de ejecución escribió en la línea 1880 su -propia «DECISIÓN CERRADA» diciendo lo contrario. **Nadie la desobedeció: nadie la vio.** - -Lección: *un backlog que mezcla estado, diseño y relato deja de proteger sus propias decisiones a -partir de cierto tamaño.* El tamaño no es estético — es el fallo. - -## ⛔ El CORTE A ESQUEMA: la estructura de fases se queda, su contenido cerrado colapsa - -⚰️ **SUSTITUYE (2026-08-23, Xavier) a la regla del 2026-07-26 «en Hermes las FASES no se aplanan».** -Aquélla decía: *«una fase de Hermes es un cuerpo de trabajo con decisiones de diseño propias, y esas -decisiones son exactamente lo que no se puede perder ⇒ se corta por CAPAS dentro de la fase, no -quitando fases»*. -⛔ **Su motivo murió, y por eso se sustituye en vez de enmendarse debajo**: las decisiones de diseño -**vivían dentro del backlog**, y desde `D6` (2026-08-22) viven en **`doc/decisiones.md`**. Cuando el -suelo de una ficha dejó de pagarse en el backlog, la regla que lo protegía se quedó sin premisa. -*(Registrada como decisión del repo — en `hermes-edge` es `Corpus·D107`, con dueño, fecha y testigo. -Cada repo que la adopte registra la suya: una regla de árbol no sustituye a la decisión del lector -de ese corpus.)* - -**La forma nueva:** - -- **La ESTRUCTURA se queda**: cabeceras de fase, **su orden actual** (aunque sea histórico y raro — la - Fase 8 del edge vive después de la 14) y las épicas. Reordenar o refundir sigue siendo **del - lector**, y sigue sin hacerse sin decirlo. -- **Una fase entera cerrada = UNA línea.** Ni ficha queda. -- **Un ítem cerrado = UNA línea**: id · enunciado · ✅ fecha · **puntero**. -- **Un ítem abierto = UNA línea**: id · enunciado · **estado o bloqueo**. Su desarrollo largo, si lo - tiene, al **doc de diseño** con puntero. -- **Las `D` siguen sin recortarse** — pero **su suelo ya no se paga aquí**: en el backlog queda el - **enunciado + id calificado** y el cuerpo vive en `decisiones.md`. - -⛔ **Y aquí está la parte que cuesta, medida en la 1ª ocurrencia (edge, 2026-08-23): el veredicto NO -cabe en la línea, y no está en la bitácora.** El careo frase a frase dio **265 de 307** afirmaciones -marcadas (⛔ ⭐ ⚠️ ⚰️) **sin copia en ninguna otra capa del corpus**. No son medidas —ésas sí estaban en -la bitácora, por fecha—: son **veredictos y fronteras** (*«esto NO se construyó y por qué»*, *«esta -premisa era falsa»*, *«esto no se puede colapsar»*, *«el testigo que no se puede fingir»*). -⇒ **El corte NO se puede ejecutar sin moverlas antes.** La forma que funcionó: una sección **§ museo** -en la entrada de bitácora **del día de la pasada**, con los **párrafos originales verbatim, agrupados -por la ficha de la que salieron**, y cada línea del backlog apuntando allí por su ficha. -⚠️ **Y hay que decirlo en el informe**: el **corpus no encoge** —el backlog sí (edge: 3.182 → 893 -líneas, 261 KB → 62 KB)—. Lo que se compra es que el documento que hay que **leer para trabajar** -vuelva a ser legible; el museo queda donde no estorba y **con fecha**. - -⛔ **Y el borde por el que CORTAS no es el borde por el que compara el careo: un detector de «fin de -ficha» se come lo que viene detrás.** *(1ª ocurrencia en `securizacion`, 2026-08-29.)* Un detector -razonable —*«la ficha acaba en la siguiente línea que empieza por `- `»*— se llevó por delante un -bloque `>` de **17 líneas** que era una **nota de sección**, no parte del ítem. ⇒ **El bloque de una -ficha son sus SUB-VIÑETAS INDENTADAS**, y nada más: para en la primera línea que no empieza por -espacios. ⭐ Lo cazó **el propio documento**, no el instrumento: la línea 78 de esa nota decía -*«un corte a ciegas de este bloque perdería…»*. **Léete lo que vas a borrar antes de borrarlo, aunque -tengas un script** — el script hace verdad el *verbatim*, no el criterio. - -⛔ **El filtro del museo se calcula contra el backlog FINAL, no contra un borrador.** Cicatriz del -mismo día: se filtró contra una versión intermedia y **una frase se perdió** —quedaba en el backlog -de entonces y se cortó después—; la cazó el careo, no la vista. ⇒ **Filtrar es el ÚLTIMO paso, y -después se vuelve a carear.** - -⭐ **Y el museo es VERBATIM, literalmente.** Al reponer esa frase se reescribió *«…NO reprodujo, y se -dice: …»* en vez de *«…NO reprodujo: …»*, y el careo la siguió dando por perdida — con razón: el -testigo es la coincidencia literal. **Si te descubres mejorando la redacción al mover, no estás -moviendo: estás reescribiendo, y el careo deja de valer.** - -### ⭐ La 2ª ocurrencia del corte (hub, 2026-08-23): cinco cosas que la 1ª no podía saber - -**1. ⛔ Cuánto del backlog vive SÓLO ahí es POR REPO, y puede ser el 100 %.** En el edge fueron **265 -de 307**; en el hub, **406 de 406** (y **401 de 406** midiendo con huella corta, por si la larga era -demasiado estricta). ⇒ **Mide el careo ANTES de prometer nada**: con 406/406 el museo sale **más -grande que el backlog que lo sustituye** (2.880 líneas frente a 1.227), y eso hay que decirlo en la -propuesta, no descubrirlo a mitad. - -**2. ⛔ El PREÁMBULO del backlog es una sección más.** Trocear por `## ` deja fuera todo lo anterior al -primer encabezado — y ahí vivían la leyenda, la colisión del prefijo `G` y la medida de las *13 -cabeceras de 63*. **Un hueco silencioso del careo**: el instrumento decía «0 perdidas» sobre un sujeto -que no incluía la cabecera. Se cazó porque quedaban 6 afirmaciones sin casa y las 6 eran de allí. - -**3. ⛔ La huella del careo se corta en el BORDE DE SU BLOQUE, no a N caracteres a ciegas.** Una huella -que arrastra el principio del bloque siguiente fabrica pérdidas que no lo son: el bloque de al lado se -fue a otra capa y la frase está entera en la suya. Fabricó **11 falsas pérdidas de 17** en la primera -pasada del hub. ⇒ Y una afirmación se da por presente **también** si su **bloque entero** está en el -corpus, que es el caso barato y el fuerte. - -**4. ⭐ El museo lo EXTRAE UN SCRIPT, y eso no es comodidad: es lo que hace verdad el «verbatim».** La -1ª ocurrencia dejó escrito *«si te descubres mejorando la redacción al mover, estás reescribiendo»* — -una advertencia a la mano. Un extractor **quita la mano**: filtra bloque a bloque contra el backlog -final y copia byte a byte. Contención **0 perdidas de 406** a la primera pasada útil, con un segundo -instrumento independiente (**1.165 tokens duros entre backticks, 0 perdidos**) que mide otra cosa. - -**5. ⛔ Un encabezado retirado se CITA (`> ### …`), no se re-declara.** Copiar los `### ` del backlog -tal cual al museo **muda el aviso `C16` de `metodo check` del backlog a la bitácora** — el contador no -drena, sólo cambia de fichero, y la bitácora hereda en su índice secciones que no son suyas. -Prefijarlos con `> ` deja el texto **byte a byte** (el careo sigue valiendo) y los devuelve a lo que -son: una cita. Medido: `126 → 123` avisos, en vez de `126 → 126`. - -⚠️ **Y una trampa de la propia regla de citar ids**: al colapsar una línea hay que **calificar** los -`Dn` desnudos, y calificar obliga a **saber de quién es la decisión**. En el hub estuvo a punto de -escribirse `E4·D12` — no existe: ese `D12` es **del edge**. ⇒ *Cualificar es donde se ve que no lo -sabías; si no lo sabes, déjalo desnudo y dilo.* - -⛔ **El ÍNDICE del museo es la línea que hay que negociar con el lector, y se declara aparte.** El hub -entregó **1.227** líneas contra un suelo medido de **~1.000**: la diferencia son los 68 punteros -*«veredictos y fronteras (…)»* con una frase diciendo **qué** guarda cada ficha. Sin ellos el backlog -manda al lector a 2.880 líneas de museo sin saber si hay algo que le sirva; con ellos el backlog no -llega a su suelo. **Es una decisión del lector — se propone con las dos cifras, no se toma.** - - -### El SUELO real de un backlog así, con su aritmética - -⛔ **«≤ 400 líneas» no es alcanzable conservando la estructura, y conviene saber por qué antes de -prometerlo.** Medido en el edge tras el corte (**893** líneas): - -| Concepto | Líneas | ¿Se puede recortar? | -|---|---|---| -| 43 cabeceras `##` + sus separadores | ~86 | no sin **refundir fases** — decisión del lector | -| 43 objetivos, a una o dos líneas | ~86 | no: es para qué existe la fase | -| ~115 enunciados de `D` (una por decisión) | ~115 | ⛔ no: es el suelo, y `D6` sólo mudó el **cuerpo** | -| 62 ítems (36 `[x]` · 14 `[ ]` · 12 `[~]`) | ~330 | los cerrados ya están al mínimo; los abiertos **llevan su bloqueo**, que es estado | -| cabecera + leyenda + tabla de Estado + tabla de bugs | ~140 | la de Estado es *«la que el lector usa»* | - -⇒ **El suelo con 43 secciones ronda las 700–900 líneas.** Bajar de ahí exige **agrupar fases** -(p. ej. «Fases 1–4, 6, 9, 10 — el transporte y el panel, cerrados»), y eso **cambia el modelo mental -del proyecto ⇒ lo decide el lector**, nunca la sesión de ordenación. **Se propone; no se toma.** - -### Lo que esta regla NO deroga - -- *«Las `D` no se recortan nunca»* — sigue, con su cuerpo en `decisiones.md`. -- *«El suelo de una ficha es su número de decisiones, no un número de líneas»* — sigue, y es - justamente lo que hace que la aritmética de arriba dé lo que da. -- *«Las fronteras las confirma el LECTOR»* — sigue, y ahora **manda más**: refundir fases es la única - palanca que queda para bajar del suelo. -- *«Mide en CARACTERES, o al menos en las dos»* (2026-08-22) — sigue. En el edge: **261.079 → 61.849 - caracteres**, o sea **−76 %**, contra **−72 %** en líneas. - -⚠️ **Y una lectura de la distribución que hay que hacer bien**: tras el corte la **mediana por ítem -SUBIÓ** (6 → 12 líneas) mientras el **p90 bajó** (45 → 19) y el **máximo se hundió** (182 → 38). No es -un empeoramiento: es que **62 ítems sustituyen a 169**, así que cada línea superviviente concentra lo -de varias. **La cola es lo que se mide; la mediana, aquí, no dice lo que parece.** - -## Las tres capas - -| Capa | Qué es | Dónde va | -|---|---|---| -| **La fase** | objetivo · **decisiones cerradas (`D1`, `D2`…)** · ítems `[x]`/`[ ]` · punteros | **backlog** — ver la regla de tamaño | -| **El diseño** | el porqué largo, alternativas descartadas, mecanismos, contratos | **doc de diseño** del frente (`mesh-dns-edge.md`, `transport-spec.md`, `test-suite.md`, `mcp-edge-contrato.md`…) | -| **El relato** | qué se midió, en qué device, qué versión, los ⛔ hallazgos, las mutaciones, los hitos | **`doc/bitacora.md`** | - -**Regla de tamaño — NO es "N líneas por fase"** *(afinado en la 1ª ocurrencia fuera de Solidaria).* -Un número por fase se pelea con la realidad: las fases muertas caben en 15 líneas y las vivas -necesitan 60–70 solo para sus `D`. La regla que de verdad funciona: - -- **Las `D` no se recortan nunca.** Son lo irrecuperable. -- **Los ítems `[x]` de una fase cerrada, a UNA línea** (el detalle está en la bitácora). -- El total sale de ahí y es defendible. *(Referencia real: el backlog del edge quedó en **658** - líneas desde 2.731, y no sobraba.)* -- ⚠️ **Podar puede AUMENTAR el total, y no es un fracaso — dilo en el informe.** *(2ª ocurrencia: el - backlog del hub subió 17 líneas porque se podaron 65 y se añadieron 62 de estructura pedida - —leyenda + fase nueva—. Sin explicarlo, un número que sube se lee como que la pasada falló.)* - Da siempre **las dos cifras**: lo cortado y lo añadido, por separado. Y recuerda que **el corpus - crece porque el trabajo crece**: una pasada compra espacio, no detiene la marea. - -**El ORDEN DE TRABAJO importa** *(mismo origen)*: verificar el diagnóstico → mapear encabezados → -leer entero → inspeccionar los destinos → **escribir la bitácora PRIMERO** → y solo entonces podar -el backlog. Es el principio 2 aplicado: **escribir el destino antes de vaciar el origen** quita el -miedo a borrar, porque el texto ya está en su sitio. Al revés se poda con la mano temblando. - -**La bitácora crece por ABAJO** (append literal al final, cronológico ascendente). Es un log -append-only: se escribe por el final y **no se reordena**. Si te encuentras la entrada más reciente -arriba del todo, alguien prependió → reubícala al final. *(El prepend es la causa medida de la -cicatriz de arriba.)* - -## Los tres trabajos (y por qué el segundo va PARTIDO EN DOS) - -- **A · Podar y reordenar.** Un doc dejó de poder leerse: la historia hecha → puntero a la bitácora, - lo vivo se queda. Es lo de las tres capas de arriba. -- **B1 · Inventariar y MARCAR la vigencia.** Recorrer **todos** los docs y clasificarlos: - **vigente** · **desfasado** (banner arriba diciendo **qué** concretamente y **desde qué fase o - commit**, ⛔ **sin arreglarlo**) · **muerto** (se retira; su historia con valor, a la bitácora). - Es **triaje**, y lo hace esta sesión. -- **B2 · Realinear.** Corregir lo marcado. **Otra sesión, y con acceso al CÓDIGO o al DEVICE.** -- **C · Afinar los workflows** con las cicatrices del periodo. LEAN: solo lo que evita recurrencia. - -🔑 **Por qué B1 y B2 no son la misma sesión** *(2ª ocurrencia, 2026-07-27)*: si quien descubre el -desfase lo arregla, lo arregla **leyendo otro doc** — y eso es *literalmente* el mecanismo de la -regresión de `D1` en Hermes. Además B daba por sabido **cuál** doc miente, que es justo lo que nadie -sabía: `mesh-dns.md` llevó un día describiendo el motor de DNS equivocado y solo se supo porque una -sesión lo anotó de pasada. **El inventario es lo que hace segura la corrección.** - -⚠️ **Y si lo marcado es MUCHO, abre una fase para B2** en el backlog (12 docs lo justificaron; -tres avisos sueltos no). Esa fase lleva su propia `D`: **marcar no es arreglar, y cada ítem se -cierra releyendo el código o el device**, nunca otro doc. - -⛔ **Excepción: lo que además de desfasado es PELIGROSO no espera a B2.** Un doc que documenta algo -viejo se marca; un doc que da una **instrucción que hace daño** se corrige en el acto. *(Cicatriz -2026-07-27: `manual-instalacion.md` recomendaba `opkg --force-overwrite`, que la `D1` de la Fase 8 -descarta porque deja el `init.d` borrado y el servicio muerto — seguirlo en un device de campo lo -convierte en un ladrillo. Y `deployment.md` llevaba una **contraseña de root en claro** en un repo -pusheado.)* Regla: **si seguir el doc rompe algo o filtra algo, no es inventario — es un arreglo.** - -## Decisiones cerradas: numeradas, en el backlog, e inmutables - -Van **en el backlog** a propósito, no en el doc de diseño: tienen que estar **donde la sesión de -ejecución escribe**, no en un fichero que quizá no abra. - -- Bloque corto **al abrir la fase**, numerado `D1`/`D2`/`D3` para poder citarlas ("contradice D2") - en vez de describirlas de nuevo. -- **Inmutables**: contradecir una `D` no es escribir otra debajo — es **PARAR, reportar y levantar - la bandera** (ver [`repos/metodo/metodo.md`](../repos/metodo/metodo.md) §6 — ⚰️ la copia de esta carpeta se retiró el 2026-08-28). -- Cada `D` dice **de quién es**: decisión del usuario / decisión técnica de implementación. Las del - usuario no las toca ninguna sesión. - -## La bandera (`AVISOS.md`) - -Lo único que Solidaria tiene y aquí falta. Lista corta, por repo, de *"una sesión tocó algo que el -lector tiene que saber el primer día, no tres semanas después leyendo un `git log`"*: - -- contradije o quiero contradecir una `D`; -- toqué producción (o encontré una bomba latente en ella); -- el diseño escrito no encaja con lo que mide el hardware. - -No bloquea a nadie: sirve para enterarse. Se revisa al abrir sesión con Xavier. - -**Criterio de ENTRADA, que es lo que la mantiene corta** *(1ª ocurrencia fuera de Solidaria; sin -esto, en tres sesiones son 20 avisos y nadie la lee)*: - -- Cada aviso dice **su estado** (🔴 vivo / 🟠 en curso / cerrada) y **quién puede cerrarlo**, con una - tabla-resumen arriba para verlos todos de un vistazo. -- ⛔ **Un aviso que NADIE puede cerrar no es un aviso: es una decisión pendiente → va al backlog.** -- ⛔ **Un aviso CERRADO colapsa a UNA línea**, con puntero a la bitácora donde vive su relato. Los - abiertos van **primero**. *(Esto es lo que faltaba y por eso la bandera del hub creció un **146 % - en un día sin que nadie hiciera nada mal**: cinco avisos cerrados ocupaban ~140 líneas y empujaban -- ⛔⛔ **PERO «cerrado» NO es el criterio para colapsar — y confundirlos es cómo se pierde una bomba.** - *(1ª ocurrencia en `securizacion`, 2026-08-29. Frontera **aceptada por Xavier**, no propuesta.)* - El estado dice si **alguien tiene que actuar**; el criterio dice si **el lector va a hacer algo - distinto por saberlo**. Son cosas distintas y en esa bandera se separaban en dos familias: - - 📏 **REGLAS**: nacieron como aviso, se midieron, y **siguen frenando una acción futura** — *«en - OpenSSL gana la última declaración, en `sysctl.d` la última, en `sshd` la PRIMERA: por eso el - fragmento va `01-` y no `99-`»*. **Un aviso se cierra; una regla no.** Fueron **6 de 32**. - ⇒ **Necesitan SECCIÓN PROPIA**, o la siguiente pasada las colapsa con los consumados y **el - trabajo de medirlas se tira**. Casi todas evitan un **testigo falso**, que es lo que más caro se - paga. - - 🚩 **Consumados con un ENCARGO VIVO dentro, y con dueño.** Fueron **3 de 32**, y uno era *«**no - reinstalar `jon`** mientras sea la línea base de `E1.5`»*. **Colapsarlo en silencio es - exactamente cómo alguien reinstala `jon`.** ⇒ El aviso colapsa; **el residuo se PROMOCIONA - arriba**, a la tabla de lo que reclama algo de alguien. - ⇒ **Cómo se cazan**: no leyendo el estado, sino **el propio texto de la celda de estado** — *«vale - para las familias que quedan»*, *«vive como regla, no como pendiente»*, *«no se cierra: es - advertencia estructural»*, *«queda sólo…»*, *«sigue en pie…»*. Lo dicen ellos. - ⚠️ **Y clasificar por emoji exige respetar el ORDEN DE EVALUACIÓN**: una celda que empieza por 🟡 - y lleva un ✅ dentro cae en «cerrado» si preguntas por ✅ primero. Salieron **40 cerrados donde - había 32**. - hacia abajo las dos bombas de producción.)* -- 📊 **La bandera se degrada MÁS RÁPIDO que el backlog y hace más daño**, porque su único trabajo es - leerse el primer día. Vigílala por separado: si no cabe en una pantalla, ya ha fallado. - -## Los principios (heredados, validados en 3 ocurrencias en Solidaria) - -1. 🔑 **EL LECTOR MANDA, no la completitud.** Un doc completo que su lector no puede seguir está - roto. Un doc de estado **abre con el estado** y usa **una sola leyenda**. -2. ⛔ **MOVER, nunca borrar → verificando el destino primero.** Hecho → **puntero**; pendiente o - diseño no-ejecutado → **MOVER íntegro**, nunca puntero a la nada. -3. **Tres cubos, no dos:** *porqué* (conserva) · *historia hecha* (puntero) · *diseño pendiente sin - construir* (conserva íntegro). "Conserva el porqué" a secas tira diseño vivo. -4. ⚠️ **Preserva las referencias cruzadas.** Tras renombrar una sección, grep de `§NombreViejo` - entrantes y repúntalas — incluidos los **espejos cross-repo** (edge ↔ hub) y `MEMORY.md`. -5. 🔑 **Ordenar CRUZA afirmaciones y caza contradicciones** — no es mover texto. Deja **solo la - versión viva** de cada decisión; **marca** lo que otra sesión dejó incoherente (marcar ≥ - reestructurar si el arreglo es invasivo: la decisión de fondo es del lector). - - ⚠️ **Con espejo cross-repo, crúzalo casilla por casilla.** El fallo típico **no** es deriva de - redacción: es que **el trabajo ejecutado desde el repo A sobre artefactos del repo B se escribe - solo en A**. Síntoma: casillas `[ ]` en B para cosas **desplegadas** en B. *(Cicatriz Hermes - 2026-07-26: el sidecar Rosenpass llevaba un día corriendo en el chart del hub y el backlog del - hub lo daba por pendiente, describiendo un plan —«dos cajas x86»— que nunca ocurrió; y - `F13.0-c`, un fix **del hub**, no aparecía en el hub.)* Estas tres no se ven leyendo un repo: - salen de poner los dos documentos uno al lado del otro. -6. 📊 **El coste escala con las CAPAS de corrección-sobre-corrección**, no con las líneas → podar al - **cerrar cada fase**, no cuando ya no se puede leer. -7. 🔴 **Realinea a lo CONSTRUIDO, NUNCA a lo diseñado-pero-no-construido.** Señal fiable: si el - cambio aún no tiene código/manifiesto aplicado, no toques el doc base por él. -8. ⛔ **La bitácora es append-only aunque pique.** Verificas que lo último está; no la reescribes. - Si detectas desorden en ella, **lo FLAGUEAS**; no lo arreglas tú. - -## Las fronteras las confirma el LECTOR - -⚠️ **Cuando el reagrupado cambia el modelo mental del proyecto, es SU decisión: pregunta el -esqueleto antes de reescribir.** *(Cicatriz de Solidaria #3: Xavier redibujó el recorrido contra el -troceo que la sesión había inferido.)* En Hermes las fases **ya existen y valen** — no se -renumeran ni se refunden sin decirlo. - -## Cuándo dispara - -**Por DEMANDA, no por calendario**: cuando un doc deja de servir a su lector. Y de forma -incremental, al cerrar cada fase (principio 6). - -### ⛔ El backlog: las DECISIONES se quedan, la EVIDENCIA se va *(regla nueva, 2026-08-01)* - -**La deriva que la trae aquí**: cada sesión cierra su ficha y **deja dentro la evidencia** —medidas, -predicciones, recuentos de mutantes, tablas de antes/después, los casi-fallos—. Es el instinto -correcto (dejar la prueba) **en la capa equivocada**, y se acumula porque una ficha cerrada no vuelve -a tocarse nunca. -**Medido el 2026-08-01**: en `Panel-Teltonika`, **17 de 30 fichas cerradas** y las de esa semana -ocupaban **144** y **104** líneas — más que las **tres primeras fases juntas** (12+26+15). No creció -con el trabajo: **cambió el estilo**. - -⇒ **`AVISOS.md` ya tiene su versión** (*«un aviso cerrado colapsa a UNA línea con puntero a la -bitácora»*), pero **copiarla tal cual al backlog sería un error**: el backlog guarda algo que un aviso -no —las **decisiones cerradas `D`, inmutables y portantes**—. - -**El test, para cualquier párrafo de una ficha cerrada:** - -> **¿Una sesión futura necesita esto para NO contradecir una decisión?** → se queda en el backlog. -> **¿Es cómo nos enteramos?** → se va a la bitácora. - -**Se QUEDA**: las `D` con su porqué · el estado y la fecha de cierre · el puntero a la bitácora. -**Se VA**: cómo se reprodujo · las tablas de medidas · las predicciones y los mutantes · las premisas -falsas · los casi-fallos · el relato de la sesión. - -> ⛔ **PRECISIÓN de Xavier, 2026-08-01 — «al cerrar: frase, y el desarrollo a bitácora».** -> *«Las decisiones se quedan»* se estaba leyendo como *«el bloque `D` entero se queda, con toda su -> justificación»*, y por eso una fase **cerrada y ya podada** seguía ocupando **103 líneas**. -> ⇒ **La `D` conserva su ENUNCIADO, no su desarrollo.** -> **Se queda**: la decisión, y **la línea que cierra las alternativas** —*«la IP de una LAN no, -> porque dependería del botón `transporte`; la del GRE no, porque hay una por enlace»*—, que es lo -> único que impide reabrirla dentro de un año. -> **Se va**: las medidas que la probaron, las tablas, los descartes razonados y el relato. -> ⇒ Una `D` ocupa **dos líneas, no dos páginas**, y sigue siendo **encontrable e inmutable**, que es -> para lo que vive en el backlog. -> -> ⏳ **Y el momento: al CERRAR la fase, no antes.** Mientras está abierta, su desarrollo **es la -> herramienta de trabajo** y se queda entero. La poda **no es una limpieza periódica: es parte del -> cierre**. - -### El SUELO de una ficha no es un número de líneas: es su número de decisiones - -⛔ **La vara «~25 líneas» es falsa para una fase con muchas `D`** *(medido 2026-08-01)*: la Fase 11 del -edge quedó en **97 líneas** y **no se puede bajar más sin romper la regla** — son **14 `D` + 13 -ítems**, a una línea cada uno, más objetivo y punteros. La Fase 13 (10 `D`) quedó en 65; `E4` (5 `D` + -2 abiertos) en 99. Sirve para una ficha de una o dos decisiones; es **inalcanzable** para una fase que -cerró catorce. - -⇒ **El criterio contable NO es la longitud, es**: **¿cuántas de estas líneas son una MEDIDA?** El -objetivo es **cero**. En esa Fase 11, de las 97 líneas **ninguna** lo es — antes eran 121 con **seis -tablas** dentro. Ése es el testigo, y se comprueba leyendo, no contando. - -### ⭐ Una `D` ENMENDADA conserva la línea que dice qué parte sigue viva - -Es el único caso donde el «desarrollo» **no es adorno**. Costó decidirlo en **3 de 45** casos, y los -tres eran el mismo tipo: decisiones enmendadas después (`D4` de la Fase 4 por `A20`, `D8` de la -Fase 13 por `F13·D10` (máster en `hermes-edge`), `D15` por `D16`). -⛔ **Sin esa línea, la siguiente sesión lee `D4` —*«en colisión cede el de teléfono mayor»*— y -reintroduce lo que `A20` acaba de quitar.** Colapsar sin la enmienda **causa** exactamente el fallo -que la inmutabilidad de las `D` existe para impedir. -⇒ Se resuelve con una cláusula ⚰️/*(…)* **dentro de la propia `D`**, diciendo **qué se le enmendó y -qué sobrevive**. Distinguir *«esta `D` está muerta»* de *«a esta `D` le cambió el mecanismo y la razón -sigue»* es información de estado, no relato. - -### Por qué al cerrar sale gratis y después cuesta un día - -**El 78 % de lo cortado el 2026-08-01 venía de CINCO fichas cerradas en los seis días anteriores.** -No es deuda de meses acumulándose despacio: **se genera a ritmo de una ficha al día**. -⇒ La sesión que cierra la salda en **dos minutos**, porque tiene la evidencia delante y **sabe cuál es -cuál**. Hecha después, cuesta releer 3.000 líneas y comprobar destinos uno a uno — que es literalmente -lo que costó esa pasada. - -⚠️ **Y colapsa al CERRAR, no en una pasada seis meses después.** La pasada grande es para lo ya -acumulado; la regla evita que vuelva a acumularse. -⛔ **Antes de vaciar, comprueba el DESTINO**: si el relato no está ya en la bitácora, **se mueve**, no -se borra. Es la técnica 2 de este mismo workflow. - -**El disparador, contable — no «por sensación»:** - -**Una ficha cerrada SIN puntero a la bitácora.** Es **estado, no tamaño**: o su relato tiene destino -escrito, o no lo tiene. - -```bash -# fichas cerradas que no apuntan a dónde vive su relato -awk '/^## /{if(t&&c&&!p)print " SIN PUNTERO: "t; t=substr($0,4,70); c=($0~/✅|⚰️|Closed|CERRAD|~~/); p=0} - /bitacora\.md/{p=1} END{if(t&&c&&!p)print " SIN PUNTERO: "t}' doc/backlog.md -``` - -**Umbral**: más de **5** ⇒ toca pasada. - -⛔ **NO uses un umbral por LÍNEAS** *(lo intentamos el 2026-08-01 y es una trampa)*: contar líneas -bajo un `##` no distingue **decisión** de **evidencia**, así que tras una pasada correcta el contador -sigue marcando fichas cuyo volumen restante son **bloques `D`** — y `D` es precisamente lo que la -regla **prohíbe** recortar. **Fiarte del número te lleva a podar decisiones.** -No mires tampoco las líneas totales: un backlog crece con el trabajo y eso está bien. Lo que importa -es **qué fracción de él es museo**, y eso lo dice el puntero, no el tamaño. - -### Tres afinados de la regla *(salidos de usarla, 2026-08-01)* - -1. ⭐ **Una premisa falsa se va; el HECHO DE DISEÑO que la desmintió se queda si sostiene una `D`.** - *«El lado hub no necesitó ni una línea porque todo viaja dentro del GRE»* no es *cómo nos - enteramos*: es **por qué `D16` funciona sin tocar el hub**, y la siguiente sesión que añada una - `/32` volverá a preguntárselo. Va **dentro de la `D`**, en una línea. -2. ⭐ **Los mapas «Qué | Dónde» de código no son ni evidencia ni decisión: son DISEÑO.** La regla no - tenía cubo para *«dónde vive esto»* — y el corpus sí: es la capa de **diseño** del frente, no la - bitácora. A quien va a tocar la ficha le ahorran media hora, y en la bitácora no los encuentra. -3. ⭐ **Un casi-fallo cuya causa sigue ABIERTA no es relato: es estado.** Se queda como **una línea - con puntero a `AVISOS.md`**, no baja a la bitácora. Solo bajan los casi-fallos **cerrados**. - -### Y lo que funcionó, para no perderlo - -- **Comprobar el destino antes de vaciar** cazó a la primera **el único puntero invertido del corpus** - —una entrada de bitácora que decía *«tablas en `backlog.md`»*— y estaba justo en la ficha más gorda. -- **Contar ids ANTES y DESPUÉS** cazó **4 referencias cruzadas** caídas al colapsar (2 de ellas - cross-repo). ⭐ **Contar solo al final no las habría distinguido de «nunca estuvieron ahí»** — la - medida previa es lo que convierte una ausencia en una pérdida. - -## Cierre - -Dos entregas al lector, **para REVISIÓN**: - -1. **La propuesta de cambios** — el diff, explicado: qué se movió y a dónde, qué se dejó a - propósito, qué contradicciones aparecieron al cruzar. **No devuelvas encargos** — vuelves con la - propuesta. -2. **Un informe de cómo fue** — qué principios funcionaron, cuáles faltaron. Es lo que mantiene - vivo este workflow: cada ocurrencia lo reafina. Anota también lo que **funcionó** (un patrón que - se asienta se hace explícito, no se refactoriza).