# Career Workspace — Product Strategy & Roadmap

**Date:** 2026-07-12
**Inputs:** `docs/cv-builder-competitor-deep-research.md` (market), `docs/cv-builder-product-teardown.md` (as-is audit), CV Builder Architecture Proposal (target design).
**Nature:** This is a *decision document*, not a summary. Where the research allowed multiple directions, this document picks one and says why. Intended as the foundation for Fable 5 product planning, the engineering roadmap, UX design, and architecture decisions.

---

## 1. Product Vision

### The one-sentence vision

> **Jobbjakt is the workspace where your career data lives once and works everywhere — every CV, cover letter, application, and interview prep session is generated from, and feeds back into, one structured career profile.**

### Evaluating "the CV is not the product; the profile is"

The premise is **correct but incomplete**. Correct: the teardown proved every current defect traces to documents-as-primary-objects, and the research proved no competitor owns the profile-first position. Incomplete: a profile sitting still is a database, not a product. What users pay attention to (and would pay money for) is what the profile *does under pressure* — during an active job search.

**Refined thesis:** the product is the **loop**, and the profile is its engine:

```
Career Profile → tailored application (CV + letter, gap-driven)
      ↑                    ↓
  learns from ← application outcome (tracked, email-observed)
```

Every competitor owns at most one arc of this loop. Teal has profile→tailor but weak rendering and stops at "Applied." Design-led builders have rendering but no career data. Reactive Resume has clean documents but zero context. **Nobody closes the loop — and we already own its rarest arc: the outcome-observation side (Gmail intelligence, status suggestions, tracking).** That asymmetry is the strategy. We don't build a CV builder and add tracking; we already have the tracking-and-intelligence layer competitors can't cheaply replicate, and we're adding the one commodity piece (a good CV builder) they all have.

### The problems we solve

1. **Fragmentation:** the modern search runs across 5–7 tools (builder, tracker, spreadsheet, keyword checker, letter writer, prep notes) with career data re-typed into each. One profile, one workspace.
2. **Tailoring cost:** serious applicants need 3–5 tailored variants; today that means duplicated documents that rot independently. Variants inherit from the profile; the profile updates everywhere.
3. **Blind applications:** applicants don't know what the ATS sees or what the JD wants. Match scoring + gap-driven tailoring + ATS-view make it visible.
4. **Career amnesia:** achievements evaporate between searches. A durable, versioned profile means the next search starts warm.
5. **Trust:** the incumbent market monetises desperation (subscription traps, resume hostage-taking, secret AI caps). We are structurally incapable of it (self-hostable, export-always-free) and say so.

### Unique value proposition

> "Other tools build you a document. Jobbjakt runs your search: one career profile that generates every tailored CV and cover letter, scores you against every job you track, reads the recruiter's reply, and preps you for the interview it lands — without ever holding your data hostage."

---

## 2. Product Positioning

### Landscape verdict (from the research, compressed to decisions)

| Cluster | Their strength | Their structural weakness | Our exploit |
|---|---|---|---|
| Design-led (Novoresume, Resume.io, Kickresume, Enhancv) | Template quality, polish, distribution | Predatory billing = trust vacuum; zero career context; PDF-only lock-ins | Fair-exit guarantee + career context they'd have to rebuild their revenue model to match |
| Free/OSS (Reactive Resume, FlowCV) | Trust, editor UX, price | Document-centric; no job context; thin AI | Match their fairness, exceed them on the loop |
| Workspace (Teal) | The loop's left half; tracker distribution | Weak rendering; stops at the application; shallow profile | Deeper profile + real rendering + post-application intelligence |
| Canvas (Canva) | Design freedom | 72% ATS failure — architecturally unfixable | "ATS-safe by construction," provable |

### Why choose us over each

- **Over Novoresume/Resume.io:** same-or-better output quality, no watermark, no hostage, and your CV knows about your job search.
- **Over FlowCV:** everything FlowCV's editor does, plus the variant you're editing is scored against the actual job and updated from your profile.
- **Over Reactive Resume:** same data-ownership ethos (self-hostable, schema published), plus tailoring, tracking, and email intelligence a document tool can't have.
- **Over Teal:** your tailored CV actually looks professional, your profile is deep (provenance, versions), and the workspace doesn't go silent after you click Apply — it reads the interview invite and preps you for it.
- **Over Canva:** structured data → deterministic parse order → every theme ATS-safe by construction, with a "view as ATS" proof.

### Positioning statement

> **For active job seekers who apply to many roles, Jobbjakt is the AI career workspace that turns one structured career profile into every tailored application — unlike resume builders that produce disconnected documents and trackers that abandon you after you apply, Jobbjakt closes the loop from profile to interview, and never holds your data hostage.**

Two positioning disciplines that follow:
1. **Never market as "resume builder."** In that category we have 6 templates against Novoresume's brand; we'd be comparison-shopped on our weakest axis. The category is *career workspace* — young enough (GigForge/ResumeTrakr-tier entrants only) that a quality product can define it.
2. **Trust is a feature with a spec:** export always free (PDF+JSON minimum), no watermark, visible AI quotas, published profile schema, one-click full data export. Each is cheap for us and revenue-model-breaking for incumbents — the definition of a durable wedge.

---

## 3. Target User Personas

Priority order is a decision, not a list: build for P1/P2 first — they exercise the loop hardest and match the product's existing DNA (the current user *is* P2).

### P1 — "Marcus," the high-volume applicant (primary)
Mid-career, applying to 30–80 roles across 2–3 title families. **Goals:** volume without quality collapse; know which applications are alive. **Frustrations:** re-tailoring is an hour per application so he stops tailoring; loses track of threads; every builder wants $25/mo at his most broke moment. **Workflow:** job boards → save → tailor (or guiltily don't) → apply → chaos of follow-ups. **Needs most:** variants with cheap tailoring (gap chips, one-click fixes), tracker + email auto-linking (exists), follow-up nudges (exists), match score triage ("which of these 12 saved jobs am I actually competitive for?").

### P2 — "Dana," the technical professional (primary; the current user)
Developer/engineer, deliberate search, 5–15 applications. **Goals:** precision-target roles; CV that survives both ATS and senior-engineer skim; own her data. **Frustrations:** builders dumb down technical content; canvas tools break ATS; distrusts SaaS lock-in. **Workflow:** deep JD reading → heavy per-role tailoring → tracked follow-ups. **Needs most:** structured editor with real skill taxonomy, ATS-view, self-hosting/schema/JSON export, constrained AI that never invents seniority, diff-on-every-AI-edit.

### P3 — "Sofia," the career changer (secondary)
Moving between fields; same history must tell two different stories. **Goals:** reframe, not fabricate. **Frustrations:** single-CV tools force one narrative; AI rewrites drift into fiction. **Needs most:** multiple *free-standing* variants from one profile (the sharpest validation of profile/variant separation), transferable-skills surfacing, fact-constrained rewriting with visible diffs, cover letters that carry the reframing story.

### P4 — "Tom," the recent graduate (secondary)
First real CV, thin content, no existing document. **Goals:** credible one-pager fast. **Frustrations:** import-only tools (our current dead end — teardown §2) assume a CV exists; blank-page paralysis. **Needs most:** from-scratch guided creation, content prompts ("what did you build at university?"), one great simple theme, honest bullet suggestions. *Strategic note: Tom is the acquisition persona (students share tools; Kickresume's student program precedent) but must not drive architecture — his needs are a subset of P1–P3's editor.*

### P5 — "Priya," the international applicant (secondary)
Cross-border applications; conventions differ (photo/no-photo, page norms, spelling, market-specific sections). **Needs most:** per-variant conventions (photo toggle exists; page mode exists), multilingual content support (rewrite `language` knob exists — rare head start), theme conventions per market, visa/eligibility custom sections. Mostly configuration breadth on top of the variant model, not new architecture.

### P6 — "Elena," the experienced executive (tertiary)
20+ years, 3-page history, selective applications. **Needs most:** selective inclusion per variant (long profile, curated projections — again the variant model), discreet public profile, quality typography. Buys or self-hosts on trust and polish. Serve architecturally, don't design for first.

**Pattern worth noticing:** P3, P5, P6 all reduce to "one deep profile, many selective projections." The personas independently re-derive the core architecture — good sign the architecture is right.

---

## 4. Core Product Model

```
CareerProfile                     ← the durable asset (one per user; N later)
 │  everything you've ever done: jobs, bullets, skills, education, projects,
 │  certs, languages; stable item IDs; normalized dates; provenance metadata
 │  (confidence, source, review state); versioned; structure canonical
 │
 ├──< CvVariant                   ← a persistent *lens* on the profile
 │     │  "Backend-focused" / "Team-lead-focused" / "Career-change: data"
 │     │  selections + overrides by item ID (inherits; profile edits flow in;
 │     │  overrides tracked, revertible)
 │     ├──< CvVersion             ← history: every save/generation; diff/restore
 │     └── ThemeRef → Theme       ← SIBLING input: declarative manifest
 │                                  (tokens, layout, section styles, page-break
 │                                  rules, ATS rating). Never welded to content.
 │
 ├──< TailoredApplication         ← the *event*: variant × JobApplication
 │     │  gap analysis (match score), per-application tweaks, its own versions
 │     └── outcome feedback ← tracker status + Gmail intelligence
 │
 └──> Outputs (adapters; each = projection of profile/variant/application + theme)
       PDF CV · DOCX CV (scoped) · ATS plain-text view · Cover letter
       Public profile (live, not snapshot) · Portfolio/personal site
       LinkedIn content · Interview prep (persisted; email-thread-aware)
```

**Relationships, precisely:**
- **Profile → Variant** is *inheritance with selection*: a variant names which profile items appear, in what order, with what per-item overrides. Edit a job title in the profile → every non-overridden variant reflects it. This single mechanism serves Marcus (volume), Sofia (two narratives), Elena (selective depth).
- **Variant → TailoredApplication** is *instantiation against a job*: the variant is durable and reusable; the tailored application is per-job, driven by the match-score gap list, and versioned so regeneration never destroys manual work (fixes the teardown's overwrite-anxiety root cause).
- **Theme** is orthogonal to all content. Any variant/application renders in any theme; switching is non-destructive by construction.
- **Outputs** are stateless projections through `IOutputAdapter<T>`. New output type ≈ one adapter + (sometimes) one theme. This is what makes Horizon-3 features (portfolio, LinkedIn, site) *cheap* instead of new products.
- **The loop closes** at TailoredApplication ← outcome: tracked status + email signals accumulate on the application, feeding analytics ("last 15 rejections wanted Kubernetes") and, eventually, tailoring suggestions.

Cover letters hang off TailoredApplication (they're per-job by nature), generated from profile + JD + (uniquely) the email thread context.

---

## 5. Feature Prioritisation

### MVP — "the loop works" (next major version)

| Feature | User value | Business value | Complexity | MoSCoW |
|---|---|---|---|---|
| Fix OAuth CV lockout (`isLocal` bug) | Unblocks all Google/MS users | Removes a dead-end for every new OAuth signup | Trivial | **Must (ship now, pre-MVP)** |
| CareerProfile + CvVariant + CvVersion migration (stable IDs, normalized dates) | Invisible now; everything later | The architecture bet | Large | **Must** |
| Structured profile editor (+ extraction review queue) | Career data becomes maintainable; provenance visible | Core differentiator vs. document tools | Large | **Must** |
| Theme engine port — best 3–4 of 6 templates as manifests | Non-destructive theme switching; quality floor | Unblocks marketplace/premium later | Large | **Must** |
| Tailoring workspace (JD gaps ↔ variant ↔ live preview ↔ rescore, full page) | The killer screen; ends modal editing | The demo that sells the product | Large | **Must** |
| Import (upload exists + paste-text) AND from-scratch creation | No user dead-ends at entry | Doubles addressable entry funnel (P4) | Medium | **Must** |
| Diff + accept/reject on every AI mutation | Trust; no silent fabrication | Anti-hallucination brand plank | Small–Med | **Must** |
| Fair-exit set: free PDF+JSON export, no watermark | Table stakes vs. OSS; trust wedge | Positioning proof | Small | **Must** |
| Live paginated preview (<300ms on 3-page CV) | FlowCV-bar editor feel | Retention; perceived quality | Medium | **Should** |
| Template gallery w/ visual previews + ATS rating per theme | Informed choice; ATS trust | Marketing surface | Small | **Should** |
| Persist interview prep / fit outputs | Work stops evaporating | Cheap retention | Small | **Should** |
| UI vocabulary cleanup (kill "reprocess/runs") | Comprehensibility | Polish | Trivial | **Should** |
| DOCX export (scoped single-column) | Loudest market complaint | Checklist parity | Medium | **Could** |
| Cover letter v1 (profile + JD) | Completes the application | Expected feature | Medium | **Could** |
| LinkedIn import | Onboarding speed | Funnel | Medium | **Not now** (parse fragility; paste-text covers 80%) |

### Version 2 — "the loop compounds"

| Feature | User value | Business value | Complexity | MoSCoW |
|---|---|---|---|---|
| Cover letters w/ email-thread context | Letters that reference the actual conversation | Unique-data moat begins | Medium | **Must (V2)** |
| ATS plain-text "what the parser sees" view | Anxiety-killer; provable claim | Marketing weapon vs. Canva/Enhancv | Small | **Must (V2)** |
| Skills-gap analytics across tracked JDs | "Your market wants X; you lack it" | Nobody has it; pure aggregation | Small–Med | **Must (V2)** |
| Email-aware interview prep (persisted, thread-fed) | Preps you for *this* interview | The post-application moat | Medium | **Should** |
| Public profile / share link (theme over live profile) | Always-current link for recruiters | Viral surface; premium candidate | Medium | **Should** |
| Fact-constraint validator (novel-entity flagging) on generation | Career integrity guarantee | Trust plank #2 | Medium | **Should** |
| Variant refresh/diff when profile changed (staleness UX on `CanonicalProfileVersion`) | Safe propagation | Completes inheritance story | Medium | **Should** |
| Published profile schema + JSON Resume import/export | Interop; technical-user trust | OSS goodwill (P2) | Small | **Should** |
| User-defined theme tokens (fonts, spacing) | Personalization | Premium candidate | Medium | **Could** |
| Multi-language variant support (leans on existing rewrite lang) | P5 unlock | Market breadth | Medium | **Could** |

### Future Vision — "the platform"

| Feature | User value | Business value | Complexity | MoSCoW |
|---|---|---|---|---|
| Portfolio / personal-site generation (adapters + themes) | Whole web presence from one profile | Category-defining | Large | **Should (V3)** |
| LinkedIn content generation (summary, about, posts) | Consistency across surfaces | Engagement between searches | Small–Med | **Should (V3)** |
| Career timeline & skills matrix visualizations | Self-knowledge; review prep | Differentiator; needs normalized dates (done in MVP) | Medium | **Could** |
| Theme marketplace (manifest sandbox enables it) | Choice explosion w/o our design time | Revenue share model | Large | **Could** |
| MCP/agent endpoint over profile | User's own AI agents read/write career data | Agent-native future (RR precedent) | Medium | **Could** |
| Multiple CareerProfiles per user | Portfolio careers, consultants | Niche but architecture-ready | Small (post-M1) | **Not now** |
| Coaching / marketplace of humans | — | Off-mission; different business | — | **Not now** |
| Auto-apply / one-click mass application | — | Reputation poison (research: spam arms race) | — | **Never** |

---

## 6. UX Strategy

### First-time user: "I need a CV" → professional PDF, one session

Target: **first rendered PDF < 10 minutes** (FlowCV bar), while quietly building a *profile*, not a document.

```
Sign up (OAuth, one click — bug fixed)
  → "How do you want to start?"   [Upload CV] [Paste text] [Start fresh]
  → Import path: extraction runs live; user lands in REVIEW flow:
     confidence-flagged cards ("We read this as… confirm/fix") —
     provenance metadata finally earns its keep as visible trust
  → Fresh path: guided mini-wizard (contact → most recent job w/ bullet
     prompts → education → skills) — enough for a one-pager, expandable later
  → Theme picker: 3–4 quality themes, visual gallery, ATS badge on each
  → Live preview appears WITH the user's real content immediately
  → Download PDF (free, no watermark) + nudge: "Track a job you're
     applying to — we'll score this CV against it."
```

That final nudge is the workspace conversion moment: the PDF is the hook; the score-against-a-real-job is the "oh, this is different" beat. Teal's lesson (research §2.4): workspace-first onboarding with no artifact feels disorienting — so we produce the artifact first and reveal the system second.

### Returning user

- **Update profile:** Profile is a top-level destination (never again a settings card). Structured sections, inline edit, per-item provenance. Edits show a "3 variants use this item" ripple indicator.
- **New variant:** from profile or by cloning: pick items, name the lens ("Platform-eng focus"), pick theme. Variants list shows which jobs each has been used for.
- **Apply to a job:** job gets a Tailor action → tailoring workspace: JD + gap chips left, variant editor center, live preview right; one-click gap fixes (constrained rewrite + diff); export/attach; tracker updates.
- **Track progress:** existing dashboard/kanban continues; applications now show attached tailored version + match score at application time.

### Navigation (recommended)

```
Dashboard · Jobs (kanban/table) · Inbox (correspondence + review queue)
Career [NEW: Profile · Variants · (later) Public profile] · Settings
```

CV ceases to exist as a noun in the nav. **Career** is the pillar; documents are things you export from it. Tailoring workspace is a *route* (`/jobs/:id/tailor`), reached from a job — full page, never a modal (teardown's hardest UX finding).

### Dashboard design

Keep tracker widgets (pipeline, reminders, analytics). Add two career widgets: **Profile health** (completeness, unreviewed low-confidence fields, variants stale vs. profile) and **Match radar** (saved jobs ranked by score — Marcus's triage). Dashboard answers "what should I do next in my search?", not "here are your documents."

---

## 7. AI Strategy

Doctrine, from research §5's useful-vs-gimmick line: **AI operates on the user's real data (profile, JD, email thread), shows its work (diff, source), and never invents facts.** Anything that generates from nothing, or hides its edit, is out.

| Feature | User problem | AI solution | Complexity | Priority |
|---|---|---|---|---|
| Extraction + confidence review | Getting existing CV into structure is tedious | Parse → normalize → classify w/ per-field confidence; user confirms flagged fields (exists; needs the review UI) | UI only | **P0 (MVP)** |
| Gap-driven tailoring | Tailoring is an hour per job | Match gaps → one-click constrained rewrite per gap → live rescore (wires existing scorer + rewrite) | Medium (UI + orchestration) | **P0 (MVP) — the flagship** |
| Bullet improve w/ diff | Weak bullets; distrust of rewrites | Per-bullet improve, before/after diff, accept/reject; select-and-rephrase constraint | Small–Med | **P0 (MVP)** |
| Fact-constraint validator | Hallucinated seniority/numbers = career damage | Generation limited to profile facts; novel named-entity/number flagging | Medium | **P1 (V2)** |
| Cover letter from profile+JD+thread | Blank-page letters; generic AI letters | Grounded generation citing actual profile items and, in V2, the actual recruiter conversation | Medium | **P1 (V2)** |
| Skills-gap analytics | "Why am I being rejected?" | Aggregate JD demands across tracked jobs vs. profile skills | Small–Med | **P1 (V2)** |
| Email-aware interview prep | Prep is generic; the invite says what the panel covers | Prep generated from profile + JD + thread; persisted; STAR stories from user's own bullets | Medium | **P1 (V2) — the moat** |
| From-scratch content prompts | Blank-page paralysis (P4) | Section-aware questions ("what did you build?") → drafted bullets user edits | Small | **P2** |
| LinkedIn summary generation | Surface consistency | Another projection of the profile | Small | **P3** |
| Career advice chat | — | **Rejected as flagship**: unbounded scope, generic output, hallucination surface; revisit only as thin UI over the grounded features above | — | **Not now** |
| Resume "score out of 100" theater | — | **Rejected**: research shows these are engagement gimmicks; our match score is per-job and actionable instead | — | **Never** |

Operational: provider router stays (Gemini/Groq cloud default in prod, Ollama local fallback); **visible quota** in UI from day one of any metering (Kickresume's secret-cap backlash is the cautionary tale); all CV-content calls remain through the delimiter-fenced, injection-hardened sidecar.

---

## 8. Technical Direction

Confirms the Architecture Proposal with the teardown's amendments. Decision summary:

**Rebuild (replace):**
- Master-CV storage: `ApplicationUser.ProfileCvText/ProfileCvStructureJson` columns → `CareerProfile` table (+ `CareerProfileVersion`). Raw text demotes to derived artifact (search corpus, export). **Structure is canonical** — one truth, stated in code.
- `TailoredCvDraft` → `CvVariant` + `CvVersion` + `TailoredApplication`(job-linked variant use). Presentation leaves the content row: `ThemeRef` + per-variant render tokens.
- `CvTemplateRenderer`'s six C# string-builders → Scriban theme manifests (declarative: tokens, layout slots, section styles, explicit page-break rules, ATS rating). Port best 3–4; retire the rest.
- Tailored-CV UI out of `JobDetailsDialog` → dedicated routes.

**Keep (assets, per teardown §3):**
- Extraction pipeline (artifacts, versioned runs, provenance metadata) — becomes the review-queue engine.
- `JobCvMatchService` + `SkillTagger` — becomes the tailoring loop's engine (retarget corpus to read from structure, not raw text).
- Playwright PDF exporter — stays as the PDF adapter behind `IOutputAdapter<T>`; RR's Chromium-cost lesson says keep the boundary swap-clean, not swap now.
- FastAPI sidecar with fencing + provider router.
- All tracker/Gmail/analytics infrastructure — untouched; it's the moat.

**Migrate gradually:**
- Schema via the raw-SQL reconciler in additive steps: create new tables → backfill from user columns + drafts (assign stable item IDs, normalize dates *during* backfill — one-time cost, teardown amendment) → dual-read period → cut over → drop columns last.
- Endpoints: new `/career/*` API grows beside `/profile-cv/*`; old routes proxy then deprecate. Frontend adopts per-screen (profile editor first, tailoring workspace second).
- Versioning: append-only version rows (profile + variant), content-hash deduped; diff computed, not stored.

**Scalability posture:** current scale is single-server self-hosted; don't over-build. The two future-proofing investments that are cheap now and brutal later: stable item IDs and normalized dates (schema), and the adapter/theme boundaries (code). Everything else (queue-based rendering, multi-tenant sharding) is **Not now**.

---

## 9. Monetisation Opportunities

**Context decision first:** this is currently a self-hosted personal/OSS-style product; Stripe work (Wave 5) is deferred pending product decisions. Monetisation strategy is therefore designed now, implemented only if/when the product goes multi-user SaaS. Design it now anyway — pricing architecture shapes feature boundaries.

**The model, if/when SaaS: FlowCV's seam, our loop.** Free = full quality, singular. Paid = multiplicity + intelligence depth.

| | Free forever | Plus (~£4–6/mo — undercut Teal/Novoresume 3–5×) |
|---|---|---|
| Profile | Full, versioned, provenance | Same |
| Variants | 1 | Unlimited |
| Tailored applications | 3 active | Unlimited |
| Themes | All core themes | Same (+ future marketplace) |
| Export | PDF+JSON, unlimited, no watermark — **always** | + DOCX |
| AI | Metered monthly allowance, **visible quota** | High allowance, still visible |
| Tracker + Gmail | Full | Full |
| Public profile | — | Custom-slug live profile |

**Monetise:** variant multiplicity (the proven seam — value scales with search intensity, exactly when willingness-to-pay peaks, without degrading free quality), AI volume (real marginal cost; honest metering), public profile (ongoing hosted value), later marketplace themes (rev-share).

**Never monetise (the trust spec):** export of your own data, watermark removal (never watermark), the tracker (Teal proved free-tracker acquisition; ours feeds the loop), re-access to documents after cancellation (the anti-Novoresume guarantee — put it on the pricing page verbatim: *"Cancel and keep everything you made."*), secret AI caps (Kickresume's one-star engine).

**Not now:** coaching/human services (different business), auto-apply (never), premium template *tiers* before a marketplace exists (6 themes is too thin to split).

---

## 10. Final Recommendation

### Executive summary

**What it becomes:** the AI Career Workspace — one structured, versioned, provenance-aware career profile that generates every output of a job search (tailored CVs, cover letters, ATS views, public profile, interview prep) and learns from every outcome (tracking, email intelligence, match analytics). The CV builder is the visible front door; the loop is the product.

**Why:** the research shows a market that is huge (55k reviews on a single incumbent), broken on trust (F BBB ratings, hostage patterns), and architecturally stuck — design-led tools can't add career context without rebuilding their revenue model, and the one workspace player (Teal) has weak rendering and stops at the application. The teardown shows our codebase already owns the hardest, least-replicable half: tracking, Gmail intelligence, match scoring, hardened AI, extraction provenance. Every audited defect shares one root cause (documents-as-primary), fixable with one architecture (profile-as-source-of-truth) that four competitor architectures each validate a quarter of.

**How we win:** (1) close the loop nobody closes — profile → gap-driven tailoring → tracked outcome → interview prep from the actual recruiter thread; (2) make trust a spec, not a slogan — export-always-free, diff-on-every-AI-edit, visible quotas, ATS-view proof, published schema; (3) sequence ruthlessly — invisible data migration first, then the structured editor, then the tailoring workspace as the demo that defines the category.

### Recommended next steps — first 10 tasks

1. **Fix the OAuth `isLocal` CV lockout** (`ProfilePage.tsx:356`) — split identity-gates from feature-gates. Ship immediately; P0 bug independent of redesign.
2. **Freeze the CareerProfile schema v1** — profile/variant/version entities, stable item IDs, normalized dates (`YYYY-MM` + `isCurrent`), provenance carried over; publish as JSON Schema doc in `docs/`. (Design task; gates everything.)
3. **Write the migration + backfill** in the raw-SQL reconciler: new tables, backfill from `ProfileCvStructureJson` + `TailoredCvDraft` rows (IDs + date normalization during backfill), dual-read flag. Test against a prod DB copy.
4. **Retarget `JobCvMatchService` to read from structure** (not raw text) — kills the dual-truth divergence and validates the new model with an existing consumer.
5. **Author the Scriban theme-manifest schema** (tokens, layout, section styles, page-break rules, ATS rating) and **port ats-minimal** end-to-end through `IOutputAdapter<Pdf>` as the proving thread. Then port the next 2–3 best templates; retire the rest.
6. **Build the structured profile editor** (new `/career/profile` route): section forms, per-bullet rows w/ reorder, provenance-flagged review queue for low-confidence fields.
7. **Add from-scratch + paste-text entry paths** feeding the same editor/normalize pipeline; wire the onboarding flow of §6 (first PDF < 10 min).
8. **Ship diff/accept-reject on all AI mutations** (rewrite, improve, generation) — the trust primitive, small enough to land while 5–6 are in flight.
9. **Build the tailoring workspace route** (`/jobs/:id/tailor`): gap chips ↔ variant editor ↔ live themed preview ↔ rescore; retire the modal editor.
10. **Ship the fair-exit set + template gallery:** free PDF+JSON export everywhere, no-watermark guarantee stated in UI, visual theme gallery with ATS badges — the positioning made tangible in the product.

Tasks 1–4 are backend-quiet and parallelizable with 5; 6–9 are the visible product; 10 is polish that carries the strategy. This sequence matches the Architecture Proposal's phases with the teardown's amendments applied, and lands the MVP of §5 in full.
