chore(plan): marca Phase F (Tasks 21-25) completada

Nota de desviación: fastapi/uvicorn instalados, routers con estilo Annotated[T, Depends],
orchestrator.snapshot() en vez de _build_graph_for_snapshot, fixture default + tests extra.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Juan
2026-05-10 15:40:57 +02:00
co-authored by Claude Opus 4.7
parent 09ec79a464
commit 19bac2bcdc
+30 -21
View File
@@ -3454,6 +3454,15 @@ git commit -m "feat(runtime): añade AgentOrchestrator para invoke + resume + sn
## Phase F — FastAPI Core (Tasks 2125) ## Phase F — FastAPI Core (Tasks 2125)
> **Nota de implementación (desviación del plan):**
> - `fastapi`/`uvicorn` no estaban instalados en el venv; se instalaron (`fastapi 0.119.1`, `uvicorn 0.31.1`).
> - Los routers usan el estilo `Annotated[T, Depends(...)]` (sin `Depends()` en defaults) para pasar ruff B008; los aliases (`RegistryDep`, `PolicyStoreDep`, `OrchestratorDep`, `SettingsDep`) viven en `api/deps.py`.
> - El orchestrator (ver Phase E) abre el checkpointer por llamada, así que el helper `_build_graph_for_snapshot` del Task 24 no aplica. En su lugar `AgentOrchestrator` expone un método público `snapshot(agent_def, policy, trace_id) -> AgentExecution | None`; el router `GET /executions/{trace_id}` y los gates de approve/reject lo usan.
> - Tests del core usan `tests/fixtures/policies/default/` (fixture mínima sin validadores) además del agente `incident_analyzer` del Task 23.
> - Se añadieron tests no contemplados en el plan: `test_persistence.py`, `test_api_executions.py`, `test_api_policies_violations.py`, y dos tests de `orchestrator.snapshot()`.
> - Los bloques de código de los Tasks 21-25 son la versión original del plan; la **versión autoritativa es la committeada** (typing mypy-strict, manejo de errores, etc.).
### Task 21: Persistence helpers (JSONL append-only) + DI ### Task 21: Persistence helpers (JSONL append-only) + DI
**Files:** **Files:**
@@ -3461,7 +3470,7 @@ git commit -m "feat(runtime): añade AgentOrchestrator para invoke + resume + sn
- Create: `core/src/agentforge_core/api/persistence.py` - Create: `core/src/agentforge_core/api/persistence.py`
- Create: `tests/unit/test_persistence.py` - Create: `tests/unit/test_persistence.py`
- [ ] **Step 1: Test** - [x] **Step 1: Test**
```python ```python
"""Tests de los helpers de persistencia JSONL.""" """Tests de los helpers de persistencia JSONL."""
@@ -3516,7 +3525,7 @@ def test_append_execution_anade_a_existente(tmp_path: Path) -> None:
assert len(lines) == 2 assert len(lines) == 2
``` ```
- [ ] **Step 2: Implementar `persistence.py`** - [x] **Step 2: Implementar `persistence.py`**
```python ```python
"""Helpers de persistencia append-only en JSONL para auditoría.""" """Helpers de persistencia append-only en JSONL para auditoría."""
@@ -3581,7 +3590,7 @@ def read_execution_summaries(data_dir: Path) -> list[AgentExecutionSummary]:
return out return out
``` ```
- [ ] **Step 3: Implementar `deps.py` (DI singletons)** - [x] **Step 3: Implementar `deps.py` (DI singletons)**
```python ```python
"""Dependencias compartidas inyectadas en los routers FastAPI.""" """Dependencias compartidas inyectadas en los routers FastAPI."""
@@ -3635,7 +3644,7 @@ def get_orchestrator() -> AgentOrchestrator:
) )
``` ```
- [ ] **Step 4: Verificar y commit** - [x] **Step 4: Verificar y commit**
```bash ```bash
pytest tests/unit/test_persistence.py -v pytest tests/unit/test_persistence.py -v
@@ -3652,7 +3661,7 @@ git commit -m "feat(api): añade persistencia JSONL y DI con factories cacheadas
- Create: `core/src/agentforge_core/main.py` - Create: `core/src/agentforge_core/main.py`
- Create: `tests/unit/test_health.py` - Create: `tests/unit/test_health.py`
- [ ] **Step 1: Test** - [x] **Step 1: Test**
```python ```python
"""Test del endpoint de health.""" """Test del endpoint de health."""
@@ -3683,7 +3692,7 @@ def test_trace_id_header_se_propaga_si_viene() -> None:
assert r.headers["x-trace-id"] == "fixed-123" assert r.headers["x-trace-id"] == "fixed-123"
``` ```
- [ ] **Step 2: Implementar `middlewares.py`** - [x] **Step 2: Implementar `middlewares.py`**
```python ```python
"""Middleware de propagación de trace_id.""" """Middleware de propagación de trace_id."""
@@ -3712,7 +3721,7 @@ class TraceIdMiddleware(BaseHTTPMiddleware):
clear_trace_id() clear_trace_id()
``` ```
- [ ] **Step 3: Implementar `main.py`** - [x] **Step 3: Implementar `main.py`**
```python ```python
"""Composición raíz de la aplicación FastAPI.""" """Composición raíz de la aplicación FastAPI."""
@@ -3752,7 +3761,7 @@ def create_app() -> FastAPI:
app = create_app() app = create_app()
``` ```
- [ ] **Step 4: Verificar y commit** - [x] **Step 4: Verificar y commit**
Nota: el test fallará temporalmente porque importa routers que aún no existen. Comentamos las líneas `include_router` si hace falta para esta task aislada, pero es preferible escribir routers en la misma tanda. Para mantener TDD honesto, dejamos los routers como stubs vacíos en el siguiente paso. Nota: el test fallará temporalmente porque importa routers que aún no existen. Comentamos las líneas `include_router` si hace falta para esta task aislada, pero es preferible escribir routers en la misma tanda. Para mantener TDD honesto, dejamos los routers como stubs vacíos en el siguiente paso.
@@ -3781,7 +3790,7 @@ git commit -m "feat(api): scaffolding FastAPI con TraceIdMiddleware, /health y r
- Create: `tests/fixtures/agents/incident_analyzer/index.yaml` (mínimo para test) - Create: `tests/fixtures/agents/incident_analyzer/index.yaml` (mínimo para test)
- Create: `tests/fixtures/agents/incident_analyzer/versions/v1.yaml` - Create: `tests/fixtures/agents/incident_analyzer/versions/v1.yaml`
- [ ] **Step 1: Crear fixtures (mínimo viable; los completos vendrán en Phase G)** - [x] **Step 1: Crear fixtures (mínimo viable; los completos vendrán en Phase G)**
`tests/fixtures/agents/incident_analyzer/index.yaml`: `tests/fixtures/agents/incident_analyzer/index.yaml`:
```yaml ```yaml
@@ -3816,7 +3825,7 @@ risk_threshold_for_hitl: 4
updated_at: 2026-04-01T00:00:00Z updated_at: 2026-04-01T00:00:00Z
``` ```
- [ ] **Step 2: Test** - [x] **Step 2: Test**
```python ```python
"""Tests del router /agents.""" """Tests del router /agents."""
@@ -3873,7 +3882,7 @@ def test_list_versions() -> None:
assert r.json()[0]["id"] == "v1" assert r.json()[0]["id"] == "v1"
``` ```
- [ ] **Step 3: Implementar router** - [x] **Step 3: Implementar router**
Modificar `core/src/agentforge_core/api/agents.py`: Modificar `core/src/agentforge_core/api/agents.py`:
```python ```python
@@ -3941,7 +3950,7 @@ def diff_versions(
return registry.diff_versions(name, v_from, v_to) return registry.diff_versions(name, v_from, v_to)
``` ```
- [ ] **Step 4: Settings — añadir `agents_dir` y `policies_dir` envvars** - [x] **Step 4: Settings — añadir `agents_dir` y `policies_dir` envvars**
Verificar que `Settings` ya las acepta. Modificar `core/src/agentforge_core/config.py` para usar `env="AGENTS_DIR"` etc.: Verificar que `Settings` ya las acepta. Modificar `core/src/agentforge_core/config.py` para usar `env="AGENTS_DIR"` etc.:
@@ -3953,7 +3962,7 @@ Verificar que `Settings` ya las acepta. Modificar `core/src/agentforge_core/conf
(Pydantic Settings ya lee `AGENTS_DIR` por convención case-insensitive — no se necesita cambio.) (Pydantic Settings ya lee `AGENTS_DIR` por convención case-insensitive — no se necesita cambio.)
- [ ] **Step 5: Verificar y commit** - [x] **Step 5: Verificar y commit**
```bash ```bash
pytest tests/unit/test_api_agents.py -v pytest tests/unit/test_api_agents.py -v
@@ -3969,7 +3978,7 @@ git commit -m "feat(api): implementa router /agents (list, get, versions, diff)"
- Modify: `core/src/agentforge_core/api/executions.py` - Modify: `core/src/agentforge_core/api/executions.py`
- Create: `tests/unit/test_api_executions.py` - Create: `tests/unit/test_api_executions.py`
- [ ] **Step 1: Test (happy path con MockProvider)** - [x] **Step 1: Test (happy path con MockProvider)**
```python ```python
"""Tests del router /executions.""" """Tests del router /executions."""
@@ -4082,7 +4091,7 @@ def test_approve_sobre_estado_invalido_devuelve_409() -> None:
assert r2.status_code == 409 assert r2.status_code == 409
``` ```
- [ ] **Step 2: Implementar router** - [x] **Step 2: Implementar router**
Modificar `core/src/agentforge_core/api/executions.py`: Modificar `core/src/agentforge_core/api/executions.py`:
```python ```python
@@ -4304,7 +4313,7 @@ async def reject_execution(
return execution return execution
``` ```
- [ ] **Step 3: Añadir helper en orchestrator** - [x] **Step 3: Añadir helper en orchestrator**
Modificar `core/src/agentforge_core/runtime/orchestrator.py` añadiendo: Modificar `core/src/agentforge_core/runtime/orchestrator.py` añadiendo:
@@ -4320,7 +4329,7 @@ Modificar `core/src/agentforge_core/runtime/orchestrator.py` añadiendo:
) )
``` ```
- [ ] **Step 4: Montar `invoke_router` en main.py** - [x] **Step 4: Montar `invoke_router` en main.py**
Modificar `core/src/agentforge_core/main.py` añadiendo: Modificar `core/src/agentforge_core/main.py` añadiendo:
@@ -4329,7 +4338,7 @@ Modificar `core/src/agentforge_core/main.py` añadiendo:
app.include_router(invoke_router, prefix="/agents", tags=["agents"]) app.include_router(invoke_router, prefix="/agents", tags=["agents"])
``` ```
- [ ] **Step 5: Verificar y commit** - [x] **Step 5: Verificar y commit**
```bash ```bash
pytest tests/unit/test_api_executions.py -v pytest tests/unit/test_api_executions.py -v
@@ -4345,7 +4354,7 @@ git commit -m "feat(api): implementa /executions con invoke + HITL approve/rejec
- Modify: `core/src/agentforge_core/api/policies.py` - Modify: `core/src/agentforge_core/api/policies.py`
- Modify: `core/src/agentforge_core/api/violations.py` - Modify: `core/src/agentforge_core/api/violations.py`
- [ ] **Step 1: Implementar `policies.py`** - [x] **Step 1: Implementar `policies.py`**
```python ```python
"""Router /policies: list y versiones.""" """Router /policies: list y versiones."""
@@ -4378,7 +4387,7 @@ def list_versions(
raise HTTPException(status_code=404, detail=str(exc)) from exc raise HTTPException(status_code=404, detail=str(exc)) from exc
``` ```
- [ ] **Step 2: Implementar `violations.py`** - [x] **Step 2: Implementar `violations.py`**
```python ```python
"""Router /violations: list filtrable.""" """Router /violations: list filtrable."""
@@ -4411,7 +4420,7 @@ def list_violations(
return items return items
``` ```
- [ ] **Step 3: Commit** - [x] **Step 3: Commit**
```bash ```bash
git add core/src/agentforge_core/api/policies.py core/src/agentforge_core/api/violations.py git add core/src/agentforge_core/api/policies.py core/src/agentforge_core/api/violations.py