Commit Graph
53 Commits
Author SHA1 Message Date
JuanandClaude Opus 4.7 c414e16357 fix(policies): detect_pii/pii_leakage solo con recognizers de patrón fiables
Con Presidio real (imagen Docker) y `en_core_web_sm`, el recognizer de PERSON daba
falsos positivos sobre los textos de los escenarios (técnicos, en español, analizados
con el modelo `en`) → `01_sip` y `02_mos` salían `blocked_by_guardrail` en lugar de
`awaiting_approval`/`completed`. Se quitan `PERSON` y `PHONE_NUMBER` de
`detect_pii.entities` (input) y `PHONE_NUMBER` de `pii_leakage.entities` (output);
quedan los recognizers puramente de patrón (`EMAIL_ADDRESS`, `ES_NIF`, `IP_ADDRESS`,
`IBAN_CODE`), fiables. El bloqueo por NIF/email del demo sigue funcionando.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:38:52 +02:00
JuanandClaude Opus 4.7 eac2ed02a4 fix(guardrails): Presidio usa en_core_web_sm cacheado (en_core_web_lg no está en la imagen)
`detect_pii` instanciaba `AnalyzerEngine()` sin configuración, así que Presidio
intentaba cargar su modelo por defecto `en_core_web_lg` (~560 MB), que no está en
la imagen Docker — `core/Dockerfile` instala `en_core_web_sm`. Resultado: el
validador fallaba con `[E050] Can't find model 'en_core_web_lg'` y, al ser la
política fail-closed, *toda* invocación quedaba `blocked_by_guardrail`. Además se
reinstanciaba el engine en cada llamada (caro; probablemente la causa del crash del
proceso al segundo invoke). Ahora:
  - `_presidio_analyzer()`: singleton perezoso con `NlpEngineProvider` → `en_core_web_sm`.
  - si Presidio no está instalado o el modelo no carga, se hace fallback a la
    detección por regex (antes solo se hacía fallback ante ImportError).
Detectado ejecutando el smoke de docker-compose (el venv local no tiene Presidio,
así que los tests usan la rama de regex y no lo veían).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 14:38:52 +02:00
JuanandClaude Opus 4.7 4a8eb34874 chore(plan): marca Fases H, I y J (Tasks 30-38) completadas
Notas de desviación: Task 31 añade per-file-ignore N999 para pages/* (Streamlit
exige nombres con emoji); se quitan noqa BLE001 inútiles y la var muerta
chosen_example; Task 37 — el build de docker falló por typer 0.12.x vs click
>=8.2, se fijó click<8.2 y el smoke pasó (core healthy /health 200, dashboard
/_stcore/health ok, down limpio). Streamlit verificado con ruff + py_compile.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:35:28 +02:00
JuanandClaude Opus 4.7 4efb86c05d fix(deps): fija click<8.2 en core (typer 0.12.x rompe con click >=8.2)
`guardrails-ai<0.6` arrastra `typer 0.12.x`, que es incompatible con click
>=8.2 ("Secondary flag is not valid for non-boolean flag"); el build de
core/Dockerfile fallaba en `python -m spacy download en_core_web_sm`. Detectado
al ejecutar el smoke de docker-compose.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:10:54 +02:00
JuanandClaude Opus 4.7 6216689511 docs: README, ARCHITECTURE, roadmap futuro y manual de QA del dashboard
- README.md: pitch, arquitectura, quickstart, demo guiada en 3 pasos, tabla de
  capacidades, estructura del repo, comandos de tests.
- ARCHITECTURE.md: patrones (Strategy, config-over-code, fail-closed,
  trazabilidad), tabla de persistencia, patrón HITL, observabilidad, errores.
- docs/futuro.md: roadmap post-MVP.
- docs/manual_qa.md: checklist del smoke manual del dashboard (5 páginas + PII +
  persistencia).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:02:06 +02:00
JuanandClaude Opus 4.7 03941acb52 build: añade docker-compose con dos servicios y healthchecks
core (8000) y dashboard (8501); dashboard depende de core service_healthy.
Monta agents/ y policies/ read-only y data/ read-write en el core; el dashboard
también monta agents/ ro para leer los escenarios. `docker compose config` valida.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 13:02:06 +02:00
JuanandClaude Opus 4.7 33bc9ed133 build: añade Dockerfiles para core y dashboard con healthchecks y usuario no-root
- core/Dockerfile: python:3.11-slim, instala requirements + modelo spaCy
  (en_core_web_sm para Presidio), corre como usuario `agent`, HEALTHCHECK sobre
  /health, CMD uvicorn :8000.
- dashboard/Dockerfile: python:3.11-slim, usuario `dash`, HEALTHCHECK sobre
  /_stcore/health, CMD streamlit :8501 headless.
- .dockerignore: excluye venv, caches, datos runtime, .env, specs/plans y tests.

Ambos pasan `docker build --check` sin warnings.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:58:51 +02:00
JuanandClaude Opus 4.7 a874d9f57d feat(dashboard): página Politicas con detalle de validadores y versiones
Selector de política; muestra descripción, on_validator_error y los validadores
de input/output (cada uno expandible con su config), más la tabla de versiones.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:57:47 +02:00
JuanandClaude Opus 4.7 a36a8afa09 feat(dashboard): página Historial con tabs ejecuciones y violaciones
Tab "Ejecuciones": tabla resumen + detalle (status, error, output, violations,
traza) por trace_id. Tab "Violaciones": log filtrable por severidad.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:53:17 +02:00
JuanandClaude Opus 4.7 826d5b494e feat(dashboard): página Aprobaciones con HITL approve/reject por acción
Lista ejecuciones en awaiting_approval; por cada acción de needs_human_for
muestra risk_score coloreado, target y rollback_plan con un checkbox de
aprobación. Aprueba el subconjunto seleccionado (con comentario) o rechaza con
razón vía /approve y /reject; rerun tras la decisión.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:44:07 +02:00
JuanandClaude Opus 4.7 ab21db2476 feat(dashboard): página Ejecutar con trace timeline y violations rendering
- components/trace_view.render_trace: decision_path como timeline con duración.
- components/violation_view.render_violations: violaciones con badge de severidad.
- pages/2_▶️_Ejecutar.py: selector de agente, botones de escenarios pregrabados,
  textarea, invoke y render de status/output/violations/traza. Aviso si queda en
  awaiting_approval. (Se omite la variable muerta chosen_example del plan.)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:42:12 +02:00
JuanandClaude Opus 4.7 f2ef01d98d feat(dashboard): página de Registro con detalle, versiones y diff coloreado
- components/diff_view.render_unified_diff: pinta +/-/@@ del unified diff.
- pages/1_🏛️_Registro.py: selector de agente, detalle (estado, owner, propósito,
  guardrails, system_prompt, output_schema, llm), tabla de versiones y comparador.
- pyproject: per-file-ignore N999 en pages/* — Streamlit exige nombres
  "<n>_<emoji>_<Label>.py" para la navegación multipágina.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:41:00 +02:00
JuanandClaude Opus 4.7 a27e972360 feat(dashboard): scaffolding Streamlit con cliente HTTP y health check
CoreClient (httpx sync, 2 retries) cubre todos los endpoints del core y mapea
404/409/422 a {"error": ...}. app.py monta la página raíz con sidebar de branding
y un health-check del core.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:39:16 +02:00
JuanandClaude Opus 4.7 00a5dc83fa chore(repo): ignora claude-session.txt (nota de hand-off entre sesiones)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 12:01:40 +02:00
JuanandClaude Opus 4.7 e30f324794 chore(plan): marca Phase G (Tasks 26-29) completada
Nota de desviación: Task 26 reescribe el escenario HSS para no colisionar con
'mos'; Task 27 colapsa EXAMPLES a una línea y reusa el __init__ del scaffolding;
Task 29 Step 2 (índice de ejecuciones persistido) ya estaba hecho en Task 24, así
que ese commit solo añade el test. Estilo del repo = ruff check (no ruff format).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 10:53:36 +02:00
JuanandClaude Opus 4.7 46d509beb1 test(integration): resume HITL tras recreación del app (checkpointing SQLite)
Invoca el escenario SIP hasta awaiting_approval, descarta el TestClient (y las
caches DI) y crea otro sobre el mismo DATA_DIR; el /approve posterior reanuda
hasta completed gracias a execution_index.json + checkpoints.sqlite.

Desviación del plan: el Task 29 Step 2 ("persistir índice de ejecuciones") ya
se implementó en el Task 24 (api/executions.py: _record_execution/_load_index/
_resolve sobre data_dir/execution_index.json), así que este commit solo añade
el test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 10:31:12 +02:00
JuanandClaude Opus 4.7 f475e66694 test(integration): HITL approve/reject + bloqueo por PII (NIF, email)
- test_invoke_hitl: escenario SIP real → awaiting_approval; approve devuelve
  status=completed con approved_actions; reject deja status=failed con
  error=rejected_by_human.
- test_invoke_pii_block: input con NIF español y email → status=blocked_by_guardrail
  y violación DetectPII con blocked=True.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 09:27:01 +02:00
JuanandClaude Opus 4.7 1f2bf24a66 test(integration): happy path end-to-end con escenario MOS sin HITL
Invoca el agente real incident_analyzer (assets del repo, LLM mock) vía
TestClient y comprueba status=completed, final_output y que el decision_path
recorre los seis nodos del grafo. Añade conftest con la fixture
integration_client (env apuntando a agents/ y policies/ del repo, caches DI
limpiadas).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 08:28:26 +02:00
JuanandClaude Opus 4.7 c4c46e4954 feat(agents): añade incident_analyzer v1+v2 con 3 escenarios de voz virtualizada
El escenario HSS evita la subcadena 'mos' (de 'últimos') para que el
MockProvider lo mapee a la respuesta canónica 'hss' y no a la de 'mos'.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 21:40:51 +02:00
JuanandClaude Opus 4.7 19bac2bcdc 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>
2026-05-10 15:40:57 +02:00
JuanandClaude Opus 4.7 09ec79a464 feat(api): implementa routers /policies y /violations (listado + filtros)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:40:09 +02:00
JuanandClaude Opus 4.7 8927b192f8 feat(api): implementa /executions con invoke + HITL approve/reject + persistencia
- POST /agents/{name}/invoke, GET /executions, GET /executions/{trace_id},
  POST /executions/{trace_id}/{approve,reject}.
- execution_index.json persiste trace_id → (agent_name, version) para reconstruir
  el contexto en approve/reject tras un reinicio.
- Refactor del orchestrator: split _snapshot → _build_execution + _snapshot, nuevo
  método público snapshot() (lee estado sin avanzar). Sustituye a los helpers
  _snapshot_execution/_build_graph_for_snapshot del plan, incompatibles con el
  checkpointer por-llamada.
- Aliases Annotated[...] de dependencias movidos a deps.py.
- Fixture mínima tests/fixtures/policies/default/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:38:44 +02:00
JuanandClaude Opus 4.7 13ba1f7826 feat(api): implementa router /agents (list, get, versions, get_version, diff)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:33:27 +02:00
JuanandClaude Opus 4.7 1c763d26d8 feat(api): scaffolding FastAPI con TraceIdMiddleware, /health y routers stub
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:30:38 +02:00
JuanandClaude Opus 4.7 38d81252c6 feat(api): añade persistencia JSONL append-only y DI con factories cacheadas
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:29:23 +02:00
JuanandClaude Opus 4.7 de738e5f15 chore(plan): marca Phase E (Tasks 17-20) completada
Incluye nota de desviación: SqliteSaver → AsyncSqliteSaver (async CM),
aiosqlite<0.21, orchestrator abre el checkpointer por llamada, +tests del orchestrator.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:21:07 +02:00
JuanandClaude Opus 4.7 5738bd3118 feat(runtime): añade AgentOrchestrator (invoke + resume HITL + snapshot)
Punto único de entrada al runtime. Cada llamada abre su propio AsyncSqliteSaver
sobre data_dir/checkpoints.sqlite, así que un awaiting_approval sobrevive a un
reinicio del proceso (verificado en test_estado_persiste_entre_instancias).
El plan no incluía tests del orchestrator; se añaden 5 (invoke feliz, pausa HITL +
resume aprobar/rechazar, bloqueo por guardrail, persistencia entre instancias).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:19:42 +02:00
JuanandClaude Opus 4.7 d56624c90e feat(runtime): añade build_graph (StateGraph + routing condicional + interrupt HITL)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:15:35 +02:00
JuanandClaude Opus 4.7 d8c5c23e2a fix(runtime): build_checkpointer asíncrono con AsyncSqliteSaver
Los nodos del grafo son async, así que se invoca con `await graph.ainvoke`,
que el SqliteSaver síncrono no soporta (NotImplementedError). Se cambia a
AsyncSqliteSaver expuesto como context manager async. Requiere aiosqlite<0.21
(la 0.21 eliminó Connection.is_alive(), usado por langgraph-checkpoint-sqlite 2.x).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 15:15:35 +02:00
JuanandClaude Opus 4.7 c305ff5711 feat(runtime): añade build_checkpointer wrapper sobre SqliteSaver
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:59:01 +02:00
JuanandClaude Opus 4.7 683cc69edc feat(runtime): añade AgentState y nodos LangGraph (validate, llm, propose, approve, finalize)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:56:25 +02:00
JuanandClaude Opus 4.7 006d781df0 chore(plan): marca Phase D (Tasks 13-16) completada
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:51:31 +02:00
JuanandClaude Opus 4.7 db68164354 feat(policies): añade política default v1 con guardrails completos
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:51:31 +02:00
JuanandClaude Opus 4.7 af8036c2d2 feat(guardrails): añade NeMo stub, CompositeEngine paralelo y factory
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:51:17 +02:00
JuanandClaude Opus 4.7 79c6fe32ff feat(guardrails): añade GuardrailsAIEngine + 8 validadores (PII, injection, schema, telco)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:50:25 +02:00
JuanandClaude Opus 4.7 b7c470405b feat(guardrails): añade Protocol GuardrailEngine
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:46:35 +02:00
JuanandClaude Opus 4.7 fee046064a chore(plan): marca Phase C (Tasks 10-12) completada
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:40:16 +02:00
JuanandClaude Opus 4.7 b297f25e2c feat(registry): añade factories para registry y policy_store
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:40:16 +02:00
JuanandClaude Opus 4.7 5cbec0d5d8 feat(registry): añade FileSystemAgentRegistry con versionado tipo Git y diff
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:39:50 +02:00
JuanandClaude Opus 4.7 85906de832 feat(registry): añade FileSystemPolicyStore con carga YAML versionada
Incluye 'yaml' en los overrides de mypy (PyYAML no trae type stubs).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:37:53 +02:00
JuanandClaude Opus 4.7 2fffecb988 chore(plan): marca Phase B (Tasks 6-9) completada
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:30:40 +02:00
JuanandClaude Opus 4.7 d774a6b509 feat(llm): añade factory que selecciona proveedor según settings
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:30:40 +02:00
JuanandClaude Opus 4.7 4630fa214d feat(llm): añade AzureOpenAIProvider y OpenAIProvider con retry exponencial
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:30:05 +02:00
JuanandClaude Opus 4.7 45b2b9367c feat(llm): añade MockProvider determinista con 3 escenarios canónicos
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:28:40 +02:00
JuanandClaude Opus 4.7 bc16059738 feat(llm): añade Protocol LLMProvider con Message y CompletionResult
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:28:40 +02:00
JuanandClaude Opus 4.7 201ecade9f chore(plan): marca Phase A (Tasks 1-5) completada
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:16:26 +02:00
JuanandClaude Opus 4.7 55d65b68bf feat(observability): logging JSON estructurado con structlog y trace_id
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:16:07 +02:00
JuanandClaude Opus 4.7 60c2bff322 feat(config): añade Settings con Pydantic Settings y .env loading
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:16:07 +02:00
JuanandClaude Opus 4.7 ad77efe366 feat(domain): añade modelos GuardrailViolation, PolicyDefinition y AgentExecution
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:14:13 +02:00
JuanandClaude Opus 4.7 73114f6731 feat(domain): añade modelo AgentDefinition + LLMConfig + AgentVersionMeta
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:10:21 +02:00
JuanandClaude Opus 4.7 62536766e6 chore: scaffolding inicial del repo (pyproject, requirements, Makefile)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 10:08:48 +02:00
JuanandClaude Opus 4.7 f5e6b8767d docs: add AgentForge implementation plan
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-10 09:56:09 +02:00
JuanandClaude Opus 4.7 b471fa454c docs: add AgentForge initial design spec
Diseño completo de la plataforma de gobernanza de agentes IA: arquitectura
two-tier (FastAPI core + Streamlit dashboard), modelos de dominio, contratos
REST, interfaces Strategy (LLM, Guardrails, Registry), flujo LangGraph con
HITL dinámico vía interrupt(), versionado tipo Git en sistema de ficheros,
política y validadores, manejo de errores y plan de testing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 20:08:59 +02:00