# Oscar Platform — Invariants (per FVW v8 §01.1.2)

**This document declares the invariants Oscar must always satisfy.**

**Date:** 2026-06-29
**Status:** Constitutional (ratified per FVW v8 §02.1.1)

---

## 1. Sovereignty Invariants

| ID | Invariant | Enforcement |
|---|---|---|
| INV-1 | Zero `@fvs/*` imports | `vp/sovereignty.test.ts` SOV-1.1 |
| INV-2 | Zero `freshvibe-studio` imports | `vp/sovereignty.test.ts` SOV-1.2 |
| INV-3 | Zero `../../../modules/...` (FVS relative) imports | `vp/sovereignty.test.ts` SOV-1.3 |
| INV-4 | Zero `@mantine/*` imports (Sovereign SPA Mode) | `vp/sovereignty.test.ts` (new) |
| INV-5 | Brand palette declared in `branding/palette.ts` | `vp/sovereignty.test.ts` SOV-2.1, SOV-2.2 |
| INV-6 | `public/logo.svg` exists | `vp/sovereignty.test.ts` SOV-2.3 |
| INV-7 | Zero `@fvs/*` aliases referenced | `vp/sovereignty.test.ts` SOV-2.4 |
| INV-8 | Oscar does not use FVS workspace selector concept | `vp/sovereignty.test.ts` SOV-2.5 |

---

## 2. Runtime Invariants

| ID | Invariant | Enforcement |
|---|---|---|
| INV-9 | Exactly 4 canonical anchor types (custom, ai-answer, surface-context, system) | `vp/runtime.test.ts` RT-1.1 |
| INV-10 | BackStack 1000/999 preserves all anchors | `vp/runtime.test.ts` RT-1.2 |
| INV-11 | KIND_TO_TYPES is Object.frozen | `vp/runtime.test.ts` RT-1.3 |
| INV-12 | Anchor positions unique | `vp/runtime.test.ts` RT-1.4 |
| INV-13 | Anchors sorted by (position, id) | `vp/runtime.test.ts` RT-1.5 |
| INV-14 | Invalid state transitions rejected | `vp/runtime.test.ts` RT-2.1 |
| INV-15 | All 4 canonical state changes accepted | `vp/runtime.test.ts` RT-2.2 |
| INV-16 | Rail visibility: visible only in `bar` | `vp/runtime.test.ts` RT-2.3 |
| INV-17 | Swipe-up valid from `bar` | `vp/runtime.test.ts` RT-2.4 |
| INV-18 | Every anchor has `surface='assistant-sheet'` | `vp/runtime.test.ts` RT-3.1 |
| INV-19 | BackStack emits both anchor + context-switch on push | `vp/runtime.test.ts` RT-3.2 |
| INV-20 | Anchor IDs deterministic (hash of content + metadata) | `vp/runtime.test.ts` RT-3.3 |

---

## 3. Intelligence Invariants

| ID | Invariant | Enforcement |
|---|---|---|
| INV-21 | 5 adapters registered (stub, smart, anthropic, openai, local) | `vp/intelligence.test.ts` INT-1.1 |
| INV-22 | Each adapter has unique ID | `vp/intelligence.test.ts` INT-1.2 |
| INV-23 | Anthropic adapter throws on missing API key | `vp/intelligence.test.ts` INT-1.3 |
| INV-24 | OpenAI adapter throws on missing API key | `vp/intelligence.test.ts` INT-1.4 |
| INV-25 | Provider ID = `oscar-arboriculture-provider` | `vp/intelligence.test.ts` INT-2.1 |
| INV-26 | System prompt mentions BS5837 + retention categories | `vp/intelligence.test.ts` INT-2.2 |
| INV-27 | `complete()` augments prompt with system context | `vp/intelligence.test.ts` INT-2.3 |
| INV-28 | `setActiveAdapter` swaps underlying adapter | `vp/intelligence.test.ts` INT-2.4 |
| INV-29 | 6 default standards (BS5837, BS3998, BS8545, AIA, AMS, ARB) | `vp/intelligence.test.ts` INT-3.1 |
| INV-30 | Every standard has plain-language summary | `vp/intelligence.test.ts` INT-3.2 |
| INV-31 | Every standard has issuer | `vp/intelligence.test.ts` INT-3.3 |

---

## 4. Data Invariants

| ID | Invariant | Enforcement |
|---|---|---|
| INV-32 | localStorage uses `oscar:` prefix | `vp/data.test.ts` DAT-1.1 |
| INV-33 | `clearAll()` removes only `oscar:*` keys | `vp/data.test.ts` DAT-1.2 |
| INV-34 | All KEYS are namespaced constants | `vp/data.test.ts` DAT-1.3 |
| INV-35 | Tree retention category is A/B/C/U | `vp/data.test.ts` DAT-2.1 |
| INV-36 | Survey status covers draft → archived | `vp/data.test.ts` DAT-2.2 |
| INV-37 | Repository class exists | `vp/data.test.ts` DAT-3.1 |
| INV-38 | IDB store list includes trees/sites/surveys/notes/reports/posts | `vp/data.test.ts` DAT-3.2 |
| INV-39 | ULID is canonical ID type | `vp/data.test.ts` DAT-3.3 |
| INV-40 | DB_VERSION = 2 | NEW (`vp/data.test.ts` extension) |

---

## 5. UX Invariants

| ID | Invariant | Enforcement |
|---|---|---|
| INV-41 | Exports EmptyState, CompletenessMeter, UndoToast, HelpTooltip, PlainLanguageLabel, StandardsLibrary | `vp/ux.test.ts` UX-1.1 |
| INV-42 | PlainLanguageLabel has BS5837/BS3998/BS8545/AIA/AMS/ARB | `vp/ux.test.ts` UX-2.1 |
| INV-43 | PlainLanguageLabel has cat-A/B/C/U and cat-1/2/3 | `vp/ux.test.ts` UX-2.2 |
| INV-44 | Every entry has friendly label + tooltip | `vp/ux.test.ts` UX-2.3 |
| INV-45 | 5 onboarding steps in canonical order | `vp/ux.test.ts` UX-3.1 |
| INV-46 | Controller state machine works (next/goTo/finish) | `vp/ux.test.ts` UX-3.2 |
| INV-47 | 7 search kinds (view/survey/tree/note/report/standard/tool) | `vp/ux.test.ts` UX-4.1 |
| INV-48 | Returns top-scored matches first (sorted desc) | `vp/ux.test.ts` UX-4.2 |
| INV-49 | Empty query returns full corpus | `vp/ux.test.ts` UX-4.3 |
| INV-50 | UndoToast wired into save flow | NEW (`vp/ux.test.ts` extension; Phase 8 audit gap) |

---

## 6. Build/Deploy Invariants

| ID | Invariant | Enforcement |
|---|---|---|
| INV-51 | TypeScript strict mode | `vp/build.test.ts` |
| INV-52 | `.gitignore` excludes dist/, node_modules/, .env | `vp/build.test.ts` |
| INV-53 | Vite config targets browser | `vp/build.test.ts` |
| INV-54 | CF Pages project = `oscar-platform` | `vp/build.test.ts` |
| INV-55 | CI gate runs all checks | `vp/build.test.ts` |

---

## 7. Constitutional Invariants (NEW — Added Phase A1)

| ID | Invariant | Enforcement |
|---|---|---|
| INV-56 | Every module has `module.json` with `constitutional_fragments` (§35) | NEW `vp/constitutional-fragments.test.ts` |
| INV-57 | Every module has `recipe.md`, `codex.md`, `rules.md` (§11) | NEW `vp/recipe-book-structure.test.ts` |
| INV-58 | Every `rules.md` contains all 9 universal things per §11.9 | NEW `vp/rules-md-checks.test.ts` |
| INV-59 | Every `codex.md` contains C1-C8 + C9 | NEW `vp/c1-c9-codex-checks.test.ts` |
| INV-60 | `pact/recipes/smart/` exists with 6 JSON files (§16.5) | NEW `vp/smart-features-checks.test.ts` |
| INV-61 | `pact/dna/app.dna.json` is well-formed (§03) | NEW `vp/dna-checks.test.ts` |
| INV-62 | `pact/trace-atlas/atlas.json` 5-level chain well-formed (§04) | NEW `vp/atlas-checks.test.ts` |

---

## END OF INVARIANTS.MD

*Constitutional invariants for Oscar Platform. Enforced by App-VP test suite.*
