From 7d84835d228790735cd2b71bb4ccee7830ff8036 Mon Sep 17 00:00:00 2001 From: sirxavor Date: Wed, 2 Sep 2026 20:51:02 +0200 Subject: [PATCH] =?UTF-8?q?chore(metodo):=20reparto=20=E2=80=94=20cinco=20?= =?UTF-8?q?parrafos=20partidos=20reparados=20+=20gate=20C39?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Insertar por numero de linea partia parrafos y la cola varada se leia como otro parrafo: cinco casos en la matriz, uno TRES DIAS en los 27 repos y otro en la cabecera del documento. Reparados. Y atado con C39, que compara cada linea cortada a mitad de frase con la siguiente que arranca bloque. El rail ya estaba escrito y no impidio nada. Lo que convierte un rail en propiedad es un numero que mueve el codigo de salida. Solo .metodo/ — byte a byte desde la matriz. Sesion: superadmin Co-Authored-By: Claude Opus 5 --- .metodo/CHECKSUMS | 4 ++-- .metodo/bin/metodo | 37 +++++++++++++++++++++++++++++++++++++ .metodo/metodo.md | 40 +++++++++++++++++++++++++++------------- 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/.metodo/CHECKSUMS b/.metodo/CHECKSUMS index 19c3a6f..738ec27 100644 --- a/.metodo/CHECKSUMS +++ b/.metodo/CHECKSUMS @@ -1,5 +1,5 @@ -c33430904d508a6398ddba6388d9968268da2e46e35509120aafb1723c268b11 metodo.md -fb7e88324524184b9f685c49c0bbcc6c9a55beb07bb5c0b1b31cd29c51c4117f bin/metodo +19c7343a4ff899dcacfddeef6dbd1113829a3f8740e69bdc3ce0d8bb28850e6b metodo.md +6850fa105390147de7c7dc6db63c20e26be483a66eb3ce0c7eb618857df092c3 bin/metodo f89b71bdf31028b05075636c1763c964e379bc37a00e0357d1c23a4dd19c09aa workflows/README.md cc241bbecf9647c747b8525b3a6b527455cd50ca0312caa44bc3544342c8ac41 workflows/comunicacion-entre-sesiones.md 2b9037f6dd57b5598c70a676cb728556654f05d1c5b024e7b716864659f7b884 workflows/sesion-ejecucion.md diff --git a/.metodo/bin/metodo b/.metodo/bin/metodo index 1b13f8a..a276390 100644 --- a/.metodo/bin/metodo +++ b/.metodo/bin/metodo @@ -154,6 +154,42 @@ EOF [ "$mal" -eq 0 ] && ok "$n commit(s) desde la adopción, todos dicen quién los hizo" } +# ── C39: prosa cortada a mitad de frase ──────────────────────────────────────── +# ⛔ Nace de una avería REAL y silenciosa: insertar un bloque por número de línea +# (`head -n L` / `tail -n +L`) parte el párrafo que hubiera en L, y **el resultado +# sigue pareciendo texto**. Medido el 2026-09-02: CINCO raíles partidos en la matriz, +# uno llevaba TRES DÍAS repartido a los 27 repos y nadie lo vio — la cola varada se lee +# como el principio de otro párrafo. Ningún check miraba la integridad de la prosa. +# ⇒ Testigo: una línea que acaba a mitad de frase (minúscula o coma) seguida de una que +# ARRANCA un bloque nuevo (⛔ ⭐ ⚠️ ⇒ ⚙️ ⚰️ ✅, una cicatriz `*(`, o una cabecera `#`). +check_prosa_partida() { + hdr "prosa cortada a mitad de frase (C39)" + local f n + local -a fs=() + [ -f "$ROOT/metodo.md" ] && fs+=("$ROOT/metodo.md") + [ -f "$ROOT/.metodo/metodo.md" ] && fs+=("$ROOT/.metodo/metodo.md") + [ ${#fs[@]} -eq 0 ] && { skip "no hay metodo.md que mirar"; return 0; } + local mal=0 + for f in "${fs[@]}"; do + n=$(perl -CSD -ne 'push @L,$_; END{ my $n=0; + for my $i (0..$#L-1){ my $a=$L[$i]; my $b=$L[$i+1]; chomp $a; chomp $b; + next if $a =~ /^\s*$/ || $a =~ /^[#|`]/ || $a =~ /^\s*[-*] /; + next unless $a =~ /[a-z\x{e1}\x{e9}\x{ed}\x{f3}\x{fa}\x{f1},]$/; + next unless $b =~ /^\s*[\x{26D4}\x{2B50}\x{26A0}\x{21D2}\x{2699}\x{26B0}\x{2705}]/ + || $b =~ /^\s*\*\(/ || $b =~ /^#/; + $n++; print STDERR " linea ".($i+1).": …".substr($a,-46)."\n"; } + print $n; }' "$f" 2>/tmp/_pp.$$) + if [ "${n:-0}" -gt 0 ]; then + bad "$(basename "$f"): $n párrafo(s) cortados a mitad de frase (C39) — una inserción por número de línea partió el texto; la cola varada se lee como otro párrafo y NO da error" + sed -n '1,6p' /tmp/_pp.$$ >&2 + mal=$((mal+1)) + fi + rm -f /tmp/_pp.$$ + done + [ "$mal" -eq 0 ] && ok "ningún párrafo cortado" + return 0 +} + check_incremento() { local f="$ROOT/.metodo/INCREMENTO" hdr "incrementos declarados (lo que este repo tiene DE MÁS)" @@ -1055,6 +1091,7 @@ cmd_check() { check_apendices_no_viajan check_sesion_trailer check_incremento + check_prosa_partida check_reparto_al_dia check_semaforo_forma check_semaforo_en_vuelo diff --git a/.metodo/metodo.md b/.metodo/metodo.md index e54fe1c..4a86cad 100644 --- a/.metodo/metodo.md +++ b/.metodo/metodo.md @@ -2,6 +2,7 @@ Principios que valen para **cualquier** sesión (exploración, ejecución, despliegue, incidente, orquestación) y para cualquier backlog. Los workflows concretos referencian este +doc en vez de repetirlo. No son teoría: cada uno lleva el caso real que lo enseñó. ⛔ **Y EL DAÑO NO ES EL QUE PARECE: UNA FILA ARRASTRADA NO QUEDA CORRUPTA — QUEDA PUBLICADA EN UNA VERSIÓN ANTERIOR.** No se rompe nada, no hay conflicto, no hay nada que se vea: simplemente el remoto **anuncia un estado de hace veinte minutos como si fuera el de ahora**. En un fichero cuyo @@ -18,7 +19,6 @@ incidente, orquestación) y para cualquier backlog. Los workflows concretos refe nuevo —*costaría más que el choque*— sino **dos gestos de una línea**: **declararlo en el mensaje** y **avisar a su dueña por el canal**, porque **el dueño es el único que sabe si lo publicado estaba al día**. -doc en vez de repetirlo. No son teoría: cada uno lleva el caso real que lo enseñó. > **Versión 2026-08-29.** Documento **autocontenido**: es lo que se vendoriza, byte a byte, a cada > repo (no lleva enlaces a rutas de un árbol concreto, para que funcione clonado en solitario). @@ -537,6 +537,11 @@ deducir**. Si no lo miraba, el artefacto es un testigo de la avería, no del sis COPIA que usa la gente está rota.** Son dos preguntas distintas —*«¿qué despliega ArgoCD?»* y *«¿qué le pasa a quien clona esto?»*— y **ninguna receta contesta las dos**. *(Cicatriz 2026-08-06: `pq-secret.sh` estaba en **CRLF en el worktree** y así ni arranca —`set -uo + pipefail\r`—, o sea que con `core.autocrlf=true` un clon en Windows deja **todos** los bancos + muertos. El censo no lo vio porque medía —bien— sobre un `git archive` en LF: **la receta correcta + tapó el defecto que la rodeaba**. Se cosió con un `.gitattributes`.)* ⇒ Cuando elijas dónde medir, + di **qué pregunta estás contestando**; y si la herramienta tiene una salida de emergencia (un + `tr -d '\r'`, un fallback), pregúntate **qué está haciendo tolerable que no deberías tolerar**. ⛔ **Y EL TESTIGO DE EOL HAY QUE VALIDARLO CON UN FICHERO QUE SEPAS QUE ES CRLF, porque el obvio MIENTE.** `grep -c $'\r'` **es ciego al CR en algunos shells**: devuelve **0** sobre un fichero que `od -c` demuestra lleno de `\r\n`. ⇒ Y lo peor: **acertó tres veces seguidas antes de fallar** — los @@ -546,11 +551,6 @@ real eran **13**, con líneas idénticas en `-` y `+`. Y el segundo intento tamb CR en 268 líneas**, un número imposible **que sólo se ve si compruebas la aritmética**.)* ⇒ **Lo que discrimina**: `od -c`, o `tr -dc '\r' | wc -c`. **Nunca `grep $'\r'`.** Y **guarda un fichero CRLF conocido** como control positivo del testigo. - pipefail\r`—, o sea que con `core.autocrlf=true` un clon en Windows deja **todos** los bancos - muertos. El censo no lo vio porque medía —bien— sobre un `git archive` en LF: **la receta correcta - tapó el defecto que la rodeaba**. Se cosió con un `.gitattributes`.)* ⇒ Cuando elijas dónde medir, - di **qué pregunta estás contestando**; y si la herramienta tiene una salida de emergencia (un - `tr -d '\r'`, un fallback), pregúntate **qué está haciendo tolerable que no deberías tolerar**. - **Si un inventario lista dos medidas del mismo día, la hora es parte del dato.** Un robot «vivo por la mañana» y «borrado por la tarde» no es una contradicción que resolver: es un **antes y un después**, y tratarlo como conflicto te hace corregir dos veces y acertar ninguna. @@ -1365,6 +1365,20 @@ construya un des-aplicar»* (**el raíl que su propio encargo repetía**) y una al ir a trabajar sobre la ficha; la orquestadora había «verificado» cada edición con un `grep` del marcador nuevo, que **siempre casa** aunque el resto haya quedado hecho trizas.)* ⇒ **Un `grep` del marcador que acabas de insertar no verifica una edición: verifica tu inserción.** +⛔⛔ **Y ESTE RAÍL ESTABA ESCRITO Y NO IMPIDIÓ NADA: SE CUMPLIÓ CINCO VECES SOBRE ESTE MISMO +DOCUMENTO.** *(Censo 2026-09-02: **cinco párrafos partidos en la matriz**. El más viejo llevaba +**tres días** repartido a los **27 repos** —lo partió, con ironía perfecta, el commit que añadía +«**la puerta hay que escribirla de modo que ATE, no que informe**»—; **dos eran de esa misma tarde y +de quien escribe esto**; y uno estaba **en la cabecera del documento**, la primera frase que lee toda +sesión. **Nadie vio ninguno**, porque una cola varada **se lee como el principio de otro párrafo**: +el texto no se rompe, se **recompone mal** y sigue siendo texto.)* +⇒ ⭐ **La lección no es sobre `sed`: es que un raíl que depende de acordarse ES PROCEDIMIENTO, NO +PROPIEDAD** — y este llevaba dos semanas escrito, en un documento que sus infractores tenían abierto. +⇒ ⭐ **Por eso se ató: `C39` del linter** compara cada línea que **acaba a mitad de frase** con la +siguiente que **arranca un bloque nuevo**, y **nombra la línea**. Ejercitado en los dos sentidos: +verde sobre el documento reparado, **rojo al partir un párrafo a propósito**. ⇒ **Lo que convierte +un raíl en una propiedad es un número que mueve el código de salida**, no repetirlo mejor. + Lo que hay que mirar es **el texto de alrededor**, y en concreto **la línea anterior y la posterior al corte**. ⇒ Y siempre que se pueda, edita por **anclas de contenido** (buscar y sustituir una cadena única) en vez de por número de línea; los números se recalculan solos y las anclas no. @@ -1455,6 +1469,7 @@ invisible desde el sitio donde se decide**. La encontró su relevo **por casuali ⇒ **Un mensaje de commit es el testigo de un CAMBIO, no el estado de un FRENTE.** Si lo que sabes cambia el estado, va a su capa **además** —`AVISOS.md`, `decisiones.md`, `backlog.md` o la bitácora— y el commit **puede** repetirlo. ⛔ **Nunca sólo en el commit**: es la quinta capa que nadie lee y que +además **no se puede recorrer** (§8). ⇒ ⛔ **Y hay un segundo filo, peor que la invisibilidad: UN AVISO CON FECHA DENTRO DE UN ARTEFACTO SIN FECHA CADUCA SIN AVISAR.** Un mensaje de commit está **congelado**: se escribió en un instante y el mundo siguió. Un *«esto NO está vivo todavía»* escrito a las 14:42 **era cierto**… y a las 15:10, con @@ -1465,7 +1480,6 @@ tiene forma de saber cuál de las dos cosas está leyendo. y no en un artefacto que **nadie vuelve a abrir para corregirlo**. ⭐ La prueba de si un sitio sirve para un aviso es: **¿alguien va a volver aquí a cerrarlo?** Si la respuesta es no, ese sitio **sólo sirve para lo que no caduca**. -además **no se puede recorrer** (§8). ⇒ **Al escribir, decide el destino UNA vez**, y los destinos son **CUATRO**: el corpus de un repo tiene **cuatro capas**, no tres. *¿Es una decisión cerrada, de las que otra sesión no puede contradecir sin PARAR?* → **`doc/decisiones.md`**, con su texto **íntegro**. *¿Es trabajo — un item @@ -2116,6 +2130,9 @@ pega tal cual. porque vio en el `diff` 21 líneas que no eran suyas.)* ⇒ ⭐ **Lo que sí lo caza es la puerta de los tres números** —`ficheros staged` · `filas tocadas` · `¿todas mías?`— **pero enrojeciendo por un motivo que no es el tuyo**: ahí habría dado `22/43` en + vez de `22/22`. **Un gate que se pone rojo por causa ajena entrena a desmentirlo**, así que cuando + salga descuadrado la pregunta no es *«¿qué he hecho mal?»* sino **«¿de quién es lo demás?»** — y la + respuesta es un mensaje, no un `commit`. ⛔⛔ **Y LA PUERTA HAY QUE ESCRIBIRLA DE MODO QUE ATE, NO QUE INFORME.** echo "filas tocadas: $n ¿mías?: $m" # INFORMA — depende de que alguien mire @@ -2170,9 +2187,6 @@ pega tal cual. ⛔ **Y por eso se escribe el NO**: una prescripción sin gate y sin explicación se lee como un descuido, y el siguiente que pase «lo arreglará» — creando justo el rojo permanente que este párrafo prohíbe. - vez de `22/22`. **Un gate que se pone rojo por causa ajena entrena a desmentirlo**, así que cuando - salga descuadrado la pregunta no es *«¿qué he hecho mal?»* sino **«¿de quién es lo demás?»** — y la - respuesta es un mensaje, no un `commit`. ⭐ **Y lo que de verdad caza el arrastre no es acordarse de mirar el `diff`: es MEDIR DOS VECES y que los números no cuadren.** *(Corrección de la propia sesión que lo frenó, 2026-08-29, y lo dijo contra su propio mérito: «no fue virtud, fue orden — medí el fichero dos veces porque los números @@ -2248,6 +2262,9 @@ pega tal cual. fichero ajeno a su cambio. El `push` sale rechazado por no-fast-forward, que es **la única razón por la que se vio**. Sin ese rechazo, la reescritura se habría publicado.)* ⇒ **Regla: en un working tree compartido, `--amend` sólo sobre un commit que sabes que es tuyo Y que + no ha salido** — y saberlo exige **mirar `git log -1` antes**, no suponer que HEAD es lo último que + escribiste tú. ⛔ **Y el rechazo del `push` NO se resuelve forzando**: se resuelve con + `git reset --soft @{u}` y recommiteando **lo tuyo solo**, que deja el commit ajeno intacto. ⛔⛔ **UNA INSPECCIÓN NO GANA UNA CARRERA — y todas las puertas de aquí arriba son inspección.** `git status --porcelain` antes del primer `add`, `git diff --cached --name-only` justo antes de commitear, predecir el diffstat: **los tres MIRAN**. Contra un competidor concurrente, mirar sólo @@ -2288,9 +2305,6 @@ pega tal cual. entra DESPUÉS de tu `add` sólo la caza el `--cached` justo antes de commitear.** ⚠️ Y **no lo generalices al revés**: que dos sesiones compartan árbol es cierto **de las que corren en la misma máquina**; de un agente en worktree aislado o en remoto, **no** — y eso **se mide, no se supone**. - no ha salido** — y saberlo exige **mirar `git log -1` antes**, no suponer que HEAD es lo último que - escribiste tú. ⛔ **Y el rechazo del `push` NO se resuelve forzando**: se resuelve con - `git reset --soft @{u}` y recommiteando **lo tuyo solo**, que deja el commit ajeno intacto. ⛔⛔ **Y LA PROPIEDAD QUE UNE A LOS CUATRO, Y DICE CUÁNDO DEJAR DE BUSCAR UN GATE: `git` ES LA ÚNICA HERRAMIENTA COMPARTIDA DEL ÁRBOL QUE NO TIENE EL CONCEPTO DE SESIÓN.** El semáforo sabe quién eres.