# AI Career Assistant (Phase 5) > Phase 5 (2026-07-18). The per-application AI Workspace: modules, prompt flow, provider abstraction, > history model, extension points. Companion to `cv-builder.md`, `career-profile-model.md`, and > `MASTER_IMPLEMENTATION_GUIDE.md` (AI philosophy). Verified against code + a running container. ## Principle AI **assists** the application workflow — it never replaces the user. Every module is **suggestion only**: it returns markdown the user reviews and copies. Nothing is applied automatically to the master profile, a CV variant, or the application. Every prompt carries the guardrail *"preserve every factual claim — never invent employers, titles, dates, qualifications, or metrics."* Job tracking stays the core product; the assistant improves the *application* it hangs off. ## Where it lives Each job application gains an **AI Workspace** tab (`AiWorkspacePanel`) in the job details dialog. It is the central place for all AI on that application. Pre-existing per-tab AI (candidate-fit, focus-plan, interview-prep) is untouched — the workspace is the unified, history-backed home for the Phase 5 modules. ## Modules `AiWorkspaceService.Modules`, all via `ISummarizerService.SummarizeSectionAsync`: | Module | Produces | |---|---| | `job-analysis` | Company/role/skills/tech/experience/education/soft-skills/responsibilities/salary/benefits/work-model/visa/language + summary + likely interview topics + confidence | | `career-match` | Match % + reasoning, strengths, weaknesses, missing skills, most-relevant experience, suggested improvements | | `cover-letter` | A tailored letter in one of 6 tones (professional, friendly, short, detailed, modern, traditional) | | `interview` | Company research, likely/behavioural/technical questions, STAR answer outlines, prep checklist | | `application-review` | Overall strength (rating), missing info, weak areas, ATS issues, grammar/clarity, formatting | Tailored CV is **not** re-implemented here — it is the Phase 4 CV Builder (`CvVariant` linked to the job application). The workspace links to it rather than duplicating it. ## Prompt flow ``` job (JobApplication + Company) ─┐ ├─► AiWorkspaceService builds { instruction + guardrail, source } master profile text ────────────┘ │ ▼ ISummarizerService.SummarizeSectionAsync ──► ai-service (active provider) │ ▼ AiInteraction (append-only history) ──► markdown suggestion to the UI ``` `source` = the job context (`BuildJobContext`) plus the user's master profile text (`ApplicationUser.ProfileCvText`). No profile fields are written; the text is read-only input. ## History model `AiInteraction` (`JobTrackerApi/Models/AiInteraction.cs`) is **append-only** — one row per generation, never overwritten. This is deliberately distinct from `AiWorkspaceNote` (a one-row-per-type *cache* for candidate-fit/focus-plan). History gives the user restore/reuse (re-surface a past result), compare (view two side by side), copy, and delete. `ResultJson` is `{ text, meta? }`; `Provider` records which provider produced it. Each row also stores input/output character counts and a conservative estimated token count (characters ÷ 4); the estimate is provider-neutral because the sidecar currently returns text rather than provider billing metadata. Tenant-scoped (owner query filter), cascades with the application. API (`AiWorkspaceController`, `/api/jobapplications/{id}/ai`): `GET modules` (+ current provider), `POST generate`, `GET history?module=`, `DELETE history/{id}`. `GET /api/ai/usage` returns current-month and all-time totals; the workspace displays the monthly calls and estimated tokens. ## Provider abstraction Generation goes through `ISummarizerService` to the ai-service. Ollama is primary; `AI_PROVIDER` names only the optional external fallback candidate. Fallback is sequential and requires administrator enablement, task approval, live Pro/user consent and the prompt cost/privacy ceiling. Each `AiInteraction` records the provider returned by the sidecar, plus bounded model/route metadata in `ResultJson.meta`; configuration alone is not treated as proof that a provider executed. Per-request user-selectable providers remain intentionally unsupported. The server-side privacy policy selects a route, not the browser, and provider credentials remain deployment-only. ## Extension points - **New module**: add a key to `AiWorkspaceService.Modules` + a prompt builder + a `switch` arm. No new storage, controller, or UI wiring — the panel enumerates modules from `AI_MODULES`. - **New cover-letter tone**: add to `CoverLetterModes` + `ModeGuidance`. - **Structured (JSON) results**: swap a module's prompt for JSON and parse into `ResultJson.meta`; the UI already renders `result.text` as markdown and can read `meta`. - **Provider policy**: add task types to the explicit server-side allowlist only after their payload, accounting and production checks pass; do not add browser provider overrides. ## Security Suggestion only; never overwrites user content; everything requires the user to copy it in. The ai-service stays backend-only (`ai_internal` network, `X-Ai-Service-Token`) — see `current.md` §16. `Markdown` renders React nodes (no `dangerouslySetInnerHTML`), so AI output has no HTML-injection path.