# Oscar Platform — FvRE Gate

**50 invariants verifying Oscar's sovereignty, runtime correctness, intelligence, data model, UX, and build/deploy.**

## Suite breakdown

| Suite | File | Count | Category |
|---|---|---|---|
| **Sovereignty** | `sovereignty-checks.ts` | 8 | No FVS imports, own brand, no workspace selector |
| **Runtime** | `runtime-checks.ts` | 12 | 4-state dock, anchor invariants, state machine, rail visibility |
| **Intelligence** | `intelligence-checks.ts` | 11 | 4 adapters, vendor-neutral provider, 6 standards |
| **Data** | `data-checks.ts` | 8 | localStorage namespace, types, Repository pattern |
| **UX** | `ux-checks.ts` | 9 | 6 components, plain-language labels, onboarding, search |
| **Build / Deploy** | `build-checks.ts` | 11 | Config files, tsconfig strict, CI sovereignty grep, CF Pages deploy |
| **Adversarial probes** | `adversarial-probes.ts` | 8 | Deep attacks against each invariant category |
| **TOTAL** | — | **50 + 8 = 58** | FvRE gate |

## Sovereignty (8)

- **SOV-1.1** no Oscar file imports `@fvs/*`
- **SOV-1.2** no Oscar file imports `freshvibe-studio`
- **SOV-1.3** no Oscar file imports via `../modules/...`
- **SOV-2.1** `branding/palette.ts` exists
- **SOV-2.2** `branding/theme.ts` exists
- **SOV-2.3** `public/logo.svg` exists
- **SOV-2.4** no `@fvs/*` aliases referenced
- **SOV-2.5** no Oscar file uses workspace selector concept

## Runtime (12)

- **RT-1.1** exactly 4 canonical anchor types
- **RT-1.2** BackStack 1000/999 preserves all anchors (pop does not remove)
- **RT-1.3** KIND_TO_TYPES is Object.frozen
- **RT-1.4** Anchor positions are unique
- **RT-1.5** Anchors sorted by (position, id)
- **RT-2.1** invalid state transitions rejected
- **RT-2.2** all 4 canonical state changes accepted
- **RT-2.3** rail visibility: visible only in `bar`
- **RT-2.4** swipe-up is valid from `bar`
- **RT-3.1** every anchor has `surface='assistant-sheet'`
- **RT-3.2** BackStack emits both anchor + context-switch on push
- **RT-3.3** Anchor IDs are deterministic (hash of content + metadata)

## Intelligence (11)

- **INT-1.1** 4 adapters registered (stub, anthropic, openai, local)
- **INT-1.2** each adapter has unique id
- **INT-1.3** anthropic adapter throws on missing key
- **INT-1.4** openai adapter throws on missing key
- **INT-2.1** provider id is `oscar-arboriculture-provider`
- **INT-2.2** system prompt mentions BS 5837 + retention categories
- **INT-2.3** complete() augments prompt with system context
- **INT-2.4** setActiveAdapter swaps underlying adapter
- **INT-3.1** 6 default standards
- **INT-3.2** every standard has plain-language summary
- **INT-3.3** every standard has issuer

## Data (8)

- **DAT-1.1** localStorage uses `oscar:` prefix
- **DAT-1.2** clearAll removes only `oscar:*` keys
- **DAT-1.3** all KEYS are namespaced constants
- **DAT-2.1** Tree retention category is A/B/C/U
- **DAT-2.2** Survey status covers draft → archived
- **DAT-3.1** Repository class exists
- **DAT-3.2** IndexedDB store list includes trees/sites/surveys/notes/reports/attachments
- **DAT-3.3** ULID is the canonical id type

## UX (9)

- **UX-1.1** exports EmptyState, CompletenessMeter, UndoToast, HelpTooltip, PlainLanguageLabel, StandardsLibrary
- **UX-2.1** PlainLanguageLabel has BS5837/BS3998/BS8545/AIA/AMS/ARB
- **UX-2.2** PlainLanguageLabel has cat-A/B/C/U and cat-1/2/3
- **UX-2.3** every entry has friendly label + tooltip
- **UX-3.1** 5 onboarding steps in canonical order
- **UX-3.2** controller state machine works (next / goTo / finish)
- **UX-4.1** 7 search kinds (view/survey/tree/note/report/standard/tool)
- **UX-4.2** returns top-scored matches first (sorted by score desc)
- **UX-4.3** search empty-query returns full corpus

## Build / Deploy (11)

- **BLD-1.1** package.json exists
- **BLD-1.2** app/tsconfig.json exists
- **BLD-1.3** app/vite.config.ts exists
- **BLD-1.4** .github/workflows/ci.yml exists
- **BLD-1.5** .github/workflows/deploy.yml exists
- **BLD-1.6** pact/platform/sovereignty.md exists
- **BLD-2.1** tsconfig has `strict: true`
- **BLD-2.2** tsconfig defines all 12 @/* aliases
- **BLD-3.1** ci.yml greps for forbidden patterns (@fvs, freshvibe-studio)
- **BLD-4.1** deploy.yml uses `wrangler pages deploy`
- **BLD-4.2** deploy.yml targets `oscar-platform` project
- **BLD-5.1** logo.svg exists
- **BLD-5.2** manifest.json declares Oscar

## Adversarial probes (8)

- **P1** BackStack 1000 push/999 pop (pop does NOT remove anchors)
- **P2** rail visibility binding
- **P3** KIND_TO_TYPES runtime mutation blocked by Object.freeze
- **P4** invalid state transitions rejected
- **P5** Oscar's own Pact (no FVS Pact dependency)
- **P6** 5th anchor type rejected
- **P7** (position, id) composite sort
- **P8** sovereignty grep (runtime CI enforcement)

## How to run

```bash
cd app
npm install
npx vitest run pact/vp/   # all FvRE checks
```

Expected output: **58/58 PASS** before declaring Phase 6 complete.

## Integration with CI

`.github/workflows/ci.yml` runs these tests on every push:

```yaml
- name: FvRE gate
  run: npx vitest run pact/vp/
```

If any of the 58 checks fail, the build fails. Oscar cannot ship with broken invariants.