# PRD: Objective Guard

## Document Status

- Status: initial draft
- Product Type: local/CI tool for programming agents
- Audience: teams using AI agents to develop, maintain, and repair software
- Provisional Name: Objective Guard

## 1. Executive Summary

Objective Guard is a programmatic continuous verification system for code agents. Its purpose is to detect, with the lowest possible latency, whether a change:

1. drifts from the declared objective;
2. breaks existing behavior or contracts;
3. modifies a larger surface than necessary;
4. lacks sufficient evidence to be considered correct.

The product does not attempt to exhaustively understand the entire repository nor replace existing tests, linters, or analyzers. It works as a control plane that, for each task, composes global rules, rules for the affected area, evidence extracted from the repository, and a temporal contract of intent. Based on the diff and impact graph, it selects the minimal necessary verifications and returns a structured and compact result to the agent.

The scalability premise is:

> The cost of validation must grow with the impact radius of the change, not with the total size of the repository.

## 2. Problem

Programming agents can produce syntactically correct code and still:

- solve a different variant of the requested problem;
- unnecessarily expand scope;
- break public contracts or non-obvious invariants;
- introduce a regression in a dependent module;
- declare success without providing verifiable evidence;
- waste context and tokens before discovering a basic error.

Existing tools validate isolated dimensions — compilation, style, tests, or security — but normally do not relate those signals to the concrete intent of the task. On the other hand, manually describing an entire repository through detailed rules is costly and degrades quickly.

## 3. Product Objective

Provide any programming agent with a deterministic, incremental, and low-latency feedback cycle that answers:

- Is the change still aligned with the objective?
- What contracts or areas might it affect?
- What evidence is missing to prove it is complete?
- Should it continue, correct, or ask for a human decision?

## 4. Non-Objectives

Objective Guard does not aim to:

- formally prove that any program is correct;
- replace agent reasoning or human review;
- maintain an exhaustive manual specification of the repository;
- always run the entire CI suite;
- decide ambiguous product requirements without human intervention;
- use a second model as the final authority on correctness.

It may use models to propose classifications or contracts, but an AI-generated rule will only be blocking when it translates to evidence or reproducible checks.

## 5. Users and Use Cases

### 5.1 Primary User

A programming agent that inspects, edits, and verifies code using local tools.

### 5.2 Secondary Users

- Developers supervising the agent.
- Platform teams defining global policies.
- Module owners maintaining local invariants.
- CI, used as final verification of the same rules.

### 5.3 Supported Task Types

| Type | Expected Minimum Test |
| --- | --- |
| `feature` | New behavior exists and relevant previous behavior is preserved. |
| `bugfix` | A reproduction of the failure exists and passes after the change; nearby regressions are covered. |
| `refactor` | Observable behavior is preserved within the affected surface. |
| `improvement` | A defined metric improves from baseline without prohibited degradations. |
| `migration` | State or contract migrates from A to B with compatibility and recovery strategy. |
| `maintenance` | Operational or dependency changes satisfy compatibility, security, and build. |
| `investigation` | Evidence and conclusions are produced; implicit productive changes are not enabled. |

If intent is ambiguous, the system uses the `discovery` state. In that state it allows inspection and contract proposal, but alerts before high-impact productive modifications.

## 6. Design Principles

### 6.1 Composite Contracts

The effective contract of a task is built through layers:

1. Global policies: security, secrets, licenses, architectural boundaries, and base commands.
2. Module policies: public contracts, invariants, and area-specific verifications.
3. Task contract: intent, expected scope, acceptance criteria, and temporal constraints.
4. Inferred evidence: manifests, types, OpenAPI, schemas, CODEOWNERS, tests, and dependency graph.

More specific layers can add restrictions. An exception to a higher-level policy must be explicit, traceable, and when appropriate, approved.

### 6.2 Incremental Validation

Cheap checks run first. Expensive verifications are triggered based on risk and impact.

### 6.3 Auditable Determinism

Each `block` must indicate rule, evidence, file, location, and how to reproduce it. A probabilistic inference can produce `warn` or propose a rule, but cannot block by itself.

### 6.4 Output Optimized for Agents

The primary output is stable, brief, and actionable JSON. Human explanation is a secondary view.

### 6.5 Safe Degradation

If sufficient information does not exist, the system should say `unknown` or request evidence. It should not convert absence of knowledge into a claim of correctness.

## 7. Product Experience

### 7.1 Task Start

The agent registers or generates a session:

```bash
oguard start \
  --kind bugfix \
  --goal "Fix checkout when coupon is expired" \
  --acceptance "Checkout continues without applying the coupon"
```

Objective Guard inspects the repository, identifies the probable area, and generates a session contract. The agent can expand or correct it before editing.

### 7.2 Fast Cycle

After each significant patch:

```bash
oguard check --staged-or-working-tree --mode fast --format json
```

Expected response:

```json
{
  "status": "block",
  "session": "og_01J...",
  "impact": {
    "risk": "high",
    "modules": ["checkout", "pricing"],
    "public_boundaries": ["CheckoutService.complete"]
  },
  "violations": [
    {
      "rule_id": "checkout.tax-invariant",
      "severity": "block",
      "file": "src/checkout/total.ts",
      "line": 48,
      "message": "Tax calculation changed outside the objective.",
      "evidence": "contract-test checkout-tax: expected 21.00, received 19.50",
      "next_action": "Restore the calculation or declare a scope expansion."
    }
  ],
  "checks_run": 7,
  "checks_skipped": 18,
  "duration_ms": 1830
}
```

### 7.3 Final Verification

Before declaring the task complete:

```bash
oguard check --mode final
```

Final mode requires evidence for each acceptance criterion and runs higher-coverage verifications within the impact radius.

## 8. Functional Requirements

### RF-1: Objective Session

The system must create an isolated session containing:

- textual objective;
- task type;
- acceptance criteria;
- explicit constraints;
- commit or state used as baseline;
- current validation state.

### RF-2: Intent Classification

Must accept an explicit classification and can suggest it automatically. If confidence or information are insufficient, must select `discovery`.

### RF-3: Repository Discovery

Must detect, through adapters:

- language, build system, and package manager;
- modules or workspaces;
- existing test, typecheck, and lint commands;
- public contract files;
- ownership and architectural boundaries;
- related tests and coverage, when available.

### RF-4: Impact Radius Calculation

From the diff must identify:

- changed symbols;
- owning and dependent modules;
- affected APIs, schemas, migrations, or events;
- directly and indirectly related tests;
- change risk level.

The system must tolerate a partial graph and declare uncertainty.

### RF-5: Check Planning

Must select checks based on a combination of:

- task type;
- modified files and symbols;
- applicable rules;
- affected public boundaries;
- historical cost of check;
- risk and uncertainty.

### RF-6: Check Execution

Must initially support:

- rules on paths and diff size;
- forbidden pattern search;
- repository commands;
- focused tests;
- focused typecheck and lint;
- OpenAPI/JSON Schema comparison;
- comparison of exports or public signatures;
- AST rules through plugins;
- validation that a bugfix includes reproduction or regression test.

### RF-7: Traceability

Each acceptance criterion must end in one of these states:

- `proven`: reproducible evidence exists;
- `violated`: evidence to the contrary exists;
- `unknown`: sufficient evidence still does not exist;
- `not_applicable`: explicitly justified.

### RF-8: Drift Budget

Must calculate independent signals, not a single opaque score:

- scope expansion;
- change in public boundaries;
- unrelated files;
- new dependencies;
- criteria without evidence;
- cumulative risk of diff.

A policy can convert combinations of signals into `warn` or `block`.

### RF-9: Exceptions

The agent can request an exception, but must include reason, affected rule, and scope. Exceptions are logged in the session and may require human approval per policy.

### RF-10: Integrations

The MVP must work through:

- local CLI;
- invocable hook by agents after editing;
- JSON output via `stdout`;
- stable exit codes for `pass`, `warn`, `block`, and `error`;
- execution in CI using the same contract.

## 9. Non-Functional Requirements

### Latency

- `fast` mode: p50 less than 2 seconds and p95 less than 8 seconds on cached checks.
- First inspection: target less than 30 seconds for medium-sized repositories.
- The system must emit partial results when a long check continues running.

### Scalability

- Must not require indexing the entire repository on each run.
- Must store indices by commit and update only changed files.
- Must support monorepos with tens of thousands of files through per-workspace adapters.

### Reproducibility

- Each result must record rule version, baseline, command, and hash of relevant inputs.
- A deterministic check must be reproducible outside the agent.

### Security

- Commands must execute with time and resource limits.
- The engine must not send code to external services by default.
- Plugins must declare permissions and capabilities.

## 10. Contract Model

Indicative example:

```yaml
version: 1
session:
  kind: bugfix
  goal: Fix checkout when coupon is expired
  baseline: git:HEAD

acceptance:
  - id: expired-coupon
    statement: Checkout continues without applying an expired coupon
    evidence:
      require:
        - test: checkout.expired_coupon
  - id: valid-coupon
    statement: Valid coupons continue to be applied
    evidence:
      require:
        - test: checkout.valid_coupon

scope:
  expected:
    - packages/checkout/**
  sensitive:
    - packages/pricing/**
    - packages/tax/**

invariants:
  - id: no-tax-change
    source: module:tax
    check: contract-test
  - id: public-api-compatible
    source: inferred:typescript-exports
    check: api-diff

policy:
  unknown_acceptance: block_on_final
  public_boundary_change: require_approval
```

This file represents the compiled contract. The user interface can accept natural language, but the engine operates on a structured representation.

## 11. Technical Approach

### 11.1 Architecture

```text
Agent / Developer / CI
          |
          v
       CLI/API
          |
          v
   Session & Contract Compiler
      |        |         |
      v        v         v
 Policy     Repo      Task-type
 Loader   Discovery    Adapter
      \        |         /
       v       v        v
        Impact Analyzer
          |
          v
       Check Planner
          |
          v
      Runner Scheduler
       |     |      |
      AST  Commands Contracts
       \     |      /
        v    v     v
      Evidence Store
          |
          v
      Verdict Engine
          |
          v
  JSON result + exit code
```

### 11.2 Components

#### Contract Compiler

Merges global policies, hierarchical repository policies, session contract, and inferences. Produces a normalized list of rules with precedence and provenance.

#### Repository Discovery

Uses adapters to recognize Gradle, Maven, npm/pnpm/bun, Cargo, or other ecosystems. Does not interpret business; discovers commands, build units, and metadata.

#### Impact Analyzer

The MVP can start with paths, imports, and manifests. Later versions add symbol analysis through Tree-sitter or language servers. Its output must include confidence level to avoid false precision.

#### Check Planner

Determines which checks to run through explicit rules. Example:

```text
IF task.kind == bugfix
AND changed.module == checkout
THEN require regression-test(checkout)

IF public_api.changed
THEN run api-diff
AND require approval when breaking
```

It is not recommended that an LLM be the definitive planner. It can suggest checks, but the final plan must be inspectable.

#### Runner Scheduler

Runs cheap and parallelizable checks first, cancels unnecessary work on conclusive blocks, and reuses cache by hash of inputs.

#### Evidence Store

A local SQLite database is sufficient for the MVP. Must store sessions, compiled rules, executions, duration, hashes, and relationship between criteria and evidence. Heavy artifacts can remain in content-addressed files.

#### Verdict Engine

Applies deterministic policies over results. Must keep separate:

- facts: "a public signature changed";
- inferences: "probably this file does not belong to the objective";
- decisions: "a public change requires approval".

### 11.3 Suggested Stack

For a portable MVP:

- Language: Rust or TypeScript.
- Initial recommendation: TypeScript for fast iteration and integration with agents; migrate critical runners only if metrics justify it.
- Persistence: SQLite.
- Multi-language parsing: Tree-sitter.
- Contracts: JSON Schema to validate configuration.
- Execution: local isolated processes with timeout.
- Distribution: packaged binary or npm package with executable.

The architecture must keep the core independent of the ecosystem through plugin interfaces.

### 11.4 Main Interfaces

```ts
interface RepositoryAdapter {
  discover(root: string): Promise<RepositoryModel>;
  affectedUnits(diff: Diff): Promise<ImpactSet>;
}

interface CheckProvider {
  plan(context: CheckContext): Promise<PlannedCheck[]>;
  run(check: PlannedCheck, signal: AbortSignal): Promise<Evidence>;
}

interface PolicyRule {
  evaluate(facts: FactSet): VerdictContribution;
}
```

### 11.5 Incremental Strategy and Cache

A check's cache key must include:

```text
hash(
  check-version,
  command-or-rule,
  relevant-input-files,
  dependency-manifests,
  environment-fingerprint
)
```

The imports and symbol index is updated only for changed files. The system invalidates consumers only when an exported boundary changes; an internal change must not automatically propagate validation to the entire repository.

## 12. MVP

### Scope

The MVP must validate a task over Git repositories with TypeScript/JavaScript and offer:

1. sessions with `feature`, `bugfix`, `refactor`, and `improvement`;
2. YAML contract validated by schema;
3. analysis of `git diff` and path rules;
4. discovery of workspaces and package manager scripts;
5. test selection by workspace and related files;
6. execution of lint, typecheck, and existing tests;
7. basic detection of modified public exports;
8. criterion-evidence traceability;
9. `fast` and `final` modes;
10. JSON output and documented exit codes;
11. local SQLite cache;
12. generic hook integration for agents.

### Out of MVP

- Reliable automatic generation of business invariants.
- Deep support for all languages.
- Distributed inter-service analysis.
- Centralized dashboard.
- Self-approval of scope changes.

### MVP Acceptance Criteria

- On an example bugfix, blocks completion if no regression evidence exists.
- On a feature, detects an incompatible change in a public export.
- On an internal refactor, avoids running tests for unaffected workspaces.
- A second run without changes is at least 70% faster.
- Every block includes a local reproduction and a suggested action.
- Can integrate with an agent using a single command and JSON via stdout.

## 13. Metrics

### Primary Metric

Percentage of deviations or regressions detected before the agent completes the task.

### Operational Metrics

- time to first useful signal;
- percentage of checks avoided compared to complete CI;
- false block rate;
- rate of tasks closed with `unknown` criteria;
- amount of corrections made within two patches after an alert;
- tokens or turns consumed after introducing a defect and before detecting it;
- cache hit rate;
- duration p50/p95 per mode.

### Initial Targets

- Detect at least 70% of embedded regressions within supported scope.
- Keep false blocks below 5%.
- Emit first deterministic signal in less than 2 seconds p50.
- Reduce at least 50% of checks run compared to complete suite on local changes.

## 14. Risks and Mitigations

| Risk | Mitigation |
| --- | --- |
| False sense of correctness | Use explicit `unknown` and report evidence coverage. |
| Difficult-to-maintain rules | Infer configuration, maintain few policies at critical boundaries, and measure unused rules. |
| False positives the agent learns to ignore | Separate `warn` from `block`; require reproducible evidence to block. |
| Incomplete impact graph | Propagate confidence; expand checks when uncertainty is high. |
| Excessive latency | Fast/final stages, cache, parallelism, and early cancellation. |
| Generated contract that changes objective | Preserve the original request, show the derived contract, and log expansions. |
| Plugins executing unsafe commands | Declared capabilities, sandbox, timeout, and allowlists. |
| Costly adoption | Initially work with scripts and metadata already in the repository. |

## 15. Proposed Roadmap

### Phase 0: Prototype

- YAML contract.
- Diff by paths.
- Command runner.
- JSON verdict.
- One test repository with seeded scenarios.

### Phase 1: MVP

- TypeScript/JavaScript adapter.
- Workspaces, affected tests, public exports, and SQLite.
- Integration with at least one code agent.
- Latency and accuracy benchmark.

### Phase 2: Precision

- AST/symbol index.
- OpenAPI/JSON Schema compatibility.
- Statistical learning only for check prioritization.
- Tools to explain and inspect the plan.

### Phase 3: Ecosystem

- Plugin SDK.
- Java/Gradle, Python, and Rust adapters.
- Distributed execution and CI result reuse.
- Signed organizational policies.

## 16. Open Questions

- What will be the first target agent or integration protocol?
- Should the task contract persist in Git or live as an ephemeral artifact?
- What level of human intervention is required for scope expansion?
- How to identify a new regression test versus a preexisting one?
- Which ecosystem best represents the pilot repository?
- What sandbox and network restrictions should be considered from the first release?

## 17. First Experimental Validation

Before building the complete product, it is recommended to create a benchmark with 30 real or synthesized tasks, balanced between feature, bugfix, refactor, and improvement. For each task, prepare:

- objective and criteria;
- correct change;
- one or more seeded deviations;
- checks that should activate;
- expected impact radius;
- maximum acceptable time to first alert.

The prototype is considered promising if it detects deviations early without resorting to a complete suite and maintains a low rate of non-actionable blocks. This benchmark must evolve as the product's own contract.

The complete experimental design, its falsifiable hypotheses, variables, controls, and statistical plan are defined in [Scientific Protocol: Agent Drift in Growing Repositories](research-protocol-agent-drift.md).
