docs(metodo): re-estampar el linter — A8: UNA sola definición de «id definido»

check_decisiones_en_backlog consume _id_scan (modo defnr) en vez de llevar su
propia copia del patrón, así que ya obedece a D101 (un D9b no cuenta como D9).
Las definiciones entran por -v y no como segundo fichero: con el truco NR==FNR y
la lista vacía la regla se tragaba el fichero entero y el check medía sobre la
nada, en silencio. Copia vendorizada: aquí NO se edita.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
sirxavor 2026-08-22 19:35:18 +02:00
parent ecee0e1d7b
commit 0979e5bb51
2 changed files with 19 additions and 5 deletions

View File

@ -1,2 +1,2 @@
140cf44bc4d8e9eff08cd4f6466df22c897efa2c6c6f83662a747e3348a4f2bd metodo.md 140cf44bc4d8e9eff08cd4f6466df22c897efa2c6c6f83662a747e3348a4f2bd metodo.md
252f0e98ca4f8e015fceff57493a132f665514e4fd590ef2172dc6e4dfa021ab bin/metodo 09189db5840b85e18a71aad9073b0642c9845dbcab08eccda2c83494d521d994 bin/metodo

View File

@ -135,10 +135,13 @@ _id_scan() { # $1 = fichero · $2 = def|forma
if (cola ~ /^[[:alnum:]]/ ) { if (modo == "subid") print "1"; next } # P9b / E2E if (cola ~ /^[[:alnum:]]/ ) { if (modo == "subid") print "1"; next } # P9b / E2E
if (cola ~ /^[.-][[:alnum:]]/ ) { if (modo == "subid") print "1"; next } # E8.a / R5-bis if (cola ~ /^[.-][[:alnum:]]/ ) { if (modo == "subid") print "1"; next } # E8.a / R5-bis
} }
if (modo == "def") print id; else if (modo == "forma") print "1" }' "$1" if (modo == "def") print id
else if (modo == "defnr") print NR "\t" id # el consumidor necesita SABER en qué línea
else if (modo == "forma") print "1" }' "$1"
} }
_ids_def() { _id_scan "$1" def; } _ids_def() { _id_scan "$1" def; }
_lineas_forma_id() { _id_scan "$1" forma | grep -c "^1$"; } _lineas_forma_id() { _id_scan "$1" forma | grep -c "^1$"; }
_ids_def_nr() { _id_scan "$1" defnr; } # <línea> <id> — para quien necesite CASAR con el fichero
_subids() { _id_scan "$1" subid | grep -c "^1$"; } # lo que el LÍMITE tira: se dice, no se calla _subids() { _id_scan "$1" subid | grep -c "^1$"; } # lo que el LÍMITE tira: se dice, no se calla
check_ids() { check_ids() {
@ -343,11 +346,22 @@ check_decisiones_en_backlog() {
hdr "textos de decisión dentro del backlog (D6)" hdr "textos de decisión dentro del backlog (D6)"
local f="$ROOT/doc/backlog.md" local f="$ROOT/doc/backlog.md"
[ -f "$f" ] || { skip "sin doc/backlog.md (repo sin corpus de estado)"; return; } [ -f "$f" ] || { skip "sin doc/backlog.md (repo sin corpus de estado)"; return; }
# ⚠️ `A8`: qué línea ES una definición de id lo decide **`_id_scan` y sólo él**. Este check
# llevaba su propia copia del patrón, y por eso NO obedecía a `D101` (un `D9b` contaba como
# `D9`). Es la lección de `A6` en su forma más literal —*el detector no hereda ni DUPLICA el
# criterio que audita*— y estaba escrita desde el día uno en la cabecera del script: «UN solo
# script, nada de dos implementaciones que diverjan». Aquí sólo se añade lo propio: quedarse
# con los ids `D` y medir el TAMAÑO del bloque.
# ⚠️ Las definiciones entran por `-v`, NO como segundo fichero: con el truco `NR==FNR` y la
# lista VACÍA (un backlog sin ids reconocidos) la regla se traga el fichero entero y el check
# mide sobre la nada **en silencio**. Lo destapó el arnés: el mutante que le devuelve su copia
# al check 8 no llegaba a ejecutarse nunca.
local defs; defs=$(_ids_def_nr "$f")
local out legacy=0 nuevos=0 id len num local out legacy=0 nuevos=0 id len num
out=$(awk ' out=$(awk -v defs="$defs" '
BEGIN { n=split(defs, L, "\n"); for (i=1;i<=n;i++) if (split(L[i], P, "\t")==2) DEF[P[1]+0]=P[2] }
function flush(){ if (id!="" && len>3) print id "\t" len; id=""; len=0 } function flush(){ if (id!="" && len>3) print id "\t" len; id=""; len=0 }
/^[[:space:]]*[-*|_]+[[:space:]]*[*~`]*D[0-9]+/ { (FNR in DEF) { flush(); if (DEF[FNR] ~ /^D[0-9]+$/) { id=DEF[FNR]; len=1 } ; next }
flush(); match($0, /D[0-9]+/); id=substr($0, RSTART, RLENGTH); len=1; next }
/^[[:space:]]+[^[:space:]]/ { if (id!="") { len++; next } } /^[[:space:]]+[^[:space:]]/ { if (id!="") { len++; next } }
{ flush() } { flush() }
END { flush() }' "$f") END { flush() }' "$f")