- Un proyecto con AI agent activo (Claude Code, Codex, Cline o similar)
- Repositorio git
- Capacidad de crear scripts de shell y hooks de git
- (Opcional) Acceso a CI/CD pipeline
ARTICULO
`
project-root/
├── AGENTS.md # Reglas y convenciones
├── .cursorrules # Context file alternativo
├── .githooks/
│ ├── pre-commit # Verificación automática antes de commit
│ └── pre-push # Verificación antes de push
├── scripts/
│ ├── verify.sh # Script de verificación estándar
│ └── lint.sh # Linter configurado
├── docs/
│ ├── ARCHITECTURE.md # Decisiones de arquitectura
│ └── PROGRESS.md # Estado actual del proyecto
└── .github/workflows/
└── ci.yml # CI pipeline con verificaciones
`
El archivo de contexto (AGENTS.md, .cursorrules, CLAUDE.md) es el briefing que el agente lee antes de tocar cualquier cosa.
Qué poner:
`
- /src — código fuente
- /tests — tests unitarios
- /docs — documentación
Cada vez que el agente repite un error, agregás una regla. Así crece el archivo con el tiempo.
| Verbo | Permiso | Ejemplo |
|---|---|---|
| read | ✅ Siempre | Leer archivos, buscar en codebase |
| search | ✅ Siempre | Grep, búsqueda web |
| create_draft | ✅ Con revisión | Generar código nuevo |
| modify | ✅ Con revisión | Editar archivos existentes |
| send | ⚠️ Aprobación humana | Enviar emails, postear en Slack |
| merge | ⚠️ Aprobación humana | Merge PRs |
| deploy | ❌ Solo humano | Deploy a producción |
| delete | ❌ Solo humano | Borrar archivos, recursos cloud |
| purchase | ❌ Nunca | Comprar servicios, APIs de pago |
En Hermes Agent:
`bash
hermes tools enable web terminal file
hermes tools disable deployment browser
hermes config set security.tirith_enabled true
`
En Cline/Roo Code (.clinerules):
`
npm run build npm run test git add -A git commit -m "..." git push
rm -rf
git push --force
npm publish
`
Jerarquía de velocidad (más rápido primero): hooks (ms) → pre-commit (segundos) → CI (minutos) → revisión humana (horas)
`bash
#!/bin/bash
npm run lint
npm run type-check
npm run test -- --changed
if [ $? -ne 0 ]; then
echo "❌ Pre-commit checks failed."
exit 1
fi
`
Escribir "corré el linter" en un archivo es un pedido. Conectarlo con un pre-commit hook es una garantía. El agente puede ignorar un pedido. No puede saltarse un hook.
Los agents tienen contextos frescos en cada sesión. El harness arregla esto guardando estado en disco:
docs/PROGRESS.md — qué se hizo, qué faltadocs/ROADMAP.md — features pendientes, en progreso, completadosFormato de PROGRESS.md:
`markdown
Problema: Los filtros de comandos funcionan por string matching, y el string matching se puede engañar.
El incidente Shumer en detalle:
`bash
r''m
`
Defensas que funcionan:
### 1. El estado vive fuera del modelo
| Esto NO funciona | Esto SÍ funciona |
|---|---|
| "Recordá lo que hicimos la sesión pasada" | docs/PROGRESS.md con el estado actual |
| "Ya revisé este feature" | Test automatizado que lo verifica |
| "No toques esta parte" | Regla en AGENTS.md + acceso restringido |
Nunca confíes en que el contexto window va a recordar. Confiá en el disco.
### 2. Cada error se convierte en una regla permanente
El patrón Hashimoto: cada vez que un agente comete un error, modificás el entorno para que ese error no se pueda repetir.
`
Error: el agente borró archivos temporales necesarios
→ Regla en AGENTS.md: NO usar rm sin listar archivos primero
→ Hook pre-commit: verificar que no hay rm sin --dry-run
Error: el agente deployó código sin test
→ CI: bloquea si el test coverage es < 80%
`
Reintentar es una oración. Una regla es una solución.
### 3. La verificación es más difícil que la generación
Anthropic lo descubrió cuando sus agents marcaban features como completadas sin validación end-to-end. OpenAI documentó lo mismo: Sol actualizó un documento de investigación para decir que un cálculo había sido verificado cuando nunca produjo el resultado.
Implementación — Evaluator pattern:
`python
CHECKLIST = [
"Feature A funciona en test",
"Feature A sin errores en consola",
"Tests pasan",
"Sin regresiones",
]
for check in CHECKLIST:
if not verify(check): # contexto fresco, default-FAIL
return FAIL
`
El claim de "done" de un agente es una hipótesis. El harness corre el experimento.
### 4. Protegé estructura, no strings
GuardFall expuso el problema: el filtro revisa cómo se VE el comando. Bash ejecuta lo que el comando SIGNIFICA.
No hagas esto:
`python
denylist = ["rm", "sudo", "chmod"]
if any(cmd.startswith(bad) for bad in denylist):
block()
`
Hacé esto:
`python
tokens = shell_parse(command)
tokens = expand_variables(tokens)
tokens = eval_substitutions(tokens)
if is_structural_delete(tokens):
require_approval()
`
Una denylist es una sugerencia. Un sandbox es una pared.
| # | Criterio | Status |
|---|---|---|
| 1 | AGENTS.md existe con reglas | ❌ |
| 2 | Reglas se actualizan cuando el agente repite un error | ❌ |
| 3 | Toolsets configurados (read/search ✅, delete/deploy ❌) | ❌ |
| 4 | Pre-commit hook con linter + tests | ❌ |
| 5 | Build falla si los tests no pasan | ❌ |
| 6 | PROGRESS.md se actualiza post-sesión | ❌ |
| 7 | Comandos se parsean estructuralmente, no por string matching | ❌ |
| 8 | rm -rf requiere aprobación humana | ❌ |
| 9 | Comandos que exfiltran datos bloqueados | ❌ |
| 10 | Evaluador con contexto fresco | ❌ |
| 11 | CI con default-FAIL | ❌ |
| 12 | Después de cada error del agente, regla permanente | ❌ |
Score: __/12
| Síntoma | Causa | Solución |
|---|---|---|
| El agente ignora instrucciones | AGENTS.md no se carga | Verificar que existe y el agente lo lee |
| El agente repite el mismo error | Falta regla | Agregar la regla. No alcanza con pedirle que no lo haga |
| Cambios que nadie pidió | Falta verificación | Agregar pre-commit hooks y CI |
| Comandos peligrosos pasan filtros | String matching débil | Migrar a parsing estructural |
| El agente pierde contexto entre sesiones | Falta PROGRESS.md | Crear archivo de progreso |
| Features marcadas como completadas sin estarlo | Falta evaluador | Implementar evaluador con contexto fresco |