# Capa 4 — Arquitectura técnica de Objective Guard

## Vista de componentes

```text
Agente / IDE / CI
        │
        ▼
Hook + CLI + API local
        │
        ├──────────────► Event Log append-only
        ▼
Session & Contract Compiler
        │
        ├── Policy Loader
        ├── Repository Discovery
        └── Task Adapter
        │
        ▼
Impact Analyzer
        │
        ▼
Check Planner
        │
        ▼
Runner Scheduler
   ┌────┼─────────┐
   ▼    ▼         ▼
Diff   AST     Commands/Contracts
   └────┼─────────┘
        ▼
Evidence Store
        │
        ▼
Verdict Engine
        │
        ▼
Delta JSON / texto compacto / exit code
```

### Hook y CLI

Reciben eventos de edición, invocaciones explícitas y CI. El hook del nivel 0 no requiere daemon en la primera implementación.

### Detectores universales

Operan sobre contenido actual y diff contra baseline. La primera implementación incluye `syntax`, `weak-test`, `stub-prod` y `new-dep`.

### Contract Compiler

Fusiona, con procedencia y precedencia:

1. políticas globales;
2. políticas jerárquicas del repositorio;
3. contrato de sesión;
4. hechos inferidos desde manifests, schemas y tipos.

### Repository Discovery

Detecta workspaces, lenguajes, gestores, comandos, contratos públicos y ownership mediante adaptadores. No intenta comprender semántica de negocio completa.

### Impact Analyzer

Comienza con paths, manifests e imports relativos estáticos de JS/MJS/CJS. Para esos imports calcula consumidores transitivos y los incorpora a los workspaces afectados. El contrato puede sumar fronteras públicas declarativas (`id`, glob de paths y workspaces consumidores): sólo un cambio que coincide con esa frontera propaga candidatos a esos consumidores; una dependencia de workspace por sí sola no lo hace. Declara explícitamente que imports dinámicos, aliases, paths de TypeScript, otros lenguajes y análisis de API por símbolos no están resueltos. Evoluciona a símbolos mediante Tree-sitter o servidores de lenguaje; siempre devuelve confianza y huecos.

Los analizadores específicos de repositorio también pueden proveer métricas estructurales normalizadas, incluida la amplificación del cambio. Objective Guard las trata como salidas versionadas de proveedores en lugar de incorporar supuestos sobre lenguajes fuente o frameworks de tests. Un proveedor identifica entidades estables y declara el significado y las unidades de frecuencia y superficie de impacto, su método de cohortes, cobertura, puntos ciegos, confianza, fingerprint del baseline y costo de cálculo. El core compara valores de baseline y candidato y aplica la política de señales; no reinterpreta la semántica del grafo específica del proveedor.

Los scans costosos de historia, la construcción completa del grafo y el cálculo de la distribución de referencia se ejecutan al refrescar el baseline o en nivel checkpoint, no por cada edición. Los caminos por edición y por turno inspeccionan sólo entidades cambiadas y el delta local del grafo, usando artefactos cacheados del proveedor cuyas entradas y versión todavía coinciden. La invalidación de caché o cobertura ausente produce un hueco explícito y puede diferir la evaluación a un nivel posterior; no puede inventar una superficie cero. La latencia del proveedor y del core se registran por separado para que un detector útil pueda quedar fuera del camino temprano cuando rompe el presupuesto de latencia.

### Check Planner

Selecciona checks mediante reglas inspeccionables y costo histórico. Un modelo puede proponer, pero no decidir de forma opaca.

### Runner Scheduler

Ejecuta primero checks baratos, paraleliza cuando es seguro, aplica timeout, cancela trabajo innecesario y reutiliza caché.

En la alpha portable, el scheduler tiene una política de seguridad más estricta: siempre ejecuta los detectores universales y `git diff --check`; sólo ejecuta comandos presentes explícitamente en `oguard.contract.json#checks`. Si descubre `package.json#scripts.test` sin una declaración equivalente, lo registra como `skipped`, nunca como aprobado ni como comando a ejecutar implícitamente. Los checks declarados pueden reutilizar una caché local bajo `.oguard/cache/checks`: la clave contiene argv, hash de contrato, versión de Node y hashes de toda la superficie modificada salvo `.oguard/**`. Cada resultado informa `cache.hit`; un cambio de entradas o contrato produce miss. No hay caché distribuida ni reutilización de checks descubiertos.

### Evidence Store y Verdict Engine

El store conserva sesiones, criterios, resultados, hashes y procedencia. El motor aplica política sobre hechos sin fusionarlos con inferencias.

## Flujo por niveles

### Nivel 0 — Por edición

```text
edit → diff de archivo → detectores paralelos → fingerprints → delta → evento
```

- Objetivo: p95 menor a 200 ms warm.
- Fallo interno: `error` en log y salida no bloqueante.
- Salida: máximo cinco líneas nuevas.

### Nivel 1 — Por save o turno

```text
patch → contrato → impacto local → tests/typecheck/lint afectados → evidencia
```

- Objetivo: p50 menor a 2 s con caché.
- Puede producir `unknown`, `warn` o `block` determinista.

### Nivel 2 — Checkpoint o cierre

```text
sesión completa → criterios → impacto ampliado → checks finales → artefacto auditable
```

- Exige estado de cada criterio.
- Reutiliza resultados válidos de niveles anteriores.
- Informa progreso para verificaciones largas.

### Plano científico

Recibe copias de eventos sin alterar inicialmente la salida al agente. Calcula features de trayectoria offline y separa calibración de evaluación.

Para amplificación del cambio registra factores de baseline y candidato, cohorte, estadístico de outlier, cruces de umbral, si la entidad sólo fue tocada o cambió su superficie de impacto, cobertura del proveedor, latencia, acción posterior y utilidad adjudicada. La telemetría orgánica del desarrollo activo es evidencia elegible de calibración, sujeta a las mismas exclusiones y reglas de etiquetado que otras señales estadísticas; la observación por sí sola no activa advertencias al agente.

## Persistencia y protocolo

Estructura local provisional:

```text
.oguard/
├── state.json          # fingerprints delta-only; descartable
├── history/             # contratos y baselines previos, append-only por hash
├── sessions/           # contratos compilados
├── evidence.sqlite     # sesiones, checks y criterios
├── cache/              # artefactos direccionados por hash
└── log/events.jsonl    # telemetría append-only
```

El estado delta es descartable: perderlo puede re-reportar un hallazgo, pero no debe silenciarlo.

La transición de ronda no sobrescribe historia: archiva el contrato y baseline activos antes de mover el puntero `session-baseline.json` a la nueva ronda. El comando exige un árbol limpio, para que el corte entre rondas tenga un commit o una decisión Git recuperable como frontera temporal.

Un contrato tipado histórico sin baseline puede generar su primer puntero mediante `adopt-baseline`, también sólo con árbol limpio. El evento append-only conserva el commit de adopción; una vez creado, el baseline no se vuelve a adoptar ni se reemplaza salvo por `next-round`, que primero archiva el anterior.

La beta escribe `state.json` mediante rename atómico y serializa mutaciones locales con un lock de corta duración. Si el estado es ilegible o sigue ocupado, devuelve `error` y conserva los archivos para revisión; no los elimina ni sustituye por un estado vacío.

Evento mínimo:

```json
{
  "run_id": "run_001",
  "step": 17,
  "action": "apply_patch",
  "files_changed": ["src/example.ts"],
  "diff_hash": "sha256:...",
  "contract_hash": "sha256:...",
  "surface": {},
  "checks": [],
  "duration_ms": 83
}
```

Fingerprint de hallazgo:

```text
hash(regla, archivo, ventana-normalizada, mensaje-normalizado, versión-regla)
```

Clave de caché:

```text
hash(check, versión, entradas-relevantes, manifests, entorno)
```

## Seguridad y fallos

- Los procesos se ejecutan con timeout y límites de recursos.
- Los plugins declaran permisos y comandos.
- No se envía código a servicios externos por defecto.
- La configuración no puede convertir `error` en `pass`.
- El kill switch existe para incidentes, pero su uso se registra localmente.
- Un detector con falsos positivos repetidos debe degradarse o deshabilitarse por política, no ser ignorado silenciosamente.
- Las excepciones conservan el hecho original y sólo alteran la decisión.
- Un hallazgo estadístico no calibrado nunca bloquea.

El lenguaje se decide con un spike de latencia. TypeScript/Bun maximiza iteración; Go o Rust pueden ser necesarios si cold start y parsing rompen el presupuesto. La arquitectura debe evitar acoplar el contrato del producto a esa elección.
