# Assistant Module — Recipe (per FVW v8 §11.1)

**Per FVW v8 v0.10.0 §11.1:** `recipe.md` describes the product itself — what the module is, what it must contain, what it must not do. Three internal sections: A. Product Description, B. Structural Contract, C. Reconstruction Notes.

**Module ID:** `oscar.assistant`
**Module version:** 0.2.0
**Status:** Constitutional (per §01 mandatory artefacts)

---

## A. Product Description

**What this module is:** The Oscar AI assistant dock — a 4-state UI surface (bar / sheet-min / sheet-full / peek) that lets the operator ask questions, classify trees, draft blog posts, and execute actions on Oscar's content. The assistant is powered by 1 of 5 LLM adapters (stub / smart / anthropic / openai / local). The Smart adapter (default) implements a 9-layer dispatcher (heuristic / web-search / data / history / classify / standard / how-to / off-topic / clarify).

**UI structure:**
- **Bar** — dormant bottom bar (when user is not interacting)
- **SheetMin** — peek state with quick input
- **SheetFull** — open state with full conversation history
- **Peek** — lifted view (peek-panel)

**Layout / geometry:** see C8 Shape Matrix in codex.

**States:** 4 dock states + BackStack with side 1000/999.

**Pedagogical section (P1):** This is the user's primary point of contact with Oscar's AI. Every other module's "AI assist" feature routes through `askOscar()`. The 9-layer dispatcher is the canonical pattern for "smart without cloud" — by §15, the default is rules-first, cached-second, AI-third.

---

## B. Structural Contract

### B.0 Reconstruction Mode Declaration (per §33, §33.5)

- **Mode:** Sovereign SPA Mode (per DO-001)
- **Target runtime:** React 18 + TypeScript + Vite
- **Module file extension:** .tsx (UI) + .ts (logic)
- **View fragment format:** React components in `<Name>.tsx`
- **State management:** React hooks + module-level singletons (`__sharedMemory`)
- **Theme tokens:** CSS custom properties
- **Render approach:** JSX with conditional render (per dock state)
- **Mount point:** `<AssistantDock>` rendered in `OscarShell`

### B.1 Inputs/Outputs

**Inputs:**
- `prompt: string` (user input)
- `history?: string[]` (previous turns)
- `provider: LlmProviderId` (active provider selection)
- `appData: DataSummary` (cached for Layer 2)

**Outputs:**
- `AskResult` = `{ text, provider, latencyMs, error? }`
- `Action[]` (rendered as chips)
- DOM updates (sheet open/close, message render)

### B.2 Interface Contract (R5)

```ts
// Single entrypoint
export async function askOscar(prompt: string, history?: string[]): Promise<AskResult>;

// Action chip types
export type AssistantAction =
  | { type: 'navigate'; target: string }
  | { type: 'open-item'; store: string; id: string }
  | { type: 'compose'; template: string }
  | { type: 'export'; format: 'pdf' | 'docx' | 'md'; source: string };

// State machine
export type DockState = 'bar' | 'sheet-min' | 'sheet-full' | 'peek';
```

### B.3 Module Boundaries

**This module OWNS:**
- AssistantDock, SheetMin, SheetFull, Bar, BackgroundNav, BackStack, state-machine
- ask, heuristics, memory, actions, web-search, data
- Anchor registry (4 canonical types)
- BackStack persistence (preserves all anchors)

**This module does NOT own:**
- IDB stores (data module)
- LLM adapters (intelligence module)
- Views (views module — uses AssistantDock via context)
- Branding / palette (branding module)

**This module may import from:**
- `assistant/` (self)
- `intelligence/adapters/` (LlmAdapter interface)
- `lib/` (utilities)
- React, react-router-dom, marked, etc.

**This module must NOT import from:**
- Any FVS / `@fvs/*` package (sovereignty)
- Any Mantine package (Sovereign SPA Mode)

### B.4 Swap Test Instructions (R6)

To swap this module for an alternative implementation:
1. Implement `askOscar(prompt, history): Promise<AskResult>` with the same shape
2. Implement `AssistantDock` component with the 4-state dock
3. Implement the 4 canonical anchor types
4. Wire to one of the 5 LLM adapters
5. Pass all 8 invariants in `vp/runtime.test.ts` + 11 in `vp/intelligence.test.ts`

### B.5 Portability Contract (P4)

Per §34 engine-agnostic truth: this Recipe Book describes the assistant's BEHAVIOUR without committing to React. An alternative implementation (Svelte, SolidJS) can satisfy the same contract by providing the same `askOscar` shape + 4-state dock.

---

## C. Reconstruction Notes

### C.1 Evidence (source-line citations)

- 4-state dock: `runtime-checks.ts` RT-1.1 to RT-3.3
- AskOscar as single entrypoint: `assistant/ask.ts`
- 9-layer dispatcher: `intelligence/adapters/smart.ts`
- 4 canonical anchor types: `assistant/types.ts`
- BackStack 1000/999: `assistant/BackStack.ts`

### C.2 Coverage Matrix Entries

See `pact/recipes/assistant/coverage-matrix.md` for the 5-column verification grid.

### C.3 Visual Anchors

- Bar: small bottom bar with green dot
- SheetMin: lifted sheet with input
- SheetFull: full conversation with bubbles, action chips, message history
- Peek: panel peeking from bottom

### C.4 Behavioural Anchors

- 9-layer dispatcher fires claim+evidence+hedge+action responses
- Action chips render below the response
- BackStack preserves anchors when popping
- Provider switch (in Settings) immediately affects next askOscar call

---

## END OF RECIPE.MD

*Product description + structural contract + reconstruction notes. Per FVW v8 §11.1.*
