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 <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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. |
|
||||
|
||||
Reference in New Issue
Block a user