docs(metodo): commitear la copia vendorizada + doc/ de tres capas
Estampada por 'metodo init' el 2026-08-12 (master 2026-08-08); sin commit no viaja al clonar (D1). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
6a10eab342
commit
2b62b8d6e9
1
.metodo/.gitattributes
vendored
Normal file
1
.metodo/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
* text eol=lf
|
||||||
2
.metodo/CHECKSUMS
Normal file
2
.metodo/CHECKSUMS
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
03db9775718f9529c2c59ea87ff6e109e77a6408e599755c9c5ee0c555466c54 metodo.md
|
||||||
|
3046e8f13185e4c6a97aaccedeb2f81a958bdc7ceb6b395d411b743c86950f50 bin/metodo
|
||||||
5
.metodo/VERSION
Normal file
5
.metodo/VERSION
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Copia vendorizada del Método (raíl C11). Gestionada por 'metodo init/update'.
|
||||||
|
master: metodo
|
||||||
|
version: 2026-08-08
|
||||||
|
estado: vendored
|
||||||
|
adopted_commit: 6a10eab342a477846ab5f3e67f8ab17169f12807
|
||||||
262
.metodo/bin/metodo
Normal file
262
.metodo/bin/metodo
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# metodo — CLI del Método. v0: sólo el linter `metodo check`.
|
||||||
|
#
|
||||||
|
# Modelo: bin/sync.sh --check de manabo-ui (raíl C11). Su anatomía, que copiamos:
|
||||||
|
# - UN solo script (nada de dos implementaciones que diverjan).
|
||||||
|
# - El testigo es una comprobación CRUDA del fichero real, no un hash guardado.
|
||||||
|
# - Veredicto DISCRETO por check, con la reparación impresa al lado.
|
||||||
|
# - Exit-code apto para CI: 0 si pasa, 1 si algo incumple.
|
||||||
|
# - Fallo benigno EXPLÍCITO (raíl 8): lo que no aplica se SALTA (SKIP), no falla.
|
||||||
|
#
|
||||||
|
# Cada AVISO cita la regla Cn de constitucion-de-facto.md que lo respalda.
|
||||||
|
# Uso: metodo check [ruta] (por defecto, el repo actual)
|
||||||
|
|
||||||
|
set -uo pipefail # -u: variable sin definir es error · pipefail: un pipe hereda el fallo.
|
||||||
|
# (NO ponemos -e: los grep sin match devuelven 1 y no queremos abortar por eso.)
|
||||||
|
|
||||||
|
ROOT="."
|
||||||
|
FAILS=0
|
||||||
|
SELF_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")/.." && pwd)" # raíz del repo del script
|
||||||
|
|
||||||
|
# sha256 portable (Git Bash trae sha256sum; si no, shasum -a 256; si ninguno, la deriva no se mide)
|
||||||
|
_hash() {
|
||||||
|
if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" 2>/dev/null | awk '{print $1}'
|
||||||
|
elif command -v shasum >/dev/null 2>&1; then shasum -a 256 "$1" 2>/dev/null | awk '{print $1}'
|
||||||
|
else return 127; fi
|
||||||
|
}
|
||||||
|
_vendored_files() { printf '%s\n' "metodo.md" "bin/metodo"; } # lo que se estampa y se vigila
|
||||||
|
_write_checksums() { # $1 = dir .metodo del destino
|
||||||
|
local md="$1" f h; : > "$md/CHECKSUMS"
|
||||||
|
for f in $(_vendored_files); do
|
||||||
|
h=$(_hash "$md/$f") || { rm -f "$md/CHECKSUMS"; return 1; }
|
||||||
|
printf '%s %s\n' "$h" "$f" >> "$md/CHECKSUMS"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
_is_matriz() { [ -f "$SELF_ROOT/constitucion-de-facto.md" ]; } # marca inequívoca de la matriz
|
||||||
|
|
||||||
|
# --- veredictos (los cuatro colores del check) ---
|
||||||
|
hdr() { printf '\n\033[1m== %s ==\033[0m\n' "$*"; }
|
||||||
|
ok() { printf ' \033[32mok \033[0m %s\n' "$*"; }
|
||||||
|
bad() { printf ' \033[31mAVISO\033[0m %s\n' "$*"; FAILS=$((FAILS+1)); }
|
||||||
|
skip() { printf ' \033[33mSKIP\033[0m %s\n' "$*"; }
|
||||||
|
|
||||||
|
# ── Check 1 · integridad de la copia vendorizada (C11) ───────────────────────
|
||||||
|
# El máster vive en OTRO repo (la matriz), así que el testigo no es el máster sino el
|
||||||
|
# CHECKSUM sellado al distribuir (metodo init/update). Caza si alguien editó la copia a mano.
|
||||||
|
check_drift() {
|
||||||
|
hdr "integridad de la copia vendorizada (C11)"
|
||||||
|
local md="$ROOT/.metodo"
|
||||||
|
[ -f "$md/VERSION" ] || { skip "no hay .metodo/VERSION — repo sin el Método vendorizado"; return; }
|
||||||
|
local ver estado
|
||||||
|
ver=$(grep -E '^version:' "$md/VERSION" | sed 's/version:[[:space:]]*//')
|
||||||
|
estado=$(grep -E '^estado:' "$md/VERSION" | sed 's/estado:[[:space:]]*//')
|
||||||
|
ok "VERSION presente (version: ${ver:-?}, estado: ${estado:-?})"
|
||||||
|
if [ ! -f "$md/CHECKSUMS" ]; then
|
||||||
|
skip "sin CHECKSUMS — corre 'metodo init|update' para sellar la línea base de integridad"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if ! _hash "$md/CHECKSUMS" >/dev/null 2>&1; then
|
||||||
|
skip "sin sha256sum/shasum disponible → no se puede comprobar la deriva"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local rec f cur drift=0
|
||||||
|
while read -r rec f; do
|
||||||
|
[ -n "$f" ] || continue
|
||||||
|
cur=$(_hash "$md/$f")
|
||||||
|
if [ -z "$cur" ]; then bad "falta la copia vendorizada: $f (C11)"; drift=$((drift+1))
|
||||||
|
elif [ "$cur" != "$rec" ]; then bad "DERIVA: .metodo/$f editado a mano — nunca se edita la copia (C11); 'metodo update' o revierte"; drift=$((drift+1)); fi
|
||||||
|
done < "$md/CHECKSUMS"
|
||||||
|
[ "$drift" -eq 0 ] && ok "copia vendorizada íntegra (coincide con lo distribuido)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 2 · colisión de ids en los ficheros de estado (C17) ────────────────
|
||||||
|
check_ids() {
|
||||||
|
hdr "colisión de ids en los ficheros de estado (C17)"
|
||||||
|
local statefiles=( "$ROOT/doc/AVISOS.md" "$ROOT/doc/backlog.md" )
|
||||||
|
local any=0 f dups id
|
||||||
|
for f in "${statefiles[@]}"; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
any=1
|
||||||
|
# id DEFINIDO = al principio de una fila de tabla (|) o item de lista (-*) en negrita.
|
||||||
|
# Así una MENCIÓN inline ("ver D5") no cuenta como definición (evita falsos positivos).
|
||||||
|
dups=$(grep -oE '^[[:space:]]*[|*_-]+[[:space:]]*\**~*\**(D|A|G|H|C|R|F|E|P)[0-9]+' "$f" \
|
||||||
|
| grep -oE '(D|A|G|H|C|R|F|E|P)[0-9]+' | sort | uniq -d)
|
||||||
|
if [ -n "$dups" ]; then
|
||||||
|
while IFS= read -r id; do
|
||||||
|
[ -n "$id" ] && bad "id duplicado en $(basename "$f"): $id — renombra o fusiona (C17)"
|
||||||
|
done <<< "$dups"
|
||||||
|
else
|
||||||
|
ok "$(basename "$f"): sin ids duplicados"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[ "$any" -eq 0 ] && skip "sin doc/AVISOS.md ni doc/backlog.md (repo sin corpus de estado)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 3 · encabezados sin marca de estado (C16) ──────────────────────────
|
||||||
|
check_headings() {
|
||||||
|
hdr "encabezados sin marca de estado (C16)"
|
||||||
|
local f hits=0 line
|
||||||
|
for f in "$ROOT"/*.md "$ROOT"/doc/*.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
# Un encabezado ## no lleva emoji de ESTADO (el estado vive en las casillas).
|
||||||
|
# ⚠️ se excluye a propósito: en un título es "bandera/aviso", no estado de sección.
|
||||||
|
while IFS= read -r line; do
|
||||||
|
bad "encabezado con estado en $(basename "$f"): ${line} — el estado va en las casillas (C16)"
|
||||||
|
hits=$((hits+1))
|
||||||
|
done < <(grep -nE '^#{2,6} .*(✅|🟢|🔴|🟠|🟡|❌)' "$f")
|
||||||
|
done
|
||||||
|
[ "$hits" -eq 0 ] && ok "ningún encabezado ##+ lleva marca de estado"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 4 · enlaces locales resuelven (integridad del corpus) ──────────────
|
||||||
|
check_links() {
|
||||||
|
hdr "enlaces locales resuelven (integridad)"
|
||||||
|
local f dir tgt found=0 broken=0
|
||||||
|
for f in "$ROOT"/*.md "$ROOT"/doc/*.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
dir=$(dirname "$f")
|
||||||
|
# process substitution (< <(...)) para que el while corra en ESTE shell y bad() cuente
|
||||||
|
# (un `grep | while` correría en un subshell y perdería el contador — raíl 1: el testigo
|
||||||
|
# tiene que medir de verdad, no en un proceso que se traga el resultado).
|
||||||
|
while IFS= read -r tgt; do
|
||||||
|
case "$tgt" in http*|\#*|mailto:*|"") continue;; esac
|
||||||
|
tgt="${tgt%%#*}" # quita el ancla #seccion
|
||||||
|
[ -z "$tgt" ] && continue
|
||||||
|
found=$((found+1))
|
||||||
|
[ -e "$dir/$tgt" ] || { bad "enlace roto en $(basename "$f"): $tgt"; broken=$((broken+1)); }
|
||||||
|
done < <(grep -oE '\]\([^)]+\)' "$f" | sed -E 's/^\]\(//; s/\)$//')
|
||||||
|
done
|
||||||
|
[ "$broken" -eq 0 ] && ok "$found enlaces locales, todos resuelven"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 5 · commits Conventional DESDE LA ADOPCIÓN (C25) ───────────────────
|
||||||
|
# Sólo se juzga lo NUEVO: la adopción es brownfield HACIA ADELANTE, el historial previo no se
|
||||||
|
# reescribe → no se juzga (juzgarlo dejaría un repo brownfield rojo para siempre — raíl 5/C35).
|
||||||
|
# El punto de adopción se sella en .metodo/VERSION (adopted_commit); sin sello = greenfield → todo.
|
||||||
|
check_commits() {
|
||||||
|
hdr "commits Conventional desde la adopción (C25)"
|
||||||
|
git -C "$ROOT" rev-parse --git-dir >/dev/null 2>&1 || { skip "no es un repo git"; return; }
|
||||||
|
local since range n s bad_c=0
|
||||||
|
since=$(grep -E '^adopted_commit:' "$ROOT/.metodo/VERSION" 2>/dev/null | sed 's/adopted_commit:[[:space:]]*//')
|
||||||
|
if [ -n "$since" ] && git -C "$ROOT" rev-parse --verify -q "$since^{commit}" >/dev/null 2>&1; then
|
||||||
|
range="${since}..HEAD"
|
||||||
|
else
|
||||||
|
range="HEAD"; since="" # sin marcador: repo nuevo → se juzga todo el historial
|
||||||
|
fi
|
||||||
|
n=$(git -C "$ROOT" rev-list --count $range 2>/dev/null || echo 0)
|
||||||
|
[ "${n:-0}" -eq 0 ] && { skip "sin commits nuevos desde la adopción (nada que revisar)"; return; }
|
||||||
|
while IFS= read -r s; do
|
||||||
|
printf '%s' "$s" | grep -qE '^(feat|fix|docs|ci|refactor|test|chore|build|perf)(\(.+\))?!?: .' \
|
||||||
|
|| { bad "commit no-Conventional: \"$s\" (C25)"; bad_c=$((bad_c+1)); }
|
||||||
|
done < <(git -C "$ROOT" log --format=%s $range 2>/dev/null)
|
||||||
|
[ "$bad_c" -eq 0 ] && ok "los ${n} commit(s) desde la adopción siguen Conventional"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── plantillas de doc/ (sólo se crean si faltan — brownfield: no pisar) ───────
|
||||||
|
_scaffold_docs() { # $1 = repo destino
|
||||||
|
# Si el repo ya tiene casa de docs propia (doc/ o docs/), NO scaffoldear: no duplicar estructura.
|
||||||
|
{ [ -d "$1/doc" ] || [ -d "$1/docs" ]; } && { echo " (doc/ o docs/ ya existe → no scaffoldeo el corpus)"; return 0; }
|
||||||
|
local d="$1/doc"; mkdir -p "$d"
|
||||||
|
[ -f "$d/backlog.md" ] || cat > "$d/backlog.md" <<'EOF'
|
||||||
|
# Backlog
|
||||||
|
|
||||||
|
> Tres capas: **este backlog** = estado (metas + decisiones cerradas `D` + items) ·
|
||||||
|
> AVISOS.md = bandera (se lee primero) · bitacora.md = relato append-only.
|
||||||
|
> Método vendorizado en ../.metodo/metodo.md. ⛔ Las `D` son inmutables. Un `##` no lleva marca de
|
||||||
|
> estado; abierto = tiene `[ ]`.
|
||||||
|
|
||||||
|
## Decisiones cerradas
|
||||||
|
|
||||||
|
## Abierto
|
||||||
|
- [ ] (siembra aquí el trabajo ABIERTO de hoy — brownfield: el pasado no se reconstruye)
|
||||||
|
EOF
|
||||||
|
[ -f "$d/AVISOS.md" ] || cat > "$d/AVISOS.md" <<'EOF'
|
||||||
|
# ⚠️ AVISOS
|
||||||
|
|
||||||
|
**Lo que hay que saber el primer día.** Se lee antes que el backlog. Cada aviso dice quién lo cierra.
|
||||||
|
|
||||||
|
| # | Qué | Estado | Quién lo cierra |
|
||||||
|
|---|---|---|---|
|
||||||
|
EOF
|
||||||
|
[ -f "$d/bitacora.md" ] || cat > "$d/bitacora.md" <<'EOF'
|
||||||
|
# Bitácora
|
||||||
|
|
||||||
|
*Relato append-only. Lo nuevo va ABAJO. Se lee por fecha.*
|
||||||
|
|
||||||
|
---
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── metodo init <repo> — vendoriza el Método a un repo por primera vez ────────
|
||||||
|
cmd_init() {
|
||||||
|
local tgt="${1:-.}"
|
||||||
|
_is_matriz || { echo "metodo init: sólo se corre desde la MATRIZ, no desde una copia vendorizada."; exit 2; }
|
||||||
|
[ -d "$tgt" ] || { echo "metodo init: no existe el destino: $tgt"; exit 2; }
|
||||||
|
local md="$tgt/.metodo"
|
||||||
|
[ -e "$md" ] && { echo "metodo init: $tgt ya tiene .metodo/ — usa 'metodo update $tgt'."; exit 2; }
|
||||||
|
mkdir -p "$md/bin"
|
||||||
|
cp "$SELF_ROOT/metodo.md" "$md/metodo.md"
|
||||||
|
cp "$SELF_ROOT/bin/metodo" "$md/bin/metodo"; chmod +x "$md/bin/metodo" 2>/dev/null || true
|
||||||
|
local mver adopt
|
||||||
|
mver=$(grep -E '^version:' "$SELF_ROOT/.metodo/VERSION" 2>/dev/null | sed 's/version:[[:space:]]*//')
|
||||||
|
adopt=$(git -C "$tgt" rev-parse HEAD 2>/dev/null || echo "") # marca de adopción brownfield
|
||||||
|
{ echo "# Copia vendorizada del Método (raíl C11). Gestionada por 'metodo init/update'."
|
||||||
|
echo "master: metodo"; echo "version: ${mver:-?}"; echo "estado: vendored"
|
||||||
|
[ -n "$adopt" ] && echo "adopted_commit: $adopt"; } > "$md/VERSION"
|
||||||
|
_write_checksums "$md" || echo " (aviso: sin sha256 → CHECKSUMS no escrito; la deriva no se medirá)"
|
||||||
|
printf '* text eol=lf\n' > "$md/.gitattributes" # un clone en Windows no mete CRLF ni falsea el checksum
|
||||||
|
[ -f "$md/realimentacion.md" ] || cat > "$md/realimentacion.md" <<EOF
|
||||||
|
# Realimentación del Método — repo: $(basename "$(cd "$tgt" && pwd)")
|
||||||
|
|
||||||
|
*Log append-only local, viaja con el repo. Anota cuando trabajar aquí enseñe algo del Método.
|
||||||
|
Etiquetas: [NUEVA-REGLA] · [REFINA Cn] · [Cn-NO-ENCAJA] · [FALSA]. Se cosecha con 'metodo harvest'.*
|
||||||
|
|
||||||
|
---
|
||||||
|
EOF
|
||||||
|
_scaffold_docs "$tgt"
|
||||||
|
echo "metodo init: $tgt inicializado — .metodo/ (máster $mver) + doc/ de tres capas."
|
||||||
|
echo " siguiente: siembra doc/backlog.md con el trabajo abierto de hoy y corre 'metodo check .'"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── metodo update <repo> — re-estampa el máster+linter en un repo ya iniciado ─
|
||||||
|
cmd_update() {
|
||||||
|
local tgt="${1:-.}"
|
||||||
|
_is_matriz || { echo "metodo update: sólo se corre desde la MATRIZ."; exit 2; }
|
||||||
|
local md="$tgt/.metodo"
|
||||||
|
[ -d "$md" ] || { echo "metodo update: $tgt no tiene .metodo/ — usa 'metodo init $tgt'."; exit 2; }
|
||||||
|
cp "$SELF_ROOT/metodo.md" "$md/metodo.md"
|
||||||
|
cp "$SELF_ROOT/bin/metodo" "$md/bin/metodo"; chmod +x "$md/bin/metodo" 2>/dev/null || true
|
||||||
|
local mver adopt
|
||||||
|
mver=$(grep -E '^version:' "$SELF_ROOT/.metodo/VERSION" 2>/dev/null | sed 's/version:[[:space:]]*//')
|
||||||
|
adopt=$(grep -E '^adopted_commit:' "$md/VERSION" 2>/dev/null | sed 's/adopted_commit:[[:space:]]*//') # se preserva
|
||||||
|
{ echo "# Copia vendorizada del Método (raíl C11). Gestionada por 'metodo init/update'."
|
||||||
|
echo "master: metodo"; echo "version: ${mver:-?}"; echo "estado: vendored"
|
||||||
|
[ -n "$adopt" ] && echo "adopted_commit: $adopt"; } > "$md/VERSION"
|
||||||
|
_write_checksums "$md" || echo " (aviso: sin sha256 → CHECKSUMS no escrito)"
|
||||||
|
printf '* text eol=lf\n' > "$md/.gitattributes"
|
||||||
|
echo "metodo update: $tgt actualizado al máster $mver (metodo.md + linter, byte a byte); realimentacion.md y adopted_commit preservados."
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_check() {
|
||||||
|
printf 'metodo check — %s\n' "$ROOT"
|
||||||
|
check_drift
|
||||||
|
check_ids
|
||||||
|
check_headings
|
||||||
|
check_links
|
||||||
|
check_commits
|
||||||
|
hdr "resultado"
|
||||||
|
if [ "$FAILS" -eq 0 ]; then
|
||||||
|
printf ' \033[32mPASA el Método\033[0m (0 avisos)\n'; exit 0
|
||||||
|
else
|
||||||
|
printf ' \033[31m%d aviso(s) — el Método NO pasa\033[0m\n' "$FAILS"; exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
check) ROOT="${2:-.}"; cmd_check ;;
|
||||||
|
init) cmd_init "${2:-.}" ;;
|
||||||
|
update) cmd_update "${2:-.}" ;;
|
||||||
|
harvest) printf "metodo harvest: aún no implementado (recogerá los .metodo/realimentacion.md al buzón de la matriz).\n"; exit 2 ;;
|
||||||
|
""|help|-h|--help) printf 'uso: metodo <check|init|update> [ruta]\n check linter · init vendoriza a un repo nuevo · update re-estampa (desde la matriz)\n'; exit 2 ;;
|
||||||
|
*) printf "metodo: subcomando desconocido: %s\n" "$1"; exit 2 ;;
|
||||||
|
esac
|
||||||
106
.metodo/metodo.md
Normal file
106
.metodo/metodo.md
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
# El Método — constitución
|
||||||
|
|
||||||
|
> **Versión 2026-08-08.** 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).
|
||||||
|
> Cada regla lleva su **cicatriz** (meta-principio: un raíl se escribe con el incidente que lo
|
||||||
|
> enseñó, no a priori). Procedencia, fuerza (nº de repos) y partición linter/juicio: fichero
|
||||||
|
> `constitucion-de-facto.md` de la matriz.
|
||||||
|
>
|
||||||
|
> ℹ️ Los 10 raíles base van hoy **en una línea** (su texto completo con cicatrices está pendiente de
|
||||||
|
> inlinar); lo promovido de la cosecha 2026-08-08 va **completo**. El árbol `redes` conserva su copia
|
||||||
|
> `redes/workflows/metodo.md` hasta que se desmantele.
|
||||||
|
|
||||||
|
## Raíles base (1–10)
|
||||||
|
|
||||||
|
1. Verifica el **RESULTADO**, no la intención (testigo independiente que sabe ponerse rojo).
|
||||||
|
2. El dato **CRUDO**, no el cocinado (backend mide, consumidor pinta).
|
||||||
|
3. **Mutation testing**: ataca el CABLEADO, no las funciones puras.
|
||||||
|
4. Ejercita el **FLUJO REAL** (abre el navegador, toca el device).
|
||||||
|
5. No inventes estados ni fallos **no medidos** ("sin dato", degrada a gris no a rojo).
|
||||||
|
6. Verifica la **PREMISA** del prompt (enmendar es SUSTITUIR; premisa falsa = PARAR). **← +C34**
|
||||||
|
7. **Fuente única** + copias vendidas + red anti-deriva (`--check`).
|
||||||
|
8. **Fallo benigno EXPLÍCITO**, nunca degradación silenciosa.
|
||||||
|
9. **Sesiones frescas** por stack; la continuidad la lleva el orquestador.
|
||||||
|
10. Lo que **"funciona por casualidad"** está roto.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Raíles nuevos (promovidos 2026-08-08)
|
||||||
|
|
||||||
|
### 11. El orden de lo irreversible: añadir antes de quitar · *C14 (4 fuentes)*
|
||||||
|
|
||||||
|
Todo lo verificable ocurre **antes** del paso que no se deshace. Se **añade antes de quitar**, se
|
||||||
|
crea antes de borrar; cada paso de una release se revierte por separado y ninguno depende de dos
|
||||||
|
cosas nuevas a la vez.
|
||||||
|
|
||||||
|
- Un tercer nodo de etcd entra **antes** de que salga el que se retira — al revés, el quórum se
|
||||||
|
queda en uno.
|
||||||
|
- "Nunca borres el `IPAddressPool` viejo hasta tener el nuevo sirviendo" (MetalLB).
|
||||||
|
- El cutover de un servicio con nombre: primero responde el nuevo, luego se retira el viejo.
|
||||||
|
|
||||||
|
### 12. Exploración solo-lectura, sin autoengaño · *C35 (Solidaria)*
|
||||||
|
|
||||||
|
Explorar es **medir sin tocar, y sin creerte tu propia medida**.
|
||||||
|
|
||||||
|
- `curl` **con control**: mira `/api/health`/`http_code`, no "parece que responde".
|
||||||
|
- **"Aquí no hay nada" es un RESULTADO**, no un fracaso — se anota igual que un hallazgo.
|
||||||
|
- Los **falsos positivos de `grep` son el riesgo nº1**: una lista larga de "roto" delata TU método
|
||||||
|
(un patrón demasiado amplio), no el sistema. Verifica cada hit contra la fuente antes de declararlo.
|
||||||
|
- Medir, no opinar. Sondear una escritura **ES** escribir (no es exploración).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entrega — la parte de "sacar el trabajo" (promovido 2026-08-08)
|
||||||
|
|
||||||
|
El método nació de verificación/UI; la cicatriz de **entrega** (git, secretos, naming, deploy) vivía
|
||||||
|
fuera, repetida en varios repos. Aquí se consolida.
|
||||||
|
|
||||||
|
### Naming · *C17, C32*
|
||||||
|
- **Ids con prefijo por ámbito**, **no se renumeran** (romperían citas cruzadas), y **antes de
|
||||||
|
añadir uno se corre el grep de colisión** — no basta con mirar.
|
||||||
|
- El nombre nombra **DESTINOS, no rutas**: ni el host, ni la IP, ni activo/reserva entran en un FQDN.
|
||||||
|
Se escribe como **regla**, no como observación.
|
||||||
|
- **Renombrar sin CNAME de cortesía**: que lo viejo rompa a la vista, no en silencio.
|
||||||
|
|
||||||
|
### Secretos · *C20, C21, C22*
|
||||||
|
- **Una frontera de credenciales por dominio**; aislamiento por **ServiceAccount** (ninguno con
|
||||||
|
acceso a secretos ajenos).
|
||||||
|
- **Capacidad > credencial**: se **actúa** con el secreto, no se **revela** (revelar lo deja en el
|
||||||
|
transcript); el estado raro se dice con la URL, nunca con el secreto.
|
||||||
|
- **Nunca en git**: imperativos / GPG / PushSecret, forzado por `.gitignore`; se documenta **cómo
|
||||||
|
recrearlos**, no el valor.
|
||||||
|
|
||||||
|
### Git · *C24, C25, C38*
|
||||||
|
- **Git canónico único y MEDIDO**: se empuja a un remoto y solo ahí; un fallo se **mide**
|
||||||
|
(dry-run/reintento) antes de concluir "no hay credenciales"; el remoto muerto se elimina localmente.
|
||||||
|
- **Commits Conventional** (`feat/fix/docs/ci` + scope); el `doc:` registra el **porqué**.
|
||||||
|
- **Working-tree compartido**: `git add` con ruta explícita (**nunca `-A`**), `git pull` antes de
|
||||||
|
deploy y antes de commitear docs, una tarea = una sesión/worktree.
|
||||||
|
|
||||||
|
### Deploy · *C12, C13*
|
||||||
|
- **Un solo flujo de build**, disparado **deliberadamente**, no por `git push`; el legacy es
|
||||||
|
**lápida** (código muerto conservado hasta MEDIR qué lo ejecuta, no borrado a ciegas).
|
||||||
|
- Todo cambio **por git → deploy declarativo**; imagen pineada por **DIGEST inmutable commiteado**;
|
||||||
|
el historial de commits ES el registro de auditoría.
|
||||||
|
- El **orden de lo irreversible** aplica aquí → **raíl 11**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Adiciones a raíles base (pendientes de inlinar en su raíl)
|
||||||
|
|
||||||
|
- **R6 (verifica la premisa) += C34**: las premisas del encargo se **numeran** (`P1`,`P2`…) con
|
||||||
|
veredicto explícito (verdadera / falsa / matizada + `fichero:línea`); el **ratio de premisas
|
||||||
|
falsas** es el termómetro de "escribo de memoria"; **"el doc lo dice" = premisa a verificar**.
|
||||||
|
- **Diseño de herramientas (R1/R8) += C39**: la **ausencia de una capacidad es un guardarraíl**. El
|
||||||
|
poder peligroso se **retiene estructuralmente** (no se expone porque no se construye): vocabulario
|
||||||
|
cerrado, sin `exec`/SQL/comando libre.
|
||||||
|
- **Docs / R7 += C30**: el **docstring/manual ES la interfaz**. Cambia el comportamiento → cambia el
|
||||||
|
docstring en el **mismo commit**; un doc que miente **ES el bug**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## La estructura de sesión no vive aquí
|
||||||
|
|
||||||
|
Los dos ejes **fase × persona** y el **handoff automático** entre fases son **procedimiento**, no
|
||||||
|
principio → viven en la capa `workflows/`, con la capa **persona opcional** (se activa solo con
|
||||||
|
interlocutor no-técnico; en infra en solitario, inactiva pero documentada).
|
||||||
6
.metodo/realimentacion.md
Normal file
6
.metodo/realimentacion.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Realimentación del Método — repo: smtp-relay
|
||||||
|
|
||||||
|
*Log append-only local, viaja con el repo. Anota cuando trabajar aquí enseñe algo del Método.
|
||||||
|
Etiquetas: [NUEVA-REGLA] · [REFINA Cn] · [Cn-NO-ENCAJA] · [FALSA]. Se cosecha con 'metodo harvest'.*
|
||||||
|
|
||||||
|
---
|
||||||
6
doc/AVISOS.md
Normal file
6
doc/AVISOS.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# ⚠️ AVISOS
|
||||||
|
|
||||||
|
**Lo que hay que saber el primer día.** Se lee antes que el backlog. Cada aviso dice quién lo cierra.
|
||||||
|
|
||||||
|
| # | Qué | Estado | Quién lo cierra |
|
||||||
|
|---|---|---|---|
|
||||||
11
doc/backlog.md
Normal file
11
doc/backlog.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Backlog
|
||||||
|
|
||||||
|
> Tres capas: **este backlog** = estado (metas + decisiones cerradas `D` + items) ·
|
||||||
|
> AVISOS.md = bandera (se lee primero) · bitacora.md = relato append-only.
|
||||||
|
> Método vendorizado en ../.metodo/metodo.md. ⛔ Las `D` son inmutables. Un `##` no lleva marca de
|
||||||
|
> estado; abierto = tiene `[ ]`.
|
||||||
|
|
||||||
|
## Decisiones cerradas
|
||||||
|
|
||||||
|
## Abierto
|
||||||
|
- [ ] (siembra aquí el trabajo ABIERTO de hoy — brownfield: el pasado no se reconstruye)
|
||||||
5
doc/bitacora.md
Normal file
5
doc/bitacora.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Bitácora
|
||||||
|
|
||||||
|
*Relato append-only. Lo nuevo va ABAJO. Se lee por fecha.*
|
||||||
|
|
||||||
|
---
|
||||||
Loading…
Reference in New Issue
Block a user