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

559 lines
39 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

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

# 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' \
<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 **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 `<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.)*
```bash
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/`](../../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 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`](../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).