# Oscar Platform — Stage 1 Upgrade Plan

**Status:** ACTIVE (operator-prompted 2026-07-02 20:57 UTC)
**Owner:** desktop Mavis
**Goal:** Make Oscar world-class across every surface. Every module works. Every action has feedback. Every item can be added, dated, filtered, found.
**Rule:** this document is the single source of truth. The operator re-reads it. I update it as we go. I never forget what's in it.

---

## How to read this

Each module has its own section. Each section follows the same pattern:

1. **What works today** — verified, currently shipped
2. **What needs fixing** — operator-reported or audit-discovered, sorted by severity
3. **What needs adding** — missing affordances, gaps the operator felt
4. **Acceptance criteria** — the exact test that proves it's done

When I close an item, I delete the row and add a brief note in the changelog at the bottom.

## Cross-cutting principles

These apply to every module, every phase.

### Universal add-item affordance

Every module that has items (voice notes, calendar events, surveys, notes, reports, media, workflows, comms messages, map layers) **must** expose an "Add X" path that:

- Works from the module page directly
- Works from the input bar (Oscar can parse "add voice note: oak survey reminder" and route to the right form)
- Has clear empty state ("No voice notes yet. Pick a project above, then record or type.")
- Has clear success feedback ("Voice note saved → Oakwood Park")

### Universal date filter

Anything with a date (voice notes, events, surveys, notes, reports, comms messages, media) **must** support:

- Click the date → filter to that day
- Sort by date (newest first by default)
- Date range filter (from / to)
- Date visible on every card

The simplest version: the existing calendar view becomes the "dates" hub. Any card can deep-link to /calendar?date=YYYY-MM-DD.

### Universal item lifecycle

Every item (in any module) has the same lifecycle actions:

- **Open** — see the full record
- **Edit** — make changes, autosave
- **Pin to Home** — adds a FreshCard to the dashboard
- **Delete** — with confirm
- **Export** — JSON / markdown / PDF depending on type

### Universal feedback

Every action in the app surfaces:

- A toast at the bottom (success / error / info)
- An optional FreshCard for major results (can be pinned)
- A undo toast for destructive actions

---

## Module: Voice

### What works
- Audio capture via MediaRecorder
- Save to project picker
- Manual transcript textbox
- Audio playback after stop
- Web Speech transcript (when it works)
- Live status indicator (live / fallback / off)

### What needs fixing
- **[critical] Web Speech fails silently on mobile** — operator saw an empty transcript box. The new fallback message helps, but mobile Chrome / Safari often doesn't expose the API at all. **Fix:** when Web Speech isn't available, automatically show a "type your transcript" prompt in big text. Pre-fill with placeholder text from common surveyor phrases.
- **[critical] No date on voice notes** — can't filter voice notes by date. **Fix:** add `created_at` display + click → /calendar?date=...
- **[critical] No way to add a voice note from outside /voice** — has to navigate to the page first. **Fix:** input-bar command "add voice note: oak survey reminder" routes to a quick-record flow on /voice.
- **[high] Voice notes list doesn't show project name** — confusing when switching projects. **Fix:** show project name on every list item.
- **[high] No way to edit transcript after saving** — has to delete and re-record. **Fix:** click a saved note → inline edit mode for transcript only.

### Acceptance criteria
- [ ] Recording shows visible status (live/fallback/off)
- [ ] If Web Speech fails, the user is told + can type instead
- [ ] Saved notes have a clickable date
- [ ] Saved notes show their project
- [ ] Click a date → filtered view (today / week / month)
- [ ] Click a saved note → can edit the transcript

---

## Module: Notes

### What works
- Tag editor (add / remove chips)
- Project + site assignment dropdowns
- #tag extraction from body
- AI retention-category extraction
- Save toast

### What needs fixing
- **[critical] Notes aren't date-filterable** — no createdAt visible. **Fix:** show date on every card, clickable.
- **[critical] No global "all notes" view with filters** — only "the list". **Fix:** add filter row: by tag / by project / by site / by date.
- **[critical] No AI rewrite from outside /notes** — has to open the note first. **Fix:** input-bar command "rewrite my last note in casual tone" routes to the right note.
- **[high] No way to add a note from the input bar** — has to navigate. **Fix:** command "note: highway verge needs banksman" creates a note.
- **[high] Notes can't be tagged via input bar** — typing in the body is the only way. **Fix:** command "tag last note with survey" updates the tag.
- **[high] Long notes don't paginate** — a 5000-word note is one giant textarea. **Fix:** virtualized list, or chunked sections with sticky headers.

### Acceptance criteria
- [ ] Notes show date + project + tags on every list card
- [ ] Filter by tag / project / site / date works
- [ ] Click a date → filtered view
- [ ] Can create a note from the input bar
- [ ] Can rewrite a note from the input bar

---

## Module: Surveys

### What works
- New survey button (auto-creates site if none)
- Form fields: site, surveyor, date, weather, methodology, status, hazards, notes
- Trees section with species autocomplete, age, condition, retention category
- Autosave to IDB
- Draft restoration on reopen
- Save / Cancel / Discard draft

### What needs fixing
- **[critical] Can't filter surveys by date** — date is in the form but not the list. **Fix:** show date on every list card, clickable.
- **[critical] No "all surveys" global view** — only current-project. **Fix:** a "All projects" toggle in the Surveys header.
- **[critical] No way to add a survey from outside /surveys** — input bar command "new survey at Oakwood Park".
- **[high] Tree species autocomplete doesn't show retention category hint** — operator has to look up BS5837 manually. **Fix:** when a species is picked, show the typical BS5837 retention range (oak = A or B, ash = B or C, etc.) as a helper text.
- **[high] Survey list doesn't sort by date** — alphabetical by site. **Fix:** sort by surveyDate desc by default.
- **[high] No "duplicate tree" button** — adding 20 oaks means 20 manual entries. **Fix:** "Duplicate" button on each tree row, with editable fields pre-filled.
- **[high] No way to export a survey as PDF/DOCX from the list view** — only the report module. **Fix:** add export menu to each list item.

### Acceptance criteria
- [ ] Survey list shows date + status + tree count on every card
- [ ] Survey list sorted by date desc by default
- [ ] Click a date → filtered view
- [ ] Can create a survey from the input bar
- [ ] Tree species autocomplete shows BS5837 hint

---

## Module: Reports

### What works
- (basic stub)

### What needs fixing
- **[critical] Reports module is a stub** — no actual drafting UI. **Fix:** a real editor with template picker (AIA / AMS / mortgage), survey picker, AI drafting.
- **[critical] No way to add a report from outside /reports** — input bar command.
- **[high] No date filter on reports** — list view.
- **[high] No export to PDF / DOCX** — claimed in /tools card, not actually wired.

### Acceptance criteria
- [ ] Reports have a real editor
- [ ] Template picker (AIA / AMS / mortgage)
- [ ] AI drafts the body from the chosen survey
- [ ] Export to PDF / DOCX works
- [ ] List shows date + template + survey on every card

---

## Module: Media

### What works
- Upload via file picker
- Filter by media type
- Sample data seeder (3 SVG images)

### What needs fixing
- **[critical] Uploaded images show as filenames, not thumbnails** — click a photo and you see "photo.jpg", not the picture. **Fix:** generate a thumbnail when uploading, render as a small grid of previews.
- **[critical] No date filter** — media has `created_at`.
- **[critical] No "all media" view across projects** — only current-project.
- **[high] Can't tag media to a tree or survey** — claim in the Tools card, no UI. **Fix:** tag dropdown on each media item.
- **[high] No way to delete uploaded media** — only the seed data shows the trash icon.

### Acceptance criteria
- [ ] Photos show as thumbnails
- [ ] Date filter works
- [ ] Can tag media to a tree or survey
- [ ] Can delete uploaded media

---

## Module: Calendar

### What works
- Month grid with prev/next navigation
- Day selection
- Event list for selected day
- Add event form (title, type, date, time)
- 5 event types with colour-coded dots
- Sample data seeder

### What needs fixing
- **[high] No week / day view** — only month grid. **Fix:** toggle between month / week / day.
- **[high] No way to drag events between days** — must delete + recreate. **Fix:** drag-and-drop on the grid.
- **[high] No recurring events** — site visits are weekly. **Fix:** recurrence rules (RRULE).
- **[high] Calendar events aren't linked to a survey or site by default** — just to a project. **Fix:** add linked_artefact_id field.

### Acceptance criteria
- [ ] Month / week / day views
- [ ] Drag-and-drop to reschedule
- [ ] Recurring events
- [ ] Events link to surveys / sites

---

## Module: Map

### What works
- SVG-based renderer (no Leaflet dependency, keeps bundle lean)
- Drawing tools: Point, Line, Polygon
- Layer list with name + link to tree
- Save to project

### What needs fixing
- **[critical] Map is abstract** — uses lat/lng projection but renders on a blank canvas. **Fix:** render a base map. Use OpenStreetMap tiles via MapLibre GL JS or Leaflet. Both are pure-JS, no API key required for OSM tiles.
- **[critical] No "current location"** — the Tools card claims "Save current location" but it's not implemented. **Fix:** add a "📍 Use my location" button that calls `navigator.geolocation.getCurrentPosition`.
- **[critical] No "save location to a tree" workflow** — Tools card promises this. **Fix:** when a tree is selected, a "Drop a pin here" button creates a map layer linked to the tree.
- **[critical] No date filter** — map layers don't have dates but the operator wants them clickable. **Fix:** add `created_at` to map layers; date clickable on list.
- **[high] Can't delete layers** — no delete button. **Fix:** add × on hover.

### Acceptance criteria
- [ ] Real basemap (OSM tiles via MapLibre or Leaflet)
- [ ] "Use my location" button
- [ ] Drop-pin-on-tree workflow
- [ ] Layers can be deleted
- [ ] Date clickable on layer list

---

## Module: Comms

### What works
- Channel list
- Message thread
- Send a message
- Sample data seeder (general channel with welcome messages)

### What needs fixing
- **[critical] Can't add a message without picking a channel** — but channels can be empty. **Fix:** if no channel selected, show "Pick a channel to start chatting" + new-channel button.
- **[critical] No date filter on messages** — message timestamp exists.
- **[critical] No way to add a channel from outside /comms** — input bar command "new channel: site walks".
- **[high] No reactions** — even 👍 is missing.
- **[high] No typing indicator** — feels dead.
- **[high] No read receipts** — operator doesn't know if anyone saw the message.

### Acceptance criteria
- [ ] Can send a message to the current channel
- [ ] Date filter on messages
- [ ] Can create a channel from the input bar
- [ ] Reactions work
- [ ] Typing indicator

---

## Module: Workflows

### What works
- Built-in workflows listed
- Run button (fires `runWorkflow`, no observable effect)

### What needs fixing
- **[critical] Run does nothing observable** — fires the runner, the runner does nothing visible, button stays "Running..." for 1.5s then resets. **Fix:** each workflow step actually executes:
  - "New site visit" creates a project + schedules a calendar event + sends a comms message
  - "Draft report" creates a report draft from the most recent survey
  - "Survey reminder" schedules a calendar event for an overdue survey
- **[critical] No date on workflows** — workflow runs should have a history (when each was run).
- **[critical] No way to create a custom workflow** — only built-ins. **Fix:** a step builder (trigger + action + condition).
- **[high] Workflows aren't linked to projects** — always run on the current project. **Fix:** project picker at the top of the workflows page.

### Acceptance criteria
- [ ] Run actually does something observable (toast, calendar event, project created)
- [ ] Run history with timestamps
- [ ] Custom workflow builder
- [ ] Project picker

---

## Module: Writing (Blog)

### What works
- Editor with markdown
- AI tone rewrite (formal / casual / technical)
- Title suggestions
- Tag suggestions
- Save as FreshCard (form-summary)
- Pin to Home from the result card

### What needs fixing
- **[high] No date filter on posts** — date exists.
- **[high] No "all posts" view across projects**.
- **[medium] Tag suggestion uses the 1.7B model which can hallucinate** — fallback to curated tags if confidence low.
- **[medium] No way to schedule a post** — just save + publish.
- **[medium] No way to export as markdown file** — claim in Tools card, no UI.

### Acceptance criteria
- [ ] Date filter on posts
- [ ] All posts view
- [ ] Confidence-thresholded tag suggestions
- [ ] Schedule a post
- [ ] Export as markdown

---

## Module: Settings

### What works
- AI provider picker
- Surveyor profile (name + company)
- LLM model picker (Ollama endpoint)
- Brain download (stub — local 0.5B model)
- Sovereignty check

### What needs fixing
- **[high] Brain download is a stub** — the `brain.ts` modules are placeholder. **Fix:** either ship the actual GGUF chunks or remove the button.
- **[high] Surveyor profile not surfaced in surveys** — has a field for "Surveys using this profile: 0" but doesn't actually pre-fill reliably.
- **[medium] No theme toggle** — `theme: 'dark' | 'light'` is in the config but the UI doesn't expose it.
- **[medium] No keyboard shortcuts list** — there are shortcuts (Cmd+K) but no cheat sheet.

### Acceptance criteria
- [ ] Brain download either works or is removed
- [ ] Theme toggle works (dark / light)
- [ ] Keyboard shortcuts cheat sheet

---

## Module: Projects

### What works
- Project cards with artefact counts
- Switch project context

### What needs fixing
- **[critical] No date on projects** — createdAt exists.
- **[high] No "all projects" view filterable by date**.
- **[high] No way to delete a project** — only the active one can be archived? Need a delete flow.
- **[high] No project search** — many projects, scroll forever.

### Acceptance criteria
- [ ] Date on every project card
- [ ] Project search
- [ ] Delete project with confirm

---

## Module: Home

### What works
- Pinned cards
- Quick actions
- Discover section
- Oscar suggests (AI-composed)

### What needs fixing
- **[critical] No "recent activity" feed** — claimed in earlier spec, not built. **Fix:** show last 5 actions (note saved, survey edited, voice captured, etc.) as FreshCards.
- **[critical] No "due today / overdue" feed** — operator has calendar events, surveys, deadlines. **Fix:** show what's due.
- **[high] "Discover" section shows the same cards to everyone** — no personalisation.

### Acceptance criteria
- [ ] Recent activity feed
- [ ] Due today / overdue feed
- [ ] Personalised Discover (least-pinned, most-used)

---

## Module: Tools

### What works
- Grid of all 11 modules as FreshCards
- Built-in workflow preview

### What needs fixing
- (low priority — this module is mostly done)

---

## Cross-cutting: Ambient AI

### What works
- Input bar with 3 modes (idle / drafting / active)
- Status row during long ops
- Bottom-mounted toasts (persistent by default)
- Curated page-doc corpus
- Conversation log
- History button (avatar) to re-open last answer

### What needs fixing
- **[critical] "Add X" command from the input bar doesn't work** — claims to, but the assistant module doesn't dispatch to form-creation flows. **Fix:** `addVoiceNote`, `addSurvey`, `addEvent`, `addNote`, `addMedia`, `addReport`, `addWorkflow`, `addChannel` commands that route to the right form with prefilled context.
- **[high] Cascading commands aren't documented** — what does "oscar draft a survey at Oakwood" do? **Fix:** a help card showing all the commands.

### Acceptance criteria
- [ ] "add X" commands work from the input bar
- [ ] Commands are documented
- [ ] Failure to route surfaces a friendly error

---

## Cross-cutting: FreshCards

### What works
- Typed primitive (`FreshCardData`)
- Registry (11 modules)
- Composer (deterministic rules)
- Pin / dismiss
- Result-toast cards

### What needs fixing
- **[high] Cards have no dates** — even though they could. **Fix:** add `createdAt` to FreshCardData, render as clickable date.
- **[high] "Date filter" doesn't exist yet** — needs a new component. **Fix:** a DateFilter component that filters any list of cards by date range.

---

## Cross-cutting: Shell

### What works
- Mobile dock (4 icons)
- Desktop sidebar (grouped, indented)
- Top bar with search + settings + drawer

### What needs fixing
- **[high] "More" drawer is huge** — 7 items. **Fix:** searchable / paginated.
- **[high] No "back" gesture on mobile** — back button on Android doesn't work in the SPA. **Fix:** add a top-bar back button + handle popstate.
- **[medium] No breadcrumb on desktop** — operator doesn't know which sub-page they're on.

### Acceptance criteria
- [ ] Drawer is searchable
- [ ] Top-bar back button works
- [ ] Desktop breadcrumbs

---

## Phases

### Stage 1 (this plan)
- Universal date filter pattern
- Universal add-item affordance
- Map: real basemap + current location + pin-on-tree
- Voice: date + project on saved notes + edit transcript
- Notes: filters + input-bar add
- Surveys: filters + input-bar add
- Workflows: actually runs something observable

### Stage 2
- Comms: reactions + typing + read receipts
- Media: thumbnails + tag-to-tree
- Reports: real editor + export
- Calendar: week/day views + drag + recurring

### Stage 3
- Brain download actually works (or removed)
- Custom workflow builder
- Personalised Home
- Theme toggle + keyboard shortcuts

---

## Changelog

- **2026-07-02 20:57 UTC** — Plan created. Operator prompted with: dates should be clickable, add-item should be universal, Map broken, audit every module, save to a persistent plan.

- **2026-07-02 21:00 UTC** — Operator FULL BACKLOG captured below. Each row = source quote + the work it implies + where it lives. Do not close items without citing the fix in this log.
---

## Operator-prompted backlog — the one true list

**Purpose.** Every operator statement below has been turned into a backlog item. Each row carries: the operator's words, my interpretation as a concrete piece of work, the module it touches, the status flag, and the date it was logged.

**Status legend.** `NEW` — operator said it, I haven't worked it. `WIP` — I started but not done. `DONE` — fixed and deployed. `PARK` — parked behind a Stage ≥ 2 phase. `CANT` — out of reach in sandbox.

### Universal patterns (cross-module)

| # | Operator said | What it means | Touches | Status | Logged |
|---|---|---|---|---|---|
| U1 | "Something has a date. Be able to show on the calendar. There should be views for it, filters." | Universal "any item with a date → click to filter / by-day / by-week / by-month / by-range" pattern. Voice, Calendar, Notes, Surveys, Reports, Comms, Media all get date clickable + filter route. | ALL | NEW | 2026-07-02 21:00 |
| U2 | "From anything I can add… whatever it is." Add-to-the-list pattern. | "Add X" affordance from the input bar AND from a +button in every list. Voice/Note/Survey/Report/Event/Media/Workflow/Channel/Map layer. | ALL | NEW | 2026-07-02 21:00 |
| U3 | "I want to have this where I tell you stuff. And you forget it. It's not acceptable." | This document is the SINGLE source of truth. I update it. I never forget what's in it. | PROCESS | NEW | 2026-07-02 20:57 |

### Module gaps (operator-confirmed broken)

| # | Module | Operator said | What needs fixing | Status | Logged |
|---|---|---|---|---|---|
| M1 | Voice | "Recording it says network error during transcription. Your audio is still saved." | Web Speech API can fail mid-session; we show "Network error" but bury the lead. Need to (a) detect failure early, (b) auto-stop recording + surface an in-bar prompt "Tap to type your transcript instead", (c) preserve audio + give it a clear transcript slot in the list. | NEW | 2026-07-02 21:00 |
| M2 | Media | "It's just showing an icon. It's not showing the actual image." | Media cards do not render `<img src={blob}>`. They show emoji. Fix: thumbnails from blob, click-to-open detail drawer, full edit (title, desc, tags, link to tree) on the back of the card. | NEW | 2026-07-02 21:00 |
| M3 | Media | "I uploaded an image called 'Colouring In Book (1).png' and I can't see the image on the front of the card. I can't click on any of these cards to see the back of them." | Same root as M2 — no `<img>` and no click target. Confirm with playwright that png + jpg cards both thumbnail + open. | NEW | 2026-07-02 21:00 |
| M4 | Media | "Add to the list. Image 2." | Operator wants a way to upload / add media from any context (input bar / +button) — covered by U2. | NEW | 2026-07-02 21:00 |
| M5 | Sidebar | "Where you click Surveys in the project — still highlighted and it just looks ugly." | Active sidebar item gets a 100%-of-row dark green background. Replace with a subtle left-rail treatment (4px green rail + slight tint, not full chunk). | NEW | 2026-07-02 21:00 |
| M6 | Map | "Maps. It's still not working. I'm not drawing it either." | Open Map view in Playwright; confirm the current page renders + point/line/polygon clicks create pending shapes. If broken: repair to U2 status. | WIP | 2026-07-01 23:30 |
| M7 | Workflows | "clicking run activates all workflows but nothing seems to happen." | Run button has no observable effect. Each workflow step must execute visibly (toast / project created / event scheduled / message posted). | NEW | 2026-07-01 23:30 |
| M8 | Reports | "PDF ingestion. PDF learning. Learning from previous reports, the style. The layout. So that when we make a report, if the client doesn't write it directly, it's written in the exact style that he would normally write it. We planned this in the original." | Bring across from oscar-ai the Style Learner + Decompiler + Template Generator. See migration plan in §"Migrations". | NEW | 2026-07-02 21:05 |

### Stage 2 / 3 — operator-confirmed missing affordances

| # | Module | Operator said | What needs adding | Status | Logged |
|---|---|---|---|---|---|
| S1 | Business | "This is used for the client to manage his business. Which is why we want to put in world-class social media, email, marketing. Mucho it." | Planning section: Social posts (LinkedIn / Instagram / X), Email campaigns (drip + newsletter), Marketing calendar. See §"Business toolkit" below. | NEW | 2026-07-02 21:00 |

### Backlog of pre-existing module fixes (already documented above in this plan)

These are the same items already captured in the per-module sections above (Voice/Notes/Surveys/Reports/Media/Calendar/Map/Comms/Workflows/Writing/Settings/Projects/Home/Tools/Shell/Ambient/FreshCards). They are the source of truth and reproduced in summary here for operator scan:

- **All modules** → universal date click + universal add-item (U1, U2)
- **Voice** → M1 + typed fallback when Web Speech fails + date on saved notes
- **Notes** → date clickable + tag/project/site filters + input-bar add
- **Surveys** → date sort + All-projects toggle + BS5837 species hint + duplicate-tree + input-bar add
- **Reports** → real editor + template picker + AI draft + export (and bring across Style Learner per M8)
- **Media** → M2 + date click + tag-to-tree + delete
- **Calendar** → week/day views + drag + recurring
- **Map** → M6 + basemap + current location + pin-on-tree + delete layers
- **Comms** → reactions + typing + read receipts
- **Workflows** → M7 + run history + custom builder
- **Writing** → date filter + tag confidence threshold + schedule + markdown export
- **Settings** → Brain download works-or-removed + theme + shortcuts cheat sheet
- **Projects** → date on cards + search + delete
- **Home** → recent activity feed + due-today + personalised discover
- **Sidebar** → M5
- **Ambient AI** → input-bar "add X" routed commands + help card
- **Shell** → drawer search + top-bar back + breadcrumbs


---

## Migration A — Oscar AI → Oscar Platform: PDF ingestion, report style learning

**Source.** Operator note 2026-07-02 21:05: "PDF ingestion. PDF learning. Learning from previous reports, the style. The layout. So that when we make a report, if the client doesn't write it directly, it's written in the exact style that he would normally write it. We planned this in the original."

**Origin repo.** `avidtech6/oscar-ai` (SvelteKit v1, location `/workspace/recon/oscar-ai`). 26 phase docs and ~2700 lines of report-intelligence code in `src/lib/intelligence/`.

**Code triage (verified 2026-07-02 21:06).**

| Module | Lines | Real-or-stub | Portable |
|---|---|---|---|
| `decompiler/ReportDecompiler.ts` + 7 detector modules | 338 | **Real** — takes raw text, detects headings/sections/lists/tables/metadata/terminology/compliance markers/appendices. | YES — pure functions on text. |
| `style-learner/ReportStyleLearner.ts` + 8 extractors + `StyleProfile.ts` | 738 | **Real** — extracts tone, sentence/paragraph patterns, section ordering, preferred phrasing, formatting, terminology, structural prefs. Builds and merges StyleProfiles with confidence score. | YES — pure functions on `DecompiledReport`. |
| `template-generator/ReportTemplateGenerator.ts` + 3 builders + 3 generators | 823 | **Real** — generates templates from registry + style profile, with placeholders / compliance / section scaffold / AI guidance / style integration. | YES — pure logic. |
| `pdf-parsing/PDFParser.ts` + 5 extractors + types | 832 | **SCAFFOLD ONLY** — `PDFParser.parse()` returns `console.log()` and a comment "// In a real implementation, we would load the PDF using a library like pdf.js". The extractor classes are stubs. | NO — needs real PDF decoder. |
| `compliance/*` + `classification/*` + `report-reasoning/*` + `orchestrator/*` | ~1500 | Partial — service modules that wire the above together. | Portable if decompiler + style + template are real. |
| `self-healing/*` + `reproduction/*` + `schema-*` + `unified-editor/*` | ~1000 | Partial | Carry over post-style-learner. |
| `document-intelligence/document-engine.ts` | 30 KB | Real | Likely duplicates effort; treat as alternative implementation to be reviewed. |

**Migration plan (Stage 1 includes first three, Stage 2 has the rest).**

### M-A.1 — Move core intelligence to oscar-platform (Stage 1 — 2 weeks)

- Copy `decompiler/`, `style-learner/`, `template-generator/`, `compliance/`, `classification/` from oscar-ai to `oscar-platform/app/src/intelligence/report-intelligence/`.
- Rewrite imports: drop SvelteKit-specific imports (e.g. `$app/stores`).
- Replace the original event emitter (SvelteKit-shimmed) with the existing `useEventBus` or a tiny portable emitter (zero deps).
- Replace `Storage.localStorage` calls (path-based `/style-profiles.json`) with an IDB store in oscar-platform's IDB schema: `style_profiles` (id, userId, reportTypeId, profile JSON, timestamps).
- Add a vitest suite that mirrors the existing 30+ tests in oscar-ai (or writes them fresh).
- Wire into the existing `Reports` view: pick a report → choose a survey → AI drafts the body using the user's style profile.

### M-A.2 — Wire Learning from previous reports (Stage 1)

- New affordance: Settings → "Style profiles" → "Learn from existing report".
- Operator picks a previous report (PDF or text), the decompiler + style learner analyse it, a style profile is created or merged.
- "Active style" profile is selected per report type (BS5837 / AIA / AMS / mortgage).
- AI drafting injects the style profile's `tone` + `preferredPhrasing` + `terminologyPreferences` + `sectionOrdering` + `formattingPreferences` into the prompt.

### M-A.3 — Wire PDF ingestion via pdfjs-dist (Stage 2)

- Add `pdfjs-dist` to `package.json`.
- Replace `PDFParser` stubs with real implementations that call `pdfjs-dist` to:
  - Open the binary
  - Iterate pages
  - Extract text with reading order
  - Extract embedded images (`getOperator(CanvasGraphics)`)
  - Extract fonts (worker)
- Implement: `PDFTextExtractor.ts`, `PDFImageExtractor.ts`, `PDFLayoutExtractor.ts`, `PDFFontExtractor.ts`, `PDFStructureRebuilder.ts`.
- Pipeline: PDF blob → `PDFParser.parse()` → `ReportDecompiler.ingest()` → `ReportStyleLearner.analyse()` → `ReportTemplateGenerator.generate()`.
- UI: in Reports, "Learn from PDF" → file picker → preview the extracted text → confirm → save style profile.

### M-A.4 — Cross-stage guard

- Until M-A.3 is done, "Learn from PDF" surfaces a friendly error: "PDF text extraction is a Stage 2 item. Paste the text directly and we'll still learn your style."
- Plain-text "Learn from text" works from Stage 1.

### Acceptance criteria for Migration A

- [ ] `decompiler` + `style-learner` + `template-generator` are imported in oscar-platform with vitest tests passing
- [ ] Existing reports in oscar-platform can be re-analysed; the analysis is identical (round-trip OK)
- [ ] Settings → Style profiles page lists each profile with tone, confidence, last-updated
- [ ] Reports → "Learn from existing report" → pick a previous report → confirm → style profile merged
- [ ] Reports → "AI draft" uses the user's active style profile (tone, phrasing, section ordering, terminology)
- [ ] (Stage 2) Reports → "Learn from PDF" actually ingests the binary

---

## Migration B — Business toolkit: social media + email + marketing

**Source.** Operator note 2026-07-02 21:00: "This is used for the client to manage his business. Which is why we want to put in world-class social media, email, marketing. Mucho it."

**Scope of this plan section.** Operator asked me to *plan* it — not implement. Below is the plan; implementation is a Stage 4 / future item.

### B-1 — Social media composer

**Goal.** Let Oscar write LinkedIn posts, Instagram captions, X threads from survey data.

**Modules.**

- `src/social/` — composer UI
- `src/social/platforms.ts` — platform presets (character limits, hashtag norms, image aspect ratios)
- `src/social/Social.tsx` — view at `/social`
- `src/social/CardBacker.tsx` — render survey → post outline
- IDB stores: `social_posts` (id, project_id, platform, body, hashtags, scheduled_at, status)

**Workflow.**

- Pick a project → pick a survey → "Draft posts for this survey".
- AI proposes one post per platform (LinkedIn, Instagram, X).
- Each post is editable, scheduled, copy-to-clipboard.
- Calendar shows scheduled social posts alongside calendar events.

**Acceptance criteria.**

- [ ] Editor for each platform
- [ ] Character / hashtag counters
- [ ] Image pickup from project media
- [ ] Schedule via calendar
- [ ] Mark as "Sent" manually (we're not connecting to API keys in Stage 1)

### B-2 — Email campaigns

**Goal.** Newsletter + drip emails from the operator's contact list.

**Modules.**

- `src/email/` — composer UI
- `src/email/templates.ts` — newsletter, drip step, update, intro, follow-up
- `src/email/contacts.ts` — contact list (import CSV, manual add)
- `src/email/Email.tsx` — view at `/email`
- IDB stores: `email_lists` (id, project_id, name, contact_ids, schedule_rules), `email_campaigns` (id, project_id, list_id, subject, body, status, scheduled_at, sent_at), `email_messages` (id, contact_id, campaign_id, opened_at, clicked_at)

**Workflow.**

- Pick a list (or import CSV of contacts).
- Pick a template (Newsletter / Drip step 1-5 / Update / Follow-up).
- AI suggests body using the client's writing style profile (Migration A).
- Schedule or send.

**Acceptance criteria.**

- [ ] CSV import of contacts
- [ ] Live preview of the email (HTML form)
- [ ] Schedule + send
- [ ] Open / click tracking (we can simulate; real ESP integration is Stage 5)

### B-3 — Marketing calendar

**Goal.** One calendar that shows surveys, social posts, email sends, events, deadlines.

Already partly covered by the existing `/calendar` view (events). Extend to:

- Surface `social_posts.scheduled_at` as a card on the calendar
- Surface `email_campaigns.scheduled_at` as a card
- Surface report due dates, project deadlines
- Filter: "Only marketing", "Only client work", "Only field"

**Acceptance criteria.**

- [ ] Calendar shows social / email cards alongside events
- [ ] Filter chips
- [ ] Click a marketing card → opens the composer

### B-4 — Stage mapping

- **Stage 4** — Social composer (single user, manual send).
- **Stage 4** — Email editor + CSV import + manual send.
- **Stage 5** — Marketing calendar overlay.
- **Stage 6** — Real ESP (Mailgun / Postmark) integration + social API (Buffer / X / LinkedIn OAuth).


---

## Migration A (expanded) — What we could bring across from `avidtech6/oscar-ai`

**Source.** `/workspace/recon/oscar-ai` (SvelteKit v1 + a parallel `OscarAI-1.0/` Electron bundle). Total ~148 K lines across 768 files. The oscar-ai repo is the **complete phase-26 mock** — most intelligence modules ship with real logic, but the actual UI surfaces only partially landed in any deployed build, and the SvelteKit app is largely broken (per operator's earlier note "oscar-ai.pages.dev is blank, repo may have been overwritten").

**Why this matters.** Operator said 2026-07-02 21:05 UTC: "We planned this in the original… you can have a look at it and there may be other things in there that you can decide to bring across."

Below is the **catalog of things we could port** — measured against what oscar-platform currently has. Operator picks which to bring; I migrate one at a time.

### A-1 — Report intelligence (HIGHEST PRIORITY — operator-named)

| Module | Lines in oscar-ai | Status in oscar-ai | Status in oscar-platform | Decision |
|---|---|---|---|---|
| `decompiler/` (detect headings, sections, lists, tables, metadata, terminology, compliance markers, appendices) | 338 | Real, tested | ❌ Absent | **Bring now (Stage 1, M-A.1)** |
| `style-learner/` (tone, sentence/paragraph patterns, section ordering, phrasing, formatting, terminology, structural prefs + 8 extractors + `StyleProfile.ts`) | 738 | Real, tested | ❌ Absent | **Bring now (Stage 1, M-A.1)** |
| `template-generator/` (template from registry+style, with placeholders/compliance/section scaffold/AI guidance/style integration + 3 generators) | 823 | Real, tested | ❌ Absent | **Bring now (Stage 1, M-A.1)** |
| `pdf-parsing/` (PDFParser + 5 extractors) | 832 | SCAFFOLD only (`// In a real implementation, we would load the PDF using a library like pdf.js`) | ❌ Absent | Stage 2 (M-A.3) — needs real `pdfjs-dist` wiring |
| `compliance/` (BS5837 / AIA / AMS compliance rules + checks) | ~500 | Partial | ❌ Absent | Stage 2 |
| `classification/` (auto-detect report type from text) | ~400 | Partial | ❌ Absent | Stage 2 |
| `report-reasoning/` (LLM-driven reasoning chain for report generation) | ~500 | Partial | ❌ Absent | Stage 2 |
| `orchestrator/` (wires it all together) | ~400 | Partial | ❌ Absent | Stage 2 |
| `self-healing/` | ~500 | Partial | ❌ Absent | Stage 3 |
| `reproduction/` | ~300 | Partial | ❌ Absent | Stage 3 |
| `schema-mapper/` + `schema-updater/` | ~600 | Partial | ❌ Absent | Stage 3 |
| `unified-editor/` | ~2 files, partial | Partial | ❌ Absent | Stage 4 |
| `document-intelligence/document-engine.ts` | 30 KB | Real (alternative impl) | ❌ Absent | Triage after M-A.1 lands |

### A-2 — Content engine (matches current Reports / Writing surfaces)

| Module | Lines | Status | Decision |
|---|---|---|---|
| `content-intelligence/blog-generator.ts` + `content-engine.ts` + `content-intelligence-system.ts` | ~700 | Real | **Bring (Stage 1)** — gives the existing Reports + Writing views a real AI-draft path that respects the user's style profile |
| `knowledge-graph/` (entity extractor + consistency detector) | ~700 | Real | Stage 2 — useful when we have many reports and want cross-report "trees mentioned in 3 reports" search |
| `extended-intelligence/` (predictive / data processor / analytics) | ~700 | Partial | Stage 3 |

### A-3 — Collaboration + sync (Supabase-shaped, but we go local)

| Module | Lines | Status | Decision |
|---|---|---|---|
| `collaboration/` (CRDT manager + presence manager + engine) | ~700 | Real but Supabase-bound | **Skip in current form.** Sovereign mode means local-first only. Stage 5+ if we add multi-device. |
| `auth/` (session, biometric, PIN, client) | ~600 | Real | **Skip.** Sovereign means no auth surface needed right now. |
| `automation/` (trigger system + automation engine) | ~600 | Real | **Bring (Stage 2).** Maps onto Workflows — currently dead. |
| `unified-editor/` | Partial | Partial | Stage 3 — when we have a real Reports editor to consolidate |
| `editor-system/` | Partial | Partial | Stage 4 |

### A-4 — Modules with strong UI surface but no oscar-platform equivalent

| Module | What it was supposed to do | Decision |
|---|---|---|
| `OscarAI-1.0/src/src/routes/+page.svelte` + 14 routes (calendar / dashboard / editor / **email** / integration / **login** / monitoring / **notes** / projects / reports / settings / **tasks** / testing / **unlock**) | The original SvelteKit route map | **Useful as reference** for what screens exist. Map onto oscar-platform's route tree. |
| `/email` route + the `email/`, `email-templates/`, etc. that were planned | Marketing email module | **Already in Migration B §B-2** — make sure we don't double-build. |
| `/tasks` route | Tasks / todos | Stage 4 — calendar-adjacent. |
| `/integration` route | Third-party integration hub | Stage 5 — once we have auth + sync. |
| `/monitoring` route | System health | Stage 5 — observability dashboard. |
| `global-assistant-system/` | Multi-context global assistant | Already partially replicated in oscar-platform's `assistant/` + ambient.ts. **Don't duplicate** — extend instead. |
| `layout/` (ai-layout-engine.ts) | AI-driven layout for report pages | Stage 3. |
| `media/` (media-manager.ts + media-types.ts) | Media orchestration | Already handled by oscar-platform's `Media.tsx` + `media/`. |

### A-5 — Already in oscar-platform (don't re-port)

- Chat-style input (the global assistant bar) → we replaced it with ambient.ts InputBar (DO-008)
- Topbar / sidebar / dock → we rebuilt from scratch (OscarShell)
- IndexedDB persistence → we have IDB v12 (oscar-ai had Supabase)
- Project / Survey / Note / Report models → we have them
- Voice note with MediaRecorder → we have it
- Calendar / Map / Comms / Workflows → we have them, M6/M7 to be fixed

### A-6 — Decision matrix for the operator

Before I start moving code, here's the question for **you**:

| Item | Priority | Worth porting in your view? |
|---|---|---|
| Style Learner + Decompiler + Template Generator | High (you named it) | **Yes / No** |
| PDF binary ingestion (pdfjs-dist + the 5 stubs) | High (you named it) | **Yes / No** |
| Blog generator / content engine | Medium — useful for AI-draft of posts | **Yes / No** |
| Report type registry (BS5837 / AIA / AMS + 6 others) | Medium — yes the 9 types from glossary | **Yes / No** |
| Knowledge graph (entity extractor) | Low — only useful with many reports | **Yes / No** |
| Extended intelligence (predictive / analytics) | Low — wait until Stage 4 | **Yes / No** |
| Workflows automation engine (replaces M7 dead Run) | High — makes Workflows module stop being a stub | **Yes / No** |
| Collaboration (CRDT + presence) | Low — sovereign means single-device | Skip for now |
| Auth (PIN / biometric / session) | Low — sovereign means no auth | Skip for now |
| Tasks / email / integration / monitoring routes | Medium — UI shells only | Decide per route |

**Operator feedback wanted.** Tell me which rows to land, and I'll migrate them one at a time.

---

## Migration B (already covered above) — Business toolkit

See `## Migration B — Business toolkit` earlier in this plan. Social / Email / Marketing. Planning only. Stage 4+ for real.

