# Capa 2 — Contrato de producto de Objective Guard

## Objetivo

Objective Guard debe acompañar a un agente de programación durante una tarea y devolver, con latencia proporcional al momento, una de cuatro clases de resultado:

- `pass`: los checks ejecutados no encontraron violaciones y el alcance de la afirmación está declarado;
- `warn`: existe un hecho no bloqueante o una señal calibrada que requiere atención;
- `block`: una política explícita aplicada a evidencia reproducible impide continuar o cerrar;
- `error`: el guard no pudo evaluar; nunca debe confundirse con `pass`.

El resultado debe ser compacto, reproducible y trazable a regla, archivo, ubicación, evidencia y siguiente acción.

## Usuarios

### Agente de programación

Consume señales durante la edición, corrige violaciones y adjunta evidencia antes de declarar una tarea terminada.

### Desarrollador supervisor

Define o aprueba objetivo, excepciones y políticas sensibles. Inspecciona explicaciones sin leer trazas completas.

### Responsable de módulo

Mantiene contratos locales, fronteras públicas, comandos focalizados e invariantes de su área.

### Equipo de plataforma

Integra hooks, CI, sandbox, políticas globales, almacenamiento y telemetría.

### Investigador o evaluador

Utiliza eventos pasivos y benchmarks para validar las métricas estadísticas sin alterar primero el comportamiento observado.

## Alcance

### Nivel 0 — Reflejo universal

Opera sin contrato de sesión sobre el archivo o diff recién modificado:

- sintaxis rota;
- tests deshabilitados o debilitados;
- stubs y placeholders en producción;
- dependencias nuevas;
- fingerprints y salida delta-only;
- eventos append-only para investigación.

### Nivel 1 — Sesión y contrato

Activa controles específicos de intención:

- tipo de tarea;
- objetivo original inmutable;
- criterios de aceptación;
- conjunto objetivo declarado;
- scope esperado y zonas sensibles;
- invariantes y contratos aplicables;
- estado de evidencia por criterio.

### Nivel 2 — Impacto incremental

Calcula paths, módulos, símbolos, fronteras y checks afectados. Selecciona verificaciones rápidas y reutiliza caché.

### Nivel 3 — Verificación final

Exige trazabilidad completa, ejecuta checks de mayor cobertura y produce un artefacto auditable para CI o revisión humana.

### Nivel científico paralelo

Registra superficie, evidencia, trayectoria, latencia y resultados. Las señales estadísticas permanecen pasivas hasta superar criterios de calibración e intervención.

## No objetivos

- Reemplazar CI, analizadores estáticos o suites de tests.
- Mantener manualmente una especificación exhaustiva del repositorio.
- Ejecutar todo el repositorio en cada edición.
- Permitir que un LLM sea autoridad final de corrección.
- Bloquear por una puntuación opaca.
- Construir desde el inicio un índice semántico universal para todos los lenguajes.
- Recomendar reescrituras completas como respuesta automática a una anomalía.

## Requisitos

### Contrato OKR jerárquico

El archivo versionado `oguard.contract.json` vincula el objetivo principal con el objetivo de ronda. Declara IDs estables, KRs objetivo, evidencia observable por path, scope esperado, non-goals y política de señal. Un contrato inválido produce error visible; no se degrada a `pass`.

Los paths modificados son candidatos de evidencia atribuida, no prueba semántica de cumplimiento. La salida conserva esa limitación mediante conteos por KR y no transforma automáticamente un archivo tocado en un KR logrado.

El agente puede consultar `oguard align` después de un patch. La salida compacta recuerda objetivo, ronda, superficie y KRs; una advertencia conserva exit code cero para que una fase temprana de integración no detenga por sí misma el trabajo.

Antes del primer cambio material, `oguard task-flow` verifica que exista contrato tipado, baseline coincidente y salud de gobernanza. Registra el evento `task-flow` con datos sanitizados y devuelve `ready` o `action-required`. Los harnesses globales entregan esta instrucción al inicio del pedido; no sustituyen la autoridad humana para inventar objetivo, scope o tipo de tarea.

Los harnesses globales Claude y Codex aplican además un gate `PreToolUse` sobre las herramientas estructuradas de edición. Sólo deja continuar cuando el último `task-flow: ready` corresponde al hash actual del contrato y tiene menos de una hora. La política es fail-open para repositorios sin contrato y no intenta inspeccionar escrituras arbitrarias dentro de comandos shell; el límite queda explícito para no presentar una cobertura parcial como aislamiento total.

Un proyecto puede versionar `oguard.kpis.json` para convertir los KPIs del inventario global en parte del preflight. `task-flow` valida esa política antes de conceder autorización y persiste su hash junto al del contrato. Una regla `block` con muestra suficiente impide editar; un cambio de política invalida la autorización anterior. Las reglas `warn` y los resultados `unknown` por muestra insuficiente informan sin simular una certeza o un bloqueo prematuros.

El inventario global registra también cada `task-flow` con un estado sanitizado. `oguard inventory dashboard --days N` agrega adopción, uso del flujo, intervención y resolución por proyecto y harness. El dashboard declara el efecto causal como `not-evaluable` mientras no exista adjudicación o diseño experimental: volumen de uso y una corrección posterior no bastan para atribuir al guard ahorro de tiempo, tokens o desvíos evitados.

`oguard init` crea una única vez un contrato v1 en modo `observe`. Es un on-ramp, no una configuración correcta por defecto: el usuario debe reemplazar objetivo, ronda, KRs, scope y non-goals antes de activar `warn`. El comando rechaza sobrescribir un contrato existente.

`oguard start` completa exclusivamente ese placeholder mediante IDs, texto de objetivo/ronda/KR, tipo de tarea y patterns de scope. Rechaza una sesión ya iniciada: una ronda posterior exige una edición versionada y deliberada del contrato, no una reescritura implícita. Al iniciarla guarda una snapshot inmutable en `.oguard/session-baseline.json` con objetivo, ronda, scope y hash inicial.

`oguard next-round` abre una sucesora tipada antes de trabajo nuevo. Exige árbol Git limpio y que el baseline activo coincida con el contrato actual; archiva con nombres dirigidos por hash el contrato y baseline previos bajo `.oguard/history/`, instala el nuevo contrato y reemplaza sólo el puntero activo de baseline. Además conserva un evento append-only `round-transition` con ambas rondas, hashes y ubicaciones de archivo. No rota una sesión con diff pendiente ni un contrato editado manualmente desde su baseline; por ello no puede acomodar retrospectivamente el trabajo que E-005 observó.

Para contratos históricos que fueron versionados antes de que existiera baseline, `oguard adopt-baseline` sólo opera sobre árbol limpio, exige contrato ya tipado y falla si ya hay baseline. Crea el primer baseline sin reescribir el contrato y registra `baseline-adopted` con commit, hash, objetivo y ronda. Es una migración local y única, no una forma de editar la historia ni aprobar diffs pendientes.

Cuando una ronda cerrada no obtuvo `pass`, pero un responsable acepta explícitamente una deuda no promocionable para poder iniciar trabajo posterior, `oguard accept-baseline --reason --actor` permite una sola aceptación local del contrato actual. Exige árbol limpio y un `round-end` ya registrado; archiva el baseline previo y registra actor, razón y status anterior. No cambia el veredicto histórico, no silencia checks y no equivale a una promoción.

`oguard.plan.json` es el plan versionado fuera del contrato de ronda. Contiene la jerarquía de objetivo y KRs que se pretende preservar; `oguard anchor-plan` sólo lo ancla desde árbol limpio y contra un baseline de contrato coincidente. El baseline conserva hash y contenido del plan. Si el archivo cambia después, el cierre emite `plan-amendment`; no se acepta que editar el contrato corriente redefina aquella referencia.

El feedback operativo de desarrollos multiagente extensos exige una separación futura entre gobernanza durable y estado de ejecución activo. Objetivos, KRs, criterios, políticas y cambios deliberados permanecen versionados. El puntero de ronda activa, la autorización de preflight, la identidad de worker o agente y el progreso del ciclo de vida pertenecen a estado operativo local append-only y no deben forzar una reescritura permanente del contrato durable por cada subronda heredada. Hasta implementar esa separación, la transición de ronda versionada actual sigue siendo autoritativa; el producto no debe simular silenciosamente el modelo futuro mutando o ignorando el contrato.

Una subronda nativa es una unidad de ejecución debajo de una ronda padre estable. Las subrondas de definición, implementación, review y corrección heredan objetivo, KRs, non-goals, política y criterios aplicables; pueden estrechar el scope de trabajo y adjuntar evidencia, pero no ampliar ni redefinir implícitamente el objetivo padre. Cada subronda posee ID estable, rol, actor o agente, ID padre, timestamps, fingerprint de baseline, superficie cambiada, evidencia, resultado y predecesor causal. Las subrondas paralelas fusionan evidencia por criterio y preservan contradicciones en lugar de sobrescribirse.

Una evolución del plan declara `amendment: {id, reason, actor, previous_hash}`. El hash previo debe coincidir con el ancla; de otro modo la alerta permanece. Un `contract_change` debe referenciar `plan_hash` o un `amendment_id` aprobado, además de su razón. Los eventos de anclaje y enmienda se exportan como evidencia sanitizada.

Antes de editar el plan se ejecuta `oguard register-plan-amendment` desde árbol limpio. El comando archiva el contenido previo bajo `.oguard/history/plan-<hash>.json` mediante creación exclusiva y emite `plan-amendment-registered` con el hash previo. La exportación conserva ese evento sin paths locales; una reescritura que no tenga archivo histórico no es una enmienda verificable.

La exportación verifica además cada evento contra el archivo archivado y su hash. Reporta `plan-chain-incomplete`, `plan-chain-archive-missing` o `plan-chain-hash-mismatch` sin inferencia estadística.

Los hallazgos de cadena tienen fingerprint estable y estado persistente: el primer cierre los emite como novedades, cierres repetidos no los duplican y una reparación registra su resolución. La evidencia exporta ambos conteos.

`oguard health --json` consolida de modo determinista el hash del plan, cantidad de enmiendas, integridad y hallazgos activos/resueltos. El mismo objeto se incluye como `governance_health` en la evidencia exportada.

Un cambio posterior de objetivo, ronda o scope debe declarar `contract_change.reason`. El baseline no se actualiza: el cierre conserva un evento append-only de cambio y, si falta razón, emite `contract-accommodation`. En esta fase la señal es preventiva, no una prueba de intención: informa que el contrato actual puede normalizar trabajo ya realizado. Una razón explícita suprime el warning pero no borra la diferencia ni el evento.

Cada ronda puede declarar `work_context.kind`: `normal`, `merge`, `rebase`, `migration` o `generated`. En contextos transicionales, si la fracción de archivos dentro del scope cae por debajo de `policy.min_scope_coverage` (0.5 por defecto), el análisis de alineación pasa a `scope_validity: not-evaluable`. Conserva la superficie y los fallos deterministas, pero no emite ruido de deriva por archivo ni lo cuenta como precisión del detector.

El contrato puede declarar `public_boundaries` como una lista de `{id, paths, consumer_workspaces}`. Es una afirmación humana, estructurada y validada: si un archivo cambiado coincide con `paths`, el planner incorpora sólo esos workspaces consumidores como candidatos. Una dependencia declarada entre workspaces no basta para propagar checks desde un archivo interno; la propagación también puede surgir de un import relativo estático observado. Una frontera no ejecuta comandos implícitamente: el check del consumidor queda `skipped` hasta ser autorizado. La salida conserva IDs de fronteras afectadas, consumidores desconocidos y límites de confianza; no infiere APIs por símbolos.

El mismo contrato puede declarar `checks` como una lista de `{id, argv, timeout_ms, modes?}`. `modes`, cuando existe, contiene una combinación única de `fast` y `final`; si se omite el check aplica a ambos. En la beta, `oguard round-end --mode fast|final` ejecuta solamente los comandos declarados para ese modo (sin shell), más los detectores universales y `git diff --check`. El planner descubre `test` siempre que exista y `lint`/`typecheck` cuando se toca código; sin autorización, o fuera del modo elegido, quedan `skipped` con su razón visible. Uno o más candidatos omitidos devuelven `unknown` con `verification: incomplete`; una omisión nunca amplía la afirmación de `pass`.

Los criterios viven en `task.acceptance_criteria` y vinculan IDs de checks reproducibles. Un criterio puede además declarar `evidence.semantic` como aserciones `{id, check, contains}`: un check aprobado sólo prueba el criterio si su salida contiene esa evidencia declarada. Si el check aprueba pero la aserción no aparece, queda `unknown`; un path coincidente jamás lo convierte en `proven`. El cierre identifica ambas fuentes como `reproducible-check` o `semantic-assertion` y los reporta como `proven`, `violated`, `unknown` o `not_applicable`; este último exige justificación explícita. En `fast`, un criterio requerido `unknown` conserva el veredicto `unknown` (salvo la obligación de regresión de `bugfix`, que sigue bloqueando); en `final`, todo criterio requerido `unknown` bloquea.

Los tipos `feature`, `refactor`, `improvement`, `migration` e `investigation` declaran `task.obligations`: cada obligación referencia uno o más IDs de criterios existentes. El conjunto requerido es fijo y visible: feature (`behavior`, `compatibility`), refactor (`preservation`), improvement (`baseline`, `metric`, `guardrails`), migration (`compatibility`, `integrity`, `recovery`) e investigation (`evidence`, `conclusion`). Una obligación sólo queda `proven` si todos sus criterios referidos están probados por checks; si falta la referencia queda `unknown` y bloquea el cierre. No se infiere una obligación desde paths, texto del objetivo ni juicio de modelo.

### RF-01 — Hook automático

Debe recibir el archivo o patch editado y ejecutar el nivel 0 sin una invocación deliberada del agente.

### RF-02 — Protocolo delta-only

Debe fingerprintar hallazgos, emitir sólo novedades y resumir resoluciones.

### RF-03 — Presupuesto de salida

Debe ordenar por severidad, limitar líneas y ofrecer un comando explícito para detalle completo.

### RF-04 — Evidencia reproducible

Cada hallazgo debe incluir regla, ubicación, mensaje, comando o comparación reproducible y versión del detector.

### RF-05 — Contrato de sesión

Debe aceptar una representación estructurada de intención sin alterar el pedido original. La clasificación automática puede proponer, pero no ocultar ambigüedad.

### RF-06 — Tipos de tarea

Debe soportar al menos `feature`, `bugfix`, `refactor`, `improvement`, `migration`, `maintenance`, `investigation` y `discovery`.

### RF-07 — Obligaciones por tipo

- `bugfix`: reproducción o test de regresión.
- `feature`: evidencia de comportamiento nuevo y compatibilidad relevante.
- `refactor`: preservación observable.
- `improvement`: baseline, métrica y guardrails.
- `migration`: compatibilidad, integridad y recuperación.
- `investigation`: evidencia y conclusiones; cambios productivos requieren transición explícita.

### RF-08 — Impacto parcial

Debe declarar confianza e incertidumbre cuando el grafo de impacto sea incompleto.

### RF-09 — Planificación de checks

Debe seleccionar checks por tipo de tarea, diff, fronteras, costo histórico, riesgo e incertidumbre mediante reglas inspeccionables.

### RF-10 — Estados de criterio

Cada criterio debe terminar en `proven`, `violated`, `unknown` o `not_applicable`, con evidencia o justificación.

### RF-11 — Excepciones auditables

Una excepción debe indicar regla, motivo, alcance, actor y expiración. No elimina el hecho observado; modifica la decisión de política.

La beta implementa excepciones locales versionadas en `exceptions[]`, con `id`, `rule`, `reason`, `actor`, `expires_at` futuro y `scope.paths` no vacío. Sólo pueden exceptuar warnings de política cuyos paths observados estén completamente dentro del scope. El cierre mantiene el warning original y registra `exception-applied`; expone por separado `effective_warnings`, que es el único conjunto que puede modificar el veredicto actual. Una excepción vencida o con schema inválido impide cargar el contrato. No hay identidad externa, aprobación remota ni autoaprobación.

### RF-12 — Instrumentación pasiva

Cada acción relevante debe producir un evento append-only con hashes, superficie, checks, duración y vínculo al contrato.

### RF-13 — Mismo motor local y CI

Las mismas reglas y contratos deben poder reproducirse fuera de la sesión del agente.

### RNF-01 — Latencia

- Nivel 0: objetivo p95 menor a 200 ms warm y menor a 400 ms cold.
- Nivel 1 rápido: p50 menor a 2 s y p95 menor a 8 s con caché.
- Nivel final: sin presupuesto único; debe informar progreso y costo esperado.

### RNF-02 — Seguridad

Los comandos usan timeout, recursos limitados y permisos declarados. El código no sale del entorno por defecto.

### RNF-03 — Reproducibilidad

Cada resultado registra baseline, hashes relevantes, versión de reglas y fingerprint del entorno.

`round-end` clasifica cada check o criterio incumplido de forma independiente como `new-failure`, `pre-existing-baseline`, `infrastructure-unavailable`, `insufficient-evidence` o `contradicted`. Un fallo global que coincide con el baseline sigue visible, pero no se informa como introducido por la ronda actual. La imposibilidad de infraestructura no equivale a una assertion fallida, y ninguna de ellas equivale a evidencia ausente.

La vista acumulativa del objetivo informa cada criterio de aceptación como `proven`, `partial`, `without-evidence` o `contradicted`, con procedencia de evidencia. Un futuro `oguard objective-status --json` expone esta vista sin tratar cantidad de archivos, churn o número de checks como progreso. En el cierre, los mismos datos producen una matriz auditable requisito → entidad cambiada → check o prueba → resultado → commit. La evidencia externa puede incluir IDs genéricos de correlación para run, task, dispatch, worker, commit y eventos de finalización; la ingesta específica de herramientas, incluida Orca, se difiere a adaptadores en lugar de incorporarse al contrato core.

La autorización de preflight informa momento de creación, duración de validez, vencimiento y la acción o transición de estado exacta que la invalida. Una denegación nombra el remedio preciso. El scope permanece declarativo, pero una corrección legítima que cruza fronteras puede adjuntar una expansión de impacto explícita con razón y evidencia; esto no redefine retroactivamente el scope padre ni suprime el hecho de que se cruzó el límite.

### RNF-04 — Escalabilidad

Los índices se actualizan por commit o archivo cambiado. Una frontera interna sin cambios públicos no debe invalidar automáticamente todo el repositorio.
