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>
559 lines
39 KiB
Markdown
559 lines
39 KiB
Markdown
# 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 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).
|