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 <noreply@anthropic.com>
5.3 KiB
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, andMASTER_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 + aswitcharm. No new storage, controller, or UI wiring — the panel enumerates modules fromAI_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 rendersresult.textas markdown and can readmeta. - User-selectable provider: thread a
providerparam throughISummarizerService→ 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.