feat(episode): TRAZA_checkpoint-antes-de-tocar-el-hook-paso_S20260518.R31_XX.ops.2.hot_inf.in.cc.es.000.MGQ_J.PMCFK_E.SGNFD

Skill: AEGIS | Type: troubleshooting
Summary: EPISODIO 31 — HANDOFF_PROMPT.md: Checkpoint — antes de tocar el hook (paso 6)
This commit is contained in:
Ember 2026-05-20 01:04:10 +00:00
parent f5741e88a4
commit b222c896b3

View file

@ -0,0 +1,46 @@
---
episode_id: "59b5a5cf-9efe-41f0-a911-e9c4b8ddf0a2"
puente_flat: "TRAZA_checkpoint-antes-de-tocar-el-hook-paso_S20260518.R31_XX.ops.2.hot_inf.in.cc.es.000.MGQ_J.PMCFK_E.SGNFD"
session_code: "S20260518.PIPELINE_FIXES"
acto_dialogico: "informar"
actor_flujo: "multi_actor"
criticidad_aegis: "low"
skill_dominante: "AEGIS"
fase_proyecto: "operations"
tipo_semantico: "troubleshooting"
summary_one_line: "EPISODIO 31 — HANDOFF_PROMPT.md: Checkpoint — antes de tocar el hook (paso 6)"
source_type: "claude_code"
trust_boundary: "internal"
created_at: "2026-05-20T01:03:11.643827+00:00"
relectura_tagged: false
forgejo_commit_sha: "pending"
---
Paso 5 — **verde**. Fase 5 pasos 1-5 completos.
## Checkpoint — antes de tocar el hook (paso 6)
**Lo que está construido y probado** (todo aislado — `mega-hook-ssh.py` sigue intacto):
| Artefacto | Estado |
|---|---|
| `docs/HALLAZGO_SSH_HOOK_QUOTE_BYPASS_S20260518.md` | spec del fix |
| `policies/` — modelo + 2 CSV | constitución declarativa (13 patrones) |
| `casbin-poc/casbin_ssh_authz.py` | motor corregido — extrae el payload, decide vía Casbin |
| `casbin-poc/test_casbin_ssh_authz.py` | 217 verificaciones + 7 tests pytest, todos verdes |
Los tests prueban contra el comportamiento **correcto**: los 3 casos que el hook roto permite hoy (`rm -rf`, `git push --force`, `docker prune` en forma `ssh "..."`) ahora dan `deny`; el caso#4 (`sed` que menciona `rm`) da `warn`, sin over-trigger.
**Lo que hace el paso 6** — la integración al hook vivo:
- Mover `casbin_ssh_authz.py` a su hogar de producción `.claude/hooks/lib/`.
- En `mega-hook-ssh.py`: reemplazar las secciones DESTRUCTIVE + MODIFY (L133-191) y la función `_is_inside_quotes` por una llamada a `evaluate(command, enabled_rules)`.
- **Conservar** todo lo demás del hook: SSH-scope gate, override flag, `ssh_mode` (BLOCK/WARN/OFF), toggles de config (pasados como `enabled_rules`), logging, formato de salida JSON.
- Backup `.bak` previo. Paso 7: re-correr el sondeo sobre el hook integrado para verificar in-vivo.
**Disclosures honestas (PROCEDENCIA):**
- El hueco de seguridad **sigue abierto en el hook vivo** hasta que el paso 6 integre el fix. La lógica está probada; la integración se verifica en el paso 7.
- Limitación residual 1: `psql -c 'DROP TABLE'` — destructivo dentro de una comilla que ejecuta — sigue `allow` (pre-existente, no regresión, documentado).
- Limitación residual 2 (la hallé al escribir los tests): la forma **sin comillas** `ssh cx43 sed -i 's/rm -rf/x/' f` da `deny` (falso positivo) — el shell local quita las comillas y deja `rm -rf` suelto. Es fail-closed (molesto, no peligroso); la forma con comillas funciona bien. La añado a la sec. 6 del doc.
- Capa C (mutation testing con mutmut) — declarada pendiente; no ejecutada.
**Reframe:** la lógica del fix está probada en aislamiento; lo que resta es el cableado al hook vivo. El riesgo pasa de "¿es correcta la lógica?" (resuelto: verde) a "¿la integración preserva las demás responsabilidades del hook?" — y eso lo verifica el paso 7. Es reversible (backup + `git checkout`).