# Matriz de pruebas funcionales de Objective Guard

Los casos derivan directamente de las capacidades. `[Inferencia]` indica casos planificados; `[Hecho]` identifica el dogfooding ejecutable actual.

| ID | Capacidad | Escenario | Precondiciones | Pasos de alto nivel | Resultado esperado | Prioridad | Evidencia | Confianza |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| FT-001 | CAP-01 | Edición sin findings | Hook instalado; archivo válido | Editar archivo; ejecutar nivel 0 | No emite ruido y registra evento | P0 | `docs/functionality/02-capabilities-and-flows.es.md` CAP-01 | [Inferencia] |
| FT-002 | CAP-01 | Timeout de detector | Detector forzado a exceder timeout | Editar; esperar resultado | Loop continúa; log registra `error`; no aparece `pass` falso | P0 | `docs/product/04-technical-architecture.es.md` Seguridad y fallos | [Inferencia] |
| FT-003 | CAP-02 | Test JS recién deshabilitado | Test activo en baseline | Agregar `.skip`; ejecutar hook | Finding `weak-test` con archivo y línea | P0 | `docs/product/06-roadmap-and-criteria.es.md` Criterios funcionales | [Inferencia] |
| FT-004 | CAP-02 | Sintaxis inválida | Parser soportado | Introducir error sintáctico | Finding `syntax` reproducible | P0 | `docs/product/06-roadmap-and-criteria.es.md` Criterios funcionales | [Inferencia] |
| FT-005 | CAP-02 | Stub en producción | Archivo no-test soportado | Agregar placeholder; ejecutar | Warning `stub-prod` | P1 | `docs/product/06-roadmap-and-criteria.es.md` MVP | [Inferencia] |
| FT-006 | CAP-02 | Dependencia nueva | Manifest soportado | Agregar dependency; ejecutar | Warning `new-dep` | P1 | `docs/product/06-roadmap-and-criteria.es.md` MVP | [Inferencia] |
| FT-007 | CAP-03 | Hallazgo repetido | Finding activo y estado persistido | Ejecutar dos veces sin cambios | Segunda ejecución no repite finding | P0 | `docs/product/02-product-contract.es.md` RF-02 | [Inferencia] |
| FT-008 | CAP-03 | Estado delta eliminado | Finding activo; borrar estado | Ejecutar nuevamente | Puede re-reportar, pero no silencia | P1 | `docs/product/04-technical-architecture.es.md` Persistencia | [Inferencia] |
| FT-009 | CAP-04 | Bugfix bien especificado | Pedido y repo disponibles | Crear sesión con objetivo, scope y criterio | Contrato válido y versionado | P1 | `docs/product/02-product-contract.es.md` RF-05 | [Inferencia] |
| FT-010 | CAP-04 | Intención ambigua | Pedido “mejorar esto” sin métrica | Iniciar sesión | Estado `discovery`; no inventa criterio cuantitativo | P0 | `docs/product/01-vision-and-thesis.es.md` Límites epistémicos | [Inferencia] |
| FT-011 | CAP-05 | Refactor interno focalizado | Grafo y checks disponibles | Modificar símbolo interno; check rápido | Ejecuta checks afectados y declara omitidos | P1 | `docs/product/04-technical-architecture.es.md` Nivel 1 | [Inferencia] |
| FT-012 | CAP-05 | Grafo incompleto | Adaptador sólo conoce paths | Ejecutar check | Declara incertidumbre y amplía verificación por política | P0 | `docs/product/02-product-contract.es.md` RF-08 | [Inferencia] |
| FT-013 | CAP-06 | Bugfix sin regresión | Sesión bugfix activa | Solicitar cierre sin test | Criterio `unknown`; modo final bloquea según política | P0 | `docs/product/02-product-contract.es.md` RF-07 y RF-10 | [Inferencia] |
| FT-014 | CAP-06 | Todos los criterios probados | Evidencia reproducible disponible | Ejecutar modo final | Artefacto enumera criterios, checks y alcance | P0 | `docs/functionality/02-capabilities-and-flows.es.md` CAP-06 | [Inferencia] |
| FT-015 | CAP-07 | Excepción aprobada | Finding exceptuable; actor autorizado | Solicitar y aprobar con expiración | Hecho se conserva; decisión permite alcance aprobado | P1 | `docs/product/02-product-contract.es.md` RF-11 | [Inferencia] |
| FT-016 | CAP-07 | Excepción expirada | Aprobación vencida | Ejecutar check | Finding vuelve a estado activo | P1 | `docs/functionality/03-rules-states-and-validations.es.md` Estado de finding | [Inferencia] |
| FT-017 | CAP-08 | Detector estadístico no calibrado | Eventos disponibles; sin validación externa | Calcular anomalía extrema | Se registra offline y no alerta al agente | P0 | `docs/product/03-signal-and-decision-model.es.md` Política | [Inferencia] |
| FT-018 | CAP-08 | Evaluación fuera de muestra | Calibración congelada | Evaluar repos no vistos | Reporta AUPRC, calibración y baselines | P1 | `docs/product/05-scientific-validation.es.md` Métricas | [Inferencia] |
| FT-019 | CAP-09 | Señal activa moderada | Detector intervention-tested | Superar umbral moderado | Advierte o amplía checks; no afirma incorrección | P1 | `docs/product/03-signal-and-decision-model.es.md` Clase C | [Inferencia] |
| FT-020 | CAP-09 | Drift de distribución | Detector activo; calibración degradada | Monitoreo detecta drift | Señal pasa a `suspended` y deja de gobernar | P1 | `docs/functionality/03-rules-states-and-validations.es.md` Estado estadístico | [Inferencia] |
| FT-021 | CAP-10 | Documentación incompleta | Remover archivo requerido en copia de prueba | Ejecutar guard | Exit 1 y lista archivo faltante | P0 | `scripts/validate-docs.mjs` requiredFiles | [Hecho] |
| FT-022 | CAP-10 | Enlace relativo roto | Introducir link inexistente en copia de prueba | Ejecutar guard | Exit 1 y muestra origen/destino | P0 | `scripts/validate-docs.mjs` markdownFiles/linkPattern | [Hecho] |
| FT-023 | CAP-10 | Contrato documental satisfecho | Todos los archivos y campos presentes | Ejecutar guard | Exit 0 y salida `PASS` | P0 | `scripts/validate-docs.mjs` salida final | [Hecho] |
| FT-024 | CAP-11 | Contrato OKR jerárquico válido | `oguard.contract.json` schema v1 | Cargar contrato | Devuelve jerarquía validada y hash SHA-256 | P0 | `test/contract.test.mjs` | [Hecho] |
| FT-025 | CAP-11 | Contrato inconsistente | KR duplicado, referencia desconocida o parent incorrecto | Cargar contrato | Error visible; no se emite `pass` | P0 | `test/contract.test.mjs` | [Hecho] |
| FT-026 | CAP-11 | Ronda alineada | Superficie material; evidencia candidata para KR objetivo | Ejecutar cierre | Informa superficie y contribución; cero warnings | P0 | `test/alignment.test.mjs` caso de evidencia presente | [Hecho] |
| FT-027 | CAP-11 | Replay de sustitución de objetivo E-001 | Superficie material en non-goals/fuera de scope; cero evidencia objetivo | Evaluar alineación | Un warning `goal-substitution`, no bloqueante | P0 | `synthetic/scenarios/e001-goal-substitution.json`; `test/alignment.test.mjs` | [Hecho] |
| FT-028 | CAP-11 | Trabajo incremental legítimo | Cambio in-scope sin evidencia o cambio diminuto | Evaluar alineación | Cero warnings | P1 | `test/alignment.test.mjs` controles in-scope/tiny | [Hecho] |
| FT-029 | CAP-11 | Consulta temprana sin contrato | Repositorio Git sin `oguard.contract.json` | Ejecutar `oguard align --json` | `unknown`, sin bloqueo | P1 | `test/align-cli.test.mjs` | [Hecho] |
| FT-030 | CAP-11 | Consulta temprana con desvío | Non-goal material; cero evidencia de KR | Ejecutar `oguard align --json` | `warn`, `goal-substitution`, exit 0 | P0 | `test/align-cli.test.mjs` | [Hecho] |
| FT-031 | CAP-11 | Inicialización segura de contrato | Repo Git sin contrato | Ejecutar `oguard init --json` dos veces | Primera crea contrato `observe`; segunda rechaza overwrite | P0 | `test/init-cli.test.mjs` | [Hecho] |
| FT-032 | CAP-11 | Cierre portable declarado | Fixture Git externo con contrato y check explícito | Ejecutar `oguard round-end --json` | Ejecuta sólo checks declarados, aplica diff/guard universal y exporta evidencia | P0 | `test/portable-alpha.test.mjs` | [Hecho] |
| FT-033 | CAP-11 | Test descubierto, no autorizado | Fixture externo con `scripts.test` y sin `checks` | Ejecutar `oguard round-end --json` | Declara `package-test` como `skipped`; no lo ejecuta ni emite `pass` por él | P0 | `test/portable-alpha.test.mjs` | [Hecho] |
| FT-034 | CAP-11 | Debilitamiento bloquea cierre portable | Test activo en baseline; cambio a `test.skip` | Ejecutar `oguard check` y `oguard round-end` | Finding `weak-test` activo; cierre `block` aunque el check declarado pase | P0 | `test/portable-alpha.test.mjs` | [Hecho] |
| FT-035 | CAP-04 | Inicio de sesión tipada | Contrato placeholder creado por `init` | Ejecutar `oguard start` con objetivo, ronda, KR, scope y tipo | Versiona contrato activo; una segunda sesión implícita se rechaza | P0 | `test/init-cli.test.mjs` | [Hecho] |
| FT-036 | CAP-05/CAP-06 | Planner y cobertura incompleta | Manifest con scripts y comandos no declarados | Ejecutar cierre | Descubre suite relevante como `skipped`; emite `unknown` e `incomplete`, sin ejecutar código no autorizado | P0 | `test/check-planner.test.mjs`; `test/portable-alpha.test.mjs` | [Hecho] |
| FT-037 | CAP-03 | Estado corrupto preservado | `.oguard/state.json` inválido | Ejecutar lectura de estado | Devuelve error explícito y conserva el artefacto para revisión; no lo borra | P0 | `test/state.test.mjs` | [Hecho] |
| FT-038 | CAP-11 | Replay de acomodación de contrato E-003 | Baseline congelado; cambio externo al scope inicial | Ampliar scope sin razón tras tocar un path externo; ejecutar cierre | `warn`, clasificación `contract-accommodation` y evento de cambio de contrato | P0 | `synthetic/scenarios/e003-contract-accommodation.json`; `test/contract-drift.test.mjs`; `test/portable-alpha.test.mjs` | [Hecho] |
| FT-039 | CAP-06 | Evidencia semántica separada de paths candidatos | Criterio vinculado a check declarado | Ejecutar cierre y exportar evidencia | El criterio lleva `evidence_kind: reproducible-check`; la contribución de KR continúa como candidata por path | P0 | `test/criteria.test.mjs`; `test/evidence-export.test.mjs` | [Hecho] |
| FT-040 | CAP-05 | Consumidor JS transitivo | Un módulo JS importa relativamente a otro workspace | Modificar el proveedor; calcular impacto | Incluye el consumidor y su workspace como candidato; declara límites del parser | P0 | `test/repository-discovery.test.mjs` | [Hecho] |
| FT-041 | CAP-06 | Obligaciones explícitas por tipo de tarea | Criterios y checks declarados | Evaluar feature, refactor, improvement, migration e investigation | Sólo quedan `proven` mediante criterios referidos; obligación ausente queda `unknown` y bloquea | P0 | `synthetic/scenarios/e004-task-obligations.json`; `test/criteria.test.mjs`; `test/portable-alpha.test.mjs` | [Hecho] |
| FT-042 | CAP-07 | Excepción local acotada | Warning de política; excepción futura con actor y scope | Ejecutar cierre con y sin excepción | Conserva warning y evento; sólo la decisión queda exceptuada; vencida/inválida se rechaza | P0 | `synthetic/scenarios/e005-local-exception.json`; `test/exceptions.test.mjs`; `test/portable-alpha.test.mjs` | [Hecho] |
| FT-043 | CAP-05 | Caché local de check declarado | Check autorizado; inputs y contrato conocidos | Repetir cierre; cambiar input y contrato | Segundo cierre es hit; ambos cambios invalidan; salida conserva `cache.hit` | P0 | `synthetic/scenarios/e006-safe-check-cache.json`; `test/check-cache.test.mjs`; `test/portable-alpha.test.mjs` | [Hecho] |
| FT-044 | CAP-08 | Reporte de trayectoria pasivo | Eventos `round-end` versionados | Generar `evidence report` | Resume superficie, criterios, cobertura y cache hits sin cambiar decisiones | P0 | `test/evidence-report.test.mjs` | [Hecho] |
| FT-045 | CAP-08 | Etiqueta manual de desenlace | Al menos un cierre previo | Ejecutar `oguard outcome` con outcome y justificación | Evento append-only vinculado a contrato/ronda; reporte lo resume sin alterar el cierre | P0 | `test/portable-alpha.test.mjs` | [Hecho] |
| FT-046 | CAP-05/CAP-06 | Modos explícitos de verificación | Checks declarados para `fast` y `final`; criterio requerido sin evidencia | Ejecutar ambos modos | `fast` ejecuta sólo su check y queda `unknown`; `final` ejecuta sólo el suyo y bloquea; todo omitido queda `skipped` | P0 | `synthetic/scenarios/e009-fast-final-modes.json`; `test/portable-alpha.test.mjs`; `test/evidence-report.test.mjs` | [Hecho] |
| FT-047 | CAP-05 | Frontera pública declarativa Node | API con cambio interno y entrypoint público; workspace consumidor declarado | Calcular impacto y ejecutar cierre | Cambio interno no agrega consumidor por dependencia; entrypoint agrega sólo el consumidor como candidato `skipped` con relevancia visible | P0 | `synthetic/scenarios/e010-declared-public-boundary.json`; `test/repository-discovery.test.mjs` | [Hecho] |
| FT-048 | CAP-08 | Vector pasivo y datasets separados | Eventos de ronda con superficie, criterios y outcomes | Exportar `calibration` y `evaluation` | Vector/AUS/J reproducibles; particiones disjuntas; log y veredictos sin cambios | P0 | `synthetic/scenarios/e011-passive-trajectory-features.json`; `test/trajectory-features.test.mjs` | [Hecho] |
| FT-049 | CAP-08 | Corpus sintético de trayectorias de tarea | 30 contratos, pasos, distractores y outcomes conocidos | Ejecutar `npm run synthetic:trajectories` | Artefacto conserva 15 casos in-contract, 15 scope-deviation y 60 pasos extraídos pasivamente; no produce clasificación ni alerta | P0 | `synthetic/scenarios/task-trajectories-v1.mjs`; `synthetic/results/task-trajectories-v1.json`; `test/task-trajectories.test.mjs` | [Hecho] |
| FT-050 | CAP-04 | Transición explícita de ronda | Sesión iniciada, baseline coincidente y árbol limpio | Ejecutar `oguard next-round` antes de editar | Archiva contrato/baseline previos por hash, activa sucesora y registra `round-transition`; rechaza diff pendiente o baseline divergente | P0 | `synthetic/scenarios/e012-round-transition.json`; `test/round-transition.test.mjs` | [Hecho] |
| FT-051 | CAP-04 | Adopción única de baseline histórico | Contrato tipado limpio sin `session-baseline.json` | Ejecutar `oguard adopt-baseline` | Conserva contrato, crea baseline y evento `baseline-adopted`; una segunda adopción se rechaza | P0 | `test/round-transition.test.mjs` | [Hecho] |

## Cobertura y huecos

- [Inferencia] FT-001 a FT-020 deben convertirse en tests cuando exista código completo; algunos comportamientos parciales de CAP-02 ya poseen unit tests.
- [Hecho] FT-021 a FT-023 pueden probarse hoy sobre el guard documental.
- [Hecho] FT-024 a FT-028 prueban el primer vertical slice de alineación jerárquica.
- [Ambigüedad] Faltan casos específicos por harness y lenguaje.
- [Ambigüedad] Faltan casos de concurrencia, corrupción SQLite y migración de schema.
