# CV-UX-AI — contextual writing assistance Owner-approved addition, 25 October 2026. This checkpoint is part of CV-UX-01 and does not close AI-P5-13 or authorise production activation. ## Existing owners and contracts `AiSectionAssistant` is already mounted beneath custom content, ordinary section content (including professional summary), and individual entry bullets (experience, projects and education). `CvBuilderEditor` supplies its existing save-before-generation and reviewed-application callbacks. The new compact actions reuse these callbacks: Improve writing (`improve`), Suggest content (`suggest`), Grammar check (`grammar`), Shorter (`shorten`). Existing additional actions remain available. `CvVariantController` requires local authentication and the existing Pro entitlement on generation/application. `CvAiSuggestionService` reads the owned variant and Career Profile, checks the requested saved revision/source, validates output shape and grounding, and issues a protected proposal capability bound to owner, variant, version and source fingerprint. Acceptance rechecks that state and uses the ordinary versioned CV save. Neither generation nor acceptance updates the canonical profile. User edits to a proposal are re-evaluated. Generation is not acceptance. `ISummarizerService` already routes generation to the self-hosted Python sidecar. Factual review uses `/cv/evaluate-rewrite`; unavailable or invalid assessments fail closed. No additional provider/model/dependency or model download is introduced. Suggest content uses the selected saved section's career evidence; it does not infer experience from job requirements. Empty fields request substantiated career facts before generation. Cross-section recommendations are not claimed. The existing cover-letter `AiWorkspaceService` uses the owned linked CV/profile and job context, returns a reviewable suggestion, and records an AI interaction. The existing Pro/local authorization remains. Its body generation does not have the CV capability/grounding evaluator contract: prompt guardrails and user review are not equivalent to semantic qualification. The four direct controls reuse its existing improve/generate/grammar/shorten operations. Local source changes, source CV changes and cancelled requests invalidate pending proposals. Acceptance edits only the local draft; the ordinary revision-checked letter save remains explicit. ## Safety and UX contract Recorded letter suggestions now bind a SHA256 source identity in existing interaction metadata. The fingerprint represents the job/CV/profile snapshot actually used for generation, relevant identity/attachment state and current letter revision. A fresh post-inference check rejects changed input before history is committed; inference is outside the short relational transaction. Stale inference still finalizes its actual usage reservation. Before local Apply, the client calls authenticated Pro, owner/job/module-scoped `POST /api/jobapplications/{jobId}/ai/history/{id}/validate-source`;204 permits local acceptance,409 requests regeneration,404 hides unavailable ownership. Legacy/malformed unbound results fail closed. Local edits, cancellation, job changes, unmount and an overlapping Save discard late validation responses. This proves source freshness at validation, not factual correctness of generated prose. Persistent letter language and AI generation language share the local settings draft. Rendering declares allowlisted English or Bokmål metadata; legacy settings default to English. Rewrite/grammar/shorten retain source-language instructions exclusively. The independently reviewed contact copy defaults name/title/email/phone on and optional location off, preserving unselected destination fields. The source prerequisite now refuses letter inference before model invocation or interaction creation unless an owned linked CV resolves actual career evidence. Identity, section headers, an advert and a prior draft are insufficient. Five source/action refusal combinations were added to the full backend suite. The UI maps `cover_letter_source_required` to actionable EN/Bokmål guidance. The four letter controls are portalled immediately beneath the body field while retaining the existing assistant read lifecycle. - Original and editable proposed text remain separate; Reject never saves and Accept is explicit. - Current document language is supplied to CV generation. Letter language uses its existing explicit selector; grammar/improvement/shortening must preserve source language and meaning. - Loading, retry and logical cancellation retain source text. Cancellation discards responses; it does not claim inference-server interruption. - Shared controls use MUI and EN/Bokmål strings. Keyboard/mobile/browser checks remain distinct from component tests. - Source documents and job descriptions are untrusted data, not authority to change instructions or career facts. ## Evidence to date (intermediate, not final acceptance) Prompt review found and removed competing selected-language instructions for improve/grammar/shorten. Those actions now request source-language preservation exclusively; content generation retains the selected output language. Eighteen EN/Bokmål action/language cases cover this split. Tests were run before the fix: 12 failed and 53 passed, demonstrating the conflicting rewrite instructions. This is prompt-contract evidence, not actual-language model qualification. The successor focused backend run passed65/65 (`prompt-language-green.trx`). Actual local sidecar8001 and Ollama11434 read-only health/inventory probes were refused; Docker had no running services at inspection. No model/service was started or downloaded. Actual inference remains BLOCKED by the absent approved local runtime, rather than being inferred from controlled responses. This does not block independent editor/persistence qualification. `contextual-ai.trx`: 83 backend CV AI tests passed, including four action review/history/canonical-preservation cases. `ai-ui.json`: 61 combined AI/letter UI tests passed. New direct-action and empty-source tests were observed failing before implementation. The new cover-letter concurrent-edit regression also failed before response invalidation was added. These controlled responses do not demonstrate actual model quality. | Action | Implementation | Frontend | Backend | Actual model / production | |---|---|---|---|---| | Improve writing | Existing CV/letter paths exposed directly | Full frontend PASS | Full backend PASS; recorded source validation | BLOCKED / not eligible | | Suggest content | New CV action; existing letter generation | Full frontend PASS; missing facts require input | Full backend PASS; letter semantic limitation above | BLOCKED / not eligible | | Grammar check | Existing paths exposed directly | Full frontend PASS | Full backend PASS; exclusive source-language instruction | BLOCKED / not eligible | | Shorter | Existing paths exposed directly | Full frontend PASS | Full backend PASS; exclusive source-language instruction | BLOCKED / not eligible | Outstanding: fresh full regression, endpoint authorization/browser coverage, actual approved self-hosted EN/Bokmål inference and adversarial semantic acceptance, source-grounding qualification for letter operations, human accessibility and language review. Production remains NO-GO; no deferred P5-13 operation is activated by this UI work. Reviewed successor evidence: source-bound letter guard103 focused backend cases pass; full Release backend1227/1227; full frontend981/981 across107 suites with before/after source hashes equal; application-assets53/53 and contact/language10/10 focused cases overlap the full frontend total. Source guard tests first produced19 failures; malformed legacy hardening produced3 failures before correction. Updated physical language assertions and seven responsive scenarios passed in two real browser cases; Windows letter oracle4/4 across14pages has zero differences. Independent re-review found no remaining material frontend/backend issue. Fresh aggregate browser/provider/Linux gates remain pending final reconciliation; actual inference remains unavailable and unqualified.