Files
fn_registry/.claude/rules/autonomous_loop.md
T
egutierrez a03675113a chore: auto-commit (286 archivos)
- .claude/agents/fn-orquestador/SKILL.md
- .claude/commands/fn_claude.md
- .claude/rules/INDEX.md
- .claude/rules/cpp_apps.md
- .claude/rules/ids_naming.md
- CHANGELOG.md
- apps/dag_engine/README.md
- apps/dag_engine/api.go
- apps/dag_engine/dags_migrated/example.yaml
- apps/dag_engine/dags_migrated/example_lineage_tracking.yaml
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 16:33:22 +02:00

76 lines
5.3 KiB
Markdown

## Bucle autonomo (`fn-orquestador` + `/autonomous-task`) — issue 0069
`fn-orquestador` recorre el ciclo reactivo (CONSTRUIR → EJECUTAR → RECOPILAR → ANALIZAR → MEJORAR) sin intervencion humana, hasta convergencia (suite verde), estancamiento (no progreso N iteraciones), timeout, o tope de iteraciones. Trabaja SIEMPRE en sandbox `auto/<issue>`, NUNCA merge a master.
### Cuando se invoca
- Skill `/autonomous-task <issue_id>` (humano lanza explicitamente).
- Cron / Dagu (planificable; no implementado por defecto).
- NO se invoca como reaccion a hooks ni a fallos de tests "en caliente". Siempre tarea explicita.
### Reglas duras
1. **Sandbox obligatorio**: rama `auto/<issue_id>-<slug>`. Si la rama existe -> reset hard contra master y reanudar. NUNCA commits a master, NUNCA push --force-with-lease a master.
2. **Paths protegidos**: respetar `dev/autonomous_protected_paths.json` exactamente. Cualquier intento de modificar un path protegido aborta la iteracion y registra `task_runs.status='aborted_protected_path'`.
3. **Filtro de proposals auto-aplicables**: el orquestador SOLO aplica proposals que cumplen:
- `kind in (bug_fix, e2e_check_add, doc_update, capability_tag_add)` -> auto-aplicable.
- `kind in (new_function, deprecate_function, refactor, schema_change)` -> NO auto-aplicable (queda `pending` para humano).
- `priority in (low, medium)` -> auto-aplicable. `high|critical` -> requiere humano salvo override `--allow-high`.
4. **Watchdog**: si la metrica de progreso (`checks_pass / checks_total`) no sube en `N=3` iteraciones consecutivas -> abort. Registrar `task_runs.status='stalled'`.
5. **Tiempo**: cada `task_run` con timeout default 30 min. Override con `--timeout-min N` hasta max 4h.
6. **Idempotencia**: re-ejecutar `/autonomous-task <id>` sobre la misma issue reanuda desde la ultima iteracion exitosa, NO reinicia desde cero (lookup en `task_runs` por `issue_id`).
7. **Trazabilidad**: cada decision se persiste en `task_runs.events_json[]` con `{ts, agent, action, evidence, diff_summary}`. El humano puede leer el log entero para auditar.
8. **No self-modification**: orquestador NUNCA modifica `.claude/agents/`, `.claude/commands/`, `.claude/rules/`, `.claude/scripts/`, `.claude/CLAUDE.md`. Reforzado en `autonomous_protected_paths.json`.
9. **NUNCA paths absolutos fuera del worktree**. Refuerzo del piloto 1 (2026-05-15): el orquestador uso `/home/lucas/fn_registry/bash/functions/...` para fixear hooks bash y contamino el repo principal. Solucion correcta: fix vive solo en el worktree. Post-cada-iteracion: `git -C <main_repo> status --short` debe permanecer igual al baseline; cualquier diff = `status=sandbox_breach` -> ABORT.
10. **Pre-commit hooks compartidos**. Worktrees comparten `.git/hooks/` con main. Si un hook llama scripts via path absoluto, ejecutara la version de main. Si el hook bloquea progreso por bug en main: aplica el fix EN EL WORKTREE (commit en auto/*); si el bug del hook excede scope: `git commit --no-verify` para ESE commit con `task_runs.events_json[].decision="skip_hook"` + razon. NO editar main.
### Estructura task_run
Migration `fn_operations/migrations/006_task_runs.sql`. Campos minimos: `id`, `issue_id`, `branch`, `started_at`, `finished_at`, `status` (`running|done|failed|aborted_protected_path|stalled|timeout`), `iterations`, `checks_pass`, `checks_fail`, `proposals_applied_json`, `proposals_skipped_json`, `events_json`, `final_diff_sha`.
### Fases por iteracion
```
loop:
1. fn-constructor (Read+Edit+Write+Bash limitados) - aplica fix segun ultima proposal seleccionada
2. fn-executor - corre build + tests + smoke
3. fn-recopilador - audita operations.db de la app
4. fn-analizador - corre e2e_checks (registra e2e_runs)
5. SI todos los checks pasan -> commit + push rama + abre PR. status=done. exit.
6. SI no progreso N iteraciones -> abort. status=stalled.
7. fn-mejorador - crea proposals desde fallos
8. orquestador filtra proposals auto-aplicables -> selecciona la primera -> goto 1.
```
### Output al humano
```
=== /autonomous-task 0068 ===
task_run_id: run_e2e_a1b2c3
branch: auto/0068-e2e-validation
iterations: 4
status: done
checks_pass: 8/8
proposals_applied: 3 (run_e2e_run_001, run_e2e_run_002, run_e2e_run_003)
proposals_skipped: 1 (refactor — needs human review)
PR: https://gitea.../pulls/42
```
### Anti-patrones
| Anti-patron | Por que es malo |
|---|---|
| Mergear `auto/<issue>` a master sin PR + humano | Salta gate, riesgo de regresion |
| Auto-aplicar proposal `kind=refactor` | Cambios sistemicos requieren revision |
| Modificar `go.sum`, `package-lock.json`, `uv.lock` | Cambios de deps requieren CVE/license review |
| Bucle infinito sin watchdog | Coste descontrolado de tokens |
| Borrar archivos sin backup en `task_runs.events_json` | Pierde auditoria |
| Override de paths protegidos via env var | Bypass de seguridad |
### Relacion con otras reglas
- [[e2e_validation]] — fn-analizador (fase 4) lee el contrato `e2e_checks` que el orquestador usa como gate.
- [[apps_tbd]] — el orquestador opera en rama `auto/*`, no exenta de TBD.
- [[feature_flags]] — si el fix no esta terminado, el orquestador puede meterlo detras de flag OFF antes de PR.
- [[registry_calls]] — toda invocacion del orquestador y sub-agentes pasa por MCP/`fn run`/heredoc canonico, registrada en call_monitor.