# Layer 4 — Objective Guard Technical Architecture

## Component view

```text
Agent / 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 / compact text / exit code
```

### Hook and CLI

Receive edit events, explicit invocations, and CI triggers. The level 0 hook does not require a daemon in the first implementation.

### Universal Detectors

Operate on current content and diff against baseline. The first implementation includes `syntax`, `weak-test`, `stub-prod`, and `new-dep`.

### Contract Compiler

Merges, with provenance and precedence:

1. global policies;
2. hierarchical repository policies;
3. session contract;
4. facts inferred from manifests, schemas, and types.

### Repository Discovery

Detects workspaces, languages, package managers, commands, public contracts, and ownership via adapters. Does not attempt to understand complete business semantics.

### Impact Analyzer

Begins with paths, manifests, and static relative JS/MJS/CJS imports. For those imports it computes transitive consumers and folds them into the affected workspaces. The contract can add declarative public boundaries (`id`, path glob, and consumer workspaces): only a change that matches that boundary propagates candidates to those consumers; a workspace dependency alone does not. It explicitly declares that dynamic imports, aliases, TypeScript paths, other languages, and symbol-level API analysis are unresolved. Evolves to symbols via Tree-sitter or language servers; always returns confidence and gaps.

Repository-specific analyzers may also provide normalized structural metrics, including change amplification. Objective Guard treats these as versioned provider outputs rather than embedding assumptions about source languages or test frameworks. A provider identifies stable entities and declares the meaning and units of frequency and impact surface, its cohorting method, coverage, blind spots, confidence, baseline fingerprint, and computation cost. The core compares baseline and candidate values and applies signal policy; it does not reinterpret provider-specific graph semantics.

Expensive history scans, full graph construction, and reference-distribution calculation run at baseline refresh or checkpoint level, not for every edit. The per-edit and per-turn paths inspect only changed entities and the local graph delta, using cached provider artifacts whose inputs and version still match. Cache invalidation or absent coverage produces an explicit gap and may defer evaluation to a later level; it cannot fabricate a zero surface. Provider and core latency are recorded separately so that an otherwise useful detector can be kept out of the early path when it breaks the latency budget.

### Check Planner

Selects checks using inspectable rules and historical cost. A model may propose, but not decide opaquely.

### Runner Scheduler

Runs cheap checks first, parallelizes when safe, applies timeout, cancels unnecessary work, and reuses cache.

In the portable alpha, the scheduler enforces a stricter security policy: it always runs the universal detectors and `git diff --check`; it only runs commands explicitly present in `oguard.contract.json#checks`. If it discovers `package.json#scripts.test` without an equivalent declaration, it records it as `skipped`, never as approved nor as a command to run implicitly. Declared checks can reuse a local cache under `.oguard/cache/checks`: the key contains argv, contract hash, Node version, and hashes of the entire modified surface except `.oguard/**`. Each result reports `cache.hit`; a change in inputs or contract produces a miss. There is no distributed cache or reuse of discovered checks.

### Evidence Store and Verdict Engine

The store preserves sessions, criteria, results, hashes, and provenance. The engine applies policy over facts without merging them with inferences.

## Flow by levels

### Level 0 — Per Edit

```text
edit → file diff → parallel detectors → fingerprints → delta → event
```

- Goal: p95 under 200 ms warm.
- Internal failure: `error` in log and non-blocking output.
- Output: maximum five new lines.

### Level 1 — Per Save or Turn

```text
patch → contract → local impact → affected tests/typecheck/lint → evidence
```

- Goal: p50 under 2 s with cache.
- Can produce deterministic `unknown`, `warn`, or `block`.

### Level 2 — Checkpoint or Close

```text
full session → criteria → expanded impact → final checks → auditable artifact
```

- Requires state of each criterion.
- Reuses valid results from earlier levels.
- Reports progress for long-running verifications.

### Scientific Plane

Receives copies of events without initially altering agent output. Calculates trajectory features offline and separates calibration from evaluation.

For change amplification it records baseline and candidate factors, cohort, outlier statistic, threshold crossings, whether the entity was merely touched or its impact surface changed, provider coverage, latency, subsequent action, and adjudicated usefulness. Organic telemetry from active development is eligible calibration evidence, subject to the same exclusions and labeling rules as other statistical signals; observation alone does not activate agent-facing warnings.

## Persistence and protocol

Provisional local structure:

```text
.oguard/
├── state.json          # delta-only fingerprints; discardable
├── history/            # previous contracts and baselines, append-only by hash
├── sessions/           # compiled contracts
├── evidence.sqlite     # sessions, checks, and criteria
├── cache/              # artifacts indexed by hash
└── log/events.jsonl    # append-only telemetry
```

Delta state is discardable: losing it may re-report a finding, but must not silence it.

Round transition does not overwrite history: it archives the active contract and baseline before moving the `session-baseline.json` pointer to the new round. The command requires a clean tree, so the cut between rounds has a commit or a recoverable Git decision as a temporal boundary.

A historical typed contract without a baseline can generate its first pointer via `adopt-baseline`, also only with a clean tree. The append-only event preserves the adoption commit; once created, the baseline is not adopted again nor replaced except by `next-round`, which first archives the previous one.

The beta writes `state.json` via atomic rename and serializes local mutations with a short-lived lock. If the state is unreadable or still locked, it returns `error` and preserves the files for review; it does not delete them or replace them with an empty state.

Minimal event:

```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
}
```

Finding fingerprint:

```text
hash(rule, file, normalized-window, normalized-message, rule-version)
```

Cache key:

```text
hash(check, version, relevant-inputs, manifests, environment)
```

## Security and failures

- Processes run with timeout and resource limits.
- Plugins declare permissions and commands.
- Code is not sent to external services by default.
- Configuration cannot convert `error` to `pass`.
- A kill switch exists for incidents, but its use is logged locally.
- A detector with repeated false positives must be degraded or disabled by policy, not silently ignored.
- Exceptions preserve the original fact and only alter the decision.
- An uncalibrated statistical finding never blocks.

Language is decided via a cold start latency spike. TypeScript/Bun maximizes iteration; Go or Rust may be necessary if cold start and parsing break the budget. Architecture must avoid coupling the product contract to that choice.
