chore(metodo): C26 — cada commit dice QUIEN lo hizo
git no tiene concepto de sesion, pero el mensaje si lo controlamos. Un trailer «Sesion: <rol>/<frente>» hace visibles en el log los filos del working tree compartido. Se juzga desde un punto de adopcion sellado por repo, asi que la historia anterior queda fuera por construccion. Sesion: superadmin Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b1301bbc91
commit
35a6b1ef7a
@ -1,5 +1,5 @@
|
||||
fd01f9f41dfbe394fcf94dbda8f9fcaf35bae1368755b7e9c47a9c9c1d35f1ec metodo.md
|
||||
c8b7746c26471b6b041abbea1583d2bf6e5b13020df63ca1b9503fa0b4757ec3 bin/metodo
|
||||
5ff67472a10f22c9425a3d0a4395d32930010c65499a2a6ce4e958ea47311f6c metodo.md
|
||||
d911bec6c3b969cce80d0a5c500780dde348eb3b0e8d15bb4ef61dbce5c8181e bin/metodo
|
||||
f89b71bdf31028b05075636c1763c964e379bc37a00e0357d1c23a4dd19c09aa workflows/README.md
|
||||
cc241bbecf9647c747b8525b3a6b527455cd50ca0312caa44bc3544342c8ac41 workflows/comunicacion-entre-sesiones.md
|
||||
2b9037f6dd57b5598c70a676cb728556654f05d1c5b024e7b716864659f7b884 workflows/sesion-ejecucion.md
|
||||
|
||||
@ -3,3 +3,4 @@ master: metodo
|
||||
version: 2026-08-30
|
||||
estado: vendored
|
||||
adopted_commit: 6a10eab342a477846ab5f3e67f8ab17169f12807
|
||||
sesion_desde: b1301bbc911b9dbf750654d841b56ca0de9ee615
|
||||
|
||||
@ -111,6 +111,34 @@ _huella_reparto() { { tr -d '\r' < "$SELF_ROOT/metodo.md"; tr -d '\r' < "$SELF_R
|
||||
# ⚠️ Se ata lo decidible: que lo declarado EXISTA. ⛔ Lo contrario —cazar un fichero que está y no
|
||||
# está declarado— NO se ata, y se dice por qué: exigiría una definición de «línea base» del corpus
|
||||
# que hoy no existe, y un gate que la adivinara daría rojos crónicos. Queda como criterio humano.
|
||||
# ⛔ C26 · QUIÉN LO HIZO (2026-08-31, idea de Xavier). `git` no tiene concepto de sesión: sólo ve un
|
||||
# working tree y un usuario, el mismo para todas. **El mensaje sí lo controlamos.** Un trailer con el
|
||||
# ROL —no el nombre de sesión, que rota en cada reinicio— convierte los cuatro filos del árbol
|
||||
# compartido en algo VISIBLE: un arrastre, un --amend ajeno o un push de lo de otra se leen en el log.
|
||||
# Sesion: <rol>/<frente> p.ej. Sesion: orquestadora/securizacion · Sesion: superadmin
|
||||
# Se juzga desde `sesion_desde:` de .metodo/VERSION (sellado la primera vez que este check llega al
|
||||
# repo) ⇒ la historia anterior queda FUERA POR CONSTRUCCIÓN, no por una lista de excepciones que
|
||||
# crecería para siempre.
|
||||
check_sesion_trailer() {
|
||||
local md="$ROOT/.metodo" desde n mal
|
||||
[ -d "$md" ] || md="$ROOT/.metodo"
|
||||
git -C "$ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1 || { skip "no es repo git — sin commits que medir"; return 0; }
|
||||
hdr "cada commit dice QUIÉN lo hizo (C26)"
|
||||
desde=$(grep -E '^sesion_desde:' "$md/VERSION" 2>/dev/null | sed 's/sesion_desde:[[:space:]]*//')
|
||||
[ -n "$desde" ] || { info "sin punto de adopción todavía — se sella en el próximo 'metodo update'"; return 0; }
|
||||
git -C "$ROOT" cat-file -e "$desde^{commit}" 2>/dev/null || { skip "el punto de adopción $desde no existe en este repo"; return 0; }
|
||||
n=0; mal=0
|
||||
while read -r sha; do
|
||||
[ -z "$sha" ] && continue
|
||||
n=$((n+1))
|
||||
git -C "$ROOT" log -1 --format='%B' "$sha" | grep -qE '^Sesion:[[:space:]]*\S' || {
|
||||
bad "commit sin 'Sesion:' — $(git -C "$ROOT" log -1 --format='%h %s' "$sha" | cut -c1-70) (C26)"; mal=$((mal+1)); }
|
||||
done <<EOF
|
||||
$(git -C "$ROOT" rev-list "$desde..HEAD" 2>/dev/null)
|
||||
EOF
|
||||
[ "$mal" -eq 0 ] && ok "$n commit(s) desde la adopción, todos dicen quién los hizo"
|
||||
}
|
||||
|
||||
check_incremento() {
|
||||
local f="$ROOT/.metodo/INCREMENTO"
|
||||
hdr "incrementos declarados (lo que este repo tiene DE MÁS)"
|
||||
@ -918,7 +946,11 @@ cmd_init() {
|
||||
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"
|
||||
[ -n "$adopt" ] && echo "adopted_commit: $adopt"
|
||||
# C26: punto de adopción del trailer de sesión — se sella UNA vez y se preserva.
|
||||
_sd=$(grep -E "^sesion_desde:" "$md/VERSION" 2>/dev/null | sed "s/sesion_desde:[[:space:]]*//")
|
||||
[ -z "$_sd" ] && _sd=$(git -C "$tgt" rev-parse HEAD 2>/dev/null)
|
||||
[ -n "$_sd" ] && echo "sesion_desde: $_sd"; } > "$md/VERSION.new" && mv "$md/VERSION.new" "$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
|
||||
@ -970,7 +1002,11 @@ cmd_update() {
|
||||
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"
|
||||
[ -n "$adopt" ] && echo "adopted_commit: $adopt"
|
||||
# C26: punto de adopción del trailer de sesión — se sella UNA vez y se preserva.
|
||||
_sd=$(grep -E "^sesion_desde:" "$md/VERSION" 2>/dev/null | sed "s/sesion_desde:[[:space:]]*//")
|
||||
[ -z "$_sd" ] && _sd=$(git -C "$tgt" rev-parse HEAD 2>/dev/null)
|
||||
[ -n "$_sd" ] && echo "sesion_desde: $_sd"; } > "$md/VERSION.new" && mv "$md/VERSION.new" "$md/VERSION"
|
||||
_write_checksums "$md" || echo " (aviso: sin sha256 → CHECKSUMS no escrito)"
|
||||
printf '* text eol=lf\n' > "$md/.gitattributes"
|
||||
_stamp_gitattributes "$tgt"
|
||||
@ -999,6 +1035,7 @@ cmd_check() {
|
||||
printf 'metodo check — %s\n' "$ROOT"
|
||||
check_drift
|
||||
check_apendices_no_viajan
|
||||
check_sesion_trailer
|
||||
check_incremento
|
||||
check_reparto_al_dia
|
||||
check_semaforo_forma
|
||||
|
||||
@ -1906,6 +1906,40 @@ pega tal cual.
|
||||
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.
|
||||
El canal sabe quién eres. El linter sabe en qué repo estás. **`git` sólo ve un working tree y un
|
||||
usuario** — y en este árbol **ese usuario es el mismo para todas**.
|
||||
⇒ Por eso **todos los filos aparecen ahí**, y por eso **ninguno lo caza un gate: no hay dato con el
|
||||
que un gate pudiera distinguirlos.** ⭐ Y eso **no es una excusa: es el criterio para parar** —
|
||||
buscarle un gate a esto es construir un instrumento sin sujeto, que es la avería que este Método más
|
||||
persigue. **Lo que sí se puede es avisar antes y decirlo después.**
|
||||
⛔ **Corolario, y es el más traicionero: `--amend` en un árbol compartido NO es una operación local.**
|
||||
Su único testigo es **un `push` rechazado**, o sea **un fallo que puede no llegar a producirse**. ⇒
|
||||
**`--amend` sólo es seguro sobre un `HEAD` que has VERIFICADO que sigue siendo tuyo** —`git log -1`—,
|
||||
nunca sobre el que recuerdas haber hecho.
|
||||
|
||||
⭐⭐ **Y LA MITAD QUE SÍ SE PUEDE ATAR, PORQUE EL MENSAJE SÍ LO CONTROLAMOS: CADA COMMIT DICE QUIÉN LO
|
||||
HIZO.** `git` no tiene concepto de sesión — pero **el mensaje es nuestro**. Un *trailer* con el **ROL**
|
||||
convierte los cuatro filos de arriba en algo **visible en el `log`**: un arrastre, un `--amend` ajeno
|
||||
o un `push` que publica lo de otra **se leen**, en vez de descubrirse por un rechazo que puede no
|
||||
llegar.
|
||||
|
||||
Sesion: <rol>/<frente> p. ej. Sesion: orquestadora/securizacion
|
||||
Sesion: ejecucion/hermes-infra
|
||||
Sesion: superadmin
|
||||
|
||||
⛔ **El ROL, no el nombre de sesión**: los nombres **rotan en cada reinicio** y el usuario **no los
|
||||
ve** — un `log` lleno de identificadores caducados no identifica a nadie. El rol **sobrevive al
|
||||
reinicio y significa algo dentro de seis meses**, que es cuando se lee un `log`.
|
||||
⇒ Se ata (`C26`) **desde un punto de adopción sellado por repo**, así que **la historia anterior queda
|
||||
fuera POR CONSTRUCCIÓN** — no por una lista de excepciones que crecería para siempre. *(Es la lección
|
||||
del rojo crónico aplicada al diseñar el gate, no después de sufrirlo.)*
|
||||
⭐ **Y lo que esto arregla de fondo**: hasta aquí, la única atribución que existía era **el mensaje**,
|
||||
y por eso *«un commit ajeno bajo un mensaje que habla de otra cosa borra la única atribución que
|
||||
hay»*. Con el trailer, **la atribución deja de depender de que el mensaje la mencione de pasada**:
|
||||
está en un campo, es constante, y **se puede contar**.
|
||||
- La **representación en disco es parte del artefacto**: cuando un hash o un runtime consume el
|
||||
checkout, se fija con el repo — **eol** por `.gitattributes` y **bit de ejecución** — o el testigo
|
||||
mide el checkout, no el contenido (una DERIVA falsa en un clone sin tocar entrena a ignorar el
|
||||
|
||||
Loading…
Reference in New Issue
Block a user