smtp-relay/.metodo/workflows/sesion-ordenacion-docs.md
sirxavor 249794c189 chore(metodo): re-estampa el Metodo 2026-08-30 (§7: el borrador muere al colocar la entrega)
Re-estampado desde la matriz. Rail nuevo en §7: colocar una entrega convierte
el borrador en una copia derivada, y el borrador se borra en el mismo gesto.
Tres ocurrencias en cuatro dias. Testigo: no que el borrador este al dia — que
no exista.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-30 01:50:26 +02:00

39 KiB
Raw Blame History

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.

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' \
  <backlog> | 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 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 <details>grep -c '<details' == grep -c '</details>'. (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.)

awk '/^- \[.\] \*\*`|^- \*\*`D[0-9]+`/{if(n)print len; n=1; len=0} {len++}' <backlog> \
  | 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/ 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 700900 líneas. Bajar de ahí exige agrupar fases (p. ej. «Fases 14, 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 6070 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 §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.

# 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).