From fd9bd3f47ac74916f037a554049ade319ea5fb16 Mon Sep 17 00:00:00 2001 From: cesnimda Date: Sat, 18 Jul 2026 15:26:04 +0200 Subject: [PATCH] docs(architecture): document the AI Career Assistant (Phase 5) ai-career-assistant.md (modules, prompt flow, provider abstraction, append-only history model, extension points, security). Master guide + roadmap Phase 5 updated with the shipped workspace and the open provider-selection extension. Co-Authored-By: Claude Opus 4.8 --- docs/MASTER_IMPLEMENTATION_GUIDE.md | 4 ++ docs/architecture/ai-career-assistant.md | 90 ++++++++++++++++++++++++ docs/implementation-roadmap.md | 10 +++ 3 files changed, 104 insertions(+) create mode 100644 docs/architecture/ai-career-assistant.md diff --git a/docs/MASTER_IMPLEMENTATION_GUIDE.md b/docs/MASTER_IMPLEMENTATION_GUIDE.md index 6ba8f7a..e09b199 100644 --- a/docs/MASTER_IMPLEMENTATION_GUIDE.md +++ b/docs/MASTER_IMPLEMENTATION_GUIDE.md @@ -56,6 +56,10 @@ career data is stored and how generated documents reference it. - `docs/cv-builder-product-teardown.md` — product teardown. - `docs/career-workspace-branch-assessment.md` — per-table recover/migrate/replace verdict for the recovered Career/CV tables. +- `docs/architecture/cv-builder.md` + `docs/architecture/cv-theme-engine.md` — the shipped CV Builder + (Phase 4/4.5): variant lens over the master profile, data-driven theme engine, public CV routing. +- `docs/architecture/ai-career-assistant.md` — the shipped AI Workspace (Phase 5): per-application + suggestion modules, append-only history, provider abstraction, extension points. **Non-negotiable, restated from those documents:** the master career profile is the single source of truth. Career data is never duplicated into CVs, applications, or variants — a diff --git a/docs/architecture/ai-career-assistant.md b/docs/architecture/ai-career-assistant.md new file mode 100644 index 0000000..0600caf --- /dev/null +++ b/docs/architecture/ai-career-assistant.md @@ -0,0 +1,90 @@ +# 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` (`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. 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}`. + +## Provider abstraction + +Generation goes through the existing `ISummarizerService` → ai-service, which routes to the active +provider (`AI_PROVIDER`: ollama | gemini | groq) — production can offload a weak local GPU to a cloud +provider. Each `AiInteraction` records the resolved provider for transparency, and `GET …/ai/modules` +returns the current provider so the UI can show it. + +**Per-request user-selectable providers** (module 8's "users can choose provider") is a plumbing +extension, not yet wired end-to-end: it needs (a) ai-service to accept a per-request `provider` +override and (b) an API **key configured for each selectable provider**. Both are deployment/credential +concerns (a live paid key per provider), so the code path is left as a documented extension point +rather than shipped half-configured. The abstraction already isolates the change to one method. + +## 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`. +- **User-selectable provider**: thread a `provider` param through `ISummarizerService` → + ai-service; gate on the provider having a configured key (see above). + +## 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. diff --git a/docs/implementation-roadmap.md b/docs/implementation-roadmap.md index b4184b2..630758f 100644 --- a/docs/implementation-roadmap.md +++ b/docs/implementation-roadmap.md @@ -145,6 +145,16 @@ Goal: `Content Tab → Customise Tab → Preview → Export` (guide `:312`). Goal: polish. This is the healthiest area — grounding in the structured profile is already right, and "AI never has final control" already holds. +> **AI Career Assistant SHIPPED 2026-07-18** (commits `f299d7b` backend, `bb0c0fe` frontend). A unified +> per-application **AI Workspace** tab with five suggestion modules — job-analysis, career-match, +> cover-letter (6 tones), interview, application-review — each running through the existing +> `ISummarizerService`/ai-service provider abstraction and stored as **append-only history** +> (`AiInteraction`) with reuse / compare / copy / delete. Suggestion-only throughout; nothing +> auto-applies; `Markdown` renders React nodes (no HTML-injection surface). See +> `docs/architecture/ai-career-assistant.md`. **Still open:** per-request user-selectable providers +> (needs an ai-service per-request override + a configured key per provider — deployment/credential +> work, documented as an extension point); 5.2 AI usage metering (Phase 7 blocker) remains. + | # | Task | Priority | Difficulty | Dependencies | Expected value | |---|---|---|---|---|---| | 5.1 | **Fix `docs/00-ai-context.md` to match the code.** **Decided 2026-07-17: do NOT build the abstraction.** | **P1** | **S** | none | The doc describes a provider interface over OpenAI/Gemini/Claude/Ollama with admin control and per-user choice. Reality: one `AI_PROVIDER` env var over Ollama/Gemini/Groq. Multi-provider cloud AI also undermines the privacy moat (see `docs/research/competitors.md` §4). Revisit only if a customer asks. `docs/architecture/current.md` §9 already records the truth. |