---
schema_id: oracle
schema_version: 1
applies_to: aiwiki/oracles/**/*.md
filename_pattern: "{slug}.md"
hard_cap_lines: 100
soft_target_lines: [20, 60]
required_frontmatter:
  schema_id: { type: string, equals: oracle }
  schema_version: { type: integer }
  slug: { type: string }
  prototype_path: { type: string }
  captured_at: { type: date }
  oracle_type: { type: enum, values: [route, render, interaction, snapshot, golden-trace] }
required_sections:
  - "## Setup"
  - "## Trigger"
  - "## Assertions"
section_order: strict
citation_rule: required
---

# Schema: oracle (prototype behavior snapshot)

## Purpose

An oracle captures observable behavior from the locked prototype so production code in Phase 6 has a concrete acceptance target. Tests in production are written *against* the oracle — if the production implementation doesn't reproduce the oracle's setup → trigger → assertions, it's not done.

The page answers "what specifically did the prototype do that production code must also do?"

## When to write one

- During harden (Phase 5), per slice or subsystem
- For every page/endpoint the prototype exposes (route oracle)
- For every demoed click-through (interaction oracle)
- For data shapes the prototype's frontend renders (snapshot oracle)

Do NOT write an oracle for: pure styling that's already captured in design tokens, throwaway prototype scaffolding the user never touched, error states that aren't part of the click-through demo.

## File location and naming

- Path: `aiwiki/oracles/{slug}.md`
- Slug: kebab-case, ≤8 words, identifies the oracle (e.g. `auth-login-success`, `dashboard-renders-empty-state`)

Example: `aiwiki/oracles/checkout-applies-discount-code.md`

## Required frontmatter

| Field | Type | Notes |
|---|---|---|
| `schema_id` | string | Must equal `oracle` |
| `schema_version` | integer | — |
| `slug` | string | Matches the filename slug |
| `prototype_path` | string | Path to the prototype file or directory the oracle was captured from |
| `captured_at` | ISO date | When the oracle was recorded |
| `oracle_type` | enum | `route` / `render` / `interaction` / `snapshot` / `golden-trace` |

## Required sections

| Section | Purpose | Citation requirement |
|---|---|---|
| `## Setup` | What state the system is in before the trigger fires | Cite the prototype seed/fixture, store init, or starting URL |
| `## Trigger` | The input or action that exercises the behavior | Cite the prototype handler / event |
| `## Assertions` | The observable outputs that must hold (DOM nodes, JSON body, HTTP status, transition sequence) | Cite the prototype's observed output |

## Line caps

- Hard cap: 100 lines (LINT fails above)
- Soft target: 20-60 lines

An oracle that needs more than 100 lines is probably two oracles, or is mixing setup details that belong in a fixture.

## Citation rules

- Every section cites the prototype source (`file:line@<sha7>` or `symbol` form)
- LINT auto-fills missing `@<sha7>` on first save
- Stale citations (prototype changed after oracle capture) fail LINT — resolve by re-capturing the oracle or annotating `// ack-stale: <reason>` if the production target intentionally deviates

## Skeleton

```markdown
---
schema_id: oracle
schema_version: 1
slug: auth-login-success
prototype_path: pocs/myapp-prototype/src/auth/Login.tsx
captured_at: 2026-05-10
oracle_type: interaction
---

## Setup

User is anonymous; auth store empty ([pocs/myapp-prototype/src/auth/store.ts:8@a3f2bc1](pocs/myapp-prototype/src/auth/store.ts:8)).

## Trigger

POST `/api/login` with body `{ email, password }` ([pocs/myapp-prototype/src/auth/Login.tsx:42@a3f2bc1](pocs/myapp-prototype/src/auth/Login.tsx:42)).

## Assertions

- HTTP 200 with body `{ token: <jwt>, user: { id, email } }`
- Auth store transitions `anonymous → authenticated` ([pocs/myapp-prototype/src/auth/store.ts:24@a3f2bc1](pocs/myapp-prototype/src/auth/store.ts:24))
- DOM redirects to `/dashboard` within 200ms
- Subsequent `GET /api/me` returns the same user payload
```
