commit e6685203fe61e1f577538a78fd51ca6d852d0331
Author: -Puter <22245429+puterhimself@users.noreply.github.com>
Date: Mon Jun 22 15:04:27 2026 +0530
feat: initial docs repo with project inventory and all documentation
- Added REPO_INVENTORY.md with all repos, branches, remotes, and staging info
- Added .gitignore
- Synced all existing docs from local workspace
- Centralized documentation hub for GrowQR team
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..53c6d76
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+*.tmp
+*.log
+node_modules/
+.env
+.env.local
\ No newline at end of file
diff --git a/Codex_Master_Parallel_Agent_Prompt.md b/Codex_Master_Parallel_Agent_Prompt.md
new file mode 100644
index 0000000..5382345
--- /dev/null
+++ b/Codex_Master_Parallel_Agent_Prompt.md
@@ -0,0 +1,223 @@
+# Codex Master Parallel Agent Prompt
+
+Paste this into a fresh Codex app session.
+
+```text
+You are the lead implementation orchestrator for the GrowQR repo at /Users/puter/Workspace/growqr.
+
+Your job is to complete all four new services in parallel using background/sub-agents and keep them running in an implementation-review loop until the work is done. Do not stop after one slice. Do not pause to ask whether you should continue unless there is a true blocker that makes continued implementation unsafe.
+
+## Primary Objective
+
+Fully implement these four services in this repo, using the existing Python FastAPI template and existing repo patterns:
+
+1. /Users/puter/Workspace/growqr/pathways-service
+2. /Users/puter/Workspace/growqr/matchmaking-service
+3. /Users/puter/Workspace/growqr/marketplace-service
+4. /Users/puter/Workspace/growqr/social-branding-service
+
+Each service already has:
+- docs/PRD.md
+- docs/plan.md
+
+There is also a master orchestration plan here:
+- /Users/puter/Workspace/growqr/docs/Four_Service_Overnight_Execution_Plan.md
+
+You must read those docs first and use them as the source of truth for implementation order, scope, dependencies, and review gates.
+
+## Mandatory Working Style
+
+You must behave as a persistent engineering manager plus implementer, not as a one-shot code assistant.
+
+You must:
+- spawn background/sub-agents for parallel work
+- keep working until all four services reach a genuinely usable implementation state
+- use a develop -> test -> review -> fix loop continuously
+- update plan checklists inside each service as phases complete
+- avoid stopping after partial progress
+- make reasonable assumptions and continue
+- only ask the user a question if there is a real product contradiction or destructive architecture risk
+
+You must not:
+- stop after a single phase and ask “should I continue?”
+- stop just because an external API is unavailable
+- stop because OAuth, scraping, payments, or third-party integrations are incomplete
+- over-focus on one service while ignoring the others
+- silently drift outside the plans without documenting the reason
+
+## Completion Standard
+
+Keep going until each service:
+- boots locally
+- has real models and APIs
+- has tests for core flows
+- has seed/demo data or fixtures
+- has Docker/Compose compatibility
+- has README and plan docs updated
+- has major PRD features implemented where feasible
+- has deferred items explicitly documented only where they are truly blocked by external systems, legal constraints, or unresolved business decisions
+
+“Done” does not mean “I built a scaffold.” It means the service is materially implemented end to end.
+
+## Repository Context To Read First
+
+Read these before implementation:
+
+- /Users/puter/Workspace/growqr/docs/Four_Service_Overnight_Execution_Plan.md
+- /Users/puter/Workspace/growqr/docs/Meeting_Notes_3_Week_Delivery_Plan.md
+- /Users/puter/Workspace/growqr/docs/PRD_Portfolio_Summary.md
+- /Users/puter/Workspace/growqr/pathways-service/docs/PRD.md
+- /Users/puter/Workspace/growqr/pathways-service/docs/plan.md
+- /Users/puter/Workspace/growqr/matchmaking-service/docs/PRD.md
+- /Users/puter/Workspace/growqr/matchmaking-service/docs/plan.md
+- /Users/puter/Workspace/growqr/marketplace-service/docs/PRD.md
+- /Users/puter/Workspace/growqr/marketplace-service/docs/plan.md
+- /Users/puter/Workspace/growqr/social-branding-service/docs/PRD.md
+- /Users/puter/Workspace/growqr/social-branding-service/docs/plan.md
+- /Users/puter/Workspace/growqr/fastapi-service-template/README.md
+- /Users/puter/Workspace/growqr/upskilling_services/services/interview-service/README.md
+- /Users/puter/Workspace/growqr/qscore_service/README.md
+
+Inspect the code of existing services before making assumptions.
+
+## Parallelization Plan
+
+Create a top-level execution plan, then spawn:
+
+- one background builder agent for Pathways
+- one background builder agent for Matchmaking
+- one background builder agent for Marketplace
+- one background builder agent for Social Branding
+- one background reviewer agent that repeatedly reviews all changed code for bugs, regressions, missing tests, broken assumptions, and plan drift
+
+The reviewer agent’s job is not to implement large features first. Its job is to find defects and missing coverage continuously while the builders are working.
+
+You should continue coordinating these agents until the full program is implemented as far as possible in this session.
+
+## Dependency Order
+
+Respect this order:
+
+1. Pathways must stabilize shared user context, recommendation context, and pathway state contracts first.
+2. Matchmaking and Marketplace can build in parallel once Pathways contracts are clear enough.
+3. Social Branding should align to Pathways persona/goal/archetype contracts, but should continue independently using placeholders if needed.
+
+Do not block all work waiting for Pathways to be perfect. Use provisional contracts, then reconcile.
+
+## Scope And Delivery Rules
+
+You must attempt to implement the PRDs broadly, but be intelligent about execution order.
+
+When a feature can be implemented with an internal adapter, mock, stub, manual workflow, or admin-assisted fallback, do that now instead of stopping.
+
+Examples:
+- scraping unavailable -> create ingestion/import/admin pipeline and scraper adapter interface
+- OAuth unavailable -> create manual import adapter and provider interface
+- payment gateway unavailable -> create internal transaction state machine and fake payment confirmation flow
+- analytics unavailable -> persist locally computed metrics and expose APIs
+- external posting unavailable -> build draft generation, approval, and publish confirmation flow
+
+Do not throw away the full PRD vision. Preserve it in:
+- models
+- adapters
+- events
+- configuration
+- deferred docs
+
+But implement the highest-value runnable version first.
+
+## Service-Specific Expectations
+
+### Pathways
+- implement Option A fully first
+- build questionnaire, profile ingest, generation, activation, weekly plans, report data, recommendation context
+- preserve extension points for Option B, Q-scores, adaptive regeneration, and wider orchestration
+
+### Matchmaking
+- implement seeker feed, manual/admin ingestion, ranking, thresholds, feedback loop, action tracking
+- preserve extension points for scrapers, enrichment, employer-side flows, and advanced weighting
+
+### Marketplace
+- implement provider application, approval, listings, browse/search/filter, recommendations, booking state machine
+- fully implement live 1:1, async review, done-for-you first
+- preserve extension points for payments, retainer, group sessions, guarantees, demand aggregation, and pre-booking
+
+### Social Branding
+- implement LinkedIn-first individual flow
+- build import/audit, Brand Score, persona strategy, content calendar, draft generation, approval queue, publish confirmation, dashboard
+- preserve extension points for OAuth, multi-platform support, enterprise workflows, and auto-posting
+
+## Review Loop Requirements
+
+After each meaningful implementation chunk:
+- run relevant tests
+- add tests if missing
+- review changed code against PRD and plan
+- update checkboxes in docs/plan.md
+- continue immediately to the next phase
+
+If a builder agent finishes its assigned phases early, reassign it to help:
+- fix reviewer findings
+- add tests
+- harden Docker/Compose
+- improve docs
+- complete deferred-but-feasible items
+
+## Stop Conditions
+
+Do not stop unless one of these is true:
+- there is a direct contradiction between required documents that materially changes implementation
+- continuing would require a destructive schema decision that could break all four services
+- a missing secret, API, or external integration cannot be bypassed with a fallback and blocks a critical required path
+
+If you hit a stop condition:
+- document the blocker clearly
+- propose the exact smallest decision needed
+- continue all unaffected work in parallel
+
+## Deliverables Before You Finally Stop
+
+Before ending the session, make sure there is:
+- implemented code in all four service folders
+- updated docs/plan.md checklists
+- updated READMEs where needed
+- tests passing where feasible
+- clear notes on any real blockers or remaining external integration work
+
+Start now by:
+1. reading the master plan and all four service plans
+2. building a concise orchestration plan
+3. spawning the sub-agents
+4. beginning implementation immediately
+5. continuing until the whole program is substantially complete
+```
+
+## Shorter Version
+
+Use this if you want a tighter prompt:
+
+```text
+Act as the lead orchestrator for /Users/puter/Workspace/growqr and complete these four services in parallel using background/sub-agents:
+
+- /Users/puter/Workspace/growqr/pathways-service
+- /Users/puter/Workspace/growqr/matchmaking-service
+- /Users/puter/Workspace/growqr/marketplace-service
+- /Users/puter/Workspace/growqr/social-branding-service
+
+Read first:
+- /Users/puter/Workspace/growqr/docs/Four_Service_Overnight_Execution_Plan.md
+- /Users/puter/Workspace/growqr/docs/Meeting_Notes_3_Week_Delivery_Plan.md
+- /Users/puter/Workspace/growqr/docs/PRD_Portfolio_Summary.md
+- each service’s docs/PRD.md
+- each service’s docs/plan.md
+
+Spawn 4 builder agents + 1 reviewer agent. Keep them running in a develop -> test -> review -> fix loop until all four services are materially implemented end to end. Do not stop after a slice and do not ask whether to continue unless there is a true blocker.
+
+Use fallbacks instead of stopping:
+- admin/manual ingestion instead of scrapers
+- internal/fake transaction flow instead of real payments
+- manual import instead of blocked OAuth
+- adapter interfaces for future integrations
+
+Pathways first for shared contracts, then Matchmaking and Marketplace in parallel, then Social Branding aligned to Pathways context. Update each docs/plan.md checklist as phases complete. Before stopping, ensure each service has real models, APIs, tests, Docker compatibility, and explicit documentation of any truly blocked remainder.
+```
diff --git a/Four_Service_Overnight_Execution_Plan.md b/Four_Service_Overnight_Execution_Plan.md
new file mode 100644
index 0000000..3f92e63
--- /dev/null
+++ b/Four_Service_Overnight_Execution_Plan.md
@@ -0,0 +1,215 @@
+# Four-Service Overnight Execution Plan
+
+## Goal
+
+By tomorrow, the target is not full PRD completion. The target is four end-to-end MVP services that are coherent, testable, Docker-runnable, and handoff-ready enough for the next team or overnight agents to keep iterating without inventing architecture.
+
+The only realistic way to do that is:
+
+1. lock a narrow MVP cut for each service now
+2. freeze shared contracts now
+3. let agents implement against those frozen cuts
+4. force a develop -> test -> review loop on every phase
+
+If the agents try to implement PRD breadth, they will fail by morning.
+
+## Hard Decisions Locked Now
+
+These decisions are made now and should not be reopened overnight.
+
+### Shared product decisions
+
+- Treat all four services as MVP delivery, not PRD-complete delivery.
+- Prefer manual/admin-assisted workflows over automation where automation depends on unstable third-party APIs.
+- Deliver backend-first. Demo or admin pages are optional. Full polished frontend is not part of the overnight target.
+- Keep auth simple for now: internal/demo-safe access pattern or stubbed auth dependency, not production auth hardening.
+- Every service must support seeded demo data so flows can be verified without external integrations.
+
+### Shared technical decisions
+
+- Stack: Python, FastAPI, `uv`, async SQLAlchemy, Docker, Docker Compose, optional Postgres and Redis.
+- Follow the service template already created in this repo.
+- Use Postgres as the main persisted state in Docker mode.
+- Use Redis only for async jobs, recomputation triggers, or event fan-out. If Redis blocks progress, keep a DB-backed fallback.
+- Use adapters for all unstable integrations: LinkedIn, social platform posting, scraping, payments, analytics sync.
+- Use deterministic logic for first-pass ranking/generation whenever possible. LLM use should enhance copy or explanation, not block core flow correctness.
+
+### Shared scope decisions
+
+- Pathways: implement Option A only. Option B exists as future extension points and data model placeholders.
+- Matchmaking: seeker-side opportunity feed only. Admin/manual opportunity ingestion only.
+- Marketplace: implement core onboarding + browse + booking around 3 formats only: live 1:1, async review, done-for-you.
+- Social Branding: individual only, LinkedIn-first, manual/import-based data sync fallback, approval-first workflow.
+
+## Explicitly Deferred Across The Board
+
+These are not overnight goals:
+
+- production-grade scraping pipelines
+- multi-provider OAuth completion across all external platforms
+- employer portal
+- enterprise social branding
+- real payment gateway, payouts, escrow, commission settlement
+- wallet integration beyond stubs
+- all 11 Pathways services at production orchestration depth
+- polished mobile/web UI beyond minimal demo/admin support
+- perfect analytics, alerting, and operational tooling
+
+If an overnight agent starts building one of these, it is off-plan.
+
+## Shared Contracts To Freeze Before Coding
+
+All four services should align on these shared payload shapes.
+
+### `profile_snapshot`
+
+```json
+{
+ "org_id": "growqr",
+ "user_id": "user-123",
+ "region": "india",
+ "current_role": "Product Analyst",
+ "years_experience": 3,
+ "industries": ["saas", "edtech"],
+ "skills": ["sql", "analytics", "stakeholder management"],
+ "goals": ["move into product management"],
+ "preferred_roles": ["product manager"],
+ "preferred_locations": ["remote", "bengaluru"],
+ "salary_range": {"min": 1200000, "max": 1800000, "currency": "INR"},
+ "pathway_archetype": null,
+ "q_scores": {},
+ "brand_score": null
+}
+```
+
+### `service_recommendation`
+
+```json
+{
+ "user_id": "user-123",
+ "service": "matchmaking",
+ "reason_codes": ["skill_gap", "job_search_phase"],
+ "priority": "high",
+ "metadata": {}
+}
+```
+
+### Core events
+
+- `pathway.generated`
+- `pathway.activated`
+- `pathway.updated`
+- `matchmaking.feed_generated`
+- `matchmaking.action_recorded`
+- `marketplace.booking_created`
+- `marketplace.booking_completed`
+- `social_branding.brand_score_updated`
+- `social_branding.content_approved`
+
+If a service cannot emit through Redis yet, it should still persist an event record and expose an internal retrieval endpoint.
+
+## Service Order
+
+### Recommended overnight order
+
+1. Pathways
+2. Matchmaking and Marketplace in parallel
+3. Social Branding after Pathways persona/profile contract is stable
+4. Final review pass across all four
+
+### Why this order
+
+- Pathways defines the shared user context, goals, pathway phase, and recommendation triggers.
+- Matchmaking and Marketplace both depend on those user signals.
+- Social Branding depends on persona/archetype and pathway milestones, so it should not invent those independently.
+
+## Optimal Agent Topology
+
+### Best case: 5 loops
+
+- Builder 1: Pathways
+- Builder 2: Matchmaking
+- Builder 3: Marketplace
+- Builder 4: Social Branding
+- Reviewer loop: reads changed code/doc/tests and only reports defects, gaps, regressions, and missing tests
+
+### If only 2 strong overnight loops are practical
+
+Run in two waves:
+
+1. Pathways + Marketplace
+2. Matchmaking + Social Branding
+
+Pathways must go first either way.
+
+## Mandatory Agent Loop
+
+Every overnight agent must follow this exact loop:
+
+1. Read:
+ - this master plan
+ - the service `docs/PRD.md`
+ - the service `docs/plan.md`
+ - [docs/Meeting_Notes_3_Week_Delivery_Plan.md](./Meeting_Notes_3_Week_Delivery_Plan.md)
+ - [docs/PRD_Portfolio_Summary.md](./PRD_Portfolio_Summary.md)
+ - the service template and at least one implemented service in this repo
+2. Implement only the current phase.
+3. Run tests for that phase.
+4. Review the result against the service acceptance checklist.
+5. Update the checklist in `docs/plan.md`.
+6. Move to the next phase only if the current phase is green.
+
+## Stop Rules
+
+An agent must not stop for these reasons:
+
+- external API unavailable
+- payment provider unavailable
+- OAuth not configured
+- scraping legality/rate-limit uncertainty
+
+Instead it must:
+
+- create an adapter interface
+- implement a stub/manual fallback
+- mark the real integration as deferred
+- continue delivering the internal flow
+
+An agent should stop only for:
+
+- destructive schema uncertainty across services
+- direct contradiction between this plan and the PRD
+- a missing dependency that makes the service impossible to boot locally
+
+## Suggested Skills And Context
+
+If the agent environment supports local skills, the most relevant ones are:
+
+- `brainstorming`
+- `avoid-feature-creep`
+- `doc-coauthoring`
+- `native-data-fetching`
+
+Local context files to load first:
+
+- [docs/Meeting_Notes_3_Week_Delivery_Plan.md](./Meeting_Notes_3_Week_Delivery_Plan.md)
+- [docs/PRD_Portfolio_Summary.md](./PRD_Portfolio_Summary.md)
+- [fastapi-service-template/README.md](../fastapi-service-template/README.md)
+- [upskilling_services/services/interview-service/README.md](../upskilling_services/services/interview-service/README.md)
+- [qscore_service/README.md](../qscore_service/README.md)
+
+## Shared Done Definition
+
+By morning, each service should meet this minimum bar:
+
+- boots locally with `uv run`
+- boots in Docker Compose
+- has a real domain model, not placeholders only
+- has core API routes for the MVP journey
+- has at least one worker/background flow if needed
+- has tests for core happy paths
+- has seed/demo data or fixture setup
+- has a clear `docs/plan.md` with checkboxes updated
+- has an explicit deferred list
+
+Anything below that is still planning, not delivery.
diff --git a/GrowQR Sellable Workflows Catalog.md b/GrowQR Sellable Workflows Catalog.md
new file mode 100644
index 0000000..a6b546f
--- /dev/null
+++ b/GrowQR Sellable Workflows Catalog.md
@@ -0,0 +1,117 @@
+1. Interview-to-Offer Accelerator
+Promise
+“Prepare me for this specific interview and help me convert it into an offer.”
+Uses
+Interview service
+Roleplay service
+Resume service
+Q Score
+Grow Agent
+Why it sells
+People pay when an interview is already scheduled. The urgency is real.
+Output
+Interview prep plan
+Likely questions
+Mock interview sessions
+Behavioral/story bank
+Resume-based talking points
+Weakness diagnosis
+Final readiness score
+
+2. Career Transition Accelerator
+Promise
+“Help me reposition from my current career into a better-fit role.”
+Uses
+Resume service
+Social branding
+Matchmaking
+Q Score
+Interview
+Roleplay
+Grow Agent
+Why it sells
+Career switching is confusing and emotionally expensive. People need a system, not just a resume.
+Output
+Target role recommendation
+Transferable skills map
+Repositioned resume
+LinkedIn/profile rewrite
+Interview narrative: “why I’m switching”
+Practice conversations
+30/60/90 transition plan
+
+3. Salary / Offer Negotiation War Room
+Promise
+“Help me negotiate my offer, raise, or promotion conversation.”
+Uses
+Roleplay service
+Matchmaking
+Q Score
+Resume service
+Social branding
+Grow Agent
+Why it sells
+Direct financial ROI. If the user gets even $5k more, the product paid for itself.
+Output
+Offer analysis
+Market positioning
+Leverage map
+Counteroffer script
+Email drafts
+Live-call practice
+Objection handling
+Confidence score
+
+4. Promotion & Leadership Readiness System
+Promise
+“Help me become promotion-ready and make a strong case for my next level.”
+Uses
+Q Score
+Roleplay service
+Resume service
+Social branding
+Matchmaking
+Grow Agent
+Why it sells
+This expands GrowQR beyond job seekers. Employed professionals have money and a clear career incentive.
+Output
+Promotion readiness score
+Achievement narrative
+Evidence packet
+Manager conversation script
+Leadership gap map
+Internal brand plan
+60/90-day promotion plan
+
+5. Personal Brand & Opportunity Engine
+Promise
+“Make me visible and credible so better opportunities come to me.”
+Uses
+Social branding
+Resume service
+Matchmaking
+Q Score
+Roleplay service
+Grow Agent
+Why it sells
+This is less urgent than interview/negotiation, but better for recurring revenue.
+Output
+LinkedIn/profile rewrite
+Positioning statement
+Content pillars
+Weekly post drafts
+Target audience map
+Networking scripts
+Brand growth score
+
+My recommended premium lineup
+If I had to pick only the strongest 4:
+Interview-to-Offer Accelerator
+Career Transition Accelerator
+Salary / Offer Negotiation War Room
+Promotion & Leadership Readiness System
+Then use:
+Job Search Lite as free acquisition
+Personal Brand Engine as subscription/add-on
+That positioning is much stronger than competing with job boards or auto-apply tools.
+
diff --git a/GrowQR-General-Design-Info.pdf b/GrowQR-General-Design-Info.pdf
new file mode 100644
index 0000000..965d33b
Binary files /dev/null and b/GrowQR-General-Design-Info.pdf differ
diff --git a/Meeting_Notes_3_Week_Delivery_Plan.md b/Meeting_Notes_3_Week_Delivery_Plan.md
new file mode 100644
index 0000000..ab271b9
--- /dev/null
+++ b/Meeting_Notes_3_Week_Delivery_Plan.md
@@ -0,0 +1,195 @@
+# Meeting Notes: 3-Week Delivery Plan
+
+## Goal of This Discussion
+
+Align on what we can realistically deliver from our side in **2 to 3 weeks max**, including:
+
+- build scope
+- integration points
+- testing
+- handoff to the next team
+
+This note covers only the four in-scope PRDs:
+
+- Pathways
+- Matchmaking
+- Marketplace
+- Social Branding
+
+Upskilling is already complete and excluded from this plan.
+
+## Recommended Position in the Meeting
+
+We should position this as a **focused MVP delivery**, not a full PRD-complete release.
+
+If we try to implement all four PRDs at full depth in 3 weeks, quality will drop and handoff risk will increase. The right plan is:
+
+- ship the **core user journeys**
+- keep advanced automation and edge-case workflows out of v1
+- finish with a stable integration and handoff package
+
+**Bottom line:** a strong **3-week MVP** is realistic. A **2-week version** is possible only if we cut harder and treat it as an internal alpha.
+
+## What We Can Realistically Deliver in 3 Weeks
+
+### 1. Pathways
+
+We can deliver:
+
+- questionnaire flow
+- LinkedIn/resume-based input only
+- career option generation
+- visual career web or list/card equivalent if web is too heavy for v1
+- basic skill-gap and recommendation output
+- pathway activation flow
+- simple weekly journey structure
+- report v1 or exportable summary
+
+We should not commit now to:
+
+- full premium psychometric pathway logic
+- all 25 Q-Score dependent adaptive behaviors
+- fully dynamic report regeneration
+- deep 11-service orchestration logic at production depth
+
+### 2. Matchmaking
+
+We can deliver:
+
+- seeker-side opportunity feed
+- core matching logic using available profile/Q-Score/preference data
+- admin/manual opportunity ingestion or controlled imports
+- action loop for save / dismiss / apply or equivalent
+- basic ranking and thresholding
+
+We should not commit now to:
+
+- large-scale multi-platform scraping across all listed sources
+- employer portal phase
+- full enrichment from every external source
+- hourly scraping pipelines
+- Travel Mode as a fully polished feature
+
+### 3. Marketplace
+
+We can deliver:
+
+- provider profile model
+- provider onboarding and admin approval flow
+- service listings
+- open browsing
+- basic booking flow
+- pathway-triggered recommendations in a simpler rules-based form
+- basic booking states and notifications
+
+We should not commit now to:
+
+- outcome guarantee engine
+- Q-Score verified provider performance system
+- group demand aggregation engine
+- pre-booking engine
+- full dispute/refund automation
+- complex commission and escrow logic
+
+### 4. Social Branding
+
+We can deliver:
+
+- LinkedIn-first MVP
+- persona selection / strategy mapping
+- profile audit and rewrite suggestions
+- content calendar generation
+- draft generation with approval queue
+- Brand Score v1 with limited inputs
+- dashboard-level summary output
+
+We should not commit now to:
+
+- full 4-platform automation at launch
+- enterprise social branding module
+- auto-posting across all platforms
+- engagement automation and response automation
+- deep analytics or recruiter visibility measurement across platforms
+
+## Proposed Delivery Sequence
+
+### Week 1: Foundation and Pathways First
+
+- freeze MVP scope across all four modules
+- lock shared entities: user profile, pathway state, provider, opportunity, social profile, recommendation event
+- define API contracts and handoff boundaries
+- build Pathways questionnaire and generation flow first
+- set up admin tooling where manual ops will replace automation in v1
+
+**Why this first:** Pathways drives the recommendation layer for the other three services. If Pathways is unclear, Matchmaking, Marketplace, and Social Branding all drift.
+
+### Week 2: Matchmaking and Marketplace Core
+
+- implement opportunity ingestion and matching service
+- build seeker feed and interaction loop
+- build provider onboarding, listing, and booking flow
+- wire simple pathway-triggered recommendations into Marketplace
+- begin integration testing across Pathways -> Matchmaking / Marketplace
+
+### Week 3: Social Branding, Stabilization, Testing, Handoff
+
+- ship LinkedIn-first Social Branding flow
+- connect Brand Score v1 back into user profile / recommendation logic
+- complete end-to-end QA on all four services
+- document APIs, states, payloads, and known gaps
+- run handoff sessions with the downstream team
+- close with bug fixes and release notes
+
+## If We Need a 2-Week Version
+
+The 2-week plan should be framed as **internal alpha only**.
+
+That version would mean:
+
+- Pathways only in a simplified form
+- Matchmaking with manual opportunity data only
+- Marketplace with browse + provider listing + request flow, not full booking depth
+- Social Branding as strategy + draft generation only, no posting workflow
+
+## First Thing We Should Do
+
+The first step is **not coding features**. The first step is to lock the MVP cut line and architecture decisions.
+
+Specifically:
+
+- decide the exact v1 journey for each module
+- identify what will be manual/admin-assisted in v1
+- confirm data sources we actually have access to
+- define what the handoff team expects from us: API-ready services, UI flows, docs, or tested modules
+
+If we do not settle this in the first 1 to 2 days, the team will burn time building PRD breadth instead of delivering a stable product slice.
+
+## Main Trade-Offs
+
+- **Speed vs completeness:** We can deliver four working modules in 3 weeks only by shipping a narrow MVP.
+- **Automation vs reliability:** Manual ingestion and admin workflows are acceptable for v1 if they reduce engineering risk.
+- **Breadth vs polish:** It is better to have one good flow per module than many half-finished flows.
+- **Platform ambition vs integration reality:** Several PRDs assume external platform access, scraping, analytics, and automation that may not be practical in the current window.
+- **Feature depth vs handoff quality:** If we overbuild, testing and documentation will suffer, which will hurt the other team more than a smaller but stable release.
+
+## Points to Raise in the Meeting
+
+- Are we aligned that this is an MVP delivery, not full PRD completion?
+- Is **Pathways Option A only** acceptable for this phase?
+- For Matchmaking, are **manual/admin-loaded opportunities** acceptable for v1?
+- For Marketplace, do we need **true booking and payment**, or is booking/request capture enough for phase 1?
+- For Social Branding, is **LinkedIn-first** acceptable, with other platforms deferred?
+- Which advanced features are explicitly deferred so they do not re-enter scope mid-sprint?
+- What exactly does the receiving team need in the handoff?
+- Who signs off on scope changes once delivery starts?
+
+## Recommended Closing Statement
+
+Our recommendation should be to commit to a **3-week MVP across all four modules**, with:
+
+- Pathways as the orchestration anchor
+- Matchmaking and Marketplace as operational core flows
+- Social Branding as a LinkedIn-first managed MVP
+- final days reserved for testing, documentation, and handoff
+
+That gives us the best chance of delivering something credible, integrated, and supportable instead of spreading effort across too much PRD depth.
diff --git a/PRD_Portfolio_Summary.md b/PRD_Portfolio_Summary.md
new file mode 100644
index 0000000..4551eb0
--- /dev/null
+++ b/PRD_Portfolio_Summary.md
@@ -0,0 +1,19 @@
+# GrowQR PRD Portfolio Summary
+
+This summary consolidates the major work described across the Pathways, Matchmaking, Marketplace, Social Branding, Courses, Assessment, Interview, and Roleplay PRDs. Together, these documents define GrowQR as an AI-led career development platform built around a central orchestration layer rather than a single tool. The platform's core promise is to understand a user's background, skills, preferences, and measured capabilities, then turn that into a dynamic pathway for growth, positioning, and opportunity.
+
+At the center is **Pathways**, which acts as GrowQR's orchestration engine. Pathways takes profile data from LinkedIn or a resume, combines it with a structured questionnaire, and for premium users adds psychometric profiling and 25 Q-Scores. It then generates a set of career options across close-match, adjacent, and stretch paths, renders them in an interactive visual career web, and activates a time-bound development journey. Once a pathway is live, Pathways coordinates all 11 GrowQR services through weekly cycles with explicit rules around sequencing, time commitment, adaptation, and progression from learning to application. It also produces a branded Pathway Report that explains the user's archetype, skill gaps, job-market fit, and action plan.
+
+Around this orchestration layer sits a set of execution services. The **Assessment Service** provides short, role-specific AI-generated assessments using a standardized input-processing-output model. It evaluates technical, behavioral, and role-fit signals, contributes directly to Q-Scores, and feeds recommendations into other services. The **Course Service** handles learning delivery through a staged strategy: first indexing external courses, then enabling third-party creators, and finally generating GrowQR-owned GenAI course IP personalized by persona, life stage, industry, and Q-Score profile. Both services deliberately avoid building a proprietary LMS and instead integrate with platforms such as Moodle and Thinkific.
+
+The practice layer is covered by **Interview** and **Roleplay**. These are avatar-based AI simulations with real-time voice, video, and optional screen sharing. Interview focuses on mock interview performance across different interviewer personas, durations, and interview types. Roleplay focuses on applied communication and scenario-based performance. Both services analyze voice, body language, facial expression, technical quality, and, where relevant, screen content such as code or presentations. Both also feed their findings back into Courses, Assessment, and the Dashboard so users can move from diagnosis to practice to improvement.
+
+The opportunity layer is defined by two closely related systems: the **Opportunity Matchmaking Engine** and the **Marketplace**. The Matchmaking Engine is a two-sided AI marketplace for jobs, gigs, events, advisory roles, surveys, temporary earning opportunities, and future-pathway opportunities. It matches users using 46 personalized attributes: 25 Q-Scores plus 20 stated preferences, with a weighted scoring model across skills, personality, culture, growth, and compensation. It also introduces a feedback loop in which actions such as apply, save, RSVP, or dismiss continuously refine future recommendations. A notable feature is Travel Mode, which temporarily expands location-aware opportunity discovery.
+
+The Marketplace is the paid services supply layer for GrowQR. It houses validated providers such as coaches, senior users, institutions, and in-house experts across formats including 1:1 sessions, async reviews, workshops, retainers, and done-for-you services. Marketplace is separate from Mentors: Marketplace is the open verified supply pool, while Mentors is a curated subset surfaced by Pathways at the right cycle moments. The PRD goes beyond basic booking flows and introduces several structural innovations intended to solve cold-start and trust problems: seeding supply from GrowQR's own successful premium users, outcome-guarantee services tied to measurable results, Q-Score-verified provider performance, group-session demand aggregation from pathway signals, and pre-booking of future services based on predicted need.
+
+The **Social Branding** service extends GrowQR from internal development to external market visibility. It automates professional brand building across LinkedIn, Instagram, X, and YouTube using a scrape-analyze-generate-approve-post-track loop. For individuals, the service builds a persona-led content system that combines a pre-baked toolkit with dynamic AI content, calculates a Brand Score, and feeds that score into RQx in the wider Q-Score model. For enterprises, it adds governance, content rules, multi-account structures, and brand voice controls. In effect, Social Branding turns reputation and discoverability into measurable, managed platform outputs rather than side effects.
+
+Across all eight PRDs, several common design principles are consistent. First, GrowQR is designed as a **microservice ecosystem** where each service is specialized but tightly integrated through shared data and events. Second, the platform is built around **measurement and feedback**, especially through Q-Scores, Brand Score, and performance history. Third, GrowQR aims to move users from insight to action: discover strengths and gaps, practice them, learn targeted skills, improve measurable scores, strengthen market presence, and finally unlock better opportunities and providers. Fourth, the platform is intentionally **adaptive**. Recommendations, pathways, and provider suggestions are expected to change as users complete services and their scores improve.
+
+In summary, the work described in these PRDs is not a collection of disconnected tools. It is a full-stack career growth operating system. Pathways determines direction, Assessments and simulations diagnose and build capability, Courses provide structured learning, Social Branding improves professional visibility, Matchmaking finds opportunities, and Marketplace connects users to verified human support. The unifying logic is that every meaningful user action should generate data, every data point should sharpen personalization, and every service should reinforce the others in a closed-loop career development system.
diff --git a/REPO_INVENTORY.md b/REPO_INVENTORY.md
new file mode 100644
index 0000000..a551f86
--- /dev/null
+++ b/REPO_INVENTORY.md
@@ -0,0 +1,187 @@
+# GrowQR Repository Inventory
+
+> Last updated: 2026-06-22
+> This document catalogs every repository, branch, and remote in the GrowQR ecosystem.
+
+---
+
+## 📍 Quick Links
+
+| Platform | Org | URL |
+|---|---|---|
+| **Gitea (Primary)** | `growqr-app` | https://git.openputer.com/growqr-app |
+| **Gitea (Legacy)** | `puter` | https://git.openputer.com/puter |
+| **GitHub** | `GrowQR-Code` | https://github.com/GrowQR-Code |
+| **GitHub** | `Growqr-org` | https://github.com/Growqr-org |
+| **GitHub** | `Prmsnls` | https://github.com/Prmsnls |
+| **Docs** | `growqr-app/docs` | https://git.openputer.com/growqr-app/docs |
+| **Linear** | `PRM` team | https://linear.app/prmsnls/team/PRM |
+
+---
+
+## 🟢 Active Repositories (In Development)
+
+### 1. `growqr-backend` — Main API Backend
+| | |
+|---|---|
+| **Description** | Core backend API: auth, users, missions, agents, events, orchestration, QScore integration |
+| **Stack** | Node.js / TypeScript / Drizzle ORM / RivetKit / Express / tRPC |
+| **Canonical Remote** | `https://git.openputer.com/puter/growqr-backend.git` |
+| **Staging Branch** | **`staging-rosh`** ← active development |
+| **Production Branch** | `main` |
+| **Other Branches** | `staging`, `chore/release`, `service-rest-events`, `subagents-microservice`, `checkpoint/pre-mission-actions-20260606-031159` |
+| **Mirror** | `https://github.com/GrowQR-Code/growqr-backend` (if exists) |
+| **VPS Deploy** | `gqr-temp` (`/opt/growqr/growqr-backend`) |
+| **Linear Issues** | PRM-41, PRM-42, PRM-63–69 |
+
+### 2. `growqr-dashboard` — Next.js Dashboard Frontend
+| | |
+|---|---|
+| **Description** | Main user-facing dashboard: home, onboarding, missions, agents, QScore, analytics |
+| **Stack** | Next.js 14 / React / TypeScript / Tailwind / shadcn |
+| **Canonical Remote** | `https://git.openputer.com/puter/growqr-dashboard.git` |
+| **Secondary Remote** | `dashboard-ui` → `https://github.com/GrowQR-Code/dashboard-ui.git` |
+| **Staging Branch** | **`staging-rosh`** ← active development |
+| **Production Branch** | `main` |
+| **Other Branches** | `staging`, `prd-new-ui`, `dashboard-ui-mission-rebrand`, `backup/mission-action-queue-ui-20260605`, `checkpoint/pre-mission-actions-20260606-031159` |
+| **VPS Deploy** | `gqr-temp` (`/opt/growqr/growqr-dashboard`) |
+| **Linear Issues** | PRM-36, PRM-48, PRM-49, PRM-52, PRM-55, PRM-56–62 |
+
+### 3. `interview-service` — AI Interview Agent
+| | |
+|---|---|
+| **Description** | Voice + text interview practice with AI avatars, LiveAvatar integration, scoring |
+| **Stack** | Node.js / Python / FastAPI / WebSocket / LiveAvatar API |
+| **Canonical Remote** | `gitea` → `https://git.openputer.com/growqr-app/interview-service.git` |
+| **GitHub Remote** | `origin` → `https://github.com/GrowQR-Code/interview-service.git` |
+| **Staging Branch** | **`staging`** |
+| **Production Branch** | `main` |
+| **Other Branches** | `dashboard-service-rest-integration`, `pr-1`, `pr-1-updated`, `q-score` |
+| **VPS Deploy** | `gqr-temp` (port 18007) |
+| **Linear Issues** | PRM-50 |
+
+### 4. `roleplay-service` — AI Roleplay Agent
+| | |
+|---|---|
+| **Description** | Roleplay scenarios for job prep, behavioral interviews, negotiation practice |
+| **Stack** | Node.js / Python / FastAPI / WebSocket |
+| **Canonical Remote** | `gitea` → `https://git.openputer.com/growqr-app/roleplay-service.git` |
+| **GitHub Remote** | `origin` → `https://github.com/GrowQR-Code/roleplay-service.git` |
+| **Staging Branch** | **`staging`** |
+| **Production Branch** | `main` |
+| **Other Branches** | `dashboard-service-rest-integration`, `feat/planning-edit-leaderboard-demo`, `pr-1-updated` |
+| **VPS Deploy** | `gqr-temp` (port 18008) |
+| **Linear Issues** | PRM-50 |
+
+### 5. `qscore_service` — QScore Calculation Engine
+| | |
+|---|---|
+| **Description** | QX Score computation, origination events, score delivery, analytics pipeline |
+| **Stack** | Python / FastAPI / UV |
+| **Canonical Remote** | `gitea` → `https://git.openputer.com/puter/qscore-service.git` |
+| **GitHub Remotes** | `origin` → `https://github.com/GrowQR-Code/qscore-service.git`, `github` → `https://github.com/Prmsnls/QScore-service.git` |
+| **Staging Branch** | **`staging`** |
+| **Production Branch** | `main` |
+| **Other Branches** | `admin-ui`, `feature/quotients-from-pillars` |
+| **VPS Deploy** | `gqr-temp` (port 18009) |
+| **Linear Issues** | PRM-45, PRM-69 |
+
+### 6. `growqr-app` — Legacy Monorepo (Partial)
+| | |
+|---|---|
+| **Description** | Legacy monorepo containing dashboard-service, frontend, orchestrator, resume-builder, user-service, social-branding, nginx, scripts |
+| **Stack** | Mixed (Next.js, Node.js, Python) |
+| **Canonical Remote** | `gitea` → `https://git.openputer.com/growqr-app/growqr-app.git` |
+| **GitHub Remote** | `origin` → `https://github.com/GrowQR-Code/growqr-app` |
+| **Staging Branch** | **`staging`** |
+| **Production Branch** | `main` |
+| **Other Branches** | `dashboard-service-rest-integration`, `migration/legacy-to-contract`, `pr-1` |
+| **Subdirectories** | `dashboard-service`, `frontend`, `orchestrator`, `resume-builder`, `user-service`, `social-branding`, `nginx`, `scripts` |
+| **Linear Issues** | PRM-41, PRM-42, PRM-46 |
+
+### 7. `agent-social-branding` — Social Branding Agent
+| | |
+|---|---|
+| **Description** | LinkedIn content generation, brand score, personal branding pipeline |
+| **Stack** | Python / FastAPI |
+| **Canonical Remote** | `gitea` → `https://git.openputer.com/growqr-app/agent-social-branding.git` |
+| **GitHub Remote** | `origin` → `https://github.com/Growqr-org/agent-social-branding` |
+| **Active Branch** | **`main`** |
+| **Other Branches** | `feature-update`, `handoff-phase-1` |
+| **Linear Issues** | PRM-70 |
+
+### 8. `docs` — Project Documentation (This Repo)
+| | |
+|---|---|
+| **Description** | Central documentation hub: runbooks, architecture, PRDs, playbooks, meeting notes |
+| **Canonical Remote** | `https://git.openputer.com/growqr-app/docs.git` |
+| **Active Branch** | **`main`** |
+
+---
+
+## 🟡 Archived / Deferred Repositories
+
+> Located in `/archived/`. These are not actively deployed but retain code history.
+
+| Repo | Description | Gitea Remote | GitHub Remote | Active Branch |
+|---|---|---|---|---|
+| `assessment-service` | Skills assessment & quiz engine | `growqr-app/assessment-service` | `GrowQR-Code/assessments` | `feature/autocourse-pipeline` |
+| `courses_service` | Course content & video delivery | `growqr-app/courses_service` | `GrowQR-Code/courses` | `feature/autocourse-pipeline` |
+| `growqr-next-frontend` | Earlier Next.js dashboard iteration | `puter/growqr-next-frontend` | `GrowQR-Code/workflows--dashboard` | `main` |
+| `marketplace-service` | Job marketplace / gig board | `growqr-app/marketplace-service` | `GrowQR-Code/marketplace` | `main` |
+| `matchmaking-service` | Job-candidate matching engine | `growqr-app/matchmaking-service` | `GrowQR-Code/matchmaking` | `main` / `feat/matchmaking-scraping` |
+| `pathways-service` | Career pathway recommendations | `growqr-app/pathways-service` | `GrowQR-Code/pathways` | `main` / `pr-1-review` |
+
+---
+
+## 🌐 Staging Environment (VPS `gqr-temp`)
+
+| Service | Local Port | Public URL | Docker Project |
+|---|---|---|---|
+| Dashboard | 13000 | `https://dashboard-staging.gqr.puter.wtf` | `growqr-dashboard-staging` |
+| Backend API | 18012 | `https://backend-staging.gqr.puter.wtf` | `growqr-backend-staging` |
+| Backend Gitea | 13001 | `https://backend-gitea-staging.gqr.puter.wtf` | `growqr-backend-staging` |
+| Interview Service | 18007 | `https://interview-staging.gqr.puter.wtf` | `interview-service-staging` |
+| Roleplay Service | 18008 | `https://roleplay-staging.gqr.puter.wtf` | `roleplay-service-staging` |
+| QScore Service | 18009 | `https://qscore-staging.gqr.puter.wtf` | `qscore-service-staging` |
+| Resume Builder | 18010 | `https://resume-staging.gqr.puter.wtf` | `resume-builder-staging` |
+| User Service | 18011 | `https://user-staging.gqr.puter.wtf` | `user-service-staging` |
+| Rivet Engine | 16420–21 | Internal | `growqr-backend-staging` |
+
+**VPS IP:** `168.144.123.127` (Debian 13)
+**Deploy Root:** `/opt/growqr/`
+**Caddyfile:** `/etc/caddy/Caddyfile`
+
+---
+
+## 🏷️ Branch Naming Conventions
+
+| Prefix | Meaning |
+|---|---|
+| `main` | Production-ready code |
+| `staging` | Pre-production integration branch |
+| `staging-rosh` | **Active feature development branch** (backend + dashboard) |
+| `feat/*` | Feature branches |
+| `chore/*` | Maintenance / tooling |
+| `checkpoint/*` | Pre-change snapshots with timestamp |
+| `backup/*` | Manual backup branches |
+| `migration/*` | Legacy-to-new migration work |
+
+---
+
+## 🔄 Sync Workflow
+
+1. **Local dev** → commit to `staging-rosh` (backend/dashboard) or `staging` (services)
+2. **Push** to Gitea origin
+3. **VPS** pulls via Git credential store (`~/.git-credentials`)
+4. **Docker compose** restart on VPS for deploy
+5. **No SCP/tar** — all sync is Git-based
+
+---
+
+## 📋 Related Linear Resources
+
+- **Team:** PRM (Prmsnls)
+- **Project:** [GrowQR](https://linear.app/prmsnls/project/growqr)
+- **Current Sprint Issues:** PRM-56 through PRM-70
+- **Members:** puter, divyansh242805, karthiksaiketha, kirti
\ No newline at end of file
diff --git a/UI design Mockup Draft.pptx b/UI design Mockup Draft.pptx
new file mode 100644
index 0000000..ad8a405
Binary files /dev/null and b/UI design Mockup Draft.pptx differ
diff --git a/architecture-diagram-1.html b/architecture-diagram-1.html
new file mode 100644
index 0000000..89255a2
--- /dev/null
+++ b/architecture-diagram-1.html
@@ -0,0 +1,89 @@
+
+
+
+
+
+ GrowQR — Linear System Flow
+
+
+
+
+ GrowQR End-to-End System Flow
+ A linear view of how a user request moves through the product: from interactive client, through auth and durable agent orchestration, into sandboxed execution, domain tools, versioned memory, and back to the UI.
+
+
+
+ Client / Gateway
+ Durable Control
+ Runtime Execution
+ Domain Tools
+ Versioned Memory
+ System DB
+
+
+
+ 1
User Interaction User opens a channel, thread, quest, or agent module.
Chat-first interface Generated UI cards Realtime progress surface
+ 2
Gateway Bootstrap Stateless backend validates identity and prepares the session.
Auth/session verification Billing/entitlement checks Repo + actor lookup
+ 3
Actor Connection Client connects to the durable control plane for live orchestration.
WebSocket event stream Actor key routing Per-user state hydration
+ 4
Intent Routing The control plane maps intent to a thread, quest workflow, or specialized agent.
Thread/session state Quest workflow state Runtime lifecycle decision
+ 5
Sandbox Startup An isolated execution environment is created or resumed.
Per-user/runtime isolation Workspace/worktree mount Agent harness session
+ 6
Agent Execution The runtime performs reasoning, tool selection, file operations, and progress streaming.
Sub-agent delegation File/read/write/bash tools Incremental UI events
+ 7
Domain Tool Calls Existing services are invoked as controlled tools, not as direct frontend destinations.
Interview / Roleplay Pathways / Q-Score Social & matching tools
+ 8
Memory Commit Outputs become versioned memory and indexed system metadata.
Markdown/JSON memory files Diff, commit, merge DB pointers + indexes
+
+
+
+
+
Request Path
+
Initial Client calls the gateway for auth, provisioning, and actor connection details.
+
Realtime Client then communicates with the durable control plane over live events/actions.
+
Return Progress, tool activity, generated UI modules, and final artifacts stream back to the client.
+
+
+
Control Responsibilities
+
Actors Hold small durable state: active threads, quest runs, runtime handles, recovery pointers.
+
Workflow Serialize long-running work, resume after restarts, coordinate runtime and memory commits.
+
Security Control which user, actor, runtime, repo, and service calls are allowed.
+
+
+
Execution & Persistence
+
Runtime Ephemeral sandbox runs the agent harness and tool execution. It can be killed/restarted.
+
Memory Git-backed files are the durable user memory and audit trail.
+
DB Relational storage keeps product metadata, indexes, recovery pointers, and billing/account records.
+
+
+
+
+ Why actors? They provide durable, addressable entities for users, threads, quests, runtimes, and score updates without rebuilding locking and recovery in the gateway.
+ Why sandbox? Agent execution can run file tools, shell commands, plugins, and service calls in an isolated, disposable runtime.
+ Why Git memory? User context becomes inspectable, versioned, diffable, reversible, and portable across runtime restarts and upgrades.
+ Why DB too? The database is not the agent memory. It is the operational index for accounts, pointers, subscriptions, recovery, and fast dashboard queries.
+
+
+GrowQR — Linear architecture flow · Client → Gateway → Durable Control → Sandbox Runtime → Tools → Memory → UI
+
+
diff --git a/architecture-diagram.html b/architecture-diagram.html
new file mode 100644
index 0000000..6639dad
--- /dev/null
+++ b/architecture-diagram.html
@@ -0,0 +1,650 @@
+
+
+
+
+
+ GrowQR — System Architecture
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Frontend
+
+
◈ React UI
+
+ Conversational interface
+ Real-time updates
+
+
+
+
+
◇ Next.js BFF
+
+ Auth & session management
+ Payments webhooks
+ Actor management proxy
+
+
+ Vercel / OpenNext
+ BFF Layer
+
+
+
+
+
+
+ 🔐 Clerk Auth
+
+
+ 💳 Stripe
+
+
+
+
+
+
+
⚡ Actor Backend — RivetKit
+
+
Actor Runner
+
Actor Engine
+
Actor Storage
+
+
+ Durable control plane — manages lifecycle, routing & state
+
+
+
+
+
+
+
Sandboxed Runtime
+
+
▣ Agent Runtime
+
+ Sub-agent orchestration
+ Skills loading
+ Tool execution
+ Dockerized isolation
+
+
+ OpenCode / Container
+ Per-user sandbox
+
+
+
+
+
+
+
+
+
+
Git Memory
+
+
● Users Repos
+
+ Profile & goals
+ Quest history
+ Channel memory
+ Artifact storage
+
+
+ Git worktrees
+ Source of truth
+
+
+
+
+
+
+
+
+
+
+
🧵 Threads API
+
+ Session tracking
+ Message logs
+
+
+
+
🧠 Memory API
+
+ Tracking memory
+ 3-layer memory model
+
+
+
+
+
+
+
+
+
+
+
🗄
+
+
PostgreSQL / AWS RDS
+
Account metadata · Recovery pointers · Operational indexes
+
+
+
+
+
+
+
+
+
+ GrowQR Architecture — Agent-centric · Git-backed · RivetKit-durable
+
+
+
+
+
+
diff --git a/business architecture.md b/business architecture.md
new file mode 100644
index 0000000..5bc5051
--- /dev/null
+++ b/business architecture.md
@@ -0,0 +1,582 @@
+I read the workflow catalog docs. My understanding is:
+
+GrowQR is not just “chat + resume + interview.” It should be a **career workflow platform** where users buy concrete outcomes:
+
+- “Help me convert this interview into an offer.”
+- “Help me switch careers.”
+- “Help me negotiate salary.”
+- “Help me become promotion-ready.”
+- “Help me build my public professional brand.”
+- “Help me become placement-ready / first-job-ready.”
+
+The workflows are the **sellable products**.
+The services, agents, OpenCode, Gitea, Q Score, matching, etc. are the **execution engine behind those products**.
+
+## 1. Core product framing
+
+The cleanest framing is:
+
+> GrowQR is a gamified career operating system where every user has a living career identity, a readiness score, an AI agent squad, version-controlled career memory, and workflows that move them toward real-world outcomes.
+
+For students, freshers, job seekers, and early professionals, the product should feel like:
+
+- a career game,
+- a guided mission system,
+- an agent squad helping them,
+- a visual progress map,
+- a score they can improve,
+- and a set of outputs they can actually use: resume, LinkedIn, interview answers, negotiation scripts, opportunity matches, promotion packet, etc.
+
+Not a boring dashboard. Not a document-heavy SaaS tool.
+
+## 2. The main architecture idea
+
+There should be five major layers:
+
+```txt
+Frontend / UX
+ ↓
+Backend API / Product Control Plane
+ ↓
+Workflow Orchestration Layer
+ ↓
+Agent + Service Execution Layer
+ ↓
+Memory / Identity / Score / Matching Layer
+```
+
+More concretely:
+
+```txt
+Next.js Frontend
+ - workflow discovery
+ - career dashboard
+ - chat/agent UI
+ - game-like progress
+ - artifacts and score UI
+
+GrowQR Backend
+ - auth
+ - users
+ - workflow catalog
+ - workflow runs
+ - billing/entitlements
+ - API gateway
+ - service adapters
+ - OpenCode lifecycle control
+ - Gitea/repo control
+
+Rivet Actors / Workflows
+ - durable user actor
+ - durable workflow runs
+ - retries
+ - step execution
+ - human approval gates
+ - long-running background tasks
+
+OpenCode Containers
+ - per-user agent runtime
+ - reads/writes user workspace
+ - generates artifacts
+ - runs agent prompts/modules
+ - commits memory/artifacts to Git
+
+Gitea / Git-backed Memory
+ - user career repo
+ - artifacts
+ - conversations
+ - workflow state snapshots
+ - versioned resumes/profiles/scripts
+ - long-term career memory
+
+Domain Services
+ - Interview service
+ - Roleplay service
+ - Q Score service
+ - Matchmaking service
+ - Social branding service
+ - Resume/profile service
+ - Future human expert marketplace
+```
+
+## 3. Workflows should be backend-owned products
+
+The frontend should not hardcode workflows.
+
+The backend should expose a workflow catalog like:
+
+```ts
+WorkflowDefinition {
+ id: "interview-to-offer"
+ title: "Interview-to-Offer Accelerator"
+ promise: "Prepare me for this specific interview and help me convert it into an offer."
+ segment: ["job-seekers", "students", "freshers"]
+ difficulty: "urgent"
+ estimatedDuration: "3-7 days"
+ priceTier: "premium"
+ visualTheme: {
+ icon: "target"
+ color: "violet"
+ mascot: "Vera"
+ mapStyle: "mission"
+ }
+ modules: [...]
+ outputs: [...]
+ qScoreDimensions: [...]
+}
+```
+
+Then the frontend renders cards from the backend.
+
+This gives us:
+
+- launch control,
+- pricing control,
+- A/B testing,
+- workflow versioning,
+- different catalog by geography/user type,
+- no fake frontend workflows,
+- no mismatch between UI and backend reality.
+
+## 4. Workflows are not services
+
+This is important.
+
+A workflow is a **business outcome**.
+
+A service is a **capability**.
+
+Example:
+
+### Interview-to-Offer Accelerator
+
+Uses:
+
+- Q Score baseline
+- Resume/profile analysis
+- Interview service
+- Roleplay service
+- Matchmaking/context
+- OpenCode artifact generation
+- Gitea memory
+- possibly human coach later
+
+### Career Transition Accelerator
+
+Uses:
+
+- Q Score
+- Resume service
+- Social branding
+- Matchmaking
+- Roleplay
+- Interview
+- OpenCode
+
+### Promotion Readiness System
+
+Uses:
+
+- Q Score
+- Roleplay
+- Resume/profile
+- Social branding
+- leadership evidence packet
+- manager conversation simulation
+
+So the system should have reusable backend capabilities:
+
+```txt
+Capability: analyze_resume
+Capability: rewrite_linkedin
+Capability: compute_qscore
+Capability: run_mock_interview
+Capability: run_roleplay
+Capability: find_opportunities
+Capability: generate_negotiation_script
+Capability: create_promotion_packet
+Capability: create_content_plan
+Capability: update_user_memory
+Capability: commit_artifact_to_git
+```
+
+Workflows compose these capabilities.
+
+That gives us scale.
+
+## 5. The backend should have a workflow registry
+
+The first real backend structure should be something like:
+
+```txt
+growqr-backend/src/workflows/
+ registry.ts
+ types.ts
+ definitions/
+ interview-to-offer.ts
+ career-transition.ts
+ salary-negotiation.ts
+ promotion-readiness.ts
+ personal-brand-engine.ts
+ first-job-launchpad.ts
+```
+
+Each workflow definition should include:
+
+- product metadata,
+- user promise,
+- visual metadata,
+- required inputs,
+- steps/modules,
+- agent assignments,
+- service dependencies,
+- output artifacts,
+- approval gates,
+- score dimensions affected,
+- billing SKU,
+- version.
+
+This becomes the source of truth for both backend and frontend.
+
+## 6. Runtime model
+
+A user starts a workflow:
+
+```txt
+POST /api/workflows/interview-to-offer/runs
+```
+
+Backend creates:
+
+```txt
+WorkflowRun {
+ id
+ userId
+ workflowId
+ workflowVersion
+ status
+ currentStep
+ modules
+ artifacts
+ timeline
+ qScoreBefore
+ qScoreAfter
+}
+```
+
+Then Rivet handles durable execution.
+
+Recommended model:
+
+```txt
+UserActor
+ - owns user-level state
+ - owns active stack/container/repo references
+ - routes messages
+ - knows current active workflows
+
+WorkflowRunActor / Rivet Workflow
+ - owns one workflow run
+ - executes steps durably
+ - retries failed service calls
+ - waits for user approvals
+ - writes artifacts
+ - updates Q Score
+ - emits events to frontend
+```
+
+This prevents one user actor from becoming a giant monolith.
+
+## 7. OpenCode’s role
+
+OpenCode should be treated as a **per-user agentic execution environment**, not as the entire backend.
+
+It is good for:
+
+- generating career artifacts,
+- reading/writing markdown memory,
+- running prompt-based agents,
+- editing repo files,
+- maintaining long-lived user workspace,
+- producing structured outputs,
+- committing artifacts to Git.
+
+It should not be the only source of truth for:
+
+- billing,
+- workflow status,
+- auth,
+- permissions,
+- global Q Score,
+- matching index,
+- public catalog,
+- analytics.
+
+Those belong in backend/Postgres/domain services.
+
+OpenCode should be called by the workflow engine as a worker.
+
+## 8. Gitea/Git memory role
+
+Gitea is very valuable here.
+
+Each user gets a repo like:
+
+```txt
+/users/{userId}/career-memory.git
+```
+
+Inside:
+
+```txt
+profile/
+ identity.md
+ goals.md
+ preferences.md
+
+artifacts/
+ resumes/
+ linkedin/
+ interview/
+ negotiation/
+ promotion/
+ brand/
+
+workflows/
+ interview-to-offer/
+ run-001/
+ plan.md
+ likely-questions.md
+ story-bank.md
+ readiness-report.md
+
+qscore/
+ snapshots/
+ dimensions.md
+
+conversations/
+ chat-summaries.md
+```
+
+The repo becomes the user’s career memory.
+
+Backend/Postgres stores transactional state.
+Gitea stores durable, inspectable, versioned career artifacts.
+
+This is powerful because every workflow improves the user’s future workflows.
+
+## 9. Q Score should be a platform layer
+
+Q Score is not just another workflow.
+
+It should be the scoring layer across everything.
+
+Every workflow should:
+
+1. read current Q Score,
+2. identify weak dimensions,
+3. improve some dimensions,
+4. produce evidence/artifacts,
+5. update score,
+6. show before/after progress.
+
+For the target audience, this should be visual and game-like:
+
+```txt
+Interview Readiness 62 → 78
+Resume Strength 55 → 81
+Market Match 49 → 67
+Communication 58 → 72
+Confidence 44 → 69
+```
+
+The user should feel:
+
+> “My career power is increasing.”
+
+That is much more engaging than showing plain reports.
+
+## 10. Matching should consume Q Score + identity + workflow outputs
+
+The matchmaking service should not just match from resume text.
+
+It should use:
+
+- Q Score dimensions,
+- user goals,
+- skills,
+- constraints,
+- location/remote preference,
+- salary target,
+- interview readiness,
+- brand strength,
+- past workflow outputs,
+- user feedback,
+- employer/job signals.
+
+Then matching becomes smarter after every workflow.
+
+Example:
+
+A user finishes Interview-to-Offer.
+Their communication score improves.
+Their target role is clearer.
+Their resume is stronger.
+Their job matches should become better.
+
+This creates compounding value.
+
+## 11. Frontend should feel like missions, not forms
+
+For Tier-2/Tier-3, India, students, freshers, and early professionals, the UX should be visual, playful, and low-reading.
+
+Think:
+
+```txt
+Choose your mission
+ 🎯 Convert my interview
+ 🚀 Get my first job
+ 🔁 Switch my career
+ 💰 Negotiate my offer
+ 🧠 Become promotion-ready
+ 📣 Build my personal brand
+```
+
+Each workflow should look like a journey map:
+
+```txt
+Start → Diagnose → Build → Practice → Improve Score → Get Matched → Final Pack
+```
+
+Use:
+
+- agent avatars,
+- progress bars,
+- badges,
+- score cards,
+- short text,
+- voice/video later,
+- “daily quests,”
+- artifact cards,
+- before/after score animations,
+- celebratory milestones.
+
+The user should not feel like they are filling enterprise forms.
+
+## 12. Backend-first launch plan
+
+I would structure launch like this:
+
+### Phase 1: Backend workflow foundation
+
+Build:
+
+- workflow registry,
+- generic workflow routes,
+- workflow run model,
+- module execution model,
+- artifact model,
+- Q Score update hooks,
+- OpenCode execution adapter,
+- Gitea artifact commit layer.
+
+Do not overbuild frontend yet.
+
+### Phase 2: First sellable workflows
+
+Launch 3-5 strong workflows:
+
+1. Interview-to-Offer Accelerator
+2. First Job / Placement Launchpad
+3. Career Transition Accelerator
+4. Salary / Offer Negotiation War Room
+5. Personal Brand & Opportunity Engine
+
+These share many primitives, so implementation reuse is high.
+
+### Phase 3: Gamified frontend
+
+Build:
+
+- workflow marketplace,
+- mission detail pages,
+- active workflow map,
+- Q Score dashboard,
+- artifact gallery,
+- agent squad chat,
+- progress timeline.
+
+### Phase 4: Human expert layer
+
+Add:
+
+- coach escalation,
+- mock interviewers,
+- resume reviewers,
+- negotiation coaches,
+- placement mentors.
+
+### Phase 5: B2B/B2B2C
+
+Expand to:
+
+- institutes,
+- cohorts,
+- placement dashboards,
+- recruiter access,
+- startup hiring,
+- enterprise internal mobility.
+
+## 13. The clean mental model
+
+The product should be understood like this:
+
+```txt
+Workflow = what the user buys.
+
+Agent Squad = how the user experiences help.
+
+Services = specialized engines that perform parts of the work.
+
+OpenCode = user-specific agent workspace and artifact builder.
+
+Gitea = version-controlled career memory.
+
+Q Score = career readiness/trust measurement layer.
+
+Matchmaking = opportunity routing layer.
+
+Rivet = durable orchestration/lifecycle layer.
+
+Backend = product/control plane.
+
+Frontend = playful mission UI.
+```
+
+## 14. What we should avoid
+
+We should avoid:
+
+- frontend-owned fake workflows,
+- one hardcoded `job-application` flow,
+- treating each service as a product page,
+- making OpenCode responsible for business state,
+- exposing container/password details to frontend,
+- long text-heavy UX,
+- workflows that only generate documents but do not improve score/matching/memory,
+- losing artifacts outside Git memory,
+- manual-only execution without durable workflow state.
+
+## 15. My high-level recommendation
+
+Architect GrowQR as a **workflow commerce platform for career outcomes**.
+
+Backend owns the catalog and execution.
+Rivet owns durability.
+OpenCode owns per-user agentic artifact work.
+Gitea owns long-term career memory.
+Q Score owns readiness measurement.
+Matching owns opportunity movement.
+Frontend makes the whole thing feel like a fun, visual career game.
+
+That gives us a coherent platform rather than a collection of disconnected tools.
\ No newline at end of file
diff --git a/curator-30day-examples-by-icp.md b/curator-30day-examples-by-icp.md
new file mode 100644
index 0000000..407d3bd
--- /dev/null
+++ b/curator-30day-examples-by-icp.md
@@ -0,0 +1,717 @@
+# GrowQR Curator — 30-Day Plan Examples by ICP
+
+Date: 2026-06-15
+Purpose: Concrete, copy-pasteable 30-day curator plans with full service integration, chat flows, and generated task shapes for each ICP.
+
+---
+
+## ICP: Student / Recent Grad
+
+**Onboarding signal**: `individual + student/recent grad + 0-2 years + before graduation/within 6 months + role/skills`
+
+**Plan theme**: "First Role Readiness Sprint"
+
+**Goal by Day 30**: Have a credible resume, practiced 5+ interviews, active social presence, and a target role with matched opportunities.
+
+---
+
+### Week 1: Baseline + First Proof
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 1 | **Q Score baseline** — review score, pick weakest driver | **Resume upload** — import LinkedIn, mark missing proof | **Pathways review** — pick target role family |
+| 2 | **Q Score check** — log confidence | **Project → proof** — pick 1 project, draft 2 bullets | **Interview preview** — behavioral, 5 min, easy |
+| 3 | **Q Score gap log** — tag skill gaps | **Resume gap scan** — compare to role requirements | **"Tell me about yourself"** — interview preview |
+| 4 | **Q Score proof ledger** — add project tags | **Proof bank v1** — list 3 projects with metrics | **Recruiter intro roleplay** — 5 min preview |
+| 5 | **Q Score confidence pulse** — rate 1-10 | **LinkedIn headline** — agent drafts, user edits | **Interview warm-up** — easy, 5 min, complete |
+| 6 | **Q Score driver review** — choose next focus | **Resume bullet rewrite** — add action verbs, outcomes | **HR screen roleplay** — common questions |
+| 7 | **Week review** — compare day 1 vs 7 | **STAR story #1** — challenge → action → result | **Apply to 2 roles** — matchmaking shortlist |
+
+### Week 2: Fix Gaps + Build Presence
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 8 | **Q Score skill gap** — pick missing skill | **Resume education section** — add relevant coursework | **Role-related interview** — medium, 10 min |
+| 9 | **Q Score proof update** — add new bullets | **LinkedIn About** — agent drafts, 3 lines + proof | **Project explanation** — interview deep dive |
+| 10 | **Q Score movement check** — any driver up? | **Resume keyword pass** — match JD language | **Mock interview medium** — complete + feedback |
+| 11 | **Q Score communication** — log clarity | **Portfolio/GitHub** — README summary + outcome | **Weakness answer** — draft + practice |
+| 12 | **Q Score application quality** — audit last 5 | **Tailored resume** — 1 JD mapped, 3 bullets | **Recruiter callback roleplay** — intro + comp + next step |
+| 13 | **Q Score interview feedback** — pattern check | **STAR story #2** — teamwork example | **Mock interview replay** — weakest area |
+| 14 | **Week 2 review** — callbacks? confidence? | **Credibility post** — agent drafts, project insight | **Behavioral round** — complete + feedback |
+
+### Week 3: Repetition + Market Action
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 15 | **Q Score interview bank** — 5 stories tagged | **Resume summary** — agent drafts, role-targeted | **Salary expectation roleplay** — define range, practice |
+| 16 | **Q Score skill drill** — 3 questions answered | **Resume final pass** — grammar, keywords, export | **Hard question practice** — 3 questions, preview |
+| 17 | **Q Score readiness check** — lowest service signal | **Portfolio polish** — add demo link, screenshot | **Project deep dive** — explain tradeoffs, preview |
+| 18 | **Q Score application audit** — drop-off analysis | **Profile proof link** — featured section update | **Rejection recovery roleplay** — ask for feedback |
+| 19 | **Q Score proof bank** — tag stories to questions | **Case study mini-deck** — before/after/result | **Full round mock** — medium, 10 min, feedback |
+| 20 | **Q Score confidence repair** — anxiety → warm-up | **Resume export** — PDF, role-named, saved | **Fresher pitch** — 60 sec, practice, save |
+| 21 | **Week 3 review** — conversion bottleneck | **Top-company resume** — tailored version | **Target company prep** — research + questions |
+
+### Week 4: Conversion + Next Sprint
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 22 | **Q Score behavioral refinement** — weakest STAR | **LinkedIn activity boost** — agent suggests 3 comments | **Recruiter screen replay** — comp + location |
+| 23 | **Q Score hard mode** — stress test | **Resume final export** — 2 versions | **Mock interview hard** — complete + review |
+| 24 | **Q Score improvement log** — day 1 vs 24 | **Case study polish** — add metric, publish | **Rejection recovery** — practice, save script |
+| 25 | **Q Score interview for top role** — best role | **Proof bank update** — new stories, metrics | **Referral ask** — roleplay, send message |
+| 26 | **Q Score application sprint** — 3 high-fit roles | **Profile final polish** — agent audits, suggests | **Confidence pitch** — roleplay, save script |
+| 27 | **Q Score replay** — weakest area, compare | **Resume versions** — 2 role exports | **Questions to ask** — 5 smart, tailored |
+| 28 | **Q Score readiness review** — baseline vs current | **Progress post** — agent drafts, learning highlight | **Mock interview final** — complete + feedback |
+| 29 | **Q Score offer readiness** — negotiation check | **Resume export** — final PDF, role-named | **Offer call roleplay** — salary + closing |
+| 30 | **Q Score 30-day outcome** — record wins, gaps | **Next sprint plan** — interview, callbacks, skills | **Claim streak** — reward, next cadence |
+
+### Example curator task shapes
+
+**Day 2 — Interview preview**
+```json
+{
+ "title": "Prepare your first mock interview",
+ "subtitle": "Behavioral round · 5 minutes · Easy pressure",
+ "serviceId": "interview-service",
+ "cta": "Open interview preview",
+ "contextNarrative": "Student targeting first role, needs confidence before real interviews.",
+ "subtasks": ["Confirm role", "Select behavioral", "Generate preview", "Complete practice"],
+ "signals": ["interview.confidence", "communication_clarity"],
+ "previewParams": { "type": "behavioral", "difficulty": "easy", "duration": 5, "source": "curator-v1" }
+}
+```
+
+**Day 5 — Agent-Social Branding**
+```json
+{
+ "title": "Draft your first credibility post",
+ "subtitle": "Agent suggests topic, drafts copy, optimizes timing",
+ "serviceId": "agent-social-branding",
+ "cta": "Draft post with agent",
+ "contextNarrative": "Student has project proof but no visibility. Agent builds inbound.",
+ "subtasks": ["Agent analyzes work", "Drafts post with hook", "User edits", "Agent schedules"],
+ "signals": ["visibility", "profile_strength", "public_proof"]
+}
+```
+
+**Day 7 — Job Matchmaking**
+```json
+{
+ "title": "Match with 2 aligned roles",
+ "subtitle": "Resume ready. Find high-fit opportunities.",
+ "serviceId": "job-matchmaking",
+ "cta": "See matched roles",
+ "contextNarrative": "Student has improved resume and interview readiness. Time for active pipeline.",
+ "subtasks": ["Analyze resume vs roles", "Score top 5", "Surface matches", "Track applications"],
+ "signals": ["opportunity_awareness", "pipeline_health", "proactive_search"]
+}
+```
+
+### Chat flow example — Day 2 Interview
+
+**User clicks**: "Prepare your first mock interview"
+
+**Curator**: This is your practice step for today. What role or interview round should I prepare the preview for?
+
+**User**: Product manager
+
+**Curator**: Got it. I prepared a mock interview preview for Product Manager behavioral practice. Behavioral · 5 minutes · Easy pressure. Open the preview to start or adjust the setup.
+
+**[CTA card appears]**
+- Eyebrow: INTERVIEW PREVIEW
+- Title: Your mock interview is ready
+- Subtitle: Behavioral · 5 min · Easy · Product Manager
+- Button: Open interview preview → `/agents/interview/preview?role=Product+Manager&type=behavioral&difficulty=easy&duration=5&source=curator-v1`
+
+---
+
+## ICP: Intern
+
+**Onboarding signal**: `individual + student/recent grad or 0-2 years + employed/internship + role/pay/grow`
+
+**Plan theme**: "Intern-to-Offer Sprint"
+
+**Goal by Day 30**: Convert internship into full-time offer or strong external backup.
+
+---
+
+### Week 1: Impact + Communication
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 1 | **Q Score baseline** — communication/proof drivers | **Capture current project** — describe, stakeholder, expected result | **Define internship outcome** — return offer / feedback / impact |
+| 2 | **Q Score pulse** — log confidence | **Turn internship work into proof** — action/result bullet | **Manager check-in roleplay** — define ask, practice |
+| 3 | **Q Score metrics** — list project KPIs | **Update resume internship section** — company, team, project | **Feedback request roleplay** — practice ask |
+| 4 | **Q Score return-offer readiness** — identify requirements | **Weekly update** — agent drafts, shipped work, learnings | **Return-offer interview preview** — behavioral, 5 min |
+| 5 | **Q Score mock feedback** — warm-up round | **Impact log start** — weekly wins, metrics | **Manager update roleplay** — concise status |
+| 6 | **Q Score scope check** — desired project | **Improve internship bullet** — agent suggests action verbs | **Ask for better scope roleplay** — practice |
+| 7 | **Week 1 review** — project progress, blockers | **Mentor conversation prep** — roleplay, save ask | **Publish learning proof** — agent drafts, anonymized |
+
+### Week 2: Conversion + Visibility
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 8 | **Q Score return-offer check** — compare proof to requirements | **Manager check-in email** — agent drafts, progress + ask | **Project deep dive interview** — open preview, practice |
+| 9 | **Q Score blocker conversation** — conflict roleplay | **Document project decisions** — list, rationale, proof bank | **Resume proof pass** — collaboration, tools, skills |
+| 10 | **Q Score mock return-offer** — complete + feedback | **Peer feedback request** — draft, send | **Q Score update** — add internship proof |
+| 11 | **Q Score final project narrative** — before/action/after | **Profile headline** — agent adds internship role, target | **Full-time conversion roleplay** — timing, ask, practice |
+| 12 | **Q Score technical questions** — 5 likely, practice | **Manager visibility** — agent drafts update, send | **Portfolio artifact** — anonymize, write summary |
+| 13 | **Q Score feedback synthesis** — pattern, improvement | **Resume internship v1** — tighten bullets, metrics, export | **Receiving criticism roleplay** — practice response |
+| 14 | **Week 2 review** — impact log, feedback, conversion action | **Thank-you note** — agent drafts, mentor, send | **Interview replay** — weakest topic |
+
+### Week 3: Offer Path + Backup
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 15 | **Q Score offer path map** — decision maker, timeline, proof | **Roleplay offer conversation** — define ask, practice | **Strengthen project proof** — metric, stakeholder quote |
+| 16 | **Q Score mock medium** — complete + review | **Demo/update deck** — 3 slides, result | **LinkedIn update** — agent drafts internship lesson |
+| 17 | **Q Score explicit feedback** — 3 questions, roleplay | **Prioritization roleplay** — conflict, tradeoff | **Q Score signal review** — lowest driver, route task |
+| 18 | **Q Score return-offer preview** — role, behavioral, practice | **Manager 1-on-1 prep** — agenda, wins, asks | **Resume role-fit tailoring** — post-internship role |
+| 19 | **Q Score project storytelling** — 90-sec story, interview | **Internal networking** — team member intro, schedule | **Impact log refresh** — week wins, blockers solved |
+| 20 | **Q Score conversion close** — direct ask, hesitation | **Mock feedback loop** — compare attempts, schedule next | **Profile polish** — agent updates headline, proof |
+| 21 | **Week 3 review** — offer odds, missing proof, final week | **Final presentation** — outline impact, metric, rehearse | **Q Score progress** — baseline vs current |
+
+### Week 4: Final Push + Close
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 22 | **Q Score presentation Q&A** — likely questions, interview | **Manager decision roleplay** — outcome, ask, save | **Resume final bullets** — refine 3, export role version |
+| 23 | **Q Score stakeholder thank-you** — agent drafts notes | **Mock hard round** — complete + review | **External backup** — 5 roles, tailor, shortlist |
+| 24 | **Q Score promotion/return script** — write, practice | **Portfolio case study** — anonymize, challenge/action/result | **LinkedIn final** — agent drafts, review, publish |
+| 25 | **Q Score offer conversation** — roleplay, comp, closing | **Interview final polish** — top 3 answers, feedback | **Q Score readiness summary** — signals, final note |
+| 26 | **Q Score recommendation** — person, draft, roleplay | **Application backup** — 3 roles, record, follow up | **Manager final update** — agent summarizes impact, interest |
+| 27 | **Q Score decision rehearsal** — comp, scope, script | **Resume export** — final grammar, PDF, version | **Proof bank** — tag stories, metrics |
+| 28 | **Q Score final review** — goals, outcomes, next move | **Mock replay** — weakness, compare, save | **Relationship plan** — contacts, follow-ups |
+| 29 | **Q Score offer/next role** — scenario, practice | **Q Score closeout** — day 1 vs 29, evidence, next sprint | **Milestone update** — agent drafts, publish |
+| 30 | **Q Score outcome** — offer/status, lessons, next plan | **Next sprint** — return offer, external, skill, leadership | **Claim streak** — reward, cadence |
+
+### Chat flow example — Day 4 Return-offer Interview
+
+**Curator**: Which return-offer role or team should this interview prepare you for?
+
+**User**: Full-time PM on the growth team
+
+**Curator**: Got it. I prepared a return-offer interview preview for Growth PM, behavioral round. 5 minutes. You can practice with your internship project as proof. Open the preview to start.
+
+**[CTA card]**
+- Eyebrow: INTERVIEW PREVIEW
+- Title: Return-offer interview preview
+- Subtitle: Growth PM · Behavioral · 5 min · Medium
+- Details: Role: Growth PM | Round: Behavioral | Difficulty: Medium
+- Button: Open preview → `/agents/interview/preview?role=Growth+PM&type=behavioral&difficulty=medium&duration=5&source=curator-v1`
+
+---
+
+## ICP: Fresher / Early Professional (< 5 years)
+
+**Onboarding signal**: `individual + 0-2 or 2-5 years + hunting/between/employed + callbacks/interviews/profile/pay/switch`
+
+**Plan theme**: "Callback-to-Offer Sprint"
+
+**Goal by Day 30**: Resume converts to callbacks, 3+ interviews practiced, 5+ applications tracked, salary confidence built.
+
+---
+
+### Week 1: Diagnose + Fix
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 1 | **Q Score baseline** — weakest driver | **Resume upload** — import, mark missing | **Target role** — pick role, industry, save |
+| 2 | **Q Score resume fit** — compare to JD, top 3 fixes | **Interview warm-up** — easy, 5 min | **Headline rewrite** — agent drafts, target role |
+| 3 | **Q Score callback diagnosis** — mismatch analysis | **STAR story #1** — achievement, structure | **Recruiter screen roleplay** — practice |
+| 4 | **Q Score resume bullets** — metrics pass | **"Why this role"** — define, interview preview | **Application shortlist** — 5 roles, rank, save 3 |
+| 5 | **Q Score mock medium** — complete + feedback | **LinkedIn About** — agent drafts, proof | **Q Score check-in** — movement, next driver |
+| 6 | **Q Score tailored resume** — 1 JD, keywords | **Salary expectation roleplay** — range, practice | **Recruiter outreach** — agent drafts, send 2 |
+| 7 | **Week 1 review** — applications, mock feedback | **Apply to 3 roles** — matchmaking, track | **Credibility post** — agent drafts, work lesson |
+
+### Week 2: Practice + Presence
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 8 | **Q Score interview weakness** — drill, preview | **Proof bank** — wins, metrics, questions | **Profile visibility** — agent suggests 3 comments |
+| 9 | **Q Score role transition** — current vs target, gap | **Resume gap fix** — missing skill proof | **Networking call roleplay** — contact, ask |
+| 10 | **Q Score mock role-related** — complete + review | **Follow-up sprint** — 3 pending, send | **Q Score proof update** — resume changes, driver |
+| 11 | **Q Score STAR #2** — conflict/teamwork | **Weakness answer** — draft, interview, practice | **Opportunity refresh** — 5 roles, rank, save |
+| 12 | **Q Score recruiter call** — intro, comp, next step | **Resume final role version** — summary, bullets, export | **Profile proof link** — featured section update |
+| 13 | **Q Score feedback loop** — pattern, practice again | **Application audit** — 5 scored, remove bad-fit | **Referral ask** — agent drafts, send |
+| 14 | **Week 2 review** — callbacks, confidence, conversion | **Behavioral round** — complete + feedback | **Proof post** — agent drafts, result |
+
+### Week 3: Conversion + Negotiation
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 15 | **Q Score conversion plan** — weak round, cadence | **Resume summary** — agent drafts, role-targeted | **Offer/salary roleplay** — scenario, range, practice |
+| 16 | **Q Score hard questions** — 3 questions, preview | **Recruiter pipeline** — active leads, follow-up | **Q Score review** — lowest driver, route next |
+| 17 | **Q Score project deep dive** — decisions, preview | **Networking follow-up** — 3 contacts, response | **Profile credibility** — agent audits, saves |
+| 18 | **Q Score application sprint** — 3 roles, record | **Rejection recovery** — feedback ask, script | **STAR #3** — leadership, structure |
+| 19 | **Q Score full round** — complete + review | **Resume keyword pass** — JD terms, export | **Personal brand post** — agent drafts, insight |
+| 20 | **Q Score answer polish** — top 3, shorten, practice | **Hiring manager roleplay** — scenario, preview | **Q Score progress** — baseline vs current, final sprint |
+| 21 | **Week 3 review** — interviews, callbacks, blocker | **Target company prep** — research, questions | **Follow-up sprint** — pending, send 3 |
+
+### Week 4: Final Push + Close
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 22 | **Q Score target company** — role, context, preview | **Referral roleplay** — contact, ask, send | **Resume final polish** — grammar, export |
+| 23 | **Q Score salary negotiation** — range, roleplay, script | **Portfolio case** — project, summary, save | **Q Score readiness** — review, gap, act |
+| 24 | **Q Score hard mode** — complete + review | **LinkedIn visibility** — agent updates, posts, messages | **Conversion audit** — stages, drop-off, fix |
+| 25 | **Q Score offer call** — scenario, practice, save | **Interview replay** — weakest, preview, compare | **Proof bank final** — tag, metrics, save |
+| 26 | **Q Score final sprint** — 3 high-fit, record | **Manager/recruiter drill** — scenario, roleplay | **Profile proof** — agent drafts, publish |
+| 27 | **Q Score questions to ask** — 5 smart, tailored | **Resume versions** — 2 roles, export | **Q Score final push** — driver, act |
+| 28 | **Q Score readiness review** — baseline vs artifacts | **Mock final** — complete + feedback | **Networking plan** — weekly, save |
+| 29 | **Q Score negotiation replay** — practice, script | **Pipeline review** — active, actions, deadlines | **Profile final** — agent audits, saves |
+| 30 | **Q Score 30-day outcome** — callbacks, interviews, wins | **Next plan** — conversion, negotiation, transition | **Claim streak** — reward, cadence |
+
+### Chat flow example — Day 6 Salary Roleplay
+
+**Curator**: What salary conversation do you need to prepare for: recruiter screen, offer call, or manager discussion?
+
+**User**: Recruiter screen
+
+**Curator**: Got it. What range are you expecting? Even a rough number helps me prepare the right scenario.
+
+**User**: 8-12 LPA
+
+**Curator**: Got it. I prepared a roleplay preview for a recruiter salary screen. Recruiter asks about expectations, you practice saying 8-12 LPA with confidence. Open the preview to practice.
+
+**[CTA card]**
+- Eyebrow: ROLEPLAY PREVIEW
+- Title: Recruiter salary screen
+- Subtitle: Practice saying your range with confidence
+- Details: Counterpart: Recruiter | Scenario: First screen | Range: 8-12 LPA
+- Button: Open preview → `/agents/roleplay/preview?scenario=salary_screen&counterpart=recruiter&range=8-12+LPA&source=curator-v1`
+
+---
+
+## ICP: Experienced Professional (> 5 years)
+
+**Onboarding signal**: `individual + 5-10 or 10+ years + employed/between/leading + leadership/pay/scope/authority`
+
+**Plan theme**: "Leadership Readiness Sprint"
+
+**Goal by Day 30**: Leadership proof packaged, senior interview confidence, promotion/scope negotiation practiced, authority presence built, 3+ senior roles matched.
+
+---
+
+### Week 1: Leadership Proof + Direction
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 1 | **Leadership Q Score baseline** — leadership drivers | **Import proof** — LinkedIn, site, mark missing | **Leadership target** — pick role, scope, save |
+| 2 | **Leadership gap map** — current vs target | **Leadership impact bullet** — project, team, outcome | **Senior stakeholder interview** — leadership round, preview |
+| 3 | **Leadership positioning** — agent drafts headline | **Leadership resume audit** — execution → scope | **Promotion roleplay** — title, scope, practice |
+| 4 | **Leadership proof bank** — team outcomes, metrics | **Senior team interview** — preview, practice | **Match senior roles** — score, save |
+| 5 | **Leadership behavioral mock** — complete + feedback | **LinkedIn positioning** — agent updates, proof | **Q Score check** — movement, next driver |
+| 6 | **Leadership compensation** — package, roleplay | **Leadership case study** — transformation, before/after | **Authority post** — agent drafts, insight |
+| 7 | **Week 1 review** — score, choose week 2 | **Apply to senior roles** — 3 roles, tailor, track | **Board/executive interview** — preview, save |
+
+### Week 2: Authority + Senior Practice
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 8 | **Leadership STAR** — team challenge, structure | **Difficult stakeholder roleplay** — scenario, practice | **Profile credibility** — agent audits, saves |
+| 9 | **Leadership bullets final** — scope, metrics, export | **Strategy round interview** — preview, practice | **Executive recruiter intro** — agent drafts, send |
+| 10 | **Leadership full mock** — complete + review | **Q Score update** — add proof, driver | **Networking follow-up** — 3 contacts |
+| 11 | **Leadership "why this company"** — research, draft | **Compensation roleplay** — package, practice | **Authority post #2** — agent drafts |
+| 12 | **Leadership case study** — transformation, save | **Leadership weakness** — gap, preview, practice | **Match executive roles** — C-suite/VP, score |
+| 13 | **Board/executive mock** — complete + review | **Profile final** — agent audits, suggests | **Q Score final gap** — choose, act |
+| 14 | **Week 2 review** — interviews, conversion | **Offer negotiation roleplay** — package, practice | **Leadership post** — agent drafts |
+
+### Week 3: Conversion + Executive Presence
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 15 | **Leadership conversion plan** — weak round, practice | **Managing up roleplay** — scenario, save | **Resume versions** — 2 roles, export |
+| 16 | **Hard leadership questions** — 3 questions, preview | **Recruiter pipeline** — leads, follow-up | **Q Score review** — driver, route |
+| 17 | **Leadership deep dive** — project, tradeoffs, preview | **Executive networking** — follow up, record | **Profile final** — agent audits, saves |
+| 18 | **Application sprint** — 3 senior roles, record | **Rejection to next role** — roleplay, save | **STAR transformation** — structure, save |
+| 19 | **Executive full mock** — complete + review | **Resume keyword** — leadership terms, export | **Thought leadership** — agent drafts |
+| 20 | **Answer polish** — top 3, shorten, practice | **Hiring manager roleplay** — preview, practice | **Q Score progress** — compare, final sprint |
+| 21 | **Week 3 review** — blocker, final push | **Target company** — research, questions | **Follow-up** — pending, send |
+
+### Week 4: Close + Next Level
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 22 | **Target company mock** — role, context, preview | **Referral** — contact, practice, send | **Resume final** — grammar, export |
+| 23 | **Negotiation prep** — package, roleplay, script | **Portfolio case** — write, save | **Q Score readiness** — gap, act |
+| 24 | **Hard mode** — complete + review | **LinkedIn visibility** — agent updates, posts | **Conversion audit** — stages, fix |
+| 25 | **Offer call** — scenario, practice, save | **Interview replay** — weakest, compare | **Proof bank final** — tag, save |
+| 26 | **Final sprint** — 3 senior, record | **Communication drill** — roleplay, save | **Profile proof** — agent drafts |
+| 27 | **Questions to ask** — 5 smart, tailored | **Resume versions** — 2 roles, export | **Q Score final push** — driver, act |
+| 28 | **Readiness review** — baseline vs artifacts | **Mock final** — complete + feedback | **Networking plan** — schedule |
+| 29 | **Negotiation replay** — practice, script | **Pipeline review** — active, deadlines | **Profile final** — agent audits |
+| 30 | **30-day outcome** — score, wins, next | **Next plan** — leadership, compensation, transition | **Claim streak** — reward, cadence |
+
+### Chat flow example — Day 3 Promotion Roleplay
+
+**Curator**: What are you asking for: title change, salary increase, larger scope, or leadership opportunity?
+
+**User**: Title change to Engineering Manager + 20% bump
+
+**Curator**: Got it. I prepared a roleplay preview for a promotion conversation with your manager. Scope: EM title + 20% increase. You will practice the ask, handle hesitation, and close with a next step. Open the preview to practice.
+
+**[CTA card]**
+- Eyebrow: ROLEPLAY PREVIEW
+- Title: Promotion conversation
+- Subtitle: Engineering Manager title + 20% increase
+- Details: Counterpart: Manager | Ask: Title + comp | Outcome: Agreement or next step
+- Button: Open preview → `/agents/roleplay/preview?scenario=promotion&counterpart=manager&ask=EM+title+20%25&source=curator-v1`
+
+---
+
+## ICP: Freelancer / Gig Worker
+
+**Onboarding signal**: `gig + starting/fewclients/sidehustle + clients/pricing/standout/trust/income + firstclient/doubleincome/fulltime/1lakh`
+
+**Plan theme**: "Client Pipeline Sprint"
+
+**Goal by Day 30**: Clear offer, 10+ leads contacted, 2+ discovery calls practiced, pricing confidence, 2+ case studies, inbound presence started.
+
+---
+
+### Week 1: Niche + Offer + First Outreach
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 1 | **Q Score baseline** — credibility/trust drivers | **Import portfolio** — LinkedIn, GitHub, mark gaps | **Define niche** — target client, pain, save |
+| 2 | **Package offer** — problem, deliverable, line | **Discovery call preview** — client scenario, practice | **Headline** — agent drafts, client type, outcome |
+| 3 | **Build case study #1** — before/action/after | **Pricing roleplay** — current/target rate, practice | **Inbound post** — agent picks pain, drafts |
+| 4 | **Pipeline map** — lead sources, top 2 | **Offer page polish** — proof, CTA | **Objection handling** — pick, practice |
+| 5 | **Q Score trust check** — credibility gaps | **Outreach sprint** — 5 messages, send | **Portfolio proof** — metric, testimonial |
+| 6 | **Discovery script** — 5 questions, roleplay | **Pricing page** — tiers, outcomes | **Credibility post** — agent drafts, publish |
+| 7 | **Week 1 review** — leads, replies, week 2 focus | **Follow-up roleplay** — polite, send 3 | **Profile update** — agent audits, saves |
+
+### Week 2: Pipeline + Conversion
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 8 | **Lead list** — 20 prospects, score top 10 | **First client call** — scenario, close, practice | **Case study polish** — visuals, outcome, publish |
+| 9 | **Offer specificity** — narrow audience, outcome | **Pricing objection drill** — choose, practice | **Cold DM** — agent drafts, personalize 5, send |
+| 10 | **Q Score credibility** — add case, movement | **Discovery replay** — practice, save feedback | **Inbound content** — agent drafts, pain, CTA |
+| 11 | **Referral ask** — past client, draft, roleplay | **Portfolio audit** — weak section, rewrite | **Pipeline follow-up** — 5 leads, status |
+| 12 | **Proposal structure** — problem, solution, timeline, price | **Proposal call** — client, preview, practice | **Proof post** — agent drafts, case insight |
+| 13 | **Rate increase plan** — current, target, proof | **Pricing hard mode** — discount, scope, practice | **Lead source review** — channels, double down |
+| 14 | **Week 2 review** — leads, calls, bottleneck | **Profile CTA** — agent writes clear, booking | **Discovery practice** — preview, save |
+
+### Week 3: Close + Premium Positioning
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 15 | **Conversion plan** — active leads, next action | **Scope creep roleplay** — boundary, script | **Case study #2** — choose, draft, save |
+| 16 | **Proposal follow-up** — draft, roleplay, send | **Q Score trust** — proof, social, improvement | **Authority post** — agent drafts, lesson |
+| 17 | **Package refinement** — starter, premium | **Premium offer roleplay** — quote, pushback, save | **Outreach sprint** — 5 targeted, send |
+| 18 | **Testimonial request** — client, draft, send | **Client call replay** — discovery, proposal, save | **Portfolio update** — testimonial, result |
+| 19 | **Inbound post #2** — agent picks pain, drafts | **Difficult client** — late payment, scope, practice | **Pipeline health** — leads, calls, proposals |
+| 20 | **Pricing confidence** — day 3 vs 20, script | **Proposal template** — sections, pricing, save | **Q Score progress** — baseline, final sprint |
+| 21 | **Week 3 review** — conversion bottleneck, push | **Close call** — practice, hesitation, save | **Lead refresh** — 20 new, score, save |
+
+### Week 4: Full-time + Inbound
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 22 | **Full-time plan** — income target, client count | **Retainer roleplay** — monthly, practice | **Profile final** — agent audits, case, CTA |
+| 23 | **Outreach sprint** — 10 personalized, send | **Discovery final** — preview, practice, save | **Publish case study** — finalize, publish, share |
+| 24 | **Referral engine** — ask, 10 contacts, send 3 | **Difficult negotiation** — discount, scope, practice | **Q Score credibility** — review, last improvement |
+| 25 | **Proposal follow-up** — list, write, send | **Premium positioning** — rewrite, proof, save | **Authority post** — agent drafts, insight |
+| 26 | **Onboarding script** — first call, roleplay | **Portfolio export** — links, CTA, save | **Pipeline actions** — every lead, next step |
+| 27 | **Close practice** — preview, script | **Retainer offer** — recurring value, price, terms | **Follow-up 5** — draft, send, record |
+| 28 | **Pipeline review** — leads, calls, revenue | **Case study final** — outcome, share, save | **Q Score final** — baseline, trust, next sprint |
+| 29 | **Highest-value call** — active lead, practice | **Recurring income plan** — retainer target, prospects | **Progress post** — agent drafts, learning |
+| 30 | **Outcome review** — leads, replies, calls, wins | **Next sprint** — first client, premium, retainer, brand | **Claim streak** — reward, cadence |
+
+### Chat flow example — Day 3 Pricing Roleplay
+
+**Curator**: What service are you pricing, and what rate do you want to confidently quote?
+
+**User**: UI design, $75/hour
+
+**Curator**: Got it. I prepared a pricing conversation roleplay. Client asks "What's your rate?" You practice saying $75/hour without apologizing. Objections: "That's expensive" and "Can you do $50?" Open the preview to practice.
+
+**[CTA card]**
+- Eyebrow: ROLEPLAY PREVIEW
+- Title: Pricing conversation
+- Subtitle: UI design · $75/hour
+- Details: Client: Generic prospect | Service: UI design | Rate: $75/hr
+- Button: Open preview → `/agents/roleplay/preview?scenario=pricing&service=ui_design&rate=75&counterpart=client&source=curator-v1`
+
+---
+
+## ICP: Founder / Solopreneur
+
+**Onboarding signal**: `founder + idea/MVP/traction/pre-revenue + customers/funding/visibility/team/model + 90-day priority`
+
+**Plan theme**: "Founder Visibility & Validation Sprint"
+
+**Goal by Day 30**: Validated assumptions, 10+ customer conversations, founder brand active, investor pitch ready, 3+ pilot prospects, 1+ hire/collaborator identified.
+
+---
+
+### Week 1: Priority + Validation
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 1 | **90-day priority** — MVP, customers, raise, hire | **Founder Q Score baseline** — credibility drivers | **Import proof** — LinkedIn, site, deck, gaps |
+| 2 | **Founder one-liner** — agent drafts: audience, problem, solution | **Customer discovery preview** — segment, assumption | **Profile headline** — agent drafts, role, venture |
+| 3 | **Riskiest assumption** — identify, evidence needed | **Build-in-public post** — agent picks learning, drafts | **Customer list** — ICP, 20 prospects, score top 10 |
+| 4 | **Discovery script** — 5 questions, non-leading | **Customer interview roleplay** — preview, practice | **Credibility audit** — agent reviews profile, site, deck |
+| 5 | **Q Score validation** — credibility, clarity | **Outreach to customers** — 5 messages, send | **One-liner revision** — agent simplifies, adds pain |
+| 6 | **Investor narrative** — problem, insight, proof | **Objection handling** — customer objection, practice | **Market insight** — agent drafts, publish |
+| 7 | **Week 1 review** — calls, replies, learning | **Discovery follow-up** — write, send, record | **Profile update** — agent updates headline, one-liner |
+
+### Week 2: Customer + Investor
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 8 | **Customer discovery round 2** — refine ICP, 5 more | **Investor intro roleplay** — stage, proof, practice | **Deck/site clarity** — problem, audience, rewrite |
+| 9 | **Pricing hypothesis** — price, buyer, test | **Pricing roleplay** — preview, practice | **Founder update** — agent drafts, learning, publish |
+| 10 | **Q Score credibility** — profile, deck, movement | **Customer call replay** — weak question, save | **Pipeline update** — statuses, next actions |
+| 11 | **MVP scope** — features, must-have, cut one | **Cofounder alignment** — role, preview, practice | **Authority post** — agent picks contrarian, drafts |
+| 12 | **First customer offer** — pilot, outcome, price | **Sales discovery roleplay** — buyer, next step, practice | **Profile proof** — agent adds traction, learning |
+| 13 | **Investor intro email** — concise, proof, send | **Investor objections** — market, team, traction, practice | **Customer synthesis** — calls, pattern, save |
+| 14 | **Week 2 review** — calls, learnings, conversion | **Build-in-public #2** — agent drafts, learning, metric | **Q Score check** — clarity, visibility, next action |
+
+### Week 3: Conversion + Fundraising
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 15 | **Conversion plan** — prospects, next ask, deadlines | **Pilot close roleplay** — offer, objection, next step | **Deck one-liner** — problem, solution, why now |
+| 16 | **Hiring need** — role, outcomes, must-haves | **First hire interview** — role, preview, practice | **Profile social proof** — agent adds customers, advisors |
+| 17 | **Customer sprint** — 10 messages, replies, calls | **Hard customer call** — skeptical, practice, save | **Market narrative** — agent drafts, insight, publish |
+| 18 | **Fundraising readiness** — stage, proof, gaps | **Investor replay** — preview, practice, save | **Deck/site proof** — traction, quotes, add |
+| 19 | **Model validation** — unit assumption, test, evidence | **Pricing/buyer roleplay** — preview, practice | **Pipeline follow-up** — 5 prospects, record |
+| 20 | **Q Score progress** — baseline, strongest, weakest | **Founder pitch** — 60 sec, roleplay, save | **Build-in-public #3** — agent drafts, progress, challenge |
+| 21 | **Week 3 review** — validation, pipeline, final push | **Pilot proposal** — scope, timeline, price, metric | **Closing roleplay** — customer, next step, practice |
+
+### Week 4: Close + Scale
+
+| Day | Measurement | Proof | Practice |
+|-----|-------------|-------|----------|
+| 22 | **Investor FAQ** — hard questions, draft answers | **Collaborator preview** — role, criteria, preview | **Profile polish** — agent audits headline, one-liner, proof |
+| 23 | **Customer outreach** — 10, record, schedule | **Objection: no budget** — practice, save | **Authority post** — agent drafts, market lesson |
+| 24 | **Traction proof** — calls, users, revenue, summarize | **Investor replay** — preview, practice, save | **Q Score final gap** — choose, complete, save |
+| 25 | **Pilot close sprint** — prospects, close asks, record | **Pitch final** — 60 sec, tighten, practice | **Deck/site clarity final** — problem, solution, proof, CTA |
+| 26 | **Hiring outreach** — target, message, send 5 | **Cofounder conversation** — equity, scope, values, practice | **Milestone update** — agent drafts, metric, publish |
+| 27 | **Customer synthesis** — patterns, pivot/persevere | **Next-step close** — pilot, customer, investor, practice | **Credibility final** — agent audits profile, site, links |
+| 28 | **Validation review** — evidence, gaps, decision | **Q Score closeout** — baseline, drivers, next | **Recap** — agent drafts progress, publish |
+| 29 | **Highest-stakes conversation** — investor, customer, hire | **Pipeline actions** — every prospect, next step, deadline | **Pitch/deck export** — final file, share-ready |
+| 30 | **Outcome review** — calls, customers, proof, score | **Next sprint** — MVP, customers, raise, hire, visibility | **Claim streak** — reward, cadence |
+
+### Chat flow example — Day 2 Customer Discovery
+
+**Curator**: Are you trying to validate customers, raise, hire, or build visibility first?
+
+**User**: Validate customers
+
+**Curator**: Good. Which customer segment should this discovery call simulate? Or should I suggest one based on your product?
+
+**User**: B2B SaaS founders
+
+**Curator**: Got it. I prepared a customer discovery roleplay preview. B2B SaaS founder segment. You practice asking non-leading questions about their workflow. The goal: validate your riskiest assumption. Open the preview to practice.
+
+**[CTA card]**
+- Eyebrow: ROLEPLAY PREVIEW
+- Title: Customer discovery call
+- Subtitle: B2B SaaS founders · Validate riskiest assumption
+- Details: Segment: B2B SaaS founders | Goal: Validate assumption | Duration: 10 min
+- Button: Open preview → `/agents/roleplay/preview?scenario=customer_discovery&segment=b2b_saas_founders&goal=validate_assumption&source=curator-v1`
+
+---
+
+## Prompt Templates (Copy-Paste Ready)
+
+### Curator base system prompt
+
+```
+You are the GrowQR Curator. You own the user's 30/60-day growth plan.
+
+Rules:
+- One focused question at a time.
+- No motivational paragraphs.
+- No internal route names in chat text.
+- Always explain business value in plain words.
+- Connect every task back to the user's goal.
+- Ask → Capture → Summarize → Handoff.
+
+Services you can route to:
+- Q Score: measurement, baseline, gap check
+- Resume: proof packaging, bullets, audit
+- Interview: confidence, preview, practice
+- Roleplay: conversation rehearsal, negotiation
+- Agent-Social Branding: agent-drafted posts, profile polish
+- Job Matchmaking: active scoring, warm intros, pipeline
+- Courses: skill gap modules, progress tracked to Q Score
+- Pathways: direction, trajectory, archetype fit
+
+Handoff rules:
+- Interview: gather role + round type → preview with defaults
+- Roleplay: gather scenario + counterpart → preview with defaults
+- Resume: gather target role → open workspace
+- Agent-Social Branding: gather topic or suggest → open branding workspace
+- Job Matchmaking: gather search intent → open matchmaking dashboard
+- Courses: identify skill gap → open course player
+- Pathways: gather direction question → open pathways report
+
+Default preview params:
+- Interview: type=behavioral, difficulty=medium, duration=5
+- Roleplay: outcome=practice, source=curator-v1
+
+CTA copy:
+- Interview: "Open interview preview"
+- Roleplay: "Open roleplay preview"
+- Resume: "Open resume workspace"
+- Agent-Social Branding: "Draft post with agent"
+- Job Matchmaking: "See matched roles"
+- Courses: "Start skill module"
+- Pathways: "Review pathway"
+```
+
+### First-turn prompt by service
+
+**Interview**: "This is your practice step for today. What role or interview round should I prepare the preview for?"
+
+**Roleplay**: "Let's rehearse the conversation before it matters. Who are you speaking with: recruiter, manager, client, investor, or customer?"
+
+**Resume**: "Let's turn your experience into proof. What role or audience should this resume section target?"
+
+**Agent-Social Branding**: "Let's build your visibility engine. Should I suggest a topic based on your recent work, or do you have a specific insight in mind?"
+
+**Job Matchmaking**: "Your profile is ready. Should I find roles that match your current skills, or roles that push you toward your target direction?"
+
+**Courses**: "I spotted a skill gap between your target role and your current proof. Which module feels most urgent: coding, analytics, communication, or strategy?"
+
+**Pathways**: "Let's clarify your direction. Are you trying to validate a target role, explore alternatives, or plan a transition?"
+
+### Handoff-ready prompt
+
+**Interview**: "Got it. I prepared a mock interview preview for [ROLE] [TYPE] practice. [TYPE] · [DURATION] min · [DIFFICULTY] pressure. Open the preview to start or adjust the setup."
+
+**Roleplay**: "Got it. I prepared a roleplay preview for a [SCENARIO] with a [COUNTERPART]. Open the preview to practice or adjust details."
+
+**Resume**: "Saved. Open the resume workspace and we'll turn this into role-fit proof."
+
+**Agent-Social Branding**: "The agent drafted a post about [TOPIC]. Review it in the branding workspace and approve when ready."
+
+**Job Matchmaking**: "I found [N] roles that match your profile. See the matches and apply directly, or request a warm intro."
+
+**Courses**: "I linked a [DURATION]-minute module to your [SKILL] gap. Start it now and apply the learning in your next interview task."
+
+**Pathways**: "I generated a direction analysis for your [ROLE] target. Review the pathway and save your chosen trajectory."
+
+---
+
+## Generated Task JSON Shapes
+
+### Interview preview task
+```json
+{
+ "title": "Prepare your [ROLE] interview preview",
+ "subtitle": "[TYPE] round · [DURATION] minutes · [DIFFICULTY] pressure",
+ "serviceId": "interview-service",
+ "serviceName": "Interview service",
+ "cta": "Open interview preview",
+ "route": "/agents/interview/preview",
+ "previewParams": {
+ "role": "Product Manager",
+ "type": "behavioral",
+ "difficulty": "medium",
+ "duration": 5,
+ "source": "curator-v1"
+ },
+ "contextNarrative": "User needs confidence before real interviews.",
+ "subtasks": ["Confirm role", "Select round type", "Generate preview", "Complete practice", "Review feedback"],
+ "signals": ["interview.confidence", "communication_clarity", "role_alignment"],
+ "timebox": "15 minutes"
+}
+```
+
+### Roleplay preview task
+```json
+{
+ "title": "Practice your [SCENARIO] conversation",
+ "subtitle": "[COUNTERPART] · [OUTCOME]",
+ "serviceId": "roleplay-service",
+ "serviceName": "Roleplay service",
+ "cta": "Open roleplay preview",
+ "route": "/agents/roleplay/preview",
+ "previewParams": {
+ "scenario": "salary_negotiation",
+ "counterpart": "recruiter",
+ "outcome": "agree_on_range",
+ "source": "curator-v1"
+ },
+ "contextNarrative": "User needs confidence before high-stakes conversation.",
+ "subtasks": ["Capture scenario", "Identify counterpart", "Define desired outcome", "Generate preview", "Practice", "Save script"],
+ "signals": ["negotiation_confidence", "communication_readiness", "salary_clarity"],
+ "timebox": "15 minutes"
+}
+```
+
+### Agent-Social Branding task
+```json
+{
+ "title": "Draft your [TOPIC] post with agent",
+ "subtitle": "Agent suggests topic, drafts copy, optimizes timing",
+ "serviceId": "agent-social-branding",
+ "serviceName": "Agent-Social Branding",
+ "cta": "Draft post with agent",
+ "route": "/agents/social-branding",
+ "previewParams": {
+ "topic": "project_insight",
+ "platform": "linkedin",
+ "tone": "professional",
+ "source": "curator-v1"
+ },
+ "contextNarrative": "User has proof but no visibility. Agent builds inbound.",
+ "subtasks": ["Agent analyzes work", "Drafts post with hook", "User edits", "Agent schedules", "Track engagement"],
+ "signals": ["visibility", "profile_strength", "public_proof", "inbound_readiness"],
+ "timebox": "10 minutes"
+}
+```
+
+### Job Matchmaking task
+```json
+{
+ "title": "Match with [N] aligned roles",
+ "subtitle": "Resume ready. Find high-fit opportunities.",
+ "serviceId": "job-matchmaking",
+ "serviceName": "Job Matchmaking",
+ "cta": "See matched roles",
+ "route": "/agents/matchmaking",
+ "previewParams": {
+ "searchType": "current_skills",
+ "limit": 5,
+ "source": "curator-v1"
+ },
+ "contextNarrative": "User has improved readiness. Time for active pipeline.",
+ "subtasks": ["Analyze resume vs roles", "Score top matches", "Surface warm intros", "Pre-draft applications", "Track pipeline"],
+ "signals": ["opportunity_awareness", "pipeline_health", "proactive_search", "application_readiness"],
+ "timebox": "10 minutes"
+}
+```
+
+### Courses task
+```json
+{
+ "title": "Complete your [SKILL] skill module",
+ "subtitle": "[DURATION]-minute module · Progress tracked to Q Score",
+ "serviceId": "courses",
+ "serviceName": "Courses",
+ "cta": "Start skill module",
+ "route": "/agents/courses",
+ "previewParams": {
+ "skill": "sql_analytics",
+ "module": "fundamentals",
+ "duration": 15,
+ "source": "curator-v1"
+ },
+ "contextNarrative": "User has skill gap between current proof and target role.",
+ "subtasks": ["Identify skill gap", "Suggest targeted module", "Complete module", "Track in Q Score", "Apply in next task"],
+ "signals": ["skill_gap_closure", "course_completion", "readiness_improvement"],
+ "timebox": "15 minutes"
+}
+```
+
+---
+
+*End of examples document.*
diff --git a/curator-call-grip-sheet.md b/curator-call-grip-sheet.md
new file mode 100644
index 0000000..0559f75
--- /dev/null
+++ b/curator-call-grip-sheet.md
@@ -0,0 +1,107 @@
+# GrowQR Curator — Call Grip Sheet
+
+## 1. What the Curator Is (30-second pitch)
+
+The Curator is a **deterministic growth operating system enriched by AI** — not a generic chatbot, not a hardcoded checklist.
+
+- It classifies every user into an ICP, generates a 30/60/90-day plan, and serves **3 daily actions** (Measurement, Proof, Practice).
+- Every task routes into a real service (Interview, Roleplay, Resume, Q Score, etc.) with a **one-click preview CTA** — no blank setup screens.
+- AI only enriches copy and context; the backbone (ICP, stage routing, handoff logic) is deterministic and reproducible.
+
+---
+
+## 2. ICP Taxonomy (6 Segments)
+
+| ICP | Trigger Signals | Default Plan | Sprint Theme |
+|-----|-----------------|--------------|--------------|
+| **Student / Recent Grad** | 0-2 yrs, before graduation, projects/skills | 30 days | "First Role Readiness" |
+| **Intern** | Currently interning, return-offer focus | 30 days | "Intern-to-Offer" |
+| **Fresher / Early Pro** | 0-5 yrs, no callbacks / weak interviews | 30 days | "Callback-to-Offer" |
+| **Experienced Pro** | 5+ yrs, leadership/pay/scope goals | 60 days | "Leadership Readiness" |
+| **Freelancer / Gig** | Clients, pricing, pipeline, trust | 60 days | "Client Pipeline" |
+| **Founder / Solopreneur** | MVP, traction, fundraising, hiring | 90 days | "Founder Visibility & Validation" |
+
+**Classifier is deterministic** — weighted scoring from onboarding answers, with AI only explaining the pick.
+
+---
+
+## 3. The 3-Column Daily Formula
+
+Every day the user sees **exactly 3 tasks**:
+
+| Column | Purpose | Typical Services |
+|--------|---------|------------------|
+| **Measurement** | Know where you stand | Q Score, Pathways, analytics |
+| **Proof** | Create/improve evidence | Resume, Agent-Social Branding, portfolio |
+| **Practice** | Rehearse real-world behavior | Interview, Roleplay, Courses, Matchmaking |
+
+**Why this matters:** Users understand their day in one sentence — *"Today we measure the gap, improve one proof point, and practice the highest-leverage next move."*
+
+---
+
+## 4. The 7 Core Formulas
+
+1. **ICP Classification** — weighted scoring from onboarding signals; AI explains, never overrides unless confidence is low.
+2. **Plan Length** — 30 days for urgent career users, 60 for experienced/freelancer, 90 for founders.
+3. **Stage Curriculum** — 6 stages (Baseline → Proof Build → Gap Fix → Practice Loop → Market Action → Conversion/Scale), mapped deterministically to days.
+4. **Daily Task Selection** — pick one per column based on stage, blockers, service readiness, and Q Score impact.
+5. **Service Priority Score** — `0.25*stageFit + 0.20*blockerFit + 0.15*goalFit + 0.15*serviceReadiness + 0.10*freshness + 0.10*qScoreImpact + 0.05*effortFit`
+6. **Minimum Context Handoff** — max 1 clarifying question before showing a CTA card with pre-filled preview params.
+7. **Streak Completion** — meaningful events (interview completed, resume updated, course passed), not just page views.
+
+---
+
+## 5. Hard Rules (Non-Negotiable)
+
+- **Never ask generic "What do you want to do?"** — first turn is service-aware and context-aware.
+- **Max 1 clarifying question** before offering a default preview.
+- **CTA card must persist** after subtask completion; never hide it.
+- **No internal routes in chat text** — `/agents/...` URLs never appear in `reply`.
+- **Deterministic routes only** — AI cannot invent routes, service IDs, or completion events.
+- **Courses only when skill gap detected** — not when proof or practice is the blocker.
+- **Matchmaking is active** — scoring, drafting, tracking, nudging — not passive browsing.
+- **Social branding is agent-driven** — agent suggests topic, drafts copy, optimizes timing; user edits and approves.
+- **ICP tone guardrails** — no student advice to experienced leaders; no job tasks to freelancers unless they want jobs.
+
+---
+
+## 6. Service Handoff Defaults
+
+| Service | Min Context | Default Preview Params | CTA Copy |
+|---------|-------------|------------------------|----------|
+| **Interview** | role or round | `type=behavioral`, `difficulty=medium`, `duration=5` | "Open interview preview" |
+| **Roleplay** | scenario or counterpart | `source=curator-v1` | "Open roleplay preview" |
+| **Resume** | target role or proof item | — | "Open resume workspace" |
+| **Agent-Social Branding** | topic or permission to suggest | `platform=linkedin`, `tone=professional` | "Draft post with agent" |
+| **Job Matchmaking** | target role + search intent | `limit=5` | "See matched roles" |
+| **Courses** | skill gap | `duration=15` | "Start skill module" |
+| **Pathways** | direction question | — | "Review pathway" |
+| **Q Score** | driver or baseline intent | — | "Review Q Score" |
+
+---
+
+## 7. The Operating Equation
+
+```
+User State + ICP Formula + Stage Curriculum + Service Readiness + Recent Signals
+= Deterministic Daily Plan
+
+Deterministic Daily Plan + AI Context Enrichment + Guardrails
+= Personalized Curator Experience
+```
+
+---
+
+## 8. What "Finished" Looks Like (Acceptance)
+
+- Backend: `/v1/curator/chat` returns `handoff.actionRoute` with `/agents/interview/preview` (or roleplay/resume/etc.)
+- Frontend: CTA card renders with eyebrow, title, subtitle, and service-specific button
+- Product: every task connects back to the user's stated goal; 30/60-day plan framing is visible
+- Streak: user clicks suggestion → chat → ≤2 turns → preview CTA → preview page → start service
+- Prompt: externalized to `prompts/curator/daily-retention-system.md`, hot-reloadable without redeploy
+
+---
+
+## 9. One-Liner for the Call
+
+> "The Curator is not a chatbot. It's a deterministic growth OS that knows who the user is, what stage they're in, and which 3 actions move them today. AI makes it feel personal; the formula makes it reliable. Every task ends in a service preview — not a blank setup screen — so users execute, not just plan."
diff --git a/curator-formulaic-workflow-model.md b/curator-formulaic-workflow-model.md
new file mode 100644
index 0000000..622abb7
--- /dev/null
+++ b/curator-formulaic-workflow-model.md
@@ -0,0 +1,1419 @@
+# GrowQR Curator Formulaic Workflow Model
+
+Date: 2026-06-16
+Status: Internal design draft
+References:
+- `docs/curator-30day-examples-by-icp.md`
+- `docs/curator-icp-comprehensive-playbook.md`
+- `docs/curator-icp-task-subtask-playbook.md`
+
+---
+
+## 1. Executive summary
+
+GrowQR Curator should not be a purely generative coach and should not be a hard-coded checklist. The correct model is a **deterministic growth operating system** enriched by AI.
+
+The deterministic layer answers:
+
+1. Who is this user?
+2. What plan length should they receive: 30, 60, or 90 days?
+3. Which stage are they in today?
+4. Which three daily actions should appear?
+5. Which service owns each action?
+6. What completion events count toward streak progress?
+7. What route should the CTA open?
+
+The AI layer answers:
+
+1. What should this task be called for this user?
+2. What first question should the curator ask?
+3. How should the task explain business value?
+4. What context should be injected into a service preview?
+5. How should the plan adapt after feedback, missed days, or new signals?
+6. Which proof, practice, or gap is most important this week?
+
+The product experience should feel like:
+
+> GrowQR knows my goal, gives me three useful daily moves, explains why each matters, opens the right service preview, and adjusts my plan based on what I actually do.
+
+The operating formula is:
+
+```txt
+User State + ICP Formula + Stage Curriculum + Service Readiness + Recent Signals
+= Deterministic Daily Plan
+
+Deterministic Daily Plan + AI Context Enrichment + Guardrails
+= Personalized Curator Experience
+```
+
+---
+
+## 2. Design principles
+
+### 2.1 Deterministic where trust matters
+
+Use deterministic logic for anything that affects product reliability:
+
+- ICP classification
+- plan length
+- day/stage progression
+- service routing
+- CTA route creation
+- streak completion criteria
+- task category balancing
+- fallback tasks
+- Q Score signal mapping
+- limits and safety gates
+
+Users should never lose the CTA card because an LLM chose the wrong status. Interview and roleplay handoffs must deterministically produce preview routes when minimum context exists.
+
+### 2.2 AI-enriched where usefulness matters
+
+Use AI for context and language:
+
+- task title variants
+- personal explanation
+- first-turn chat prompt
+- summary after user answer
+- role/scenario extraction
+- proof gap inference
+- nudge wording
+- re-plan explanation
+- service-specific setup text
+
+AI should make deterministic plans feel personal, not decide the whole system from scratch.
+
+### 2.3 Three daily actions, always legible
+
+Every daily plan should present three actions:
+
+| Column | Product meaning | Primary services |
+|---|---|---|
+| **Measurement** | Know where the user stands and what changed | Q Score, Pathways, analytics |
+| **Proof** | Create or improve evidence that others can trust | Resume, Agent-Social Branding, portfolio/profile |
+| **Practice** | Rehearse or execute market-facing behavior | Interview, Roleplay, Courses, Job Matchmaking |
+
+The user should understand the day in one sentence:
+
+> Today we measure the gap, improve one proof point, and practice the highest-leverage next move.
+
+### 2.4 Services are execution modules, not menu items
+
+The curator decides when to route users into services:
+
+- Q Score measures and selects gaps.
+- Resume packages evidence.
+- Interview builds answer confidence.
+- Roleplay prepares high-stakes conversations.
+- Agent-Social Branding turns proof into visibility.
+- Job Matchmaking turns readiness into opportunities.
+- Courses close skill gaps only when a skill gap is the blocker.
+- Pathways clarifies direction when direction is uncertain.
+
+### 2.5 Streak is the behavioral engine
+
+A streak is not a vanity counter. It is the adherence mechanism for the growth plan.
+
+A streak day is valid when the user completes at least one meaningful action from the day, and ideally completes all three actions across Measurement, Proof, and Practice.
+
+---
+
+## 3. Core vocabulary
+
+### 3.1 User state
+
+```ts
+type UserState = {
+ userId: string;
+ icp: ICP;
+ segmentConfidence: number;
+ planLengthDays: 30 | 60 | 90;
+ sprintTheme: string;
+ primaryGoal: string;
+ blockers: string[];
+ urgency: "low" | "medium" | "high";
+ experienceBand: "student" | "0-2" | "2-5" | "5-10" | "10+" | "founder" | "freelancer";
+ activeSearch: boolean;
+ currentRole?: string;
+ targetRole?: string;
+ targetIndustry?: string;
+ desiredOutcome?: string;
+ qScore: QScoreState;
+ serviceState: ServiceState;
+ planState: PlanState;
+ recentSignals: RecentSignal[];
+};
+```
+
+### 3.2 ICP
+
+```ts
+type ICP =
+ | "student_recent_grad"
+ | "intern"
+ | "fresher_early_professional"
+ | "experienced_professional"
+ | "freelancer_gig_worker"
+ | "founder_solopreneur";
+```
+
+### 3.3 Plan stage
+
+```ts
+type PlanStage =
+ | "baseline"
+ | "gap_fix"
+ | "proof_build"
+ | "practice_loop"
+ | "market_action"
+ | "conversion"
+ | "scale";
+```
+
+### 3.4 Daily task
+
+```ts
+type CuratorTask = {
+ id: string;
+ date: string;
+ dayIndex: number;
+ planLengthDays: 30 | 60 | 90;
+ column: "measurement" | "proof" | "practice";
+ stage: PlanStage;
+ icp: ICP;
+ title: string;
+ subtitle: string;
+ businessReason: string;
+ serviceId: ServiceId;
+ serviceName: string;
+ cta: string;
+ route: string;
+ previewParams?: Record;
+ contextNarrative: string;
+ subtasks: string[];
+ signals: string[];
+ completionEvents: string[];
+ timeboxMinutes: 5 | 10 | 15 | 20 | 30;
+ priorityScore: number;
+ generatedBy: "deterministic" | "ai_enriched" | "hybrid";
+};
+```
+
+### 3.5 Service IDs
+
+```ts
+type ServiceId =
+ | "qscore-service"
+ | "resume-service"
+ | "interview-service"
+ | "roleplay-service"
+ | "agent-social-branding"
+ | "job-matchmaking"
+ | "courses"
+ | "pathways";
+```
+
+---
+
+## 4. The formulaic operating model
+
+## 4.1 Full pipeline
+
+```txt
+1. Ingest onboarding
+2. Classify ICP
+3. Select plan length and sprint theme
+4. Create baseline user state
+5. Generate deterministic curriculum skeleton
+6. Score available services by stage, blockers, and readiness
+7. Select daily Measurement / Proof / Practice tasks
+8. AI-enrich task copy and chat behavior
+9. Render streak / weekly progress UI
+10. User clicks a task
+11. Curator chat captures minimum context
+12. Deterministic handoff creates CTA route
+13. Service completion emits event
+14. Q Score and plan state update
+15. Next day/week is adjusted
+```
+
+This pipeline should be event-driven and repeatable. AI can enrich but must not make the core plan non-reproducible.
+
+---
+
+## 4.2 Formula 1: ICP classification
+
+### Deterministic classifier
+
+Use onboarding answers to assign an ICP and confidence.
+
+```txt
+ICP = argmax(score_icp(user_onboarding_signals))
+```
+
+Example scoring:
+
+```txt
+score_student =
+ 3 * is_student_or_recent_grad
++ 2 * is_0_to_2_years
++ 2 * has_before_graduation_or_first_job_goal
++ 1 * mentions_projects_or_skills
+
+score_intern =
+ 3 * has_internship_state
++ 2 * mentions_return_offer_or_manager
++ 1 * is_student_or_0_to_2
+
+score_fresher =
+ 2 * has_0_to_5_years
++ 2 * active_job_search
++ 2 * blocker_no_callbacks_or_interviews
++ 1 * target_higher_pay_or_switch
+
+score_experienced =
+ 3 * has_5_plus_years
++ 2 * mentions_leadership_scope_or_pay
++ 2 * employed_or_between_senior_roles
+
+score_freelancer =
+ 4 * selected_gig_or_freelance
++ 2 * mentions_clients_pricing_pipeline
++ 1 * has_service_area
+
+score_founder =
+ 4 * selected_founder_or_startup
++ 2 * mentions_customers_funding_team_mvp
++ 1 * has_90_day_priority
+```
+
+If two ICPs are close, use a secondary rule:
+
+- Founder beats freelancer if they mention MVP, funding, customers, cofounder.
+- Freelancer beats fresher if they mention clients, pricing, packages, retainers.
+- Intern beats student if they are currently in an internship.
+- Experienced beats fresher if experience is 5+ years even if job hunting.
+
+### AI enrichment
+
+AI may summarize the classification:
+
+> “You look like an Early Professional in an active search. Your first sprint should focus on callback recovery and interview conversion.”
+
+AI must not override the deterministic ICP unless confidence is below a threshold and a human/user confirmation is needed.
+
+---
+
+## 4.3 Formula 2: plan length selection
+
+Plan length should be deterministic by urgency and goal complexity.
+
+```txt
+planLength =
+ if urgency == high and goal is immediate job/client/interview -> 30
+ else if goal requires transition, offer conversion, or pipeline building -> 60
+ else if founder/freelancer scaling or career pivot -> 90
+```
+
+Recommended defaults:
+
+| ICP | Default | When 30 days | When 60 days | When 90 days |
+|---|---:|---|---|---|
+| Student | 30 | first role readiness | role clarity + skill gaps | long graduation runway |
+| Intern | 30 | return offer window | external backup needed | long internship + conversion |
+| Fresher | 30 | no callbacks/interview soon | active search but weak assets | career switch |
+| Experienced | 60 | specific interview/promotion | leadership readiness | executive transition |
+| Freelancer | 60 | first client sprint | pipeline + pricing | income scale / retainers |
+| Founder | 90 | urgent customer/fundraise push | validation + visibility | MVP/customers/fundraise cycle |
+
+---
+
+## 4.4 Formula 3: stage curriculum
+
+Every plan maps days into stages. The stage controls task selection.
+
+### 30-day curriculum
+
+| Days | Stage | Goal |
+|---:|---|---|
+| 1-3 | baseline | Understand score, goal, assets, and blocker |
+| 4-7 | proof_build | Create first useful proof and first practice session |
+| 8-14 | gap_fix | Fix the highest-confidence gap |
+| 15-21 | practice_loop | Repeat interviews/roleplays and public proof |
+| 22-29 | market_action | Apply, reach out, negotiate, pitch, publish |
+| 30 | conversion | Review, claim streak, set next sprint |
+
+### 60-day curriculum
+
+| Days | Stage | Goal |
+|---:|---|---|
+| 1-7 | baseline | Diagnose and choose target |
+| 8-14 | proof_build | Build core proof assets |
+| 15-28 | gap_fix | Close proof, skill, or confidence gaps |
+| 29-42 | practice_loop | Repeated service loops with feedback |
+| 43-55 | market_action | Applications, clients, customers, interviews, outreach |
+| 56-60 | conversion | Negotiate, decide, plan next sprint |
+
+### 90-day curriculum
+
+| Days | Stage | Goal |
+|---:|---|---|
+| 1-10 | baseline | Diagnose and choose focus |
+| 11-25 | proof_build | Build assets and public credibility |
+| 26-45 | gap_fix | Course modules, proof gaps, role clarity |
+| 46-65 | practice_loop | Interview, roleplay, pitch, sales, leadership practice |
+| 66-82 | market_action | Pipeline, investor/customer/client/job execution |
+| 83-90 | scale | Conversion review, next system, cadence continuation |
+
+---
+
+## 4.5 Formula 4: daily three-task selection
+
+Each day chooses one task per column.
+
+```txt
+DailyPlan(day) = [
+ selectMeasurementTask(userState, stage, day),
+ selectProofTask(userState, stage, day),
+ selectPracticeTask(userState, stage, day)
+]
+```
+
+### Column rules
+
+#### Measurement
+
+Purpose: identify, compare, or update readiness.
+
+Typical services:
+
+- Q Score
+- Pathways
+- Analytics
+
+Examples:
+
+- Q Score baseline
+- weakest driver review
+- confidence pulse
+- application pipeline health
+- leadership readiness check
+- founder validation score
+
+#### Proof
+
+Purpose: create evidence that others can evaluate.
+
+Typical services:
+
+- Resume
+- Agent-Social Branding
+- portfolio/profile
+
+Examples:
+
+- resume bullet rewrite
+- proof bank entry
+- LinkedIn headline
+- founder update post
+- freelance case study
+- leadership impact story
+
+#### Practice
+
+Purpose: rehearse or execute real-world behavior.
+
+Typical services:
+
+- Interview
+- Roleplay
+- Courses
+- Job Matchmaking
+
+Examples:
+
+- interview preview
+- salary roleplay
+- customer discovery roleplay
+- course module
+- matched roles shortlist
+- recruiter warm intro
+
+---
+
+## 4.6 Formula 5: service priority score
+
+Each candidate task receives a priority score.
+
+```txt
+priorityScore =
+ 0.25 * stageFit
++ 0.20 * blockerFit
++ 0.15 * goalFit
++ 0.15 * serviceReadiness
++ 0.10 * freshness
++ 0.10 * qScoreImpact
++ 0.05 * effortFit
+```
+
+Where:
+
+| Factor | Meaning |
+|---|---|
+| `stageFit` | Does this task belong in the current plan stage? |
+| `blockerFit` | Does it address the user's stated blocker? |
+| `goalFit` | Does it move the user's desired outcome? |
+| `serviceReadiness` | Can the service produce useful output today? |
+| `freshness` | Has the user not done this recently? |
+| `qScoreImpact` | Will it improve a weak Q Score driver? |
+| `effortFit` | Can the user complete it in available time? |
+
+### Service readiness examples
+
+```txt
+Resume readiness = has_resume_uploaded OR can_upload_now
+Interview readiness = has_target_role OR can_collect_role_in_one_question
+Roleplay readiness = has_scenario OR can_collect_scenario_in_one_question
+Courses readiness = has_skill_gap_detected
+Matchmaking readiness = has_target_role AND resume_or_profile_exists
+Social Branding readiness = has_proof_point OR can_suggest_topic
+Pathways readiness = goal_unclear OR transition_signal_present
+Q Score readiness = always true
+```
+
+---
+
+## 4.7 Formula 6: minimum context for handoff
+
+The curator chat should not block on perfect data. Each service has a minimum context threshold.
+
+```txt
+handoffReady = hasMinimumContext(serviceId, messages, task, userState)
+```
+
+### Minimum context table
+
+| Service | Minimum context | If missing, ask one question | Handoff route |
+|---|---|---|---|
+| Interview | role OR round OR target company/job | “What role or interview round should I prepare?” | `/agents/interview/preview` |
+| Roleplay | scenario OR counterpart OR desired outcome | “Who are you speaking with and what outcome do you want?” | `/agents/roleplay/preview` or valid preview equivalent |
+| Resume | target role OR proof item | “What role or section should this resume work target?” | `/agents/resume` |
+| Agent-Social Branding | topic OR proof point OR permission to suggest | “Should I suggest a topic based on your recent work?” | `/agents/social-branding` |
+| Job Matchmaking | target role/client/customer + location/type if available | “Should I match current-skill roles or stretch roles?” | `/agents/matchmaking` |
+| Courses | skill gap | “Which gap feels most urgent?” | `/agents/courses` |
+| Pathways | direction question | “Are you validating a target, exploring alternatives, or planning a switch?” | `/agents/pathways` or current pathways route |
+| Q Score | driver or baseline intent | “Which driver do you want to inspect?” | `/agents/qscore` or current Q Score route |
+
+### Handoff invariant
+
+If `handoffReady === true`, the response must include a CTA card. It is not optional.
+
+```txt
+service-backed task + enough context => CTA card
+```
+
+---
+
+## 4.8 Formula 7: streak completion
+
+Streak completion should be based on meaningful events, not button clicks alone.
+
+```txt
+streakDayComplete =
+ completedMeasurement OR completedProof OR completedPractice
+```
+
+Recommended stronger model:
+
+```txt
+dayQualityScore =
+ 1.0 * completedMeasurement
++ 1.2 * completedProof
++ 1.5 * completedPractice
++ 0.5 * completedAllThreeBonus
+
+streakDayComplete = dayQualityScore >= 1.0
+highQualityDay = dayQualityScore >= 2.5
+perfectDay = dayQualityScore >= 4.2
+```
+
+### Completion event examples
+
+| Service | Completion events |
+|---|---|
+| Q Score | `qscore.baseline_completed`, `qscore.driver_reviewed`, `qscore.signal_projected` |
+| Resume | `resume.uploaded`, `resume.parsed`, `resume.updated`, `resume.exported` |
+| Interview | `interview.configured`, `interview.completed`, `interview.review_completed` |
+| Roleplay | `roleplay.configured`, `roleplay.completed`, `roleplay.review_completed` |
+| Agent-Social Branding | `branding.draft_created`, `branding.post_approved`, `branding.post_published` |
+| Job Matchmaking | `matchmaking.roles_scored`, `matchmaking.application_tracked`, `matchmaking.intro_requested` |
+| Courses | `course.started`, `course.completed`, `course.quiz_passed` |
+| Pathways | `pathways.report_reviewed`, `pathways.direction_saved` |
+
+---
+
+## 5. Deterministic + AI agent pipeline
+
+## 5.1 Pipeline roles
+
+Think of the curator system as a team of agents with strict responsibility boundaries.
+
+| Layer | Owner | Deterministic or AI? | Responsibility |
+|---|---|---|---|
+| Signal Ingestor | backend | deterministic | Normalize onboarding, events, service completions |
+| ICP Classifier | backend | deterministic + AI explanation | Select segment and sprint theme |
+| Curriculum Planner | backend | deterministic | Generate day/stage skeleton |
+| Task Selector | backend | deterministic | Pick Measurement/Proof/Practice tasks |
+| Context Enricher | AI | AI | Personalize title, business reason, first question |
+| Handoff Builder | backend | deterministic | Build route, preview params, CTA card |
+| Curator Chat | AI with guards | hybrid | Ask one question, summarize, capture context |
+| Status Evaluator | backend + small AI | hybrid | Determine needs context vs handoff ready |
+| Event Projector | backend | deterministic | Update Q Score, plan, streak, analytics |
+| Replanner | backend + AI explanation | hybrid | Adjust next week based on behavior |
+
+---
+
+## 5.2 Agent pipeline sequence
+
+### Step 1: Normalize user signals
+
+Input:
+
+- onboarding answers
+- resume state
+- Q Score baseline
+- active missions
+- service events
+- recent conversations
+- missed days
+- completed tasks
+
+Output:
+
+```json
+{
+ "icp": "fresher_early_professional",
+ "primaryGoal": "land a higher-paying product role",
+ "blockers": ["no callbacks", "interview confidence"],
+ "targetRole": "Product Manager",
+ "urgency": "high",
+ "activeSearch": true
+}
+```
+
+### Step 2: Generate deterministic skeleton
+
+```json
+{
+ "planLengthDays": 30,
+ "theme": "Callback-to-Offer Sprint",
+ "days": [
+ { "day": 1, "stage": "baseline", "columns": ["measurement", "proof", "practice"] },
+ { "day": 2, "stage": "proof_build", "columns": ["measurement", "proof", "practice"] }
+ ]
+}
+```
+
+### Step 3: Select task candidates
+
+For each column, choose candidates from the service task library.
+
+```txt
+candidateTasks = serviceTaskLibrary.filter(
+ icp matches AND stage matches AND service readiness true
+)
+```
+
+### Step 4: Rank task candidates
+
+Use the service priority score.
+
+```txt
+selectedTask = max(candidateTasks, priorityScore)
+```
+
+### Step 5: AI-enrich selected tasks
+
+AI receives only structured context and a narrow prompt.
+
+AI may produce:
+
+- title
+- subtitle
+- first-turn question
+- business reason
+- context narrative
+- suggested preview params
+
+AI may not produce:
+
+- arbitrary route
+- arbitrary service ID
+- completion event names
+- hidden system policy
+- unbounded task lists
+
+### Step 6: Build deterministic CTA/handoff
+
+Backend constructs the route.
+
+Example:
+
+```ts
+buildInterviewPreviewRoute({
+ role: extractedRole ?? userState.targetRole ?? "Target role",
+ type: extractedType ?? "behavioral",
+ difficulty: selectedDifficulty ?? "medium",
+ duration: 5,
+ source: "curator-v1",
+ curatorTaskId: task.id
+});
+```
+
+### Step 7: Emit and project events
+
+Every meaningful step emits an event:
+
+- `curator.task.started`
+- `curator.subtask.captured`
+- `curator.service_handoff.prepared`
+- service completion event
+- Q Score projection event
+- streak update event
+
+---
+
+## 6. ICP-specific formula maps
+
+## 6.1 Student / Recent Grad
+
+### Deterministic pattern
+
+```txt
+Goal: first credible role readiness
+Primary blocker: low proof density + low interview confidence
+Plan default: 30 days
+Column bias: Measurement 25%, Proof 40%, Practice 35%
+```
+
+### Service sequence
+
+| Stage | Measurement | Proof | Practice |
+|---|---|---|---|
+| Baseline | Q Score, Pathways | Resume upload, project inventory | easy interview preview |
+| Gap fix | skill gap check | proof bank, LinkedIn headline | tell-me-about-yourself |
+| Practice loop | confidence pulse | STAR stories | interview and recruiter roleplay |
+| Market action | application quality | tailored resume, public proof | matchmaking, referral ask |
+
+### AI enrichment guidance
+
+Use encouraging but practical language. Avoid over-professional jargon. Convert projects/coursework into evidence.
+
+---
+
+## 6.2 Intern
+
+### Deterministic pattern
+
+```txt
+Goal: convert internship into offer or strong backup
+Primary blocker: impact communication + manager conversation
+Plan default: 30 days
+Column bias: Measurement 25%, Proof 35%, Practice 40%
+```
+
+### Service sequence
+
+| Stage | Measurement | Proof | Practice |
+|---|---|---|---|
+| Baseline | return-offer readiness | internship project proof | manager check-in roleplay |
+| Gap fix | requirement map | weekly update, impact log | feedback request roleplay |
+| Practice loop | mock feedback | project narrative | return-offer interview |
+| Market action | backup opportunity score | final resume bullets | full-time conversion roleplay |
+
+### AI enrichment guidance
+
+Make tasks workplace-safe. Encourage anonymized proof for social posts. Prioritize manager communication.
+
+---
+
+## 6.3 Fresher / Early Professional
+
+### Deterministic pattern
+
+```txt
+Goal: callbacks, interview conversion, compensation confidence
+Primary blocker: weak positioning or poor conversion
+Plan default: 30 days
+Column bias: Measurement 30%, Proof 35%, Practice 35%
+```
+
+### Service sequence
+
+| Stage | Measurement | Proof | Practice |
+|---|---|---|---|
+| Baseline | callback diagnosis | resume upload/audit | target role selection |
+| Gap fix | JD fit score | headline, STAR story | recruiter screen roleplay |
+| Practice loop | interview weakness review | proof bank | interview preview, salary roleplay |
+| Market action | pipeline health | tailored resume | matchmaking, follow-ups |
+
+### AI enrichment guidance
+
+Be direct. Tie each task to callbacks, interviews, or salary. Avoid vague career advice.
+
+---
+
+## 6.4 Experienced Professional
+
+### Deterministic pattern
+
+```txt
+Goal: leadership readiness, scope, compensation, senior opportunities
+Primary blocker: translating execution into leadership proof
+Plan default: 60 days
+Column bias: Measurement 25%, Proof 40%, Practice 35%
+```
+
+### Service sequence
+
+| Stage | Measurement | Proof | Practice |
+|---|---|---|---|
+| Baseline | leadership Q Score | import profile, leadership inventory | senior role target |
+| Gap fix | leadership gap map | scope/impact bullets | stakeholder interview |
+| Practice loop | executive presence check | authority post, case study | promotion/comp roleplay |
+| Market action | senior role fit score | leadership resume version | executive matchmaking |
+
+### AI enrichment guidance
+
+Use senior language: scope, outcomes, teams, influence, strategy. Avoid entry-level advice.
+
+---
+
+## 6.5 Freelancer / Gig Worker
+
+### Deterministic pattern
+
+```txt
+Goal: clients, pricing confidence, pipeline, trust
+Primary blocker: positioning + lead generation + pricing
+Plan default: 60 days
+Column bias: Measurement 25%, Proof 35%, Practice 40%
+```
+
+### Service sequence
+
+| Stage | Measurement | Proof | Practice |
+|---|---|---|---|
+| Baseline | trust/pipeline score | offer definition, portfolio import | niche selection |
+| Gap fix | pricing confidence | case study, profile CTA | discovery call roleplay |
+| Practice loop | pipeline review | inbound authority post | pricing objection roleplay |
+| Market action | lead score | proposal template | outreach, client matchmaking |
+
+### AI enrichment guidance
+
+Translate skills into offers. Prioritize revenue and client trust. Avoid job-search framing unless user wants employment.
+
+---
+
+## 6.6 Founder / Solopreneur
+
+### Deterministic pattern
+
+```txt
+Goal: validation, customers, funding, visibility, hiring
+Primary blocker: clarity + proof + conversations
+Plan default: 90 days
+Column bias: Measurement 30%, Proof 30%, Practice 40%
+```
+
+### Service sequence
+
+| Stage | Measurement | Proof | Practice |
+|---|---|---|---|
+| Baseline | 90-day priority, founder Q Score | profile/site/deck import | riskiest assumption |
+| Gap fix | validation score | one-liner, build-in-public | customer discovery roleplay |
+| Practice loop | customer synthesis | deck/site proof | investor/customer/hiring roleplay |
+| Market action | pipeline review | founder update | customer outreach, investor intros |
+
+### AI enrichment guidance
+
+Use founder language: assumptions, validation, customers, traction, proof, narrative. Avoid generic job advice.
+
+---
+
+## 7. Behavioral rules for the streak chat
+
+## 7.1 First-turn behavior
+
+The first assistant turn should be service-aware and context-aware.
+
+Bad:
+
+> What should I capture next?
+
+Good:
+
+> This is your interview practice step for today. What role or round should I prepare the preview for?
+
+### First-turn formula
+
+```txt
+FirstTurn =
+ why_this_task_today
++ one_missing_context_question
++ no extra explanation
+```
+
+Example:
+
+```txt
+This is your practice step for today's readiness sprint. What role or interview round should I prepare the preview for?
+```
+
+---
+
+## 7.2 Capture behavior
+
+When the user answers, the curator should:
+
+1. Extract minimum context.
+2. Save a concise summary.
+3. Decide whether context is enough.
+4. If enough, prepare CTA.
+5. If not enough, ask exactly one follow-up.
+
+### Capture state machine
+
+```txt
+opened -> asked_first_question -> user_answered -> evaluate_context
+
+evaluate_context -> needs_more_context -> ask_one_follow_up
+
+evaluate_context -> handoff_ready -> show_cta_card
+
+evaluate_context -> captured_no_service -> mark_subtask_done
+```
+
+---
+
+## 7.3 CTA persistence rule
+
+CTA cards must persist after completion.
+
+```txt
+If a service handoff was prepared once, keep the CTA visible until user leaves the chat or opens the service.
+```
+
+The completed footer can say:
+
+> Context saved. Your preview is ready.
+
+But it must also keep the button:
+
+> Open interview preview
+
+---
+
+## 7.4 Service handoff copy
+
+### Interview
+
+```txt
+Got it. I prepared a mock interview preview for [ROLE].
+[TYPE] · [DURATION] min · [DIFFICULTY] pressure.
+Open the preview to start or adjust the setup.
+```
+
+CTA:
+
+```txt
+Eyebrow: INTERVIEW PREVIEW
+Title: Your mock interview is ready
+Subtitle: [ROLE] · [TYPE] · [DURATION] min · [DIFFICULTY]
+Button: Open interview preview
+```
+
+### Roleplay
+
+```txt
+Got it. I prepared a roleplay preview for [SCENARIO] with [COUNTERPART].
+Open the preview to practice or adjust details.
+```
+
+CTA:
+
+```txt
+Eyebrow: ROLEPLAY PREVIEW
+Title: Your conversation practice is ready
+Subtitle: [SCENARIO] · [COUNTERPART] · [OUTCOME]
+Button: Open roleplay preview
+```
+
+---
+
+## 8. Task generation architecture
+
+## 8.1 Deterministic task template
+
+```json
+{
+ "templateId": "interview.behavioral.preview.v1",
+ "icps": ["student_recent_grad", "fresher_early_professional", "intern"],
+ "stages": ["proof_build", "practice_loop"],
+ "column": "practice",
+ "serviceId": "interview-service",
+ "defaultTitle": "Prepare your [ROLE] interview preview",
+ "defaultSubtitle": "Behavioral round · 5 minutes · Medium pressure",
+ "requiredContext": ["role"],
+ "optionalContext": ["company", "difficulty", "interviewType"],
+ "defaultPreviewParams": {
+ "type": "behavioral",
+ "difficulty": "medium",
+ "duration": 5,
+ "source": "curator-v1"
+ },
+ "completionEvents": ["interview.configured", "interview.completed", "interview.review_completed"],
+ "signals": ["interview.confidence", "communication_clarity", "role_alignment"],
+ "timeboxMinutes": 15
+}
+```
+
+## 8.2 AI enrichment prompt contract
+
+The AI receives:
+
+```json
+{
+ "userState": {
+ "icp": "fresher_early_professional",
+ "targetRole": "Product Manager",
+ "blockers": ["interviews not converting"],
+ "qScoreWeakDrivers": ["communication_clarity"]
+ },
+ "taskTemplate": {
+ "serviceId": "interview-service",
+ "column": "practice",
+ "stage": "practice_loop"
+ },
+ "recentSignals": [
+ "resume.updated",
+ "interview.review_completed"
+ ]
+}
+```
+
+The AI returns:
+
+```json
+{
+ "title": "Practice your Product Manager behavioral round",
+ "subtitle": "5 minutes · Medium pressure · focused on clearer stories",
+ "businessReason": "Your resume proof is improving, but interview conversion depends on making your stories sharper under pressure.",
+ "firstTurnQuestion": "Which PM round should I prepare: behavioral, product sense, or execution?",
+ "contextNarrative": "Early professional targeting PM roles with communication clarity as the current weak driver."
+}
+```
+
+AI must not return arbitrary routes. Routes are built by backend.
+
+---
+
+## 9. Replanning formula
+
+Plans should adjust weekly, not chaotically every message.
+
+```txt
+weeklyReplanScore =
+ missedDaysPenalty
++ repeatedWeakSignalWeight
++ completedServiceMomentum
++ explicitUserGoalChange
++ upcomingDeadlineWeight
+```
+
+If score crosses threshold, re-plan the next 7 days.
+
+### Replan triggers
+
+| Trigger | Behavior |
+|---|---|
+| User misses 3 days | Reduce effort, preserve same goal |
+| User completes interview but low score | Add interview replay + proof refinement |
+| User updates resume and gets callbacks | Increase interview/roleplay tasks |
+| User has skill gap | Insert Courses into Practice column |
+| User says goal changed | Re-run ICP/goal selection and regenerate plan |
+| User has upcoming interview/client/investor call | Prioritize roleplay/interview for next 48 hours |
+
+### Replan explanation
+
+AI can explain the change:
+
+> You completed the resume fixes, so this week shifts from proof-building to interview conversion. Expect more interview previews and recruiter roleplays.
+
+---
+
+## 10. Department-by-department implications
+
+## 10.1 Product
+
+Product owns:
+
+- ICP definitions
+- plan length defaults
+- service taxonomy
+- CTA copy
+- streak completion rules
+- task visibility and UX priorities
+
+Product should review:
+
+- whether every task has a business reason
+- whether users understand why the task matters
+- whether the three daily tasks feel manageable
+
+## 10.2 Engineering
+
+Engineering owns:
+
+- deterministic planning engine
+- task templates
+- route builders
+- event schema
+- prompt loading
+- AI guardrails
+- service integration
+
+Engineering should ensure:
+
+- AI cannot break CTA routing
+- prompts are externalized
+- fallback tasks exist
+- service completion events update plan state
+- preview routes are valid
+
+## 10.3 AI / Data Science
+
+AI/Data owns:
+
+- enrichment prompts
+- extraction models
+- scoring weights
+- plan effectiveness measurement
+- Q Score signal impact analysis
+- experimentation design
+
+AI/Data should evaluate:
+
+- task completion rate
+- CTA click-through
+- service completion rate
+- Q Score movement
+- retention by plan stage
+- whether AI recommendations outperform deterministic fallback
+
+## 10.4 Design
+
+Design owns:
+
+- streak progress clarity
+- daily task card hierarchy
+- chat flow readability
+- CTA persistence
+- service handoff card patterns
+- progress states
+
+Design should ensure:
+
+- daily plan feels like coaching, not a checklist
+- CTA cards are obvious
+- completion state does not hide next action
+- Measurement/Proof/Practice are understandable
+
+## 10.5 Growth / Marketing
+
+Growth owns:
+
+- ICP language
+- plan promise
+- activation moments
+- habit loops
+- notification copy
+- proof of value within first 3 days
+
+Growth should track:
+
+- first task completion
+- first service handoff
+- day 3 retention
+- day 7 streak
+- invite/referral moments after visible progress
+
+## 10.6 Customer Success / Ops
+
+CS/Ops owns:
+
+- failure mode review
+- user confusion patterns
+- escalation rules
+- manual overrides if needed
+- support-safe explanations
+
+CS should know:
+
+- why a task appeared
+- what service owns it
+- what event marks it complete
+- what fallback should happen if service fails
+
+---
+
+## 11. Metrics and experiments
+
+## 11.1 Primary metrics
+
+| Metric | Meaning |
+|---|---|
+| Day 1 task completion | onboarding-to-action activation |
+| CTA card render rate | handoff reliability |
+| CTA click-through | action relevance |
+| Service completion rate | service usefulness |
+| Streak day 3/7/14 retention | habit formation |
+| Q Score movement | value evidence |
+| Replan acceptance | trust in adaptive plan |
+
+## 11.2 Quality metrics
+
+| Metric | Meaning |
+|---|---|
+| repeated-question rate | curator coherence problem |
+| no-CTA-after-service-chat rate | handoff bug |
+| route failure rate | integration bug |
+| task abandonment after first question | bad prompt or too much friction |
+| user edits to AI-generated social copy | brand voice accuracy |
+| matchmaking save/apply rate | opportunity fit quality |
+
+## 11.3 Experiment ideas
+
+1. Deterministic-only task titles vs AI-enriched titles.
+2. Three daily tasks vs one recommended task + two optional tasks.
+3. 30-day default vs adaptive 30/60/90 explanation.
+4. CTA card immediately after one answer vs after two answers.
+5. Courses inserted only on detected gap vs fixed weekly course cadence.
+6. Social branding task in Week 1 vs Week 2.
+
+---
+
+## 12. Failure modes and guardrails
+
+## 12.1 Failure: AI asks endless questions
+
+Guardrail:
+
+```txt
+Maximum one missing-context follow-up before offering a default preview.
+```
+
+Example:
+
+If user says “PM interview,” do not ask company, seniority, round, duration, and difficulty. Use defaults and show preview.
+
+## 12.2 Failure: CTA route missing
+
+Guardrail:
+
+```txt
+Service-backed task + handoff_ready must build deterministic route.
+```
+
+If preview params are incomplete, use defaults.
+
+## 12.3 Failure: wrong ICP tone
+
+Guardrail:
+
+Use ICP-specific vocabulary and forbidden patterns.
+
+- Do not give student tasks to experienced leaders.
+- Do not give job tasks to freelancers unless they want jobs.
+- Do not give founder tasks generic career advice.
+
+## 12.4 Failure: courses overused
+
+Guardrail:
+
+Courses only appear when:
+
+```txt
+skill_gap_detected == true
+AND proof_gap is not the primary blocker
+AND practice_gap is not more urgent
+```
+
+## 12.5 Failure: social branding feels manual
+
+Guardrail:
+
+Agent-Social Branding tasks must be agent-driven:
+
+- suggest topic
+- draft copy
+- optimize timing
+- preserve voice
+- user approves
+
+## 12.6 Failure: matchmaking becomes passive browsing
+
+Guardrail:
+
+Job Matchmaking tasks must include active execution:
+
+- score matches
+- draft application/outreach
+- track status
+- suggest warm intro
+- nudge follow-up
+
+---
+
+## 13. Example end-to-end workflow
+
+### User
+
+Early professional, 2 years experience, actively applying for PM roles, no callbacks, weak interview confidence.
+
+### Deterministic classification
+
+```json
+{
+ "icp": "fresher_early_professional",
+ "planLengthDays": 30,
+ "theme": "Callback-to-Offer Sprint",
+ "primaryGoal": "Land PM role",
+ "blockers": ["no callbacks", "interview confidence"]
+}
+```
+
+### Day 2 generated plan
+
+| Column | Task | Service |
+|---|---|---|
+| Measurement | Check PM resume fit against one JD | Q Score / Resume |
+| Proof | Rewrite headline for PM callbacks | Agent-Social Branding / Resume |
+| Practice | Prepare PM behavioral interview preview | Interview |
+
+### User clicks Practice
+
+Curator:
+
+> This is your practice step for today's callback sprint. What PM round should I prepare: behavioral, product sense, or execution?
+
+User:
+
+> Behavioral.
+
+Curator:
+
+> Got it. I prepared a PM behavioral interview preview. 5 minutes, medium pressure. Open the preview to start or adjust the setup.
+
+CTA:
+
+```json
+{
+ "eyebrow": "INTERVIEW PREVIEW",
+ "title": "Your PM mock interview is ready",
+ "subtitle": "Product Manager · Behavioral · 5 min · Medium",
+ "button": "Open interview preview",
+ "route": "/agents/interview/preview?role=Product+Manager&type=behavioral&difficulty=medium&duration=5&source=curator-v1"
+}
+```
+
+### Completion
+
+Interview service emits:
+
+```txt
+interview.review_completed
+```
+
+Projector updates:
+
+- streak day complete
+- Q Score interview confidence signal
+- next day Practice task may become interview replay or recruiter roleplay depending on review
+
+---
+
+## 14. Implementation checklist
+
+### Backend
+
+- [ ] Encode ICP classifier.
+- [ ] Encode plan length selector.
+- [ ] Encode 30/60/90 stage maps.
+- [ ] Build service task template registry.
+- [ ] Build daily Measurement/Proof/Practice selector.
+- [ ] Build deterministic route builders for all services.
+- [ ] Externalize prompts into markdown/txt files.
+- [ ] Add AI enrichment contract with strict schema.
+- [ ] Add handoff readiness evaluator with deterministic overrides.
+- [ ] Add event-to-streak projection rules.
+- [ ] Add weekly replanning job or on-demand replan action.
+
+### Frontend
+
+- [ ] Show three daily tasks as Measurement / Proof / Practice.
+- [ ] Keep CTA cards visible after subtask completion.
+- [ ] Display service-specific handoff cards.
+- [ ] Show why-this-matters copy.
+- [ ] Use clear loading state while curator prepares handoff.
+- [ ] Make completed state point to the next service action.
+- [ ] Support 30/60/90 plan progress visualization.
+
+### Data / Analytics
+
+- [ ] Track task render, click, chat start, handoff prepared, CTA click, service completion.
+- [ ] Track repeated-question rate.
+- [ ] Track route failure rate.
+- [ ] Track Q Score movement by service and plan stage.
+- [ ] Compare deterministic fallback vs AI-enriched copy.
+
+---
+
+## 15. Product decision defaults
+
+These defaults should hold until changed by product leadership.
+
+| Decision | Default |
+|---|---|
+| Daily suggestions | 3 tasks: Measurement, Proof, Practice |
+| Plan length | 30 for urgent career users, 60 for experienced/freelancer, 90 for founders |
+| Interview handoff | Preview route, not setup route |
+| Roleplay handoff | Preview route or valid preview-equivalent route |
+| Courses | Only when skill gap detected |
+| Social branding | Agent-driven, user approves before publish |
+| Matchmaking | Active scoring/tracking, not passive browsing |
+| CTA persistence | CTA card remains after completion |
+| AI authority | Enrich copy/context, do not own routing or completion logic |
+| Streak completion | Meaningful event or captured service handoff, not page view alone |
+
+---
+
+## 16. The simplest mental model
+
+For every user, every day, GrowQR should ask:
+
+1. **Measurement**: What do we now know about readiness?
+2. **Proof**: What evidence did we improve?
+3. **Practice**: What real-world behavior did we rehearse or execute?
+
+For every task, the system should ask:
+
+1. Why this user?
+2. Why today?
+3. Which service owns it?
+4. What is the minimum question before handoff?
+5. What CTA should appear?
+6. What event marks progress?
+7. What should change in tomorrow's plan?
+
+That is the deterministic formula. AI makes it feel human, specific, and useful.
diff --git a/curator-icp-comprehensive-playbook.md b/curator-icp-comprehensive-playbook.md
new file mode 100644
index 0000000..bbaf61f
--- /dev/null
+++ b/curator-icp-comprehensive-playbook.md
@@ -0,0 +1,2312 @@
+# GrowQR Curator Comprehensive ICP Playbook
+
+Date: 2026-06-15
+Purpose: Define complete 30/60-day streak tasks, weekly progress suggestions, and service handoffs for all 8 core GrowQR services across every ICP.
+
+---
+
+## 1. Product framing
+
+GrowQR is not a collection of tools. It is a **productized growth plan** that turns onboarding signals into a coached, daily execution path.
+
+> Onboarding identifies your current situation, goals, blockers, and urgency. GrowQR turns that into a 30/60-day instructed growth plan. Streaks and weekly progress are the daily execution layer. Every task creates evidence, improves confidence, raises your Q Score, or moves you toward real opportunities.
+
+### Core services
+
+| Service | What it does | When the curator routes here |
+|---|---|---|
+| **Q Score** | Readiness measurement and progress ledger | Baseline, weekly check-in, gap identification, before/after comparison |
+| **Resume** | Proof packaging, role-fit evidence, credibility artifact | Every time the user needs to package or improve evidence |
+| **Interview** | Confidence, articulation, offer-readiness practice | Before real interviews, after resume gaps are fixed, for confidence building |
+| **Roleplay** | High-stakes conversation practice: recruiter, manager, client, investor, negotiation | Before any high-stakes conversation the user is nervous about |
+| **Agent-Social Branding** | Agent-driven visibility engine: content suggestions, posting cadence, engagement optimization, brand voice consistency, platform-specific formatting | When proof exists but no one sees it; when inbound is needed; when credibility is the blocker |
+| **Job Matchmaking** | Active job matching, application tracking, recruiter warm intros, opportunity scoring | When the user is in active search or wants to convert readiness into real roles |
+| **Courses** | Skill gap learning paths, targeted modules, progress tracked back to Q Score | When the user's readiness gap is a skill gap, not a proof or practice gap |
+| **Pathways** | Career direction, multi-year trajectory, archetype-fit analysis | When the user doesn't know where to aim, or wants to validate their chosen direction |
+
+The curator must always answer: **why this task today, what service it unlocks, and what the user gets after completing it.**
+
+---
+
+## 2. ICP taxonomy from onboarding
+
+### A. Individual career users
+
+Onboarding signals:
+- **Intent**: better job, feel stuck, grow here, know where I stand.
+- **Current state**: actively hunting, employed but ready to move, between jobs, student/recent grad, exploring.
+- **Blockers**: don't know where to start, no callbacks, interviews not converting, weak profile, stuck in role, not enough time.
+- **Goal**: land exciting role, higher pay, switch field, build skills, leadership, start own thing.
+- **Work area**: tech/product/data, design/creative, sales/growth/partnerships, leadership/strategy, student, other.
+- **Experience**: 0-2, 2-5, 5-10, 10+ years.
+- **Pace**: 1-month sprint, 3-month steady climb, flexible long game.
+
+Primary sub-segments:
+
+1. Students / recent grads
+2. Interns
+3. Freshers / early professionals under 5 years
+4. Experienced professionals above 5 years
+
+### B. Gig / freelance users
+
+Onboarding signals:
+- **Current state**: just starting, few clients, steady income, ready to scale, side hustle.
+- **Blockers**: client pipeline, pricing, standing out, online trust, income consistency, referrals.
+- **Goal**: consistent pipeline, higher rates, work I love, personal brand, full-time freelancing, recurring income.
+- **Service area**: design, tech/dev, writing/content, consulting/strategy, coaching/training, marketing/social.
+- **Experience**: new, under 1 year, 1-3 years, 3+ years.
+- **First milestone**: first client, double income, full-time, Rs 1L/month, waitlist.
+
+### C. Founder / solopreneur users
+
+Onboarding signals:
+- **Stage**: idea, MVP, traction, scaling, pre-revenue.
+- **Blockers**: team, funding, visibility, customers, proving model, burn.
+- **Goal**: hire key people, raise, authority, first 100 customers, validate idea, cofounder.
+- **Space**: B2B SaaS, consumer, marketplace, deeptech/hardware, services/agency, other.
+- **Founder type**: first-time, built before, serial, operator turned founder.
+- **90-day priority**: ship MVP, close customers, hire, raise pre-seed, build presence.
+
+---
+
+## 3. Curator task design rules
+
+Every curator task must have:
+
+1. **Business reason**: why this helps the user's stated outcome.
+2. **Service owner**: Q Score, Resume, Interview, Roleplay, Agent-Social Branding, Job Matchmaking, Courses, Pathways.
+3. **One focused action**: no broad advice.
+4. **Subtasks**: 2-4 small steps max.
+5. **Handoff**: if service-backed, the user lands directly in a useful preview/workspace state.
+6. **Signal**: what will improve in Q Score or user readiness ledger.
+7. **Timebox**: preferably 5, 10, 15, or 20 minutes.
+
+Good task title examples:
+- "Prepare your first PM interview preview"
+- "Turn your project into a resume proof point"
+- "Practice your salary ask with a recruiter"
+- "Package your freelance offer"
+- "Draft your founder credibility post"
+- "Match with 5 aligned roles this week"
+- "Complete your DSA skill gap module"
+- "Publish your weekly authority post"
+
+Bad task title examples:
+- "Improve career"
+- "Use interview service"
+- "Complete profile"
+- "Do task 1"
+
+---
+
+## 4. Universal 30/60-day plan structure
+
+### Days 1-7: Baseline and first proof
+
+Goal: establish Q Score baseline, identify target, create first useful artifact, begin content/social presence.
+
+- Complete Q Score baseline.
+- Upload/import resume, LinkedIn, portfolio, GitHub, website, pitch deck.
+- Pick one target outcome.
+- Generate first service preview: interview, roleplay, resume audit, or profile audit.
+- Complete one confidence-building practice.
+- Set up Agent-Social Branding cadence (first post plan).
+- Map first matchmaking opportunities or job targets.
+
+### Days 8-14: Fix obvious gaps
+
+Goal: remove blockers surfaced by onboarding.
+
+- Rewrite weak headline / summary / resume bullets.
+- Practice top interview or conversation blocker.
+- Build proof bank: projects, client wins, traction, metrics.
+- Create first public credibility artifact.
+- Complete first skill gap course module.
+- Match with 3-5 relevant opportunities.
+
+### Days 15-30: Repetition, market-facing action, and conversion
+
+Goal: repeat practice, publish/apply/reach out, collect feedback, match and convert.
+
+- 2-4 mock interviews or roleplays.
+- 5 targeted applications / leads / warm intros.
+- 1-2 social posts per week (Agent-Social Branding).
+- One profile/resume iteration using results.
+- One Q Score check-in.
+- 1-2 course completions.
+- Review matchmaking pipeline and act on top matches.
+
+### Days 31-60: Conversion loop
+
+Goal: convert readiness into outcomes.
+
+- Interview-to-offer loop.
+- Salary/client/investor conversation practice.
+- Stronger market proof: case study, portfolio, founder update.
+- Active job matchmaking or client pipeline.
+- Course completion tied to Q Score improvement.
+- Weekly social branding cadence producing inbound.
+
+---
+
+## 5. Service definitions and handoff behavior
+
+### 5.1 Q Score
+
+- **Purpose**: Measure readiness. Baseline on day 1. Weekly pulse.
+- **Curator task examples**: Baseline, gap review, driver selection, proof update.
+- **Handoff**: Q Score review page with specific driver focus.
+- **CTA**: "Review Q Score" | "See readiness gaps" | "Pick next driver"
+
+### 5.2 Resume
+
+- **Purpose**: Package proof. Role-fit evidence. Credibility artifact.
+- **Curator task examples**: Upload, audit, rewrite bullets, add project, LinkedIn sync.
+- **Handoff**: Resume workspace with target role pre-selected.
+- **CTA**: "Open resume workspace" | "Review profile audit" | "Rewrite this proof point"
+
+### 5.3 Interview
+
+- **Purpose**: Build confidence. Practice answers. Get feedback. Convert to offers.
+- **Curator task examples**: First mock, behavioral, role-related, warm-up, STAR practice.
+- **Handoff**: Interview preview page with role/type/difficulty pre-filled.
+- **CTA**: "Open interview preview" | "Preview your mock interview" | "Start from preview"
+
+### 5.4 Roleplay
+
+- **Purpose**: Rehearse high-stakes conversations before they happen.
+- **Curator task examples**: Recruiter screen, salary negotiation, manager check-in, client call, investor intro.
+- **Handoff**: Roleplay preview with scenario/counterpart/outcome pre-filled.
+- **CTA**: "Open roleplay preview" | "Practice this conversation" | "Preview roleplay scenario"
+
+### 5.5 Agent-Social Branding
+
+- **Purpose**: Automated, agent-driven content creation and posting strategy. Not just "write a post" — the agent suggests topics, drafts copy, optimizes timing, maintains brand voice, and tracks engagement.
+- **Curator task examples**: First authority post, weekly cadence setup, founder build-in-public, freelance case study post, recruiter-facing profile polish, engagement optimization.
+- **Handoff**: Social branding workspace with suggested post pre-drafted, or profile editor with AI suggestions.
+- **CTA**: "Draft post with agent" | "Open branding workspace" | "Publish this week"
+- **Note**: This is distinct from generic "Social/Branding" — it is agent-driven, not manual. The agent proposes, the user edits and approves.
+
+### 5.6 Job Matchmaking
+
+- **Purpose**: Active matching, not passive browsing. The agent scores fit, surfaces warm intros, tracks applications, and nudges on stale opportunities.
+- **Curator task examples**: Match with aligned roles, warm intro to recruiter, application tracker review, follow-up nudge, opportunity score check.
+- **Handoff**: Matchmaking dashboard with pre-scored opportunities, or recruiter message pre-drafted.
+- **CTA**: "See matched roles" | "Warm intro to recruiter" | "Track application" | "Score this opportunity"
+- **Note**: Distinct from Pathways. Pathways = direction. Matchmaking = execution. Matchmaking only appears when the user is in active search or wants to convert readiness.
+
+### 5.7 Courses
+
+- **Purpose**: Close skill gaps with targeted modules. Progress tracked back to Q Score.
+- **Curator task examples**: Complete DSA module, product analytics course, design system basics, sales discovery training, leadership communication module.
+- **Handoff**: Course player with specific module pre-selected, or course catalog filtered by skill gap.
+- **CTA**: "Start skill module" | "Continue course" | "Close this gap"
+- **Note**: Only routed when the curator identifies a skill gap, not a proof gap or practice gap.
+
+### 5.8 Pathways
+
+- **Purpose**: Direction and trajectory. Multi-year archetype-fit analysis. Career compass.
+- **Curator task examples**: Target role selection, trajectory analysis, archetype validation, 12-week plan generation.
+- **Handoff**: Pathways report or direction dashboard.
+- **CTA**: "Review pathway" | "Update direction" | "See trajectory"
+
+---
+
+## 6. ICP playbooks
+
+## 6.1 Students / recent grads
+
+### Main jobs-to-be-done
+- Figure out what roles to target.
+- Build a credible identity before graduation.
+- Turn coursework/projects into proof.
+- Practice interviews before real rounds.
+- Build confidence and a daily habit.
+- Start social presence (even small).
+- Close skill gaps before they matter.
+
+### Suggested 30-day plan theme
+**"First Role Readiness Sprint"**
+
+### Example tasks
+
+#### Task: Pick your first target role
+**Service**: Pathways / Q Score
+**Business reason**: students often lack direction; role clarity makes resume and interview prep specific.
+
+Subtasks:
+1. Choose 1-2 role families.
+2. Capture current strengths: coursework, projects, internships, societies.
+3. Compare requirements against your current proof.
+4. Save target role into GrowQR plan.
+
+Curator first question:
+> Which role family do you want to prepare for first: engineering, product, data, design, growth, or something else?
+
+CTA: "Review pathway" | "Update Q Score baseline"
+Signals: goal clarity, role alignment, readiness baseline
+
+#### Task: Turn one project into resume proof
+**Service**: Resume
+**Business reason**: students usually have weak experience sections but strong hidden project evidence.
+
+Subtasks:
+1. Pick one project/coursework/internship.
+2. Capture problem, action, result.
+3. Convert it into 2 resume bullets.
+4. Save to resume workspace.
+
+Curator first question:
+> Which project should we package today, and what did it achieve?
+
+CTA: "Open resume workspace"
+Signals: resume evidence, proof density, project articulation
+
+#### Task: Prepare first mock interview preview
+**Service**: Interview
+**Business reason**: early practice reduces anxiety and creates interview readiness signals.
+
+Subtasks:
+1. Pick role and round type.
+2. Choose difficulty: easy/medium.
+3. Generate interview preview.
+4. Complete the practice and review feedback.
+
+Curator first question:
+> What role should I prepare this mock interview for?
+
+Default preview: type=behavioral, difficulty=medium, duration=5, source=curator-v1
+CTA: "Open interview preview"
+Signals: interview confidence, communication clarity, Q Score practice signal
+
+#### Task: Practice "Tell me about yourself"
+**Service**: Interview or Roleplay
+**Business reason**: this is the most reusable first-round answer.
+
+Subtasks:
+1. Capture target role.
+2. Capture current student background.
+3. Practice 60-second pitch.
+4. Save improved version.
+
+Curator first question:
+> What role should your intro be tailored toward?
+
+CTA: "Open interview preview" or "Open roleplay preview"
+Signals: self-pitch quality, confidence, communication readiness
+
+#### Task: Build your first credibility post with Agent-Social Branding
+**Service**: Agent-Social Branding
+**Business reason**: public proof can increase recruiter trust even before full-time experience. The agent suggests the topic and drafts the copy.
+
+Subtasks:
+1. Pick a project or learning insight (or let agent suggest).
+2. Agent drafts LinkedIn post with hook and CTA.
+3. User edits and approves.
+4. Agent schedules optimal posting time.
+
+Curator first question:
+> Which project or lesson should this post highlight? Or should I suggest one?
+
+CTA: "Draft post with agent" | "Open branding workspace"
+Signals: visibility, public proof, profile strength
+
+#### Task: Complete your first skill gap module
+**Service**: Courses
+**Business reason**: students often have coursework gaps in practical skills (e.g., DSA, SQL, Figma, analytics).
+
+Subtasks:
+1. Identify weakest skill vs target role.
+2. Agent suggests 1-2 modules.
+3. Complete 15-minute module.
+4. Track progress in Q Score.
+
+Curator first question:
+> Which skill feels most shaky for your target role: coding, analytics, design, communication, or something else?
+
+CTA: "Start skill module"
+Signals: skill gap closure, course completion, readiness improvement
+
+---
+
+## 6.2 Interns
+
+### Main jobs-to-be-done
+- Convert internship into full-time offer.
+- Communicate impact to manager/team.
+- Build workplace confidence.
+- Prepare for return offer or external interviews.
+
+### Suggested 30-day plan theme
+**"Intern-to-Offer Sprint"**
+
+### Example tasks
+
+#### Task: Capture your internship impact
+**Service**: Resume / Q Score
+
+Subtasks:
+1. List current internship project.
+2. Capture metric or visible outcome.
+3. Convert into resume bullet.
+4. Add to proof bank.
+
+Curator first question:
+> What project are you working on in your internship, and what changed because of your work?
+
+CTA: "Open resume workspace"
+Signals: proof density, experience clarity
+
+#### Task: Practice manager check-in
+**Service**: Roleplay
+
+Subtasks:
+1. Define desired outcome: feedback, extension, full-time offer, better project.
+2. Capture manager context.
+3. Generate roleplay preview.
+4. Practice the check-in.
+
+Curator first question:
+> What do you want from the manager conversation: feedback, return offer, clearer expectations, or project scope?
+
+CTA: "Open roleplay preview"
+Signals: workplace communication, confidence, initiative
+
+#### Task: Prepare return-offer interview
+**Service**: Interview
+
+Subtasks:
+1. Choose role/function.
+2. Capture internship project context.
+3. Generate preview.
+4. Complete one mock round.
+
+Curator first question:
+> Which return-offer role or team should this interview prepare you for?
+
+CTA: "Open interview preview"
+Signals: interview readiness, internship conversion readiness
+
+#### Task: Draft weekly internship update with Agent-Social Branding
+**Service**: Agent-Social Branding
+
+Subtasks:
+1. Agent captures what shipped this week from user context.
+2. Drafts LinkedIn learning post (anonymized).
+3. User edits and approves.
+4. Agent schedules post.
+
+Curator first question:
+> What did you learn or ship this week that would build credibility without revealing confidential details?
+
+CTA: "Draft post with agent"
+Signals: workplace visibility, learning proof, public credibility
+
+#### Task: Match with return-offer opportunities
+**Service**: Job Matchmaking
+
+Subtasks:
+1. Map intern's target role and company.
+2. Score open return-offer or full-time roles.
+3. Surface warm intros or recruiter contacts.
+4. Track application pipeline.
+
+Curator first question:
+> Are you focused on a return offer at your current company, or also exploring external full-time roles?
+
+CTA: "See matched roles" | "Warm intro to recruiter"
+Signals: opportunity awareness, pipeline health, proactive search
+
+---
+
+## 6.3 Freshers / early professionals under 5 years
+
+### Main jobs-to-be-done
+- Get callbacks.
+- Convert interviews.
+- Switch role/field or grow compensation.
+- Build confidence and sharper positioning.
+- Close skill gaps that block callbacks.
+
+### Suggested 30-day plan themes
+- **"Callback Recovery Sprint"** for no callbacks.
+- **"Interview Conversion Sprint"** for interviews not converting.
+- **"Role Switch Sprint"** for career transition.
+
+### Example tasks
+
+#### Task: Diagnose why callbacks are low
+**Service**: Resume / Q Score / Job Matchmaking
+
+Subtasks:
+1. Select target role.
+2. Upload or open resume.
+3. Run resume role-fit audit.
+4. Match with 5 sample roles to see fit score.
+5. Save top 3 fixes.
+
+Curator first question:
+> What role are you applying for most often right now?
+
+CTA: "Open resume audit" | "See matched roles"
+Signals: resume fit, role alignment, application readiness
+
+#### Task: Rewrite your headline and summary
+**Service**: Agent-Social Branding / Resume
+
+Subtasks:
+1. Capture current role and target role.
+2. Capture 2 strongest proof points.
+3. Agent generates headline options with recruiter optimization.
+4. Save best version.
+
+Curator first question:
+> What target role should your profile headline sell you for?
+
+CTA: "Draft profile update with agent"
+Signals: profile clarity, recruiter discoverability
+
+#### Task: Generate interview preview for target role
+**Service**: Interview
+
+Subtasks:
+1. Confirm role.
+2. Pick round type.
+3. Generate preview.
+4. Practice and review feedback.
+
+Curator first question:
+> Which role and interview round should I prepare for you today?
+
+CTA: "Open interview preview"
+Signals: interview practice, answer structure, confidence
+
+#### Task: Practice salary expectation answer
+**Service**: Roleplay
+
+Subtasks:
+1. Capture current/target salary or range.
+2. Capture role and recruiter context.
+3. Generate negotiation roleplay preview.
+4. Practice answer.
+
+Curator first question:
+> What salary conversation do you need to prepare for: recruiter screen, offer call, or manager discussion?
+
+CTA: "Open roleplay preview"
+Signals: negotiation confidence, communication readiness
+
+#### Task: Close your top skill gap
+**Service**: Courses
+
+Subtasks:
+1. Identify gap from Q Score or resume audit.
+2. Agent suggests targeted module.
+3. Complete module.
+4. Update Q Score with completion.
+
+Curator first question:
+> What's the biggest skill gap between your resume and your target role's requirements?
+
+CTA: "Start skill module"
+Signals: skill gap closure, course completion, readiness improvement
+
+#### Task: Match with high-fit roles
+**Service**: Job Matchmaking
+
+Subtasks:
+1. Analyze resume and target role.
+2. Score 10 open roles for fit.
+3. Surface top 3 matches with explanation.
+4. Pre-draft application messages.
+
+Curator first question:
+> Should I find roles that match your current profile, or roles that match where you're trying to grow?
+
+CTA: "See matched roles" | "Warm intro to recruiter"
+Signals: opportunity awareness, pipeline health, proactive search
+
+---
+
+## 6.4 Experienced professionals above 5 years
+
+### Main jobs-to-be-done
+- Move into leadership or higher compensation.
+- Communicate strategic impact.
+- Prepare for senior interviews.
+- Negotiate scope, salary, title, or authority.
+- Build authority presence, not just visibility.
+
+### Suggested plan theme
+**"Leadership Readiness Sprint"**
+
+### Example tasks
+
+#### Task: Translate execution into leadership impact
+**Service**: Resume
+
+Subtasks:
+1. Pick one major project.
+2. Capture business outcome, team size, scope.
+3. Rewrite into leadership bullet.
+4. Save to resume.
+
+Curator first question:
+> Which project best proves you can lead beyond individual execution?
+
+CTA: "Open resume workspace"
+Signals: leadership proof, seniority alignment
+
+#### Task: Practice senior stakeholder interview
+**Service**: Interview
+
+Subtasks:
+1. Choose target role.
+2. Pick round: leadership, strategy, behavioral.
+3. Generate preview.
+4. Complete mock.
+
+Curator first question:
+> What senior role or leadership round should this mock prepare you for?
+
+CTA: "Open interview preview"
+Signals: executive communication, senior interview readiness
+
+#### Task: Roleplay promotion conversation
+**Service**: Roleplay
+
+Subtasks:
+1. Capture desired title/scope.
+2. Capture manager/stakeholder context.
+3. Generate promotion conversation preview.
+4. Practice and refine ask.
+
+Curator first question:
+> What are you asking for: title change, salary increase, larger scope, or leadership opportunity?
+
+CTA: "Open roleplay preview"
+Signals: negotiation confidence, leadership communication
+
+#### Task: Build authority proof post with Agent-Social Branding
+**Service**: Agent-Social Branding
+
+Subtasks:
+1. Agent suggests strategic lesson from user's work.
+2. Adds one example from user's experience.
+3. Drafts concise, authority-building post.
+4. User edits and approves. Agent schedules.
+
+Curator first question:
+> What leadership lesson or strategic insight can you credibly talk about this week? Or should I suggest one?
+
+CTA: "Draft authority post with agent"
+Signals: market visibility, senior credibility
+
+#### Task: Match with senior/leadership roles
+**Service**: Job Matchmaking
+
+Subtasks:
+1. Map leadership experience.
+2. Score senior roles for fit.
+3. Surface executive recruiter intros.
+4. Track pipeline.
+
+Curator first question:
+> Are you looking for leadership roles at startups, established companies, or both?
+
+CTA: "See matched leadership roles"
+Signals: opportunity awareness, senior pipeline health
+
+---
+
+## 6.5 Freelancers and gig workers
+
+### Main jobs-to-be-done
+- Find clients consistently.
+- Stand out in crowded markets.
+- Price confidently.
+- Build trust online.
+- Move from inconsistent income to predictable pipeline.
+- Build inbound brand, not just outbound hustle.
+
+### Suggested 30-day plan themes
+- **"First Client Sprint"** for new freelancers.
+- **"Pipeline Stabilizer"** for feast/famine.
+- **"Premium Rate Sprint"** for pricing/positioning.
+
+### Example tasks
+
+#### Task: Package your offer clearly
+**Service**: Resume/Profile/Agent-Social Branding
+
+Subtasks:
+1. Define target client.
+2. Define painful problem solved.
+3. Package one clear offer.
+4. Save as profile headline/portfolio intro.
+5. Agent drafts offer post.
+
+Curator first question:
+> Who do you want to serve first, and what problem do you solve for them?
+
+CTA: "Draft offer with agent" | "Open profile workspace"
+Signals: positioning clarity, client readiness
+
+#### Task: Practice discovery call
+**Service**: Roleplay
+
+Subtasks:
+1. Choose client type.
+2. Define service offered.
+3. Generate discovery call preview.
+4. Practice handling objections.
+
+Curator first question:
+> What kind of client call should we rehearse: first discovery, pricing, scope, or renewal?
+
+CTA: "Open roleplay preview"
+Signals: sales confidence, client communication
+
+#### Task: Build pricing confidence script
+**Service**: Roleplay
+
+Subtasks:
+1. Capture current rate and target rate.
+2. Capture service value.
+3. Generate pricing conversation.
+4. Practice saying the rate clearly.
+
+Curator first question:
+> What service are you pricing, and what rate do you want to confidently quote?
+
+CTA: "Open roleplay preview"
+Signals: pricing confidence, sales readiness
+
+#### Task: Draft inbound authority post with Agent-Social Branding
+**Service**: Agent-Social Branding
+
+Subtasks:
+1. Agent analyzes client pain points.
+2. Drafts teaching post with clear CTA.
+3. User edits and approves.
+4. Agent schedules optimal time.
+
+Curator first question:
+> What client problem do you want to be known for solving? Or should I analyze your work and suggest one?
+
+CTA: "Draft authority post with agent"
+Signals: visibility, inbound readiness
+
+#### Task: Match with freelance opportunities
+**Service**: Job Matchmaking
+
+Subtasks:
+1. Map freelance skills and target clients.
+2. Score freelance/gig opportunities.
+3. Surface warm client intros.
+4. Track pipeline.
+
+Curator first question:
+> Are you looking for project-based work, retainer clients, or both?
+
+CTA: "See freelance opportunities"
+Signals: pipeline health, opportunity awareness
+
+#### Task: Complete client communication course
+**Service**: Courses
+
+Subtasks:
+1. Identify communication skill gap.
+2. Suggest targeted module.
+3. Complete module.
+4. Update Q Score.
+
+Curator first question:
+> Which client conversation feels hardest: discovery, pricing, scope negotiation, or closing?
+
+CTA: "Start communication module"
+Signals: skill gap closure, sales readiness
+
+---
+
+## 6.6 Solopreneurs and founders
+
+### Main jobs-to-be-done
+- Validate idea.
+- Build public credibility.
+- Find customers, investors, cofounders, or hires.
+- Practice high-stakes conversations.
+- Convert founder identity into trust.
+- Build founder brand, not just product marketing.
+
+### Suggested 30/60-day themes
+- **"MVP Validation Sprint"**
+- **"First 100 Customers Sprint"**
+- **"Founder Visibility Sprint"**
+- **"Fundraising Readiness Sprint"**
+- **"Cofounder / First Hire Sprint"**
+
+### Example tasks
+
+#### Task: Clarify founder one-liner
+**Service**: Agent-Social Branding / Q Score
+
+Subtasks:
+1. Capture product, audience, problem.
+2. Draft one-line positioning.
+3. Compare against current profile.
+4. Save as founder identity statement.
+5. Agent suggests profile updates.
+
+Curator first question:
+> In one sentence, what are you building, for whom, and what painful problem does it solve?
+
+CTA: "Draft founder profile with agent"
+Signals: positioning clarity, founder credibility
+
+#### Task: Practice customer discovery call
+**Service**: Roleplay
+
+Subtasks:
+1. Define customer segment.
+2. Define assumption to validate.
+3. Generate discovery roleplay preview.
+4. Practice asking non-leading questions.
+
+Curator first question:
+> Which customer segment should this discovery call simulate?
+
+CTA: "Open roleplay preview"
+Signals: customer discovery skill, validation readiness
+
+#### Task: Practice investor intro
+**Service**: Roleplay
+
+Subtasks:
+1. Capture stage: idea, MVP, traction, raise.
+2. Capture traction or proof.
+3. Generate investor conversation preview.
+4. Practice concise pitch and objection handling.
+
+Curator first question:
+> Are you pitching an idea, MVP, traction story, or active fundraise?
+
+CTA: "Open roleplay preview"
+Signals: fundraising readiness, founder communication
+
+#### Task: Draft build-in-public update with Agent-Social Branding
+**Service**: Agent-Social Branding
+
+Subtasks:
+1. Agent captures milestone or learning.
+2. Adds founder insight.
+3. Drafts post with appropriate transparency level.
+4. User edits and approves. Agent schedules.
+
+Curator first question:
+> What did you learn or ship this week that would build trust with customers, investors, or collaborators?
+
+CTA: "Draft founder update with agent"
+Signals: authority, visibility, credibility
+
+#### Task: Match with investors or cofounders
+**Service**: Job Matchmaking
+
+Subtasks:
+1. Map founder stage and needs.
+2. Score investor/cofounder matches.
+3. Surface warm intros.
+4. Track pipeline.
+
+Curator first question:
+> Are you looking for investors, cofounders, first hires, or customers right now?
+
+CTA: "See investor matches" | "See cofounder matches"
+Signals: opportunity awareness, pipeline health
+
+#### Task: Validate business model with course
+**Service**: Courses
+
+Subtasks:
+1. Identify business model knowledge gap.
+2. Suggest targeted module (e.g., SaaS metrics, pricing, go-to-market).
+3. Complete module.
+4. Update Q Score.
+
+Curator first question:
+> What's the riskiest part of your business model right now: pricing, customer acquisition, unit economics, or something else?
+
+CTA: "Start business model module"
+Signals: skill gap closure, model validation
+
+---
+
+## 7. Service-specific task libraries
+
+### 7.1 Interview task library
+
+Use for: students, interns, freshers, experienced professionals, founders hiring candidates.
+
+Task examples:
+1. First mock interview for target role.
+2. Behavioral round preview.
+3. Role-related technical/product/design/data round.
+4. Internship return-offer interview.
+5. Senior leadership interview.
+6. Career switch interview.
+7. Founder first-hire interview.
+8. STAR story practice.
+9. Weakness/strength answer practice.
+10. "Tell me about yourself" practice.
+
+Standard subtasks:
+1. Capture target role.
+2. Capture round type.
+3. Capture difficulty or pressure level.
+4. Generate preview.
+5. Complete session.
+6. Review feedback and update Q Score.
+
+Default preview params:
+- role: inferred from onboarding target, user answer, task context.
+- type: behavioral unless task says technical/role-related.
+- difficulty: medium.
+- duration: 5 minutes for streak tasks.
+- source: curator-v1 or daily-mission.
+
+Good CTA copy:
+- "Open interview preview"
+- "Preview your mock interview"
+- "Start from preview"
+
+### 7.2 Roleplay task library
+
+Use for: conversations where the user needs to speak with another person.
+
+Task examples:
+1. Recruiter screen practice.
+2. Salary expectation conversation.
+3. Offer negotiation.
+4. Manager promotion ask.
+5. Internship return-offer check-in.
+6. Client discovery call.
+7. Freelance pricing call.
+8. Scope creep conversation.
+9. Investor intro.
+10. Customer discovery.
+11. Cofounder alignment conversation.
+12. Difficult stakeholder conversation.
+
+Standard subtasks:
+1. Capture scenario.
+2. Capture counterpart.
+3. Capture desired outcome.
+4. Generate preview.
+5. Practice.
+6. Save best script or learning.
+
+Default preview params:
+- scenario: inferred from task and answer.
+- counterpart: recruiter, manager, client, investor, customer, cofounder, stakeholder.
+- outcome: offer, feedback, price agreement, intro, validation, next step.
+- source: curator-v1 or daily-mission.
+
+Good CTA copy:
+- "Open roleplay preview"
+- "Practice this conversation"
+- "Preview roleplay scenario"
+
+### 7.3 Resume/profile task library
+
+Task examples:
+1. Resume baseline upload.
+2. Role-fit audit.
+3. Rewrite top 3 bullets.
+4. Add project proof.
+5. Convert internship to experience.
+6. Convert freelance project to case study.
+7. Founder profile rewrite.
+8. Leadership impact rewrite.
+9. LinkedIn headline and summary.
+10. Portfolio/GitHub audit.
+
+Standard subtasks:
+1. Capture target role or audience.
+2. Import/upload artifact.
+3. Identify top gap.
+4. Generate rewrite.
+5. Save changes.
+
+Good CTA copy:
+- "Open resume workspace"
+- "Review profile audit"
+- "Rewrite this proof point"
+
+### 7.4 Q Score task library
+
+Task examples:
+1. Complete baseline Q Score.
+2. Review weakest readiness driver.
+3. Compare current vs target role.
+4. Check confidence after mock interview.
+5. Update proof ledger after resume change.
+6. Weekly progress check-in.
+7. Readiness gap summary.
+
+Standard subtasks:
+1. Confirm target.
+2. Review score breakdown.
+3. Pick one driver to improve.
+4. Route to service action.
+5. Recalculate signal.
+
+Good CTA copy:
+- "Review Q Score"
+- "See readiness gaps"
+- "Pick next driver"
+
+### 7.5 Agent-Social Branding task library
+
+Task examples:
+1. LinkedIn headline rewrite with agent.
+2. About section rewrite with agent.
+3. Weekly project/lesson post (agent-drafted).
+4. Founder build-in-public update (agent-drafted).
+5. Freelance case study post (agent-drafted).
+6. Student learning proof post (agent-drafted).
+7. Leadership insight post (agent-drafted).
+8. Recruiter-facing profile polish (agent-suggested).
+9. Investor-facing founder profile polish (agent-suggested).
+10. Engagement optimization review (agent-analyzed).
+11. Content cadence setup (agent-planned).
+12. Brand voice consistency check (agent-audited).
+
+Standard subtasks:
+1. Agent analyzes audience and proof.
+2. Agent drafts post with hook, body, CTA.
+3. User edits and approves.
+4. Agent schedules optimal posting time.
+5. Track engagement and update Q Score.
+
+Good CTA copy:
+- "Draft post with agent"
+- "Open branding workspace"
+- "Publish this week"
+- "Review brand voice"
+
+### 7.6 Job Matchmaking task library
+
+Task examples:
+1. Match with aligned roles.
+2. Warm intro to recruiter.
+3. Application tracker review.
+4. Follow-up nudge on stale application.
+5. Opportunity score check.
+6. Recruiter profile optimization.
+7. Interview pipeline tracking.
+8. Salary benchmark check.
+9. Referral request drafting.
+10. Rejection recovery strategy.
+
+Standard subtasks:
+1. Analyze resume and target role.
+2. Score open opportunities for fit.
+3. Surface top matches with explanation.
+4. Pre-draft application messages or warm intros.
+5. Track status and nudge on stale items.
+
+Good CTA copy:
+- "See matched roles"
+- "Warm intro to recruiter"
+- "Track application"
+- "Score this opportunity"
+
+### 7.7 Courses task library
+
+Task examples:
+1. Complete DSA skill gap module.
+2. Product analytics fundamentals.
+3. Design system basics.
+4. Sales discovery training.
+5. Leadership communication module.
+6. SQL/data analysis module.
+7. Figma/UI design module.
+8. Go-to-market strategy module.
+9. SaaS metrics and pricing module.
+10. Interview-specific skill module.
+
+Standard subtasks:
+1. Identify skill gap from Q Score or resume audit.
+2. Suggest targeted module.
+3. Complete module (15-30 min segments).
+4. Track progress in Q Score.
+5. Apply skill in next interview/resume task.
+
+Good CTA copy:
+- "Start skill module"
+- "Continue course"
+- "Close this gap"
+- "Apply in practice"
+
+### 7.8 Pathways task library
+
+Task examples:
+1. Target role selection.
+2. Trajectory analysis.
+3. Archetype validation.
+4. 12-week plan generation.
+5. Career direction review.
+6. Multi-year mapping.
+
+Standard subtasks:
+1. Capture current state.
+2. Capture desired outcome.
+3. Generate pathway analysis.
+4. Save direction.
+5. Route to matching service tasks.
+
+Good CTA copy:
+- "Review pathway"
+- "Update direction"
+- "See trajectory"
+
+---
+
+## 8. Three-suggestion weekly progress model
+
+When a user clicks the streak/week progress component, show three suggestions that map to their onboarding state.
+
+### Suggested formula
+
+1. **One measurement or direction task**: Q Score / Pathways / Matchmaking.
+2. **One proof or visibility task**: Resume / Agent-Social Branding.
+3. **One practice or skill task**: Interview / Roleplay / Courses.
+
+### Examples by ICP
+
+#### Student
+1. "Pick your first target role" — Pathways / Q Score.
+2. "Turn one project into resume proof" — Resume.
+3. "Practice your first mock interview" — Interview.
+
+#### Intern
+1. "Capture internship impact" — Resume.
+2. "Practice manager check-in" — Roleplay.
+3. "Prepare return-offer interview" — Interview.
+
+#### Fresher under 5 years
+1. "Diagnose why callbacks are low" — Resume / Q Score / Matchmaking.
+2. "Build one STAR story" — Interview.
+3. "Practice salary expectation answer" — Roleplay.
+
+#### Experienced professional
+1. "Translate execution into leadership impact" — Resume.
+2. "Match with senior roles" — Job Matchmaking.
+3. "Practice senior stakeholder interview" — Interview.
+
+#### Freelancer
+1. "Package your offer clearly" — Profile / Agent-Social Branding.
+2. "Practice discovery call" — Roleplay.
+3. "Match with freelance opportunities" — Job Matchmaking.
+
+#### Founder
+1. "Clarify founder one-liner" — Agent-Social Branding / Q Score.
+2. "Practice customer discovery call" — Roleplay.
+3. "Match with investors or cofounders" — Job Matchmaking.
+
+---
+
+## 9. Example generated curator tasks
+
+### Student example
+
+```json
+{
+ "title": "Prepare your first PM interview preview",
+ "subtitle": "Turn your student projects into a confident first-round story.",
+ "serviceId": "interview-service",
+ "serviceName": "Interview service",
+ "cta": "Open interview preview",
+ "contextNarrative": "The user is a student/recent grad targeting product roles and needs confidence before first interviews.",
+ "subtasks": [
+ "Confirm target role and round type",
+ "Pick one project to use as proof",
+ "Generate mock interview preview",
+ "Complete practice and review feedback"
+ ],
+ "signals": ["interview.confidence", "role_alignment", "communication_clarity"]
+}
+```
+
+### Fresher example
+
+```json
+{
+ "title": "Match with 5 high-fit roles this week",
+ "subtitle": "Your resume is ready. Let's find roles that match your proof.",
+ "serviceId": "job-matchmaking",
+ "serviceName": "Job Matchmaking",
+ "cta": "See matched roles",
+ "contextNarrative": "The user is a fresher with improved resume and interview readiness, now needs active opportunity pipeline.",
+ "subtasks": [
+ "Analyze resume vs open roles",
+ "Score top 5 matches",
+ "Surface warm recruiter intros",
+ "Track application pipeline"
+ ],
+ "signals": ["opportunity_awareness", "pipeline_health", "proactive_search"]
+}
+```
+
+### Freelancer example
+
+```json
+{
+ "title": "Draft your first inbound authority post",
+ "subtitle": "The agent will suggest a topic, draft the copy, and optimize timing.",
+ "serviceId": "agent-social-branding",
+ "serviceName": "Agent-Social Branding",
+ "cta": "Draft post with agent",
+ "contextNarrative": "The user is a freelancer who needs inbound visibility, not just outbound hustle.",
+ "subtasks": [
+ "Agent analyzes client pain points",
+ "Agent drafts post with hook and CTA",
+ "User edits and approves",
+ "Agent schedules optimal posting time"
+ ],
+ "signals": ["visibility", "inbound_readiness", "brand_strength"]
+}
+```
+
+### Founder example
+
+```json
+{
+ "title": "Complete your go-to-market skill module",
+ "subtitle": "Close the gap between your product and your first 100 customers.",
+ "serviceId": "courses",
+ "serviceName": "Courses",
+ "cta": "Start GTM module",
+ "contextNarrative": "The user is a founder with MVP but struggling with customer acquisition. Skill gap is go-to-market strategy.",
+ "subtasks": [
+ "Identify GTM knowledge gap",
+ "Complete 15-min module segment",
+ "Apply in customer discovery task",
+ "Track progress in Q Score"
+ ],
+ "signals": ["skill_gap_closure", "gtm_readiness", "customer_acquisition"]
+}
+```
+
+---
+
+## 10. Curator prompt guidance
+
+The prompt should make the curator act like a productized growth coach, not a generic chatbot.
+
+### Voice
+- Warm, direct, concise.
+- One question at a time.
+- No long motivational paragraphs.
+- No internal route names in text.
+- Always explain the business value in plain words.
+- Connect every task back to the user's 30/60-day goal.
+
+### First-turn examples
+
+Interview task:
+> This is your practice step for today. What role or interview round should I prepare the preview for?
+
+Roleplay task:
+> Let's rehearse the conversation before it matters. Who are you speaking with: recruiter, manager, client, investor, or customer?
+
+Resume task:
+> Let's turn your experience into proof. What role or audience should this resume section target?
+
+Agent-Social Branding task:
+> Let's build your visibility engine. Should I suggest a topic based on your recent work, or do you have a specific insight in mind?
+
+Job Matchmaking task:
+> Your profile is ready. Should I find roles that match your current skills, or roles that push you toward your target direction?
+
+Courses task:
+> I spotted a skill gap between your target role and your current proof. Which module feels most urgent: coding, analytics, communication, or strategy?
+
+Founder task:
+> Let's make this useful for your next milestone. Are you trying to validate customers, raise, hire, or build visibility first?
+
+### Handoff-ready examples
+
+Interview:
+> Got it. I prepared a mock interview preview for Product Manager behavioral practice. Open the preview to start or adjust the setup.
+
+Roleplay:
+> Got it. I prepared a roleplay preview for a salary conversation with a recruiter. Open the preview to practice or adjust details.
+
+Resume:
+> Saved. Open the resume workspace and we will turn this into role-fit proof.
+
+Agent-Social Branding:
+> The agent drafted a post about your project insight. Review it in the branding workspace and approve when ready.
+
+Job Matchmaking:
+> I found 3 roles that match your profile. See the matches and apply directly, or request a warm intro.
+
+Courses:
+> I linked a 15-minute module to your skill gap. Start it now and apply the learning in your next interview task.
+
+---
+
+## 11. UX requirements for streak chat
+
+The DailyRetentionStrip chat should show:
+
+1. Assistant message.
+2. User answer.
+3. Assistant summary.
+4. Service preview card when handoff is ready.
+5. Persistent CTA even after subtask is marked complete.
+
+CTA card fields:
+
+- Eyebrow: `INTERVIEW PREVIEW`, `ROLEPLAY PREVIEW`, `RESUME WORKSPACE`, `Q SCORE CHECK`, `AGENT-SOCIAL PREVIEW`, `MATCHED ROLES`, `SKILL MODULE`, `PATHWAY REVIEW`.
+- Title: clear outcome.
+- Subtitle: why this helps.
+- Details: role, scenario, difficulty, duration, service, module name, match count.
+- Button: action verb.
+
+Important: for interview and roleplay, the CTA should route to preview or preview-equivalent state, not a blank setup screen.
+
+---
+
+## 12. Prioritization matrix
+
+### If user blocker is "not getting callbacks"
+Priority:
+1. Resume role-fit audit.
+2. LinkedIn/profile rewrite (Agent-Social Branding).
+3. Job Matchmaking opportunity check.
+4. Interview warm-up only after proof improves.
+
+### If blocker is "interviews not converting"
+Priority:
+1. Interview preview.
+2. STAR story practice.
+3. Roleplay recruiter or salary conversation.
+4. Courses for specific skill gaps.
+
+### If blocker is "don't know where to start"
+Priority:
+1. Q Score baseline.
+2. Pathway/target role selection.
+3. One small proof task.
+
+### If blocker is "pricing confidently"
+Priority:
+1. Offer packaging.
+2. Pricing roleplay.
+3. Case study proof.
+4. Agent-Social Branding for authority.
+
+### If blocker is "fundraising"
+Priority:
+1. Founder one-liner (Agent-Social Branding).
+2. Investor roleplay.
+3. Founder authority post.
+4. Job Matchmaking for investor/cofounder matching.
+
+### If blocker is "finding customers"
+Priority:
+1. Customer segment clarity.
+2. Discovery roleplay.
+3. Build-in-public/customer pain post (Agent-Social Branding).
+4. Courses for GTM skills.
+
+### If blocker is "weak social presence"
+Priority:
+1. Agent-Social Branding for profile polish.
+2. Authority post drafting.
+3. Content cadence setup.
+
+### If blocker is "skill gap"
+Priority:
+1. Courses for targeted module.
+2. Apply skill in interview/resume task.
+3. Q Score update.
+
+---
+
+## 13. Implementation implications
+
+For the upcoming engineering pass:
+
+1. **Externalize curator prompt**: These rules should live in a markdown/txt file, not hardcoded TypeScript.
+2. **CuratorTask generation**: Use onboarding answers to pick ICP, blocker, goal, urgency, service, and task library.
+3. **Streak chat independence**: Do not reuse TalkToMe route/component. Borrow UX patterns only.
+4. **Service handoff routes**: Interview and roleplay should route directly to preview with default params. Resume to workspace. Agent-Social Branding to branding workspace. Job Matchmaking to matchmaking dashboard. Courses to course player. Pathways to direction report.
+5. **Handoff CTA determinism**: Persistent, visible, service-specific copy.
+6. **Completion without hiding action**: Subtask completion should not hide the service CTA.
+7. **Signal mapping**: Every daily task should map to at least one Q Score/progress signal.
+8. **Agent-Social Branding integration**: The agent must be able to suggest topics, draft copy, and schedule. This is not just a "write a post" task.
+9. **Job Matchmaking integration**: Active scoring, not passive browsing. Warm intro capability.
+10. **Courses integration**: Skill gap detection, module suggestion, progress tracking back to Q Score.
+
+---
+
+## 14. Open product questions
+
+1. Should students get a 30-day default and professionals/founders get 60-day default, or should plan length depend on urgency?
+2. Should Q Score visible baseline always start at 35 after onboarding, or vary by imported proof quality?
+3. Should streak completion require service completion, or just curator context capture?
+4. Should interview/roleplay preview generation count as a streak completion, or only completed session/review?
+5. Should freelancers and founders see "Q Score" language, "QX Score", or a more business-facing label like "Credibility Score"?
+6. Should Agent-Social Branding be a first-class service in the curator registry for all ICPs, or only when visibility is the blocker?
+7. Should Job Matchmaking appear for all ICPs, or only when the user is in active search?
+8. Should Courses appear only when skill gaps are detected, or as a standard third suggestion?
+9. Should preview cards support "Change details" quick action directly inside the chat?
+10. Should the agent draft social posts automatically, or only after user approves topic?
+
+---
+
+# 15. Literal 30-day progression examples by ICP
+
+Use these as concrete seed examples for curator plans. Each day has three suggestions. Each suggestion includes small subtasks. In production, pick/modify based on onboarding signals, imported data, service history, and completion events.
+
+## 15.1 Student / recent grad: First Role Readiness Sprint
+
+Onboarding: `individual + student/recent grad + 0-2 years + role/skills + before graduation/within 6 months`.
+
+### Day 1
+1. **Set your first target role** — Pathways/Q Score — subtasks: pick role family; choose target role; save role goal.
+2. **Start Q Score baseline** — Q Score — subtasks: review baseline score; pick weakest driver; save first improvement focus.
+3. **Upload resume or LinkedIn** — Resume — subtasks: import profile; confirm education/projects; mark missing proof.
+
+### Day 2
+1. **Turn one project into proof** — Resume — subtasks: choose project; capture problem/action/result; draft 2 bullets.
+2. **Prepare first mock interview preview** — Interview — subtasks: confirm role; select behavioral round; open preview.
+3. **Draft student profile headline with agent** — Agent-Social Branding — subtasks: agent suggests headline; user picks; agent drafts About; save.
+
+### Day 3
+1. **Practice "Tell me about yourself"** — Interview — subtasks: capture background; pick one project proof; open interview preview.
+2. **Map role requirements** — Pathways — subtasks: list 3 must-have skills; mark known gaps; choose one gap to fix.
+3. **Agent drafts first credibility post** — Agent-Social Branding — subtasks: agent suggests topic; drafts post; user edits; schedules.
+
+### Day 4
+1. **Resume gap scan** — Resume — subtasks: compare resume to role; identify weak section; open resume workspace.
+2. **Roleplay recruiter intro** — Roleplay — subtasks: choose recruiter scenario; define desired next step; open roleplay preview.
+3. **Build proof bank v1** — Resume — subtasks: list projects; add metrics; tag best 3 for interviews.
+
+### Day 5
+1. **Mock interview: easy warm-up** — Interview — subtasks: open preview; complete 5-min round; review feedback.
+2. **Complete first skill gap module** — Courses — subtasks: identify weak skill; complete 15-min module; save progress.
+3. **Q Score check-in** — Q Score — subtasks: review changed drivers; log confidence; choose weekend focus.
+
+### Day 6
+1. **Prepare application shortlist** — Job Matchmaking — subtasks: choose 5 roles; score fit; save top 2.
+2. **Practice common HR screen** — Roleplay — subtasks: choose fresher screen; capture expected questions; open roleplay preview.
+3. **Polish LinkedIn About with agent** — Agent-Social Branding — subtasks: agent drafts About; user edits; save update.
+
+### Day 7
+1. **Weekly readiness review** — Q Score — subtasks: review completed tasks; note score movement; pick next week theme.
+2. **Create STAR story #1** — Interview — subtasks: choose challenge; write situation/task/action/result; save story.
+3. **Apply to two aligned roles** — Job Matchmaking — subtasks: pick roles; tailor resume headline; record applications.
+
+### Day 8
+1. **Skill gap micro-plan** — Courses — subtasks: pick one missing skill; choose resource; schedule 3 practice blocks.
+2. **Interview preview: role-related** — Interview — subtasks: confirm role; select role-related round; open preview.
+3. **Improve education/project section** — Resume — subtasks: remove filler; add relevant coursework; add project result.
+
+### Day 9
+1. **Practice project explanation** — Interview — subtasks: pick project; define architecture/approach; open interview preview.
+2. **Draft outreach message** — Agent-Social Branding — subtasks: choose alumni/recruiter; agent drafts 80-word note; save/send.
+3. **Update Q Score proof ledger** — Q Score — subtasks: add project proof; tag skill; refresh readiness driver.
+
+### Day 10
+1. **Mock interview: medium pressure** — Interview — subtasks: open preview; complete round; save feedback.
+2. **Fix top resume weakness** — Resume — subtasks: select weakness; rewrite section; compare before/after.
+3. **Roleplay networking call** — Roleplay — subtasks: choose alumni scenario; define ask; open roleplay preview.
+
+### Day 11
+1. **Build portfolio/GitHub proof** — Resume — subtasks: select repo/project; write README summary; add outcome.
+2. **Practice weakness answer** — Interview — subtasks: choose honest weakness; add improvement proof; open interview preview.
+3. **Agent drafts learning post** — Agent-Social Branding — subtasks: pick technical lesson; agent drafts; user edits; schedules.
+
+### Day 12
+1. **Application tailoring sprint** — Job Matchmaking — subtasks: select one JD; map keywords; tailor 3 bullets.
+2. **Roleplay recruiter callback** — Roleplay — subtasks: define screen goal; practice intro; save best answer.
+3. **Q Score confidence pulse** — Q Score — subtasks: rate confidence; compare to day 1; choose next practice.
+
+### Day 13
+1. **Mock interview review loop** — Interview — subtasks: read feedback; pick one weak pattern; generate next preview.
+2. **Build STAR story #2** — Interview — subtasks: choose teamwork example; structure STAR; save story.
+3. **Profile credibility check with agent** — Agent-Social Branding — subtasks: agent reviews headline/About; suggests updates; save.
+
+### Day 14
+1. **Week 2 review** — Q Score — subtasks: review applications/practice; log wins; pick week 3 conversion goal.
+2. **Apply to three roles** — Job Matchmaking — subtasks: select roles; tailor resume; record status.
+3. **Practice first-round interview** — Interview — subtasks: open preview; complete round; save feedback.
+
+### Day 15
+1. **Build interview story bank** — Interview — subtasks: list 5 stories; tag leadership/teamwork/problem-solving; save.
+2. **Roleplay salary expectation** — Roleplay — subtasks: define range; practice recruiter answer; save script.
+3. **Improve resume summary with agent** — Agent-Social Branding — subtasks: agent writes target summary; user edits; save.
+
+### Day 16
+1. **Technical/role skill drill** — Courses — subtasks: pick weak topic; answer 3 questions; log confidence.
+2. **Mock interview: targeted weakness** — Interview — subtasks: choose weak area; open preview; practice.
+3. **Draft recruiter follow-up with agent** — Agent-Social Branding — subtasks: choose application; agent drafts follow-up; send.
+
+### Day 17
+1. **Project deep-dive practice** — Interview — subtasks: select project; explain tradeoffs; open interview preview.
+2. **Portfolio polish** — Resume — subtasks: add screenshot/demo link; write impact; save.
+3. **Q Score readiness check** — Q Score — subtasks: review score; identify lowest service signal; route next action.
+
+### Day 18
+1. **Roleplay group discussion** — Roleplay — subtasks: define scenario; practice concise contribution; save feedback.
+2. **Resume bullet metrics pass** — Resume — subtasks: find vague bullets; add numbers/scope; save.
+3. **Agent drafts proof post** — Agent-Social Branding — subtasks: pick project outcome; agent drafts; publish.
+
+### Day 19
+1. **Mock interview: medium full round** — Interview — subtasks: open preview; complete; review feedback.
+2. **Application quality audit** — Job Matchmaking — subtasks: review last 5 applications; identify mismatch; adjust target list.
+3. **Networking ask practice** — Roleplay — subtasks: pick contact; roleplay ask; send message.
+
+### Day 20
+1. **Create final fresher pitch** — Interview — subtasks: draft 60-sec pitch; practice; save best version.
+2. **Interview confidence repair** — Interview — subtasks: pick anxiety point; run warm-up preview; note improvement.
+3. **Role-fit score update** — Q Score — subtasks: compare proof to JD; update gaps; choose next proof.
+
+### Day 21
+1. **Week 3 conversion review** — Q Score — subtasks: review callbacks; review mock scores; choose final sprint focus.
+2. **Prepare top-company version** — Job Matchmaking — subtasks: choose target company; tailor resume; create interview preview.
+3. **Follow-up queue** — Job Matchmaking — subtasks: list pending applications; draft follow-ups; send 2.
+
+### Day 22
+1. **Behavioral story refinement** — Interview — subtasks: choose weakest STAR; tighten action/result; practice.
+2. **Roleplay recruiter screen** — Roleplay — subtasks: simulate screen; practice compensation/location; save script.
+3. **LinkedIn activity boost with agent** — Agent-Social Branding — subtasks: agent suggests 3 posts to comment on; publish one insight; record.
+
+### Day 23
+1. **Mock interview: hard question set** — Interview — subtasks: open preview; complete; review feedback.
+2. **Resume final pass** — Resume — subtasks: grammar scan; role keyword scan; export version.
+3. **Opportunity shortlist refresh** — Job Matchmaking — subtasks: find 5 new roles; rank fit; save top 3.
+
+### Day 24
+1. **Practice rejection recovery** — Roleplay — subtasks: roleplay rejection; ask for feedback; save response.
+2. **Case/project mini-deck** — Resume — subtasks: outline project; add result; create shareable summary.
+3. **Q Score improvement log** — Q Score — subtasks: compare day 1/day 24; note drivers; choose final week target.
+
+### Day 25
+1. **Interview preview for top role** — Interview — subtasks: choose best role; open preview; complete practice.
+2. **Referral request roleplay** — Roleplay — subtasks: pick contact; practice ask; send message.
+3. **Update proof bank** — Resume — subtasks: add new stories; tag to questions; save.
+
+### Day 26
+1. **Application sprint** — Job Matchmaking — subtasks: tailor resume; apply to 3 roles; record status.
+2. **Confidence pitch practice** — Roleplay — subtasks: open roleplay; practice intro; save script.
+3. **Profile final polish with agent** — Agent-Social Branding — subtasks: agent audits headline/About; suggests final edits; save.
+
+### Day 27
+1. **Mock interview replay** — Interview — subtasks: rerun weakest area; compare feedback; save improvement.
+2. **Prepare interview questions to ask** — Interview — subtasks: draft 5 questions; tailor to role; save.
+3. **Networking follow-up** — Job Matchmaking — subtasks: follow up with 3 contacts; record replies.
+
+### Day 28
+1. **Final readiness review** — Q Score — subtasks: review Q Score; review resume; review interview feedback.
+2. **Create next 30-day plan** — Pathways — subtasks: choose goal; select service focus; schedule cadence.
+3. **Publish progress proof with agent** — Agent-Social Branding — subtasks: agent drafts progress post; user edits; publish.
+
+### Day 29
+1. **Offer-readiness roleplay** — Roleplay — subtasks: practice offer call; salary answer; closing question.
+2. **Top role interview preview** — Interview — subtasks: open preview; complete; save feedback.
+3. **Resume export and versioning** — Resume — subtasks: export PDF; name by role; save.
+
+### Day 30
+1. **30-day outcome review** — Q Score — subtasks: compare baseline/current; record wins; identify next gap.
+2. **Choose next sprint** — Pathways — subtasks: interview conversion, callbacks, skills, or networking; save.
+3. **Celebrate streak and unlock next plan** — Q Score — subtasks: claim reward; set cadence; start next stage.
+
+---
+
+## 15.2 Intern: Intern-to-Offer Sprint
+
+Onboarding: `individual + student/recent grad or 0-2 years + employed/internship context + role/pay/grow`.
+
+### Day 1
+1. **Define internship outcome** — Q Score — subtasks: choose return offer/feedback/project impact; save goal; set deadline.
+2. **Capture current project** — Resume — subtasks: describe project; identify stakeholder; list expected result.
+3. **Start Q Score baseline** — Q Score — subtasks: review score; pick communication/proof driver; save focus.
+
+### Day 2
+1. **Practice manager check-in** — Roleplay — subtasks: define ask; capture manager context; open roleplay preview.
+2. **Turn internship work into proof** — Resume — subtasks: pick task; capture action/result; draft resume bullet.
+3. **Write weekly update v1 with agent** — Agent-Social Branding — subtasks: agent captures shipped work; drafts update; user edits; save.
+
+### Day 3
+1. **Clarify success metrics** — Q Score — subtasks: list project KPIs; ask what good looks like; save metrics.
+2. **Roleplay feedback request** — Roleplay — subtasks: define feedback needed; practice ask; save script.
+3. **Update resume internship section** — Resume — subtasks: add company/team; add project; add first bullet.
+
+### Day 4
+1. **Prepare return-offer interview preview** — Interview — subtasks: confirm role; select behavioral; open preview.
+2. **Stakeholder map** — Pathways — subtasks: list manager/mentor/peer; identify influence; plan one touchpoint.
+3. **Agent drafts LinkedIn learning post** — Agent-Social Branding — subtasks: pick lesson; remove confidential details; agent drafts; schedule.
+
+### Day 5
+1. **Mock interview warm-up** — Interview — subtasks: open preview; complete 5-min round; review feedback.
+2. **Manager update roleplay** — Roleplay — subtasks: simulate status update; practice concise wording; save.
+3. **Q Score pulse** — Q Score — subtasks: log confidence; choose next week improvement; save.
+
+### Day 6
+1. **Build impact log** — Resume — subtasks: create weekly wins list; add metric/evidence; save proof bank.
+2. **Ask for better scope** — Roleplay — subtasks: define desired project; roleplay ask; prepare message.
+3. **Improve internship bullet with agent** — Agent-Social Branding — subtasks: agent suggests action verbs; user edits; save resume update.
+
+### Day 7
+1. **Week 1 internship review** — Q Score — subtasks: review project progress; identify blocker; choose next action.
+2. **Prepare mentor conversation** — Roleplay — subtasks: define question; roleplay mentor chat; save ask.
+3. **Publish learning proof with agent** — Agent-Social Branding — subtasks: agent drafts; user edits; publish; record signal.
+
+### Day 8
+1. **Return-offer readiness check** — Q Score — subtasks: identify requirements; compare proof; choose gap.
+2. **Interview preview: project deep dive** — Interview — subtasks: choose project; open preview; practice.
+3. **Draft manager check-in email with agent** — Agent-Social Branding — subtasks: agent summarizes progress; drafts ask; send/save.
+
+### Day 9
+1. **Practice conflict/blocker conversation** — Roleplay — subtasks: define blocker; roleplay manager discussion; save script.
+2. **Document project decisions** — Resume — subtasks: list decisions; note rationale; add to proof bank.
+3. **Resume proof pass** — Resume — subtasks: add collaboration detail; add tool/skill; save.
+
+### Day 10
+1. **Mock return-offer round** — Interview — subtasks: open preview; complete; review feedback.
+2. **Peer feedback request** — Roleplay — subtasks: identify peer; draft ask; send.
+3. **Q Score update** — Q Score — subtasks: add internship proof; check driver movement; choose next task.
+
+### Day 11
+1. **Prepare final project narrative** — Resume — subtasks: write before/action/after; identify metric; save.
+2. **Roleplay full-time conversion ask** — Roleplay — subtasks: define timing; practice ask; save script.
+3. **Profile headline update with agent** — Agent-Social Branding — subtasks: agent suggests headline; add internship role; add target role; save.
+
+### Day 12
+1. **Practice technical/project questions** — Interview — subtasks: list 5 likely questions; open interview preview; practice.
+2. **Manager visibility touchpoint** — Agent-Social Branding — subtasks: choose update; send concise note; record response.
+3. **Build portfolio artifact** — Resume — subtasks: anonymize project; write summary; save.
+
+### Day 13
+1. **Feedback synthesis** — Q Score — subtasks: collect feedback; identify pattern; choose improvement.
+2. **Roleplay receiving criticism** — Roleplay — subtasks: simulate feedback; practice response; save.
+3. **Resume internship finalization v1** — Resume — subtasks: tighten bullets; add metrics; export draft.
+
+### Day 14
+1. **Week 2 review** — Q Score — subtasks: review impact log; review feedback; set conversion action.
+2. **Interview replay on weakness** — Interview — subtasks: choose weak topic; open preview; practice.
+3. **Draft thank-you / relationship note with agent** — Agent-Social Branding — subtasks: choose mentor; agent drafts; send/save.
+
+### Day 15
+1. **Full-time offer path map** — Pathways — subtasks: identify decision maker; timeline; required proof.
+2. **Roleplay offer conversation** — Roleplay — subtasks: define ask; open roleplay preview; practice.
+3. **Strengthen project proof** — Resume — subtasks: add metric; add stakeholder quote; save.
+
+### Day 16
+1. **Mock interview: medium pressure** — Interview — subtasks: open preview; complete; review.
+2. **Prepare demo/update deck** — Resume — subtasks: outline 3 slides; add result; save.
+3. **LinkedIn credibility update with agent** — Agent-Social Branding — subtasks: agent drafts internship lesson; publish/save.
+
+### Day 17
+1. **Ask for explicit feedback** — Roleplay — subtasks: draft 3 questions; roleplay ask; send.
+2. **Roleplay prioritization discussion** — Roleplay — subtasks: define conflict; practice tradeoff explanation; save.
+3. **Q Score signal review** — Q Score — subtasks: review communication/proof; select lowest driver; route task.
+
+### Day 18
+1. **Return-offer interview preview** — Interview — subtasks: role; behavioral; open preview; practice.
+2. **Manager one-on-one prep** — Roleplay — subtasks: agenda; wins; asks; send/save.
+3. **Resume role-fit tailoring** — Resume — subtasks: choose post-internship role; tailor bullets; save.
+
+### Day 19
+1. **Practice project storytelling** — Interview — subtasks: prepare 90-sec story; open interview; save best answer.
+2. **Internal networking task** — Job Matchmaking — subtasks: pick team member; write intro; schedule chat.
+3. **Impact log refresh** — Resume — subtasks: add week wins; add blockers solved; save.
+
+### Day 20
+1. **Roleplay conversion close** — Roleplay — subtasks: practice direct ask; handle hesitation; save script.
+2. **Mock interview feedback loop** — Interview — subtasks: compare attempts; pick improvement; schedule next.
+3. **Profile polish with agent** — Agent-Social Branding — subtasks: agent updates headline; adds internship proof; save.
+
+### Day 21
+1. **Week 3 conversion review** — Q Score — subtasks: assess offer odds; identify missing proof; plan final week.
+2. **Prepare final presentation** — Resume — subtasks: outline impact; add metric; rehearse.
+3. **Q Score progress check** — Q Score — subtasks: compare baseline/current; choose final improvement.
+
+### Day 22
+1. **Practice final presentation Q&A** — Interview — subtasks: list likely questions; open interview preview; practice.
+2. **Roleplay manager decision meeting** — Roleplay — subtasks: define outcome; practice ask; save.
+3. **Resume final internship bullets** — Resume — subtasks: refine 3 bullets; export role version; save.
+
+### Day 23
+1. **Stakeholder thank-you loop** — Agent-Social Branding — subtasks: agent drafts notes; list people; send.
+2. **Mock interview hard round** — Interview — subtasks: open preview; complete; review.
+3. **External backup plan** — Job Matchmaking — subtasks: choose 5 roles; tailor resume; save shortlist.
+
+### Day 24
+1. **Promotion/return-offer script** — Roleplay — subtasks: write ask; practice; save.
+2. **Portfolio case study** — Resume — subtasks: anonymize project; write challenge/action/result; save.
+3. **LinkedIn post final with agent** — Agent-Social Branding — subtasks: agent drafts; review confidentiality; publish/save.
+
+### Day 25
+1. **Offer conversation preview** — Roleplay — subtasks: choose roleplay; set counterpart manager; practice.
+2. **Interview final polish** — Interview — subtasks: practice top 3 answers; save feedback.
+3. **Q Score readiness summary** — Q Score — subtasks: review signals; save final sprint note; choose next.
+
+### Day 26
+1. **Ask for recommendation/referral** — Roleplay — subtasks: choose person; draft ask; roleplay if needed.
+2. **Application backup sprint** — Job Matchmaking — subtasks: apply to 3 roles; record status; follow up.
+3. **Manager update final** — Agent-Social Branding — subtasks: agent summarizes impact; states interest; send.
+
+### Day 27
+1. **Decision meeting rehearsal** — Roleplay — subtasks: roleplay; practice compensation/role scope; save script.
+2. **Resume export** — Resume — subtasks: final grammar; export PDF; save version.
+3. **Proof bank finalization** — Resume — subtasks: tag stories; tag metrics; save.
+
+### Day 28
+1. **Final internship review** — Q Score — subtasks: compare goals; capture outcomes; identify next move.
+2. **Mock interview replay** — Interview — subtasks: rerun weakness; compare feedback; save.
+3. **Relationship maintenance plan** — Job Matchmaking — subtasks: list contacts; schedule follow-ups; save.
+
+### Day 29
+1. **Offer or next-role roleplay** — Roleplay — subtasks: choose scenario; open preview; practice.
+2. **Q Score closeout** — Q Score — subtasks: compare day 1/day 29; record evidence; choose next sprint.
+3. **Publish milestone update with agent** — Agent-Social Branding — subtasks: agent drafts; review; publish/save.
+
+### Day 30
+1. **Intern-to-offer outcome review** — Q Score — subtasks: record offer/status; note lessons; choose next plan.
+2. **Start next sprint** — Pathways — subtasks: return offer, external search, skill gap, or leadership; save.
+3. **Claim streak milestone** — Q Score — subtasks: review streak; claim reward; schedule cadence.
+
+---
+
+## 15.3 Fresher / early professional under 5 years: Callback-to-Offer Sprint
+
+Onboarding: `individual + 0-2 or 2-5 years + hunting/between/employed + callbacks/interviews/profile/pay/switch`.
+
+### Day 1
+1. **Choose your target role** — Pathways — subtasks: pick role; pick industry; save goal.
+2. **Run Q Score baseline** — Q Score — subtasks: review score; choose weakest driver; save focus.
+3. **Import resume/profile** — Resume — subtasks: upload resume; connect LinkedIn; mark missing proof.
+
+### Day 2
+1. **Resume role-fit audit** — Resume — subtasks: select target JD; compare resume; save top 3 fixes.
+2. **Interview warm-up preview** — Interview — subtasks: choose role; open preview; practice.
+3. **Rewrite profile headline with agent** — Agent-Social Branding — subtasks: agent suggests headline; target role; proof point; save.
+
+### Day 3
+1. **Callback blocker diagnosis** — Q Score/Job Matchmaking — subtasks: review applications; identify mismatch; update target list.
+2. **Build STAR story #1** — Interview — subtasks: choose achievement; structure STAR; save.
+3. **Roleplay recruiter screen** — Roleplay — subtasks: choose scenario; open preview; practice.
+
+### Day 4
+1. **Rewrite top resume bullets** — Resume — subtasks: select 3 bullets; add metrics; save.
+2. **Practice "why this role"** — Interview — subtasks: define motivation; open interview preview; save answer.
+3. **Application shortlist** — Job Matchmaking — subtasks: find 5 roles; rank fit; save top 3.
+
+### Day 5
+1. **Mock interview medium round** — Interview — subtasks: open preview; complete; review feedback.
+2. **LinkedIn About rewrite with agent** — Agent-Social Branding — subtasks: agent drafts summary; add proof; save.
+3. **Q Score check-in** — Q Score — subtasks: review movement; choose next driver; save.
+
+### Day 6
+1. **Tailor resume to one JD** — Resume — subtasks: map keywords; rewrite summary; export version.
+2. **Roleplay salary expectation** — Roleplay — subtasks: define range; open preview; practice.
+3. **Draft recruiter outreach with agent** — Agent-Social Branding — subtasks: agent drafts message; send 2; record.
+
+### Day 7
+1. **Week 1 review** — Q Score — subtasks: review applications; review mock feedback; choose week 2 focus.
+2. **Apply to three roles** — Job Matchmaking — subtasks: tailor resume; apply; record status.
+3. **Publish credibility post with agent** — Agent-Social Branding — subtasks: agent suggests work lesson; draft; publish/save.
+
+### Day 8
+1. **Interview weakness drill** — Interview — subtasks: pick weak answer; open preview; practice.
+2. **Proof bank v1** — Resume — subtasks: list wins; tag metrics; connect to questions.
+3. **Profile visibility action with agent** — Agent-Social Branding — subtasks: agent suggests 3 posts to comment on; record.
+
+### Day 9
+1. **Role transition map** — Pathways — subtasks: compare current/target; identify gaps; pick one gap.
+2. **Resume gap fix** — Resume — subtasks: add missing skill proof; rewrite section; save.
+3. **Roleplay networking call** — Roleplay — subtasks: choose contact; open preview; practice ask.
+
+### Day 10
+1. **Mock interview role-related** — Interview — subtasks: open preview; complete; review.
+2. **Follow-up sprint** — Job Matchmaking — subtasks: list pending applications; draft follow-ups; send 3.
+3. **Q Score proof update** — Q Score — subtasks: add resume changes; refresh driver; save.
+
+### Day 11
+1. **STAR story #2** — Interview — subtasks: choose conflict/teamwork; structure; save.
+2. **Practice weakness answer** — Interview — subtasks: draft honest answer; open interview; practice.
+3. **Opportunity shortlist refresh** — Job Matchmaking — subtasks: find 5 roles; rank; save.
+
+### Day 12
+1. **Recruiter call roleplay** — Roleplay — subtasks: intro; compensation; next step; practice.
+2. **Resume final role version** — Resume — subtasks: edit summary; bullets; export.
+3. **Profile proof link with agent** — Agent-Social Branding — subtasks: add project/case link; update featured section; save.
+
+### Day 13
+1. **Mock interview feedback loop** — Interview — subtasks: review last feedback; pick pattern; practice again.
+2. **Application quality audit** — Job Matchmaking — subtasks: score 5 applications; remove bad-fit roles; save.
+3. **Draft referral ask with agent** — Agent-Social Branding — subtasks: pick contact; agent drafts ask; send.
+
+### Day 14
+1. **Week 2 review** — Q Score — subtasks: compare callbacks; compare confidence; choose conversion goal.
+2. **Practice behavioral round** — Interview — subtasks: open preview; complete; save feedback.
+3. **Publish proof post with agent** — Agent-Social Branding — subtasks: pick result; agent drafts; publish/save.
+
+### Day 15
+1. **Interview conversion plan** — Interview — subtasks: identify weak round; choose practice cadence; save.
+2. **Roleplay offer/salary call** — Roleplay — subtasks: scenario; desired range; practice.
+3. **Update resume with new proof** — Resume — subtasks: add story; add metric; save.
+
+### Day 16
+1. **Hard question practice** — Interview — subtasks: choose 3 hard questions; open preview; practice.
+2. **Recruiter pipeline update** — Job Matchmaking — subtasks: list active leads; next action; send follow-up.
+3. **Q Score review** — Q Score — subtasks: check lowest driver; route next service; save.
+
+### Day 17
+1. **Project deep dive practice** — Interview — subtasks: select project; explain decisions; open preview.
+2. **Networking follow-up** — Job Matchmaking — subtasks: follow up 3 contacts; record response.
+3. **Profile credibility pass with agent** — Agent-Social Branding — subtasks: agent audits headline/About/featured; save.
+
+### Day 18
+1. **Application sprint** — Job Matchmaking — subtasks: tailor; apply to 3 roles; record status.
+2. **Roleplay rejection recovery** — Roleplay — subtasks: practice asking feedback; save script.
+3. **STAR story #3** — Interview — subtasks: leadership/ownership example; structure; save.
+
+### Day 19
+1. **Mock interview full round** — Interview — subtasks: open preview; complete; review.
+2. **Resume keyword pass** — Resume — subtasks: compare JD; add relevant terms; export.
+3. **Personal brand post with agent** — Agent-Social Branding — subtasks: choose insight; agent drafts; publish/save.
+
+### Day 20
+1. **Interview answer polish** — Interview — subtasks: pick top 3 answers; shorten; practice.
+2. **Roleplay hiring manager call** — Roleplay — subtasks: define scenario; open preview; practice.
+3. **Q Score progress note** — Q Score — subtasks: compare baseline/current; note drivers; choose final sprint.
+
+### Day 21
+1. **Week 3 review** — Q Score — subtasks: review interviews/callbacks; identify blocker; choose final week push.
+2. **Target company prep** — Job Matchmaking — subtasks: choose company; research; prepare questions.
+3. **Follow-up sprint** — Job Matchmaking — subtasks: pending list; send 3; record.
+
+### Day 22
+1. **Mock interview target company** — Interview — subtasks: role; company context; open preview.
+2. **Referral request roleplay** — Roleplay — subtasks: pick contact; practice ask; send.
+3. **Resume final polish** — Resume — subtasks: grammar; formatting; export.
+
+### Day 23
+1. **Salary negotiation prep** — Roleplay — subtasks: define range; roleplay; save script.
+2. **Portfolio/case proof** — Resume — subtasks: choose project; write case summary; save.
+3. **Q Score readiness check** — Q Score — subtasks: review score; choose final gap; act.
+
+### Day 24
+1. **Mock interview hard mode** — Interview — subtasks: open preview; complete; review.
+2. **LinkedIn recruiter visibility with agent** — Agent-Social Branding — subtasks: agent updates headline; suggests posts; send 2 messages.
+3. **Application conversion audit** — Job Matchmaking — subtasks: analyze stages; identify drop-off; plan fix.
+
+### Day 25
+1. **Offer call roleplay** — Roleplay — subtasks: scenario; compensation; closing ask; practice.
+2. **Interview replay on weakest area** — Interview — subtasks: open preview; practice; compare feedback.
+3. **Proof bank final pass** — Resume — subtasks: tag stories; add metrics; save.
+
+### Day 26
+1. **Final application sprint** — Job Matchmaking — subtasks: apply to 3 high-fit roles; record; follow up.
+2. **Manager/recruiter communication drill** — Roleplay — subtasks: choose scenario; roleplay; save.
+3. **Profile proof publish with agent** — Agent-Social Branding — subtasks: agent drafts; publish/save; record.
+
+### Day 27
+1. **Interview questions to ask** — Interview — subtasks: draft 5 smart questions; tailor; save.
+2. **Resume export versions** — Resume — subtasks: create 2 role versions; export; save.
+3. **Q Score final push** — Q Score — subtasks: pick one driver; complete linked task; save.
+
+### Day 28
+1. **Readiness review** — Q Score — subtasks: compare baseline; review artifacts; identify next sprint.
+2. **Mock interview final** — Interview — subtasks: open preview; complete; save feedback.
+3. **Networking cadence plan** — Job Matchmaking — subtasks: choose contacts; schedule weekly outreach; save.
+
+### Day 29
+1. **Negotiation or recruiter screen replay** — Roleplay — subtasks: open roleplay; practice; save script.
+2. **Opportunity pipeline review** — Job Matchmaking — subtasks: active roles; next actions; deadlines.
+3. **Profile final polish with agent** — Agent-Social Branding — subtasks: agent audits; suggests final edits; save.
+
+### Day 30
+1. **30-day outcome review** — Q Score — subtasks: callbacks/interviews/score; record wins; choose next sprint.
+2. **Select next plan** — Pathways — subtasks: interview conversion, salary negotiation, transition, leadership; save.
+3. **Claim streak milestone** — Q Score — subtasks: review progress; claim reward; schedule next cadence.
+
+---
+
+## 15.4 Freelancer / gig worker: Client Pipeline Sprint
+
+Onboarding: `gig + starting/fewclients/sidehustle + clients/pricing/standout/trust/income + firstclient/doubleincome/fulltime/1lakh`.
+
+### Day 1
+1. **Define your client niche** — Pathways — subtasks: choose target client; define pain; save niche.
+2. **Start credibility/Q Score baseline** — Q Score — subtasks: review baseline; pick trust driver; save focus.
+3. **Import portfolio/profile** — Resume — subtasks: add LinkedIn/portfolio/GitHub; mark missing proof.
+
+### Day 2
+1. **Package your core offer** — Resume/Profile — subtasks: define problem; define deliverable; write offer line.
+2. **Practice discovery call preview** — Roleplay — subtasks: choose client scenario; open roleplay preview; practice.
+3. **Draft profile headline with agent** — Agent-Social Branding — subtasks: client type; outcome; agent drafts; save.
+
+### Day 3
+1. **Build case study #1** — Resume — subtasks: pick project; before/action/after; draft summary.
+2. **Pricing confidence roleplay** — Roleplay — subtasks: current/target rate; open preview; practice.
+3. **Draft inbound post with agent** — Agent-Social Branding — subtasks: agent picks client pain; drafts insight; save/publish.
+
+### Day 4
+1. **Client pipeline map** — Pathways — subtasks: list lead sources; rank channels; choose first 2.
+2. **Offer page/profile polish** — Resume — subtasks: add offer; add proof; add CTA.
+3. **Roleplay objection handling** — Roleplay — subtasks: pick objection; open preview; practice.
+
+### Day 5
+1. **Outreach message v1** — Job Matchmaking — subtasks: define audience; write message; send 5.
+2. **Q Score trust check** — Q Score — subtasks: review credibility gaps; choose proof task; save.
+3. **Portfolio proof pass** — Resume — subtasks: add metric/testimonial; improve case study; save.
+
+### Day 6
+1. **Discovery call script** — Roleplay — subtasks: write 5 questions; roleplay call; save script.
+2. **Pricing page draft** — Resume — subtasks: define package tiers; add outcomes; save.
+3. **Publish credibility post with agent** — Agent-Social Branding — subtasks: agent drafts; publish; record.
+
+### Day 7
+1. **Week 1 pipeline review** — Q Score — subtasks: leads sent; replies; learnings; choose week 2 focus.
+2. **Follow-up roleplay** — Roleplay — subtasks: practice polite follow-up; send 3.
+3. **Update service profile with agent** — Agent-Social Branding — subtasks: agent audits headline/offer/proof; save.
+
+### Day 8
+1. **Create lead list** — Job Matchmaking — subtasks: find 20 prospects; score fit; save top 10.
+2. **Roleplay first client call** — Roleplay — subtasks: scenario; desired close; practice.
+3. **Case study polish** — Resume — subtasks: add visuals/link; add outcome; publish/save.
+
+### Day 9
+1. **Improve offer specificity** — Resume — subtasks: narrow audience; narrow outcome; update copy.
+2. **Pricing objection drill** — Roleplay — subtasks: choose objection; roleplay; save response.
+3. **Draft cold DM/email with agent** — Agent-Social Branding — subtasks: agent writes version; personalize 5; send.
+
+### Day 10
+1. **Q Score credibility update** — Q Score — subtasks: add case proof; review movement; pick next gap.
+2. **Client discovery replay** — Roleplay — subtasks: open roleplay; practice; save feedback.
+3. **Inbound content draft with agent** — Agent-Social Branding — subtasks: client pain; teaching point; CTA.
+
+### Day 11
+1. **Referral ask script** — Roleplay — subtasks: pick past client/contact; write ask; roleplay.
+2. **Portfolio homepage audit** — Resume — subtasks: identify weak section; rewrite; save.
+3. **Pipeline follow-up sprint** — Job Matchmaking — subtasks: follow up 5 leads; record status.
+
+### Day 12
+1. **Proposal structure** — Resume — subtasks: define problem; solution; timeline; price.
+2. **Roleplay proposal call** — Roleplay — subtasks: client scenario; open preview; practice.
+3. **Proof post with agent** — Agent-Social Branding — subtasks: share case insight; agent drafts; publish/save.
+
+### Day 13
+1. **Rate increase plan** — Pathways — subtasks: current rate; target; justification proof.
+2. **Pricing roleplay hard mode** — Roleplay — subtasks: discount objection; scope objection; practice.
+3. **Lead source review** — Job Matchmaking — subtasks: compare channels; double down; save.
+
+### Day 14
+1. **Week 2 review** — Q Score — subtasks: leads/replies/calls; bottleneck; week 3 focus.
+2. **Update profile CTA with agent** — Agent-Social Branding — subtasks: agent writes clear CTA; adds booking/contact; save.
+3. **Discovery call practice** — Roleplay — subtasks: open roleplay; practice; save.
+
+### Day 15
+1. **Client conversion plan** — Job Matchmaking — subtasks: identify active leads; next action; deadlines.
+2. **Scope creep roleplay** — Roleplay — subtasks: define scenario; practice boundary; save script.
+3. **Case study #2** — Resume — subtasks: choose project; draft; save.
+
+### Day 16
+1. **Proposal follow-up script** — Roleplay — subtasks: draft; roleplay; send.
+2. **Q Score trust review** — Q Score — subtasks: review proof/social; choose next improvement.
+3. **Authority post with agent** — Agent-Social Branding — subtasks: client lesson; agent drafts; publish/save.
+
+### Day 17
+1. **Package refinement** — Resume — subtasks: define starter package; define premium package; save.
+2. **Roleplay premium offer** — Roleplay — subtasks: practice quote; handle pushback; save.
+3. **Outreach sprint** — Job Matchmaking — subtasks: send 5 targeted messages; record.
+
+### Day 18
+1. **Testimonial request** — Roleplay — subtasks: choose client; draft request; send.
+2. **Client call replay** — Roleplay — subtasks: practice discovery/proposal; save feedback.
+3. **Portfolio proof update** — Resume — subtasks: add testimonial/result; save.
+
+### Day 19
+1. **Inbound post #2 with agent** — Agent-Social Branding — subtasks: agent picks recurring pain; drafts; publish.
+2. **Roleplay difficult client** — Roleplay — subtasks: late payment/scope; practice; save.
+3. **Pipeline health check** — Job Matchmaking — subtasks: leads/calls/proposals; next actions.
+
+### Day 20
+1. **Pricing confidence review** — Roleplay — subtasks: compare day 3/day 20; update script; save.
+2. **Proposal template final** — Resume — subtasks: refine sections; add pricing; save.
+3. **Q Score progress note** — Q Score — subtasks: compare baseline; choose final sprint focus.
+
+### Day 21
+1. **Week 3 review** — Q Score — subtasks: identify conversion bottleneck; choose final week push.
+2. **Roleplay close call** — Roleplay — subtasks: practice close; handle hesitation; save.
+3. **Lead list refresh** — Job Matchmaking — subtasks: add 20 leads; score; save.
+
+### Day 22
+1. **Full-time freelancing plan** — Pathways — subtasks: income target; client count; package math.
+2. **Pricing/retainer roleplay** — Roleplay — subtasks: monthly retainer scenario; practice.
+3. **Profile final proof pass with agent** — Agent-Social Branding — subtasks: agent audits headline/case studies/CTA; save.
+
+### Day 23
+1. **Outreach sprint** — Job Matchmaking — subtasks: personalize 10; send; record.
+2. **Discovery call final practice** — Roleplay — subtasks: open roleplay; practice; save.
+3. **Publish case study with agent** — Agent-Social Branding — subtasks: finalize; publish; share.
+
+### Day 24
+1. **Referral engine setup** — Job Matchmaking — subtasks: write referral ask; identify 10 contacts; send 3.
+2. **Difficult negotiation roleplay** — Roleplay — subtasks: discount/scope; practice; save.
+3. **Q Score credibility check** — Q Score — subtasks: review; choose last improvement; act.
+
+### Day 25
+1. **Proposal follow-up sprint** — Job Matchmaking — subtasks: list proposals; write follow-ups; send.
+2. **Premium positioning update** — Resume — subtasks: rewrite offer; add proof; save.
+3. **Authority post with agent** — Agent-Social Branding — subtasks: client insight; agent drafts; publish.
+
+### Day 26
+1. **Client onboarding script** — Roleplay — subtasks: define first call; roleplay; save.
+2. **Portfolio final export/share** — Resume — subtasks: update links; test CTA; save.
+3. **Pipeline next actions** — Job Matchmaking — subtasks: assign next step to every lead; record.
+
+### Day 27
+1. **Close-call practice** — Roleplay — subtasks: open roleplay; practice; save script.
+2. **Retainer offer draft** — Resume — subtasks: define recurring value; price; terms.
+3. **Follow-up 5 leads** — Job Matchmaking — subtasks: draft; send; record.
+
+### Day 28
+1. **30-day pipeline review prep** — Q Score — subtasks: leads/replies/calls/revenue; summarize.
+2. **Case study final polish** — Resume — subtasks: add outcome; share; save.
+3. **Q Score final review** — Q Score — subtasks: compare baseline; note trust gains; choose next sprint.
+
+### Day 29
+1. **Roleplay highest-value call** — Roleplay — subtasks: choose active lead; practice; save.
+2. **Recurring income plan** — Pathways — subtasks: define retainer target; prospect list; next actions.
+3. **Publish progress post with agent** — Agent-Social Branding — subtasks: agent drafts learning; publish; record.
+
+### Day 30
+1. **Client Pipeline outcome review** — Q Score — subtasks: count leads/replies/calls; record wins; choose next plan.
+2. **Select next sprint** — Pathways — subtasks: first client, premium rates, retainer, inbound brand; save.
+3. **Claim streak milestone** — Q Score — subtasks: claim reward; set next cadence; start next stage.
+
+---
+
+## 15.5 Founder / solopreneur: Founder Visibility & Validation Sprint
+
+Onboarding: `founder + idea/MVP/traction/pre-revenue + customers/funding/visibility/team/model + 90-day priority`.
+
+### Day 1
+1. **Clarify 90-day founder priority** — Pathways — subtasks: choose MVP/customers/raise/hire/presence; save goal.
+2. **Founder Q Score baseline** — Q Score — subtasks: review credibility drivers; pick weakest; save focus.
+3. **Import founder proof** — Resume — subtasks: add LinkedIn/site/deck; mark missing proof.
+
+### Day 2
+1. **Write founder one-liner** — Agent-Social Branding — subtasks: audience; problem; solution; agent drafts; save.
+2. **Practice customer discovery preview** — Roleplay — subtasks: choose segment; assumption; open roleplay.
+3. **Draft founder profile headline with agent** — Agent-Social Branding — subtasks: role; venture; outcome; agent drafts; save.
+
+### Day 3
+1. **Map riskiest assumption** — Pathways — subtasks: identify assumption; define evidence needed; save.
+2. **Build-in-public post v1 with agent** — Agent-Social Branding — subtasks: agent picks learning; drafts; publish/save.
+3. **Customer list v1** — Job Matchmaking — subtasks: define ICP; list 20 prospects; score top 10.
+
+### Day 4
+1. **Discovery call script** — Roleplay — subtasks: write 5 questions; avoid leading; save.
+2. **Roleplay customer interview** — Roleplay — subtasks: open preview; practice; save feedback.
+3. **Founder credibility audit with agent** — Agent-Social Branding — subtasks: agent reviews profile/site/deck; saves top fixes.
+
+### Day 5
+1. **Q Score validation check** — Q Score — subtasks: review credibility/clarity; choose next action.
+2. **Outreach message to customers** — Job Matchmaking — subtasks: write message; send 5; record.
+3. **Founder one-liner revision with agent** — Agent-Social Branding — subtasks: agent simplifies; adds pain; saves.
+
+### Day 6
+1. **Investor/customer narrative draft** — Resume — subtasks: problem; insight; traction/proof; save.
+2. **Roleplay objection handling** — Roleplay — subtasks: choose customer objection; practice; save.
+3. **Publish market insight with agent** — Agent-Social Branding — subtasks: agent drafts; publish; record.
+
+### Day 7
+1. **Week 1 validation review** — Q Score — subtasks: calls booked; replies; learning; choose week 2 focus.
+2. **Discovery follow-up** — Job Matchmaking — subtasks: write follow-up; send; record.
+3. **Update founder profile with agent** — Agent-Social Branding — subtasks: agent updates headline/one-liner/venture link; save.
+
+### Day 8
+1. **Customer discovery round 2** — Job Matchmaking — subtasks: refine ICP; send 5 more; record.
+2. **Roleplay investor intro** — Roleplay — subtasks: stage; proof; open preview; practice.
+3. **Deck/site clarity pass** — Resume — subtasks: rewrite problem; rewrite audience; save.
+
+### Day 9
+1. **Validate pricing hypothesis** — Pathways — subtasks: define price; buyer; test question.
+2. **Pricing conversation roleplay** — Roleplay — subtasks: open preview; practice; save.
+3. **Founder update post with agent** — Agent-Social Branding — subtasks: share learning; agent drafts; publish.
+
+### Day 10
+1. **Q Score credibility update** — Q Score — subtasks: add profile/deck changes; review movement.
+2. **Customer call replay** — Roleplay — subtasks: practice weak question; save feedback.
+3. **Prospect pipeline update** — Job Matchmaking — subtasks: statuses; next actions; save.
+
+### Day 11
+1. **MVP scope check** — Pathways — subtasks: list features; mark must-have; cut one feature.
+2. **Roleplay cofounder alignment** — Roleplay — subtasks: define role; open preview; practice.
+3. **Authority post with agent** — Agent-Social Branding — subtasks: pick contrarian insight; agent drafts; publish.
+
+### Day 12
+1. **First customer offer** — Resume — subtasks: define pilot; outcome; price/free terms.
+2. **Roleplay sales discovery** — Roleplay — subtasks: buyer; desired next step; practice.
+3. **Profile proof update with agent** — Agent-Social Branding — subtasks: add traction/learning; save.
+
+### Day 13
+1. **Investor intro email** — Job Matchmaking — subtasks: draft concise note; add proof; save/send.
+2. **Roleplay investor objections** — Roleplay — subtasks: market/team/traction objection; practice.
+3. **Customer insight synthesis** — Pathways — subtasks: summarize calls; identify pattern; save.
+
+### Day 14
+1. **Week 2 review** — Q Score — subtasks: calls/learnings/proof; choose week 3 conversion goal.
+2. **Build-in-public post #2 with agent** — Agent-Social Branding — subtasks: learning; metric; ask; agent drafts; publish.
+3. **Q Score check-in** — Q Score — subtasks: review clarity/visibility; choose next action.
+
+### Day 15
+1. **Customer conversion plan** — Job Matchmaking — subtasks: active prospects; next ask; deadlines.
+2. **Roleplay pilot close** — Roleplay — subtasks: offer; objection; next step; practice.
+3. **Deck one-liner polish** — Resume — subtasks: problem; solution; why now; save.
+
+### Day 16
+1. **Hiring/collaborator need** — Pathways — subtasks: define role; outcomes; score must-haves.
+2. **Interview first hire preview** — Interview — subtasks: role; round; open interview preview.
+3. **Founder profile social proof with agent** — Agent-Social Branding — subtasks: add customers/advisors/proof; save.
+
+### Day 17
+1. **Customer discovery sprint** — Job Matchmaking — subtasks: send 10 messages; record replies; schedule calls.
+2. **Roleplay hard customer call** — Roleplay — subtasks: skeptical buyer; practice; save.
+3. **Market narrative post with agent** — Agent-Social Branding — subtasks: write insight; agent drafts; publish.
+
+### Day 18
+1. **Fundraising readiness check** — Q Score — subtasks: stage; proof; gaps; choose fix.
+2. **Investor roleplay replay** — Roleplay — subtasks: open preview; practice; save.
+3. **Website/deck proof pass** — Resume — subtasks: add traction/quotes; save.
+
+### Day 19
+1. **Model validation task** — Pathways — subtasks: unit assumption; test method; evidence target.
+2. **Pricing/buyer roleplay** — Roleplay — subtasks: open preview; practice; save.
+3. **Pipeline follow-up** — Job Matchmaking — subtasks: follow up 5 prospects; record.
+
+### Day 20
+1. **Q Score progress note** — Q Score — subtasks: compare baseline; identify strongest/weakest driver.
+2. **Founder pitch practice** — Roleplay — subtasks: 60-sec pitch; roleplay; save script.
+3. **Build-in-public post #3 with agent** — Agent-Social Branding — subtasks: progress; challenge; ask; agent drafts; publish.
+
+### Day 21
+1. **Week 3 review** — Q Score — subtasks: validation evidence; customer pipeline; choose final week push.
+2. **Pilot proposal draft** — Resume — subtasks: scope; timeline; price; success metric.
+3. **Roleplay closing conversation** — Roleplay — subtasks: customer; next step; practice.
+
+### Day 22
+1. **Investor/customer FAQ** — Resume — subtasks: list hard questions; draft answers; save.
+2. **Interview/collaborator preview** — Interview — subtasks: role; criteria; open preview.
+3. **Founder profile polish with agent** — Agent-Social Branding — subtasks: headline; one-liner; proof; agent audits; save.
+
+### Day 23
+1. **Customer outreach sprint** — Job Matchmaking — subtasks: send 10; record; schedule.
+2. **Roleplay objection: no budget** — Roleplay — subtasks: practice; save response.
+3. **Authority post with agent** — Agent-Social Branding — subtasks: market lesson; agent drafts; publish.
+
+### Day 24
+1. **Traction proof package** — Resume — subtasks: collect calls/replies/users/revenue; summarize.
+2. **Investor intro replay** — Roleplay — subtasks: open roleplay; practice; save.
+3. **Q Score final gap action** — Q Score — subtasks: choose gap; complete linked task; save.
+
+### Day 25
+1. **Pilot close sprint** — Job Matchmaking — subtasks: active prospects; send close asks; record.
+2. **Founder pitch final** — Roleplay — subtasks: tighten 60-sec pitch; practice; save.
+3. **Deck/site final clarity** — Resume — subtasks: problem; solution; proof; CTA.
+
+### Day 26
+1. **Hiring/collaborator outreach** — Job Matchmaking — subtasks: define target; write message; send 5.
+2. **Roleplay cofounder conversation** — Roleplay — subtasks: equity/scope/values; practice.
+3. **Publish milestone update with agent** — Agent-Social Branding — subtasks: metric/learning; agent drafts; publish.
+
+### Day 27
+1. **Customer interview synthesis** — Pathways — subtasks: summarize patterns; decide pivot/persevere; save.
+2. **Roleplay next-step close** — Roleplay — subtasks: pilot/customer/investor; practice.
+3. **Founder credibility final pass with agent** — Agent-Social Branding — subtasks: profile; site; proof links; agent audits; save.
+
+### Day 28
+1. **30-day validation review prep** — Q Score — subtasks: evidence; gaps; decision; next sprint.
+2. **Q Score closeout** — Q Score — subtasks: compare baseline; note drivers; choose next.
+3. **Build-in-public recap with agent** — Agent-Social Branding — subtasks: agent drafts progress recap; publish/save.
+
+### Day 29
+1. **Highest-stakes conversation practice** — Roleplay — subtasks: investor/customer/hire; open roleplay; practice.
+2. **Pipeline next actions** — Job Matchmaking — subtasks: every prospect next step; deadlines; save.
+3. **Pitch/deck export** — Resume — subtasks: final file/link; save; share-ready.
+
+### Day 30
+1. **Founder sprint outcome review** — Q Score — subtasks: calls, customers, proof, score; record.
+2. **Choose next founder sprint** — Pathways — subtasks: MVP, customers, fundraising, hiring, visibility; save.
+3. **Claim streak milestone** — Q Score — subtasks: claim reward; schedule next cadence; start next stage.
+
+---
+
+## 15.6 Experienced professional above 5 years: Leadership Readiness Sprint
+
+Onboarding: `individual + 5-10 or 10+ years + employed/between/leading + leadership/pay/scope/authority`.
+
+### Day 1
+1. **Define leadership target** — Pathways — subtasks: pick leadership role; define scope; save goal.
+2. **Leadership Q Score baseline** — Q Score — subtasks: review leadership drivers; pick weakest; save focus.
+3. **Import leadership proof** — Resume — subtasks: add LinkedIn/site; mark missing proof.
+
+### Day 2
+1. **Translate execution into leadership impact** — Resume — subtasks: pick major project; capture business outcome; rewrite leadership bullet.
+2. **Practice senior stakeholder interview** — Interview — subtasks: choose target role; pick leadership round; open preview.
+3. **Draft leadership profile with agent** — Agent-Social Branding — subtasks: agent suggests strategic positioning; drafts headline; save.
+
+### Day 3
+1. **Map leadership gaps** — Pathways — subtasks: compare current vs target; identify gaps; pick one gap.
+2. **Roleplay promotion conversation** — Roleplay — subtasks: capture desired title/scope; generate preview; practice.
+3. **Agent drafts authority post** — Agent-Social Branding — subtasks: pick strategic lesson; agent drafts; publish/save.
+
+### Day 4
+1. **Leadership resume audit** — Resume — subtasks: identify execution-heavy bullets; add team/scope/outcome; save.
+2. **Practice senior team interview** — Interview — subtasks: choose round; open preview; practice.
+3. **Match with senior roles** — Job Matchmaking — subtasks: map leadership experience; score senior roles; save.
+
+### Day 5
+1. **Mock interview: leadership behavioral** — Interview — subtasks: open preview; complete; review feedback.
+2. **LinkedIn leadership positioning with agent** — Agent-Social Branding — subtasks: agent updates About; adds leadership proof; save.
+3. **Q Score check-in** — Q Score — subtasks: review movement; choose next driver; save.
+
+### Day 6
+1. **Practice salary/scope negotiation** — Roleplay — subtasks: define desired package; open preview; practice.
+2. **Build leadership proof bank** — Resume — subtasks: list team outcomes; add metrics; tag for interviews.
+3. **Draft leadership insight post with agent** — Agent-Social Branding — subtasks: agent suggests insight; drafts; publish.
+
+### Day 7
+1. **Week 1 leadership review** — Q Score — subtasks: review tasks; note score; choose week 2 focus.
+2. **Apply to senior roles** — Job Matchmaking — subtasks: select 3 roles; tailor resume; record.
+3. **Practice board/executive interview** — Interview — subtasks: choose round; open preview; save.
+
+### Day 8
+1. **STAR story: leadership example** — Interview — subtasks: choose team challenge; structure STAR; save.
+2. **Roleplay difficult stakeholder** — Roleplay — subtasks: define scenario; practice; save.
+3. **Profile credibility pass with agent** — Agent-Social Branding — subtasks: agent audits headline/About; saves.
+
+### Day 9
+1. **Resume leadership bullets final** — Resume — subtasks: refine 3 bullets; add scope/metrics; export.
+2. **Interview preview: strategy round** — Interview — subtasks: choose role; open preview; practice.
+3. **Recruiter relationship with agent** — Agent-Social Branding — subtasks: agent drafts executive recruiter intro; send.
+
+### Day 10
+1. **Mock interview: full leadership round** — Interview — subtasks: open preview; complete; review.
+2. **Q Score leadership update** — Q Score — subtasks: add leadership proof; check driver; save.
+3. **Networking follow-up** — Job Matchmaking — subtasks: follow up 3 contacts; record.
+
+### Day 11
+1. **Practice "why this company"** — Interview — subtasks: research company; draft answer; open preview.
+2. **Roleplay compensation discussion** — Roleplay — subtasks: define package; practice; save.
+3. **Authority post #2 with agent** — Agent-Social Branding — subtasks: agent drafts; publish.
+
+### Day 12
+1. **Leadership case study** — Resume — subtasks: pick transformation; write before/after; save.
+2. **Interview weakness: leadership** — Interview — subtasks: pick gap; open preview; practice.
+3. **Match with executive roles** — Job Matchmaking — subtasks: score C-suite/VP roles; save.
+
+### Day 13
+1. **Mock interview: board/executive** — Interview — subtasks: open preview; complete; review.
+2. **Profile final polish with agent** — Agent-Social Branding — subtasks: agent audits; suggests final edits; save.
+3. **Q Score final gap** — Q Score — subtasks: choose gap; complete linked task; save.
+
+### Day 14
+1. **Week 2 review** — Q Score — subtasks: review interviews; choose conversion goal.
+2. **Practice offer negotiation** — Roleplay — subtasks: define package; practice; save.
+3. **Publish leadership post with agent** — Agent-Social Branding — subtasks: agent drafts; publish.
+
+### Day 15
+1. **Leadership conversion plan** — Interview — subtasks: identify weak round; choose practice; save.
+2. **Roleplay: managing up** — Roleplay — subtasks: define scenario; practice; save.
+3. **Resume export versions** — Resume — subtasks: create 2 versions; export.
+
+### Day 16
+1. **Hard leadership question practice** — Interview — subtasks: choose 3 questions; open preview; practice.
+2. **Recruiter pipeline update** — Job Matchmaking — subtasks: list leads; next action; send.
+3. **Q Score review** — Q Score — subtasks: check driver; route next; save.
+
+### Day 17
+1. **Project deep dive: leadership** — Interview — subtasks: select project; explain tradeoffs; open preview.
+2. **Executive networking** — Job Matchmaking — subtasks: follow up 3; record.
+3. **Profile final pass with agent** — Agent-Social Branding — subtasks: agent audits; save.
+
+### Day 18
+1. **Application sprint** — Job Matchmaking — subtasks: apply to 3 roles; record.
+2. **Roleplay: rejection to next role** — Roleplay — subtasks: practice; save.
+3. **STAR story: transformation** — Interview — subtasks: structure; save.
+
+### Day 19
+1. **Mock interview: full executive round** — Interview — subtasks: open preview; complete; review.
+2. **Resume keyword pass** — Resume — subtasks: add leadership terms; export.
+3. **Thought leadership post with agent** — Agent-Social Branding — subtasks: agent drafts; publish.
+
+### Day 20
+1. **Interview answer polish** — Interview — subtasks: pick top 3; shorten; practice.
+2. **Roleplay: hiring manager discussion** — Roleplay — subtasks: define; open preview; practice.
+3. **Q Score progress** — Q Score — subtasks: compare; choose final sprint.
+
+### Day 21
+1. **Week 3 review** — Q Score — subtasks: review; identify blocker; choose final push.
+2. **Target company prep** — Job Matchmaking — subtasks: research; prepare questions.
+3. **Follow-up sprint** — Job Matchmaking — subtasks: send 3; record.
+
+### Day 22
+1. **Mock interview: target company** — Interview — subtasks: role; context; open preview.
+2. **Referral request** — Roleplay — subtasks: pick contact; practice; send.
+3. **Resume final polish** — Resume — subtasks: grammar; export.
+
+### Day 23
+1. **Negotiation prep** — Roleplay — subtasks: define; practice; save.
+2. **Portfolio proof** — Resume — subtasks: write case; save.
+3. **Q Score readiness** — Q Score — subtasks: review; choose gap; act.
+
+### Day 24
+1. **Mock interview: hard mode** — Interview — subtasks: open preview; complete; review.
+2. **LinkedIn visibility with agent** — Agent-Social Branding — subtasks: agent updates; suggests posts; send.
+3. **Conversion audit** — Job Matchmaking — subtasks: analyze; plan fix.
+
+### Day 25
+1. **Offer call roleplay** — Roleplay — subtasks: scenario; practice; save.
+2. **Interview replay** — Interview — subtasks: open preview; practice; compare.
+3. **Proof bank final** — Resume — subtasks: tag; save.
+
+### Day 26
+1. **Final application sprint** — Job Matchmaking — subtasks: apply to 3; record.
+2. **Communication drill** — Roleplay — subtasks: practice; save.
+3. **Profile proof with agent** — Agent-Social Branding — subtasks: agent drafts; publish.
+
+### Day 27
+1. **Interview questions to ask** — Interview — subtasks: draft 5; tailor; save.
+2. **Resume versions** — Resume — subtasks: create 2; export.
+3. **Q Score final push** — Q Score — subtasks: pick driver; act.
+
+### Day 28
+1. **Readiness review** — Q Score — subtasks: compare; review artifacts; choose next.
+2. **Mock interview final** — Interview — subtasks: open preview; complete; save.
+3. **Networking plan** — Job Matchmaking — subtasks: schedule; save.
+
+### Day 29
+1. **Negotiation replay** — Roleplay — subtasks: open preview; practice; save.
+2. **Pipeline review** — Job Matchmaking — subtasks: active; next actions; deadlines.
+3. **Profile final with agent** — Agent-Social Branding — subtasks: agent audits; saves.
+
+### Day 30
+1. **30-day outcome review** — Q Score — subtasks: score; wins; choose next.
+2. **Select next plan** — Pathways — subtasks: leadership, compensation, transition; save.
+3. **Claim streak** — Q Score — subtasks: claim; schedule; start next.
+
+---
+
+*End of comprehensive playbook.*
diff --git a/curator-icp-task-subtask-playbook.md b/curator-icp-task-subtask-playbook.md
new file mode 100644
index 0000000..49375bf
--- /dev/null
+++ b/curator-icp-task-subtask-playbook.md
@@ -0,0 +1,2178 @@
+# GrowQR Curator ICP Task & Subtask Playbook
+
+Date: 2026-06-15
+Purpose: define example 30/60-day streak tasks, weekly progress suggestions, and service handoffs for the GrowQR curator across core ICPs.
+
+## 1. Product framing
+
+GrowQR should not feel like a list of disconnected tools. The user experience should feel like:
+
+> Onboarding identifies my current situation, goals, blockers, and urgency. GrowQR turns that into a 30/60-day instructed growth plan. Streaks and weekly progress are the daily execution layer. Each task either creates evidence, improves confidence, raises Q Score, or moves me closer to opportunities.
+
+Core services:
+
+- **Q Score / QX Score**: readiness measurement and progress ledger.
+- **Resume**: proof packaging, role-fit evidence, credibility artifact.
+- **Interview**: confidence, articulation, offer-readiness practice.
+- **Roleplay**: high-stakes conversation practice: recruiter, manager, client, investor, negotiation.
+- **Social / personal branding**: visibility, trust, inbound surface area.
+- **Pathways / matchmaking**: convert readiness into direction, jobs, clients, collaborators, or customers.
+
+The curator should always answer: **why this task today, what service it unlocks, and what the user gets after completing it.**
+
+---
+
+## 2. ICP taxonomy from onboarding
+
+### A. Individual career users
+
+Onboarding signals:
+
+- Intent: better job, feel stuck, grow here, know where I stand.
+- Current state: actively hunting, employed but ready to move, between jobs, student/recent grad, exploring.
+- Blockers: don't know where to start, no callbacks, interviews not converting, weak profile, stuck in role, not enough time.
+- Goal: land exciting role, higher pay, switch field, build skills, leadership, start own thing.
+- Work area: tech/product/data, design/creative, sales/growth/partnerships, leadership/strategy, student, other.
+- Experience: 0-2, 2-5, 5-10, 10+ years.
+- Pace: 1-month sprint, 3-month steady climb, flexible long game.
+
+Primary sub-segments for this doc:
+
+1. Students / recent grads.
+2. Interns.
+3. Freshers / early professionals under 5 years.
+4. Experienced professionals above 5 years.
+
+### B. Gig / freelance users
+
+Onboarding signals:
+
+- Current state: just starting, few clients, steady income, ready to scale, side hustle.
+- Blockers: client pipeline, pricing, standing out, online trust, income consistency, referrals.
+- Goal: consistent pipeline, higher rates, work I love, personal brand, full-time freelancing, recurring income.
+- Service area: design, tech/dev, writing/content, consulting/strategy, coaching/training, marketing/social.
+- Experience: new, under 1 year, 1-3 years, 3+ years.
+- First milestone: first client, double income, full-time, Rs 1L/month, waitlist.
+
+### C. Founder / solopreneur users
+
+Onboarding signals:
+
+- Stage: idea, MVP, traction, scaling, pre-revenue.
+- Blockers: team, funding, visibility, customers, proving model, burn.
+- Goal: hire key people, raise, authority, first 100 customers, validate idea, cofounder.
+- Space: B2B SaaS, consumer, marketplace, deeptech/hardware, services/agency, other.
+- Founder type: first-time, built before, serial, operator turned founder.
+- 90-day priority: ship MVP, close customers, hire, raise pre-seed, build presence.
+
+---
+
+## 3. Curator task design rules
+
+Every curator task should have:
+
+1. **Business reason**: why this helps the user's stated outcome.
+2. **Service owner**: Q Score, Resume, Interview, Roleplay, Social, Pathways, Matchmaking.
+3. **One focused action**: no broad advice.
+4. **Subtasks**: 2-4 small steps max.
+5. **Handoff**: if service-backed, the user should land directly in a useful preview/setup state.
+6. **Signal**: what will improve in Q Score or user readiness ledger.
+7. **Timebox**: preferably 5, 10, 15, or 20 minutes.
+
+Good task title examples:
+
+- “Prepare your first PM interview preview”
+- “Turn your project into a resume proof point”
+- “Practice your salary ask with a recruiter”
+- “Package your first freelance offer”
+- “Draft your founder credibility post”
+
+Bad task title examples:
+
+- “Improve career”
+- “Use interview service”
+- “Complete profile”
+- “Do task 1”
+
+---
+
+## 4. Universal 30/60-day plan structure
+
+### Days 1-7: Baseline and first proof
+
+Goal: establish Q Score baseline, identify target, create first useful artifact.
+
+Common tasks:
+
+- Complete Q Score baseline.
+- Upload/import resume, LinkedIn, portfolio, GitHub, website, pitch deck.
+- Pick one target outcome.
+- Generate first service preview: interview, roleplay, resume audit, or profile audit.
+- Complete one confidence-building practice.
+
+### Days 8-14: Fix obvious gaps
+
+Goal: remove blockers surfaced by onboarding.
+
+Common tasks:
+
+- Rewrite weak headline / summary / resume bullets.
+- Practice top interview or conversation blocker.
+- Build proof bank: projects, client wins, traction, metrics.
+- Create first public credibility artifact.
+
+### Days 15-30: Repetition and market-facing action
+
+Goal: repeat practice, publish/apply/reach out, collect feedback.
+
+Common tasks:
+
+- 2-4 mock interviews or roleplays.
+- 5 targeted applications / leads / warm intros.
+- One profile/resume iteration using results.
+- One Q Score check-in.
+
+### Days 31-60: Conversion loop
+
+Goal: convert readiness into outcomes.
+
+Common tasks:
+
+- Interview-to-offer loop.
+- Salary/client/investor conversation practice.
+- Stronger market proof: case study, portfolio, founder update.
+- Matchmaking / opportunities / collaborator pipeline.
+
+---
+
+## 5. ICP playbooks
+
+## 5.1 Students / recent grads
+
+### Main jobs-to-be-done
+
+- Figure out what roles to target.
+- Build a credible identity before graduation.
+- Turn coursework/projects into proof.
+- Practice interviews before real rounds.
+- Build confidence and a daily habit.
+
+### Suggested 30-day plan theme
+
+**“First Role Readiness Sprint”**
+
+### Example weekly progress suggestions
+
+#### Task: Pick your first target role
+
+Service: Pathways / Q Score
+Business reason: students often lack direction; role clarity makes resume and interview prep specific.
+
+Subtasks:
+
+1. Choose 1-2 role families: software, product, data, design, growth, consulting.
+2. Capture current strengths: coursework, projects, internships, societies.
+3. Compare requirements against your current proof.
+4. Save target role into GrowQR plan.
+
+Curator first question:
+
+> Which role family do you want to prepare for first: engineering, product, data, design, growth, or something else?
+
+CTA:
+
+- “Review pathway”
+- “Update Q Score baseline”
+
+Signals:
+
+- goal clarity
+- role alignment
+- readiness baseline
+
+#### Task: Turn one project into resume proof
+
+Service: Resume
+Business reason: students usually have weak experience sections but strong hidden project evidence.
+
+Subtasks:
+
+1. Pick one project/coursework/internship.
+2. Capture problem, action, result.
+3. Convert it into 2 resume bullets.
+4. Save to resume workspace.
+
+Curator first question:
+
+> Which project should we package today, and what did it achieve?
+
+CTA:
+
+- “Open resume workspace”
+
+Signals:
+
+- resume evidence
+- proof density
+- project articulation
+
+#### Task: Prepare first mock interview preview
+
+Service: Interview
+Business reason: early practice reduces anxiety and creates interview readiness signals.
+
+Subtasks:
+
+1. Pick role and round type.
+2. Choose difficulty: easy/medium.
+3. Generate interview preview.
+4. Complete the practice and review feedback.
+
+Curator first question:
+
+> What role should I prepare this mock interview for?
+
+Default preview:
+
+- type: behavioral
+- difficulty: medium
+- duration: 5 minutes
+- media: audio or video depending quota/default
+
+CTA:
+
+- “Open interview preview”
+
+Signals:
+
+- interview confidence
+- communication clarity
+- Q Score practice signal
+
+#### Task: Practice “Tell me about yourself”
+
+Service: Roleplay or Interview
+Business reason: this is the most reusable first-round answer.
+
+Subtasks:
+
+1. Capture target role.
+2. Capture current student background.
+3. Practice 60-second pitch.
+4. Save improved version.
+
+Curator first question:
+
+> What role should your intro be tailored toward?
+
+CTA:
+
+- “Open roleplay preview” or “Open interview preview”
+
+Signals:
+
+- self-pitch quality
+- confidence
+- communication readiness
+
+#### Task: Build your first credibility post
+
+Service: Social / Personal branding
+Business reason: public proof can increase recruiter trust even before full-time experience.
+
+Subtasks:
+
+1. Pick a project or learning insight.
+2. Draft a LinkedIn post.
+3. Add one measurable takeaway.
+4. Save/publish.
+
+Curator first question:
+
+> Which project or lesson should this post highlight?
+
+CTA:
+
+- “Draft profile post”
+
+Signals:
+
+- visibility
+- public proof
+- profile strength
+
+---
+
+## 5.2 Interns
+
+### Main jobs-to-be-done
+
+- Convert internship into full-time offer.
+- Communicate impact to manager/team.
+- Build workplace confidence.
+- Prepare for return offer or external interviews.
+
+### Suggested 30-day plan theme
+
+**“Intern-to-Offer Sprint”**
+
+### Example tasks
+
+#### Task: Capture your internship impact
+
+Service: Resume / Q Score
+
+Subtasks:
+
+1. List current internship project.
+2. Capture metric or visible outcome.
+3. Convert into resume bullet.
+4. Add to proof bank.
+
+Curator first question:
+
+> What project are you working on in your internship, and what changed because of your work?
+
+CTA:
+
+- “Open resume workspace”
+
+Signals:
+
+- proof density
+- experience clarity
+
+#### Task: Practice manager check-in
+
+Service: Roleplay
+
+Subtasks:
+
+1. Define desired outcome: feedback, extension, full-time offer, better project.
+2. Capture manager context.
+3. Generate roleplay preview.
+4. Practice the check-in.
+
+Curator first question:
+
+> What do you want from the manager conversation: feedback, return offer, clearer expectations, or project scope?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- workplace communication
+- confidence
+- initiative
+
+#### Task: Prepare return-offer interview
+
+Service: Interview
+
+Subtasks:
+
+1. Choose role/function.
+2. Capture internship project context.
+3. Generate preview.
+4. Complete one mock round.
+
+Curator first question:
+
+> Which return-offer role or team should this interview prepare you for?
+
+CTA:
+
+- “Open interview preview”
+
+Signals:
+
+- interview readiness
+- internship conversion readiness
+
+#### Task: Write your weekly internship update
+
+Service: Social / Resume
+
+Subtasks:
+
+1. Capture what shipped this week.
+2. Capture what you learned.
+3. Draft manager-ready update.
+4. Save one resume proof point.
+
+Curator first question:
+
+> What did you complete or learn this week that your manager should notice?
+
+CTA:
+
+- “Draft update”
+
+Signals:
+
+- communication discipline
+- workplace visibility
+
+---
+
+## 5.3 Freshers / early professionals under 5 years
+
+### Main jobs-to-be-done
+
+- Get callbacks.
+- Convert interviews.
+- Switch role/field or grow compensation.
+- Build confidence and sharper positioning.
+
+### Suggested 30-day plan themes
+
+- **“Callback Recovery Sprint”** for no callbacks.
+- **“Interview Conversion Sprint”** for interviews not converting.
+- **“Role Switch Sprint”** for career transition.
+
+### Example tasks
+
+#### Task: Diagnose why callbacks are low
+
+Service: Resume / Q Score
+
+Subtasks:
+
+1. Select target role.
+2. Upload or open resume.
+3. Run resume role-fit audit.
+4. Save top 3 fixes.
+
+Curator first question:
+
+> What role are you applying for most often right now?
+
+CTA:
+
+- “Open resume audit”
+
+Signals:
+
+- resume fit
+- role alignment
+- application readiness
+
+#### Task: Rewrite your headline and summary
+
+Service: Social / Resume
+
+Subtasks:
+
+1. Capture current role and target role.
+2. Capture 2 strongest proof points.
+3. Generate headline options.
+4. Save best version.
+
+Curator first question:
+
+> What target role should your profile headline sell you for?
+
+CTA:
+
+- “Draft profile update”
+
+Signals:
+
+- profile clarity
+- recruiter discoverability
+
+#### Task: Generate interview preview for target role
+
+Service: Interview
+
+Subtasks:
+
+1. Confirm role.
+2. Pick round type: behavioral, role-related, warm-up.
+3. Generate preview.
+4. Practice and review feedback.
+
+Curator first question:
+
+> Which role and interview round should I prepare for you today?
+
+CTA:
+
+- “Open interview preview”
+
+Signals:
+
+- interview practice
+- answer structure
+- confidence
+
+#### Task: Practice salary expectation answer
+
+Service: Roleplay
+
+Subtasks:
+
+1. Capture current/target salary or range.
+2. Capture role and recruiter context.
+3. Generate negotiation roleplay preview.
+4. Practice answer.
+
+Curator first question:
+
+> What salary conversation do you need to prepare for: recruiter screen, offer call, or manager discussion?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- negotiation confidence
+- communication readiness
+
+#### Task: Build one STAR story
+
+Service: Interview / Resume
+
+Subtasks:
+
+1. Pick one work/project situation.
+2. Capture task/action/result.
+3. Convert to STAR answer.
+4. Practice it in interview preview.
+
+Curator first question:
+
+> Which achievement or challenge should we turn into a STAR story today?
+
+CTA:
+
+- “Open interview preview”
+
+Signals:
+
+- story bank depth
+- answer quality
+
+---
+
+## 5.4 Experienced professionals above 5 years
+
+### Main jobs-to-be-done
+
+- Move into leadership or higher compensation.
+- Communicate strategic impact.
+- Prepare for senior interviews.
+- Negotiate scope, salary, title, or authority.
+
+### Suggested plan theme
+
+**“Leadership Readiness Sprint”**
+
+### Example tasks
+
+#### Task: Translate execution into leadership impact
+
+Service: Resume
+
+Subtasks:
+
+1. Pick one major project.
+2. Capture business outcome, team size, scope.
+3. Rewrite into leadership bullet.
+4. Save to resume.
+
+Curator first question:
+
+> Which project best proves you can lead beyond individual execution?
+
+CTA:
+
+- “Open resume workspace”
+
+Signals:
+
+- leadership proof
+- seniority alignment
+
+#### Task: Practice senior stakeholder interview
+
+Service: Interview
+
+Subtasks:
+
+1. Choose target role.
+2. Pick round: leadership, strategy, behavioral.
+3. Generate preview.
+4. Complete mock.
+
+Curator first question:
+
+> What senior role or leadership round should this mock prepare you for?
+
+CTA:
+
+- “Open interview preview”
+
+Signals:
+
+- executive communication
+- senior interview readiness
+
+#### Task: Roleplay promotion conversation
+
+Service: Roleplay
+
+Subtasks:
+
+1. Capture desired title/scope.
+2. Capture manager/stakeholder context.
+3. Generate promotion conversation preview.
+4. Practice and refine ask.
+
+Curator first question:
+
+> What are you asking for: title change, salary increase, larger scope, or leadership opportunity?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- negotiation confidence
+- leadership communication
+
+#### Task: Build authority proof post
+
+Service: Social
+
+Subtasks:
+
+1. Pick strategic lesson.
+2. Add one example from your work.
+3. Draft concise post.
+4. Save/publish.
+
+Curator first question:
+
+> What leadership lesson or strategic insight can you credibly talk about this week?
+
+CTA:
+
+- “Draft authority post”
+
+Signals:
+
+- market visibility
+- senior credibility
+
+---
+
+## 5.5 Freelancers and gig workers
+
+### Main jobs-to-be-done
+
+- Find clients consistently.
+- Stand out in crowded markets.
+- Price confidently.
+- Build trust online.
+- Move from inconsistent income to predictable pipeline.
+
+### Suggested 30-day plan themes
+
+- **“First Client Sprint”** for new freelancers.
+- **“Pipeline Stabilizer”** for feast/famine.
+- **“Premium Rate Sprint”** for pricing/positioning.
+
+### Example tasks
+
+#### Task: Package your offer clearly
+
+Service: Resume/Profile/Social
+
+Subtasks:
+
+1. Define target client.
+2. Define painful problem solved.
+3. Package one clear offer.
+4. Save as profile headline/portfolio intro.
+
+Curator first question:
+
+> Who do you want to serve first, and what problem do you solve for them?
+
+CTA:
+
+- “Draft offer profile”
+
+Signals:
+
+- positioning clarity
+- client readiness
+
+#### Task: Practice discovery call
+
+Service: Roleplay
+
+Subtasks:
+
+1. Choose client type.
+2. Define service offered.
+3. Generate discovery call preview.
+4. Practice handling objections.
+
+Curator first question:
+
+> What kind of client call should we rehearse: first discovery, pricing, scope, or renewal?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- sales confidence
+- client communication
+
+#### Task: Build pricing confidence script
+
+Service: Roleplay
+
+Subtasks:
+
+1. Capture current rate and target rate.
+2. Capture service value.
+3. Generate pricing conversation.
+4. Practice saying the rate clearly.
+
+Curator first question:
+
+> What service are you pricing, and what rate do you want to confidently quote?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- pricing confidence
+- sales readiness
+
+#### Task: Turn a client/project into a case study
+
+Service: Resume/Profile/Social
+
+Subtasks:
+
+1. Pick a project.
+2. Capture before/after/result.
+3. Draft case study summary.
+4. Add to portfolio/profile.
+
+Curator first question:
+
+> Which project best proves the outcome you deliver for clients?
+
+CTA:
+
+- “Draft case study”
+
+Signals:
+
+- proof quality
+- trust surface area
+
+#### Task: Draft one inbound post
+
+Service: Social
+
+Subtasks:
+
+1. Pick client pain point.
+2. Add quick teaching insight.
+3. Draft post.
+4. Save/publish.
+
+Curator first question:
+
+> What client problem do you want to be known for solving?
+
+CTA:
+
+- “Draft LinkedIn post”
+
+Signals:
+
+- visibility
+- inbound readiness
+
+---
+
+## 5.6 Solopreneurs and founders
+
+### Main jobs-to-be-done
+
+- Validate idea.
+- Build public credibility.
+- Find customers, investors, cofounders, or hires.
+- Practice high-stakes conversations.
+- Convert founder identity into trust.
+
+### Suggested 30/60-day themes
+
+- **“MVP Validation Sprint”**
+- **“First 100 Customers Sprint”**
+- **“Founder Visibility Sprint”**
+- **“Fundraising Readiness Sprint”**
+- **“Cofounder / First Hire Sprint”**
+
+### Example tasks
+
+#### Task: Clarify founder one-liner
+
+Service: Social / Q Score
+
+Subtasks:
+
+1. Capture product, audience, problem.
+2. Draft one-line positioning.
+3. Compare against current profile.
+4. Save as founder identity statement.
+
+Curator first question:
+
+> In one sentence, what are you building, for whom, and what painful problem does it solve?
+
+CTA:
+
+- “Draft founder profile”
+
+Signals:
+
+- positioning clarity
+- founder credibility
+
+#### Task: Practice customer discovery call
+
+Service: Roleplay
+
+Subtasks:
+
+1. Define customer segment.
+2. Define assumption to validate.
+3. Generate discovery roleplay preview.
+4. Practice asking non-leading questions.
+
+Curator first question:
+
+> Which customer segment should this discovery call simulate?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- customer discovery skill
+- validation readiness
+
+#### Task: Practice investor intro
+
+Service: Roleplay
+
+Subtasks:
+
+1. Capture stage: idea, MVP, traction, raise.
+2. Capture traction or proof.
+3. Generate investor conversation preview.
+4. Practice concise pitch and objection handling.
+
+Curator first question:
+
+> Are you pitching an idea, MVP, traction story, or active fundraise?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- fundraising readiness
+- founder communication
+
+#### Task: Prepare first-hire interview
+
+Service: Interview / Roleplay
+
+Subtasks:
+
+1. Define role needed.
+2. Capture what success looks like.
+3. Generate interview or roleplay preview.
+4. Practice evaluating fit.
+
+Curator first question:
+
+> What key role are you trying to hire or find as a collaborator?
+
+CTA:
+
+- “Open interview preview” or “Open roleplay preview”
+
+Signals:
+
+- hiring readiness
+- team-building clarity
+
+#### Task: Draft build-in-public update
+
+Service: Social
+
+Subtasks:
+
+1. Pick milestone or learning.
+2. Add founder insight.
+3. Draft post.
+4. Save/publish.
+
+Curator first question:
+
+> What did you learn or ship this week that would build trust with customers, investors, or collaborators?
+
+CTA:
+
+- “Draft founder update”
+
+Signals:
+
+- authority
+- visibility
+- credibility
+
+#### Task: Validate pricing or business model
+
+Service: Roleplay / Q Score
+
+Subtasks:
+
+1. Capture pricing hypothesis.
+2. Pick target buyer.
+3. Roleplay pricing conversation.
+4. Save learning.
+
+Curator first question:
+
+> What price or business model assumption do you need to test first?
+
+CTA:
+
+- “Open roleplay preview”
+
+Signals:
+
+- model validation
+- buyer communication
+
+---
+
+## 6. Service-specific task libraries
+
+## 6.1 Interview task library
+
+Use for students, interns, freshers, experienced professionals, and founders hiring candidates.
+
+Task examples:
+
+1. First mock interview for target role.
+2. Behavioral round preview.
+3. Role-related technical/product/design/data round.
+4. Internship return-offer interview.
+5. Senior leadership interview.
+6. Career switch interview.
+7. Founder first-hire interview.
+8. STAR story practice.
+9. Weakness/strength answer practice.
+10. “Tell me about yourself” practice.
+
+Standard subtasks:
+
+1. Capture target role.
+2. Capture round type.
+3. Capture difficulty or pressure level.
+4. Generate preview.
+5. Complete session.
+6. Review feedback and update Q Score.
+
+Default preview params:
+
+- role: inferred from onboarding target, user answer, task context.
+- type: behavioral unless task says technical/role-related.
+- difficulty: medium.
+- duration: 5 minutes for streak tasks.
+- source: curator-v1 or daily-mission.
+
+Good CTA copy:
+
+- “Open interview preview”
+- “Preview your mock interview”
+- “Start from preview”
+
+## 6.2 Roleplay task library
+
+Use for conversations where the user needs to speak with another person.
+
+Task examples:
+
+1. Recruiter screen practice.
+2. Salary expectation conversation.
+3. Offer negotiation.
+4. Manager promotion ask.
+5. Internship return-offer check-in.
+6. Client discovery call.
+7. Freelance pricing call.
+8. Scope creep conversation.
+9. Investor intro.
+10. Customer discovery.
+11. Cofounder alignment conversation.
+12. Difficult stakeholder conversation.
+
+Standard subtasks:
+
+1. Capture scenario.
+2. Capture counterpart.
+3. Capture desired outcome.
+4. Generate preview.
+5. Practice.
+6. Save best script or learning.
+
+Default preview params:
+
+- scenario: inferred from task and answer.
+- counterpart: recruiter, manager, client, investor, customer, cofounder, stakeholder.
+- outcome: offer, feedback, price agreement, intro, validation, next step.
+- source: curator-v1 or daily-mission.
+
+Good CTA copy:
+
+- “Open roleplay preview”
+- “Practice this conversation”
+- “Preview roleplay scenario”
+
+## 6.3 Resume/profile task library
+
+Task examples:
+
+1. Resume baseline upload.
+2. Role-fit audit.
+3. Rewrite top 3 bullets.
+4. Add project proof.
+5. Convert internship to experience.
+6. Convert freelance project to case study.
+7. Founder profile rewrite.
+8. Leadership impact rewrite.
+9. LinkedIn headline and summary.
+10. Portfolio/GitHub audit.
+
+Standard subtasks:
+
+1. Capture target role or audience.
+2. Import/upload artifact.
+3. Identify top gap.
+4. Generate rewrite.
+5. Save changes.
+
+Good CTA copy:
+
+- “Open resume workspace”
+- “Review profile audit”
+- “Rewrite this proof point”
+
+## 6.4 Q Score task library
+
+Task examples:
+
+1. Complete baseline Q Score.
+2. Review weakest readiness driver.
+3. Compare current vs target role.
+4. Check confidence after mock interview.
+5. Update proof ledger after resume change.
+6. Weekly progress check-in.
+7. Readiness gap summary.
+
+Standard subtasks:
+
+1. Confirm target.
+2. Review score breakdown.
+3. Pick one driver to improve.
+4. Route to service action.
+5. Recalculate signal.
+
+Good CTA copy:
+
+- “Review Q Score”
+- “See readiness gaps”
+- “Pick next driver”
+
+## 6.5 Social / branding task library
+
+Task examples:
+
+1. LinkedIn headline rewrite.
+2. About section rewrite.
+3. Weekly project post.
+4. Founder build-in-public update.
+5. Freelance case study post.
+6. Student learning proof post.
+7. Leadership insight post.
+8. Recruiter-facing profile polish.
+9. Investor-facing founder profile polish.
+
+Standard subtasks:
+
+1. Pick audience.
+2. Pick proof/insight.
+3. Draft copy.
+4. Save/publish.
+5. Track profile signal.
+
+Good CTA copy:
+
+- “Draft post”
+- “Update profile”
+- “Save authority proof”
+
+---
+
+## 7. Three-suggestion weekly progress model
+
+When a user clicks the streak/week progress component, show three suggestions that map to their onboarding state.
+
+### Suggested formula
+
+1. **One measurement task**: Q Score / readiness check.
+2. **One proof task**: resume/profile/project/case study.
+3. **One practice task**: interview or roleplay preview.
+
+### Examples by ICP
+
+#### Student
+
+1. “Pick your first target role” - Q Score / Pathways.
+2. “Turn one project into resume proof” - Resume.
+3. “Practice your first mock interview” - Interview.
+
+#### Intern
+
+1. “Capture internship impact” - Resume.
+2. “Practice manager check-in” - Roleplay.
+3. “Prepare return-offer interview” - Interview.
+
+#### Fresher under 5 years
+
+1. “Diagnose why callbacks are low” - Resume/Q Score.
+2. “Build one STAR story” - Interview.
+3. “Practice salary expectation answer” - Roleplay.
+
+#### Freelancer
+
+1. “Package your offer clearly” - Profile.
+2. “Practice discovery call” - Roleplay.
+3. “Draft one inbound post” - Social.
+
+#### Founder / solopreneur
+
+1. “Clarify founder one-liner” - Social/Q Score.
+2. “Practice customer discovery call” - Roleplay.
+3. “Draft build-in-public update” - Social.
+
+---
+
+## 8. Example generated curator tasks
+
+These are examples of what the backend curator could generate as `CuratorTask`-like objects.
+
+### Student example
+
+```json
+{
+ "title": "Prepare your first PM interview preview",
+ "subtitle": "Turn your student projects into a confident first-round story.",
+ "serviceId": "interview-service",
+ "serviceName": "Interview service",
+ "cta": "Open interview preview",
+ "contextNarrative": "The user is a student/recent grad targeting product roles and needs confidence before first interviews.",
+ "subtasks": [
+ "Confirm target role and round type",
+ "Pick one project to use as proof",
+ "Generate mock interview preview",
+ "Complete practice and review feedback"
+ ],
+ "signals": ["interview.confidence", "role_alignment", "communication_clarity"]
+}
+```
+
+### Freelancer example
+
+```json
+{
+ "title": "Practice your next pricing conversation",
+ "subtitle": "Build confidence quoting your rate without discounting too early.",
+ "serviceId": "roleplay-service",
+ "serviceName": "Roleplay service",
+ "cta": "Open roleplay preview",
+ "contextNarrative": "The user is a freelancer who selected pricing confidently as a blocker.",
+ "subtasks": [
+ "Capture service and target client",
+ "Capture current and target rate",
+ "Generate pricing roleplay preview",
+ "Practice objection handling"
+ ],
+ "signals": ["pricing_confidence", "client_communication", "sales_readiness"]
+}
+```
+
+### Founder example
+
+```json
+{
+ "title": "Rehearse your customer discovery call",
+ "subtitle": "Validate the riskiest assumption before building more.",
+ "serviceId": "roleplay-service",
+ "serviceName": "Roleplay service",
+ "cta": "Open roleplay preview",
+ "contextNarrative": "The user is a first-time founder at idea/MVP stage trying to validate customers.",
+ "subtasks": [
+ "Choose customer segment",
+ "Capture assumption to validate",
+ "Generate discovery call preview",
+ "Save learning after practice"
+ ],
+ "signals": ["customer_discovery", "validation_readiness", "founder_communication"]
+}
+```
+
+---
+
+## 9. Curator prompt guidance
+
+The prompt should make the curator act like a productized growth coach, not a generic chatbot.
+
+### Voice
+
+- Warm, direct, concise.
+- One question at a time.
+- No long motivational paragraphs.
+- No internal route names in text.
+- Always explain the business value in plain words.
+
+### First-turn examples
+
+Interview task:
+
+> This is your practice step for today. What role or interview round should I prepare the preview for?
+
+Roleplay task:
+
+> Let's rehearse the conversation before it matters. Who are you speaking with: recruiter, manager, client, investor, or customer?
+
+Resume task:
+
+> Let's turn your experience into proof. What role or audience should this resume section target?
+
+Founder task:
+
+> Let's make this useful for your next milestone. Are you trying to validate customers, raise, hire, or build visibility first?
+
+### Handoff-ready examples
+
+Interview:
+
+> Got it. I prepared a mock interview preview for Product Manager behavioral practice. Open the preview to start or adjust the setup.
+
+Roleplay:
+
+> Got it. I prepared a roleplay preview for a salary conversation with a recruiter. Open the preview to practice or adjust details.
+
+Resume:
+
+> Saved. Open the resume workspace and we will turn this into role-fit proof.
+
+---
+
+## 10. UX requirements for streak chat
+
+The DailyRetentionStrip chat should show:
+
+1. Assistant message.
+2. User answer.
+3. Assistant summary.
+4. Service preview card when handoff is ready.
+5. Persistent CTA even after subtask is marked complete.
+
+CTA card fields:
+
+- Eyebrow: `INTERVIEW PREVIEW`, `ROLEPLAY PREVIEW`, `RESUME WORKSPACE`, `Q SCORE CHECK`.
+- Title: clear outcome.
+- Subtitle: why this helps.
+- Details: role, scenario, difficulty, duration, service.
+- Button: action verb.
+
+Important: for interview and roleplay, the CTA should route to preview or preview-equivalent state, not a blank setup screen.
+
+---
+
+## 11. Prioritization matrix
+
+### If user blocker is “not getting callbacks”
+
+Priority:
+
+1. Resume role-fit audit.
+2. LinkedIn/profile rewrite.
+3. Interview warm-up only after proof improves.
+
+### If blocker is “interviews not converting”
+
+Priority:
+
+1. Interview preview.
+2. STAR story practice.
+3. Roleplay recruiter or salary conversation.
+
+### If blocker is “don't know where to start”
+
+Priority:
+
+1. Q Score baseline.
+2. Pathway/target role selection.
+3. One small proof task.
+
+### If blocker is “pricing confidently”
+
+Priority:
+
+1. Offer packaging.
+2. Pricing roleplay.
+3. Case study proof.
+
+### If blocker is “fundraising”
+
+Priority:
+
+1. Founder one-liner.
+2. Investor roleplay.
+3. Founder authority post.
+
+### If blocker is “finding customers”
+
+Priority:
+
+1. Customer segment clarity.
+2. Discovery roleplay.
+3. Build-in-public/customer pain post.
+
+---
+
+## 12. Implementation implications
+
+For the upcoming engineering pass:
+
+1. The curator prompt should be externalized so these rules can be edited without TypeScript changes.
+2. `CuratorTask` generation should use onboarding answers to pick ICP, blocker, goal, urgency, service, and task library.
+3. The streak chat should not reuse TalkToMe route/component; it should only borrow UX patterns.
+4. Interview and roleplay handoffs should route directly to preview or preview-equivalent pages with default params.
+5. Handoff CTA should be deterministic and persistent.
+6. Completion should not hide the next action.
+7. Every daily task should map to at least one Q Score/progress signal.
+
+---
+
+## 13. Open product questions
+
+1. Should students get a 30-day default and professionals/founders get 60-day default, or should plan length depend on urgency?
+2. Should Q Score visible baseline always start at 35 after onboarding, or vary by imported proof quality?
+3. Should streak completion require service completion, or just curator context capture?
+4. Should interview/roleplay preview generation count as a streak completion, or only completed session/review?
+5. Should freelancers and founders see “Q Score” language, “QX Score”, or a more business-facing label like “Credibility Score”?
+6. Should social branding be a first-class service in the curator registry for all ICPs?
+7. Should preview cards support “Change details” quick action directly inside the chat?
+
+
+---
+
+# 14. Literal 30-day progression examples by ICP
+
+Use these as concrete seed examples for curator plans. Each day has three suggestions. Each suggestion includes small subtasks. In production, pick/modify based on onboarding signals, imported resume/LinkedIn/portfolio data, service history, and completion events.
+
+## 14.1 Student / recent grad: First Role Readiness Sprint
+
+Onboarding pattern: `individual + student/recent grad + 0-2 years + role/skills + before graduation/within 6 months`.
+
+### Day 1
+1. **Set your first target role** — subtasks: pick role family; choose target role; save role goal.
+2. **Start Q Score baseline** — subtasks: review baseline score; pick weakest driver; save first improvement focus.
+3. **Upload resume or LinkedIn** — subtasks: import profile; confirm education/projects; mark missing proof.
+
+### Day 2
+1. **Turn one project into proof** — subtasks: choose project; capture problem/action/result; draft 2 bullets.
+2. **Prepare first mock interview preview** — subtasks: confirm role; select behavioral round; open preview.
+3. **Draft student profile headline** — subtasks: pick target audience; write headline; save best version.
+
+### Day 3
+1. **Practice “Tell me about yourself”** — subtasks: capture background; pick one project proof; open interview preview.
+2. **Map role requirements** — subtasks: list 3 must-have skills; mark known gaps; choose one gap to fix.
+3. **Create first credibility post** — subtasks: pick project insight; draft post; save/publish.
+
+### Day 4
+1. **Resume gap scan** — subtasks: compare resume to role; identify weak section; open resume workspace.
+2. **Roleplay recruiter intro** — subtasks: choose recruiter scenario; define desired next step; open roleplay preview.
+3. **Build proof bank v1** — subtasks: list projects; add metrics; tag best 3 for interviews.
+
+### Day 5
+1. **Mock interview: easy warm-up** — subtasks: open preview; complete 5-min round; review feedback.
+2. **Rewrite project bullet** — subtasks: select weak bullet; add action verb; add outcome.
+3. **Q Score check-in** — subtasks: review changed drivers; log confidence; choose weekend focus.
+
+### Day 6
+1. **Prepare application shortlist** — subtasks: choose 5 roles; score fit; save top 2.
+2. **Practice common HR screen** — subtasks: choose fresher screen; capture expected questions; open roleplay preview.
+3. **Polish LinkedIn About** — subtasks: draft 3-line summary; add role target; save update.
+
+### Day 7
+1. **Weekly readiness review** — subtasks: review completed tasks; note score movement; pick next week theme.
+2. **Create STAR story #1** — subtasks: choose challenge; write situation/task/action/result; save story.
+3. **Apply to two aligned roles** — subtasks: pick roles; tailor resume headline; record applications.
+
+### Day 8
+1. **Skill gap micro-plan** — subtasks: pick one missing skill; choose resource; schedule 3 practice blocks.
+2. **Interview preview: role-related** — subtasks: confirm role; select role-related round; open preview.
+3. **Improve education/project section** — subtasks: remove filler; add relevant coursework; add project result.
+
+### Day 9
+1. **Practice project explanation** — subtasks: pick project; define architecture/approach; open interview preview.
+2. **Draft outreach message** — subtasks: choose alumni/recruiter; write 80-word note; save/send.
+3. **Update Q Score proof ledger** — subtasks: add project proof; tag skill; refresh readiness driver.
+
+### Day 10
+1. **Mock interview: medium pressure** — subtasks: open preview; complete round; save feedback.
+2. **Fix top resume weakness** — subtasks: select weakness; rewrite section; compare before/after.
+3. **Roleplay networking call** — subtasks: choose alumni scenario; define ask; open roleplay preview.
+
+### Day 11
+1. **Build portfolio/GitHub proof** — subtasks: select repo/project; write README summary; add outcome.
+2. **Practice weakness answer** — subtasks: choose honest weakness; add improvement proof; open interview preview.
+3. **Draft learning post** — subtasks: pick technical lesson; write concise post; save/publish.
+
+### Day 12
+1. **Application tailoring sprint** — subtasks: select one JD; map keywords; tailor 3 bullets.
+2. **Roleplay recruiter callback** — subtasks: define screen goal; practice intro; save best answer.
+3. **Q Score confidence pulse** — subtasks: rate confidence; compare to day 1; choose next practice.
+
+### Day 13
+1. **Mock interview review loop** — subtasks: read feedback; pick one weak pattern; generate next preview.
+2. **Build STAR story #2** — subtasks: choose teamwork example; structure STAR; save story.
+3. **Profile credibility check** — subtasks: review headline/About; add project link; save update.
+
+### Day 14
+1. **Week 2 review** — subtasks: review applications/practice; log wins; pick week 3 conversion goal.
+2. **Apply to three roles** — subtasks: select roles; tailor resume; record status.
+3. **Practice first-round interview** — subtasks: open preview; complete round; save feedback.
+
+### Day 15
+1. **Build interview story bank** — subtasks: list 5 stories; tag leadership/teamwork/problem-solving; save.
+2. **Roleplay salary expectation** — subtasks: define range; practice recruiter answer; save script.
+3. **Improve resume summary** — subtasks: write target summary; remove vague words; save.
+
+### Day 16
+1. **Technical/role skill drill** — subtasks: pick weak topic; answer 3 questions; log confidence.
+2. **Mock interview: targeted weakness** — subtasks: choose weak area; open preview; practice.
+3. **Draft recruiter follow-up** — subtasks: choose application; write follow-up; send/record.
+
+### Day 17
+1. **Project deep-dive practice** — subtasks: select project; explain tradeoffs; open interview preview.
+2. **Portfolio polish** — subtasks: add screenshot/demo link; write impact; save.
+3. **Q Score readiness check** — subtasks: review score; identify lowest service signal; route next action.
+
+### Day 18
+1. **Roleplay group discussion** — subtasks: define scenario; practice concise contribution; save feedback.
+2. **Resume bullet metrics pass** — subtasks: find vague bullets; add numbers/scope; save.
+3. **Publish proof post** — subtasks: pick project outcome; draft; publish/save.
+
+### Day 19
+1. **Mock interview: medium full round** — subtasks: open preview; complete; review feedback.
+2. **Application quality audit** — subtasks: review last 5 applications; identify mismatch; adjust target list.
+3. **Networking ask practice** — subtasks: pick contact; roleplay ask; send message.
+
+### Day 20
+1. **Create final fresher pitch** — subtasks: draft 60-sec pitch; practice; save best version.
+2. **Interview confidence repair** — subtasks: pick anxiety point; run warm-up preview; note improvement.
+3. **Role-fit score update** — subtasks: compare proof to JD; update gaps; choose next proof.
+
+### Day 21
+1. **Week 3 conversion review** — subtasks: review callbacks; review mock scores; choose final sprint focus.
+2. **Prepare top-company version** — subtasks: choose target company; tailor resume; create interview preview.
+3. **Follow-up queue** — subtasks: list pending applications; draft follow-ups; send 2.
+
+### Day 22
+1. **Behavioral story refinement** — subtasks: choose weakest STAR; tighten action/result; practice.
+2. **Roleplay recruiter screen** — subtasks: simulate screen; practice compensation/location; save script.
+3. **LinkedIn activity boost** — subtasks: comment on 3 posts; publish one insight; record.
+
+### Day 23
+1. **Mock interview: hard question set** — subtasks: open preview; complete; review feedback.
+2. **Resume final pass** — subtasks: grammar scan; role keyword scan; export version.
+3. **Opportunity shortlist refresh** — subtasks: find 5 new roles; rank fit; save top 3.
+
+### Day 24
+1. **Practice rejection recovery** — subtasks: roleplay rejection; ask for feedback; save response.
+2. **Case/project mini-deck** — subtasks: outline project; add result; create shareable summary.
+3. **Q Score improvement log** — subtasks: compare day 1/day 24; note drivers; choose final week target.
+
+### Day 25
+1. **Interview preview for top role** — subtasks: choose best role; open preview; complete practice.
+2. **Referral request roleplay** — subtasks: pick contact; practice ask; send message.
+3. **Update proof bank** — subtasks: add new stories; tag to questions; save.
+
+### Day 26
+1. **Application sprint** — subtasks: tailor resume; apply to 3 roles; record status.
+2. **Confidence pitch practice** — subtasks: open roleplay; practice intro; save script.
+3. **Profile final polish** — subtasks: headline; About; featured project link.
+
+### Day 27
+1. **Mock interview replay** — subtasks: rerun weakest area; compare feedback; save improvement.
+2. **Prepare interview questions to ask** — subtasks: draft 5 questions; tailor to role; save.
+3. **Networking follow-up** — subtasks: follow up with 3 contacts; record replies.
+
+### Day 28
+1. **Final readiness review** — subtasks: review Q Score; review resume; review interview feedback.
+2. **Create next 30-day plan** — subtasks: choose goal; select service focus; schedule cadence.
+3. **Publish progress proof** — subtasks: draft post; highlight learning; publish/save.
+
+### Day 29
+1. **Offer-readiness roleplay** — subtasks: practice offer call; salary answer; closing question.
+2. **Top role interview preview** — subtasks: open preview; complete; save feedback.
+3. **Resume export and versioning** — subtasks: export PDF; name by role; save.
+
+### Day 30
+1. **30-day outcome review** — subtasks: compare baseline/current; record wins; identify next gap.
+2. **Choose next sprint** — subtasks: interview conversion, callbacks, skills, or networking; save.
+3. **Celebrate streak and unlock next plan** — subtasks: claim reward; set cadence; start next stage.
+
+## 14.2 Intern: Intern-to-Offer Sprint
+
+Onboarding pattern: `individual + student/recent grad or 0-2 years + employed/internship context + role/pay/grow`.
+
+### Day 1
+1. **Define internship outcome** — subtasks: choose return offer/feedback/project impact; save goal; set deadline.
+2. **Capture current project** — subtasks: describe project; identify stakeholder; list expected result.
+3. **Start Q Score baseline** — subtasks: review score; pick communication/proof driver; save focus.
+
+### Day 2
+1. **Practice manager check-in** — subtasks: define ask; capture manager context; open roleplay preview.
+2. **Turn internship work into proof** — subtasks: pick task; capture action/result; draft resume bullet.
+3. **Write weekly update v1** — subtasks: list shipped work; list blockers; draft update.
+
+### Day 3
+1. **Clarify success metrics** — subtasks: list project KPIs; ask what good looks like; save metrics.
+2. **Roleplay feedback request** — subtasks: define feedback needed; practice ask; save script.
+3. **Update resume internship section** — subtasks: add company/team; add project; add first bullet.
+
+### Day 4
+1. **Prepare return-offer interview preview** — subtasks: confirm role; select behavioral; open preview.
+2. **Stakeholder map** — subtasks: list manager/mentor/peer; identify influence; plan one touchpoint.
+3. **Draft LinkedIn learning post** — subtasks: pick lesson; remove confidential details; draft.
+
+### Day 5
+1. **Mock interview warm-up** — subtasks: open preview; complete 5-min round; review feedback.
+2. **Manager update roleplay** — subtasks: simulate status update; practice concise wording; save.
+3. **Q Score pulse** — subtasks: log confidence; choose next week improvement; save.
+
+### Day 6
+1. **Build impact log** — subtasks: create weekly wins list; add metric/evidence; save proof bank.
+2. **Ask for better scope** — subtasks: define desired project; roleplay ask; prepare message.
+3. **Improve internship bullet** — subtasks: add action verb; add metric; save resume update.
+
+### Day 7
+1. **Week 1 internship review** — subtasks: review project progress; identify blocker; choose next action.
+2. **Prepare mentor conversation** — subtasks: define question; roleplay mentor chat; save ask.
+3. **Publish learning proof** — subtasks: finalize post; publish/save; record signal.
+
+### Day 8
+1. **Return-offer readiness check** — subtasks: identify requirements; compare proof; choose gap.
+2. **Interview preview: project deep dive** — subtasks: choose project; open preview; practice.
+3. **Draft manager check-in email** — subtasks: summarize progress; ask for feedback; send/save.
+
+### Day 9
+1. **Practice conflict/blocker conversation** — subtasks: define blocker; roleplay manager discussion; save script.
+2. **Document project decisions** — subtasks: list decisions; note rationale; add to proof bank.
+3. **Resume proof pass** — subtasks: add collaboration detail; add tool/skill; save.
+
+### Day 10
+1. **Mock return-offer round** — subtasks: open preview; complete; review feedback.
+2. **Peer feedback request** — subtasks: identify peer; draft ask; send.
+3. **Q Score update** — subtasks: add internship proof; check driver movement; choose next task.
+
+### Day 11
+1. **Prepare final project narrative** — subtasks: write before/action/after; identify metric; save.
+2. **Roleplay full-time conversion ask** — subtasks: define timing; practice ask; save script.
+3. **Profile headline update** — subtasks: add internship role; add target role; save.
+
+### Day 12
+1. **Practice technical/project questions** — subtasks: list 5 likely questions; open interview preview; practice.
+2. **Manager visibility touchpoint** — subtasks: choose update; send concise note; record response.
+3. **Build portfolio artifact** — subtasks: anonymize project; write summary; save.
+
+### Day 13
+1. **Feedback synthesis** — subtasks: collect feedback; identify pattern; choose improvement.
+2. **Roleplay receiving criticism** — subtasks: simulate feedback; practice response; save.
+3. **Resume internship finalization v1** — subtasks: tighten bullets; add metrics; export draft.
+
+### Day 14
+1. **Week 2 review** — subtasks: review impact log; review feedback; set conversion action.
+2. **Interview replay on weakness** — subtasks: choose weak topic; open preview; practice.
+3. **Draft thank-you / relationship note** — subtasks: choose mentor; write note; send/save.
+
+### Day 15
+1. **Full-time offer path map** — subtasks: identify decision maker; timeline; required proof.
+2. **Roleplay offer conversation** — subtasks: define ask; open roleplay preview; practice.
+3. **Strengthen project proof** — subtasks: add metric; add stakeholder quote; save.
+
+### Day 16
+1. **Mock interview: medium pressure** — subtasks: open preview; complete; review.
+2. **Prepare demo/update deck** — subtasks: outline 3 slides; add result; save.
+3. **LinkedIn credibility update** — subtasks: draft internship lesson; publish/save.
+
+### Day 17
+1. **Ask for explicit feedback** — subtasks: draft 3 questions; roleplay ask; send.
+2. **Roleplay prioritization discussion** — subtasks: define conflict; practice tradeoff explanation; save.
+3. **Q Score signal review** — subtasks: review communication/proof; select lowest driver; route task.
+
+### Day 18
+1. **Return-offer interview preview** — subtasks: role; behavioral; open preview; practice.
+2. **Manager one-on-one prep** — subtasks: agenda; wins; asks; send/save.
+3. **Resume role-fit tailoring** — subtasks: choose post-internship role; tailor bullets; save.
+
+### Day 19
+1. **Practice project storytelling** — subtasks: prepare 90-sec story; open interview; save best answer.
+2. **Internal networking task** — subtasks: pick team member; write intro; schedule chat.
+3. **Impact log refresh** — subtasks: add week wins; add blockers solved; save.
+
+### Day 20
+1. **Roleplay conversion close** — subtasks: practice direct ask; handle hesitation; save script.
+2. **Mock interview feedback loop** — subtasks: compare attempts; pick improvement; schedule next.
+3. **Profile polish** — subtasks: update headline; add internship proof; save.
+
+### Day 21
+1. **Week 3 conversion review** — subtasks: assess offer odds; identify missing proof; plan final week.
+2. **Prepare final presentation** — subtasks: outline impact; add metric; rehearse.
+3. **Q Score progress check** — subtasks: compare baseline/current; choose final improvement.
+
+### Day 22
+1. **Practice final presentation Q&A** — subtasks: list likely questions; open interview preview; practice.
+2. **Roleplay manager decision meeting** — subtasks: define outcome; practice ask; save.
+3. **Resume final internship bullets** — subtasks: refine 3 bullets; export role version; save.
+
+### Day 23
+1. **Stakeholder thank-you loop** — subtasks: list people; write notes; send.
+2. **Mock interview hard round** — subtasks: open preview; complete; review.
+3. **External backup plan** — subtasks: choose 5 roles; tailor resume; save shortlist.
+
+### Day 24
+1. **Promotion/return-offer script** — subtasks: write ask; practice; save.
+2. **Portfolio case study** — subtasks: anonymize project; write challenge/action/result; save.
+3. **LinkedIn post final** — subtasks: draft; review confidentiality; publish/save.
+
+### Day 25
+1. **Offer conversation preview** — subtasks: choose roleplay; set counterpart manager; practice.
+2. **Interview final polish** — subtasks: practice top 3 answers; save feedback.
+3. **Q Score readiness summary** — subtasks: review signals; save final sprint note; choose next.
+
+### Day 26
+1. **Ask for recommendation/referral** — subtasks: choose person; draft ask; roleplay if needed.
+2. **Application backup sprint** — subtasks: apply to 3 roles; record status; follow up.
+3. **Manager update final** — subtasks: summarize impact; state interest; send.
+
+### Day 27
+1. **Decision meeting rehearsal** — subtasks: roleplay; practice compensation/role scope; save script.
+2. **Resume export** — subtasks: final grammar; export PDF; save version.
+3. **Proof bank finalization** — subtasks: tag stories; tag metrics; save.
+
+### Day 28
+1. **Final internship review** — subtasks: compare goals; capture outcomes; identify next move.
+2. **Mock interview replay** — subtasks: rerun weakness; compare feedback; save.
+3. **Relationship maintenance plan** — subtasks: list contacts; schedule follow-ups; save.
+
+### Day 29
+1. **Offer or next-role roleplay** — subtasks: choose scenario; open preview; practice.
+2. **Q Score closeout** — subtasks: compare day 1/day 29; record evidence; choose next sprint.
+3. **Publish milestone update** — subtasks: draft; review; publish/save.
+
+### Day 30
+1. **Intern-to-offer outcome review** — subtasks: record offer/status; note lessons; choose next plan.
+2. **Start next sprint** — subtasks: return offer, external search, skill gap, or leadership; save.
+3. **Claim streak milestone** — subtasks: review streak; claim reward; schedule cadence.
+
+## 14.3 Fresher / early professional under 5 years: Callback-to-Offer Sprint
+
+Onboarding pattern: `individual + 0-2 or 2-5 years + hunting/between/employed + callbacks/interviews/profile/pay/switch`.
+
+### Day 1
+1. **Choose your target role** — subtasks: pick role; pick industry; save goal.
+2. **Run Q Score baseline** — subtasks: review score; choose weakest driver; save focus.
+3. **Import resume/profile** — subtasks: upload resume; connect LinkedIn; mark missing proof.
+
+### Day 2
+1. **Resume role-fit audit** — subtasks: select target JD; compare resume; save top 3 fixes.
+2. **Interview warm-up preview** — subtasks: choose role; open preview; practice.
+3. **Rewrite profile headline** — subtasks: target role; proof point; save headline.
+
+### Day 3
+1. **Callback blocker diagnosis** — subtasks: review applications; identify mismatch; update target list.
+2. **Build STAR story #1** — subtasks: choose achievement; structure STAR; save.
+3. **Roleplay recruiter screen** — subtasks: choose scenario; open preview; practice.
+
+### Day 4
+1. **Rewrite top resume bullets** — subtasks: select 3 bullets; add metrics; save.
+2. **Practice “why this role”** — subtasks: define motivation; open interview preview; save answer.
+3. **Application shortlist** — subtasks: find 5 roles; rank fit; save top 3.
+
+### Day 5
+1. **Mock interview medium round** — subtasks: open preview; complete; review feedback.
+2. **LinkedIn About rewrite** — subtasks: draft summary; add proof; save.
+3. **Q Score check-in** — subtasks: review movement; choose next driver; save.
+
+### Day 6
+1. **Tailor resume to one JD** — subtasks: map keywords; rewrite summary; export version.
+2. **Roleplay salary expectation** — subtasks: define range; open preview; practice.
+3. **Draft recruiter outreach** — subtasks: write message; send 2; record.
+
+### Day 7
+1. **Week 1 review** — subtasks: review applications; review mock feedback; choose week 2 focus.
+2. **Apply to three roles** — subtasks: tailor resume; apply; record status.
+3. **Publish credibility post** — subtasks: choose work lesson; draft; publish/save.
+
+### Day 8
+1. **Interview weakness drill** — subtasks: pick weak answer; open preview; practice.
+2. **Proof bank v1** — subtasks: list wins; tag metrics; connect to questions.
+3. **Profile visibility action** — subtasks: comment on 3 relevant posts; record.
+
+### Day 9
+1. **Role transition map** — subtasks: compare current/target; identify gaps; pick one gap.
+2. **Resume gap fix** — subtasks: add missing skill proof; rewrite section; save.
+3. **Roleplay networking call** — subtasks: choose contact; open preview; practice ask.
+
+### Day 10
+1. **Mock interview role-related** — subtasks: open preview; complete; review.
+2. **Follow-up sprint** — subtasks: list pending applications; draft follow-ups; send 3.
+3. **Q Score proof update** — subtasks: add resume changes; refresh driver; save.
+
+### Day 11
+1. **STAR story #2** — subtasks: choose conflict/teamwork; structure; save.
+2. **Practice weakness answer** — subtasks: draft honest answer; open interview; practice.
+3. **Opportunity shortlist refresh** — subtasks: find 5 roles; rank; save.
+
+### Day 12
+1. **Recruiter call roleplay** — subtasks: intro; compensation; next step; practice.
+2. **Resume final role version** — subtasks: edit summary; bullets; export.
+3. **Profile proof link** — subtasks: add project/case link; update featured section; save.
+
+### Day 13
+1. **Mock interview feedback loop** — subtasks: review last feedback; pick pattern; practice again.
+2. **Application quality audit** — subtasks: score 5 applications; remove bad-fit roles; save.
+3. **Draft referral ask** — subtasks: pick contact; write ask; send.
+
+### Day 14
+1. **Week 2 review** — subtasks: compare callbacks; compare confidence; choose conversion goal.
+2. **Practice behavioral round** — subtasks: open preview; complete; save feedback.
+3. **Publish proof post** — subtasks: pick result; draft; publish/save.
+
+### Day 15
+1. **Interview conversion plan** — subtasks: identify weak round; choose practice cadence; save.
+2. **Roleplay offer/salary call** — subtasks: scenario; desired range; practice.
+3. **Update resume with new proof** — subtasks: add story; add metric; save.
+
+### Day 16
+1. **Hard question practice** — subtasks: choose 3 hard questions; open preview; practice.
+2. **Recruiter pipeline update** — subtasks: list active leads; next action; send follow-up.
+3. **Q Score review** — subtasks: check lowest driver; route next service; save.
+
+### Day 17
+1. **Project deep dive practice** — subtasks: select project; explain decisions; open preview.
+2. **Networking follow-up** — subtasks: follow up 3 contacts; record response.
+3. **Profile credibility pass** — subtasks: headline; About; featured; save.
+
+### Day 18
+1. **Application sprint** — subtasks: tailor; apply to 3 roles; record status.
+2. **Roleplay rejection recovery** — subtasks: practice asking feedback; save script.
+3. **STAR story #3** — subtasks: leadership/ownership example; structure; save.
+
+### Day 19
+1. **Mock interview full round** — subtasks: open preview; complete; review.
+2. **Resume keyword pass** — subtasks: compare JD; add relevant terms; export.
+3. **Personal brand post** — subtasks: choose insight; draft; publish/save.
+
+### Day 20
+1. **Interview answer polish** — subtasks: pick top 3 answers; shorten; practice.
+2. **Roleplay hiring manager call** — subtasks: define scenario; open preview; practice.
+3. **Q Score progress note** — subtasks: compare baseline/current; note drivers; choose final sprint.
+
+### Day 21
+1. **Week 3 review** — subtasks: review interviews/callbacks; identify blocker; choose final week push.
+2. **Target company prep** — subtasks: choose company; research; prepare questions.
+3. **Follow-up sprint** — subtasks: pending list; send 3; record.
+
+### Day 22
+1. **Mock interview target company** — subtasks: role; company context; open preview.
+2. **Referral request roleplay** — subtasks: pick contact; practice ask; send.
+3. **Resume final polish** — subtasks: grammar; formatting; export.
+
+### Day 23
+1. **Salary negotiation prep** — subtasks: define range; roleplay; save script.
+2. **Portfolio/case proof** — subtasks: choose project; write case summary; save.
+3. **Q Score readiness check** — subtasks: review score; choose final gap; act.
+
+### Day 24
+1. **Mock interview hard mode** — subtasks: open preview; complete; review.
+2. **LinkedIn recruiter visibility** — subtasks: update headline; comment on posts; send 2 messages.
+3. **Application conversion audit** — subtasks: analyze stages; identify drop-off; plan fix.
+
+### Day 25
+1. **Offer call roleplay** — subtasks: scenario; compensation; closing ask; practice.
+2. **Interview replay on weakest area** — subtasks: open preview; practice; compare feedback.
+3. **Proof bank final pass** — subtasks: tag stories; add metrics; save.
+
+### Day 26
+1. **Final application sprint** — subtasks: apply to 3 high-fit roles; record; follow up.
+2. **Manager/recruiter communication drill** — subtasks: choose scenario; roleplay; save.
+3. **Profile proof publish** — subtasks: draft post; publish/save; record.
+
+### Day 27
+1. **Interview questions to ask** — subtasks: draft 5 smart questions; tailor; save.
+2. **Resume export versions** — subtasks: create 2 role versions; export; save.
+3. **Q Score final push** — subtasks: pick one driver; complete linked task; save.
+
+### Day 28
+1. **Readiness review** — subtasks: compare baseline; review artifacts; identify next sprint.
+2. **Mock interview final** — subtasks: open preview; complete; save feedback.
+3. **Networking cadence plan** — subtasks: choose contacts; schedule weekly outreach; save.
+
+### Day 29
+1. **Negotiation or recruiter screen replay** — subtasks: open roleplay; practice; save script.
+2. **Opportunity pipeline review** — subtasks: active roles; next actions; deadlines.
+3. **Profile final polish** — subtasks: headline; About; resume link; save.
+
+### Day 30
+1. **30-day outcome review** — subtasks: callbacks/interviews/score; record wins; choose next sprint.
+2. **Select next plan** — subtasks: interview conversion, salary negotiation, transition, leadership; save.
+3. **Claim streak milestone** — subtasks: review progress; claim reward; schedule next cadence.
+
+## 14.4 Freelancer / gig worker: Client Pipeline Sprint
+
+Onboarding pattern: `gig + starting/fewclients/sidehustle + clients/pricing/standout/trust/income + firstclient/doubleincome/fulltime/1lakh`.
+
+### Day 1
+1. **Define your client niche** — subtasks: choose target client; define pain; save niche.
+2. **Start credibility/Q Score baseline** — subtasks: review baseline; pick trust driver; save focus.
+3. **Import portfolio/profile** — subtasks: add LinkedIn/portfolio/GitHub; mark missing proof.
+
+### Day 2
+1. **Package your core offer** — subtasks: define problem; define deliverable; write offer line.
+2. **Practice discovery call preview** — subtasks: choose client scenario; open roleplay preview; practice.
+3. **Draft profile headline** — subtasks: client type; outcome; save headline.
+
+### Day 3
+1. **Build case study #1** — subtasks: pick project; before/action/after; draft summary.
+2. **Pricing confidence roleplay** — subtasks: current/target rate; open preview; practice.
+3. **Draft inbound post** — subtasks: pick client pain; write insight; save/publish.
+
+### Day 4
+1. **Client pipeline map** — subtasks: list lead sources; rank channels; choose first 2.
+2. **Offer page/profile polish** — subtasks: add offer; add proof; add CTA.
+3. **Roleplay objection handling** — subtasks: pick objection; open preview; practice.
+
+### Day 5
+1. **Outreach message v1** — subtasks: define audience; write message; send 5.
+2. **Q Score trust check** — subtasks: review credibility gaps; choose proof task; save.
+3. **Portfolio proof pass** — subtasks: add metric/testimonial; improve case study; save.
+
+### Day 6
+1. **Discovery call script** — subtasks: write 5 questions; roleplay call; save script.
+2. **Pricing page draft** — subtasks: define package tiers; add outcomes; save.
+3. **Publish credibility post** — subtasks: finalize post; publish; record.
+
+### Day 7
+1. **Week 1 pipeline review** — subtasks: leads sent; replies; learnings; choose week 2 focus.
+2. **Follow-up roleplay** — subtasks: practice polite follow-up; send 3.
+3. **Update service profile** — subtasks: headline; offer; proof; save.
+
+### Day 8
+1. **Create lead list** — subtasks: find 20 prospects; score fit; save top 10.
+2. **Roleplay first client call** — subtasks: scenario; desired close; practice.
+3. **Case study polish** — subtasks: add visuals/link; add outcome; publish/save.
+
+### Day 9
+1. **Improve offer specificity** — subtasks: narrow audience; narrow outcome; update copy.
+2. **Pricing objection drill** — subtasks: choose objection; roleplay; save response.
+3. **Draft cold DM/email** — subtasks: write version; personalize 5; send.
+
+### Day 10
+1. **Q Score credibility update** — subtasks: add case proof; review movement; pick next gap.
+2. **Client discovery replay** — subtasks: open roleplay; practice; save feedback.
+3. **Inbound content draft** — subtasks: client pain; teaching point; CTA.
+
+### Day 11
+1. **Referral ask script** — subtasks: pick past client/contact; write ask; roleplay.
+2. **Portfolio homepage audit** — subtasks: identify weak section; rewrite; save.
+3. **Pipeline follow-up sprint** — subtasks: follow up 5 leads; record status.
+
+### Day 12
+1. **Proposal structure** — subtasks: define problem; solution; timeline; price.
+2. **Roleplay proposal call** — subtasks: client scenario; open preview; practice.
+3. **Proof post** — subtasks: share case insight; publish/save; record.
+
+### Day 13
+1. **Rate increase plan** — subtasks: current rate; target; justification proof.
+2. **Pricing roleplay hard mode** — subtasks: discount objection; scope objection; practice.
+3. **Lead source review** — subtasks: compare channels; double down; save.
+
+### Day 14
+1. **Week 2 review** — subtasks: leads/replies/calls; bottleneck; week 3 focus.
+2. **Update profile CTA** — subtasks: write clear CTA; add booking/contact; save.
+3. **Discovery call practice** — subtasks: open roleplay; practice; save.
+
+### Day 15
+1. **Client conversion plan** — subtasks: identify active leads; next action; deadlines.
+2. **Scope creep roleplay** — subtasks: define scenario; practice boundary; save script.
+3. **Case study #2** — subtasks: choose project; draft; save.
+
+### Day 16
+1. **Proposal follow-up script** — subtasks: draft; roleplay; send.
+2. **Q Score trust review** — subtasks: review proof/social; choose next improvement.
+3. **Authority post** — subtasks: client lesson; draft; publish/save.
+
+### Day 17
+1. **Package refinement** — subtasks: define starter package; define premium package; save.
+2. **Roleplay premium offer** — subtasks: practice quote; handle pushback; save.
+3. **Outreach sprint** — subtasks: send 5 targeted messages; record.
+
+### Day 18
+1. **Testimonial request** — subtasks: choose client; draft request; send.
+2. **Client call replay** — subtasks: practice discovery/proposal; save feedback.
+3. **Portfolio proof update** — subtasks: add testimonial/result; save.
+
+### Day 19
+1. **Inbound post #2** — subtasks: pick recurring client pain; draft; publish.
+2. **Roleplay difficult client** — subtasks: late payment/scope; practice; save.
+3. **Pipeline health check** — subtasks: leads/calls/proposals; next actions.
+
+### Day 20
+1. **Pricing confidence review** — subtasks: compare day 3/day 20; update script; save.
+2. **Proposal template final** — subtasks: refine sections; add pricing; save.
+3. **Q Score progress note** — subtasks: compare baseline; choose final sprint focus.
+
+### Day 21
+1. **Week 3 review** — subtasks: identify conversion bottleneck; choose final week push.
+2. **Roleplay close call** — subtasks: practice close; handle hesitation; save.
+3. **Lead list refresh** — subtasks: add 20 leads; score; save.
+
+### Day 22
+1. **Full-time freelancing plan** — subtasks: income target; client count; package math.
+2. **Pricing/retainer roleplay** — subtasks: monthly retainer scenario; practice.
+3. **Profile final proof pass** — subtasks: headline; case studies; CTA.
+
+### Day 23
+1. **Outreach sprint** — subtasks: personalize 10; send; record.
+2. **Discovery call final practice** — subtasks: open roleplay; practice; save.
+3. **Publish case study** — subtasks: finalize; publish; share.
+
+### Day 24
+1. **Referral engine setup** — subtasks: write referral ask; identify 10 contacts; send 3.
+2. **Difficult negotiation roleplay** — subtasks: discount/scope; practice; save.
+3. **Q Score credibility check** — subtasks: review; choose last improvement; act.
+
+### Day 25
+1. **Proposal follow-up sprint** — subtasks: list proposals; write follow-ups; send.
+2. **Premium positioning update** — subtasks: rewrite offer; add proof; save.
+3. **Authority post** — subtasks: client insight; draft; publish.
+
+### Day 26
+1. **Client onboarding script** — subtasks: define first call; roleplay; save.
+2. **Portfolio final export/share** — subtasks: update links; test CTA; save.
+3. **Pipeline next actions** — subtasks: assign next step to every lead; record.
+
+### Day 27
+1. **Close-call practice** — subtasks: open roleplay; practice; save script.
+2. **Retainer offer draft** — subtasks: define recurring value; price; terms.
+3. **Follow-up 5 leads** — subtasks: draft; send; record.
+
+### Day 28
+1. **30-day pipeline review prep** — subtasks: leads/replies/calls/revenue; summarize.
+2. **Case study final polish** — subtasks: add outcome; share; save.
+3. **Q Score final review** — subtasks: compare baseline; note trust gains; choose next sprint.
+
+### Day 29
+1. **Roleplay highest-value call** — subtasks: choose active lead; practice; save.
+2. **Recurring income plan** — subtasks: define retainer target; prospect list; next actions.
+3. **Publish progress post** — subtasks: write learning; publish; record.
+
+### Day 30
+1. **Client Pipeline outcome review** — subtasks: count leads/replies/calls; record wins; choose next plan.
+2. **Select next sprint** — subtasks: first client, premium rates, retainer, inbound brand; save.
+3. **Claim streak milestone** — subtasks: claim reward; set next cadence; start next stage.
+
+## 14.5 Founder / solopreneur: Founder Visibility & Validation Sprint
+
+Onboarding pattern: `founder + idea/MVP/traction/pre-revenue + customers/funding/visibility/team/model + 90-day priority`.
+
+### Day 1
+1. **Clarify 90-day founder priority** — subtasks: choose MVP/customers/raise/hire/presence; save goal.
+2. **Founder Q Score baseline** — subtasks: review credibility drivers; pick weakest; save focus.
+3. **Import founder proof** — subtasks: add LinkedIn/site/deck; mark missing proof.
+
+### Day 2
+1. **Write founder one-liner** — subtasks: audience; problem; solution; save.
+2. **Practice customer discovery preview** — subtasks: choose segment; assumption; open roleplay.
+3. **Draft founder profile headline** — subtasks: role; venture; outcome; save.
+
+### Day 3
+1. **Map riskiest assumption** — subtasks: identify assumption; define evidence needed; save.
+2. **Build-in-public post v1** — subtasks: pick learning; draft; publish/save.
+3. **Customer list v1** — subtasks: define ICP; list 20 prospects; score top 10.
+
+### Day 4
+1. **Discovery call script** — subtasks: write 5 questions; avoid leading; save.
+2. **Roleplay customer interview** — subtasks: open preview; practice; save feedback.
+3. **Founder credibility audit** — subtasks: review profile/site/deck; save top fixes.
+
+### Day 5
+1. **Q Score validation check** — subtasks: review credibility/clarity; choose next action.
+2. **Outreach message to customers** — subtasks: write message; send 5; record.
+3. **Founder one-liner revision** — subtasks: simplify; add pain; save.
+
+### Day 6
+1. **Investor/customer narrative draft** — subtasks: problem; insight; traction/proof; save.
+2. **Roleplay objection handling** — subtasks: choose customer objection; practice; save.
+3. **Publish market insight** — subtasks: draft; publish; record.
+
+### Day 7
+1. **Week 1 validation review** — subtasks: calls booked; replies; learning; choose week 2 focus.
+2. **Discovery follow-up** — subtasks: write follow-up; send; record.
+3. **Update founder profile** — subtasks: headline; one-liner; venture link; save.
+
+### Day 8
+1. **Customer discovery round 2** — subtasks: refine ICP; send 5 more; record.
+2. **Roleplay investor intro** — subtasks: stage; proof; open preview; practice.
+3. **Deck/site clarity pass** — subtasks: rewrite problem; rewrite audience; save.
+
+### Day 9
+1. **Validate pricing hypothesis** — subtasks: define price; buyer; test question.
+2. **Pricing conversation roleplay** — subtasks: open preview; practice; save.
+3. **Founder update post** — subtasks: share learning; draft; publish.
+
+### Day 10
+1. **Q Score credibility update** — subtasks: add profile/deck changes; review movement.
+2. **Customer call replay** — subtasks: practice weak question; save feedback.
+3. **Prospect pipeline update** — subtasks: statuses; next actions; save.
+
+### Day 11
+1. **MVP scope check** — subtasks: list features; mark must-have; cut one feature.
+2. **Roleplay cofounder alignment** — subtasks: define role; open preview; practice.
+3. **Authority post** — subtasks: pick contrarian insight; draft; publish.
+
+### Day 12
+1. **First customer offer** — subtasks: define pilot; outcome; price/free terms.
+2. **Roleplay sales discovery** — subtasks: buyer; desired next step; practice.
+3. **Profile proof update** — subtasks: add traction/learning; save.
+
+### Day 13
+1. **Investor intro email** — subtasks: draft concise note; add proof; save/send.
+2. **Roleplay investor objections** — subtasks: market/team/traction objection; practice.
+3. **Customer insight synthesis** — subtasks: summarize calls; identify pattern; save.
+
+### Day 14
+1. **Week 2 review** — subtasks: calls/learnings/proof; choose week 3 conversion goal.
+2. **Build-in-public post #2** — subtasks: learning; metric; ask; publish.
+3. **Q Score check-in** — subtasks: review clarity/visibility; choose next action.
+
+### Day 15
+1. **Customer conversion plan** — subtasks: active prospects; next ask; deadlines.
+2. **Roleplay pilot close** — subtasks: offer; objection; next step; practice.
+3. **Deck one-liner polish** — subtasks: problem; solution; why now; save.
+
+### Day 16
+1. **Hiring/collaborator need** — subtasks: define role; outcomes; score must-haves.
+2. **Interview first hire preview** — subtasks: role; round; open interview preview.
+3. **Founder profile social proof** — subtasks: add customers/advisors/proof; save.
+
+### Day 17
+1. **Customer discovery sprint** — subtasks: send 10 messages; record replies; schedule calls.
+2. **Roleplay hard customer call** — subtasks: skeptical buyer; practice; save.
+3. **Market narrative post** — subtasks: write insight; publish; record.
+
+### Day 18
+1. **Fundraising readiness check** — subtasks: stage; proof; gaps; choose fix.
+2. **Investor roleplay replay** — subtasks: open preview; practice; save.
+3. **Website/deck proof pass** — subtasks: add traction/quotes; save.
+
+### Day 19
+1. **Model validation task** — subtasks: unit assumption; test method; evidence target.
+2. **Pricing/buyer roleplay** — subtasks: open preview; practice; save.
+3. **Pipeline follow-up** — subtasks: follow up 5 prospects; record.
+
+### Day 20
+1. **Q Score progress note** — subtasks: compare baseline; identify strongest/weakest driver.
+2. **Founder pitch practice** — subtasks: 60-sec pitch; roleplay; save script.
+3. **Build-in-public post #3** — subtasks: progress; challenge; ask; publish.
+
+### Day 21
+1. **Week 3 review** — subtasks: validation evidence; customer pipeline; choose final week push.
+2. **Pilot proposal draft** — subtasks: scope; timeline; price; success metric.
+3. **Roleplay closing conversation** — subtasks: customer; next step; practice.
+
+### Day 22
+1. **Investor/customer FAQ** — subtasks: list hard questions; draft answers; save.
+2. **Interview/collaborator preview** — subtasks: role; criteria; open preview.
+3. **Founder profile polish** — subtasks: headline; one-liner; proof; save.
+
+### Day 23
+1. **Customer outreach sprint** — subtasks: send 10; record; schedule.
+2. **Roleplay objection: no budget** — subtasks: practice; save response.
+3. **Authority post** — subtasks: market lesson; draft; publish.
+
+### Day 24
+1. **Traction proof package** — subtasks: collect calls/replies/users/revenue; summarize.
+2. **Investor intro replay** — subtasks: open roleplay; practice; save.
+3. **Q Score final gap action** — subtasks: choose gap; complete linked task; save.
+
+### Day 25
+1. **Pilot close sprint** — subtasks: active prospects; send close asks; record.
+2. **Founder pitch final** — subtasks: tighten 60-sec pitch; practice; save.
+3. **Deck/site final clarity** — subtasks: problem; solution; proof; CTA.
+
+### Day 26
+1. **Hiring/collaborator outreach** — subtasks: define target; write message; send 5.
+2. **Roleplay cofounder conversation** — subtasks: equity/scope/values; practice.
+3. **Publish milestone update** — subtasks: metric/learning; publish; record.
+
+### Day 27
+1. **Customer interview synthesis** — subtasks: summarize patterns; decide pivot/persevere; save.
+2. **Roleplay next-step close** — subtasks: pilot/customer/investor; practice.
+3. **Founder credibility final pass** — subtasks: profile; site; proof links; save.
+
+### Day 28
+1. **30-day validation review prep** — subtasks: evidence; gaps; decision; next sprint.
+2. **Q Score closeout** — subtasks: compare baseline; note drivers; choose next.
+3. **Build-in-public recap** — subtasks: draft progress recap; publish/save.
+
+### Day 29
+1. **Highest-stakes conversation practice** — subtasks: investor/customer/hire; open roleplay; practice.
+2. **Pipeline next actions** — subtasks: every prospect next step; deadlines; save.
+3. **Pitch/deck export** — subtasks: final file/link; save; share-ready.
+
+### Day 30
+1. **Founder sprint outcome review** — subtasks: calls, customers, proof, score; record.
+2. **Choose next founder sprint** — subtasks: MVP, customers, fundraising, hiring, visibility; save.
+3. **Claim streak milestone** — subtasks: claim reward; schedule next cadence; start next stage.
diff --git a/curator-user-scenarios-state-machine.md b/curator-user-scenarios-state-machine.md
new file mode 100644
index 0000000..cad483b
--- /dev/null
+++ b/curator-user-scenarios-state-machine.md
@@ -0,0 +1,455 @@
+# GrowQR Curator — User Scenarios & Engagement State Machine
+
+Date: 2026-06-19
+Purpose: Map every user behavior pattern to Curator behavior, tasks, streak handling, and recovery logic.
+
+---
+
+## 1. Engagement States (User Behavior Patterns)
+
+Think of the user as moving through these states, not just "active" or "inactive."
+
+| State | Definition | Streak Status | Curator Priority |
+|-------|-----------|---------------|------------------|
+| **Ghost** | Signed up, never completed Day 1 | 0 | Re-activation: lower friction, simpler ask |
+| **Day 1 Dropper** | Completed Day 1, never returned | 1 then 0 | Diagnose why: too hard? too vague? time? |
+| **Streak Broken** | Had 3-7 day streak, then missed 2-7 days | Broken | Graceful recovery: don't shame, reduce load |
+| **Streak Dead** | Broken for 14+ days | Dead | Soft reset: treat like Week 1, new baseline |
+| **Sporadic** | Uses platform 1-2x/week, no streak | 0-2 | Lower daily load, bigger tasks when they show up |
+| **Re-engaging** | Returning after 7+ days, clicking around | 0 | Acknowledge absence, one task max, no guilt |
+| **Active** | 3-14 day streak, completes daily tasks | 3-14 | Full 3-column plan, maintain momentum |
+| **Super-user** | 14+ day streak, all 3 columns complete | 14+ | Increase difficulty, introduce market-action tasks |
+| **Conversion mode** | Active + real interviews/offers in flight | — | Emergency override: prioritize interview/roleplay |
+| **Lost** | 30+ days no activity, no response to nudges | — | Archive plan, send "new sprint" offer |
+
+---
+
+## 2. Day-by-Day Progression (The Curator's Mindset)
+
+### Day 1: The Hook
+
+**User state:** Curious, low trust, high friction sensitivity.
+
+**Curator behavior:**
+- **Measurement:** Q Score baseline (5 min, max)
+- **Proof:** Resume upload OR LinkedIn import (one click, not full audit)
+- **Practice:** One warm-up interview (behavioral, easy, 3 min) OR skip if user seems overwhelmed
+
+**Rules:**
+- Show **only 1-2 tasks**, not 3. Third task is a bonus if they finish early.
+- No long onboarding. Extract from signup data silently.
+- First task must produce a visible artifact or feedback (score, feedback, draft).
+- If user drops after first task: **Day 2 nudge is about the artifact, not the streak.**
+
+**Example nudge:**
+> "Your Q Score baseline is ready. You scored highest on [X], lowest on [Y]. Here's one move that closes the gap in 10 minutes."
+
+---
+
+### Day 2: The Habit Test
+
+**User state:** Either hooked (returns easily) or testing (needs a reason).
+
+**Curator behavior:**
+- **Measurement:** Review Day 1 baseline, show one gap
+- **Proof:** Resume headline rewrite OR first project proof point
+- **Practice:** Interview or roleplay (still easy, 5 min)
+
+**Rules:**
+- If Day 1 was missed: **pick up where they left off, don't reset.**
+- If Day 1 was completed: **reference the artifact.** "Your resume is uploaded. Let's fix the headline so recruiters see you."
+- If Day 1 was completed but Day 2 is late: **reduce to 1 task, make it the most fun/valuable.**
+
+---
+
+### Day 3-7: The Build Phase
+
+**User state:** Either forming habit or deciding to quit.
+
+**Curator behavior:**
+- Full 3-column plan kicks in.
+- Tasks are **timeboxed (5-10 min)**. No 20-min tasks.
+- **Practice column is interview/roleplay warm-up** — not hard rounds.
+- **Proof column is resume bullets or LinkedIn headline** — not full rewrites.
+
+**Rules:**
+- If user misses 1 day: ignore, continue as if nothing happened.
+- If user misses 2 days: next task is **1 task only, 5 min max.**
+- If user misses 3 days: see "Streak Recovery" below.
+
+---
+
+### Day 8-14: The Gap-Fix Phase
+
+**User state:** Habit forming or habit fragile.
+
+**Curator behavior:**
+- Tasks now reference prior work. "Your resume headline is fixed. Now let's turn one project into proof."
+- **Practice gets harder.** Medium difficulty, 10 min.
+- **Proof gets real.** First public post, first case study, first tailored resume.
+
+**Rules:**
+- If streak alive: introduce **weekly review task** (Day 7, Day 14) — "What changed this week?"
+- If streak broken: see recovery logic.
+
+---
+
+### Day 15-21: The Practice Loop
+
+**User state:** Habit locked or falling off.
+
+**Curator behavior:**
+- **Practice is the star.** 2-4 interviews/roleplays per week.
+- **Proof is iteration.** Resume v2, profile polish, second post.
+- **Measurement is Q Score check-in.** Show movement from Day 1.
+
+**Rules:**
+- If Q Score moved: celebrate. "Your communication score is up 12 points from Day 1."
+- If Q Score didn't move: diagnose. "Your resume proof is better, but interview practice is still light. Let's fix that."
+
+---
+
+### Day 22-29: The Market Action Phase
+
+**User state:** Ready to apply or already applying.
+
+**Curator behavior:**
+- **Practice:** Salary negotiation, recruiter screens, real interview prep.
+- **Proof:** Tailored resume versions, application tracker, outreach drafts.
+- **Measurement:** Application pipeline health, callback rate.
+
+**Rules:**
+- If user has no callbacks: return to proof + resume audit.
+- If user has interviews: **emergency override.** All 3 tasks become interview/roleplay prep.
+
+---
+
+### Day 30: The Close
+
+**User state:** Wants to see results.
+
+**Curator behavior:**
+- **30-day review artifact:** Day 1 vs Day 30 Q Score, proof created, interviews completed.
+- **Next sprint:** Offer 3 options (continue, intensify, pivot).
+- **Streak claim:** Visual reward, shareable, unlocks next ICP stage or advanced features.
+
+---
+
+### Day 31+: The Loop
+
+**Curator behavior:**
+- **Replan every 7 days.**
+- If 30-day sprint was successful: **60-day sprint unlocks.** More advanced tasks, market-action heavy.
+- If 30-day sprint was weak: **repeat the weak stage** (gap-fix, proof-build) with adjusted tone.
+
+---
+
+## 3. Scenario-by-Scenario Playbook
+
+### Scenario A: Happy Path — Active User, Completes Daily
+
+**Day 1:** Q Score baseline, resume upload, warm-up interview.
+**Day 2:** Gap review, headline rewrite, behavioral interview.
+**Day 3-7:** Project proof, recruiter roleplay, LinkedIn post.
+**Day 8-14:** Resume audit, salary roleplay, application tracker.
+**Day 15-21:** Interview replay, tailored resume, matchmaking.
+**Day 22-29:** Real interview prep, offer negotiation, outreach.
+**Day 30:** Review, next sprint selection.
+
+**Curator tone:** Direct, momentum-driven. "This is your interview practice step for today."
+**Streak:** Visual fire, increasing. Weekly milestone celebrations.
+**Adaptation:** None needed. System is in maintenance mode.
+
+---
+
+### Scenario B: Ghost — Signed Up, Never Started Day 1
+
+**Trigger:** 24h after signup, no Q Score baseline.
+**Curator action:**
+- Send **one nudge** via notification/email: "Your Q Score takes 3 minutes. Here's the link."
+- If no response in 48h: **reduce ask.** "Just upload your resume. One click."
+- If no response in 72h: **change channel.** Send a WhatsApp/SMS if available.
+- If no response in 7 days: **archive.** Mark as "cold." Re-engage in 14 days with "New sprint ready."
+
+**Curator tone:** Helpful, zero pressure. No streak guilt.
+**Task count:** 1 task max.
+**Recovery:** On return, treat as Day 1 but skip onboarding. Resume from last known state.
+
+---
+
+### Scenario C: Day 1 Dropper — Did Day 1, Never Returned
+
+**Trigger:** 48h after Day 1 completion, no Day 2 activity.
+**Curator action:**
+- Nudge references **Day 1 artifact.** "Your Q Score showed a communication gap. One practice fixes it."
+- Offer **same task type, slightly easier.** If Day 1 was interview, Day 2 nudge is a 3-min warm-up.
+- If no response in 72h: **ask why.** One question: "What stopped you: time, confusion, or not relevant?"
+- If they answer: **adapt plan.**
+ - "Time" → 5-minute tasks only.
+ - "Confusion" → simpler tasks, more guidance.
+ - "Not relevant" → re-ICP or replan.
+
+**Curator tone:** Curious, not accusatory. "What would make this useful?"
+**Streak:** 1. Treat as broken streak recovery.
+
+---
+
+### Scenario D: Streak Broken — 3-7 Days of Silence
+
+**Trigger:** Missed 3 days after active streak.
+**Curator action:**
+- **Day 1 of return:** 1 task only. 5 minutes. No mention of missed days unless they bring it up.
+- **Task:** Resume headline fix OR interview warm-up — something they already know how to do.
+- **Day 2 of return:** 2 tasks. Reference the Day 1 return: "Back to building. Let's fix one proof point."
+- **Day 3 of return:** Full 3 tasks. Resume normal plan.
+
+**Curator tone:** Welcoming, no guilt. "Pick up where you left off."
+**Streak:** Reset to 1 on return. Don't show broken streak flame.
+**Recovery speed:** 3 days to full plan.
+
+---
+
+### Scenario E: Streak Dead — 14+ Days of Silence
+
+**Trigger:** 14 days no activity.
+**Curator action:**
+- **Soft reset.** Treat as new 30-day sprint, but skip onboarding.
+- **Day 1:** New Q Score baseline (or review old one). "Here's where you stand today."
+- **Day 2:** One proof task, one practice task. Not 3.
+- **Week 1:** Rebuild trust. Tasks must produce visible wins.
+- **If no return after 14 days:** Send "Your new sprint is ready" message. Highlight one changed thing (e.g., new job market data, new interview template).
+
+**Curator tone:** Fresh start. "New sprint. New target. Same goal."
+**Streak:** 0. Start over.
+**Plan:** Re-run ICP classifier if onboarding data is stale.
+
+---
+
+### Scenario F: Sporadic — 1-2x/Week, No Streak
+
+**User archetype:** Busy, platform is a tool not a habit.
+
+**Curator action:**
+- **Don't optimize for streak.** Optimize for value per session.
+- **When they show up:** Give them **the highest-impact 1 task** from their current stage.
+- **Don't give 3 tasks.** They won't do them. Give 1, with a "next time" teaser.
+- **Tasks are bigger:** 15-20 min, not 5 min. Since they come rarely, they need bigger wins.
+- **Example:** "You haven't practiced in 5 days. You have a real interview coming up. Here's a 10-minute roleplay."
+
+**Curator tone:** Respects their time. "This is the one move for this week."
+**Streak:** Don't show streak UI. Show "last session [X] days ago" and "this week: 1 task done."
+**Plan:** Weekly plan, not daily plan. 3 tasks per week, not per day.
+
+---
+
+### Scenario G: Re-engaging — Returning After 7+ Days, Browsing
+
+**Trigger:** User opens app after 7+ days, clicks around but doesn't complete tasks.
+
+**Curator action:**
+- **Detect browsing.** If they open but don't start a task within 2 min: trigger a chat bubble.
+- **Chat:** "Welcome back. What changed since you were last here?" (job, timeline, goal, nothing)
+- **If they say nothing:** "Your Q Score was [X]. One thing improved it since then: [task]. 5 minutes."
+- **If they say goal changed:** Re-ICP, replan, Day 1 of new sprint.
+- **If they say timeline moved:** Adjust urgency, plan length.
+
+**Curator tone:** Warm, acknowledging. "Good to see you."
+**Task:** 1 task max. Make it the one they abandoned last time.
+
+---
+
+### Scenario H: Super-user — 14+ Day Streak, All 3 Columns
+
+**Curator action:**
+- **Introduce harder tasks.** Hard interview mode, executive roleplay, leadership case study.
+- **Introduce market-action tasks.** Apply to real roles, send recruiter outreach, schedule real interviews.
+- **Introduce cross-service tasks.** "Practice this interview, then turn the answer into a LinkedIn post."
+- **Unlock 60-day plan.** "You've completed 30 days. Ready for the conversion sprint?"
+- **Add variety.** Alternate interview types, alternate roleplay scenarios. Prevent boredom.
+
+**Curator tone:** Partner, not coach. "You're ready for the real thing. Let's go."
+**Streak:** Celebrate 7, 14, 21, 30. Visual badges.
+**Plan:** 60-day or 90-day plan. More self-directed options.
+
+---
+
+### Scenario I: Conversion Mode — Has Real Interview/Offer in Flight
+
+**Trigger:** User inputs interview date, or matchmaking tracks application.
+
+**Curator action:**
+- **Emergency override.** All 3 tasks become interview/roleplay prep.
+- **Measurement:** Q Score gap for that specific role.
+- **Proof:** Tailored resume for that company.
+- **Practice:** Interview or roleplay for that exact scenario.
+- **Countdown:** "Interview in 3 days. Today: behavioral round. Tomorrow: roleplay the salary."
+
+**Curator tone:** Urgent, focused. "This is your prep. Nothing else matters."
+**Streak:** Pause normal streak. Create "interview prep streak" sub-streak.
+**Plan:** Frozen. All resources directed to interview prep.
+
+---
+
+### Scenario J: Lost — 30+ Days, No Response to Nudges
+
+**Curator action:**
+- **Archive current plan.**
+- **Send final nudge:** "Your 30-day plan is paused. Start a new sprint when you're ready."
+- **Re-engagement trigger:** New feature, new job market signal, new season, or user-initiated.
+- **On return:** Full soft reset. New Day 1. Ask if goal changed.
+
+**Curator tone:** Neutral, door open. "When you're ready."
+**Streak:** 0. Plan archived.
+
+---
+
+## 4. State Machine Diagram (Text)
+
+```
+SIGNUP
+ |
+ +--> [Day 1 complete] --> ACTIVE (Day 2)
+ | |
+ | +--> [Daily completion] --> STREAK (Day 3-7)
+ | | |
+ | | +--> [Continues] --> BUILD (Day 8-14)
+ | | | |
+ | | | +--> [Continues] --> LOOP (Day 15-21)
+ | | | | |
+ | | | | +--> [Continues] --> MARKET (Day 22-29)
+ | | | | | |
+ | | | | | +--> [Day 30] --> REVIEW (Day 31+)
+ | | | | | |
+ | | | | | +--> [Miss 3 days] --> BROKEN
+ | | | | | |
+ | | | | | +--> [Miss 14 days] --> DEAD
+ | | | | | |
+ | | | | | +--> [Has interview] --> CONVERSION
+ | | | | | |
+ | | | | | +--> [14+ streak] --> SUPER
+ | | | | |
+ | | | | +--> [Miss 3 days] --> BROKEN
+ | | | |
+ | | | +--> [Miss 2 days] --> BROKEN (early)
+ | | |
+ | | +--> [Miss 1 day] --> ACTIVE (no change)
+ | |
+ | +--> [Day 1 missed] --> GHOST
+ | |
+ | +--> [Return in 24h] --> ACTIVE (Day 1)
+ | |
+ | +--> [Return in 7d] --> RE-ENGAGING (Day 1)
+ | |
+ | +--> [No return] --> LOST
+ |
+ +--> [Day 1 partial] --> DAY 1 DROPPER
+ |
+ +--> [Return in 48h] --> ACTIVE (Day 2)
+ |
+ +--> [No return] --> GHOST
+
+BROKEN
+ |
+ +--> [Return] --> RECOVERY (1 task, 5 min)
+ | |
+ | +--> [Day 2] --> RECOVERY (2 tasks)
+ | |
+ | +--> [Day 3] --> ACTIVE (full 3 tasks)
+ |
+ +--> [No return 14 days] --> DEAD
+
+DEAD
+ |
+ +--> [Return] --> SOFT RESET (new Day 1)
+ |
+ +--> [No return 30 days] --> LOST
+
+SUPER
+ |
+ +--> [Miss 1 day] --> ACTIVE (still)
+ |
+ +--> [Miss 3 days] --> BROKEN
+ |
+ +--> [Interview in flight] --> CONVERSION
+
+CONVERSION
+ |
+ +--> [Interview done] --> ACTIVE or MARKET
+ |
+ +--> [Offer received] --> NEGOTIATION (new sub-mode)
+ |
+ +--> [Rejected] --> ACTIVE (comfort + rebuild)
+
+SPORADIC (orthogonal, can enter from any state)
+ |
+ +--> [Weekly session] --> 1 big task
+ |
+ +--> [Increasing frequency] --> ACTIVE
+```
+
+---
+
+## 5. Curator Tone Matrix by State
+
+| State | Tone | Example Opening |
+|-------|------|-----------------|
+| Ghost | Invitation, zero pressure | "Your Q Score takes 3 minutes. Ready when you are." |
+| Day 1 Dropper | Curious, artifact-focused | "Your resume is uploaded. Let's fix the headline." |
+| Broken | Welcoming, no guilt | "Pick up where you left off. One task, 5 minutes." |
+| Dead | Fresh start, optimistic | "New sprint. New target. Same goal." |
+| Sporadic | Respectful, high-value | "This is the one move for this week." |
+| Re-engaging | Warm, acknowledging | "Good to see you. What's changed?" |
+| Active | Direct, momentum | "This is your practice step for today." |
+| Super | Partner, challenger | "You're ready for the real thing. Let's go." |
+| Conversion | Urgent, focused | "Interview in 3 days. Here's today's prep." |
+| Lost | Neutral, door open | "When you're ready, start a new sprint." |
+
+---
+
+## 6. Task Count Rules by State
+
+| State | Tasks per Day | Time per Task | Total Time |
+|-------|---------------|---------------|------------|
+| Ghost / Day 1 Dropper | 1 | 3-5 min | 5 min |
+| Re-engaging / Recovery | 1 | 5 min | 5 min |
+| Sporadic | 1 | 15-20 min | 20 min |
+| Active | 3 | 5-10 min | 15-30 min |
+| Super | 3 | 10-20 min | 30-45 min |
+| Conversion | 3 | 10-15 min | 30-45 min |
+
+---
+
+## 7. Nudge Strategy by State
+
+| State | Nudge Timing | Channel | Content |
+|-------|-------------|---------|---------|
+| Ghost | 24h, 48h, 72h | In-app, email, WhatsApp | Artifact reference, reduced ask |
+| Day 1 Dropper | 48h, 72h | In-app, push | "Your Q Score showed [X]. One move fixes it." |
+| Broken | 24h after return | In-app | "Welcome back. One task." |
+| Dead | 7d, 14d, 30d | Email, WhatsApp | "New sprint ready." / "Your market changed." |
+| Sporadic | Weekly | Push | "This week's one move: [task]." |
+| Active | Daily | In-app | Daily plan + streak fire |
+| Super | Weekly | In-app | "30 days complete. Next sprint unlocked." |
+| Conversion | Daily | In-app, push, WhatsApp | Countdown + specific prep task |
+| Lost | 30d, 60d | Email | "Start a new sprint." |
+
+---
+
+## 8. Summary: The 10 Scenarios at a Glance
+
+| Scenario | Core Principle | Curator's Job |
+|----------|---------------|---------------|
+| A. Happy path | Maintain momentum | 3 tasks/day, celebrate, escalate difficulty |
+| B. Ghost | Reduce friction | 1 tiny task, multiple channels, artifact hook |
+| C. Day 1 dropper | Diagnose and adapt | Ask why, adjust plan, reduce or refocus |
+| D. Streak broken | Graceful recovery | 1 task, no guilt, 3-day ramp back |
+| E. Streak dead | Soft reset | New Day 1, skip onboarding, rebuild trust |
+| F. Sporadic | Value per session | 1 big task/week, no streak pressure |
+| G. Re-engaging | Acknowledge and pivot | Chat bubble, ask what changed, 1 task |
+| H. Super-user | Challenge and unlock | Harder tasks, 60-day plan, market action |
+| I. Conversion | Emergency override | All tasks → interview prep, countdown |
+| J. Lost | Door open | Archive, final nudge, wait for return |
+
+---
+
+*End of scenarios document.*
diff --git a/delivery-map.md b/delivery-map.md
new file mode 100644
index 0000000..55bfcf0
--- /dev/null
+++ b/delivery-map.md
@@ -0,0 +1,463 @@
+# GrowQR Delivery Map — June 3, 2026
+
+> **Goal:** Ship a testable GrowQR dashboard + backend to AVPS in one session. Team should be able to log in, start a workflow, chat with the agent, open service pages, and see analytics.
+
+---
+
+## 1. Repo Landscape
+
+| Repo | Role | Status |
+|---|---|---|
+| `growqr-backend` | Production backend (Hono + Rivet + Drizzle + AI SDK) | Active development |
+| `growqr-dashboard` | **Target dashboard UI** (Next.js 14 + Clerk + Tailwind) | Mock data — needs API integration |
+| `growqr-next-frontend` | **Reference only** — has v2/v3 UI we can borrow from | Abandoned as primary frontend |
+| `growqr-app/frontend` | **Reference only** — production interview/roleplay/resume components | Still in production separately |
+
+**Rule:** All new UI goes into `growqr-dashboard`. Other repos are read-only reference.
+
+---
+
+## 2. Backend Current State
+
+### What already works
+
+- Clerk-authenticated Hono routes
+- Rivet actor registry with per-user `userActor`, per-run `workflowRunActor`, and service actors (`interviewServiceActor`, `roleplayServiceActor`, `resumeServiceActor`)
+- Workflow registry with 5 sellable workflow definitions
+- Database tables: `workflowRuns`, `workflowRunModules`, `workflowEvents`, `workflowArtifacts`, `workflowApprovals`, `qscoreSnapshots`
+- Service adapters for resume, interview, roleplay, Q Score
+- Chat route with LLM fallback + tool dispatch (start interview, start roleplay, analyze resume, compute qscore)
+- Gitea per-user repo model
+- OpenCode container lifecycle
+- Prompt/agent markdown loading
+
+### Backend API surface
+
+```
+GET /workflows — list all workflow definitions
+GET /workflows/:workflowId — get single workflow definition
+POST /workflows/:workflowId/runs — start a workflow run
+GET /workflows/:workflowId/runs/current — get current run for workflow
+GET /workflows/capabilities/services — list service capabilities
+GET /workflows/capabilities/health — health check all services
+GET /workflows/runs/history — user's run history
+GET /workflows/validate — validate all workflow defs
+
+GET /workflow-runs/:runId — full run detail (modules, artifacts, events)
+POST /workflow-runs/:runId/pause — pause run
+POST /workflow-runs/:runId/resume — resume run
+POST /workflow-runs/:runId/run — run all modules until next gate
+POST /workflow-runs/:runId/modules/:moduleId/run — run single module
+GET /workflow-runs/:runId/artifacts — list artifacts
+GET /workflow-runs/:runId/artifacts/:id/content — read artifact content
+GET /workflow-runs/:runId/events — list events
+POST /workflow-runs/:runId/approvals/:id — approve/reject gate
+
+POST /chat — chat with Grow Agent
+
+# Legacy compat aliases
+GET /workflows/job-application
+POST /workflows/job-application
+POST /workflows/job-application/pause
+POST /workflows/job-application/resume
+POST /workflows/job-application/agents/:moduleId/run
+POST /workflows/job-application/agents/:moduleId/score
+```
+
+### 5 Sellable Workflows
+
+| ID | Title | Urgency | Duration | Modules |
+|---|---|---|---|---|
+| `interview-to-offer` | Interview-to-Offer Accelerator | High | 2–5 days | resume → interview-plan → sara → emily → qscore |
+| `career-transition` | Career Transition Sprint | Medium | 1–2 weeks | transition-map → resume |
+| `salary-negotiation-war-room` | Salary Negotiation War Room | High | 24–72 hrs | negotiation-script → emily |
+| `promotion-readiness` | Promotion Readiness Packet | Medium | 1 week | evidence-packet → emily |
+| `personal-brand-opportunity-engine` | Personal Brand Opportunity Engine | Low | 1 week | profile-rewrite |
+
+### What the backend still needs today
+
+- Verify build/typecheck passes
+- Verify all routes respond locally
+- Add clean analytics/Q Score summary endpoint if missing
+- Ensure service actors work for Q Score
+- Smoke-test workflow creation → module run
+- Confirm env vars are correct for AVPS deploy
+
+---
+
+## 3. Dashboard Current State
+
+### Existing pages (all using mock data)
+
+```
+app/page.tsx — Home
+app/analytics/page.tsx — Analytics
+app/community/page.tsx — Community
+app/events/page.tsx — Events
+app/features/page.tsx — Features (available/active tabs)
+app/features/[id]/page.tsx — Feature detail
+app/mentor/page.tsx — Mentor
+app/pathways/page.tsx — Pathways
+app/productivity/page.tsx — Productivity
+app/rewards/page.tsx — Rewards
+app/settings/page.tsx — Settings
+app/social/page.tsx — Social
+app/suggestions/page.tsx — Suggestions
+app/workflows/page.tsx — Workflows (available/active tabs)
+app/workflows/[id]/page.tsx — Workflow detail
+```
+
+### Dashboard components
+
+```
+components/AppShell.tsx
+components/ModuleHeader.tsx
+components/ActiveWorkflowDetail.tsx
+components/AvailableWorkflowCard.tsx
+components/PromptBar.tsx
+```
+
+### Dashboard design system
+
+- Tailwind with custom theme (`brand-orange`, `ink`, `surface-rail`, etc.)
+- `rounded-tile` pattern for cards
+- Day simulation via `useDay()` for demo progression
+
+### What the dashboard needs today
+
+1. **API layer** — typed client to backend (replace mock `getWorkflows`, `getFeatures`, etc.)
+2. **API proxy** — `app/api/growqr/[...path]/route.ts` to avoid CORS issues
+3. **Workflows page** — wire to real backend
+4. **Workflow detail** — add mission state sidebar + workflow chat
+5. **Talk to Me chat** — new chat page with streaming-ish UI
+6. **Feature pages** — port interview/roleplay/resume/Q Score from other repos
+7. **Analytics** — merge Q Score + career performance data
+
+---
+
+## 4. Reference UI Sources
+
+### From `growqr-next-frontend`
+
+| What | Source Path | Use For |
+|---|---|---|
+| v3 Workflows layout | `src/app/v3/workflows/page.tsx` | Workflow page layout with slim sidebar |
+| v3 Workflow detail | `src/app/v3/workflows/interview-to-offer/page.tsx` | Active workflow detail pattern |
+| v2 Services (already ported) | `src/app/v2/services/interview/*` | Interview/roleplay/resume pages |
+| Q Score | `src/app/qx-score/page.tsx`, `src/app/v2/qx-score/page.tsx` | Analytics/Q Score UI |
+| Chat route | `src/app/api/chat/route.ts` | Streaming chat backend pattern |
+| Auth flow | `src/app/auth/*` | Career profile, goals, onboarding |
+
+### From `growqr-app/frontend`
+
+| What | Source Path | Use For |
+|---|---|---|
+| Interview components | `src/components/interview/*` | LiveAvatarVideo, CoachingBanner, EquipmentCheck, etc. |
+| Interview pages | `src/app/(dashboard)/upskilling/interview/*` | Setup, preview, feedback |
+| Roleplay components | `src/components/roleplay/*` | LiveAvatarVideo, RoleplayLaunchOverlay, FeedbackDashboard |
+| Resume components | `src/components/resume/*` | ResumeUpload, ResumeCard, ResumePreviewModal, TemplateGallery |
+| Interview hooks | `src/hooks/useInterview*.ts` | Session, media, review, recording hooks |
+| Interview lib | `src/lib/interview/*` | Types, API helpers |
+
+---
+
+## 5. Execution Plan — 6 Hours
+
+### Phase 1: Stabilize & Map (0:00–0:30)
+
+**Goal:** Know exactly what's broken before touching UI.
+
+- [ ] Run `growqr-backend` build + typecheck
+- [ ] Run `growqr-dashboard` build
+- [ ] Check envs: backend URL, Clerk keys, service URLs, AVPS deploy env
+- [ ] Confirm backend routes respond locally (`/workflows`, `/chat`, etc.)
+- [ ] Document short failure list
+
+**Deliverable:** Known broken things list. No UI changes yet.
+
+---
+
+### Phase 2: Dashboard API Layer (0:30–1:30)
+
+**Goal:** Dashboard can talk to backend instead of mock data.
+
+Create in `growqr-dashboard`:
+
+```
+lib/api.ts — Base fetch wrapper with auth
+lib/growqr-api.ts — Typed API client
+types/workflows.ts — Workflow/run/module types
+types/chat.ts — Chat message types
+app/api/growqr/[...path]/route.ts — Next.js API proxy
+```
+
+Client methods needed:
+
+```ts
+listWorkflows()
+getWorkflow(id)
+startWorkflow(workflowId, goal?, input?)
+getCurrentRun(workflowId)
+getWorkflowRun(runId)
+runWorkflow(runId)
+runModule(runId, moduleId)
+pauseRun(runId)
+resumeRun(runId)
+sendChat(messages)
+getRunArtifacts(runId)
+getRunEvents(runId)
+approveGate(runId, approvalId, status)
+```
+
+**Deliverable:** Dashboard fetches real workflow data from backend.
+
+---
+
+### Phase 3: Workflows Page MVP (1:30–2:30)
+
+**Goal:** Workflows become real product pages.
+
+Update these files:
+
+```
+app/workflows/page.tsx — Wire to real API
+app/workflows/[id]/page.tsx — Wire to real API
+components/AvailableWorkflowCard.tsx — Show real workflow data
+components/ActiveWorkflowDetail.tsx — Show real run state
+```
+
+Required behavior:
+
+- Available tab lists 5 backend workflows with real data
+- Each card shows: promise, modules, duration, price, "Start workflow" button
+- Starting a workflow calls `POST /workflows/:workflowId/runs`
+- Active section calls `GET /workflows/:workflowId/runs/current`
+- Detail page layout:
+ - Left: slim workflow nav
+ - Top: current workflow title + status bar
+ - Center: workflow chat / work area
+ - Right: mission state (modules, artifacts, events, approvals)
+
+**Deliverable:** User can start and view a workflow from the dashboard.
+
+---
+
+### Phase 4: Chat Surfaces (2:30–3:30)
+
+**Goal:** Product feels agentic with two chat surfaces.
+
+#### A. Global "Talk to Me" Chat
+
+New page:
+
+```
+app/talk/page.tsx (or app/chat/page.tsx)
+```
+
+Purpose:
+
+- Agent discovery & workflow recommendation
+- Starting workflows from conversation
+- Pulling workflow status
+- User preferences & memory
+- General career questions
+
+Backend: `POST /chat`
+
+UI should show:
+
+- Streaming-like assistant response (staged states if not truly streaming)
+- Tool/session cards when backend returns sessions
+- Workflow suggestion/action buttons when backend recommends one
+- Progressive states: "Reading memory…" → "Checking workflows…" → "Thinking…" → response
+
+#### B. Workflow-Specific Chat
+
+Inside `app/workflows/[id]/page.tsx`:
+
+- "Run next step", "Show status", "Launch interview", "Open artifact", "Approve plan"
+- Calls same `/chat` with workflow context prepended
+- Shows module execution results inline
+
+**Deliverable:** Both chat surfaces are functional and connected to backend.
+
+---
+
+### Phase 5: Feature/Service Pages (3:30–4:45)
+
+**Goal:** Feature cards route to working service UIs.
+
+New pages in dashboard:
+
+```
+app/features/resume/page.tsx
+app/features/interview/page.tsx
+app/features/roleplay/page.tsx
+app/features/qscore/page.tsx
+```
+
+Port strategy (in priority order):
+
+1. **Interview** — from `growqr-app/frontend/src/components/interview/*` + `growqr-next-frontend/src/app/v2/services/interview/*`
+2. **Roleplay** — from `growqr-app/frontend/src/components/roleplay/*` + `growqr-next-frontend/src/app/v2/services/roleplay/*`
+3. **Resume** — from `growqr-app/frontend/src/components/resume/*` + `growqr-next-frontend/src/app/v2/services/resume/*`
+4. **Q Score** — from `growqr-next-frontend/src/app/v2/qx-score/*`
+
+Shortcut approach:
+
+- Create dashboard-compatible wrappers, not perfect ports
+- Missing backend data → clean empty/loading states
+- Support workflow query params: `?workflowRunId=...&moduleId=...`
+
+**Deliverable:** Feature cards open functional service pages.
+
+---
+
+### Phase 6: Q Score + Analytics (4:45–5:30)
+
+**Goal:** Coherent analytics page with real data where available.
+
+Merge from:
+
+- `growqr-dashboard/app/analytics/page.tsx` (existing)
+- `growqr-next-frontend/src/app/qx-score/page.tsx`
+- `growqr-next-frontend/src/app/v2/qx-score/page.tsx`
+
+Minimum analytics sections:
+
+- Current Q Score (gauge/number)
+- Baseline vs Latest comparison
+- Workflow progress contribution
+- Readiness dimension breakdown
+- Recent sessions/events timeline
+- Recommended next action
+
+Backend data sources:
+
+- `workflowRuns.qscoreBefore` for baseline
+- `qscoreSnapshots` table for history
+- `/workflow-runs/:runId` for module progress
+- Add `GET /analytics/summary` endpoint if needed
+
+**Deliverable:** Analytics page shows real Q Score + workflow progress.
+
+---
+
+### Phase 7: Build, Fix, Deploy (5:30–6:15)
+
+**Goal:** Everything builds, deploys, and team can test.
+
+- [ ] `cd growqr-backend && bun run typecheck && bun run build`
+- [ ] `cd growqr-dashboard && pnpm build`
+- [ ] Fix only blockers: type errors, missing imports, env names, auth/proxy
+- [ ] Deploy to AVPS
+- [ ] Send test links + testing checklist to team
+
+**Deliverable:** Deployed link on AVPS.
+
+---
+
+## 6. Hard Cuts — What We Are NOT Doing Today
+
+To finish in 6 hours, we explicitly skip:
+
+- Homepage rethink / redesign
+- Full billing / entitlement / SKU enforcement
+- True streaming protocol (SSE/WebSocket) — simulate with staged UI
+- Complete service UI parity with `growqr-app`
+- Deep memory/conversation history UI
+- Advanced workflow graph animations
+- New backend architecture changes
+- Moving/cleaning all three repos
+- Community, events, social, rewards, productivity, mentor, pathways, suggestions pages
+- Mobile responsiveness polish
+- E2E tests
+
+---
+
+## 7. MVP Acceptance Checklist
+
+By end of session, team should be able to test all of these:
+
+- [ ] **Auth:** Login works with Clerk
+- [ ] **Workflows page:** Lists 5 workflows from backend
+- [ ] **Start workflow:** User can start Interview-to-Offer
+- [ ] **Active workflow:** Detail page shows modules/state/events
+- [ ] **Run module:** User can trigger at least one module
+- [ ] **Talk to Me chat:** Responds to messages, can suggest/trigger workflows
+- [ ] **Workflow chat:** Exists inside workflow detail page
+- [ ] **Features page:** Opens Interview, Roleplay, Resume, Q Score
+- [ ] **Analytics:** Shows Q Score and workflow progress
+- [ ] **Deploy:** Dashboard builds and deploys to AVPS
+- [ ] **Team test link:** Sent with testing instructions
+
+---
+
+## 8. Implementation Priority Order
+
+If time runs short, do these in exactly this order:
+
+1. Dashboard API proxy + typed client
+2. Real workflows list / start / current-run
+3. Workflow detail shell with mission state + chat
+4. Global Talk-to-Me chat page
+5. Feature page routing to service pages
+6. Q Score / analytics page
+7. Build / deploy / test links
+
+---
+
+## 9. Key Files Reference
+
+### Backend
+
+```
+growqr-backend/src/index.ts — App entry
+growqr-backend/src/config.ts — Env config
+growqr-backend/src/actors/registry.ts — Rivet actor registry
+growqr-backend/src/actors/user-actor.ts — Per-user actor
+growqr-backend/src/actors/workflow-run-actor.ts — Per-run actor
+growqr-backend/src/actors/product-service-actors.ts — Service actors
+growqr-backend/src/routes/workflows.ts — Workflow + run routes
+growqr-backend/src/routes/chat.ts — Chat route
+growqr-backend/src/routes/services.ts — Service routes
+growqr-backend/src/workflows/registry.ts — 5 workflow definitions
+growqr-backend/src/workflows/module-runner.ts — Module execution
+growqr-backend/src/workflows/types.ts — Workflow types
+growqr-backend/src/db/schema.ts — Database schema
+growqr-backend/src/agents/catalog.ts — Agent catalog + prompts
+```
+
+### Dashboard
+
+```
+growqr-dashboard/app/layout.tsx — Root layout
+growqr-dashboard/app/page.tsx — Home
+growqr-dashboard/app/workflows/page.tsx — Workflows list
+growqr-dashboard/app/workflows/[id]/page.tsx — Workflow detail
+growqr-dashboard/app/features/page.tsx — Features list
+growqr-dashboard/app/features/[id]/page.tsx — Feature detail
+growqr-dashboard/app/analytics/page.tsx — Analytics
+growqr-dashboard/components/AppShell.tsx — Shell + sidebar
+growqr-dashboard/components/PromptBar.tsx — Chat input bar
+growqr-dashboard/middleware.ts — Clerk middleware
+growqr-dashboard/lib/state.ts — Day simulation state
+growqr-dashboard/data/workflows.ts — Mock workflow data (TO REPLACE)
+growqr-dashboard/data/features.ts — Mock feature data (TO REPLACE)
+```
+
+### Reference (read-only)
+
+```
+growqr-next-frontend/src/app/v3/workflows/* — Workflow UI pattern
+growqr-next-frontend/src/app/v2/services/interview/* — Interview pages
+growqr-next-frontend/src/app/v2/services/roleplay/* — Roleplay pages
+growqr-next-frontend/src/app/v2/services/resume/* — Resume pages
+growqr-next-frontend/src/app/v2/qx-score/* — Q Score UI
+growqr-next-frontend/src/app/api/chat/route.ts — Chat streaming pattern
+growqr-app/frontend/src/components/interview/* — Production interview components
+growqr-app/frontend/src/components/roleplay/* — Production roleplay components
+growqr-app/frontend/src/components/resume/* — Production resume components
+growqr-app/frontend/src/hooks/useInterview*.ts — Interview hooks
+growqr-app/frontend/src/lib/interview/* — Interview lib
+```
diff --git a/dev-test-account.md b/dev-test-account.md
new file mode 100644
index 0000000..8e454f4
--- /dev/null
+++ b/dev-test-account.md
@@ -0,0 +1,86 @@
+# Dev Test Account
+
+## Credentials
+
+| Field | Value |
+|----------|--------------------------|
+| Email | test@test.com |
+| Password | Violet-Mountain-97!qR |
+| User ID | user_3EXAwsYrQ6WtQgxjaJtxVTEWYqz |
+
+## How the account was created
+
+### 1. Create user in Clerk
+
+```bash
+cd growqr-next-frontend
+
+node - <<'NODE'
+const { createClerkClient } = require("@clerk/backend");
+const fs = require("fs");
+const secretKey = fs.readFileSync(".env.local", "utf8").match(/^CLERK_SECRET_KEY=(.*)$/m)[1].trim();
+const clerk = createClerkClient({ secretKey });
+
+(async () => {
+ const email = "test@test.com";
+ const password = "Violet-Mountain-97!qR";
+ const existing = await clerk.users.getUserList({ emailAddress: [email] });
+ if (existing.data?.[0]) {
+ console.log("already exists:", existing.data[0].id);
+ return;
+ }
+ const user = await clerk.users.createUser({
+ emailAddress: [email],
+ password,
+ firstName: "Test",
+ lastName: "User",
+ skipPasswordChecks: true,
+ });
+ console.log("created:", user.id, email);
+})();
+NODE
+```
+
+### 2. Mirror user into local Postgres
+
+```bash
+cd growqr-backend
+
+docker compose exec -T postgres psql -U growqr -d growqr -c \
+ "INSERT INTO users (id, email, display_name)
+ VALUES ('user_3EXAwsYrQ6WtQgxjaJtxVTEWYqz', 'test@test.com', 'Test User')
+ ON CONFLICT (id) DO UPDATE SET email = EXCLUDED.email, display_name = EXCLUDED.display_name, updated_at = now();"
+```
+
+## Logging in without email verification (dev token)
+
+Clerk enforces email verification on sign-in. For dev, generate a sign-in token
+and open it directly in the browser:
+
+```bash
+cd growqr-next-frontend
+
+TOKEN=$(node -e '
+const { createClerkClient } = require("@clerk/backend");
+const fs = require("fs");
+const secretKey = fs.readFileSync(".env.local", "utf8").match(/^CLERK_SECRET_KEY=(.*)$/m)[1].trim();
+const clerk = createClerkClient({ secretKey });
+(async () => {
+ const userId = (await clerk.users.getUserList({ emailAddress: ["test@test.com"] })).data[0].id;
+ const t = await clerk.signInTokens.createSignInToken({ userId, expiresInSeconds: 3600 });
+ process.stdout.write(t.token);
+})();
+')
+
+open "http://localhost:3000/auth/signin?__clerk_ticket=$TOKEN"
+```
+
+This signs in as **Test User** and redirects to `/v2`.
+
+## Notes
+
+- Clerk is in **development mode** (test instance: `noted-elephant-23`).
+- `skipPasswordChecks: true` bypasses breach-detection (the first password
+ `Test1234!` was rejected as compromised).
+- The sign-in token flow avoids the email code verification step entirely.
+- Token expires after 1 hour; re-run the command to get a fresh one.
diff --git a/event flow.md b/event flow.md
new file mode 100644
index 0000000..66adbfb
--- /dev/null
+++ b/event flow.md
@@ -0,0 +1,849 @@
+> **Missions are not chat flows. Missions are event-driven product journeys.**
+> Chat/Grow Agent is only one optional surface that can read mission state and help the user decide what to do next.
+
+The mission dashboard should work even if the user never opens chat.
+
+I read the Rivet docs you linked, the current backend mission/actor code, the old `growqr-app/orchestrator`, and the service event patterns. The correct production design is a **mission event system + dashboard projection**, not a chat-first workflow.
+
+---
+
+# Revised product model
+
+## User buys a mission
+
+Example:
+
+> **Interview-to-Offer Accelerator — $10/month**
+
+Includes limits like:
+
+- 10 mock interviews/month
+- X resume analyses/optimizations
+- maybe 1 final readiness report
+- optional add-ons later: roleplay, extra interviews, video analysis, etc.
+
+After purchase, the user gets an **active mission dashboard**.
+
+The dashboard shows:
+
+- current mission progress
+- next required action
+- completed service actions
+- generated artifacts
+- interview/resume results
+- Q Score/readiness trend
+- quota usage
+- recommendations
+
+Chat can help, but the dashboard is the primary surface.
+
+---
+
+# Important correction for Interview-to-Offer
+
+If the team says this mission currently uses only:
+
+- Resume
+- Interview
+
+Then don’t force Roleplay into the core package.
+
+Roleplay can become:
+
+1. an upsell,
+2. a recommended recovery action,
+3. a premium variant,
+4. or a later stage only if interview results show communication weakness.
+
+So the core mission becomes:
+
+## Interview-to-Offer Accelerator v1
+
+### Included services
+
+- Resume Building
+- Mock Interview
+- Q Score/readiness analytics
+- Grow Agent/planning only as backend intelligence, not necessarily chat
+
+### Core stages
+
+1. Purchase / mission activated
+2. Resume uploaded or selected
+3. Resume analyzed/improved for target interview
+4. Interview prep plan generated
+5. Mock interview configured
+6. Mock interview completed
+7. Review received
+8. Final readiness score/report generated
+
+That is much cleaner.
+
+---
+
+# What exists today
+
+From the code:
+
+## Backend already has
+
+- `grow_active_missions`
+- mission actors like `interviewToOfferMissionActor`
+- mission snapshots
+- explicit APIs to update stages and artifacts
+- PG-first persistence for active missions
+- Q Score snapshots/workflow event tables from older workflow infra
+
+But right now, mission progress updates mostly happen through explicit backend calls like:
+
+```txt
+POST /missions/active/:instanceId/stages/:stageId
+POST /missions/active/:instanceId/artifacts
+```
+
+That means the dashboard does not automatically know when a microservice finishes something unless we explicitly update the mission.
+
+## Old orchestrator already had a useful pattern
+
+The old `growqr-app/orchestrator`:
+
+- routes actions to services
+- receives `agent_data` messages
+- extracts Q Score signals from service results
+- publishes signals to `qscore.signal_events`
+- handles real-time score updates
+
+But it has too much routing registry logic:
+
+```py
+ACTION_TO_AGENT
+PAGE_TO_AGENT
+COMPOSITE_WORKFLOWS
+```
+
+We should not rebuild that as another large registry.
+
+## Services emit useful events/messages already
+
+Examples:
+
+Resume emits A2A-style messages:
+
+- `resume_created`
+- `resume_loaded`
+- `version_saved`
+- `ai_analysis_complete`
+- `ai_summary_optimized`
+- `ai_skills_suggested`
+- `export_ready`
+
+Interview emits:
+
+- `interview_configured`
+- `session.completed` over live WS
+- review endpoint returns `completed`, `processing`, `failed`, `not_eligible`
+- `review_loaded` through agentic path
+
+Roleplay emits similar patterns.
+
+Q Score already has a strong event ingestion path:
+
+```txt
+qscore.signal_events Redis stream
+```
+
+So the missing layer is not “service capability.” It is a **GrowQR mission event ingestion/projection layer**.
+
+---
+
+# Correct architecture
+
+## Principle
+
+> Postgres is the source of truth. Actors are live reducers/projectors. Chat is just one consumer.
+
+## Event flow
+
+```txt
+Service action happens
+ ↓
+GrowQR backend receives/creates event
+ ↓
+Raw event is stored in Postgres event inbox
+ ↓
+Event is forwarded to the relevant mission actor
+ ↓
+Mission actor updates mission snapshot/progress/artifacts
+ ↓
+Dashboard reads updated mission snapshot
+ ↓
+Q Score signals are published/updated
+ ↓
+Grow/chat may optionally read the same state
+```
+
+---
+
+# New concept: dynamic mission events
+
+We do **not** need a rigid event registry.
+
+We need one flexible event envelope.
+
+## Generic event envelope
+
+```ts
+type GrowEvent = {
+ id: string;
+ userId: string;
+ orgId?: string;
+
+ source: string;
+ // resume-service, interview-service, roleplay-service, qscore-service, grow-backend
+
+ type: string;
+ // resume.ai_analysis_complete
+ // interview.session_completed
+ // interview.review_completed
+ // mission.purchased
+ // qscore.updated
+
+ category:
+ | "mission"
+ | "service"
+ | "artifact"
+ | "usage"
+ | "qscore"
+ | "entitlement"
+ | "system";
+
+ occurredAt: string;
+
+ mission?: {
+ instanceId?: string;
+ missionId?: string;
+ stageId?: string;
+ };
+
+ subject?: {
+ kind: string;
+ id: string;
+ };
+ // example: { kind: "interview_session", id: sessionId }
+
+ correlation?: {
+ requestId?: string;
+ sessionId?: string;
+ resumeId?: string;
+ externalId?: string;
+ };
+
+ payload: Record;
+};
+```
+
+The important thing: **we store unknown events too.**
+
+If an event type is new, we don’t reject it. We save it, attach it to the user/mission if possible, and show it in debugging/timeline if useful.
+
+---
+
+# Postgres tables needed
+
+Do not rely on actor state for durable history.
+
+Add something like:
+
+## `grow_events`
+
+Append-only event inbox.
+
+Fields:
+
+- `id`
+- `user_id`
+- `mission_instance_id`
+- `source`
+- `type`
+- `category`
+- `subject_kind`
+- `subject_id`
+- `correlation_id`
+- `payload`
+- `occurred_at`
+- `received_at`
+- `processed_at`
+- `processing_status`
+- `error`
+
+## `mission_service_sessions`
+
+Tracks external service objects created for a mission.
+
+Examples:
+
+- interview session ID
+- resume ID
+- roleplay session ID
+- qscore run ID
+
+Fields:
+
+- `id`
+- `user_id`
+- `mission_instance_id`
+- `stage_id`
+- `service_id`
+- `external_type`
+- `external_id`
+- `status`
+- `last_event_id`
+- `last_checked_at`
+- `created_at`
+- `updated_at`
+
+This table is crucial because the dashboard needs to know:
+
+> “This mission’s interview stage corresponds to interview session `abc123`.”
+
+## `mission_artifacts`
+
+Could either reuse current snapshot artifacts or make durable table.
+
+Examples:
+
+- resume fit scan
+- interview prep plan
+- interview review
+- readiness report
+
+---
+
+# Actor design
+
+Do **not** put this all in `growActor`.
+
+`growActor` is becoming chat/conversation/user home state. Missions should not depend on it.
+
+## Best actor model
+
+### 1. Mission actor per active mission
+
+Already exists:
+
+```txt
+interviewToOfferMissionActor[userId, instanceId]
+```
+
+Extend it conceptually to support:
+
+```ts
+ingestEvent(event)
+recomputeProjection()
+scheduleExternalCheck()
+getDashboardSnapshot()
+```
+
+The actor stores only bounded state:
+
+- current stage
+- progress
+- latest known service session IDs
+- latest scores
+- artifact summaries
+- next action
+- last few events maybe
+
+Raw events stay in Postgres.
+
+### 2. Optional user analytics actor
+
+A per-user analytics actor can exist later:
+
+```txt
+userAnalyticsActor[userId]
+```
+
+Its job:
+
+- update user-level Q Score trend
+- aggregate events across missions
+- maintain dashboard analytics
+- detect recommendations
+
+But don’t make it mandatory for v1. The mission actor + PG event store is enough.
+
+### 3. Do not create one god event actor
+
+Avoid:
+
+```txt
+globalEventProcessorActor
+```
+
+That becomes a bottleneck.
+
+Better:
+
+```txt
+event ingest route → Postgres → mission actor for that mission/user
+```
+
+Rivet docs support actor queues and schedules, which are good primitives here. Use queues for ordered event processing and schedules for later status checks. The docs also note actor `noSleep` is deprecated in current docs, so we should avoid relying on permanent awake actors long-term, even though the project is pinned to `rivetkit ^2.2.1`.
+
+---
+
+# Event ingestion paths
+
+We need multiple ingestion paths because not every service currently emits backend webhooks.
+
+## 1. Backend gateway-generated events
+
+Whenever the dashboard calls GrowQR backend gateway:
+
+```txt
+POST /services/interview/configure
+POST /services/resume/resumes/:id/analyze
+POST /services/interview/review/:sessionId
+```
+
+The backend should emit internal events like:
+
+```txt
+interview.configured
+resume.analysis_requested
+resume.analysis_completed
+interview.review_completed
+```
+
+This is the easiest first layer.
+
+## 2. Service webhook/event endpoint
+
+Add a backend route:
+
+```txt
+POST /events/ingest
+```
+
+Services can call this when they complete things:
+
+```txt
+resume.ai_analysis_complete
+interview.session_completed
+interview.review_completed
+roleplay.review_completed
+```
+
+This is ideal long term.
+
+## 3. Redis stream bridge
+
+Old services already use Redis streams for task responses.
+
+We can add a backend consumer that listens to service response messages and converts them into Grow events.
+
+But I would not make Redis the only source of truth. It should feed Postgres.
+
+## 4. Polling/checker fallback
+
+This is mandatory.
+
+Some events will be missed. Some services currently only expose state through REST. Some live WebSocket events go straight to the browser.
+
+So when a mission creates an interview session, store:
+
+```txt
+mission instance → interview session id
+```
+
+Then schedule checks:
+
+```txt
+check interview session/review in 30s
+check again in 2m
+check again in 5m
+stop when completed/failed/expired
+```
+
+Actors are good for this because Rivet supports scheduled actions.
+
+---
+
+# How the mission updates automatically
+
+Example: Interview-to-Offer.
+
+## User buys mission
+
+Backend creates event:
+
+```txt
+mission.purchased
+```
+
+Mission actor receives it:
+
+- status: active
+- stage: resume
+- progress: 0–10%
+- next action: upload/select resume
+
+Dashboard shows:
+
+> Next: Update your resume for this interview.
+
+---
+
+## User analyzes resume
+
+Dashboard calls Resume service through backend.
+
+Backend stores:
+
+```txt
+resume.analysis_requested
+```
+
+When result returns or poller finds result:
+
+```txt
+resume.ai_analysis_complete
+```
+
+Mission actor applies dynamic reducer:
+
+- source = resume-service
+- event contains resume analysis
+- mission stage = resume
+- mark resume stage done
+- create artifact: Resume Fit Scan
+- update progress
+- next action: Start mock interview
+
+No chat required.
+
+---
+
+## User starts interview
+
+Backend gateway calls Interview service configure.
+
+Backend stores:
+
+```txt
+interview.configured
+```
+
+Mission actor:
+
+- links session ID to mission
+- marks interview stage ready/in_progress
+- next action: Start interview session
+
+---
+
+## User completes interview
+
+Live WS sends `session.completed` to browser today.
+
+But backend should know through one of:
+
+1. service webhook,
+2. backend polling review endpoint,
+3. frontend callback to backend,
+4. Redis bridge if session completion is emitted there.
+
+Backend stores:
+
+```txt
+interview.session_completed
+```
+
+Mission actor:
+
+- stage status: review pending
+- next action: wait for review / view processing
+
+---
+
+## Review becomes available
+
+Backend fetches:
+
+```txt
+GET /services/interview/review/:sessionId
+```
+
+If completed, store:
+
+```txt
+interview.review_completed
+```
+
+Mission actor:
+
+- creates artifact: Mock Interview Review
+- marks interview stage done
+- extracts score/weaknesses
+- publishes Q Score signals
+- computes/requests final readiness
+- updates dashboard
+
+---
+
+# Q Score integration
+
+Q Score should be event-fed, not chat-fed.
+
+Current old orchestrator extracts signals from service messages. We can reuse that idea but move it into backend event processing.
+
+## Signal mapper should be dynamic-ish
+
+Instead of a giant event registry, use a few generic extractors by category/source:
+
+```txt
+resume event → resume signal extractor
+interview event → interview signal extractor
+roleplay event → roleplay signal extractor
+engagement/mission event → workflow signal extractor
+```
+
+This is not a mission registry. It is a small set of signal extractors.
+
+Example interview review signals:
+
+```txt
+interview.completed
+interview.overall_score
+interview.language_score
+interview.voice_score
+interview.body_language_score
+interview.filler_words
+interview.technical_quality
+```
+
+Resume signals:
+
+```txt
+resume.uploaded
+resume.ats_compatibility
+resume.keyword_relevance
+resume.grammar_clarity
+resume.impact_statements
+```
+
+Mission signals:
+
+```txt
+mission.interview_to_offer.started
+mission.interview_to_offer.resume_completed
+mission.interview_to_offer.interview_completed
+mission.interview_to_offer.completed
+```
+
+These are then sent to Q Score.
+
+---
+
+# Dashboard behavior
+
+The mission dashboard should be driven by mission state, not chat messages.
+
+## Active mission page
+
+For Interview-to-Offer:
+
+```txt
+Interview-to-Offer Accelerator
+
+Progress: 55%
+Plan: $10/month
+Usage:
+- Interviews: 2 / 10
+- Resume analyses: 1 / 3
+
+Current step:
+Mock Interview
+
+Next action:
+Start your 15-minute behavioral mock interview.
+
+Completed:
+✓ Mission purchased
+✓ Resume selected
+✓ Resume analyzed
+✓ Resume fit scan generated
+
+Artifacts:
+- Resume Fit Scan
+- Interview Prep Plan
+- Mock Interview Review, pending
+
+Readiness:
+Baseline Q Score: 64
+Current Q Score: 71
+Delta: +7
+```
+
+## Stage cards
+
+Each card has its own CTA:
+
+Resume stage:
+
+- Upload resume
+- Select resume
+- Analyze resume
+- View fit scan
+
+Interview stage:
+
+- Configure mock interview
+- Start interview
+- View review
+
+Final stage:
+
+- Generate readiness report
+- View final Q Score
+
+No chat required.
+
+---
+
+# Chat/Grow Agent’s new role
+
+Chat becomes a reader/writer of the same mission system.
+
+It can:
+
+- explain current mission status
+- recommend next action
+- call mission/service tools
+- summarize artifacts
+- answer “what should I do next?”
+
+But if the user never opens chat, the mission still progresses.
+
+So the Grow Agent should not own the mission. It should consume the mission projection.
+
+---
+
+# Subscription/usage tracking
+
+For paid missions, usage should also be event-based.
+
+Events:
+
+```txt
+entitlement.granted
+usage.interview_session_created
+usage.interview_session_completed
+usage.resume_analysis_requested
+usage.resume_analysis_completed
+usage.limit_reached
+subscription.renewed
+subscription.cancelled
+```
+
+The gateway should enforce limits before creating expensive service sessions.
+
+Example:
+
+```txt
+User clicks Start Interview
+↓
+Backend checks entitlement
+↓
+If allowed, create interview session
+↓
+Insert usage event
+↓
+Increment monthly usage
+```
+
+Do not rely on frontend hiding buttons.
+
+---
+
+# What I would build first
+
+## Phase 1 — Mission event backbone
+
+No new product logic yet. Just make events durable.
+
+- `grow_events`
+- `mission_service_sessions`
+- `/events/ingest`
+- backend helper: `recordGrowEvent()`
+- event forwarding to mission actor
+- mission actor `ingestEvent()`
+
+## Phase 2 — Backend gateway emits mission events
+
+Whenever dashboard uses service routes, backend records events.
+
+Examples:
+
+- interview configured
+- interview review fetched
+- resume analyzed
+- resume version saved
+
+## Phase 3 — Mission actor becomes projection reducer
+
+Add generic dynamic handling:
+
+- store unknown events
+- update timeline
+- if event matches current stage service, update stage
+- attach artifacts if payload has review/analysis/export
+- update next action
+
+## Phase 4 — Polling fallback
+
+For linked external sessions:
+
+- poll interview review until completed
+- poll roleplay review until completed
+- poll resume analysis state if needed
+
+## Phase 5 — Q Score bridge
+
+Convert service events into Q Score signals and publish them.
+
+## Phase 6 — Dashboard reads projection
+
+Dashboard should not guess. It reads:
+
+```txt
+GET /missions/active/:instanceId
+```
+
+and renders:
+
+- stages
+- events
+- artifacts
+- next action
+- usage
+- score trend
+
+---
+
+# Key recommendation
+
+Do not create another large service/action registry.
+
+Use this instead:
+
+1. **Feature registry** remains the product source of truth.
+2. **Mission definitions** define stages and included services.
+3. **Events are dynamic** and stored raw.
+4. **Small generic reducers** interpret categories/sources.
+5. **Unknown events are accepted, stored, and visible.**
+6. **Actors project events into live mission state.**
+7. **Postgres remains authoritative.**
+
+That gives you the cohesive, event-driven mission system you’re describing without recreating the old orchestrator registry.
\ No newline at end of file
diff --git a/frontend-v2-service-ui-port-plan.md b/frontend-v2-service-ui-port-plan.md
new file mode 100644
index 0000000..3b61ecb
--- /dev/null
+++ b/frontend-v2-service-ui-port-plan.md
@@ -0,0 +1,456 @@
+# Frontend V2 Service UI Port Plan
+
+Date: 2026-06-01
+
+## Purpose
+
+This document is the handoff/merge plan for porting only the useful service UIs from `growqr-app/frontend` into `growqr-next-frontend` under `/v2`, without pulling unrelated legacy app changes.
+
+The backend now has workflow orchestration and service facades for interview, roleplay, resume, and qscore. The next frontend work should expose polished service pages that workflows can redirect users into when a human/live sub-agent step is required.
+
+## Source and target repos
+
+Source UI reference:
+
+```txt
+/Users/puter/Workspace/growqr/growqr-app/frontend
+```
+
+Target frontend:
+
+```txt
+/Users/puter/Workspace/growqr/growqr-next-frontend
+```
+
+Target mount namespace:
+
+```txt
+/v2/services/*
+```
+
+## Important constraint
+
+Do **not** port all of `growqr-app/frontend`.
+
+Only port the service surfaces needed by workflows:
+
+- Interview service UI
+- Roleplay service UI
+- Resume service UI
+- Shared analysis/live-session widgets used by the above
+
+Avoid unrelated areas:
+
+- Billing / Razorpay
+- Cover letters, unless explicitly needed later
+- Settings pages
+- Onboarding flows
+- Old dashboard shell
+- Social branding pages
+- Legacy app navigation/sidebar
+
+## Desired routes in `growqr-next-frontend`
+
+Create these pages:
+
+```txt
+src/app/v2/services/interview/page.tsx
+src/app/v2/services/interview/setup/page.tsx
+src/app/v2/services/interview/preview/page.tsx
+src/app/v2/services/interview/feedback/page.tsx
+
+src/app/v2/services/roleplay/page.tsx
+src/app/v2/services/roleplay/setup/page.tsx
+src/app/v2/services/roleplay/builder/page.tsx
+src/app/v2/services/roleplay/feedback/page.tsx
+
+src/app/v2/services/resume/page.tsx
+src/app/v2/services/resume/[id]/page.tsx
+```
+
+Workflow redirects should eventually point to these routes, for example:
+
+```txt
+interview module → /v2/services/interview/setup?workflowRunId=...
+roleplay module → /v2/services/roleplay/setup?workflowRunId=...
+resume module → /v2/services/resume?workflowRunId=...
+```
+
+## Interview UI to port
+
+Source pages:
+
+```txt
+growqr-app/frontend/src/app/(dashboard)/upskilling/interview/page.tsx
+growqr-app/frontend/src/app/(dashboard)/upskilling/interview/setup/page.tsx
+growqr-app/frontend/src/app/(dashboard)/upskilling/interview/preview/page.tsx
+growqr-app/frontend/src/app/(dashboard)/upskilling/interview/feedback/page.tsx
+```
+
+Source components:
+
+```txt
+growqr-app/frontend/src/components/interview/InterviewLaunchOverlay.tsx
+growqr-app/frontend/src/components/interview/EquipmentCheckModal.tsx
+growqr-app/frontend/src/components/interview/LiveAvatarVideo.tsx
+growqr-app/frontend/src/components/interview/CoachingBanner.tsx
+growqr-app/frontend/src/components/interview/BuilderTipsCarousel.tsx
+growqr-app/frontend/src/components/interview/InterviewTipsCarousel.tsx
+growqr-app/frontend/src/components/interview/YourResultsSection.tsx
+
+growqr-app/frontend/src/components/feedback/FeedbackDashboard.tsx
+growqr-app/frontend/src/components/feedback/PresenceSection.tsx
+growqr-app/frontend/src/components/feedback/VideoAnalysisSection.tsx
+```
+
+Supporting hooks/libs:
+
+```txt
+growqr-app/frontend/src/hooks/useInterviewMedia.ts
+growqr-app/frontend/src/hooks/useInterviewSession.ts
+growqr-app/frontend/src/hooks/useInterviewReview.ts
+growqr-app/frontend/src/hooks/useSessionRecorder.ts
+growqr-app/frontend/src/hooks/useFaceFeedback.ts
+growqr-app/frontend/src/hooks/useLighting.ts
+growqr-app/frontend/src/hooks/useCoachingHints.ts
+growqr-app/frontend/src/hooks/usePresenceAggregator.ts
+
+growqr-app/frontend/src/lib/interview/types.ts
+growqr-app/frontend/src/lib/interview/lastRoute.ts
+growqr-app/frontend/src/lib/api/interview.ts
+growqr-app/frontend/src/lib/coaching/*
+```
+
+What this gives us:
+
+- Interview landing / role selection
+- Setup screen with persona, duration, audio/video mode
+- Generated interview plan preview
+- Live Avatar launch overlay
+- Equipment check
+- Live mic/camera session UI
+- Transcript handling
+- Post-interview analysis report
+- Presence/video analysis sections
+
+## Roleplay UI to port
+
+Source pages:
+
+```txt
+growqr-app/frontend/src/app/(dashboard)/upskilling/roleplay/page.tsx
+growqr-app/frontend/src/app/(dashboard)/upskilling/roleplay/setup/page.tsx
+growqr-app/frontend/src/app/(dashboard)/upskilling/roleplay/builder/page.tsx
+growqr-app/frontend/src/app/(dashboard)/upskilling/roleplay/feedback/page.tsx
+```
+
+Source components:
+
+```txt
+growqr-app/frontend/src/components/roleplay/RoleplayLaunchOverlay.tsx
+growqr-app/frontend/src/components/roleplay/LiveAvatarVideo.tsx
+growqr-app/frontend/src/components/roleplay/RoleplayFeedbackDashboard.tsx
+```
+
+Shared components reused from interview/feedback:
+
+```txt
+growqr-app/frontend/src/components/interview/EquipmentCheckModal.tsx
+growqr-app/frontend/src/components/interview/CoachingBanner.tsx
+growqr-app/frontend/src/components/feedback/PresenceSection.tsx
+growqr-app/frontend/src/components/feedback/VideoAnalysisSection.tsx
+```
+
+Supporting hooks/libs:
+
+```txt
+growqr-app/frontend/src/hooks/useRoleplaySession.ts
+growqr-app/frontend/src/hooks/useRoleplayReview.ts
+growqr-app/frontend/src/lib/roleplay/types.ts
+growqr-app/frontend/src/lib/roleplay/scenarios.ts
+growqr-app/frontend/src/lib/roleplay/lastRoute.ts
+growqr-app/frontend/src/lib/api/roleplay.ts
+```
+
+What this gives us:
+
+- Roleplay scenario picker
+- Custom scenario builder
+- Generated roleplay brief preview
+- Live Avatar roleplay overlay
+- Post-roleplay feedback/analysis report
+
+## Resume UI to port
+
+Source pages:
+
+```txt
+growqr-app/frontend/src/app/(dashboard)/opportunities/resume/page.tsx
+growqr-app/frontend/src/app/(dashboard)/opportunities/resume/[id]/page.tsx
+```
+
+Source components:
+
+```txt
+growqr-app/frontend/src/components/resume/ResumeList.tsx
+growqr-app/frontend/src/components/resume/ResumeCard.tsx
+growqr-app/frontend/src/components/resume/ResumeUpload.tsx
+growqr-app/frontend/src/components/resume/ResumePreviewModal.tsx
+
+growqr-app/frontend/src/components/resume/ResumeEditor/ResumeEditor.tsx
+growqr-app/frontend/src/components/resume/ResumeEditor/ResumeStrengthBar.tsx
+growqr-app/frontend/src/components/resume/ResumeEditor/AccordionPanel.tsx
+growqr-app/frontend/src/components/resume/ResumeEditor/components/*
+growqr-app/frontend/src/components/resume/ResumeEditor/sections/*
+growqr-app/frontend/src/components/resume/ResumeEditor/tabs/AICopilot.tsx
+growqr-app/frontend/src/components/resume/ResumeEditor/tabs/DesignTab.tsx
+
+growqr-app/frontend/src/components/resume/AIAnalysis/*
+```
+
+Supporting libs/types:
+
+```txt
+growqr-app/frontend/src/lib/api/resumes.ts
+growqr-app/frontend/src/types/resume.ts
+```
+
+Important resume adaptation:
+
+The source resume hub includes a cover-letter tab. For this phase, remove the cover-letter tab and keep resume-only UI.
+
+## API integration strategy
+
+Prefer our backend service facades through the existing Next proxy:
+
+```txt
+/api/growqr/services/interview/*
+/api/growqr/services/roleplay/*
+/api/growqr/services/resume/*
+```
+
+Backend facade examples already present:
+
+```txt
+GET /services/catalog
+GET /services/:service/health
+
+POST /services/interview/configure
+POST /services/interview/preview
+POST /services/interview/questions
+POST /services/interview/approve
+GET /services/interview/review/:sessionId
+GET /services/interview/leaderboard
+GET /services/interview/artifacts/:sessionId/:artifactType
+POST /services/interview/sessions/:sessionId/video/upload-url
+POST /services/interview/sessions/:sessionId/video/uploaded
+
+POST /services/roleplay/configure
+POST /services/roleplay/preview
+POST /services/roleplay/questions
+POST /services/roleplay/approve
+GET /services/roleplay/review/:sessionId
+GET /services/roleplay/leaderboard
+GET /services/roleplay/artifacts/:sessionId/:artifactType
+POST /services/roleplay/sessions/:sessionId/video/upload-url
+POST /services/roleplay/sessions/:sessionId/video/uploaded
+
+GET /services/resume/templates
+GET /services/resume/resumes
+POST /services/resume/resumes
+GET /services/resume/resumes/:resumeId
+PUT /services/resume/resumes/:resumeId
+POST /services/resume/resumes/:resumeId/analyze
+GET /services/resume/resumes/:resumeId/suggestions
+POST /services/resume/ai/copilot
+POST /services/resume/ai/optimize-summary
+POST /services/resume/ai/optimize-experience
+POST /services/resume/ai/suggest-skills
+POST /services/resume/ai/generate-summary
+GET /services/resume/resumes/:resumeId/versions
+POST /services/resume/resumes/:resumeId/versions
+GET /services/resume/resumes/:resumeId/preview
+```
+
+Recommended target API clients:
+
+```txt
+growqr-next-frontend/src/lib/services/interview.ts
+growqr-next-frontend/src/lib/services/roleplay.ts
+growqr-next-frontend/src/lib/services/resume.ts
+```
+
+These should call `/api/growqr/services/...`, not raw service URLs, wherever possible.
+
+## WebSocket caveat
+
+The existing Next route proxy at:
+
+```txt
+growqr-next-frontend/src/app/api/growqr/[...path]/route.ts
+```
+
+is HTTP-only and does not proxy WebSockets.
+
+Live interview/roleplay session overlays still need direct service WS URLs unless we add a backend WS gateway later:
+
+```txt
+NEXT_PUBLIC_INTERVIEW_WS_URL
+NEXT_PUBLIC_ROLEPLAY_WS_URL
+```
+
+The old source defaults were:
+
+```txt
+ws://localhost:8007/api/v1
+ws://localhost:8008/api/v1
+```
+
+Keep this in mind when validating the live avatar/audio session flow.
+
+## Dependencies likely needed in `growqr-next-frontend`
+
+Source UI uses these packages not guaranteed in target:
+
+```txt
+@mediapipe/tasks-vision
+livekit-client
+html2canvas
+jspdf
+react-markdown
+```
+
+Source imports `motion/react`. Target already has `framer-motion`; either:
+
+1. add `motion`, or
+2. rewrite imports from `motion/react` to `framer-motion`.
+
+Prefer option 2 if low-friction, to reduce dependency drift.
+
+## Assets to copy
+
+```txt
+growqr-app/frontend/public/mediapipe/*
+growqr-app/frontend/public/assets/images/personas/john.jpg
+growqr-app/frontend/public/assets/images/company-logos/*
+```
+
+The MediaPipe files are required by the face-feedback/presence coaching hooks.
+
+## CSS utilities to port
+
+From:
+
+```txt
+growqr-app/frontend/src/app/globals.css
+```
+
+Port only the service UI utilities/tokens needed by copied components:
+
+```css
+--color-brand-orange
+--color-brand-orangeLight
+--color-brand-orangeMuted
+
+.scrollbar-orange
+.glass
+.glass-strong
+.gradient-mesh
+.gradient-hero
+.gradient-orange
+.text-gradient
+.glow-primary
+.glow-orange
+.animate-float
+.animate-pulse-glow
+```
+
+Also verify Tailwind theme exposes `brand-orange` if copied components use classes like:
+
+```txt
+text-brand-orange
+bg-brand-orange
+border-brand-orange
+```
+
+## Layout adaptation
+
+Do not port the old `growqr-app` dashboard shell.
+
+Use target app's existing V2 shell:
+
+```txt
+growqr-next-frontend/src/app/v2/layout.tsx
+growqr-next-frontend/src/components/layout-v2/DashboardLayout.tsx
+```
+
+When copying source pages, remove imports of:
+
+```txt
+@/components/layout/DashboardLayout
+```
+
+because `/v2/layout.tsx` already wraps children.
+
+If a copied page needs full-width/no-padding behavior for live overlays or feedback reports, adapt locally inside `/v2/services/...` rather than replacing the global V2 layout.
+
+## Known import cleanup to avoid pulling too much
+
+Some source components import unrelated pieces. Replace or stub these:
+
+```txt
+src/components/dashboard-v2/cards/QuotientDistributionCard.tsx
+src/components/leaderboard/Leaderboard.tsx
+```
+
+Options:
+
+1. Port tiny versions if needed by feedback sections.
+2. Replace with simple local cards.
+3. Temporarily remove leaderboard sections from service pages if they block build.
+
+For resume, avoid imports from:
+
+```txt
+src/components/coverLetter/*
+src/components/billing/*
+src/components/onboarding/*
+```
+
+## Suggested implementation order
+
+1. Add service API clients in target.
+2. Port shared CSS tokens/utilities and assets.
+3. Port interview types/hooks/components/pages.
+4. Build and fix interview only.
+5. Port roleplay types/hooks/components/pages.
+6. Build and fix roleplay only.
+7. Port resume types/API/components/pages, resume-only.
+8. Build and fix resume only.
+9. Update workflow UI redirects/buttons to point to `/v2/services/...`.
+10. Run final validation.
+
+## Validation commands
+
+From target frontend:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-next-frontend
+bunx tsc --noEmit
+bun run build
+```
+
+Known note: lint may have unrelated legacy/pre-existing failures. Do not treat unrelated lint noise as the merge blocker unless the new service UI introduces it.
+
+## Merge checklist
+
+- [ ] New service pages live under `/v2/services/*` only.
+- [ ] No unrelated billing/settings/onboarding/social-branding UI copied.
+- [ ] Interview setup → preview → live overlay → feedback compiles.
+- [ ] Roleplay setup/builder → live overlay → feedback compiles.
+- [ ] Resume list/upload/editor/analysis compiles.
+- [ ] All service HTTP calls go through `/api/growqr/services/...` where possible.
+- [ ] WebSocket env vars documented for live interview/roleplay sessions.
+- [ ] Workflows can redirect to the new service routes.
+- [ ] `bunx tsc --noEmit` passes.
+- [ ] `bun run build` passes.
diff --git a/growqr-backend-launch-gap-plan.md b/growqr-backend-launch-gap-plan.md
new file mode 100644
index 0000000..3fbe867
--- /dev/null
+++ b/growqr-backend-launch-gap-plan.md
@@ -0,0 +1,553 @@
+# GrowQR Backend Launch Gap Plan
+
+This document only lists the **differences between the current backend and the target sellable-workflow platform**. It is written so a backend agent can work independently from the frontend/UI agent.
+
+Target assumption: workflows are sellable products; services are reusable capability engines; OpenCode is the per-user agentic execution workspace; Gitea is version-backed career memory; Rivet provides durable actor/workflow orchestration.
+
+---
+
+## 1. Current backend state observed
+
+Relevant backend files inspected:
+
+- `growqr-backend/src/index.ts`
+- `growqr-backend/src/config.ts`
+- `growqr-backend/src/routes/workflows.ts`
+- `growqr-backend/src/routes/chat.ts`
+- `growqr-backend/src/routes/agents.ts`
+- `growqr-backend/src/routes/opencode.ts`
+- `growqr-backend/src/actors/user-actor.ts`
+- `growqr-backend/src/db/schema.ts`
+- `growqr-backend/src/docker/manager.ts`
+- `growqr-backend/src/lib/opencode.ts`
+- `growqr-backend/src/lib/prompt-loader.ts`
+- `growqr-backend/src/services/service-agents.ts`
+- `growqr-backend/prompts/system.txt`
+- `growqr-backend/agents/*.md`
+
+### Already aligned / do not rewrite now
+
+- Clerk-authenticated backend routes exist.
+- Central Gitea + per-user repo model exists.
+- Per-user OpenCode container lifecycle exists.
+- Custom OpenCode image support exists.
+- OpenCode workspace cloning/syncing exists.
+- Prompt/agent markdown loading exists.
+- Password is stripped from public stack responses.
+- User actor exists and can manage chat, workflow state, service calls, Gitea memory, and stack provisioning.
+- Basic microservice adapters exist for resume, interview, roleplay, and Q Score.
+
+---
+
+## 2. Critical backend gaps
+
+### Gap A — Workflow API is hardcoded to `job-application`
+
+Current evidence:
+
+- `routes/workflows.ts` exposes only:
+ - `GET /workflows/job-application`
+ - `POST /workflows/job-application`
+ - `POST /workflows/job-application/pause`
+ - `POST /workflows/job-application/resume`
+ - `POST /workflows/job-application/agents/:moduleId/run`
+ - `POST /workflows/job-application/agents/:moduleId/score`
+- `user-actor.ts` sets IDs like `job-application:${userId}`.
+- `prompt-loader.ts` has `jobApplicationModuleIds()` hardcoded to `resume`, `job-search`, `job-apply`, `sara`, `emily`, `qscore`.
+
+Target difference:
+
+- Backend owns a real workflow product catalog.
+- Routes are parameterized by workflow ID.
+- The current route surface can stay as compatibility aliases, but the canonical API should be generic.
+
+Required change:
+
+Add backend workflow registry:
+
+```txt
+src/workflows/
+ types.ts
+ registry.ts
+ definitions/
+ interview-to-offer.ts
+ career-transition.ts
+ salary-negotiation-war-room.ts
+ promotion-readiness.ts
+ personal-brand-opportunity-engine.ts
+ first-job-launchpad.ts
+```
+
+Add routes:
+
+```txt
+GET /workflows
+GET /workflows/:workflowId
+POST /workflows/:workflowId/runs
+GET /workflows/:workflowId/runs/current
+GET /workflow-runs/:runId
+POST /workflow-runs/:runId/pause
+POST /workflow-runs/:runId/resume
+POST /workflow-runs/:runId/modules/:moduleId/run
+POST /workflow-runs/:runId/approvals/:approvalId
+```
+
+Keep temporary aliases:
+
+```txt
+/workflows/job-application → /workflows/interview-to-offer or /workflows/job-fit-apply-autopilot
+```
+
+---
+
+### Gap B — Workflow state is only actor memory, not a production run model
+
+Current evidence:
+
+- `db/schema.ts` has users, stacks, actors, repos, sessions, events.
+- No `workflow_definitions`, `workflow_runs`, `workflow_steps`, `workflow_artifacts`, `workflow_approvals`, or `qscore_snapshots` tables exist.
+- `user-actor.ts` keeps one workflow state in actor state: `workflowId`, `workflowStatus`, `workflowGoal`, `modules`, `timeline`.
+
+Target difference:
+
+- Workflow runs should be queryable, auditable, resumable, and visible even if the actor is unavailable.
+- Actor state can stay as the fast durable executor, but Postgres needs product/run records.
+
+Required change:
+
+Add minimal launch tables:
+
+```txt
+workflow_runs
+ id
+ user_id
+ workflow_id
+ workflow_version
+ status
+ goal
+ input jsonb
+ current_step_id
+ progress_percent
+ qscore_before jsonb
+ qscore_after jsonb
+ created_at
+ updated_at
+ completed_at
+
+workflow_run_modules
+ id
+ run_id
+ module_id
+ title
+ status
+ service
+ output_summary
+ output jsonb
+ error
+ started_at
+ completed_at
+
+workflow_artifacts
+ id
+ run_id
+ module_id
+ type
+ title
+ repo_path
+ public_url
+ metadata jsonb
+ created_at
+
+workflow_events
+ id
+ run_id
+ user_id
+ type
+ payload jsonb
+ created_at
+```
+
+For tomorrow, these can be simple Drizzle tables plus migration, not a full enterprise workflow engine.
+
+---
+
+### Gap C — No backend-owned sellable workflow definitions
+
+Current evidence:
+
+- Agent markdown files exist, but workflow products do not.
+- Workflow metadata such as title, promise, pricing, outputs, visual theme, required inputs, score dimensions, and artifact specs is absent.
+- Frontend currently fills this gap with hardcoded workflow cards.
+
+Target difference:
+
+- Backend should return workflow products directly to frontend.
+
+Required launch definitions:
+
+1. `interview-to-offer`
+2. `career-transition`
+3. `salary-negotiation-war-room`
+4. `promotion-readiness`
+5. `personal-brand-opportunity-engine`
+6. optional: `first-job-launchpad`
+
+Each definition should include:
+
+```ts
+type WorkflowDefinition = {
+ id: string;
+ version: string;
+ title: string;
+ shortTitle: string;
+ promise: string;
+ segment: string[];
+ urgency: "low" | "medium" | "high";
+ estimatedDuration: string;
+ priceTier: "free" | "starter" | "premium";
+ visual: {
+ icon: string;
+ color: string;
+ mascotAgentIds: string[];
+ };
+ requiredInputs: Array<{ id: string; label: string; type: string; required: boolean }>;
+ modules: WorkflowModuleDefinition[];
+ outputs: ArtifactDefinition[];
+ qscoreDimensions: string[];
+ approvalGates: ApprovalDefinition[];
+}
+```
+
+---
+
+### Gap D — Workflow modules can still complete as local placeholders
+
+Current evidence:
+
+- In `user-actor.ts`, modules with no `service` return summaries like:
+ - `completed a local workflow step for ...`
+ - `completed a local workflow step.`
+- `service-agents.ts` returns `status: "local"` for agents without a service.
+- `job-search` and `job-apply` currently act as local modules.
+
+Target difference:
+
+- No backend route should report real completion unless one of these happened:
+ 1. microservice executed,
+ 2. OpenCode executed and produced an artifact,
+ 3. user/human approval happened,
+ 4. module is explicitly marked `blocked` / `manual_required` / `coming_soon`.
+
+Required change:
+
+- Replace local success with explicit statuses:
+ - `blocked_service_unavailable`
+ - `manual_required`
+ - `waiting_for_input`
+ - `opencode_required`
+ - `coming_soon`
+- For launch workflows, every module must either call a real service, call OpenCode, or return a non-success blocked/manual status.
+
+---
+
+### Gap E — OpenCode exists but is not yet the workflow execution engine
+
+Current evidence:
+
+- `lib/opencode.ts` can create sessions and send messages.
+- `routes/opencode.ts` exposes session creation/message proxy.
+- `docker/manager.ts` provisions per-user OpenCode containers and syncs workspace to Git.
+- `user-actor.ts` workflow modules call `runServiceAgentProbe()` directly and do not use OpenCode for artifact generation.
+
+Target difference:
+
+- OpenCode should execute prompt-backed career artifact work when a module needs generated files or memory writes.
+
+Required change:
+
+Create a backend adapter:
+
+```txt
+src/workflows/executors/opencode-executor.ts
+```
+
+Responsibilities:
+
+- ensure/provision stack,
+- create OpenCode session per workflow module,
+- send workflow-specific prompt,
+- require structured JSON or markdown outputs,
+- write artifacts under `/workspace/artifacts/...`,
+- sync workspace to Git,
+- return artifact metadata to `workflow_artifacts`.
+
+Launch use cases for OpenCode:
+
+- interview prep plan,
+- likely questions,
+- behavioral story bank,
+- negotiation script,
+- promotion evidence packet,
+- LinkedIn/profile rewrite draft,
+- weekly brand content plan.
+
+---
+
+### Gap F — Prompt system is global, not workflow/product optimized
+
+Current evidence:
+
+- `prompts/system.txt` is one global Grow Agent prompt.
+- Agent markdown files load into `{{MODULE_DESCRIPTIONS}}`.
+- `user-actor.ts` manually defines tools and a special `start_interview_to_offer` path.
+- No workflow-specific prompt packs, output schemas, or eval checks exist.
+
+Target difference:
+
+- Each sellable workflow should have prompt packs and artifact contracts.
+
+Required change:
+
+Add workflow prompt files:
+
+```txt
+prompts/workflows/
+ interview-to-offer/
+ orchestrator.md
+ resume-analysis.md
+ interview-plan.md
+ story-bank.md
+ final-readiness-report.md
+ career-transition/
+ salary-negotiation-war-room/
+ promotion-readiness/
+ personal-brand-opportunity-engine/
+```
+
+Each module prompt should specify:
+
+- role,
+- inputs,
+- user tone,
+- output artifact path,
+- required sections,
+- JSON metadata contract,
+- Q Score dimensions affected,
+- what must be saved to memory.
+
+For prompt optimization tomorrow:
+
+- Add a small local prompt smoke test that verifies each workflow prompt produces required sections/JSON keys.
+- Version prompts with `PROMPT_VERSION`.
+- Store prompt version on `workflow_runs` and artifacts.
+
+---
+
+### Gap G — Chat route duplicates orchestration and infers workflow state
+
+Current evidence:
+
+- `routes/chat.ts` first tries Rivet actor, then falls back to direct LLM/tool dispatch.
+- The fallback has its own tool list, service calls, hardcoded localhost demo URLs, and `inferWorkflowStep()` heuristic.
+- `user-actor.ts` also has tool dispatch and workflow logic.
+
+Target difference:
+
+- Backend chat should not maintain a separate workflow engine.
+- Direct fallback may answer conversationally, but should not fabricate workflow state or duplicate module execution.
+
+Required change:
+
+- Make `userActor` / workflow service the only workflow mutation path.
+- In `routes/chat.ts`, fallback options should be limited to:
+ - simple LLM response with no workflow state, or
+ - call backend workflow service APIs, not duplicate logic.
+- Remove `inferWorkflowStep()` as product state source.
+- Replace session URL construction with service-provided/public configured URLs.
+
+---
+
+### Gap H — Session URLs are hardcoded to localhost
+
+Current evidence:
+
+- `user-actor.ts` returns session URLs using `http://localhost:8007` and `http://localhost:8008`.
+- `routes/chat.ts` does the same.
+
+Target difference:
+
+- Backend should return service URLs configured for the current environment.
+- Frontend should never construct or guess microservice URLs.
+
+Required change:
+
+- Add config values:
+ - `INTERVIEW_PUBLIC_URL`
+ - `ROLEPLAY_PUBLIC_URL`
+ - `RESUME_PUBLIC_URL` if needed
+- Service adapters should return canonical `sessionUrl` fields.
+- Actor/chat responses should pass through those URLs.
+
+---
+
+### Gap I — Q Score is not yet a durable platform layer
+
+Current evidence:
+
+- `service-agents.ts` uses static signal examples and can return an estimated Q Score fallback.
+- No durable `qscore_snapshots` table exists in backend.
+- Frontend QX page is mostly static.
+
+Target difference:
+
+- Every workflow should read baseline Q Score, update signals, and save before/after snapshots.
+
+Required change:
+
+- Add `qscore_snapshots` or store snapshots on `workflow_runs` for launch.
+- Add `qscore_signal_events` later if needed.
+- Workflow module results should include `qscoreDelta` metadata when relevant.
+- Do not claim score improvement unless Q Score service or explicit estimate contract returns it.
+
+---
+
+### Gap J — No entitlement/billing gate around sellable workflows
+
+Current evidence:
+
+- No workflow SKU/entitlement model in schema.
+- Routes allow authenticated users to start workflows without plan checks.
+
+Target difference:
+
+- Sellable workflows need at least a launch-ready entitlement boundary.
+
+Required launch change:
+
+Add simple fields to workflow definition:
+
+```txt
+priceTier
+sku
+isPurchasable
+isFreePreview
+```
+
+Add minimal backend checks:
+
+- Free workflows can start.
+- Paid workflows return `402/payment_required` or `locked` response if no entitlement.
+- For tomorrow, this can be stubbed with env/config allowlist while payment is wired later.
+
+---
+
+## 3. Big backend phases
+
+### Phase 1 — Tomorrow sellable workflow control plane
+
+Goal: make backend safe to sell real workflows even if some specialized services are still evolving.
+
+Must build/change:
+
+1. Workflow registry with launch workflow definitions.
+2. `GET /workflows` and generic workflow detail endpoint.
+3. Generic workflow run routes.
+4. Minimal workflow run persistence tables.
+5. User actor updated to accept `workflowId` and use registry modules.
+6. Replace local fake module success with blocked/manual/OpenCode statuses.
+7. Add OpenCode executor for artifact-producing modules.
+8. Add workflow-specific prompts and artifact contracts.
+9. Return service/session URLs from config or service response, not localhost constants.
+10. Keep `job-application` route aliases temporarily for old frontend calls.
+
+Definition of done:
+
+- Backend returns a real catalog of sellable workflows.
+- A user can start `interview-to-offer` and get a durable run ID.
+- Modules either execute a real service/OpenCode task or show an honest blocked/manual status.
+- Generated artifacts are written to user repo and recorded in backend.
+- Frontend can render run state without hardcoded workflow knowledge.
+
+---
+
+### Phase 2 — Production-grade orchestration and memory
+
+Goal: make workflow runs reliable, resumable, and supportable.
+
+Must build/change:
+
+1. Move long-running module execution toward Rivet workflow steps or one actor/action per run.
+2. Add retry policy and idempotency keys per module.
+3. Add approval gates:
+ - user input required,
+ - review artifact,
+ - approve next step,
+ - human escalation.
+4. Add event stream/poll endpoint for frontend progress.
+5. Add artifact browser API:
+ - list artifacts,
+ - read artifact metadata,
+ - get repo path/content.
+6. Add prompt/output validation:
+ - required files produced,
+ - required JSON keys,
+ - no empty success.
+7. Add run history and completed workflow summaries.
+
+Definition of done:
+
+- A workflow can survive backend restarts and actor restarts.
+- Support can inspect run events/artifacts.
+- Users can resume an interrupted workflow.
+
+---
+
+### Phase 3 — Scale, entitlements, and product ops
+
+Goal: make the backend ready for paid launch scale and operational control.
+
+Must build/change:
+
+1. Real billing/entitlement integration.
+2. Workflow version rollout controls.
+3. Prompt version rollout controls.
+4. Admin observability:
+ - failed runs,
+ - blocked services,
+ - OpenCode container health,
+ - Gitea sync health.
+5. Service capability registry:
+ - which microservices are enabled,
+ - health,
+ - supported operations,
+ - public session URL patterns.
+6. Analytics events:
+ - workflow viewed,
+ - run started,
+ - module started/completed/failed,
+ - artifact generated,
+ - score updated.
+
+Definition of done:
+
+- Workflows are measurable, billable, versioned, and operationally safe.
+
+---
+
+## 4. Backend agent handoff checklist
+
+Work in this order:
+
+1. Add `src/workflows/types.ts` and `src/workflows/registry.ts`.
+2. Define the 5 launch workflow products.
+3. Add `GET /workflows` and `GET /workflows/:workflowId`.
+4. Add minimal workflow run tables and migration.
+5. Generalize `routes/workflows.ts` while keeping `job-application` aliases.
+6. Update `user-actor.ts` so `startWorkflow({ workflowId, goal, input })` uses registry modules.
+7. Replace local success fallback with honest non-success statuses.
+8. Add OpenCode workflow executor for artifact modules.
+9. Add workflow prompt packs and output contracts.
+10. Remove localhost session URL construction from actor/chat responses.
+11. Simplify `routes/chat.ts` so workflow mutation only goes through actor/workflow service.
+
+Do not spend this pass on rewriting specialized microservices. Treat them as capability adapters behind stable workflow module contracts.
diff --git a/growqr-frontend-v2-launch-gap-plan.md b/growqr-frontend-v2-launch-gap-plan.md
new file mode 100644
index 0000000..bc2b271
--- /dev/null
+++ b/growqr-frontend-v2-launch-gap-plan.md
@@ -0,0 +1,389 @@
+# GrowQR Frontend v2 Launch Gap Plan
+
+This document only lists the **differences between the current v2 frontend and the target sellable-workflow product**. It is written so a frontend/UI agent can work independently from the backend agent.
+
+Target assumption: backend owns workflow definitions, runs, score data, artifacts, agent availability, entitlements, and session URLs. The frontend renders that state in a playful, visual, low-reading experience.
+
+---
+
+## 1. Current frontend state observed
+
+Relevant v2 files inspected:
+
+- `growqr-next-frontend/src/app/v2/page.tsx`
+- `growqr-next-frontend/src/app/v2/workflows/page.tsx`
+- `growqr-next-frontend/src/app/v2/chat/page.tsx`
+- `growqr-next-frontend/src/app/v2/dashboard/page.tsx`
+- `growqr-next-frontend/src/app/v2/agents/page.tsx`
+- `growqr-next-frontend/src/app/v2/qx-score/page.tsx`
+- `growqr-next-frontend/src/app/v2/pathways/page.tsx`
+- `growqr-next-frontend/src/app/v2/marketplace/page.tsx`
+- `growqr-next-frontend/src/app/v2/qvue/page.tsx`
+- `growqr-next-frontend/src/components/home-v2/GrowChat.tsx`
+- `growqr-next-frontend/src/components/home-v2/WorkflowDiscovery.tsx`
+- `growqr-next-frontend/src/components/home-v2/WorkflowProgress.tsx`
+- `growqr-next-frontend/src/components/home-v2/ChatInterface.tsx`
+- `growqr-next-frontend/src/app/api/growqr/[...path]/route.ts`
+
+### Already useful
+
+- `/v2/workflows/page.tsx` is mostly backend-only and no longer shows example workflow progress.
+- `/v2/chat/page.tsx` uses `GrowChat`, which calls the backend/actor path and avoids local fabricated final answers when the backend fails.
+- `/api/growqr/[...path]/route.ts` exists as a Clerk-authenticated proxy to the backend.
+- The visual direction is correct: agent avatars, large cards, simple labels, progress bars, and playful dashboard shell.
+
+### Additional UI reference checked
+
+Source: `docs/UI design Mockup Draft.pptx`.
+
+The mockup makes the frontend direction more explicit than the original gap plan did: GrowQR should feel like a **visual career operating system**, not a text dashboard. Keep the existing GrowQR branding/colors, but change the UI/UX toward:
+
+- **iPhone/App Library style grouping**: Home should group many capabilities into simple visual folders/widgets instead of long menus or dense dashboards. Example groups from the mockup: Suggestions, Workflows, Pathways, Daily Rewards, Social, Productivity.
+- **Widget-first Home**: Home is not a report page. It should show daily actions, active workflows/opportunities, Q Score, rewards, and small group summaries as tappable widgets that drill down.
+- **Low-reading UX**: for Tier-2/Tier-3 India, students, freshers, and seekers, most information should be absorbed through icons, agent avatars, cards, progress maps, charts, badges, animations, and pictorial states. English copy should be short: one clear line + one CTA.
+- **TalkwithME as a primary mode**: a video/avatar conversational surface should support voice and text, suggested prompt chips, history, and personalized guidance from the user journey. It should compare progress with peers/industry standards only when backend data is real.
+- **Workflows as agent squads**: workflow cards should visually show the group of agents working together toward one outcome in a finite period of time. Active workflows need tabs, summary, action buttons, agent areas, artifact previews, charts, and feedback controls.
+- **Available vs Active mental model**: Workflows, Opportunities/Agents, and other catalog surfaces should separate what can be bought/started from what is already running.
+- **Opportunities/Agents are one-off tasks**: workflows are outcome bundles; opportunities/agents are cheaper single-purpose actions such as Resume, Social Branding, Interview, Role Play, Assessments, Jobs, Courses, Mentorships. Pathway is a one-time report/agent, while daily guidance belongs in workflows.
+- **Apple-inspired simplicity**: complex product breadth should be hidden behind grouped widgets, folders, bottom/side navigation, and progressive disclosure. Maximum capability, minimum visible complexity.
+
+---
+
+## 2. Critical product gaps
+
+### Gap A — Workflow discovery is still frontend-owned
+
+Current evidence:
+
+- `WorkflowDiscovery.tsx` has a hardcoded `WORKFLOWS` object.
+- The cards include IDs like `job-preparation`, `interview-practice`, `resume-boost`, `career-switch`, and `job-search` that do not all exist as backend workflow products.
+- `/v2/workflows/page.tsx` only knows `/workflows/job-application`.
+
+Target difference:
+
+- Frontend should call `GET /workflows` and render backend-owned workflow products.
+- Cards should represent sellable launch SKUs such as:
+ - `interview-to-offer`
+ - `career-transition`
+ - `salary-negotiation-war-room`
+ - `promotion-readiness`
+ - `personal-brand-opportunity-engine`
+ - optionally `first-job-launchpad`
+- Frontend may own presentation, but not product definition.
+
+Required change:
+
+- Replace `WORKFLOWS` in `WorkflowDiscovery.tsx` with backend catalog data.
+- Update `/v2/workflows/page.tsx` from one hardcoded job-application screen to:
+ - catalog grid,
+ - workflow detail drawer/page,
+ - active run view,
+ - module/artifact/status cards.
+
+---
+
+### Gap B — Multiple v2 pages still show static/demo business data
+
+Current evidence:
+
+- `dashboard/page.tsx` hardcodes QX score `76`, applications, interviews, skills, milestones, weekly activity, and agent stats.
+- `agents/page.tsx` hardcodes agents, metrics, and “Active” state.
+- `qx-score/page.tsx` hardcodes score `74` and visual areas.
+- `pathways/page.tsx` hardcodes pathway programs and progress.
+- `marketplace/page.tsx` hardcodes experts, ratings, availability, and counts.
+- `qvue/page.tsx` hardcodes videos, views, ratings, and categories.
+- `DashboardSections.tsx`, `AgentExecution.tsx`, and `CareerCoPilot.tsx` also contain static/demo surfaces.
+
+Target difference:
+
+- For launch, every visible claim should be one of:
+ 1. real backend data,
+ 2. a real backend catalog item,
+ 3. an empty/coming-soon locked state,
+ 4. a marketing card that clearly starts a real backend workflow.
+
+Required change:
+
+- Convert pages into real-data shells:
+ - Dashboard: active workflow runs, latest artifacts, latest Q Score snapshot, next recommended workflow.
+ - Agents: backend agent catalog + availability/status only.
+ - QX Score: backend Q Score summary; if unavailable, show “Run Q Score” CTA, not fake score.
+ - Pathways/QVue/Marketplace: either hide from launch nav or convert to locked/coming-soon backed by backend catalog.
+
+---
+
+### Gap C — Chat has duplicated and conflicting implementations
+
+Current evidence:
+
+- `/v2/chat/page.tsx` uses `GrowChat`.
+- `HomeV2Client.tsx` and `marketplace/page.tsx` can use `ChatInterface`.
+- `ChatInterface.tsx` contains `processResponse()` with local fabricated suggestions and action cards.
+- `ChatInterface.tsx` still references old `growAgent` actor naming.
+- `GrowChat.tsx` is closer to the desired path, but still contains hardcoded suggestions, hardcoded agent metadata, and backend/session assumptions.
+
+Target difference:
+
+- One production chat surface for v2.
+- Chat should only display:
+ - assistant text from backend,
+ - backend sessions,
+ - backend workflow suggestions,
+ - backend workflow run state,
+ - backend artifacts.
+
+Required change:
+
+- Make `GrowChat` the only v2 chat component for launch.
+- Stop using `ChatInterface` in v2 launch surfaces, or refactor it to delegate to `GrowChat` and delete local `processResponse()`.
+- Move suggestions from frontend constants to backend responses/catalog.
+
+---
+
+### Gap D — Initial query behavior is still fragile
+
+Current evidence:
+
+- In `GrowChat.tsx`, welcome message is inserted on mount.
+- The `initialQuery` effect only sends when `messages.length === 0`.
+- Once the welcome message exists, `initialQuery` may not fire.
+
+Target difference:
+
+- Clicking workflow cards, agent cards, QVue cards, etc. must reliably start the real backend action.
+
+Required change:
+
+- Track consumed `initialQuery` with a ref instead of `messages.length`.
+- Allow initial query to run after welcome message insertion.
+- Clear or preserve welcome intentionally, but do not block the backend call.
+
+---
+
+### Gap E — Workflow progress is hardcoded to one job-prep sequence
+
+Current evidence:
+
+- `WorkflowProgress.tsx` has a static six-step `WORKFLOW_STEPS` list.
+- Chat infers workflow progress from local step numbers returned by backend chat fallback.
+
+Target difference:
+
+- Progress should come from the active `WorkflowRun`:
+ - `steps[]`,
+ - `currentStepId`,
+ - status,
+ - agent/module state,
+ - approval gates,
+ - artifacts.
+
+Required change:
+
+- Replace static `WORKFLOW_STEPS` with workflow definition/run data.
+- Support varied workflows: interview-to-offer, transition, negotiation, promotion, brand engine.
+
+---
+
+### Gap F — API access is inconsistent
+
+Current evidence:
+
+- `/v2/workflows/page.tsx` calls `NEXT_PUBLIC_GROWQR_BACKEND_URL` directly.
+- `GrowChat.tsx` sometimes calls backend URL directly and sometimes calls `/api/growqr/...`.
+- `/api/growqr/[...path]/route.ts` already exists and handles Clerk auth server-side.
+
+Target difference:
+
+- Browser frontend should prefer `/api/growqr/*` proxy for backend control-plane calls.
+- Direct public backend URL should be a fallback only when explicitly needed.
+
+Required change:
+
+- Standardize v2 frontend calls on a small API client:
+ - `getWorkflowCatalog()`
+ - `startWorkflow(workflowId, input)`
+ - `getWorkflowRun(runId)`
+ - `runWorkflowStep(runId, stepId)`
+ - `sendChatMessage()`
+- Use `/api/growqr/*` by default.
+
+---
+
+### Gap G — Home/navigation is still too dashboard-like for the mockup direction
+
+Current evidence:
+
+- `/v2/page.tsx` has an Apple-like folder idea already, but still mixes fake score widgets, dashboard report cards, long explanatory copy, and many routes.
+- `SidebarMinimal.tsx` exposes product sections as a standard SaaS sidebar: Home, Chat, Agents, Workflows, Dashboard, QX Score, Q-Vue.
+- The mockup instead frames the product around simple modes and grouped widgets: Home, Workflows, Opportunities, Analytics, Rewards, plus user identity/community modes such as Seeker, Mentor, Events, Community.
+
+Target difference:
+
+- Home should become a visual launchpad with grouped widgets/folders and one primary daily action.
+- Navigation should reduce cognitive load. Users should not need to understand every product section before acting.
+- The first screen should answer visually: “What should I do today?”, “Which workflow is active?”, “What reward/score changed?”, “Who is helping me?”
+
+Required change:
+
+- Replace dense dashboard sections with widget groups:
+ - Today / Daily Actions,
+ - Active Workflows,
+ - Opportunities / Agents,
+ - Q Score / Analytics,
+ - Rewards / Badges.
+- Use icon tiles and illustrated cards for catalog entries: Mock Interviews, Mock Tests, Jobs, Courses, Mentorships, Resume, Social Branding, Interview, Role Play, Assessments.
+- Keep detailed analytics behind drill-down widgets; do not put dense text/charts on the first view.
+- Add micro-interactions only where they clarify state: progress animation, agent typing/working state, reward unlock, workflow step completion.
+
+---
+
+## 3. Big frontend phases
+
+### Phase 1 — Tomorrow sellable-workflow launch UI
+
+Goal: make the frontend safe to sell workflows without fake claims.
+
+Must change:
+
+1. Replace hardcoded workflow cards with backend `GET /workflows` catalog.
+2. Replace hardcoded `/workflows/job-application` calls with `/:workflowId` routes once backend exposes them.
+3. Make `/v2/workflows` the main launch surface:
+ - visual mission cards,
+ - available/active tabs,
+ - start button,
+ - active run panel,
+ - agent squad cards,
+ - module cards,
+ - artifact preview tiles,
+ - Q Score before/after slot.
+4. Make `/v2` Home a safe visual launchpad:
+ - no fake score/report widgets,
+ - Apple/App-Library-style grouped folders,
+ - Today action widget,
+ - Active workflow widget,
+ - Opportunities/Agents widget,
+ - Rewards/Badges locked or real.
+5. Fix `GrowChat` initialQuery.
+6. Remove/deactivate `ChatInterface` local fake responses from launch paths.
+7. Hide or lock pages that still show fake metrics: marketplace, qvue, pathways, full dashboard sections.
+8. Standardize API calls through `/api/growqr`.
+
+Definition of done:
+
+- A user can select a real workflow from backend catalog.
+- Starting the workflow creates a backend run.
+- The UI shows real run status/modules/artifacts only.
+- If a service is unavailable, the UI shows blocked/unavailable from backend, not fake success.
+- No visible fake Q Score, fake experts, fake videos, fake applications, or fake milestones on launch surfaces.
+
+---
+
+### Phase 2 — Gamified low-reading workflow UX
+
+Goal: make the product feel like a playful career mission system for students/freshers/Tier-2/Tier-3 users, using the mockup and iPhone/App Library as interaction references.
+
+Must change:
+
+1. Render backend workflow definitions as visual missions:
+ - icon/mascot,
+ - one-line promise,
+ - estimated time,
+ - reward/outcome,
+ - agent squad avatars,
+ - “Start Mission” CTA.
+2. Render workflow runs as maps:
+ - Start → Diagnose → Build → Practice → Score → Match/Finish.
+3. Add Apple-style grouped widgets/folders:
+ - Workflows,
+ - Opportunities,
+ - Pathways/Reports,
+ - Analytics/Q Score,
+ - Rewards,
+ - Social/Productivity.
+4. Add artifact cards:
+ - resume version,
+ - LinkedIn rewrite,
+ - interview plan,
+ - negotiation script,
+ - promotion evidence packet,
+ - brand posts.
+5. Add score-delta and analytics cards that are visual before textual:
+ - before/after Q Score ring,
+ - dimensions improved,
+ - mini graph/sparkline,
+ - badges unlocked.
+6. Add lightweight mobile-first states:
+ - one primary CTA,
+ - short copy,
+ - visual status,
+ - low text density,
+ - voice/text TalkwithME entry point.
+7. Add daily personalization feedback:
+ - like/dislike/filter controls on workflow outputs,
+ - “show me more like this” chips,
+ - backend-backed preference state only.
+
+Definition of done:
+
+- Users understand each workflow in under 5 seconds without reading paragraphs.
+- Each workflow has visible reward/output cards.
+- Home feels like a visual app library/career OS, not a SaaS report dashboard.
+- The UX sells outcomes, not internal services.
+
+---
+
+### Phase 3 — Production polish and conversion
+
+Goal: make frontend reliable for paid users and measurable launch.
+
+Must change:
+
+1. Add entitlement states:
+ - free preview,
+ - locked premium workflow,
+ - purchased/active,
+ - expired/completed.
+2. Add durable loading/error states:
+ - provisioning OpenCode,
+ - service unavailable,
+ - waiting for user input,
+ - approval required,
+ - retry available.
+3. Add run history:
+ - completed workflows,
+ - generated artifacts,
+ - score changes,
+ - next recommended workflow.
+4. Add analytics events:
+ - catalog viewed,
+ - workflow clicked,
+ - workflow started,
+ - module completed,
+ - artifact opened,
+ - payment intent.
+
+Definition of done:
+
+- The frontend is sales-ready, supportable, and measurable without inventing product state.
+
+---
+
+## 4. Frontend agent handoff checklist
+
+Work in this order:
+
+1. Create a frontend API client for `/api/growqr`.
+2. Replace workflow discovery with backend catalog.
+3. Generalize `/v2/workflows` to multiple workflow IDs.
+4. Convert `/v2` Home into a visual launchpad:
+ - grouped widgets/folders,
+ - one daily action,
+ - Active vs Available surfaces,
+ - no fake metrics.
+5. Fix `GrowChat` initial query.
+6. Remove `ChatInterface` from launch routes or delete its local response engine.
+7. Hide/lock fake-data pages from nav until backend data exists.
+8. Convert QX/Dashboard cards to backend-backed empty/real states.
+9. Keep copy short and visual-first: icon/illustration + one line + CTA.
+
+Do not work on microservice internals in this frontend pass.
diff --git a/growqrApp.md b/growqrApp.md
new file mode 100644
index 0000000..900f0aa
--- /dev/null
+++ b/growqrApp.md
@@ -0,0 +1,952 @@
+Yeah — this repo is doing something pretty unusual, and honestly pretty smart.
+
+## The shortest possible explanation
+
+This is **not** a normal “frontend ↔ API” app.
+
+It’s more like:
+
+- the **UI** is a Next.js app
+- the **orchestrator** is a **super-agent router / session broker**
+- the **user-service** is the **identity + profile source of truth**
+- the domain services are treated like **agents**
+- **Redis Streams** is the internal task bus
+- **Q-Score** is a cross-cutting scoring engine fed by events extracted from agent outputs
+- some flows are **agentized**, some are still **direct REST**, and live audio flows are **direct WebSocket to specialty services**
+
+So the system has **multiple communication lanes**, not one.
+
+---
+
+# 1. The mental model: 4 communication lanes
+
+## Lane A — Direct frontend → service REST
+Used for normal CRUD.
+
+Examples:
+- frontend → `user-service` for `/users/me`, `/users/ensure`, photo upload, QR
+- frontend → `resume-builder` for resumes, versions, export, parse
+- frontend → `social-branding` for profiles, analysis history, content generation
+- frontend → `interview-service` / `roleplay-service` artifact APIs
+
+This is the boring, standard lane.
+
+---
+
+## Lane B — Frontend → orchestrator WebSocket → domain agents
+Used for **page sessions**, **agent actions**, **cross-service flows**, **progressive updates**.
+
+Examples:
+- home dashboard
+- resume hub/editor actions
+- social media page
+- job matching
+- pathways
+- some interview/roleplay setup/feedback flows
+
+This is the **signature architecture** of the app.
+
+---
+
+## Lane C — Domain agent ↔ orchestrator via Redis Streams or A2A HTTP
+This is **internal service-to-service orchestration**.
+
+The orchestrator can invoke an agent in two ways:
+
+### Default: Redis Streams
+- orchestrator writes task to `tasks:`
+- service worker consumes it
+- service publishes response messages to `responses:`
+- orchestrator relays those messages back to frontend
+
+### Fallback: HTTP A2A
+- orchestrator POSTs to `//a2a/tasks`
+- service runs the same session logic and returns collected messages
+
+So they built a dual transport layer:
+- **event-driven / stream-based**
+- with **HTTP fallback**
+
+That’s very distinctive.
+
+---
+
+## Lane D — Direct live media WebSockets
+Used for **real-time interview / roleplay audio sessions**.
+
+Examples:
+- frontend `useInterviewSession()` connects directly to interview-service
+- frontend `useRoleplaySession()` connects directly to roleplay-service
+
+So live voice does **not** go through the orchestrator data path.
+
+That’s another important part of the uniqueness:
+**not everything is forced through one gateway.**
+
+---
+
+# 2. UI app: how the frontend is structured
+
+Main app: `frontend/`
+
+Core stack:
+- Next.js 16
+- React 19
+- Clerk auth
+- App Router
+- Tailwind
+- custom hooks for API + agent sessions
+
+---
+
+## 2.1 Frontend has two personalities
+
+The UI is doing **both**:
+
+### A. Standard SaaS frontend
+Using API clients like:
+- `src/lib/api/users.ts`
+- `src/lib/api/resumes.ts`
+- `src/lib/api/socialBranding.ts`
+
+These attach Clerk Bearer tokens and call REST endpoints directly.
+
+### B. Agent-driven frontend
+Using:
+- `src/hooks/useAgentSession.ts`
+
+This hook is the key.
+
+It:
+- gets Clerk token
+- opens WebSocket to orchestrator:
+ `ws://.../ws/agent?token=`
+- sends:
+ ```json
+ { "type": "session_start", "page": "...", "params": {...} }
+ ```
+- later sends:
+ ```json
+ { "type": "user_action", "action": "...", "params": {...} }
+ ```
+
+And it listens for structured messages like:
+- `capabilities_updated`
+- `agent_routed`
+- `agent_thinking`
+- `agent_data`
+- `agent_suggestion`
+- `agent_activity`
+- `agent_error`
+- `qscore_loaded`
+- `qscore_updated`
+- copilot streaming chunks
+
+So the frontend is basically talking to a **message protocol**, not just fetching JSON.
+
+---
+
+## 2.2 Important frontend providers
+
+### `QScoreProvider`
+At dashboard layout level:
+- `frontend/src/app/(dashboard)/layout.tsx`
+
+This persists Q-Score across dashboard navigation.
+
+### `UserProvider`
+In `DashboardLayout.tsx`
+
+This does:
+- `usersApi.ensureUser()`
+- loads the GrowQR user record
+- exposes `user`, `isPro`, `refreshUser`
+
+So Clerk is auth, but **user-service is the app identity profile**.
+
+---
+
+## 2.3 What page loads feel like
+
+When a page uses `useAgentSession(...)`, the frontend is not directly loading page data from the domain service.
+
+Instead:
+1. connect to orchestrator
+2. orchestrator authenticates
+3. orchestrator resolves user context via user-service
+4. orchestrator routes page to correct agent
+5. agent sends structured messages back
+6. UI renders from `latestData[action]`
+
+Example:
+- Home page uses:
+ `useAgentSession(WS_URL, "home")`
+- It waits for `dashboard_loaded`
+
+So the page isn’t “call GET /dashboard”.
+It’s more like:
+> “Start an agent session for page `home` and stream me the result.”
+
+That’s very different from normal SaaS frontend architecture.
+
+---
+
+## 2.4 Frontend communication split by feature
+
+### Home dashboard
+- goes through orchestrator
+- page = `"home"`
+- routed to `dashboard-service`
+
+### Resume pages
+- direct REST for CRUD/export/parse
+- orchestrator WS for page session + AI/copilot/page-level orchestration
+
+### Social branding
+- direct REST for profiles/analysis/content
+- orchestrator WS for page session and agent-like flows
+
+### Settings / profile
+- direct REST to `user-service`
+- user data also available through orchestrator-resolved context
+
+### Job matching
+- orchestrator-driven agent page
+
+### Pathways
+- orchestrator-driven agent page
+
+### Interview / roleplay
+- setup/feedback pages use orchestrator-style session hooks
+- actual live conversation uses **direct WS** to the interview/roleplay service
+
+### Helper chat
+There’s also:
+- `frontend/src/app/api/chat/route.ts`
+
+That one calls OpenAI directly from Next server route, outside the orchestrator pattern.
+
+So even inside frontend, you’ve got:
+- direct REST
+- orchestrated WS
+- direct live WS
+- direct Next server AI route
+
+---
+
+# 3. Orchestrator: what it really is
+
+Main folder:
+- `orchestrator/`
+
+Key file:
+- `orchestrator/app/main.py`
+- `orchestrator/app/agent/session.py`
+
+## The orchestrator is basically:
+### a WebSocket gateway
++ auth layer
++ service discovery layer
++ routing layer
++ context enrichment layer
++ signal extraction layer
++ Q-Score event publisher
++ background workflow coordinator
+
+That’s why it feels unique.
+
+---
+
+## 3.1 What happens when frontend connects
+
+In `orchestrator/app/agent/websocket.py`:
+
+1. WebSocket opens with `?token=`
+2. orchestrator verifies Clerk JWT
+3. extracts Clerk user id
+4. creates `SuperAgentSession`
+
+Then in `SuperAgentSession.run()`:
+
+### Step 1
+Send capabilities snapshot
+
+### Step 2
+Resolve user identity via `user-service`
+
+### Step 3
+Process:
+- `session_start`
+- `user_action`
+- `session_end`
+
+So every agent session begins with:
+- who is this user?
+- what agents are available?
+- what’s the current user context?
+
+---
+
+## 3.2 Service discovery is dynamic
+
+Files:
+- `orchestrator/app/discovery/registry.py`
+- `orchestrator/app/discovery/health.py`
+
+The orchestrator periodically calls:
+- `/.well-known/agent-card.json`
+- fallback `/.well-known/agent.json`
+
+from each configured agent URL.
+
+It stores:
+- agent name
+- description
+- skills
+- health state
+
+So the orchestrator is not hardcoded to just “known APIs”.
+It has a **registry of discovered agent capabilities**.
+
+That’s a real agent-style pattern.
+
+---
+
+## 3.3 Routing is page-based and action-based
+
+In `orchestrator/app/agent/session.py`:
+
+### Page routing
+`PAGE_TO_AGENT` maps:
+- `home` → `dashboard-service`
+- `resume-hub` → `resume-builder`
+- `social-media` → `social-branding`
+- `job-matching` → `matchmaking-service`
+- `settings` → `user-service`
+- `pathways` → `pathways-service`
+- etc.
+
+### Action routing
+`ACTION_TO_AGENT` maps actions like:
+- `ai_analyze` → `resume-builder`
+- `run_analysis` → `social-branding`
+- `update_preferences` → `user-service`
+- `get_feed` → `matchmaking-service`
+- `generate_pathway` → `pathways-service`
+
+So the orchestrator understands:
+- “which page belongs to which agent”
+- “which user action belongs to which agent”
+
+That makes the frontend simpler: it just emits actions, not service URLs.
+
+---
+
+## 3.4 The orchestrator always resolves user context first
+
+This is one of the most important design choices.
+
+In `_resolve_user_identity()`:
+
+1. call `user-service` action `view_profile`
+2. get the real user profile
+3. extract the app UUID
+4. enrich with skills from:
+ - `resume-builder /api/state/{clerk_id}`
+ - `social-branding /api/state/{clerk_id}`
+
+So the orchestrator creates a **portable user context** that can be sent to any domain agent.
+
+That means agents don’t each need to re-fetch identity basics every time.
+
+This is a huge reason the architecture feels “agentic” instead of “API-ish”.
+
+---
+
+## 3.5 Dual transport: Redis first, HTTP fallback
+
+Files:
+- `orchestrator/app/a2a/redis_transport.py`
+- `orchestrator/app/a2a/client.py`
+
+### Redis mode
+- publish task to `tasks:`
+- subscribe to `responses:`
+- stream messages to frontend in real time
+
+### HTTP mode
+- POST to `//a2a/tasks`
+- get collected messages back
+
+So the orchestrator can treat agents as:
+- synchronous HTTP responders
+- or event-driven streaming workers
+
+That’s sophisticated.
+
+---
+
+## 3.6 Q-Score is deeply embedded into orchestration
+
+This is another unique thing.
+
+The orchestrator doesn’t just route actions.
+It also watches agent outputs and turns them into **scoring signals**.
+
+Files:
+- `orchestrator/app/qscore/signal_mapper.py`
+- `publisher.py`
+- `subscriber.py`
+- `client.py`
+
+### On session init
+It:
+- fetches latest Q-Score over HTTP from qscore-service
+- registers callback for live score updates via Redis stream
+- publishes engagement + onboarding signals
+
+### After domain-agent responses
+It scans returned messages:
+- resume analysis
+- LinkedIn analysis
+- job matching actions
+- interview review
+- roleplay review
+- pathway progress
+
+Then extracts signals like:
+- `resume.ats_compatibility`
+- `linkedin.headline_quality`
+- `matching.feed_active`
+- `interview.overall_score`
+- `pathway.completion_pct`
+
+Then publishes them to:
+- `qscore.signal_events`
+
+So the orchestrator is not just a router.
+It is also a **semantic event interpreter**.
+
+That’s rare.
+
+---
+
+## 3.7 Background workflows are coordinated here
+
+Endpoint:
+- `POST /api/v1/background-task`
+
+Used by:
+- `resume-builder` after resume upload
+- `social-branding` after LinkedIn fetch/connect
+
+Flow:
+1. service notifies orchestrator
+2. orchestrator resolves user context
+3. dispatches background task to agent
+4. collects messages
+5. extracts Q-Score signals
+6. extracts auto-populate info
+7. PATCHes `user-service /users/auto-populate`
+
+So the orchestrator also acts like a **workflow engine**.
+
+---
+
+# 4. User-service: why it’s more important than it first looks
+
+Main folder:
+- `user-service/`
+
+Key files:
+- `app/main.py`
+- `app/api/v1/users.py`
+- `app/api/v1/webhooks.py`
+- `app/agent/session.py`
+
+This service is not just “users table CRUD”.
+
+It is the **identity gateway** of the whole platform.
+
+---
+
+## 4.1 It is the source of truth for app-level user state
+
+It owns:
+- GrowQR user record
+- Clerk id mapping
+- email / first_name / last_name
+- avatar_url
+- plan
+- preferences
+- metadata
+- QR code data
+- profile photo
+- onboarding state (stored in preferences)
+
+This is the canonical application profile.
+
+---
+
+## 4.2 It bridges Clerk identity to internal GrowQR identity
+
+Frontend auth is Clerk.
+
+But Q-Score and some internal flows need a stable internal user UUID.
+
+That comes from `user-service`.
+
+So the mapping is basically:
+
+- Clerk user id → auth identity
+- GrowQR user UUID → internal cross-service identity
+
+That’s why orchestrator hits user-service first.
+
+---
+
+## 4.3 It supports three access styles
+
+### 1. Direct REST from frontend
+Examples:
+- `/api/v1/users/me`
+- `/api/v1/users/ensure`
+- `/api/v1/users/me/photo`
+- `/api/v1/users/me/qr-code`
+
+### 2. Agent-style access
+Via:
+- `/ws/agent`
+- `/a2a/tasks`
+
+So user-service itself behaves like an agent.
+
+### 3. Internal state endpoint
+- `/api/state/{clerk_id}`
+
+Used by dashboard-service and orchestrator.
+
+So user-service exposes both:
+- user-facing API
+- internal aggregation API
+- agent protocol surface
+
+---
+
+## 4.4 It auto-creates users on first sign-in
+
+In `UserProvider`, frontend calls:
+- `ensureUser()`
+
+Server side `/users/ensure`:
+- if user exists → return it
+- if not → fetch from Clerk API if possible
+- create GrowQR user row
+- generate QR code
+
+So app account creation is **lazy and synchronized** off Clerk login.
+
+---
+
+## 4.5 It stores onboarding state
+The frontend hook:
+- `useOnboarding()`
+
+writes onboarding into:
+- `user.preferences.onboarding`
+
+This is clever because onboarding becomes part of the shared user context, not some isolated frontend state.
+
+That means orchestrator and Q-Score can use it.
+
+---
+
+## 4.6 It handles Clerk webhooks
+In `app/api/v1/webhooks.py`:
+
+Supported:
+- `user.created`
+- `user.updated`
+- `user.deleted`
+- `session.created`
+
+Effects:
+- create/update/soft-delete user
+- update last sign-in
+- trigger downstream cleanup on delete
+
+So user-service is the **sync point between external auth identity and internal domain data**.
+
+---
+
+## 4.7 It also owns QR/public identity features
+It handles:
+- uploaded profile photo
+- branded QR generation
+- public profile endpoint
+- QR regeneration
+
+That’s not just admin/user metadata. It also powers the outward-facing GrowQR identity layer.
+
+---
+
+## 4.8 Auto-populate is a hidden important feature
+Orchestrator can call:
+- `PATCH /api/v1/users/auto-populate`
+
+It fills empty user/profile/settings fields based on:
+- parsed resume data
+- LinkedIn profile data
+
+But only if those fields are empty.
+
+That creates a very smooth onboarding loop:
+- upload resume / connect LinkedIn
+- AI/background processing runs
+- settings fill themselves
+
+This is one of the better-designed pieces.
+
+---
+
+# 5. Why this architecture feels unique
+
+Because the services aren’t just APIs.
+
+They are treated like **page/domain agents** with a common invocation model.
+
+## The pattern is:
+
+Each service has a central session object, like:
+- `UserAgentSession`
+- `DashboardAgentSession`
+- similar in resume/social/etc.
+
+That same session logic can be invoked through:
+
+### A. native WebSocket
+actual user-agent page session
+
+### B. HTTP A2A
+via `/a2a/tasks`
+
+### C. Redis Stream worker
+consumes `tasks:` and publishes responses
+
+That means **one domain behavior implementation** is reused across multiple transports.
+
+That’s actually a strong architectural idea.
+
+---
+
+# 6. How each service communicates with others
+
+Here’s the clean map.
+
+## 6.1 Frontend
+Talks to:
+- `user-service` via REST
+- `resume-builder` via REST
+- `social-branding` via REST
+- `orchestrator` via WS
+- `interview-service` via direct WS + REST
+- `roleplay-service` via direct WS + REST
+- internal Next `/api/chat` route for helper chat
+
+---
+
+## 6.2 Orchestrator
+Talks to:
+- `user-service` for identity resolution + metadata persistence + auto-populate target
+- `resume-builder` for page/actions + skill enrichment + background parse/analyze
+- `social-branding` for page/actions + skill enrichment + background analysis
+- `dashboard-service` for home page payload
+- `matchmaking-service` for job matching actions
+- `pathways-service` for pathway actions
+- `qscore-service` for initial read + signal publication + update subscription
+
+Transport used:
+- Redis Streams preferred
+- HTTP A2A fallback
+- HTTP internal state calls for enrichment
+
+---
+
+## 6.3 Dashboard-service
+Talks to:
+- `user-service /api/state/{clerk_id}`
+- `resume-builder /api/state/{clerk_id}`
+- `social-branding /api/state/{clerk_id}`
+- `qscore-service /v1/qscore/{uuid}`
+
+It acts like an **aggregator service**:
+- collect distributed state
+- merge
+- evaluate card rules
+- compute lifecycle
+- return `dashboard_loaded`
+
+So dashboard-service is basically a **read model / composition engine**.
+
+---
+
+## 6.4 Resume-builder
+Talks to:
+- orchestrator for background-task kickoff after upload
+- likely user auth verification through Clerk token on direct REST
+- exposes state to orchestrator/dashboard
+- emits analysis data consumed by orchestrator → qscore
+
+It is both:
+- CRUD/document service
+- AI analysis agent
+
+---
+
+## 6.5 Social-branding
+Talks to:
+- orchestrator for background-task kickoff after LinkedIn profile connect/fetch
+- exposes state to orchestrator/dashboard
+- emits analysis data that becomes qscore signals
+
+It is both:
+- profile ingestion service
+- AI profile-analysis agent
+
+---
+
+## 6.6 User-service
+Talks to:
+- Clerk webhooks
+- resume/social cleanup endpoints on delete
+- orchestrator
+- dashboard-service
+- frontend
+
+It is the central identity/state hub.
+
+---
+
+## 6.7 Qscore-service
+Talks to:
+- orchestrator via HTTP read + Redis streams
+- receives signals on `qscore.signal_events`
+- computes score
+- publishes updates on `qscore.score_updates`
+
+So Qscore is event-fed, not directly computed inline on every user request.
+
+That’s a strong decoupling.
+
+---
+
+## 6.8 Matchmaking-service
+Observed pattern:
+- external sibling service
+- has Redis stream worker + A2A endpoints
+- orchestrator routes job-matching actions to it
+- likely handles scraping, ranking, worker queues
+
+So it fits the **agentized service** model.
+
+---
+
+## 6.9 Pathways-service
+Observed pattern:
+- external sibling service
+- Redis worker + A2A endpoints
+- has `/api/state/{clerk_id}`
+- orchestrator routes pathway actions to it
+
+Also fits the agentized pattern.
+
+---
+
+## 6.10 Interview-service / Roleplay-service
+These are more hybrid.
+
+### Definitely observed:
+- direct REST configure/review endpoints
+- direct live WebSocket session endpoints
+- frontend hooks connect directly for live audio
+
+### Architectural meaning:
+These are **specialized real-time media services**.
+They don’t cleanly fit the normal agent/session transport path the way user/resume/social/dashboard/pathways/matchmaking do.
+
+So the system is not “pure agent architecture”.
+It is **agent architecture + specialized realtime sidecars**.
+
+That hybrid is part of what makes it interesting.
+
+---
+
+# 7. End-to-end flows
+
+## Flow A — User opens Home
+1. frontend connects to orchestrator WS
+2. orchestrator verifies Clerk JWT
+3. orchestrator asks user-service for profile
+4. orchestrator enriches user context from resume/social state
+5. orchestrator fetches initial Q-Score
+6. frontend sends `session_start(page="home")`
+7. orchestrator routes to dashboard-service
+8. dashboard-service fetches state from user/resume/social/qscore
+9. dashboard-service builds `dashboard_loaded`
+10. orchestrator relays it to frontend
+11. later Q-Score updates can stream in live
+
+That’s a very nontraditional home-page load.
+
+---
+
+## Flow B — User changes settings
+1. frontend calls `user-service /users/me` directly
+2. user-service updates preferences
+3. those preferences become part of future orchestrator-resolved context
+4. Q-Score / pathways / matching can later use them
+
+So settings are not isolated—they feed the broader system.
+
+---
+
+## Flow C — User uploads resume during onboarding
+1. frontend uploads PDF directly to `resume-builder`
+2. resume-builder stores PDF + thumbnail
+3. resume-builder triggers orchestrator `/api/v1/background-task`
+4. orchestrator resolves user context
+5. orchestrator dispatches `bg_parse_analyze`
+6. resume-builder parses PDF, builds structured content, runs AI analysis
+7. orchestrator extracts:
+ - auto-populate fields
+ - qscore signals
+8. orchestrator PATCHes `user-service /users/auto-populate`
+9. user settings/profile become prefilled
+
+That’s a really elegant async flow.
+
+---
+
+## Flow D — User connects LinkedIn
+1. frontend hits social-branding
+2. social-branding stores/fetches profile
+3. social-branding triggers orchestrator background task
+4. orchestrator dispatches `bg_analyze`
+5. social-branding emits `profile_loaded`, `profile_scored`, `analysis_complete`
+6. orchestrator:
+ - extracts auto-populate fields
+ - publishes qscore signals
+ - updates user-service
+
+Again: domain output becomes shared platform intelligence.
+
+---
+
+## Flow E — User starts interview live session
+1. frontend likely uses orchestrator/setup flow to configure session metadata
+2. interview-service returns `session_id`
+3. frontend opens direct WS to interview-service
+4. audio packets stream directly
+5. review/artifacts are later fetched from interview-service
+6. orchestrator may later use review/history outputs for Q-Score
+
+So live media bypasses the general agent path for latency reasons.
+
+---
+
+# 8. What makes this architecture strong
+
+## Strengths
+
+### 1. Clear separation of concerns
+- UI
+- identity
+- orchestration
+- domain intelligence
+- scoring
+- realtime media
+
+### 2. Reusable agent/session abstraction
+Same business session logic can work over:
+- frontend WS
+- HTTP A2A
+- Redis worker
+
+### 3. Great for incremental AI adoption
+AI doesn’t have to be one giant “assistant”.
+Each domain agent is specialized.
+
+### 4. Cross-service intelligence
+Resume + social + onboarding + engagement all feed Q-Score.
+
+### 5. Good async workflow design
+Background tasks avoid blocking user flows.
+
+### 6. Nice read-model approach on dashboard
+Dashboard-service composes distributed state into one home payload.
+
+---
+
+# 9. Tradeoffs / complexity
+
+## This architecture is powerful, but expensive mentally.
+
+### 1. Multiple protocols
+You have:
+- REST
+- orchestrator WS
+- Redis streams
+- A2A HTTP
+- direct media WS
+
+That’s a lot to hold in your head.
+
+### 2. Mixed patterns
+Some services are fully agentized.
+Some are direct APIs.
+Some are hybrid realtime.
+
+### 3. Debugging is multi-hop
+A page issue might involve:
+- Clerk token
+- orchestrator auth
+- user-service resolution
+- agent routing
+- Redis stream worker
+- qscore side effects
+
+### 4. Service discovery + routing adds indirection
+Great power, but more moving parts.
+
+### 5. Some services live outside repo root
+Operationally a bit awkward.
+
+---
+
+# 10. The cleanest way to describe this app
+
+If I had to describe GrowQR to an engineer in one paragraph:
+
+> GrowQR is a hybrid microservice platform where the frontend uses both direct REST and a central orchestrator WebSocket. The orchestrator authenticates users once, resolves a shared user context through user-service, dynamically discovers domain agents, routes page sessions and actions to those agents over Redis Streams or HTTP A2A, extracts semantic signals from their outputs, and feeds those signals into a separate Q-Score engine. Meanwhile, traditional CRUD and low-latency media workflows still use direct service APIs and direct WebSockets. So the system combines SaaS API architecture, agent orchestration, event-driven messaging, and realtime media pipelines in one platform.
+
+That’s why it feels unique.
+
+---
+
+# 11. The single most important insight
+
+The **user-service + orchestrator combo** is the heart.
+
+- **user-service** = “who is this user in GrowQR?”
+- **orchestrator** = “given this user and this page/action, which domain intelligence should run now?”
+
+Everything else plugs into that.
+
+---
+
+If you want, next I can do one of these:
+
+1. **draw you a plain-English sequence diagram** for the whole app
+2. **map every page in frontend to its backend path/service**
+3. **explain only the orchestrator internals deeply**
+4. **make you an architecture doc you can share with your team**
\ No newline at end of file
diff --git a/integration-problem-analysis.md b/integration-problem-analysis.md
new file mode 100644
index 0000000..fea6b8c
--- /dev/null
+++ b/integration-problem-analysis.md
@@ -0,0 +1,403 @@
+# GrowQR Integration Problem Analysis
+
+## Current Pain Points
+
+### 1. Hardcoded Routing Maps
+The orchestrator has hardcoded `PAGE_TO_AGENT` and `ACTION_TO_AGENT` dictionaries in `session.py`. When new services are added or actions renamed, these maps must be updated, requiring:
+- Code changes to orchestrator
+- Redeployment of orchestrator
+- Coordination between your team (service changes) and original team (orchestrator updates)
+
+### 2. Redis Streams Complexity
+Current event-driven architecture uses Redis Streams with specific naming conventions:
+- Stream naming: `tasks:{agent_name}`
+- Response channels: `responses:{task_id}`
+- Message format with specific JSON schema
+- Pub/sub completion sentinels (`__task_complete__`)
+
+Contributors must understand this protocol, implement consumers, handle backpressure, etc.
+
+### 3. Dual Transport Maintenance
+Services must implement both:
+- Redis Stream worker (for streaming/async)
+- HTTP A2A endpoints (for synchronous fallback)
+
+This doubles the integration surface area.
+
+### 4. Contract Breaking on Changes
+When you modify microservices:
+- Action names change
+- Message formats evolve
+- New parameters added
+- Response structures modified
+
+The original team must update all consumers (orchestrator, other services) to match.
+
+### 5. No Runtime Tool Registration
+Agent cards (`/.well-known/agent-card.json`) are static JSON files. To add/modify skills:
+- Change JSON
+- Redeploy service
+- Orchestrator must rediscover
+
+There's no dynamic "tool marketplace" where contributors can register capabilities at runtime.
+
+## Goals for Improvement
+
+1. **Minimize breaking changes** - Changes to services shouldn't require orchestrator updates
+2. **Simplify contributor integration** - New developers should add tools without deep Redis/protocol knowledge
+3. **Dynamic tool management** - Frontend-visible tools should be registrable at runtime
+4. **Pluggable interface** - SDK-like experience without building a full SDK
+5. **Preserve architecture** - Keep the 4-lane model, orchestrator pattern, Q-Score signals
+
+## Potential Solution Paths
+
+### Path A: Dynamic Tool Registry (Database-Driven)
+Replace hardcoded maps with a database table that stores:
+- Tool ID, name, description
+- Target agent/service URL
+- Input schema (JSON Schema)
+- Output schema (JSON Schema)
+- Routing rules (page patterns, action patterns)
+- Version info
+
+**Pros:**
+- Runtime tool registration
+- Versioning support
+- Frontend can show available tools dynamically
+- No orchestrator redeploy for new tools
+
+**Cons:**
+- Still need to define schemas
+- Database migration required
+- Some complexity in registry UI/management
+
+### Path B: HTTP-Only Standardization (Simplify Transport)
+Standardize on HTTP A2A for ALL service communication. Remove Redis Streams complexity.
+
+**Changes:**
+- All services implement `/a2a/tasks` endpoint
+- Standardized request/response format
+- Streaming via SSE (Server-Sent Events) instead of Redis pub/sub
+- Orchestrator routes all traffic via HTTP
+
+**Pros:**
+- Single transport to understand
+- HTTP is familiar to all developers
+- Easy to test/debug with curl/Postman
+- Load balancing built-in
+- No Redis consumer complexity
+
+**Cons:**
+- Loses Redis persistence/replay capability
+- Slightly higher latency (acceptable?)
+- WebSocket to HTTP bridging needed
+
+### Path C: Schema Registry + Code Generation
+Maintain a central schema registry (like Confluent Schema Registry or simple JSON Schema store):
+- Services register their message schemas
+- Orchestrator validates messages against schemas
+- Code generation for type-safe clients
+- Schema evolution rules (backward/forward compatibility)
+
+**Pros:**
+- Strong typing
+- Schema evolution managed
+- Clear contracts
+
+**Cons:**
+- Complex to implement
+- Still requires coordination
+- Overhead for simple services
+
+### Path D: GraphQL Federation
+Replace REST/A2A with GraphQL:
+- Single GraphQL gateway (orchestrator becomes gateway)
+- Services expose GraphQL schemas
+- Frontend queries exactly what it needs
+- Natural stitching of services
+
+**Pros:**
+- Single query for multi-service data
+- Strong typing
+- Introspection = automatic discovery
+- Frontend-driven queries
+
+**Cons:**
+- Major architectural shift
+- Learning curve for team
+- Q-Score signals need separate path
+- Breaking change to entire system
+
+### Path E: Plugin Architecture with Self-Registration
+Services self-register at startup via a "Plugin Registry" API:
+```python
+# In service startup
+await plugin_registry.register({
+ "service_name": "interview-service",
+ "version": "2.0.0",
+ "tools": [
+ {
+ "tool_id": "configure_interview",
+ "name": "Configure Interview",
+ "endpoint": "/a2a/tasks",
+ "input_schema": {...},
+ "triggers": ["page:interview", "action:configure_interview"],
+ "outputs": ["interview_configured", "qscore_signals"]
+ }
+ ]
+})
+```
+
+**Pros:**
+- Services describe themselves
+- No hardcoded maps
+- Runtime discovery
+- Can include health checks
+
+**Cons:**
+- Services must implement registration logic
+- Registration order matters
+- Need deregistration/cleanup
+
+### Path F: OpenAPI-Based Dynamic Client Generation
+Services expose OpenAPI specs at `/.well-known/openapi.json`:
+- Orchestrator fetches specs
+- Generates client code dynamically (or uses generic client)
+- Routes based on operationIds
+- Validates requests/responses
+
+**Pros:**
+- Industry standard
+- Auto-generated docs
+- Code generation tools exist
+- Language agnostic
+
+**Cons:**
+- Still need routing logic
+- OpenAPI can be verbose
+- Doesn't solve the action/page routing problem
+
+### Path G: gRPC with Reflection
+Replace HTTP A2A with gRPC:
+- Services define .proto files
+- gRPC reflection for discovery
+- Strongly typed, efficient
+- Streaming support built-in
+
+**Pros:**
+- Type safety
+- Performance
+- Streaming
+- Reflection = discovery
+
+**Cons:**
+- Major architectural change
+- Frontend needs gRPC-web or gateway
+- Learning curve
+- Overkill for simple CRUD
+
+## Recommended Hybrid Approach
+
+Based on the constraints (minimal breaking changes, contributor-friendly, pluggable), I recommend a **hybrid approach combining Path A + Path B + Path E**:
+
+### Phase 1: Dynamic Tool Registry (Immediate Win)
+
+**Create a Tool Registry Service (or add to orchestrator):**
+
+```python
+# Tool Registry Schema
+tool_registry = {
+ "tool_id": "resume_analyze",
+ "name": "AI Resume Analysis",
+ "description": "Analyzes resume for ATS compatibility",
+ "service_name": "resume-builder", # Maps to agent name
+ "service_url": "http://resume-builder:8000",
+ "triggers": {
+ "pages": ["resume-hub", "resume-editor"],
+ "actions": ["ai_analyze", "analyze_resume"],
+ "skills": ["resume.analysis"]
+ },
+ "input_schema": {
+ "type": "object",
+ "properties": {
+ "resume_id": {"type": "string"},
+ "deep_analysis": {"type": "boolean"}
+ },
+ "required": ["resume_id"]
+ },
+ "output_schema": {
+ "type": "object",
+ "properties": {
+ "score": {"type": "number"},
+ "suggestions": {"type": "array"}
+ }
+ },
+ "qscore_signals": ["resume.ats_score", "resume.completeness"],
+ "version": "2.1.0",
+ "enabled": True,
+ "created_by": "contributor-xyz",
+ "created_at": "2024-01-15"
+}
+```
+
+**Changes to Orchestrator:**
+1. Replace hardcoded `PAGE_TO_AGENT` and `ACTION_TO_AGENT` with registry lookups
+2. Cache registry in memory with periodic refresh
+3. New admin endpoints for tool CRUD
+4. Frontend can query available tools for a page
+
+### Phase 2: HTTP-First with Optional Redis (Simplify Transport)
+
+**Standardize on HTTP A2A as primary transport:**
+1. Make HTTP A2A the default (already implemented)
+2. Deprecate Redis Streams for new services (keep for existing)
+3. Add SSE streaming support for real-time updates
+4. Contributors only need to implement: `POST /a2a/tasks`
+
+**Service Template for Contributors:**
+```python
+# Minimal service template
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+class TaskRequest(BaseModel):
+ task_id: str
+ action: str
+ params: dict
+ user_id: str
+ user_context: dict | None = None
+
+@app.post("/a2a/tasks")
+async def handle_task(request: TaskRequest):
+ # Route to appropriate handler
+ if request.action == "my_tool_action":
+ result = await my_tool.execute(request.params, request.user_context)
+ return {
+ "task_id": request.task_id,
+ "status": "completed",
+ "messages": [{
+ "type": "agent_data",
+ "action": "my_tool_complete",
+ "data": result
+ }]
+ }
+```
+
+### Phase 3: Self-Registration with Health Checks (Plugin Architecture)
+
+**Services self-register on startup:**
+```python
+# Service startup
+async def register_tools():
+ async with httpx.AsyncClient() as client:
+ await client.post(
+ "http://orchestrator:8000/api/v1/tools/register",
+ json={
+ "service_name": "my-new-service",
+ "tools": [
+ {
+ "tool_id": "my_tool",
+ "triggers": {
+ "pages": ["my-page"],
+ "actions": ["my_action"]
+ },
+ "endpoint": "/a2a/tasks",
+ "health_check": "/health"
+ }
+ ]
+ },
+ headers={"Authorization": f"Bearer {REGISTRATION_TOKEN}"}
+ )
+```
+
+**Orchestrator enhancements:**
+- Accept dynamic registrations
+- Health check polling
+- Automatic deregistration on unhealthy services
+- Tool versioning (multiple versions of same tool)
+
+### Phase 4: Frontend Tool Marketplace
+
+**Allow dynamic tool enabling from frontend:**
+```typescript
+// Admin interface
+interface ToolConfig {
+ toolId: string;
+ enabled: boolean;
+ visibleToUsers: boolean;
+ requirePlan: 'free' | 'pro' | 'enterprise';
+ customParams: Record;
+}
+
+// Users see tools based on registry + their plan
+const availableTools = await fetch('/api/v1/tools/available?page=resume-hub');
+```
+
+## Implementation Roadmap (Minimal Breaking Changes)
+
+### Week 1-2: Registry Foundation
+1. Create `ToolRegistry` class in orchestrator (in-memory first)
+2. Add `/api/v1/tools` CRUD endpoints
+3. Load hardcoded maps into registry at startup
+4. Switch routing to use registry lookups
+
+**Breaking change:** None - just refactoring
+
+### Week 3-4: Service Self-Registration
+1. Add registration endpoint to orchestrator
+2. Create simple registration helper library
+3. Update one service (e.g., interview-service) to self-register
+4. Test end-to-end
+
+**Breaking change:** None for existing services
+
+### Week 5-6: Frontend Integration
+1. Add tool discovery API: `/api/v1/tools?page={page}`
+2. Frontend fetches available tools per page
+3. Dynamic UI rendering based on tool registry
+4. Admin interface for tool management
+
+**Breaking change:** None - additive feature
+
+### Week 7-8: HTTP-First Migration
+1. Ensure all services have HTTP A2A endpoints
+2. Switch orchestrator default to HTTP
+3. Add SSE streaming for real-time updates
+4. Document contributor template
+
+**Breaking change:** Redis becomes optional (not default)
+
+### Week 9-10: Contributor SDK (Lightweight)
+1. Python decorator library:
+```python
+from growqr_sdk import tool, register_service
+
+@tool(
+ tool_id="analyze_resume",
+ triggers=["page:resume-hub", "action:analyze"]
+)
+async def analyze_resume(params, user_context):
+ # Implementation
+ return {"score": 85}
+
+register_service(
+ name="my-service",
+ orchestrator_url="http://orchestrator:8000",
+ tools=[analyze_resume]
+)
+```
+
+2. JavaScript/TypeScript equivalent for Node services
+
+## Summary: Why This Works
+
+1. **Minimal breaking changes**: Existing services keep working, Redis optional
+2. **Contributor-friendly**: Single HTTP endpoint to implement, decorator SDK optional
+3. **Pluggable**: Runtime registration, dynamic UI, no orchestrator redeploy
+4 **Preserves architecture**: Still 4-lane, still orchestrated, still Q-Score signals
+5 **Your team benefits**: You change services independently, original team gets stability
+6 **Original team benefits**: Less integration code, dynamic capabilities, easier debugging
+
+The key insight: **The orchestrator should ask "what tools are available?" not "is this action in my hardcoded map?"**
diff --git a/junior-dashboard-delegation-prd.md b/junior-dashboard-delegation-prd.md
new file mode 100644
index 0000000..b360a18
--- /dev/null
+++ b/junior-dashboard-delegation-prd.md
@@ -0,0 +1,1079 @@
+# PRD — Junior/Intern Delegation Plan for GrowQR Dashboard MVP
+
+**Date:** June 3, 2026
+**Owner:** Senior engineer / user
+**Delegate audience:** interns / junior engineers
+**Target repo for all implementation:** `growqr-dashboard`
+**Deadline context:** same-day AVPS deploy, 6-hour session
+**Primary objective:** make non-critical dashboard pages demo-ready while senior engineer owns workflow/chat/API/backend integration.
+
+---
+
+## 1. Executive Summary
+
+We are shipping a testable GrowQR dashboard + backend to AVPS today. The senior engineer will own all critical integration work: backend workflow routes, dashboard API proxy/client, workflow start/detail behavior, and chat surfaces.
+
+Junior/intern work should still stay inside `growqr-dashboard`, but the target has changed from static shells to **as much feature parity as possible** with `growqr-app/frontend` for Interview, Roleplay, and Resume. The senior engineer still owns backend changes, workflow/chat integration, Clerk/proxy decisions, and deployment, but juniors can now port frontend service UI, types, hooks, and client adapters that call the new backend service gateway or direct service WebSockets.
+
+**Interns should not touch backend, Clerk middleware, workflow/chat logic, or deployment configuration. They may port frontend-only service code and may add dashboard service API clients/types under senior-approved paths.**
+
+---
+
+## 2. Current Repo / Branch State
+
+Run from workspace root: `/Users/puter/Workspace/growqr`.
+
+| Repo | Branch | Role | Intern access |
+|---|---:|---|---|
+| `growqr-dashboard` | `main` tracking `origin/main` | **Only implementation target** | ✅ edit only here |
+| `growqr-backend` | `chore/release` tracking `origin/chore/release` | Production backend / API | ❌ do not edit |
+| `growqr-next-frontend` | `main` tracking `origin/main` | Reference UI only | 👀 read only |
+| `growqr-app` | `main`, behind origin by 1 | Reference UI only | 👀 read only |
+
+### Existing uncommitted changes to be careful around
+
+Current `growqr-dashboard` has existing changes. Juniors must not overwrite unrelated work.
+
+Observed modified/untracked files:
+
+```txt
+.gitignore
+app/layout.tsx
+app/social/page.tsx
+components/LeftRail.tsx
+components/tiles/SuggestionsTile.tsx
+package.json
+middleware.ts
+pnpm-lock.yaml
+pnpm-workspace.yaml
+package-lock.json deleted
+```
+
+**Instruction:** before editing, run:
+
+```bash
+git -C growqr-dashboard status --short --branch
+```
+
+If a file is already modified and not assigned below, do not edit it without asking.
+
+---
+
+## 3. Non-Negotiable Rules
+
+1. **Work only in `growqr-dashboard`.**
+2. **Do not edit `growqr-backend`.**
+3. **Do not edit `growqr-next-frontend` or `growqr-app`; use them only as references.**
+4. **Do not edit backend code.** Frontend calls are allowed only through approved dashboard service clients or direct Interview/Roleplay WS env vars.
+5. **Do not touch global chat implementation.**
+6. **Do not touch workflow start/run/current-run logic.**
+7. **Do not touch Clerk middleware/auth/proxy/deployment envs. Document required env vars instead of changing deployment config.**
+8. **No homepage work today.** Homepage is explicitly deferred.
+9. **No billing, entitlement, community, events, mentor, pathways, suggestions, rewards, social polish, E2E tests, mobile polish, or advanced animations.**
+10. **Keep it functional and clean, not perfect.**
+
+---
+
+## 4. Product Goal for Delegated Work
+
+When the team tests the deployed MVP, they should be able to click around and see credible pages for:
+
+- Interview practice
+- Roleplay practice
+- Resume review/building
+- Q Score / Queue Score
+- Career analytics
+
+The first fallback can be static/demo-driven, but the desired target is real frontend parity with `growqr-app/frontend`: configure sessions, launch direct live Interview/Roleplay WebSockets, show review/feedback when available, and support Resume list/upload/analyze/preview where the backend gateway supports it.
+
+---
+
+## 5A. Full-Parity Service Architecture Context
+
+### Old frontend behavior in `growqr-app/frontend`
+
+`growqr-app/frontend` uses three patterns:
+
+1. **Old orchestrator WebSocket** for page setup, review polling, and agent data:
+
+```txt
+NEXT_PUBLIC_ORCHESTRATOR_WS_URL/ws/agent?token=...
+```
+
+Old action names:
+
+```txt
+configure_interview
+get_review
+configure_roleplay
+get_roleplay_review
+```
+
+2. **Direct Interview WebSocket** for live audio/avatar interview sessions:
+
+```txt
+NEXT_PUBLIC_INTERVIEW_WS_URL/api/v1/session/:sessionId
+Default: ws://localhost:8007/api/v1/session/:sessionId
+```
+
+3. **Direct Roleplay WebSocket** for live audio/avatar roleplay sessions:
+
+```txt
+NEXT_PUBLIC_ROLEPLAY_WS_URL/api/v1/roleplays/session/:sessionId
+Default: ws://localhost:8008/api/v1/roleplays/session/:sessionId
+```
+
+4. **Resume REST service** for templates, resumes, upload, parse, AI analysis, preview/export:
+
+```txt
+NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1
+```
+
+### New backend gateway available in `growqr-backend`
+
+The new backend already exposes service gateway routes under `/services`:
+
+```txt
+/services/interview/configure
+/services/interview/preview
+/services/interview/approve
+/services/interview/review/:sessionId
+/services/interview/artifacts/:sessionId/:artifactType
+/services/interview/sessions/:sessionId/video/upload-url
+/services/interview/sessions/:sessionId/video/uploaded
+
+/services/roleplay/configure
+/services/roleplay/preview
+/services/roleplay/approve
+/services/roleplay/review/:sessionId
+/services/roleplay/artifacts/:sessionId/:artifactType
+/services/roleplay/sessions/:sessionId/video/upload-url
+/services/roleplay/sessions/:sessionId/video/uploaded
+
+/services/resume/templates
+/services/resume/resumes
+/services/resume/resumes/:resumeId
+/services/resume/resumes/:resumeId/analyze
+/services/resume/resumes/:resumeId/suggestions
+/services/resume/ai/copilot
+/services/resume/ai/optimize-summary
+/services/resume/ai/optimize-experience
+/services/resume/ai/suggest-skills
+/services/resume/ai/generate-summary
+/services/resume/resumes/:resumeId/versions
+/services/resume/resumes/:resumeId/preview
+```
+
+### Full-parity strategy for dashboard
+
+- Use the **new backend REST service gateway** for configure/preview/approve/review/resume operations.
+- Use **direct frontend WebSocket connections** to Interview and Roleplay services for live sessions.
+- Do **not** recreate the old orchestrator WebSocket in the dashboard. Replace old `sendAction(...)` flows with REST calls.
+- Preserve old WebSocket message contracts for live session hooks as much as possible.
+
+### Required frontend env vars to document / expect
+
+Do not edit deployment env. Document these if missing:
+
+```txt
+NEXT_PUBLIC_GROWQR_BACKEND_URL=https://
+NEXT_PUBLIC_INTERVIEW_WS_URL=wss:///api/v1
+NEXT_PUBLIC_INTERVIEW_ARTIFACTS_URL=https:///api/v1
+NEXT_PUBLIC_ROLEPLAY_WS_URL=wss:///api/v1
+NEXT_PUBLIC_ROLEPLAY_ARTIFACTS_URL=https:///api/v1
+```
+
+Resume should preferably go through the dashboard/backend proxy, not direct public resume service, unless senior engineer approves otherwise.
+
+### Old source files to port from
+
+```txt
+growqr-app/frontend/src/hooks/useInterviewSession.ts
+growqr-app/frontend/src/hooks/useInterviewMedia.ts
+growqr-app/frontend/src/hooks/useInterviewReview.ts
+growqr-app/frontend/src/hooks/useRoleplaySession.ts
+growqr-app/frontend/src/hooks/useRoleplayReview.ts
+growqr-app/frontend/src/lib/interview/types.ts
+growqr-app/frontend/src/lib/roleplay/types.ts
+growqr-app/frontend/src/lib/api/interview.ts
+growqr-app/frontend/src/lib/api/roleplay.ts
+growqr-app/frontend/src/lib/api/resumes.ts
+growqr-app/frontend/src/types/resume.ts
+growqr-app/frontend/src/components/interview/*
+growqr-app/frontend/src/components/roleplay/*
+growqr-app/frontend/src/components/resume/*
+```
+
+Port carefully. Do not blindly copy imports that reference old app-only contexts, billing, onboarding, or layout. Create dashboard-compatible wrappers where needed.
+
+---
+
+## 5. Priority-Ordered Delegated Tasks
+
+Tasks are listed in priority order. Start from the top. If time runs out, leave lower-priority tasks unfinished.
+
+---
+
+# P0 — Frontend Service Parity Foundation
+
+## Owner
+Junior/intern, with senior review before final wiring.
+
+## Files to create
+
+```txt
+growqr-dashboard/lib/services/service-config.ts
+growqr-dashboard/lib/services/interview-service.ts
+growqr-dashboard/lib/services/roleplay-service.ts
+growqr-dashboard/lib/services/resume-service.ts
+growqr-dashboard/types/interview.ts
+growqr-dashboard/types/roleplay.ts
+growqr-dashboard/types/resume.ts
+```
+
+## Goal
+Create dashboard-compatible service clients/types that replace the old orchestrator action pattern with explicit REST calls to the new backend service gateway, while preserving direct WS base URLs for live Interview/Roleplay.
+
+## Requirements
+
+### Service config
+
+Expose frontend-safe constants:
+
+```ts
+export const GROWQR_BACKEND_URL = process.env.NEXT_PUBLIC_GROWQR_BACKEND_URL ?? "";
+export const INTERVIEW_WS_BASE_URL = process.env.NEXT_PUBLIC_INTERVIEW_WS_URL ?? "ws://localhost:8007/api/v1";
+export const INTERVIEW_ARTIFACTS_BASE_URL = process.env.NEXT_PUBLIC_INTERVIEW_ARTIFACTS_URL ?? "http://localhost:8007/api/v1";
+export const ROLEPLAY_WS_BASE_URL = process.env.NEXT_PUBLIC_ROLEPLAY_WS_URL ?? "ws://localhost:8008/api/v1";
+export const ROLEPLAY_ARTIFACTS_BASE_URL = process.env.NEXT_PUBLIC_ROLEPLAY_ARTIFACTS_URL ?? "http://localhost:8008/api/v1";
+```
+
+If the senior API proxy exists, REST calls should use `/api/growqr/services/...` instead of direct backend URL.
+
+### Interview REST client
+
+Implement functions equivalent to old orchestrator actions:
+
+```ts
+configureInterview(payload) // POST /services/interview/configure
+previewInterview(payload) // POST /services/interview/preview
+approveInterview(sessionId) // POST /services/interview/approve
+getInterviewReview(sessionId) // GET /services/interview/review/:sessionId
+requestInterviewVideoUploadUrl(sessionId)
+confirmInterviewVideoUploaded(sessionId)
+```
+
+### Roleplay REST client
+
+```ts
+configureRoleplay(payload) // POST /services/roleplay/configure
+previewRoleplay(payload) // POST /services/roleplay/preview
+approveRoleplay(sessionId) // POST /services/roleplay/approve
+getRoleplayReview(sessionId) // GET /services/roleplay/review/:sessionId
+requestRoleplayVideoUploadUrl(sessionId)
+confirmRoleplayVideoUploaded(sessionId)
+```
+
+### Resume REST client
+
+Implement what the new backend gateway currently supports:
+
+```ts
+listTemplates()
+listResumes()
+createResume(payload)
+getResume(resumeId)
+updateResume(resumeId, payload)
+analyzeResume(resumeId, payload?)
+getResumeSuggestions(resumeId)
+optimizeSummary(payload)
+optimizeExperience(payload)
+suggestSkills(payload)
+generateSummary(payload)
+listVersions(resumeId)
+createVersion(resumeId, payload)
+getPreview(resumeId)
+```
+
+Also document missing full-parity endpoints if needed:
+
+```txt
+multipart upload
+parse resume
+delete resume
+set primary resume
+binary PDF/original PDF export
+analysis report PDF export
+```
+
+## Acceptance criteria
+
+- Clients compile.
+- No backend code edited.
+- No old orchestrator dependency remains in new dashboard service clients.
+- Missing parity endpoints are clearly listed in handoff notes.
+
+---
+
+# P1 — Port Live Interview Frontend Flow
+
+## Owner
+Junior/intern for frontend port; senior reviews service call wiring.
+
+## Files to create/update
+
+```txt
+growqr-dashboard/app/features/interview/page.tsx
+growqr-dashboard/hooks/useInterviewSession.ts
+growqr-dashboard/hooks/useInterviewMedia.ts
+growqr-dashboard/hooks/useInterviewReview.ts
+growqr-dashboard/components/interview/*
+```
+
+## Goal
+Port as much of the old Interview UX as possible from `growqr-app/frontend` into dashboard.
+
+## Required behavior
+
+1. Configure interview via new REST client, not old orchestrator.
+2. Receive or store `session_id` from configure response.
+3. Connect live session directly to:
+
+```txt
+${NEXT_PUBLIC_INTERVIEW_WS_URL}/session/:sessionId
+```
+
+4. Preserve old WS protocol:
+
+Frontend sends:
+
+```txt
+session.start
+audio.input
+session.finish
+avatar.frontend_ready
+presence_metrics_summary
+```
+
+Frontend receives:
+
+```txt
+session.ready
+assistant.audio
+assistant.audio.interrupted
+assistant.transcript
+candidate.transcript
+turn.saved
+session.completed
+session.time_warning
+session.context.warning
+session.terminated
+error
+```
+
+5. Poll review via REST:
+
+```txt
+GET /services/interview/review/:sessionId
+```
+
+## Cut lines
+
+If time is short, keep the UI flow but disable or stub:
+
+- LiveKit/avatar rendering
+- video recording/upload
+- advanced video analysis
+
+Do not block live audio/session parity on those.
+
+## Acceptance criteria
+
+- User can configure/start an interview session when services are available.
+- Direct WS hook uses dashboard env vars.
+- Transcript renders.
+- Finish session works.
+- Review area attempts real review polling and degrades gracefully.
+
+---
+
+# P2 — Port Live Roleplay Frontend Flow
+
+## Owner
+Junior/intern for frontend port; senior reviews service call wiring.
+
+## Files to create/update
+
+```txt
+growqr-dashboard/app/features/roleplay/page.tsx
+growqr-dashboard/hooks/useRoleplaySession.ts
+growqr-dashboard/hooks/useRoleplayReview.ts
+growqr-dashboard/components/roleplay/*
+```
+
+## Goal
+Port as much of the old Roleplay UX as possible from `growqr-app/frontend` into dashboard.
+
+## Required behavior
+
+1. Configure roleplay via new REST client, not old orchestrator.
+2. Receive or store `session_id` from configure response.
+3. Connect live session directly to:
+
+```txt
+${NEXT_PUBLIC_ROLEPLAY_WS_URL}/roleplays/session/:sessionId
+```
+
+4. Preserve old WS protocol:
+
+Frontend sends:
+
+```txt
+session.start
+audio.input
+session.finish
+avatar.frontend_ready
+presence_metrics_summary
+```
+
+Frontend receives:
+
+```txt
+session.ready
+assistant.audio
+assistant.audio.interrupted
+assistant.transcript
+candidate.transcript
+turn.saved
+session.completed
+error
+```
+
+5. Poll review via REST:
+
+```txt
+GET /services/roleplay/review/:sessionId
+```
+
+## Cut lines
+
+If time is short, keep scenario selection + live WS + transcript. Stub advanced feedback/video analysis if needed.
+
+## Acceptance criteria
+
+- User can configure/start a roleplay when services are available.
+- Direct WS hook uses dashboard env vars.
+- Transcript renders.
+- Finish session works.
+- Review area attempts real review polling and degrades gracefully.
+
+---
+
+# P3 — Port Resume Frontend Flow
+
+## Owner
+Junior/intern for frontend port; senior reviews service call wiring.
+
+## Files to create/update
+
+```txt
+growqr-dashboard/app/features/resume/page.tsx
+growqr-dashboard/components/resume/*
+growqr-dashboard/types/resume.ts
+growqr-dashboard/lib/services/resume-service.ts
+```
+
+## Goal
+Port as much of the old Resume UX as the new backend gateway currently supports.
+
+## Required behavior
+
+- List resumes if backend service is available.
+- Show resume cards.
+- Create/edit basic resume data if practical.
+- Analyze resume through:
+
+```txt
+POST /services/resume/resumes/:resumeId/analyze
+```
+
+- Show analysis score/breakdown if returned.
+- Show preview if gateway supports it.
+
+## Known full-parity gaps likely requiring senior/backend work
+
+```txt
+POST multipart upload
+POST multipart parse
+DELETE resume
+PATCH primary resume
+binary PDF export
+original PDF fetch
+analysis report export
+```
+
+Do not implement backend for these. Add UI fallbacks and document gaps.
+
+## Acceptance criteria
+
+- Resume page uses real client functions where supported.
+- Missing operations show graceful disabled/coming-soon states instead of broken buttons.
+- Old resume components are adapted without importing old app-only contexts.
+
+---
+
+# P4 — Q Score Page / Service Analytics
+
+## Owner
+Junior/intern.
+
+## Files to create/update
+
+```txt
+growqr-dashboard/app/features/qscore/page.tsx
+growqr-dashboard/app/analytics/page.tsx
+```
+
+## Goal
+Provide Q Score page and analytics that integrate real data if available and static fallback otherwise.
+
+## Acceptance criteria
+
+- Q Score page exists.
+- Analytics page exists.
+- Static fallback is credible if service summary endpoint is not ready.
+
+---
+
+# P5 — Feature Pages MVP Shells / Fallback
+
+## Owner
+Junior/intern.
+
+## Files to create or update
+
+```txt
+growqr-dashboard/app/features/interview/page.tsx
+growqr-dashboard/app/features/roleplay/page.tsx
+growqr-dashboard/app/features/resume/page.tsx
+growqr-dashboard/app/features/qscore/page.tsx
+```
+
+If the folder structure does not exist, create it.
+
+## Goal
+Create four demo-ready service pages using static data and existing dashboard styling.
+
+## Requirements
+
+Each page should have:
+
+- Clear page title
+- Short user-facing explanation
+- Status/summary cards
+- One primary CTA
+- 2–4 supporting sections that make the service feel real
+- No backend dependency
+- No fake loading spinners that never resolve
+- No lorem ipsum
+- No broken links
+
+## Page-specific guidance
+
+### Interview page
+
+Title examples:
+
+- `Interview Practice`
+- `Interview Coach`
+
+Suggested sections:
+
+- Readiness score
+- Upcoming mock interview / practice session card
+- Focus areas: behavioral answers, role fit, confidence, technical clarity
+- Recent feedback summary
+
+Primary CTA:
+
+- `Start Interview Practice`
+
+Reference only:
+
+```txt
+growqr-next-frontend/src/app/v2/services/interview/*
+growqr-app/frontend/src/components/interview/*
+growqr-app/frontend/src/app/(dashboard)/upskilling/interview/*
+```
+
+Do not port complex media/avatar/session hooks. Keep the dashboard page simple.
+
+### Roleplay page
+
+Suggested sections:
+
+- Scenario cards: recruiter screen, hiring manager, salary negotiation, promotion conversation
+- Confidence score
+- Last practice feedback
+- Recommended next roleplay
+
+Primary CTA:
+
+- `Start Roleplay`
+
+Reference only:
+
+```txt
+growqr-next-frontend/src/app/v2/services/roleplay/*
+growqr-app/frontend/src/components/roleplay/*
+```
+
+### Resume page
+
+Suggested sections:
+
+- Resume strength score
+- ATS readiness
+- Missing keywords
+- Suggested improvements
+- Recent resume versions/demo cards
+
+Primary CTA:
+
+- `Analyze Resume`
+
+Reference only:
+
+```txt
+growqr-next-frontend/src/app/v2/services/resume/*
+growqr-app/frontend/src/components/resume/*
+```
+
+### Q Score page
+
+Suggested sections:
+
+- Q Score / Queue Score headline score
+- Score breakdown: resume, interview, roleplay, market fit, momentum
+- Trend or progress cards
+- Recommended next actions
+
+Primary CTA:
+
+- `Improve My Q Score`
+
+Reference only:
+
+```txt
+growqr-next-frontend/src/app/qx-score/page.tsx
+growqr-next-frontend/src/app/v2/qx-score/page.tsx
+```
+
+## Acceptance criteria
+
+- `pnpm build` or at least `pnpm lint` does not fail because of these pages.
+- Each page opens directly by URL.
+- Each page uses static/demo data only.
+- Each page feels coherent enough for a customer/team demo.
+
+---
+
+# P6 — Feature Catalog Cleanup
+
+## Owner
+Junior/intern.
+
+## Files to update
+
+```txt
+growqr-dashboard/app/features/page.tsx
+growqr-dashboard/data/features.ts
+```
+
+## Goal
+Make the features index page focus on the four MVP services.
+
+## Requirements
+
+Feature cards should include only or prominently emphasize:
+
+1. Interview
+2. Roleplay
+3. Resume
+4. Q Score
+
+Each card should have:
+
+- Name
+- Short benefit-driven description
+- Status badge or category
+- CTA/link to the correct page
+
+Recommended routes:
+
+```txt
+/features/interview
+/features/roleplay
+/features/resume
+/features/qscore
+```
+
+## Acceptance criteria
+
+- All four cards are visible.
+- All four cards link to working pages.
+- No dead CTA buttons.
+- Non-MVP features are removed, hidden, or clearly de-emphasized.
+
+---
+
+# P7 — Analytics / Career Score Dashboard Fallback
+
+## Owner
+Junior/intern.
+
+## File to update
+
+```txt
+growqr-dashboard/app/analytics/page.tsx
+```
+
+## Goal
+Make analytics feel career-specific and aligned with Q Score, even if static for today.
+
+## Requirements
+
+Use static/demo data. Include:
+
+- Overall Q Score
+- Interview readiness
+- Resume strength
+- Roleplay confidence
+- Workflow progress
+- Recommended next action
+
+Suggested visual sections:
+
+- Top KPI cards
+- Score breakdown cards
+- Progress/trend area
+- Recent activity list
+- Recommended next actions
+
+Do not wait on backend analytics. Senior engineer may later plug real data into this.
+
+## Acceptance criteria
+
+- Page renders cleanly.
+- Looks intentional and career-focused.
+- Does not use unrelated generic analytics copy.
+- No backend dependency.
+
+---
+
+# P8 — Reusable Empty / Loading / Error UI Components
+
+## Owner
+Junior/intern.
+
+## Files to create
+
+```txt
+growqr-dashboard/components/EmptyState.tsx
+growqr-dashboard/components/LoadingState.tsx
+growqr-dashboard/components/ErrorState.tsx
+```
+
+## Goal
+Create small presentational components senior engineer can plug into API-driven workflow/chat pages.
+
+## Requirements
+
+Components should be dumb/presentational only.
+
+Suggested props:
+
+```ts
+type EmptyStateProps = {
+ title: string;
+ description?: string;
+ actionLabel?: string;
+ href?: string;
+};
+
+type LoadingStateProps = {
+ title?: string;
+ description?: string;
+};
+
+type ErrorStateProps = {
+ title?: string;
+ description?: string;
+ actionLabel?: string;
+ onAction?: () => void;
+};
+```
+
+Use existing card/tile styling patterns.
+
+## Acceptance criteria
+
+- Components compile.
+- No API calls.
+- No external dependencies unless already installed.
+- Easy for senior engineer to import.
+
+---
+
+# P9 — Navigation Copy / MVP Path Cleanup
+
+## Owner
+Junior/intern, but coordinate before editing because current nav files are already modified.
+
+## Candidate files
+
+```txt
+growqr-dashboard/components/LeftRail.tsx
+growqr-dashboard/app/layout.tsx
+```
+
+## Goal
+Make demo navigation obvious.
+
+## Desired MVP nav order
+
+1. Dashboard
+2. Workflows
+3. Talk to Me
+4. Features
+5. Analytics
+6. Settings
+
+## Important warning
+
+`components/LeftRail.tsx` and `app/layout.tsx` already have uncommitted changes. Do not edit without checking with senior engineer.
+
+## Acceptance criteria
+
+- MVP routes are easy to find.
+- No prominent links to unfinished/community/social/rewards/mentor/pathways pages.
+- No broken nav links.
+
+---
+
+# P10 — Copy Polish Pass
+
+## Owner
+Junior/intern.
+
+## Files
+Any assigned feature/analytics files, plus potentially `data/features.ts`.
+
+## Goal
+Make labels and descriptions sellable and human-readable.
+
+## Tone
+
+- Clear
+- Benefit-driven
+- Professional
+- Not too verbose
+- Not too technical
+
+## Important workflow names to use consistently
+
+```txt
+Interview-to-Offer Accelerator
+Career Transition Sprint
+Salary Negotiation War Room
+Promotion Readiness Packet
+Personal Brand Opportunity Engine
+```
+
+## Avoid
+
+- Lorem ipsum
+- Placeholder copy
+- Over-promising AI capabilities
+- Internal implementation terms like `actor`, `moduleId`, `adapter`, `Rivet`, `Drizzle`
+
+---
+
+## 6. Tasks Not Assigned to Juniors
+
+The senior engineer owns these:
+
+```txt
+growqr-dashboard/app/api/growqr/[...path]/route.ts
+growqr-dashboard/lib/api.ts
+growqr-dashboard/lib/growqr-api.ts
+growqr-dashboard/types/workflows.ts
+growqr-dashboard/types/chat.ts
+growqr-dashboard/app/workflows/page.tsx
+growqr-dashboard/app/workflows/[id]/page.tsx
+growqr-dashboard/app/talk/page.tsx or app/chat/page.tsx
+growqr-dashboard/components/ActiveWorkflowDetail.tsx
+growqr-dashboard/components/AvailableWorkflowCard.tsx
+growqr-dashboard/components/PromptBar.tsx
+growqr-backend/**
+```
+
+Do not modify these unless explicitly asked.
+
+---
+
+## 7. Backend API Context for Awareness Only
+
+Juniors may call approved `/services/...` routes through dashboard service clients, but should not touch workflow routes unless explicitly asked.
+
+Key backend routes:
+
+```txt
+GET /workflows
+GET /workflows/:workflowId
+POST /workflows/:workflowId/runs
+GET /workflows/:workflowId/runs/current
+GET /workflow-runs/:runId
+POST /workflow-runs/:runId/run
+POST /workflow-runs/:runId/modules/:moduleId/run
+GET /workflow-runs/:runId/artifacts
+GET /workflow-runs/:runId/events
+POST /chat
+```
+
+The senior engineer will own workflow/chat API proxy wiring. Service pages should prefer the approved dashboard service clients described above.
+
+---
+
+## 8. Sellable Workflow Context
+
+The dashboard should align with these five workflows:
+
+| ID | Display name | Modules / services |
+|---|---|---|
+| `interview-to-offer` | Interview-to-Offer Accelerator | Resume, interview plan, Sara, Emily, Q Score |
+| `career-transition` | Career Transition Sprint | Transition map, resume |
+| `salary-negotiation-war-room` | Salary Negotiation War Room | Negotiation script, Emily roleplay |
+| `promotion-readiness` | Promotion Readiness Packet | Evidence packet, Emily roleplay |
+| `personal-brand-opportunity-engine` | Personal Brand Opportunity Engine | Profile rewrite |
+
+Feature pages should feel like services that support these workflows.
+
+---
+
+## 9. Design / Implementation Guidelines
+
+Use the existing `growqr-dashboard` style. Prefer existing components and classes.
+
+Common style direction:
+
+- Rounded cards / tiles
+- Soft surfaces
+- Clear section headers
+- Simple status badges
+- Brand orange accents where appropriate
+- Desktop-first; mobile polish not required today
+
+Keep implementation simple:
+
+- Use client components only where hooks, browser media, or WebSockets are required.
+- Avoid complex animations.
+- Avoid new dependencies.
+- Prefer frontend wrappers over broad refactors.
+- Use static fallback data only when a real service endpoint is missing or unavailable.
+- Do not import old app-only providers/contexts unless they are also ported safely.
+
+---
+
+## 10. Suggested Work Plan for Interns
+
+### First 15 minutes
+
+1. Pull latest branch.
+2. Run status check.
+3. Inspect existing dashboard page/component style.
+4. Confirm assigned files.
+
+Commands:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+git status --short --branch
+pnpm install
+pnpm lint
+```
+
+### Next 45–60 minutes
+
+Build P0 service parity foundation: config, types, REST clients, direct WS constants.
+
+### Next 90–120 minutes
+
+Port P1 Interview flow: configure → direct WS live session → transcript → review fallback.
+
+### Next 90–120 minutes
+
+Port P2 Roleplay flow: configure → direct WS live session → transcript → review fallback.
+
+### Next 60–90 minutes
+
+Port P3 Resume flow for gateway-supported operations; document missing parity endpoints.
+
+### Optional final 30–45 minutes
+
+Build P4/P6/P8 polish: Q Score, feature catalog, reusable states, copy.
+
+---
+
+## 11. Handoff Checklist
+
+Before handing off, juniors should report:
+
+- Files changed
+- Routes created/updated
+- Any known broken links
+- Whether lint/build was run
+- Any errors seen
+
+Minimum validation commands:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+pnpm lint
+pnpm build
+```
+
+If `pnpm build` fails for unrelated existing project issues, capture the error and report it. Do not attempt broad refactors.
+
+---
+
+## 12. Definition of Done
+
+Delegated work is done when:
+
+- `/features` shows the four MVP services.
+- `/features/interview` works.
+- `/features/roleplay` works.
+- `/features/resume` works.
+- `/features/qscore` works.
+- `/analytics` shows career/Q Score analytics.
+- Interview/Roleplay use direct WS URLs when services are available.
+- Resume uses real gateway-supported operations where possible.
+- Missing full-parity endpoints are documented and have graceful UI fallbacks.
+- No lorem ipsum or obvious placeholders remain.
+- No critical senior-owned files were modified.
+
+---
+
+## 13. Delegation Message to Send
+
+Copy/paste:
+
+> Please work only in `growqr-dashboard` on branch `main`. Do not touch backend, chat, Clerk middleware, API proxy, deployment env, or workflow logic. New target is as much feature parity as possible with `growqr-app/frontend` for Interview, Roleplay, and Resume. Work in this order:
+> 1. Create dashboard service config/types/clients for Interview, Roleplay, Resume using `/services/...` REST and direct Interview/Roleplay WS env vars.
+> 2. Port Interview flow from `growqr-app/frontend`: configure via REST, connect direct WS, render transcript, finish session, poll review.
+> 3. Port Roleplay flow similarly: configure via REST, connect direct WS, render transcript, finish session, poll review.
+> 4. Port Resume flow for supported gateway operations: list/create/get/update/analyze/suggestions/preview; document missing upload/export/parse parity.
+> 5. Add Q Score/analytics and feature catalog polish with graceful fallbacks.
+>
+> Use existing dashboard styles, no new dependencies, no backend code edits, and no lorem ipsum. Frontend service calls are allowed only through approved dashboard clients. Run `pnpm lint` and `pnpm build` before handoff or send the errors if they are unrelated.
diff --git a/phase1-tool-registry-implementation.md b/phase1-tool-registry-implementation.md
new file mode 100644
index 0000000..f78f05b
--- /dev/null
+++ b/phase1-tool-registry-implementation.md
@@ -0,0 +1,1031 @@
+# Phase 1: Dynamic Tool Registry Implementation
+
+This document provides the concrete implementation plan for the first phase - replacing hardcoded routing maps with a dynamic tool registry.
+
+## Goals of Phase 1
+
+1. Replace `PAGE_TO_AGENT` and `ACTION_TO_AGENT` hardcoded dictionaries with database lookups
+2. Zero breaking changes to existing services
+3. Orchestrator behavior remains identical
+4. Foundation for runtime tool registration
+
+## Database Schema
+
+```sql
+-- tools table
+CREATE TABLE tools (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tool_id VARCHAR(255) UNIQUE NOT NULL, -- e.g., "resume_analyze"
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+
+ -- Service routing
+ service_name VARCHAR(255) NOT NULL, -- e.g., "resume-builder"
+ service_url VARCHAR(500), -- optional override
+ endpoint VARCHAR(255) DEFAULT '/a2a/tasks',
+
+ -- Triggers (how this tool is invoked)
+ page_triggers VARCHAR(255)[], -- e.g., ["resume-hub", "resume-editor"]
+ action_triggers VARCHAR(255)[], -- e.g., ["ai_analyze", "analyze_resume"]
+ skill_triggers VARCHAR(255)[], -- e.g., ["resume.analysis"]
+
+ -- JSON Schemas for validation
+ input_schema JSONB, -- JSON Schema for params
+ output_schema JSONB, -- JSON Schema for responses
+
+ -- Q-Score integration
+ qscore_signals VARCHAR(255)[], -- e.g., ["resume.ats_score"]
+
+ -- Versioning & metadata
+ version VARCHAR(50) DEFAULT '1.0.0',
+ enabled BOOLEAN DEFAULT true,
+ is_builtin BOOLEAN DEFAULT false, -- true for hardcoded tools
+
+ -- Ownership
+ created_by VARCHAR(255),
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMP DEFAULT NOW()
+);
+
+-- Index for fast lookups
+CREATE INDEX idx_tools_page_triggers ON tools USING GIN(page_triggers);
+CREATE INDEX idx_tools_action_triggers ON tools USING GIN(action_triggers);
+CREATE INDEX idx_tools_service ON tools(service_name);
+CREATE INDEX idx_tools_enabled ON tools(enabled) WHERE enabled = true;
+
+-- Composite workflows table (for multi-step actions)
+CREATE TABLE composite_workflows (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ workflow_id VARCHAR(255) UNIQUE NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+
+ -- Steps as ordered JSON array
+ steps JSONB NOT NULL, -- [{"tool_id": "...", "params_mapping": {...}}]
+
+ action_trigger VARCHAR(255),
+ enabled BOOLEAN DEFAULT true,
+ created_at TIMESTAMP DEFAULT NOW()
+);
+```
+
+## New Files to Create
+
+### 1. `orchestrator/app/tools/registry.py`
+
+```python
+"""Dynamic tool registry - replaces hardcoded PAGE_TO_AGENT and ACTION_TO_AGENT."""
+
+import logging
+from dataclasses import dataclass
+from typing import Optional
+from datetime import datetime
+import json
+
+import asyncpg
+from asyncpg import Pool
+
+logger = logging.getLogger(__name__)
+
+
+@dataclass
+class Tool:
+ """A registered tool that can be invoked by the orchestrator."""
+ id: str
+ tool_id: str
+ name: str
+ description: str
+ service_name: str
+ service_url: Optional[str]
+ endpoint: str
+ page_triggers: list[str]
+ action_triggers: list[str]
+ skill_triggers: list[str]
+ input_schema: Optional[dict]
+ output_schema: Optional[dict]
+ qscore_signals: list[str]
+ version: str
+ enabled: bool
+ is_builtin: bool
+
+
+class ToolRegistry:
+ """Database-backed tool registry with in-memory caching."""
+
+ def __init__(self, db_pool: Pool, cache_ttl_seconds: int = 30):
+ self._db = db_pool
+ self._cache_ttl = cache_ttl_seconds
+ self._cache: dict[str, Tool] = {} # tool_id -> Tool
+ self._page_index: dict[str, list[str]] = {} # page -> [tool_ids]
+ self._action_index: dict[str, list[str]] = {} # action -> [tool_ids]
+ self._last_refresh: Optional[datetime] = None
+
+ async def initialize(self):
+ """Load all tools from database into cache."""
+ await self._refresh_cache()
+ logger.info(f"Tool registry initialized with {len(self._cache)} tools")
+
+ async def _refresh_cache(self):
+ """Refresh the in-memory cache from database."""
+ async with self._db.acquire() as conn:
+ rows = await conn.fetch("""
+ SELECT * FROM tools WHERE enabled = true
+ """)
+
+ # Clear and rebuild
+ self._cache.clear()
+ self._page_index.clear()
+ self._action_index.clear()
+
+ for row in rows:
+ tool = Tool(
+ id=str(row['id']),
+ tool_id=row['tool_id'],
+ name=row['name'],
+ description=row['description'] or '',
+ service_name=row['service_name'],
+ service_url=row['service_url'],
+ endpoint=row['endpoint'],
+ page_triggers=row['page_triggers'] or [],
+ action_triggers=row['action_triggers'] or [],
+ skill_triggers=row['skill_triggers'] or [],
+ input_schema=row['input_schema'],
+ output_schema=row['output_schema'],
+ qscore_signals=row['qscore_signals'] or [],
+ version=row['version'],
+ enabled=row['enabled'],
+ is_builtin=row['is_builtin'],
+ )
+ self._cache[tool.tool_id] = tool
+
+ # Build indexes
+ for page in tool.page_triggers:
+ self._page_index.setdefault(page, []).append(tool.tool_id)
+ for action in tool.action_triggers:
+ self._action_index.setdefault(action, []).append(tool.tool_id)
+
+ self._last_refresh = datetime.utcnow()
+
+ async def get_tool_for_page(self, page: str) -> Optional[Tool]:
+ """Find the primary tool for a given page."""
+ await self._maybe_refresh()
+
+ tool_ids = self._page_index.get(page, [])
+ if not tool_ids:
+ return None
+
+ # Return first enabled tool (or prioritize by version/is_builtin)
+ for tool_id in tool_ids:
+ tool = self._cache.get(tool_id)
+ if tool and tool.enabled:
+ return tool
+ return None
+
+ async def get_tool_for_action(self, action: str) -> Optional[Tool]:
+ """Find the primary tool for a given action."""
+ await self._maybe_refresh()
+
+ # Exact match first
+ tool_ids = self._action_index.get(action, [])
+ if tool_ids:
+ for tool_id in tool_ids:
+ tool = self._cache.get(tool_id)
+ if tool and tool.enabled:
+ return tool
+
+ # Prefix match (e.g., "improve_headline" matches "improve_" prefix)
+ for trigger, tool_ids in self._action_index.items():
+ if trigger.endswith('_') and action.startswith(trigger):
+ for tool_id in tool_ids:
+ tool = self._cache.get(tool_id)
+ if tool and tool.enabled:
+ return tool
+
+ return None
+
+ async def get_service_for_page(self, page: str) -> Optional[str]:
+ """Get service name for a page (backward compatible with old behavior)."""
+ tool = await self.get_tool_for_page(page)
+ return tool.service_name if tool else None
+
+ async def get_service_for_action(self, action: str) -> Optional[str]:
+ """Get service name for an action (backward compatible)."""
+ tool = await self.get_tool_for_action(action)
+ return tool.service_name if tool else None
+
+ async def get_all_tools_for_page(self, page: str) -> list[Tool]:
+ """Get all tools available for a page (for UI rendering)."""
+ await self._maybe_refresh()
+
+ tool_ids = self._page_index.get(page, [])
+ return [self._cache[tid] for tid in tool_ids if tid in self._cache]
+
+ async def list_tools(self, service_name: Optional[str] = None) -> list[Tool]:
+ """List all tools, optionally filtered by service."""
+ await self._maybe_refresh()
+
+ tools = list(self._cache.values())
+ if service_name:
+ tools = [t for t in tools if t.service_name == service_name]
+ return tools
+
+ async def _maybe_refresh(self):
+ """Refresh cache if TTL expired."""
+ if self._last_refresh is None:
+ await self._refresh_cache()
+ return
+
+ elapsed = (datetime.utcnow() - self._last_refresh).total_seconds()
+ if elapsed > self._cache_ttl:
+ await self._refresh_cache()
+
+ # Admin methods (for runtime registration)
+
+ async def register_tool(self, tool_data: dict) -> Tool:
+ """Register a new tool at runtime."""
+ async with self._db.acquire() as conn:
+ row = await conn.fetchrow("""
+ INSERT INTO tools (
+ tool_id, name, description, service_name, service_url,
+ endpoint, page_triggers, action_triggers, skill_triggers,
+ input_schema, output_schema, qscore_signals,
+ version, enabled, is_builtin, created_by
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
+ ON CONFLICT (tool_id) DO UPDATE SET
+ name = EXCLUDED.name,
+ description = EXCLUDED.description,
+ service_name = EXCLUDED.service_name,
+ service_url = EXCLUDED.service_url,
+ endpoint = EXCLUDED.endpoint,
+ page_triggers = EXCLUDED.page_triggers,
+ action_triggers = EXCLUDED.action_triggers,
+ skill_triggers = EXCLUDED.skill_triggers,
+ input_schema = EXCLUDED.input_schema,
+ output_schema = EXCLUDED.output_schema,
+ qscore_signals = EXCLUDED.qscore_signals,
+ version = EXCLUDED.version,
+ updated_at = NOW()
+ RETURNING *
+ """,
+ tool_data['tool_id'],
+ tool_data['name'],
+ tool_data.get('description'),
+ tool_data['service_name'],
+ tool_data.get('service_url'),
+ tool_data.get('endpoint', '/a2a/tasks'),
+ tool_data.get('page_triggers', []),
+ tool_data.get('action_triggers', []),
+ tool_data.get('skill_triggers', []),
+ json.dumps(tool_data.get('input_schema')) if tool_data.get('input_schema') else None,
+ json.dumps(tool_data.get('output_schema')) if tool_data.get('output_schema') else None,
+ tool_data.get('qscore_signals', []),
+ tool_data.get('version', '1.0.0'),
+ tool_data.get('enabled', True),
+ tool_data.get('is_builtin', False),
+ tool_data.get('created_by', 'system')
+ )
+
+ await self._refresh_cache()
+
+ return Tool(
+ id=str(row['id']),
+ tool_id=row['tool_id'],
+ name=row['name'],
+ description=row['description'] or '',
+ service_name=row['service_name'],
+ service_url=row['service_url'],
+ endpoint=row['endpoint'],
+ page_triggers=row['page_triggers'] or [],
+ action_triggers=row['action_triggers'] or [],
+ skill_triggers=row['skill_triggers'] or [],
+ input_schema=row['input_schema'],
+ output_schema=row['output_schema'],
+ qscore_signals=row['qscore_signals'] or [],
+ version=row['version'],
+ enabled=row['enabled'],
+ is_builtin=row['is_builtin'],
+ )
+
+ async def unregister_tool(self, tool_id: str) -> bool:
+ """Disable a tool (soft delete)."""
+ async with self._db.acquire() as conn:
+ result = await conn.execute("""
+ UPDATE tools SET enabled = false WHERE tool_id = $1
+ """, tool_id)
+
+ await self._refresh_cache()
+ return result == "UPDATE 1"
+```
+
+### 2. Migration Script: `orchestrator/migrations/001_seed_builtin_tools.py`
+
+```python
+"""Seed the tools table with current hardcoded mappings."""
+
+import asyncio
+import asyncpg
+from app.config import get_settings
+
+# Copy of current hardcoded mappings from session.py
+BUILTIN_TOOLS = [
+ # Dashboard
+ {
+ "tool_id": "home_dashboard",
+ "name": "Home Dashboard",
+ "description": "Main user dashboard with Q-Score and activity",
+ "service_name": "dashboard-service",
+ "page_triggers": ["home"],
+ "action_triggers": [],
+ "qscore_signals": ["dashboard.engagement"],
+ "is_builtin": True,
+ },
+
+ # Resume builder tools
+ {
+ "tool_id": "resume_page",
+ "name": "Resume Hub",
+ "description": "Resume management hub page",
+ "service_name": "resume-builder",
+ "page_triggers": ["resume-hub", "resume-editor", "cover-letter-editor"],
+ "action_triggers": [],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "resume_delete",
+ "name": "Delete Resume",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["delete_resume"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "resume_set_primary",
+ "name": "Set Primary Resume",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["set_primary", "remove_primary"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "resume_create",
+ "name": "Create Resume",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["create_resume"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "resume_parse",
+ "name": "Parse Resume",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["parse_resume"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "resume_analyze",
+ "name": "AI Resume Analysis",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["ai_analyze"],
+ "qscore_signals": ["resume.ats_compatibility", "resume.completeness"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "resume_copilot",
+ "name": "Resume AI Copilot",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["ai_copilot", "ai_optimize_summary", "ai_optimize_experience",
+ "ai_suggest_skills", "ai_generate_summary"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "resume_export",
+ "name": "Export Resume",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["export_pdf", "export_analysis_pdf", "save_version", "update_resume_meta"],
+ "is_builtin": True,
+ },
+
+ # Cover letter tools
+ {
+ "tool_id": "cover_letter_generate",
+ "name": "Generate Cover Letter",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["generate_cover_letter", "cover_letter_copilot"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "cover_letter_manage",
+ "name": "Manage Cover Letter",
+ "service_name": "resume-builder",
+ "page_triggers": [],
+ "action_triggers": ["delete_cover_letter", "save_cover_letter_version",
+ "update_cover_letter_meta", "analyze_cover_letter", "export_cover_letter_pdf"],
+ "is_builtin": True,
+ },
+
+ # Social branding tools
+ {
+ "tool_id": "social_page",
+ "name": "Social Media Page",
+ "service_name": "social-branding",
+ "page_triggers": ["social-media"],
+ "action_triggers": [],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "social_submit_url",
+ "name": "Submit Social Profile URL",
+ "service_name": "social-branding",
+ "page_triggers": [],
+ "action_triggers": ["submit_url"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "social_sync",
+ "name": "Sync Social Profile",
+ "service_name": "social-branding",
+ "page_triggers": [],
+ "action_triggers": ["sync_profile", "remove_profile"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "social_analyze",
+ "name": "Analyze Social Profile",
+ "service_name": "social-branding",
+ "page_triggers": [],
+ "action_triggers": ["run_analysis"],
+ "qscore_signals": ["linkedin.headline_quality", "linkedin.profile_completeness"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "social_improve",
+ "name": "Improve Social Profile",
+ "service_name": "social-branding",
+ "page_triggers": [],
+ "action_triggers": ["improve_"], # prefix match
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "social_strategy",
+ "name": "Social Strategy",
+ "service_name": "social-branding",
+ "page_triggers": [],
+ "action_triggers": ["quick_wins", "generate_strategy", "generate_content_strategy"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "social_content_delete",
+ "name": "Delete Social Content",
+ "service_name": "social-branding",
+ "page_triggers": [],
+ "action_triggers": ["delete_content"],
+ "is_builtin": True,
+ },
+
+ # Matchmaking tools
+ {
+ "tool_id": "matchmaking_page",
+ "name": "Job Matching Page",
+ "service_name": "matchmaking-service",
+ "page_triggers": ["job-matching"],
+ "action_triggers": [],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "matchmaking_sync",
+ "name": "Sync Matchmaking Preferences",
+ "service_name": "matchmaking-service",
+ "page_triggers": [],
+ "action_triggers": ["sync_preferences"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "matchmaking_feed",
+ "name": "Get Job Feed",
+ "service_name": "matchmaking-service",
+ "page_triggers": [],
+ "action_triggers": ["get_feed"],
+ "qscore_signals": ["matching.feed_active"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "matchmaking_feedback",
+ "name": "Record Job Feedback",
+ "service_name": "matchmaking-service",
+ "page_triggers": [],
+ "action_triggers": ["record_feedback", "get_opportunity_detail"],
+ "is_builtin": True,
+ },
+
+ # User service tools
+ {
+ "tool_id": "user_page",
+ "name": "User Profile Page",
+ "service_name": "user-service",
+ "page_triggers": ["profile", "settings"],
+ "action_triggers": ["view_profile"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "user_update",
+ "name": "Update User",
+ "service_name": "user-service",
+ "page_triggers": [],
+ "action_triggers": ["update_preferences", "update_plan", "update_metadata"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "user_qr",
+ "name": "QR Code Management",
+ "service_name": "user-service",
+ "page_triggers": [],
+ "action_triggers": ["get_qr_code", "regenerate_qr"],
+ "is_builtin": True,
+ },
+
+ # Interview service tools
+ {
+ "tool_id": "interview_page",
+ "name": "Interview Page",
+ "service_name": "interview-service",
+ "page_triggers": ["interview"],
+ "action_triggers": [],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "interview_configure",
+ "name": "Configure Interview",
+ "service_name": "interview-service",
+ "page_triggers": [],
+ "action_triggers": ["configure_interview"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "interview_review",
+ "name": "Get Interview Review",
+ "service_name": "interview-service",
+ "page_triggers": [],
+ "action_triggers": ["get_review", "get_session_history"],
+ "qscore_signals": ["interview.overall_score"],
+ "is_builtin": True,
+ },
+
+ # Roleplay service tools
+ {
+ "tool_id": "roleplay_page",
+ "name": "Roleplay Page",
+ "service_name": "roleplay-service",
+ "page_triggers": ["roleplay"],
+ "action_triggers": [],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "roleplay_configure",
+ "name": "Configure Roleplay",
+ "service_name": "roleplay-service",
+ "page_triggers": [],
+ "action_triggers": ["configure_roleplay"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "roleplay_review",
+ "name": "Get Roleplay Review",
+ "service_name": "roleplay-service",
+ "page_triggers": [],
+ "action_triggers": ["get_roleplay_review", "get_roleplay_history"],
+ "qscore_signals": ["roleplay.communication_score"],
+ "is_builtin": True,
+ },
+
+ # Q-Score tools
+ {
+ "tool_id": "qscore_get",
+ "name": "Get Q-Score",
+ "service_name": "qscore-service",
+ "page_triggers": [],
+ "action_triggers": ["get_qscore", "get_signals", "get_registry"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "qscore_compute",
+ "name": "Compute Q-Score",
+ "service_name": "qscore-service",
+ "page_triggers": [],
+ "action_triggers": ["compute_qscore"],
+ "is_builtin": True,
+ },
+
+ # Pathways tools
+ {
+ "tool_id": "pathways_page",
+ "name": "Pathways Page",
+ "service_name": "pathways-service",
+ "page_triggers": ["pathways", "pathways-questionnaire", "pathways-generate", "pathways-weekly-plan"],
+ "action_triggers": [],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "pathways_profile",
+ "name": "Ingest Pathways Profile",
+ "service_name": "pathways-service",
+ "page_triggers": [],
+ "action_triggers": ["ingest_profile"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "pathways_questionnaire",
+ "name": "Save Questionnaire",
+ "service_name": "pathways-service",
+ "page_triggers": [],
+ "action_triggers": ["save_questionnaire"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "pathways_generate",
+ "name": "Generate Pathway",
+ "service_name": "pathways-service",
+ "page_triggers": [],
+ "action_triggers": ["generate_pathway", "activate_pathway", "get_pathway", "get_report"],
+ "qscore_signals": ["pathway.completion_pct"],
+ "is_builtin": True,
+ },
+ {
+ "tool_id": "pathways_tasks",
+ "name": "Pathway Task Management",
+ "service_name": "pathways-service",
+ "page_triggers": [],
+ "action_triggers": ["complete_task", "uncomplete_task", "get_weekly_plan"],
+ "is_builtin": True,
+ },
+]
+
+
+async def migrate():
+ settings = get_settings()
+ pool = await asyncpg.create_pool(settings.database_url)
+
+ async with pool.acquire() as conn:
+ # Create tables
+ await conn.execute("""
+ CREATE TABLE IF NOT EXISTS tools (
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ tool_id VARCHAR(255) UNIQUE NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ description TEXT,
+ service_name VARCHAR(255) NOT NULL,
+ service_url VARCHAR(500),
+ endpoint VARCHAR(255) DEFAULT '/a2a/tasks',
+ page_triggers VARCHAR(255)[],
+ action_triggers VARCHAR(255)[],
+ skill_triggers VARCHAR(255)[],
+ input_schema JSONB,
+ output_schema JSONB,
+ qscore_signals VARCHAR(255)[],
+ version VARCHAR(50) DEFAULT '1.0.0',
+ enabled BOOLEAN DEFAULT true,
+ is_builtin BOOLEAN DEFAULT false,
+ created_by VARCHAR(255),
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMP DEFAULT NOW()
+ )
+ """)
+
+ await conn.execute("""
+ CREATE INDEX IF NOT EXISTS idx_tools_page_triggers ON tools USING GIN(page_triggers)
+ """)
+ await conn.execute("""
+ CREATE INDEX IF NOT EXISTS idx_tools_action_triggers ON tools USING GIN(action_triggers)
+ """)
+ await conn.execute("""
+ CREATE INDEX IF NOT EXISTS idx_tools_service ON tools(service_name)
+ """)
+
+ # Insert builtin tools
+ for tool in BUILTIN_TOOLS:
+ await conn.execute("""
+ INSERT INTO tools (
+ tool_id, name, description, service_name,
+ page_triggers, action_triggers, skill_triggers, qscore_signals,
+ is_builtin, enabled
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
+ ON CONFLICT (tool_id) DO NOTHING
+ """,
+ tool['tool_id'],
+ tool['name'],
+ tool.get('description'),
+ tool['service_name'],
+ tool.get('page_triggers', []),
+ tool.get('action_triggers', []),
+ tool.get('skill_triggers', []),
+ tool.get('qscore_signals', []),
+ True, # is_builtin
+ True, # enabled
+ )
+
+ count = await conn.fetchval("SELECT COUNT(*) FROM tools WHERE is_builtin = true")
+ print(f"Seeded {count} builtin tools")
+
+ await pool.close()
+
+
+if __name__ == "__main__":
+ asyncio.run(migrate())
+```
+
+### 3. Modified `orchestrator/app/agent/session.py`
+
+Key changes to existing session.py (showing only the modified parts):
+
+```python
+# REMOVE these hardcoded dictionaries:
+# PAGE_TO_AGENT = {...}
+# ACTION_TO_AGENT = {...}
+
+# REPLACE with:
+from app.tools.registry import ToolRegistry
+
+class SuperAgentSession:
+ def __init__(
+ self,
+ websocket: WebSocket,
+ user_id: str,
+ registry: AgentRegistry,
+ tool_registry: ToolRegistry, # NEW parameter
+ a2a_client: A2AClient,
+ # ... rest of params
+ ):
+ # ... existing init
+ self.tool_registry = tool_registry # NEW
+
+ # REMOVE these functions:
+ # def _resolve_agent_for_page(page, registry)
+ # def _resolve_agent_for_action(action, registry)
+ # def _resolve_agent_name_for_page(page)
+ # def _resolve_agent_name_for_action(action, registry)
+
+ # REPLACE with async versions using tool registry:
+
+ async def _resolve_agent_for_page(self, page: str):
+ """Find the healthy agent responsible for a page using tool registry."""
+ tool = await self.tool_registry.get_tool_for_page(page)
+ if not tool:
+ return None
+
+ agent = self.registry.get_agent_by_name(tool.service_name)
+ if agent and agent.is_healthy:
+ return agent
+ return None
+
+ async def _resolve_agent_for_action(self, action: str):
+ """Find the healthy agent responsible for an action using tool registry."""
+ tool = await self.tool_registry.get_tool_for_action(action)
+ if not tool:
+ return None
+
+ agent = self.registry.get_agent_by_name(tool.service_name)
+ if agent and agent.is_healthy:
+ return agent
+ return None
+
+ async def _resolve_agent_name_for_page(self, page: str) -> str | None:
+ """Return the agent name for a page using tool registry."""
+ return await self.tool_registry.get_service_for_page(page)
+
+ async def _resolve_agent_name_for_action(self, action: str) -> str | None:
+ """Return the agent name for an action using tool registry."""
+ return await self.tool_registry.get_service_for_action(action)
+
+ # UPDATE on_session_start and on_user_action to be async and use new methods
+
+ async def on_session_start(self, page: str, params: dict):
+ """Route session_start to the appropriate domain agent."""
+ if self._use_redis:
+ agent_name = await self._resolve_agent_name_for_page(page) # NOW ASYNC
+ # ... rest of method
+ else:
+ agent = await self._resolve_agent_for_page(page) # NOW ASYNC
+ # ... rest of method
+
+ async def on_user_action(self, action: str, params: dict):
+ """Route action to domain agent or composite workflow."""
+ # ... composite check stays same
+
+ if self._use_redis:
+ agent_name = await self._resolve_agent_name_for_action(action) # NOW ASYNC
+ # ... rest of method
+ else:
+ agent = await self._resolve_agent_for_action(action) # NOW ASYNC
+ # ... rest of method
+```
+
+### 4. New API Endpoints: `orchestrator/app/api/v1/tools.py`
+
+```python
+"""Admin API for tool registry management."""
+
+from fastapi import APIRouter, Depends, HTTPException
+from pydantic import BaseModel
+from typing import Optional, List
+
+from app.tools.registry import ToolRegistry
+from app.auth import require_admin # You'll need to implement this
+
+router = APIRouter()
+
+
+class ToolRegistration(BaseModel):
+ tool_id: str
+ name: str
+ description: Optional[str] = None
+ service_name: str
+ service_url: Optional[str] = None
+ endpoint: str = "/a2a/tasks"
+ page_triggers: List[str] = []
+ action_triggers: List[str] = []
+ skill_triggers: List[str] = []
+ input_schema: Optional[dict] = None
+ output_schema: Optional[dict] = None
+ qscore_signals: List[str] = []
+ version: str = "1.0.0"
+
+
+class ToolResponse(BaseModel):
+ id: str
+ tool_id: str
+ name: str
+ service_name: str
+ enabled: bool
+ version: str
+
+
+@router.post("/register", response_model=ToolResponse)
+async def register_tool(
+ registration: ToolRegistration,
+ registry: ToolRegistry = Depends(get_tool_registry),
+ admin = Depends(require_admin),
+):
+ """Register a new tool dynamically.
+
+ This allows services to self-register their capabilities at runtime.
+ """
+ tool = await registry.register_tool(registration.dict())
+ return ToolResponse(
+ id=tool.id,
+ tool_id=tool.tool_id,
+ name=tool.name,
+ service_name=tool.service_name,
+ enabled=tool.enabled,
+ version=tool.version,
+ )
+
+
+@router.post("/{tool_id}/unregister")
+async def unregister_tool(
+ tool_id: str,
+ registry: ToolRegistry = Depends(get_tool_registry),
+ admin = Depends(require_admin),
+):
+ """Disable a tool (soft delete)."""
+ success = await registry.unregister_tool(tool_id)
+ if not success:
+ raise HTTPException(status_code=404, detail="Tool not found")
+ return {"success": True}
+
+
+@router.get("/available")
+async def get_available_tools(
+ page: Optional[str] = None,
+ service: Optional[str] = None,
+ registry: ToolRegistry = Depends(get_tool_registry),
+):
+ """Get available tools for a page or service.
+
+ Used by frontend to discover what tools are available on a given page.
+ """
+ if page:
+ tools = await registry.get_all_tools_for_page(page)
+ else:
+ tools = await registry.list_tools(service_name=service)
+
+ return {
+ "tools": [
+ {
+ "tool_id": t.tool_id,
+ "name": t.name,
+ "description": t.description,
+ "service_name": t.service_name,
+ "action_triggers": t.action_triggers,
+ "qscore_signals": t.qscore_signals,
+ "version": t.version,
+ }
+ for t in tools if t.enabled
+ ]
+ }
+
+
+@router.get("/{tool_id}")
+async def get_tool_details(
+ tool_id: str,
+ registry: ToolRegistry = Depends(get_tool_registry),
+):
+ """Get detailed information about a specific tool."""
+ # Implementation to fetch single tool details
+ pass
+
+
+def get_tool_registry() -> ToolRegistry:
+ """Dependency to get the tool registry instance."""
+ # This should return the singleton instance from app state
+ from app.main import app
+ return app.state.tool_registry
+```
+
+## Configuration Changes
+
+### `orchestrator/app/config.py`
+
+Add database URL for tool registry:
+
+```python
+class Settings(BaseSettings):
+ # ... existing settings
+
+ # Tool registry database (can be same as other services or separate)
+ tool_registry_database_url: str = os.getenv(
+ "TOOL_REGISTRY_DATABASE_URL",
+ os.getenv("DATABASE_URL", "postgresql://user:pass@localhost/growqr_tools")
+ )
+
+ # Cache TTL for tool registry
+ tool_registry_cache_ttl: int = int(os.getenv("TOOL_REGISTRY_CACHE_TTL", "30"))
+```
+
+### `orchestrator/app/main.py`
+
+Initialize tool registry on startup:
+
+```python
+from app.tools.registry import ToolRegistry
+
+@app.on_event("startup")
+async def startup():
+ # ... existing startup code
+
+ # Initialize tool registry
+ db_pool = await asyncpg.create_pool(settings.tool_registry_database_url)
+ tool_registry = ToolRegistry(db_pool, cache_ttl_seconds=settings.tool_registry_cache_ttl)
+ await tool_registry.initialize()
+
+ app.state.tool_registry = tool_registry
+ app.state.db_pool = db_pool
+
+@app.on_event("shutdown")
+async def shutdown():
+ # ... existing shutdown code
+
+ if hasattr(app.state, 'db_pool'):
+ await app.state.db_pool.close()
+```
+
+## Migration Steps (Zero Downtime)
+
+1. **Pre-deploy: Database Setup**
+ ```bash
+ # Run migration script to create tables and seed builtin tools
+ cd orchestrator
+ python migrations/001_seed_builtin_tools.py
+ ```
+
+2. **Deploy: New Orchestrator Version**
+ - Deploy orchestrator with tool registry changes
+ - New code reads from database but falls back to hardcoded if needed
+ - Old services continue working unchanged
+
+3. **Verify: Check Registry Loaded**
+ ```bash
+ curl http://orchestrator:8000/api/v1/tools/available?page=home
+ # Should return dashboard-service tool
+ ```
+
+4. **Post-deploy: Remove Hardcoded Fallbacks**
+ - After verification, deploy version 2 that removes hardcoded dictionaries entirely
+
+## Benefits Achieved in Phase 1
+
+1. **Routing is now data-driven**: Change page/action routing by updating database, not code
+2. **No orchestrator redeploy needed** for new tool registrations
+3. **Original team can add tools** via API without your involvement
+4. **Your service changes** don't break routing as long as service_name stays consistent
+5. **Foundation for Phase 2**: Self-registration becomes trivial
+6. **Audit trail**: Database records who created what tool and when
+
+## Next Steps After Phase 1
+
+- Phase 2: Add service self-registration (services call `/api/v1/tools/register` on startup)
+- Phase 3: Add frontend tool discovery API for dynamic UI rendering
+- Phase 4: Create lightweight SDK for contributors
diff --git a/qscore/docs/Q-Score_Implementation_Plan.md b/qscore/docs/Q-Score_Implementation_Plan.md
new file mode 100644
index 0000000..fa71f3b
--- /dev/null
+++ b/qscore/docs/Q-Score_Implementation_Plan.md
@@ -0,0 +1,818 @@
+# GrowQR Q-Score Microservice Implementation Plan
+
+Status: Draft for team confirmation in review meeting
+Owner: Rahul (Engineering)
+Prepared on: 2026-02-11
+Related docs: `growqr/Q-Score_Service.md`
+
+---
+
+## 1) Executive Summary
+
+We are building a Python FastAPI + Postgres microservice that is the core Q-Score engine.
+
+MVP behavior:
+- Accept processed/scored signals (per-rule/per-input) from other services via a pub/sub stream.
+- Compute Q-Score from those stored signals using the internal formula (CI/SV, pillar weights, pillar CI, contributions).
+- Return and store a full explainable breakdown (rule-level + pillar-level + CI/SV math).
+- Expose a small surface area to read signals and read the latest computed Q-Score.
+- Publish live Q-Score updates so the orchestrator agent receives changes instantly.
+
+Additional requirements (post-meeting):
+- Multi-tenant from day 1: every signal and score is keyed by `org_id`.
+- Formula can vary by profession/profile type (e.g., student vs professor) within an org.
+- Team members must be able to update formulas via API (in addition to JSON-on-disk).
+
+Explicitly out of scope for this delivery:
+- Tier assignment (removed for now).
+- Any upstream processing or enrichment (LinkedIn scraping, resume parsing/ATS, education validation, etc.).
+- Complex multi-broker support (we start with one broker; can swap later).
+
+Target: delivery ASAP; pub/sub may extend delivery by 1-2 days beyond Saturday if needed.
+
+---
+
+## 2) Confirmed Product/Engineering Decisions
+
+These are locked based on latest discussion:
+
+1. This service is the Q-Score calculation engine only.
+2. All rule processing happens outside this service. This service only accepts processed/scored signals.
+3. GET/read endpoint must return full scoring transparency:
+ - each rule score
+ - each pillar score and contribution
+ - CI/SV values and final math
+4. Engagement signals exist but are not required for initial (day-1) score computations.
+5. Auth is deferred; keep middleware hook to add later without endpoint logic rewrite.
+6. Pillar 11 (Recognition & Rewards) uses 3 onboarding achievements; points mapping is pending confirmation.
+7. Goals signals can be ingested and stored now; they do not impact score in current MVP.
+8. Pillar CI formula clarification:
+
+```
+Pillar_CI = weighted average of input CIs contributing to that pillar
+weight_i = proportion of pillar data points from input_i
+```
+
+Where "data points" for v1 = number of rules from that input used in that pillar.
+
+9. For Saturday, keep orchestration simple:
+ - no separate job queue system (e.g., RQ)
+ - use a Redis Stream consumer worker + a small scheduler/micro-batcher for near-real-time updates
+
+10. Signal storage must be versioned per user:
+ - we keep an append-only ledger of every ingested signal update (`signal_ledger`)
+ - we keep a per-user latest materialized view/table for fast compute (`user_signal_latest`)
+ - we store every computed Q-Score run (`qscore_runs`) to track how outputs evolve over time
+
+11. Provide a validation endpoint for producers (fire-and-forget): upstream services can call a check endpoint with `user_id`, `signal_id`, and `score` to validate that the signal is acceptable for the current formula registry.
+
+12. Pub/sub is required:
+ - orchestrator agent publishes a live stream of signals for each user
+ - Q-Score engine consumes signals and publishes a live stream of Q-Score updates
+ - agent subscribes to Q-Score updates (bi-directional communication via streams)
+
+13. Freshness target: score update latency should be < 10 seconds.
+ - intermediate updates are acceptable
+ - compute/publish is paced (micro-batched) to handle continuous signal dumps
+
+---
+
+## 3) Scope
+
+### MVP Scope (this sprint)
+
+- Signal ingest (stream-based; plus HTTP fallback endpoint)
+- Compute Q-Score endpoint (writes a qscore run)
+- Read endpoints for signals and latest Q-Score run
+- Scoring engine (signals -> rules -> inputs -> pillars -> final Q)
+- Postgres persistence (signals + qscore history)
+- Pub/sub broker (Redis Streams) + consumer/producer worker
+- Docker Compose local stack (API + Postgres + Redis + worker)
+
+### Future Scope (not blocking MVP)
+
+- Full auth middleware implementation
+- Additional signals / pillars / formula versions (Excel-driven expansion)
+- Batch recompute tuning (dynamic micro-batching, backpressure, autoscaling)
+- Broker swap (Kafka/NATS/etc.) behind a small adapter layer if needed
+
+---
+
+## 4) System Architecture
+
+## Components
+
+1. **FastAPI API service**
+ - request validation
+ - orchestration
+ - scoring invocation
+ - DB writes/reads
+
+2. **Scoring engine module (pure Python)**
+ - deterministic aggregation and formula application
+ - CI/SV calculations
+ - pillar aggregation and contributions
+ - final score output
+
+3. **Postgres**
+ - stored signals (latest)
+ - optional signal event log (append-only)
+ - qscore history
+
+4. **Redis (Streams)**
+ - input signal stream (agent -> qscore)
+ - output score update stream (qscore -> agent)
+
+5. **Worker process**
+ - consumes input signal stream
+ - writes ledger + latest state
+ - recomputes Q-Score (micro-batch)
+ - publishes score update events
+
+Notes:
+- This service does not fetch/enrich any upstream data. Upstream services are responsible for producing scored signals.
+
+---
+
+## 5) High-Level Flows
+
+### Flow A: Live Signal Publish (agent -> qscore)
+
+1. Orchestrator agent publishes signal events to the input stream.
+2. Worker consumes signal events.
+3. Worker appends each signal update into `signal_ledger` (append-only history).
+4. Worker upserts latest signal values into `user_signal_latest`.
+5. Worker marks the user as dirty for compute (e.g., updates `user_dirty.last_signal_at`).
+
+Pacing behavior (continuous stream):
+- Worker schedules computes per user using a pacer (debounce + max staleness).
+- Recency-first priority for user updates; periodic sweep ensures no long-running backlog.
+
+### Flow B: Q-Score Compute
+
+Two triggers are supported:
+
+1) Manual compute-now:
+ 1. Client/producer calls `POST /v1/qscore/compute` with `user_id`.
+ 2. API reads latest signals for user from `user_signal_latest`.
+ 3. Engine computes input CI/SV, pillar scores, pillar CI, contributions, and final Q.
+ 4. API writes a new row in `qscore_runs` with full breakdown.
+ 5. API returns score + breakdown.
+
+2) Scheduled batch compute:
+ 1. Scheduler runs every `BATCH_INTERVAL_SECONDS` (default: 300) and checks if there are dirty users.
+ 2. For each dirty user, compute Q-Score from `user_signal_latest`.
+ 3. Write `qscore_runs` and mark user clean.
+
+Additionally (live updates):
+- Worker performs micro-batched computes when new signal events arrive (debounced per user).
+- When a user's Q-Score changes, worker publishes an update event to the output stream.
+
+Freshness guarantee (configurable):
+- even under continuous events, each dirty user should get recomputed at least once per `MAX_STALENESS_MS` (default: 10000)
+
+### Flow C: Read
+
+1. Client calls `GET /v1/signals/{user_id}` to read latest signals.
+2. Client calls `GET /v1/qscore/{user_id}` to read latest Q-Score + breakdown.
+
+---
+
+## 6) API Endpoints
+
+## 6.1 Signal Ingest
+
+`POST /v1/signals/ingest`
+
+Purpose:
+- HTTP fallback for producers that cannot publish directly to the broker.
+- Server validates and then publishes into the input stream.
+
+Profession handling:
+- If `profession` is provided, the service upserts it into `user_profile`.
+- If `profession` is omitted, the service uses the existing `user_profile.profession`.
+- If neither exists, the service uses a default profession (configurable) and records it.
+
+Request (example):
+
+```json
+{
+ "org_id": "growqr",
+ "user_id": "b5f9e91f-6a95-4f2f-9f11-4f8f7f5f4c77",
+ "profession": "student",
+ "source": "social_branding_service",
+ "signals": [
+ {
+ "signal_id": "linkedin.account_connected",
+ "present": true,
+ "score": 100,
+ "raw": "CONNECTED"
+ },
+ {
+ "signal_id": "resume.ats_compatibility",
+ "present": true,
+ "score": 72,
+ "raw": {"ats_score": 72}
+ }
+ ],
+ "occurred_at": "2026-02-11T12:00:00Z"
+}
+```
+
+Response (example):
+
+```json
+{
+ "org_id": "growqr",
+ "user_id": "b5f9e91f-6a95-4f2f-9f11-4f8f7f5f4c77",
+ "formula_version": "v1",
+ "upserted": 2
+}
+```
+
+## 6.2 Compute Q-Score
+
+`POST /v1/qscore/compute`
+
+Request (example):
+
+```json
+{
+ "org_id": "growqr",
+ "user_id": "b5f9e91f-6a95-4f2f-9f11-4f8f7f5f4c77"
+}
+```
+
+Response (example):
+
+```json
+{
+ "org_id": "growqr",
+ "user_id": "b5f9e91f-6a95-4f2f-9f11-4f8f7f5f4c77",
+ "q_score": 67.42,
+ "profession": "student",
+ "calculated_at": "2026-02-11T12:01:10Z",
+ "breakdown": {
+ "inputs": {},
+ "rules": {},
+ "pillars": {},
+ "math": {}
+ }
+}
+```
+
+## 6.3 Read Latest Score (full explainability)
+
+`GET /v1/qscore/{user_id}`
+
+Query params:
+- `org_id`
+
+Returns latest `qscore_runs.breakdown` in full detail.
+
+## 6.4 Read Latest Signals
+
+`GET /v1/signals/{user_id}`
+
+Query params:
+- `org_id`
+
+Returns latest stored signals for the user (including `present`, `score`, and `raw`).
+
+## 6.5 Signal Check (producer validation)
+
+`POST /v1/signals/check`
+
+Purpose:
+- Producer-side validation so upstream can verify a signal is acceptable for the current registry before ingesting.
+
+Request (example):
+
+```json
+{
+ "org_id": "growqr",
+ "user_id": "b5f9e91f-6a95-4f2f-9f11-4f8f7f5f4c77",
+ "profession": "student",
+ "signal_id": "resume.ats_compatibility",
+ "score": 72,
+ "raw": {"ats_score": 72}
+}
+```
+
+Response (example):
+
+```json
+{
+ "valid": true,
+ "errors": [],
+ "warnings": []
+}
+```
+
+Validation rules (v1):
+- `signal_id` exists in current formula registry OR is in an allowed "unknown" namespace list (configurable)
+- `score` is numeric and within `0..100`
+- optional metadata size limits (to protect DB)
+
+## 6.6 Registry Endpoints (sanitized)
+
+`GET /v1/registry/signals`
+
+Returns the list of accepted `signal_id`s and minimal metadata needed by producers (no secret sauce formula details).
+
+Query params (recommended):
+- `org_id`
+- `profession`
+
+`POST /v1/formula/reload`
+
+Reload formula JSON from disk and swap in-memory formula if validation passes (auth to be added later).
+
+## 6.7 Formula Management (team updates)
+
+We support both:
+- JSON-on-disk for version control
+- DB-backed formula definitions for API updates
+
+Formula resolution (which formula is used for a user):
+1) Read `user_profile.profession` (set via ingest).
+2) Resolve active formula version for `(org_id, profession)`.
+3) Allow per-user override via `user_profile.formula_version_override` (future).
+4) Effective formula key: `{org_id}:{profession}:{version}`.
+
+Filesystem layout (when `FORMULA_STORE=filesystem`):
+- `FORMULA_DIR/{version}/{profession}/formula.json`
+
+DB layout (when `FORMULA_STORE=db`):
+- `formula_definitions` rows keyed by `(org_id, profession, version)`.
+
+Endpoints:
+
+`GET /v1/formulas`
+- lists available formulas (org_id + profession + version + active)
+
+`PUT /v1/formulas/{org_id}/{profession}/{version}`
+- upserts a formula JSON blob into Postgres
+
+`POST /v1/formulas/{org_id}/{profession}/activate`
+- sets the active formula version for a profession within an org
+
+`GET /v1/users/{org_id}/{user_id}/profile`
+- returns the stored profession + active formula resolution (debugging)
+
+## 6.8 Stream Contracts (pub/sub)
+
+Input stream (signals):
+- stream name (default): `qscore.signal_events`
+- event shape matches `POST /v1/signals/ingest` payload
+
+Output stream (qscore updates):
+- stream name (default): `qscore.score_updates`
+- event shape (example):
+
+```json
+{
+ "org_id": "growqr",
+ "user_id": "b5f9e91f-6a95-4f2f-9f11-4f8f7f5f4c77",
+ "profession": "student",
+ "q_score": 67.42,
+ "formula_version": "v1",
+ "formula_id": "growqr:student:v1",
+ "qscore_run_id": "...",
+ "events_considered": {
+ "ledger_seq_from": 1201,
+ "ledger_seq_to": 1215,
+ "count": 15,
+ "sample_ledger_seqs": [1201, 1202, 1203]
+ },
+ "changed": true,
+ "created_at": "2026-02-11T12:01:10Z",
+ "breakdown": {"inputs": {}, "rules": {}, "pillars": {}, "math": {}}
+}
+```
+
+Note:
+- agent subscribes to the output stream to receive score updates instantly.
+- agent can also read the latest computed value from Redis key `qscore:latest:{org_id}:{user_id}` (updated on every publish).
+- `ledger_seq_from` is typically `user_dirty.last_computed_seq + 1` and `ledger_seq_to` is `user_dirty.last_signal_seq` at compute time.
+
+---
+
+## 7) Scoring Model Design
+
+## 7.1 Input CI
+
+For each input `i`:
+
+```
+SV_i = present_rules_i / total_rules_i
+CI_i = (0.7 * VS_i) + (0.3 * SV_i)
+```
+
+VS constants (current):
+- Input 1 LinkedIn: 1.0
+- Input 2 Resume: 0.9
+- Input 3 Education: 0.9
+- Input 4 Engagement: 0.7
+- Input 5 Goals: 0.5 (stored only for now)
+- Input 6 Platform (for pillar 11 placeholder): configurable (default 1.0)
+
+## 7.2 Rule Scoring Contract
+
+Every rule returns:
+
+```json
+{
+ "present": true,
+ "included_in_pillar_average": true,
+ "score": 75.0,
+ "raw": "source value used for this rule"
+}
+```
+
+Missing data behavior (confirmed):
+- If the input data for a rule is not available, return:
+ - `present=false`
+ - `score=0`
+ - `included_in_pillar_average=false`
+- Missing rules do not penalize `pillar_score` directly, but they reduce `SV_i` and therefore `CI_i`.
+
+## 7.3 Pillar Score
+
+```
+pillar_score = average(score of rules where included_in_pillar_average=true)
+```
+
+If no rules are included in the pillar average, the pillar is inactive unless configured as always-on placeholder.
+
+## 7.4 Pillar CI (confirmed logic)
+
+```
+pillar_ci = sum(weight_i * CI_i)
+weight_i = rules_from_input_i_in_pillar / total_rules_in_pillar
+```
+
+## 7.5 Pillar Contribution
+
+```
+contribution = pillar_score * pillar_weight * pillar_ci
+```
+
+## 7.6 Final Q-Score
+
+```
+Q = sum(contributions_of_active_pillars) / sum(active_pillar_weights)
+```
+
+Notes:
+- no tier assignment in this release
+- no percentile requirement in this release
+
+---
+
+## 8) Pillars and Rules Handling
+
+Pillars locked for Saturday release (from `growqr/Q-Score_Service.md`):
+- Pillar 01 Presence & Profile (20.0%)
+- Pillar 02 Learning & Credentials (19.3%)
+- Pillar 05 Engagement & Consistency (3.3%)
+- Pillar 06 Communication Signals (4.0%)
+- Pillar 11 Recognition & Rewards (0.9%)
+
+Initial (day-1) score computations are expected to activate pillars 01, 02, 06, 11 if those signals are ingested.
+
+Engagement pillar (05) is not required for day-1 and becomes active only when engagement signals are later ingested.
+
+Important current behavior choices:
+- Goals input is persisted but not used in score math right now.
+- Engagement signal IDs are part of the formula registry, but are not expected to be present on day-1.
+- Platform pillar (11) uses 3 onboarding achievements; scoring/points mapping is an open item to confirm.
+
+Config examples:
+- `P11_ACHIEVEMENT_COUNT=3`
+- `P11_ACHIEVEMENT_SCORE_DEFAULT=100`
+
+---
+
+## 9) Persistence Design
+
+Migration approach:
+- Use Alembic migrations for all schema changes (job-service currently uses `metadata.create_all`, but Q-Score should be migration-driven).
+
+## 9.1 `signal_ledger` (append-only, versioned history)
+- `seq` bigserial pk
+- `id` uuid unique
+- `org_id` text not null
+- `user_id` uuid not null
+- `profession` text null
+- `signal_id` text not null
+- `source` text null
+- `score` numeric(5,2) not null
+- `raw` jsonb null
+- `occurred_at` timestamptz null
+- `formula_version` text not null
+- `created_at` timestamptz not null
+
+Indexes:
+- `(org_id, user_id, created_at desc)`
+- `(org_id, user_id, signal_id, created_at desc)`
+
+## 9.2 `user_signal_latest` (materialized latest state)
+- `org_id` text not null
+- `user_id` uuid not null
+- `signal_id` text not null
+- `source` text null
+- `score` numeric(5,2) not null
+- `raw` jsonb null
+- `last_occurred_at` timestamptz null
+- `last_seen_at` timestamptz not null
+- `formula_version` text not null
+
+Primary key / unique:
+- `(org_id, user_id, signal_id)`
+
+## 9.3 `user_profile` (formula resolution)
+- `org_id` text not null
+- `user_id` uuid not null
+- `profession` text not null
+- `formula_version_override` text null
+- `updated_at` timestamptz not null
+
+Primary key / unique:
+- `(org_id, user_id)`
+
+## 9.4 `formula_definitions` (team-managed formulas)
+- `org_id` text not null
+- `profession` text not null
+- `version` text not null
+- `active` boolean not null
+- `formula_json` jsonb not null
+- `created_at` timestamptz not null
+- `updated_at` timestamptz not null
+
+Primary key / unique:
+- `(org_id, profession, version)`
+
+## 9.5 `user_dirty` (compute scheduling helper)
+- `org_id` text not null
+- `user_id` uuid not null
+- `last_signal_seq` bigint not null
+- `last_computed_seq` bigint null
+- `next_compute_at` timestamptz null
+- `last_published_at` timestamptz null
+
+Primary key / unique:
+- `(org_id, user_id)`
+
+## 9.6 `qscore_runs` (append-only, versioned outputs)
+- `id` uuid pk
+- `org_id` text not null
+- `user_id` uuid not null
+- `profession` text not null
+- `q_score` numeric(5,2) not null
+- `breakdown` jsonb not null
+- `formula_version` text not null
+- `formula_id` text not null
+- `ledger_seq_from` bigint null
+- `ledger_seq_to` bigint null
+- `created_at` timestamptz not null
+
+Indexes:
+- `qscore_runs(org_id, user_id, created_at desc)`
+- `user_signal_latest(org_id, user_id)`
+- `signal_ledger(org_id, user_id, created_at desc)`
+
+---
+
+## 10) Batch Recompute
+
+Compute orchestration (MVP):
+
+1) Live pacer (primary):
+- worker updates `user_dirty.last_signal_seq` on every ingested ledger event
+- worker sets `user_dirty.next_compute_at` using debounce logic
+- pacer loop selects users whose `next_compute_at <= now` (recency-first)
+- pacer loop must also ensure progress on older dirty users under sustained load (avoid starvation)
+- compute uses `user_signal_latest`
+- write `qscore_runs` + publish to `qscore.score_updates`
+- update `user_dirty.last_computed_seq` + `last_published_at`
+
+2) Periodic sweep (backlog safety):
+- every `BATCH_INTERVAL_SECONDS` (default: 300), select users where `last_signal_seq > last_computed_seq`
+- compute and publish
+
+Freshness goal:
+- cap staleness with `MAX_STALENESS_MS` (default: 10000)
+
+Post-Saturday enhancements:
+- selects users whose signals changed
+- computes Q-Score in bulk
+- writes new `qscore_runs`
+
+Implementation note (Saturday):
+- simplest is a second process/container that runs a loop (sleep -> check dirty -> compute) using the same codebase.
+- we can also run it as a background task in the API process, but a separate worker is cleaner for production.
+
+---
+
+## 11) Codebase Layout
+
+Proposed project path: `growqr/qscore-service/`
+
+Reference scaffold (UV + FastAPI, job-service-like layout): `growqr/plans/qscore-service-uv-scaffold.md`
+
+```
+app/
+ main.py
+ api/
+ signals.py
+ qscore.py
+ registry.py
+ formulas.py
+ health.py
+ core/
+ config.py
+ logging.py
+ db/
+ session.py
+ models.py
+ repositories/
+ scoring/
+ engine/
+ loader.py
+ evaluator.py
+ breakdown.py
+ formula/
+ v1/
+ formula.json
+ worker/
+ stream_consumer.py
+ pacer.py
+ sweep.py
+alembic/
+docker-compose.yml
+Dockerfile
+README.md
+```
+
+---
+
+## 12) Configuration (env vars)
+
+Required:
+- `DATABASE_URL`
+
+Pub/Sub:
+- `REDIS_URL`
+- `SIGNAL_STREAM=qscore.signal_events`
+- `QSCORE_UPDATE_STREAM=qscore.score_updates`
+- `SIGNAL_CONSUMER_GROUP=qscore_engine`
+- `SIGNAL_CONSUMER_NAME` (unique per worker instance)
+
+Scoring/behavior:
+- `FORMULA_VERSION=v1`
+- `FORMULA_STORE=filesystem|db` (default: filesystem for local)
+- `FORMULA_DIR=./scoring/formula` (used when FORMULA_STORE=filesystem)
+- `BATCH_INTERVAL_SECONDS=300`
+- `LIVE_DEBOUNCE_MS=750`
+- `MAX_STALENESS_MS=10000`
+- `MIN_PUBLISH_INTERVAL_MS=1500`
+- `SCORE_CHANGE_EPSILON=0.01`
+- `RAW_METADATA_MAX_BYTES=65536`
+- `QSCORE_LATEST_TTL_SECONDS=86400`
+- `P11_ACHIEVEMENT_COUNT=3`
+- `P11_ACHIEVEMENT_SCORE_DEFAULT=100`
+- optional VS overrides (`VS_INPUT_1`, etc.)
+
+Ops:
+- `LOG_LEVEL`
+- `ENV`
+
+---
+
+## 13) Non-Functional Requirements
+
+- API endpoints should be fast (target: < 300ms local for ingest/reads).
+- Q-Score compute should remain under 5 seconds for a single user.
+- No external network calls during Q-Score calculation (DB-only).
+- Deterministic scoring logic for same stored inputs.
+- Full explainability payload stored and retrievable.
+
+---
+
+## 14) Test Strategy
+
+Unit tests:
+- CI/SV formulas
+- pillar CI weighted-average formula
+- rule scoring edge cases per input
+- final score active-weight denominator behavior
+- formula.json schema validation and hot reload swap rules
+- signal check endpoint validation rules
+
+Integration tests:
+- ingest signals -> compute qscore -> read latest
+- ingest partial signals -> compute qscore (missing rules excluded from pillar avg; still impacts CI via SV)
+- scheduler processes dirty users and updates `qscore_runs`
+- stream consumer ingests signals and publishes score updates
+- per-profession formula selection: same signals yield different Q when profession differs
+- org_id isolation: signals from org A do not affect org B
+
+Contract tests:
+- validate signal ingest payload shape and `signal_id` naming conventions
+
+Performance checks:
+- ingest/read endpoints stay fast; compute remains under target runtime
+
+---
+
+## 15) Delivery Plan (Wed to Sat)
+
+## Wednesday
+- finalize spec mapping in code constants
+- scaffold service, DB models, migrations, compose
+- implement baseline scoring engine and response schema
+- implement signals ingest contract + persistence
+
+## Thursday
+- implement `/v1/qscore/compute`
+- implement `/v1/qscore/{user_id}` read
+- implement `/v1/signals/check` and `/v1/registry/signals`
+- add Redis streams to docker-compose and implement stream publish/consume
+
+## Friday
+- complete full rule-level breakdown output
+- implement `/v1/signals/{user_id}` read
+- implement batch scheduler loop (every 5 minutes, configurable)
+- publish score update events on recompute
+- write tests and fix gaps
+
+## Saturday (buffer + integration)
+- integration fixes with upstream callers
+- perf pass and hardening
+- docs and handoff
+
+---
+
+## 16) Meeting Walkthrough Script (for team confirmation)
+
+Use this sequence in the call:
+
+1. **Goal**: one explainable Q-Score service, ready by Saturday.
+2. **Scope**: live signal stream ingest + compute Q-Score + publish live score updates + read endpoints.
+3. **Decisions locked**:
+ - no tiers now
+ - this service only computes Q (no rule processing)
+ - full breakdown response required
+ - upstream services produce scored signals; this service only computes Q
+4. **Math**: explain CI per input, weighted pillar CI, final active-weight normalization.
+5. **Data flow**: agent publishes signal events to the input stream; engine consumes and publishes Q-Score update events.
+6. **Future-safe design**: formula versioning + ledger history + scalable micro-batching.
+7. **Timeline**: Wed/Thu/Fri/Sat milestones.
+8. **Sign-off checklist** (below).
+
+---
+
+## 17) Sign-off Checklist
+
+Please confirm in meeting:
+
+- [ ] Endpoint contracts are approved.
+- [ ] Rule and pillar mapping in `Q-Score_Service.md` is final for this sprint.
+- [ ] Pillar 11 placeholder scoring is acceptable for MVP.
+- [ ] Pillar 11 achievements/points mapping confirmed (open item for tonight).
+- [ ] Goals stored-only behavior is approved.
+- [ ] No-tier response format is approved.
+- [ ] Signal ingest contract is approved (signal_id naming + score semantics).
+- [ ] Signal check contract is approved (validation rules + unknown-signal behavior).
+- [ ] Registry exposure scope approved (sanitized signals list vs full formula exposure).
+- [ ] Multi-tenancy decision: include `org_id` now or defer.
+
+---
+
+## 18) Risks and Mitigations
+
+1. **Spec ambiguity in pillar/rule mapping**
+ Mitigation: freeze a code-side config map and share before implementation lock.
+
+2. **Upstream signal contract churn**
+ Mitigation: define stable `signal_id` registry and allow unknown signals to be stored but ignored by formula v1.
+
+3. **Formula evolution complexity**
+ Mitigation: version the formula (`FORMULA_VERSION`) and make formula definitions config-driven.
+
+---
+
+## 19) Final Delivery Artifacts
+
+By handoff, we will provide:
+- running service via docker compose
+- API endpoints documented
+- DB migrations
+- rule/pillar scoring engine
+- explainable read response
+- operational README for local + staging setup
+
+---
+
+This document is intended to be the single source of implementation alignment for the current sprint.
diff --git a/qscore/docs/Q-Score_Meeting_Brief.md b/qscore/docs/Q-Score_Meeting_Brief.md
new file mode 100644
index 0000000..7442ce5
--- /dev/null
+++ b/qscore/docs/Q-Score_Meeting_Brief.md
@@ -0,0 +1,179 @@
+# GrowQR Q-Score Engine - Meeting Brief (Top-Down)
+
+Prepared for: Team alignment meeting
+
+## 1) What We Are Building (Conceptual)
+
+The Q-Score service is a dedicated "scoring engine" with live pub/sub feeds.
+
+- Other services (agents) compute individual signals (rule outputs) from raw data.
+ - Example producers: social branding/LinkedIn agent, resume analyzer, education verifier, engagement logger, etc.
+- The Q-Score engine does NOT scrape, parse, or analyze raw inputs.
+- The Q-Score engine owns the formula (the "secret sauce") that converts signals into:
+ - pillar scores and contributions
+ - a final Q-Score
+ - a fully explainable breakdown that can be shown in the UI
+
+Live communication requirement:
+- The orchestrator agent publishes a continuous stream of signals.
+- The Q-Score engine publishes a continuous stream of score updates.
+- The agent subscribes to score updates so it can react instantly.
+
+Practical meaning:
+- Every microservice can remain "agent-owned" (each owns its own processing).
+- Q-Score remains the shared engine that only aggregates and scores.
+
+Agent "latest value" access without APIs:
+- In addition to consuming the update stream, the engine writes `qscore:latest:{org_id}:{user_id}` in Redis.
+- Agent can read that key to recover the last known score after restart.
+
+In short:
+"Producers compute signals. Q-Score engine aggregates and scores."
+
+## 2) How We Implement It (Service Responsibilities)
+
+The service has three core responsibilities:
+
+1) Accept signals from producers and store them (with history).
+2) Resolve the correct formula for the user (org + profession).
+3) Compute Q-Score using that formula.
+4) Publish score updates when the computed score changes.
+5) Serve explainable outputs (rules + pillars + math) to the frontend/clients.
+
+We keep the implementation modular so we can scale from today's ~44 rules to hundreds of signals and multiple formula versions.
+
+## 3) How Rules, Pillars, and the Formula Work
+
+### 3.1 Signals and Rules
+
+- A "rule" in v1 is effectively a named slot that expects a processed signal.
+- Each signal arrives already normalized to a `score` in `0..100`.
+- Producers send only what they have; missing signals are interpreted as missing at compute time.
+
+### 3.2 Inputs and CI (Confidence/Completeness)
+
+We group rules into inputs (LinkedIn, Resume, Education, Engagement, Goals, Platform). Each input has:
+
+- VS (verification score): fixed constant per input (from the current spec)
+- SV (signal volume): how complete the input is based on which rules have signals
+
+CI per input:
+
+`CI = (0.7 * VS) + (0.3 * SV)`
+
+Important behavior (agreed):
+
+- If a signal is missing, it does NOT reduce the pillar average directly.
+- Missing signals DO reduce SV, which reduces CI (so completeness still matters).
+
+### 3.3 Pillars
+
+- A pillar is a weighted group of rules.
+- Pillar score: average of rule scores that are present (missing rules are excluded from the average).
+
+Pillar CI (agreed): weighted average of input CIs contributing to the pillar.
+
+- weights are based on "data points" = number of rules from each input inside that pillar.
+
+### 3.4 Final Q-Score
+
+- Each pillar contributes:
+ - `contribution = pillar_score * pillar_weight * pillar_ci`
+- Final Q-Score is normalized by active pillar weights:
+ - `Q = sum(contributions) / sum(active_weights)`
+
+## 4) The API Surface (How Teams Use the Engine)
+
+Producers (upstream services):
+
+1) Discover accepted signal IDs
+- `GET /v1/registry/signals`
+ - returns a sanitized list of accepted `signal_id`s + basic metadata
+
+Multi-tenant + profession aware:
+- Requests/streams are keyed by `org_id`.
+- Each user has a `profession`, which selects the active formula.
+
+2) Validate a signal payload (fire-and-forget safety)
+- `POST /v1/signals/check`
+ - input: `{ user_id, signal_id, score, raw? }`
+ - output: `{ valid, errors[], warnings[] }`
+
+3) Ingest signals
+- `POST /v1/signals/ingest`
+ - input: `{ user_id, source, occurred_at?, signals:[{signal_id, score, raw?}] }`
+
+Streaming (preferred integration):
+- Agent publishes signal events to the input stream (same shape as ingest).
+- Agent subscribes to the output stream to receive Q-Score updates instantly.
+
+Output updates include the full explainability breakdown so the agent/UI can render without extra RPC.
+
+Consumers (frontend / read clients):
+
+4) Compute now (manual trigger)
+- `POST /v1/qscore/compute` with `{ user_id }`
+
+5) Read latest score (full explainability)
+- `GET /v1/qscore/{user_id}`
+
+6) Read latest signals (debug + transparency)
+- `GET /v1/signals/{user_id}`
+
+## 5) Dataflow and Storage (Ledger + Latest + Outputs)
+
+We store data in a way that preserves history AND keeps compute fast.
+
+1) Append-only ledger (history)
+- Every signal update is written to `signal_ledger`.
+- This provides a timeline of how the user evolved.
+
+2) Latest materialized state (fast compute)
+- For each `(user_id, signal_id)` we keep the latest entry in `user_signal_latest`.
+- Q-score compute reads from `user_signal_latest` (not from the full ledger).
+
+3) Q-score outputs are versioned
+- Every compute produces a new row in `qscore_runs` (append-only).
+- This lets us track how computed outputs evolve over time.
+
+4) Scheduler orchestration (batch)
+- A small scheduler runs every `BATCH_INTERVAL_SECONDS` (default 300).
+- It recomputes only users whose signals changed since the last compute.
+- This is the path to scalable batch processing (intraday/hourly) without real-time pressure.
+
+5) Live update loop (pub/sub)
+- The engine consumes signal events continuously.
+- The engine recomputes quickly (micro-batched / debounced).
+- When the score changes, the engine publishes a score update event.
+
+## 6) Formula Storage and Hot Reload
+
+- Formula definitions live in a committed JSON file (version controlled): `formula.json`.
+- We can support v1/v2 side-by-side.
+- We support a reload mechanism:
+ - `POST /v1/formula/reload` reloads JSON from disk and swaps it only if validation passes.
+
+## 7) Saturday Scope (What Is "Done")
+
+For Saturday, we aim to deliver:
+
+- A working engine-only service (no upstream processing logic)
+- v1 formula JSON for the current rules and pillars (from `Q-Score_Service.md`)
+- The ingest/check/registry/compute/read endpoints
+- Ledger + latest + qscore_runs persistence
+- Scheduler running every 5 minutes (configurable) + live micro-batched updates
+- Explainability payload that is UI-ready
+
+## 8) Clarifications to Close in Meeting
+
+These are the only remaining items that affect integration and long-term scaling:
+
+1) Canonical `signal_id` naming convention (and who owns the list going forward)
+2) What raw metadata we store in the ledger (and size/PII limits)
+3) Registry exposure scope:
+ - sanitized signals list only (recommended)
+ - or full formula exposure
+4) Multi-tenancy decision:
+ - include `org_id` now (default "growqr")
+ - or defer until the first B2B client
+5) Pillar 11 achievements: exact mapping of the 3 achievements to scores/points
diff --git a/qscore/docs/Q-Score_Service.md b/qscore/docs/Q-Score_Service.md
new file mode 100644
index 0000000..acb7fd0
--- /dev/null
+++ b/qscore/docs/Q-Score_Service.md
@@ -0,0 +1,75 @@
+**Q-SCORE SERVICE \- DEVELOPER HANDOFF SPECIFICATION**
+
+FEBRUARY 28TH LAUNCH | Minimal Viable Product | From: Katie | To: Rahul (Developer)
+
+1\. THE 5 KPI (Current Release Only)
+
+| Input \# | KPI Name | Data Source | VS Score | What to Extract |
+| :---- | :---- | :---- | :---- | :---- |
+| **1** | LinkedIn Profile | LinkedIn API (OAuth) | 1.0 | Connections, skills, endorsements, experience, headline, summary, photo |
+| **2** | Resume/CV Upload | File Upload \+ GPT-4 | 0.9 | ATS score, keywords, projects, grammar, achievements, years exp |
+| **3** | Education Docs | Document Upload | 0.9 | Institution name, degree, GPA, major, graduation year, verification |
+| **4** | Engagement Activity | Backend Tracking | 0.7 | Login frequency, streaks, session time, features used, trends |
+| **5** | Goals & Self-Assessment | User Form | 0.5 | Career goals, timeline, urgency, work preferences, target role |
+
+**2\. RULES & CALCULATIONS (Grouped by Input Source)**
+
+| KPI 1: LINKEDIN (11 rules) • Account connected: Binary (0 or 100\) • Profile photo: Binary (0 or 100\) • Headline quality: Length \+ keywords (0-100) • Summary complete: % filled (0-100) • Experience detail: Entries × detail (0-100) • Skills listed: 0=0, 5=50, 10+=100 • Endorsements: 0=0, 10=50, 50+=100 • Recommendations: 0=0, 3=50, 10+=100 • Connections: 0-50=20, 51-200=50, 201-500=75, 500+=100 • Post engagement (90d): (Likes+comments+shares)/posts • Education listed: Binary (0 or 100\) KPI 2: RESUME (15 rules) • Resume uploaded: Binary (0 or 100\) • ATS compatibility: GPT-4 scan (0-100) • Keyword relevance: Match to role (0-100) • Quantified achievements: Count metrics (0-100) • Grammar & clarity: AI analysis (0-100) • Format & structure: Sections/hierarchy (0-100) • Contact info: Email+phone+LinkedIn (0-100) • Page count: 1-2 pages=100, 3+=50 • Technical keywords: Count (0-100) • Project count: 0=0, 2=50, 3=75, 5+=100 • Project complexity: Tech stack × impact (0-100) • Years experience: 0=0, 1=40, 2=70, 3+=100 • Leadership indicators: Led/managed keywords • Impact statements: Increased/reduced verbs • Education section: Degree+institution+year KPI 3: EDUCATION (4 rules) • Documents uploaded: Binary (0 or 100\) • Institution tier: IIT/IIM=100, NIT=80, Tier2=60, Tier3=40 • Degree relevance: Match to career path (0-100) • GPA/percentage: Normalized (0-100) | KPI 4: ENGAGEMENT (8 rules)• Login frequency: Logins per week (0-7 scale)• Session duration avg: Minutes per session• Features used: Count of different features• Current streak: Consecutive days active• Longest streak: Historical max streak• Streak recovery: Ability to resume streaks• 30-day trend: Activity increase/decrease %• 90-day trend: Long-term activity patternKPI 5: GOALS (6 rules)• Goals set: Binary \+ count• Goal clarity: Specific=100, Vague=50• Timeline urgency: Immediate=100, Long-term=50• Work preferences: Remote/hybrid/officeINPUT6: |
+| :---- | :---- |
+
+**3\. KPI WEIGHTAGES (11 Pillars \- Must Total 100%)**
+
+| Pillar | | Primary Inputs Used | Example Calculation |
+| :---- | :---- | :---- | :---- |
+| **01\. Presence & Profile** | | KPI 1, 2 | LinkedIn(11 rules) \+ Resume(15) |
+| **02\. Learning & Credentials\*** | | KPI 3 | Education(4) |
+| | | | |
+| | | | |
+| **05\. Engagement & Consistency** | | KPI 4 | All 8 engagement rules → Avg → Pillar Score |
+| **06\. Communication Signals** | | KPI 1, 2 | LinkedIn summary \+ Resume grammar → Avg |
+| | | | |
+| | | | |
+| | | | |
+| | | | |
+| **11\. Recognition & Rewards** | | Platform (Input 6\) | Badges \+ Points → Simple scoring \[BASIC\] |
+
+\*the educations needs to be validated
+
+| Input \# | KPI Name | Student Weightage& Q’s it gives | Prof-Technical Weightage & Q’s it gives | Prof-Creative Weightage & Q’s it gives | Prof-Sales/BD Weightage & Q’s it gives | Prof-Leadership Weightage & Q’s it gives | Prof-Marketing Weightage & Q’s it gives | Prof-Entrepreneur Weightage & Q’s it gives |
+| :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- | :---- |
+| **1** | LinkedIn Profile | 2.84, SQ, CQm, NQ, CuQ, | 2.15, SQ, CQm, NQ, CuQ, RQx | 2.58, SQ, CQm, NQ, CuQ | 3.49, SQ, CQm, NQ, CuQ, RQx | 3.34, SQ, CQm, NQ, CuQ, RQx | 2.96, SQ, CQm, NQ, CuQ | 2.05, SQ, CQm, NQ, CuQ |
+| **2** | Resume/CV Upload | 3.78, XQ, CQm, VQ | 3.01, XQ, CQm, VQ | 3.01, XQ, CQm, VQ | 3.1, XQ, CQm, VQ, RQx | 2.92, XQ, CQm, VQ, RQx | 2.96, XQ, CQm, VQ | 2.05, XQ, CQm, VQ |
+| **3** | Education Docs | 3.78 | 2.58, DQm | 2.58 | 1.94, RQx | 2.5, RQx | 2.11 | 1.37 |
+| **4** | Engagement Activity | 4.25, XQ, GQ, DQ | 3.44, XQ, GQ, DQ | 3.44, XQ, GQ, DQ | 3.1, XQ, GQ, DQ | 2.92, XQ, GQ, DQ | 3.37, XQ, GQ, DQ | 2.4, XQ, GQ, DQ |
+| **5** | Goals & Self-Assessment | 3.5, GQ, VQ, DQ | 3.25, GQ, VQ, DQ | 3.5, GQ, VQ, DQ | 6, GQ, VQ, DQ | 4.25, GQ, VQ, DQ | 4, GQ, VQ, DQ | 7.5, GQ, VQ, DQ |
+| **6\.** | Cover Letter | 1.89, CQm,VQ | 1.29, CQm,VQ | 1.72, CQm,VQ | 1.94, CQm,VQ, InQ | 1.67, CQm,VQ, InQ | 1.69, CQm,VQ | 1.03, CQm,VQ |
+
+**SQ- Social Quotient, XQ- Execution Quotient, CQm- Communication Quotient, VQ- Vision Quotient, DQ- Drive Quotient,**
+**GQ- Growth Quotient , RQx- Reputation Quotient ,DQM- Domain Quotient**
+
+**4\. CORE ALGORITHM (Step-by-Step Implementation)**
+
+| STEP 1: Calculate CIFormula:CI \= (0.7 × VS) \+ (0.3 × SV)Where:VS \= Verification Score Input 1 (LinkedIn) \= 1.0 Input 2 (Resume) \= 0.9 Input 3 (Education) \= 0.9 Input 4 (Engagement) \= 0.7 Input 5 (Goals) \= 0.5SV \= Signal Volume Count of rules with data Normalize to 0-1 scaleExample:LinkedIn: VS=1.0, SV=0.9CI \= (0.7×1.0)+(0.3×0.9)CI \= 0.97 | STEP 2: Pillar Scores Formula: Pillar \= Score × Weight × CI Process: 1\. For each pillar: Get all rules for that pillar Calculate avg score 2\. Apply formula: Contribution \= Score × Weight × CI Example (Pillar 01): LinkedIn score: 75/100 Weight: 20% \= 0.20 CI: 0.97 Contribution: 75 × 0.20 × 0.97 \= 14.55 Do this for all 11 pillars | STEP 3: Final Q-ScoreFormula:Q \= Σ(Pillars) / Σ(Weights)Process:1\. Sum all pillar contributions2\. Sum active weights (Exclude Pillars 03, 08, 09 if not enabled / no data)3\. Divide: Q-Score \= Total / Active WeightsExample:Total contributions: 50.20Active weights: 0.752(Excludes Pillar 03, 08, 09\)Q-Score:50.20 / 0.752 \= 66.76Output:• Q-Score: 67.85/100• Tier: Job Ready• Percentile: Calculate rank |
+| :---- | :---- | :---- |
+
+**5\. SIGNALS MEASURED (What Each Input Captures)**
+
+| Input | Signal Type | What It Tells Us |
+| :---- | :---- | :---- |
+| **1\. LinkedIn** | Professional Network | |
+| **2\. Resume** | Skills & Experience | |
+| **3\. Education** | Academic Foundation | |
+| **4\. Engagement** | Commitment & Drive | |
+| **5\. Goals** | Vision & Planning | |
+
+**6\. ONBOARDING INTEGRATION (API Contract)**
+
+| | Processing Logic:1\. Receive onboarding data2\. Validate all 5 inputs present3\. Run all \~44 rules4\. Calculate 11 pillar scores5\. Apply weights & CI6\. Generate Q-Score (0-100)7\. Determine tier & percentile8\. Store in database9\. Return responseProcessing Time: \< 5 seconds |
+| :---- | :---- |
+
+**7\. MINIMAL REQUIREMENTS FOR FEB 28TH LAUNCH**
+
+| MUST HAVE ✓✓ 5 input parameters working✓ \~44 core rules implemented✓ 11 pillar calculations✓ CI formula working✓ Q-Score calculation (0-100)✓ Tier assignment (5 tiers)✓ Onboarding endpoint✓ Read endpoint✓ Database persistence✓ Basic error handling✓ Returns score in | SHOULD HAVE \~ \~ Update endpoint (for future) \~ Admin interface skeleton \~ Percentile calculation \~ Score breakdown in response \~ Logging & monitoring \~ Basic validation \~ API documentation \~ Scalable architecture |
+| :---- | :---- |
+
+CRITICAL: Focus on the \~44 rules from 5 inputs. Get the calculation engine working. The onboarding endpoint must return accurate Q-Score. Everything else is Phase 2\.
\ No newline at end of file
diff --git a/qscore/docs/linkedin_response.txt b/qscore/docs/linkedin_response.txt
new file mode 100644
index 0000000..dffd4be
--- /dev/null
+++ b/qscore/docs/linkedin_response.txt
@@ -0,0 +1,789 @@
+{
+"_meta": {
+"document": "GrowQR Social Branding API — LinkedIn Profile Fetch",
+"version": "1.0",
+"generated_from": "Live database record (2026-02-11T07:47:30Z)",
+"base_url": "https:///api/v1/profiles",
+"authentication": "Bearer in Authorization header"
+},
+"endpoint": {
+"method": "POST",
+"path": "/api/v1/profiles/fetch-by-url",
+"description": "Fetches full LinkedIn profile data by scraping the provided URL via two external APIs (Bright Data + Scrapetable), merges the results, stores in database, and returns the enriched profile.",
+"headers": {
+"Authorization": "Bearer ",
+"Content-Type": "application/json"
+}
+},
+"request": {
+"linkedin_url": "https://www.linkedin.com/in/rahul2608/"
+},
+"data_extraction_pipeline": {
+"_note": "This section documents HOW each field in the response is sourced and transformed. Understanding this pipeline confirms the response structure is correct.",
+"step_1_parallel_fetch": {
+"description": "Two external APIs are called concurrently via asyncio.gather()",
+"source_a": {
+"name": "Bright Data Web Scraper API",
+"url": "https://api.brightdata.com/datasets/v3/scrape",
+"provides": [
+"experience",
+"education",
+"skills",
+"certifications",
+"languages",
+"courses",
+"projects",
+"organizations",
+"honors_awards",
+"recommendations",
+"activity",
+"current_company",
+"banner_image_url",
+"industry",
+"headline",
+"summary",
+"first_name",
+"last_name",
+"location",
+"profile_picture_url",
+"followers_count",
+"connections_count"
+],
+"field_mapping": {
+"raw → normalized": {
+"name → first_name/last_name": "Split on first space, or use first_name/last_name directly",
+"position|headline → headline": "Falls back to 'headline' if 'position' missing",
+"about → summary": "Direct map",
+"city|location → location": "Prefers 'city' field",
+"avatar|profile_picture_url → profile_picture_url": "Prefers 'avatar'",
+"banner_image|background_image → banner_image_url": "Prefers 'banner_image'",
+"url|linkedin_url → public_profile_url": "Direct map",
+"followers|followers_count → followers_count": "Prefers 'followers'",
+"connections|connections_count → connections_count": "Prefers 'connections'",
+"current_company.industry → industry": "Extracted from nested company object",
+"current_company.link|url|linkedin_url → current_company.url": "Prefers 'link'",
+"current_company.logo|logo_url → current_company.logo_url": "Prefers 'logo'",
+"experience[].company_linkedin_url → experience[].company_url": "Renamed field",
+"education[].title|school → education[].school": "Prefers 'title'",
+"education[].start_year|start_date → education[].start_date": "Prefers 'start_year'",
+"certifications[].title|name → certifications[].name": "Prefers 'title'",
+"certifications[].subtitle|authority → certifications[].authority": "Prefers 'subtitle'",
+"certifications[].meta → certifications[].start_date": "Parsed from 'Issued MMM YYYY'",
+"skills[]: string|{name|skill} → skills[]: string": "Extracts name from object if needed",
+"languages[].title|name → languages[].name": "Prefers 'title'",
+"languages[].subtitle|proficiency → languages[].proficiency": "Prefers 'subtitle'",
+"courses[].title → courses[].name": "Renamed",
+"courses[].subtitle → courses[].number": "Renamed",
+"organizations[].title → organizations[].name": "Renamed",
+"organizations[].membership_type → organizations[].position": "Renamed",
+"honors_and_awards[].publication → honors_awards[].issuer": "Renamed",
+"activity[].link → activity[].url": "Renamed",
+"activity[].interaction → activity[].type": "Renamed",
+"activity[].reactions → activity[].likes": "Renamed",
+"recommendations[]: string → {text, recommender_name}": "Parsed from 'Name \"text\"' format"
+}
+}
+},
+"source_b": {
+"name": "Scrapetable API",
+"url": "https://v3.scrapetable.com/linkedin/people",
+"provides": [
+"experience",
+"education",
+"skills",
+"first_name",
+"last_name",
+"headline",
+"summary",
+"location",
+"profile_picture_url",
+"linkedin_id",
+"followers_count",
+"connections_count"
+],
+"field_mapping": {
+"raw → normalized": {
+"person.firstName → first_name": "Direct map",
+"person.lastName → last_name": "Direct map",
+"person.headline → headline": "Direct map",
+"person.summary → summary": "Direct map",
+"person.geoFull → location": "Full geo string",
+"person.profilePicture → profile_picture_url": "CDN-hosted image URL",
+"person.profileUrl → public_profile_url": "Direct map",
+"person.linkedinId → linkedin_id": "Direct map",
+"person.followers → followers_count": "Direct map",
+"person.connections → connections_count": "Direct map",
+"person.skills → skills": "Already a string array, used directly",
+"person.positions[].companyName → experience[].company": "Renamed",
+"person.positions[].startYear + startMonth → experience[].start_date": "Formatted as MM/YYYY",
+"person.positions[].endYear + endMonth → experience[].end_date": "Formatted as MM/YYYY or 'Present'",
+"person.positions[].companyId → experience[].company_url": "Constructed as linkedin.com/company/{id}",
+"person.education[].schoolName → education[].school": "Renamed",
+"person.education[].startYear → education[].start_date": "Year string only",
+"person.education[].endYear → education[].end_date": "Year string only"
+}
+}
+}
+},
+"step_2_merge_strategy": {
+"description": "Fields are merged with priority rules — Scrapetable for structured data quality, Bright Data for breadth.",
+"priority_rules": {
+"experience": "Scrapetable first, Bright Data fallback",
+"education": "Scrapetable first, Bright Data fallback",
+"skills": "Scrapetable first, Bright Data fallback",
+"headline": "Scrapetable first, Bright Data fallback",
+"summary": "Longer of the two (more complete)",
+"first_name": "Scrapetable first, Bright Data fallback",
+"last_name": "Scrapetable first, Bright Data fallback",
+"location": "Scrapetable first, Bright Data fallback",
+"profile_picture_url": "Scrapetable first (higher quality CDN)",
+"linkedin_id": "Scrapetable first, Bright Data fallback",
+"followers_count": "Whichever has data",
+"connections_count": "Whichever has data",
+"industry": "Bright Data only",
+"certifications": "Bright Data only",
+"languages": "Bright Data only",
+"courses": "Bright Data only",
+"projects": "Bright Data only",
+"organizations": "Bright Data only",
+"honors_awards": "Bright Data only",
+"recommendations": "Bright Data only",
+"activity": "Bright Data only",
+"current_company": "Bright Data only",
+"banner_image_url": "Bright Data only"
+}
+},
+"step_3_db_persistence": {
+"description": "Merged data is written to linkedin_profiles table (PostgreSQL JSONB columns for arrays/objects, TEXT/VARCHAR for scalars). connection_status set to CONNECTED, last_synced_at set to now()."
+},
+"step_4_response_assembly": {
+"description": "The _build_profile_detail_response() function reads the DB model and constructs LinkedInProfileDetailResponse Pydantic model, which is wrapped in FetchByUrlResponse."
+}
+},
+"response": {
+"success": true,
+"message": "Profile fetched successfully",
+"fetch_status": "completed",
+"profile": {
+"id": "70529a20-873d-4a6f-bc11-ab6bcec5b8b0",
+"linkedin_id": "ACoAAB8LpMUB2XVVN-uGsshaioFR58XxqPmOwZM",
+"first_name": "Rahul",
+"last_name": "Gupta",
+"headline": "Walmart Global Tech | MS in Computer Science",
+"summary": "At Fleuxlabs, our team leverages artificial intelligence to transform user interaction with digital platforms, fostering a seamless fusion of human cognitive processes and technological innovation. Our solutions, powered by AI expertise, particularly in PyTorch and Jupyter, are designed to deliver intuitive experiences that resonate with our users.\n\nMy educational pursuits at San Diego State University in Computer Science are instrumental in shaping the strategic direction of Fleuxlabs. With a solid background in AI and deep learning, the insights gained from my studies are integral to the pioneering work we do, ensuring that our technological advancements continue to set industry standards.",
+"industry": null,
+"location": "United States",
+"profile_picture_url": "https://scrapetable.b-cdn.net/linkedin-people/linkedin-profile-rahul2608-1770796033431.jpg",
+"public_profile_url": "https://www.linkedin.com/in/rahul2608/",
+"connection_status": "CONNECTED",
+"connections_count": 500,
+"followers_count": 623,
+"last_synced_at": "2026-02-11T07:47:30.361228+00:00",
+"created_at": "2026-02-11T07:47:10.284378+00:00",
+"email": null,
+"banner_image_url": "https://media.licdn.com/dms/image/v2/C5116AQGVMt-5-aC2TQ/profile-displaybackgroundimage-shrink_200_800/profile-displaybackgroundimage-shrink_200_800/0/1517506105412?e=2147483647&v=beta&t=YxKKlI8jdr7gzD3rg5c4GSwh9NZDr9yt2Y68CYG4wp4",
+"current_company": {
+"name": "Walmart Global Tech",
+"industry": null,
+"url": "https://www.linkedin.com/company/walmartglobaltech?trk=public_profile_topcard-current-company",
+"logo_url": null
+},
+"experience": [
+{
+"title": "AI Engineer | ML Ops",
+"company": "Walmart Global Tech",
+"company_url": "https://www.linkedin.com/company/11174522",
+"location": "Sunnyvale, California, United States",
+"start_date": "06/2018",
+"end_date": "06/2025",
+"duration": null,
+"is_current": false,
+"description": null
+},
+{
+"title": "Software Development Engineer II",
+"company": "Walmart Global Tech",
+"company_url": "https://www.linkedin.com/company/11174522",
+"location": "Sunnyvale, California, United States",
+"start_date": "06/2021",
+"end_date": "08/2022",
+"duration": null,
+"is_current": false,
+"description": null
+},
+{
+"title": "Peer Mentor",
+"company": "San Diego State University",
+"company_url": "https://www.linkedin.com/company/6206",
+"location": "International Student Centre, San Diego",
+"start_date": "09/2016",
+"end_date": "05/2018",
+"duration": null,
+"is_current": false,
+"description": "As a student mentor, I worked with incoming international freshmen to help them adapt to a new culture and environment. I ensured that they were successful by guiding and counseling them on how to navigate their first semester at the university. I also made sure that they connected with the various resources available on campus."
+},
+{
+"title": "Software Developer",
+"company": "Cal Hacks",
+"company_url": "https://www.linkedin.com/company/6430466",
+"location": null,
+"start_date": "10/2015",
+"end_date": "10/2015",
+"duration": null,
+"is_current": false,
+"description": "I developed a virtual reality game using the Myo motion detector, which allowed users to virtually interact with objects and characters in the game."
+}
+],
+"education": [
+{
+"school": "San Diego State University",
+"degree": "Master of Science - MS",
+"field_of_study": "Computer Science",
+"start_date": "2022",
+"end_date": "2024",
+"school_url": null,
+"description": null,
+"activities": null
+},
+{
+"school": "San Diego State University-California State University",
+"degree": "Bachelor of Science (B.S.)",
+"field_of_study": "Computer Science",
+"start_date": "2014",
+"end_date": "2018",
+"school_url": null,
+"description": null,
+"activities": null
+}
+],
+"skills": [
+"PyTorch",
+"Jupyter",
+"Artificial Intelligence (AI)",
+"Vector Databases",
+"Large Language Models (LLM)",
+"Next.js",
+"Machine Learning",
+"Java",
+"C",
+"C++",
+"Bash",
+"Data Structures",
+"Computer Architecture",
+"Lua",
+"Haskell",
+"Unix",
+"SQL",
+"Object-Oriented Programming (OOP)",
+"Python",
+"JavaScript"
+],
+"certifications": [
+{
+"name": "Oracle Certified Professional, Java SE 8 Programmer II",
+"issuing_organization": null,
+"authority": "Oracle",
+"issue_date": null,
+"credential_url": null,
+"license_number": null,
+"url": "https://www.youracclaim.com/badges/95333ac3-13e2-422f-a75c-9d9ab8fc1d7b/linked_in_profile?trk=public_profile_see-credential",
+"start_date": "Apr 2019",
+"end_date": null
+},
+{
+"name": "Oracle Certified Associate, Java SE 8 Programmer",
+"issuing_organization": null,
+"authority": "Oracle",
+"issue_date": null,
+"credential_url": null,
+"license_number": null,
+"url": "https://www.youracclaim.com/badges/a8858bd2-295e-4590-ad76-0cb1bd9b83e7/linked_in_profile?trk=public_profile_see-credential",
+"start_date": "Feb 2019",
+"end_date": null
+}
+],
+"languages": [
+{
+"name": "English",
+"proficiency": "Full professional proficiency"
+},
+{
+"name": "Hindi",
+"proficiency": "Native or bilingual proficiency"
+}
+],
+"courses": [
+{
+"name": "Assembly Language and Machine Learning",
+"number": "237",
+"associated_with": null
+},
+{
+"name": "Computer Architecture",
+"number": "370",
+"associated_with": null
+},
+{
+"name": "Intermediate Java Programming",
+"number": "108",
+"associated_with": null
+},
+{
+"name": "Programming Languages",
+"number": "320",
+"associated_with": null
+},
+{
+"name": "Statistical Methods",
+"number": "350A",
+"associated_with": null
+}
+],
+"projects": [
+{
+"name": "Fleuxlabs",
+"url": null,
+"start_date": "Aug 2022",
+"end_date": null,
+"description": null,
+"associated_with": null
+}
+],
+"organizations": [
+{
+"name": "Golden Key International Honour Society",
+"position": "Member",
+"start_date": "Sep 2016",
+"end_date": "Present",
+"description": "One of the most prestigious honour society at SDSU which only accepts students who are in the top 15 percent of their class.The purpose of the society is to recognize and encourage scholastic achievement and excellence in all undergraduate fields of study, to unite with collegiate faculties and administrators in developing and maintaining high educational standards, to provide scholarships to outstanding initiates, and to foster altruistic conduct through voluntary service."
+},
+{
+"name": "Model United Nations (SDSU)",
+"position": "Member",
+"start_date": "Sep 2016",
+"end_date": "Present",
+"description": "This platform gave me a chance talk about issues that concern our entire humanity, and gain leadership skills. The chance to attend conferences in different campuses not only helped me inculcate people skills but also listening to my fellows made me realise that there are so many things that we can learn from each other."
+},
+{
+"name": "Phi Eta Sigma National Honor Society, Inc.",
+"position": "Member",
+"start_date": "Sep 2015",
+"end_date": "Present",
+"description": "Phi Eta Sigma is an all-disciplines freshman national honor society established in 1923. The purpose of Phi Eta Sigma is to encourage and reward high scholastic achievement among freshmen students in institutions of higher education. This society definitely helped to evolve my character and care for my fellow beings. Now I truly believe that it is essential to use our academic prowess not only for our personal benefits but rather for the betterment of entire mankind."
+},
+{
+"name": "The National Society of Collegiate Scholars",
+"position": "Member",
+"start_date": "Sep 2015",
+"end_date": "Present",
+"description": "The National Society of Collegiate Scholars (NSCS) is an honors organization that recognizes and elevates high achievers."
+}
+],
+"honors_awards": [
+{
+"title": "Dean's List Awardee",
+"issuer": "College of Sciences, San Diego State University",
+"date": "2016-09-01T00:00:00.000Z",
+"description": "Spring 2016",
+"associated_with": null
+},
+{
+"title": "Dean's List Awardee",
+"issuer": "College of Sciences, San Diego State University",
+"date": "2016-01-01T00:00:00.000Z",
+"description": "Fall 2015",
+"associated_with": null
+},
+{
+"title": "Dean's List Awardee",
+"issuer": "College of Sciences, San Diego State University",
+"date": "2015-09-01T00:00:00.000Z",
+"description": "Spring 2015",
+"associated_with": null
+},
+{
+"title": "Dean's List Awardee",
+"issuer": "College of Sciences, San Diego State University",
+"date": "2015-01-01T00:00:00.000Z",
+"description": "Fall 2014",
+"associated_with": null
+}
+],
+"recommendations": [
+{
+"recommender_name": null,
+"recommender_title": null,
+"relationship": null,
+"text": "Parvesh Koya “I have known Rahul from our first day at San Diego State University. From the first day I met him, it was very clear that he was committed, motivated, and profoundly intelligent. I have had the opportunity of working together with him on many projects and have seen first hand his leadership capabilities and his attention to detail. His leadership qualities combined with his in-depth knowledge of the various fields of computer science, Rahul is a priceless asset to any team. ”",
+"date": null
+}
+],
+"activity": [
+{
+"type": "Liked by Rahul Gupta",
+"title": "I hosted the China-India Youth Dialogue on February 25th alongside Su Chen from the Political Department of the Embassy of the People's Republic of…",
+"url": "https://www.linkedin.com/posts/amulyagupta1_bilateralties-globalcitizenship-collaborationbeyondborder-activity-7300845318680522752-UTAz",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "Are we all just performing? In a world where every moment is curated and shared, the line between authenticity and performance is blurrier than ever.…",
+"url": "https://www.linkedin.com/posts/akarshkain_modernhumanspodcast-opherbrayer-authenticity-activity-7298798754554355712-VMOe",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "Leadership Exodus: Founders, CEOs Who Quit Their Startups In 2024👇 One of the most common occurrences in the world’s third-largest startup…",
+"url": "https://www.linkedin.com/posts/inc42_leadershipexodus-founderstories-indianstartups-activity-7278993255994683392-0hEZ",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "I am excited to share that I have graduated from San Diego State University with a Bachelor of Science in Computer Science, achieving the distinction…",
+"url": "https://www.linkedin.com/posts/bennett-hilck-96080226a_i-am-excited-to-share-that-i-have-graduated-activity-7201032802018959360-8tg3",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "The Empire State Building is getting a fresh new look with new uniforms for its employees 🏙️ Designed by renowned fashion designer Peyman Umay…",
+"url": "https://www.linkedin.com/posts/naumd_empirestatebuilding-peymanumay-workwear-activity-7026300330476802048-BI4q",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "💬 As someone who's had many conversations with founders lately, I've come up with a helpful list for anyone looking to improve their company's…",
+"url": "https://www.linkedin.com/posts/kharitojulia_as-someone-whos-had-many-conversations-activity-7026301274086146048-jFiP",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "Just wanted to share my top three tools for staying organized and on top of both work and personal life! 💻📅 1️⃣ Asana - a game-changer for project…",
+"url": "https://www.linkedin.com/posts/kharitojulia_just-wanted-to-share-my-top-three-tools-for-activity-7025981147188789248-E0oc",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "⚠️ If you still think of your target audience as \"people of a certain age,\" you're missing out on an opportunity to connect with them. This might…",
+"url": "https://www.linkedin.com/posts/kharitojulia_if-you-still-think-of-your-target-audience-activity-7025946215502536704-WiKR",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "Are you tired of posting on social media and not seeing the results you want? I know, it's frustrating when your hard work doesn't seem to be paying…",
+"url": "https://www.linkedin.com/posts/kharitojulia_are-you-tired-of-posting-on-social-media-activity-7024181789279608832-DARV",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "Yes I'm still using the hypebeast stack core: - react - typescript - node.js - postgresql addons: - graphql -…",
+"url": "https://www.linkedin.com/posts/benawad_coding-programming-softwareengineering-activity-6991436280869916673-a9l0",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "Did you know that 95% of total television coverage focuses on men’s sports? Women’s leagues are hardly the focus of mainstream media, nor are they…",
+"url": "https://www.linkedin.com/posts/femalequotient_did-you-know-that-95-of-total-television-activity-6998073717616492544-m6rJ",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "Hi folks, wanted to inform everyone that I am one of the unfortunate 11000 people affected due to recent layoffs at Meta. My heart goes out to…",
+"url": "https://www.linkedin.com/posts/neeraj-desh_opentowork-metalayoffs-h1bvisa-activity-6996348074730139648-h33E",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "The hardest part of being a software engineer is not getting fat eating all the free snacks #coding #programming #softwareengineering…",
+"url": "https://www.linkedin.com/posts/benawad_coding-programming-softwareengineering-activity-6996576933727653888-CLVq",
+"date": null,
+"likes": null,
+"comments": null
+},
+{
+"type": "Liked by Rahul Gupta",
+"title": "I think companies should own a bit of responsibility when treating international employees on Visa. Maybe work with Congress to give extra runway (6…",
+"url": "https://www.linkedin.com/posts/7ankit_i-think-companies-should-own-a-bit-of-responsibility-activity-6994394684668198912-43Tv",
+"date": null,
+"likes": null,
+"comments": null
+}
+]
+}
+},
+"error_responses": {
+"auth_missing": {
+"status_code": 401,
+"body": {
+"detail": "Authentication required"
+}
+},
+"invalid_url": {
+"status_code": 400,
+"body": {
+"detail": "Invalid LinkedIn URL format. URL should be like: https://linkedin.com/in/username"
+}
+},
+"both_sources_failed": {
+"status_code": 200,
+"body": {
+"success": false,
+"message": "Failed to fetch profile data from both sources. Please try again later.",
+"profile": null,
+"fetch_status": "failed"
+}
+}
+},
+"field_reference": {
+"_note": "Complete field-level reference for every key in profile object",
+"top_level_envelope": {
+"success": {
+"type": "boolean",
+"values": [
+true,
+false
+]
+},
+"message": {
+"type": "string",
+"example": "Profile fetched successfully"
+},
+"fetch_status": {
+"type": "string",
+"enum": [
+"pending",
+"fetching",
+"completed",
+"failed"
+]
+},
+"profile": {
+"type": "LinkedInProfileDetailResponse | null"
+}
+},
+"profile_scalars": {
+"id": {
+"type": "uuid",
+"source": "DB-generated"
+},
+"linkedin_id": {
+"type": "string",
+"source": "Scrapetable > Bright Data",
+"example": "ACoAAB8LpMUB2XVVN-uGsshaioFR58XxqPmOwZM"
+},
+"first_name": {
+"type": "string|null",
+"source": "Scrapetable > Bright Data"
+},
+"last_name": {
+"type": "string|null",
+"source": "Scrapetable > Bright Data"
+},
+"headline": {
+"type": "string|null",
+"source": "Scrapetable > Bright Data",
+"max_length": 500
+},
+"summary": {
+"type": "string|null",
+"source": "Longer of Scrapetable vs Bright Data"
+},
+"industry": {
+"type": "string|null",
+"source": "Bright Data only (from current_company)"
+},
+"location": {
+"type": "string|null",
+"source": "Scrapetable > Bright Data"
+},
+"profile_picture_url": {
+"type": "string|null",
+"source": "Scrapetable > Bright Data (Scrapetable preferred for CDN quality)"
+},
+"public_profile_url": {
+"type": "string|null",
+"source": "Input linkedin_url"
+},
+"connection_status": {
+"type": "string",
+"enum": [
+"CONNECTED",
+"DISCONNECTED"
+]
+},
+"connections_count": {
+"type": "integer|null",
+"source": "Whichever source has data"
+},
+"followers_count": {
+"type": "integer|null",
+"source": "Whichever source has data"
+},
+"last_synced_at": {
+"type": "ISO 8601 datetime|null",
+"source": "Set on successful fetch"
+},
+"created_at": {
+"type": "ISO 8601 datetime",
+"source": "DB-generated on first insert"
+},
+"email": {
+"type": "string|null",
+"source": "Not populated by scraping"
+},
+"banner_image_url": {
+"type": "string|null",
+"source": "Bright Data only"
+}
+},
+"profile_objects": {
+"current_company": {
+"type": "object|null",
+"source": "Bright Data only",
+"fields": {
+"name": "string|null",
+"industry": "string|null",
+"url": "string|null — LinkedIn company page URL",
+"logo_url": "string|null — Company logo image URL"
+}
+}
+},
+"profile_arrays": {
+"experience[]": {
+"source": "Scrapetable > Bright Data",
+"fields": {
+"title": "string|null — Job title",
+"company": "string|null — Company name",
+"company_url": "string|null — LinkedIn company page URL",
+"location": "string|null — City, State, Country",
+"start_date": "string|null — Format: MM/YYYY",
+"end_date": "string|null — Format: MM/YYYY or 'Present'",
+"duration": "string|null — e.g. '3 yrs 2 mos'",
+"is_current": "boolean — true if no end_date",
+"description": "string|null — Role description"
+}
+},
+"education[]": {
+"source": "Scrapetable > Bright Data",
+"fields": {
+"school": "string|null — Institution name",
+"degree": "string|null — e.g. 'Master of Science - MS'",
+"field_of_study": "string|null — e.g. 'Computer Science'",
+"start_date": "string|null — Year only: 'YYYY'",
+"end_date": "string|null — Year only: 'YYYY'",
+"school_url": "string|null — LinkedIn school page URL",
+"description": "string|null",
+"activities": "string|null"
+}
+},
+"skills[]": {
+"source": "Scrapetable > Bright Data",
+"type": "string[] — Flat array of skill name strings"
+},
+"certifications[]": {
+"source": "Bright Data only",
+"fields": {
+"name": "string|null — Certification name",
+"issuing_organization": "string|null",
+"authority": "string|null — e.g. 'Oracle'",
+"issue_date": "string|null",
+"credential_url": "string|null",
+"license_number": "string|null",
+"url": "string|null — Credential verification URL",
+"start_date": "string|null — e.g. 'Apr 2019'",
+"end_date": "string|null"
+}
+},
+"languages[]": {
+"source": "Bright Data only",
+"fields": {
+"name": "string|null — e.g. 'English'",
+"proficiency": "string|null — e.g. 'Full professional proficiency'"
+}
+},
+"courses[]": {
+"source": "Bright Data only",
+"fields": {
+"name": "string|null — Course name",
+"number": "string|null — Course number e.g. '370'",
+"associated_with": "string|null"
+}
+},
+"projects[]": {
+"source": "Bright Data only",
+"fields": {
+"name": "string|null — Project name",
+"url": "string|null — Project URL",
+"start_date": "string|null — e.g. 'Aug 2022'",
+"end_date": "string|null",
+"description": "string|null",
+"associated_with": "string|null"
+}
+},
+"organizations[]": {
+"source": "Bright Data only",
+"fields": {
+"name": "string|null — Organization name",
+"position": "string|null — e.g. 'Member'",
+"start_date": "string|null — e.g. 'Sep 2016'",
+"end_date": "string|null — e.g. 'Present'",
+"description": "string|null"
+}
+},
+"honors_awards[]": {
+"source": "Bright Data only",
+"fields": {
+"title": "string|null — Award name",
+"issuer": "string|null — Issuing organization",
+"date": "string|null — ISO 8601 date or free text",
+"description": "string|null",
+"associated_with": "string|null"
+}
+},
+"recommendations[]": {
+"source": "Bright Data only",
+"fields": {
+"recommender_name": "string|null",
+"recommender_title": "string|null",
+"relationship": "string|null",
+"text": "string|null — Full recommendation text",
+"date": "string|null"
+}
+},
+"activity[]": {
+"source": "Bright Data only",
+"fields": {
+"type": "string|null — e.g. 'Liked by Rahul Gupta'",
+"title": "string|null — Post preview text (truncated)",
+"url": "string|null — LinkedIn post URL",
+"date": "string|null",
+"likes": "integer|null",
+"comments": "integer|null"
+}
+}
+}
+}
+}
diff --git a/qscore/docs/plan.md b/qscore/docs/plan.md
new file mode 100644
index 0000000..dc23a7b
--- /dev/null
+++ b/qscore/docs/plan.md
@@ -0,0 +1,187 @@
+# Plan: Quotients Derived from Pillars/Rules (QScore Service)
+
+## Branch
+- Working branch: `feature/quotients-from-pillars`
+- Base branch: `admin-ui`
+
+## Goal
+Add **quotient outputs** (e.g., SQ, XQ, CQm, VQ, DQ, GQ, RQx, DQm, etc.) to QScore outputs so frontend/consumers can show which quotients are available for a user and their computed values.
+
+This must be derived from existing scoring context (signals -> rules -> pillars -> weights -> CI), not hardcoded per user.
+
+Delivery scope includes **every output path**:
+- API responses (`/v1/qscore/compute`, `/v1/qscore/{user_id}`)
+- Redis score update stream (`qscore.score_updates`)
+- Redis latest cache key (`qscore:latest:{org_id}:{user_id}`)
+
+---
+
+## What changed in product doc
+From updated `docs/Q-Score_Service.md` table:
+- Each KPI/input now includes associated quotient tags per profession.
+- Example: LinkedIn input for student maps to `SQ, CQm, NQ, CuQ`, Resume maps to `XQ, CQm, VQ`, etc.
+
+---
+
+## Design proposal (quick, extensible)
+
+### 1) Formula metadata extension
+Add optional quotient tags to each input in formula JSON:
+
+```json
+"inputs": {
+ "linkedin": {
+ "vs": 1.0,
+ "label": "LinkedIn Profile",
+ "signal_ids": [...],
+ "quotients": ["SQ", "CQm", "NQ", "CuQ"]
+ }
+}
+```
+
+Why input-level first:
+- Doc table currently maps quotients at KPI/input level.
+- Rules already map to inputs; pillars map to rules.
+- We can derive rule/pillar quotient linkage without duplicating metadata everywhere.
+
+### 2) Rule + pillar quotient attribution
+- A rule inherits quotients from its input.
+- A pillar’s quotient exposure = union of quotient tags from all rules in that pillar.
+- For each quotient within a pillar, compute rule-share:
+ - `quotient_rule_share = rules_in_pillar_with_quotient / total_rules_in_pillar`
+
+### 3) Quotient scoring math
+Use same normalization pattern as Q-Score with pillar weights:
+- `quotient_contribution += pillar.contribution * quotient_rule_share`
+- `quotient_active_weight += pillar.weight * quotient_rule_share` (only active pillars)
+- `quotient_score = quotient_contribution / quotient_active_weight` (if weight > 0 else 0)
+
+This keeps quotient math aligned with existing pillar-weighted scoring.
+
+### 4) API response changes
+Add new top-level field in both compute/read responses:
+
+```json
+"quotients": {
+ "SQ": { "score": 71.2, "active": true, "contribution_sum": 21.34, "active_weight_sum": 0.299 },
+ "CQm": { ... }
+}
+```
+
+Also include quotient details in breakdown for transparency:
+
+```json
+"breakdown": {
+ ...,
+ "quotients": {
+ "SQ": {
+ "score": 71.2,
+ "contribution_sum": 21.34,
+ "active_weight_sum": 0.299,
+ "pillars": ["p01_presence_profile", "p06_communication_signals"]
+ }
+ }
+}
+```
+
+### 5) Redis output contract changes (producer/consumer path)
+Add quotient data to worker-published stream payload (`qscore.score_updates`) and latest cache key:
+
+- Stream event (`publisher.py`) should include:
+ - `quotients` (JSON string)
+ - `breakdown` already includes `breakdown.quotients`
+- Latest key (`qscore:latest:{org_id}:{user_id}`) should include:
+ - `quotients`
+
+Example stream fields added:
+
+```json
+{
+ "q_score": "67.42",
+ "formula_version": "v1",
+ "quotients": "{\"SQ\":{\"score\":71.2,...}}",
+ "breakdown": "{\"inputs\":...,\"quotients\":...}"
+}
+```
+
+---
+
+## Files to update
+
+### Scoring engine
+- `app/scoring/engine/loader.py`
+ - extend `FormulaInput` with optional `quotients: list[str] = []`
+- `app/scoring/engine/evaluator.py`
+ - compute quotient attribution + scores from pillar/rule structure
+ - include quotient results in `QScoreResult`
+- `app/scoring/engine/breakdown.py`
+ - append `quotients` section to breakdown payload
+
+### API contracts
+- `app/api/schemas.py`
+ - add `quotients: dict[str, Any]` to:
+ - `QScoreComputeResponse`
+ - `QScoreReadResponse`
+- `app/api/qscore.py`
+ - return new `quotients` in both compute/read paths
+
+### Stream/cache contracts
+- `app/worker/publisher.py`
+ - publish `quotients` in `qscore.score_updates` stream event
+ - include `quotients` in `qscore:latest:{org_id}:{user_id}` cache payload
+- `app/worker/compute.py`
+ - pass computed `quotients` into publisher
+
+### Formula data
+- `app/scoring/formula/v1/*/formula.json`
+ - add `quotients` array to each input, profession-specific per updated doc table
+
+### Docs
+- `README.md`
+ - update endpoint contract examples with `quotients`
+- `docs/Q-Score_Service.md`
+ - keep as source-of-truth reference (already updated by product)
+
+### Tests
+- `tests/unit/test_loader.py`
+ - validate formulas with new `quotients` field
+- `tests/unit/test_evaluator.py`
+ - verify quotient score derivation and deterministic behavior
+- `tests/unit/test_breakdown.py`
+ - verify `breakdown.quotients` exists and is JSON-serializable
+- `tests/unit` (new publisher-focused test or extend existing)
+ - verify stream payload includes `quotients` and latest cache payload includes `quotients`
+
+---
+
+## Backward compatibility
+- Make `quotients` optional in formula schema, default `[]`.
+- Existing formulas without quotient metadata still load.
+- In that case, API returns empty `quotients` object.
+
+---
+
+## Implementation order (fast path)
+1. Extend loader schema and defaults.
+2. Add quotient computation in evaluator.
+3. Add breakdown + API response fields.
+4. Add Redis stream/latest payload quotient fields.
+5. Patch all v1 formula files with quotient tags.
+6. Update tests and docs.
+
+---
+
+## Open items to confirm before coding
+1. **Output shape preference**: top-level `quotients` only, or both top-level and `breakdown.quotients`? (recommended: both)
+2. **Code names**: keep exact short codes from doc (`SQ`, `CQm`, `RQx`, etc.) as API keys? (recommended: yes)
+3. **Undefined codes in legend** (e.g., `NQ`, `CuQ`, `InQ`) should we still pass through as-is from doc? (recommended: yes, pass-through)
+
+---
+
+## Acceptance criteria
+- `POST /v1/qscore/compute` and `GET /v1/qscore/{user_id}` return non-empty `quotients` when mapped signals exist.
+- `qscore.score_updates` stream events include `quotients`.
+- `qscore:latest:{org_id}:{user_id}` cache payload includes `quotients`.
+- Quotient values change when pillar/rule scores change.
+- Existing Q-Score output remains unchanged.
+- Formula files load successfully with new metadata.
diff --git a/qscore/qscore-service-uv-scaffold.md b/qscore/qscore-service-uv-scaffold.md
new file mode 100644
index 0000000..e1fc6f0
--- /dev/null
+++ b/qscore/qscore-service-uv-scaffold.md
@@ -0,0 +1,123 @@
+# Q-Score Service Scaffold (UV + FastAPI) - Reference
+
+Goal: mirror `growqr/job-service/` structure, but use `uv` + `pyproject.toml` + `uv.lock`.
+
+## 1) Target Folder Structure
+
+Proposed repo path: `growqr/qscore-service/`
+
+```
+qscore-service/
+ .env.example
+ .gitignore
+ README.md
+ docker-compose.yml
+ Dockerfile
+ pyproject.toml
+ uv.lock
+ app/
+ __init__.py
+ main.py
+ config.py
+ database.py
+ api/
+ __init__.py
+ v1/
+ __init__.py
+ router.py
+ signals.py
+ qscore.py
+ registry.py
+ formulas.py
+ auth/
+ __init__.py
+ middleware.py
+ schemas/
+ __init__.py
+ signals.py
+ qscore.py
+ formulas.py
+ services/
+ __init__.py
+ engine_service.py
+ scoring/
+ __init__.py
+ engine/
+ __init__.py
+ loader.py
+ evaluator.py
+ breakdown.py
+ formula/
+ v1/
+ formula.json
+ alembic/
+ env.py
+ versions/
+ scripts/
+ run_worker.py
+```
+
+Notes:
+- This keeps the same mental model as `growqr/job-service/app/...`.
+- We include Alembic so schema changes are migration-driven (job-service currently uses create_all).
+
+## 2) UV Commands (Day 1)
+
+Create project:
+
+```bash
+uv init .
+uv python pin 3.12
+uv venv
+```
+
+Add runtime deps:
+
+```bash
+uv add fastapi "uvicorn[standard]" pydantic pydantic-settings sqlalchemy asyncpg
+uv add redis
+```
+
+Add dev deps:
+
+```bash
+uv add --dev ruff black pytest pytest-asyncio
+```
+
+Lock + sync:
+
+```bash
+uv lock
+uv sync --frozen
+```
+
+Run:
+
+```bash
+uv run uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
+```
+
+## 3) Dockerfile Pattern (UV)
+
+Use the recommended uv-based Docker pattern:
+
+- copy `pyproject.toml` + `uv.lock`
+- `uv sync --frozen --no-dev`
+- copy `app/`
+
+## 4) Migration Setup (Alembic)
+
+We use Alembic for Postgres schema:
+
+- `alembic init alembic`
+- configure `DATABASE_URL` in `app/config.py`
+- import SQLAlchemy Base metadata in `alembic/env.py`
+
+## 5) How This Matches job-service
+
+`growqr/job-service/app/` has:
+- `main.py`, `config.py`, `database.py`
+- `api/v1/router.py` to include routes
+- `schemas/` + `services/`
+
+Q-score service follows the same layout so engineers can jump between services without relearning structure.
diff --git a/requirements-curator-streak-chat-flow.md b/requirements-curator-streak-chat-flow.md
new file mode 100644
index 0000000..52eff9e
--- /dev/null
+++ b/requirements-curator-streak-chat-flow.md
@@ -0,0 +1,250 @@
+# Requirements: Curator Streak Chat Flow — Service Handoff & Preview UX
+
+**Date:** 2026-06-15
+**Status:** Draft — pending stakeholder review
+**Repos:** `growqr-backend`, `growqr-dashboard`
+**Branch:** `staging-rosh` (VPS staging)
+**Priority:** P0 — main blocker for staging user testing
+
+---
+
+## 1. Goal
+
+When a user clicks a daily/weekly streak or progress suggestion in the GrowQR dashboard, the system must guide them through a focused, coherent conversation that produces a **service preview CTA** — not a blank setup screen — so they can immediately start the intended service (interview, roleplay, resume, etc.) with sensible defaults derived from their onboarding profile and goals.
+
+**What good looks like:** a user who clicks "practice behavioral interview" gets asked at most one clarifying question, then sees a clear card with a button that says "Open interview preview" and lands directly on a preview screen with the role, round type, and difficulty already set.
+
+---
+
+## 2. Scope — What This Covers
+
+| In Scope | Out of Scope |
+|----------|-------------|
+| Streak/weekly progress component chat modal | TalkToMe chat route/component |
+| Curator backend prompt behavior | New AI model selection |
+| Interview preview handoff | Resume parser internals |
+| Roleplay preview handoff | Q Score calculation engine |
+| Service CTA card rendering | Social branding / courses |
+| Prompt externalization | Billing/subscription flows |
+| 3-suggestion daily task model | Admin dashboards |
+| 30/60-day growth plan coherence | Full mission actor rewrite |
+
+---
+
+## 3. Stakeholder Experience — The Exact Flow
+
+### 3.1 User Lands on Dashboard
+
+The user sees:
+- **Streak progress** (e.g., "5-day streak 🔥")
+- **Weekly progress** with 3 suggestions
+- Each suggestion has a title, subtitle, and an actionable CTA
+
+The suggestions are derived from the user's onboarding answers (ICP, goals, blockers) and current Q Score / readiness state.
+
+### 3.2 User Clicks a Suggestion
+
+Example: **"Practice behavioral interview — Product Manager"**
+
+A chat modal opens. The assistant header shows:
+- Avatar + "Daily Mission" label
+- Subtask title: "Practice behavioral interview"
+- Service name: "Interview Coach"
+
+### 3.3 First Turn
+
+The curator should **not** ask a generic "What do you want to do?" question.
+
+It should say something like:
+
+> "I’ll set up a 5-minute behavioral interview preview for you. What role should I focus on — or is Product Manager still your target?"
+
+If the onboarding already captured the role, it should **skip the question entirely** and proceed directly to the preview card.
+
+### 3.4 User Answers (or Skips)
+
+- User types: "Product Manager" (or just hits Enter if already known)
+- Assistant: "Got it. Preparing your preview now."
+
+### 3.5 Preview CTA Card Appears
+
+A card appears in the chat with:
+- **Eyebrow:** INTERVIEW PREVIEW
+- **Title:** "Your mock interview is ready"
+- **Details:** Role · Round · Difficulty · Duration
+- **Button:** "Open interview preview" (or "Open roleplay preview")
+- **Secondary link:** "Change settings" (opens setup with params pre-filled)
+
+### 3.6 User Clicks the CTA
+
+The user is routed to:
+
+```
+/agents/interview/preview?role=Product+Manager&type=behavioral&difficulty=medium&duration=5&source=curator-v1&curatorTaskId=...
+```
+
+The preview page loads with the session already configured. The user can:
+- Start the interview immediately
+- Request question changes
+- Go back to chat
+
+### 3.7 Roleplay Equivalent
+
+Same flow, but for roleplay:
+
+> "I’ll set up a salary negotiation practice. What scenario should we rehearse?"
+
+Then CTA card → `/agents/roleplay/preview?scenario=...` or equivalent builder route with pre-filled params.
+
+---
+
+## 4. Acceptance Criteria — What "Finish" Looks Like
+
+### 4.1 Backend Acceptance Criteria
+
+| # | Criteria | How to Verify |
+|---|----------|---------------|
+| B1 | Curator prompt is externalized to a markdown/txt file | `cat prompts/curator/daily-retention-system.md` returns the prompt |
+| B2 | Interview handoff returns preview route, not setup | `/v1/curator/chat` response includes `handoff.actionRoute` containing `/agents/interview/preview` |
+| B3 | Roleplay handoff returns preview route, not setup | Same as B2, but for roleplay |
+| B4 | Status is `handoff_ready` when service context is sufficient | `statusUpdate.status === "handoff_ready"` after one answer for known role |
+| B5 | No infinite questioning — max 1 clarifying question per service task | Log review: assistant never asks same question twice |
+| B6 | Default params are sensible: `type=behavioral`, `difficulty=medium`, `duration=5` | Preview loads without user needing to configure |
+| B7 | Route includes onboarding-derived role when available | `role` param is pre-filled from user profile |
+| B8 | Curator does not leak internal routes in chat text | No `/agents/...` URLs in `reply` field |
+| B9 | Service handoff works for Resume (workspace), Q Score (review), Pathways (report) | Each returns correct route with pre-filled context |
+| B10 | Build passes on VPS | `npm run typecheck` and `npm run build` succeed on staging-rosh |
+
+### 4.2 Frontend Acceptance Criteria
+
+| # | Criteria | How to Verify |
+|---|----------|---------------|
+| F1 | Streak chat shows service preview CTA card reliably | Click interview suggestion → card appears within 2 turns |
+| F2 | CTA card is visually distinct and action-oriented | Card has eyebrow, title, details grid, and primary button |
+| F3 | CTA persists after subtask is marked complete | Even in "completed" footer state, the card remains visible |
+| F4 | Button copy is service-specific | Interview: "Open interview preview"; Roleplay: "Open roleplay preview"; Resume: "Open resume workspace" |
+| F5 | Clicking CTA navigates to correct preview route | Browser URL matches `/agents/interview/preview?...` or `/agents/roleplay/preview?...` |
+| F6 | Preview page loads with pre-filled params | Interview preview shows role, type, difficulty without user re-entering |
+| F7 | No regression to TalkToMe, home feed, or other dashboard pages | Smoke test: dashboard, talk-to-me, missions, settings all load |
+| F8 | Build passes on VPS | `npm run build` succeeds on staging-rosh |
+| F9 | Mobile: chat modal and CTA card are usable | Test on mobile viewport: card readable, button tappable |
+| F10 | Loading state is clear and non-blocking | "Preparing your preview..." shown instead of generic spinner |
+
+### 4.3 Product Coherence Criteria
+
+| # | Criteria | How to Verify |
+|---|----------|---------------|
+| P1 | Every task connects back to user's stated goal | Chat copy references user's target role or goal from onboarding |
+| P2 | 30/60-day plan framing is visible | Suggestion labels include week/day context (e.g., "Week 2 — Day 3") |
+| P3 | Tasks follow the 3-suggestion model: Measurement + Proof + Practice | Daily suggestions show one of each category |
+| P4 | Streak is meaningful — not just a counter | Completing a task shows progress toward a goal, not just +1 day |
+| P5 | User can see why this task matters | Assistant explains: "This builds your interview readiness signal, which improves your Q Score." |
+
+---
+
+## 5. Non-Functional Requirements
+
+| Requirement | Target |
+|-------------|--------|
+| Curator chat response time | < 3s end-to-end (backend + frontend) |
+| Preview page load time | < 2s after CTA click |
+| Build time on VPS | < 5 minutes per repo |
+| Downtime during deploy | Zero — rolling restart via Docker Compose |
+| Prompt hot-reload | Possible without code redeploy (external file) |
+| Browser compatibility | Chrome, Safari, Firefox latest 2 versions |
+
+---
+
+## 6. Edge Cases & Error Handling
+
+| Scenario | Expected Behavior |
+|----------|-----------------|
+| User gives vague answer | Assistant asks ONE follow-up, then shows preview card with best guess |
+| User has no onboarding role | Assistant asks "What role are you targeting?" — answer generates preview |
+| Service is temporarily down | Assistant shows "Service is warming up — try again in a moment" instead of broken link |
+| User clicks CTA but preview fails | Preview page shows friendly error with "Go back to chat" button |
+| User refreshes dashboard mid-chat | Chat state is lost — acceptable for MVP; later: conversation persistence |
+| User is on mobile | Modal is full-screen, CTA card is thumb-friendly, no horizontal scroll |
+| User has multiple active missions | Curator picks the most relevant mission context for the task |
+| User is a new Day 1 user | Suggestions are simpler: Q Score baseline, Resume upload, Warm-up interview |
+
+---
+
+## 7. Success Metrics
+
+Once deployed to staging, we will measure:
+
+| Metric | Baseline | Target |
+|--------|----------|--------|
+| Interview preview CTA visibility rate | 0% (broken) | 100% when interview task is active |
+| Roleplay preview CTA visibility rate | 0% (broken) | 100% when roleplay task is active |
+| User reaches preview page after CTA click | N/A | > 90% of clicks |
+| Avg chat turns to preview | N/A | ≤ 2 turns |
+| Chat abandonment rate | N/A | < 20% |
+| Build pass rate | N/A | 100% |
+| Staging smoke test pass | N/A | 100% of test cases |
+
+---
+
+## 8. Dependencies
+
+| Dependency | Status | Owner |
+|------------|--------|-------|
+| Interview service preview page | ✅ Exists | Interview service team |
+| Roleplay service preview page | ⚠️ Needs verification | Roleplay service team |
+| Backend curator routes | ✅ Exists | Backend team |
+| Dashboard streak component | ✅ Exists | Dashboard team |
+| Onboarding → ICP mapping | ✅ Exists | Product (docs) |
+| 30-day plan examples | ✅ Exists | Product (docs) |
+| VPS staging environment | ✅ Running | DevOps |
+
+---
+
+## 9. Open Questions
+
+| # | Question | Impact |
+|---|----------|--------|
+| Q1 | Does roleplay have a true `/preview` route, or should we use `/setup` with pre-filled params? | Determines route generation in backend |
+| Q2 | Should resume handoff go to `/agents/resume` list or directly to editor? | UX flow |
+| Q3 | Should Q Score handoff go to `/analytics` or `/agents/qscore`? | Route decision |
+| Q4 | Do we want the assistant to stream tokens, or is JSON response acceptable for MVP? | Scope / time |
+| Q5 | Should the curator chat be its own separate route from TalkToMe, or share the conversation actor? | Architecture |
+
+---
+
+## 10. Definition of Done
+
+This requirement is **finished** when:
+
+1. ✅ All backend acceptance criteria (B1–B10) pass on staging
+2. ✅ All frontend acceptance criteria (F1–F10) pass on staging
+3. ✅ All product coherence criteria (P1–P5) are verified by stakeholder
+4. ✅ Staging VPS is stable — no crashes, no 500s, no broken routes
+5. ✅ User can click a streak suggestion → chat → preview CTA → preview page → start service, in under 5 interactions
+6. ✅ Prompt file is externalized and editable without code redeploy
+7. ✅ Changes are committed to `staging-rosh` on both repos
+8. ✅ Staging smoke test passes for all 6 test cases (Section 4)
+
+---
+
+## 11. Related Documents
+
+- `docs/curator-icp-task-subtask-playbook.md` — ICP taxonomy and task libraries
+- `docs/curator-icp-comprehensive-playbook.md` — Full service definitions and 30-day plans
+- `docs/curator-30day-examples-by-icp.md` — Copy-pasteable 30-day plans, chat flows, prompt templates
+- `docs/staging-vps-service-deployment-runbook.md` — VPS deployment procedures
+
+---
+
+## 12. Sign-off
+
+| Role | Name | Status |
+|------|------|--------|
+| Product Owner | Rosh | Pending review |
+| Backend Lead | — | Pending assignment |
+| Frontend Lead | — | Pending assignment |
+| QA / Staging | — | Pending test execution |
+
+---
+
+*End of requirements document*
diff --git a/runbook.md b/runbook.md
new file mode 100644
index 0000000..d1c0282
--- /dev/null
+++ b/runbook.md
@@ -0,0 +1,463 @@
+# GrowQR Demo Runbook
+
+Use this when restarting the full local demo after everything has been stopped. It should bring back the workflows dashboard, growqr-app frontend session launchers, backend, Rivet workflow actor runner, interview-service, roleplay-service, QScore service, resume-builder, matchmaking, and the per-user Gitea/OpenCode stack.
+
+## What Must Be Running
+
+- Docker Desktop
+- `qscore-service`: Postgres, Redis, API, worker
+- `interview-service`: API, Postgres, MinIO, bucket setup
+- `roleplay-service`: API, Postgres, MinIO, bucket setup
+- `resume-builder`: Docker container with Postgres (port 5433), API (port 8002)
+- `matchmaking`: API on host port 8006
+- `growqr-backend`: backend Postgres plus local Node backend
+- `workflows--dashboard`: Next.js frontend
+- `growqr-app/frontend`: Next.js frontend for the new interview/roleplay session UI
+- Per-user OpenCode containers, created by backend provisioning (Gitea is central/shared)
+
+The known demo ports are:
+
+- Workflows dashboard: `http://localhost:3000`
+- GrowQR app frontend session launchers: `http://localhost:3002`
+- Backend: `http://localhost:4000`
+- Backend Rivet proxy: `http://localhost:4000/api/rivet`
+- Interview service: `http://localhost:8007`
+- Roleplay service: `http://localhost:8008`
+- QScore service: `http://localhost:8000`
+- Resume builder: `http://localhost:8002`
+- Matchmaking service: `http://localhost:8006`
+- Resume builder DB: `localhost:5433`
+- QScore Redis: `localhost:6379`
+- Central Gitea: `http://localhost:3001` (shared org-wide, changes.md §2A)
+- Backend Postgres: `localhost:5432`
+- Per-user OpenCode containers: dynamically allocated from `20000-29999`
+
+## Required Env Files
+
+Before starting, verify these files exist and contain the local demo values:
+
+- `growqr-backend/.env`
+- `growqr-backend/.env.local`
+- `workflows--dashboard/.env.local`
+- `growqr-app/frontend/.env.local`
+- `interview-service/.env`
+- `roleplay-service/.env`
+- `growqr-app/resume-builder/.env.local` (created by setup script)
+
+Do not print secrets into chat or commit them. The important non-secret shape is:
+
+- Backend service URLs should point to `127.0.0.1`:
+ - `INTERVIEW_SERVICE_URL=http://127.0.0.1:8007`
+ - `ROLEPLAY_SERVICE_URL=http://127.0.0.1:8008`
+ - `QSCORE_SERVICE_URL=http://127.0.0.1:8000`
+ - `RESUME_SERVICE_URL=http://127.0.0.1:8002`
+ - `MATCHMAKING_SERVICE_URL=http://127.0.0.1:8006`
+ - `GROWQR_APP_FRONTEND_URL=http://localhost:3002`
+- Backend per-user containers should use:
+ - `OPENCODE_IMAGE=ghcr.io/anomalyco/opencode:latest`
+ - `USER_CONTAINER_HOST=127.0.0.1`
+ - `USER_DATA_ROOT=./.data/users`
+- Frontend should use:
+ - `NEXT_PUBLIC_RIVET_ENDPOINT=http://127.0.0.1:4000/api/rivet`
+ - `NEXT_PUBLIC_GROWQR_BACKEND_URL=http://127.0.0.1:4000` (NOT `GROWQR_BACKEND_URL` — must have NEXT_PUBLIC_ prefix for client-side)
+ - `OPENCODE_API_KEY=` (must match backend)
+ - `LLM_BASE_URL=https://opencode.ai/zen/v1`
+ - `LLM_MODEL=kimi-k2.6`
+- Resume builder should use:
+ - `DATABASE_URL=postgresql+asyncpg://postgres:postgres@host.docker.internal:5433/growqr_resume` (host.docker.internal when running in Docker, localhost when running locally)
+ - `API_PORT=8002`
+ - `OPENCODE_API_KEY=` — **CRITICAL: must be the EXACT same key as backend.** Both services share the same OpenCode account.
+ - `OPENCODE_BASE_URL=https://opencode.ai/zen/v1`
+ - `AI_MODEL=kimi-k2.6`
+ - `CLERK_JWKS_URL=https://noted-elephant-23.accounts.dev/.well-known/jwks.json`
+ - `CLERK_ISSUER=https://noted-elephant-23.accounts.dev`
+ - `CORS_ORIGINS="http://localhost:3000,http://localhost:3001,http://127.0.0.1:3000"`
+ - `A2A_ALLOWED_KEYS=dev-a2a-key`
+ - `REDIS_URL=redis://host.docker.internal:6379/0`
+ - `DEBUG=true`
+- `SERVICE_TOKEN` and `A2A_ALLOWED_KEY` must match across backend and services.
+- Clerk keys must match between frontend and backend.
+- Gemini and OpenCode keys must be present for the audio/session and LLM paths.
+
+### OpenCode API Key Sync (IMPORTANT)
+
+The backend and resume-builder share the same OpenCode API key. When copying values, always use `growqr-backend/.env` as the **source of truth**. The resume-builder's `.env.local` was previously out of sync (25-char dummy key vs 67-char real key), causing silent LLM failures.
+
+To verify keys are synced:
+```bash
+diff <(grep OPENCODE_API_KEY growqr-backend/.env | head -1) <(grep OPENCODE_API_KEY growqr-app/resume-builder/.env.local | head -1)
+# Should show no differences
+```
+
+Note: interview-service and roleplay-service use Gemini (not OpenCode) — they don't need an OpenCode key.
+
+## Start Order
+
+Run all commands from `/Users/divyansh/Desktop/growQR` unless a command changes directory.
+
+### 0. Start Central Gitea first (NEW per changes.md §2A)
+
+The central Gitea is now a shared compose service in the backend's docker-compose. **Note:** Gitea health check uses port 3000 internally (container), mapped to 3001 on host. Port mapping is `3001:3000`.
+
+```bash
+docker compose -f growqr-backend/docker-compose.yml up -d gitea
+```
+
+Wait until Gitea is healthy (~30 seconds on first startup):
+
+```bash
+curl http://127.0.0.1:3001/api/v1/version
+# Expected: {"version":"1.22.6"}
+```
+
+Per-user Gitea containers are NO LONGER spawned dynamically. All users share the central Gitea instance with one repo per user under the `growqr` org.
+
+### 1. Start QScore first
+
+QScore owns the Redis instance exposed on `localhost:6379`. The interview service currently uses that host Redis for workflow task dispatch, so QScore should come up first.
+
+```bash
+docker compose -f qscore-service/docker-compose.yml up -d --build
+```
+
+Wait until all QScore containers are healthy/running:
+
+```bash
+docker compose -f qscore-service/docker-compose.yml ps
+curl http://127.0.0.1:8000/health
+# Expected: {"status":"ok"}
+```
+
+### 2. Start Interview Service
+
+```bash
+docker compose -f interview-service/docker-compose.yml up -d --build
+```
+
+Verify:
+
+```bash
+curl http://127.0.0.1:8007/health
+# Expected: {"status":"ok","service":"interview-service","a2a":true,"agent":true}
+```
+
+### 3. Start Roleplay Service
+
+```bash
+docker compose -f roleplay-service/docker-compose.yml up -d --build
+```
+
+Verify:
+
+```bash
+curl http://127.0.0.1:8008/health
+# Expected: {"status":"ok","service":"roleplay-service","a2a":true,"agent":true}
+```
+
+### 4. Start Resume Builder (NEW)
+
+The resume builder runs as a Docker container built from `growqr-app/resume-builder/Dockerfile`. It uses its own Postgres database on port 5433.
+
+```bash
+# Start resume-builder Postgres
+docker compose -f growqr-app/resume-builder/docker-compose.yml up -d postgres
+
+# Build resume-builder image (first time only)
+docker build -t growqr-resume-builder growqr-app/resume-builder
+
+# Run migrations
+cd growqr-app/resume-builder
+uv run --env-file .env.local alembic upgrade head
+
+# Start the service with synced OpenCode key from backend
+cd /Users/divyansh/Desktop/growQR
+OPENCODE_KEY=$(grep OPENCODE_API_KEY growqr-backend/.env | head -1 | cut -d= -f2)
+
+docker rm -f growqr-resume-builder 2>/dev/null
+docker run -d --name growqr-resume-builder \
+ -p 8002:8002 \
+ -e DATABASE_URL=postgresql+asyncpg://postgres:postgres@host.docker.internal:5433/growqr_resume \
+ -e OPENCODE_API_KEY="${OPENCODE_KEY}" \
+ -e OPENCODE_BASE_URL=https://opencode.ai/zen/v1 \
+ -e AI_MODEL=kimi-k2.6 \
+ -e CLERK_JWKS_URL=https://noted-elephant-23.accounts.dev/.well-known/jwks.json \
+ -e CLERK_ISSUER=https://noted-elephant-23.accounts.dev \
+ -e CORS_ORIGINS="http://localhost:3000,http://localhost:3001,http://127.0.0.1:3000" \
+ -e A2A_ALLOWED_KEYS=dev-a2a-key \
+ -e REDIS_URL=redis://host.docker.internal:6379/0 \
+ -e DEBUG=true \
+ growqr-resume-builder uvicorn app.main:app --host 0.0.0.0 --port 8002
+
+# Verify
+curl http://127.0.0.1:8002/health
+# Expected: {"status":"healthy","service":"resume-builder","mcp":true,"agent":true,"a2a":true}
+```
+
+### 5. Start Backend Postgres
+
+For the demo path that avoids Rivet `no_capacity`, run the backend locally with its embedded Rivet runner and start only the backend Postgres from compose:
+
+```bash
+docker compose -f growqr-backend/docker-compose.yml up -d postgres
+```
+
+**Important:** If the backend was previously running with older schema, you may need to add missing columns:
+
+```bash
+docker exec growqr-postgres psql -U growqr -d growqr -c "
+ ALTER TABLE user_stacks ADD COLUMN IF NOT EXISTS gitea_repo_name TEXT;
+ ALTER TABLE user_stacks ADD COLUMN IF NOT EXISTS gitea_repo_owner TEXT;
+ ALTER TABLE user_stacks ADD COLUMN IF NOT EXISTS image_version TEXT;
+ ALTER TABLE user_stacks ADD COLUMN IF NOT EXISTS migration_version TEXT;
+ ALTER TABLE user_stacks ADD COLUMN IF NOT EXISTS prompt_version TEXT;
+"
+```
+
+Then migrate:
+
+```bash
+cd /Users/divyansh/Desktop/growQR/growqr-backend
+npm run db:migrate
+```
+
+Start the backend:
+
+```bash
+cd /Users/divyansh/Desktop/growQR/growqr-backend
+RIVET_RUN_ENGINE=1 npm run dev
+```
+
+Keep this terminal open. Verify in a separate terminal:
+
+```bash
+curl http://127.0.0.1:4000/healthz
+# Expected: {"ok":true}
+```
+
+The backend will auto-provision OpenCode containers for existing users on boot (reconcileOnBoot).
+
+### 6. Start Matchmaking
+
+The matchmaking service powers the Scout/job-search handoff. It runs on port 8000 internally and port 8006 on the host.
+
+```bash
+docker compose -f matchmaking/docker-compose.yml up -d --build
+curl http://127.0.0.1:8006/api/v1/health
+# Expected: {"status":"healthy", ...}
+```
+
+### 7. Start Frontends
+
+Start the dashboard on port 3000:
+
+```bash
+cd /Users/divyansh/Desktop/growQR/workflows--dashboard
+npm run build
+npm run start
+```
+
+Start the growqr-app frontend on port 3002. This app now owns the product UI for interview and roleplay sessions launched from workflow chat.
+
+```bash
+cd /Users/divyansh/Desktop/growQR/growqr-app/frontend
+npm install --legacy-peer-deps
+npm run dev -- -p 3002
+```
+
+Keep both terminals open. Open:
+
+```text
+http://localhost:3000/v2/workflows
+```
+
+## Provision OpenCode Containers
+
+OpenCode containers are per-user and spawned dynamically by the backend Docker manager. Gitea is NO LONGER per-user — it's a central shared service (changes.md §2A).
+
+After provisioning, `docker ps` should show containers with names like:
+
+```text
+growqr-opencode-user_
+```
+
+If they are missing, sign into the dashboard and allow the user stack bootstrap to run. The local data is under:
+
+```text
+growqr-backend/.data/users
+```
+
+That folder is intentionally gitignored and should stay local.
+
+## Demo Path — Interview-to-Offer Accelerator
+
+Use this path for the Interview-to-Offer workflow demo:
+
+1. Open `http://localhost:3000/v2/workflows`.
+2. Type in the chat: `I have an interview at Google for SWE`
+3. The AI responds with a conversational message and the **WorkflowDiscovery card** (red, 4 agents, 4 steps) appears below.
+4. Click **"Start this workflow"** on the card.
+5. The workflow progresses step-by-step:
+ - **Step 1**: AI asks for job description → you respond with details
+ - **Step 2**: AI asks for resume → you respond
+ - **Step 3**: Resume Agent analyzes and tailors (shows "DONE")
+ - **Step 4**: Sara interview session ready → shows **"Open" button**
+ - **Step 5**: Emily roleplay session ready → shows **"Open" button**
+ - **Step 6**: Quinn computes Q-Score → shows results
+6. Click **Open** on Sara's card → new tab opens `http://localhost:3002/service-sessions/interview?session_id=...`
+7. On the new GrowQR interview launcher, click **Start interview** and allow microphone/camera access.
+8. Click **Open** on Emily's card → new tab opens `http://localhost:3002/service-sessions/roleplay?session_id=...`
+9. On the new GrowQR roleplay launcher, click **Start roleplay** and allow microphone/camera access.
+10. Completed steps are marked with **green checkmarks** in the chat.
+
+### Alternative Workflow Trigger Queries
+
+| Workflow | Trigger Query |
+|---|---|
+| Interview-to-Offer | `I have an interview at Google for SWE` |
+| Career Switch | `I want to switch from marketing to product management` |
+| Resume Boost | `My resume isn't getting any responses` |
+| Job Search | `Find me backend engineering jobs` |
+| Job Preparation | `Prepare me for a role at Stripe` |
+
+Direct service demo pages are for low-level service debugging only. Product workflow links should use the new `growqr-app/frontend` launchers:
+
+```text
+http://localhost:3002/service-sessions/interview?session_id=
+http://localhost:3002/service-sessions/roleplay?session_id=
+```
+
+## Health Checks
+
+Use these after startup:
+
+```bash
+curl http://127.0.0.1:4000/healthz # Backend
+curl http://127.0.0.1:8007/health # Interview
+curl http://127.0.0.1:8008/health # Roleplay
+curl http://127.0.0.1:8000/health # QScore
+curl http://127.0.0.1:8002/health # Resume builder
+curl http://127.0.0.1:8006/api/v1/health # Matchmaking
+curl -I 'http://localhost:3002/service-sessions/interview?session_id=demo-interview'
+curl -I 'http://localhost:3002/service-sessions/roleplay?session_id=demo-roleplay'
+curl http://127.0.0.1:3001/api/v1/version # Gitea
+docker ps # All containers
+```
+
+If the workflow actor fails with `no_capacity`, restart the backend with:
+
+```bash
+cd /Users/divyansh/Desktop/growQR/growqr-backend
+RIVET_RUN_ENGINE=1 npm run dev
+```
+
+## Shutdown
+
+Stop frontend and backend with `Ctrl+C` in their terminals.
+
+**Also kill any lingering backend Node processes:**
+```bash
+pkill -f "tsx watch" 2>/dev/null
+pkill -f "tsx.*src/index" 2>/dev/null
+```
+
+Stop compose services:
+
+```bash
+docker compose -f growqr-backend/docker-compose.yml down
+docker compose -f interview-service/docker-compose.yml down
+docker compose -f roleplay-service/docker-compose.yml down
+docker compose -f qscore-service/docker-compose.yml down
+docker compose -f matchmaking/docker-compose.yml down
+docker compose -f growqr-app/resume-builder/docker-compose.yml down
+docker rm -f growqr-resume-builder
+```
+
+Stop per-user OpenCode containers if still running:
+
+```bash
+docker ps --filter "name=growqr-opencode-user"
+```
+
+Then stop/remove the shown containers by name:
+
+```bash
+docker stop
+docker rm
+```
+
+They can be recreated later by the backend provisioning flow. The local persistent data remains in `growqr-backend/.data/users`.
+
+## Build Rule
+
+Whenever code changes are made, run the relevant build before calling the demo ready:
+
+```bash
+cd /Users/divyansh/Desktop/growQR/growqr-backend && npm run build
+cd /Users/divyansh/Desktop/growQR/workflows--dashboard && npm run build
+cd /Users/divyansh/Desktop/growQR/growqr-app/frontend && npm run build
+```
+
+For Dockerized Python services, rebuild with their compose commands:
+
+```bash
+docker compose -f interview-service/docker-compose.yml up -d --build
+docker compose -f roleplay-service/docker-compose.yml up -d --build
+docker compose -f qscore-service/docker-compose.yml up -d --build
+```
+
+## Agent Architecture & Flow
+
+The system has 5 real service-backed agents:
+
+| Agent | Name | Service | Port | Provider | Creates |
+|---|---|---|---|---|---|
+| Resume Agent | Mira | resume-builder | 8002 | OpenCode (kimi-k2.6) | Resume analysis + tailoring |
+| Interview Agent | Sara | interview-service + growqr-app frontend launcher | 8007 + 3002 | Gemini (audio) | Live interview sessions in new UI |
+| Roleplay Agent | Emily | roleplay-service + growqr-app frontend launcher | 8008 + 3002 | Gemini (audio) | Roleplay scenario sessions in new UI |
+| Q-Score Agent | Quinn | qscore-service | 8000 | Internal formula | Readiness scores |
+| Job Search Agent | Scout | matchmaking | 8006 | Internal ranking engine | Ranked opportunity feed |
+
+### Chat Flow (Conversational Step-by-Step)
+
+1. User types message → Frontend sends to `POST http://127.0.0.1:4000/api/chat` (with Clerk auth)
+2. Backend tries Rivet actor first, falls back to direct LLM with tools
+3. LLM responds conversationally OR calls a tool (`start_interview_session`, `analyze_resume`, etc.)
+4. If tool is called, backend executes it against the real microservice
+5. Response includes `{ reply, sessions[], workflow }` — sessions contain real URLs
+6. Frontend renders agent cards with photos, status badges, and **Open** buttons
+
+### Trigger Queries (what to type)
+
+| For this agent | Type this |
+|---|---|
+| Resume analysis | `analyze my resume for Google SWE` |
+| Interview session | `launch a behavioral interview for Software Engineer at Google` |
+| Roleplay session | `launch a roleplay for negotiating a Google offer` |
+| Q-Score | `compute my Q-Score` |
+| Full workflow | `I have an interview at Google for SWE` |
+
+### Session URLs
+
+When a session is created, the backend preserves the `session_id` from the service configure response and returns one of these product URLs:
+
+- Interview: `http://localhost:3002/service-sessions/interview?session_id=&role=&type=`
+- Roleplay: `http://localhost:3002/service-sessions/roleplay?session_id=&goal=&type=`
+
+The old direct demo pages still exist for service debugging, but workflow chat should not link to them.
+
+### Key Files
+
+- System prompt: `growqr-backend/prompts/system.txt`
+- Agent definitions: `growqr-backend/agents/*.md`
+- Service probes: `growqr-backend/src/services/service-agents.ts`
+- Chat route (with tool dispatch): `growqr-backend/src/routes/chat.ts`
+- Frontend chat component: `workflows--dashboard/src/components/home-v2/GrowChat.tsx`
+- New service launchers: `growqr-app/frontend/src/app/service-sessions/interview/page.tsx`, `growqr-app/frontend/src/app/service-sessions/roleplay/page.tsx`
+- Product flow requirements: `.growqr_memory.md`
+
+### Known Quirks
+
+- **Roleplay configure is slow** (30-60s): The roleplay service calls an LLM to generate scenarios. Be patient.
+- **Rivet `/actors` returns 400**: Cosmetic console warning from the Rivet frontend SDK. Does not affect chat — chat uses HTTP fallback.
+- **Rivet proxy vs handler conflict**: When `RIVET_RUN_ENGINE=1`, the backend proxies `/api/rivet/*` to the engine at `localhost:6420` instead of using `registry.handler()`. This avoids the "Runtime already started as runner" error.
+- **Multiple backend processes**: `tsx watch` sometimes spawns orphans. Always `pkill -f "tsx watch"` before restarting.
diff --git a/sellable-workflows-catalog.md b/sellable-workflows-catalog.md
new file mode 100644
index 0000000..7dd5e02
--- /dev/null
+++ b/sellable-workflows-catalog.md
@@ -0,0 +1,615 @@
+# GrowQR Market-Aligned Sellable Workflows Catalog
+
+This catalog is intentionally **not constrained by the primitives GrowQR has today**. It uses the current primitives inventory as an implementation reference, but the portfolio is organized around the broader market described by the GrowQR landing page: **one career identity, specialized AI agents, human experts, QX score, verified achievements, deep matching, and workflows for Students, Individuals, Coaches, Freelancers, Startups, Recruiters, Enterprises, and Institutes.**
+
+The product surface is not “Resume Builder + Interview Tool + Matchmaking.” The product surface is:
+
+> **Your career/opportunity co-pilot: an AI agent squad plus human experts that turns identity, skills, proof, and ambition into outcomes.**
+
+---
+
+## 1. Landing Page Positioning Signals
+
+The workflow catalog should map to these public promises.
+
+### 1.1 Core promise
+
+- **One QR for everything you are** — a portable career/professional identity.
+- **QX-Score** — 25 signals condensed into a meaningful readiness/trust score.
+- **Personalized AI** — agents learn as the user grows.
+- **Verified achievements** — proof that cannot be faked.
+- **Deep matching** — matching across jobs, gigs, internships, teams, courses, mentors, and opportunities.
+- **Human intelligence** — coaches, mentors, experts, interviewers, and advisors when AI is not enough.
+
+### 1.2 Public agent squad
+
+| Agent | Market role |
+|---|---|
+| Scout — Opportunity Finder | Finds jobs, internships, gigs, candidates, clients, and other opportunities |
+| Mira — Resume Expert | Converts user history into strong applications/profiles |
+| Vera — Interviewer | Simulates and scores real interviews |
+| Kai — Roleplay Coach | Practices hard professional conversations |
+| Nova — Brand Voice | Builds public visibility, positioning, and content |
+| Sage — Skill Trainer | Diagnoses gaps and builds improvement plans |
+| Lyra — Learning Curator | Curates courses and learning paths |
+| Atlas — Pathway Guide | Maps career options, pivots, and next steps |
+| Drape — Presence Coach | Coaches appearance, speech, room presence, and professional behavior |
+
+### 1.3 Market segments from the landing page
+
+| Segment | Landing-page ambition | Workflow implication |
+|---|---|---|
+| Students | Discover career fit, land first internship, learn relevant skills | B2C + institutional placement-readiness products |
+| Individuals | Find a job that fits who they are | Job search, career fit, interview, resume, brand, negotiation |
+| Coaches | Find clients who value and pay for their work | Expert marketplace, client pipeline, outcome proof |
+| Freelancers | Find gigs that respect their skills and rates | Gig matching, pricing, portfolio, client acquisition |
+| Startups | Build the right team from day one | Team design, candidate matching, early hiring workflows |
+| Recruiters | Find the right candidate fast | Candidate intelligence, screening, matching, pipeline products |
+| Enterprises | Keep best people happy | Retention, internal mobility, upskilling, manager intelligence |
+| Institutes | Make every student placement-ready | Cohort readiness, placement ops, employer matching |
+
+---
+
+## 2. Coherence Filter
+
+A workflow is top-level only if it satisfies most of these:
+
+1. **Market-facing ambition:** It maps to a named user/segment ambition.
+2. **Outcome promise:** It changes a real-world state: hired, matched, promoted, retained, paid, certified, placed, booked, or discovered.
+3. **Economic buyer:** Someone has a clear reason to pay: user, parent, institution, employer, recruiter, startup, coach, or freelancer.
+4. **Repeatability:** It can be rerun daily/weekly/monthly or across cohorts/pipelines.
+5. **Data compounding:** It strengthens the QR identity, QX score, talent graph, or verified achievement layer.
+6. **Human escalation:** It can route to a coach, mentor, interviewer, advisor, or expert when trust matters.
+7. **Marketplace potential:** It can create supply/demand liquidity across users, experts, jobs, gigs, institutions, and employers.
+
+### 2.1 What is not a top-level workflow
+
+| Idea | Better treatment |
+|---|---|
+| Resume Builder | Capability inside application, career identity, and job workflows |
+| Interview Tool | Capability inside job, internship, promotion, and recruiter workflows |
+| Roleplay Tool | Capability inside negotiation, sales, leadership, interview, and presence workflows |
+| QX Score | Measurement/trust layer across all workflows |
+| Opportunity Feed | Reusable surface inside job, internship, freelance, startup, recruiter, and institute workflows |
+| Marketplace Human Expert | Escalation/add-on layer across workflows |
+| LinkedIn Growth | Variant of visibility/brand workflows |
+| Courses | Capability inside skill, placement, retention, and transition workflows |
+| QR Profile | Identity substrate; can have its own onboarding workflow, but its bigger value is network-wide |
+
+---
+
+## 3. Value Ranking Method
+
+The workflows below are sorted from **least to most valuable** by broader market/TAM potential, not by current implementation readiness.
+
+Ranking factors:
+
+- **TAM / buyer pool size**
+- **ACV / willingness to pay**
+- **Urgency and budget ownership**
+- **Recurring revenue potential**
+- **Network effects and data moat**
+- **Cross-segment leverage**
+- **Outcome measurability**
+- **Strategic fit with GrowQR landing-page promise**
+
+---
+
+## 4. Market-Aligned Workflow Portfolio — Least to Most Valuable
+
+### 1. Presence & Room Readiness Coach
+
+**Primary segment:** Individuals, students, founders, leaders, interview candidates
+**Value level:** Low-to-medium, high emotional appeal
+**Promise:** “Tell me how to show up, speak, dress, and carry myself for this room.”
+
+**Why it exists:** The landing page introduces Drape, the Presence Coach. This is distinctive and emotionally resonant, but narrower than hiring, retention, or placement workflows.
+
+**Example use cases:** Interview outfit/readiness, first day at work, investor meeting, sales meeting, presentation, networking event, conference.
+
+**Outputs:** Presence plan, dress guidance, speaking cues, room-specific checklist, roleplay practice, confidence score.
+
+**Business model:** Low-cost one-time pack, premium add-on before interviews/events, coach upsell.
+
+**Memory/data created:** Presence preferences, event contexts, confidence deltas, accepted/rejected recommendations.
+
+---
+
+### 2. Career QR Identity Setup
+
+**Primary segment:** Everyone
+**Value level:** Low direct monetization, high strategic acquisition
+**Promise:** “Create one trusted QR identity for everything I am professionally.”
+
+**Why it exists:** This is the foundation of the public promise: “One QR for everything you are.” It should likely be free or freemium because its main value is identity adoption and data compounding.
+
+**Outputs:** Public/private QR profile, professional summary, skills, goals, proof links, portfolio, share settings, baseline QX score.
+
+**Business model:** Free acquisition, premium profile enhancements, verification/credential upgrades, recruiter/employer unlocks.
+
+**Memory/data created:** Identity graph, sharing permissions, profile claims, verified artifacts, baseline score.
+
+---
+
+### 3. Skill Gap & Learning Sprint
+
+**Primary segment:** Students, individuals, enterprises, institutes
+**Value level:** Medium
+**Promise:** “Show me the exact skills blocking my next move and the shortest path to close them.”
+
+**Why it ranks here:** Huge market, but crowded and indirect unless tied to a concrete opportunity, placement, promotion, or retention goal.
+
+**Outputs:** Skill diagnosis, QX gap map, curated courses, project plan, assessment checkpoints, proof artifacts.
+
+**Business model:** Individual sprint, course affiliate revenue, institute/enterprise cohort plans, marketplace tutor/mentor upsell.
+
+**Memory/data created:** Skill graph, course progress, assessment outcomes, verified learning artifacts.
+
+---
+
+### 4. Career Discovery & Pathway Fit
+
+**Primary segment:** Students, early-career users, career changers
+**Value level:** Medium
+**Promise:** “Help me discover what career actually fits me.”
+
+**Why it ranks here:** Broad appeal and excellent onboarding, but payment urgency varies. It is a strong top-of-funnel workflow that routes users into higher-value outcomes.
+
+**Outputs:** Career identity statement, pathway map, close/adjacent/stretch options, QX baseline, gap map, recommended opportunities and learning paths.
+
+**Business model:** Free diagnostic, premium report, parent/student package, institute package, coach debrief.
+
+**Memory/data created:** Ambition graph, pathway selection, preference data, strengths/weaknesses, long-term career plan.
+
+---
+
+### 5. Resume, Profile & Application Conversion Kit
+
+**Primary segment:** Individuals, students, freelancers, coaches
+**Value level:** Medium-high
+**Promise:** “Turn my experience into materials that convert.”
+
+**Why it ranks here:** Clear buyer intent and easy to understand. It is still usually a conversion component inside bigger job, internship, freelance, or coaching-client workflows.
+
+**Outputs:** Resume, cover letter, LinkedIn/profile rewrite, portfolio narrative, pitch bio, job/gig-specific variants.
+
+**Business model:** One-time purchase, per-application variant, premium human review, bundled with job/internship/gig search.
+
+**Memory/data created:** Reusable narrative, achievements, proof points, target-role language, conversion history.
+
+---
+
+### 6. Interview & Roleplay Gym
+
+**Primary segment:** Job seekers, students, salespeople, managers, founders
+**Value level:** High
+**Promise:** “Practice the real conversation before it matters.”
+
+**Why it ranks here:** Strong urgency when an interview, sales call, negotiation, conflict, pitch, or presentation is near. Also has subscription potential as a professional practice gym.
+
+**Outputs:** Mock interviews, roleplay sessions, transcripts, rubric scores, improvement plan, confidence trend, expert escalation.
+
+**Business model:** One-time bootcamp, daily/weekly practice subscription, human interviewer/coach marketplace add-on, enterprise training package.
+
+**Memory/data created:** Communication signals, behavior trends, readiness scores, role-specific practice history.
+
+---
+
+### 7. Personal Brand & Visibility Engine
+
+**Primary segment:** Individuals, coaches, freelancers, founders, executives
+**Value level:** High
+**Promise:** “Make the right market notice and trust me.”
+
+**Why it ranks here:** Broad market and recurring potential. It is especially valuable for freelancers/coaches/founders where visibility directly affects revenue.
+
+**Outputs:** Positioning, content pillars, profile rewrites, post drafts, portfolio proof, audience plan, brand score, engagement strategy.
+
+**Business model:** Monthly subscription, ghostwriter/coach upsell, freelancer/coach revenue packages, enterprise advocacy variant.
+
+**Memory/data created:** Brand voice, audience response, market positioning, proof library, content performance.
+
+---
+
+### 8. First Internship / First Job Launchpad
+
+**Primary segment:** Students, parents, institutes
+**Value level:** High
+**Promise:** “Get me from student to placement-ready, then into my first real opportunity.”
+
+**Why it ranks here:** Strong emotional buyer, large global market, and B2B2C potential through institutes. Higher value than generic career discovery because the outcome is concrete.
+
+**Outputs:** Student QR, readiness score, internship-ready resume, skill plan, opportunity shortlist, mock interview prep, weekly application plan, placement dashboard.
+
+**Business model:** Student/parent package, institute cohort license, placement success fee, employer-sponsored talent pool.
+
+**Memory/data created:** Student readiness graph, placement status, verified projects, cohort benchmarks, employer feedback.
+
+---
+
+### 9. Job Fit & Apply Autopilot
+
+**Primary segment:** Individuals, active job seekers, passive switchers
+**Value level:** Very high
+**Promise:** “Find roles that actually fit me and help me apply well.”
+
+**Why it ranks here:** Direct employment outcome, high urgency, recurring usage, and strong fit with Scout + Mira + Vera + Nova.
+
+**Outputs:** Matched roles, fit explanations, tailored materials, outreach messages, tracker, interview prep, follow-up reminders.
+
+**Business model:** Premium subscription, per-application sprint, success premium, expert resume/interview upsell.
+
+**Memory/data created:** Job preferences, applied/rejected/advanced outcomes, fit signal feedback, employer response data.
+
+---
+
+### 10. Freelancer / Coach Revenue Engine
+
+**Primary segment:** Freelancers, coaches, mentors, advisors, experts
+**Value level:** Very high
+**Promise:** “Find clients who value my expertise and help me sell at the right price.”
+
+**Why it ranks here:** The landing page explicitly targets coaches and freelancers, not just job seekers. This opens a creator/service-provider TAM and seeds the human expert marketplace.
+
+**Outputs:** Offer packaging, pricing guidance, QR service profile, credibility proof, lead list, outreach drafts, client call roleplay, booking funnel.
+
+**Business model:** Monthly business-growth subscription, marketplace take rate, lead-gen fee, premium positioning package.
+
+**Memory/data created:** Expert supply graph, service outcomes, conversion rates, pricing signals, verified client results.
+
+---
+
+### 11. Startup Team Builder
+
+**Primary segment:** Startups, founders, early teams
+**Value level:** Very high
+**Promise:** “Help me design and hire the right early team.”
+
+**Why it ranks here:** Higher ACV than individual workflows and direct hiring pain. It can connect candidate QR profiles, QX scores, interviews, roleplays, and advisor support.
+
+**Outputs:** Team gap map, role specs, candidate shortlist, fit explanations, interview kits, founder-candidate roleplays, offer/closing guidance.
+
+**Business model:** Startup subscription, per-role fee, success fee, advisor add-on.
+
+**Memory/data created:** Startup team graph, role requirements, candidate fit outcomes, hiring signal data.
+
+---
+
+### 12. Recruiter Candidate Intelligence Workflow
+
+**Primary segment:** Recruiters, staffing firms, hiring teams
+**Value level:** Very high
+**Promise:** “Find the right candidate faster, with more signal and less noise.”
+
+**Why it ranks here:** Recruiters already have budget, urgency, and repeated demand. GrowQR’s differentiation is verified identity, QX score, deep matching, and practice/performance signals.
+
+**Outputs:** Ranked candidate lists, fit explanations, verified profile summaries, outreach drafts, screening packs, interview signals, pipeline analytics.
+
+**Business model:** Recruiter seats, usage-based search credits, candidate unlocks, pipeline subscription, placement fee.
+
+**Memory/data created:** Demand-side matching signals, recruiter feedback, candidate market value, hiring outcomes.
+
+---
+
+### 13. Institute Placement-Readiness OS
+
+**Primary segment:** Universities, colleges, bootcamps, training institutes
+**Value level:** Very high / enterprise-scale
+**Promise:** “Make every student placement-ready and prove progress to employers.”
+
+**Why it ranks here:** Large cohorts, institutional budgets, measurable outcomes, and strong alignment with students + first internship/job + verified achievements.
+
+**Outputs:** Cohort dashboard, student QX baselines, readiness tracks, resume/interview completion, employer-ready QR profiles, placement pipeline, at-risk student alerts.
+
+**Business model:** Annual SaaS per institution, per-student fee, placement success fee, employer sponsorship, premium coaching packages.
+
+**Memory/data created:** Cohort benchmark graph, placement readiness data, verified achievement records, employer feedback loops.
+
+---
+
+### 14. Enterprise Retention & Internal Mobility OS
+
+**Primary segment:** Enterprises, HR, talent development, people leaders
+**Value level:** Highest ACV
+**Promise:** “Keep our best people happy by matching them to growth, mobility, learning, and managers before they leave.”
+
+**Why it ranks here:** Enterprise retention has large budgets and urgent ROI. Losing high performers is expensive. This expands GrowQR from career acquisition into workforce intelligence.
+
+**Outputs:** Employee growth QR, internal mobility matches, skill gap plans, manager coaching scripts, flight-risk signals, learning recommendations, internal gig marketplace.
+
+**Business model:** Enterprise SaaS, per-employee pricing, talent marketplace module, coaching marketplace take rate, analytics add-on.
+
+**Memory/data created:** Workforce skill graph, internal opportunity graph, retention signals, manager/team health, growth-path outcomes.
+
+---
+
+### 15. Verified Talent & Opportunity Network
+
+**Primary segment:** All segments
+**Value level:** Highest strategic TAM / network moat
+**Promise:** “Create a trusted network where people, proof, opportunities, experts, employers, and institutions match through verified identity and outcomes.”
+
+**Why it ranks highest:** This is bigger than a workflow. It is the market network implied by the landing page: QR identity + QX score + verified achievements + AI agents + human experts + deep matching. Every workflow feeds it; every participant makes it more valuable.
+
+**Network participants:** Students, workers, freelancers, coaches, mentors, recruiters, employers, startups, enterprises, institutes, course providers.
+
+**Outputs:** Verified profiles, achievement credentials, opportunity graph, expert marketplace, matching APIs, trust scores, outcome records.
+
+**Business model:** Multi-sided marketplace take rate, enterprise/institute SaaS, recruiter access, verification fees, premium identity, API/data products, success fees.
+
+**Memory/data created:** Durable talent graph, proof graph, opportunity graph, outcome graph, reputation graph.
+
+---
+
+## 5. Portfolio Organization by Market Segment
+
+### Students
+
+- Career Discovery & Pathway Fit
+- First Internship / First Job Launchpad
+- Skill Gap & Learning Sprint
+- Interview & Roleplay Gym
+- Career QR Identity Setup
+- Institute Placement-Readiness OS
+
+### Individuals
+
+- Job Fit & Apply Autopilot
+- Resume, Profile & Application Conversion Kit
+- Interview & Roleplay Gym
+- Personal Brand & Visibility Engine
+- Salary/negotiation and presence variants
+- Career Discovery & Pathway Fit
+
+### Coaches / Mentors / Advisors
+
+- Freelancer / Coach Revenue Engine
+- Personal Brand & Visibility Engine
+- Career QR Identity Setup
+- Verified Talent & Opportunity Network
+- Human expert marketplace integrations
+
+### Freelancers
+
+- Freelancer / Coach Revenue Engine
+- Personal Brand & Visibility Engine
+- Interview & Roleplay Gym for sales/client calls
+- Resume/Profile Conversion Kit adapted to portfolio/pitch
+- Opportunity matching for gigs
+
+### Startups
+
+- Startup Team Builder
+- Recruiter Candidate Intelligence Workflow
+- Founder brand/presence variants
+- Verified Talent & Opportunity Network
+
+### Recruiters
+
+- Recruiter Candidate Intelligence Workflow
+- Verified Talent & Opportunity Network
+- Interview/screening automation
+- Candidate outreach and pipeline workflows
+
+### Enterprises
+
+- Enterprise Retention & Internal Mobility OS
+- Skill Gap & Learning Sprint at workforce scale
+- Interview & Roleplay Gym for management/sales/customer roles
+- Personal Brand/employee advocacy variants
+
+### Institutes
+
+- Institute Placement-Readiness OS
+- First Internship / First Job Launchpad
+- Skill Gap & Learning Sprint
+- Recruiter/employer matching portal
+- Verified achievement/credential layer
+
+---
+
+## 6. Practical Launch Sequencing
+
+### Phase 1 — Prove individual value and identity adoption
+
+1. Career QR Identity Setup
+2. Career Discovery & Pathway Fit
+3. Resume, Profile & Application Conversion Kit
+4. Job Fit & Apply Autopilot
+5. Interview & Roleplay Gym
+
+### Phase 2 — Build recurring usage and marketplace supply
+
+6. Personal Brand & Visibility Engine
+7. Skill Gap & Learning Sprint
+8. Freelancer / Coach Revenue Engine
+9. Human expert escalation across workflows
+
+### Phase 3 — Expand into B2B/B2B2C
+
+10. First Internship / First Job Launchpad
+11. Institute Placement-Readiness OS
+12. Startup Team Builder
+13. Recruiter Candidate Intelligence Workflow
+
+### Phase 4 — Build the strategic platform moat
+
+14. Enterprise Retention & Internal Mobility OS
+15. Verified Talent & Opportunity Network
+
+---
+
+## 7. Workflow Creation Template for Broader TAM
+
+Use this when creating new workflows. It deliberately starts from market and TAM, not from current implementation.
+
+```md
+# Workflow: {Name}
+
+## 1. Segment and Buyer
+- User segment:
+- Economic buyer:
+- Budget owner:
+- Buyer type: B2C / B2B / B2B2C / marketplace / platform
+- Landing-page ambition this maps to:
+
+## 2. User Promise
+One sentence in the user's language:
+“Help me {achieve concrete outcome}.”
+
+## 3. Market/TAM Hypothesis
+- How many people/organizations have this problem?
+- How often does the problem occur?
+- What do they already spend money on instead?
+- What is the current alternative?
+- Why can GrowQR be 10x better?
+
+## 4. Urgency and Trigger Moment
+- Trigger event:
+- Deadline or pain intensity:
+- Why now?
+- What happens if the user does nothing?
+
+## 5. Willingness to Pay
+- ROI logic:
+- Emotional value:
+- Suggested price model:
+- Expansion/upsell path:
+
+## 6. Outcome Definition
+- Primary outcome:
+- Secondary outcomes:
+- What would count as success in 7 days?
+- What would count as success in 30/90 days?
+
+## 7. Workflow Scope
+- Start state:
+- End state:
+- In scope:
+- Out of scope:
+- Human escalation moments:
+
+## 8. Agent Squad
+- Lead agent:
+- Supporting agents:
+- Human expert type:
+- New capability needed if not currently available:
+
+## 9. Step Sequence
+1. Capture ambition and context.
+2. Build or update QR identity.
+3. Establish baseline QX/readiness/trust score.
+4. Diagnose gaps or opportunities.
+5. Generate plan/options.
+6. Ask for approval at first major decision.
+7. Execute or prepare artifacts.
+8. Match to opportunities/people/resources.
+9. Escalate to human expert if needed.
+10. Verify outputs/outcomes where possible.
+11. Save memory and update score/profile.
+12. Recommend next workflow or recurring cadence.
+
+## 10. Data and Network Effects
+- What new data does this create?
+- How does it improve matching?
+- How does it improve QX score?
+- How does it strengthen the QR identity?
+- Does it add supply, demand, proof, or outcomes to the network?
+
+## 11. Outputs and Artifacts
+- User-facing artifacts:
+- Buyer/admin artifacts:
+- Public/shareable artifacts:
+- Verified artifacts:
+
+## 12. Approval and Trust Gates
+- What requires explicit user approval?
+- What requires admin/buyer approval?
+- What can be automated safely?
+- What must never be automated?
+
+## 13. Business Model
+- Free hook:
+- Paid SKU:
+- Subscription potential:
+- Success fee/take rate:
+- Enterprise/institution package:
+- Marketplace add-on:
+
+## 14. Success Metrics
+- User outcome metric:
+- Buyer ROI metric:
+- Marketplace liquidity metric:
+- Retention metric:
+- Data/moat metric:
+
+## 15. Implementation Assumptions
+- Current primitives usable:
+- New primitives needed:
+- Third-party integrations needed:
+- Manual ops acceptable for v1:
+- Risks or hard parts:
+```
+
+---
+
+## 8. Internal Workflow Object Shape
+
+```ts
+type Workflow = {
+ id: string
+ name: string
+ segment: Array<
+ | "students"
+ | "individuals"
+ | "coaches"
+ | "freelancers"
+ | "startups"
+ | "recruiters"
+ | "enterprises"
+ | "institutes"
+ >
+ buyerType: "b2c" | "b2b" | "b2b2c" | "marketplace" | "platform"
+ economicBuyer: string
+ landingPageAmbition: string
+ promise: string
+ tamHypothesis: string
+ valueRank: number
+ urgencyTrigger: string
+ pricing: {
+ freeHook?: string
+ oneTime?: string
+ subscription?: string
+ successFee?: string
+ enterprise?: string
+ marketplaceTakeRate?: string
+ }
+ leadAgent: string
+ supportingAgents: string[]
+ humanEscalation?: string[]
+ currentPrimitives?: string[]
+ newCapabilitiesNeeded?: string[]
+ steps: WorkflowStep[]
+ approvalPoints: ApprovalPoint[]
+ outputs: ArtifactSpec[]
+ verifiedArtifacts?: ArtifactSpec[]
+ memoryWritten: string[]
+ qxSignalsUpdated: string[]
+ networkEffects: string[]
+ successMetrics: string[]
+}
+```
+
+---
+
+## 9. Product Positioning
+
+Old framing:
+
+> GrowQR has resume, interview, roleplay, matching, courses, Q-score, and coaches.
+
+Better framing:
+
+> GrowQR is an adaptive opportunity network where every person has a trusted QR identity, every ambition gets an AI agent squad, every important moment can escalate to a human expert, and every outcome strengthens the matching graph.
+
+The workflows are how users buy outcomes. The QR identity, QX score, verified achievements, expert marketplace, and matching graph are how GrowQR compounds value across the whole market.
diff --git a/services_prd/MATCHMAKING ENGINE.docx.md b/services_prd/MATCHMAKING ENGINE.docx.md
new file mode 100644
index 0000000..047aba5
--- /dev/null
+++ b/services_prd/MATCHMAKING ENGINE.docx.md
@@ -0,0 +1,407 @@
+**GrowQR OPPORTUNITY MATCHMAKING ENGINE**
+
+**BUSINESS REQUIREMENTS DOCUMENT**
+
+Two-Sided AI Marketplace | 7 Opportunity Types | 46 Attributes
+
+
+
+**1\. EXECUTIVE SUMMARY**
+
+GrowQR Opportunity Matchmaking Engine is a two-sided AI-powered marketplace connecting users to 7 opportunity types:
+
+· Full-time Jobs
+· Contracts/Gigs
+· Events/Meetups
+· Board Advisory Roles
+· Surveys/Research
+· Temporary Earning Opportunities (location-based)
+· Future Pathway Opportunities
+
+**Core Principle:** Users engage with the platform, build their professional profile, and the system intelligently surfaces opportunities aligned to their capabilities, preferences, and goals.
+
+Matching Engine analyzes 46 personalized attributes per user:
+
+· 25 Q-Scores: IQ, EQ, SQ, XQ, AQ, LQ, CQm, GQ, PJQ, RQ, VQ, DQ, NQ, CuQ, TQ, CrQ, StQ, LdrQ, InQ, BQ, MQ, FQ, DQm, CQx, RQx
+· 20 User Preferences: Work style, compensation, location, industry, culture, growth priorities, etc.
+· Special Feature: Travel Mode within Location Preference (discover temp opportunities in cities during travel)
+
+Weighted Algorithm calculates compatibility:
+
+· Skills Match: 40% weight
+· Personality Fit: 30% weight
+· Company Culture: 15% weight
+· Career Growth: 10% weight
+· Compensation: 5% weight
+· Threshold: Show opportunities ≥60% match
+· Highly Recommended: ≥75% match
+
+Data Sources:
+
+· Platform Scraping: LinkedIn, Naukri, Indeed, Glassdoor, Monster, Company Pages
+· Employer Direct Posts: Opportunities with specified requirements
+· Enrichment: Glassdoor ratings, company culture data, salary benchmarks
+
+Feedback Loop: System learns from user actions
+
+· APPLY / RSVP → Boost similar opportunities \+20-30%
+· SAVE → Neutral-positive boost \+10%
+· DISMISS → Reduce similar opportunities \-15-20%
+
+Two POV:
+
+· POV 1 (Seeker View): Users receive daily personalized feeds of 10-15 opportunities
+· POV 2 (Employer View): Employers post opportunities and view matched candidates
+
+Goal: Automate 70-80% of traditional hiring workflows through intelligent matching.
+
+![][image1]
+
+
+
+**2\. DATA SOURCES & SCRAPING SPECIFICATIONS**
+
+PLATFORM 1: LINKEDIN
+
+· Data Points to Scrape:
+· Job ID, Job Title, Company Name, Location (city, country, remote status)
+· Job Description (full text), Posted Date, Application Deadline
+· Employment Type (Full-time, Contract, Part-time, Internship)
+· Experience Level (Entry, Mid, Senior, Executive)
+· Salary Range (if disclosed), Benefits listed
+· Required Skills (parsed from description)
+· Company Size, Industry, Company LinkedIn URL
+· Number of Applicants, Easy Apply status
+· Scraping Frequency: Hourly for new postings
+· Scraping Method: LinkedIn Jobs API (if available) or web scraping
+
+PLATFORM 2: NAUKRI (India-focused)
+
+· Data Points to Scrape:
+· Job ID, Title, Company, Location, Salary Range
+· Experience Required (years), Industry, Functional Area
+· Key Skills, Job Description, Posted Date
+· Company Profile, Reviews Rating
+· Scraping Frequency: Hourly
+· Scraping Method: Naukri API or web scraping
+
+PLATFORM 3: INDEED
+
+· Data Points to Scrape:
+· Job ID, Title, Company, Location, Salary (if available)
+· Job Type, Experience Level, Full Description
+· Company Reviews Rating, Posted Date
+· Application URL, Required Qualifications
+· Scraping Frequency: Hourly
+· Scraping Method: Indeed API or web scraping
+
+PLATFORM 4: GLASSDOOR
+
+· Data Points to Scrape:
+· Jobs: Same as above platforms
+· Company Data (Critical for Enrichment):
+· Overall Rating (1-5 stars)
+· Culture & Values Rating
+· Work-Life Balance Rating
+· Senior Management Rating
+· Compensation & Benefits Rating
+· Career Opportunities Rating
+· CEO Approval %
+· Recommend to Friend %
+· Pros/Cons from reviews (sentiment analysis)
+· Salary data by role and location
+· Scraping Frequency: Daily for company data, Hourly for jobs
+
+PLATFORM 5: MONSTER
+
+· Data Points: Same as Indeed
+· Scraping Frequency: Daily
+
+PLATFORM 6: COMPANY CAREER PAGES
+
+· Target: Top 1000 companies in India/target markets
+· Data Points: Direct job postings, company culture info, benefits
+· Scraping Frequency: Daily
+· Scraping Method: Custom scrapers per company website structure
+
+EMPLOYER DIRECT POSTS
+
+· Data Points:
+· All standard job fields PLUS employer-specified Q-Score requirements
+· Example: "EQ ≥ 80, TQ ≥ 75, CQm ≥ 70"
+· This enables precise candidate matching
+
+
+
+**3\. 46 PERSONALIZED ATTRIBUTES**
+
+25 Q-SCORES (0-100 scale, capability measurement):
+
+· IQ (Intelligence) \- Analytical thinking, problem-solving
+· EQ (Emotional) \- Self-awareness, empathy, emotional regulation
+· SQ (Social) \- Interpersonal skills, relationship building
+· XQ (Execution) \- Getting things done, follow-through
+· AQ (Adaptability) \- Flexibility, change management
+· LQ (Learning) \- Learning speed, knowledge retention
+· CQm (Communication) \- Verbal and written communication
+· GQ (Growth) \- Growth mindset, ambition
+· PJQ (Project) \- Project management, organization
+· RQ (Resilience) \- Stress management, bouncing back
+· VQ (Vision) \- Strategic thinking, future orientation
+· DQ (Drive) \- Motivation, self-discipline
+· NQ (Network) \- Networking ability, connections
+· CuQ (Cultural) \- Cross-cultural awareness, diversity
+· TQ (Technical) \- Technical skills, domain expertise
+· CrQ (Creativity) \- Innovation, creative problem-solving
+· StQ (Strategic) \- Strategic planning, long-term thinking
+· LdrQ (Leadership) \- Leadership capability, influence
+· InQ (Influence) \- Persuasion, negotiation
+· BQ (Business) \- Business acumen, commercial awareness
+· MQ (Marketing) \- Marketing knowledge, brand thinking
+· FQ (Financial) \- Financial literacy, budget management
+· DQm (Domain) \- Industry-specific knowledge
+· CQx (Customer Experience) \- Customer empathy, service orientation
+· RQx (Reputation) \- Professional reputation, personal brand
+
+20 USER PREFERENCES (Filters & Scorers):
+
+FILTERS (Binary Gate \- Show/Hide):
+
+· Remote Work Preference: On-site, Hybrid, Remote, Flexible
+· Company Size: Startup (\<50), Small (50-200), Medium (200-1000), Large (1000+), Any
+· Industry: Technology, Finance, Healthcare, Education, etc. (multi-select)
+· Role Level: Entry, Mid, Senior, Executive, C-Suite
+· Job Function: Engineering, Product, Sales, Marketing, Operations, etc.
+· Travel Willingness: Percentage \+ Frequency
+· Job Stability vs Risk: Stable, Moderate, High Risk (startups)
+· Opportunity Type: Full-time, Contract, Mix, Events, Advisory
+· Search Radius: 5, 10, 25, 50, 100 miles, Any
+· Commute Time Tolerance: \<15, \<30, \<45, \<60 min, Any
+
+SCORERS (Contribute to Match % with Specified Weights):
+
+· Growth Opportunity Importance: Contributes to Growth component (10% of total)
+· Salary Expectation Range: Contributes to Compensation component (5% of total)
+· Company Culture Fit: Contributes to Culture component (15% of total)
+· Career Stage Goals: Contributes to Growth component (10% of total)
+· Learning & Development Priority: Contributes to Growth component (10% of total)
+· Benefits Importance: Contributes to Compensation component (5% of total)
+· Diversity & Inclusion Priority: Boosts companies with strong D\&I ratings
+· Work Style: Independent, Collaborative, Mix \- matches job descriptions
+· Impact & Meaning Importance: Boosts mission-driven organizations
+
+LOCATION PREFERENCE (Multi-Component Filter):
+
+· Current Location: City \+ Country
+· Search Radius: Linked to Filter \#9 above
+· Willing to Relocate: Yes/No \+ Preferred Cities list
+· Travel Mode Feature (Optional):
+· User adds temporary location with travel dates
+· System shows opportunities in HOME location \+ TRAVEL location
+· User specifies types to show: Events (always), Temp Gigs (always), Jobs (if willing to relocate)
+· UI displays tabs: \[HOME\] \[TRAVEL\] \[REMOTE\] \[ALL\]
+· Auto-deactivates after end date
+
+
+
+**4\. MATCHING ALGORITHM \- DETAILED WEIGHTAGES**
+
+OVERALL FORMULA:
+
+· Match Score \= (Skills × 0.40) \+ (Personality × 0.30) \+ (Culture × 0.15) \+ (Growth × 0.10) \+ (Compensation × 0.05)
+· Result: 0-100% compatibility score
+· Threshold: Show if ≥60%
+· Highly Recommended: If ≥75%
+
+COMPONENT 1: SKILLS MATCH (40% of total score)
+
+· Technical Roles Formula:
+· TQ × 0.40 (40% weight)
+· IQ × 0.25 (25% weight)
+· XQ × 0.20 (20% weight)
+· DQm × 0.15 (15% weight)
+· Business Roles Formula:
+· BQ × 0.40 (40% weight)
+· StQ × 0.25 (25% weight)
+· FQ × 0.20 (20% weight)
+· MQ × 0.15 (15% weight)
+· People/HR Roles Formula:
+· EQ × 0.40 (40% weight)
+· SQ × 0.25 (25% weight)
+· CuQ × 0.20 (20% weight)
+· LdrQ × 0.15 (15% weight)
+· Creative Roles Formula:
+· CrQ × 0.40 (40% weight)
+· CQx × 0.25 (25% weight)
+· TQ × 0.20 (20% weight)
+· IQ × 0.15 (15% weight)
+· Sales/Marketing Roles Formula:
+· MQ × 0.40 (40% weight)
+· CQm × 0.25 (25% weight)
+· InQ × 0.20 (20% weight)
+· NQ × 0.15 (15% weight)
+· Leadership Roles Formula:
+· LdrQ × 0.40 (40% weight)
+· StQ × 0.25 (25% weight)
+· VQ × 0.20 (20% weight)
+· InQ × 0.15 (15% weight)
+
+COMPONENT 2: PERSONALITY FIT (30% of total score)
+
+· IF employer specifies required Q-Scores: Average user's scores for those specific Q-Scores
+· IF no employer specification: Average all 25 Q-Scores
+· BOOST: \+10% if user's top 3 highest Q-Scores match job category
+· Cap at 100%
+
+COMPONENT 3: COMPANY CULTURE (15% of total score)
+
+· Formula: (Culture Preference Match × 0.50) \+ (CuQ × 0.30) \+ (Glassdoor Rating × 0.20)
+· Culture Preference Match Scoring:
+· Exact match (user wants Fast-paced, company is Fast-paced): 100%
+· User selects "Balanced": 80% for any culture
+· Partial compatibility: 60%
+· Mismatch: 40%
+· Glassdoor Rating: Convert 1-5 stars to 0-100% → (Rating / 5.0) × 100
+
+COMPONENT 4: CAREER GROWTH (10% of total score)
+
+· Formula: (GQ × 0.40) \+ (Growth Importance Alignment × 0.35) \+ (Job Growth Potential × 0.25)
+· Job Growth Potential Calculation (Keyword Analysis):
+· Leadership words in title (Lead, Senior, Manager, Director): \+20 points
+· Career advancement in description (promotion, advancement): \+15 points
+· Learning in description (training, development, learning): \+15 points
+· Startup or scaling company (\< 500 employees): \+20 points
+· Total capped at 100 points
+
+COMPONENT 5: COMPENSATION (5% of total score)
+
+· Salary range overlap:
+· Job salary overlaps user expectation: 100%
+· Job salary meets/exceeds expectation: 100%
+· Job salary 10% below: 80%
+· Job salary 20% below: 60%
+· Job salary 30% below: 40%
+· Job salary 40%+ below: 20%
+· Job salary not disclosed: 70% (neutral)
+
+
+
+**5\. SEVEN OPPORTUNITY TYPES WITH DAILY FEED DISTRIBUTION**
+
+1\. FULL-TIME JOBS
+
+· Matching: All 5 algorithm components
+· Data Sources: LinkedIn, Naukri, Indeed, Glassdoor, Monster, Company Pages
+· Daily Feed: 5 opportunities shown
+· User Actions: Apply, Save, Dismiss
+
+2\. CONTRACTS/GIGS
+
+· Matching: Emphasizes Skills (40%) \+ Compensation (5%)
+· Data Sources: Same platforms, tagged as Contract/Freelance
+· Daily Feed: 3 opportunities shown
+· User Actions: Apply, Save, Dismiss
+
+3\. EVENTS/MEETUPS
+
+· Matching: NQ (Network) \+ SQ (Social) \+ CuQ (Cultural) \+ Industry match
+· Data Sources: Eventbrite, Meetup, Lu.ma, LinkedIn Events
+· Daily Feed: 2 opportunities shown
+· User Actions: RSVP, Save, Dismiss
+
+4\. BOARD ADVISORY ROLES
+
+· Matching: LdrQ \+ StQ \+ BQ \+ Experience level
+· Data Sources: Board director websites, LinkedIn groups, company postings
+· Daily Feed: 1 opportunity shown
+· User Actions: Express Interest, Save, Dismiss
+
+5\. SURVEYS/RESEARCH
+
+· Matching: Minimal filtering (low barrier entry)
+· Data Sources: UserTesting, Respondent, survey platforms
+· Daily Feed: 2 opportunities shown
+· User Actions: Participate, Dismiss
+
+6\. TEMPORARY EARNING (Location-based)
+
+· Matching: Location proximity \+ Skills \+ Availability
+· Trigger: Only shown when Travel Mode is active
+· Data Sources: Local gig platforms, short-term contract sites
+· Daily Feed: 2 opportunities shown (during travel)
+· User Actions: Apply, Save, Dismiss
+
+7\. FUTURE PATHWAY OPPORTUNITIES
+
+· Matching: Pathway goals \+ Skills to develop \+ Q-Score gaps
+· Data Sources: Integrated with Pathways service
+· Daily Feed: 1 opportunity shown
+· User Actions: Save for Later, Plan Toward, Dismiss
+
+TOTAL DAILY FEED: 10-15 opportunities (16 max if travel mode active)
+
+
+
+**6\. USER ACTIONS & FEEDBACK LOOP WEIGHTAGES**
+
+APPLY (Jobs/Contracts):
+
+· Records application in database
+· Tracks application status
+· Boosts similar opportunities: \+20-30%
+· Attributes boosted: Company (+30%), Industry (+20%), Role type (+20%), Location type (+15%), Company size (+15%)
+
+RSVP (Events):
+
+· Records RSVP in database
+· Optional: Adds to user calendar
+· Boosts similar events: \+20-30%
+· Attributes boosted: Event type (+30%), Industry (+20%), Location (+20%)
+
+SAVE (All Types):
+
+· Bookmarks opportunity for later review
+· Shows in "Saved Opportunities" section
+· Neutral-positive signal: \+10% boost
+· Attributes boosted: Company (+10%), Industry (+10%)
+
+DISMISS (All Types):
+
+· Hides opportunity from feed
+· Records dismissal reason (optional user feedback)
+· Reduces similar opportunities: \-15-20%
+· Attributes reduced: Company (-20%), Industry (-15%), Role type (-15%), Company size (-10%)
+
+LEARNING CYCLE:
+
+· After 10 user actions: System identifies patterns
+· After 25 actions: Algorithm meaningfully adjusted
+· After 50 actions: Personalization highly refined
+· Continuous: Every action incrementally improves matching
+
+
+
+**7\. ACCEPTANCE CRITERIA**
+
+Each criterion must pass for system to be launch-ready:
+
+
+
+| \# | Acceptance Criteria | Pass/Fail |
+| :---- | :---- | :---- |
+| **1** | 46 attributes (25 Q-Scores \+ 20 Preferences) captured and stored correctly | \[ \] Pass \[ \] Fail |
+| **2** | All 6 data sources operational: LinkedIn, Naukri, Indeed, Glassdoor, Monster, Company Pages scraping successfully | \[ \] Pass \[ \] Fail |
+| **3** | Glassdoor enrichment data (ratings, culture, salary) integrated and displayed correctly | \[ \] Pass \[ \] Fail |
+| **4** | ML algorithm calculates all 5 components with exact weightages: Skills (40%), Personality (30%), Culture (15%), Growth (10%), Compensation (5%) | \[ \] Pass \[ \] Fail |
+| **5** | Travel Mode feature works: Users can activate, set temp location/dates, see HOME \+ TRAVEL tabs, auto-deactivates after end date | \[ \] Pass \[ \] Fail |
+| **6** | Daily feed generates 10-15 opportunities across 7 types with correct distribution (5 jobs, 3 contracts, 2 events, etc.) | \[ \] Pass \[ \] Fail |
+| **7** | User actions (Apply, RSVP, Save, Dismiss) record correctly and trigger feedback loop with specified weightages | \[ \] Pass \[ \] Fail |
+| **8** | Feedback loop demonstrably improves matches: After 10+ actions, system shows measurable improvement in relevance | \[ \] Pass \[ \] Fail |
+| **9** | Employer View (Phase 2): Employers can post opportunities, view ranked candidates, take actions | \[ \] Pass \[ \] Fail |
+| **10** | Match score threshold enforcement: Only ≥60% shown, ≥75% marked "Highly Recommended" | \[ \] Pass \[ \] Fail |
+| **11** | Daily feed generation \<5 seconds per user, API response \<500ms | \[ \] Pass \[ \] Fail |
+| **12** | System handles edge cases: incomplete profiles, missing salary data, new users with no action history | \[ \] Pass \[ \] Fail |
+
+
+
+[image1]:
\ No newline at end of file
diff --git a/services_prd/Marketplace_BRD.docx.md b/services_prd/Marketplace_BRD.docx.md
new file mode 100644
index 0000000..30799f4
--- /dev/null
+++ b/services_prd/Marketplace_BRD.docx.md
@@ -0,0 +1,584 @@
+**GrowQR**
+
+**MARKETPLACE**
+
+**DEVELOPER BRD — TECHNICAL SPECIFICATION**
+
+Career Services Platform • Verified Providers • 5 Delivery Formats • v1.0 • March 2026
+
+| Marketplace Microservice This document contains specifications, business logic, and acceptance criteria required for development. |
+| :---: |
+
+| Document Title | Marketplace — Developer BRD Technical Specification |
+| :---- | :---- |
+
+| Version | 1.0 — March 2026 |
+| :---- | :---- |
+
+| Service Type | Standalone Microservice — Career Services Supply Layer |
+| :---- | :---- |
+
+| Provider Types | GrowQR-Certified Coaches | Verified Senior Users | Corporate Firms | GrowQR In-House |
+| :---- | :---- |
+
+| Delivery Formats | Live 1:1 Video | Async Review | Group Workshop | Done-For-You | Retainer Package |
+| :---- | :---- |
+
+| Pricing Model | Provider sets price freely — GrowQR takes commission % (rate TBD — business decision pending) |
+| :---- | :---- |
+
+| Discovery | Open browsing \+ Pathway-triggered smart recommendations |
+| :---- | :---- |
+
+| Mentors Relationship | Marketplace is the supply layer. Mentors (11-service) \= curated subset drawn from Marketplace providers. |
+| :---- | :---- |
+
+| Innovation Features | Supply Seeding | Outcome Guarantee | Q-Score Verified Results | Group Demand Aggregation | Pre-Booking Engine |
+| :---- | :---- |
+
+| 1\. EXECUTIVE SUMMARY |
+| :---- |
+
+GrowQR Marketplace is a verified career services platform where professionals offer paid services to GrowQR users. It operates as a standalone microservice and serves as the supply layer for the entire GrowQR platform — including the Mentors service within the 11-service pathway model.
+
+Unlike generic freelance marketplaces, every provider on GrowQR Marketplace is validated and approved before going live. Services are directly aligned to career development needs: interview preparation, resume building, social branding, job search coaching, domain guidance, and more.
+
+Users discover providers through open browsing and through intelligent recommendations surfaced by the Pathways engine based on their Q-Score gaps and current cycle phase.
+
+## **1.1 Marketplace vs Mentors — Architectural Relationship**
+
+| Marketplace and Mentors are not the same thing. Marketplace is the full open platform of verified providers. Mentors is a curated, GrowQR-selected subset of Marketplace providers that is surfaced inside a user’s active pathway cycle. A provider must first be listed on Marketplace before they can be selected as a Mentor. |
+| :---- |
+
+| Dimension | Marketplace | Mentors (11-Service) |
+| :---- | :---- | :---- |
+| Access | Any verified GrowQR user can browse and book freely | Surfaced by Pathways engine at scheduled cycle touchpoints |
+| Provider selection | User chooses any available provider | GrowQR curates and recommends based on pathway match |
+| Pricing | Provider sets price; GrowQR takes commission | May be subsidised or coin-redeemable within pathway |
+| Booking trigger | User-initiated at any time | Pathway-triggered (monthly touchpoint) |
+| Provider pool | All validated Marketplace providers | Curated subset hand-picked by GrowQR from Marketplace |
+| Session format | All 5 formats available | Primarily live 1:1 and retainer |
+
+| 2\. PROVIDER TYPES & VALIDATION |
+| :---- |
+
+Four provider types are permitted on the Marketplace. All must complete GrowQR’s validation process before their profile goes live. Validation criteria vary by provider type.
+
+| Provider Type | Description | Validation Requirements |
+| :---- | :---- | :---- |
+| GrowQR-Certified External Coach | Independent coaches and mentors certified by GrowQR through an internal accreditation process | Application \+ credentials review \+ sample session evaluation \+ GrowQR certification badge awarded |
+| Verified Senior User | Experienced GrowQR platform users (typically 5+ years in their domain) who apply to offer services to peers | Minimum Q-Score thresholds \+ experience verification \+ portfolio review \+ GrowQR approval |
+| Corporate / Institutional Provider | Coaching firms, HR consultancies, universities, and training organisations offering team or individual services | Business registration \+ service catalogue review \+ compliance check \+ signed provider agreement |
+| GrowQR In-House Expert | GrowQR staff or contracted experts offering services directly on the platform | Internal onboarding only — no external validation required |
+
+## **2.1 Provider Validation Flow**
+
+| Step | Action | System Behaviour | Outcome |
+| :---- | :---- | :---- | :---- |
+| 1 | Provider submits application | Application form: personal/company info, domain expertise, credentials, work samples, service types intended | Application record created with status: Pending Review |
+| 2 | GrowQR review | Internal team reviews credentials, samples, and profile completeness | Status updated: Under Review |
+| 3 | Sample session (coaches only) | Applicant completes a 20-min sample session with a GrowQR reviewer | Session scored on rubric; pass/fail recorded |
+| 4 | Decision | GrowQR approves or rejects | Approved: profile activated. Rejected: reason sent, reapplication permitted after 30 days |
+| 5 | Profile build | Provider builds their Marketplace profile, sets services, prices, availability | Profile status: Draft until published |
+| 6 | Go live | Provider publishes profile | Profile visible to all users; eligible for pathway recommendations |
+
+## **2.2 Provider Profile Contents**
+
+* Full name and professional photo
+
+* Domain expertise tags (e.g. Software Engineering, Product Management, Sales, Marketing)
+
+* Years of experience and career highlights
+
+* Services offered: format, duration, price per service
+
+* Portfolio: sample work, case studies, testimonials
+
+* Certifications and credentials (verified badge shown if GrowQR-certified)
+
+* Availability calendar: real-time slots for live sessions
+
+* Response time indicator for async services
+
+* Rating and review history (post-launch, populated by completed bookings)
+
+* Total sessions completed and repeat booking rate
+
+| 3\. SERVICE CATEGORIES |
+| :---- |
+
+Marketplace services are organised into categories aligned to GrowQR’s career development modules. Providers list their services under one or more categories. The Pathways engine uses category tags to surface relevant provider recommendations.
+
+| Category | Services Included | GrowQR Module Alignment |
+| :---- | :---- | :---- |
+| Interview Preparation | Mock interviews, interview strategy coaching, role-specific interview practice, pre-interview briefing sessions | Upskills — Practice / Interview Service |
+| Resume & Cover Letter | Resume review, resume rewrite, cover letter writing, ATS optimisation, LinkedIn profile review | Opportunity — Resume & Cover Letter Service |
+| Social & Personal Branding | LinkedIn profile overhaul, content strategy, personal brand audit, thought leadership coaching | Opportunity — Social Branding Service |
+| Career Coaching | Career direction coaching, career change strategy, goal-setting sessions, career identity clarity | Pathways — General Guidance |
+| Job Search Strategy | Job search planning, application strategy, recruiter outreach coaching, salary negotiation prep | Opportunity — Job Matchmaking |
+| Domain & Industry Guidance | Sector-specific career advice, industry entry coaching, domain skill gap guidance | Pathways — Domain Mapping |
+| Skills Development Coaching | Personalised skill-building plans, learning roadmap sessions, soft skills coaching | Upskills — Courses / Roleplay |
+| Entrepreneurship & Business | Startup mentoring, business validation sessions, founder coaching, side-hustle guidance | Pathways — Entrepreneurial Builder Archetype |
+| Academic & Graduate Guidance | University application coaching, graduate programme strategy, first-job preparation | Pathways — Student Persona |
+
+| 4\. FIVE SERVICE DELIVERY FORMATS |
+| :---- |
+
+Every service listed on Marketplace must be assigned to one of five delivery formats. Each format has distinct booking flows, delivery requirements, and completion criteria.
+
+| ▶ FORMAT 1: LIVE 1:1 VIDEO SESSION |
+| :---- |
+| User books a specific time slot from the provider’s availability calendar |
+| Duration options set by provider: 20 min / 30 min / 45 min / 60 min / 90 min |
+| Session conducted via GrowQR’s integrated video tool (or provider-specified link) |
+| Booking confirmed: calendar invite sent to both parties; reminder notifications at 24hr and 1hr before |
+| Session recording: optional, requires consent from both parties before session starts |
+| Post-session: provider submits session notes within 24hrs; user prompted to leave a review |
+| Completion triggered: when session end time is reached or provider marks as complete |
+| Cancellation policy: enforced per platform rules (see Section 8\) |
+
+| ⏱ FORMAT 2: ASYNC REVIEW |
+| :---- |
+| User submits material for review: resume, LinkedIn profile URL, cover letter, portfolio, or other document |
+| Provider has a defined turnaround time (set at listing creation): 24hrs / 48hrs / 72hrs |
+| Provider delivers feedback as: annotated document, written report, or recorded video walkthrough |
+| User receives notification when feedback is delivered |
+| User can submit one follow-up question within 48hrs of receiving feedback (included in service) |
+| Completion triggered: when provider marks delivery as complete |
+| Suitable for: Resume reviews, LinkedIn audits, portfolio feedback, cover letter reviews |
+
+| 👥 FORMAT 3: GROUP SESSION / WORKSHOP |
+| :---- |
+| Provider creates a group session with defined: topic, date/time, max participants (cap set by provider), price per seat |
+| Users browse upcoming sessions and book individual seats |
+| Minimum participant threshold: provider sets minimum number required for session to run (e.g. 3 of 10 seats) |
+| If minimum not met 24hrs before session: session cancelled, all users refunded automatically |
+| Session conducted via GrowQR’s integrated group video tool |
+| Session recording available to all attendees for 7 days post-session (default) |
+| Post-session: all attendees prompted to review; provider receives aggregate rating |
+| Suitable for: Industry panels, skill workshops, cohort coaching, webinars |
+
+| ✅ FORMAT 4: DONE-FOR-YOU SERVICE |
+| :---- |
+| Provider delivers a completed work product on behalf of the user |
+| User submits brief: role target, key achievements, tone preferences, and any existing materials |
+| Provider sets delivery timeline at listing creation: 3 days / 5 days / 7 days |
+| Provider submits first draft to user via platform messaging |
+| User entitled to: 1 revision request within 5 days of first draft delivery |
+| Final delivery marked complete by user or auto-completed after 5 days of no response |
+| Suitable for: Resume writing, cover letter writing, LinkedIn profile rewrite, bio writing |
+| Quality review applies to this format (see Section 8 — Dispute Resolution) |
+
+| 📅 FORMAT 5: RETAINER / MULTI-SESSION PACKAGE |
+| :---- |
+| Provider offers a structured package: defined number of sessions over a defined period |
+| Examples: 4 sessions over 4 weeks / 8 sessions over 2 months / 12 sessions over 3 months |
+| Full package price paid upfront at booking; provider cannot change price after booking |
+| Scheduling: individual sessions booked by user within the package period using provider’s availability |
+| Unused sessions: if package period expires with unused sessions, partial refund issued per platform policy |
+| Suitable for: Ongoing career coaching, job search accountability, skill development programmes |
+| This format feeds directly into the Mentors (11-service) model for Tier 3 pathway users |
+
+| 5\. PRICING & COMMISSION MODEL |
+| :---- |
+
+| Commission rate is a business decision pending final approval. The BRD specifies the commission architecture and enforcement logic. The actual percentage must be confirmed by the business team before development of the payments module. |
+| :---- |
+
+## **5.1 Pricing Model**
+
+Providers set their own prices freely for all services and packages. GrowQR does not restrict pricing. The platform takes a commission percentage from each completed transaction. This model follows the Fiverr/Upwork approach and incentivises providers to price competitively.
+
+| Pricing Rule | Detail |
+| :---- | :---- |
+| Provider sets price | No minimum or maximum enforced by platform at v1. Provider enters price at service listing creation. |
+| Price displayed to user | User sees the full price inclusive of all platform fees. No hidden charges. |
+| Commission deducted | GrowQR commission deducted from provider payout at the point of transaction completion. Rate: TBD. |
+| Provider payout | Net amount (price minus commission) transferred to provider. Payout schedule: TBD by business team. |
+| Currency | Platform handles transactions in the user’s regional currency. Currency conversion logic: TBD. |
+| Refunds | Refund amount returned to user in full. GrowQR absorbs commission on refunded transactions. |
+| Package pricing | Retainer packages priced as a single total. Commission applied to full package value at booking. |
+
+## **5.2 Commission Architecture**
+
+| Commission Component | Specification |
+| :---- | :---- |
+| Commission rate | TBD — Business decision pending. To be confirmed before payments module development. |
+| Commission trigger | Commission deducted when: session marked complete / async delivery accepted / done-for-you final delivery confirmed |
+| Dispute hold | If dispute raised, commission held in escrow until resolution. Released to GrowQR on dispute closure. |
+| Refund handling | On full refund: GrowQR absorbs commission. On partial refund: commission recalculated on net completed value. |
+| Provider dashboard | Provider sees: gross earnings, commission deducted, net payout, pending transactions, payout history |
+
+| 6\. DISCOVERY & RECOMMENDATION ENGINE |
+| :---- |
+
+Users find Marketplace providers through two complementary mechanisms: open browsing with search and filters, and intelligent recommendations surfaced by the GrowQR Pathways engine based on Q-Score gaps and current pathway cycle phase.
+
+## **6.1 Open Browsing**
+
+* Marketplace homepage: featured providers, recently added, top-rated, trending by category
+
+* Search bar: free-text search by provider name, skill, service type, or keyword
+
+* Filter panel: Category, Delivery format, Price range, Rating (min stars), Availability (date range), Provider type (certified/verified/corporate/in-house), Duration
+
+* Sort options: Relevance, Price (low to high / high to low), Rating, Most booked, Newest
+
+* Provider card view: photo, name, top category, rating, price from, verified badge, quick-book button
+
+* Provider profile page: full details, all services listed, availability calendar, reviews, portfolio
+
+## **6.2 Pathway-Triggered Smart Recommendations**
+
+* Pathways engine analyses user’s current Q-Score gaps and active cycle phase
+
+* Matches gaps to Marketplace service categories and provider specialisms
+
+* Surfaces up to 3 recommended providers per relevant category at the right cycle moment
+
+* Recommendation card shown in: Pathway dashboard, weekly cycle task list, and Marketplace homepage (personalised section)
+
+* Example triggers:
+
+ * User Q-Score CQm below target → recommend Interview Prep or Social Branding providers
+
+ * User entering Job Matching phase (Week 4+) → recommend Resume & Cover Letter providers
+
+ * User archetype: Entrepreneurial Builder → surface Entrepreneurship & Business coaching providers
+
+ * User’s pathway milestone: first interview booked → recommend pre-interview 1:1 session
+
+* Pathway recommendations are suggestions only — user is never forced to book and can dismiss
+
+## **6.3 Mentors Pool Selection**
+
+* GrowQR internal team curates the Mentors pool from active, high-rated Marketplace providers
+
+* Selection criteria: minimum rating threshold, minimum sessions completed, active availability, domain alignment to GrowQR archetypes
+
+* Mentors pool reviewed and updated monthly
+
+* Providers are not informed of their Mentor pool status — it does not change their Marketplace listing
+
+* When Pathways engine surfaces a Mentor touchpoint in a user’s cycle, it draws exclusively from the Mentors pool
+
+| 7\. BOOKING & SESSION MANAGEMENT |
+| :---- |
+
+## **7.1 Booking Flow**
+
+| Step | User Action | System Response | Data Captured |
+| :---- | :---- | :---- | :---- |
+| 1 | User selects service from provider profile | Display service details, price, available slots (live) or turnaround time (async) | Service ID, User ID |
+| 2 | User selects slot / submits brief | Live: calendar slot picker. Async/Done-For-You: brief submission form. Group: seat selection. | Slot / brief / seat preference |
+| 3 | Payment | User completes payment. Amount shown in full before confirmation. | Payment intent created; transaction ID |
+| 4 | Confirmation | Booking confirmed. Calendar invite sent (live sessions). Confirmation email to both parties. | Booking ID, status: Confirmed |
+| 5 | Delivery | Provider delivers service per format requirements | Completion event sent to system |
+| 6 | Completion | User confirms receipt (or auto-completed per format rules) | Status: Completed; commission triggered |
+| 7 | Review | User prompted to leave rating and written review (optional but encouraged) | Rating, review text, timestamp |
+
+## **7.2 Booking States**
+
+| State | Condition | System Behaviour |
+| :---- | :---- | :---- |
+| Pending | Payment initiated but not confirmed | Hold slot/seat; release if payment not confirmed within 10 minutes |
+| Confirmed | Payment successful | Send confirmations; add to provider’s schedule; notify user |
+| In Progress | Session started or delivery underway | Timer active for live sessions; turnaround clock active for async |
+| Delivered | Provider marks delivery complete | Notify user; start 5-day acceptance window (async/done-for-you) |
+| Completed | User confirms or acceptance window expires | Release commission; prompt review; update provider stats |
+| Disputed | User raises dispute before completion | Hold commission; escalate to GrowQR review team |
+| Cancelled | Cancelled by user or provider per policy | Refund processed per cancellation policy; slot released |
+| No-Show | Provider does not attend live session | Auto-refund issued; provider strike recorded |
+
+## **7.3 Cancellation Policy**
+
+| Cancellation Timing | User Refund | Provider Payout |
+| :---- | :---- | :---- |
+| More than 24hrs before live session | Full refund | No payout |
+| Less than 24hrs before live session | 50% refund | 50% payout (late cancellation fee) |
+| No-show by user | No refund | Full payout to provider |
+| No-show by provider | Full refund \+ platform credit | No payout \+ strike recorded |
+| Async/Done-For-You: cancelled before provider starts | Full refund | No payout |
+| Async/Done-For-You: cancelled after provider starts | No refund | Full payout |
+| Group session: cancelled by platform (min not met) | Full refund to all attendees | No payout to provider |
+
+| 8\. QUALITY ASSURANCE & DISPUTE RESOLUTION |
+| :---- |
+
+GrowQR operates a two-layer quality model: proactive quality review (before and during provider listing) and reactive dispute resolution (after a service is delivered). Both mechanisms are required at v1, particularly given the Done-For-You service format.
+
+## **8.1 Proactive Quality Controls**
+
+| Control | Description | Applies To |
+| :---- | :---- | :---- |
+| Provider validation | All providers pass GrowQR’s approval process before any service goes live | All provider types |
+| Sample session review | Coaches and mentors complete a graded sample session before certification | GrowQR-certified coaches |
+| Listing review | All service listings reviewed by GrowQR team before publishing. Listings that misrepresent scope rejected. | All service formats |
+| Ongoing rating monitoring | Providers with average rating below 3.5 stars (from minimum 5 reviews) flagged for review | All providers |
+| Dispute rate monitoring | Providers with dispute rate above 10% of total sessions placed on probation and reviewed | All providers |
+| Re-validation | Providers inactive for 6+ months must re-validate before re-activating their listing | All providers |
+
+## **8.2 Dispute Resolution Process**
+
+| Step | Timeframe | Action |
+| :---- | :---- | :---- |
+| 1\. User raises dispute | Within 5 days of delivery | User selects dispute reason from defined list: Service not delivered / Quality significantly below description / Provider no-show / Other |
+| 2\. System holds commission | Immediate | Commission held in escrow. Provider notified of dispute. |
+| 3\. Provider responds | Within 48hrs | Provider submits response and any supporting evidence via platform messaging |
+| 4\. GrowQR review | Within 3 business days | GrowQR review team assesses dispute, evidence, and delivery record |
+| 5\. Resolution | Within 5 business days total | GrowQR issues decision: Full refund / Partial refund / No refund \+ commission released to provider |
+| 6\. Appeals | Within 48hrs of decision | Either party may appeal once. Final decision issued within 3 additional business days. No further appeals. |
+
+## **8.3 Dispute Reasons Defined**
+
+* Service not delivered: Provider did not deliver within stated timeframe and did not communicate
+
+* Quality significantly below description: Delivered work materially does not match the service listing
+
+* Provider no-show: Live session not attended by provider without prior notice
+
+* Scope mismatch: Provider delivered something outside the agreed service scope
+
+* Technical failure: Session could not proceed due to platform technical issue (GrowQR liability — auto-refund)
+
+## **8.4 Provider Strike System**
+
+| Strike Event | Action |
+| :---- | :---- |
+| 1 no-show | Warning issued. Recorded on provider account. |
+| 2 no-shows OR 1 upheld dispute | Formal warning. 7-day listing suspension. Mandatory response to GrowQR review team. |
+| 3 no-shows OR 2 upheld disputes | Listing suspended. Full re-validation required before reinstatement. |
+| 4 strikes of any type | Permanent removal from Marketplace. Provider cannot reapply. |
+
+| 9\. INTEGRATION WITH GROWQR PLATFORM |
+| :---- |
+
+| Integrated Service | Data Shared | Direction | Purpose |
+| :---- | :---- | :---- | :---- |
+| Pathways Service | User Q-Score gaps, current cycle phase, archetype | Pathways → Marketplace | Drives pathway-triggered provider recommendations |
+| Pathways Service — Mentors | Curated mentor pool (provider IDs, domain tags, archetypes) | Marketplace → Pathways | Feeds the Mentors touchpoint in pathway cycles |
+| Wallet / Rewards | Coin balance, transaction events | Marketplace → Wallet | Enables coin-subsidised bookings |
+| Notification Service | Booking confirmations, reminders, delivery alerts, dispute updates | Marketplace → Notify | Push, email, and in-app notifications for all booking events |
+| Dashboard Service | Bookings count, sessions completed, providers reviewed | Marketplace → Dashboard | Updates user’s activity summary and achievement tracking |
+| Assessment Service | Q-Score gap profile | Assessment → Marketplace | Used by recommendation engine to match service category to skill gaps |
+| User Profile Service | Verified user status, Q-Score profile, pathway tier | Profile → Marketplace | Controls access; verifies eligibility to book services |
+
+| 10\. INNOVATION FEATURES — MARKET FAILURE PREVENTION |
+| :---- |
+
+Five structural innovations are built into the Marketplace to prevent the cold start problem and drive sustainable supply-demand balance. These features are first-principles differentiators — no competing career marketplace offers all five simultaneously.
+
+| The cold start problem is the primary cause of marketplace failure: providers will not list if there are no users, and users will not come if there are no providers. Each innovation below directly addresses a specific failure mode. |
+| :---- |
+
+## **10.1 Supply Seeding from GrowQR’s Own Platform**
+
+Problem solved: Empty marketplace at launch — no providers, no trust signals, no bookings.
+
+GrowQR’s own Tier 3 Premium users who complete their pathway and achieve a verifiable outcome (job placement, promotion, career pivot) are the first provider candidates. They have three things no external recruit has: a verified GrowQR success story, measurable Q-Score improvement data, and platform credibility.
+
+**How it works:**
+
+* System monitors pathway completions and outcome events (job landed, promotion recorded, career pivot confirmed)
+
+* Users who meet the threshold (pathway completed \+ Q-Score improvement of 15+ points \+ outcome verified) are flagged as Provider Candidates
+
+* GrowQR sends a targeted invitation: “You went from Q-Score 45 to 78 and landed a Senior PM role in 3 months. Help others do the same — earn from your experience.”
+
+* Invited users enter a fast-track validation flow (abbreviated — platform activity serves as credential verification)
+
+* First cohort of providers seeded before public Marketplace launch
+
+**System Requirements:**
+
+* Pathway Service must emit outcome events to Marketplace microservice
+
+* Candidate flagging logic: pathway\_completed \= true AND q\_score\_delta ≥ 15 AND outcome\_event received
+
+* Fast-track provider application flow: reduced steps, platform data pre-fills credentials
+
+* Provider profile auto-populates: Q-Score improvement stats, pathway completed badge, outcome verified badge
+
+## **10.2 Outcome Guarantee Tier**
+
+Problem solved: User trust — why pay for a service when I don’t know if it will work?
+
+Providers who opt in to the Outcome Guarantee tier commit to a defined, measurable outcome for the user. If the outcome is not achieved within the agreed timeframe, the user receives a partial refund. This is structurally impossible on any other career marketplace because no other platform can measure outcomes the way GrowQR can via Q-Scores.
+
+**Outcome types by service category:**
+
+| Service Category | Outcome Definition | Timeframe | Refund if Unmet |
+| :---- | :---- | :---- | :---- |
+| Interview Preparation | User receives at least 1 interview invitation within 30 days of session | 30 days post-session | 50% refund |
+| Resume & Cover Letter | User’s resume ATS score improves by defined threshold (measured in-platform) | Immediate on delivery | Full refund |
+| Social Branding | User’s LinkedIn profile view count increases by 20%+ within 30 days | 30 days | 50% refund |
+| Career Coaching | User Q-Score in target domain improves by 10+ points within 60 days | 60 days | 50% refund |
+| Skills Development | User Q-Score in coached skill area improves by 8+ points within 45 days | 45 days | 50% refund |
+
+**System Requirements:**
+
+* Provider opts in at service listing level — not all services must be Outcome Guaranteed
+
+* Outcome Guarantee badge displayed prominently on provider card and service listing
+
+* System tracks outcome trigger events per booking: interview invitations, Q-Score reassessment results, LinkedIn analytics sync
+
+* Automated outcome check at timeframe expiry: if outcome event not detected → refund triggered automatically
+
+* Provider payout held in partial escrow for outcome guarantee period
+
+* Providers with Outcome Guarantee badge ranked higher in search results and pathway recommendations
+
+* New DB fields required: outcome\_guarantee (BOOL), outcome\_type, outcome\_timeframe\_days, outcome\_refund\_pct on marketplace\_services table
+
+## **10.3 Q-Score Verified Results on Provider Profiles**
+
+Problem solved: Fake or unverifiable reviews — the standard 5-star system is gamed on every marketplace.
+
+Because GrowQR measures Q-Scores before and after every service interaction, provider profiles can display objective, platform-verified outcome data that no external marketplace can replicate. This makes GrowQR’s social proof structurally defensible.
+
+**What is displayed on each provider profile:**
+
+* Average Q-Score improvement across all clients (e.g. “Clients improved their CQm by an average of 18 points”)
+
+* Q-Score improvement breakdown by domain (per service category)
+
+* Number of verified Q-Score measurements (sample size shown for credibility)
+
+* Comparison badge: “Top 10% of Interview Prep providers by client Q-Score improvement”
+
+* Timeline chart: client Q-Score trajectory before and after working with this provider
+
+**System Requirements:**
+
+* Q-Score delta calculated per booking: compare user’s relevant Q-Score at booking date vs next reassessment date
+
+* Attribution window: Q-Score improvement attributed to provider if reassessment occurs within 60 days of session completion
+
+* Minimum sample size: Q-Score stats shown only after provider has 3+ completed bookings with Q-Score data
+
+* Privacy: Q-Score data displayed as aggregated averages only — no individual user data exposed on provider profile
+
+* New DB table required: marketplace\_qscore\_outcomes (booking\_id, provider\_id, q\_score\_name, score\_before, score\_after, delta, measurement\_date, attributed BOOL)
+
+* Provider profile API must include q\_score\_stats object in response
+
+## **10.4 Group Session Demand Aggregation Engine**
+
+Problem solved: Providers fear empty calendars; individual booking volumes too low to sustain a provider’s time investment early in the platform lifecycle.
+
+The Pathways engine actively aggregates demand for group sessions by matching pathway cycle phases across users. When a provider posts a group session, GrowQR pushes targeted notifications to all users whose current pathway cycle and Q-Score gaps align with that session’s topic — filling seats without the provider needing to do any marketing.
+
+**How it works:**
+
+* Provider creates a group session: topic, category, date/time, price per seat, max/min participants
+
+* System identifies all active pathway users whose: current cycle week is 2–4 AND service category matches session topic AND Q-Score gap in relevant domain is ≥15 points
+
+* Targeted push notification sent to matched users: “Based on your pathway, this session is recommended for you this week”
+
+* Session also surfaced in weekly cycle task list as a recommended touchpoint
+
+* Provider dashboard shows: seats filled, demand score (how many users were notified vs booked)
+
+* If session reaches minimum participants early: “Almost full” urgency indicator shown to remaining matched users
+
+**System Requirements:**
+
+* Group session matching query: JOIN pathway\_weekly\_cycles \+ marketplace\_services on category \+ q\_score\_gap threshold
+
+* Notification Service integration: targeted push/email per matched user with session details and booking link
+
+* Pathway engine must expose current\_week and gap\_categories per active user for matching query
+
+* Demand score tracking: notifications\_sent vs bookings\_converted per group session (for provider analytics)
+
+## **10.5 Pre-Booking Engine**
+
+Problem solved: Users disengage before they reach the stage where Marketplace is most valuable; providers have unpredictable and lumpy demand.
+
+The Pre-Booking Engine allows users to reserve a provider slot in advance — at the moment the pathway cycle predicts they will need it — with no charge until 48 hours before the session. This locks future demand, fills provider calendars weeks in advance, and keeps users committed to their pathway progression.
+
+**How it works:**
+
+* When user activates a pathway, Pathways engine calculates future high-value Marketplace moments based on the weekly cycle schedule
+
+* At those predicted moments (e.g. Week 3: user entering interview phase), system surfaces: “You’ll be ready for interview prep in 2 weeks. Book a top-rated coach now — no charge until 48hrs before.”
+
+* User selects provider and slot — booking is held with zero payment captured
+
+* 48 hours before session: payment captured automatically from saved payment method. User notified.
+
+* Cancellation before 48hr window: no charge, slot released
+
+* Cancellation within 48hr window: standard cancellation policy applies
+
+* Provider sees pre-bookings in calendar as “Pending Payment” — slot is held and cannot be double-booked
+
+**System Requirements:**
+
+* New booking status: pre\_booked (slot held, payment not yet captured)
+
+* Payment capture job: runs every hour, captures payment for pre\_booked sessions where slot\_datetime is within 48hrs
+
+* Pathway engine must emit pre-booking suggestion events with predicted\_need\_week and service\_category
+
+* Provider availability: pre\_booked slots shown as held in availability calendar — not available for other bookings
+
+* User payment method must be saved at pre-booking time (card saved, no charge yet)
+
+* New DB fields on marketplace\_bookings: booking\_type (standard/pre\_booked), payment\_capture\_scheduled\_at, payment\_captured\_at
+
+| 10.6 ADDITIONAL DATABASE FIELDS — INNOVATION FEATURES |
+| :---- |
+
+| Table | Additional Fields for Innovation Features |
+| :---- | :---- |
+| marketplace\_services | outcome\_guarantee (BOOL default false), outcome\_type (enum), outcome\_definition (text), outcome\_timeframe\_days (INT), outcome\_refund\_pct (INT 0-100), outcome\_escrow\_days (INT) |
+| marketplace\_bookings | booking\_type (enum: standard/pre\_booked), payment\_capture\_scheduled\_at (TIMESTAMP nullable), payment\_captured\_at (TIMESTAMP nullable), outcome\_check\_due\_at (TIMESTAMP nullable), outcome\_achieved (BOOL nullable) |
+| marketplace\_providers | is\_seeded\_provider (BOOL), seed\_pathway\_id (FK nullable), seed\_q\_score\_delta (INT nullable), fast\_track\_validated (BOOL), q\_score\_avg\_improvement (DECIMAL), q\_score\_sample\_size (INT) |
+| marketplace\_qscore\_outcomes | outcome\_id (PK), booking\_id (FK), provider\_id (FK), user\_id (FK), q\_score\_name, score\_before (INT), score\_after (INT), delta (INT), measurement\_date (DATE), attributed (BOOL), attribution\_window\_days (INT) |
+| marketplace\_group\_demand | demand\_id (PK), service\_id (FK), users\_notified (INT), users\_booked (INT), notification\_sent\_at (TIMESTAMP), cycle\_week\_match (INT), gap\_category (VARCHAR) |
+
+| 11\. ACCEPTANCE CRITERIA |
+| :---- |
+
+| \# | Acceptance Criterion | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Provider application flow completes successfully for all four provider types. Application record created with correct status transitions: Pending → Under Review → Approved / Rejected. | \[ \] PASS \[ \] FAIL |
+| **2** | Approved providers can build a profile and publish services. Unapproved providers cannot publish. Rejected providers cannot reapply for 30 days. | \[ \] PASS \[ \] FAIL |
+| **3** | All five delivery formats (Live 1:1, Async, Group, Done-For-You, Retainer) can be created as service listings by providers and booked by users. | \[ \] PASS \[ \] FAIL |
+| **4** | Open browsing returns correctly filtered and sorted provider results. All filter options (category, format, price, rating, availability, provider type) function correctly. | \[ \] PASS \[ \] FAIL |
+| **5** | Pathway-triggered recommendations surface up to 3 relevant providers per category based on user Q-Score gaps and active cycle phase. Recommendations appear in Pathway dashboard and weekly cycle task list. | \[ \] PASS \[ \] FAIL |
+| **6** | Booking flow completes for all five formats: payment processed, booking confirmed, calendar invite sent (live sessions), brief received (async/done-for-you), seat assigned (group). | \[ \] PASS \[ \] FAIL |
+| **7** | All booking state transitions function correctly: Pending → Confirmed → In Progress → Delivered → Completed. | \[ \] PASS \[ \] FAIL |
+| **8** | Cancellation policy enforced: correct refund and payout amounts calculated for each cancellation scenario. | \[ \] PASS \[ \] FAIL |
+| **9** | Provider no-show triggers automatic full refund and strike recorded on provider account. | \[ \] PASS \[ \] FAIL |
+| **10** | Dispute flow completes end-to-end: user raises dispute, commission held in escrow, provider notified, GrowQR review team receives escalation, resolution issued within 5 business days. | \[ \] PASS \[ \] FAIL |
+| **11** | Strike system enforced: correct action taken at 1, 2, 3, and 4 strike thresholds. | \[ \] PASS \[ \] FAIL |
+| **12** | Commission deducted correctly at transaction completion. Provider payout calculated as gross minus commission. Commission rate field configurable by admin (pending business decision on rate). | \[ \] PASS \[ \] FAIL |
+| **13** | Group session auto-cancels and refunds all attendees if minimum participant threshold not met 24hrs before session. | \[ \] PASS \[ \] FAIL |
+| **14** | Retainer packages: full amount charged at booking. Partial refund issued for unused sessions when package period expires. | \[ \] PASS \[ \] FAIL |
+| **15** | Mentor pool API endpoint returns correctly curated provider subset. Pathways service can query by archetype and domain tag. | \[ \] PASS \[ \] FAIL |
+| **16** | Provider dashboard shows gross earnings, commission deducted, net payout, pending transactions, and payout history accurately. | \[ \] PASS \[ \] FAIL |
+| **17** | Review system: users can leave rating and review only after booking is marked Completed. Provider rating average updates correctly. Provider cannot review their own service. | \[ \] PASS \[ \] FAIL |
+| **18** | Done-for-you 1-revision entitlement enforced: user can submit one revision request within 5 days of first draft. Second revision requests rejected. | \[ \] PASS \[ \] FAIL |
+| **19** | Provider rating monitoring: providers below 3.5 stars (min 5 reviews) flagged in admin dashboard. Providers above 10% dispute rate flagged for review. | \[ \] PASS \[ \] FAIL |
+| **20** | Supply Seeding: System correctly identifies Provider Candidates (pathway completed \+ Q-Score delta ≥15 \+ outcome event). Fast-track application flow pre-fills profile from platform data. Seeded provider badge displays on profile. | \[ \] PASS \[ \] FAIL |
+| **21** | Outcome Guarantee: Providers can opt in per service listing. Outcome badge displays on provider card and listing. Outcome check job fires at timeframe expiry. Automated refund triggered correctly if outcome not detected. Partial escrow held and released correctly. | \[ \] PASS \[ \] FAIL |
+| **22** | Q-Score Verified Results: q\_score\_outcomes table populated correctly with before/after scores attributed within 60-day window. Provider profile displays aggregated Q-Score improvement stats. Stats hidden until minimum 3 bookings with Q-Score data. No individual user data exposed. | \[ \] PASS \[ \] FAIL |
+| **23** | Group Demand Aggregation: Matching query correctly identifies users whose cycle week and Q-Score gap align with group session topic. Targeted notifications sent to matched users. Demand score (notified vs booked) tracked per session and visible in provider dashboard. | \[ \] PASS \[ \] FAIL |
+| **24** | Pre-Booking Engine: Pre-booked slots held in provider calendar and blocked from other bookings. Payment capture job fires correctly within 48hrs of session time. Cancellations before 48hr window result in zero charge. Pathway engine suggestion events surface pre-booking prompts at correct cycle weeks. | \[ \] PASS \[ \] FAIL |
+
+| DOCUMENT APPROVAL |
+| :---- |
+
+| Product Owner | \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ Date: \_\_\_/\_\_\_/\_\_\_\_\_\_ |
+| :---- | :---- |
+
+| Tech Lead | \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ Date: \_\_\_/\_\_\_/\_\_\_\_\_\_ |
+| :---- | :---- |
+
+| Status: \[ \] APPROVED — Ready for development \[ \] REVISIONS NEEDED Comments: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ |
+| :---- |
+
diff --git a/services_prd/Pathways_BRD.docx.md b/services_prd/Pathways_BRD.docx.md
new file mode 100644
index 0000000..190d156
--- /dev/null
+++ b/services_prd/Pathways_BRD.docx.md
@@ -0,0 +1,278 @@
+**GrowQR**
+
+**PATHWAYS**
+
+**MICROSERVICE SPECIFICATION**
+
+Option A: LinkedIn / Resume-Based • Option B: Premium Psychometric • v4.0 • March 2026
+
+| Pathway Microservice — Development Handover This document defines the business logic, user flows, and acceptance criteria for the Pathways service. |
+| :---: |
+
+| Service | Pathways — Career Development Orchestration Engine |
+| :---- | :---- |
+
+| Generation Options | Option A: LinkedIn / Resume scan | Option B: Psychometric \+ Q-Score (Premium) |
+| :---- | :---- |
+
+| User Tiers | Tier 1: Basic (Free) | Tier 2: Report (One-Time) | Tier 3: Premium (Subscription) |
+| :---- | :---- |
+
+| Platforms | LinkedIn— multi-country labour data: India, USA, Europe |
+| :---- | :---- |
+
+| Version | 4.0 — March 2026 |
+| :---- | :---- |
+
+| 1\. WHAT IS PATHWAYS? |
+| :---- |
+
+Pathways is the central orchestration engine of GrowQR. It takes a user’s background, interests, skills, and goals — and turns them into a personalised career development journey coordinated across all 11 GrowQR services.
+
+**The core question Pathways answers:**
+
+***“What else can I — given my personality, skills, and background — do and achieve in the world?”***
+
+Not just: “What is the next job title in my current career?”
+
+Pathways generates a wide range of career combination options — some expected, some surprising — based on who the user actually is, not just what their CV says. It then activates a structured journey to help them get there.
+
+| What Pathways Does | What Pathways Is Not |
+| :---- | :---- |
+| Generates multiple career path options from the user’s profile and questionnaire | A simple job search tool |
+| Orchestrates 11 services into weekly development cycles | A course platform or LMS |
+| Produces a professional Pathway Report PDF | A static one-time plan |
+| Adapts in real-time as Q-Scores improve and activities complete | A rigid 12-month roadmap |
+| Surfaces live job market data by region (India, USA, Europe) | A recruitment agency |
+
+| 2\. THE QUESTIONNAIRE FLOW |
+| :---- |
+
+Before any pathway is generated — whether Option A or Option B — the user completes a short questionnaire. This is the input layer that drives career combination generation. It is asking about experience, interests, and skills — but GrowQR goes further by combining this with profile data and Q-Scores.
+
+| The questionnaire is designed to take 5–10 minutes maximum. Questions are conversational, not clinical. The goal is to surface what the user cares about and where they want to go — not to test them. |
+| :---- |
+
+**2.1 Questionnaire Structure — Four Steps (Most of it can be taken Linkedin or Resume)**
+
+| STEP 1: PREVIOUS EXPERIENCE |
+| :---- |
+| What is your current or most recent job title? |
+| How many years of professional experience do you have? (Student / 0–2 years / 3–5 years / 6–10 years / 10+ years) |
+| Which industry or domain have you worked in most? (dropdown with multi-select) |
+| What are 3–5 things you have done professionally that you are most proud of? (free text, short) |
+
+| STEP 2: INTERESTS & WHAT ENERGISES YOU |
+| :---- |
+| Which of these activities energise you most? (multi-select from 12–15 options e.g. solving complex problems, leading people, building products, creating content, selling ideas, analysing data, coaching others, designing experiences) |
+| What topics do you find yourself reading about or watching videos on outside of work? (free text) |
+| Do you prefer working independently, in a team, or leading others? (single select) |
+| What kind of environment brings out your best work? (e.g. fast-moving startup, large organisation, remote, client-facing) |
+
+| STEP 3: SKILLS |
+| :---- |
+| What are your top 3–5 skills? (free text or tag selection from skill bank) |
+| Which skills do you most want to develop in the next 12 months? (multi-select) |
+| Are there any domains or tools you have taught yourself outside of formal education? (free text) |
+
+| STEP 4: GOALS & DIRECTION |
+| :---- |
+| Where do you want to be in your career in 1–3 years? (free text) |
+| What matters more to you right now — higher earnings, greater fulfilment, or a balance of both? (slider: 0% earnings / 100% fulfilment ↔ 100% earnings / 0% fulfilment) |
+| Is there a specific role, company type, or industry you are aiming for? (optional, free text) |
+| What is your biggest career challenge right now? (multi-select: lack of direction / skills gaps / not getting interviews / need to change industry / want to grow faster / starting from scratch) |
+
+**2.2 What the Questionnaire Generates**
+
+Once the four steps are complete, the system combines questionnaire responses with any available profile data (LinkedIn scan or resume) to generate:
+
+* A wide range of career combination options — not just one or two obvious paths, but a broader set of possibilities the user may not have considered
+
+* Each combination shows: role title, domain, match rationale, required skills, salary range (by region), and demand level
+
+* Options are grouped by: Close Match (high overlap with current skills), Adjacent (moderate pivot), and Stretch (ambitious but achievable with development)
+
+* The Visual Career Web is rendered from this output — showing the combinations as an interactive node map
+
+* A Career Identity Statement is generated: 2–3 sentences summarising the user’s transferable value
+
+| The questionnaire output feeds both Option A and Option B. For Option A users, it is the primary input. For Option B Premium users, it is combined with the psychometric assessment and full 25 Q-Score results for deeper personalisation. |
+| :---- |
+
+| 3\. VISUAL CAREER WEB |
+| :---- |
+
+The Visual Career Web is the primary output display of the questionnaire flow. Instead of showing career options as a plain list, it renders them as an interactive node diagram — the user’s current role or profile at the centre, with recommended career paths radiating outward.
+
+**3.1 How It Works**
+
+* Centre node: user’s current role or “Your Starting Point” if no current role
+
+* Surrounding nodes: career path combinations grouped by Close Match, Adjacent, and Stretch
+
+* Each node shows on hover or tap: role title, match %, salary range, demand level (High / Medium / Low)
+
+* Clicking a node expands it: skill gaps, top courses, live job links, regional salary chart
+
+* Filter bar: user can adjust weightings (skills match / salary priority / growth potential / interests alignment) — web re-renders
+
+* Colour coding: Green \= high demand, Amber \= medium demand, Grey \= low demand or emerging
+
+* Mobile: full interactive on desktop and tablet; card-stack view on mobile
+
+**3.2 Tier-Gated Behaviour**
+
+| Feature | Tier 1 Basic | Tier 2 Report | Tier 3 Premium |
+| :---- | :---- | :---- | :---- |
+| Career web visible | Yes — full web | Yes — full web | Yes — full web |
+| Node expansion (full detail) | 2 nodes only, rest locked | All nodes | All nodes \+ Q-Score gap mapping |
+| Live job links per path | 3 per node | 10 per node | Unlimited real-time |
+| Salary data | Range only | Full chart | Full chart \+ regional comparison |
+| Pathway activation | Locked — upgrade prompt | 1-month activation | 3 / 6 / 12-month activation |
+
+| 4\. THREE-TIER USER MODEL |
+| :---- |
+
+Users enter at any tier. Each tier delivers real value. Higher tiers unlock deeper personalisation and longer pathway activation.
+
+| | Tier 1: Basic | Tier 2: Report | Tier 3: Premium |
+| :---- | :---- | :---- | :---- |
+| Access | Free — no account required | One-time purchase | Subscription |
+| Input | LinkedIn URL or resume upload \+ questionnaire | Same as Tier 1 | Psychometric assessment \+ 25 Q-Scores \+ questionnaire |
+| Career Web | Full web, 2 nodes expandable | Full web, all nodes | Full web, all nodes \+ Q-Score mapping |
+| Report | 2-section teaser PDF | Full 14–16 page PDF | Full PDF, auto-updates as progress made |
+| Pathway Activation | None | 1 month — all 11 services | 3 / 6 / 12 months — all 11 services |
+| Personalisation | Profile \+ questionnaire | Profile \+ questionnaire | Psychometric \+ Q-Score \+ questionnaire |
+| Upgrade Prompt | Purchase Report or start Premium | Upgrade to Premium after 1 month | Ongoing — no further upgrade needed |
+
+| 5\. TWO PATHWAY GENERATION OPTIONS |
+| :---- |
+
+Both options activate the full 11-service orchestration engine once a pathway is live. The difference is the depth of input used to personalise the pathway.
+
+| OPTION A: BASIC — LinkedIn / Resume-Based Available to Tier 1, 2 and 3 as starting point • No psychometric required |
+| :---- |
+| Input: LinkedIn URL or uploaded resume (PDF / DOCX) \+ completed questionnaire (4 steps) |
+| Parser extracts: current role, skills, work history, education, certifications, industry |
+| Combined with questionnaire responses to generate career combination options |
+| Career Identity Statement generated: 2–3 sentences of transferable value summary |
+| Visual Career Web rendered: 3–5+ career path combinations across Close Match, Adjacent, Stretch |
+| Skill gap analysis per path: which skills need development to reach each option |
+| 4-week curriculum generated with specific course links mapped to skill gaps |
+| Live job postings surfaced per path from regional job platforms |
+| Regional labour market data applied: salary, demand, top hiring companies (India / USA / Europe) |
+| Full Pathway Report PDF generated for Tier 2 and Tier 3 users |
+| 1-month pathway activated for Tier 2\. 3/6/12-month pathway activated for Tier 3\. |
+
+| OPTION B: PREMIUM — Psychometric \+ Q-Score Tier 3 only • Maximum personalisation • Scientifically validated |
+| :---- |
+| Input: Completed psychometric assessment (10–30 questions) \+ all 25 Q-Scores measured \+ questionnaire |
+| Big Five personality profiling \+ behavioural analysis (work style, learning style, motivation drivers) |
+| Algorithm: 60% psychometric weighting \+ 40% Q-Score weighting \+ questionnaire as contextual layer |
+| User sets earnings vs. fulfilment ratio (slider) — adjusts pathway recommendations accordingly |
+| Personality Archetype assigned: one of five (see Section 7\) |
+| Three pathway options ranked: Primary (85%+ match), Alternative 1 (75–85%), Alternative 2 (65–75%) |
+| User selects and activates one pathway — only one active pathway permitted at any time |
+| Full 14–16 page Pathway Report PDF generated with archetype analysis, radar charts, and GrowQR branding |
+| Weekly cycles generated across all 11 services for 3, 6, or 12 months |
+| Adaptive engine: pathway adjusts in real-time as Q-Scores improve and services are completed |
+| Monthly Q-Score reassessment; Report PDF auto-updated on significant score changes |
+
+| 6\. 11-SERVICE ORCHESTRATION |
+| :---- |
+
+Pathways does not contain the 11 services. It is an orchestration layer that coordinates them through touchpoints. Once a user activates a pathway (Tier 2 or Tier 3), all 11 services are engaged in a structured weekly cycle. Suggestions:
+
+| Service | Primary Skills Built | Cycle Frequency |
+| :---- | :---- | :---- |
+| 1\. Roleplay (LMS) | Communication, Emotional Intelligence, Influence | Weekly |
+| 2\. Interview Practice | Analytical thinking, Communication, Leadership | Weekly |
+| 3\. Courses | Technical, Domain, Business, Learning skills | Weekly — heavy in Month 1 |
+| 4\. Assessment | All 25 Q-Scores measured | Week 1 baseline; monthly after |
+| 5\. Resume & Cover Letter | Updated automatically as skills develop | As skills develop |
+| 6\. Social Branding | Reputation, Influence, Networking, Marketing | Bi-weekly |
+| 7\. Job Matching | All Q-Scores (matching layer) | Light Month 1; heavy Month 2+ |
+| 8\. Events | Networking, Social, Cultural | 1–2 per month |
+| 9\. Networking | Networking, Social, Influence | Weekly Month 1; bi-weekly after |
+| 10\. Mentors | Learning, Growth, Vision, Leadership | Monthly sessions |
+| 11\. Community | Social, Networking, Reputation | Bi-weekly |
+
+**6.1 Six Weekly Cycle Rules \- Suggestions:**
+
+| Rule | Description |
+| :---- | :---- |
+| Rule 1: Start with Assessment | Week 1 always begins with Q-Score baseline measurement. Cannot be skipped. |
+| Rule 2: Core Services Weekly | Courses, Roleplay, and Interview Practice appear every week throughout the pathway. |
+| Rule 3: Support Services Scheduled | Mentors monthly. Community bi-weekly. Networking weekly in Month 1, bi-weekly after. |
+| Rule 4: Time Balance | Total weekly commitment: 2–3 hours. Hard cap: 3.5 hours. Prevents burnout. |
+| Rule 5: Progression | Month 1: 60% Learn / 40% Apply. Month 2: 50/50. Month 3+: 30% Learn / 70% Apply. |
+| Rule 6: Adaptive | Skipped service \= higher priority next week. Q-Score \+10 points \= advanced content unlocked. |
+
+| 7\. PATHWAY REPORT — PDF SPECIFICATION |
+| :---- |
+
+The Pathway Report is a professionally designed PDF document generated for Tier 2 (one-time purchase) and Tier 3 (subscription). Tier 1 receives a 2-section teaser. The report is 14–16 pages, full colour, GrowQR branded.
+
+| Section | Title | Contents |
+| :---- | :---- | :---- |
+| 1 | Your Personality Archetype | Archetype badge, top 5 Q-Scores with radar chart, what motivates you, how you work best |
+| 2 | Career Path Recommendations | Primary path (85%+), Alternative 1 (75–85%), Alternative 2 (65–75%), comparison table |
+| 3 | Skill Development Plan | Q-Score gap analysis, top 5 priority skills, course links, milestone checkpoints |
+| 4 | Job Market Alignment | Demand indicator, salary range by experience (region-specific), top 15 companies hiring |
+| 5 | Weekly Action Plan | Month 1 week-by-week calendar, 11-service touchpoint grid, monthly goals checklist |
+| 6 | 11 Services Map | Each service: what it does, when to use, expected outcome |
+| 7 | Progress Tracking | Q-Score trend chart, monthly snapshot, milestone checklist, application pipeline |
+| 8 | Next Steps | Top 3 immediate actions, support resources, motivational close |
+
+| 8\. FIVE PERSONALITY ARCHETYPES — OPTION B REFERENCE |
+| :---- |
+
+Used in Option B (Premium) only. Archetype is assigned based on Q-Score profile after psychometric assessment is complete.
+
+| Archetype | Q-Score Thresholds | Typical Pathways |
+| :---- | :---- | :---- |
+| Technical Specialist | TQ ≥75, IQ ≥75, XQ ≥70, DQ ≥70 | Software Engineer, Data Scientist, Technical Architect |
+| Strategic Leader | StQ ≥75, LdrQ ≥75, VQ ≥70, InQ ≥70, EQ ≥70 | VP/Director, Strategy Consultant, Founder/CEO |
+| Creative Innovator | CrQ ≥75, CQx ≥70, IQ ≥70, CQm ≥70 | Product Designer, UX Researcher, Creative Director |
+| Sales & Influence Driver | MQ ≥75, InQ ≥75, NQ ≥70, CQm ≥70 | Sales Director, Business Development, Growth Lead |
+| Entrepreneurial Builder | GQ ≥75, XQ ≥75, DQ ≥75, AQ ≥70, RQ ≥70 | Founder/Startup, Product Manager, Independent Consultant |
+
+| 9\. SYSTEM CONSTRAINTS |
+| :---- |
+
+The following constraints must be enforced by the system at all times:
+
+| \# | Constraint |
+| :---- | :---- |
+| 1 | Only 1 active pathway permitted per user at any time. Activating a new pathway deactivates the previous. |
+| 2 | Pathway switching requires a minimum of 2- 4 weeks completed on the current pathway. |
+| 3 | Pathway regeneration is limited to once per calendar month. |
+| 4 | Timeline options are fixed: 1 month (Tier 2), or 3 / 6 / 12 months (Tier 3). No custom timelines. |
+| 5 | Option B generation requires all 25 Q-Scores to be completed. Partial assessments are rejected. |
+| 6 | Career goal input is validated by NLP. Vague goals (e.g. ‘better job’) are rejected with a clarification prompt. |
+| 7 | Weekly cycle time cap: maximum 3.5 hours of service touchpoints per week. |
+| 8 | Questionnaire must be completed before any pathway is generated, regardless of option or tier. |
+| 9 | Region is auto-detected on first use. Labour market data served from matching regional dataset. Manual override available. |
+| 10 | Generated reports stored for 12 months from creation date. |
+
+| 10\. ACCEPTANCE CRITERIA |
+| :---- |
+
+| \# | Acceptance Criterion | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Questionnaire flow completes all 4 steps for all users (Tier 1, 2, and 3). Responses captured correctly. Questionnaire must be completed before pathway generation is triggered. | \[ \] PASS \[ \] FAIL |
+| **2** | Career combination options generated from questionnaire \+ profile data. Options grouped correctly into Close Match, Adjacent, and Stretch categories. | \[ \] PASS \[ \] FAIL |
+| **3** | Career Identity Statement generated for every user on questionnaire completion. | \[ \] PASS \[ \] FAIL |
+| **4** | Visual Career Web renders with correct nodes per combination category. Filter adjustments re-render the web in real-time. Tier-gated content enforced (Tier 1: 2 nodes expandable; Tier 2+: all nodes). | \[ \] PASS \[ \] FAIL |
+| **5** | Option A pathway generated correctly from LinkedIn URL or resume upload \+ questionnaire. Skill gap analysis, 4-week curriculum, and live job postings populated per path. | \[ \] PASS \[ \] FAIL |
+| **6** | Option B pathway generated using 60% psychometric \+ 40% Q-Score algorithm. Requires all 25 Q-Scores completed. Archetype assigned correctly from Q-Score thresholds. | \[ \] PASS \[ \] FAIL |
+| **7** | Three pathway options generated for Option B: Primary (85%+), Alt 1 (75–85%), Alt 2 (65–75%). Match percentages calculated correctly. | \[ \] PASS \[ \] FAIL |
+| **8** | Tier 1: 2-section teaser PDF generated with upgrade CTA. Tier 2 and 3: Full 14–16 page Pathway Report PDF generated with all 8 sections and GrowQR branding. Generation time under 5 seconds. | \[ \] PASS \[ \] FAIL |
+| **9** | Tier 2: 1-month pathway activated on purchase. All 11 services available. Deactivates after 30 days if not upgraded. | \[ \] PASS \[ \] FAIL |
+| **10** | Tier 3: 3/6/12-month pathway active. Weekly cycles follow all 6 generation rules. Adaptive engine adjusts cycle based on Q-Score changes and service completions. | \[ \] PASS \[ \] FAIL |
+| **11** | Both Option A and Option B activate full 11-service orchestration on pathway activation. | \[ \] PASS \[ \] FAIL |
+| **12** | Regional labour market data served correctly for India, USA, and Europe. Salary, demand, and company data accurate per region. Auto-detection functional with manual override. | \[ \] PASS \[ \] FAIL |
+| **13** | All 10 system constraints enforced correctly. | \[ \] PASS \[ \] FAIL |
+| **14** | Monthly Q-Score reassessment updates pathway recommendations and triggers report regeneration when score changes by 10+ points. | \[ \] PASS \[ \] FAIL |
+| **15** | Google Drive PDF save functions correctly for Tier 3 users (optional feature). | \[ \] PASS \[ \] FAIL |
+
diff --git a/services_prd/SocialBranding_BRD.docx.md b/services_prd/SocialBranding_BRD.docx.md
new file mode 100644
index 0000000..1dd4d37
--- /dev/null
+++ b/services_prd/SocialBranding_BRD.docx.md
@@ -0,0 +1,396 @@
+**GrowQR**
+
+**SOCIAL BRANDING**
+
+**DEVELOPER BRD — TECHNICAL SPECIFICATION**
+
+Individual Social Branding • Enterprise Social Branding • 4 Platforms • 6 Personas • v1.0 • March 2026
+
+| Social Branding Microservices This document contains specifications, business logic, and acceptance criteria for development. |
+| :---: |
+
+| Document Title | Social Branding Service — Developer BRD Technical Specification |
+| :---- | :---- |
+
+| Version | 1.0 — March 2026 |
+| :---- | :---- |
+
+| Service Type | Standalone Microservice — Part of Opportunity Module |
+| :---- | :---- |
+
+| Target Platforms | LinkedIn | Instagram | Twitter/X | YouTube |
+| :---- | :---- |
+
+| Target Launch | April 1st — LinkedIn, Instagram, YouTube, Twitter/X , Git |
+| :---- | :---- |
+
+| Part 1 | Individual Social Branding — 6 end-goal personas, full automation with approval |
+| :---- | :---- |
+
+| Part 2 | Enterprise Social Branding — Company brand presence, governance, multi-platform management |
+| :---- | :---- |
+
+| Q-Score Integration | Brand Score (0–100) feeds RQx. Q-Score changes trigger automatic profile and content updates. |
+| :---- | :---- |
+
+| Data Collection | Method TBD by technical team — BRD specifies data requirements only |
+| :---- | :---- |
+
+| PART 1 — INDIVIDUAL SOCIAL BRANDING |
+| :---: |
+
+Part 1 covers the Social Branding service for individual GrowQR users. It is a fully automated, AI-managed presence builder across LinkedIn, Instagram, Twitter/X, and YouTube — with user approval at every execution step.
+
+| 1\. SERVICE OVERVIEW — INDIVIDUAL |
+| :---- |
+
+The Individual Social Branding service transforms a user’s professional presence from a passive profile into an active, consistent, and strategically managed brand. The service operates on a Scrape → Analyse → Generate → Approve → Post → Track loop, fully managed by GrowQR’s AI layer.
+
+The service is built on five structural pillars drawn from proven social branding principles:
+
+| Pillar | Definition | How GrowQR Implements It |
+| :---- | :---- | :---- |
+| Consistency | Uniform brand voice, visual style, and messaging across all platforms | AI enforces tone, vocabulary, and visual style rules per persona across all connected platforms |
+| Target Audience | Understanding the social habits of the user’s ideal audience (recruiters, clients, peers, investors) | Audience profile built from user’s pathway archetype, target role, and Q-Score profile |
+| Content Strategy | A defined mix of educational, entertaining, and inspirational content mapped to brand values | 80/20 content model: 80% pre-baked persona toolkit, 20% dynamic AI-generated content |
+| Engagement | Active interaction with followers: likes, comments, DMs, connection requests | AI drafts engagement responses; user approves or auto-approves based on engagement rules |
+| Platform Selection | Right platforms for the user’s archetype and target audience | Archetype-conditional platform activation — not all platforms recommended to all users |
+
+## **1.1 The Automation Loop**
+
+| Stage | Action | Human Touch Point |
+| :---- | :---- | :---- |
+| 1\. Connect | User connects social accounts via OAuth | One-time setup per platform |
+| 2\. Scrape / Collect | System collects profile data, post history, engagement metrics, follower data | None — automated |
+| 3\. Analyse | AI analyses profile completeness, content performance, audience alignment, Brand Score calculated | User reviews Brand Score dashboard |
+| 4\. Generate | AI generates: profile rewrites, content calendar, post drafts, engagement responses | User reviews all generated content |
+| 5\. Approve | User approves, edits, or rejects each item in the approval queue | Primary user interaction point |
+| 6\. Post / Execute | Approved content scheduled and posted. Profile updates applied. Engagement responses sent. | None — automated post-approval |
+| 7\. Track | System monitors: impressions, profile views, follower growth, engagement rate, recruiter search appearances | User reviews weekly analytics dashboard |
+| 8\. Feed Back | Performance data feeds Brand Score and RQx Q-Score. Pathway engine updates recommendations. | None — automated |
+
+| 2\. BRAND SCORE — THE SOCIAL Q-SCORE |
+| :---- |
+
+Brand Score is a single 0–100 metric that measures the strength, consistency, and discoverability of a user’s professional presence across all connected platforms. It is GrowQR’s proprietary social presence measurement and feeds directly into RQx (Reputation Quotient) in the Q-Score engine.
+
+| Brand Score is not a vanity metric. It is calculated from objective, measurable signals. As the user takes actions recommended by the Social Branding service, their Brand Score improves. Brand Score improvement directly improves their RQx Q-Score, which in turn updates their pathway recommendations. |
+| :---- |
+
+## **2.1 Brand Score Components**
+
+| Component | Weight | What It Measures |
+| :---- | :---- | :---- |
+| Profile Completeness | 20% | All profile sections populated, keyword-optimised, and aligned to target role across active platforms |
+| Content Consistency | 20% | Posting frequency maintained, tone consistent, visual style uniform across platforms |
+| Audience Growth | 15% | Follower/connection growth rate over 30-day rolling window |
+| Engagement Rate | 15% | Likes, comments, shares, and saves as a percentage of reach per post |
+| Recruiter Visibility | 15% | Profile appearance rate in relevant recruiter and talent searches (LinkedIn primary) |
+| Content Quality | 10% | AI-assessed relevance, originality, and alignment to persona content framework |
+| Cross-Platform Consistency | 5% | Messaging and voice alignment across all connected platforms |
+
+## **2.2 Brand Score → RQx Integration**
+
+* Brand Score calculated after every platform data sync (example: frequency: daily for LinkedIn, 48hrs for others)
+
+* Brand Score mapped to RQx using a defined conversion formula: RQx contribution \= Brand Score × 0.4 (40% weighting of RQx from Brand Score)
+
+* RQx update event emitted to Assessment Service and Pathways Service on every Brand Score change of 5+ points
+
+* Pathways engine re-evaluates Social Branding touchpoint recommendations on RQx update
+
+* User’s Brand Score history stored and displayed as a trend line on the Social Branding dashboard
+
+| 3\. SIX END-GOAL PERSONAS — CONTENT FRAMEWORK |
+| :---- |
+
+Every user’s Social Branding strategy is driven by their end-goal persona. The persona is derived from the user’s active pathway archetype, target role, and career goal input. Users can switch personas as their goals evolve. Each persona has a defined platform mix, content angle, and posting frequency.
+
+| Platform activation is archetype-conditional. Not all platforms are recommended to all users. The system activates platforms relevant to the user’s persona and prompts the user to connect them. Users can override and connect any platform manually. |
+| :---- |
+
+| PERSONA 1: JOB SEEKER Archetype: All archetypes — active job search phase |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (secondary for tech/creative roles) **Content Angle** Recruiter visibility, skills signalling, open-to-work positioning, achievement highlights **Posting Frequency** LinkedIn: 4x per week. Twitter/X: 3x per week if active. |
+
+| PERSONA 2: CAREER TRANSITIONER Archetype: All archetypes — changing domain or role type |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Instagram (if transitioning to creative/coaching/consulting) **Content Angle** Narrative reframing: connecting past experience to new direction, learning journey documentation **Posting Frequency** LinkedIn: 3x per week. Instagram: 2x per week if active. |
+
+| PERSONA 3: THOUGHT LEADER Archetype: Strategic Leader, Entrepreneurial Builder, Domain Expert |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (primary), YouTube (secondary) **Content Angle** Industry insights, opinion pieces, trend analysis, frameworks and models, contrarian takes **Posting Frequency** LinkedIn: 5x per week. Twitter/X: daily. YouTube: 1x per month minimum. |
+
+| PERSONA 4: DOMAIN EXPERT Archetype: Technical Specialist, Creative Innovator |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), GitHub (external link), YouTube (tutorials/walkthroughs) **Content Angle** Deep technical content, how-to posts, case studies, project showcases, certification highlights **Posting Frequency** LinkedIn: 3x per week. YouTube: 2x per month. |
+
+| PERSONA 5: ENTREPRENEUR / FOUNDER Archetype: Entrepreneurial Builder |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (primary), Instagram (brand building), YouTube (storytelling) **Content Angle** Build-in-public content, startup journey, lessons learned, team culture, product milestones **Posting Frequency** LinkedIn: 5x per week. Twitter/X: daily. Instagram: 3x per week. YouTube: 2x per month. |
+
+| PERSONA 6: EXECUTIVE / ENTERPRISE LEADER Archetype: Strategic Leader — VP, Director, C-suite level |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (secondary) **Content Angle** Executive presence: strategic vision, culture and values, industry leadership, org transformation, speaking engagements **Posting Frequency** LinkedIn: 3x per week. Twitter/X: 2x per week. |
+
+| 4\. THE 80/20 CONTENT MODEL |
+| :---- |
+
+All content generated by GrowQR’s Social Branding service follows an 80/20 split: 80% pre-baked toolkit content and 20% dynamic AI-generated content. This balance ensures consistency and quality (80%) while maintaining relevance and freshness (20%).
+
+## **4.1 80% — Pre-Baked Toolkit**
+
+The pre-baked toolkit is a library of proven content frameworks, post templates, hooks, and evergreen structures mapped to each persona and platform. This content is designed, tested, and maintained by GrowQR. It does not require AI generation — it is filled with user-specific data at execution time.
+
+| Content Type | Description | Persona Applicability |
+| :---- | :---- | :---- |
+| Achievement Post | Structured template: milestone \+ what it took \+ what you learned. Fills with user’s real achievements from pathway completions. | All personas |
+| Skills Signal Post | Highlights a specific skill or certification. Links to Q-Score improvement data. | Job Seeker, Domain Expert, Career Transitioner |
+| Insight Share | Short opinion or observation on an industry trend. Structure: Hook \+ Insight \+ Question to audience. | Thought Leader, Executive, Entrepreneur |
+| Career Story Post | Narrative format: where I was \+ what changed \+ where I am now. Used for transitions and milestones. | Career Transitioner, Entrepreneur |
+| Project Showcase | Work sample or project result with context. Visual-first for Instagram; text+image for LinkedIn. | Domain Expert, Creative Innovator, Entrepreneur |
+| Engagement Prompt | Question or poll to drive comments. Mapped to user’s domain for relevant audience response. | All personas |
+| Weekly Reflection | End-of-week summary: what I worked on, what I learned, what’s next. | Thought Leader, Entrepreneur, Executive |
+| Company/Role Spotlight | Highlights a company or role the user is targeting or has experience with. Builds recruiter relevance. | Job Seeker, Career Transitioner |
+
+## **4.2 20% — Dynamic Content**
+
+Dynamic content is AI-generated in real-time based on signals from the user’s platform activity, Q-Score progress, pathway milestones, and trending topics in their domain. This content is fresh, timely, and personalised — it cannot be pre-baked.
+
+* Q-Score improvement post: auto-generated when user improves a Q-Score by 10+ points. Frames the improvement as a professional growth story.
+
+* Pathway milestone post: auto-generated when user completes a course, earns a certificate, or achieves a pathway milestone.
+
+* Trending topic response: AI monitors trending topics in the user’s domain. Generates a short opinion post when a relevant trend is detected.
+
+* Interview or job application event: auto-generated encouragement and visibility post when user applies for a role or secures an interview (with user consent).
+
+* Engagement response drafts: AI drafts replies to comments on the user’s posts, maintaining persona tone and voice.
+
+* Profile update trigger: when user’s Q-Scores or pathway status changes significantly, AI generates updated headline, about section, and skills list for user approval.
+
+## **4.3 Content Calendar Generation Rules**
+
+| Rule | Description |
+| :---- | :---- |
+| Rule 1: Frequency Enforcement | System enforces minimum posting frequency per persona. If user has not approved content for upcoming slots, system sends reminder 48hrs in advance. |
+| Rule 2: Platform Sequencing | Content is not duplicated across platforms. Each platform receives a uniquely formatted version adapted to that platform’s style and audience. |
+| Rule 3: Content Mix Enforcement | System ensures the 80/20 split is maintained over any 2-week rolling window. Prevents over-reliance on either toolkit or dynamic content. |
+| Rule 4: No Auto-Post Without Approval | No content is ever posted without explicit user approval. Auto-approve mode is available as an opt-in setting only. |
+| Rule 5: Tone Lock | Once user’s brand voice is established (after first 2 weeks), tone settings are locked unless user explicitly resets them. |
+| Rule 6: Sensitive Topic Filter | AI applies a topic filter before generating content. Posts that touch on politically sensitive, legally risky, or reputationally harmful territory are flagged and not queued for approval. |
+
+| 5\. PLATFORM SPECIFICATIONS — INDIVIDUAL |
+| :---- |
+
+## **5.1 LinkedIn**
+
+| Capability | Specification |
+| :---- | :---- |
+| Profile Analysis | Audit: Headline, About, Experience, Skills, Recommendations, Featured section, Activity. Score each section 0–100. Benchmark against target role requirements and top 10% of professionals in same role. |
+| Profile Rewrite | AI generates optimised versions of: Headline (3 variants), About section, Experience bullet points (per role), Skills list (mapped to Q-Scores and target JD keywords). User selects and approves. |
+| Recruiter Visibility | Keyword gap analysis: identifies terms recruiters search for this role that are missing from profile. Injects keywords into profile sections naturally. |
+| Content Posting | Supports: text posts, image posts, document carousels, polls, article links. Content formatted to LinkedIn algorithm best practices (hook in first 2 lines, no external links in body). |
+| Connection Strategy | Identifies target connections based on user’s pathway: target companies, role peers, hiring managers in target domain. AI drafts personalised connection request notes. |
+| Engagement Automation | AI drafts comments on posts from target connections and industry leaders. User approves before sending. Builds visibility with relevant audience. |
+| Analytics Tracked | Profile views (7-day, 30-day), Search appearances, Post impressions, Engagement rate per post, Connection acceptance rate, Follower growth |
+
+## **5.2 Instagram**
+
+| Instagram is activated for: Career Transitioner (creative/coaching roles), Entrepreneur/Founder, Domain Expert (creative/design roles). Not recommended by default for Technical Specialist or Strategic Leader personas unless user opts in. |
+| :---- |
+
+| Capability | Specification |
+| :---- | :---- |
+| Profile Analysis | Bio, profile photo, link-in-bio, highlight covers, grid aesthetic consistency, story frequency. Score for professional brand alignment. |
+| Content Types | Feed posts (static image, carousel), Reels (short-form video), Stories (ephemeral). Each type has distinct content templates in the pre-baked toolkit. |
+| Visual Style Consistency | AI enforces visual brand rules: colour palette (derived from user’s LinkedIn brand colours), font style, filter consistency. Applied to all generated visual templates. |
+| Caption Framework | Each caption follows: Hook (first line visible before ‘more’) \+ Value (body) \+ CTA (final line) \+ Hashtags (max 5, domain-specific). Hashtag bank maintained per persona. |
+| Story Strategy | Stories used for: behind-the-scenes content, quick tips, polls, Q\&As. Frequency: 3–5 stories per week. Story templates provided per persona. |
+| Analytics Tracked | Reach, Impressions, Profile visits, Follower growth, Story views, Reel plays, Link-in-bio clicks, Saves per post |
+
+## **5.3 Twitter / X**
+
+| Twitter/X is targeted for Phase 2 launch. Architecture and data model specified here for development readiness. April 1st launch excludes Twitter/X. |
+| :---- |
+
+| Capability | Specification |
+| :---- | :---- |
+| Profile Analysis | Bio (160 chars), header image, pinned tweet, posting frequency, engagement rate, follower-to-following ratio. |
+| Content Types | Short posts (under 280 chars), Threads (multi-tweet narrative), Quote posts (with commentary), Replies (engagement strategy). |
+| Thread Framework | Threads used for: insight breakdowns, how-to guides, career lessons, domain deep-dives. Format: Hook tweet \+ 5–10 body tweets \+ CTA final tweet. |
+| Posting Strategy | Optimal posting times calculated per user’s audience timezone. Threads on weekdays, shorter posts and replies on weekends. |
+| Analytics Tracked | Impressions, Engagements, Profile clicks, Link clicks, Follower growth, Thread completion rate |
+
+## **5.4 YouTube**
+
+| Capability | Specification |
+| :---- | :---- |
+| Channel Analysis | Channel art, About section, playlist structure, video titles and descriptions (SEO), thumbnail consistency, upload frequency, subscriber growth rate. |
+| Content Types | Long-form (10–20 min): deep dives, case studies, tutorials. Short-form (YouTube Shorts, under 60 sec): tips, quick insights, career advice clips. |
+| Video Brief Generation | AI generates video briefs: title (3 variants), hook script (first 30 seconds), chapter outline, description with keywords, tags, thumbnail concept. User records; AI does not generate video. |
+| SEO Optimisation | Title keyword analysis, description keyword injection, tag strategy, chapter timestamps. Benchmarked against top-performing videos in user’s domain. |
+| Thumbnail Strategy | AI generates thumbnail design brief: text overlay, colour scheme, facial expression guidance (if talking head). Thumbnail template provided per persona. |
+| Upload Frequency | Persona-based targets: Thought Leader (1x/month minimum), Domain Expert (2x/month), Entrepreneur (2x/month). System prompts user when cadence is falling behind. |
+| Analytics Tracked | Views, Watch time, Subscriber growth, Click-through rate (thumbnails), Average view duration, Top traffic sources |
+
+| 6\. DATA REQUIREMENTS — INDIVIDUAL |
+| :---- |
+
+| Data collection method (API vs scraping vs user-authenticated export) is TBD and left to the technical team. This section specifies what data is required. The technical team must define the collection mechanism, document any legal or rate-limit constraints, and confirm data availability before development of the collection layer. |
+| :---- |
+
+| Platform | Data Required | Frequency |
+| :---- | :---- | :---- |
+| LinkedIn | Profile sections (headline, about, experience, education, skills, certifications, featured, recommendations). Post history (last 90 days). Engagement per post (likes, comments, shares). Profile view count. Search appearance count. Connection count. Follower count. | Daily sync |
+| Instagram | Bio, profile photo URL, follower count, following count, post count. Feed posts (last 60 days): caption, image URL, likes, comments, saves, reach, impressions. Story views (last 30 days). Reel plays. | 48-hour sync |
+| Twitter/X | Bio, follower count, following count. Tweet history (last 60 days): text, impressions, engagements, link clicks, retweets, replies. Profile visits. | 48-hour sync (Phase 2\) |
+| YouTube | Channel stats: subscriber count, total views, video count. Per-video: title, description, tags, views, watch time, CTR, average view duration, subscriber change. Upload dates. | Weekly sync |
+
+| PART 2 — ENTERPRISE SOCIAL BRANDING |
+| :---: |
+
+Part 2 covers the Social Branding service for companies and organisations. An enterprise account manages its brand presence across social platforms — defining what to post, what not to post, maintaining brand voice consistency, and managing AI-assisted content creation and scheduling across multiple platforms with an internal approval workflow.
+
+| 7\. SERVICE OVERVIEW — ENTERPRISE |
+| :---- |
+
+Enterprise Social Branding gives companies a governed, AI-assisted platform to manage their professional brand presence. It is distinct from the individual service in three fundamental ways: it serves an organisation rather than a person, it includes multi-user approval workflows (not just single-user approval), and it includes brand governance rules that define what content is and is not acceptable before the AI generates anything.
+
+| Dimension | Individual Social Branding | Enterprise Social Branding |
+| :---- | :---- | :---- |
+| Subject | A person’s professional brand | A company’s brand presence |
+| Platforms | Personalised per archetype and persona | Standardised across all company-connected platforms |
+| Content strategy | Persona-driven, career-goal aligned | Brand voice and values-driven, audience-targeted |
+| Approval workflow | Single user approves | Multi-role workflow: Creator → Editor → Approver |
+| Brand governance | Tone rules per persona | Explicit content policy: what to post, what not to post |
+| Analytics focus | Individual brand growth, recruiter visibility | Company reach, audience growth, brand sentiment |
+| Q-Score integration | Feeds RQx for individual | Not Q-Score integrated — separate enterprise analytics |
+
+## **7.1 Enterprise Account Structure**
+
+* An enterprise account is associated with a company entity (not an individual user)
+
+* Multiple team members can be added to the enterprise account with defined roles
+
+* Three roles: Content Creator (drafts content), Content Editor (reviews and edits), Brand Approver (final approval before posting)
+
+* At least one Brand Approver must be assigned before any content can go live
+
+* Enterprise account connects company social profiles (LinkedIn Company Page, Instagram Business, Twitter/X Business, YouTube Channel)
+
+| 8\. BRAND GOVERNANCE FRAMEWORK — ENTERPRISE |
+| :---- |
+
+Brand governance is the defining capability of the Enterprise service. Before the AI generates any content, it operates within a set of brand rules defined by the company. These rules determine what gets created, what gets filtered, and what gets flagged for human review.
+
+## **8.1 Brand Voice Definition**
+
+The enterprise sets its brand voice at account setup. Brand voice is defined across five dimensions:
+
+| Dimension | Options | Example |
+| :---- | :---- | :---- |
+| Tone | Professional / Conversational / Authoritative / Inspirational / Technical | A fintech company selects: Professional \+ Authoritative |
+| Formality | Formal / Semi-formal / Casual | Most enterprises: Semi-formal |
+| Perspective | First person (we) / Third person (company name) | Most LinkedIn company posts: First person (we) |
+| Language style | Simple and direct / Rich and descriptive / Data-led / Story-led | Tech companies often: Simple and direct \+ Data-led |
+| Audience | Talent/Recruitment / Clients/Customers / Industry peers / Investors / General public | Can select multiple; content adapted per audience tag |
+
+## **8.2 Content Policy — What to Post**
+
+* Company milestones: product launches, funding announcements, partnerships, awards
+
+* Thought leadership: industry trends, company perspective on market developments, research and data
+
+* Culture and values: team stories, behind-the-scenes, company events, diversity and inclusion content
+
+* Product and service highlights: feature announcements, case studies, client success stories (with consent)
+
+* Recruitment content: open roles, employer brand, employee testimonials, workplace benefits
+
+* Educational content: how-to guides, industry education, tips relevant to the company’s domain
+
+* Engagement content: polls, questions, community challenges aligned to brand values
+
+## **8.3 Content Policy — What Not to Post (Governance Rules)**
+
+The following rule categories are configurable by the enterprise at account setup. The AI applies these rules as filters before generating any content. Content that violates a rule is not queued — it is discarded or flagged for human review.
+
+| Rule Category | Default Setting | Configurable? |
+| :---- | :---- | :---- |
+| Political statements or partisan content | Blocked — never generated | Yes — enterprise can unlock with justification |
+| Commentary on competitors by name | Blocked — never generated | Yes — enterprise can unlock for specific approved comparisons |
+| Unverified claims or statistics | Flagged for human review before queuing | No — always flagged |
+| Sensitive social topics (religion, race, gender commentary) | Flagged for human review | Yes — enterprise can block entirely |
+| Legal or compliance-sensitive content (regulatory, financial) | Flagged for legal review tag | No — always flagged |
+| Crisis or incident response content | Blocked from AI generation — must be human-authored | No — always blocked from AI |
+| Content featuring named individuals (external) | Requires explicit approval flag | No — always requires approval |
+| Off-brand tone (outside defined voice dimensions) | Regenerated automatically before queuing | No — always enforced |
+
+| 9\. ENTERPRISE CONTENT ENGINE |
+| :---- |
+
+## **9.1 Content Generation Flow**
+
+| Step | Action | Role Responsible | System Behaviour |
+| :---- | :---- | :---- | :---- |
+| 1 | Content brief input | Content Creator or AI-initiated | Creator provides topic/theme OR system auto-generates brief from content calendar schedule |
+| 2 | Brand governance check | System (automated) | Brief checked against content policy rules. Blocked topics discarded. Flagged topics tagged for review. |
+| 3 | AI content generation | System (automated) | AI generates post draft applying: brand voice rules, platform format requirements, 80/20 content model, audience targeting |
+| 4 | Creator review | Content Creator | Creator reviews draft, makes edits, adds platform-specific adjustments |
+| 5 | Editor review | Content Editor | Editor reviews for brand alignment, tone consistency, factual accuracy |
+| 6 | Brand approval | Brand Approver | Final approval. Can approve, request changes, or reject. Only Brand Approver can push to scheduled. |
+| 7 | Schedule and post | System (automated) | Approved content scheduled per platform optimal posting time. Posted automatically at scheduled time. |
+| 8 | Performance tracking | System (automated) | Impressions, engagement, follower data collected. Brand analytics dashboard updated. |
+
+## **9.2 Enterprise 80/20 Content Model**
+
+The same 80/20 content model applies to enterprise, with enterprise-specific content types:
+
+| Content Type | Category | Description |
+| :---- | :---- | :---- |
+| Company milestone post | 80% Toolkit | Template: announcement \+ context \+ what it means for customers/team \+ CTA. Fills with company-specific data. |
+| Thought leadership post | 80% Toolkit | Template: industry observation \+ company perspective \+ supporting data point \+ question to audience. |
+| Culture post | 80% Toolkit | Template: team story or value highlight \+ what it demonstrates about the company \+ employee quote (with consent). |
+| Job opening post | 80% Toolkit | Template: role title \+ why this role matters \+ what kind of person thrives here \+ apply link. |
+| Educational post | 80% Toolkit | Template: common misconception or question in domain \+ company perspective \+ practical takeaway. |
+| Trending topic response | 20% Dynamic | AI monitors industry news. Generates company perspective post when relevant trend detected. Always flagged for Brand Approver review. |
+| Milestone reaction | 20% Dynamic | AI auto-generates draft when company milestone event detected (e.g. funding announcement, award won). Requires full approval workflow. |
+| Engagement response | 20% Dynamic | AI drafts responses to comments on company posts. Creator reviews before sending. |
+
+| 10\. ACCEPTANCE CRITERIA |
+| :---- |
+
+**Part 1 — Individual Social Branding**
+
+| \# | Acceptance Criterion | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | OAuth connection completes for all four platforms (LinkedIn, Instagram, Twitter/X, YouTube). Profile data collected on first sync. Sync schedule runs per defined frequency. | \[ \] PASS \[ \] FAIL |
+| **2** | Brand Score calculated correctly from all 7 components. Brand Score feeds RQx via defined formula. RQx update event emitted to Assessment and Pathways services on Brand Score change of 5+ points. | \[ \] PASS \[ \] FAIL |
+| **3** | Profile analysis runs for all four platforms. Section-by-section audit scores generated. Benchmark against target role applied. Profile recommendations generated with current and recommended text. | \[ \] PASS \[ \] FAIL |
+| **4** | Profile recommendations can be approved and applied to the live platform profile. Rejected recommendations discarded. Applied recommendations update the social\_profile\_recommendations table correctly. | \[ \] PASS \[ \] FAIL |
+| **5** | Content calendar generated for correct persona with correct platform mix. 80/20 split enforced over any 2-week rolling window. All 6 content calendar rules applied correctly. | \[ \] PASS \[ \] FAIL |
+| **6** | Pre-baked toolkit content fills correctly with user-specific data (achievements, Q-Score stats, pathway milestones). All 8 toolkit content types functional. | \[ \] PASS \[ \] FAIL |
+| **7** | Dynamic content triggers fire correctly: Q-Score improvement event, pathway milestone event, trending topic detection, profile update trigger. | \[ \] PASS \[ \] FAIL |
+| **8** | Approval queue functions correctly: user can approve (with optional edits), reject, or request regeneration for each content item. No content posted without approved status. | \[ \] PASS \[ \] FAIL |
+| **9** | Auto-approve mode available as opt-in only. When enabled, content posts without individual approval. Can be disabled at any time. | \[ \] PASS \[ \] FAIL |
+| **10** | Approved content posted to correct platform at scheduled time. Platform-specific formatting applied (LinkedIn: no external link in body. Instagram: hashtags appended. YouTube: description and tags generated.) | \[ \] PASS \[ \] FAIL |
+| **11** | Engagement queue populated with AI-drafted responses to comments and connection requests. User approval required before sending. | \[ \] PASS \[ \] FAIL |
+| **12** | Analytics collected per platform per sync cycle. Performance data stored in social\_content\_performance table. Analytics dashboard displays all tracked metrics with trend lines. | \[ \] PASS \[ \] FAIL |
+| **13** | Persona switching updates platform activation recommendations, content calendar strategy, and posting frequency rules immediately. | \[ \] PASS \[ \] FAIL |
+| **14** | Archetype-conditional platform activation: Instagram not recommended by default for Technical Specialist or Strategic Leader personas. System surfaces recommendation prompt for relevant personas only. | \[ \] PASS \[ \] FAIL |
+
+**Part 2 — Enterprise Social Branding**
+
+| \# | Acceptance Criterion | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Enterprise account creation completes with brand voice and content policy configuration. Multi-role team setup (Creator, Editor, Approver) functional. Minimum one Approver enforced before content can go live. | \[ \] PASS \[ \] FAIL |
+| **2** | Brand governance rules applied before AI content generation. Blocked topics discarded without queuing. Flagged topics tagged and routed to enterprise\_content\_flags table for human review. | \[ \] PASS \[ \] FAIL |
+| **3** | All 8 governance rule categories enforced: political content blocked, competitor mentions blocked, unverified claims flagged, sensitive topics flagged, legal content flagged, crisis content blocked from AI, named individuals require approval, off-brand tone regenerated. | \[ \] PASS \[ \] FAIL |
+| **4** | Brand voice rules (tone, formality, perspective, language style, audience) applied to all AI-generated content. Off-brand drafts regenerated automatically before entering approval queue. | \[ \] PASS \[ \] FAIL |
+| **5** | Three-stage approval workflow enforced: Creator → Editor → Brand Approver. Content cannot skip stages. Only Brand Approver role can push content to scheduled status. | \[ \] PASS \[ \] FAIL |
+| **6** | All 8 enterprise content types (5 toolkit \+ 3 dynamic) generated correctly. Trending topic and milestone dynamic content always routed to Brand Approver regardless of workflow stage. | \[ \] PASS \[ \] FAIL |
+| **7** | Flagged content resolution workflow completes: flag raised → human reviews → approved/rejected/edited → flag closed. Content entry status updates correctly on resolution. | \[ \] PASS \[ \] FAIL |
+| **8** | Enterprise analytics collected per platform. Brand analytics dashboard displays follower growth, impressions, engagement rate, and top-performing posts per platform. | \[ \] PASS \[ \] FAIL |
+| **9** | Enterprise content calendar visible across all team member roles with correct status labels per approval stage. Each role sees only the actions available to their role. | \[ \] PASS \[ \] FAIL |
+
diff --git a/social_branding/CHANGELOGS.md b/social_branding/CHANGELOGS.md
new file mode 100644
index 0000000..ce43c36
--- /dev/null
+++ b/social_branding/CHANGELOGS.md
@@ -0,0 +1,275 @@
+# Changelogs (main ➜ feature-update)
+
+Date: 26 Mar 2026
+Scope: Diff between `origin/main` and `feature-update`
+
+## Summary
+
+`feature-update` is a large feature + architecture update.
+
+- **Scale of change:** 85 files changed, **+11,633 / -3,266** lines.
+- **Primary outcomes:**
+ - Adds **QScore integration** and user-level caching.
+ - Adds a **Brand Score engine** (with audit output, quick wins, and optional eventing).
+ - Introduces a more explicit architecture: **Adapters → Use-cases → Repositories → Engine**.
+ - Improves worker/job processing with **job dispatching + idempotency**.
+ - Adds **demo/dev ergonomics**: no-auth mode, demo token, and `/demo` UI.
+ - Adds significant **test coverage** and **documentation**.
+
+---
+
+## What’s new (features added)
+
+### 1) QScore integration
+
+**Goal:** Fetch/compute QScore and persist a read-optimized snapshot for downstream UX and scoring.
+
+**Key additions:**
+- API module: `app/api/v1/qscore.py`
+- Client: `app/clients/qscore_client.py`
+- Service: `app/services/qscore_service.py`
+- Schema types: `app/schemas/qscore.py`
+- DB cache column via migration:
+ - `alembic/versions/20260325_000001_add_qscore_summary_to_social_users.py`
+- Model update:
+ - `app/models/user.py` adds `qscore_summary` (JSONB)
+
+**Net effect:** The service can expose QScore data and keep the latest snapshot in the user row for fast reads.
+
+---
+
+### 2) Brand Score engine (+ summaries)
+
+**Goal:** Compute and explain a “Brand Score” with actionable guidance.
+
+**Key additions:**
+- Engine modules:
+ - `app/engine/brand_score_engine.py`
+ - `app/engine/audit_engine.py`
+ - `app/engine/persona_engine.py`
+ - `app/engine/draft_engine.py`
+ - `app/engine/calendar_engine.py`
+ - `app/engine/contracts.py`
+ - `app/engine/scoring_rules.py`
+- Eventing:
+ - `app/services/brand_score_eventing.py`
+- DB cache column via migration:
+ - `alembic/versions/20260325_000002_add_brand_score_summary_to_social_users.py`
+- Model update:
+ - `app/models/user.py` adds `brand_score_summary` (JSONB)
+
+**Behavioral highlights:**
+- Brand score output includes structured “**strengths**” and top “**quick wins**” derived from audit explanations.
+
+---
+
+### 3) Job dispatcher + worker pipeline improvements
+
+**Goal:** Make background job handling explicit, testable, and safer on retries.
+
+**Key additions:**
+- Job framework:
+ - `app/jobs/dispatcher.py` (routes `job_type` → handler)
+ - `app/jobs/definitions.py`
+ - `app/jobs/__init__.py`
+
+**Notable behaviors:**
+- Optional **idempotency key** support (Redis `SETEX`, 24h TTL) to avoid double-processing when messages are re-delivered.
+
+---
+
+### 4) Demo/dev UX improvements
+
+**Goal:** Run and validate the service without external auth dependencies in dev/demo scenarios.
+
+**Key additions:**
+- `app/auth/dependencies.py`
+ - `no_auth_mode` (always treat caller as `demo_user_id`)
+ - `demo_auth_enabled` + token value `demo` shortcut
+- `app/main.py`
+ - `GET /demo` serves `app/static/demo.html` (fallback redirects to `/docs`)
+- `app/static/demo.html` (mini UI)
+
+---
+
+## What changed (behavioral refactors)
+
+### APIs: “fat routes” ➜ use-case driven routes
+
+Many endpoints were refactored to:
+- Stop doing SQLAlchemy querying/ownership checks directly inside routers.
+- Delegate to use-cases via `provide_use_case(...)`.
+
+**Examples of refactored routers:**
+- `app/api/v1/profiles.py`
+- `app/api/v1/content.py`
+- `app/api/v1/internal.py`
+- Dashboard state endpoint in `app/main.py` now delegates to `app/use_cases/get_dashboard.py`
+
+**Net effect:** Controllers become thinner and easier to reason about; business and persistence logic becomes reusable and testable.
+
+---
+
+### Scoring logic: service module ➜ pure engine module
+
+- Previous: `app/services/scoring_service.py` contained large amounts of pure scoring logic.
+- Now: `app/services/scoring_service.py` is a **compatibility wrapper** that re-exports scoring functions/constants from `app/engine/scoring_rules.py`.
+
+**Why:** Centralizes domain logic in the Engine layer and keeps import stability for older code.
+
+---
+
+## What was removed (or relocated)
+
+### 1) `app/services/branding_intelligence.py` removed
+
+- Deleted: `app/services/branding_intelligence.py`
+- Replaced by layered structure:
+ - Added: `app/adapters/branding_intelligence.py`
+
+This is part of a broader “**services → adapters**” refactor.
+
+### 2) Service modules moved under adapters
+
+Renames (logical move; functionality preserved):
+- `app/services/ai_service.py` → `app/adapters/ai_service.py`
+- `app/services/brightdata_service.py` → `app/adapters/brightdata_service.py`
+- `app/services/scrapetable_service.py` → `app/adapters/scrapetable_service.py`
+
+---
+
+## Architecture: before vs after
+
+### Previous architecture (main)
+
+**Common traits observed in the diff:**
+- Routers frequently performed:
+ - DB access (`select`, `update`, joins)
+ - Ownership/security checks
+ - Data merging/enrichment logic
+ - Commit/flush patterns
+- Most domain logic lived in *service* modules, often mixing:
+ - domain rules
+ - provider orchestration
+ - persistence decisions
+
+**Typical pain points:**
+- Harder to test logic without DB + IO.
+- Harder to reuse workflows between:
+ - HTTP routes
+ - background jobs
+ - agent/worker flows
+- High coupling between external providers and business logic.
+
+---
+
+### Current architecture (feature-update)
+
+The code is reorganized around clearer boundaries:
+
+1) **Adapters** (`app/adapters/`)
+ - External IO: AI providers, BrightData, Scrapetable, branding intelligence provider glue.
+
+2) **Use-cases** (`app/use_cases/`)
+ - Application workflows (orchestration):
+ - validate inputs
+ - call repos, engines, adapters
+ - decide persistence / commit points
+
+3) **Repositories** (`app/repositories/`)
+ - Database access patterns:
+ - fetch by clerk id
+ - fetch profile for user
+ - save scores/drafts
+
+4) **Engine** (`app/engine/`)
+ - Pure or mostly-pure domain logic:
+ - scoring rules
+ - auditing
+ - persona generation
+ - calendar/draft logic
+
+5) **API controllers** (`app/api/...`)
+ - Translate HTTP requests to use-case calls.
+ - Convert errors to HTTP codes.
+
+---
+
+## Why the new architecture is better
+
+### 1) Testability
+- Engine logic can be unit-tested without network or DB.
+- Use-cases can be tested with mocked adapters and in-memory db sessions.
+
+### 2) Separation of concerns (less coupling)
+- External providers are isolated in adapters.
+- Domain logic is isolated in engine modules.
+- DB access is consolidated and reusable in repositories.
+
+### 3) Reuse across execution contexts
+The same use-cases can be invoked from:
+- REST APIs
+- workers/jobs
+- agent flows
+
+This reduces duplication and “slightly-different” implementations.
+
+### 4) Safer background jobs
+- Dispatcher introduces structured routing and idempotency support.
+- Makes retries less risky and easier to reason about.
+
+### 5) Better dev ergonomics
+- No-auth mode and a demo UI make local validation faster.
+- Less dependency on Clerk for basic smoke tests.
+
+---
+
+## Developer-facing changes to be aware of
+
+### Authentication behavior
+- `app/auth/dependencies.py` now supports:
+ - **global no-auth mode** (treat all calls as `demo_user_id`)
+ - **demo token** shortcut (token == `demo`)
+
+### DB migrations now required
+- Brand/QScore summaries require running Alembic migrations before using those features.
+
+### Import path changes
+- External integrations moved under `app/adapters/*`.
+- Scoring logic moved to `app/engine/scoring_rules.py` (service remains as a compatibility re-export).
+
+---
+
+## Tests added/updated
+
+**New tests:**
+- `tests/test_engine.py`
+- `tests/test_hardening.py`
+- `tests/test_qscore_integration.py`
+- `tests/test_rqx_formula.py`
+- `tests/test_worker_convergence.py`
+
+**Updated tests:**
+- `tests/test_branding_intelligence.py`
+
+---
+
+## Documentation added
+
+A significant set of planning/architecture docs was added, including:
+- `docs/PRD.md`
+- `docs/qscore-integration.md`
+- `docs/eventing-contract.md`
+- plus multiple architecture/plan/audit checklists under `docs/`
+
+---
+
+## Quick file index (most important additions)
+
+- Engine: `app/engine/*`
+- Use-cases: `app/use_cases/*`
+- Repositories: `app/repositories/*`
+- QScore: `app/api/v1/qscore.py`, `app/services/qscore_service.py`, `app/clients/qscore_client.py`, `app/schemas/qscore.py`
+- DB migrations: `alembic/versions/20260325_000001_*`, `alembic/versions/20260325_000002_*`
+- Demo: `app/static/demo.html`, `GET /demo` in `app/main.py`
+- Jobs: `app/jobs/dispatcher.py`
diff --git a/social_branding/PRD.md b/social_branding/PRD.md
new file mode 100644
index 0000000..1dd4d37
--- /dev/null
+++ b/social_branding/PRD.md
@@ -0,0 +1,396 @@
+**GrowQR**
+
+**SOCIAL BRANDING**
+
+**DEVELOPER BRD — TECHNICAL SPECIFICATION**
+
+Individual Social Branding • Enterprise Social Branding • 4 Platforms • 6 Personas • v1.0 • March 2026
+
+| Social Branding Microservices This document contains specifications, business logic, and acceptance criteria for development. |
+| :---: |
+
+| Document Title | Social Branding Service — Developer BRD Technical Specification |
+| :---- | :---- |
+
+| Version | 1.0 — March 2026 |
+| :---- | :---- |
+
+| Service Type | Standalone Microservice — Part of Opportunity Module |
+| :---- | :---- |
+
+| Target Platforms | LinkedIn | Instagram | Twitter/X | YouTube |
+| :---- | :---- |
+
+| Target Launch | April 1st — LinkedIn, Instagram, YouTube, Twitter/X , Git |
+| :---- | :---- |
+
+| Part 1 | Individual Social Branding — 6 end-goal personas, full automation with approval |
+| :---- | :---- |
+
+| Part 2 | Enterprise Social Branding — Company brand presence, governance, multi-platform management |
+| :---- | :---- |
+
+| Q-Score Integration | Brand Score (0–100) feeds RQx. Q-Score changes trigger automatic profile and content updates. |
+| :---- | :---- |
+
+| Data Collection | Method TBD by technical team — BRD specifies data requirements only |
+| :---- | :---- |
+
+| PART 1 — INDIVIDUAL SOCIAL BRANDING |
+| :---: |
+
+Part 1 covers the Social Branding service for individual GrowQR users. It is a fully automated, AI-managed presence builder across LinkedIn, Instagram, Twitter/X, and YouTube — with user approval at every execution step.
+
+| 1\. SERVICE OVERVIEW — INDIVIDUAL |
+| :---- |
+
+The Individual Social Branding service transforms a user’s professional presence from a passive profile into an active, consistent, and strategically managed brand. The service operates on a Scrape → Analyse → Generate → Approve → Post → Track loop, fully managed by GrowQR’s AI layer.
+
+The service is built on five structural pillars drawn from proven social branding principles:
+
+| Pillar | Definition | How GrowQR Implements It |
+| :---- | :---- | :---- |
+| Consistency | Uniform brand voice, visual style, and messaging across all platforms | AI enforces tone, vocabulary, and visual style rules per persona across all connected platforms |
+| Target Audience | Understanding the social habits of the user’s ideal audience (recruiters, clients, peers, investors) | Audience profile built from user’s pathway archetype, target role, and Q-Score profile |
+| Content Strategy | A defined mix of educational, entertaining, and inspirational content mapped to brand values | 80/20 content model: 80% pre-baked persona toolkit, 20% dynamic AI-generated content |
+| Engagement | Active interaction with followers: likes, comments, DMs, connection requests | AI drafts engagement responses; user approves or auto-approves based on engagement rules |
+| Platform Selection | Right platforms for the user’s archetype and target audience | Archetype-conditional platform activation — not all platforms recommended to all users |
+
+## **1.1 The Automation Loop**
+
+| Stage | Action | Human Touch Point |
+| :---- | :---- | :---- |
+| 1\. Connect | User connects social accounts via OAuth | One-time setup per platform |
+| 2\. Scrape / Collect | System collects profile data, post history, engagement metrics, follower data | None — automated |
+| 3\. Analyse | AI analyses profile completeness, content performance, audience alignment, Brand Score calculated | User reviews Brand Score dashboard |
+| 4\. Generate | AI generates: profile rewrites, content calendar, post drafts, engagement responses | User reviews all generated content |
+| 5\. Approve | User approves, edits, or rejects each item in the approval queue | Primary user interaction point |
+| 6\. Post / Execute | Approved content scheduled and posted. Profile updates applied. Engagement responses sent. | None — automated post-approval |
+| 7\. Track | System monitors: impressions, profile views, follower growth, engagement rate, recruiter search appearances | User reviews weekly analytics dashboard |
+| 8\. Feed Back | Performance data feeds Brand Score and RQx Q-Score. Pathway engine updates recommendations. | None — automated |
+
+| 2\. BRAND SCORE — THE SOCIAL Q-SCORE |
+| :---- |
+
+Brand Score is a single 0–100 metric that measures the strength, consistency, and discoverability of a user’s professional presence across all connected platforms. It is GrowQR’s proprietary social presence measurement and feeds directly into RQx (Reputation Quotient) in the Q-Score engine.
+
+| Brand Score is not a vanity metric. It is calculated from objective, measurable signals. As the user takes actions recommended by the Social Branding service, their Brand Score improves. Brand Score improvement directly improves their RQx Q-Score, which in turn updates their pathway recommendations. |
+| :---- |
+
+## **2.1 Brand Score Components**
+
+| Component | Weight | What It Measures |
+| :---- | :---- | :---- |
+| Profile Completeness | 20% | All profile sections populated, keyword-optimised, and aligned to target role across active platforms |
+| Content Consistency | 20% | Posting frequency maintained, tone consistent, visual style uniform across platforms |
+| Audience Growth | 15% | Follower/connection growth rate over 30-day rolling window |
+| Engagement Rate | 15% | Likes, comments, shares, and saves as a percentage of reach per post |
+| Recruiter Visibility | 15% | Profile appearance rate in relevant recruiter and talent searches (LinkedIn primary) |
+| Content Quality | 10% | AI-assessed relevance, originality, and alignment to persona content framework |
+| Cross-Platform Consistency | 5% | Messaging and voice alignment across all connected platforms |
+
+## **2.2 Brand Score → RQx Integration**
+
+* Brand Score calculated after every platform data sync (example: frequency: daily for LinkedIn, 48hrs for others)
+
+* Brand Score mapped to RQx using a defined conversion formula: RQx contribution \= Brand Score × 0.4 (40% weighting of RQx from Brand Score)
+
+* RQx update event emitted to Assessment Service and Pathways Service on every Brand Score change of 5+ points
+
+* Pathways engine re-evaluates Social Branding touchpoint recommendations on RQx update
+
+* User’s Brand Score history stored and displayed as a trend line on the Social Branding dashboard
+
+| 3\. SIX END-GOAL PERSONAS — CONTENT FRAMEWORK |
+| :---- |
+
+Every user’s Social Branding strategy is driven by their end-goal persona. The persona is derived from the user’s active pathway archetype, target role, and career goal input. Users can switch personas as their goals evolve. Each persona has a defined platform mix, content angle, and posting frequency.
+
+| Platform activation is archetype-conditional. Not all platforms are recommended to all users. The system activates platforms relevant to the user’s persona and prompts the user to connect them. Users can override and connect any platform manually. |
+| :---- |
+
+| PERSONA 1: JOB SEEKER Archetype: All archetypes — active job search phase |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (secondary for tech/creative roles) **Content Angle** Recruiter visibility, skills signalling, open-to-work positioning, achievement highlights **Posting Frequency** LinkedIn: 4x per week. Twitter/X: 3x per week if active. |
+
+| PERSONA 2: CAREER TRANSITIONER Archetype: All archetypes — changing domain or role type |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Instagram (if transitioning to creative/coaching/consulting) **Content Angle** Narrative reframing: connecting past experience to new direction, learning journey documentation **Posting Frequency** LinkedIn: 3x per week. Instagram: 2x per week if active. |
+
+| PERSONA 3: THOUGHT LEADER Archetype: Strategic Leader, Entrepreneurial Builder, Domain Expert |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (primary), YouTube (secondary) **Content Angle** Industry insights, opinion pieces, trend analysis, frameworks and models, contrarian takes **Posting Frequency** LinkedIn: 5x per week. Twitter/X: daily. YouTube: 1x per month minimum. |
+
+| PERSONA 4: DOMAIN EXPERT Archetype: Technical Specialist, Creative Innovator |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), GitHub (external link), YouTube (tutorials/walkthroughs) **Content Angle** Deep technical content, how-to posts, case studies, project showcases, certification highlights **Posting Frequency** LinkedIn: 3x per week. YouTube: 2x per month. |
+
+| PERSONA 5: ENTREPRENEUR / FOUNDER Archetype: Entrepreneurial Builder |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (primary), Instagram (brand building), YouTube (storytelling) **Content Angle** Build-in-public content, startup journey, lessons learned, team culture, product milestones **Posting Frequency** LinkedIn: 5x per week. Twitter/X: daily. Instagram: 3x per week. YouTube: 2x per month. |
+
+| PERSONA 6: EXECUTIVE / ENTERPRISE LEADER Archetype: Strategic Leader — VP, Director, C-suite level |
+| :---- |
+| **Recommended Platforms** LinkedIn (primary), Twitter/X (secondary) **Content Angle** Executive presence: strategic vision, culture and values, industry leadership, org transformation, speaking engagements **Posting Frequency** LinkedIn: 3x per week. Twitter/X: 2x per week. |
+
+| 4\. THE 80/20 CONTENT MODEL |
+| :---- |
+
+All content generated by GrowQR’s Social Branding service follows an 80/20 split: 80% pre-baked toolkit content and 20% dynamic AI-generated content. This balance ensures consistency and quality (80%) while maintaining relevance and freshness (20%).
+
+## **4.1 80% — Pre-Baked Toolkit**
+
+The pre-baked toolkit is a library of proven content frameworks, post templates, hooks, and evergreen structures mapped to each persona and platform. This content is designed, tested, and maintained by GrowQR. It does not require AI generation — it is filled with user-specific data at execution time.
+
+| Content Type | Description | Persona Applicability |
+| :---- | :---- | :---- |
+| Achievement Post | Structured template: milestone \+ what it took \+ what you learned. Fills with user’s real achievements from pathway completions. | All personas |
+| Skills Signal Post | Highlights a specific skill or certification. Links to Q-Score improvement data. | Job Seeker, Domain Expert, Career Transitioner |
+| Insight Share | Short opinion or observation on an industry trend. Structure: Hook \+ Insight \+ Question to audience. | Thought Leader, Executive, Entrepreneur |
+| Career Story Post | Narrative format: where I was \+ what changed \+ where I am now. Used for transitions and milestones. | Career Transitioner, Entrepreneur |
+| Project Showcase | Work sample or project result with context. Visual-first for Instagram; text+image for LinkedIn. | Domain Expert, Creative Innovator, Entrepreneur |
+| Engagement Prompt | Question or poll to drive comments. Mapped to user’s domain for relevant audience response. | All personas |
+| Weekly Reflection | End-of-week summary: what I worked on, what I learned, what’s next. | Thought Leader, Entrepreneur, Executive |
+| Company/Role Spotlight | Highlights a company or role the user is targeting or has experience with. Builds recruiter relevance. | Job Seeker, Career Transitioner |
+
+## **4.2 20% — Dynamic Content**
+
+Dynamic content is AI-generated in real-time based on signals from the user’s platform activity, Q-Score progress, pathway milestones, and trending topics in their domain. This content is fresh, timely, and personalised — it cannot be pre-baked.
+
+* Q-Score improvement post: auto-generated when user improves a Q-Score by 10+ points. Frames the improvement as a professional growth story.
+
+* Pathway milestone post: auto-generated when user completes a course, earns a certificate, or achieves a pathway milestone.
+
+* Trending topic response: AI monitors trending topics in the user’s domain. Generates a short opinion post when a relevant trend is detected.
+
+* Interview or job application event: auto-generated encouragement and visibility post when user applies for a role or secures an interview (with user consent).
+
+* Engagement response drafts: AI drafts replies to comments on the user’s posts, maintaining persona tone and voice.
+
+* Profile update trigger: when user’s Q-Scores or pathway status changes significantly, AI generates updated headline, about section, and skills list for user approval.
+
+## **4.3 Content Calendar Generation Rules**
+
+| Rule | Description |
+| :---- | :---- |
+| Rule 1: Frequency Enforcement | System enforces minimum posting frequency per persona. If user has not approved content for upcoming slots, system sends reminder 48hrs in advance. |
+| Rule 2: Platform Sequencing | Content is not duplicated across platforms. Each platform receives a uniquely formatted version adapted to that platform’s style and audience. |
+| Rule 3: Content Mix Enforcement | System ensures the 80/20 split is maintained over any 2-week rolling window. Prevents over-reliance on either toolkit or dynamic content. |
+| Rule 4: No Auto-Post Without Approval | No content is ever posted without explicit user approval. Auto-approve mode is available as an opt-in setting only. |
+| Rule 5: Tone Lock | Once user’s brand voice is established (after first 2 weeks), tone settings are locked unless user explicitly resets them. |
+| Rule 6: Sensitive Topic Filter | AI applies a topic filter before generating content. Posts that touch on politically sensitive, legally risky, or reputationally harmful territory are flagged and not queued for approval. |
+
+| 5\. PLATFORM SPECIFICATIONS — INDIVIDUAL |
+| :---- |
+
+## **5.1 LinkedIn**
+
+| Capability | Specification |
+| :---- | :---- |
+| Profile Analysis | Audit: Headline, About, Experience, Skills, Recommendations, Featured section, Activity. Score each section 0–100. Benchmark against target role requirements and top 10% of professionals in same role. |
+| Profile Rewrite | AI generates optimised versions of: Headline (3 variants), About section, Experience bullet points (per role), Skills list (mapped to Q-Scores and target JD keywords). User selects and approves. |
+| Recruiter Visibility | Keyword gap analysis: identifies terms recruiters search for this role that are missing from profile. Injects keywords into profile sections naturally. |
+| Content Posting | Supports: text posts, image posts, document carousels, polls, article links. Content formatted to LinkedIn algorithm best practices (hook in first 2 lines, no external links in body). |
+| Connection Strategy | Identifies target connections based on user’s pathway: target companies, role peers, hiring managers in target domain. AI drafts personalised connection request notes. |
+| Engagement Automation | AI drafts comments on posts from target connections and industry leaders. User approves before sending. Builds visibility with relevant audience. |
+| Analytics Tracked | Profile views (7-day, 30-day), Search appearances, Post impressions, Engagement rate per post, Connection acceptance rate, Follower growth |
+
+## **5.2 Instagram**
+
+| Instagram is activated for: Career Transitioner (creative/coaching roles), Entrepreneur/Founder, Domain Expert (creative/design roles). Not recommended by default for Technical Specialist or Strategic Leader personas unless user opts in. |
+| :---- |
+
+| Capability | Specification |
+| :---- | :---- |
+| Profile Analysis | Bio, profile photo, link-in-bio, highlight covers, grid aesthetic consistency, story frequency. Score for professional brand alignment. |
+| Content Types | Feed posts (static image, carousel), Reels (short-form video), Stories (ephemeral). Each type has distinct content templates in the pre-baked toolkit. |
+| Visual Style Consistency | AI enforces visual brand rules: colour palette (derived from user’s LinkedIn brand colours), font style, filter consistency. Applied to all generated visual templates. |
+| Caption Framework | Each caption follows: Hook (first line visible before ‘more’) \+ Value (body) \+ CTA (final line) \+ Hashtags (max 5, domain-specific). Hashtag bank maintained per persona. |
+| Story Strategy | Stories used for: behind-the-scenes content, quick tips, polls, Q\&As. Frequency: 3–5 stories per week. Story templates provided per persona. |
+| Analytics Tracked | Reach, Impressions, Profile visits, Follower growth, Story views, Reel plays, Link-in-bio clicks, Saves per post |
+
+## **5.3 Twitter / X**
+
+| Twitter/X is targeted for Phase 2 launch. Architecture and data model specified here for development readiness. April 1st launch excludes Twitter/X. |
+| :---- |
+
+| Capability | Specification |
+| :---- | :---- |
+| Profile Analysis | Bio (160 chars), header image, pinned tweet, posting frequency, engagement rate, follower-to-following ratio. |
+| Content Types | Short posts (under 280 chars), Threads (multi-tweet narrative), Quote posts (with commentary), Replies (engagement strategy). |
+| Thread Framework | Threads used for: insight breakdowns, how-to guides, career lessons, domain deep-dives. Format: Hook tweet \+ 5–10 body tweets \+ CTA final tweet. |
+| Posting Strategy | Optimal posting times calculated per user’s audience timezone. Threads on weekdays, shorter posts and replies on weekends. |
+| Analytics Tracked | Impressions, Engagements, Profile clicks, Link clicks, Follower growth, Thread completion rate |
+
+## **5.4 YouTube**
+
+| Capability | Specification |
+| :---- | :---- |
+| Channel Analysis | Channel art, About section, playlist structure, video titles and descriptions (SEO), thumbnail consistency, upload frequency, subscriber growth rate. |
+| Content Types | Long-form (10–20 min): deep dives, case studies, tutorials. Short-form (YouTube Shorts, under 60 sec): tips, quick insights, career advice clips. |
+| Video Brief Generation | AI generates video briefs: title (3 variants), hook script (first 30 seconds), chapter outline, description with keywords, tags, thumbnail concept. User records; AI does not generate video. |
+| SEO Optimisation | Title keyword analysis, description keyword injection, tag strategy, chapter timestamps. Benchmarked against top-performing videos in user’s domain. |
+| Thumbnail Strategy | AI generates thumbnail design brief: text overlay, colour scheme, facial expression guidance (if talking head). Thumbnail template provided per persona. |
+| Upload Frequency | Persona-based targets: Thought Leader (1x/month minimum), Domain Expert (2x/month), Entrepreneur (2x/month). System prompts user when cadence is falling behind. |
+| Analytics Tracked | Views, Watch time, Subscriber growth, Click-through rate (thumbnails), Average view duration, Top traffic sources |
+
+| 6\. DATA REQUIREMENTS — INDIVIDUAL |
+| :---- |
+
+| Data collection method (API vs scraping vs user-authenticated export) is TBD and left to the technical team. This section specifies what data is required. The technical team must define the collection mechanism, document any legal or rate-limit constraints, and confirm data availability before development of the collection layer. |
+| :---- |
+
+| Platform | Data Required | Frequency |
+| :---- | :---- | :---- |
+| LinkedIn | Profile sections (headline, about, experience, education, skills, certifications, featured, recommendations). Post history (last 90 days). Engagement per post (likes, comments, shares). Profile view count. Search appearance count. Connection count. Follower count. | Daily sync |
+| Instagram | Bio, profile photo URL, follower count, following count, post count. Feed posts (last 60 days): caption, image URL, likes, comments, saves, reach, impressions. Story views (last 30 days). Reel plays. | 48-hour sync |
+| Twitter/X | Bio, follower count, following count. Tweet history (last 60 days): text, impressions, engagements, link clicks, retweets, replies. Profile visits. | 48-hour sync (Phase 2\) |
+| YouTube | Channel stats: subscriber count, total views, video count. Per-video: title, description, tags, views, watch time, CTR, average view duration, subscriber change. Upload dates. | Weekly sync |
+
+| PART 2 — ENTERPRISE SOCIAL BRANDING |
+| :---: |
+
+Part 2 covers the Social Branding service for companies and organisations. An enterprise account manages its brand presence across social platforms — defining what to post, what not to post, maintaining brand voice consistency, and managing AI-assisted content creation and scheduling across multiple platforms with an internal approval workflow.
+
+| 7\. SERVICE OVERVIEW — ENTERPRISE |
+| :---- |
+
+Enterprise Social Branding gives companies a governed, AI-assisted platform to manage their professional brand presence. It is distinct from the individual service in three fundamental ways: it serves an organisation rather than a person, it includes multi-user approval workflows (not just single-user approval), and it includes brand governance rules that define what content is and is not acceptable before the AI generates anything.
+
+| Dimension | Individual Social Branding | Enterprise Social Branding |
+| :---- | :---- | :---- |
+| Subject | A person’s professional brand | A company’s brand presence |
+| Platforms | Personalised per archetype and persona | Standardised across all company-connected platforms |
+| Content strategy | Persona-driven, career-goal aligned | Brand voice and values-driven, audience-targeted |
+| Approval workflow | Single user approves | Multi-role workflow: Creator → Editor → Approver |
+| Brand governance | Tone rules per persona | Explicit content policy: what to post, what not to post |
+| Analytics focus | Individual brand growth, recruiter visibility | Company reach, audience growth, brand sentiment |
+| Q-Score integration | Feeds RQx for individual | Not Q-Score integrated — separate enterprise analytics |
+
+## **7.1 Enterprise Account Structure**
+
+* An enterprise account is associated with a company entity (not an individual user)
+
+* Multiple team members can be added to the enterprise account with defined roles
+
+* Three roles: Content Creator (drafts content), Content Editor (reviews and edits), Brand Approver (final approval before posting)
+
+* At least one Brand Approver must be assigned before any content can go live
+
+* Enterprise account connects company social profiles (LinkedIn Company Page, Instagram Business, Twitter/X Business, YouTube Channel)
+
+| 8\. BRAND GOVERNANCE FRAMEWORK — ENTERPRISE |
+| :---- |
+
+Brand governance is the defining capability of the Enterprise service. Before the AI generates any content, it operates within a set of brand rules defined by the company. These rules determine what gets created, what gets filtered, and what gets flagged for human review.
+
+## **8.1 Brand Voice Definition**
+
+The enterprise sets its brand voice at account setup. Brand voice is defined across five dimensions:
+
+| Dimension | Options | Example |
+| :---- | :---- | :---- |
+| Tone | Professional / Conversational / Authoritative / Inspirational / Technical | A fintech company selects: Professional \+ Authoritative |
+| Formality | Formal / Semi-formal / Casual | Most enterprises: Semi-formal |
+| Perspective | First person (we) / Third person (company name) | Most LinkedIn company posts: First person (we) |
+| Language style | Simple and direct / Rich and descriptive / Data-led / Story-led | Tech companies often: Simple and direct \+ Data-led |
+| Audience | Talent/Recruitment / Clients/Customers / Industry peers / Investors / General public | Can select multiple; content adapted per audience tag |
+
+## **8.2 Content Policy — What to Post**
+
+* Company milestones: product launches, funding announcements, partnerships, awards
+
+* Thought leadership: industry trends, company perspective on market developments, research and data
+
+* Culture and values: team stories, behind-the-scenes, company events, diversity and inclusion content
+
+* Product and service highlights: feature announcements, case studies, client success stories (with consent)
+
+* Recruitment content: open roles, employer brand, employee testimonials, workplace benefits
+
+* Educational content: how-to guides, industry education, tips relevant to the company’s domain
+
+* Engagement content: polls, questions, community challenges aligned to brand values
+
+## **8.3 Content Policy — What Not to Post (Governance Rules)**
+
+The following rule categories are configurable by the enterprise at account setup. The AI applies these rules as filters before generating any content. Content that violates a rule is not queued — it is discarded or flagged for human review.
+
+| Rule Category | Default Setting | Configurable? |
+| :---- | :---- | :---- |
+| Political statements or partisan content | Blocked — never generated | Yes — enterprise can unlock with justification |
+| Commentary on competitors by name | Blocked — never generated | Yes — enterprise can unlock for specific approved comparisons |
+| Unverified claims or statistics | Flagged for human review before queuing | No — always flagged |
+| Sensitive social topics (religion, race, gender commentary) | Flagged for human review | Yes — enterprise can block entirely |
+| Legal or compliance-sensitive content (regulatory, financial) | Flagged for legal review tag | No — always flagged |
+| Crisis or incident response content | Blocked from AI generation — must be human-authored | No — always blocked from AI |
+| Content featuring named individuals (external) | Requires explicit approval flag | No — always requires approval |
+| Off-brand tone (outside defined voice dimensions) | Regenerated automatically before queuing | No — always enforced |
+
+| 9\. ENTERPRISE CONTENT ENGINE |
+| :---- |
+
+## **9.1 Content Generation Flow**
+
+| Step | Action | Role Responsible | System Behaviour |
+| :---- | :---- | :---- | :---- |
+| 1 | Content brief input | Content Creator or AI-initiated | Creator provides topic/theme OR system auto-generates brief from content calendar schedule |
+| 2 | Brand governance check | System (automated) | Brief checked against content policy rules. Blocked topics discarded. Flagged topics tagged for review. |
+| 3 | AI content generation | System (automated) | AI generates post draft applying: brand voice rules, platform format requirements, 80/20 content model, audience targeting |
+| 4 | Creator review | Content Creator | Creator reviews draft, makes edits, adds platform-specific adjustments |
+| 5 | Editor review | Content Editor | Editor reviews for brand alignment, tone consistency, factual accuracy |
+| 6 | Brand approval | Brand Approver | Final approval. Can approve, request changes, or reject. Only Brand Approver can push to scheduled. |
+| 7 | Schedule and post | System (automated) | Approved content scheduled per platform optimal posting time. Posted automatically at scheduled time. |
+| 8 | Performance tracking | System (automated) | Impressions, engagement, follower data collected. Brand analytics dashboard updated. |
+
+## **9.2 Enterprise 80/20 Content Model**
+
+The same 80/20 content model applies to enterprise, with enterprise-specific content types:
+
+| Content Type | Category | Description |
+| :---- | :---- | :---- |
+| Company milestone post | 80% Toolkit | Template: announcement \+ context \+ what it means for customers/team \+ CTA. Fills with company-specific data. |
+| Thought leadership post | 80% Toolkit | Template: industry observation \+ company perspective \+ supporting data point \+ question to audience. |
+| Culture post | 80% Toolkit | Template: team story or value highlight \+ what it demonstrates about the company \+ employee quote (with consent). |
+| Job opening post | 80% Toolkit | Template: role title \+ why this role matters \+ what kind of person thrives here \+ apply link. |
+| Educational post | 80% Toolkit | Template: common misconception or question in domain \+ company perspective \+ practical takeaway. |
+| Trending topic response | 20% Dynamic | AI monitors industry news. Generates company perspective post when relevant trend detected. Always flagged for Brand Approver review. |
+| Milestone reaction | 20% Dynamic | AI auto-generates draft when company milestone event detected (e.g. funding announcement, award won). Requires full approval workflow. |
+| Engagement response | 20% Dynamic | AI drafts responses to comments on company posts. Creator reviews before sending. |
+
+| 10\. ACCEPTANCE CRITERIA |
+| :---- |
+
+**Part 1 — Individual Social Branding**
+
+| \# | Acceptance Criterion | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | OAuth connection completes for all four platforms (LinkedIn, Instagram, Twitter/X, YouTube). Profile data collected on first sync. Sync schedule runs per defined frequency. | \[ \] PASS \[ \] FAIL |
+| **2** | Brand Score calculated correctly from all 7 components. Brand Score feeds RQx via defined formula. RQx update event emitted to Assessment and Pathways services on Brand Score change of 5+ points. | \[ \] PASS \[ \] FAIL |
+| **3** | Profile analysis runs for all four platforms. Section-by-section audit scores generated. Benchmark against target role applied. Profile recommendations generated with current and recommended text. | \[ \] PASS \[ \] FAIL |
+| **4** | Profile recommendations can be approved and applied to the live platform profile. Rejected recommendations discarded. Applied recommendations update the social\_profile\_recommendations table correctly. | \[ \] PASS \[ \] FAIL |
+| **5** | Content calendar generated for correct persona with correct platform mix. 80/20 split enforced over any 2-week rolling window. All 6 content calendar rules applied correctly. | \[ \] PASS \[ \] FAIL |
+| **6** | Pre-baked toolkit content fills correctly with user-specific data (achievements, Q-Score stats, pathway milestones). All 8 toolkit content types functional. | \[ \] PASS \[ \] FAIL |
+| **7** | Dynamic content triggers fire correctly: Q-Score improvement event, pathway milestone event, trending topic detection, profile update trigger. | \[ \] PASS \[ \] FAIL |
+| **8** | Approval queue functions correctly: user can approve (with optional edits), reject, or request regeneration for each content item. No content posted without approved status. | \[ \] PASS \[ \] FAIL |
+| **9** | Auto-approve mode available as opt-in only. When enabled, content posts without individual approval. Can be disabled at any time. | \[ \] PASS \[ \] FAIL |
+| **10** | Approved content posted to correct platform at scheduled time. Platform-specific formatting applied (LinkedIn: no external link in body. Instagram: hashtags appended. YouTube: description and tags generated.) | \[ \] PASS \[ \] FAIL |
+| **11** | Engagement queue populated with AI-drafted responses to comments and connection requests. User approval required before sending. | \[ \] PASS \[ \] FAIL |
+| **12** | Analytics collected per platform per sync cycle. Performance data stored in social\_content\_performance table. Analytics dashboard displays all tracked metrics with trend lines. | \[ \] PASS \[ \] FAIL |
+| **13** | Persona switching updates platform activation recommendations, content calendar strategy, and posting frequency rules immediately. | \[ \] PASS \[ \] FAIL |
+| **14** | Archetype-conditional platform activation: Instagram not recommended by default for Technical Specialist or Strategic Leader personas. System surfaces recommendation prompt for relevant personas only. | \[ \] PASS \[ \] FAIL |
+
+**Part 2 — Enterprise Social Branding**
+
+| \# | Acceptance Criterion | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Enterprise account creation completes with brand voice and content policy configuration. Multi-role team setup (Creator, Editor, Approver) functional. Minimum one Approver enforced before content can go live. | \[ \] PASS \[ \] FAIL |
+| **2** | Brand governance rules applied before AI content generation. Blocked topics discarded without queuing. Flagged topics tagged and routed to enterprise\_content\_flags table for human review. | \[ \] PASS \[ \] FAIL |
+| **3** | All 8 governance rule categories enforced: political content blocked, competitor mentions blocked, unverified claims flagged, sensitive topics flagged, legal content flagged, crisis content blocked from AI, named individuals require approval, off-brand tone regenerated. | \[ \] PASS \[ \] FAIL |
+| **4** | Brand voice rules (tone, formality, perspective, language style, audience) applied to all AI-generated content. Off-brand drafts regenerated automatically before entering approval queue. | \[ \] PASS \[ \] FAIL |
+| **5** | Three-stage approval workflow enforced: Creator → Editor → Brand Approver. Content cannot skip stages. Only Brand Approver role can push content to scheduled status. | \[ \] PASS \[ \] FAIL |
+| **6** | All 8 enterprise content types (5 toolkit \+ 3 dynamic) generated correctly. Trending topic and milestone dynamic content always routed to Brand Approver regardless of workflow stage. | \[ \] PASS \[ \] FAIL |
+| **7** | Flagged content resolution workflow completes: flag raised → human reviews → approved/rejected/edited → flag closed. Content entry status updates correctly on resolution. | \[ \] PASS \[ \] FAIL |
+| **8** | Enterprise analytics collected per platform. Brand analytics dashboard displays follower growth, impressions, engagement rate, and top-performing posts per platform. | \[ \] PASS \[ \] FAIL |
+| **9** | Enterprise content calendar visible across all team member roles with correct status labels per approval stage. Each role sees only the actions available to their role. | \[ \] PASS \[ \] FAIL |
+
diff --git a/social_branding/audit-2026-03-25-architecture-plan-prd.md b/social_branding/audit-2026-03-25-architecture-plan-prd.md
new file mode 100644
index 0000000..fe70fdf
--- /dev/null
+++ b/social_branding/audit-2026-03-25-architecture-plan-prd.md
@@ -0,0 +1,458 @@
+# Social Branding Service Audit — Architecture, Integration, Plan/PRD Alignment
+
+Date: 2026-03-25
+
+## Purpose
+
+This report updates the prior audit (`docs/plan-prd-implementation-audit.md`, dated 2026-03-23) with:
+
+- a detailed review of **layering leaks / integration issues** (surface vs service vs engine)
+- a clear summary of **how far we’ve progressed since the prior audit**
+- a mapping of the current implementation against:
+ - the **narrow plan** in `docs/plan.md`
+ - the broader **PRD** in `docs/PRD.md`
+- an explicit **acceptance criteria coverage** summary (met vs not met)
+
+Auth is treated as non-blocking unless it materially affects architecture boundaries.
+
+---
+
+## Executive Summary
+
+The architecture is **significantly more aligned** to the desired Engine → Service (Use-cases) → Surface split than it was in the 2026-03-23 audit.
+
+Key improvements versus the prior audit:
+
+- an explicit `app/engine/` package now exists with normalized I/O contracts (`app/engine/contracts.py`)
+- API routes mostly delegate to `app/use_cases/*` orchestration modules
+- persistence is generally accessed via `app/repositories/*`
+- Redis worker has a functional job execution path (`job_type`) and idempotency semantics
+- migrations are now the schema source of truth (no startup `create_all()` behavior)
+
+However, there are still **layering leaks** and clarity issues:
+
+- the engine layer depends on `app/services/scoring_service.py` (a layer inversion)
+- `app/services/` mixes concerns (domain logic + adapters + AI provider orchestration)
+- surfaces still pass DB sessions directly into use-cases (minor leak; helper exists to hide it)
+- worker supports both job-based and legacy session-based processing paths (migration state)
+
+Bottom line:
+
+- **Plan alignment:** largely achieved at the capability level, though the API surface has evolved from the plan’s original endpoint list.
+- **PRD alignment:** still intentionally partial (LinkedIn-first subset). Cross-platform automation, scheduled posting, RQx integration, and enterprise workflows remain out of scope / incomplete.
+
+---
+
+## Current Architecture (Observed)
+
+### Surface layer
+
+Surfaces are primarily HTTP routes:
+
+- FastAPI app composition: `app/main.py`
+- v1 router aggregation: `app/api/v1/router.py`
+- route modules:
+ - `app/api/v1/profiles.py`
+ - `app/api/v1/analysis.py`
+ - `app/api/v1/content.py`
+ - `app/api/v1/internal.py`
+
+Additional surfaces also exist:
+
+- WebSocket agent surface: `app/main.py` → `/ws/agent`
+- A2A surfaces: `app/a2a/*`
+- MCP tool surface: `app/main.py` mounts `/mcp`
+
+### Service layer (orchestration)
+
+Orchestration is primarily represented by:
+
+- Use-cases: `app/use_cases/*`
+- Persistence boundaries: `app/repositories/*`
+
+Example orchestration pattern:
+
+- `app/use_cases/enrich_profile.py`:
+ - loads user + profile via repos (`AccountsRepo`, `ProfilesRepo`)
+ - calls an external adapter (`BrightDataService`)
+ - persists changes via repos
+ - returns the updated ORM object
+
+### Engine layer (pure decision logic)
+
+The engine now has:
+
+- normalized contracts: `app/engine/contracts.py`
+- decision engines:
+ - `app/engine/audit_engine.py`
+ - `app/engine/brand_score_engine.py`
+ - `app/engine/persona_engine.py`
+ - `app/engine/calendar_engine.py`
+ - `app/engine/draft_engine.py`
+
+### Worker + jobs
+
+- Worker consumes Redis Stream `tasks:social-branding`: `app/adk/worker.py`
+- Jobs are normalized and enumerated: `app/jobs/definitions.py`
+- Worker supports:
+ 1. **Job path** (new): `job_type` → jobs dispatcher → use-cases
+ 2. **Legacy session path**: agent session-based behavior
+
+See README job summary: `README.md` (“Job system”).
+
+---
+
+## Progress vs prior audit (2026-03-23 → 2026-03-25)
+
+The previous audit described the repo as:
+
+- HTTP-only in practice
+- a single application service mixing persistence + orchestration + business logic
+- an engine-like set of helpers, but not separated as explicit engine/package boundary
+- Redis and worker as scaffolding only
+
+### What has improved substantially
+
+1) **Engine extraction is real**
+
+- New explicit `app/engine/` package
+- New normalized boundary models in `app/engine/contracts.py`
+
+This directly addresses the prior audit’s top architectural mismatch (“no explicit normalized engine contract”).
+
+2) **Service logic is decomposed into use-cases + repositories**
+
+- Routes in `app/api/v1/*` generally call `app/use_cases/*`.
+- Use-cases generally rely on repositories for DB access.
+
+This reduces the prior “one large service” problem.
+
+3) **Worker is now an operational path**
+
+- `app/adk/worker.py` supports a job-based path via `job_type`.
+- `app/jobs/definitions.py` defines job types and an idempotency key mechanism.
+
+This is stricter and more production-like than the prior “scaffold” characterization.
+
+4) **Schema is migration-managed**
+
+README explicitly states:
+
+- app does not auto-create tables
+- Alembic migrations are required
+
+This removes a major “MVP-only” footgun from the earlier audit.
+
+### Verification evidence
+
+- Unit tests: `pytest -q` → **106 passed** (2 warnings)
+
+---
+
+## Layering leaks / integration issues (detailed)
+
+### Leak A — Engine depends on `app/services/*` (layer inversion)
+
+**Evidence**
+
+- `app/engine/audit_engine.py` imports `app.services.scoring_service` inside `run_audit()`.
+
+**Why this is a leak**
+
+The intended architecture says engine is pure and should not depend on service/adapters.
+
+Even if `scoring_service.py` is currently pure, it lives in `app/services/`, which is conceptually “above” engine.
+
+**Risk**
+
+- future edits may add I/O, config, or provider calls into `scoring_service.py`
+- engine purity becomes fragile and the architecture story becomes ambiguous
+
+**Recommendation**
+
+Move the scoring rules into the engine layer and reverse dependencies:
+
+- rename/move `app/services/scoring_service.py` → `app/engine/scoring_rules.py` (or similar)
+- update `audit_engine.py` to call `app.engine.scoring_rules`
+- optionally keep a thin compatibility wrapper in `app/services/scoring_service.py` for external callers
+
+Success criteria:
+
+- `app/engine/*` imports only stdlib + `app.engine.contracts` (+ pydantic)
+- no `app.services.*`, no SQLAlchemy, no FastAPI
+
+---
+
+### Leak B — `app/services/` mixes multiple layers (domain logic + adapters + provider orchestration)
+
+**Evidence**
+
+`app/services/` contains:
+
+- domain-like rules logic: `app/services/scoring_service.py`
+- external platform adapters:
+ - `app/services/brightdata_service.py`
+ - `app/services/scrapetable_service.py`
+- AI orchestration / provider layer:
+ - `app/services/branding_intelligence.py`
+ - `app/services/ai_service.py`
+
+**Why this matters**
+
+It’s not “wrong” operationally, but it weakens the 3-layer presentation (engine/service/surface).
+
+Right now the actual runtime conceptual layers are closer to:
+
+- surfaces
+- use-cases (service orchestration)
+- engine
+- adapters/providers (BrightData/Scrapetable/OpenAI/DSPy)
+
+**Recommendation**
+
+Split by intent:
+
+- `app/engine/` → pure decision logic
+- `app/use_cases/` → orchestration
+- `app/repositories/` → persistence boundary
+- `app/adapters/` (or `app/integrations/`) → brightdata/scrapetable/ai providers
+
+This is mostly a packaging clarity move, but it reduces future layering violations.
+
+---
+
+### Leak C — Surfaces still pass DB sessions directly (minor leak)
+
+**Evidence**
+
+Routes commonly use:
+
+- `session=Depends(get_session)`
+- then call use-cases with `execute(session, clerk_id=..., ...)`
+
+Examples:
+
+- `app/api/v1/analysis.py`
+- `app/api/v1/profiles.py`
+- `app/api/v1/content.py`
+
+There is already a helper intended to hide this:
+
+- `app/api/dependencies.py` defines `provide_use_case(fn)`
+
+**Why it matters**
+
+This makes surfaces slightly “thicker” and exposes infrastructure plumbing.
+
+**Recommendation**
+
+Optional cleanup:
+
+- adopt `provide_use_case()` consistently so route modules don’t touch sessions directly
+
+---
+
+### Leak D — Worker supports two execution models (job path + legacy session path)
+
+**Evidence**
+
+- `app/adk/worker.py`:
+ - job path: `job_type` → jobs dispatcher
+ - legacy path: `SocialAgentSession` based on `action` / `session_start`
+
+**Why it matters**
+
+Having two paths for “doing work” means:
+
+- idempotency/retry semantics may differ
+- auth context may differ
+- business invariants can diverge
+
+**Recommendation**
+
+Treat this as an explicit migration state:
+
+- long-term goal: agent/session path should call use-cases (or enqueue jobs) so there’s one service boundary
+
+---
+
+## Plan alignment (`docs/plan.md`)
+
+The plan is a LinkedIn-first, individual-only MVP with:
+
+- ingest profile data
+- compute Brand Score v1
+- persona-based strategy
+- content calendar + draft generation
+- approval queue + manual publish confirmation
+- dashboard exposure
+
+### Capability-level mapping (observed)
+
+1) **Ingest / import**
+
+- URL-first ingestion and refresh flows exist:
+ - `app/api/v1/profiles.py`
+ - use-cases: `save_linkedin_url`, `fetch_profile_by_url`, `sync_profile`, `enrich_profile`
+- Worker supports `IMPORT_PROFILE` job: `app/jobs/definitions.py`
+
+Status: **Met** (though ingestion method has evolved vs plan’s “manual JSON import endpoint”).
+
+2) **Audit + Brand Score v1**
+
+- rule-based auditing exists:
+ - `app/services/scoring_service.py`
+ - `app/engine/audit_engine.py`
+- Brand score engine exists:
+ - `app/engine/brand_score_engine.py`
+- brand score use-case exists: `app/use_cases/recalculate_brand_score.py`
+
+Status: **Met**
+
+3) **Persona + calendar + drafts**
+
+- persona engine: `app/engine/persona_engine.py`
+- calendar engine: `app/engine/calendar_engine.py`
+- draft engine: `app/engine/draft_engine.py`
+- calendar use-case: `app/use_cases/generate_calendar.py`
+- worker job: `GENERATE_CALENDAR`
+
+Status: **Met**
+
+4) **Approval queue + publish confirmation**
+
+- use-case exists: `app/use_cases/approval_workflow.py`
+
+Status: **Likely met** (use-case exists, test suite passes broadly), but endpoint-level verification should be confirmed if this is presentation-critical.
+
+5) **Dashboard**
+
+- dashboard use-case: `app/use_cases/get_dashboard.py`
+- dashboard state endpoint for ecosystem: `app/main.py` → `/api/state/{clerk_id}`
+
+Status: **Met**
+
+### Plan checklist items (from plan.md “Review Checklist”)
+
+- Service works without Live LinkedIn OAuth → **Met** (URL-based ingestion)
+- LinkedIn is the only live platform in v1 → **Met** (runtime behavior)
+- Brand Score does not depend on unavailable metrics → **Met**
+- Approval queue blocks publishing until approval → **Likely met** (verify approval endpoints and state transitions if needed)
+- Multi-platform and enterprise features stay deferred → **Met**
+- Dashboard exposes useful state → **Met**
+
+---
+
+## PRD alignment (`docs/PRD.md`)
+
+PRD describes a broader multi-platform automation loop:
+
+Connect → Collect → Analyze → Generate → Approve → Post → Track → Feed back (Brand Score → RQx)
+
+### What is covered (partial PRD)
+
+- LinkedIn profile analysis exists (rule-based + AI routes)
+- Strategy generation exists (`app/api/v1/content.py` and `app/use_cases/generate_content_strategy.py`)
+- Approval concept exists (approval workflow use-case)
+- Intelligence provider architecture exists (`app/services/branding_intelligence.py`) with heuristic fallback
+
+### What is not covered / missing vs PRD
+
+Not observed in current codebase (and consistent with MVP scope):
+
+- OAuth connect flows per platform
+- Cross-platform runtime collection + posting (Instagram/X/YouTube)
+- Scheduled posting executors
+- Recurring sync cadence engine (daily/48h/weekly) as an orchestrated scheduler
+- Brand Score → RQx formula mapping and cross-service event emission
+ - string search found no `RQx`, `Assessment Service`, or `Pathways Service` integration hooks in `app/**`
+- Tone lock and sensitive-topic filtering
+- Auto-approve mode (opt-in)
+- Engagement automation workflow (draft replies/comments end-to-end)
+- Enterprise governance and multi-role approval workflow
+
+PRD alignment conclusion:
+
+- **PRD-complete:** No
+- **PRD-partial (LinkedIn-first subset / foundations):** Yes
+
+---
+
+## Acceptance Criteria Coverage Summary
+
+### Plan acceptance criteria (interpreted from `docs/plan.md`)
+
+Met:
+
+- LinkedIn-first, individual-only MVP flow is implemented in current architecture
+- ingestion without OAuth dependency is supported
+- audit, persona, calendar, drafts, brand score, dashboard exist
+- background job path exists and is documented
+- migrations required (no implicit schema creation)
+
+Not fully verified in this pass:
+
+- approval queue endpoints + publish confirmation endpoints (use-case exists; verify routes/state transitions if required for demo)
+
+### PRD acceptance criteria (high-level)
+
+Met (foundation-level only):
+
+- analysis + generation surfaces exist
+- approval touchpoint exists conceptually
+
+Not met (major PRD features):
+
+- automated cross-platform loop (connect/collect/post/track)
+- scheduled posting
+- analytics parity + recurring sync
+- Brand Score → RQx integration + downstream event emission
+- tone lock, sensitive-topic filter
+- auto-approve mode
+- engagement automation
+- enterprise governance workflows
+
+---
+
+## Quality gates (evidence)
+
+- Tests: `pytest -q` → **106 passed** (2 warnings)
+
+Warnings:
+
+- Pydantic v2 deprecation warning about class-based Config (non-blocking)
+
+---
+
+## Recommendations (prioritized)
+
+### 1) Fix engine purity (remove layer inversion)
+
+- Move rule-based scoring logic from `app/services/scoring_service.py` into `app/engine/`.
+- Update `app/engine/audit_engine.py` to call engine-local scoring.
+
+This is the cleanest, highest-signal architecture fix.
+
+### 2) Clarify adapter/provider layer
+
+- Split `app/services/` into `app/adapters/` (or `app/integrations/`) vs domain logic.
+
+### 3) Thin surfaces further (optional)
+
+- adopt `app/api/dependencies.py::provide_use_case()` so routes don’t pass sessions directly.
+
+### 4) Converge worker execution paths
+
+- make legacy session path invoke use-cases (or enqueue jobs) so there is one orchestration boundary.
+
+---
+
+## Bottom line
+
+Compared to 2026-03-23, this repo is now **meaningfully closer** to the desired target architecture:
+
+- explicit engine and normalized contracts
+- use-case based orchestration
+- worker jobs are functional and documented
+
+The main remaining architecture debt is **layer purity and packaging clarity**, not missing MVP features.
diff --git a/social_branding/plan-brand-score-component-model.md b/social_branding/plan-brand-score-component-model.md
new file mode 100644
index 0000000..a5dcdcb
--- /dev/null
+++ b/social_branding/plan-brand-score-component-model.md
@@ -0,0 +1,376 @@
+# Implementation plan — Brand Score: full PRD component model + breakdown
+
+Date: 2026-03-27
+Scope: PRD additions item **(1)** (from `prd-additions.md`)
+Non-goals (explicit PRD exclusions for this phase): posting, executing actions on platforms, adding new platforms beyond LinkedIn-first.
+
+---
+
+## Checklist (requirements coverage)
+
+- [ ] Add remaining Brand Score components as **first-class computed fields** (not just a single audit-derived score):
+ - [ ] Content Consistency (20%)
+ - [ ] Audience Growth (15%)
+ - [ ] Engagement Rate (15%)
+ - [ ] Recruiter Visibility (15%)
+ - [ ] Content Quality (10%)
+ - [ ] Cross-Platform Consistency (5%) (schema-ready; compute from available platforms only)
+- [ ] Store/persist **component breakdown** and PRD-required **“objective, measurable signals”** explanations
+- [ ] Implement Brand Score **trend line** (history storage + API response)
+- [ ] Implement **v1 proxies + renormalization** for LinkedIn-private analytics gaps
+- [ ] Add **metrics snapshot persistence** (followers/connections over time) so Audience Growth + trendline are computable
+
+---
+
+## 1) Outcome + contract
+
+### Inputs
+Per `user_id` and a computation window (rolling), compute with:
+- LinkedIn profile snapshot: headline/about/experience/skills (as currently ingested)
+- Post/activity list over a window (suggest 30 days): timestamps, text, and any available post metrics
+- Metrics snapshots over time (if present/collectible): followers/connections, impressions, engagements, profile views, search appearances
+- Persona context (if present): target persona/role signals used in content quality and recruiter visibility proxy
+
+**v1 data reality (current repo ingestion):**
+- Profile snapshot fields + `followers_count`/`connections_count` are present.
+- `activity` exists but is typically limited (date/title/url + sometimes likes/comments).
+- Impressions/reach, profile views, and search appearances are typically not available in LinkedIn-first v1; treat as proxy/N.A.
+
+### Outputs
+- `brand_score_total` (0–100)
+- `brand_score_components[]` each with:
+ - `key` (stable enum)
+ - `weight` (PRD)
+ - `score` (0–100)
+ - `weighted_points` (score × weight)
+ - `signals` (structured numeric strings/values for auditability)
+ - `explanation` (human-readable, objective/measurable)
+ - `insufficient_data` (boolean)
+- `brand_score_history[]` trendline points (date, total score)
+
+### Error + missing data behavior
+Pick **one explicit policy** so scores don’t jitter unpredictably:
+- **Recommended v1:** *weight renormalization*.
+ - If component lacks minimum data, mark `insufficient_data=true`.
+ - Exclude it from total weighting and renormalize remaining weights to sum to 1.0.
+ - Still return the missing component in breakdown (so UI can display “N/A”).
+
+**v1 proxy rule:** if a PRD metric is not collectible on LinkedIn (e.g., impressions, profile views, search appearances), compute a deterministic proxy where possible; otherwise mark the component `insufficient_data=true` and rely on renormalization.
+
+### Versioning
+Persist a scoring version string (e.g. `2026-03-27.v1`) with each snapshot to support future formula tweaks.
+
+---
+
+## 2) Component model (PRD weights + measurable signals)
+
+> Scores are 0–100. Each component must produce structured `signals` and a plain-language explanation referencing those signals.
+
+### 2.1 Content Consistency — 20%
+
+**Goal:** consistency of posting frequency + tone consistency over a rolling window.
+
+**Signals (v1):**
+- `posts_last_30d`
+- `days_between_posts_avg`
+- `days_between_posts_stddev`
+- `weeks_meeting_target_cadence` (e.g., >=2 posts/week or configured target)
+- `tone_label_distribution` (optional v1) or `tone_consistency_score`
+
+**v1 note:** cadence is computable from `activity[].date` if present.
+
+**Important v1 filter:** Bright Data “activity” often includes *interactions* (e.g., “Liked by X”), not just authored posts. Use `activity[].type` (populated from Bright Data `interaction` when available) to **exclude** non-authored items from cadence calculations.
+
+Tone is optional and should be `insufficient_data=true` unless post text is available.
+
+#### Tone consistency (addendum — v1.1 implementation checklist)
+
+We currently score **cadence** deterministically from activity dates; this addendum covers adding the optional “tone consistency” portion without destabilizing totals.
+
+- [ ] Extend ingestion/normalization so activity items include **authored post text** when available
+ - [ ] Prefer a stable field name in the normalized profile dict (e.g. `activity[].text`).
+ - [ ] Ensure non-authored items are filtered (continue using `activity[].type/interaction` heuristics).
+
+- [ ] Add tone classification (deterministic-first, AI optional)
+ - [ ] Add adapter method (or reuse existing AI adapter) to classify tone labels for a post: e.g. `{tone: "educational"|"opinion"|"personal"|"promo"|...}`
+ - [ ] Cache tone labels per post URL/id when possible to avoid re-scoring.
+
+- [ ] Compute tone consistency signals
+ - [ ] `tone_label_distribution` (counts per label)
+ - [ ] `tone_entropy` (or similar) as the numeric signal
+ - [ ] `tone_consistency_score` mapped 0–100
+ - [ ] If fewer than N posts have text (suggest N=3), mark tone as `insufficient_data=true`.
+
+- [ ] Merge cadence + tone into the existing `content_consistency` score
+ - [ ] Recommended split: cadence 70%, tone 30% (configurable)
+ - [ ] Keep overall component deterministic when AI is unavailable:
+ - [ ] If AI tone classification fails, fall back to `insufficient_data=true` for tone and score cadence only.
+
+- [ ] Update explanation string to include tone when scored
+ - [ ] Example: “Cadence variance is X days; tone consistency is Y/100 across N posts.”
+
+- [ ] Add tests
+ - [ ] Test cadence-only path remains unchanged.
+ - [ ] Test tone-scored path produces stable distribution + score.
+
+**Computation idea (v1 deterministic + optional AI):**
+- Frequency score derived from cadence stability:
+ - reward meeting minimum weekly target
+ - penalize high variance in gaps
+- Tone consistency (optional): classify each post tone (adapter AI), compute entropy / variance; map to 0–100.
+
+**Explanation template:**
+- “You posted {posts_last_30d} times in 30 days. Cadence variance is {stddev} days; {weeks_meeting_target_cadence}/4 weeks meet target.”
+
+### 2.2 Audience Growth — 15%
+
+**Goal:** follower/connection growth rate over last 30 days.
+
+**Signals:**
+- `followers_start_30d`
+- `followers_end_30d`
+- `follower_growth_abs`
+- `follower_growth_rate`
+
+**v1 requirement:** this component needs historical follower counts. Implement via metrics snapshots (see §3.3).
+
+**Computation (v1):**
+- `growth_rate = (end - start) / max(start, 1)`
+- Map to 0–100 using bands (configurable), e.g.:
+ - <=0% → 10
+ - 0–1% → 40
+ - 1–3% → 70
+ - 3–6% → 85
+ - >6% → 95
+
+**Explanation:**
+- “Followers changed from {start} → {end} (+{abs}, {rate:.1%}) in 30 days; target band is {target_band}.”
+
+### 2.3 Engagement Rate — 15%
+
+**Goal:** likes/comments/shares/saves as % of reach.
+
+**Signals:**
+- `posts_counted`
+- `impressions_total` (or `reach_total` if you have it)
+- `engagements_total`
+- `engagement_rate_weighted_avg`
+- `engagement_rate_p50` / `p75` (optional)
+
+**Computation (v1):**
+- Prefer weighted average: `sum(engagements)/sum(impressions)` across posts with impressions.
+- Guardrails for low denom.
+
+**v1 LinkedIn-first proxy:** if impressions/reach aren’t available, use a deterministic proxy:
+- `engagements_total = sum(likes + comments)` across recent activity items with those fields
+- `engagements_per_post_avg = engagements_total / max(posts_counted, 1)`
+- Optional normalization: `engagements_per_post_per_1k_followers`
+If engagement signals are missing/too sparse, mark `insufficient_data=true` and renormalize.
+
+**Important v1 filter:** only count *authored posts* (exclude “liked/commented/shared by user” items based on `activity[].type`).
+
+**Explanation:**
+- “Avg engagement rate is {rate:.2%} across {posts_counted} posts; benchmark target band {target_band}.”
+
+### 2.4 Recruiter Visibility — 15%
+
+**Goal:** profile appearance rate in recruiter/talent searches.
+
+**Signals (best effort LinkedIn-first):**
+- Preferred if collectible:
+ - `search_appearances_7d`, `search_appearances_30d`
+ - `profile_views_7d`, `profile_views_30d`
+- Proxy if not collectible:
+ - `keyword_coverage_score` (0–100)
+ - `missing_keywords_count`
+
+**Computation (v1):**
+- If search appearances/profile views available: score by percentile bands.
+- Else: compute proxy keyword coverage vs target role/persona keyword set.
+
+**v1 default:** treat search appearances/profile views as unavailable and use keyword coverage proxy.
+
+**Explanation:**
+- “Search appearances (7d): {x}. Keyword coverage {coverage}/100; missing {n} high-signal recruiter keywords.”
+
+### 2.5 Content Quality — 10%
+
+**Goal:** AI-assessed relevance/originality/alignment to persona framework.
+
+**Signals:**
+- `ai_quality_score_avg`
+- `ai_relevance_avg` (optional detail)
+- `ai_originality_avg` (optional detail)
+- `ai_persona_alignment_avg` (optional detail)
+- `low_quality_flags` (e.g., repetitive template, too short)
+
+**Computation (v1):**
+- Use AI adapter to score posts (sample last N posts).
+- Average to 0–100; apply small penalties for repeated/low-effort patterns.
+
+**v1 fallback:** if post text isn’t collectible, score using profile text (headline + summary + recent roles) and reflect that in `signals`.
+
+**Explanation:**
+- “Quality score {score}/100 across {n} posts: relevance {r}/100, originality {o}/100, persona alignment {p}/100.”
+
+### 2.6 Cross-Platform Consistency — 5% (schema-ready)
+
+**Goal:** messaging/voice alignment across connected platforms.
+
+**Signals:**
+- `connected_platforms`
+- `platforms_scored`
+- `cross_platform_similarity` (if >1 platform)
+
+**Computation (v1):**
+- If only LinkedIn connected: mark `insufficient_data=true` and exclude via renormalization.
+- If multiple: compare embedding similarity of bios/headlines + recent posts themes.
+
+**Explanation:**
+- “Only LinkedIn connected; cross-platform consistency isn’t scored yet.”
+
+---
+
+## 3) Persistence + history (trend line)
+
+### 3.1 Storage model
+Add a snapshot table to store history and component breakdown for auditability.
+
+**Recommended table:** `brand_score_snapshots`
+- `id`
+- `user_id`
+- `platform` (string/enum)
+- `window_start`, `window_end`
+- `score_total` (numeric)
+- `components_json` (JSON/JSONB)
+- `scoring_version` (string)
+- `created_at`
+
+Also store a “latest” summary on the user profile (fast reads):
+- `latest_brand_score_total`
+- `latest_brand_score_components_json`
+- `latest_brand_score_calculated_at`
+
+### 3.2 Trendline
+- Provide daily points (last N days).
+- If multiple snapshots/day: use latest per day (simple, stable).
+
+### 3.3 Metrics snapshots (Audience Growth input)
+
+Add a small metrics history table so we can compute change-over-time deterministically.
+
+**Recommended table:** `social_metrics_snapshots`
+- `id`
+- `user_id`
+- `platform` (string/enum; v1 = `linkedin`)
+- `followers_count` (int nullable)
+- `connections_count` (int nullable)
+- `captured_at` (timestamp)
+
+**Capture policy (v1):**
+- Insert a snapshot after each successful LinkedIn sync.
+- Optional dedupe: keep at most 1 snapshot/day per user+platform.
+
+---
+
+## 4) Engine design (code structure)
+
+### 4.1 Orchestrator
+In `app/engine/brand_score_engine.py` (or equivalent), implement:
+- `compute_brand_score(user_id, platform, window_days=30) -> BrandScoreResult`
+- `compute_and_persist_brand_score(...) -> BrandScoreSnapshot`
+
+### 4.2 Component functions
+Create pure functions (easy to test):
+- `score_content_consistency(data) -> ComponentResult`
+- `score_audience_growth(data) -> ComponentResult`
+- `score_engagement_rate(data) -> ComponentResult`
+- `score_recruiter_visibility(data) -> ComponentResult`
+- `score_content_quality(data) -> ComponentResult`
+- `score_cross_platform_consistency(data) -> ComponentResult`
+
+### 4.3 Config + thresholds
+Centralize mapping bands and targets so they’re easy to tune:
+- engagement target bands
+- growth target bands
+- cadence target
+- minimum sample sizes (e.g., >=3 posts for some components)
+
+---
+
+## 5) API changes
+
+### 5.1 Endpoints (or dashboard response augmentation)
+Add (or extend existing dashboard routes):
+
+1) `GET /brand-score/latest`
+- Returns: total + components breakdown + `scoring_version` + `window`.
+
+2) `GET /brand-score/trend?days=30`
+- Returns: array of `{date, score_total}` (optionally include component totals later).
+
+### 5.2 Response schemas
+Add Pydantic models:
+- `BrandScoreComponentBreakdown`
+- `BrandScoreSnapshotResponse`
+- `BrandScoreTrendResponse`
+
+---
+
+## 6) Triggering computations
+
+Compute snapshot when inputs change.
+
+**Recommended triggers:**
+- After each LinkedIn sync job completes
+- Optionally: nightly job (backup) to ensure fresh trendline
+
+Implementation:
+- Hook into job dispatcher / sync pipeline to call `compute_and_persist_brand_score(user_id, "linkedin")`.
+
+**v1 addition:** after LinkedIn sync, also write a `social_metrics_snapshots` row (followers/connections) so Audience Growth works.
+
+---
+
+## 7) Tests (minimum set)
+
+Add unit tests in `tests/` to stabilize the scoring math:
+
+1) `test_brand_score_components_happy_path`
+- Fake dataset with posts + metrics
+- Assert all 6 component keys present
+- Assert weights consistent with PRD
+- Assert total score within expected range and deterministic
+
+2) `test_brand_score_missing_data_renormalization`
+- Omit recruiter visibility metrics & cross-platform
+- Assert `insufficient_data` flagged
+- Assert total calculation uses renormalized weights
+
+3) `test_brand_score_snapshot_persistence`
+- Compute-and-persist writes a snapshot and updates “latest” summary
+
+4) `test_metrics_snapshots_enable_audience_growth`
+- Insert two snapshots in-window
+- Assert the Audience Growth component derives start/end from snapshots
+
+---
+
+## 8) Execution steps (recommended order)
+
+1) Add DB migration(s): `brand_score_snapshots` + latest fields on user summary
+1b) Add DB migration: `social_metrics_snapshots`
+2) Implement/extend scoring engine with component spec + versioning
+3) Add repository methods for snapshot insert + trend queries
+4) Add API endpoints/schemas for latest + trendline
+5) Wire compute trigger after sync
+6) Add tests and make them green
+
+---
+
+## 9) Notes / open questions (non-blocking)
+
+- Recruiter visibility and search appearances might be hard to collect reliably without LinkedIn API access; v1 can use a proxy keyword coverage score.
+- Engagement rate impressions/reach may be unavailable on LinkedIn-first v1; use engagement proxies or mark insufficient data + renormalize.
+- Cross-platform consistency should be marked “insufficient data” unless multiple platforms are connected.
+- If you already have brand score summary fields on `social_users`, reuse them; otherwise add them.
diff --git a/social_branding/plan-brand-score-rqx-mapping-events.md b/social_branding/plan-brand-score-rqx-mapping-events.md
new file mode 100644
index 0000000..8453869
--- /dev/null
+++ b/social_branding/plan-brand-score-rqx-mapping-events.md
@@ -0,0 +1,244 @@
+# Implementation Plan: Brand Score → RQx mapping + events
+
+Date: 2026-03-27
+Scope source: `docs/prd-additions.md` → section **“2) Brand Score → RQx mapping + events”**
+Out of scope: Posting/automation to platforms; adding new platforms.
+
+---
+
+## ✅ Requirements checklist (PRD)
+
+- [ ] Compute & store **RQx contribution** as: `Brand Score × 0.4`
+- [ ] Ensure recalculation runs **after every platform sync** (LinkedIn daily in PRD)
+- [ ] Emit update when Brand Score changes by **5+ points**, including before/after + metadata
+- [ ] Persist and expose Brand Score history for the dashboard (trendline)
+
+---
+
+## Tiny contract (what we’ll build)
+
+### Inputs
+- `social_user_id`
+- `platform` (initially `linkedin`)
+- `sync_context` metadata (at least: `sync_job_id`, `sync_started_at`, `sync_finished_at`, `source`)
+
+### Computation
+- `brand_score` (0–100) from the active Brand Score engine (v1/v2)
+- `rqx_contribution = brand_score * 0.4`
+
+### Outputs
+1. **Current state** persisted on the user (fast reads):
+ - `brand_score` (and updated timestamp)
+ - `rqx_contribution` (and updated timestamp)
+2. **History** row appended each recompute:
+ - before/after values + delta
+ - metadata (platform, sync_job_id, engine version)
+3. **Event** emitted only when threshold met:
+ - condition: `abs(brand_score_after - brand_score_before) >= 5`
+
+### Error handling expectations
+- If sync fails → do not recompute.
+- If recompute fails → do not partially write; record failure on the job.
+- If no previous score exists → write current + history. Event emission rule should be explicit (see Decisions).
+
+---
+
+## Decisions to lock (before coding)
+
+1. **Engine selection**
+ - Confirm whether `app/engine/brand_score_engine.py` or `app/engine/brand_score_v2_engine.py` is source-of-truth.
+ - Add `engine_version` to history metadata to prevent confusion during the migration period.
+
+2. **First-time score event behavior**
+ - Option A: Do **not** emit threshold event on first compute.
+ - Option B: Emit `brand_score.initialized` as a separate event.
+
+3. **Event delivery mechanism**
+ - If an existing emitter/bus exists (e.g., `app/adk/emitter.py`), reuse it.
+ - If not, implement an **Outbox table** (durable events) and a worker to dispatch them.
+
+---
+
+## Prerequisites / gaps to confirm in the repo
+
+These should be verified before implementation to avoid rework:
+
+1. **Where Brand Score and summaries are stored today**
+ - Migrations suggest existing work (e.g., brand score “summary”, “snapshots”, “metrics history”). Confirm actual tables/columns.
+
+2. **Platform sync lifecycle hook**
+ - Identify the “sync completed successfully” point for LinkedIn.
+ - We need a stable callback/hook to trigger recomputation exactly once per successful sync.
+
+3. **Existing RQx representation**
+ - There are tests around the RQx formula. Confirm whether there’s a persisted “RQx” score model already.
+ - Ensure `rqx_contribution` doesn’t conflict with other RQx computation.
+
+4. **History API shape already used by dashboard**
+ - If the dashboard already expects a trendline format, align the endpoint/DTO to it.
+
+---
+
+## Data model plan
+
+### A) Current state (likely on `social_users`)
+
+Add/confirm:
+- `brand_score` (numeric)
+- `rqx_contribution` (numeric)
+- `brand_score_updated_at` (datetime)
+
+Indexes:
+- `(id)` already
+- optional: `(brand_score_updated_at)` if filtered queries are common
+
+### B) History table (trendline + auditing)
+
+If not already present, add a new table like `brand_score_history`:
+
+- `id` (pk)
+- `social_user_id` (fk)
+- `platform` (string)
+- `brand_score_before` (numeric, nullable)
+- `brand_score_after` (numeric, not null)
+- `rqx_before` (numeric, nullable)
+- `rqx_after` (numeric, not null)
+- `delta` (numeric, not null)
+- `sync_job_id` (string/uuid, nullable)
+- `engine_version` (string)
+- `metadata` (json)
+- `created_at` (datetime)
+
+Indexes:
+- `(social_user_id, created_at desc)`
+- `(platform, created_at desc)` (optional)
+
+Note: If an existing “snapshots/history” table already exists, extend it rather than duplicating.
+
+---
+
+## Service boundary (single place to do it right)
+
+Create/extend a service method:
+
+`BrandScoreService.recalculate_and_persist(social_user_id, platform, sync_context) -> RecalcResult`
+
+Responsibilities:
+1. Load current user and previous score.
+2. Compute new `brand_score` via engine.
+3. Compute `rqx_contribution = brand_score * 0.4`.
+4. Persist updates:
+ - update current fields on user row
+ - append history row
+5. Event threshold logic:
+ - if previous exists and `abs(delta) >= 5` → emit event
+
+Why this matters:
+- Keeps sync jobs thin.
+- Prevents duplicated threshold logic across code paths.
+
+---
+
+## Wiring: recompute after every platform sync
+
+### Where to hook
+- Identify the LinkedIn sync job/task entrypoint (likely under `app/jobs/` or `app/services/`).
+
+### When to hook
+- **After** all sync writes are committed (so the score uses fresh data).
+- Prefer same DB session/transaction boundaries when reasonable.
+
+### Backfill / catch-up
+- Add a safe admin-only/manual job to recompute for all users (optional, but useful after schema change).
+
+---
+
+## Event design
+
+### Event name
+- `brand_score.updated` (threshold-triggered)
+- optional: `brand_score.initialized`
+
+### Payload (PRD-required)
+- `social_user_id`
+- `platform`
+- `brand_score_before`
+- `brand_score_after`
+- `brand_score_delta`
+- `rqx_before`
+- `rqx_after`
+- `computed_at`
+- `sync_job_id` (if present)
+- `engine_version`
+- `metadata` (freeform)
+
+### Delivery
+- If existing emitter exists: publish immediately.
+- If not: write to durable outbox and dispatch asynchronously.
+
+---
+
+## API changes: trendline exposed for dashboard
+
+### Endpoint (example)
+- `GET /v1/social-users/{id}/brand-score/history?days=30`
+
+### Response shape (example)
+- `current`: `{ brand_score, rqx_contribution, updated_at }`
+- `trendline`: array of `{ date, brand_score, rqx_contribution }`
+
+Implementation notes:
+- Ensure efficient paging/limit.
+- Default window (e.g., 30 or 90 days).
+
+---
+
+## Tests (minimum set)
+
+1. **Unit**: computes `rqx_contribution = brand_score * 0.4`
+2. **Unit**: emits event only when `abs(delta) >= 5`
+3. **Unit**: first-time compute behavior (explicit rule)
+4. **Integration-ish**: “sync completed” triggers recalculation call
+5. **API**: history endpoint returns ordered trendline
+
+---
+
+## Step-by-step execution plan
+
+1. **Recon** (fast repo check)
+ - Confirm existing tables/migrations for brand score history/snapshots.
+ - Identify sync pipeline completion point.
+ - Identify current event/emitter infra.
+
+2. **Schema**
+ - Add missing columns/tables for `rqx_contribution` + history fields.
+ - Add indexes.
+
+3. **Service**
+ - Implement `recalculate_and_persist`.
+ - Add tests.
+
+4. **Sync wiring**
+ - Call service after LinkedIn sync success.
+ - Add a test around the hook.
+
+5. **Events**
+ - Implement emission (or outbox write).
+ - Test threshold behavior.
+
+6. **API**
+ - Add/extend endpoint for trendline.
+ - Add tests.
+
+7. **Backfill (optional but recommended)**
+ - Add a job/CLI path to compute and write missing `rqx_contribution` + history.
+
+---
+
+## Acceptance criteria
+
+- On every successful LinkedIn sync, Brand Score recomputes and persists.
+- `rqx_contribution` is always consistent with `brand_score * 0.4`.
+- History shows a trendline (at least daily points or per-sync points).
+- When Brand Score changes by **≥ 5**, an event is emitted with complete before/after + metadata.
+- Unit tests cover formula + threshold + first-time behavior.
diff --git a/social_branding/plan-linkedin-profile-rewrite-variants.md b/social_branding/plan-linkedin-profile-rewrite-variants.md
new file mode 100644
index 0000000..b90e1a4
--- /dev/null
+++ b/social_branding/plan-linkedin-profile-rewrite-variants.md
@@ -0,0 +1,340 @@
+# Implementation Plan: LinkedIn Profile Rewrite Variants + User Selection (Draft-only)
+
+Date: 2026-03-27
+Source: `docs/PRD.md` → “5.1 LinkedIn → Profile Rewrite” + `docs/prd-additions.md` item (3)
+Scope: **Generate → Approve (select)** only. **No posting**. **No LinkedIn write-back**.
+
+---
+
+## Goals (what we’re shipping)
+
+Implement a draft-only workflow that:
+
+1. Generates rewrite options for a user’s LinkedIn profile.
+2. Returns them via API for review.
+3. Lets the user select/approve one option per section.
+4. Persists both the generated variants and the user’s selection for dashboard/UI use.
+
+PRD-required deliverables:
+
+- Headline: **3 variants**
+- About section: optimized version(s)
+- Experience bullet points: per role
+- Skills list: mapped to **Q-Score signals** + **target JD keywords**
+
+---
+
+## Non-goals / explicit exclusions
+
+- No automated posting.
+- No executing edits on LinkedIn.
+- No new platform support (LinkedIn-first only).
+
+---
+
+## Existing repo capabilities we will reuse
+
+### AI generation primitives (already present)
+
+The repo already includes AI adapter functions in `app/adapters/ai_service.py`:
+
+- `improve_headline(profile_data, current_headline, context)`
+- `improve_summary(profile_data, current_summary, context)`
+- `improve_experience(profile_data, experience_entry, context)`
+- `suggest_skills(profile_data, context)`
+
+These are thin wrappers over `BrandingIntelligenceEngine` and should be reused to avoid duplicating prompt logic.
+
+### LinkedIn profile persistence (already present)
+
+`app/services/brand_score_recalc_service.py` demonstrates that a user has persisted LinkedIn profiles via `user.linkedin_profiles` and that a “latest profile” can be selected using `last_synced_at`.
+
+### Approval workflow patterns (already present)
+
+There’s a state-machine style approval flow in `app/use_cases/approval_workflow.py` (currently for content drafts). We’ll mirror the same ergonomics for rewrite drafts (approve/reject), but with rewrite-specific statuses.
+
+---
+
+## Proposed domain contract (inputs/outputs)
+
+### Inputs (Generate)
+
+- `social_user_id` (derived from auth)
+- `platform` = `linkedin`
+- `target_role`: string (e.g., “Senior Product Manager”)
+- `target_jd_keywords`: list[string] (0..N)
+- Optional: `context` string (free-form notes like “targeting fintech”, “prefer concise voice”)
+
+### Output (Draft)
+
+A persisted “rewrite draft” with generated variants and stable IDs so frontends can select precisely.
+
+Recommended structure (API DTO / Pydantic schema):
+
+- `id` (uuid)
+- `user_id`
+- `platform`
+- `source_linkedin_profile_id` (the snapshot/profile record used)
+- `inputs`: `{ target_role, target_jd_keywords, context }`
+- `generated`:
+ - `headline_variants`: **3** items
+ - `about_variants`: 1–2 items (recommend 2 for user choice)
+ - `experience_variants`: per role, list of bullet options
+ - `skills_suggestions`: ranked list with provenance tags
+- `selection` (nullable until approved)
+- `status`: `draft | approved | rejected | superseded`
+- `created_at`, `updated_at`
+
+---
+
+## Data model & migrations
+
+### Option A (recommended): JSON-first, minimal tables
+
+Add a new table, e.g. `linkedin_profile_rewrites`:
+
+- `id` UUID PK
+- `user_id` FK (or clerk id; follow existing account conventions)
+- `platform` string (`linkedin`)
+- `source_linkedin_profile_id` FK (or just store the profile UUID)
+- `inputs_json` JSONB
+- `generated_json` JSONB
+- `selection_json` JSONB nullable
+- `status` enum/string
+- `created_at` / `updated_at`
+
+Pros: fastest to ship; easy to evolve.
+
+### Option B: normalized variants tables
+
+Add separate tables for variants and selections. Pros: easier analytics/search. Cons: more work now.
+
+**Decision:** Start with Option A unless we have an immediate need to query variants independently.
+
+### Migration tasks
+
+- Create Alembic revision adding the new table and any needed enums.
+- Indexes:
+ - `(user_id, created_at desc)`
+ - `(user_id, status)`
+
+---
+
+## Generation service design
+
+Add a new service, e.g. `app/services/linkedin_profile_rewrite_service.py`.
+
+### Responsibilities
+
+1. Load the **latest** connected LinkedIn profile for the user (same selection logic as BrandScore recalc).
+2. Build `profile_data` dict in the same shape used by AI functions.
+3. Generate variants:
+
+#### Headline: 3 variants
+
+Implementation approach:
+
+- Use `ai_service.improve_headline` three times with different context “styles” to force diversity:
+ 1) Recruiter/keyword-forward
+ 2) Achievement/value-prop
+ 3) Persona/voice-forward
+
+Additionally, enforce:
+
+- Char limit validation (keep within a safe LinkedIn headline cap)
+- Deduplication (variants must be meaningfully different)
+
+#### About: optimized version(s)
+
+- Use `ai_service.improve_summary` to produce 2 variants (recommended).
+- Enforce max length.
+
+#### Experience bullets: per role
+
+- For each experience entry, call `ai_service.improve_experience` with:
+ - target role
+ - keywords
+ - “prefer metrics and outcomes”
+
+Store results per role.
+
+#### Skills: mapped to Q-Scores + JD keywords
+
+- Use `ai_service.suggest_skills` with context containing:
+ - target role
+ - JD keywords
+ - any available Q-score signals (see prerequisites below)
+
+Then post-process:
+
+- Normalize (title case / trim)
+- Deduplicate
+- Tag provenance for each skill: `jd | qscore | both | ai`
+
+### Explainability (“objective signals”)
+
+While PRD item (3) doesn’t explicitly demand explanations, it helps UX and aligns with later recruiter visibility features.
+
+For each variant include:
+
+- `keywords_used`: list[string]
+- `rationale`: short string
+
+---
+
+## API endpoints
+
+Add routes under `app/api/v1/` (exact module placement should match existing routing conventions).
+
+### 1) Generate
+
+`POST /v1/linkedin/profile-rewrite/generate`
+
+Body:
+
+- `target_role`
+- `target_jd_keywords`
+- optional `context`
+
+Response: rewrite draft DTO.
+
+### 2) Fetch by id
+
+`GET /v1/linkedin/profile-rewrite/{rewrite_id}`
+
+Response: rewrite draft DTO.
+
+### 3) Approve / select
+
+`POST /v1/linkedin/profile-rewrite/{rewrite_id}/approve`
+
+Body (selection contract):
+
+- `headline_variant_index` or `headline_variant_id`
+- `about_variant_index` or `about_variant_id`
+- `experience_selection`: per role key, chosen bullets (either “accept all” or per-bullet indices)
+- `skills_final`: final list of skills the user wants
+
+Response: updated rewrite DTO with `status=approved` and non-null `selection`.
+
+### 4) Reject (optional but recommended)
+
+`POST /v1/linkedin/profile-rewrite/{rewrite_id}/reject`
+
+Body: optional feedback.
+
+---
+
+## State machine & lifecycle
+
+Suggested statuses:
+
+- `draft`: generated, awaiting decision
+- `approved`: selection persisted
+- `rejected`: user rejected (optional feedback)
+- `superseded`: a newer draft was generated; keep old one for audit
+
+Rules:
+
+- Approve only allowed from `draft`.
+- Reject only allowed from `draft`.
+- Generating a new draft can mark older `draft` rows as `superseded` (optional, but recommended).
+
+---
+
+## Prerequisites / missing pieces to confirm before implementing
+
+These are required to meet PRD item (3) fully and cleanly:
+
+1) **Target role + JD keywords source**
+- We need a stable way to supply `target_role` and `target_jd_keywords`.
+- If not already stored in DB, we’ll require the frontend/client to pass them in the `generate` request.
+
+2) **Q-Score signals beyond a single number**
+- “Skills list mapped to Q-Scores” implies we can access either:
+ - a Q-score category breakdown, or
+ - a list of validated skill signals.
+- If current Q-score integration only returns an aggregate score, we should define a short-term mapping strategy:
+ - Treat JD keywords as first-class and tag them as `jd`
+ - Tag AI-suggested skills as `ai`
+ - Add `qscore` provenance only when breakdown is available
+
+3) **Stable LinkedIn profile snapshot identifier**
+- We can already pick the latest `linkedin_profiles` record.
+- We must ensure we can store a stable `source_linkedin_profile_id` (UUID) and that it’s available in the model.
+
+4) **AI engine supports deterministic structured outputs**
+- Current AI functions return `dict`. We’ll need to validate:
+ - headline output includes a `headline` string (or similar)
+ - summary output includes `summary`
+ - experience output includes bullet list
+ - skills output includes list
+- If current outputs are not structured enough, we’ll add a thin normalization layer in the rewrite service.
+
+---
+
+## Testing plan
+
+Add tests in `tests/` that cover:
+
+1) **Variant counts & structure**
+- Generate returns exactly **3** headline variants.
+- About returns at least 1 variant (prefer 2).
+- Experience returns entries for each role.
+
+2) **Approval persistence**
+- Approve endpoint updates status to `approved`.
+- Selection is persisted and returned.
+
+3) **Ownership / auth**
+- Users can’t approve/fetch drafts they don’t own.
+
+4) **Idempotency & superseding**
+- Generating multiple drafts for the same user creates multiple rows.
+- (If implemented) older drafts become `superseded`.
+
+---
+
+## Rollout notes
+
+- Keep endpoints feature-flagged if you already have feature flag patterns.
+- Log generation/approval events without leaking secrets.
+
+---
+
+## Acceptance criteria
+
+1) **Generate**
+- Given a user with a connected LinkedIn profile, calling `POST /v1/linkedin/profile-rewrite/generate` returns a persisted draft containing:
+ - Headline variants: **exactly 3**
+ - About variants: **>= 1**
+ - Experience rewrites: per experience role in the source profile
+ - Skills suggestions: list includes JD keywords when provided
+
+2) **Approve (user selection)**
+- Calling `POST /v1/linkedin/profile-rewrite/{id}/approve` persists the selection and changes status to `approved`.
+- Approved draft is retrievable via `GET /v1/linkedin/profile-rewrite/{id}` with `selection` populated.
+
+3) **Draft-only**
+- No endpoint performs posting or any platform write-back.
+- No code path attempts to modify LinkedIn.
+
+4) **Security/ownership**
+- Users cannot access or approve drafts they don’t own.
+
+5) **Regression safety**
+- Existing content approval workflow is unaffected.
+- Existing Brand Score recalculation remains unaffected.
+
+---
+
+## Final implementation checklist
+
+- [ ] Confirm where/how `target_role` and `target_jd_keywords` will be sourced (request-only vs persisted profile settings).
+- [ ] Confirm Q-score breakdown availability; decide interim provenance strategy if breakdown is missing.
+- [ ] Add DB model(s) + Alembic migration for rewrite drafts.
+- [ ] Add Pydantic schemas for request/response.
+- [ ] Implement `linkedin_profile_rewrite_service` using `app/adapters/ai_service.py` primitives.
+- [ ] Add API routes: generate, get by id, approve (and optional reject).
+- [ ] Add tests for generation counts, approval persistence, ownership.
+- [ ] Run unit tests and ensure green.
diff --git a/social_branding/plan-migrate-brand-score-v1-to-v2.md b/social_branding/plan-migrate-brand-score-v1-to-v2.md
new file mode 100644
index 0000000..810bbd5
--- /dev/null
+++ b/social_branding/plan-migrate-brand-score-v1-to-v2.md
@@ -0,0 +1,184 @@
+# Execution playbook — migrate Brand Score v1 → v2 (component model)
+
+Date: 2026-03-27
+Scope: replace audit-derived Brand Score v1 with PRD component-model Brand Score v2.
+
+This doc is the **step-by-step execution order** for completing the migration, plus a **final verification checklist** to confirm nothing still depends on v1.
+
+---
+
+## What we’re migrating (quick references)
+
+### v1 (legacy)
+
+- **Engine:** `app/engine/brand_score_engine.py`
+ - Function: `compute(audit, extra_profile_data)`
+ - Output: `BrandScoreResult` with `brand_score`, `grade`, `strengths`, `quick_wins`
+
+### v2 (target)
+
+- **Engine:** `app/engine/brand_score_v2_engine.py`
+ - Function: `compute_v2(inputs, ...)`
+ - Output: `BrandScoreV2Result` with `brand_score_total`, `components[]`, `scoring_version`, `window_*`
+- **Persistence wrapper (canonical path):** `app/services/brand_score_service.py::compute_and_persist_v2()`
+ - Writes:
+ - Snapshot row (`brand_score_snapshots`)
+ - Cache (`social_users.brand_score_summary` + `social_users.brand_score_latest_calculated_at`)
+
+### Known v1 call sites to remove
+
+- `app/use_cases/run_profile_analysis.py`
+ - Imports and calls v1 compute: `from app.engine.brand_score_engine import compute as compute_brand_score`
+ - Writes legacy cache keys: `{"brand_score": ..., "brand_grade": ...}`
+- `app/use_cases/recalculate_brand_score.py`
+ - Imports and calls v1 compute
+ - Writes legacy cache keys
+- `app/use_cases/get_analysis_view.py`
+ - References `BrandScoreEngine` (verify if legacy/unused and migrate/remove)
+
+### Confirmed v1 usage map (what actually hits prod today)
+
+This section is here so we can migrate with confidence and not miss a real runtime path.
+
+#### Production (API)
+
+- `POST /api/v1/analysis/profile/{profile_id}`
+ - Route: `app/api/v1/analysis.py::run_profile_analysis`
+ - Use-case: `app/use_cases/run_profile_analysis.py::execute`
+ - v1 call: inside `execute()`
+ - `from app.engine.brand_score_engine import compute as compute_brand_score`
+ - `brand = compute_brand_score(audit, profile_data)`
+
+#### Production (worker job)
+
+- Job type: `recalculate_brand_score`
+ - Dispatcher: `app/jobs/dispatcher.py::_handle_recalculate_brand_score`
+ - Use-case: `app/use_cases/recalculate_brand_score.py::execute`
+ - v1 call: `brand = compute_brand_score(audit, profile_data)`
+
+#### Non-production (tests/docs)
+
+- Tests: `tests/test_engine.py`
+ - Imports v1 compute and asserts legacy outputs.
+ - Must be migrated/removed before deleting v1.
+- Docs: multiple references (this plan + architecture docs)
+ - No runtime impact, but keep in sync with the final migration state.
+
+---
+
+## Execution order ✅
+
+### 0) Pre-flight (don’t change behavior yet)
+
+- [ ] Confirm DB migrations are present and applied in dev:
+ - [ ] `brand_score_snapshots`
+ - [ ] `social_metrics_snapshots`
+ - [ ] `social_users.brand_score_latest_calculated_at`
+- [ ] Confirm v2 endpoints work without v1:
+ - [ ] `GET /brand-score/latest`
+ - [ ] `GET /brand-score/trend`
+
+### 1) Introduce a migration flag (safe rollout)
+
+- [ ] Add a settings/env flag (example name): `BRAND_SCORE_VERSION=v2|v1`
+ - [ ] Default should be **v2**.
+ - [ ] Keep `v1` only as a temporary fallback.
+
+### 2) Stop writing the legacy v1 cache shape (make v2 the source of truth)
+
+Target: only v2 writes the **canonical** cache and snapshot.
+
+- [ ] Update `app/use_cases/run_profile_analysis.py`
+ - [ ] Remove/avoid calling `app.engine.brand_score_engine.compute()`
+ - [ ] Ensure it calls **only** `compute_and_persist_v2()` when the flag is v2
+ - [ ] Ensure `social_users.brand_score_summary` is not overwritten with legacy keys after v2 runs
+
+- [ ] Update `app/use_cases/recalculate_brand_score.py`
+ - [ ] Remove/avoid calling v1 compute
+ - [ ] Return brand score value from v2 total (`brand_score_total`) for any callers expecting a number
+ - [ ] Ensure it doesn’t overwrite the v2 cache shape
+
+- [ ] Update/verify `app/use_cases/get_analysis_view.py`
+ - [ ] If it still reads v1 fields (`brand_score`, `grade`), migrate it to read v2 cache
+ - [ ] If it constructs or uses a separate BrandScoreEngine abstraction, collapse it onto v2
+
+### 3) Update eventing/delta logic to compare v2 totals
+
+If you emit `brand_score.delta` events anywhere:
+
+- [ ] Change “before/after” comparison to use:
+ - `brand_score_total` (v2) from `social_users.brand_score_summary`
+- [ ] Keep the same delta threshold (>= 5) unless PRD says otherwise
+- [ ] Ensure the computed `rqx_contribution` continues to be derived from the total (v2 total)
+
+### 4) Ensure metrics snapshots are captured (audience growth + trend stability)
+
+- [ ] Verify the capture points write `social_metrics_snapshots` after successful sync/import:
+ - [ ] `app/use_cases/sync_profile.py`
+ - [ ] `app/use_cases/import_profile.py`
+- [ ] Ensure the “at most 1/day per user+platform” behavior remains (via `MetricsRepo.upsert_daily_snapshot()`)
+
+### 5) Backfill (optional but recommended)
+
+- [ ] Create a one-off job/script to backfill:
+ - [ ] `social_metrics_snapshots` (if missing)
+ - [ ] `brand_score_snapshots` for last N days (or at least one snapshot per user)
+- [ ] Confirm `GET /brand-score/trend` returns non-empty results for existing users
+
+### 6) Remove v1 usage (+ cleanup)
+
+- [ ] Remove imports/usages of v1 engine from all use-cases
+- [ ] Remove “legacy” writes to `social_users.brand_score_summary` keys:
+ - `brand_score`, `brand_grade`
+- [ ] Keep `GET /brand-score/latest` backward-compatible temporarily (it already supports both shapes)
+- [ ] After a confidence window:
+ - [ ] Delete or archive `app/engine/brand_score_engine.py`
+ - [ ] Remove v1 compatibility branch from `app/use_cases/get_brand_score_latest.py`
+
+### 7) Verify wiring is clean (routes + worker)
+
+These are the two *runtime* paths that must be free of v1 imports before you can claim the migration is complete.
+
+- [ ] API path no longer imports v1:
+ - [ ] `app/use_cases/run_profile_analysis.py` has no `brand_score_engine` import
+ - [ ] `POST /api/v1/analysis/profile/{profile_id}` still succeeds and returns expected payload
+- [ ] Worker path no longer imports v1:
+ - [ ] `app/use_cases/recalculate_brand_score.py` has no `brand_score_engine` import
+ - [ ] `JobType.RECALCULATE_BRAND_SCORE` job still succeeds and updates v2 snapshot + cache
+
+---
+
+## Final verification checklist (done = migration complete)
+
+### Codebase checks
+
+- [ ] No remaining imports of v1 engine:
+ - [ ] `from app.engine.brand_score_engine import ...` is gone
+ - [ ] No references to `BrandScoreEngine` remain unless it’s v2-only
+- [ ] `social_users.brand_score_summary` is written in **exactly one place**:
+ - [ ] `app/services/brand_score_service.py::compute_and_persist_v2()`
+- [ ] No code overwrites `brand_score_summary` with legacy keys after v2 runs
+
+### Data shape checks (runtime)
+
+- [ ] `GET /brand-score/latest` returns:
+ - [ ] `brand_score_total`
+ - [ ] `components[]` (6 keys)
+ - [ ] `scoring_version`
+ - [ ] `window`
+- [ ] `GET /brand-score/trend` returns daily points from `brand_score_snapshots`
+- [ ] New sync/import actions write `social_metrics_snapshots` for the user
+
+### Scoring behavior checks
+
+- [ ] Renormalization is stable when a component lacks data:
+ - [ ] missing components are marked `insufficient_data=true`
+ - [ ] total score remains in 0–100 and doesn’t crash
+
+### Test coverage checks
+
+- [ ] Unit tests cover v2 engine (already present)
+- [ ] Add/green: persistence + cache update tests:
+ - [ ] snapshot row created
+ - [ ] cache updated in v2 shape
+- [ ] Add/green: delta/eventing compares v2 totals
diff --git a/social_branding/plan-prd-implementation-audit.md b/social_branding/plan-prd-implementation-audit.md
new file mode 100644
index 0000000..4cba10c
--- /dev/null
+++ b/social_branding/plan-prd-implementation-audit.md
@@ -0,0 +1,1175 @@
+# Social Branding Service Audit
+
+Date: 2026-03-23
+
+## Purpose
+
+This document compares:
+
+1. the product BRD / PRD in [`docs/PRD.md`](./PRD.md)
+2. the narrowed execution plan in [`docs/plan.md`](./plan.md)
+3. the current implementation in `app/` and `tests/`
+
+It is intended as a handoff and presentation document so another engineer or stakeholder can answer:
+
+- what was planned
+- what was actually built
+- which decisions were taken to narrow scope
+- which assumptions phase one was built on
+- what is still missing versus the plan
+- what is still missing versus the PRD
+- what architecture should be used going forward
+
+Auth is intentionally excluded from blocker status for this review. Future auth is assumed to be Clerk-issued JWT at the service boundary.
+
+## Executive Summary
+
+The current repo is best understood as a narrowed, LinkedIn-first individual-user MVP that is substantially aligned with the overnight plan, but not aligned with the full PRD.
+
+The implementation does support the plan's core demo loop:
+
+1. import a LinkedIn profile snapshot
+2. compute a LinkedIn audit and Brand Score v1
+3. infer or select a persona strategy
+4. generate a 2-week content calendar with an 80/20 split
+5. generate LinkedIn drafts
+6. move drafts through approval, rejection, regeneration, and manual publish confirmation
+7. expose dashboard and local event history
+
+That flow is implemented and tested. `uv run pytest` passed with `4 passed, 1 warning` on 2026-03-23.
+
+However, the repo is not PRD-complete. The PRD describes a broader multi-platform, more automated system with richer scoring, profile rewrites, live collection, scheduled posting, analytics, engagement automation, and enterprise workflows. Those are not implemented here.
+
+The biggest architectural mismatch with the desired next version is this:
+
+- the code already has some engine-like pure logic
+- but the engine is not yet separated as an explicit domain package or service boundary
+- orchestration, persistence, and business logic are still mixed inside one application service
+- surfaces are currently HTTP-only in practice
+- Redis and the worker exist as scaffolding, not as an active runtime path
+
+## Canonical Scope Hierarchy
+
+The repo currently has three levels of scope, and they should not be confused during presentation.
+
+### 1. PRD scope
+
+The PRD is the broad product target:
+
+- individual plus enterprise
+- LinkedIn, Instagram, X, YouTube
+- automated connect -> collect -> analyze -> generate -> approve -> post -> track loop
+- Brand Score feeding RQx
+- richer content and analytics behavior
+
+Relevant references:
+
+- `docs/PRD.md:21-36`
+- `docs/PRD.md:42-70`
+- `docs/PRD.md:80-102`
+- `docs/PRD.md:183-248`
+- `docs/PRD.md:360-397`
+
+### 2. Plan scope
+
+The plan is the locked overnight MVP and is the real governing doc for what this repo was trying to ship immediately:
+
+- individual only
+- LinkedIn only
+- manual import fallback instead of hard OAuth
+- Brand Score v1 from available LinkedIn data
+- content calendar, drafts, approval queue, manual publish confirmation
+- dashboard and local events
+- enterprise and multi-platform behavior deferred
+
+Relevant references:
+
+- `docs/plan.md:9-38`
+- `docs/plan.md:78-128`
+- `docs/plan.md:149-158`
+
+### 3. Current implementation scope
+
+The code matches the narrowed plan much more closely than it matches the PRD. It is therefore more accurate to describe the current service as:
+
+"A request-driven, LinkedIn-first social branding MVP for individual users with manual ingestion, simplified scoring, deterministic content generation, approval workflow, dashboard summaries, and local event persistence."
+
+That description is also how the README frames it:
+
+- `README.md:3-23`
+- `README.md:81-85`
+
+## Current Architecture Assessment
+
+## What exists today
+
+The current architecture is:
+
+- HTTP API surface in `app/api/v1/`
+- one application service in `app/services/social_branding.py`
+- several pure or mostly pure helper modules in:
+ - `app/services/brand_score.py`
+ - `app/services/persona_strategy.py`
+ - `app/services/content_calendar.py`
+- persistence in SQLAlchemy models in `app/models.py`
+- queue abstraction in `app/services/queue.py`
+- a worker loop in `app/worker/main.py`
+
+This is a valid MVP architecture, but it is not yet the target split you described.
+
+## Desired target architecture
+
+For the next version, the clean split should be:
+
+### 1. Social branding engine
+
+A pure, platform-agnostic decision engine that takes normalized inputs and produces outputs such as:
+
+- audits
+- scores
+- persona strategy decisions
+- calendar plans
+- draft suggestions
+- recommendation bundles
+
+This layer should not know about:
+
+- FastAPI
+- SQLAlchemy sessions
+- Clerk JWTs
+- Redis
+- Postgres
+- HTTP request shapes
+
+### 2. Social branding service layer
+
+An orchestration layer that:
+
+- receives authenticated user context
+- loads and stores data
+- calls the engine
+- persists outputs
+- emits events
+- coordinates approval and posting workflows
+- exposes use cases to surfaces
+
+### 3. Surfaces
+
+Adapters on top of the service layer, for example:
+
+- HTTP API
+- background worker consumers
+- Redis/event consumers
+- internal command handlers
+- future admin or operator surfaces
+
+### 4. External adapters
+
+Per-platform collectors and posters:
+
+- LinkedIn import adapter
+- Instagram connector
+- X connector
+- YouTube connector
+- GitHub connector (signals + content source)
+- manual upload/import adapter
+
+See also: `docs/external-adapters-plan.md` for the platform-compliance contract and phased implementation plan.
+
+### 5. Infrastructure
+
+- Postgres
+- Redis
+- storage
+- auth verification
+- observability
+
+## How close the current code is to that shape
+
+Partially aligned:
+
+- `app/services/brand_score.py` already looks like engine logic.
+- `app/services/persona_strategy.py` already looks like engine logic.
+- `app/services/content_calendar.py` already looks like engine logic.
+
+Not yet aligned:
+
+- `app/services/social_branding.py` combines orchestration, persistence, workflow rules, and business decisions in one class.
+- there is no explicit normalized engine contract
+- there is no repository layer
+- there are no platform adapter interfaces
+- surfaces are API routes only in practical use
+
+Conclusion:
+
+The repo contains the beginnings of an engine, but the engine is still embedded inside the service implementation rather than clearly separated.
+
+## What Was Implemented
+
+## Data model and persistence
+
+The main persistence model is present and broadly follows the plan:
+
+- `social_accounts`
+- `social_profile_snapshots`
+- `brand_scores`
+- `persona_strategies`
+- `content_calendar_items`
+- `content_drafts`
+- `approval_queue`
+- `posting_records`
+- `analytics_snapshots`
+- `engagement_drafts`
+- `integration_events`
+
+Reference:
+
+- `app/models.py:58-235`
+
+Observations:
+
+- The model names mostly match the plan's domain model.
+- `posting_records` and `integration_events` were added beyond the explicit plan list and are useful.
+- `engagement_drafts` exists in schema only and is not actively used in the service flow.
+- Everything is stored through `create_all()` on startup; there is no migration system yet.
+
+## API surface
+
+The HTTP routes listed in the README and plan are implemented:
+
+- LinkedIn import
+- persona select
+- brand score recalculate
+- content calendar generate/list
+- drafts generate
+- approval approve/reject/regenerate
+- publish confirm
+- dashboard
+- events
+- demo seed
+- health
+
+References:
+
+- `README.md:25-39`
+- `app/api/v1/__init__.py`
+- `app/api/v1/accounts.py`
+- `app/api/v1/brand_score.py`
+- `app/api/v1/content.py`
+- `app/api/v1/dashboard.py`
+- `app/api/v1/events.py`
+- `app/api/v1/demo.py`
+- `app/api/v1/health.py`
+- `app/api/v1/persona.py`
+
+## LinkedIn ingest and audit
+
+Implemented:
+
+- manual LinkedIn import payload
+- account upsert
+- profile snapshot persistence
+- section-level audit scoring
+- recommendation list persistence
+
+References:
+
+- `app/services/social_branding.py:190-239`
+- `app/services/brand_score.py:37-88`
+
+What it actually does:
+
+- scores headline, about, experience, skills, recommendations, featured, and activity
+- persists overall score and recommendations
+- uses simple heuristic thresholds, not benchmarked analysis
+
+## Brand Score v1
+
+Implemented:
+
+- Brand Score computation on import
+- manual recalculation endpoint
+- score history persistence
+- event emission when score changes materially or when forced
+
+References:
+
+- `app/services/social_branding.py:134-188`
+- `app/services/social_branding.py:241-274`
+- `app/services/brand_score.py:91-142`
+
+What it actually does:
+
+- computes five components:
+ - profile completeness
+ - content consistency
+ - engagement quality
+ - visibility
+ - audience growth
+- uses LinkedIn metrics only
+- stores local integration events in the service database
+
+## Persona strategy
+
+Implemented:
+
+- six persona enums
+- heuristic persona inference from pathway context
+- manual persona override
+- cadence, tone, target role, and source context persistence
+
+References:
+
+- `app/models.py:35-41`
+- `app/services/persona_strategy.py:8-127`
+- `app/services/social_branding.py:67-96`
+
+What it actually does:
+
+- infers persona from role and goals
+- always assigns LinkedIn as the active platform
+- stores one active strategy at a time per user
+
+## Content calendar and drafts
+
+Implemented:
+
+- 2-week calendar generation
+- 80/20 toolkit versus dynamic split
+- deterministic topic sequencing
+- LinkedIn draft generation
+
+References:
+
+- `app/services/social_branding.py:276-322`
+- `app/services/content_calendar.py:26-84`
+- `app/services/social_branding.py:360-459`
+- `app/services/content_calendar.py:97-144`
+
+What it actually does:
+
+- uses persona cadence to create slots over 14 days
+- marks some slots as dynamic using deterministic spacing
+- chooses from a fixed toolkit topic list per persona
+- generates simple template-based LinkedIn drafts
+
+## Approval and publish flow
+
+Implemented:
+
+- queue item creation per draft
+- approve
+- reject
+- regenerate
+- posting state transitions
+- manual publish confirmation
+- local approval event emission
+
+References:
+
+- `app/services/social_branding.py:333-359`
+- `app/services/social_branding.py:360-418`
+- `app/services/social_branding.py:486-620`
+
+What it actually does:
+
+- every draft becomes an approval item and posting record
+- approving immediately transitions the posting record to `ready_for_manual_publish`
+- publish is confirmed manually by user-supplied external reference
+
+## Dashboard and events
+
+Implemented:
+
+- latest brand score and recent trend
+- queue summary
+- posting state summary
+- latest analytics snapshot view
+- local event listing
+
+References:
+
+- `app/services/social_branding.py:622-705`
+- `app/services/social_branding.py:707-722`
+
+## Worker and queue
+
+Implemented in scaffold form:
+
+- queue backend abstraction
+- database no-op backend
+- Redis backend
+- worker loop
+
+References:
+
+- `app/services/queue.py:1-83`
+- `app/worker/main.py:14-36`
+- `README.md:83-85`
+
+Important reality:
+
+- the current product flow is request-driven
+- the worker does not execute domain jobs
+- the Redis queue is infrastructure-ready, not feature-ready
+
+## Test coverage
+
+Implemented:
+
+- health check
+- happy path full MVP flow
+- limited-data import path
+- regenerate path state behavior
+
+Reference:
+
+- `tests/test_social_branding_flow.py:32-207`
+
+Observed verification:
+
+- command run: `uv run pytest`
+- result: `4 passed, 1 warning`
+
+## Phase-One Foundations: Decisions and Assumptions
+
+The user asked specifically for the assumptions and decisions behind the current phase-one implementation. Those are below.
+
+## Decision 1: Narrow to individual plus LinkedIn only
+
+Why:
+
+- the PRD is much broader than can be implemented quickly
+- LinkedIn is the primary value surface in the PRD and plan
+- multi-platform plus enterprise would have blocked delivery
+
+Where it shows up:
+
+- `docs/plan.md:11-30`
+- `README.md:10-23`
+- `app/services/persona_strategy.py:124`
+- `app/services/social_branding.py:201-206`
+- `app/services/social_branding.py:313`
+
+Assumption:
+
+- proving one strong individual LinkedIn flow is more valuable than partial support across four platforms
+
+## Decision 2: Use manual import instead of OAuth-first collection
+
+Why:
+
+- the PRD explicitly leaves data collection method to engineering
+- LinkedIn collection is the riskiest integration area
+- the overnight plan avoids blocking on OAuth and unstable APIs
+
+Where it shows up:
+
+- `docs/PRD.md:36`
+- `docs/PRD.md:240-248`
+- `docs/plan.md:13`
+- `docs/plan.md:35`
+- `app/schemas/social_branding.py:47-52`
+- `app/services/social_branding.py:190-239`
+
+Assumption:
+
+- GrowQR can seed or receive normalized LinkedIn data from a manual process, future adapter, or another service
+
+## Decision 3: Treat Brand Score as a simplified v1
+
+Why:
+
+- the PRD's full seven-component score depends on data that does not exist in the narrowed MVP
+- the plan explicitly says not to block on unavailable cross-platform metrics
+
+Where it shows up:
+
+- `docs/plan.md:36`
+- `app/services/brand_score.py:18-24`
+- `app/services/brand_score.py:91-142`
+
+Assumption:
+
+- a meaningful but incomplete score is acceptable for v1 if it is stable, stored, and trendable
+
+## Decision 4: Use deterministic content generation instead of real AI orchestration
+
+Why:
+
+- the plan prioritizes demonstrating flow and content structure over model sophistication
+- deterministic output is easy to test and explain
+
+Where it shows up:
+
+- `docs/plan.md:38`
+- `app/services/content_calendar.py:26-84`
+- `app/services/content_calendar.py:97-144`
+
+Assumption:
+
+- content templates and placeholders are enough for MVP validation
+
+## Decision 5: Make publish manual-confirmed
+
+Why:
+
+- the plan explicitly allows manual publish confirmation
+- live posting would introduce platform API risk and auth complexity
+
+Where it shows up:
+
+- `docs/plan.md:37`
+- `app/services/social_branding.py:507-508`
+- `app/services/social_branding.py:591-620`
+
+Assumption:
+
+- for v1, it is enough to generate approved content and let the user confirm it was posted manually
+
+## Decision 6: Keep async infrastructure scaffolded but not operationally central
+
+Why:
+
+- Postgres and Redis are useful for future scale and service consistency
+- the immediate flow can be run synchronously
+
+Where it shows up:
+
+- `README.md:75-85`
+- `.env.example`
+- `.env.docker`
+- `app/services/queue.py:1-83`
+- `app/worker/main.py:14-36`
+
+Assumption:
+
+- request-driven synchronous use cases are acceptable for phase one, with queue infrastructure reserved for later work
+
+## Decision 7: Trust caller-provided `user_id`
+
+Why:
+
+- auth is intentionally out of scope
+
+Where it shows up:
+
+- almost every request schema accepts `user_id` directly, for example `app/schemas/social_branding.py:47-52`, `87-91`, `111-115`, `153-157`
+
+Assumption:
+
+- an upstream system or future JWT layer will replace body-supplied identity
+
+## Implementation Status Versus Plan
+
+The plan is mostly implemented, but some items are implemented in a thin MVP form rather than a durable production form.
+
+## Phase 1: Foundations
+
+Plan status: implemented
+
+Evidence:
+
+- social branding models exist in `app/models.py:58-235`
+- persona enums exist in `app/models.py:35-41`
+- brand score component model exists in `app/models.py:89-99`
+- persona topic libraries exist in `app/services/persona_strategy.py:26-63`
+
+Assessment:
+
+- This phase is done for MVP purposes.
+- The main gap is architectural: these foundations are not yet separated into engine/service/adapters.
+
+## Phase 2: Profile ingest and audit
+
+Plan status: implemented, simplified
+
+Evidence:
+
+- import endpoint exists
+- manual payload fallback is the main supported path
+- audit scoring and recommendations are persisted
+- limited-data import test exists
+
+Assessment:
+
+- Done for MVP.
+- Not equivalent to PRD-grade platform analysis.
+
+## Phase 3: Brand Score and persona strategy
+
+Plan status: implemented, simplified
+
+Evidence:
+
+- brand score is computed and stored
+- persona inference and manual selection work
+- score update events are persisted
+
+Assessment:
+
+- Done for MVP.
+- The score model is intentionally reduced from the PRD.
+- Events are local persistence records, not cross-service integration delivery.
+
+## Phase 4: Content calendar and drafts
+
+Plan status: implemented, partially shallow
+
+Evidence:
+
+- 2-week calendar exists
+- 80/20 split exists
+- LinkedIn draft generation exists
+
+Assessment:
+
+- Done for demo and workflow validation.
+- Dynamic triggers are represented as preselected topic types, not event-driven runtime behavior.
+- Drafts are deterministic templates, not model-generated or personalized beyond a few fields.
+
+## Phase 5: Approval and publish flow
+
+Plan status: implemented
+
+Evidence:
+
+- queue, approve, reject, regenerate, publish confirmation, and state transitions all exist
+
+Assessment:
+
+- Strongly implemented for the narrowed MVP.
+- Still single-user only.
+- No scheduling engine or platform posting adapter exists.
+
+## Phase 6: Dashboard and hardening
+
+Plan status: mostly implemented
+
+Evidence:
+
+- dashboard endpoint exists
+- happy-path tests exist
+- deferred scope is documented
+
+Assessment:
+
+- Done for MVP handoff and demo.
+- Not hardening-complete for production.
+- Missing migrations, background jobs, external integrations, auth, observability, and deeper test coverage.
+
+## Implementation Status Versus PRD
+
+This is the most important presentation distinction:
+
+- plan alignment: mostly yes
+- PRD alignment: no, not yet
+
+## PRD items that are fully or mostly covered
+
+### Individual personas exist
+
+- six personas exist in the model
+- persona selection and switching are present
+
+Caveat:
+
+- active platform mix is not implemented beyond LinkedIn
+
+### LinkedIn-first audit and content flow exists
+
+- LinkedIn import
+- audit
+- Brand Score v1
+- calendar
+- approval queue
+- manual publish confirmation
+
+### Brand Score history and dashboard exposure exist
+
+- score history is persisted
+- dashboard returns recent trend
+
+## PRD items that are only partially covered
+
+### Brand Score formula
+
+PRD expectation:
+
+- seven components
+- RQx formula
+- downstream event to Assessment and Pathways services
+
+Current implementation:
+
+- five components only
+- no RQx mapping
+- local event persistence only
+
+References:
+
+- `docs/PRD.md:82-102`
+- `app/services/brand_score.py:18-24`
+- `app/services/social_branding.py:174-188`
+
+### Content model
+
+PRD expectation:
+
+- rich toolkit catalog and multiple dynamic triggers
+- platform-aware formatting and platform mix rules
+
+Current implementation:
+
+- reduced toolkit topics
+- three dynamic topic types
+- LinkedIn-only output
+
+References:
+
+- `docs/PRD.md:141-181`
+- `app/services/persona_strategy.py:26-63`
+- `app/services/content_calendar.py:38-43`
+
+### Analytics
+
+PRD expectation:
+
+- platform analytics per sync cycle
+- richer performance tracking and trend lines
+
+Current implementation:
+
+- only snapshot summaries based on imported metrics
+- no real recurring sync
+- no per-content performance table
+
+References:
+
+- `docs/PRD.md:243-248`
+- `docs/PRD.md:371-381`
+- `app/models.py:198-211`
+- `app/services/social_branding.py:656-696`
+
+## PRD items that are not implemented
+
+### Multi-platform runtime support
+
+Not implemented:
+
+- Instagram runtime collection/generation/posting
+- X runtime collection/generation/posting
+- YouTube analysis/brief generation/posting pipeline
+
+Even though platform enums exist, runtime behavior does not.
+
+References:
+
+- `docs/PRD.md:21-24`
+- `docs/PRD.md:198-235`
+- `app/models.py:28-32`
+
+### OAuth connect and recurring sync
+
+Not implemented:
+
+- platform OAuth flow
+- scheduled sync jobs
+- recurring collection cadence
+- delta-based collector jobs
+
+References:
+
+- `docs/PRD.md:63-70`
+- `docs/PRD.md:243-248`
+- `app/worker/main.py:14-36`
+
+### Profile rewrites and application to platform
+
+Not implemented:
+
+- rewrite generation for headline/about/experience
+- approval flow for profile updates
+- apply-to-platform action
+
+References:
+
+- `docs/PRD.md:190-193`
+- no corresponding route or service use case exists
+
+### Recruiter visibility and keyword gap analysis
+
+Not implemented beyond basic visibility scoring inputs.
+
+Missing:
+
+- target-role benchmark
+- keyword gap detection
+- profile rewrite recommendations based on gaps
+
+### Auto-posting and scheduling
+
+Not implemented.
+
+Current system only records manual publish confirmation.
+
+References:
+
+- `docs/PRD.md:68-70`
+- `docs/PRD.md:179`
+- `docs/PRD.md:369-381`
+- `app/services/social_branding.py:591-620`
+
+### Auto-approve mode
+
+Not implemented.
+
+The PRD explicitly calls for opt-in auto-approve.
+
+References:
+
+- `docs/PRD.md:179`
+- `docs/PRD.md:376`
+
+### Sensitive-topic filter and tone lock
+
+Not implemented.
+
+Missing:
+
+- sensitive-topic classification before queueing
+- tone locking after initial brand establishment
+- policy-based regeneration or suppression
+
+References:
+
+- `docs/PRD.md:176-181`
+
+### Engagement automation
+
+Not implemented.
+
+Notes:
+
+- the table `engagement_drafts` exists
+- no service flow populates it
+- no routes expose it
+
+References:
+
+- `docs/PRD.md:56`
+- `docs/PRD.md:168`
+- `docs/PRD.md:194-195`
+- `app/models.py:214-225`
+
+### Enterprise social branding
+
+Not implemented.
+
+That entire scope is still absent.
+
+References:
+
+- `docs/PRD.md:250-397`
+- `docs/plan.md:25`
+
+## Key Product and Technical Assumptions Embedded in the Current Repo
+
+These assumptions should be stated explicitly in any presentation so the current implementation is not oversold.
+
+### Assumption: one service owns both business workflow and persistence
+
+The code assumes one deployable service can hold:
+
+- workflow logic
+- persistence rules
+- local event persistence
+- API-facing use cases
+
+This is acceptable for MVP, but it is why the engine is not yet truly reusable.
+
+### Assumption: normalized external data will eventually arrive
+
+The import request shape assumes someone else can provide:
+
+- profile sections
+- aggregate metrics
+- pathway context
+
+without this service solving collection first.
+
+### Assumption: demo readiness was more important than platform completeness
+
+This is visible in:
+
+- deterministic content generation
+- manual publish confirmation
+- local event storage
+- request-driven flow
+
+### Assumption: Postgres and Redis are deployment options, not proof of async completeness
+
+The repo can run on Postgres and Redis in Docker, but that should not be presented as meaning:
+
+- scheduled jobs are implemented
+- queue processing is meaningful
+- Redis is part of the live product loop today
+
+### Assumption: auth will be added upstream later
+
+Today the service trusts request bodies for `user_id`.
+
+For Clerk JWT integration, the service should move to:
+
+- derive subject from JWT
+- remove `user_id` from externally writable bodies where possible
+- enforce per-user access at the service layer
+
+## What Is Missing to Finish the Plan Properly
+
+Strictly speaking, the plan's demo definition is met. But if "finish the plan properly" means "make the narrowed MVP robust and presentation-safe for handoff", the remaining work is:
+
+### 1. Separate the engine from the service layer
+
+Required:
+
+- create an explicit engine package
+- move pure decision logic out of application orchestration
+- define normalized engine input and output contracts
+
+Why:
+
+- this is the biggest gap against the intended architecture
+- it makes later multi-surface work cleaner
+
+### 2. Add repository and adapter boundaries
+
+Required:
+
+- persistence repositories
+- platform import adapters
+- event publisher abstraction
+- posting adapter abstraction
+
+Why:
+
+- right now platform, persistence, and workflow assumptions are tightly coupled
+
+### 3. Replace startup `create_all()` with migrations
+
+Required:
+
+- Alembic or equivalent
+
+Why:
+
+- handoff and deployment reliability
+- production schema evolution
+
+### 4. Turn queue and worker into real use-case execution paths
+
+Required:
+
+- actual queued job types
+- background handlers
+- idempotency rules
+- retry behavior
+
+Why:
+
+- the current worker is only scaffolded
+
+### 5. Add stronger tests
+
+Required:
+
+- service-layer unit tests for engine outputs
+- route-level error case tests
+- Postgres integration tests
+- Redis queue tests if worker becomes real
+
+Why:
+
+- current tests prove happy-path MVP behavior only
+
+## What Is Missing to Reach the PRD
+
+This is the longer roadmap beyond the narrowed MVP.
+
+## Individual PRD completion
+
+Required work:
+
+- live or semi-live collection strategy per platform
+- recurring sync engine
+- full seven-component Brand Score
+- RQx mapping and real cross-service event delivery
+- profile rewrite generation and apply flow
+- richer toolkit library
+- real dynamic trigger ingestion
+- topic safety filtering
+- tone lock
+- optional auto-approve mode
+- scheduled posting adapters
+- platform-specific formatting
+- engagement queue generation
+- richer analytics model and trend views
+- platform activation recommendations per persona/archetype
+
+## Enterprise PRD completion
+
+Required work:
+
+- enterprise account domain
+- company brand voice settings
+- governance rules and flags
+- multi-role approvals
+- enterprise content types
+- enterprise analytics
+- enterprise content calendar visibility and role actions
+
+## Recommended Next Architecture and Work Packages
+
+If the goal is to build toward the plan and finally the PRD while matching the desired split, the implementation sequence should be:
+
+## Work Package 1: Explicit engine extraction
+
+Create a package such as `app/engine/` or `app/domain/engine/` with:
+
+- audit engine
+- score engine
+- persona engine
+- calendar engine
+- draft engine
+
+Inputs should be normalized Python models, not SQLAlchemy rows.
+
+## Work Package 2: Application service boundary
+
+Refactor `SocialBrandingService` into use cases such as:
+
+- import_profile
+- select_persona
+- recalculate_brand_score
+- generate_calendar
+- generate_drafts
+- approve_content
+- reject_content
+- regenerate_draft
+- confirm_publish
+- get_dashboard
+
+Each use case should orchestrate repositories and engine calls.
+
+## Work Package 3: Adapter layer
+
+Add adapter interfaces for:
+
+- profile collectors
+- posting executors
+- event publishers
+- analytics ingestors
+
+Start with:
+
+- manual import adapter
+- LinkedIn placeholder adapter
+
+## Work Package 4: Surface layer cleanup
+
+Keep surfaces thin:
+
+- HTTP API maps requests to use cases
+- worker consumes jobs and invokes use cases
+- Redis/event subscribers invoke the same use cases
+
+## Work Package 5: Auth integration
+
+When Clerk JWT is added:
+
+- resolve user identity from token
+- remove body-driven identity where possible
+- add service-layer authorization guards
+
+## Work Package 6: Platform expansion
+
+After the architecture split is in place:
+
+- add Instagram adapter
+- add X adapter
+- add YouTube adapter
+
+Do not add those directly into the current `SocialBrandingService` shape, or the service will become harder to evolve.
+
+## Final Readout
+
+## What is done
+
+The narrowed LinkedIn-first MVP is real and working:
+
+- ingest
+- audit
+- Brand Score v1
+- persona strategy
+- 2-week calendar
+- LinkedIn drafts
+- approval queue
+- manual publish confirmation
+- dashboard
+- local events
+- demo seed
+- tests passing
+
+## What decisions were taken
+
+The implementation intentionally chose:
+
+- LinkedIn-only runtime
+- manual import over OAuth-first
+- simplified Brand Score
+- deterministic templates
+- manual publish confirmation
+- request-driven flow
+- local event persistence
+- deferred auth
+
+## What assumptions phase one was built on
+
+Phase one assumes:
+
+- upstream or manual data can be provided
+- one-user flows are enough for validation
+- live posting is not required
+- local persistence is enough to prove the workflow
+- Redis/Postgres readiness is useful even without full async execution
+- the engine can be extracted later from the current helper modules and service logic
+
+## What is left versus the plan
+
+Very little is left for the narrowed MVP feature set itself. The main unfinished work is structural and production-grade:
+
+- engine extraction
+- repository/adaptor boundaries
+- migrations
+- real worker jobs
+- broader tests
+
+## What is left versus the PRD
+
+A large amount remains:
+
+- multi-platform support
+- real collection and sync
+- richer scoring and RQx integration
+- profile rewrites
+- scheduled posting
+- engagement automation
+- richer analytics
+- safety and policy logic
+- enterprise workflows
+
+## Bottom line
+
+This repo should be presented as:
+
+"Plan-complete for a narrowed LinkedIn-first MVP, but not PRD-complete. The next major step is not adding random features inside the current service. It is separating the engine from the service and surfaces so the PRD can be implemented cleanly."
diff --git a/social_branding/plan.md b/social_branding/plan.md
new file mode 100644
index 0000000..3f76256
--- /dev/null
+++ b/social_branding/plan.md
@@ -0,0 +1,158 @@
+# Social Branding Service Plan
+
+## Mission
+
+Build a LinkedIn-first, individual-only social branding MVP that can ingest profile data, compute Brand Score v1, generate persona-based strategy and content plans, manage an approval queue, and expose progress back to the GrowQR ecosystem.
+
+## Locked Scope
+
+### In scope tonight
+
+- individual service only
+- LinkedIn-first profile import/audit flow
+- manual import or adapter fallback instead of hard OAuth dependency
+- persona selection from pathway goal/archetype context
+- Brand Score v1
+- content calendar generation
+- draft generation for LinkedIn
+- approval queue
+- posting state machine and manual/export-based publish completion
+- dashboard and analytics snapshots
+- event emission for Brand Score updates
+
+### Explicitly deferred
+
+- enterprise social branding
+- Instagram, X, YouTube runtime support
+- real auto-posting to live platforms
+- full engagement automation
+- recruiter search visibility integrations that depend on unstable APIs
+- multi-platform analytics parity
+
+## Implementation Decisions
+
+- LinkedIn is the only live platform for v1. Other platforms remain schema-ready only.
+- Support manual JSON/import or URL-backed profile snapshot ingestion so the service is not blocked on OAuth.
+- Brand Score v1 must normalize to available LinkedIn data. Do not block on missing cross-platform metrics.
+- The publish step may be manual-confirmed: generate final copy and mark it posted when the user confirms it was used.
+- Use deterministic templates for the 80% toolkit and limited AI generation only for the 20% dynamic layer.
+
+## Domain Model
+
+- `social_accounts`
+- `social_profile_snapshots`
+- `brand_scores`
+- `persona_strategies`
+- `content_calendar_items`
+- `content_drafts`
+- `approval_queue`
+- `analytics_snapshots`
+- `engagement_drafts`
+
+## Core APIs
+
+- `POST /api/v1/accounts/linkedin/import`
+- `POST /api/v1/persona/select`
+- `POST /api/v1/brand-score/recalculate`
+- `GET /api/v1/dashboard/{user_id}`
+- `POST /api/v1/content-calendar/generate`
+- `GET /api/v1/content-calendar/{user_id}`
+- `POST /api/v1/drafts/generate`
+- `POST /api/v1/approval-queue/{item_id}/approve`
+- `POST /api/v1/approval-queue/{item_id}/reject`
+- `POST /api/v1/approval-queue/{item_id}/regenerate`
+- `POST /api/v1/publish/{item_id}/confirm`
+
+## Pathways Dependency
+
+Consume or mock:
+
+- target role
+- pathway milestone events
+- goal/persona hints
+- optional archetype
+- optional Q-score changes
+
+Use those to select persona strategy and dynamic content triggers.
+
+## Phase Plan
+
+### Phase 1: Foundations
+
+- [x] Replace template domain with social profile/content models
+- [x] Define persona enums and LinkedIn-only account type
+- [x] Add Brand Score component model
+- [x] Seed persona templates and content toolkit examples
+
+### Phase 2: Profile Ingest And Audit
+
+- [x] Implement LinkedIn import endpoint with manual payload fallback
+- [x] Build profile audit scoring
+- [x] Persist profile recommendations
+- [x] Add tests for audit output
+
+### Phase 3: Brand Score And Persona Strategy
+
+- [x] Compute Brand Score v1 from available LinkedIn metrics
+- [x] Map pathway context to one of the personas
+- [x] Persist strategy settings and posting cadence
+- [x] Emit Brand Score update event on meaningful changes
+
+### Phase 4: Content Calendar And Drafts
+
+- [x] Generate a 2-week content calendar
+- [x] Enforce 80/20 split
+- [x] Generate LinkedIn draft content
+- [x] Add dynamic triggers for pathway milestone and score-change events
+
+### Phase 5: Approval And Publish Flow
+
+- [x] Implement approval queue
+- [x] Support approve/reject/regenerate
+- [x] Support manual publish confirmation
+- [x] Record posting state transitions
+
+### Phase 6: Dashboard And Hardening
+
+- [x] Build dashboard endpoint with score trend and queue summary
+- [x] Add happy path tests
+- [x] Document deferred multi-platform and enterprise work
+
+## Review Checklist
+
+- [x] Service works without live LinkedIn OAuth
+- [x] LinkedIn is the only live platform in v1
+- [x] Brand Score does not depend on unavailable metrics
+- [x] Approval queue blocks publishing until approval
+- [x] Multi-platform and enterprise features stay deferred
+- [x] Dashboard exposes useful state to Pathways and users
+
+## Suggested File Layout
+
+- `app/api/v1/accounts.py`
+- `app/api/v1/content.py`
+- `app/api/v1/dashboard.py`
+- `app/services/brand_score.py`
+- `app/services/persona_strategy.py`
+- `app/services/content_calendar.py`
+- `tests/test_social_branding_flow.py`
+
+## Commands
+
+```bash
+cp .env.example .env
+uv sync --extra dev
+uv run pytest
+docker compose up --build
+```
+
+## Done Definition
+
+This service is done for the overnight run when a seeded user can:
+
+1. import a LinkedIn profile snapshot
+2. receive an audit and Brand Score
+3. get a persona-based 2-week content calendar
+4. review generated drafts in an approval queue
+5. approve and mark a post as published
+6. see score and activity reflected in a dashboard response
diff --git a/social_branding/prd-additions.md b/social_branding/prd-additions.md
new file mode 100644
index 0000000..a2e6226
--- /dev/null
+++ b/social_branding/prd-additions.md
@@ -0,0 +1,161 @@
+# PRD additions we can implement next (excluding posting + new platforms)
+
+Date: 2026-03-26
+Source: `docs/PRD.md`
+Exclusions: **(1)** anything that actually posts/executes content to platforms, **(2)** adding/supporting new platforms beyond the current LinkedIn-first implementation.
+
+This doc lists **only** items explicitly described in the PRD that are either missing or only partially implemented in the current codebase.
+
+---
+
+## 1) Brand Score: full PRD component model + breakdown
+
+**PRD section:** “2.1 Brand Score Components”, “2.2 Brand Score → RQx Integration”
+
+Add the remaining Brand Score components as first-class computed fields (and store their breakdown), not just a profile audit-derived score:
+
+- **Content Consistency (20%)**: consistency of posting frequency + tone consistency over a rolling window.
+- **Audience Growth (15%)**: follower/connection growth rate over a 30-day rolling window.
+- **Engagement Rate (15%)**: likes/comments/shares/saves as % of reach.
+- **Recruiter Visibility (15%)**: profile appearance rate in recruiter/talent searches (LinkedIn primary).
+- **Content Quality (10%)**: AI-assessed relevance/originality/alignment to persona framework.
+- **Cross-Platform Consistency (5%)**: messaging/voice alignment across connected platforms (schema-ready; compute from available platforms only).
+
+Also implement PRD-required outputs:
+
+- Brand Score trend line (history storage + API response)
+- “objective, measurable signals” explanations per component
+
+---
+
+## 2) Brand Score → RQx mapping + events
+
+**PRD section:** “2.2 Brand Score → RQx Integration”
+
+Implement/confirm the PRD mapping and event rules end-to-end:
+
+- Compute & store **RQx contribution** as: `Brand Score × 0.4`
+- Ensure recalculation runs **after every platform sync** (LinkedIn daily in PRD)
+- Emit update when Brand Score changes by **5+ points** (PRD) and include before/after + metadata
+- Persist and expose Brand Score history for the dashboard (trendline)
+
+---
+
+## 3) LinkedIn profile rewrite variants + user selection
+
+**PRD section:** “5.1 LinkedIn → Profile Rewrite”
+
+Generate PRD-specified rewrite options for user approval/selection:
+
+- Headline: **3 variants**
+- About section: optimized version(s)
+- Experience bullet points (per role)
+- Skills list mapped to Q-Scores + target JD keywords
+
+This is PRD “Generate → Approve” behavior and does **not** require posting.
+
+---
+
+## 4) Recruiter visibility: keyword gap analysis + injection recommendations
+
+**PRD section:** “5.1 LinkedIn → Recruiter Visibility”; Brand Score component “Recruiter Visibility”
+
+Add the PRD keyword gap workflow:
+
+- Identify missing recruiter-search terms for the target role
+- Provide **where to inject** them (headline/about/experience/skills) and generate suggested rewrites
+- Score each section 0–100 and benchmark vs target role (PRD says “benchmark against top 10% in same role”)
+
+---
+
+## 5) Connection strategy drafts (no sending)
+
+**PRD section:** “5.1 LinkedIn → Connection Strategy”
+
+Implement the PRD deliverables without executing any connection actions:
+
+- Identify target connections (target companies, peers, hiring managers)
+- Draft **personalized connection request notes** for approval
+- Track acceptance-rate analytics inputs (data collection method TBD per PRD)
+
+---
+
+## 6) Engagement response drafts (approval-gated, no automation)
+
+**PRD sections:** Pillar “Engagement”; “4.2 Dynamic Content → Engagement response drafts”; “5.1 LinkedIn → Engagement Automation”
+
+Add draft generation (only) for:
+
+- Replies to comments on user posts
+- Comments on posts from target connections/industry leaders
+
+All actions remain **draft-only** and **approval-gated**.
+
+---
+
+## 7) Content calendar generation rules enforcement (planning-side only)
+
+**PRD section:** “4.3 Content Calendar Generation Rules”
+
+Enforce the PRD rules in calendar generation + approval queue mechanics:
+
+- **Rule 1: Frequency enforcement** + reminders 48hrs in advance if slots aren’t approved
+- **Rule 2: Platform sequencing** (formatting/unique versions) — for now enforce at least “no naive duplication” within LinkedIn content types/templates
+- **Rule 3: 80/20 split** maintained over a rolling 2-week window
+- **Rule 4: No auto-post without approval** (keep; optionally support PRD “auto-approve mode” as opt-in *approval behavior*, not posting)
+- **Rule 5: Tone lock** after first 2 weeks unless user resets
+- **Rule 6: Sensitive topic filter**: risky content is flagged and not queued for approval
+
+These changes are about **planning, generation, and approvals**, not posting.
+
+---
+
+## 8) Tracking + weekly analytics dashboard (read-only metrics)
+
+**PRD section:** “1.1 The Automation Loop → Track”; “5.1 LinkedIn → Analytics Tracked”
+
+Implement the PRD “Track” layer to collect, store, and display (no posting needed):
+
+- Profile views (7-day, 30-day)
+- Search appearances
+- Post impressions
+- Engagement rate per post
+- Connection acceptance rate
+- Follower growth
+
+Add PRD-required presentation:
+
+- Weekly analytics dashboard
+- Brand Score trend line
+
+---
+
+## 9) Data requirements layer (LinkedIn) — collection mechanism + constraints doc
+
+**PRD section:** “6. Data Requirements — Individual”
+
+PRD leaves the method “TBD by technical team” but requires confirmation of availability. Add the engineering artifacts the PRD calls for:
+
+- Document collection mechanism (API vs scraping vs user export)
+- Document legal/rate-limit constraints
+- Confirm which fields in PRD can/can’t be reliably collected now
+- Implement a stable “profile snapshot + metrics snapshot” storage model for the required data
+
+---
+
+## 10) Persona switching support
+
+**PRD section:** “3. Six end-goal personas — content framework”
+
+PRD states users can switch personas as goals evolve. Implement:
+
+- Changing persona for a profile
+- Persist persona choice and regenerate future calendar/drafts under the new persona
+- Keep approval queue consistent (what happens to existing suggested/scheduled items)
+
+---
+
+## Notes / alignment with current repo state
+
+- The repo already has foundations for: LinkedIn profile ingest, audit, deterministic calendar/draft generation, approval workflow, Brand Score v1, and dashboard state.
+- The items above are the next PRD-scoped additions that don’t require new platforms or posting.
diff --git a/staging-vps-service-deployment-runbook.md b/staging-vps-service-deployment-runbook.md
new file mode 100644
index 0000000..1bbb0b6
--- /dev/null
+++ b/staging-vps-service-deployment-runbook.md
@@ -0,0 +1,1849 @@
+# GrowQR Staging VPS Service Deployment Runbook
+
+Date: 2026-06-05
+VPS SSH alias: `gqr-temp`
+VPS IP: `168.144.123.127`
+Staging wildcard DNS: `*.gqr.puter.wtf`
+Deployment root on VPS: `/opt/growqr`
+
+## User instructions followed
+
+- Deploy services one by one to the staging VPS.
+- For each service repo:
+ - Check Git status, current branch, remotes, and Gitea remote.
+ - If deployable work exists on a non-main branch, create a `staging` branch from the current branch.
+ - Push `staging` to Gitea.
+ - Deploy the `staging` branch/content to the VPS.
+- Most repos are expected to have a Gitea remote named `gitea`; if not, handle case by case.
+- Copy the local `.env` file to the VPS deployment.
+- Use Caddy as reverse proxy for APIs.
+- Keep room for many services/ports:
+ - bind service/internal ports to `127.0.0.1` only
+ - expose publicly only through Caddy subdomains
+- Use the wildcard DNS under `*.gqr.puter.wtf` for service URLs.
+
+## VPS base setup performed
+
+Installed required packages on `gqr-temp`:
+
+```bash
+apt-get update
+apt-get install -y git docker.io docker-compose caddy ca-certificates curl
+systemctl enable --now docker caddy
+```
+
+Notes:
+
+- Debian 13 package name was `docker-compose`, not `docker-compose-plugin`.
+- Caddy is managed by systemd.
+- Docker Compose command available as `docker-compose`.
+
+## Git deployment branch procedure
+
+For each service repo locally:
+
+```bash
+cd
+git status --short --branch
+git remote -v
+git fetch --all --prune
+git remote show gitea
+git rev-list --left-right --count HEAD...gitea/main
+git ls-remote --heads gitea staging origin staging
+```
+
+If there is no existing `staging` branch and the current branch contains the intended deployable changes:
+
+```bash
+git switch -c staging
+git push -u gitea staging
+```
+
+## Source transfer procedure used
+
+Initial direct HTTPS clone from Gitea on the VPS failed because the remote requires credentials:
+
+```txt
+fatal: could not read Username for 'https://git.openputer.com': No such device or address
+```
+
+So we deployed by archiving the local `staging` worktree and copying it to the VPS:
+
+```bash
+cd
+COPYFILE_DISABLE=1 tar \
+ --exclude='./.venv' \
+ --exclude='./__pycache__' \
+ --exclude='*/__pycache__' \
+ --exclude='./.pytest_cache' \
+ -czf /tmp/-staging.tgz .
+
+scp /tmp/-staging.tgz gqr-temp:/tmp/
+
+ssh gqr-temp '
+ rm -rf /opt/growqr/
+ mkdir -p /opt/growqr/
+ tar --no-same-owner -xzf /tmp/-staging.tgz -C /opt/growqr/
+ cd /opt/growqr/
+ find . -name "._*" -type f -delete
+ chown -R root:root .
+ chmod 600 .env
+ git status --short --branch
+'
+```
+
+Important cleanup:
+
+- macOS archive metadata files like `._*` were deleted on the VPS.
+- `.env` permissions were set to `600`.
+- Ownership was normalized to `root:root`.
+
+## Port allocation strategy
+
+To leave public port space clean, service ports were patched on the VPS so Docker only binds to loopback.
+
+Pattern:
+
+| Purpose | Port range style |
+|---|---:|
+| API public reverse-proxy backend | `127.0.0.1:180xx` |
+| Postgres internal/debug only | `127.0.0.1:154xx` |
+| MinIO API internal/debug only | `127.0.0.1:190xx` |
+| MinIO console internal/debug only | `127.0.0.1:190xx+1` |
+
+Only Caddy listens publicly on `80`/`443`.
+
+## Caddy procedure
+
+For each service, append a site block to `/etc/caddy/Caddyfile`:
+
+```caddy
+.gqr.puter.wtf {
+ encode gzip zstd
+ reverse_proxy 127.0.0.1:
+}
+```
+
+Then validate, format, and reload:
+
+```bash
+cp /etc/caddy/Caddyfile /etc/caddy/Caddyfile.bak.$(date +%Y%m%d%H%M%S)
+caddy fmt --overwrite /etc/caddy/Caddyfile
+caddy validate --config /etc/caddy/Caddyfile
+systemctl reload caddy
+```
+
+Caddy automatically obtained Let's Encrypt certificates via the wildcard DNS-resolved subdomains.
+
+## Service 1: interview-service
+
+### Local repo status
+
+Path:
+
+```txt
+/Users/puter/Workspace/growqr/interview-service
+```
+
+Before staging:
+
+- Branch: `dashboard-service-rest-integration`
+- Worktree: clean
+- Gitea remote: `https://git.openputer.com/growqr-app/interview-service.git`
+- GitHub origin also exists: `https://github.com/GrowQR-Code/interview-service.git`
+- Gitea default branch: `main`
+- Current branch was 1 commit ahead of `gitea/main`
+- No existing `staging` branch found
+
+Created and pushed:
+
+```bash
+cd interview-service
+git switch -c staging
+git push -u gitea staging
+```
+
+### VPS deployment
+
+Remote path:
+
+```txt
+/opt/growqr/interview-service
+```
+
+Patched Docker Compose bindings on VPS:
+
+```txt
+api: 127.0.0.1:18007 -> 8000
+postgres: 127.0.0.1:15440 -> 5432
+minio: 127.0.0.1:19000 -> 9000
+minio: 127.0.0.1:19001 -> 9001
+```
+
+Also changed Redis URL for this staging compose from host Redis to internal compose Redis:
+
+```txt
+REDIS_URL: redis://redis:6379/0
+```
+
+Started with:
+
+```bash
+cd /opt/growqr/interview-service
+docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d --build
+```
+
+Caddy URL:
+
+```txt
+https://interview-staging.gqr.puter.wtf
+```
+
+Health check:
+
+```bash
+curl -fsS https://interview-staging.gqr.puter.wtf/health
+```
+
+Expected response:
+
+```json
+{"status":"ok","service":"interview-service","a2a":true,"agent":true}
+```
+
+Final container state:
+
+```txt
+interview-service-api-1 healthy 127.0.0.1:18007->8000
+interview-service-postgres-1 healthy 127.0.0.1:15440->5432
+interview-service-minio-1 healthy 127.0.0.1:19000->9000, 127.0.0.1:19001->9001
+interview-service-redis-1 healthy internal only
+```
+
+## Service 2: roleplay-service
+
+### Local repo status
+
+Path:
+
+```txt
+/Users/puter/Workspace/growqr/roleplay-service
+```
+
+Before staging:
+
+- Branch: `dashboard-service-rest-integration`
+- Worktree: clean
+- Gitea remote: `https://git.openputer.com/growqr-app/roleplay-service.git`
+- GitHub origin also exists: `https://github.com/GrowQR-Code/roleplay-service.git`
+- Gitea default branch: `main`
+- Current branch was 1 commit ahead of `gitea/main`
+- No existing `staging` branch found
+
+Created and pushed:
+
+```bash
+cd roleplay-service
+git switch -c staging
+git push -u gitea staging
+```
+
+### VPS deployment
+
+Remote path:
+
+```txt
+/opt/growqr/roleplay-service
+```
+
+Patched Docker Compose bindings on VPS:
+
+```txt
+api: 127.0.0.1:18008 -> 8000
+postgres: 127.0.0.1:15441 -> 5432
+minio: 127.0.0.1:19010 -> 9000
+minio: 127.0.0.1:19011 -> 9001
+```
+
+Started with:
+
+```bash
+cd /opt/growqr/roleplay-service
+docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d --build
+```
+
+Caddy URL:
+
+```txt
+https://roleplay-staging.gqr.puter.wtf
+```
+
+Health check:
+
+```bash
+curl -fsS https://roleplay-staging.gqr.puter.wtf/health
+```
+
+Expected response:
+
+```json
+{"status":"ok","service":"roleplay-service","a2a":true,"agent":true}
+```
+
+Final container state:
+
+```txt
+roleplay-service-api-1 healthy 127.0.0.1:18008->8000
+roleplay-service-postgres-1 healthy 127.0.0.1:15441->5432
+roleplay-service-minio-1 healthy 127.0.0.1:19010->9000, 127.0.0.1:19011->9001
+```
+
+## qscore_service deployment (2026-06-05)
+
+### Local Git state
+
+Repository:
+
+```txt
+/Users/puter/Workspace/growqr/qscore_service
+```
+
+Observed before deployment:
+
+```txt
+current branch: feature/quotients-from-pillars
+modified: docker-compose.yml
+untracked: .DS_Store, uv.lock
+local .env: not present
+```
+
+Gitea remote was present as SSH fetch URL but SSH push failed with public-key auth. The push URL was changed to HTTPS and `staging` was pushed successfully:
+
+```bash
+cd qscore_service
+git switch -C staging
+git remote set-url --push gitea https://git.openputer.com/puter/qscore-service.git
+git push -u gitea staging
+```
+
+### VPS deployment
+
+Remote path:
+
+```txt
+/opt/growqr/qscore_service
+```
+
+No local `.env` existed, so `.env.example` was copied to `.env` on the VPS and locked down with `chmod 600`.
+
+Patched Docker Compose bindings on VPS:
+
+```txt
+api: 127.0.0.1:18009 -> 8000
+postgres: 127.0.0.1:15442 -> 5432
+redis: 127.0.0.1:16380 -> 6379
+```
+
+Started with:
+
+```bash
+cd /opt/growqr/qscore_service
+docker-compose -p qscore-service-staging up -d --build
+```
+
+Caddy URL:
+
+```txt
+https://qscore-staging.gqr.puter.wtf
+```
+
+Health check:
+
+```bash
+curl -fsS https://qscore-staging.gqr.puter.wtf/health
+```
+
+Expected response:
+
+```json
+{"status":"ok"}
+```
+
+Final container state:
+
+```txt
+qscore-service-staging-api-1 up 127.0.0.1:18009->8000
+qscore-service-staging-postgres-1 healthy 127.0.0.1:15442->5432
+qscore-service-staging-redis-1 healthy 127.0.0.1:16380->6379
+qscore-service-staging-worker-1 up
+```
+
+## growqr-app resume-builder and user-service deployment (2026-06-05)
+
+These services live inside the monorepo:
+
+```txt
+/Users/puter/Workspace/growqr/growqr-app
+```
+
+### Local Git state
+
+Current branch before staging was `dashboard-service-rest-integration`, with modified service files under `resume-builder/` and `user-service/`.
+
+Created/pushed monorepo staging branch:
+
+```bash
+cd growqr-app
+git switch -C staging
+git push -u gitea staging
+```
+
+### user-service VPS deployment
+
+Remote path:
+
+```txt
+/opt/growqr/user-service
+```
+
+Copied local `.env` to the VPS and locked it down with `chmod 600`.
+
+Patched Docker Compose bindings on VPS:
+
+```txt
+api: 127.0.0.1:18011 -> 8003
+postgres: 127.0.0.1:15444 -> 5432
+redis: 127.0.0.1:16382 -> 6379
+```
+
+Staging service URLs patched in compose:
+
+```txt
+PUBLIC_BASE_URL=https://user-staging.gqr.puter.wtf
+RESUME_SERVICE_URL=https://resume-staging.gqr.puter.wtf
+QSCORE_SERVICE_URL=https://qscore-staging.gqr.puter.wtf
+```
+
+Started with:
+
+```bash
+cd /opt/growqr/user-service
+docker-compose -p user-service-staging up -d --build
+```
+
+Caddy URL:
+
+```txt
+https://user-staging.gqr.puter.wtf
+```
+
+Health check:
+
+```bash
+curl -fsS https://user-staging.gqr.puter.wtf/health
+```
+
+Expected response:
+
+```json
+{"status":"healthy","service":"user-service","mcp":true,"agent":true,"a2a":true}
+```
+
+### resume-builder VPS deployment
+
+Remote path:
+
+```txt
+/opt/growqr/resume-builder
+```
+
+Copied local `.env` to the VPS and locked it down with `chmod 600`.
+
+Patched Docker Compose bindings on VPS:
+
+```txt
+api: 127.0.0.1:18010 -> 8000
+postgres: 127.0.0.1:15443 -> 5432
+redis: internal compose network only, exposed as 6379/tcp inside Docker
+```
+
+Patched `USER_SERVICE_URL` in compose:
+
+```txt
+USER_SERVICE_URL=https://user-staging.gqr.puter.wtf
+```
+
+Started with:
+
+```bash
+cd /opt/growqr/resume-builder
+docker-compose -p resume-builder-staging up -d --build
+```
+
+Caddy URL:
+
+```txt
+https://resume-staging.gqr.puter.wtf
+```
+
+Health check:
+
+```bash
+curl -fsS https://resume-staging.gqr.puter.wtf/health
+```
+
+Expected response:
+
+```json
+{"status":"healthy","service":"resume-builder","mcp":true,"agent":true,"a2a":true}
+```
+
+Final container state:
+
+```txt
+growqr_resume_api healthy 127.0.0.1:18010->8000
+growqr_resume_db healthy 127.0.0.1:15443->5432
+growqr_resume_redis up 6379/tcp
+growqr_user_service up 127.0.0.1:18011->8003
+growqr_users_db healthy 127.0.0.1:15444->5432
+growqr_users_redis up 127.0.0.1:16382->6379
+```
+
+## growqr-backend deployment
+
+Local repo:
+
+```txt
+/Users/puter/Workspace/growqr/growqr-backend
+```
+
+Branch and commit deployed:
+
+```txt
+staging @ d10ef2a feat: personalize home feed suggestions
+```
+
+Started from `chore/release`, committed the local home-feed changes, created `staging`, and pushed to Gitea:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-backend
+npm run typecheck
+git switch -c staging
+git add src/home/home-feed-agent.ts src/home/home-feed.ts src/home/types.ts src/routes/home.ts
+git commit -m "feat: personalize home feed suggestions"
+git push -u origin staging
+```
+
+Remote path:
+
+```txt
+/opt/growqr/growqr-backend
+```
+
+Copied local `.env` to the VPS via the tar deployment and locked it down with `chmod 600`.
+
+Patched Docker Compose bindings on VPS:
+
+```txt
+backend api: 127.0.0.1:18012 -> 4000
+postgres: 127.0.0.1:15445 -> 5432
+gitea http: 127.0.0.1:13001 -> 3000
+gitea ssh: 127.0.0.1:12222 -> 2222
+rivet api: 127.0.0.1:16420 -> 6420
+rivet guard: 127.0.0.1:16421 -> 6421
+```
+
+Patched staging URLs in `.env`/compose:
+
+```txt
+GITEA_PUBLIC_URL=https://backend-gitea-staging.gqr.puter.wtf
+GITEA_ROOT_URL=https://backend-gitea-staging.gqr.puter.wtf
+RIVET_CLIENT_ENDPOINT=https://backend-staging.gqr.puter.wtf/api/rivet
+INTERVIEW_SERVICE_URL=https://interview-staging.gqr.puter.wtf
+ROLEPLAY_SERVICE_URL=https://roleplay-staging.gqr.puter.wtf
+QSCORE_SERVICE_URL=https://qscore-staging.gqr.puter.wtf
+RESUME_SERVICE_URL=https://resume-staging.gqr.puter.wtf
+FRONTEND_ORIGIN=https://dashboard-staging.gqr.puter.wtf
+```
+
+Started with:
+
+```bash
+cd /opt/growqr/growqr-backend
+docker-compose -p growqr-backend-staging up -d --build
+```
+
+The first backend boot failed because the fresh Postgres volume had no tables. Applied migrations from the compiled runtime image:
+
+```bash
+docker-compose -p growqr-backend-staging run --rm backend node dist/db/migrate.js
+docker-compose -p growqr-backend-staging up -d backend
+```
+
+Caddy URLs:
+
+```txt
+https://backend-staging.gqr.puter.wtf
+https://backend-gitea-staging.gqr.puter.wtf
+```
+
+Health checks:
+
+```bash
+curl -fsS https://backend-staging.gqr.puter.wtf/healthz
+curl -fsS https://backend-gitea-staging.gqr.puter.wtf/api/v1/version
+```
+
+Expected responses:
+
+```json
+{"ok":true}
+{"version":"1.22.6"}
+```
+
+## growqr-dashboard frontend deployment
+
+Local repo:
+
+```txt
+/Users/puter/Workspace/growqr/growqr-dashboard
+```
+
+Branch deployed:
+
+```txt
+staging @ 45ce954 updates
+```
+
+`growqr-dashboard` was on `main` ahead of `origin/main` by one commit. Created and pushed `staging` to Gitea:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+npm run build
+git switch -c staging
+git push -u origin staging
+```
+
+Remote path:
+
+```txt
+/opt/growqr/growqr-dashboard
+```
+
+Copied local `.env` to the VPS and locked it down with `chmod 600`.
+
+Patched staging env values on VPS:
+
+```txt
+NEXT_PUBLIC_RIVET_ENDPOINT=https://backend-staging.gqr.puter.wtf/api/rivet
+NEXT_PUBLIC_GROWQR_BACKEND_URL=https://backend-staging.gqr.puter.wtf
+GROWQR_BACKEND_URL=https://backend-staging.gqr.puter.wtf
+NEXT_PUBLIC_INTERVIEW_WS_URL=wss://interview-staging.gqr.puter.wtf/api/v1
+NEXT_PUBLIC_ROLEPLAY_WS_URL=wss://roleplay-staging.gqr.puter.wtf/api/v1
+```
+
+Created `Dockerfile.staging` and `docker-compose.staging.yml` on the VPS. Dashboard binds only to localhost:
+
+```txt
+dashboard: 127.0.0.1:13000 -> 3000
+```
+
+Build note: `npm ci` failed because `@clerk/nextjs@7.4.2` peer requirements conflict with `next@14.2.18`, while local build already uses the existing dependency resolution. The staging Dockerfile uses:
+
+```bash
+npm install --legacy-peer-deps
+```
+
+Started with:
+
+```bash
+cd /opt/growqr/growqr-dashboard
+docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build
+```
+
+Caddy URL:
+
+```txt
+https://dashboard-staging.gqr.puter.wtf
+```
+
+Verification:
+
+```bash
+curl -fsSI https://dashboard-staging.gqr.puter.wtf
+```
+
+Expected status:
+
+```txt
+HTTP/2 200
+```
+
+## Verification commands
+
+Check all running services:
+
+```bash
+ssh gqr-temp 'docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"'
+```
+
+Check local listening ports:
+
+```bash
+ssh gqr-temp 'ss -ltnp | grep -E ":(80|443|13000|18007|18008|18009|18010|18011|18012|15440|15441|15442|15443|15444|15445|16380|16382|19000|19001|19010|19011|12222|13001|16420|16421)" || true'
+```
+
+Check Caddy logs:
+
+```bash
+ssh gqr-temp 'journalctl -u caddy --no-pager -n 80'
+```
+
+Check service logs:
+
+```bash
+ssh gqr-temp 'cd /opt/growqr/interview-service && docker-compose -f docker-compose.yml -f docker-compose.staging.yml logs --tail=100 api'
+ssh gqr-temp 'cd /opt/growqr/roleplay-service && docker-compose -f docker-compose.yml -f docker-compose.staging.yml logs --tail=100 api'
+ssh gqr-temp 'cd /opt/growqr/qscore_service && docker-compose -p qscore-service-staging logs --tail=100 api'
+ssh gqr-temp 'cd /opt/growqr/user-service && docker-compose -p user-service-staging logs --tail=100 user-service'
+ssh gqr-temp 'cd /opt/growqr/resume-builder && docker-compose -p resume-builder-staging logs --tail=100 api'
+ssh gqr-temp 'cd /opt/growqr/growqr-backend && docker-compose -p growqr-backend-staging logs --tail=100 backend'
+```
+
+## Service dependency map
+
+Staging services point at each other via public HTTPS URLs (not `host.docker.internal`):
+
+```
+dashboard-staging.gqr.puter.wtf
+ ├─→ backend-staging.gqr.puter.wtf (API + Gitea + Rivet)
+ ├─→ interview-staging.gqr.puter.wtf
+ ├─→ roleplay-staging.gqr.puter.wtf
+ ├─→ resume-staging.gqr.puter.wtf
+ ├─→ user-staging.gqr.puter.wtf
+ └─→ qscore-staging.gqr.puter.wtf
+
+backend-staging.gqr.puter.wtf
+ ├─→ interview-staging.gqr.puter.wtf
+ ├─→ roleplay-staging.gqr.puter.wtf
+ ├─→ qscore-staging.gqr.puter.wtf
+ └─→ resume-staging.gqr.puter.wtf
+
+user-service-staging
+ ├─→ resume-staging.gqr.puter.wtf
+ └─→ qscore-staging.gqr.puter.wtf
+
+resume-builder-staging
+ └─→ user-staging.gqr.puter.wtf
+```
+
+## Port allocation reference
+
+| Service | API | Postgres | Redis | MinIO API | MinIO Console | Other |
+|---|---|---|---|---|---|---|
+| interview-service | 18007 | 15440 | internal | 19000 | 19001 | — |
+| roleplay-service | 18008 | 15441 | internal | 19010 | 19011 | — |
+| qscore_service | 18009 | 15442 | 16380 | — | — | — |
+| resume-builder | 18010 | 15443 | internal | — | — | — |
+| user-service | 18011 | 15444 | 16382 | — | — | — |
+| growqr-backend | 18012 | 15445 | — | — | — | Gitea 13001/12222, Rivet 16420/16421 |
+| growqr-dashboard | 13000 | — | — | — | — | — |
+
+Public ports: only Caddy on `80`/`443`.
+
+## Health check endpoints quick reference
+
+| Service | Endpoint | Expected response |
+|---|---|---|
+| interview-service | `GET /health` | `{"status":"ok","service":"interview-service","a2a":true,"agent":true}` |
+| roleplay-service | `GET /health` | `{"status":"ok","service":"roleplay-service","a2a":true,"agent":true}` |
+| qscore_service | `GET /health` | `{"status":"ok"}` |
+| resume-builder | `GET /health` | `{"status":"healthy","service":"resume-builder","mcp":true,"agent":true,"a2a":true}` |
+| user-service | `GET /health` | `{"status":"healthy","service":"user-service","mcp":true,"agent":true,"a2a":true}` |
+| growqr-backend | `GET /healthz` | `{"ok":true}` |
+| growqr-gitea | `GET /api/v1/version` | `{"version":"1.22.6"}` |
+| growqr-dashboard | `GET /` (root page) | `HTTP/2 200` |
+
+## Post-reboot / resize recovery
+
+After a VPS reboot or resize, Docker containers with `restart: unless-stopped` or compose `restart` policies may not auto-start if they were not running when systemd shut down. To recover all services:
+
+```bash
+# Backend services
+ssh gqr-temp '
+ cd /opt/growqr/interview-service && docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d
+ cd /opt/growqr/roleplay-service && docker-compose -f docker-compose.yml -f docker-compose.staging.yml up -d
+ cd /opt/growqr/qscore_service && docker-compose -p qscore-service-staging up -d
+ cd /opt/growqr/user-service && docker-compose -p user-service-staging up -d
+ cd /opt/growqr/resume-builder && docker-compose -p resume-builder-staging up -d
+ cd /opt/growqr/growqr-backend && docker-compose -p growqr-backend-staging up -d
+ cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d
+'
+```
+
+Also ensure Caddy is running:
+
+```bash
+ssh gqr-temp 'systemctl is-active caddy || systemctl start caddy'
+```
+
+## Common issues & fixes encountered
+
+### 1. Gitea clone requires credentials on VPS
+
+Direct HTTPS clone from `git.openputer.com` fails because the VPS has no stored credentials. Fix: archive the local worktree, `scp` it, and extract on the VPS.
+
+### 2. Gitea SSH push fails with public-key auth
+
+`qscore_service` had a Gitea SSH remote but push failed. Fix: switch the push URL to HTTPS:
+
+```bash
+git remote set-url --push gitea https://git.openputer.com/puter/qscore-service.git
+```
+
+### 3. Fresh backend Postgres has no tables
+
+On first `growqr-backend` deploy, the backend container crashed with:
+
+```
+PostgresError: relation "user_stacks" does not exist
+```
+
+Fix: run the compiled migration script inside the built image before starting the backend:
+
+```bash
+cd /opt/growqr/growqr-backend
+docker-compose -p growqr-backend-staging run --rm backend node dist/db/migrate.js
+docker-compose -p growqr-backend-staging up -d backend
+```
+
+### 4. Next.js peer dependency conflict during Docker build
+
+`npm ci` failed because `@clerk/nextjs@7.4.2` peer requirements conflict with `next@14.2.18`. Fix in the Dockerfile:
+
+```bash
+RUN npm install --legacy-peer-deps
+```
+
+### 5. VPS overloaded during Next.js build
+
+The initial VPS size (1 vCPU / 2 GB RAM) caused the `next build` to hang and the VPS became unreachable. Fix: resize the VPS to at least 4 vCPU / 8 GB RAM for frontend builds, or build locally and copy only the `.next` output.
+
+### 6. Caddy certificate issuance delay
+
+New subdomains may take 10–30 seconds for Let's Encrypt TLS-ALPN-01 validation. During that window, `curl` may return `SSL: TLS alert internal error`. Fix: wait for Caddy logs to show `certificate obtained successfully` before verifying HTTPS.
+
+## Environment variable staging checklist
+
+When deploying a new service, the following env vars usually need changing from `localhost`/`host.docker.internal` to staging URLs:
+
+- `GITEA_PUBLIC_URL` / `GITEA_ROOT_URL` → `https://backend-gitea-staging.gqr.puter.wtf`
+- `RIVET_CLIENT_ENDPOINT` → `https://backend-staging.gqr.puter.wtf/api/rivet`
+- `GROWQR_BACKEND_URL` / `NEXT_PUBLIC_GROWQR_BACKEND_URL` → `https://backend-staging.gqr.puter.wtf`
+- `FRONTEND_ORIGIN` → `https://dashboard-staging.gqr.puter.wtf`
+- `INTERVIEW_SERVICE_URL` / `NEXT_PUBLIC_INTERVIEW_WS_URL` → `https://interview-staging.gqr.puter.wtf` / `wss://interview-staging.gqr.puter.wtf`
+- `ROLEPLAY_SERVICE_URL` / `NEXT_PUBLIC_ROLEPLAY_WS_URL` → `https://roleplay-staging.gqr.puter.wtf` / `wss://roleplay-staging.gqr.puter.wtf`
+- `QSCORE_SERVICE_URL` → `https://qscore-staging.gqr.puter.wtf`
+- `RESUME_SERVICE_URL` → `https://resume-staging.gqr.puter.wtf`
+- `USER_SERVICE_URL` / `PUBLIC_BASE_URL` → `https://user-staging.gqr.puter.wtf`
+- `DATABASE_URL` / Redis URLs → use internal compose service names (`postgres`, `redis`) unless binding to host for debugging
+
+## Docker build tips
+
+- Always add a `.dockerignore` on the VPS to reduce build context:
+
+```
+node_modules
+.next
+.git
+screenshots
+tsconfig.tsbuildinfo
+.DS_Store
+._*
+*.tgz
+```
+
+- For Node.js projects, if `package-lock.json` is stale, `npm ci` may fail. Use `npm install --legacy-peer-deps` as a fallback.
+- For Next.js frontends, the build requires significant RAM. If the VPS is small, consider building locally with `npm run build` and copying only the `.next/` directory and `public/` to the VPS.
+
+## Things to preserve for future services
+
+- Always check Git state before deployment.
+- Prefer Gitea remote `gitea` for staging branches.
+- Create `staging` branch from the currently validated deploy branch.
+- Push `staging` to Gitea before deploying.
+- Copy `.env` to the VPS with restrictive permissions.
+- Bind Docker service ports to `127.0.0.1`, not `0.0.0.0`.
+- Use unique local port ranges for each service.
+- Expose APIs only through Caddy subdomains.
+- Validate Caddy before reload.
+- Confirm both localhost health and public HTTPS health.
+- Keep deployment directories under `/opt/growqr/`.
+- After a VPS resize/reboot, remember to restart all stopped Docker Compose stacks.
+- Run database migrations for new backends before starting the API container.
+
+## Final staging polish: auth, CORS, service URLs, and restart policy
+
+Performed on 2026-06-05 after the dashboard exposed a stale `localhost:8007` browser request and backend `/home/feed` returned 500s from miswired user-service calls.
+
+Canonical staging URLs now used consistently:
+
+| Surface | URL |
+|---|---|
+| Dashboard | `https://dashboard-staging.gqr.puter.wtf` |
+| Backend API | `https://backend-staging.gqr.puter.wtf` |
+| Backend Gitea | `https://backend-gitea-staging.gqr.puter.wtf` |
+| Interview | `https://interview-staging.gqr.puter.wtf` |
+| Roleplay | `https://roleplay-staging.gqr.puter.wtf` |
+| QScore | `https://qscore-staging.gqr.puter.wtf` |
+| Resume Builder | `https://resume-staging.gqr.puter.wtf` |
+| User Service | `https://user-staging.gqr.puter.wtf` |
+
+Applied consistency fixes:
+
+- Copied the same Clerk publishable/secret/JWKS/issuer values from local envs into all deployed service envs that use or may validate Clerk tokens.
+- Set `NODE_ENV=production` for backend/dashboard and `ENV=production` for FastAPI-style staging services.
+- Replaced stale downstream URLs (`localhost`, `host.docker.internal`) with staging HTTPS URLs where cross-service calls happen through Caddy.
+- Set CORS origins to include at least `https://dashboard-staging.gqr.puter.wtf` and `https://backend-staging.gqr.puter.wtf` across services.
+- Patched dashboard leaderboard/artifact defaults so browser code falls back to `/api/growqr/services/*`, not `http://localhost:8007` / `:8008`.
+- Rebuilt `growqr-dashboard` so `NEXT_PUBLIC_*` values were baked into the production bundle.
+- Recreated service containers with updated env and set Docker restart policy to `unless-stopped` for deployed service containers.
+
+Verification commands:
+
+```bash
+# No baked frontend localhost service URLs
+ssh gqr-temp 'docker exec growqr-dashboard sh -lc "grep -R \"localhost:800[2378]\|127.0.0.1:800[2378]\" -n .next/static .next/server 2>/dev/null | head || true"'
+
+# Public health checks
+for url in \
+ https://dashboard-staging.gqr.puter.wtf/ \
+ https://backend-staging.gqr.puter.wtf/healthz \
+ https://backend-gitea-staging.gqr.puter.wtf/api/v1/version \
+ https://interview-staging.gqr.puter.wtf/health \
+ https://roleplay-staging.gqr.puter.wtf/health \
+ https://qscore-staging.gqr.puter.wtf/health \
+ https://resume-staging.gqr.puter.wtf/health \
+ https://user-staging.gqr.puter.wtf/health; do
+ curl -ksS -o /tmp/out -w "%{http_code} %{url_effective}\n" "$url"
+ head -c 160 /tmp/out; echo
+done
+
+# CORS preflight example
+curl -ksSI -X OPTIONS https://backend-staging.gqr.puter.wtf/healthz \
+ -H 'Origin: https://dashboard-staging.gqr.puter.wtf' \
+ -H 'Access-Control-Request-Method: GET' \
+ -H 'Access-Control-Request-Headers: authorization,content-type'
+```
+
+Expected state after polish:
+
+- All public health checks return `200`.
+- CORS preflights include `access-control-allow-origin: https://dashboard-staging.gqr.puter.wtf`.
+- `growqr-backend` can fetch health from user, resume, interview, roleplay, and qscore via their staging HTTPS URLs.
+- Dashboard production bundle contains no `localhost:8007`, `localhost:8008`, `127.0.0.1:8007`, or `127.0.0.1:8008` service URLs.
+
+Additional actor/runtime polish:
+
+- Added/passed `RIVET_RUNNER_VERSION=staging-20260605-polish` for the backend image/build so RivetKit self-hosted runner stops warning about unversioned actors.
+- Verified `growqr-rivet` is running and backend starts without the `RIVET_RUNNER_VERSION is not set` warning.
+- Verified backend `/home/feed` returns `200` with a trusted service token smoke test after the user-service URL fix.
+
+## Staging fix: onboarding QScore baseline and Clerk avatar image loading
+
+Performed on 2026-06-05 after a fresh-account onboarding showed three different Q Score states:
+
+- onboarding completion screen: static `QX Score · 35`
+- dashboard header: home-feed fallback score `47`
+- `/agents/qscore`: `Not ready` / `Not computed yet`
+
+Code changes deployed:
+
+| Repo | Staging commit | Purpose |
+|---|---|---|
+| `growqr-backend` | `213987a fix: persist onboarding qscore baseline` | Persists the onboarding baseline as a real Q Score projection when onboarding is completed and the account has no existing Q Score signals. |
+| `growqr-dashboard` | `08f0250 fix: align qscore header and avatar images` | Removes the fake header default score, shows an awaiting state until the backend returns a score, and bypasses Next image optimization for Clerk avatars. |
+
+Backend behavior after this fix:
+
+- On `PATCH /users/me`, if `preferences.onboarding.completed_at` is present and the user has no existing Q Score signals/projection, backend seeds:
+ - `grow_qscore_latest.signal_id = onboarding.completed_baseline`
+ - `score = 35`
+ - `source = onboarding`
+ - `grow_qscore_projection_state.score = 35`
+- `/home/feed` also lazily seeds the same baseline from user-service preferences before building the identity rail.
+- `/services/qscore/current` also lazily seeds before reading the Q Score page data, so direct navigation to `/agents/qscore` becomes consistent after a fresh onboarding.
+- Existing users with any Q Score signal or non-zero projection are not overwritten.
+
+Dashboard behavior after this fix:
+
+- The top bar no longer initializes QX Score to the fake `76` or keeps stale fallback values after failed fetches.
+- Header score now renders `—` / `Awaiting baseline` until the backend returns a real score.
+- Clerk avatars use `next/image` with `unoptimized` so remote Clerk/Google avatar URLs do not fail through Next's image optimizer.
+- `next.config.mjs` also allows common Clerk/Google/Gravatar remote hosts for other optimized image usage.
+
+Deployment commands used:
+
+```bash
+# Local verification before deploy
+cd /Users/puter/Workspace/growqr/growqr-backend
+npm run typecheck
+npm run build
+
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+npm run build
+
+# Push staging branches
+cd /Users/puter/Workspace/growqr/growqr-backend
+git push origin staging
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+git push origin staging
+
+# Copy changed files without overwriting remote .env / compose staging patches
+scp growqr-backend/src/events/onboarding-qscore.ts gqr-temp:/opt/growqr/growqr-backend/src/events/onboarding-qscore.ts
+scp growqr-backend/src/routes/users.ts growqr-backend/src/routes/services.ts gqr-temp:/opt/growqr/growqr-backend/src/routes/
+scp growqr-backend/src/home/home-feed.ts gqr-temp:/opt/growqr/growqr-backend/src/home/
+scp growqr-dashboard/components/layout/TopBar.tsx gqr-temp:/opt/growqr/growqr-dashboard/components/layout/TopBar.tsx
+scp growqr-dashboard/next.config.mjs gqr-temp:/opt/growqr/growqr-dashboard/next.config.mjs
+
+# Rebuild/recreate only affected services
+ssh gqr-temp 'cd /opt/growqr/growqr-backend && docker-compose -p growqr-backend-staging build backend && docker-compose -p growqr-backend-staging up -d backend'
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml build dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d dashboard'
+```
+
+Verification commands:
+
+```bash
+ssh gqr-temp 'docker ps --filter name=growqr-backend --filter name=growqr-dashboard --format "{{.Names}} {{.Status}}"'
+ssh gqr-temp 'curl -fsS http://127.0.0.1:18012/healthz && echo'
+curl -fsS https://backend-staging.gqr.puter.wtf/healthz
+curl -fsSI https://dashboard-staging.gqr.puter.wtf | head -n 1
+
+# Ensure new backend helper is in the running image
+ssh gqr-temp 'docker exec growqr-backend sh -lc "grep -R \"completed onboarding baseline\" -n /app/dist | head -5"'
+
+# Ensure old fake dashboard score initializer is gone from built assets
+ssh gqr-temp 'docker exec growqr-dashboard sh -lc "grep -R \"useState(76)\" -n /app/.next/server /app/.next/static 2>/dev/null || true"'
+```
+
+Expected user-facing result:
+
+- A fresh onboarded account that has no service activity should consistently show Q Score `35` in the onboarding baseline, dashboard header, and Q Score page after refresh/navigation.
+- Once real service signals arrive, the backend projection replaces the empty state with the computed readiness score and signal ledger.
+- The top-right account image should render instead of showing a broken optimized image response.
+
+## Staging fix: hide mission mocks in production and fix AppShell sidebar avatar
+
+Performed on 2026-06-05 after the staging Missions page showed mock `Interview-to-Offer Accelerator` data to a fresh production-like account.
+
+Code changes deployed:
+
+| Repo | Staging commit | Purpose |
+|---|---|---|
+| `growqr-dashboard` | `c7bbfb8 fix: hide demo missions in production` | Gates mission mock fallbacks behind `NEXT_PUBLIC_SHOW_DEMO_MISSIONS=true`; production/staging now render real backend data or empty states. |
+| `growqr-dashboard` | `95f0e75 fix: render Clerk avatars without optimizer` | Applies the same Clerk avatar image fix to the AppShell sidebar and the top-bar dropdown avatar. |
+
+Behavior after this fix:
+
+- `/missions/active` no longer falls back to `MOCK_ACTIVE_SNAPSHOTS` unless `NEXT_PUBLIC_SHOW_DEMO_MISSIONS=true`.
+- `/missions/available` no longer falls back to `MOCK_AVAILABLE_MISSIONS` unless `NEXT_PUBLIC_SHOW_DEMO_MISSIONS=true`.
+- `/missions/[id]` no longer resolves mock mission details unless the demo flag is enabled.
+- Production/staging empty state for no active missions: `Nothing active yet` with a CTA to browse available missions.
+- Production/staging empty state for no available missions: `No missions available yet`.
+- Sidebar and account dropdown Clerk avatars use `next/image` with `unoptimized` to avoid broken Next image optimizer responses for Clerk/remote account-image URLs.
+
+Demo mode:
+
+```bash
+# Only set this in local/dev/demo deployments, not staging production-like deployments.
+NEXT_PUBLIC_SHOW_DEMO_MISSIONS=true
+```
+
+Deployment commands used:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+npm run build
+git push origin staging
+
+scp 'growqr-dashboard/app/missions/(list)/active/page.tsx' 'gqr-temp:/opt/growqr/growqr-dashboard/app/missions/(list)/active/page.tsx'
+scp 'growqr-dashboard/app/missions/(list)/available/page.tsx' 'gqr-temp:/opt/growqr/growqr-dashboard/app/missions/(list)/available/page.tsx'
+scp 'growqr-dashboard/app/missions/[id]/page.tsx' 'gqr-temp:/opt/growqr/growqr-dashboard/app/missions/[id]/page.tsx'
+scp growqr-dashboard/lib/demo-flags.ts gqr-temp:/opt/growqr/growqr-dashboard/lib/demo-flags.ts
+scp growqr-dashboard/components/layout/Sidebar.tsx growqr-dashboard/components/layout/TopBar.tsx gqr-temp:/opt/growqr/growqr-dashboard/components/layout/
+
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml build dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d dashboard'
+```
+
+Verification commands:
+
+```bash
+ssh gqr-temp 'docker ps --filter name=growqr-dashboard --format "{{.Names}} {{.Status}}"'
+curl -ksS -o /dev/null -w "%{http_code}\n" https://dashboard-staging.gqr.puter.wtf/
+
+# Staging should not set this flag.
+ssh gqr-temp 'docker exec growqr-dashboard sh -lc "printenv NEXT_PUBLIC_SHOW_DEMO_MISSIONS || true; printenv NODE_ENV"'
+
+# The active missions build should include the flag-gated path, not unconditional mock fallback.
+ssh gqr-temp 'docker exec growqr-dashboard sh -lc "grep -R \"NEXT_PUBLIC_SHOW_DEMO_MISSIONS\|showDemoMissions\" -n /app/.next/server/app/missions /app/.next/static/chunks/app/missions 2>/dev/null | head"'
+```
+
+## Staging fix: resume upload parsing state
+
+Performed on 2026-06-05 after uploaded resumes showed only `Uploaded`, while the background parser was still working, and clicking Edit could surface a blocking `Failed to parse resume` browser alert.
+
+Code change deployed:
+
+| Repo | Staging commit | Purpose |
+|---|---|---|
+| `growqr-dashboard` | `be9671e fix: show resume parsing state` | Treats uploaded resumes as parsing/processing, polls the resume API until parsed, and replaces blocking alerts with an in-UI parsing status modal. |
+
+Behavior after this fix:
+
+- A newly uploaded resume with `status=uploaded` now displays as `Parsing` with a spinner.
+- The resume card shows a processing overlay instead of implying it is ready.
+- The resume list polls `/resumes` every 3s while any resume remains `uploaded` or an edit-triggered parse is open.
+- Clicking Edit on an uploaded resume opens a non-blocking `Preparing resume` modal.
+- If parse-on-demand fails while background parsing is still underway, the UI keeps the card visible, shows the message inline, and continues polling instead of using `alert()`.
+- When the API reports the resume has moved out of `uploaded`, the modal clears and the card becomes editable.
+
+Deployment commands used:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+npm run build
+git push origin staging
+
+scp growqr-dashboard/components/resume/ResumeCard.tsx growqr-dashboard/components/resume/ResumeList.tsx gqr-temp:/opt/growqr/growqr-dashboard/components/resume/
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml build dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d dashboard'
+```
+
+Verification commands:
+
+```bash
+ssh gqr-temp 'docker ps --filter name=growqr-dashboard --format "{{.Names}} {{.Status}}"'
+curl -ksS -o /dev/null -w "%{http_code}\n" https://dashboard-staging.gqr.puter.wtf/
+ssh gqr-temp 'docker exec growqr-dashboard sh -lc "grep -R \"We.ll unlock editing\|Large PDFs can take\|Parsing resume\" -n /app/.next/static/chunks /app/.next/server 2>/dev/null | head"'
+```
+
+## Dashboard staging UI review deploy — PRM-32/33/34/37/44
+
+Date: 2026-06-05
+Repo: `/Users/puter/Workspace/growqr/growqr-dashboard`
+Branch: `staging`
+Commit: `61d0bea fix: polish dashboard review items`
+Remote: `origin` → `https://git.openputer.com/puter/growqr-dashboard.git`
+VPS path: `/opt/growqr/growqr-dashboard`
+Compose project: `growqr-dashboard-staging`
+Container: `growqr-dashboard`
+Public URL: `https://dashboard-staging.gqr.puter.wtf`
+
+Changes deployed:
+
+- PRM-33: Added `GettingStartedHero` above `AgentSquad`; uses Clerk user data, `useDay()`, and `getRewards(day)` for streak; camera button opens Clerk `UserProfile` via `openUserProfile()`.
+- PRM-44: Added global `growqr:toggle-chat` event wiring and mounted `HelperChatToggle` from `AppShell`; TopBar chat button dispatches the event and collapses label on mobile.
+- PRM-37: Added `QScoreWheel` to `IdentityRail`; growth drivers display weight %, score %, chevron affordance, and clickable rows.
+- PRM-34: Standardized resume and cover-letter template thumbnail previews to `aspect-[8.5/11]`.
+- PRM-32: Added `docs/user-qr-code-plan.md` design plan.
+
+Local verification:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+npm run build
+# Result: compiled successfully; zero build errors.
+git diff --check
+# Result: clean.
+```
+
+Deployment commands used:
+
+```bash
+cd /Users/puter/Workspace/growqr/growqr-dashboard
+git add app/page.tsx components/AppShell.tsx \
+ components/coverLetter/CoverLetterEditor/tabs/CoverLetterDesignTab.tsx \
+ components/home/IdentityRail.tsx components/home/GettingStartedHero.tsx \
+ components/layout/HelperChatToggle.tsx components/layout/TopBar.tsx \
+ components/qscore/QScoreWheel.tsx \
+ components/resume/ResumeEditor/tabs/DesignTab.tsx \
+ components/resume/TemplateCard.tsx docs/user-qr-code-plan.md
+git commit -m "fix: polish dashboard review items"
+git push origin staging
+
+TMP=/tmp/growqr-dashboard-staging-$(date +%s).tar.gz
+tar --exclude='.git' --exclude='.next' --exclude='node_modules' --exclude='.env' --exclude='._*' -czf "$TMP" .
+scp "$TMP" gqr-temp:/tmp/growqr-dashboard-staging.tar.gz
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && tar -xzf /tmp/growqr-dashboard-staging.tar.gz && find . -name "._*" -type f -delete && chown -R root:root . && chmod 600 .env && echo 61d0bea > .deployed-dashboard-git-sha'
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build'
+```
+
+Post-deploy verification:
+
+```bash
+curl -I http://127.0.0.1:13000/
+curl -I https://dashboard-staging.gqr.puter.wtf/
+ssh gqr-temp 'docker inspect -f "{{.Name}} {{.State.Status}} {{.State.Running}} restart={{.HostConfig.RestartPolicy.Name}}" growqr-dashboard'
+ssh gqr-temp 'docker exec growqr-dashboard sh -lc "find /app/.next -path /app/.next/cache -prune -o -type f -print | xargs grep -n \"localhost:8007\\|localhost:8008\\|127.0.0.1:8007\\|127.0.0.1:8008\" 2>/dev/null || true"'
+```
+
+Results:
+
+- Local and remote Docker builds succeeded.
+- Public dashboard returned `HTTP/2 200`.
+- Local dashboard returned `HTTP/1.1 200 OK` on `127.0.0.1:13000`.
+- Container running with `restart=unless-stopped`.
+- Runtime bundle audit excluding `.next/cache` found no old `localhost:8007/8008` service references.
+
+Note: Docker build emitted transient Google Fonts fetch retry messages, then completed successfully.
+
+## Dashboard idle/data-fetching stability fix (2026-06-05)
+
+Root cause found in staging: dashboard server-side proxy requests were going from the dashboard container to `https://backend-staging.gqr.puter.wtf`, causing public HTTPS/Caddy hairpin timeouts from inside Docker after idle/reconnect periods. This made `/api/growqr/*` intermittently return `backend_timeout`, which caused the home/resume UI to replace real state with empty fallback state.
+
+Fix applied:
+
+- Dashboard runtime env now keeps public client URLs public, but uses internal Docker DNS for server-side proxying:
+ - `NEXT_PUBLIC_GROWQR_BACKEND_URL=https://backend-staging.gqr.puter.wtf`
+ - `GROWQR_BACKEND_URL=http://growqr-backend:4000`
+- `/opt/growqr/growqr-dashboard/docker-compose.staging.yml` attaches the dashboard container to the backend compose network:
+
+```yaml
+services:
+ dashboard:
+ networks:
+ - default
+ - growqr-backend
+
+networks:
+ growqr-backend:
+ external: true
+ name: growqr-backend-staging_default
+```
+
+Verification commands:
+
+```bash
+ssh gqr-temp 'docker exec growqr-dashboard sh -lc "wget -qO- --timeout=5 http://growqr-backend:4000/healthz"'
+ssh gqr-temp 'docker logs --since=5m growqr-dashboard 2>&1 | grep -i backend_timeout || true'
+```
+
+Frontend robustness shipped in `growqr-dashboard` commit `0be0b65`:
+
+- Client API retries once with a fresh Clerk token (`getToken({ skipCache: true })`) on `401/403`.
+- Home feed and TopBar send Clerk bearer tokens to `/api/growqr/*`, preserve last good data on transient failures, and refresh on focus/online/visibility restore.
+- Resume list preserves last good data instead of blanking after idle, refreshes in the background, and reconciles uploaded resumes before showing parse errors.
+- Resume edit flow no longer treats an on-demand parse race/timeout as terminal; it keeps polling and opens the editor automatically once the stored resume reaches `draft`/`complete`.
+
+## Resume upload/edit parsing correction (2026-06-05)
+
+Problem: staging had drifted away from the original `growqr-app/frontend` resume flow. Uploads could trigger/background-track parsing and the dashboard UI waited/polled as if parsing had already begun. The intended flow is: upload stores the PDF as `uploaded`; parsing starts only when the user clicks **Edit Resume**; successful parse transitions the resume to `draft` and opens the editor.
+
+Source commits pushed:
+
+- `growqr-dashboard` `staging`: `42ba346 fix: parse uploaded resumes on edit`
+- `growqr-app` `staging`: `e1b38d2 fix: defer resume parsing until edit`
+
+Files deployed to `gqr-temp`:
+
+- `/opt/growqr/resume-builder/app/api/v1/resumes.py`
+- `/opt/growqr/growqr-dashboard/app/api/growqr/[...path]/route.ts`
+- `/opt/growqr/growqr-dashboard/components/resume/ResumeList.tsx`
+- `/opt/growqr/growqr-dashboard/components/resume/ResumeUpload.tsx`
+
+Backups were written with `.pre-edit-parse-flow-bak` before replacing files.
+
+Docker Compose deployment commands used:
+
+```bash
+ssh gqr-temp 'cd /opt/growqr/resume-builder && docker-compose -p resume-builder-staging up -d --build api'
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build dashboard'
+```
+
+Verification:
+
+```bash
+ssh gqr-temp 'cd /opt/growqr/resume-builder && docker-compose -p resume-builder-staging ps'
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml ps'
+curl -fsS https://resume-staging.gqr.puter.wtf/health
+curl -fsS -I https://dashboard-staging.gqr.puter.wtf/features/resume
+```
+
+Results:
+
+- `growqr_resume_api` rebuilt via Docker Compose and is healthy.
+- `growqr-dashboard` rebuilt via Docker Compose and returns `HTTP/2 200` on the public resume route.
+- Resume upload endpoint no longer dispatches the orchestrator background parse task.
+- Dashboard proxy timeout default increased to 180 seconds so on-edit parsing can complete through `/api/growqr/services/resume` without a premature proxy `backend_timeout`.
+
+## Resume stored-PDF parse proxy fix (2026-06-05)
+
+Follow-up issue from browser testing: clicking an uploaded resume showed `Failed to parse resume`; DevTools showed a FastAPI validation error:
+
+```json
+{"detail":[{"type":"missing","loc":["body","file"],"msg":"Field required"}]}
+```
+
+Root cause: the dashboard called the correct client path:
+
+```txt
+/api/growqr/services/resume/parse/resume//parse
+```
+
+but `growqr-backend` extracted the resume-service subpath with:
+
+```ts
+c.req.path.split("/resume/")[1]
+```
+
+Because the target path itself contains `/resume/`, this truncated the forwarded route to `parse`, so the resume service received:
+
+```txt
+POST /api/v1/parse
+```
+
+instead of:
+
+```txt
+POST /api/v1/parse/resume//parse
+```
+
+Fixes shipped:
+
+- `growqr-backend` `c47e6de fix: preserve nested resume service proxy paths`
+ - Uses the first `/resume/` marker index and slices the remainder, preserving nested `/resume/` path segments.
+- `growqr-dashboard` `624c5af fix: show uploaded resumes as ready to parse`
+ - Uploaded resumes now display as `Uploaded — click Edit to parse`.
+ - The spinner overlay only appears during an actual Edit-triggered parse request.
+
+Docker Compose deployment commands used:
+
+```bash
+ssh gqr-temp 'cd /opt/growqr/growqr-backend && docker-compose -p growqr-backend-staging up -d --build backend'
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build dashboard'
+```
+
+Safe route verification used a non-existent UUID, so no resume was parsed or mutated:
+
+```bash
+curl -X POST \
+ -H "Authorization: Bearer $SERVICE_TOKEN" \
+ -H "x-growqr-user: user_3EX1LG3gBk3KY6kfD9PiTkWubs4" \
+ http://127.0.0.1:18012/services/resume/parse/resume/00000000-0000-0000-0000-000000000000/parse
+```
+
+Expected/observed result:
+
+```txt
+404 {"detail":"Resume not found"}
+```
+
+Resume-service log confirmed the corrected forwarded path:
+
+```txt
+POST /api/v1/parse/resume/00000000-0000-0000-0000-000000000000/parse HTTP/1.1
+```
+
+Public verification:
+
+```bash
+curl -I https://backend-staging.gqr.puter.wtf/healthz
+curl -I https://dashboard-staging.gqr.puter.wtf/features/resume
+```
+
+Both returned `HTTP/2 200`.
+
+## Interview live-avatar, personalization, MediaPipe, and video-analysis fix (2026-06-05)
+
+Problem: after moving the interview UI from `growqr-app/frontend`/orchestrator to `growqr-dashboard`/`growqr-backend`, several orchestration behaviors were missing or incomplete:
+
+- The dashboard build did not ship the MediaPipe runtime files used by `useFaceFeedback`, so live camera coaching/presence analysis could not reliably start in production.
+- `growqr-backend` called `interview-service` directly but did not recreate the orchestrator's enriched `user_context` flow (`candidate_name`, resume skills/experience/education, LinkedIn headline/summary/experience, and opt-in `candidate_profile`).
+- `interview-service` page-state always returned `resume_available=false` and `linkedin_available=false`, hiding the personalization checkbox.
+- The browser video-analysis upload flow posted with an empty body while `growqr-backend` tried to parse JSON before proxying the request, so recorded session video registration could fail before the presigned upload flow began.
+- LiveAvatar envs were not enabled on the staging interview/roleplay containers.
+- Interview-service supported only Docker-internal MinIO presign URLs; browsers need public HTTPS presign endpoints.
+
+Source commits pushed:
+
+- `growqr-dashboard` `staging`: `4c95dcb fix: restore interview video analysis assets`
+- `growqr-backend` `staging`: `aa8f285 fix: enrich interview service context`
+- `interview-service` `staging`: `78c7070 fix: support public interview artifact presigning`
+- `roleplay-service` `staging`: `6e64519 fix: support liveavatar api alias`
+
+Key source changes:
+
+- `growqr-dashboard/package.json`
+ - Added `@mediapipe/tasks-vision`.
+ - Added `copy-mediapipe`, `predev`, and `prebuild` scripts.
+ - `copy-mediapipe` copies `vision_bundle.mjs` and the MediaPipe WASM files from `node_modules` into `public/mediapipe` at build time.
+- `growqr-dashboard/public/mediapipe/face_landmarker.task`
+ - Checked in the face landmark model required by `useFaceFeedback`.
+- `growqr-dashboard/lib/api/interview.ts` and `lib/api/roleplay.ts`
+ - Video upload-url/uploaded calls now send `{}` JSON bodies for compatibility with older backend deployments.
+- `growqr-dashboard/app/features/interview/preview/page.tsx` and `app/agents/interview/preview/page.tsx`
+ - Regenerate preserves `personalize=1` so regenerated plans keep the grounded candidate profile.
+- `growqr-backend/src/routes/services.ts`
+ - Recreates the orchestrator context enrichment flow by reading user-service profile plus resume/social state.
+ - Enriches interview configure payloads with `candidate_name` and, when requested, a compact `candidate_profile` built from resume + LinkedIn data.
+ - Enriches `/services/interview/page-state` with real `resume_available` and `linkedin_available` flags.
+ - Video upload proxy routes no longer require JSON parsing before proxying.
+- `growqr-backend/src/services/product-service-clients.ts`
+ - Video upload proxy calls are explicit `POST`s even when no body is required.
+- `interview-service/app/core/config.py`, `app/services/storage.py`, and `app/api/artifacts.py`
+ - Added `S3_PUBLIC_ENDPOINT_URL` support for browser-reachable presigned URLs.
+ - Added compatibility with the existing `LIVEAVATAR_API` env alias.
+- `roleplay-service/app/core/config.py`
+ - Added compatibility with the existing `LIVEAVATAR_API` env alias.
+
+Staging env changes applied on `gqr-temp` (values redacted in this runbook):
+
+```txt
+/opt/growqr/interview-service/.env
+ LIVEAVATAR_ENABLED=true
+ LIVEAVATAR_API_KEY=
+ LIVEAVATAR_API=
+ S3_PUBLIC_ENDPOINT_URL=https://interview-minio-staging.gqr.puter.wtf
+
+/opt/growqr/roleplay-service/.env
+ LIVEAVATAR_ENABLED=true
+ LIVEAVATAR_API_KEY=
+ LIVEAVATAR_API=
+ S3_PUBLIC_ENDPOINT_URL=https://roleplay-minio-staging.gqr.puter.wtf
+```
+
+Backups were created with:
+
+```txt
+.env.pre-interview-fix-bak-
+```
+
+Caddy blocks added for browser-reachable, presigned MinIO upload/download URLs:
+
+```caddy
+interview-minio-staging.gqr.puter.wtf {
+ reverse_proxy 127.0.0.1:19000
+}
+
+roleplay-minio-staging.gqr.puter.wtf {
+ reverse_proxy 127.0.0.1:19010
+}
+```
+
+Validated and reloaded Caddy:
+
+```bash
+caddy validate --config /etc/caddy/Caddyfile
+systemctl reload caddy
+```
+
+Docker Compose deployment commands used:
+
+```bash
+ssh gqr-temp 'cd /opt/growqr/growqr-backend && docker-compose -p growqr-backend-staging up -d --build backend'
+ssh gqr-temp 'cd /opt/growqr/interview-service && docker-compose -p interview-service up -d --build api'
+ssh gqr-temp 'cd /opt/growqr/roleplay-service && docker-compose -p roleplay-service up -d --build api'
+ssh gqr-temp 'cd /opt/growqr/growqr-dashboard && docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build dashboard'
+```
+
+Verification commands:
+
+```bash
+curl -fsS http://127.0.0.1:18012/healthz
+curl -fsS http://127.0.0.1:18007/health
+curl -fsS http://127.0.0.1:18008/health
+curl -I https://dashboard-staging.gqr.puter.wtf/mediapipe/vision_bundle.mjs
+curl -I https://dashboard-staging.gqr.puter.wtf/mediapipe/wasm/vision_wasm_internal.wasm
+curl -I https://dashboard-staging.gqr.puter.wtf/mediapipe/face_landmarker.task
+curl -I https://interview-minio-staging.gqr.puter.wtf/minio/health/live
+curl -I https://roleplay-minio-staging.gqr.puter.wtf/minio/health/live
+```
+
+Observed:
+
+- Backend, interview-service, roleplay-service, and dashboard all healthy.
+- Dashboard route returns `HTTP/2 200`.
+- MediaPipe bundle, WASM, and `face_landmarker.task` all return `HTTP/2 200`.
+- Both MinIO public health endpoints return `HTTP/2 200`.
+- `/services/interview/page-state` now returns real personalization availability (verified with service-token probe: `resume_available=true` for the probed staging user).
+- A presign probe against an existing interview session returned a browser-reachable URL beginning with `https://interview-minio-staging.gqr.puter.wtf/...`.
+
+### LiveAvatar sandbox-mode correction and VIP codes (2026-06-05)
+
+Follow-up from browser comparison with the production interview page: staging was still showing the static interviewer headshot even when `avatar_mode=video` was stored on the interview session.
+
+Root cause:
+
+- `LIVEAVATAR_ENABLED=true` and the API key were present, but `LIVEAVATAR_SANDBOX` was still at the service default of `true`.
+- The selected Payal/Emma/John persona avatar IDs are not supported in LiveAvatar sandbox mode. LiveAvatar returned `400 Bad Request` with `This avatar is not supported in sandbox mode`, so the service correctly degraded to the static-photo path.
+
+Fix:
+
+```txt
+/opt/growqr/interview-service/.env
+ LIVEAVATAR_SANDBOX=false
+ INTERVIEW_UNLIMITED_PHRASE=GQR-VIDEO-VIP-2026,GQR-LIVEAVATAR-TEST,PUTER-VIDEO-TEST
+
+/opt/growqr/roleplay-service/.env
+ LIVEAVATAR_SANDBOX=false
+ ROLEPLAY_UNLIMITED_PHRASE=GQR-VIDEO-VIP-2026,GQR-LIVEAVATAR-TEST,PUTER-VIDEO-TEST
+```
+
+Source commits:
+
+- `interview-service` `staging`: `7c67ceb fix: support multiple interview vip codes`
+- `roleplay-service` `staging`: `90392e0 fix: support multiple roleplay vip codes`
+
+Deployment:
+
+```bash
+ssh gqr-temp 'cd /opt/growqr/interview-service && docker-compose -p interview-service up -d --build api'
+ssh gqr-temp 'cd /opt/growqr/roleplay-service && docker-compose -p roleplay-service up -d --build api'
+```
+
+Verification:
+
+- Container settings now show `LIVEAVATAR_ENABLED=True`, `LIVEAVATAR_SANDBOX=False`, API key present, and all three VIP codes loaded.
+- A staging backend configure call using `unlimited_phrase=GQR-LIVEAVATAR-TEST` produced `config.avatar_mode=video` for a user already at the video cap.
+- A direct websocket smoke test for that configured session returned:
+
+```txt
+session.ready has_avatar=True provider=liveavatar livekit_url=wss://heygen-...
+```
+
+User-facing test instruction: choose **Video** mode on Interview Setup, expand/enter VIP code, and use any of:
+
+```txt
+GQR-VIDEO-VIP-2026
+GQR-LIVEAVATAR-TEST
+PUTER-VIDEO-TEST
+```
+
+## 2026-06-05 — Roleplay LiveAvatar parity polish
+
+Goal: make staging Roleplay behave like the production GrowQR app/orchestrator path, same as the Interview LiveAvatar polish.
+
+### Source changes
+
+- `growqr-backend/src/routes/services.ts`
+ - Added roleplay configure enrichment equivalent to the production orchestrator/A2A flow.
+ - `POST /services/roleplay/configure` now resolves Grow user context from user-service, resume-builder, and social-branding, then forwards:
+ - `metadata.candidate_name`
+ - `metadata.target_role`
+ - `metadata.candidate_role`
+ - `metadata.difficulty`
+ - `metadata.candidate_profile`
+ - `metadata.context_notes`
+ - `user_context`
+ - qscore fallback/defaults
+ - `GET /services/roleplay/page-state` now augments roleplay page-state with `resume_available` and `linkedin_available` just like interview page-state.
+
+- `roleplay-service/app/services/storage.py`
+ - Fixed public MinIO presigning so explicit staging domains like `https://roleplay-minio-staging.gqr.puter.wtf` are preserved.
+ - The old fallback rewrite now only changes the exact Docker-internal hostname `minio` to `localhost`; it no longer rewrites public domains containing the word `minio`.
+
+### Commits deployed
+
+```txt
+growqr-backend staging: 170d358 fix: enrich roleplay service context
+roleplay-service staging: e3d50e5 fix: preserve public roleplay minio presign host
+```
+
+### Staging deployment notes
+
+During tar-based redeploy, the staging-only compose/env patches must be preserved or re-applied:
+
+- Backend API port: `127.0.0.1:18012:4000`
+- Roleplay API port: `127.0.0.1:18008:8000`
+- Roleplay Postgres: `127.0.0.1:15441:5432`
+- Roleplay MinIO: `127.0.0.1:19010:9000`, `127.0.0.1:19011:9001`
+- Backend env URLs must point at staging HTTPS service domains, not local worktree defaults.
+- Backend `RIVET_RUNNER_VERSION` must be set to a non-`dev` staging value to avoid Rivet runner version collisions.
+- Roleplay env must include:
+
+```txt
+BASE_URL=https://roleplay-staging.gqr.puter.wtf
+S3_ENDPOINT_URL=http://minio:9000
+S3_PUBLIC_ENDPOINT_URL=https://roleplay-minio-staging.gqr.puter.wtf
+LIVEAVATAR_ENABLED=true
+LIVEAVATAR_SANDBOX=false
+ROLEPLAY_UNLIMITED_PHRASE=GQR-VIDEO-VIP-2026,GQR-LIVEAVATAR-TEST,PUTER-VIDEO-TEST
+CORS_ORIGINS=https://dashboard-staging.gqr.puter.wtf,https://backend-staging.gqr.puter.wtf
+```
+
+### Verification performed
+
+Health:
+
+```bash
+curl -fsS http://127.0.0.1:18012/healthz
+curl -fsS http://127.0.0.1:18008/health
+```
+
+Roleplay configure smoke through backend with VIP video mode returned:
+
+```txt
+session_id=
+avatar_mode=video
+metadata includes candidate_profile/context_notes
+```
+
+Roleplay presigned upload URL now starts with the browser-reachable HTTPS MinIO domain:
+
+```txt
+https://roleplay-minio-staging.gqr.puter.wtf/roleplay-artifacts/...
+```
+
+End-to-end WebSocket smoke:
+
+```txt
+wss://roleplay-staging.gqr.puter.wtf/api/v1/roleplays/session/
+→ send {"type":"session.start"}
+→ received session.ready with avatar.provider=liveavatar and livekit_url present
+```
+
+Tested VIP code:
+
+```txt
+GQR-LIVEAVATAR-TEST
+```
+
+## 2026-06-06 — Dashboard mission runtime + home feed wiring polish
+
+Goal: keep the existing dashboard UI, but wire it to the mission-first backend runtime and make Home/Missions production-ready on staging.
+
+Changes deployed:
+
+- `growqr-dashboard` staging commit `d52c160` (`fix: wire mission runtime to dashboard`)
+ - `/api/growqr/*` now guards against stale loopback backend envs in production Docker. If `GROWQR_BACKEND_URL` is accidentally `localhost:4000` / `127.0.0.1:4000`, the proxy uses `http://growqr-backend:4000` on the shared compose network.
+ - `lib/grow-api.ts` now understands `actionsByMission` and mission action endpoints:
+ - approve/reject/run/answer/snooze
+ - manual daily scrum: `POST /missions/active/:instanceId/scrum/run`
+ - Active mission cards now render backend `mission_actions` inside the existing card-deck UI and can execute HITL actions without adding new navigation/sidebar surfaces.
+- `growqr-backend` staging commit `dd48321` (`fix: keep home feed responsive`)
+ - Product service page-state calls used by Home feed now have a short timeout (`PRODUCT_SERVICE_TIMEOUT_MS`, default `3500ms`) so one slow service cannot block the dashboard.
+ - Home Feed Agent LLM refinement has a bounded timeout (`HOME_FEED_AGENT_TIMEOUT_MS`, default `8000ms`) and falls back to deterministic notifications.
+- Staging dashboard env fixed in `/opt/growqr/growqr-dashboard/.env`:
+ - `GROWQR_BACKEND_URL=http://growqr-backend:4000`
+ - `NEXT_PUBLIC_GROWQR_BACKEND_URL=https://backend-staging.gqr.puter.wtf`
+ - `GROWQR_BACKEND_TIMEOUT_MS=180000`
+
+Deployment commands used:
+
+```bash
+# Dashboard: copy only committed mission/proxy files, preserving unrelated working-tree UI edits
+cd growqr-dashboard
+git archive --format=tar HEAD \
+ 'app/api/growqr/[...path]/route.ts' \
+ 'app/missions/(list)/active/page.tsx' \
+ components/mission/ActiveMissionView.tsx \
+ components/mission/AgentCard.tsx \
+ components/mission/adapter.ts \
+ lib/grow-api.ts \
+ > /tmp/growqr-dashboard-mission-wire.tar
+scp /tmp/growqr-dashboard-mission-wire.tar gqr-temp:/tmp/
+
+# Backend: copy only responsive home-feed files
+cd growqr-backend
+git archive --format=tar HEAD \
+ src/home/home-feed-agent.ts \
+ src/services/product-service-clients.ts \
+ > /tmp/growqr-backend-home-responsive.tar
+scp /tmp/growqr-backend-home-responsive.tar gqr-temp:/tmp/
+
+ssh gqr-temp
+cd /opt/growqr/growqr-dashboard
+cp .env .env.pre-mission-wire-bak.$(date +%Y%m%d%H%M%S)
+tar -xf /tmp/growqr-dashboard-mission-wire.tar
+chmod 600 .env
+
+cd /opt/growqr/growqr-backend
+tar -xf /tmp/growqr-backend-home-responsive.tar
+
+docker-compose -p growqr-backend-staging up -d --build backend
+cd /opt/growqr/growqr-dashboard
+docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build dashboard
+```
+
+Verification performed:
+
+```bash
+# Dashboard container can reach backend over Docker DNS
+docker exec growqr-dashboard wget -qO- http://growqr-backend:4000/healthz
+# => {"ok":true}
+
+# Public app and backend are healthy
+curl -I https://dashboard-staging.gqr.puter.wtf/
+curl https://backend-staging.gqr.puter.wtf/healthz
+
+# Dashboard proxy works for mission definitions, active mission runtime, and home feed
+curl -H "Authorization: Bearer $SERVICE_TOKEN" -H "x-growqr-user: $USER_ID" \
+ http://127.0.0.1:13000/api/growqr/missions/available
+curl -H "Authorization: Bearer $SERVICE_TOKEN" -H "x-growqr-user: $USER_ID" \
+ http://127.0.0.1:13000/api/growqr/missions/active
+curl -H "Authorization: Bearer $SERVICE_TOKEN" -H "x-growqr-user: $USER_ID" \
+ http://127.0.0.1:13000/api/growqr/home/feed
+
+# Manual mission scrum endpoint works through dashboard proxy
+curl -X POST -H "Authorization: Bearer $SERVICE_TOKEN" -H "x-growqr-user: $USER_ID" \
+ http://127.0.0.1:13000/api/growqr/missions/active//scrum/run
+```
+
+Expected browser result after hard refresh:
+
+- Home tiles should show real backend notification counts/content instead of all-zero fallback tiles.
+- `/missions/available` should show the five backend mission definitions.
+- `/missions/active` should show active missions and backend action/HITL cards in the existing active mission card UI.
+
+## 2026-06-06 — Interview/Roleplay staging WebSocket endpoint fix
+
+Symptom: the dashboard preview/session UI showed `WebSocket connection error` after successful Interview configure calls.
+
+Root cause: `growqr-dashboard` staging `.env` still baked loopback WebSocket URLs into the Next.js browser bundle:
+
+```txt
+NEXT_PUBLIC_INTERVIEW_WS_URL=ws://127.0.0.1:8007/api/v1
+NEXT_PUBLIC_ROLEPLAY_WS_URL=ws://127.0.0.1:8040/api/v1
+```
+
+Those URLs work only from the VPS, not from a user's browser. The public browser endpoints must use the Caddy HTTPS domains with `wss://`.
+
+Fix deployed:
+
+- `growqr-dashboard` commit `6604ff8` (`fix: use staging websocket endpoints`)
+- Runtime/source fallback now maps `*.gqr.puter.wtf` browser sessions to:
+ - `wss://interview-staging.gqr.puter.wtf/api/v1`
+ - `wss://roleplay-staging.gqr.puter.wtf/api/v1`
+- Staging `.env` patched to explicitly bake:
+
+```txt
+NEXT_PUBLIC_INTERVIEW_WS_URL=wss://interview-staging.gqr.puter.wtf/api/v1
+NEXT_PUBLIC_ROLEPLAY_WS_URL=wss://roleplay-staging.gqr.puter.wtf/api/v1
+NEXT_PUBLIC_INTERVIEW_API_URL=/api/growqr/services/interview
+NEXT_PUBLIC_ROLEPLAY_API_URL=/api/growqr/services/roleplay
+NEXT_PUBLIC_INTERVIEW_ARTIFACTS_URL=/api/growqr/services/interview
+NEXT_PUBLIC_ROLEPLAY_ARTIFACTS_URL=/api/growqr/services/roleplay
+```
+
+Deployment command:
+
+```bash
+cd /opt/growqr/growqr-dashboard
+docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build dashboard
+```
+
+Verification:
+
+```bash
+# Dashboard bundle must not contain browser-invalid loopback WS URLs
+docker exec growqr-dashboard sh -lc '
+ for p in "localhost:8007" "127.0.0.1:8007" "localhost:8008" "127.0.0.1:8040"; do
+ echo "$p:$(grep -R -l "$p" /app/.next/static /app/.next/server 2>/dev/null | wc -l)"
+ done
+'
+# all counts should be 0
+
+# Public websocket handshake should succeed; fake session should connect then return Session not found
+# Interview: wss://interview-staging.gqr.puter.wtf/api/v1/session/
+# Roleplay: wss://roleplay-staging.gqr.puter.wtf/api/v1/roleplays/session/
+```
+
+Browser action required: hard-refresh `https://dashboard-staging.gqr.puter.wtf` so the new Next.js chunks are loaded.
+
+## 2026-06-06 — Dashboard onboarding first-login trigger fix
+
+Symptom: after signing in through the dashboard modal, a not-yet-onboarded user landed on the dashboard and the onboarding modal only appeared after a hard refresh.
+
+Root cause: immediately after modal sign-in, Clerk client state can become signed-in before a usable session token/cookie is available to the Next.js `/api/growqr/users/bootstrap` proxy. The first user bootstrap could fail once, leaving `UserProvider` with `user=null`; `OnboardingGate` therefore had no user profile to inspect until a page refresh retried bootstrap with a settled session.
+
+Fix deployed:
+
+- `growqr-dashboard` commit `1140d43` (`fix: trigger onboarding immediately after sign-in`)
+- `UserProvider` now retries user bootstrap with `getToken({ skipCache: true })` before giving up.
+- `GrowBootstrap` sends an explicit Clerk bearer token instead of relying only on server-side cookies.
+- `useOnboarding` now merges saves with `DEFAULT_ONBOARDING_DATA` and the freshest `preferences.onboarding`, so every onboarding step persists a complete onboarding object to user-service.
+
+Deployment command:
+
+```bash
+cd /opt/growqr/growqr-dashboard
+docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build dashboard
+```
+
+Verification performed:
+
+```bash
+cd growqr-dashboard
+npm run build
+
+curl -I https://dashboard-staging.gqr.puter.wtf/
+# => HTTP/2 200
+```
+
+Browser verification:
+
+1. Hard-refresh once to load commit `1140d43`.
+2. Sign out / sign in with a user whose `preferences.onboarding.completed_at` is missing.
+3. Confirm the onboarding modal opens automatically without manually refreshing.
+4. Complete onboarding and confirm `preferences.onboarding.completed_at` plus the collected fields are saved in user-service.
+
+## 2026-06-06 — Onboarding privacy-screen loop fix
+
+Symptom: the first onboarding step opened, but clicking Continue after accepting privacy terms sent the user back to the same privacy screen.
+
+Root cause: each onboarding step save calls `refreshUser()` after persisting to user-service. The previous first-login fix made `UserProvider.fetchUser()` set global `isLoading=true` for every refresh. `OnboardingGate` returned `null` while `isLoading` was true, which unmounted `AdaptiveOnboarding`; when the profile refresh completed, the modal remounted from local `step=0`, creating a loop back to the privacy screen.
+
+Fix deployed:
+
+- `growqr-dashboard` commit `dbdd681` (`fix: keep onboarding mounted during saves`)
+- `UserProvider` now shows global loading only before the first user profile arrives, not during refreshes.
+- `OnboardingGate` keeps the modal mounted while an existing user profile is refreshing.
+
+Deployment command:
+
+```bash
+cd /opt/growqr/growqr-dashboard
+docker-compose -p growqr-dashboard-staging -f docker-compose.staging.yml up -d --build dashboard
+```
+
+Verification performed:
+
+```bash
+cd growqr-dashboard
+npm run build
+curl -I https://dashboard-staging.gqr.puter.wtf/
+# => HTTP/2 200
+```
+
+Browser action required: hard-refresh the dashboard once so the new bundle is used, then continue onboarding. Step saves should no longer reset the modal back to the privacy screen.
+
+## 2026-06-06 — Onboarding Q Score baseline correction
+
+Symptom: immediately after onboarding, the dashboard showed `QX Score 100` even though a new user should start around the baseline (`35`).
+
+Root cause: `growqr-backend` projected a plain `resume.uploaded` event as a perfect `100` signal. Users who uploaded a resume during onboarding therefore got a projection of `100` before any parsed resume analysis, interview review, or roleplay review existed.
+
+Fix deployed:
+
+- `growqr-backend` commit `9fd478c` (`fix: keep onboarding qscore baseline at 35`)
+- `resume.uploaded` now projects as baseline `35`, not `100`.
+- The onboarding baseline seeder also repairs users affected by the old upload-only `100` projection.
+
+Deployment note:
+
+- Docker Hub returned `429 Too Many Requests` while resolving `node:22-alpine`.
+- Workaround used on staging: tag the existing backend image as the local `node:22-alpine` base, then rebuild without pulling.
+
+```bash
+docker tag growqr-backend-staging-backend:latest node:22-alpine
+cd /opt/growqr/growqr-backend
+DOCKER_BUILDKIT=0 docker-compose -p growqr-backend-staging up -d --build backend
+```
+
+Verification performed for `sumit26696@gmail.com`:
+
+```txt
+resume.uploaded: 100 -> 35
+home/feed identity.qx: { from: 35, to: 42, baseline: 35 }
+```
+
+The user's current score was `42` because later roleplay review signals existed; a fresh onboarding-only user with only the resume-upload baseline should now show `35`, not `100`.
diff --git a/upskilling/docs/GrowQR_Roleplay_Rubrics_v1.docx b/upskilling/docs/GrowQR_Roleplay_Rubrics_v1.docx
new file mode 100644
index 0000000..74f3e90
Binary files /dev/null and b/upskilling/docs/GrowQR_Roleplay_Rubrics_v1.docx differ
diff --git a/upskilling/docs/Interview & Role Play Rubrics_v3.docx.md b/upskilling/docs/Interview & Role Play Rubrics_v3.docx.md
new file mode 100644
index 0000000..cb0adfc
--- /dev/null
+++ b/upskilling/docs/Interview & Role Play Rubrics_v3.docx.md
@@ -0,0 +1,251 @@
+**GrowQR**
+
+**Interview & Roleplay Services**
+
+Candidate Performance Rubrics
+
+Universal Scoring \+ Archetype Modifiers • v1.0 • March 2026
+
+**1\. Purpose & Scope**
+
+This document defines how a candidate's performance is evaluated across the Interview and Roleplay services on GrowQR. It is used by:
+
+* AI analysis engine — to assign per-metric scores and compute the overall weighted score
+
+* Platform recommendation logic — to generate personalised improvement guidance
+
+* Coaches and pathway managers — to review session results and decide progression
+
+* Candidates — to understand exactly what is expected at each performance level
+
+**1.1 Handling Behavioural Questions — STAR Framework**
+
+Behavioural questions appear across all 4 interview types. When the AI detects a behavioural question (typically starting with 'Tell me about a time when…', 'Describe a situation where…', or 'Give me an example of…'), it evaluates the candidate's response using the STAR framework. STAR output feeds into Language scoring, P-S-I completeness, and Bluff Detection — it is not a separate metric.
+
+| STAR Framework — Handling Instruction for Behavioural Questions • Applies to all 4 interview types | | | |
+| ----- | :---- | :---- | :---- |
+| When a behavioural question is asked (e.g. 'Tell me about a time when…'), the AI evaluates structure using the STAR framework. STAR is not a separate scored metric — it feeds directly into Language (structure and articulation), Content Quality / P-S-I (completeness and impact framing), and Bluff Detection (specificity and ownership of the Action). The table below defines what the AI looks for at each component and how it connects to scoring. | | | |
+| **Component** | **Definition** | **What the AI looks for** | **Scoring impact** |
+| **S** **Situation** | Set the context. What was the background or environment at the time? | Does the candidate establish a clear, specific scenario rather than a generic one? Is the context relevant to the question asked? Is the situation described concisely — setting the scene without over-explaining? | Missing or vague Situation scores lower on Language (structure) and Content Quality. A candidate who jumps straight to action without context is flagged under Technical Flow. |
+| **T** **Task** | What was your specific responsibility or challenge within that situation? | Does the candidate distinguish their individual role from the team's role? Is the task framed as their personal ownership — not just 'we had a problem'? Is the complexity or stakes of the task communicated? | Candidates who blur Situation and Task together, or who cannot articulate their specific ownership, score lower on Language and trigger Resume vs Answer Mismatch checks if the claimed seniority is inconsistent. |
+| **A** **Action** | What specific steps did you personally take to address the task? | Are the actions described in first person ('I did X') not team actions ('we did X')? Are the steps specific and sequential — not vague ('I worked hard on it')? Does the action demonstrate the competency being assessed by the question? | This is the highest-weight STAR component in the AI's evaluation. Vague action with no personal specificity is the primary Bluff Detection trigger. Missing or generic actions pull Language and Voice scores down. |
+| **R** **Result** | What was the measurable outcome or impact? Quantify where possible. | Is the result quantified — speed, accuracy, cost, users, revenue, time saved? Does the candidate own the result or deflect it to the team or circumstances? Is the result proportionate to the action described — not over-claimed? | Result maps directly to the Impact component of P-S-I. Missing Result \= lower Language score. Quantified Result with business framing \= Score 4–5 indicator. Over-claimed Result without supporting Action \= Bluff Detection flag. |
+
+**2\. Pass / Fail Logic**
+
+The following rules govern whether a candidate session is marked as Passed, Progressing, or Not Passed.
+
+| Rule | Detail |
+| :---- | :---- |
+| **Overall Pass Threshold** | Weighted overall score ≥ 60% across all active metrics. Scores below 60% \= session not passed. |
+| **Blocking Floor** | Any single metric scoring 1 (Needs Major Work) is a blocking flag — session cannot be marked Passed regardless of overall weighted score. Candidate must remediate and re-attempt. |
+| **Certificate Eligibility** | Roleplay only: certificate issued when weighted overall score ≥ 70% with no metric scoring below 2\. |
+| **Archetype Override** | Archetype modifiers (Section 4\) may raise per-metric pass thresholds above the universal floor. The universal 60% weighted threshold still applies; archetype modifiers add per-metric minimum requirements on top. |
+| **Historical Progression** | A candidate who scores below 60% but shows a positive trend across ≥3 sessions may be flagged for Progressing status rather than a hard fail — at coach or pathway manager discretion. |
+
+**3\. Scoring Scale Reference**
+
+All metrics use a 1–5 integer scale. Each score maps to a performance level with defined meaning and action.
+
+| Score | Level | Meaning for Candidate | Action Required |
+| ----- | :---- | :---- | :---- |
+| **1** | **Needs Major Work** | Fundamental gaps; performance significantly below minimum standard | Immediate targeted coaching or course; re-assess before progressing |
+| **2** | **Developing** | Below standard; clear gaps but early-stage development visible | Structured practice plan required; progress to next stage only with support |
+| **3** | **Approaching** | Close to standard; minor but consistent gaps remain | Specific gap remediation; eligible to progress with a development note |
+| **4** | **Proficient** | Meets standard; demonstrates expected professional competency | Ready to progress; log as strength if consistent across sessions |
+| **5** | **Exemplary** | Exceeds standard; stands out as a strong performer in this area | Highlight as differentiator; recommend showcase or advanced challenge |
+
+**4\. Interview Service — Universal Candidate Rubrics**
+
+*The Interview Service uses 8 scored metrics. Weights shown are the universal defaults — Voice 17%, Technical Quality 3%, Time Intelligence 5% (new in v2.0). Archetype-adjusted weights are in Section 7\.*
+
+| INTERVIEW SERVICE — 8 Metrics • Universal Weights • Total \= 100% | | | |
+| :---- | ----- | :---- | :---- |
+| **Metric & Weight** | **Score / Level** | **What the candidate demonstrates** | **Red-flag behaviours to log** |
+| **Intro (Opening)** *Weight: 10%* | **1** **Needs Major Work** | Fails to introduce themselves No name, role, or context offered | Silence or confusion at start Reads from notes word-for-word Introduces irrelevant personal information |
+| | **2** **Developing** | States name but omits professional context Introduction is present but very brief with no narrative thread | Tone is flat or apologetic from the first sentence Cannot summarise what they do in one sentence |
+| | **3** **Approaching** | Introduces name, current role, and general background Shows basic confidence in delivery Sets a broadly relevant context for the interview | Introduction runs over 90 seconds without prompting Jumps into full career history rather than a focused opener |
+| | **4** **Proficient** | Clear, structured opener: name, role, key expertise, and why they are here Confident tone and natural pacing Creates a positive first impression within 45–60 seconds | No notable issues; minor polish on specificity |
+| | **5** **Exemplary** | Compelling 30–45 second opener that frames their value proposition Hooks the interviewer with a specific achievement or differentiator Tone is warm, confident, and conversational — feels unrehearsed yet polished | None expected at this level |
+| **Facial Expression** *Weight: 20%* | **1** **Needs Major Work** | Expressionless throughout the session No eye contact with camera | Visible stress or anxiety (tense jaw, furrowed brow sustained throughout) Looking away from screen persistently Visible eye-rolling or disengaged expression |
+| | **2** **Developing** | Occasional eye contact but inconsistent Expression shifts slightly with question changes but lacks warmth | Expression incongruent with content (smiling while describing failure) Stares blankly at screen for extended periods |
+| | **3** **Approaching** | Maintains moderate eye contact through most responses Expression is broadly appropriate to conversation tone Occasional natural smile present | Eye contact breaks frequently during difficult questions Expression noticeably tightens under pressure |
+| | **4** **Proficient** | Consistent eye contact with camera throughout Expressions are natural and match the tone of each response Smile is appropriate and genuine when context allows Emotional state reads as calm and engaged | Slight over-correction (forced smile when inappropriate) |
+| | **5** **Exemplary** | Dynamic, expressive face that reinforces key points Eye contact is commanding without being uncomfortable Authentic emotional range — empathy, enthusiasm, seriousness deployed appropriately Expressions actively build rapport across the session | None expected at this level |
+| **Body Language** *Weight: 20%* | **1** **Needs Major Work** | Slouched or collapsed posture throughout Fidgeting continuously (touching face, tapping, swivelling) | Head in hands or hunched over Turning away from camera repeatedly Arms crossed and body closed for full session |
+| | **2** **Developing** | Posture is mostly upright but collapses under pressure Gestures are present but erratic or distracting | Excessive self-touching (hair, face, collar) Visible restlessness in seat Gestures cut off at camera frame — no visible impact |
+| | **3** **Approaching** | Upright seated posture maintained for majority of session Gestures are present and broadly controlled Minimal fidgeting observed | Posture deteriorates noticeably in the second half Gestures repeat without purpose (filler gestures) |
+| | **4** **Proficient** | Consistently upright and open posture throughout Gestures are purposeful and reinforce key points No distracting movement observed Professionalism reads clearly in physical presence | Occasional single gesture that is distracting — does not recur |
+| | **5** **Exemplary** | Posture conveys authority and ease simultaneously Gestures are varied, well-timed, and add meaning to speech Physical stillness during listening communicates attentiveness Overall physical presence would stand out positively in a panel interview | None expected at this level |
+| **Language** *Weight: 15%* *Two sub-criteria embedded across all 4 interview types: (1) P-S-I — when explaining work or projects, responses should be structured as Problem → Solution → Impact. (2) Technical Flow — when explaining domain concepts, ideas should connect logically in sequence (e.g. Tokenization → Embeddings → Attention → Inference). Technical Flow directly strengthens Bluff Detection: a candidate who cannot chain concepts is flagged regardless of confident tone.* | **1** **Needs Major Work** | Frequent grammatical errors that impede understanding Vocabulary is too limited to articulate responses clearly P-S-I: No structure evident — response is a stream of disconnected statements with no identifiable problem, solution, or impact Technical Flow: Concepts mentioned in isolation with no logical connection between them — e.g. names LLM and Embeddings but cannot explain how one leads to the other | Incomplete sentences left hanging Cannot find words and falls silent mid-thought regularly Uses slang or highly informal register throughout Cannot describe what problem their work solved Uses correct technical keywords but cannot sequence them — strong bluff signal |
+| | **2** **Developing** | Basic grammatical structure mostly present Vocabulary is functional but lacks range for professional context P-S-I: One element present (usually Solution only) — candidate describes what they did but not why or what changed Technical Flow: One or two concept links are made correctly but chain breaks down or reverses midway | Frequent repetition of same limited phrases Sentence structures are consistently simple and short Technical terms used incorrectly or avoided entirely Describes actions with no context or outcome Concept chain stalls after the first step — cannot proceed without prompting |
+| | **3** **Approaching** | Clear sentence structure throughout Vocabulary is appropriate for the level and role Responses are articulate and understandable with minimal re-listening needed P-S-I: Two of three elements present — typically Problem \+ Solution but Impact is vague or absent Technical Flow: Concept chain is mostly correct — candidate sequences 3–4 ideas logically but loses precision or depth at the final step | Occasional grammatical slip under pressure Some over-reliance on a limited phrase set Impact described but not quantified — 'it went well' without specifics Concept chain correct but shallow — links are made without explaining why each step follows |
+| | **4** **Proficient** | Varied vocabulary deployed naturally and accurately Grammar is consistently correct including under pressure Uses precise language — avoids vague filler phrases ('kind of', 'sort of') Sentence structure reflects logical thinking P-S-I: All three elements present and clearly sequenced — Problem is contextualised, Solution includes their specific role, Impact is concrete Technical Flow: Full concept chain delivered accurately and in correct sequence — each step explained and linked to the next | Rare slip on technical terminology Impact is stated but not quantified numerically Concept chain is complete but one link is explained less clearly than the others |
+| | **5** **Exemplary** | Sophisticated, professional vocabulary used with confidence Language is persuasive and well-constructed under all conditions Candidate adapts register to question type (technical vs. behavioural) Demonstrates command of industry-relevant language naturally P-S-I: All three elements delivered with precision — Impact is quantified (speed, accuracy, cost, users), Solution distinguishes their individual contribution from team effort, Problem is framed in business terms not just technical terms Technical Flow: Concept chain is complete, correctly sequenced, and delivered with depth at every link — candidate can also explain why the sequence matters, not just what it is | None expected at this level |
+| **Voice** *Weight: 17%* | **1** **Needs Major Work** | Volume too low to hear clearly OR monotone throughout Pace is either so fast responses blur or so slow they lose the thread | 10+ filler words per minute Vocal tremor throughout suggesting extreme anxiety Mumbling that requires repeated listening |
+| | **2** **Developing** | Volume is audible but flat with no tonal variation Pace fluctuates noticeably but does not break comprehension | 6–9 filler words per minute Upward inflection on statements (sounds like questions) Breath sounds audible and distracting |
+| | **3** **Approaching** | Volume is consistent and clear Pace is broadly controlled — slows for key points occasionally Tone shifts with question topic Filler word count: 3–5 per minute | Filler count increases under pressure Monotone returns on longer answers |
+| | **4** **Proficient** | Clear, confident vocal delivery throughout Tone, pace, and volume vary purposefully across the session Filler word count: 1–2 per minute or fewer Silence is used effectively before complex answers | Occasional filler on transition between topics |
+| | **5** **Exemplary** | Voice is a clear communication asset — engaging and authoritative Pace modulated precisely: slower for complex points, energised for enthusiasm Zero or near-zero filler words throughout the full session Strategic use of pause creates emphasis and demonstrates composure | None expected at this level |
+| **Outro (Closing)** *Weight: 10%* | **1** **Needs Major Work** | Session ends without a closing statement Candidate simply stops talking with no wrap-up | Abrupt 'I think that's it' or equivalent No questions asked of the interviewer when offered Final impression is confusion or disengagement |
+| | **2** **Developing** | A brief closing exists but it is generic ('Thanks for having me') One question asked but it is low-effort (e.g., 'What's the salary?') | Closing contradicts earlier answers Question to interviewer reveals no research or interest in the role |
+| | **3** **Approaching** | Clear closing statement that re-states interest in the role One or two relevant questions asked Ends on a broadly positive note | Closing is formulaic but inoffensive Questions are predictable and do not differentiate the candidate |
+| | **4** **Proficient** | Confident closing that references something specific from the interview 2–3 thoughtful questions that show genuine role/company knowledge Candidate reaffirms their fit in a natural, non-scripted way Final impression is positive and memorable | Closing is slightly over-rehearsed — minor authenticity gap |
+| | **5** **Exemplary** | Closing creates a lasting impression: references a specific interview moment and ties it to their value Questions are incisive and demonstrate genuine strategic thinking about the role Candidate controls the final narrative — ends on their terms Interviewer's last impression is that this person is ready | None expected at this level |
+| **Technical Quality** *Weight: 3%* | **1** **Needs Major Work** | Setup is so poor it undermines the interview (dark room, no audio, chaotic background) | Camera is not on face — candidate not visible Audio is inaudible Background is deeply unprofessional (others visible, noise throughout) |
+| | **2** **Developing** | Setup is substandard but interview can proceed One or two technical issues that distract but do not block evaluation | Lighting casts heavy shadows on face Background has moving distractions Audio has persistent background noise |
+| | **3** **Approaching** | Acceptable setup — lighting is adequate, framing is centred, background is neutral Audio is clear with minor occasional noise | Framing is slightly off-centre Lighting is functional but not flattering |
+| | **4** **Proficient** | Well-lit face, centred framing, clean or professional background Audio is consistently clear throughout Setup communicates that the candidate took the interview seriously | Minor background element that is noticeable but not distracting |
+| | **5** **Exemplary** | Setup is interview-ready and projects professionalism Lighting, framing, background, and audio are all at a high standard Setup actively contributes to a positive overall impression | None expected at this level |
+| **Time Intelligence** *Weight: 5%* *Measures cognitive response patterns under pressure — not just speed, but the quality of thinking behind the timing. Healthy pauses score positively; blank freezes and overthinking loops score negatively.* | **1** **Needs Major Work** | Response latency is so long (\>20s of silence) that the interview is disrupted Candidate freezes and cannot recover without interviewer prompting on most questions | Blank freezes exceeding 20 seconds on standard questions Consistently restates the question back as a stalling tactic Overthinking loop visible — candidate goes in circles without committing to an answer Delay patterns cluster on basic questions, not just difficult ones |
+| | **2** **Developing** | Responses begin but with significant latency (10–20s) on most questions Thinking pauses are present but feel like blank hesitation rather than active processing | Excessive hedging that prevents any substantive answer from forming Delay patterns cluster on predictable topic areas revealing consistent knowledge gaps Candidate regularly restates or rephrases the question before answering |
+| | **3** **Approaching** | Response latency is within acceptable range (3–8s) for most questions Pauses feel like genuine thinking rather than blank freezes Performance degrades on harder questions but candidate recovers and delivers an answer Delay patterns are limited to clearly complex or unfamiliar topics | Occasional overthinking loop on one or two questions Latency increases noticeably on topic-specific questions — possible gap signal |
+| | **4** **Proficient** | Response latency is consistently appropriate — short pause before complex answers, faster on familiar topics Thinking pauses are deliberate and purposeful; candidate uses them to structure their answer Performance under harder questions is composed — slight increase in latency but no freezes No overthinking loops observed; candidate commits to an answer direction and follows through | One topic area shows marginally longer delay — flag for follow-up but not penalised |
+| | **5** **Exemplary** | Response timing is a communication strength — pauses are used strategically for emphasis Complex questions receive a brief, deliberate pause followed by a structured, confident answer No blank freezes across the full session including on curveball questions Delay patterns show no topic-specific clustering — consistent across all question types Candidate demonstrates real-time adaptability: new topics handled without latency spike | None expected at this level |
+
+**5\. Consistency & Truth Check — Integrity Flags**
+
+This dimension is unweighted and does not affect the candidate's scored rubric. The AI raises flags in each of the three categories below based on cross-referencing resume/LinkedIn data against session responses. Recruiter and coach see full flag detail. Candidate sees a summary 'Consistency Check' result only.
+
+| ⚑ Consistency & Truth Check — Unweighted integrity flags — raised by AI for recruiter/coach review. Candidate sees summary result only. | | |
+| :---- | :---- | :---- |
+| **Flag Type** | **What AI Monitors** | **Flag Output — what recruiter/coach sees** |
+| **Resume vs Answer Mismatch** *AI cross-references skills, experience, and achievements claimed on the candidate's uploaded resume or LinkedIn profile against what they demonstrate and state verbally during the session.* | Skill listed on resume cannot be explained or demonstrated when probed — e.g., claims Python proficiency but cannot answer basic syntax questions Experience duration or seniority level claimed on resume inconsistent with depth of answers given Specific achievement or project mentioned on resume but candidate cannot provide detail when asked Claimed certifications or qualifications not supported by demonstrated knowledge | Flag raised with: specific resume claim, specific interview moment, mismatch severity (Minor / Moderate / Significant) |
+| **Contradiction Tracking** *AI tracks statements made across the full session and flags direct contradictions — e.g., claiming a strength in one answer that is contradicted by a specific weakness admission later.* | Candidate states conflicting information about the same event, project, or role in two different answers Team size, timeline, or scope of a project described differently in separate answers Candidate claims credit for a decision in one answer and attributes it to someone else in a later answer Technical approach described differently across two answers on the same topic | Flag raised with: answer 1 timestamp, answer 2 timestamp, verbatim conflict summary |
+| **Bluff Detection** *AI identifies responses that sound confident but are technically vague, logically circular, or fall apart under follow-up questioning.* | Confident tone but answer contains no substantive technical or factual content — sounds plausible but says nothing specific Candidate uses correct terminology but cannot explain what the term means when asked to elaborate Answer evades the question by pivoting to a related but different topic Response contradicts itself internally within the same answer Follow-up question on the same topic reveals the initial answer was surface-level — depth was not present | Flag raised with: question asked, answer summary, specific evasion or gap identified |
+
+**6\. Roleplay Service — Universal Candidate Rubrics**
+
+*The Roleplay Service uses 5 scored metrics. Weights shown are universal defaults. P-S-I framework is embedded in Content Quality (new in v2.0). Archetype-adjusted weights and minimum scores are in Section 7\.*
+
+| ROLEPLAY SERVICE — 5 Metrics • Universal Weights • Total \= 100% | | | |
+| :---- | ----- | :---- | :---- |
+| **Metric & Weight** | **Score / Level** | **What the candidate demonstrates** | **Red-flag behaviours to log** |
+| **Voice** *Weight: 35%* | **1** **Needs Major Work** | Inaudible or monotone throughout the scenario Pace makes content impossible to follow | 10+ filler words per minute Candidate cannot sustain voice for the scenario duration Tone is entirely inappropriate to the scenario context |
+| | **2** **Developing** | Basic vocal delivery — audible but flat Tone shows minimal variation across the scenario | 6–9 filler words per minute Pace rushes through critical scenario moments Vocal confidence drops sharply when challenged by the AI persona |
+| | **3** **Approaching** | Clear vocal delivery throughout most of the scenario Tone adapts to scenario context (formal vs. collaborative) Filler count: 3–5 per minute Pace is broadly appropriate | Filler words cluster at scenario transitions Tone does not fully match the scenario type |
+| | **4** **Proficient** | Confident, clear, scenario-appropriate voice throughout Filler count: 1–2 per minute Pace and tone actively serve the scenario narrative Candidate sounds credible and competent in the scenario role | Occasional filler on complex turns |
+| | **5** **Exemplary** | Voice is a scenario asset — conveys authority, warmth, or precision as required Near-zero filler words throughout Pace and emphasis deployed with intent Voice alone communicates engagement and professional confidence | None expected at this level |
+| **Facial Expression** *Weight: 25%* | **1** **Needs Major Work** | Expressionless or visibly stressed throughout No eye contact with camera | Expression is incongruent with scenario tone throughout Candidate appears disconnected from the scenario entirely |
+| | **2** **Developing** | Minimal expression — present but not engaged Eye contact inconsistent | Smile inappropriate for the scenario type Stress visible on face during most exchanges with the AI persona |
+| | **3** **Approaching** | Appropriate expressions for the scenario context Moderate eye contact maintained through most turns Shows engagement when the AI persona challenges them | Expression drops in intensity during longer monologue turns |
+| | **4** **Proficient** | Expressions actively reinforce the scenario role Consistent, natural eye contact that conveys presence Emotional range is scenario-appropriate — not over-performed | Rare mismatch between expression and content |
+| | **5** **Exemplary** | Facial performance matches the professional situation being simulated Eye contact builds trust and engagement with the AI persona Dynamic expression range — enthusiasm, empathy, calm deployed at the right moments Would stand out positively in a real-world version of the scenario | None expected at this level |
+| **Body Language** *Weight: 20%* | **1** **Needs Major Work** | Posture is collapsed or turned away from camera throughout | Fidgeting is constant and distracting Body language contradicts verbal message (closed posture while claiming confidence) Movement is so frequent that analysis is compromised |
+| | **2** **Developing** | Posture is mostly upright but falls under pressure Gestures are present but not controlled | Physical restlessness increases as scenario progresses Closed arm posture dominant |
+| | **3** **Approaching** | Upright posture for most of the scenario Gestures are present and do not distract Physical presence is broadly appropriate to the scenario context | Posture deteriorates noticeably after 10 minutes |
+| | **4** **Proficient** | Open, upright posture throughout Gestures are purposeful and add to the communication Physical stillness when listening signals attentiveness Professionalism reads clearly in physical presentation | Single distracting gesture that does not recur |
+| | **5** **Exemplary** | Physical presence is a communication strength Body language is aligned with voice and expression throughout Scenario-appropriate authority or approachability projected through physicality Candidate would be compelling in-person based on what is observable on camera | None expected at this level |
+| **Technical Quality** *Weight: 10%* | **1** **Needs Major Work** | Setup prevents meaningful evaluation (no light, no audio, disruptive background) | Camera not showing face Background has people or high noise throughout Audio is inaudible |
+| | **2** **Developing** | Substandard but session can continue One persistent technical issue throughout | Lighting obscures facial analysis Background noise triggers at least once per minute |
+| | **3** **Approaching** | Acceptable setup across all four dimensions Minor issues do not impact analysis | Framing is off-centre for most of the session |
+| | **4** **Proficient** | Well-lit, centred, clean background, clear audio throughout Setup signals preparation and professionalism | Single brief audio or background interruption |
+| | **5** **Exemplary** | Setup is a professional asset — all four dimensions at high standard Audio, light, framing, and background all contribute to a polished impression | None expected at this level |
+| **Content Quality** *Weight: 10%* *P-S-I sub-criterion: when explaining scenario context, decisions, or past work, candidates should structure responses as Problem → Solution → Impact. Scores reflect both content completeness and narrative structure.* | **1** **Needs Major Work** | Responses are irrelevant to the scenario or entirely off-topic Cannot complete the scenario task P-S-I: No structure — response has no identifiable Problem, Solution, or Impact framing | Candidate abandons the scenario premise mid-session Responses are factually wrong in a way that would fail in a real situation No attempt to meet the scenario objective |
+| | **2** **Developing** | Responses are on-topic but shallow and incomplete Scenario task is partially addressed only P-S-I: Solution only — candidate describes what they did or would do but provides no problem context and no impact outcome | Key scenario objectives are left unaddressed Responses rely on generic statements rather than scenario-specific reasoning Cannot articulate what success looks like in the scenario |
+| | **3** **Approaching** | Responses are relevant and mostly complete Core scenario objective is addressed Accuracy is broadly acceptable P-S-I: Problem \+ Solution present — scenario challenge acknowledged and response is relevant, but Impact is absent or vague | One or two scenario objectives missed or underaddressed Outcome described loosely without measurable framing |
+| | **4** **Proficient** | All scenario objectives addressed accurately and completely Responses are relevant, structured, and demonstrate genuine understanding of the scenario context Candidate adds value beyond the minimum scenario requirement P-S-I: All three elements present — Problem is framed clearly, Solution includes specific actions taken, Impact is concrete and scenario-relevant | Minor omission in one area that does not affect overall outcome |
+| | **5** **Exemplary** | Scenario is mastered — all objectives addressed with insight and precision Candidate demonstrates a level of thinking that exceeds the scenario brief Responses show domain command, strategic awareness, and situational intelligence Would achieve a strong real-world outcome in this scenario P-S-I: Exemplary structure — Problem is framed in stakeholder terms, Solution distinguishes their role from team contribution, Impact is quantified and tied to business or user outcome | None expected at this level |
+
+**7\. Archetype Modifiers**
+
+For each of the 5 GrowQR archetypes, the tables below define: (1) adjusted metric weights that re-prioritise what matters for that archetype, (2) per-metric minimum scores that must be reached regardless of the overall weighted average, and (3) what 'good' looks like for that archetype specifically. Time Intelligence is now included across all 5 archetypes with archetype-specific minimum scores. Cells highlighted in green indicate a higher-than-universal weight. Cells highlighted in red indicate a minimum score above the universal floor.
+
+*⚑ Terminology note: The Pathways Booklet (source document) references 8 archetypes (The Strategist, The Executor, The Innovator, The Connector, The Specialist, The Explorer, The Builder, The Catalyst). This rubric uses the 5 locked GrowQR platform archetypes. Reconciliation of booklet language to the locked 5 is required before Pathways BRD v5 is finalised.*
+
+**Technical Specialist**
+
+| Technical Specialist — Depth of expertise, precision of communication, credibility under scrutiny | | | | |
+| ----- | :---- | ----- | ----- | :---- |
+| **Service** | **Metric** | **Adjusted Weight** | **Min Score to Pass** | **What 'Good' Looks Like for This Archetype** |
+| **Interview** | **Intro** | 8% | **3** | Opener should reference domain expertise and a specific technical achievement; generic openers score lower for this archetype. |
+| | **Facial Expression** | 15% | **3** | Moderate expressiveness is acceptable; assessment prioritises authenticity over performance. Forced warmth scores lower than composed neutrality. |
+| | **Body Language** | 15% | **3** | Composed stillness is valued over expressive gestures. Fidgeting during technical explanations is weighted more heavily as it signals uncertainty. |
+| | **Language** | **22%** | **4** | Precise technical vocabulary is a core requirement. Must score ≥4 — inability to articulate technical concepts clearly is a critical gap for this archetype. |
+| | **Voice** | 15% | **3** | Clarity and pace matter more than charisma. A measured, deliberate pace during technical explanations is a strength. |
+| | **Outro** | 8% | **3** | Questions asked should reflect technical curiosity (stack, architecture, engineering culture). Generic questions score lower. |
+| | **Technical Quality** | **12%** | **3** | Setup quality is weighted higher — screen share functionality must be tested as part of this archetype's typical coding interview scenarios. |
+| | **Time Intelligence** | 5% | **4** | Deliberate, structured pauses before technical answers are a positive signal. However, blank freezes on fundamental domain questions are a critical gap — must score ≥4. |
+| | **Learning Ability** | — | **3** | Additional passing criterion — unweighted but blocking. When the AI persona gives a hint or correction mid-session, the candidate must demonstrate measurable improvement in the very next relevant answer. Score ≥3 required: candidate grasps the hint and applies it. Score 1–2 \= blocking flag regardless of overall weighted score. |
+| **Roleplay** | **Voice** | 30% | **3** | Precision over charisma. Clarity during technical explanation turns is the key voice indicator. |
+| | **Facial Expression** | 20% | **3** | Engagement is important but over-performance is penalised. Composed focus is a strength. |
+| | **Body Language** | 18% | **3** | Stillness during technical delivery is a positive indicator, not a deficit. |
+| | **Technical Quality** | **12%** | **4** | Higher weight and minimum for this archetype — professional setup is expected; IDEs and coding demo screen shares must function correctly. |
+| | **Content Quality** | **20%** | **4** | Content accuracy is critical. Technical errors in scenario responses are blocking for this archetype. Must score ≥4. |
+
+**Strategic Leader**
+
+| Strategic Leader — Executive presence, structured thinking, command of room and narrative | | | | |
+| ----- | :---- | ----- | ----- | :---- |
+| **Service** | **Metric** | **Adjusted Weight** | **Min Score to Pass** | **What 'Good' Looks Like for This Archetype** |
+| **Interview** | **Intro** | **12%** | **4** | Opening must establish leadership narrative and strategic framing within 45 seconds. Must score ≥4 — a weak opener is disqualifying for this archetype. |
+| | **Facial Expression** | **22%** | **4** | Executive presence requires strong expressive engagement. Eye contact must project authority and warmth simultaneously. Must score ≥4. |
+| | **Body Language** | **22%** | **4** | Posture and gesture are leadership signals. Open, upright, deliberate physicality is a core requirement. Must score ≥4. |
+| | **Language** | 18% | **4** | Structured, precise language with strategic vocabulary. Candidate should frame responses in terms of impact, outcomes, and decisions. |
+| | **Voice** | 15% | **4** | Tone of authority is expected. Pace should be deliberate. Filler words are weighted more heavily as they undermine executive presence. |
+| | **Outro** | 6% | **3** | Closing should be decisive and forward-looking. Questions to interviewer should reflect strategic thinking about the organisation. |
+| | **Technical Quality** | 2% | **2** | Minimal weight. Basic acceptable setup is sufficient. Setup quality is not a differentiator for this archetype. |
+| | **Time Intelligence** | 3% | **5** | Deliberate, composed pacing is a core leadership signal. Any hesitation or overthinking loop is penalised heavily — must score ≥5 to confirm executive-level command of timing. |
+| **Roleplay** | **Voice** | **38%** | **4** | Voice is the primary leadership instrument. Tone of authority, deliberate pacing, and near-zero filler are all required at ≥4. |
+| | **Facial Expression** | **28%** | **4** | Commanding presence through expression is a core requirement. Must score ≥4. |
+| | **Body Language** | **24%** | **4** | Physical authority is non-negotiable for this archetype. Open, stable, deliberate physicality throughout scenario. Must score ≥4. |
+| | **Technical Quality** | 4% | **2** | Low weight. Acceptable setup is sufficient. |
+| | **Content Quality** | 6% | **3** | Content should reflect strategic framing — responses framed around decisions, outcomes, and stakeholder impact score higher. |
+
+**Creative Innovator**
+
+| Creative Innovator — Original thinking, enthusiasm, ability to sell ideas and inspire curiosity | | | | |
+| ----- | :---- | ----- | ----- | :---- |
+| **Service** | **Metric** | **Adjusted Weight** | **Min Score to Pass** | **What 'Good' Looks Like for This Archetype** |
+| **Interview** | **Intro** | **12%** | **4** | Opening should establish a distinctive personal narrative or creative differentiator. Generic openers score much lower for this archetype. Must score ≥4. |
+| | **Facial Expression** | **22%** | **4** | Enthusiasm and genuine emotional engagement are core. Expressiveness is a strength, not a risk. Must score ≥4. |
+| | **Body Language** | 15% | **3** | Energy and openness in physicality valued. Expressive gestures score positively — controlled stillness alone is not sufficient for this archetype. |
+| | **Language** | 20% | **3** | Vivid, imaginative language is a positive indicator. Candidate should demonstrate range and the ability to explain creative concepts clearly. |
+| | **Voice** | 20% | **3** | Tonal variety and genuine enthusiasm are key voice indicators. Flat delivery is penalised more than filler words for this archetype. |
+| | **Outro** | 6% | **3** | Closing should leave a memorable, distinctive impression. A creative or unexpected closing question scores highly. |
+| | **Technical Quality** | 2% | **2** | Low weight. Setup just needs to be functional. |
+| | **Time Intelligence** | 3% | **3** | Response timing flexibility is valued for this archetype — thinking pauses score positively as signs of genuine ideation. Overthinking loops are penalised only when they prevent any answer. |
+| **Roleplay** | **Voice** | 35% | **4** | Vocal energy and tonal variety are the strongest indicators. Monotone delivery scores lower than filler-heavy enthusiastic delivery for this archetype. |
+| | **Facial Expression** | **30%** | **4** | Highest weight category. Expressive engagement is the primary differentiator. Must score ≥4. |
+| | **Body Language** | 20% | **3** | Open, expressive physicality is valued. Gestures that reinforce creative ideas score positively. |
+| | **Technical Quality** | 5% | **2** | Low weight. Basic functional setup is sufficient. |
+| | **Content Quality** | 10% | **3** | Originality and unexpected angles in scenario responses score higher than technically correct but predictable answers. |
+
+**Sales & Influence Driver**
+
+| Sales & Influence Driver — Persuasion, rapport, emotional intelligence, energy and conviction | | | | |
+| ----- | :---- | ----- | ----- | :---- |
+| **Service** | **Metric** | **Adjusted Weight** | **Min Score to Pass** | **What 'Good' Looks Like for This Archetype** |
+| **Interview** | **Intro** | **15%** | **4** | The opener IS the pitch. Must hook the interviewer within 30 seconds. Compelling narrative, energy, and confidence are all required. Must score ≥4. |
+| | **Facial Expression** | **25%** | **4** | Warmth, rapport, and engagement through expression are essential. Genuine smile and consistent eye contact are minimum requirements. Must score ≥4. |
+| | **Body Language** | **20%** | **4** | Physicality is part of the persuasion toolkit. Open, energetic, forward-leaning presence. Must score ≥4. |
+| | **Language** | 15% | **3** | Persuasive, benefit-focused language scores higher. Candidate should demonstrate storytelling ability and use of social proof. |
+| | **Voice** | **19%** | **4** | Voice is a primary influence tool. Energy, warmth, and confidence are all required. Flat delivery is highly penalised. Must score ≥4. |
+| | **Outro** | 2% | **3** | Low weight but a strong closing is still expected — the closing is a natural home for a soft CTA or memorable statement. |
+| | **Technical Quality** | 1% | **2** | Minimal weight. Functional setup is sufficient. |
+| | **Time Intelligence** | 3% | **4** | Response speed signals confidence for this archetype — fast, assured responses reinforce influence. Hesitation or overthinking directly undermine persuasiveness. Must score ≥4. |
+| **Roleplay** | **Voice** | **40%** | **4** | Highest weight. Voice is the primary influence vehicle. Energy, pace, and conviction are all required. Must score ≥4. |
+| | **Facial Expression** | **28%** | **4** | Rapport through expression is core to this archetype's scenario performance. Must score ≥4. |
+| | **Body Language** | **20%** | **4** | Persuasive physicality — open, forward, engaged. Must score ≥4. |
+| | **Technical Quality** | 2% | **2** | Minimal weight. |
+| | **Content Quality** | 10% | **3** | Storytelling structure and benefit framing in responses score higher than factual completeness alone. |
+
+**Entrepreneurial Builder**
+
+| Entrepreneurial Builder — Bias to action, resilience, vision clarity, credibility under ambiguity | | | | |
+| ----- | :---- | ----- | ----- | :---- |
+| **Service** | **Metric** | **Adjusted Weight** | **Min Score to Pass** | **What 'Good' Looks Like for This Archetype** |
+| **Interview** | **Intro** | **12%** | **4** | Must communicate a clear vision or founding narrative. 'What they are building or have built' must be central to the opener. Must score ≥4. |
+| | **Facial Expression** | 18% | **3** | Genuine conviction and authentic enthusiasm are the key expression indicators. Polished performance is valued less than authenticity. |
+| | **Body Language** | 18% | **3** | Energy and presence are valued. Gestural expressiveness is a positive indicator. Some roughness at the edges is acceptable if energy is strong. |
+| | **Language** | 17% | **3** | Concrete, outcome-oriented language is valued. Candidate should speak in terms of what they built, shipped, or achieved — not what they planned. |
+| | **Voice** | 20% | **3** | Energy and conviction are the primary voice indicators. Polished delivery is valued less than genuine passion for the subject. |
+| | **Outro** | **10%** | **4** | Higher weight. The closing should pitch the candidate's next move or vision. A builder who closes weakly scores lower — the outro should feel like a CTA. Must score ≥4. |
+| | **Technical Quality** | 2% | **2** | Low weight. Functional setup is sufficient. |
+| | **Time Intelligence** | 3% | **3** | Bias-to-action means faster responses are valued over extended deliberation. However, structured pauses before complex answers score positively. Blank freezes contradict the builder identity. |
+| **Roleplay** | **Voice** | 32% | **3** | Authentic energy and conviction. Raw delivery with strong conviction scores higher than polished but flat. |
+| | **Facial Expression** | 22% | **3** | Genuine conviction visible in expression. Authenticity weighted more than performance polish. |
+| | **Body Language** | 20% | **3** | Energy and openness. Minor roughness acceptable if overall physical presence communicates engagement. |
+| | **Technical Quality** | 8% | **2** | Moderate weight — builder archetypes often demo products so screen share setup quality matters more than other archetypes. |
+| | **Content Quality** | **18%** | **4** | Higher weight. Scenario responses must demonstrate bias to action and outcome focus. Vague or planning-heavy responses score low. Must score ≥4. |
+
diff --git a/upskilling/docs/plans/2026-03-24-interview-live-relay-migration.md b/upskilling/docs/plans/2026-03-24-interview-live-relay-migration.md
new file mode 100644
index 0000000..49a1a05
--- /dev/null
+++ b/upskilling/docs/plans/2026-03-24-interview-live-relay-migration.md
@@ -0,0 +1,140 @@
+# Interview Service Live Relay Migration
+
+## Summary
+- Keep the backend-owned Gemini Live relay websocket as the primary live interview transport. The browser does not connect to Gemini directly and does not run browser STT.
+- Keep `POST /configure` and `POST /start`; after `start`, the client uses one app websocket for live transcript, prompt streaming, orchestration events, upload state, and analysis-stage updates.
+- Keep per-turn audio upload, not one session-long file. Each answer records locally, commits from the live transcript on `turn.stop`, then uploads that turn’s blob to S3 in the background.
+- Final review uses the live transcript as the grading source of truth in the normal path. Uploaded turn audio is retained for playback and voice/audio evidence, and is used for transcript recovery only when live STT fails for a specific turn.
+
+## Key Changes
+- Add `session_mode="live_audio"` as the primary live path. Keep REST `/responses` only as legacy fallback.
+- For `live_audio`, enforce duration options `5`, `10`, and `15` minutes. Treat conflicting `30`-minute references in repo docs/schema as stale and update them during implementation.
+- Add `WS /api/v1/interviews/{session_id}/live` in `services/interview-service/app/api/v1/interviews.py`. `POST /start` returns `live_ws_url` and the opening prompt.
+- Introduce a backend live-session manager in `services/interview-service/app/services/interview_service.py` or a sibling live service that:
+ - opens an upstream Gemini Live session with `inputAudioTranscription` enabled
+ - disables automatic activity detection and drives explicit `activityStart` / `activityEnd`
+ - treats Gemini as transcription transport only; backend orchestration and prompt generation remain owned by the existing intelligence stack
+ - discards all unsolicited upstream model output instead of surfacing it to the client
+- Handle Gemini connection lifetime explicitly:
+ - official docs say audio-only sessions are limited to 15 minutes and connection lifetime is around 10 minutes, with `GoAway` before close and optional session resumption
+ - v1 does not depend on Gemini session resumption because Gemini carries no authoritative orchestration state for us
+ - the backend rotates the upstream Gemini connection between turns whenever the connection is older than 8 minutes or after `GoAway`
+ - the browser websocket remains stable while the backend swaps Gemini connections underneath it
+- Finalize turns safely:
+ - `turn.stop` sends upstream `activityEnd` immediately and stops forwarding PCM
+ - the backend waits on a finalization barrier before commit: no transcript growth for a short quiet window plus either upstream `serverContent.turnComplete` or a bounded timeout
+ - if timeout is used, persist finalization metadata on the turn
+- Resolve mid-turn upstream failure without deadlock:
+ - if Gemini dies before the transcript can be committed, the backend emits `turn.degraded_awaiting_audio`
+ - the client pauses the interview UI, prioritizes that turn’s blob upload ahead of the normal upload queue, and does not advance to the next prompt
+ - the backend blocks orchestration for that turn until the degraded turn artifact is registered and legacy server transcription completes, or until recovery fails and the session is marked errored
+- Keep Google TTS for interviewer audio. Emit prompt text immediately, then `prompt.audio.pending`, `prompt.audio.ready`, or `prompt.audio.failed`. The mic stays locked until audio is ready or text-only fallback is declared.
+- Keep per-turn artifact upload:
+ - after the transcript transaction commits, the server emits `turn.committed` with `response_id`
+ - the client upload worker requests presign only when an item reaches the front of the queue
+ - normal uploads run through a strict queue with concurrency `1`
+ - the queue uses bounded retries, exponential backoff, and terminal `failed` state so one bad turn cannot poison later uploads
+ - degraded-turn recovery uploads bypass the normal queue and run in a dedicated priority lane because they are blocking orchestration
+- Add upload-aware interview finish:
+ - `session.finish` includes `pending_upload_response_ids` and `failed_upload_response_ids`
+ - background review waits only for the pending ids to register or for a bounded grace window such as 30 seconds to expire
+ - failed ids are transcript-only immediately and do not block finish
+- Fix capture and transport normalization:
+ - PCM extraction and `MediaRecorder` must share the same `MediaStream`
+ - the client must not emit `turn.start` until both the PCM path and the blob recorder report started
+ - the client normalizes outbound PCM to little-endian 16-bit mono at 16kHz and labels chunks as `audio/pcm;rate=16000`
+ - although Live can resample other input rates, standardizing client-side avoids browser hardware variability and reduces payload size
+ - on stop, the client sends websocket `turn.stop` immediately, but it does not enqueue the blob upload until the final `MediaRecorder` flush promise resolves
+- Fix replay and spoofing:
+ - backend rejects `turn.start` unless `prompt_id` exactly matches the authoritative current prompt
+ - backend rejects reused, stale, or already-closed `client_turn_id`
+ - any mismatch triggers `error` plus a fresh `session.ready`
+- Fix commit ordering:
+ - `turn.committed` is emitted only after the transcript row is fully committed to Postgres
+ - artifact registration cannot race ahead of transcript commit
+- Keep the websocket alive after `session.finish`:
+ - heartbeat ping/pong continues through upload grace waiting and the full review pipeline
+ - the backend explicitly ends the socket with `session.closed` only after final result delivery or terminal failure
+- Prevent premature tab close data loss:
+ - while uploads are pending, the client installs a `beforeunload` guard warning that interview audio is still syncing
+ - the post-interview UI shows explicit syncing progress and does not expose the final exit CTA until the queue is drained or remaining items are marked failed
+
+## Public APIs / Protocol
+- `ConfigureInterviewRequest.session_mode` gains `live_audio`.
+- `ConfigureInterviewRequest.duration_minutes` is restricted to `5 | 10 | 15` for `live_audio`.
+- `StartInterviewResponse` gains `live_ws_url`.
+- `RegisterArtifactRequest` gains optional `response_id`.
+- `InterviewArtifact` gains optional indexed `response_id`.
+- Websocket client messages:
+ - `turn.start` with `prompt_id` and `client_turn_id`
+ - binary PCM audio frames for the active `client_turn_id`
+ - `turn.stop` with `client_turn_id`
+ - `session.finish` with `pending_upload_response_ids` and `failed_upload_response_ids`
+- Websocket server messages:
+ - `session.ready` with authoritative state: `current_prompt_id`, `turn_state`, `last_committed_response_id`, pending uploads
+ - `transcript.partial`, `transcript.final`
+ - `turn.committed` with `client_turn_id`, `response_id`, transcript text, and finalization metadata
+ - `turn.degraded_awaiting_audio`
+ - `turn.timeout`
+ - `prompt.delta`, `prompt.final`
+ - `prompt.audio.pending`, `prompt.audio.ready`, `prompt.audio.failed`
+ - `artifact.registered`
+ - `analysis.queued`, `analysis.stage`, `analysis.completed`, `analysis.failed`
+ - `session.closed`
+ - `error`
+- Keep existing artifact presign/upload/register endpoints. Live clients still use them, but only the upload worker or degraded-turn recovery path talks to them.
+
+## Test Plan
+- Validation:
+ - `live_audio` accepts `5`, `10`, `15`
+ - `30` is rejected in live mode
+ - legacy non-live modes still work
+- Gemini lifetime handling:
+ - backend rotates upstream Gemini between turns before connection expiry
+ - `GoAway` causes clean pre-turn rotation without affecting the browser websocket
+ - browser websocket survives the full post-finish review window and closes only on `session.closed`
+- Transcript finalization:
+ - `turn.stop` waits through the quiet-window barrier and includes trailing words
+ - `serverContent.turnComplete` path commits cleanly
+ - timeout path commits with explicit metadata instead of silent truncation
+- Mid-turn failure recovery:
+ - upstream Gemini close during a turn emits `turn.degraded_awaiting_audio`
+ - degraded turn upload jumps ahead of the normal queue
+ - orchestration stays blocked until degraded-turn server transcription completes
+- Upload queue:
+ - presign is requested only at queue head
+ - queue concurrency remains `1`
+ - bounded retries and backoff work
+ - one permanently failed upload does not block later turns
+ - degraded-turn priority upload bypasses normal queue safely
+- Capture and blob integrity:
+ - `turn.start` is never sent before both PCM and blob recording are armed
+ - outbound PCM is 16kHz Int16 mono
+ - upload queue starts only after final `MediaRecorder` flush resolves
+- Reconnect and ghost turn handling:
+ - reconnect after `turn.stop` but before `turn.committed` reconciles to server state
+ - stale local recordings are dropped if the server already advanced
+ - stale or spoofed `prompt_id` / `client_turn_id` is rejected
+- Finish barrier:
+ - `session.finish` waits for listed pending uploads before review
+ - failed uploads are excluded from the wait barrier and degrade cleanly
+ - `beforeunload` warning appears while uploads remain pending
+- DB ordering:
+ - artifact registration immediately after `turn.committed` succeeds because the transcript row is already committed
+- Review behavior:
+ - final grading uses live transcript only in the normal path
+ - uploaded per-turn audio contributes to voice/audio evidence when present
+ - explicit live-STT failure path can recover a turn transcript from uploaded audio
+
+## Assumptions And Defaults
+- Scope is `services/interview-service` only.
+- Backend relay websocket is the authoritative live transport; Gemini credentials stay server-side.
+- Gemini Live is used for realtime transcription transport, not interviewer prompt generation.
+- Gemini carries no authoritative interview state, so cold reconnect/rotation between turns is acceptable and preferred over depending on session resumption in v1.
+- Final per-turn live transcript is the source of truth for realtime orchestration and final grading in the normal path.
+- Uploaded turn audio is evidence and playback data, not a second grading transcript except for explicit live-STT recovery fallback.
+- Official docs informing this plan:
+ - [Live API capabilities guide](https://ai.google.dev/gemini-api/docs/live-guide)
+ - [Session management with Live API](https://ai.google.dev/gemini-api/docs/live-session)
+ - [Live WebSockets API reference](https://ai.google.dev/api/live)
+ - [Get started with Live API](https://ai.google.dev/api/multimodal-live)
\ No newline at end of file
diff --git a/upskilling/docs/plans/2026-04-01-roleplay-audio-v0-clone-plan.md b/upskilling/docs/plans/2026-04-01-roleplay-audio-v0-clone-plan.md
new file mode 100644
index 0000000..5566565
--- /dev/null
+++ b/upskilling/docs/plans/2026-04-01-roleplay-audio-v0-clone-plan.md
@@ -0,0 +1,688 @@
+# Roleplay Service Audio-First v0 Clone Plan
+
+## Summary
+- Ship `services/roleplay-service` by cloning the production-ready `services/interview-service` and making the smallest set of changes needed to support live audio-first roleplay.
+- Reuse the same backend-owned Gemini Live WebSocket transport, turn persistence, artifact archival, storage, and asynchronous post-session review flow.
+- Replace interview-specific planning, prompting, routing, and rubric logic with roleplay-specific equivalents.
+- Persist every generated roleplay scenario separately so the generated plans and transcripts can later become the seed catalogue for curated scenarios.
+
+## Confirmed Decisions
+- Roleplay v0 is audio-first only.
+- Facial, body, video, and screen-share analysis are out of scope for v0.
+- Use a new audio-only roleplay rubric for v0.
+- Keep the same live WebSocket streaming protocol as the interview service.
+- Create a new scenario row for every configure request.
+- `brief` is optional in the configure request.
+- Reuse the interview DSPy planning path, but feed it a roleplay brief and store the full generated payloads.
+
+## Goals
+1. Launch a live roleplay service quickly by reusing the already-approved interview service architecture.
+2. Preserve enough structure and generated data to evolve into a managed scenario catalogue later.
+3. Keep the implementation surgical so production risk stays low.
+4. Avoid introducing video and screen analysis complexity before the audio path is live.
+
+## Non-Goals
+- Video capture or storage.
+- Screen-share capture or storage.
+- Facial expression, body language, or visual technical quality scoring.
+- Admin scenario management UI.
+- Scenario reuse or deduplication logic.
+- Full BRD parity for all roleplay metrics in v0.
+
+## Baseline To Reuse From Interview Service
+The following pieces from `services/interview-service` are already a strong foundation and should be cloned with minimal behavioral change:
+
+- FastAPI app shell and health endpoint.
+- Sync SQLAlchemy session management and DB initialization.
+- Live WebSocket session loop in `app/api/session_ws.py`.
+- Gemini Live relay in `app/services/live_relay.py`.
+- Turn persistence for final assistant and candidate transcripts.
+- Audio archive builder in `app/services/archive.py`.
+- Storage upload service in `app/services/storage.py`.
+- Background review generation scheduling and retry flow.
+- Existing DSPy client structure for plan generation and review generation.
+
+## High-Level Service Shape
+Create a new service directory by copying `services/interview-service` to `services/roleplay-service`.
+
+The initial structure stays intentionally similar:
+
+- `app/main.py`
+- `app/api/`
+- `app/db/`
+- `app/services/`
+- `app/assets/`
+- `tests/`
+
+The aim is to keep as much of the runtime and deployment story identical as possible.
+
+## Public API v0
+All endpoints live under `/api/v1`.
+
+### 1. Configure Roleplay
+`POST /api/v1/roleplays/configure`
+
+Purpose:
+- Create a new scenario record.
+- Create a new roleplay session.
+- Run DSPy planning against a roleplay brief.
+- Persist the generated scenario definition and session prompt plan.
+
+Request payload:
+
+```json
+{
+ "user_id": "user-123",
+ "org_id": "org-456",
+ "persona_id": "emma",
+ "duration_minutes": 15,
+ "roleplay_type": "custom",
+ "brief": "optional freeform roleplay brief",
+ "metadata": {
+ "target_role": "Customer Success Manager",
+ "candidate_name": "Asha",
+ "experience_level": "mid"
+ }
+}
+```
+
+Response payload:
+
+```json
+{
+ "session_id": "...",
+ "scenario_id": "...",
+ "config": {
+ "persona_id": "emma",
+ "duration_minutes": 15,
+ "roleplay_type": "custom",
+ "metadata": {}
+ },
+ "opening_prompt": "...",
+ "prompt_outline": [
+ {
+ "sequence": 1,
+ "prompt": "...",
+ "signals": ["..."],
+ "rubric_dimensions": ["voice", "content", "scenario_adherence"]
+ }
+ ],
+ "scenario": {
+ "title": "...",
+ "setup": "...",
+ "constraints": [],
+ "success_criteria": []
+ }
+}
+```
+
+### 2. Live Session WebSocket
+`WS /api/v1/roleplays/session/{session_id}`
+
+Purpose:
+- Preserve the same proven transport contract from the interview service.
+- Use the same client integration pattern as interview.
+
+Client messages:
+- `session.start`
+- `audio.input`
+- `session.finish`
+
+Server messages:
+- `session.ready`
+- `assistant.audio`
+- `assistant.transcript`
+- `candidate.transcript`
+- `turn.saved`
+- `session.completed`
+- `error`
+
+### 3. Review Polling
+`GET /api/v1/roleplays/review/{session_id}`
+
+Purpose:
+- Poll review status after `session.finish`.
+- Return completed review payload and artifacts.
+
+Response states:
+- `processing`
+- `completed`
+- `failed`
+
+Completed payload additions beyond interview:
+- `certificate_eligible`
+- `provider_payload` can remain stored in DB only for v0 unless explicitly exposed later
+
+### 4. Optional Read Endpoints
+These are low-risk and useful, but not required for the first implementation slice:
+
+- `GET /api/v1/roleplays/personas`
+- `GET /api/v1/roleplays/scenarios`
+- `GET /api/v1/roleplays/scenarios/{scenario_id}`
+
+## Data Model
+The data model should stay close to the interview schema so the cloned service remains easy to reason about.
+
+### New Table: `roleplay_scenarios`
+Purpose:
+- Persist every generated scenario independently.
+- Capture the open-ended scenario brief and the generated planning payloads.
+- Form the basis of a future reusable scenario catalogue.
+
+Fields:
+- `id`
+- `org_id`
+- `user_id`
+- `persona_id`
+- `roleplay_type`
+- `brief_text`
+- `scenario_payload` JSON
+- `plan_payload` JSON
+- `created_at`
+- `updated_at`
+
+Recommended `scenario_payload` shape:
+
+```json
+{
+ "title": "...",
+ "setup": "...",
+ "persona_role": "...",
+ "candidate_role": "...",
+ "success_criteria": ["..."],
+ "constraints": ["..."],
+ "tags": ["..."],
+ "difficulty": "..."
+}
+```
+
+Recommended `plan_payload` shape:
+
+```json
+{
+ "greeting_text": "...",
+ "questions": ["..."],
+ "follow_up_policy": {},
+ "safety_guardrails": {},
+ "source": "dspy"
+}
+```
+
+### Table: `roleplay_sessions`
+Clone of `interview_sessions` with roleplay-specific naming and one extra link to the scenario row.
+
+Fields:
+- `id`
+- `scenario_id`
+- `user_id`
+- `org_id`
+- `roleplay_config` JSON
+- `status`
+- `planning_context` JSON
+- `prompt_plan` JSON list
+- `opening_prompt`
+- `created_at`
+- `updated_at`
+- `completed_at`
+
+Recommended `roleplay_config` contents:
+- `persona_id`
+- `duration_minutes`
+- `roleplay_type`
+- `metadata`
+- `rubric_profile_id`
+
+Recommended `planning_context` contents:
+- `plan_input`
+- `history_summary`
+- `follow_up_policy`
+- `scenario_payload`
+- `plan_payload`
+- `review_generation`
+- `finalization_error`
+- `session_termination`
+
+### Table: `roleplay_turns`
+Clone of `interview_turns`.
+
+Fields:
+- `id`
+- `session_id`
+- `sequence`
+- `speaker`
+- `turn_type`
+- `transcript`
+- `timing`
+- `turn_metadata`
+- `created_at`
+
+### Table: `roleplay_artifacts`
+Clone of `interview_artifacts`.
+
+Fields:
+- `id`
+- `session_id`
+- `artifact_type`
+- `s3_key`
+- `mime_type`
+- `duration_ms`
+- `size_bytes`
+- `manifest_metadata`
+- `created_at`
+
+### Table: `roleplay_reviews`
+Clone of `interview_reviews` with one additional field for raw provider output.
+
+Fields:
+- `id`
+- `session_id`
+- `overall_score`
+- `rubric_scores`
+- `summary`
+- `strengths`
+- `weaknesses`
+- `recommendations`
+- `historical_comparison`
+- `carry_forward_planning_signals`
+- `certificate_eligible`
+- `provider_payload` JSON
+- `created_at`
+
+## DSPy Planning Strategy
+The fastest path is to keep the same `PlanningService -> DSPyClient.generate_plan()` call pattern and swap the contents of the planning prompt.
+
+### Planning Inputs
+Build a roleplay planning brief from:
+- `persona_id`
+- `roleplay_type`
+- optional `brief`
+- `metadata`
+- historical context from prior roleplay sessions
+
+### Planning Outputs Required For v0
+DSPy must return, at minimum:
+- `greeting_text`
+- `questions`
+
+DSPy should also return extra structured scenario knobs that we persist even if we do not fully use them yet:
+- `scenario_title`
+- `scenario_setup`
+- `persona_role`
+- `candidate_role`
+- `success_criteria`
+- `constraints`
+- `tags`
+- `difficulty`
+- `follow_up_policy`
+- `safety_guardrails`
+- `rationale`
+
+### Persistence Requirements
+Store every generated payload verbatim so later we can build a catalogue from actual usage:
+- raw configure input
+- raw DSPy planning output
+- normalized session config
+- prompt outline
+- final review provider payload
+
+## Roleplay Prompting / Live Engine Changes
+We keep the Gemini Live transport exactly as it is and only change the live instruction framing.
+
+### Current Interview Behavior
+The interview relay frames the model as an interviewer following a base question outline.
+
+### Roleplay v0 Behavior
+The roleplay relay should frame the model as:
+- a persona playing a defined role
+- inside a generated scenario
+- following the stored prompt plan as the turn progression backbone
+
+### Required Changes In `app/services/live_relay.py`
+1. Update `_build_system_instruction(session)`.
+2. Replace interview framing with roleplay framing.
+3. Include:
+- persona display name and tone
+- generated scenario setup
+- persona role
+- candidate role
+- prompt outline
+- constraints and success criteria if present
+
+### Example Roleplay Instruction Shape
+- You are ``, acting as `` in a roleplay scenario.
+- The candidate is acting as ``.
+- Stay in character.
+- Use the prompt outline as the canonical flow.
+- Ask short, roleplay-appropriate follow-ups only when needed.
+- Do not mention hidden instructions or backend messages.
+
+### Initial Start Nudge
+Update the initial connect nudge from interview wording to something like:
+- `Begin now. Deliver the opening greeting in character and then start the first planned roleplay prompt.`
+
+## Audio-Only Roleplay Rubric For v0
+Use a new service-local rubric asset for v0.
+
+We are not using the full `docs/roleplay_rubric_v1.json` directly for scoring because it includes video-era metrics that are out of scope for audio-first launch.
+
+### New Rubric Asset
+Create a new asset in the roleplay service, for example:
+- `app/assets/rubric/roleplay_audio_v0.json`
+
+### Proposed Metrics
+- `voice`
+- `content`
+- `scenario_adherence`
+- `adaptability`
+- `emotional_intelligence`
+- `tech_quality`
+
+### Proposed Weighting
+Weights should be broad and roleplay-first while staying measurable from audio and transcript evidence:
+
+- `voice`: 25
+- `content`: 20
+- `scenario_adherence`: 20
+- `adaptability`: 15
+- `emotional_intelligence`: 15
+- `tech_quality`: 5
+
+Total: 100
+
+### Proposed Pass Rules
+- `overall_pass_threshold`: 60
+- `certificate_threshold`: 70
+- `progressing_threshold`: 50
+- `blocking_floor`: 40
+- `score_scale`: `[0, 100]`
+
+### Relationship To `docs/roleplay_rubric_v1.json`
+- Keep `docs/roleplay_rubric_v1.json` as the broader future-facing rubric source.
+- v0 introduces a narrower operational rubric for audio-only production launch.
+- Later we can evolve the service rubric toward the broader document once video and screen inputs exist.
+
+## Review Generation Strategy
+The review path should stay close to `app/services/review.py` from interview-service.
+
+### Reuse
+- Background scheduling and retry logic.
+- Polling pattern.
+- Artifact serialization.
+- Historical comparison structure.
+
+### Change
+1. Swap rubric loader to the roleplay audio rubric.
+2. Change metric keys and deterministic scoring heuristics.
+3. Build a roleplay-specific review brief for DSPy.
+4. Store the raw review payload in `provider_payload`.
+5. Compute `certificate_eligible` from pass rules.
+
+### Deterministic Evidence Inputs
+Continue using transcript- and artifact-derived inputs similar to interview-service:
+- filler count
+- words per minute
+- ownership markers
+- quantified outcomes
+- role and scenario keyword overlap
+- duration and pacing
+- audio artifact presence and manifest signals
+
+### Historical Comparison
+Same approach as interview-service:
+- compare against most recent prior completed roleplay review for the same user and org
+- compute overall delta
+- compute per-metric deltas
+
+### Carry-Forward Planning Signals
+Keep these because they are useful for future scenario generation and progressive coaching:
+- `focus_areas`
+- `recurring_weak_areas`
+- `weakness_summary`
+
+## Minimal File-Level Implementation Plan
+
+### Slice 1: Clone and Rename Service Identity
+Create `services/roleplay-service` by copying `services/interview-service`.
+
+Update:
+- `pyproject.toml`
+- `README.md`
+- `Dockerfile`
+- `docker-compose.yml`
+- `app/main.py`
+- `app/core/config.py`
+
+Required renames:
+- service title and package metadata
+- database filename / DB name
+- temp directory path
+- storage bucket name
+- local docker port
+
+### Slice 2: Rename Data Layer
+Update:
+- `app/db/models.py`
+- `app/db/session.py`
+
+Tasks:
+- rename interview models to roleplay models
+- introduce `RoleplayScenario`
+- add `certificate_eligible` and `provider_payload` to review model
+- keep relationships otherwise parallel to interview
+
+### Slice 3: Configure Endpoint And Planning
+Update:
+- `app/api/configure.py`
+- `app/services/planning.py`
+- `app/services/dspy_client.py`
+- `app/services/assets.py`
+
+Tasks:
+- change route to `/roleplays/configure`
+- accept `roleplay_type`, optional `brief`, and `metadata`
+- persist a new `RoleplayScenario`
+- create a linked `RoleplaySession`
+- store the full DSPy outputs into both scenario and session context
+
+### Slice 4: Live WebSocket Route
+Update:
+- `app/api/session_ws.py`
+- `app/services/live_relay.py`
+
+Tasks:
+- change route path to `/roleplays/session/{session_id}`
+- keep message protocol unchanged
+- swap the system prompt framing to roleplay
+- return `prompt_outline` and roleplay config in `session.ready`
+
+### Slice 5: Artifacts And Storage Prefixes
+Update:
+- `app/services/archive.py`
+
+Tasks:
+- change artifact storage prefix from `interviews/...` to `roleplays/...`
+- rename manifest keys from `interview_config` to `roleplay_config`
+
+### Slice 6: Review Endpoint And Scoring
+Update:
+- `app/api/review.py`
+- `app/services/review.py`
+- `app/assets/rubric/roleplay_audio_v0.json`
+
+Tasks:
+- change route path to `/roleplays/review/{session_id}`
+- compute roleplay metric scores using the audio-only rubric
+- compute `certificate_eligible`
+- persist `provider_payload`
+
+### Slice 7: Tests
+Clone and adapt the interview tests:
+
+- `tests/test_configure.py`
+- `tests/test_session_ws.py`
+- `tests/test_review.py`
+
+Required assertions:
+- configure persists both scenario and session
+- raw DSPy plan payload is stored
+- WS session persists turns and uploads artifacts
+- review returns roleplay metrics and certificate eligibility
+
+## Concrete Data Contracts
+
+### Configure Plan Storage In `planning_context`
+Recommended shape:
+
+```json
+{
+ "plan_input": {
+ "roleplay_type": "custom",
+ "brief": "...",
+ "metadata": {}
+ },
+ "history_summary": {
+ "prior_session_count": 0,
+ "recent_weak_areas": [],
+ "recent_summaries": []
+ },
+ "follow_up_policy": {
+ "max_follow_ups_per_prompt": 1,
+ "max_follow_ups_per_session": 2,
+ "allowed_objectives": ["depth", "clarity", "example", "adaptation", "tone"]
+ },
+ "scenario_payload": {},
+ "plan_payload": {}
+}
+```
+
+### Prompt Outline Shape
+
+```json
+[
+ {
+ "sequence": 1,
+ "prompt": "...",
+ "signals": ["dspy planned", "scenario focus: stakeholder tension"],
+ "rubric_dimensions": ["voice", "content", "scenario_adherence"]
+ }
+]
+```
+
+### Review Response Shape
+
+```json
+{
+ "status": "completed",
+ "session_id": "...",
+ "overall_score": 78.4,
+ "rubric_scores": {
+ "voice": 81,
+ "content": 76,
+ "scenario_adherence": 79,
+ "adaptability": 72,
+ "emotional_intelligence": 80,
+ "tech_quality": 85
+ },
+ "summary": "...",
+ "strengths": ["..."],
+ "weaknesses": ["..."],
+ "recommendations": ["..."],
+ "historical_comparison": null,
+ "carry_forward_planning_signals": {
+ "focus_areas": ["adaptability"],
+ "recurring_weak_areas": [],
+ "weakness_summary": ["Could adapt faster to objections"]
+ },
+ "certificate_eligible": true,
+ "audio_artifacts": []
+}
+```
+
+## Risks And Mitigations
+
+### Risk 1: Roleplay Planning Is Too Open-Ended
+Because scenario generation is intentionally open, outputs may be inconsistent.
+
+Mitigation:
+- enforce a structured DSPy JSON schema
+- persist all plan payloads for later tuning
+- keep prompt outline authoritative for the live session
+
+### Risk 2: Prompt Drift During Live Session
+The live model may improvise away from the scenario.
+
+Mitigation:
+- make prompt outline explicit in system instruction
+- instruct the model to stay in character and use the outline as the canonical flow
+
+### Risk 3: Review Rubric Expectations Drift From BRD
+Audio-only v0 will not match the broader visual roleplay rubric.
+
+Mitigation:
+- use a dedicated operational audio rubric for v0
+- keep the broader doc rubric intact for later phases
+
+### Risk 4: Scenario Table Could Grow Quickly
+Every configure request creates a new scenario row.
+
+Mitigation:
+- this is intentional in v0
+- later introduce scenario grouping, dedupe, or promotion-to-catalogue workflows
+
+## Test Plan
+
+### Configure
+- accepts optional `brief`
+- persists a `RoleplayScenario`
+- persists a linked `RoleplaySession`
+- stores raw DSPy `scenario_payload` and `plan_payload`
+- returns `opening_prompt` and `prompt_outline`
+
+### WebSocket Live Session
+- rejects missing session id
+- rejects invalid session state transition
+- starts roleplay session successfully
+- persists assistant and candidate final transcripts
+- builds and uploads artifacts on `session.finish`
+- schedules review generation
+
+### Review
+- returns `processing` before review exists
+- returns `failed` when generation fails
+- returns `completed` with roleplay rubric scores
+- returns `certificate_eligible`
+- returns artifact list
+
+## Rollout Shape
+
+### Phase A
+- land the new service with configure + live WS + review
+- keep only personas as asset-backed read data
+- scenarios are generated on demand and stored every time
+
+### Phase B
+- add read endpoints for generated scenarios
+- analyze stored plans and transcripts to identify reusable patterns
+
+### Phase C
+- curate generated scenarios into a controlled catalogue
+- introduce guardrails, scenario templates, and reuse flows
+- expand rubric toward visual and screen-aware metrics once media inputs exist
+
+## Recommended First Execution Order
+1. Clone `interview-service` into `roleplay-service`.
+2. Rename config, DB models, and storage prefixes.
+3. Add `RoleplayScenario` and wire configure persistence.
+4. Swap planning prompt and configure endpoint.
+5. Swap live relay prompt framing.
+6. Add audio-only roleplay rubric and review logic.
+7. Adapt tests and run them.
+
+## Definition Of Done For v0
+- `services/roleplay-service` exists and boots independently.
+- A client can configure a roleplay session with an optional brief.
+- A live audio session runs over the same WS protocol as interview-service.
+- Final transcripts, artifacts, scenario payloads, and plan payloads are persisted.
+- Post-session review completes using the audio-only roleplay rubric.
+- Review output includes `certificate_eligible`.
+- The implementation remains close enough to interview-service that future maintenance is straightforward.
diff --git a/upskilling/docs/prd/Assessment Service.docx.md b/upskilling/docs/prd/Assessment Service.docx.md
new file mode 100644
index 0000000..de8c950
--- /dev/null
+++ b/upskilling/docs/prd/Assessment Service.docx.md
@@ -0,0 +1,322 @@
+**GrowQR**
+
+**ASSESSMENT SERVICE**
+
+Business Requirements Document • v2.0 • March 2026
+
+| Upskilling Module • Microservice Specification Integrates with: Roleplay • Interview • Course • Pathways • Dashboard |
+| :---: |
+
+
+
+
+
+| Document Title | Assessment Service — Business Requirements Document |
+| :---- | :---- |
+
+
+
+| Service Type | Standalone Microservice (Part of Upskilling Services) |
+| :---- | :---- |
+
+
+
+| Version | |
+| :---- | :---- |
+
+
+
+| Integration | Shares data with Roleplay, Interview, Course services \+ Pathways \+ Dashboard |
+| :---- | :---- |
+
+
+
+| Third-Party LMS | Moodle, Thinkific (no proprietary LMS built) |
+| :---- | :---- |
+
+
+
+
+
+| 1\. SERVICE OVERVIEW |
+| :---- |
+
+
+
+The Assessment Service provides AI-generated, role-specific skill assessments structured around a three-box engine: Input, Processing, and Output. Assessments are micro-format (3–4 minutes), designed for engagement and measurability. The platform integrates with third-party LMS platforms (Moodle, Thinkific) and does not build a proprietary LMS.
+
+
+
+## **1.1 Three-Box Engine Architecture**
+
+All assessments flow through a standardized three-stage engine: ![][image1]
+
+
+
+## **1.2 Core Features**
+
+• Three-box engine: Input (corporate/institutes/LLM) → Processing (intent \+ tier) → Output (standardized report)
+
+• Micro-assessments: 3–4 minutes per session for high engagement and completion
+
+• AI-generated role-specific questions (21 per assessment); GenAI rephrases for binary clarity
+
+• Difficulty levels: Easy, Medium, Hard (adaptive or fixed per question)
+
+• Multiple choice format (4 options per question), timed with countdown timer
+
+• STAR schema evaluation for situational/behavioral questions
+
+• Certificates awarded for passing score (70%+) on eligible assessments
+
+• Fallback pre-built question bank when AI generation fails
+
+• Third-party LMS integration: Moodle, Thinkific (no proprietary LMS)
+
+• Recruiter and university posting capability via corporate input channel
+
+
+
+## **1.3 Value Proposition**
+
+Small, focused assessments help college students and professionals measure fit for roles, motivation, culture alignment, and company values. The question bank concept enables HR integration and recruiter-led workflows. Assessments directly feed into Q-Score improvements and job opportunity matching.
+
+
+
+
+
+
+
+| 2\. FUNCTIONS |
+| :---- |
+
+
+
+## **FUNCTION 1: Assessment Generation**
+
+**2.1.1 Generation Sources**
+
+Assessments are generated from two input channels:
+
+1\. Corporate Input: Recruiters or universities post role-specific assessments directly to the platform. Questions are pre-authored and stored in the question bank.
+
+2\. LLM Input: AI generates 21 questions tailored to the user’s role, covering technical skills, behavioral scenarios, and domain knowledge. GenAI rephrases questions for binary clarity where needed.
+
+
+
+**2.1.2 Assessment Design Principles**
+
+• Micro-format: Each assessment completes in 3–4 minutes to maximize engagement
+
+• Questions must be clear and binary where possible; GenAI rephrases ambiguous questions
+
+• Situational questions evaluated using STAR schema (Situation, Task, Action, Reaction)
+
+• Background verification: Situational responses cross-referenced against user profile data
+
+• Communication style evaluated alongside content accuracy
+
+• Open-ended questions are not used — monitoring and scoring reliability is insufficient
+
+
+
+**2.1.3 Data Requirements**
+
+| Field | Description |
+| :---- | :---- |
+| Assessment ID | Unique identifier |
+| User ID | Who is taking the assessment |
+| Role / Title | Job role (e.g., Python Backend Developer) |
+| Input Source | Corporate (recruiter-posted) / LLM (AI-generated) / Hybrid |
+| Question Bank | Array of 21 question objects |
+| Question Object | Question text, 4 options, correct answer, difficulty, topic, STAR tag |
+| Time Limit | Total time allowed (e.g., 20 minutes) |
+| Tier | User subscription tier — determines question depth and volume |
+| Started At | Timestamp when assessment started |
+| Status | Generating / Ready / In Progress / Completed |
+
+
+
+**2.1.4 States**
+
+| State | Backend Response |
+| :---- | :---- |
+| Generating | Show: 'Generating Assessment… Our AI is crafting unique questions for this role.' (10–15 seconds) |
+| Ready | Questions generated; return assessment ID \+ start link |
+| AI Error | AI generation failed → Use fallback question bank; flag question source in UI |
+| Invalid Role | Role not recognized → Ask user to specify or use generic assessment |
+
+
+
+
+
+## **FUNCTION 2: Taking the Assessment**
+
+**2.2.1 Assessment Flow**
+
+• User starts assessment → Timer begins (countdown: 19:59, 19:58…)
+
+• Questions displayed one at a time: 'Question 3 of 21'
+
+• User selects one of 4 multiple choice options (radio buttons)
+
+• User can navigate: Previous / Next Question
+
+• Difficulty badge shown per question: 'Medium Difficulty'
+
+• STAR-tagged questions display scenario context before answer options
+
+• User can submit early OR timer expires → Auto-submit
+
+
+
+**2.2.2 Measurement Framework**
+
+For situational / behavioral questions, the platform applies the STAR schema:
+
+| Component | Stands For | How Evaluated |
+| :---- | :---- | :---- |
+| S | Situation | Cross-referenced against user’s profile and background data |
+| T | Task | Verified for role-relevance and complexity level |
+| A | Action | Evaluated for decision quality and communication style |
+| R | Reaction | Assessed for outcome awareness and self-reflection |
+
+
+
+**2.2.3 Data Captured**
+
+• User answers: Array of selected options per question
+
+• Time per question: Seconds spent on each question
+
+• Navigation pattern: Sequence of question views (for analysis)
+
+• Submission type: Early submit / Timer expired
+
+• Completion time: Total time taken
+
+• Score: Number correct / 21 (percentage)
+
+
+
+
+
+## **FUNCTION 3: Results & Analysis**
+
+**2.3.1 Standardised Output Report**
+
+Every completed assessment produces a well-defined, standardised report. Outputs feed into Q-Score calculations and job opportunity matching pipelines.
+
+• Overall score: Percentage (e.g., 85%)
+
+• Score by topic/category (e.g., 'Python Basics: 90%, Backend: 75%')
+
+• STAR schema breakdown for behavioral questions
+
+• Communication style rating (derived from scenario responses)
+
+• Correct vs. incorrect breakdown with explanations
+
+• Time spent per question
+
+• Comparison to average user in same role
+
+• Recommended focus areas (topics with low scores)
+
+• Q-Score contribution: Which Q-Scores are updated based on results
+
+• Job opportunity flag: Whether results unlock specific job matches
+
+
+
+**2.3.2 Certificate Generation**
+
+• Certificate issued when: Score \>= 70% AND assessment is certificate-eligible
+
+• Practice / diagnostic assessments are not certificate-eligible
+
+• Certificate includes: User name, Assessment title, Score, Date, Certificate ID
+
+
+
+
+
+## **FUNCTION 4: Third-Party LMS Integration**
+
+GrowQR will not build a proprietary LMS. All courseware and assessment delivery integrates with established third-party platforms.
+
+
+
+| Platform | Integration Type | Use Case |
+| :---- | :---- | :---- |
+| Moodle | API / Webhook | Open-source LMS for institutional and corporate assessment delivery |
+| Thinkific | API / Embed | Course and assessment hosting for third-party content creators |
+| Internal Fallback | Native | GrowQR question bank used when no external source is available |
+
+
+
+
+
+| 3\. DATA SHARING WITH OTHER SERVICES |
+| :---- |
+
+
+
+| Target Service | Data Shared | Purpose |
+| :---- | :---- | :---- |
+| Course Service | Low-scoring topics, skill gaps identified | Recommend courses to address weak areas |
+| Interview Service | Technical knowledge gaps, topics scored low | Tailor interview questions to validate weak areas |
+| Roleplay Service | Behavioural/scenario performance, weak competencies | Suggest roleplay scenarios for practice |
+| Pathways Service | Assessment completion, Q-Score deltas, role fit scores | Update weekly cycle priorities and pathway recommendations |
+| Dashboard Service | Assessment count, scores, certificates earned, focus areas | Update Q-Score, show progress, display achievements |
+| Job Matchmaking | Role fit score, Q-Score contributions, skill signals | Surface relevant job opportunities post-assessment |
+
+
+
+
+
+| 4\. TECHNICAL REQUIREMENTS |
+| :---- |
+
+
+
+## **4.1 Performance Requirements**
+
+| Operation | Target SLA |
+| :---- | :---- |
+| Question generation (21 questions) | \< 15 seconds |
+| Assessment start (after generation) | \< 1 second |
+| Question navigation | \< 200ms |
+| Score calculation | \< 3 seconds after submission |
+| Report generation | \< 5 seconds |
+| Certificate generation (if eligible) | \< 3 seconds |
+| LMS sync (Moodle / Thinkific) | \< 10 seconds |
+
+
+
+
+
+| 5\. ACCEPTANCE CRITERIA |
+| :---- |
+
+
+
+| \# | Must Pass | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Three-box engine operates correctly: Input (corporate/LLM), Processing (intent \+ tier), Output (standardised report) | \[ \] PASS \[ \] FAIL |
+| **2** | AI generates 21 questions within 15s. Fallback question bank activates on AI failure. | \[ \] PASS \[ \] FAIL |
+| **3** | Micro-assessment format completes within 3–4 minutes for standard question sets. | \[ \] PASS \[ \] FAIL |
+| **4** | GenAI rephrasing produces binary, clear questions. No open-ended questions in scored flow. | \[ \] PASS \[ \] FAIL |
+| **5** | STAR schema correctly applied to situational questions. Background cross-reference works. | \[ \] PASS \[ \] FAIL |
+| **6** | Timer counts down correctly. Navigation (Prev/Next) works. Auto-submit on timeout. | \[ \] PASS \[ \] FAIL |
+| **7** | Score calculated correctly. Topic breakdown accurate. Comparison to average shown. | \[ \] PASS \[ \] FAIL |
+| **8** | Standardised report generated with Q-Score contributions and job opportunity flags. | \[ \] PASS \[ \] FAIL |
+| **9** | Certificates generated for eligible assessments with score \>= 70%. Download works. | \[ \] PASS \[ \] FAIL |
+| **10** | Moodle and Thinkific integrations functional for corporate/institutional assessment delivery. | \[ \] PASS \[ \] FAIL |
+| **11** | Skill gaps and Q-Score signals shared with all connected services correctly. | \[ \] PASS \[ \] FAIL |
+| **12** | Recruiter and university posting workflow functional via corporate input channel. | \[ \] PASS \[ \] FAIL |
+
+
+
+
+[image1]:
\ No newline at end of file
diff --git a/upskilling/docs/prd/Courses.docx.md b/upskilling/docs/prd/Courses.docx.md
new file mode 100644
index 0000000..d7a42b7
--- /dev/null
+++ b/upskilling/docs/prd/Courses.docx.md
@@ -0,0 +1,335 @@
+**GrowQR**
+
+**COURSE SERVICE**
+
+Business Requirements Document • v2.0 • March 2026
+
+| Upskilling Module • Microservice Specification Three-Phase Courseware Strategy • No Proprietary LMS |
+| :---: |
+
+
+
+
+
+| Document Title | Course Service — Business Requirements Document |
+| :---- | :---- |
+
+
+
+| Service Type | Standalone Microservice (Part of Upskilling Services) |
+| :---- | :---- |
+
+
+
+| Version | |
+| :---- | :---- |
+
+
+
+| Integration | Shares data with Roleplay, Interview, Assessment, Pathways \+ Dashboard |
+| :---- | :---- |
+
+
+
+| Courseware Strategy | Three-phase: External Index → Third-Party Creator → GenAI IP Generation |
+| :---- | :---- |
+
+
+
+| LMS Approach | No proprietary LMS. Integrates with Coursera, Moodle, Thinkific and others |
+| :---- | :---- |
+
+
+
+
+
+| 1\. SERVICE OVERVIEW |
+| :---- |
+
+
+
+The Course Service provides a curated learning library with external provider integrations and community-created content. Users enroll using credits, track progress, and earn certificates upon completion. GrowQR does not build a proprietary LMS — all courseware delivery relies on third-party platforms and a three-phase strategy to progressively own intellectual property.
+
+
+
+## **1.1 Core Features**
+
+• Three-phase courseware strategy: External mapping → Third-party creation → GenAI IP generation
+
+• No proprietary LMS: Integration with Coursera, Moodle, Thinkific, LinkedIn Learning
+
+• Course catalog with external provider integrations and community scenarios
+
+• AI-powered recommendations based on skill gaps from Assessment, Interview, Roleplay, Q-Score
+
+• Credit-based enrolment tracking: In Progress / Completed / Abandoned
+
+• Certificate generation upon course completion (eligible courses only)
+
+• Persona-driven content mapping across 20–25 unique user profiles, industries, and life stages
+
+
+
+
+
+
+
+| 2\. THREE-PHASE COURSEWARE STRATEGY |
+| :---- |
+
+
+
+The courseware strategy follows a deliberate, staged approach that builds toward platform intellectual property (IP) through GenAI-generated, persona-driven content. Each phase unlocks the next.
+
+
+
+| PHASE 1: External Mapping & Indexing |
+| :---- |
+| • Map user personas to purchased or indexed external courses (e.g., Coursera, LinkedIn Learning, Udemy) |
+| • Users browse a curated catalog; GrowQR surfaces the most relevant content per role, industry, and Q-Score gap |
+| • Course metadata indexed: title, provider, duration, difficulty, skills covered, rating, price |
+| • AI recommendation engine selects top matches from external catalog based on skill gap analysis |
+| • Revenue model: Affiliate commissions from enrolled courses via provider APIs |
+| • No content creation required — pure aggregation and curation layer |
+
+
+
+| PHASE 2: Third-Party Creator Platform |
+| :---- |
+| • Platform opens to third parties: Heads of Departments (HODs), corporates, and subject matter experts |
+| • Creators bundle and publish their own content within the GrowQR platform |
+| • Content types: Video modules, guided projects, assessments, case studies |
+| • GrowQR provides creator tools, hosting (via Moodle / Thinkific integration), and distribution |
+| • Revenue model: Revenue share with creators; premium access tiers for corporate bundles |
+| • Quality control: Community ratings, completion rates, and AI-driven content scoring |
+| • Enables industry-specific content that external platforms do not cover |
+
+
+
+| PHASE 3: GenAI IP Generation (Intellectual Property) |
+| :---- |
+| • Full-blown personalised course generation using Generative AI |
+| • Content defined by 20–25 unique user personas, mapped to industry, role, and life stage |
+| • Each persona receives a structured, distinct learning path — not just filtered external content |
+| • GrowQR owns this content as platform IP: structured curricula, assessments, and roleplay scenarios |
+| • Life stage mapping: College student → First job → Career pivot → Leadership → Entrepreneurship |
+| • Industry mapping: Tech, Finance, Healthcare, Marketing, Operations, Creative, etc. |
+| • GenAI generates course scripts, quizzes, scenario prompts, and practice exercises on demand |
+| • This phase creates the long-term competitive moat and differentiated platform identity |
+
+
+
+
+
+
+
+| 3\. FUNCTIONS |
+| :---- |
+
+
+
+## **FUNCTION 1: Course Discovery & Catalog**
+
+**3.1.1 Course Sources (by Phase)**
+
+| Phase | Source | Description |
+| :---- | :---- | :---- |
+| Phase 1 | Coursera, LinkedIn Learning, Udemy, edX | Externally indexed courses mapped to user personas and Q-Score gaps |
+| Phase 1 | Internal Fallback / Question Bank | GrowQR-curated content when external APIs are unavailable |
+| Phase 2 | HODs, Corporates, Subject Matter Experts | Third-party content created and hosted via Moodle / Thinkific |
+| Phase 2 | Community Scenarios | User-generated learning content, peer-reviewed and rated |
+| Phase 3 | GenAI Generated (GrowQR IP) | Fully personalised courses generated from 20–25 user personas by GenAI |
+
+
+
+**3.1.2 Persona Mapping (Phase 3 Foundation)**
+
+Course content is structured around 20–25 distinct user personas. Each persona is defined by the intersection of:
+
+• Role category (e.g., Software Engineer, Product Manager, Sales Leader)
+
+• Industry (e.g., FinTech, Healthcare, E-commerce, SaaS)
+
+• Life stage (e.g., College student, Early career, Career pivot, Leadership track, Entrepreneur)
+
+• Q-Score profile (which of the 25 Q-Scores are high, low, or developing)
+
+• Motivation archetype (Technical Specialist, Strategic Leader, Creative Innovator, etc.)
+
+
+
+**3.1.3 Data Requirements**
+
+| Field | Description |
+| :---- | :---- |
+| Course ID | Unique identifier |
+| Title | Course name |
+| Provider | Coursera, LinkedIn Learning, Moodle, Thinkific, GrowQR IP, etc. |
+| Phase | 1 (External) / 2 (Third-Party) / 3 (GenAI IP) |
+| Type | Full Course / Guided Project / Micro-module |
+| Persona Tags | Array of persona IDs this course maps to |
+| Q-Score Tags | Which Q-Scores this course develops |
+| Life Stage | College / Early Career / Pivot / Leadership / Entrepreneur |
+| Duration | Estimated time to complete |
+| Difficulty | Beginner / Intermediate / Advanced |
+| Certificate Available | Boolean — awards certificate on completion? |
+| Credit Cost | Free (1 credit) / Guided Project (2 credits) / Full Course (3 credits) |
+
+
+
+
+
+## **FUNCTION 2: Course Enrolment**
+
+**3.2.1 Enrolment Flow**
+
+1\. User selects course → System checks: credits available, not already enrolled
+
+2\. Credit deducted based on course type
+
+3\. Enrolment record created: User ID, Course ID, Start date, Phase, Status (In Progress)
+
+4\. External courses: Redirect to provider platform with tracking link
+
+5\. Phase 3 / Internal courses: Delivered natively within GrowQR
+
+
+
+**3.2.2 Credit Costs**
+
+• Free courses: 1 credit to enrol
+
+• Guided Projects: 2 credits
+
+• Full Courses: 3 credits
+
+• GenAI IP courses (Phase 3): Credit cost TBD based on persona depth
+
+
+
+
+
+## **FUNCTION 3: Progress Tracking & Certificates**
+
+• Track enrolment status: In Progress / Completed / Abandoned
+
+• External courses (Phase 1): Webhook from provider OR periodic sync
+
+• Third-party courses (Phase 2): Progress tracked via Moodle / Thinkific integration
+
+• GenAI IP courses (Phase 3): Module-level completion tracked natively
+
+• Certificate issued when: Course completed AND Certificate Available \= true
+
+• Certificate includes: User name, Course title, Provider/Phase, Completion date, Certificate ID
+
+
+
+
+
+## **FUNCTION 4: AI-Powered Recommendations**
+
+**3.4.1 Recommendation Logic**
+
+• Analyse data from Assessment, Interview, and Roleplay services
+
+• Identify Q-Score gaps and map to relevant course tags
+
+• Cross-reference user persona profile (role, industry, life stage, archetype)
+
+• Prioritise: Highest-rated courses, best persona match, free courses first
+
+• Phase 3 courses prioritised for users with established Q-Score histories
+
+
+
+**3.4.2 Data Inputs**
+
+• Assessment results: Low-scoring topics and Q-Score contributions
+
+• Interview feedback: Weak areas identified
+
+• Roleplay performance: Scenarios user struggles with
+
+• User profile: Career goals, current role, life stage, archetype
+
+• Pathway data: Current week in cycle and progression phase (Learn vs. Apply ratio)
+
+
+
+
+
+| 4\. DATA SHARING WITH OTHER SERVICES |
+| :---- |
+
+
+
+| Target Service | Data Shared | Purpose |
+| :---- | :---- | :---- |
+| Assessment Service | Courses completed, topics learned | Re-test user on completed course topics to show improvement |
+| Interview Service | Course completion, skills learned | Tailor interview questions to validate learning |
+| Roleplay Service | Course completion, skills practiced | Suggest roleplay scenarios for learned skills |
+| Pathways Service | Enrolment count, completed courses, Q-Score signals | Adjust weekly cycle priorities and learning/apply ratio |
+| Dashboard Service | Enrolment count, completed courses, certificates earned | Update Q-Score, display achievements and progress |
+| Job Matchmaking | Skills learned, certifications, course completion signals | Improve opportunity match quality and relevance |
+
+
+
+
+
+| 5\. TECHNICAL REQUIREMENTS |
+| :---- |
+
+
+
+## **5.1 External API Integrations**
+
+| Provider | Phase | Integration Method |
+| :---- | :---- | :---- |
+| Coursera | Phase 1 | Coursera Catalog API \+ affiliate tracking |
+| LinkedIn Learning | Phase 1 | LinkedIn Learning API |
+| Udemy | Phase 1 | Udemy Affiliate API |
+| edX | Phase 1 | edX API |
+| Moodle | Phase 2 | Moodle REST API \+ Webhook for completion tracking |
+| Thinkific | Phase 2 | Thinkific API \+ Embed for third-party creator content |
+| GrowQR GenAI | Phase 3 | Internal LLM pipeline — on-demand course generation |
+
+
+
+## **5.2 Performance Requirements**
+
+| Operation | Target SLA |
+| :---- | :---- |
+| Course catalog load | \< 2 seconds |
+| Enrolment processing | \< 1 second (after credit check) |
+| AI course recommendation | \< 2 seconds |
+| Certificate generation | \< 3 seconds after completion |
+| External provider sync (Phase 1\) | \< 5 seconds |
+| Moodle / Thinkific sync (Phase 2\) | \< 10 seconds |
+| GenAI course generation (Phase 3\) | \< 30 seconds for full micro-module |
+
+
+
+
+
+| 6\. ACCEPTANCE CRITERIA |
+| :---- |
+
+
+
+| \# | Must Pass | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Phase 1: All courses load from external APIs (Coursera, Udemy, LinkedIn Learning). Filters and persona mapping work. | \[ \] PASS \[ \] FAIL |
+| **2** | Phase 2: Moodle and Thinkific integrations functional. Third-party creators can publish and bundle content. | \[ \] PASS \[ \] FAIL |
+| **3** | Phase 3: GenAI generates structured micro-courses for at least 5 validated personas. Content is unique and role-specific. | \[ \] PASS \[ \] FAIL |
+| **4** | Credits deducted correctly on enrolment. Enrolment record created. External redirect works. | \[ \] PASS \[ \] FAIL |
+| **5** | Progress status updates correctly for all three phases. External sync works or shows last known state. | \[ \] PASS \[ \] FAIL |
+| **6** | Certificates generated for eligible completed courses. Download link works. | \[ \] PASS \[ \] FAIL |
+| **7** | AI recommends relevant courses based on Q-Score gaps, persona profile, and pathway cycle phase. | \[ \] PASS \[ \] FAIL |
+| **8** | Completion data and Q-Score signals shared with all connected services. Dashboard receives course count. | \[ \] PASS \[ \] FAIL |
+| **9** | Persona mapping covers minimum 20 distinct profiles across role, industry, and life stage dimensions. | \[ \] PASS \[ \] FAIL |
+| **10** | Pathway integration: Course recommendations align with current week’s learn/apply ratio in the weekly cycle. | \[ \] PASS \[ \] FAIL |
+
+
+
+
\ No newline at end of file
diff --git a/upskilling/docs/prd/Interview_OnePager.docx.md b/upskilling/docs/prd/Interview_OnePager.docx.md
new file mode 100644
index 0000000..b21a75a
--- /dev/null
+++ b/upskilling/docs/prd/Interview_OnePager.docx.md
@@ -0,0 +1,76 @@
+
+
+| GrowQR Interview Service — One-PagerAvatar-Based AI Interviewers \+ Video/Voice \+ Screen Share | v3 | INTERVIEW |
+| :---- | :---: |
+
+| PURPOSE |
+| ----- |
+| AI-powered mock interviews with 4 avatar-based interviewers (Payal, Emma, John, Kapil) that speak using real-time voice synthesis. Users recorded via video/audio and can share screen for coding tests/technical demos. Comprehensive analysis across 6 metrics (Intro, Facial Expression, Body Language, Language, Voice including filler word count, Outro) \+ Technical Quality (lighting, framing, background, audio). Historical comparison tracks improvement over time. |
+
+| CORE FEATURES | |
+| :---: | :---- |
+| **1** | 4 AI Interviewer Avatars: Payal (warm, friendly), Emma (professional, structured), John (authoritative, challenging), Kapil (casual, conversational) \- each with distinct voice |
+| **2** | Real-Time Voice Synthesis: AI interviewers SPEAK all questions with personality-matched voices and natural intonation |
+| **3** | Interview Types: Warm Up (Non-technical), Coding (Programming), Role-Related (Technical), Behavioral (HR) |
+| **4** | Duration Tiers: 5 mins (1 credit), 15 mins (2 credits \- Premium), 30 mins (3 credits \- Premium) |
+| **5** | Screen Share: User shares specific window for coding tests, technical demos, presentations |
+| **6** | 7-Metric Analysis: Intro (10%), Facial Expression (20%), Body Language (20%), Language (15%), Voice (20% \- includes filler word count), Outro (10%), Technical Quality (5%) |
+| **7** | Historical Comparison: Track improvement across multiple interviews with trend analysis |
+
+| USER JOURNEY | | | |
+| :---: | ----- | ----- | ----- |
+| **Step** | **User Action** | **System Response** | **Data Captured** |
+| **1** | User configures interview | Validate: type, duration, persona, credits | Config parameters |
+| **2** | User starts interview | Deduct credits, load avatar, request permissions | Session ID, Credits deducted |
+| **3** | Avatar speaks greeting | Voice synthesis: "Hello\! I'm your AI interviewer..." | Timer starts, Recording begins |
+| **4** | User shares screen (optional) | Capture window, start screen analysis | Screen recording, Window type |
+| **5** | Avatar speaks question | Voice synthesis with lip-sync | Question logged |
+| **6** | User responds (voice/text) | Capture video/audio, analyze filler words, process screen | Transcript, Filler count, Technical quality, Screen |
+| **7** | Session ends | Stop recordings, trigger analysis | End time, Completion status |
+| **8** | Analysis completes | Calculate 7 metrics, compare to history | All metric scores \+ historical comparison |
+
+| KEY STATES TO HANDLE | | |
+| ----- | ----- | ----- |
+| **State** | **Condition** | **System Behavior** |
+| **Permission Denied** | User blocks camera/mic | Error: 'Camera/mic required. Screen share optional for coding.' |
+| **Avatar Loading** | Persona initializing | Show: 'Preparing interview with \[Name\]...' (5-10s) |
+| **Active Interview** | Session in progress | Avatar speaks, user responds, timer running |
+| **Screen Share Active** | User sharing window | Screen content captured and analyzed |
+| **AI Service Error** | AI unavailable | Show error, use fallback questions |
+| **Voice Synthesis Error** | TTS fails | Fallback: text bubbles |
+| **Analysis Processing** | Calculating metrics | Show: 'Analyzing...' (30-60s) |
+| **Results Ready** | Analysis complete | Display 7 metrics \+ screen \+ historical \+ recommendations |
+
+| ANALYSIS METRICS | |
+| ----- | ----- |
+| **Metric** | **What's Analyzed** |
+| **Intro (10%)** | Opening greeting quality, confidence, first impression, professionalism |
+| **Facial Expression (20%)** | Engagement, authenticity, eye contact, smile appropriateness, emotional state |
+| **Body Language (20%)** | Posture, Gestures, Professionalism, Fidgeting, Movement patterns |
+| **Language (15%)** | Grammar, Vocabulary, Clarity, Sentence structure, Articulation |
+| **Voice (20%)** | Tone, Pace (WPM), Volume, Filler words COUNT (um, uh, like, you know), Vocal confidence |
+| **Outro (10%)** | Closing statement, Questions to interviewer, Professionalism, Final impression |
+| **Technical Quality (5%)** | Lighting: Well-lit/Poor | Framing: Centered/Off | Background: Professional/Distracting | Audio: Clear/Noisy |
+| **Screen Content** | Code: Syntax, Structure, Logic | Presentations: Quality, Clarity | Demos: Completeness |
+
+| DATA SHARING WITH OTHER SERVICES | | |
+| ----- | ----- | ----- |
+| **Target Service** | **Data Shared** | **Purpose** |
+| **Roleplay Service** | Communication gaps, weak types, low scores, filler patterns | Suggest roleplay scenarios for weak areas |
+| **Assessment Service** | Technical gaps, low topics, code quality issues | Recommend assessments for validation |
+| **Course Service** | Skill gaps, low metrics, coding weaknesses | Recommend courses (interview prep, communication, technical) |
+| **Dashboard Service** | Interview count, scores across 7 metrics, trends, code analysis | Update Q-Score, show progress, achievements |
+
+| ACCEPTANCE CRITERIA | | |
+| :---: | ----- | :---: |
+| **\#** | **Must Pass** | **Pass/Fail** |
+| **1** | All 4 personas render correctly. Voice synthesis works with distinct voices and lip-sync. | \[ \] PASS \[ \] FAIL |
+| **2** | All interview types selectable. Premium durations tier-gated with upgrade prompts. | \[ \] PASS \[ \] FAIL |
+| **3** | Video/audio captured throughout. Stored in cloud. Download links work. | \[ \] PASS \[ \] FAIL |
+| **4** | User can share specific window. Screen recording works. Can stop/resume sharing. | \[ \] PASS \[ \] FAIL |
+| **5** | AI analyzes voice with filler word COUNT. Count displayed in feedback. | \[ \] PASS \[ \] FAIL |
+| **6** | AI analyzes technical quality: Lighting, Framing, Background, Audio. Ratings displayed. | \[ \] PASS \[ \] FAIL |
+| **7** | AI analyzes screen content: Code quality, Presentation quality, Demo completeness. | \[ \] PASS \[ \] FAIL |
+| **8** | All 7 metrics calculated correctly. Analysis completes within 60s. | \[ \] PASS \[ \] FAIL |
+| **9** | Historical comparison works: Shows previous scores with dates vs current. Includes all metrics. | \[ \] PASS \[ \] FAIL |
+
diff --git a/upskilling/docs/prd/Roleplay_OnePager.docx.md b/upskilling/docs/prd/Roleplay_OnePager.docx.md
new file mode 100644
index 0000000..efcd812
--- /dev/null
+++ b/upskilling/docs/prd/Roleplay_OnePager.docx.md
@@ -0,0 +1,71 @@
+
+
+| GrowQR Roleplay Service — One-PagerAvatar-Based AI \+ Real-Time Video/Voice \+ Screen Share | v3 | ROLEPLAY |
+| :---- | :---: |
+
+| PURPOSE |
+| ----- |
+| Avatar-based AI roleplay with real-time video/audio/screen interaction. AI personas speak using voice synthesis. Users respond via voice/text and can share screen (specific window) for coding/presentation demos. System analyzes voice (including filler word count), facial expressions, body language, technical setup quality (lighting, framing), and screen content to provide comprehensive performance feedback and certificates. |
+
+| CORE FEATURES | |
+| :---: | :---- |
+| **1** | Avatar-Based AI Personas: Visual characters with voice synthesis, lip-sync, emotional expressions |
+| **2** | Real-Time Voice Synthesis: AI persona SPEAKS all questions and responses (not just text bubbles) |
+| **3** | Video/Audio Recording: Capture user's camera and microphone throughout entire session |
+| **4** | Screen Share: User shares specific window (IDE, slides, demo app) \- NOT full desktop |
+| **5** | AI Screen Content Analysis: Analyzes code quality (syntax, logic), presentation slides, demos |
+| **6** | Comprehensive Analysis: Voice (tone, pace, filler word count), Facial (engagement, eye contact), Body (posture, gestures), Technical Quality (lighting, framing, background), Screen content |
+| **7** | Performance Scoring: Voice 35%, Facial 25%, Body Language 20%, Technical Quality 10%, Content 10% |
+
+| USER JOURNEY | | | |
+| :---: | ----- | ----- | ----- |
+| **Step** | **User Action** | **System Response** | **Data Captured** |
+| **1** | User selects scenario | Load AI persona avatar, request camera/mic/screen permissions | Scenario ID, User ID |
+| **2** | Permissions granted | Initialize avatar rendering, voice synthesis, recording systems | Media access granted |
+| **3** | Session starts | Deduct 1 credit, start all recording (video/audio/screen), avatar speaks first question | Session ID, Start time, Recording streams |
+| **4** | User shares screen (optional) | Capture specific window, begin screen content analysis | Screen recording, Content type detected |
+| **5** | User responds (voice/text) | Capture response, AI analyzes voice/facial/body/technical/screen in real-time or queued | Transcript, Voice metrics (including filler count), Facial timeline, Body timeline, Technical quality (lighting/framing), Screen analysis |
+| **6** | AI persona responds | Voice synthesis speaks follow-up, avatar lip-syncs | Conversation flow |
+| **7** | Session completes | Stop all recordings, finalize analysis, calculate scores across all metrics | Overall score, Voice 88%, Facial 75%, Body 82%, Technical 90%, Screen 85% |
+
+| KEY STATES TO HANDLE | | |
+| ----- | ----- | ----- |
+| **State** | **Condition** | **System Behavior** |
+| **Permission Denied** | User blocks camera/mic/screen | Show error: 'Camera, microphone required. Screen share optional but recommended.' |
+| **Media Loading** | Avatar/voice/recording initializing | Show: 'Preparing your session...' with progress (5-10s) |
+| **Connection Unstable** | Poor network, dropped frames/audio | Degrade quality or switch to text-only mode, continue session |
+| **Voice Synthesis Error** | TTS service fails | Fallback: Display text bubbles instead of speaking, avatar remains visible |
+| **Screen Share Stopped** | User stops sharing mid-session | Continue session without screen analysis, note in results |
+| **Active Session** | Roleplay in progress | Avatar speaks, user responds, all recording/analysis systems active |
+| **Analysis Complete** | Post-session processing done | Display all scores: Voice, Facial, Body Language, Technical Quality, Screen Content (if shared), Overall |
+
+| ANALYSIS METRICS | |
+| ----- | ----- |
+| **Metric** | **What's Analyzed** |
+| **Voice (35%)** | Tone (friendly/professional), Pace (WPM), Clarity (articulation), Confidence (vocal strength), Filler words COUNT (um, uh, like, you know) |
+| **Facial Expression (25%)** | Smile frequency, Eye contact (camera gaze), Emotional state (neutral/happy/stressed), Engagement level |
+| **Body Language (20%)** | Posture (upright/slouched), Gestures (open/closed), Fidgeting, Professionalism rating |
+| **Technical Quality (10%)** | Lighting: Well-lit/Acceptable/Poor | Framing: Centered in frame/Off-center | Background: Professional/Neutral/Distracting | Audio quality: Clear/Background noise |
+| **Content Quality (10%)** | Relevance, Completeness, Accuracy of responses |
+| **Screen Content (if shared)** | Code: Syntax, structure, logic, best practices | Presentations: Slide design, clarity | Demos: Feature completeness, explanation quality |
+| **Overall Performance** | Weighted combination of all metrics with historical comparison to track improvement |
+
+| DATA SHARING WITH OTHER SERVICES | | |
+| ----- | ----- | ----- |
+| **Target Service** | **Data Shared** | **Purpose** |
+| **Interview Service** | Voice/facial/body/technical/screen scores, weak communication areas, filler word patterns | Tailor interview questions to address roleplay gaps |
+| **Assessment Service** | Topic performance, behavioral competencies, communication patterns, technical setup quality | Recommend targeted assessments for weak areas |
+| **Course Service** | Skill gaps (communication, presentation, technical), low metric scores, setup quality issues | Recommend soft skills, communication, technical courses, setup guidance |
+| **Dashboard Service** | Session count, certificates earned, performance scores (all metrics), credits remaining | Update Q-Score based on performance, show progress achievements, suggest improvements |
+
+| ACCEPTANCE CRITERIA | | |
+| :---: | ----- | :---: |
+| **\#** | **Must Pass** | **Pass/Fail** |
+| **1** | Avatar renders correctly. Voice synthesis works with lip-sync within 100ms. Fallback to text if voice fails. | \[ \] PASS \[ \] FAIL |
+| **2** | User camera/microphone captured throughout session. All recordings stored in cloud. Download links work. | \[ \] PASS \[ \] FAIL |
+| **3** | User can share specific window. Screen recorded alongside video/audio. User can stop sharing anytime. | \[ \] PASS \[ \] FAIL |
+| **4** | AI analyzes voice including filler word COUNT (um, uh, like, you know). Counts displayed in feedback. | \[ \] PASS \[ \] FAIL |
+| **5** | AI analyzes technical quality: Lighting (well-lit/acceptable/poor), Framing (centered/off-center), Background (professional/distracting), Audio quality (clear/noisy). | \[ \] PASS \[ \] FAIL |
+| **6** | AI analyzes screen content: Code quality (syntax, structure, logic) for IDEs, Slide quality (design, clarity) for presentations, Demo completeness for apps. | \[ \] PASS \[ \] FAIL |
+| **7** | All metrics calculated correctly (Voice, Facial, Body, Technical Quality, Screen Content). Overall weighted score accurate. Certificate generated for 70%+ on eligible scenarios. | \[ \] PASS \[ \] FAIL |
+
diff --git a/upskilling/docs/roleplay_rubric_v1.json b/upskilling/docs/roleplay_rubric_v1.json
new file mode 100644
index 0000000..13264da
--- /dev/null
+++ b/upskilling/docs/roleplay_rubric_v1.json
@@ -0,0 +1,153 @@
+{
+ "rubric_profile_id": "text_roleplay_interview_v1",
+ "rubric_version": "2026-03-31",
+ "session_mode": "roleplay",
+ "metrics": {
+ "voice": {
+ "weight": 25,
+ "blocking_floor": 2,
+ "evidence_expectations": ["tone", "pace", "filler_words", "vocal_confidence"]
+ },
+ "facial": {
+ "weight": 20,
+ "blocking_floor": 2,
+ "evidence_expectations": ["facial_expressions", "eye_contact", "expressiveness"]
+ },
+ "body": {
+ "weight": 15,
+ "blocking_floor": 2,
+ "evidence_expectations": ["posture", "gestures", "body_language"]
+ },
+ "tech_quality": {
+ "weight": 5,
+ "blocking_floor": 2,
+ "evidence_expectations": ["audio_clarity", "video_clarity", "connection_stability"]
+ },
+ "content": {
+ "weight": 8,
+ "blocking_floor": 2,
+ "evidence_expectations": ["psi_structure", "specific_examples", "ownership", "impact"]
+ },
+ "scenario_adherence": {
+ "weight": 15,
+ "blocking_floor": 2,
+ "evidence_expectations": ["role_engagement", "context_awareness", "boundary_respect"]
+ },
+ "adaptability": {
+ "weight": 10,
+ "blocking_floor": 2,
+ "evidence_expectations": ["ai_persona_response", "in_session_learning", "pivot_ability"]
+ },
+ "emotional_intelligence": {
+ "weight": 10,
+ "blocking_floor": 2,
+ "evidence_expectations": ["empathy_demonstration", "tone_matching", "emotional_awareness"]
+ }
+ },
+ "pass_rules": {
+ "overall_pass_threshold": 60,
+ "certificate_threshold": 70,
+ "progressing_threshold": 50,
+ "blocking_floor": 2,
+ "score_scale": [1, 5],
+ "blocking_rule": "Any single metric scoring 1 (Needs Major Work) blocks passing regardless of overall weighted score"
+ },
+ "evidence_expectations": {
+ "deterministic": [
+ "word_count",
+ "duration_seconds",
+ "pacing_words_per_minute",
+ "filler_word_count_per_minute",
+ "scenario_keyword_overlap",
+ "role_keyword_overlap",
+ "psi_structure_completeness",
+ "ownership_marker_count",
+ "quantified_number_count",
+ "structural_marker_count"
+ ],
+ "dspy": [
+ "voice_quality",
+ "tone_appropriateness",
+ "pace_consistency",
+ "filler_control",
+ "facial_expressiveness",
+ "eye_contact_maintenance",
+ "body_language_awareness",
+ "content_clarity",
+ "example_quality",
+ "ownership_strength",
+ "impact_demonstration",
+ "scenario_engagement",
+ "role_fidelity",
+ "adaptation_quality",
+ "in_session_learning",
+ "empathy_score",
+ "emotional_tone_match",
+ "tech_quality_score"
+ ],
+ "video": [
+ "facial_expressiveness_score",
+ "eye_contact_ratio",
+ "posture_score",
+ "gesture_frequency",
+ "video_clarity_score",
+ "background_appropriateness"
+ ],
+ "audio": [
+ "clarity_score",
+ "noise_level",
+ "pace_consistency",
+ "filler_density",
+ "vocal_confidence",
+ "tone_stability"
+ ]
+ },
+ "scenario_type_overrides": {
+ "informational_interview": {
+ "adjustments": {
+ "content": {"weight_increase": 5, "min_score": 3},
+ "scenario_adherence": {"weight_decrease": 5}
+ },
+ "certificate_eligible": true
+ },
+ "client_feedback": {
+ "adjustments": {
+ "emotional_intelligence": {"weight_increase": 5, "min_score": 3},
+ "voice": {"weight_decrease": 5}
+ },
+ "certificate_eligible": true
+ },
+ "team_conflict": {
+ "adjustments": {
+ "emotional_intelligence": {"weight_increase": 5, "min_score": 3},
+ "adaptability": {"weight_increase": 5, "min_score": 3}
+ },
+ "certificate_eligible": false
+ },
+ "leadership_elevator_pitch": {
+ "adjustments": {
+ "voice": {"weight_increase": 5, "min_score": 3},
+ "content": {"weight_increase": 5, "min_score": 3}
+ },
+ "certificate_eligible": false
+ }
+ },
+ "sub_criteria": {
+ "psi_structure": {
+ "embedded_in": "content",
+ "description": "Problem → Solution → Impact structured explanation",
+ "evidence_expectations": ["problem_identification", "solution_approach", "measured_outcome"]
+ },
+ "screen_content": {
+ "embedded_in": "content",
+ "conditional": true,
+ "activates_on": "screen_share_used",
+ "description": "Code, slides, or demo quality when screen sharing"
+ },
+ "in_session_learning": {
+ "embedded_in": "adaptability",
+ "description": "Measurable improvement after AI persona correction mid-scenario",
+ "learning_concern_threshold": "failure_to_improve_after_two_consecutive_hints"
+ }
+ }
+}
diff --git a/upskilling/extras/interview service plan.md b/upskilling/extras/interview service plan.md
new file mode 100644
index 0000000..9dd9da1
--- /dev/null
+++ b/upskilling/extras/interview service plan.md
@@ -0,0 +1,2448 @@
+# GrowQR Interview Service - Technical Plan
+
+## 🎯 Executive Summary
+
+**Last Updated**: February 25, 2026 (Post-Meeting)
+**Status**: ✅ All Architectural Ambiguities Resolved
+
+### Architecture: Client-First Media Processing
+
+**Core Principle**: Client does heavy lifting, server orchestrates and analyzes.
+
+```
+┌─────────────┐ ┌──────────────┐
+│ CLIENT │ ───── HTTP ──────> │ SERVER │
+│ │ │ │
+│ • Records │ <──── Avatar ───── │ • Generates │
+│ • Encodes │ Videos │ Questions │
+│ • Uploads │ │ • Stores │
+│ • Auth │ ───── Chunks ────> │ Media │
+│ │ │ • Analyzes │
+└─────────────┘ └──────────────┘
+```
+
+### Key Decisions (FINALIZED)
+
+| Component | Decision | Why |
+|-----------|----------|-----|
+| 🎬 **Avatar** | Option A: D-ID (Full Avatar + Lip-Sync) | Premium experience |
+| 🎥 **Recording** | Client-Side (MediaRecorder API) | Lower server costs, scales better |
+| 🖥️ **Screen Capture** | Client-Side (Screen Capture API) | No server processing |
+| 🏗️ **Architecture** | Standalone Microservice | No tight coupling, independent |
+| 🔐 **Auth** | Client-Managed (JWT) | Stateless server |
+| 📊 **Analysis** | Post-Interview (Celery) | Better accuracy, async |
+
+### Responsibilities Matrix
+
+| Task | Client | Server |
+|------|--------|--------|
+| Recording Media | ✅ | ❌ |
+| Encoding Video | ✅ | ❌ |
+| Screen Capture | ✅ | ❌ |
+| Authentication | ✅ | Validates JWT |
+| Session Management | ✅ | ❌ |
+| Question Generation | ❌ | ✅ |
+| Avatar Videos | ❌ | ✅ (via D-ID) |
+| Media Storage | ❌ | ✅ |
+| Analysis | ❌ | ✅ (Celery) |
+| Score Calculation | ❌ | ✅ |
+
+---
+
+## Project Overview
+AI-powered mock interview microservice with 4 avatar-based interviewers, real-time voice synthesis, video/audio recording, screen share capability, and comprehensive 7-metric analysis system.
+
+**Tech Stack**: Python + UV + FastAPI + PostgreSQL
+
+---
+
+## 🎯 FINAL ARCHITECTURAL DECISIONS
+
+### ✅ Client-First Media Processing Model
+
+**Core Principle**: All media processing happens on the client. Server handles only post-upload logic and orchestration.
+
+1. **Avatar Implementation**: ✅ **Option A - Full Avatar with Lip-Sync (D-ID)**
+ - D-ID generates avatar videos with lip-sync
+ - Client receives video URLs and plays them
+ - No server-side video processing
+
+2. **Recording Approach**: ✅ **Option A - Client-Side Recording**
+ - All audio, video, and screen recording happens in browser (WebRTC MediaRecorder API)
+ - Client processes and compresses recordings
+ - Client uploads completed chunks to server
+ - No real-time server streaming
+ - No server-side recording infrastructure needed
+
+3. **Screen Recording**: ✅ **Fully Client-Side**
+ - Browser Screen Capture API
+ - Client-side processing and compression
+ - Upload after recording complete
+ - Server only receives final processed files
+
+4. **Service Architecture**: ✅ **Standalone Module**
+ - No direct connections to other internal services
+ - All inputs consumed via APIs (no tight coupling)
+ - Stateless service design
+ - Can be deployed independently
+
+5. **Authentication**: ✅ **Client-Managed**
+ - Authentication and session handling entirely on client
+ - Server receives authenticated requests with tokens
+ - No session management on server side
+ - Stateless JWT-based auth
+
+---
+
+## 1. Updated Technology Stack
+
+### 1.1 Avatar Generation (DECIDED: D-ID)
+
+**✅ CHOSEN: D-ID - Full Avatar with Lip-Sync**
+
+**Why D-ID?**
+- Production-grade quality
+- Simple REST API integration
+- Fast video generation
+- Reliable infrastructure
+- Best balance of quality, ease, and pricing
+
+**Integration Approach**:
+```python
+# Server generates avatar videos via D-ID API
+# Returns video URLs to client
+# Client plays videos (no server streaming)
+
+import requests
+
+def generate_avatar_question(question_text: str, persona: str):
+ """Generate avatar video for a question"""
+ response = requests.post(
+ "https://api.d-id.com/talks",
+ headers={"Authorization": f"Bearer {D_ID_API_KEY}"},
+ json={
+ "script": {
+ "type": "text",
+ "input": question_text,
+ "provider": {
+ "type": "microsoft",
+ "voice_id": get_voice_id_for_persona(persona)
+ }
+ },
+ "source_url": get_avatar_image_url(persona),
+ "config": {"stitch": True}
+ }
+ )
+ return response.json()["id"] # Returns talk_id for polling
+```
+
+**Cost**: $0.12-0.30 per video minute
+
+**Alternatives Considered**:
+- **Wav2Lip** (Free): Lower quality, requires GPU, complex setup
+- **HeyGen** ($24-120/month): More expensive, similar quality
+- **Synthesia** ($22+/month): Enterprise-focused, overkill
+
+---
+
+### 1.2 Client-Side Recording (DECIDED: MediaRecorder API)
+
+**✅ CHOSEN: Browser MediaRecorder API**
+
+**Why MediaRecorder API?**
+- Native browser support (no dependencies)
+- Works on all modern browsers
+- Zero server-side infrastructure needed
+- Client handles all processing
+- Simple upload after recording
+
+**Client Implementation** (Reference for frontend team):
+```javascript
+// Client-side recording (for reference)
+class InterviewRecorder {
+ async startRecording() {
+ const stream = await navigator.mediaDevices.getUserMedia({
+ video: { width: 1280, height: 720, frameRate: 30 },
+ audio: { sampleRate: 48000, channelCount: 1 }
+ });
+
+ this.mediaRecorder = new MediaRecorder(stream, {
+ mimeType: 'video/webm;codecs=vp9,opus',
+ videoBitsPerSecond: 2500000
+ });
+
+ this.chunks = [];
+ this.mediaRecorder.ondataavailable = (e) => {
+ if (e.data.size > 0) {
+ this.chunks.push(e.data);
+ // Upload chunk if > 5MB
+ if (this.getTotalSize() > 5 * 1024 * 1024) {
+ this.uploadChunk();
+ }
+ }
+ };
+
+ this.mediaRecorder.start(1000); // 1 second chunks
+ }
+
+ async uploadChunk() {
+ const blob = new Blob(this.chunks, { type: 'video/webm' });
+ const formData = new FormData();
+ formData.append('file', blob, `chunk_${this.chunkNumber}.webm`);
+ formData.append('session_id', this.sessionId);
+ formData.append('chunk_number', this.chunkNumber);
+
+ await fetch('/api/v1/interview/upload-recording', {
+ method: 'POST',
+ body: formData,
+ headers: { 'Authorization': `Bearer ${this.token}` }
+ });
+
+ this.chunks = [];
+ this.chunkNumber++;
+ }
+}
+```
+
+**Server Responsibility**:
+- Accept uploaded chunks
+- Store in object storage
+- Trigger analysis after upload complete
+
+**Cost**: Zero (native browser API)
+
+**Alternatives Considered**:
+- **Server-side recording (Twilio, Janus)**: Expensive, complex, unnecessary
+- **RecordRTC**: Additional library, same capability as native API
+
+---
+
+### 1.3 Screen Capture (DECIDED: Screen Capture API)
+
+**✅ CHOSEN: Browser Screen Capture API**
+
+**Client Implementation** (Reference):
+```javascript
+class ScreenRecorder {
+ async startScreenShare() {
+ this.screenStream = await navigator.mediaDevices.getDisplayMedia({
+ video: { cursor: "always", displaySurface: "window" }
+ });
+
+ this.screenRecorder = new MediaRecorder(this.screenStream, {
+ mimeType: 'video/webm;codecs=vp9'
+ });
+
+ // Handle recording similar to video/audio
+ }
+}
+```
+
+**Server Responsibility**:
+- Receive screen recording chunks
+- Store in object storage
+- Analyze code/content in post-processing
+
+**Cost**: Zero (native browser API)
+
+---
+
+### 1.4 Storage (RECOMMENDED: Cloudflare R2)
+
+**✅ RECOMMENDED: Cloudflare R2**
+
+**Why Cloudflare R2?**
+- Zero egress fees (huge savings)
+- S3-compatible API (easy migration)
+- $0.015 per GB/month storage
+- Global CDN built-in
+- Best for video/audio delivery
+
+**Alternatives**:
+
+**Open-Source/Free:**
+1. **MinIO** - S3-compatible self-hosted
+ - Pros: Free, unlimited storage, S3 API
+ - Cons: Requires server infrastructure, maintenance
+ - Best for: Self-hosted deployments with existing infrastructure
+ - **RECOMMENDED (FREE)**: Best self-hosted option
+
+2. **SeaweedFS** - Distributed file system
+ - Pros: Fast, efficient, free, good for large files
+ - Cons: Complex setup, requires expertise
+ - Best for: Large-scale file storage
+
+3. **Local Filesystem + NFS** - Traditional storage
+ - Pros: Simple, free, direct access
+ - Cons: Not scalable, no CDN, backup complexity
+ - Best for: Development/testing only
+
+**Paid Services:**
+1. **Cloudflare R2** ⭐ **RECOMMENDED**
+ - Pros: No egress fees, S3-compatible, cheap, global CDN
+ - Cons: $0.015 per GB/month
+ - Best for: High bandwidth applications
+ - **WHY RECOMMENDED**: Zero egress fees save massive costs on video delivery
+
+2. **AWS S3** - Object storage
+ - Pros: Industry standard, reliable, CDN integration
+ - Cons: $0.023 per GB/month + egress costs (expensive)
+ - Best for: AWS ecosystem
+
+3. **Google Cloud Storage** - Object storage
+ - Pros: Reliable, good CDN, lifecycle management
+ - Cons: $0.020 per GB/month + egress
+ - Best for: Google Cloud users
+
+**Integration**:
+```python
+import boto3
+from botocore.config import Config
+
+# R2 uses S3-compatible API
+r2_client = boto3.client(
+ 's3',
+ endpoint_url=f'https://{ACCOUNT_ID}.r2.cloudflarestorage.com',
+ aws_access_key_id=R2_ACCESS_KEY_ID,
+ aws_secret_access_key=R2_SECRET_ACCESS_KEY,
+ config=Config(signature_version='s3v4')
+)
+
+# Upload recording chunk
+r2_client.upload_fileobj(
+ file_obj,
+ 'interview-recordings',
+ f'sessions/{session_id}/video/{chunk_number}.webm'
+)
+```
+
+**Cost Comparison (1000 interviews/month, 15min each, 250MB per interview)**:
+- Total storage: 250GB
+- Cloudflare R2: $3.75/month storage + $0 egress = **$3.75/month**
+- AWS S3: $5.75/month storage + $25/month egress = **$30.75/month**
+- MinIO: $0 (self-hosted server costs apply)
+
+---
+
+### 1.5 AI Analysis Services
+
+#### 1.5.1 LLM for Content Analysis
+
+**✅ RECOMMENDED: Anthropic Claude 3.5 Sonnet**
+
+**Why Claude 3.5 Sonnet?**
+- Best for nuanced analysis
+- Long context window (200K tokens)
+- Excellent at code review
+- Strong reasoning capabilities
+- Competitive pricing
+
+**Alternatives**:
+
+**Open-Source/Free:**
+1. **Ollama (Llama 3.2)** - Local LLM runtime
+ - Pros: Free, private, self-hosted, good quality
+ - Cons: Requires GPU, slower, quality variance
+ - Best for: Privacy-critical, self-hosted
+ - **RECOMMENDED (FREE)**: Best local LLM solution
+
+2. **Hugging Face Transformers** - Open model library
+ - Pros: Free, many models, customizable
+ - Cons: Self-hosting needed, resource intensive
+ - Best for: Custom fine-tuning
+
+3. **LM Studio** - Local LLM GUI
+ - Pros: Easy setup, multiple models, free
+ - Cons: Desktop app, not server-ready
+ - Best for: Development/testing
+
+**Paid Services:**
+1. **Anthropic Claude 3.5 Sonnet** ⭐ **RECOMMENDED**
+ - Pros: Excellent analysis depth, long context, code understanding
+ - Cons: $3 per 1M input tokens, $15 per 1M output
+ - Best for: Deep analysis tasks
+ - **WHY RECOMMENDED**: Best for nuanced interview analysis
+
+2. **OpenAI GPT-4o** - Latest GPT model
+ - Pros: Excellent quality, fast, reliable
+ - Cons: $2.50 per 1M input tokens, $10 per 1M output
+ - Best for: General purpose LLM needs
+
+3. **Google Gemini Pro** - Multimodal AI
+ - Pros: Multimodal, good quality, cheap
+ - Cons: $1.25 per 1M input tokens, $5 per 1M output
+ - Best for: Cost-conscious multimodal
+
+**Usage Pattern**:
+```python
+import anthropic
+
+client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)
+
+def analyze_interview_response(transcript: str, question: str):
+ message = client.messages.create(
+ model="claude-3-5-sonnet-20241022",
+ max_tokens=2000,
+ messages=[{
+ "role": "user",
+ "content": f"""Analyze this interview response:
+
+Question: {question}
+
+Response: {transcript}
+
+Evaluate:
+1. Grammar and vocabulary (0-100)
+2. Clarity and structure (0-100)
+3. Relevance to question (0-100)
+4. Technical accuracy (if applicable)
+
+Return JSON format."""
+ }]
+ )
+ return message.content
+```
+
+**Cost per 15-min interview**: ~$0.15-0.30 (500-1000 tokens in, 1500-2000 tokens out)
+
+---
+
+#### 1.5.2 Facial Expression Analysis
+
+**✅ RECOMMENDED: Azure Face API (Paid) or MediaPipe (Free)**
+
+**Open-Source/Free:**
+1. **MediaPipe Face Mesh** - Google's ML solution ⭐ **RECOMMENDED (FREE)**
+ - Pros: Fast, free, real-time, lightweight, 468 landmarks
+ - Cons: Requires custom emotion interpretation layer
+ - Best for: Real-time client-side or budget deployments
+ - **WHY RECOMMENDED**: Production-ready, fast, zero cost
+
+2. **OpenFace** - Facial behavior analysis
+ - Pros: Free, academic-backed, comprehensive
+ - Cons: Setup complexity, C++ compilation required
+ - Best for: Research projects
+
+3. **DeepFace** - Python facial recognition
+ - Pros: Multiple models, easy to use, free
+ - Cons: Less accurate emotion detection
+ - Best for: Simple facial analysis
+
+**Paid Services:**
+1. **Azure Face API** ⭐ **RECOMMENDED (PAID)**
+ - Pros: Detailed emotions, face attributes, reliable, easy API
+ - Cons: $1 per 1000 transactions
+ - Best for: Enterprise Microsoft stack
+ - **WHY RECOMMENDED**: Best accuracy/features balance
+
+2. **AWS Rekognition** - Computer vision service
+ - Pros: Accurate, scalable, AWS integration
+ - Cons: $1 per 1000 images analyzed
+ - Best for: AWS ecosystem
+
+3. **Google Vision AI** - Face detection
+ - Pros: Good quality, emotion detection
+ - Cons: $1.50 per 1000 images
+ - Best for: Google Cloud users
+
+**Integration (Azure)**:
+```python
+from azure.cognitiveservices.vision.face import FaceClient
+from msrest.authentication import CognitiveServicesCredentials
+
+face_client = FaceClient(FACE_ENDPOINT, CognitiveServicesCredentials(FACE_KEY))
+
+def analyze_facial_expressions(video_path: str):
+ """Extract key frames and analyze emotions"""
+ frames = extract_key_frames(video_path, fps=1) # 1 frame per second
+
+ results = []
+ for frame in frames:
+ detected_faces = face_client.face.detect_with_stream(
+ frame,
+ return_face_attributes=['emotion', 'smile', 'headPose']
+ )
+ results.append(detected_faces)
+
+ return aggregate_emotion_scores(results)
+```
+
+**Cost per 15-min interview**: ~$0.15 (analyzing 1 frame/second = 900 frames = $0.90, but batch discounts apply)
+
+---
+
+#### 1.5.3 Body Language Analysis
+
+**✅ RECOMMENDED: MediaPipe Pose (Free) or Azure Video Indexer (Paid)**
+
+**Open-Source/Free:**
+1. **MediaPipe Pose** - Google's pose estimation ⭐ **RECOMMENDED (FREE)**
+ - Pros: Real-time, accurate, 33 landmarks, free
+ - Cons: Requires custom interpretation for posture/gestures
+ - Best for: Real-time pose tracking
+ - **WHY RECOMMENDED**: Production-ready, fast, accurate
+
+2. **OpenPose** - CMU pose estimation
+ - Pros: Academic standard, accurate, multi-person
+ - Cons: GPU required, slower, complex setup
+ - Best for: Offline batch processing
+
+3. **AlphaPose** - Multi-person pose estimator
+ - Pros: Good accuracy, handles occlusion
+ - Cons: Resource intensive
+ - Best for: Research environments
+
+**Paid Services:**
+1. **Azure Video Indexer** ⭐ **RECOMMENDED (PAID)**
+ - Pros: Body tracking, gesture recognition, comprehensive
+ - Cons: $0.0524 per processed minute (Standard)
+ - Best for: Full video analysis
+ - **WHY RECOMMENDED**: Most comprehensive, reasonable pricing
+
+2. **AWS Rekognition Video** - Video analysis
+ - Pros: Person tracking, activity recognition
+ - Cons: $0.10 per minute
+ - Best for: AWS infrastructure
+
+3. **Google Video Intelligence API** - Video understanding
+ - Pros: Person detection, action recognition
+ - Cons: $0.10 per minute
+ - Best for: Google Cloud ecosystem
+
+**Integration (MediaPipe)**:
+```python
+import mediapipe as mp
+
+mp_pose = mp.solutions.pose
+pose = mp_pose.Pose(min_detection_confidence=0.5)
+
+def analyze_body_language(video_path: str):
+ """Analyze posture and gestures"""
+ frames = extract_frames(video_path, fps=5)
+
+ posture_scores = []
+ fidget_count = 0
+
+ for frame in frames:
+ results = pose.process(frame)
+ if results.pose_landmarks:
+ posture_score = calculate_posture_score(results.pose_landmarks)
+ fidget_detected = detect_fidgeting(results.pose_landmarks)
+
+ posture_scores.append(posture_score)
+ if fidget_detected:
+ fidget_count += 1
+
+ return {
+ "average_posture": np.mean(posture_scores),
+ "fidget_count": fidget_count,
+ "posture_consistency": np.std(posture_scores)
+ }
+```
+
+**Cost**: Free for MediaPipe, ~$0.80 for Azure (15 min video)
+
+---
+
+#### 1.5.4 Speech Analysis (Filler Words, Pace, Tone)
+
+**✅ RECOMMENDED: Deepgram (Paid) or Whisper (Free)**
+
+**Open-Source/Free:**
+1. **Whisper (OpenAI)** - Speech-to-text ⭐ **RECOMMENDED (FREE)**
+ - Pros: Free, accurate, multiple languages, word-level timestamps
+ - Cons: No built-in filler detection, GPU beneficial
+ - Best for: Transcription + custom filler analysis
+ - **WHY RECOMMENDED**: Best free option, very accurate
+
+2. **Vosk** - Offline speech recognition
+ - Pros: Offline, fast, lightweight, free
+ - Cons: Lower accuracy, limited features
+ - Best for: Offline requirements
+
+3. **wav2vec 2.0** - Facebook's speech model
+ - Pros: High quality, free, self-hosted
+ - Cons: Requires ML expertise, GPU needed
+ - Best for: Custom model training
+
+**Paid Services:**
+1. **Deepgram** - AI speech platform ⭐ **RECOMMENDED (PAID)**
+ - Pros: Real-time, diarization, sentiment, word-level timestamps, filler detection
+ - Cons: $0.0043 per minute (Nova-2)
+ - Best for: Production speech analysis
+ - **WHY RECOMMENDED**: Built-in filler word detection, best features
+
+2. **AssemblyAI** - Audio intelligence API
+ - Pros: Sentiment, topic detection, filler words, good docs
+ - Cons: $0.015 per minute
+ - Best for: Comprehensive audio analysis
+
+3. **Rev.ai** - Speech-to-text API
+ - Pros: High accuracy, async/streaming
+ - Cons: $0.02 per minute
+ - Best for: High accuracy needs
+
+**Integration (Deepgram)**:
+```python
+from deepgram import Deepgram
+
+dg_client = Deepgram(DEEPGRAM_API_KEY)
+
+async def analyze_speech(audio_url: str):
+ response = await dg_client.transcription.prerecorded({
+ 'url': audio_url
+ }, {
+ 'punctuate': True,
+ 'utterances': True,
+ 'diarize': False,
+ 'filler_words': True, # Detects um, uh, like, etc.
+ 'measurements': True # WPM, timing
+ })
+
+ transcript = response['results']['channels'][0]['alternatives'][0]
+
+ # Extract filler words
+ filler_words = {
+ 'um': 0, 'uh': 0, 'like': 0, 'you_know': 0
+ }
+
+ for word in transcript['words']:
+ if word.get('filler'):
+ filler_type = word['word'].lower()
+ if filler_type in filler_words:
+ filler_words[filler_type] += 1
+
+ # Calculate WPM
+ total_words = len(transcript['words'])
+ duration_seconds = transcript['words'][-1]['end']
+ wpm = (total_words / duration_seconds) * 60
+
+ return {
+ 'transcript': transcript['transcript'],
+ 'filler_words': filler_words,
+ 'total_filler_count': sum(filler_words.values()),
+ 'wpm': wpm,
+ 'duration': duration_seconds
+ }
+```
+
+**Cost per 15-min interview**: ~$0.06 with Deepgram, $0 with Whisper
+
+---
+
+#### 1.5.5 Code Analysis (Screen Content)
+
+**✅ RECOMMENDED: SonarCloud (Paid) or SonarQube Community (Free)**
+
+**Open-Source/Free:**
+1. **SonarQube Community** - Code quality platform ⭐ **RECOMMENDED (FREE)**
+ - Pros: Multi-language, comprehensive, free, proven
+ - Cons: Self-hosted, setup overhead
+ - Best for: Team code review, self-hosted
+ - **WHY RECOMMENDED**: Most comprehensive free option
+
+2. **Tree-sitter** - Parsing library
+ - Pros: Fast, accurate parsing, multi-language
+ - Cons: Requires integration work, just parsing
+ - Best for: Syntax analysis only
+
+3. **Pylint/Ruff/Flake8** - Python linters
+ - Pros: Free, comprehensive, configurable
+ - Cons: Python-specific
+ - Best for: Python code quality
+
+**Paid Services:**
+1. **SonarCloud** - Cloud code quality ⭐ **RECOMMENDED (PAID)**
+ - Pros: No hosting, automatic, multi-language, security scanning
+ - Cons: $10-150/month based on LOC
+ - Best for: Production code analysis
+ - **WHY RECOMMENDED**: Zero maintenance, excellent features
+
+2. **GitHub Copilot Analysis** - AI code review
+ - Pros: Context-aware, modern, security scanning
+ - Cons: $10-39/month per user
+ - Best for: GitHub integration
+
+3. **CodeClimate** - Automated code review
+ - Pros: Test coverage, maintainability scoring
+ - Cons: $50-750/month per repo
+ - Best for: Team collaboration
+
+**Integration**:
+```python
+import subprocess
+import json
+
+def analyze_code_from_screen(screen_recording_path: str):
+ """
+ 1. Extract code from screen recording (OCR or direct capture)
+ 2. Save to temp file
+ 3. Run static analysis
+ """
+
+ # Extract code (client should send code directly, not just video)
+ code_content = extract_code_from_recording(screen_recording_path)
+
+ # Save to temp file
+ with open('/tmp/interview_code.py', 'w') as f:
+ f.write(code_content)
+
+ # Run Pylint for Python (example)
+ result = subprocess.run(
+ ['pylint', '--output-format=json', '/tmp/interview_code.py'],
+ capture_output=True,
+ text=True
+ )
+
+ issues = json.loads(result.stdout)
+
+ return {
+ 'syntax_errors': len([i for i in issues if i['type'] == 'error']),
+ 'style_issues': len([i for i in issues if i['type'] == 'convention']),
+ 'quality_score': calculate_quality_score(issues),
+ 'issues': issues
+ }
+```
+
+**Recommendation**: For screen recordings, have client also send the code text separately for easier analysis.
+
+**Cost**: Free for SonarQube, $10-150/month for SonarCloud
+
+---
+
+### 1.6 Database (DECIDED: PostgreSQL)
+
+**✅ CONFIRMED: PostgreSQL**
+
+**Hosting Options**:
+
+**Self-Hosted** (Free):
+- Full control, free, unlimited scale
+- Requires DevOps expertise
+- Best for: Experienced teams
+
+**Managed Services**:
+1. **Supabase Pro** - $25/month ⭐ **RECOMMENDED**
+ - 8GB database, backups, monitoring
+ - Best value for startups
+
+2. **AWS RDS PostgreSQL** - $15-1000+/month
+ - Enterprise-grade
+ - Best for: AWS infrastructure
+
+3. **Neon** - Serverless PostgreSQL - $0-19/month
+ - Good for: Development
+
+**Our Choice**: Self-hosted for production (cost), Supabase for staging/dev
+
+---
+
+### 1.7 Cache & Queue
+
+**Cache: Redis (Self-Hosted)**
+- Free, battle-tested
+- For session data, rate limiting
+
+**Task Queue: Celery + Redis (Self-Hosted)**
+- Free, Python-native
+- For async analysis processing
+
+**Alternatives**:
+- **Upstash Redis**: $0.2 per 100K requests (serverless)
+- **AWS SQS**: $0.40 per million (if going serverless)
+
+**Our Choice**: Self-hosted Redis + Celery (zero cost, full control)
+
+---
+
+### 1.8 WebSocket (FastAPI Native)
+
+**✅ DECIDED: FastAPI Built-in WebSocket**
+
+**Why?**
+- Native support in FastAPI
+- No additional dependencies
+- Sufficient for our use case
+- Free
+
+**Alternatives** (Not needed):
+- Pusher, Ably: Expensive, overkill for our needs
+- Socket.io: Additional complexity
+
+---
+
+## 2. System Architecture
+
+### 2.1 High-Level Architecture
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│ CLIENT (Browser) │
+│ │
+│ ┌──────────────┐ ┌──────────────┐ ┌─────────────────────┐ │
+│ │ Camera & │ │ Screen │ │ Media Processor │ │
+│ │ Microphone │ │ Capture │ │ (Compression, etc) │ │
+│ └──────┬───────┘ └──────┬───────┘ └──────────┬──────────┘ │
+│ │ │ │ │
+│ └──────────────────┴──────────────────────┘ │
+│ │ │
+│ ┌───────▼────────┐ │
+│ │ Upload Chunks │ │
+│ └───────┬────────┘ │
+└────────────────────────────┼──────────────────────────────────┘
+ │
+ │ HTTPS Upload
+ │
+┌────────────────────────────▼──────────────────────────────────┐
+│ FASTAPI SERVER │
+│ │
+│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
+│ │ REST API │ │ WebSocket │ │ File Upload │ │
+│ │ Endpoints │ │ Handler │ │ Handler │ │
+│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
+│ │ │ │ │
+│ │ ┌───────▼────────────────────▼────────┐ │
+│ │ │ Session Manager │ │
+│ │ │ (Stateless, validates JWT) │ │
+│ │ └───────┬──────────────────────────────┘ │
+│ │ │ │
+│ ┌──────▼──────────────────▼─────────────────┐ │
+│ │ Business Logic Layer │ │
+│ │ - Interview Config │ │
+│ │ - Question Generation (D-ID) │ │
+│ │ - Recording Management │ │
+│ │ - Analysis Orchestration │ │
+│ └──────┬────────────────┬─────────────┬─────┘ │
+│ │ │ │ │
+│ ┌──────▼─────┐ ┌─────▼──────┐ ┌──▼────────────┐ │
+│ │ PostgreSQL │ │ Redis │ │ Celery Queue │ │
+│ │ Database │ │ Cache │ │ (Analysis) │ │
+│ └────────────┘ └────────────┘ └───────┬───────┘ │
+└───────────────────────────────────────────┼─────────────────┘
+ │
+ ┌───────────────────────▼────────────────────┐
+ │ CELERY WORKERS │
+ │ │
+ │ ┌────────────────────────────────────┐ │
+ │ │ Analysis Pipeline │ │
+ │ │ 1. Facial (Azure/MediaPipe) │ │
+ │ │ 2. Body Language (Azure/MediaPipe)│ │
+ │ │ 3. Speech (Deepgram/Whisper) │ │
+ │ │ 4. Language (Claude) │ │
+ │ │ 5. Code (SonarCloud/SonarQube) │ │
+ │ │ 6. Aggregate & Score │ │
+ │ └────────────────────────────────────┘ │
+ └────────────────────────────────────────────┘
+ │
+ ┌───────────────────────▼────────────────────┐
+ │ EXTERNAL SERVICES │
+ │ │
+ │ D-ID API │ Cloudflare R2 │ AI APIs │
+ │ (Avatar) │ (Storage) │ (Analysis) │
+ └─────────────────────────────────────────────┘
+```
+
+### 2.2 Client-Server Interaction Flow
+
+```
+CLIENT SERVER
+ │ │
+ │ 1. Configure Interview │
+ │────────────────────────────────────>│
+ │ POST /api/v1/interview/configure │
+ │ │
+ │ <──────────────────────────────── │
+ │ { session_id, avatar_config, ...} │
+ │ │
+ │ 2. Start Interview │
+ │────────────────────────────────────>│
+ │ POST /api/v1/interview/start │
+ │ │
+ │ <──────────────────────────────── │
+ │ { websocket_url, upload_token } │
+ │ │
+ │ 3. Connect WebSocket │
+ │<═══════════════════════════════════>│
+ │ WS: /ws/interview/{id} │
+ │ │
+ │ 4. Server sends avatar question │
+ │ <─────────────────────────────── │
+ │ { type: "question", audio_url } │
+ │ │
+ │ [CLIENT PLAYS AVATAR VIDEO] │
+ │ [CLIENT RECORDS USER RESPONSE] │
+ │ │
+ │ 5. Client processes & uploads │
+ │────────────────────────────────────>│
+ │ POST /upload-recording (chunks) │
+ │ │
+ │ 6. Repeat for all questions │
+ │<═══════════════════════════════════>│
+ │ │
+ │ 7. End Interview │
+ │────────────────────────────────────>│
+ │ POST /api/v1/interview/end │
+ │ │
+ │ │ [TRIGGER CELERY TASK]
+ │ │ Analysis starts
+ │ │
+ │ 8. Poll for Analysis │
+ │────────────────────────────────────>│
+ │ GET /api/v1/interview/analysis/{id}│
+ │ │
+ │ <──────────────────────────────── │
+ │ { status: "processing", ...} │
+ │ │
+ │ 9. Get Complete Analysis │
+ │────────────────────────────────────>│
+ │ GET /api/v1/interview/analysis/{id}│
+ │ │
+ │ <──────────────────────────────── │
+ │ { status: "completed", metrics } │
+ │ │
+```
+
+---
+
+## 3. API Endpoints (Client-First Architecture)
+
+**ARCHITECTURE CLARIFICATION**:
+- ✅ Client handles ALL authentication (JWT tokens)
+- ✅ Client handles ALL media recording and encoding
+- ✅ Server only validates tokens, orchestrates workflow, stores data
+- ✅ NO session management on server (stateless)
+- ✅ NO real-time media streaming to server
+- ✅ Server triggers async analysis after upload completes
+
+---
+
+### 3.1 POST /api/v1/interview/configure
+
+**Purpose**: Configure interview session (server generates questions + avatar videos)
+
+**Authentication**: Bearer token (JWT) in `Authorization` header
+
+**Client Responsibilities BEFORE calling this**:
+- Authenticate user (get JWT)
+- Check user credits (optional, can be done server-side too)
+- Validate device permissions (camera, mic available)
+
+**Request**:
+```json
+{
+ "interview_type": "warmup|coding|role_related|behavioral",
+ "duration_minutes": 5|15|30,
+ "persona": "payal|emma|john|kapil",
+ "job_role": "Software Engineer (optional)",
+ "programming_language": "python (optional, for coding)"
+}
+```
+
+**Server Actions**:
+1. ✅ Extract user_id from JWT token (validate signature)
+2. ✅ Optionally: Check credits via external API (if not done by client)
+3. ✅ Generate unique session_id
+4. ✅ Store session configuration in PostgreSQL
+5. ✅ Generate interview questions using LLM (based on type, role, user profile)
+6. ✅ Create avatar greeting video via D-ID API
+7. ✅ Return configuration to client
+
+**Response**:
+```json
+{
+ "session_id": "550e8400-e29b-41d4-a716-446655440000",
+ "credits_required": 2,
+ "avatar_config": {
+ "name": "Payal",
+ "avatar_image_url": "https://cdn.example.com/avatars/payal.png",
+ "voice_id": "payal_voice_en",
+ "greeting_video_url": "https://d-id-storage.../greeting_12345.mp4"
+ },
+ "estimated_questions": 8,
+ "upload_endpoint": "/api/v1/interview/upload-chunk",
+ "max_chunk_size_mb": 10
+}
+```
+
+---
+
+### 3.2 POST /api/v1/interview/start
+
+**Purpose**: Mark session as started and get WebSocket URL for state sync
+
+**Authentication**: Bearer token
+
+**Client Responsibilities BEFORE calling this**:
+- Initialize MediaRecorder for audio/video
+- Request screen capture permission (if coding interview)
+- Start local recording
+- Be ready to upload chunks
+
+**Request**:
+```json
+{
+ "session_id": "550e8400-e29b-41d4-a716-446655440000",
+ "client_capabilities": {
+ "video_recording": true,
+ "audio_recording": true,
+ "screen_sharing": true,
+ "video_codec": "vp9",
+ "audio_codec": "opus"
+ }
+}
+```
+
+**Server Actions**:
+1. ✅ Validate session exists and belongs to user (via JWT)
+2. ✅ Update session status to "started" in database
+3. ✅ Record start timestamp
+4. ✅ Deduct credits (if not done earlier)
+5. ✅ Return WebSocket URL for real-time state sync
+6. ✅ Return upload token for chunk uploads
+
+**Response**:
+```json
+{
+ "status": "started",
+ "websocket_url": "wss://api.growqr.com/ws/interview/550e8400...",
+ "upload_token": "eyJhbGci...",
+ "session_expires_at": "2026-02-24T16:04:50Z",
+ "first_question": {
+ "question_id": "q_001",
+ "video_url": "https://d-id-storage.../question_001.mp4",
+ "text": "Tell me about yourself and your experience.",
+ "expected_duration_seconds": 120
+ }
+}
+```
+
+**Client Actions AFTER receiving response**:
+- ✅ Open WebSocket connection
+- ✅ Play first question video
+- ✅ Start recording user response
+- ✅ Begin uploading chunks as they're recorded
+
+---
+
+### 3.3 WebSocket: /ws/interview/{session_id}
+
+**Purpose**: Real-time state synchronization (NOT media streaming)
+
+**Authentication**: Via query param `?token=`
+
+**IMPORTANT**:
+- ❌ WebSocket is NOT used for media streaming
+- ✅ WebSocket is ONLY for interview state synchronization
+- ✅ Media upload happens via separate HTTP POST endpoints
+
+**Client → Server Messages**:
+
+```json
+// Notify server that client is ready for next question
+{
+ "type": "ready_for_next",
+ "previous_question_id": "q_001",
+ "response_recorded": true,
+ "chunk_count": 3
+}
+
+// Notify server of recording status
+{
+ "type": "recording_status",
+ "video_recording": true,
+ "audio_recording": true,
+ "screen_recording": true
+}
+
+// Request to pause interview
+{
+ "type": "pause_request",
+ "reason": "user_break"
+}
+
+// Session ended by client
+{
+ "type": "session_ended",
+ "reason": "completed|interrupted|user_cancelled",
+ "questions_answered": 8,
+ "total_chunks_uploaded": 45
+}
+```
+
+**Server → Client Messages**:
+
+```json
+// Next question (avatar video URL)
+{
+ "type": "question",
+ "question_id": "q_002",
+ "question_number": 2,
+ "total_questions": 10,
+ "question_text": "Describe a time when you had to debug a complex issue.",
+ "video_url": "https://d-id-storage.../question_002.mp4",
+ "duration_seconds": 15,
+ "expected_response_duration": 120,
+ "category": "technical"
+}
+
+// Interview progress update
+{
+ "type": "progress",
+ "questions_answered": 2,
+ "total_questions": 10,
+ "time_elapsed_seconds": 180,
+ "time_remaining_seconds": 720
+}
+
+// Time warning
+{
+ "type": "time_warning",
+ "message": "2 minutes remaining",
+ "time_remaining_seconds": 120
+}
+
+// Session ending
+{
+ "type": "session_complete",
+ "message": "Interview complete! Analyzing your responses...",
+ "total_questions_answered": 10,
+ "analysis_started": true,
+ "estimated_completion": "2026-02-24T15:11:00Z"
+}
+
+// Error
+{
+ "type": "error",
+ "code": "session_expired",
+ "message": "Session has expired. Please start a new interview."
+}
+```
+ "video_url": "https://d-id.com/talks/question_001.mp4",
+ "expected_duration_seconds": 120
+}
+
+// Progress update
+{
+ "type": "progress",
+ "current_question": 3,
+ "total_questions": 10,
+ "time_elapsed_seconds": 180
+}
+
+// Session complete
+{
+ "type": "session_complete",
+ "video_url": "https://d-id.com/talks/closing_001.mp4",
+ "message": "Analysis will be ready shortly"
+}
+```
+
+**Client → Server Messages**:
+
+```json
+// Ready for next question
+{
+ "type": "ready_next",
+ "previous_question_id": "q_001"
+}
+
+// Recording status
+{
+ "type": "recording_status",
+ "video_recording": true,
+ "audio_recording": true,
+ "screen_recording": true
+}
+```
+
+---
+
+---
+
+### 3.4 POST /api/v1/interview/upload-chunk
+
+**Purpose**: Upload PRE-PROCESSED recording chunks from client
+
+**Authentication**: Bearer token OR upload token from /start
+
+**CRITICAL**:
+- ✅ Client has ALREADY processed/encoded the media
+- ✅ Server receives ready-to-store files (WebM format)
+- ❌ Server does NOT process, encode, or transcode
+- ✅ Server ONLY stores and tracks metadata
+
+**Client Processing BEFORE Upload**:
+1. ✅ Capture media (getUserMedia, getDisplayMedia)
+2. ✅ Encode using MediaRecorder (VP9 video + Opus audio)
+3. ✅ Create WebM chunks (5-10 seconds each)
+4. ✅ Compress if needed
+5. ✅ Upload via this endpoint
+
+**Request** (multipart/form-data):
+```
+session_id: 550e8400-e29b-41d4-a716-446655440000
+chunk_number: 1
+total_chunks: 45 (estimated, can change)
+chunk_type: video|audio|screen
+file: [binary WebM data]
+timestamp: 2026-02-24T15:05:00Z
+duration_ms: 5000
+file_size_bytes: 524288
+codec: vp9 (for video) | opus (for audio)
+```
+
+**Server Actions**:
+1. ✅ Validate token and session ownership
+2. ✅ Verify chunk_number is sequential (prevent duplicates)
+3. ✅ Upload file to object storage (Cloudflare R2)
+ - Path: `sessions/{session_id}/{chunk_type}/chunk_{number}.webm`
+4. ✅ Store chunk metadata in `recording_chunks` table
+5. ✅ Return storage URL
+
+**Response**:
+```json
+{
+ "chunk_received": true,
+ "chunk_number": 1,
+ "storage_url": "https://r2-cdn.../sessions/550e.../video/chunk_001.webm",
+ "next_chunk_number": 2,
+ "total_received": 1
+}
+```
+
+**Error Responses**:
+```json
+// Duplicate chunk
+{
+ "error": "duplicate_chunk",
+ "message": "Chunk 1 already uploaded",
+ "existing_chunk_url": "https://..."
+}
+
+// Session not found or unauthorized
+{
+ "error": "invalid_session",
+ "message": "Session not found or you don't have permission"
+}
+
+// File too large
+{
+ "error": "chunk_too_large",
+ "message": "Chunk exceeds 10MB limit",
+ "max_size_mb": 10
+}
+```
+
+---
+
+### 3.5 POST /api/v1/interview/end
+
+**Purpose**: Signal interview completion and trigger async analysis
+
+**Authentication**: Bearer token
+
+**Client Responsibilities BEFORE calling this**:
+- ✅ Stop all recording
+- ✅ Upload ALL remaining chunks
+- ✅ Verify all uploads succeeded
+- ✅ Close WebSocket connection
+
+**Request**:
+```json
+{
+ "session_id": "550e8400-e29b-41d4-a716-446655440000",
+ "completion_status": "completed|interrupted|user_cancelled",
+ "questions_answered": 8,
+ "total_duration_seconds": 600,
+ "chunks_uploaded": {
+ "video": 45,
+ "audio": 45,
+ "screen": 30
+ }
+}
+```
+
+**Server Actions**:
+1. ✅ Validate all chunks received (verify count)
+2. ✅ Update session status to "completed" in database
+3. ✅ Create analysis record with status "pending"
+4. ✅ Trigger Celery task for async analysis:
+ - Facial expression analysis
+ - Body language analysis
+ - Speech analysis (filler words, pace, tone)
+ - Language analysis (grammar, vocabulary)
+ - Screen content analysis (if applicable)
+ - LLM-based overall assessment
+ - Score calculation
+ - Historical comparison
+ - Recommendation generation
+5. ✅ Return analysis_id for polling
+
+**Response**:
+```json
+{
+ "status": "processing",
+ "analysis_id": "analysis_550e8400-1234",
+ "session_id": "550e8400-e29b-41d4-a716-446655440000",
+ "estimated_completion": "2026-02-24T15:11:00Z",
+ "estimated_duration_seconds": 60,
+ "poll_url": "/api/v1/interview/analysis/analysis_550e8400-1234",
+ "webhook_url": null
+}
+```
+
+**Client Actions AFTER receiving response**:
+- ✅ Show "Analyzing your interview..." message
+- ✅ Poll `/analysis/{analysis_id}` every 5-10 seconds
+- ✅ Display progress bar based on `progress` field
+- ✅ Show results when `status` becomes "completed"
+
+---
+
+### 3.6 GET /api/v1/interview/analysis/{analysis_id}
+
+**Purpose**: Get analysis results (with polling support)
+
+**Authentication**: Bearer token
+
+**Response (Processing)**:
+```json
+{
+ "analysis_id": "analysis_550e8400-1234",
+ "status": "processing",
+ "progress": 65,
+ "current_step": "analyzing_voice",
+ "estimated_completion": "2026-02-24T15:11:00Z"
+}
+```
+
+**Response (Completed)** - See detailed response in section 5 below
+
+---
+
+### 3.7 GET /api/v1/interview/history
+
+**Purpose**: Get user's interview history
+
+**Authentication**: Bearer token (user_id extracted from JWT)
+
+**Query Params**:
+```
+limit: int (default: 10)
+offset: int (default: 0)
+interview_type: string (optional filter)
+```
+
+**Response**: See section 5 below for detailed structure
+
+---
+
+---
+
+## 4. Standalone Service Architecture (No Tight Coupling)
+
+### 4.1 Design Principle: Loose Coupling via APIs
+
+**CONFIRMED**: This service is designed as a **standalone microservice** that:
+- ❌ Does NOT have direct connections to other internal services
+- ✅ Consumes external data via API calls when needed
+- ✅ Operates independently
+- ✅ Can be deployed, scaled, and maintained separately
+
+### 4.2 External API Integration Pattern
+
+When this service needs data from other services, it makes **standard REST API calls**:
+
+```python
+import httpx
+from typing import Optional
+
+class ExternalServiceClient:
+ """Client for making API calls to other services"""
+
+ def __init__(self, base_url: str, api_key: str):
+ self.base_url = base_url
+ self.headers = {"Authorization": f"Bearer {api_key}"}
+
+ async def get_user_profile(self, user_id: str) -> Optional[dict]:
+ """Get user profile from User Onboarding Service"""
+ async with httpx.AsyncClient() as client:
+ try:
+ response = await client.get(
+ f"{self.base_url}/api/v1/users/{user_id}/profile",
+ headers=self.headers,
+ timeout=5.0
+ )
+ if response.status_code == 200:
+ return response.json()
+ return None
+ except httpx.RequestError:
+ # Service unavailable - continue without profile data
+ return None
+
+ async def check_user_credits(self, user_id: str, credits_required: int) -> dict:
+ """Check if user has sufficient credits"""
+ async with httpx.AsyncClient() as client:
+ response = await client.get(
+ f"{self.base_url}/api/v1/tiering/check-credits",
+ params={"user_id": user_id, "credits_required": credits_required},
+ headers=self.headers,
+ timeout=5.0
+ )
+ return response.json()
+
+ async def share_analysis_results(self, user_id: str, analysis_data: dict):
+ """Share interview analysis with Dashboard Service (fire and forget)"""
+ async with httpx.AsyncClient() as client:
+ try:
+ await client.post(
+ f"{self.base_url}/api/v1/dashboard/interview-completed",
+ json=analysis_data,
+ headers=self.headers,
+ timeout=10.0
+ )
+ except httpx.RequestError:
+ # Log error but don't fail the analysis
+ pass
+```
+
+### 4.3 When to Call External Services
+
+#### MUST Call (Required for functionality):
+1. **Credit Validation** (Optional - can be client-side):
+ - Service: Tiering Service
+ - When: Before starting interview
+ - Endpoint: `GET /api/v1/tiering/check-credits`
+ - Failure: Return error to client if insufficient credits
+
+2. **Credit Deduction** (If not done by client):
+ - Service: Tiering Service
+ - When: When interview starts
+ - Endpoint: `POST /api/v1/tiering/deduct-credits`
+ - Failure: Block interview start
+
+#### SHOULD Call (Enhances functionality):
+3. **User Profile Data** (For personalized questions):
+ - Service: User Onboarding Service
+ - When: During question generation
+ - Endpoint: `GET /api/v1/users/{user_id}/profile`
+ - Failure: Continue with generic questions
+
+4. **Resume Data** (For context-aware questions):
+ - Service: Resume & Cover Letter Service
+ - When: During question generation for technical interviews
+ - Endpoint: `GET /api/v1/resume/extract-experience`
+ - Failure: Continue without resume context
+
+#### OPTIONAL Call (Nice to have):
+5. **Share Analysis Results** (For dashboard updates):
+ - Service: Dashboard Service
+ - When: After analysis completes
+ - Endpoint: `POST /api/v1/dashboard/interview-completed`
+ - Failure: Log but don't fail analysis
+
+6. **Recommend Practice** (For user improvement):
+ - Service: Roleplay/Course/Assessment Services
+ - When: After analysis completes
+ - Endpoint: Various recommendation endpoints
+ - Failure: User can still see analysis results
+
+### 4.4 Configuration for External Services
+
+```yaml
+# config/external_services.yaml
+
+external_services:
+ enabled: true
+
+ tiering_service:
+ base_url: "https://tiering-api.growqr.com"
+ timeout_seconds: 5
+ required: false # Client can handle credits
+
+ user_service:
+ base_url: "https://users-api.growqr.com"
+ timeout_seconds: 5
+ required: false # Can work without profile
+
+ resume_service:
+ base_url: "https://resume-api.growqr.com"
+ timeout_seconds: 5
+ required: false # Can work without resume data
+
+ dashboard_service:
+ base_url: "https://dashboard-api.growqr.com"
+ timeout_seconds: 10
+ required: false # Fire and forget
+ retry_count: 0 # Don't retry
+
+ roleplay_service:
+ base_url: "https://roleplay-api.growqr.com"
+ timeout_seconds: 10
+ required: false
+
+ course_service:
+ base_url: "https://courses-api.growqr.com"
+ timeout_seconds: 10
+ required: false
+
+ assessment_service:
+ base_url: "https://assessments-api.growqr.com"
+ timeout_seconds: 10
+ required: false
+
+# All external calls are:
+# - Async (non-blocking)
+# - Timeout-protected
+# - Failure-tolerant (service continues if external service fails)
+# - Optionally cacheable (for profile/resume data)
+```
+
+### 4.5 Benefits of Standalone Architecture
+
+✅ **Independent Deployment**: Can deploy/update without coordinating with other services
+✅ **Fault Isolation**: If this service fails, others continue working
+✅ **Scalability**: Can scale independently based on interview load
+✅ **Testing**: Easier to test in isolation (mock external APIs)
+✅ **Maintenance**: Clear boundaries, easier to maintain
+✅ **Technology Independence**: Can use different tech stack if needed
+
+### 4.6 Tradeoffs
+
+❌ **Network Latency**: API calls add latency vs direct database access
+❌ **External Dependencies**: Relies on other services being available
+❌ **Data Consistency**: No distributed transactions (eventual consistency)
+✅ **Mitigation**: Cache frequently accessed data, design for failure
+
+---
+
+## 5. Database Schema (PostgreSQL)
+
+### 4.1 interview_sessions
+
+```sql
+CREATE TABLE interview_sessions (
+ session_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ user_id UUID NOT NULL,
+
+ -- Configuration
+ interview_type VARCHAR(50) NOT NULL,
+ duration_minutes INTEGER NOT NULL,
+ persona VARCHAR(20) NOT NULL,
+ job_role VARCHAR(255),
+ programming_language VARCHAR(50),
+
+ -- Status
+ status VARCHAR(20) NOT NULL DEFAULT 'configured',
+
+ -- Timing
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ started_at TIMESTAMPTZ,
+ ended_at TIMESTAMPTZ,
+
+ -- Metadata
+ questions_generated INTEGER,
+ questions_answered INTEGER,
+ total_duration_seconds INTEGER,
+
+ -- Recording URLs (in Cloudflare R2)
+ video_url TEXT,
+ audio_url TEXT,
+ screen_url TEXT,
+
+ -- Analysis reference
+ analysis_id UUID,
+
+ -- Indexes
+ CONSTRAINT chk_status CHECK (status IN ('configured', 'started', 'active', 'completed', 'interrupted', 'failed')),
+ CONSTRAINT chk_type CHECK (interview_type IN ('warmup', 'coding', 'role_related', 'behavioral')),
+ CONSTRAINT chk_duration CHECK (duration_minutes IN (5, 15, 30)),
+ CONSTRAINT chk_persona CHECK (persona IN ('payal', 'emma', 'john', 'kapil'))
+);
+
+CREATE INDEX idx_sessions_user_id ON interview_sessions(user_id);
+CREATE INDEX idx_sessions_status ON interview_sessions(status);
+CREATE INDEX idx_sessions_created_at ON interview_sessions(created_at DESC);
+```
+
+---
+
+### 4.2 interview_questions
+
+```sql
+CREATE TABLE interview_questions (
+ question_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ session_id UUID NOT NULL REFERENCES interview_sessions(session_id) ON DELETE CASCADE,
+
+ question_text TEXT NOT NULL,
+ question_number INTEGER NOT NULL,
+ category VARCHAR(50) NOT NULL,
+
+ -- D-ID generated video
+ avatar_video_url TEXT,
+ video_duration_seconds INTEGER,
+
+ asked_at TIMESTAMPTZ,
+ expected_duration_seconds INTEGER,
+
+ -- User response metadata
+ was_answered BOOLEAN DEFAULT FALSE,
+
+ CONSTRAINT chk_category CHECK (category IN ('intro', 'technical', 'behavioral', 'coding', 'closing'))
+);
+
+CREATE INDEX idx_questions_session_id ON interview_questions(session_id);
+```
+
+---
+
+### 4.3 interview_analyses
+
+```sql
+CREATE TABLE interview_analyses (
+ analysis_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ session_id UUID NOT NULL UNIQUE REFERENCES interview_sessions(session_id) ON DELETE CASCADE,
+ user_id UUID NOT NULL,
+
+ -- Status
+ status VARCHAR(20) NOT NULL DEFAULT 'pending',
+
+ -- Timing
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+ completed_at TIMESTAMPTZ,
+ processing_duration_seconds INTEGER,
+
+ -- Overall scores (0-100)
+ overall_score DECIMAL(5,2),
+
+ -- Individual metric scores
+ intro_score DECIMAL(5,2),
+ facial_expression_score DECIMAL(5,2),
+ body_language_score DECIMAL(5,2),
+ language_score DECIMAL(5,2),
+ voice_score DECIMAL(5,2),
+ outro_score DECIMAL(5,2),
+ technical_quality_score DECIMAL(5,2),
+
+ -- Detailed analysis (JSONB)
+ facial_expression_details JSONB,
+ body_language_details JSONB,
+ language_details JSONB,
+ voice_details JSONB,
+ technical_quality_details JSONB,
+ screen_analysis_details JSONB,
+
+ -- Historical comparison
+ historical_comparison JSONB,
+
+ -- Recommendations
+ recommendations JSONB,
+
+ -- Error tracking
+ error_message TEXT,
+
+ CONSTRAINT chk_status CHECK (status IN ('pending', 'processing', 'completed', 'failed'))
+);
+
+CREATE INDEX idx_analyses_user_id ON interview_analyses(user_id);
+CREATE INDEX idx_analyses_status ON interview_analyses(status);
+CREATE INDEX idx_analyses_created_at ON interview_analyses(created_at DESC);
+```
+
+---
+
+### 4.4 recording_chunks
+
+```sql
+CREATE TABLE recording_chunks (
+ chunk_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
+ session_id UUID NOT NULL REFERENCES interview_sessions(session_id) ON DELETE CASCADE,
+
+ chunk_number INTEGER NOT NULL,
+ chunk_type VARCHAR(20) NOT NULL,
+
+ -- Cloudflare R2 storage
+ storage_url TEXT NOT NULL,
+ size_bytes BIGINT,
+
+ duration_milliseconds INTEGER,
+ uploaded_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+
+ CONSTRAINT chk_chunk_type CHECK (chunk_type IN ('video', 'audio', 'screen')),
+ CONSTRAINT unique_chunk UNIQUE (session_id, chunk_type, chunk_number)
+);
+
+CREATE INDEX idx_chunks_session_id ON recording_chunks(session_id);
+```
+
+---
+
+### 4.5 user_interview_stats
+
+```sql
+CREATE TABLE user_interview_stats (
+ user_id UUID PRIMARY KEY,
+
+ -- Counts
+ total_interviews INTEGER DEFAULT 0,
+ completed_interviews INTEGER DEFAULT 0,
+
+ -- Interview type breakdown
+ warmup_count INTEGER DEFAULT 0,
+ coding_count INTEGER DEFAULT 0,
+ role_related_count INTEGER DEFAULT 0,
+ behavioral_count INTEGER DEFAULT 0,
+
+ -- Score statistics
+ average_overall_score DECIMAL(5,2),
+ best_overall_score DECIMAL(5,2),
+ latest_overall_score DECIMAL(5,2),
+
+ -- Individual metric averages
+ average_intro_score DECIMAL(5,2),
+ average_facial_score DECIMAL(5,2),
+ average_body_language_score DECIMAL(5,2),
+ average_language_score DECIMAL(5,2),
+ average_voice_score DECIMAL(5,2),
+ average_outro_score DECIMAL(5,2),
+ average_technical_quality_score DECIMAL(5,2),
+
+ -- Trends
+ score_trend VARCHAR(20),
+
+ last_interview_at TIMESTAMPTZ,
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
+
+ CONSTRAINT chk_trend CHECK (score_trend IN ('improving', 'declining', 'stable', 'fluctuating'))
+);
+
+CREATE INDEX idx_user_stats_last_interview ON user_interview_stats(last_interview_at DESC);
+```
+
+---
+
+## 5. Analysis Response Format
+
+### Complete Analysis Response
+
+```json
+{
+ "analysis_id": "analysis_550e8400-1234",
+ "session_id": "550e8400-e29b-41d4-a716-446655440000",
+ "user_id": "user_uuid",
+ "status": "completed",
+
+ "overall_score": 75.5,
+ "grade": "B+",
+
+ "metrics": {
+ "intro": {
+ "score": 80,
+ "weight": 10,
+ "feedback": "Strong opening! Good eye contact and confident tone."
+ },
+
+ "facial_expression": {
+ "score": 70,
+ "weight": 20,
+ "feedback": "Good engagement with natural expressions. Some distraction detected.",
+ "details": {
+ "smile_count": 15,
+ "eye_contact_percentage": 78,
+ "engagement_score": 72
+ }
+ },
+
+ "body_language": {
+ "score": 65,
+ "weight": 20,
+ "feedback": "Posture started strong but declined. Reduce fidgeting.",
+ "details": {
+ "posture_score": 70,
+ "fidgeting_count": 18,
+ "gesture_appropriateness": 60
+ }
+ },
+
+ "language": {
+ "score": 85,
+ "weight": 15,
+ "feedback": "Excellent vocabulary and grammar! Clear articulation.",
+ "details": {
+ "grammar_score": 90,
+ "vocabulary_richness": 85,
+ "clarity_score": 88
+ }
+ },
+
+ "voice": {
+ "score": 72,
+ "weight": 20,
+ "feedback": "Good tone but filler word usage needs improvement (23 total).",
+ "details": {
+ "filler_words": {
+ "total_count": 23,
+ "breakdown": {
+ "um": 12,
+ "uh": 6,
+ "like": 3,
+ "you_know": 2
+ },
+ "per_minute": 2.9
+ },
+ "pace_wpm": 165,
+ "tone_score": 80,
+ "volume_score": 85
+ }
+ },
+
+ "outro": {
+ "score": 78,
+ "weight": 10,
+ "feedback": "Good closing with thoughtful questions."
+ },
+
+ "technical_quality": {
+ "score": 90,
+ "weight": 5,
+ "feedback": "Excellent setup! Well-lit, centered, clear audio.",
+ "details": {
+ "lighting": "well-lit",
+ "framing": "centered",
+ "background": "professional",
+ "audio": "clear"
+ }
+ }
+ },
+
+ "screen_analysis": {
+ "was_shared": true,
+ "type": "code",
+ "language": "python",
+ "quality_score": 75,
+ "details": {
+ "syntax_errors": 2,
+ "style_score": 70,
+ "logic_score": 88
+ },
+ "feedback": "Clean code with minor syntax issues. Add error handling."
+ },
+
+ "historical_comparison": {
+ "previous_interviews_count": 4,
+ "improvement_summary": {
+ "overall_change": "+7.5",
+ "trend": "improving",
+ "best_improvement": "language (+15)",
+ "needs_work": "voice (+2)"
+ }
+ },
+
+ "recommendations": [
+ {
+ "priority": "high",
+ "category": "voice",
+ "action": "Reduce filler words from 23 to under 10",
+ "tip": "Pause silently instead of saying 'um'"
+ },
+ {
+ "priority": "medium",
+ "category": "body_language",
+ "action": "Maintain posture and reduce fidgeting",
+ "tip": "Keep hands visible and still when not gesturing"
+ }
+ ],
+
+ "media_assets": {
+ "video_recording_url": "https://r2.../550e.../video.mp4",
+ "audio_recording_url": "https://r2.../550e.../audio.mp3",
+ "screen_recording_url": "https://r2.../550e.../screen.mp4",
+ "transcript_url": "https://r2.../550e.../transcript.txt"
+ }
+}
+```
+
+---
+
+## 6. Celery Analysis Pipeline
+
+### 6.1 Analysis Task Flow
+
+```python
+from celery import Celery, chain
+
+celery_app = Celery('interview_analysis')
+
+@celery_app.task
+def analyze_interview(analysis_id: str):
+ """Main orchestrator task"""
+
+ # Run analysis steps in parallel where possible
+ analysis_tasks = [
+ analyze_facial_expressions.s(analysis_id),
+ analyze_body_language.s(analysis_id),
+ analyze_speech.s(analysis_id),
+ analyze_language.s(analysis_id),
+ analyze_technical_quality.s(analysis_id),
+ analyze_screen_content.s(analysis_id)
+ ]
+
+ # Wait for all to complete, then aggregate
+ workflow = chord(analysis_tasks)(
+ aggregate_results.s(analysis_id)
+ )
+
+ return workflow
+
+@celery_app.task
+def analyze_facial_expressions(analysis_id: str):
+ """Analyze facial expressions using Azure Face API or MediaPipe"""
+ session = get_session_by_analysis_id(analysis_id)
+ video_url = session.video_url
+
+ # Download video from R2
+ video_path = download_from_r2(video_url)
+
+ # Extract frames (1 per second)
+ frames = extract_frames(video_path, fps=1)
+
+ # Analyze with Azure Face API
+ emotions = []
+ for frame in frames:
+ result = azure_face_client.detect_emotions(frame)
+ emotions.append(result)
+
+ # Aggregate results
+ score = calculate_facial_score(emotions)
+
+ # Save to database
+ save_metric_score(analysis_id, 'facial_expression', score, emotions)
+
+ return {'facial_expression_score': score}
+
+@celery_app.task
+def analyze_body_language(analysis_id: str):
+ """Analyze body language using MediaPipe Pose or Azure"""
+ # Similar pattern to facial analysis
+ pass
+
+@celery_app.task
+def analyze_speech(analysis_id: str):
+ """Analyze speech using Deepgram or Whisper"""
+ session = get_session_by_analysis_id(analysis_id)
+ audio_url = session.audio_url
+
+ # Analyze with Deepgram
+ result = deepgram_client.transcribe(
+ audio_url,
+ options={'filler_words': True, 'measurements': True}
+ )
+
+ # Extract filler words
+ filler_count = sum(result['filler_words'].values())
+ wpm = result['wpm']
+
+ score = calculate_voice_score(filler_count, wpm)
+
+ save_metric_score(analysis_id, 'voice', score, result)
+
+ return {'voice_score': score}
+
+@celery_app.task
+def analyze_language(analysis_id: str):
+ """Analyze language using Claude"""
+ # Get transcript from speech analysis
+ transcript = get_transcript(analysis_id)
+
+ # Analyze with Claude
+ analysis = claude_client.analyze(transcript)
+
+ score = calculate_language_score(analysis)
+
+ save_metric_score(analysis_id, 'language', score, analysis)
+
+ return {'language_score': score}
+
+@celery_app.task
+def aggregate_results(results: list, analysis_id: str):
+ """Aggregate all metric scores and calculate overall score"""
+
+ # Combine all scores
+ all_scores = {}
+ for result in results:
+ all_scores.update(result)
+
+ # Calculate weighted overall score
+ overall_score = (
+ all_scores['intro_score'] * 0.10 +
+ all_scores['facial_expression_score'] * 0.20 +
+ all_scores['body_language_score'] * 0.20 +
+ all_scores['language_score'] * 0.15 +
+ all_scores['voice_score'] * 0.20 +
+ all_scores['outro_score'] * 0.10 +
+ all_scores['technical_quality_score'] * 0.05
+ )
+
+ # Get historical data
+ history = get_user_interview_history(analysis_id)
+ comparison = calculate_historical_comparison(overall_score, history)
+
+ # Generate recommendations
+ recommendations = generate_recommendations(all_scores, comparison)
+
+ # Update analysis record
+ update_analysis(
+ analysis_id,
+ status='completed',
+ overall_score=overall_score,
+ recommendations=recommendations,
+ historical_comparison=comparison
+ )
+
+ # Update user stats
+ update_user_stats(analysis_id)
+
+ return {'overall_score': overall_score}
+```
+
+---
+
+## 7. External API Integration (REMOVED)
+
+**✅ DECISION**: This service is **standalone** - no direct integration with other internal services.
+
+All required data is consumed via client requests:
+- User ID: Extracted from JWT token
+- Credits: Validated by client before reaching our service (or via external API call if needed)
+- Profile data: Sent by client in configure request if needed
+
+**No tight coupling** with:
+- User Onboarding Service
+- Resume Service
+- Dashboard Service
+- Tiering Service
+- etc.
+
+If integration is needed later, it can be added as separate API calls, but not baked into core logic.
+
+---
+
+## 8. Assumptions & Pending Decisions
+
+### 8.1 Finalized Decisions ✅
+
+**ALL AMBIGUITIES RESOLVED - CONFIRMED ARCHITECTURE**
+
+#### 1. **Avatar Implementation: OPTION A - Full Avatar with Lip-Sync**
+ - ✅ Using: D-ID, HeyGen, or Synthesia
+ - ✅ Full avatar video generation with synchronized lip movements
+ - ✅ 4 distinct avatar personalities (Payal, Emma, John, Kapil)
+ - Impact: Premium user experience, higher cost per interview
+
+#### 2. **Recording Approach: OPTION A - Client-Side Processing**
+ - ✅ **ALL audio/video/screen recording happens on CLIENT**
+ - ✅ Client captures, encodes, and processes media
+ - ✅ Client uploads pre-processed media chunks to server
+ - ✅ NO real-time server streaming
+ - ✅ NO server-side media processing
+ - Technologies: WebRTC MediaRecorder API, Screen Capture API
+ - Impact: Lower server load, better scalability, client bandwidth dependent
+
+#### 3. **Screen Recording: Client-Side Only**
+ - ✅ Screen recording fully handled by client
+ - ✅ Screen content captured using browser Screen Capture API
+ - ✅ Client processes and uploads screen recording
+ - ✅ Server receives completed screen recording for post-analysis
+ - Impact: No server screen processing, analysis happens post-upload
+
+#### 4. **Service Architecture: Standalone Microservice**
+ - ✅ **NOT directly connected to other internal services**
+ - ✅ **All inputs consumed via APIs (loose coupling)**
+ - ✅ No cross-service tight coupling
+ - ✅ Service operates independently
+ - ✅ Uses external API calls when needed
+ - Impact: Better modularity, easier maintenance, independent scaling
+
+#### 5. **Authentication & Session Management: Client-Managed**
+ - ✅ **Authentication handled entirely on CLIENT**
+ - ✅ **Session management on CLIENT**
+ - ✅ Server receives authenticated requests with JWT tokens
+ - ✅ Server validates tokens but doesn't manage sessions
+ - Impact: Stateless server architecture, simpler backend
+
+#### 6. **Media Processing Model: Client-First**
+ - ✅ Client does ALL heavy lifting (recording, encoding, compression)
+ - ✅ Server only handles:
+ - Receiving pre-processed media uploads
+ - Storing media in object storage
+ - Post-upload AI analysis (async via Celery)
+ - Serving results via API
+ - Impact: Server becomes orchestration layer, not processing layer
+
+### 8.2 Architecture Overview (Post-Clarification)
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ CLIENT SIDE │
+│ ┌────────────────────────────────────────────────────────┐ │
+│ │ 1. Authentication & Session Management (JWT) │ │
+│ │ 2. Avatar Video Playback (D-ID URLs from server) │ │
+│ │ 3. Audio Recording (MediaRecorder API) │ │
+│ │ 4. Video Recording (getUserMedia + MediaRecorder) │ │
+│ │ 5. Screen Capture (getDisplayMedia + MediaRecorder) │ │
+│ │ 6. Media Encoding (WebM: VP9 video + Opus audio) │ │
+│ │ 7. Chunk Upload (POST processed chunks to server) │ │
+│ │ 8. Real-time WebSocket (Interview state sync) │ │
+│ └────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+ ▼ ▼ ▼
+ HTTPS/WSS (Authenticated Requests)
+ ▼ ▼ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ SERVER SIDE │
+│ ┌────────────────────────────────────────────────────────┐ │
+│ │ FastAPI Service (Orchestration Layer) │ │
+│ │ - Token validation (no session management) │ │
+│ │ - Interview configuration API │ │
+│ │ - Question generation (LLM + D-ID) │ │
+│ │ - Media chunk reception & storage │ │
+│ │ - WebSocket state sync │ │
+│ │ - Trigger async analysis (Celery) │ │
+│ │ - Serve analysis results via API │ │
+│ └────────────────────────────────────────────────────────┘ │
+│ │
+│ ┌────────────────────────────────────────────────────────┐ │
+│ │ Celery Workers (Post-Interview Analysis) │ │
+│ │ - Facial expression analysis (Azure/MediaPipe) │ │
+│ │ - Body language analysis (Azure/MediaPipe) │ │
+│ │ - Speech analysis (Deepgram/Whisper) │ │
+│ │ - Code quality analysis (SonarQube/SonarCloud) │ │
+│ │ - LLM analysis (Claude/GPT-4) │ │
+│ │ - Generate recommendations │ │
+│ │ - Calculate scores & trends │ │
+│ └────────────────────────────────────────────────────────┘ │
+│ │
+│ ┌────────────────────────────────────────────────────────┐ │
+│ │ Storage Layer │ │
+│ │ - PostgreSQL: Metadata, scores, analysis │ │
+│ │ - Redis: Celery queue, caching │ │
+│ │ - Object Storage: Video/audio/screen files │ │
+│ └────────────────────────────────────────────────────────┘ │
+└─────────────────────────────────────────────────────────────┘
+ ▼ ▼ ▼
+ External API Calls (When Needed)
+ ▼ ▼ ▼
+┌─────────────────────────────────────────────────────────────┐
+│ EXTERNAL SERVICES (OPTIONAL) │
+│ - Other microservices via REST APIs (if needed) │
+│ - User profile data (API call when needed) │
+│ - Credit validation (API call if needed) │
+│ - Recommendation sharing (API call after analysis) │
+└─────────────────────────────────────────────────────────────┘
+```
+
+**Key Architectural Principles**:
+
+1. **Client = Processing, Server = Orchestration**
+ - Client handles all media capture and encoding
+ - Server handles workflow, storage, and analysis
+
+2. **Stateless Server**
+ - No session management on server
+ - JWT validation only
+ - Each request is independent
+
+3. **Loose Coupling**
+ - No direct service-to-service calls
+ - All external data via API requests
+ - Service can operate independently
+
+4. **Async Processing**
+ - Interview recording: Synchronous (client uploads)
+ - Analysis: Asynchronous (Celery workers)
+ - Results: Polling or webhook
+
+### 8.3 Remaining Assumptions
+
+1. **Storage Provider**:
+ - RECOMMENDED: Cloudflare R2 (zero egress fees)
+ - Alternative: MinIO (self-hosted)
+ - DECISION NEEDED: Final choice for production
+
+2. **AI Service Providers**:
+ - LLM: Claude 3.5 Sonnet (recommended)
+ - Facial: Azure Face API or MediaPipe (budget dependent)
+ - Body: Azure Video Indexer or MediaPipe (budget dependent)
+ - Speech: Deepgram or Whisper (budget dependent)
+ - Code: SonarCloud or SonarQube Community (budget dependent)
+ - DECISION NEEDED: Final mix of paid vs free services
+
+3. **Database Hosting**:
+ - ASSUMPTION: Self-hosted PostgreSQL for production
+ - Supabase for staging/development
+ - DECISION NEEDED: Confirm approach
+
+4. **Question Generation**:
+ - ASSUMPTION: Server generates questions using Claude + user context
+ - Questions sent as D-ID video URLs
+ - Client plays videos sequentially
+
+5. **Credits & Access Control**:
+ - ASSUMPTION: Client validates credits before interview
+ - Server can optionally verify via external API
+ - DECISION NEEDED: Credit check location (client vs server)
+
+6. **Recording Format**:
+ - ASSUMPTION: Client sends WebM (VP9 + Opus)
+ - Server accepts and stores as-is
+ - DECISION NEEDED: Any transcoding needed?
+
+7. **Analysis Timing**:
+ - ASSUMPTION: All analysis happens post-interview (not real-time)
+ - Celery processes analysis in 30-60 seconds
+ - Client polls for results
+
+8. **Video Storage Duration**:
+ - ASSUMPTION: Recordings kept for 30 days
+ - DECISION NEEDED: Retention policy?
+
+9. **Privacy & Compliance**:
+ - ASSUMPTION: User consent managed by client
+ - Server stores recordings securely
+ - DECISION NEEDED: GDPR/data deletion requirements?
+
+10. **Error Handling**:
+ - ASSUMPTION: If upload fails, client retries
+ - If analysis fails, Celery retries 3 times
+ - DECISION NEEDED: Refund policy for failed interviews?
+
+### 8.3 Open Questions
+
+1. **Scalability**:
+ - Expected concurrent users?
+ - Peak interview load?
+ - Storage growth projections?
+
+2. **Features**:
+ - MVP vs Phase 2 features?
+ - Mobile app support timeline?
+ - Live feedback during interview?
+
+3. **Business Logic**:
+ - Can users retry failed interviews?
+ - Maximum interview length?
+ - Pause/resume time limits?
+
+---
+
+## 9. Cost Estimates (Updated)
+
+### 9.1 Budget Stack (Free/Open-Source)
+
+**Infrastructure**:
+- Server (8 core, 16GB RAM, GPU): $150-300/month
+- PostgreSQL: Self-hosted ($0)
+- Redis: Self-hosted ($0)
+- Storage: MinIO self-hosted ($0)
+
+**Per Interview Costs**:
+- D-ID Avatar (15 min): $4.50
+- Whisper (free): $0
+- MediaPipe Face/Pose (free): $0
+- Ollama/Llama3 (free): $0
+- SonarQube (free): $0
+- **Total per interview**: ~$4.50
+
+**At 100 interviews/day**:
+- Monthly interviews: ~$13,500
+- Infrastructure: ~$200
+- **Total**: ~$13,700/month
+
+---
+
+### 9.2 Hybrid Stack (Mixed)
+
+**Infrastructure**:
+- Server (smaller, 4 core, 8GB): $50-100/month
+- Supabase Pro: $25/month
+- Upstash Redis: ~$10/month
+- Cloudflare R2: ~$20/month (estimated)
+
+**Per Interview Costs** (15 min):
+- D-ID Avatar: $4.50
+- Deepgram Speech: $0.06
+- Azure Face: $0.15
+- MediaPipe Pose (free): $0
+- Claude 3.5: $0.25
+- SonarQube (free): $0
+- **Total per interview**: ~$4.96
+
+**At 100 interviews/day**:
+- Monthly interviews: ~$14,880
+- Infrastructure: ~$105
+- **Total**: ~$14,985/month
+
+---
+
+### 9.3 Premium Stack (All Paid)
+
+**Infrastructure**:
+- Supabase Pro: $25/month
+- Upstash Redis: ~$20/month
+- Cloudflare R2: ~$50/month
+
+**Per Interview Costs** (15 min):
+- D-ID Avatar: $4.50
+- Deepgram Speech: $0.06
+- Azure Face: $0.15
+- Azure Video Indexer: $0.80
+- Claude 3.5: $0.30
+- SonarCloud: ~$0.10
+- **Total per interview**: ~$5.91
+
+**At 100 interviews/day**:
+- Monthly interviews: ~$17,730
+- Infrastructure: ~$95
+- **Total**: ~$17,825/month
+
+---
+
+## 10. Implementation Roadmap
+
+### Phase 1: Core Infrastructure (Week 1-2)
+- [ ] Setup FastAPI project with UV
+- [ ] Setup PostgreSQL database schema
+- [ ] Setup Redis + Celery
+- [ ] Implement authentication middleware (JWT validation)
+- [ ] Basic REST endpoints (configure, start, end)
+
+### Phase 2: Avatar Integration (Week 2-3)
+- [ ] Integrate D-ID API for avatar video generation
+- [ ] Question generation logic (with Claude)
+- [ ] WebSocket server implementation
+- [ ] Test avatar video delivery
+
+### Phase 3: Recording Upload (Week 3)
+- [ ] Implement file upload endpoint
+- [ ] Integrate Cloudflare R2 storage
+- [ ] Chunk handling and validation
+- [ ] Test large file uploads
+
+### Phase 4: Analysis Pipeline (Week 4-5)
+- [ ] Celery worker setup
+- [ ] Facial analysis (Azure or MediaPipe)
+- [ ] Body language analysis (Azure or MediaPipe)
+- [ ] Speech analysis (Deepgram or Whisper)
+- [ ] Language analysis (Claude)
+- [ ] Code analysis (SonarCloud or SonarQube)
+- [ ] Score aggregation
+- [ ] Historical comparison
+
+### Phase 5: Polish & Testing (Week 5-6)
+- [ ] Error handling and retries
+- [ ] Comprehensive testing (unit + integration)
+- [ ] Load testing
+- [ ] Documentation
+- [ ] Deployment setup
+
+### Phase 6: Production Readiness (Week 6-7)
+- [ ] Security audit
+- [ ] Performance optimization
+- [ ] Monitoring and alerting setup
+- [ ] Backup and disaster recovery
+- [ ] Production deployment
+
+---
+
+## 11. Final Architecture Diagram
+
+```
+ ┌─────────────────────────────┐
+ │ CLIENT │
+ │ (Browser/Mobile App) │
+ │ │
+ │ • Records video/audio │
+ │ • Captures screen │
+ │ • Processes media │
+ │ • Uploads chunks │
+ │ • Manages auth (JWT) │
+ └───────────┬─────────────────┘
+ │
+ │ HTTPS/WSS
+ │
+ ┌───────────▼─────────────────┐
+ │ FASTAPI SERVER │
+ │ (Stateless Service) │
+ │ │
+ │ • JWT validation only │
+ │ • Question generation │
+ │ • File upload handling │
+ │ • WebSocket messaging │
+ │ • Analysis orchestration │
+ └───────┬────────────┬────────┘
+ │ │
+ ┌───────────▼─┐ ┌───▼────────┐
+ │ PostgreSQL │ │ Redis │
+ │ Database │ │ Cache │
+ └─────────────┘ └────────────┘
+ │
+ ┌───────────▼─────────────────┐
+ │ CELERY WORKERS │
+ │ (Analysis Processing) │
+ │ │
+ │ • Facial analysis │
+ │ • Body language analysis │
+ │ • Speech analysis │
+ │ • Language analysis │
+ │ • Code analysis │
+ │ • Score aggregation │
+ └───────────┬─────────────────┘
+ │
+ ┌───────────────┴──────────────┐
+ │ │
+ ┌───────────▼────────┐ ┌───────────▼────────┐
+ │ CLOUDFLARE R2 │ │ EXTERNAL APIs │
+ │ (File Storage) │ │ │
+ │ │ │ • D-ID (Avatar) │
+ │ • Video files │ │ • Azure (Analysis)│
+ │ • Audio files │ │ • Deepgram (STT) │
+ │ • Screen files │ │ • Claude (LLM) │
+ │ • Transcripts │ │ • SonarCloud │
+ └────────────────────┘ └────────────────────┘
+```
+
+---
+
+## 12. Next Steps
+
+1. **Immediate Actions**:
+ - [ ] Finalize storage provider (Cloudflare R2 vs MinIO)
+ - [ ] Finalize AI service mix (paid vs free)
+ - [ ] Setup development environment
+ - [ ] Create repository and project structure
+
+2. **Week 1 Goals**:
+ - [ ] Setup FastAPI + PostgreSQL + Redis
+ - [ ] Implement basic authentication
+ - [ ] Create database migrations
+ - [ ] Setup D-ID integration
+ - [ ] Implement /configure endpoint
+
+3. **Communication**:
+ - [ ] Share API documentation with frontend team
+ - [ ] Define WebSocket message formats
+ - [ ] Clarify client responsibilities (recording, processing, uploading)
+ - [ ] Establish error handling protocols
+
+---
+
+**This plan is now complete and ready for implementation!** 🚀
+
+All architectural ambiguities have been resolved:
+✅ Client-side media processing
+✅ D-ID for avatars
+✅ Standalone service (no tight coupling)
+✅ Client-managed authentication
+✅ Post-upload analysis only
+
+Ready to start coding! 💪
diff --git a/upskilling/extras/interview-service-rebuild-plan.md b/upskilling/extras/interview-service-rebuild-plan.md
new file mode 100644
index 0000000..197098d
--- /dev/null
+++ b/upskilling/extras/interview-service-rebuild-plan.md
@@ -0,0 +1,407 @@
+# Interview Service Rebuild Plan
+
+## Summary
+
+Rebuild `interview-service` from scratch in its canonical location under `services/` and preserve the current implementation as a reference-only archive.
+
+This plan intentionally replaces the older avatar-heavy and client/media-split direction with a much smaller phase-1 service focused on:
+
+- interview configuration and planning
+- one Gemini Live session path
+- transcript and turn persistence
+- dual-track audio archival with S3 upload
+- rubric-based review generation with historical comparison
+
+The rebuilt service remains named `interview-service`. There is no `v2` naming in code, docs, or runtime configuration.
+
+## Goals
+
+- Keep the public API to exactly 3 surfaces:
+ - `POST /configure`
+ - `WS /session/{session_id}`
+ - `GET /review/{session_id}`
+- Preserve the product behaviors that matter:
+ - persona- and interview-aware planning
+ - bounded historical context reuse
+ - Gemini Live interview execution
+ - rubric scoring and review generation
+ - S3 archival of session audio artifacts
+ - historical comparison and carry-forward planning signals
+- Remove operational and architectural bloat from phase 1.
+
+## Non-Goals
+
+The phase-1 rebuild explicitly excludes:
+
+- avatars
+- screen share
+- technical-quality video analysis
+- Redis
+- SSE
+- external job queues or workers
+- demo app code
+- multi-mode runtimes
+- fallback-heavy abstractions
+
+Audio-only interviewing is the only live mode in scope.
+
+## Repository Transition
+
+The repo transition should happen before implementation starts:
+
+1. Rename the current service folder from `services/interview-service` to `services/interview-service-reference`.
+2. Create a fresh `services/interview-service` folder beside it.
+3. Treat `interview-service-reference` as a source of assets and selected logic only.
+4. Do not refactor in place from the archived codebase.
+
+Reference code may be copied only when it directly supports the reduced phase-1 scope, primarily:
+
+- personas
+- prompts
+- rubric definitions
+- selected planning logic
+- selected review/scoring logic
+
+## Target Service Shape
+
+Build a small FastAPI service with a narrow, obvious structure:
+
+```text
+services/interview-service/
+ app/
+ api/
+ configure.py
+ session_ws.py
+ review.py
+ assets/
+ personas/
+ prompts/
+ rubric/
+ services/
+ planning.py
+ gemini_live.py
+ review.py
+ audio_archive.py
+ storage.py
+ db/
+ models.py
+ session.py
+ core/
+ config.py
+ logging.py
+ main.py
+ alembic/
+ tests/
+```
+
+Guiding rule: each module should map to one durable service concern. Avoid framework layers that exist only for optionality that phase 1 does not need.
+
+## Public API
+
+### `POST /configure`
+
+Responsibilities:
+
+- validate persona, interview type, duration, and context
+- load bounded historical review context for the user
+- build the interview plan using current config plus retained history signals
+- persist the session row before live execution begins
+
+Response should return:
+
+- `session_id`
+- normalized configuration
+- opening prompt
+- ordered question outline
+- history summary used for planning
+
+Planning output should remain explicit and bounded:
+
+- opening prompt
+- ordered base questions
+- follow-up policy
+- focus areas influenced by history
+
+### `WS /session/{session_id}`
+
+This is the only live runtime path in phase 1.
+
+Accepted inbound events:
+
+- `session.start`
+- `audio.input`
+- `session.finish`
+
+Outbound events:
+
+- `session.ready`
+- `assistant.transcript`
+- `assistant.audio`
+- `candidate.transcript`
+- `turn.saved`
+- `session.completed`
+- `error`
+
+Responsibilities:
+
+- attach to the persisted session
+- run Gemini Live relay for the interview
+- persist turns as they occur
+- write assistant and candidate audio into the archive pipeline
+- finalize artifacts and upload to S3 on `session.finish`
+- mark the session complete
+- start in-process async review generation after completion
+
+### `GET /review/{session_id}`
+
+Behavior:
+
+- return `status: processing` until review generation finishes
+- return the final review payload when available
+
+Final payload should include:
+
+- overall score
+- rubric scores
+- strengths
+- weaknesses
+- recommendations
+- historical comparison
+- carry-forward planning signals
+- audio artifact metadata
+
+This endpoint is read-only. It does not trigger new work.
+
+## Data Model
+
+Keep only 4 tables.
+
+### `interview_sessions`
+
+Fields:
+
+- session id
+- user and org identifiers
+- interview configuration JSON
+- status
+- planning context JSON
+- question plan JSON
+- opening prompt
+- created/updated/completed timestamps
+
+Purpose:
+
+- own the session lifecycle
+- preserve normalized planning inputs and outputs
+
+### `interview_turns`
+
+Fields:
+
+- session id
+- sequence
+- speaker
+- turn type
+- transcript
+- timing metadata
+- Gemini or session metadata JSON
+
+Purpose:
+
+- preserve ordered transcript and turn-level execution state
+
+### `interview_artifacts`
+
+Fields:
+
+- session id
+- artifact type
+- S3 key
+- mime type
+- duration and size
+- manifest metadata JSON
+- created timestamp
+
+Purpose:
+
+- register all persisted review-related artifacts
+
+### `interview_reviews`
+
+Fields:
+
+- session id
+- overall score
+- rubric scores JSON
+- summary
+- strengths JSON
+- weaknesses JSON
+- recommendations JSON
+- historical comparison JSON
+- carry-forward planning signals JSON
+- created timestamp
+
+Purpose:
+
+- cache the final review payload
+- expose direct planning signals for the next `configure` call
+
+## Planning Logic
+
+Planning behavior to preserve from the prior service:
+
+- use recent completed interview history
+- use aggregated recurring weak areas
+- let low historical scores and repeated gaps influence question selection
+- adjust question emphasis and difficulty based on prior performance
+
+Planning constraints for the rebuild:
+
+- bound history lookup to a small recent window
+- summarize recurring weaknesses instead of loading unbounded detail
+- keep planning output deterministic enough to inspect and test
+- store the history summary actually used during planning
+
+Expected planning artifacts:
+
+- normalized interview configuration
+- bounded history summary
+- focus areas
+- ordered base questions
+- opening prompt
+- follow-up policy
+
+## Review Logic
+
+Review behavior to preserve:
+
+- score against the retained rubric
+- use transcripts together with session audio artifacts
+- generate strengths, weaknesses, and recommendations
+- compare against prior interviews
+- emit carry-forward signals for the next session
+
+Carry-forward planning signals should be explicit and reusable, for example:
+
+- recurring weak areas
+- rubric dimensions trending down
+- recommended follow-up difficulty
+- suggested topic emphasis for the next interview
+
+The review service should persist the finished result once and let `GET /review/{session_id}` return that cached payload directly.
+
+## Audio Archival and S3 Layout
+
+Phase 1 archives both sides of the session, not candidate-only audio.
+
+Recommended S3 object layout:
+
+```text
+interviews/{user_id}/{session_id}/session-dual.wav
+interviews/{user_id}/{session_id}/session-mixed.mp3
+interviews/{user_id}/{session_id}/manifest.json
+```
+
+Artifact roles:
+
+- `session-dual.wav` is the canonical review source
+- `session-mixed.mp3` is a secondary convenience playback artifact
+- `manifest.json` links session metadata, channel mapping, transcript/review references, and artifact properties
+
+Channel mapping:
+
+- channel 1 = assistant
+- channel 2 = candidate
+
+Implementation rules:
+
+- assemble artifacts incrementally on disk
+- never buffer the full session in memory
+- finalize and upload all artifacts on `session.finish`
+- persist artifact rows after successful upload with S3 key and metadata
+
+## Runtime Simplification
+
+Keep runtime configuration intentionally small:
+
+- database URL
+- Gemini credentials and model
+- S3 bucket settings
+- review model settings
+- temp directory
+- history window size
+- logging level
+
+Operational decisions for phase 1:
+
+- no Redis
+- no SSE
+- no external queue or worker process
+- no polling orchestration endpoint beyond `GET /review/{session_id}`
+- review generation starts as an in-process async task after `session.finish`
+
+If review generation fails, the failure should be stored clearly enough for diagnosis and surfaced predictably through the review endpoint or logs.
+
+## Delivery Sequence
+
+1. Archive the current service as `interview-service-reference`.
+2. Scaffold a fresh `interview-service`.
+3. Copy only personas, prompts, rubric, and the minimum selected planning/review logic.
+4. Create the 4-table schema and initial migration.
+5. Implement `POST /configure`.
+6. Implement the Gemini Live WebSocket session path.
+7. Add ordered turn persistence.
+8. Add dual-track archive assembly, mixed export, and manifest generation.
+9. Add S3 upload on session completion.
+10. Start in-process review generation on `session.finish`.
+11. Implement `GET /review/{session_id}`.
+12. Validate the rebuilt service against the simplified phase-1 scope.
+
+## Test Plan
+
+The initial test suite should prove the simplified contract end to end.
+
+Core cases:
+
+- `POST /configure` rejects invalid config
+- `POST /configure` returns normalized config and history-aware planning output
+- historical weak areas alter the next session question plan
+- `WS /session/{session_id}` rejects invalid or missing sessions
+- turns are persisted in correct sequence order
+- assistant and candidate audio are both captured into the archive workflow
+- `session-dual.wav`, `session-mixed.mp3`, and `manifest.json` are produced with correct metadata
+- S3 upload stores expected keys and artifact rows
+- `session.finish` marks the session complete and starts review generation
+- `GET /review/{session_id}` returns `processing` before completion and a full payload afterward
+- final review includes historical comparison and carry-forward planning signals
+- the end-to-end flow works without Redis, SSE, or queue infrastructure
+
+## Acceptance Criteria
+
+The rebuild is ready for phase-1 validation when all of the following are true:
+
+- the service exposes only the 3 required public surfaces
+- the archived implementation is preserved separately as `interview-service-reference`
+- the new service has only the 4 required database tables
+- planning uses bounded historical context and persists the exact planning summary used
+- the WebSocket path is Gemini Live only
+- both sides of the interview are archived into the canonical dual-track artifact
+- artifacts are uploaded to S3 and registered in `interview_artifacts`
+- review generation persists rubric-based output plus historical comparison
+- the next `configure` call can reuse carry-forward signals directly
+- the service runs without Redis, SSE, or external worker infrastructure
+
+## Assumptions and Defaults
+
+- Service name remains `interview-service`.
+- The old implementation is preserved only as `interview-service-reference`.
+- Audio-only interviewing is the only live mode in phase 1.
+- Avatars, screen share, and technical-quality video analysis are deferred.
+- Historical context is bounded to a recent window plus aggregated weak-area summaries.
+- Review generation runs asynchronously inside the web process.
+- `session-dual.wav` is the canonical review artifact.
+- `session-mixed.mp3` exists as a convenience artifact, not the source of truth.
+
+## Recommended Next Step
+
+Use this document as the implementation baseline, then create a task-by-task execution checklist in the new `services/interview-service` workspace as soon as the folder archive and scaffold step is complete.
diff --git a/upskilling/extras/meeting_notes.md b/upskilling/extras/meeting_notes.md
new file mode 100644
index 0000000..163ea0d
--- /dev/null
+++ b/upskilling/extras/meeting_notes.md
@@ -0,0 +1,338 @@
+# GrowQR — Interview Service — Meeting Notes (Decision & Tradeoff Doc)
+
+**Primary purpose:** help the team make high-quality engineering decisions for the Interview Service (and how it composes into the **Upscaling module**: Interview + Roleplay + Courses + Assessment).
+
+**Updated after meeting:** 2026-02-27
+
+**Related cross-service doc:** `growqr/plans/upscaling_redundancy_breakdown.md`
+
+---
+
+## 0) What we learned from the meeting (delta from earlier plan)
+
+### 0.1 Compliance / security baseline is mandatory
+You called this “DITA compliant” in the meeting. I’m interpreting that as: **baseline privacy + security controls suitable for US/EU/India markets** (not full SOC2-from-day-1, but not a hobby project).
+
+### 0.2 Timeline changed
+- Previous assumption: ~6–7 working days
+- New agreed direction: **~3 weeks** so we can optimize latency, consistency, and security properly.
+
+### 0.3 Latency is now a core requirement
+We need the experience to be:
+- fast to interact
+- seamless (no awkward waits)
+- less robotic (voice prosody + conversational pacing)
+
+This affects where we put STT/TTS/avatar/lip-sync (client vs server) and whether we do streaming.
+
+### 0.4 Client vs server split was debated
+- Team leaned server-side for “control”
+- You argued client-side for **cost, scalability, compliance, and lower infra**
+- Current direction: **client-heavy media + near-real-time text to server** (recommended compromise)
+
+---
+
+## 1) Baseline compliance & security checklist (US/EU/India)
+
+### 1.1 What we should implement in v1 (minimum)
+- **TLS everywhere**
+- **Encryption at rest** (DB + object storage; KMS-managed keys where possible)
+- **Least privilege IAM** (per-service roles; scoped permissions)
+- **Presigned URLs** for uploads/downloads (short expiry; scoped paths)
+- **PII minimization**: explicitly classify data
+ - Tier A: account identifiers
+ - Tier B: transcripts (sensitive)
+ - Tier C: raw recordings (highly sensitive)
+ - Tier D: derived metrics (lower sensitivity)
+- **Retention controls**: configurable retention for recordings and transcripts
+- **Deletion workflow**: delete user data on request; delete expired artifacts automatically
+- **Access audit logs**: log access to raw recordings and reports
+- **Vendor DPAs** (if using paid AI providers): confirm acceptable processing + region
+
+### 1.2 Security guardrails that improve decision-making
+- Prefer **client-side processing** for sensitive media where possible.
+- If we must use paid providers, prefer:
+ - providers that support enterprise controls and DPAs
+ - region pinning/data residency where required
+
+---
+
+## 2) What is a “real-time streaming pipeline” (and what we actually need)
+
+A real-time streaming pipeline processes data continuously while it’s produced.
+
+### Level 0 — Batch (simplest)
+- Record → upload → analyze.
+- Low engineering risk, high latency.
+
+### Level 1 — Near-real-time (recommended)
+- Client produces transcript quickly and sends **text turn** immediately.
+- Server generates next question immediately (optionally with **token streaming**).
+- Media uploads continue in background and are used for **post-session analysis**.
+
+### Level 2 — True streaming (complex/expensive)
+- Stream audio/video to server (WebRTC/WebSocket)
+- Streaming STT → streaming LLM → streaming TTS
+- Maximum complexity, maximum compliance surface area.
+
+**Recommendation:** Level 1. It achieves “fast and seamless” without heavy streaming of user audio/video.
+
+---
+
+## 3) Optimal client vs server split (for cost, latency, and compliance)
+
+### 3.1 Client-side (recommended)
+These reduce backend infra cost and reduce compliance risk.
+
+1) **Media capture + encoding**
+- camera/mic recording
+- screen share (specific window)
+- local compression
+
+2) **STT (speech-to-text) where feasible**
+- produce transcript locally and send text; enables fast turn-taking
+
+3) **TTS (text-to-speech) for AI persona**
+- fast, avoids voice vendor calls; BUT voice quality can vary across devices
+
+4) **Avatar rendering + lip sync**
+- best in client renderer (2D/3D) for low latency
+- accuracy improves if we can get **viseme/phoneme timing** from TTS
+
+5) **Optional CV feature extraction**
+- MediaPipe landmarks → send compact features/metrics rather than raw frames
+
+
+### 3.2 Server-side (should remain centralized)
+1) **Session orchestration + persistence**
+- state machine, timing, idempotency
+
+2) **Question selection/generation**
+- interview type logic, persona rules
+
+3) **Scoring + report generation**
+- deterministic numeric scoring
+- LLM-generated narrative sections (structured)
+
+4) **Artifact registry + storage broker**
+- presigned URLs, metadata, retention/deletion
+
+5) **History/trends**
+
+6) **Integrations**
+- emit results to Dashboard/Courses/Assessment/Roleplay
+
+---
+
+## 4) On-device models (browser): realistic options
+
+You mentioned bundling “a small whisper model for TTS” — Whisper is **STT**, not TTS.
+
+### 4.1 STT client options
+- **Fastest (low engineering):** Web Speech Recognition
+- **Self-contained:** `whisper.cpp` / WASM Whisper (tiny/base)
+ - Pros: privacy + no vendor
+ - Cons: model download size + CPU cost
+- **Hybrid fallback:** try local STT; if unavailable/slow, user opts-in to server STT
+
+### 4.2 TTS client options
+- **Simple:** Web Speech Synthesis / native OS voices
+- **Higher quality + lip sync friendly (paid):** Azure Speech TTS (supports visemes)
+ - Note: only the assistant text is sent; user audio/video still stays client-side
+
+### 4.3 Lip sync options (for “not robotic”)
+- **Best for latency:** client-rendered avatar + viseme timing (from TTS or heuristic)
+- **Worst for latency:** pre-rendered avatar videos per utterance (often seconds delay)
+
+---
+
+## 5) Modules required (composition modules)
+
+1) API layer (HTTP)
+2) AuthN/AuthZ verification
+3) Session State Machine & Orchestrator
+4) Question Bank + Rubrics
+5) Turn ingestion (Q/A turns)
+6) Media broker (presigned URLs, metadata)
+7) Background jobs (analysis worker)
+8) Signal processing (optional)
+9) Scoring engine (deterministic)
+10) Report generator (structured feedback)
+11) History/trends
+12) Outbound integrations (events/webhooks + outbox)
+13) Observability
+14) Compliance controls (retention/deletion/audit)
+
+---
+
+## 6) Implementation options per module (OSS vs Paid vs Paid-simple)
+
+**Legend**
+- **OSS** = self-hostable
+- **Paid** = best quality / flexible
+- **Paid-simple** = easiest integration / fewest moving parts
+
+### 6.1 API layer
+- OSS: FastAPI / NestJS
+- Paid: AWS API Gateway
+- Paid-simple: Cloudflare Workers
+
+**Decision (LOCKED):** **FastAPI**
+
+### 6.2 Database
+- OSS: Postgres self-host
+- Paid: RDS/Cloud SQL
+- Paid-simple: Supabase Postgres
+
+**Decision (LOCKED):** **Self-hosted Postgres** (on GCP/compute)
+
+### 6.3 Storage
+- OSS: MinIO
+- Paid: S3 / GCS
+- Paid-simple: Cloudflare R2
+
+**Decision (LOCKED):** **Google Cloud Storage (GCS)** (S3-compatible bucket)
+
+### 6.4 Jobs/queue
+- OSS: RQ/Celery + Redis
+- Paid: SQS + ECS/Lambda
+- Paid-simple: Step Functions
+
+**Decision (LOCKED):** **RQ + Redis** (built into the service)
+
+### 6.5 LLM (questions + report narrative)
+- OSS: Ollama / vLLM
+- Paid: OpenAI / Anthropic / Gemini
+- Paid-simple: single-provider adapter
+
+**Decision (LOCKED):** **OpenRouter / OpenAI key** (via an adapter)
+
+### 6.6 STT
+- OSS: faster-whisper (server) / whisper.cpp WASM (client)
+- Paid: Deepgram / AssemblyAI / Google STT
+- Paid-simple: AWS Transcribe
+
+**Decision (LOCKED):** **Whisper WASM** on the client side
+
+### 6.7 TTS
+- OSS: Piper / Coqui
+- Paid: ElevenLabs / Azure Speech
+- Paid-simple: native/browser TTS
+
+**Decision (LOCKED):** **Google Cloud TTS** (we have an account, simple integration)
+
+### 6.8 Facial/body/technical quality
+- OSS: MediaPipe client or server
+- Paid: Rekognition/Azure Face
+- Paid-simple: client-only metrics
+
+**Decision (LOCKED):** **MediaPipe on the client** (no AWS Rekognition)
+
+### 6.9 Screen-share / coding analysis
+- OSS: structured artifacts + tree-sitter
+- Paid: LLM code feedback; optional sandbox
+- Paid-simple: LLM-only feedback from code text
+
+**Decision (LOCKED):** **Simple feedback only** for now (no heavy OCR/analysis)
+
+---
+
+## 7) Two best-path approaches
+
+### Option A — Client-heavy + Paid AI (recommended)
+- Client: capture + encode + (STT/TTS/avatar/lip-sync)
+- Server: orchestration + scoring + report + history + compliance + integrations
+- Paid LLM for narrative + follow-ups
+
+**Pros:** best speed-to-quality tradeoff, minimal infra, easier compliance.
+**Cons:** variable LLM cost; requires careful client contract.
+
+### Option B — OSS/self-hosted ML
+- Self-host LLM + STT + TTS + CV
+
+**Pros:** maximum control, lower marginal cost at scale.
+**Cons:** GPU ops + longer timeline.
+
+---
+
+## 8) Tradeoffs (Paid vs OSS)
+
+| Dimension | Client-heavy + Paid AI | OSS-first |
+|---|---|---|
+| Time-to-ship | Best | Slower |
+| Latency UX | Best (if we stream text + client TTS) | Depends on infra |
+| Compliance surface | Smaller (less user media sent) | Smallest if fully local |
+| Ops burden | Low | High |
+| Cost profile | Usage-based | Fixed infra + ops |
+
+---
+
+## 9) Timeline estimate (updated)
+
+### 9.1 Recommended plan — **~3 weeks**
+**Week 1: foundations + compliance**
+- finalize client/server contract
+- DB schema + migrations
+- state machine
+- artifact broker (presigned URLs)
+- retention + deletion hooks + audit logging
+
+**Week 2: latency + interaction path**
+- “fast path” transcript turn-taking
+- SSE streaming responses (if using LLM)
+- deterministic scoring engine + report generator v1
+- background worker pipeline
+
+**Week 3: reliability + integrations + polish**
+- idempotency, retries, outbox
+- perf budget enforcement (≤60s analysis)
+- events to Dashboard/Courses/Assessment/Roleplay
+- security review checklist + load test
+
+### 9.2 If we insist on true server-side streaming (Level 2)
+Add **+3 to +6 weeks** (complexity explodes: streaming STT/TTS, infra, compliance).
+
+---
+
+## 10) Cost model (decision-friendly, not exact pricing)
+
+### 10.1 What costs money
+- LLM tokens (follow-ups + narrative report)
+- STT minutes (if server-side fallback)
+- TTS characters (if server-side paid voices)
+- storage (video/audio/screen)
+- compute for workers
+
+### 10.2 Cheapest sustainable shape
+- Keep user audio/video processing **client-side**
+- Send only **text turns** to server for interaction
+- Upload media in background for post-analysis (or make recording storage opt-in)
+
+### 10.3 “Buy vs build” money tradeoff (qualitative)
+- Buying LLM/STT/TTS reduces engineering and ops cost immediately, but increases variable cost.
+- OSS reduces variable cost at scale, but increases:
+ - GPU infra costs
+ - reliability/monitoring burden
+ - engineering time
+
+---
+
+## 11) Cross-service redundancy note
+
+Interview/Roleplay/Courses/Assessment share platform concerns (credits, artifacts, certificates, events, skill taxonomy, compliance).
+
+See: `growqr/plans/upscaling_redundancy_breakdown.md`
+
+---
+
+## 12) Open questions (need answers to lock implementation)
+
+1) When we say “DITA compliant”, confirm the target:
+ - baseline GDPR/DPDP/CCPA + security controls?
+ - or a specific internal standard?
+
+2) Do we store raw recordings by default or make it opt-in with retention caps?
+
+3) For “less robotic voice”: do we accept platform TTS variance, or require consistent paid TTS (Azure Speech, etc.)?
+
+4) Client STT: commit to WASM Whisper now, or as a progressive enhancement/fallback?
diff --git a/upskilling/extras/server_client_split.md b/upskilling/extras/server_client_split.md
new file mode 100644
index 0000000..568b079
--- /dev/null
+++ b/upskilling/extras/server_client_split.md
@@ -0,0 +1,1286 @@
+# GrowQR Interview Service - Server/Client Responsibility Split
+
+**Version:** 1.0
+**Date:** March 2, 2026
+**Purpose:** Define clear boundaries between server and client implementations
+
+---
+
+## 🎯 Quick Summary
+
+| Aspect | Server | Client |
+|--------|--------|--------|
+| **Primary Role** | Orchestrator & Intelligence | Media Processor & User Interface |
+| **Heavy Lifting** | AI logic, business rules, data persistence | Recording, encoding, speech processing |
+| **Data Flow** | Text-based (transcripts, questions, metadata) | Media-based (video, audio, screen capture) |
+| **Technology** | Python + FastAPI | JavaScript/TypeScript + Browser APIs |
+| **Scalability** | Horizontal scaling via stateless design | Scales with user devices |
+
+---
+
+## 📦 SERVER-SIDE: What Goes on Server
+
+### Core Principle
+**Server = Stateless orchestrator that handles AI, business logic, auth, and data persistence**
+
+### Server Responsibilities Overview
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ SERVER SIDE │
+│ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 1. AUTHENTICATION & AUTHORIZATION │ │
+│ │ • JWT token validation │ │
+│ │ • User identity verification │ │
+│ │ • Permission checks │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 2. BUSINESS LOGIC & ORCHESTRATION │ │
+│ │ • Session state machine │ │
+│ │ • Interview flow control │ │
+│ │ • Credits/entitlements management │ │
+│ │ • Timer and progress tracking │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 3. AI LOGIC (LLM Integration) │ │
+│ │ • Question generation │ │
+│ │ • Follow-up question logic │ │
+│ │ • Transcript analysis │ │
+│ │ • Narrative feedback generation │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 4. STORAGE BROKER │ │
+│ │ • Pre-signed URL generation │ │
+│ │ • Artifact metadata registry │ │
+│ │ • Retention policy enforcement │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 5. POST-PROCESSING & ANALYSIS │ │
+│ │ • Scoring algorithms (7 metrics) │ │
+│ │ • Report generation │ │
+│ │ • Historical trends calculation │ │
+│ │ • Event emission (integrations) │ │
+│ └──────────────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## 🖥️ SERVER MODULES (Detailed Breakdown)
+
+### Module 1: Authentication & Authorization
+
+**Purpose:** Verify user identity and permissions
+
+**Responsibilities:**
+- ✅ Validate JWT tokens (signature, expiry, claims)
+- ✅ Extract user_id from token
+- ✅ Check user permissions (org visibility, feature access)
+- ✅ Rate limiting per user
+
+**Technology Stack:**
+- JWT library (PyJWT)
+- Middleware pattern (FastAPI dependencies)
+- Redis for rate limiting
+
+**Inputs:**
+- JWT token (from Authorization header)
+
+**Outputs:**
+- Validated User object
+- HTTP 401 if invalid
+- HTTP 429 if rate limited
+
+**TODO:**
+- Implement JWT validation middleware
+- Define token claims structure
+- Setup rate limiting rules
+
+---
+
+### Module 2: Credits & Entitlements
+
+**Purpose:** Manage user credits and interview quotas
+
+**Responsibilities:**
+- ✅ Check available credits before starting interview
+- ✅ Deduct credits atomically (prevent double-spend)
+- ✅ Handle different interview types (different credit costs)
+- ✅ Support refunds (if interview fails)
+
+**Technology Stack:**
+- PostgreSQL transactions
+- Database-level locks
+- Optional: External credits service API
+
+**Database Schema:**
+```
+user_credits:
+ - user_id
+ - credits_balance
+ - last_updated
+
+credit_transactions:
+ - id
+ - user_id
+ - session_id
+ - amount (positive or negative)
+ - transaction_type (deduct, refund, purchase)
+ - created_at
+```
+
+**Inputs:**
+- User ID
+- Interview type
+
+**Outputs:**
+- Success/failure
+- Remaining credits
+
+**TODO:**
+- Implement atomic deduction logic
+- Define credit costs per interview type
+- Create refund workflow
+
+---
+
+### Module 3: Session State Machine
+
+**Purpose:** Manage interview session lifecycle
+
+**Responsibilities:**
+- ✅ Create new sessions
+- ✅ Track session state transitions
+- ✅ Enforce state rules (can't submit turn if not started)
+- ✅ Handle timeouts and abandonment
+
+**States:**
+```
+configured → in_progress → completed → processing → ready
+ ↓
+ abandoned/timeout
+```
+
+**Technology Stack:**
+- PostgreSQL for persistence
+- Redis for active session cache
+- FSM (Finite State Machine) pattern
+
+**Database Schema:**
+```
+interview_sessions:
+ - id (UUID)
+ - user_id
+ - interview_type
+ - status (enum: configured, in_progress, completed, processing, ready, abandoned)
+ - started_at
+ - completed_at
+ - created_at
+ - metadata (JSONB)
+```
+
+**Inputs:**
+- Session ID
+- State transition request
+
+**Outputs:**
+- Updated session state
+- Validation errors
+
+**TODO:**
+- Implement state machine logic
+- Define transition rules
+- Create timeout handling (background job)
+
+---
+
+### Module 4: Question Generation (AI)
+
+**Purpose:** Generate personalized interview questions using LLM
+
+**Responsibilities:**
+- ✅ Generate 8-10 questions based on interview type
+- ✅ Personalize based on user profile (role, experience, skills)
+- ✅ Create avatar scripts (conversational versions)
+- ✅ Mix difficulty levels (easy/medium/hard)
+- ✅ Store questions in database
+
+**Technology Stack:**
+- Anthropic Claude 3.5 Sonnet OR OpenAI GPT-4
+- LLM client library
+- Prompt templates
+
+**Prompt Strategy:**
+```
+Input:
+- Interview type (technical, behavioral, coding, warmup)
+- User profile (role, experience, skills, previous interviews)
+- Programming language (for coding interviews)
+
+Output (JSON):
+[
+ {
+ "text": "Question for interviewer",
+ "avatar_script": "Conversational version",
+ "category": "technical|behavioral|problem_solving",
+ "difficulty": "easy|medium|hard",
+ "expected_duration": 120
+ }
+]
+```
+
+**Database Schema:**
+```
+interview_questions:
+ - id (UUID)
+ - session_id
+ - question_order (int)
+ - question_text
+ - avatar_script
+ - category
+ - difficulty
+ - expected_duration_seconds
+ - is_followup (boolean)
+ - parent_question_id (UUID, nullable)
+```
+
+**Inputs:**
+- Interview type
+- User profile
+- Programming language (optional)
+
+**Outputs:**
+- List of questions (JSON)
+- Stored in database
+
+**TODO:**
+- Create prompt templates
+- Implement LLM API integration
+- Define question validation rules
+- Handle LLM failures (retry logic)
+
+---
+
+### Module 5: Follow-up Question Logic (AI)
+
+**Purpose:** Decide whether to ask follow-up or proceed to next question
+
+**Responsibilities:**
+- ✅ Analyze user's answer transcript
+- ✅ Determine if follow-up is needed (incomplete, interesting, or unclear answer)
+- ✅ Generate contextual follow-up question
+- ✅ Limit follow-ups (max 1-2 per main question)
+
+**Technology Stack:**
+- LLM (Claude/GPT-4)
+- Context window management
+- Prompt templates
+
+**Decision Logic:**
+```
+Input:
+- Previous question
+- User's transcript
+- Session context (time remaining, questions completed)
+
+LLM Analysis:
+1. Is the answer complete?
+2. Did user mention something interesting worth exploring?
+3. Is clarification needed?
+4. Do we have time for follow-up?
+
+Output:
+- followup_needed: true/false
+- followup_question: "..." (if needed)
+```
+
+**Inputs:**
+- Session ID
+- Previous question + answer transcript
+- Time remaining
+
+**Outputs:**
+- Next question (follow-up or sequential)
+
+**TODO:**
+- Create follow-up analysis prompt
+- Implement decision logic
+- Set follow-up limits per session
+
+---
+
+### Module 6: Pre-signed URL Generation
+
+**Purpose:** Generate secure, time-limited upload URLs for client
+
+**Responsibilities:**
+- ✅ Generate S3/R2 pre-signed URLs
+- ✅ Scope URLs to session + chunk number
+- ✅ Set expiry (15 minutes)
+- ✅ Generate URLs in batches (5-10 at a time)
+- ✅ Support URL refresh requests
+
+**Technology Stack:**
+- Boto3 (S3 SDK) or Cloudflare R2 SDK
+- S3-compatible API (signature v4)
+
+**URL Structure:**
+```
+https://storage.growqr.com/sessions/{session_id}/{media_type}/chunk_{n}.webm?
+ X-Amz-Algorithm=AWS4-HMAC-SHA256&
+ X-Amz-Credential=...&
+ X-Amz-Date=...&
+ X-Amz-Expires=900&
+ X-Amz-Signature=...
+```
+
+**Security:**
+- PUT-only permission
+- Content-Type restricted (video/webm)
+- Path scoped to session
+- Short expiry (15 min)
+
+**Inputs:**
+- Session ID
+- Chunk numbers
+- Media type (video, screen, audio)
+
+**Outputs:**
+- Array of pre-signed URLs with metadata
+
+**TODO:**
+- Implement URL generation function
+- Configure S3/R2 bucket permissions
+- Create URL refresh endpoint
+
+---
+
+### Module 7: Turn Management
+
+**Purpose:** Store and manage Q&A turns during interview
+
+**Responsibilities:**
+- ✅ Store transcript for each answer
+- ✅ Record metadata (duration, chunks uploaded, confidence)
+- ✅ Link turn to question
+- ✅ Validate turn completeness
+
+**Technology Stack:**
+- PostgreSQL
+
+**Database Schema:**
+```
+interview_turns:
+ - id (UUID)
+ - session_id
+ - question_id
+ - transcript (TEXT)
+ - duration_seconds (INT)
+ - chunks_uploaded (INT[])
+ - metadata (JSONB) - STT confidence, language detected, etc.
+ - created_at
+```
+
+**Inputs:**
+- Session ID
+- Question ID
+- Transcript
+- Duration
+- Chunks uploaded
+
+**Outputs:**
+- Stored turn record
+- Validation result
+
+**TODO:**
+- Implement turn storage endpoint
+- Add validation rules
+- Create turn query APIs
+
+---
+
+### Module 8: Media Artifact Registry
+
+**Purpose:** Track uploaded media chunks and metadata
+
+**Responsibilities:**
+- ✅ Register chunk uploads (after client uploads to S3)
+- ✅ Track upload completeness
+- ✅ Store metadata (size, duration, storage path)
+- ✅ Support retention policies
+
+**Technology Stack:**
+- PostgreSQL
+
+**Database Schema:**
+```
+media_chunks:
+ - id (UUID)
+ - session_id
+ - chunk_number
+ - media_type (video, screen, audio)
+ - storage_key (S3 path)
+ - file_size_bytes
+ - duration_seconds
+ - uploaded_at
+ - expires_at (based on retention policy)
+```
+
+**Inputs:**
+- Session ID
+- Chunk metadata (from client callback)
+
+**Outputs:**
+- Registered chunk record
+
+**TODO:**
+- Implement chunk registration endpoint
+- Create retention policy job
+- Setup deletion workflow
+
+---
+
+### Module 9: Scoring Engine
+
+**Purpose:** Calculate 7 performance metrics from interview data
+
+**Responsibilities:**
+- ✅ Communication clarity (0-100)
+- ✅ Technical accuracy (0-100)
+- ✅ Problem-solving approach (0-100)
+- ✅ Confidence (0-100)
+- ✅ Professionalism (0-100)
+- ✅ Engagement (0-100)
+- ✅ Overall score (weighted average)
+
+**Scoring Algorithms:**
+
+**1. Communication Clarity:**
+- Word count / duration = words per minute
+- Filler word detection (um, uh, like, you know)
+- Penalty for excessive fillers
+- Score: 100 - (filler_count × 2)
+
+**2. Technical Accuracy:**
+- LLM analysis of answers vs expected concepts
+- Keyword/concept matching
+- Code correctness (if applicable)
+
+**3. Problem-Solving:**
+- Answer structure analysis
+- Breaking down complex problems
+- Logical flow
+
+**4. Confidence:**
+- Speech rate consistency
+- Pause analysis
+- Filler word ratio
+
+**5. Professionalism:**
+- Language formality
+- No inappropriate content
+- Proper terminology
+
+**6. Engagement:**
+- Answer completeness
+- Enthusiasm markers
+- Eye contact (if using video analysis)
+
+**Technology Stack:**
+- Python (NumPy for calculations)
+- LLM for qualitative analysis
+- Optional: Speech analysis libraries
+
+**Inputs:**
+- All turns (transcripts)
+- Session metadata
+- Optional: Media files for advanced analysis
+
+**Outputs:**
+- Scores object (JSON)
+- Metric breakdowns
+
+**TODO:**
+- Implement deterministic scoring logic
+- Integrate LLM for qualitative metrics
+- Define scoring weights
+- Create testing suite for score consistency
+
+---
+
+### Module 10: Report Generation (AI)
+
+**Purpose:** Generate narrative feedback using LLM
+
+**Responsibilities:**
+- ✅ Analyze complete interview transcript
+- ✅ Generate strengths (top 3 with examples)
+- ✅ Generate improvements (top 3 with examples)
+- ✅ Overall assessment (2-3 sentences)
+- ✅ Actionable recommendations
+
+**Technology Stack:**
+- LLM (Claude/GPT-4)
+- Structured output (JSON)
+- Report templates
+
+**Prompt Strategy:**
+```
+Input:
+- Full interview transcript (all Q&A pairs)
+- Quantitative scores
+- User profile
+
+Prompt:
+"Analyze this interview performance. Provide:
+1. Top 3 strengths (with specific examples from transcript)
+2. Top 3 areas for improvement (with specific examples)
+3. Overall assessment (2-3 sentences)
+4. Actionable next steps
+
+Be specific, constructive, and reference actual quotes."
+
+Output (JSON):
+{
+ "strengths": ["...", "...", "..."],
+ "improvements": ["...", "...", "..."],
+ "overall_assessment": "...",
+ "recommendations": ["...", "..."]
+}
+```
+
+**Database Schema:**
+```
+interview_reports:
+ - id (UUID)
+ - session_id (unique)
+ - scores (JSONB)
+ - feedback (JSONB)
+ - metrics (JSONB)
+ - processing_duration_seconds
+ - created_at
+```
+
+**Inputs:**
+- Session ID
+- All turns
+- Scores
+
+**Outputs:**
+- Complete report (JSON)
+- Stored in database
+
+**TODO:**
+- Create feedback prompt template
+- Implement LLM integration
+- Define report structure
+- Add caching for identical transcripts
+
+---
+
+### Module 11: Historical Trends & Comparison
+
+**Purpose:** Track user progress over time
+
+**Responsibilities:**
+- ✅ Retrieve previous interview scores
+- ✅ Calculate improvement/decline trends
+- ✅ Identify consistent strengths/weaknesses
+- ✅ Generate progress charts data
+
+**Technology Stack:**
+- PostgreSQL aggregations
+- Window functions (SQL)
+
+**Calculations:**
+```
+- Average score change (last 5 interviews)
+- Metric-specific trends (e.g., communication improving)
+- Consistency analysis (score variance)
+- Time between interviews (engagement)
+```
+
+**Inputs:**
+- User ID
+- Current session scores
+
+**Outputs:**
+- Trend data (JSON)
+- Comparison with previous average
+
+**TODO:**
+- Implement trend calculation queries
+- Define minimum interviews for trends (need 2+)
+- Create visualization data format
+
+---
+
+### Module 12: Background Jobs (Celery Workers)
+
+**Purpose:** Async processing for heavy tasks
+
+**Responsibilities:**
+- ✅ Post-interview analysis (fetch media, score, report)
+- ✅ Retention policy enforcement (delete old media)
+- ✅ Session timeout handling
+- ✅ Abandoned session cleanup
+
+**Technology Stack:**
+- Celery (Python task queue)
+- Redis (broker + result backend)
+- Worker processes
+
+**Jobs:**
+
+**1. analyze_interview(session_id)**
+- Fetch all turns
+- Run scoring engine
+- Generate LLM report
+- Calculate trends
+- Update session status → "ready"
+- Emit events
+
+**2. cleanup_expired_media()**
+- Query expired chunks
+- Delete from S3
+- Delete from database
+
+**3. handle_session_timeout(session_id)**
+- Mark session as "abandoned"
+- Partial refund (if applicable)
+- Cleanup resources
+
+**Inputs:**
+- Job-specific (session_id, etc.)
+
+**Outputs:**
+- Task results
+- Updated database records
+
+**TODO:**
+- Setup Celery configuration
+- Implement worker tasks
+- Define retry policies
+- Setup monitoring (Flower)
+
+---
+
+### Module 13: Event Publishing & Integrations
+
+**Purpose:** Share interview results with other services
+
+**Responsibilities:**
+- ✅ Emit events after interview completion
+- ✅ Outbox pattern for reliability
+- ✅ Integration with Dashboard, Courses, Assessment, Roleplay
+
+**Technology Stack:**
+- Outbox table pattern
+- Message queue (RabbitMQ, Kafka, or SQS)
+- Event schemas
+
+**Event Schema:**
+```json
+{
+ "event_type": "interview.completed",
+ "event_version": "1.0",
+ "timestamp": "2026-03-02T15:30:00Z",
+ "user_id": "uuid",
+ "session_id": "uuid",
+ "payload": {
+ "interview_type": "technical",
+ "overall_score": 81,
+ "scores": {...},
+ "skill_gaps": [
+ {
+ "skill_id": "python-async",
+ "proficiency": 65,
+ "target": 80
+ }
+ ],
+ "recommended_courses": ["course-id-1", "course-id-2"]
+ }
+}
+```
+
+**Database Schema:**
+```
+outbox_events:
+ - id (UUID)
+ - event_type
+ - payload (JSONB)
+ - published (boolean)
+ - published_at
+ - created_at
+```
+
+**Inputs:**
+- Session results
+
+**Outputs:**
+- Published events
+
+**TODO:**
+- Define event schemas
+- Implement outbox pattern
+- Setup message queue
+- Create consumer contracts
+
+---
+
+### Module 14: Compliance & Audit
+
+**Purpose:** GDPR/CCPA compliance and security auditing
+
+**Responsibilities:**
+- ✅ Audit log for sensitive operations
+- ✅ Data deletion workflow
+- ✅ Retention policy enforcement
+- ✅ Access logging
+
+**Technology Stack:**
+- PostgreSQL (audit log)
+- S3 lifecycle policies
+- Scheduled jobs
+
+**Database Schema:**
+```
+audit_logs:
+ - id (UUID)
+ - user_id
+ - action (viewed_report, deleted_session, etc.)
+ - resource_id (session_id, etc.)
+ - ip_address
+ - user_agent
+ - created_at
+```
+
+**Operations to Audit:**
+- Session creation
+- Report viewing
+- Media access
+- Session deletion
+- Admin actions
+
+**TODO:**
+- Implement audit logging middleware
+- Create deletion API
+- Setup retention jobs
+- Define retention periods per market
+
+---
+
+## 🌐 CLIENT-SIDE: What Goes on Client
+
+### Core Principle
+**Client = Smart media processor that handles all recording, encoding, and speech processing**
+
+### Client Responsibilities Overview
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ CLIENT SIDE │
+│ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 1. MEDIA CAPTURE │ │
+│ │ • Camera/Microphone recording │ │
+│ │ • Screen capture (for coding) │ │
+│ │ • Device permission management │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 2. MEDIA PROCESSING │ │
+│ │ • Video/audio compression │ │
+│ │ • Chunking (30-second segments) │ │
+│ │ • Format encoding (WebM/VP9/Opus) │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 3. SPEECH PROCESSING │ │
+│ │ • Speech-to-Text (Whisper WASM) │ │
+│ │ • Text-to-Speech (Web Speech API) │ │
+│ │ • Real-time transcription │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 4. AVATAR RENDERING │ │
+│ │ • 2D/3D avatar display │ │
+│ │ • Lip sync (viseme mapping) │ │
+│ │ • Facial expressions │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 5. UPLOAD MANAGEMENT │ │
+│ │ • Direct S3/R2 uploads │ │
+│ │ • Background upload (non-blocking) │ │
+│ │ • Retry logic │ │
+│ │ • Progress tracking │ │
+│ └──────────────────────────────────────────────────────┘ │
+│ ↓ │
+│ ┌──────────────────────────────────────────────────────┐ │
+│ │ 6. USER INTERFACE │ │
+│ │ • Interview flow UI │ │
+│ │ • Real-time feedback │ │
+│ │ • Progress indicators │ │
+│ │ • Error handling │ │
+│ └──────────────────────────────────────────────────────┘ │
+└──────────────────────────────────────────────────────────────┘
+```
+
+---
+
+## 💻 CLIENT MODULES & TECHNOLOGIES
+
+### Module 1: Media Recorder
+
+**Purpose:** Capture video, audio, and screen
+
+**Technology:**
+- **MediaRecorder API** (native browser)
+- **getUserMedia API** (camera/mic access)
+- **getDisplayMedia API** (screen capture)
+
+**Features:**
+- Configure video resolution (1280x720)
+- Audio quality settings (48kHz, echo cancellation)
+- Chunked recording (30-second timeslices)
+- Format: WebM with VP9 video codec and Opus audio codec
+
+**Implementation:**
+```javascript
+navigator.mediaDevices.getUserMedia({
+ video: { width: 1280, height: 720 },
+ audio: { echoCancellation: true, noiseSuppression: true }
+})
+```
+
+**TODO:**
+- Handle device permissions
+- Implement fallback for unsupported browsers
+- Add device selection UI
+
+---
+
+### Module 2: Speech-to-Text (STT)
+
+**Purpose:** Convert speech to text in real-time
+
+**Technology Options:**
+
+**Primary: Whisper.cpp WASM**
+- Local processing (privacy)
+- Model sizes: tiny (40MB), base (140MB)
+- Offline capable
+- High accuracy
+
+**Fallback: Web Speech Recognition API**
+- Native browser API
+- Online only
+- Variable accuracy across browsers
+
+**Decision:** Start with Web Speech API, add Whisper WASM as enhancement
+
+**Features:**
+- Real-time or near-real-time transcription
+- Confidence scores
+- Language detection
+- Punctuation
+
+**TODO:**
+- Integrate Whisper.cpp WASM bindings
+- Implement Web Speech API fallback
+- Add language selection
+- Handle low-confidence results
+
+---
+
+### Module 3: Text-to-Speech (TTS)
+
+**Purpose:** Synthesize avatar voice from text
+
+**Technology Options:**
+
+**Primary: Web Speech Synthesis API**
+- Native browser voices
+- Zero cost
+- Immediate playback
+- Variable quality across platforms
+
+**Premium: Azure Speech SDK (optional)**
+- Consistent quality
+- Neural voices
+- Viseme data (for lip sync)
+- Cost: ~$0.016 per 1K characters
+
+**Features:**
+- Voice selection
+- Rate/pitch/volume control
+- Playback callbacks
+- SSML support (optional)
+
+**TODO:**
+- Implement Web Speech Synthesis
+- Add voice selection UI
+- Optionally integrate Azure SDK for premium users
+- Handle speech interruption
+
+---
+
+### Module 4: Avatar Renderer
+
+**Purpose:** Render AI interviewer with lip sync
+
+**Technology Options:**
+
+**Option 1: Canvas 2D**
+- Simple 2D animated avatar
+- Lightweight
+- Good browser support
+
+**Option 2: WebGL/Three.js**
+- 3D realistic avatar
+- More engaging
+- Higher performance requirements
+
+**Lip Sync Technology:**
+- **Viseme mapping** (phoneme → mouth shape)
+- Sync with TTS timing
+- Facial expressions (optional)
+
+**Features:**
+- Smooth animations
+- Lip sync accuracy
+- Idle animations
+- Expression changes (friendly, thinking, etc.)
+
+**TODO:**
+- Choose 2D vs 3D approach
+- Design/source avatar assets
+- Implement viseme mapping
+- Add facial expressions
+
+---
+
+### Module 5: Upload Manager
+
+**Purpose:** Upload media chunks to S3/R2 via pre-signed URLs
+
+**Technology:**
+- **Fetch API** (native)
+- Chunked uploads
+- Background processing
+
+**Features:**
+- Direct PUT to pre-signed URLs (no server proxy)
+- Progress tracking per chunk
+- Retry logic (exponential backoff)
+- Queue management (upload in order)
+- Handle URL expiry (refresh from server)
+
+**Flow:**
+```
+1. Receive pre-signed URL from server
+2. Chunk ready → PUT request to URL
+3. Track upload progress
+4. On success: notify server, mark chunk complete
+5. On failure: retry 3 times, then report error
+6. If URL expired: request new URL, retry
+```
+
+**TODO:**
+- Implement upload queue
+- Add retry logic with exponential backoff
+- Create progress indicator UI
+- Handle network failures gracefully
+
+---
+
+### Module 6: State Management
+
+**Purpose:** Manage client-side interview state
+
+**Technology:**
+- React Context API (if React)
+- Zustand / Redux (for complex state)
+- LocalStorage (persistence)
+
+**State to Manage:**
+- Current session config
+- Current question
+- Recording status
+- Upload progress
+- User responses (transcripts)
+- Timer/progress
+- Connection status
+
+**TODO:**
+- Define state structure
+- Implement state management
+- Add state persistence (survive page refresh)
+- Handle state sync with server
+
+---
+
+### Module 7: WebSocket Handler
+
+**Purpose:** Real-time state sync with server
+
+**Technology:**
+- Native WebSocket API
+- Reconnection logic
+
+**Events from Server:**
+- Next question
+- Time warnings
+- Session end
+- Error messages
+
+**Events to Server:**
+- Ready for next question
+- Recording status updates
+- Pause requests
+
+**TODO:**
+- Implement WebSocket connection
+- Add reconnection logic
+- Handle connection failures
+- Define message protocols
+
+---
+
+### Module 8: User Interface Components
+
+**Purpose:** Interview experience UI
+
+**Technology:**
+- React / Vue / Svelte (framework choice)
+- Tailwind CSS / Material-UI (styling)
+- Responsive design
+
+**Components:**
+- Interview setup screen
+- Question display
+- Avatar display
+- Recording indicator
+- Timer/progress bar
+- Answer input (transcript display)
+- Navigation controls
+- Results display
+
+**TODO:**
+- Design UI mockups
+- Implement component library
+- Add responsive layouts
+- Create loading states
+- Add error states
+
+---
+
+### Module 9: Optional - MediaPipe Integration
+
+**Purpose:** Extract facial and body landmarks (client-side CV)
+
+**Technology:**
+- **MediaPipe Face Mesh** (468 landmarks)
+- **MediaPipe Pose** (33 landmarks)
+- WASM-based (runs in browser)
+
+**Use Case:**
+- Extract features locally
+- Send compact feature data (not raw frames)
+- Privacy-friendly
+- Reduces upload bandwidth
+
+**Features:**
+- Real-time landmark detection
+- Feature extraction (eye contact, posture)
+- Export compact JSON (not video frames)
+
+**TODO:**
+- Evaluate if needed for v1
+- Integrate MediaPipe libraries
+- Define features to extract
+- Create feature export format
+
+---
+
+## 📊 Data Flow Summary
+
+### During Interview
+
+```
+CLIENT SERVER
+ │ │
+ │ 1. POST /configure │
+ │ ───────────────────────────> │ Generate questions
+ │ <─────────────────────────── │ Return config + URLs
+ │ │
+ │ 2. Record user response │
+ │ (local processing) │
+ │ │
+ │ 3. PUT chunk to S3 │
+ │ ──────────────────────> [S3] │ (direct, no server)
+ │ │
+ │ 4. POST /turn (transcript) │
+ │ ───────────────────────────> │ Store transcript
+ │ <─────────────────────────── │ Return next question
+ │ │
+ │ 5. Repeat steps 2-4 │
+ │ │
+ │ 6. POST /complete │
+ │ ───────────────────────────> │ Queue analysis job
+ │ <─────────────────────────── │ Return job ID
+ │ │
+ │ 7. Poll GET /report │
+ │ ───────────────────────────> │
+ │ <─────────────────────────── │ Return report (when ready)
+```
+
+### Media Never Touches Server
+
+```
+CLIENT S3/R2 SERVER
+ │ │ │
+ │ Record & Encode │ │
+ │ ─────────────> │ │
+ │ │ │
+ │ Upload (PUT) │ │
+ │ ──────────────────────>│ │
+ │ │ │
+ │ (text only) POST /turn │ │
+ │ ─────────────────────────────────────────> │
+ │ │ │
+ │ │ Fetch for analysis │
+ │ │ <───────────────── │
+```
+
+---
+
+## 🔧 Technology Stack Summary
+
+### Server Stack
+
+| Layer | Technology | Purpose |
+|-------|------------|---------|
+| **Language** | Python 3.11+ | Backend logic |
+| **Framework** | FastAPI | REST API |
+| **Package Manager** | UV | Fast dependency management |
+| **Database** | PostgreSQL 15+ | Data persistence |
+| **Cache** | Redis | Session cache, queue broker |
+| **Storage** | S3 / Cloudflare R2 | Media storage |
+| **Queue** | Celery + Redis | Background jobs |
+| **LLM** | Claude 3.5 / GPT-4 | AI logic |
+| **Auth** | JWT | Stateless authentication |
+| **Deployment** | Docker + ECS/EC2 | Containerized deployment |
+
+### Client Stack
+
+| Layer | Technology | Purpose |
+|-------|------------|---------|
+| **Language** | JavaScript/TypeScript | Frontend logic |
+| **Framework** | React / Vue / Svelte | UI framework |
+| **Recording** | MediaRecorder API | Native recording |
+| **STT** | Whisper.cpp WASM / Web Speech | Speech-to-text |
+| **TTS** | Web Speech Synthesis / Azure | Text-to-speech |
+| **Avatar** | Canvas 2D / Three.js | Avatar rendering |
+| **Upload** | Fetch API | Direct S3 uploads |
+| **State** | Context / Zustand | State management |
+| **Styling** | Tailwind CSS | UI styling |
+| **Build** | Vite / Webpack | Bundling |
+
+---
+
+## ✅ Decision Checklist
+
+### Server Decisions Needed:
+- [ ] LLM provider: Claude vs GPT-4?
+- [ ] Storage: S3 vs Cloudflare R2?
+- [ ] Deployment: AWS vs GCP vs Azure?
+- [ ] Auth: Internal JWT or external service?
+- [ ] Database: Self-hosted PostgreSQL or managed (RDS)?
+
+### Client Decisions Needed:
+- [ ] Framework: React vs Vue vs Svelte?
+- [ ] STT: Start with Web Speech or go straight to Whisper WASM?
+- [ ] TTS: Web Speech only or add Azure premium option?
+- [ ] Avatar: 2D simple or 3D realistic?
+- [ ] MediaPipe: Include in v1 or later?
+
+---
+
+## 📋 Implementation Priority
+
+### Phase 1 (Week 1): Foundation
+**Server:**
+- [ ] Basic API structure
+- [ ] JWT validation (TODO: design)
+- [ ] Database setup
+- [ ] Session management
+- [ ] Pre-signed URL generation
+
+**Client:**
+- [ ] Media recording
+- [ ] Basic UI
+- [ ] Upload manager
+- [ ] Web Speech API integration
+
+### Phase 2 (Week 2): Intelligence
+**Server:**
+- [ ] LLM question generation
+- [ ] Follow-up logic
+- [ ] Celery worker setup
+- [ ] Scoring algorithms (basic)
+
+**Client:**
+- [ ] Avatar rendering
+- [ ] TTS integration
+- [ ] WebSocket connection
+- [ ] State management
+
+### Phase 3 (Week 3): Polish
+**Server:**
+- [ ] Complete scoring (7 metrics)
+- [ ] Report generation
+- [ ] Historical trends
+- [ ] Event publishing
+- [ ] Compliance features
+
+**Client:**
+- [ ] UI polish
+- [ ] Error handling
+- [ ] Progress indicators
+- [ ] Report display
+- [ ] Offline handling
+
+---
+
+## 🎯 Success Criteria
+
+**Server:**
+- ✅ API latency p95 < 200ms
+- ✅ Can handle 100 concurrent sessions
+- ✅ Analysis completes in < 5 minutes
+- ✅ Zero data loss
+- ✅ GDPR/CCPA compliant
+
+**Client:**
+- ✅ Recording works on Chrome, Firefox, Safari, Edge
+- ✅ STT accuracy > 90%
+- ✅ Upload success rate > 99%
+- ✅ Avatar lip sync smooth (no lag)
+- ✅ Works on 5 Mbps connection
+
+---
+
+## 📝 Notes
+
+1. **Authentication is placeholder**: JWT validation needs to be designed based on your auth system
+2. **Cost optimization**: Client-side processing saves ~70% on server costs
+3. **Privacy**: Media stays client-side or in storage, never processed on server in real-time
+4. **Scalability**: Stateless server design enables horizontal scaling
+5. **Offline capability**: Client can record offline, upload later (future enhancement)
diff --git a/upskilling/extras/upscaling_redundancy_breakdown.md b/upskilling/extras/upscaling_redundancy_breakdown.md
new file mode 100644
index 0000000..b9d964f
--- /dev/null
+++ b/upskilling/extras/upscaling_redundancy_breakdown.md
@@ -0,0 +1,198 @@
+# GrowQR — Upscaling Module — Redundancy vs Unique Work (Interview / Roleplay / Courses / Assessment)
+
+**Purpose:** break down the 4 services in the Upscaling module, identify **redundant modules** we should share/standardize, and clarify **what is unique** per service.
+
+**Inputs reviewed (in `growqr/plans/`):**
+- `interview service plan.md`
+- `Roleplay_OnePager.docx`
+- `Course_OnePager.docx`
+- `Assessment_OnePager.docx`
+
+---
+
+## 1) Upscaling module: services and their primary job
+
+1) **Interview Service**
+- Real-time-ish interview practice, persona-driven Q/A
+- Records user media + optional screen share
+- Outputs 7-metric coaching + historical comparison
+
+2) **Roleplay Service**
+- Avatar-based AI roleplay (video/voice) + optional screen share
+- Heavier focus on avatar, lip-sync, emotional expression
+- Outputs weighted performance scoring + certificates for scenario thresholds
+
+3) **Courses Service**
+- Course catalog + external provider integrations
+- Enrollment/progress tracking + certificates
+- Recommendation engine consumes gaps from other services
+
+4) **Assessment Service**
+- Multi-stakeholder assessment marketplace
+- Upload-first (CSV/JSON/Excel), AI-generated assessments as secondary
+- Psychometric/behavioral data feeds the global recommendation engine
+
+---
+
+## 2) Redundant modules (should be shared or standardized)
+
+### 2.1 Identity / auth verification
+All services require:
+- verify user identity
+- enforce org visibility (marketplace vs private library)
+
+**Recommendation:** standard auth library / gateway policy + shared middleware.
+
+### 2.2 Credits / entitlements
+All services deduct credits:
+- Interview: duration tier → credits
+- Roleplay: per session
+- Courses: per course type
+- Assessment: possibly per attempt / premium
+
+**Recommendation:** one central Credits/Entitlements service or shared library + consistent idempotent “deduct” contract.
+
+### 2.3 Artifact storage + media broker
+Interview/Roleplay generate large artifacts (video/audio/screen). Courses/Assessments generate smaller artifacts (certificates, uploads).
+
+Shared needs:
+- presigned upload/download
+- artifact metadata registry
+- retention policy and deletion
+
+**Recommendation:** shared “Artifact Registry” module/service (even if storage is per-service).
+
+### 2.4 Certificate generation
+Courses, Assessments, Roleplay (and potentially Interview) all generate certificates.
+
+Shared needs:
+- template engine
+- signing/verification
+- storage + download links
+
+**Recommendation:** shared Certificate service/library.
+
+### 2.5 Eventing + outbox pattern
+All services share data with each other and Dashboard.
+
+Shared needs:
+- event schema versioning
+- retries, idempotency
+
+**Recommendation:** standard event format + outbox implementation that every service uses.
+
+### 2.6 Skill taxonomy + skill-gap representation
+Recommendations depend on consistent “skills” and “gaps” representation.
+
+Shared needs:
+- canonical skill IDs
+- mapping metrics → skills
+
+**Recommendation:** define a shared Skill Taxonomy and a `SkillGap` schema used by all services.
+
+### 2.7 Recommendation engine inputs/outputs
+Courses are recommended based on:
+- Interview weaknesses
+- Roleplay weaknesses
+- Assessment topic gaps + psychometrics
+
+Shared needs:
+- consistent “signals” API (what each service emits)
+
+**Recommendation:** a shared “Recommendation Signals” contract:
+- `SignalProduced(service, userId, signalType, payload, timestamp, version)`
+
+### 2.8 Compliance baseline (US/EU/India)
+All services must support:
+- PII minimization
+- retention controls
+- deletion workflows
+- access auditing
+
+**Recommendation:** shared compliance checklist + shared primitives (retention tags, audit log schema).
+
+---
+
+## 3) Unique modules (must be built per service)
+
+### 3.1 Interview Service — unique work
+- persona-driven interview state machine
+- question bank and follow-up generation
+- 7-metric interview-specific scoring weights
+- historical comparison optimized for interview metrics
+
+### 3.2 Roleplay Service — unique work
+- avatar rendering integration strategy (real-time avatar vs pre-rendered video)
+- voice synthesis + lip-sync quality targets (≤100ms target mentioned)
+- scenario configuration and scenario-specific certificate rules
+- roleplay-specific weights (Voice 35%, Facial 25%, Body 20%, Technical 10%, Content 10%)
+
+### 3.3 Courses Service — unique work
+- external provider integrations and progress sync/webhooks
+- catalog ingestion + caching strategy
+- enrollment state machine (in progress/completed/abandoned)
+
+### 3.4 Assessment Service — unique work
+- multi-stakeholder creator workflows
+- bulk upload parsing + validation
+- flexible data collection schema per creator
+- timer/navigation engine
+- creator analytics dashboards + exports
+- psychometric/behavioral modeling signals
+
+---
+
+## 4) Where client-side vs server-side makes sense (cross-service)
+
+### For Interview + Roleplay (real-time experiences)
+**Client-side is optimal for:**
+- recording + encoding
+- optional local STT (for fast turn-taking)
+- avatar rendering + lip sync
+- optional MediaPipe feature extraction
+
+**Server-side is optimal for:**
+- session orchestration + credits
+- question generation
+- post-session scoring + report
+- artifacts registry + retention/audit
+
+### For Courses + Assessment
+Mostly server-side:
+- workflows are CRUD + marketplace + sync
+- no need for client-side heavy ML
+
+---
+
+## 5) Recommended shared platform building blocks (minimal)
+
+If we want “shared but not over-engineered”, build these as either shared libraries or small internal services:
+
+1) **Credits/Entitlements** (idempotent deduction API)
+2) **Artifact Registry** (metadata + presigned URL patterns)
+3) **Certificates** (template + signing)
+4) **Event schemas + outbox** (reliable cross-service sharing)
+5) **Skill taxonomy + SkillGap schema** (powering recommendations)
+6) **Compliance primitives** (retention tags, deletion requests, audit events)
+
+---
+
+## 6) Quick risk notes
+
+- If Interview and Roleplay choose different avatar/TTS strategies, they can still share:
+ - the session + artifacts + scoring/report patterns
+ - the eventing + skill gap outputs
+
+- If we attempt server-side real-time audio/video streaming early, we significantly increase:
+ - cost
+ - compliance surface area
+ - time-to-ship
+
+---
+
+## 7) Next planning step
+
+Decide and document:
+1) The **shared contracts** (Credits, Artifacts, Events, SkillGap)
+2) The **client/server contract** for Interview + Roleplay (what must client compute vs server)
+3) The **retention + deletion policy** for recordings across markets
diff --git a/upskilling/prd/Assessment Service.docx.md b/upskilling/prd/Assessment Service.docx.md
new file mode 100644
index 0000000..de8c950
--- /dev/null
+++ b/upskilling/prd/Assessment Service.docx.md
@@ -0,0 +1,322 @@
+**GrowQR**
+
+**ASSESSMENT SERVICE**
+
+Business Requirements Document • v2.0 • March 2026
+
+| Upskilling Module • Microservice Specification Integrates with: Roleplay • Interview • Course • Pathways • Dashboard |
+| :---: |
+
+
+
+
+
+| Document Title | Assessment Service — Business Requirements Document |
+| :---- | :---- |
+
+
+
+| Service Type | Standalone Microservice (Part of Upskilling Services) |
+| :---- | :---- |
+
+
+
+| Version | |
+| :---- | :---- |
+
+
+
+| Integration | Shares data with Roleplay, Interview, Course services \+ Pathways \+ Dashboard |
+| :---- | :---- |
+
+
+
+| Third-Party LMS | Moodle, Thinkific (no proprietary LMS built) |
+| :---- | :---- |
+
+
+
+
+
+| 1\. SERVICE OVERVIEW |
+| :---- |
+
+
+
+The Assessment Service provides AI-generated, role-specific skill assessments structured around a three-box engine: Input, Processing, and Output. Assessments are micro-format (3–4 minutes), designed for engagement and measurability. The platform integrates with third-party LMS platforms (Moodle, Thinkific) and does not build a proprietary LMS.
+
+
+
+## **1.1 Three-Box Engine Architecture**
+
+All assessments flow through a standardized three-stage engine: ![][image1]
+
+
+
+## **1.2 Core Features**
+
+• Three-box engine: Input (corporate/institutes/LLM) → Processing (intent \+ tier) → Output (standardized report)
+
+• Micro-assessments: 3–4 minutes per session for high engagement and completion
+
+• AI-generated role-specific questions (21 per assessment); GenAI rephrases for binary clarity
+
+• Difficulty levels: Easy, Medium, Hard (adaptive or fixed per question)
+
+• Multiple choice format (4 options per question), timed with countdown timer
+
+• STAR schema evaluation for situational/behavioral questions
+
+• Certificates awarded for passing score (70%+) on eligible assessments
+
+• Fallback pre-built question bank when AI generation fails
+
+• Third-party LMS integration: Moodle, Thinkific (no proprietary LMS)
+
+• Recruiter and university posting capability via corporate input channel
+
+
+
+## **1.3 Value Proposition**
+
+Small, focused assessments help college students and professionals measure fit for roles, motivation, culture alignment, and company values. The question bank concept enables HR integration and recruiter-led workflows. Assessments directly feed into Q-Score improvements and job opportunity matching.
+
+
+
+
+
+
+
+| 2\. FUNCTIONS |
+| :---- |
+
+
+
+## **FUNCTION 1: Assessment Generation**
+
+**2.1.1 Generation Sources**
+
+Assessments are generated from two input channels:
+
+1\. Corporate Input: Recruiters or universities post role-specific assessments directly to the platform. Questions are pre-authored and stored in the question bank.
+
+2\. LLM Input: AI generates 21 questions tailored to the user’s role, covering technical skills, behavioral scenarios, and domain knowledge. GenAI rephrases questions for binary clarity where needed.
+
+
+
+**2.1.2 Assessment Design Principles**
+
+• Micro-format: Each assessment completes in 3–4 minutes to maximize engagement
+
+• Questions must be clear and binary where possible; GenAI rephrases ambiguous questions
+
+• Situational questions evaluated using STAR schema (Situation, Task, Action, Reaction)
+
+• Background verification: Situational responses cross-referenced against user profile data
+
+• Communication style evaluated alongside content accuracy
+
+• Open-ended questions are not used — monitoring and scoring reliability is insufficient
+
+
+
+**2.1.3 Data Requirements**
+
+| Field | Description |
+| :---- | :---- |
+| Assessment ID | Unique identifier |
+| User ID | Who is taking the assessment |
+| Role / Title | Job role (e.g., Python Backend Developer) |
+| Input Source | Corporate (recruiter-posted) / LLM (AI-generated) / Hybrid |
+| Question Bank | Array of 21 question objects |
+| Question Object | Question text, 4 options, correct answer, difficulty, topic, STAR tag |
+| Time Limit | Total time allowed (e.g., 20 minutes) |
+| Tier | User subscription tier — determines question depth and volume |
+| Started At | Timestamp when assessment started |
+| Status | Generating / Ready / In Progress / Completed |
+
+
+
+**2.1.4 States**
+
+| State | Backend Response |
+| :---- | :---- |
+| Generating | Show: 'Generating Assessment… Our AI is crafting unique questions for this role.' (10–15 seconds) |
+| Ready | Questions generated; return assessment ID \+ start link |
+| AI Error | AI generation failed → Use fallback question bank; flag question source in UI |
+| Invalid Role | Role not recognized → Ask user to specify or use generic assessment |
+
+
+
+
+
+## **FUNCTION 2: Taking the Assessment**
+
+**2.2.1 Assessment Flow**
+
+• User starts assessment → Timer begins (countdown: 19:59, 19:58…)
+
+• Questions displayed one at a time: 'Question 3 of 21'
+
+• User selects one of 4 multiple choice options (radio buttons)
+
+• User can navigate: Previous / Next Question
+
+• Difficulty badge shown per question: 'Medium Difficulty'
+
+• STAR-tagged questions display scenario context before answer options
+
+• User can submit early OR timer expires → Auto-submit
+
+
+
+**2.2.2 Measurement Framework**
+
+For situational / behavioral questions, the platform applies the STAR schema:
+
+| Component | Stands For | How Evaluated |
+| :---- | :---- | :---- |
+| S | Situation | Cross-referenced against user’s profile and background data |
+| T | Task | Verified for role-relevance and complexity level |
+| A | Action | Evaluated for decision quality and communication style |
+| R | Reaction | Assessed for outcome awareness and self-reflection |
+
+
+
+**2.2.3 Data Captured**
+
+• User answers: Array of selected options per question
+
+• Time per question: Seconds spent on each question
+
+• Navigation pattern: Sequence of question views (for analysis)
+
+• Submission type: Early submit / Timer expired
+
+• Completion time: Total time taken
+
+• Score: Number correct / 21 (percentage)
+
+
+
+
+
+## **FUNCTION 3: Results & Analysis**
+
+**2.3.1 Standardised Output Report**
+
+Every completed assessment produces a well-defined, standardised report. Outputs feed into Q-Score calculations and job opportunity matching pipelines.
+
+• Overall score: Percentage (e.g., 85%)
+
+• Score by topic/category (e.g., 'Python Basics: 90%, Backend: 75%')
+
+• STAR schema breakdown for behavioral questions
+
+• Communication style rating (derived from scenario responses)
+
+• Correct vs. incorrect breakdown with explanations
+
+• Time spent per question
+
+• Comparison to average user in same role
+
+• Recommended focus areas (topics with low scores)
+
+• Q-Score contribution: Which Q-Scores are updated based on results
+
+• Job opportunity flag: Whether results unlock specific job matches
+
+
+
+**2.3.2 Certificate Generation**
+
+• Certificate issued when: Score \>= 70% AND assessment is certificate-eligible
+
+• Practice / diagnostic assessments are not certificate-eligible
+
+• Certificate includes: User name, Assessment title, Score, Date, Certificate ID
+
+
+
+
+
+## **FUNCTION 4: Third-Party LMS Integration**
+
+GrowQR will not build a proprietary LMS. All courseware and assessment delivery integrates with established third-party platforms.
+
+
+
+| Platform | Integration Type | Use Case |
+| :---- | :---- | :---- |
+| Moodle | API / Webhook | Open-source LMS for institutional and corporate assessment delivery |
+| Thinkific | API / Embed | Course and assessment hosting for third-party content creators |
+| Internal Fallback | Native | GrowQR question bank used when no external source is available |
+
+
+
+
+
+| 3\. DATA SHARING WITH OTHER SERVICES |
+| :---- |
+
+
+
+| Target Service | Data Shared | Purpose |
+| :---- | :---- | :---- |
+| Course Service | Low-scoring topics, skill gaps identified | Recommend courses to address weak areas |
+| Interview Service | Technical knowledge gaps, topics scored low | Tailor interview questions to validate weak areas |
+| Roleplay Service | Behavioural/scenario performance, weak competencies | Suggest roleplay scenarios for practice |
+| Pathways Service | Assessment completion, Q-Score deltas, role fit scores | Update weekly cycle priorities and pathway recommendations |
+| Dashboard Service | Assessment count, scores, certificates earned, focus areas | Update Q-Score, show progress, display achievements |
+| Job Matchmaking | Role fit score, Q-Score contributions, skill signals | Surface relevant job opportunities post-assessment |
+
+
+
+
+
+| 4\. TECHNICAL REQUIREMENTS |
+| :---- |
+
+
+
+## **4.1 Performance Requirements**
+
+| Operation | Target SLA |
+| :---- | :---- |
+| Question generation (21 questions) | \< 15 seconds |
+| Assessment start (after generation) | \< 1 second |
+| Question navigation | \< 200ms |
+| Score calculation | \< 3 seconds after submission |
+| Report generation | \< 5 seconds |
+| Certificate generation (if eligible) | \< 3 seconds |
+| LMS sync (Moodle / Thinkific) | \< 10 seconds |
+
+
+
+
+
+| 5\. ACCEPTANCE CRITERIA |
+| :---- |
+
+
+
+| \# | Must Pass | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Three-box engine operates correctly: Input (corporate/LLM), Processing (intent \+ tier), Output (standardised report) | \[ \] PASS \[ \] FAIL |
+| **2** | AI generates 21 questions within 15s. Fallback question bank activates on AI failure. | \[ \] PASS \[ \] FAIL |
+| **3** | Micro-assessment format completes within 3–4 minutes for standard question sets. | \[ \] PASS \[ \] FAIL |
+| **4** | GenAI rephrasing produces binary, clear questions. No open-ended questions in scored flow. | \[ \] PASS \[ \] FAIL |
+| **5** | STAR schema correctly applied to situational questions. Background cross-reference works. | \[ \] PASS \[ \] FAIL |
+| **6** | Timer counts down correctly. Navigation (Prev/Next) works. Auto-submit on timeout. | \[ \] PASS \[ \] FAIL |
+| **7** | Score calculated correctly. Topic breakdown accurate. Comparison to average shown. | \[ \] PASS \[ \] FAIL |
+| **8** | Standardised report generated with Q-Score contributions and job opportunity flags. | \[ \] PASS \[ \] FAIL |
+| **9** | Certificates generated for eligible assessments with score \>= 70%. Download works. | \[ \] PASS \[ \] FAIL |
+| **10** | Moodle and Thinkific integrations functional for corporate/institutional assessment delivery. | \[ \] PASS \[ \] FAIL |
+| **11** | Skill gaps and Q-Score signals shared with all connected services correctly. | \[ \] PASS \[ \] FAIL |
+| **12** | Recruiter and university posting workflow functional via corporate input channel. | \[ \] PASS \[ \] FAIL |
+
+
+
+
+[image1]:
\ No newline at end of file
diff --git a/upskilling/prd/Courses.docx.md b/upskilling/prd/Courses.docx.md
new file mode 100644
index 0000000..d7a42b7
--- /dev/null
+++ b/upskilling/prd/Courses.docx.md
@@ -0,0 +1,335 @@
+**GrowQR**
+
+**COURSE SERVICE**
+
+Business Requirements Document • v2.0 • March 2026
+
+| Upskilling Module • Microservice Specification Three-Phase Courseware Strategy • No Proprietary LMS |
+| :---: |
+
+
+
+
+
+| Document Title | Course Service — Business Requirements Document |
+| :---- | :---- |
+
+
+
+| Service Type | Standalone Microservice (Part of Upskilling Services) |
+| :---- | :---- |
+
+
+
+| Version | |
+| :---- | :---- |
+
+
+
+| Integration | Shares data with Roleplay, Interview, Assessment, Pathways \+ Dashboard |
+| :---- | :---- |
+
+
+
+| Courseware Strategy | Three-phase: External Index → Third-Party Creator → GenAI IP Generation |
+| :---- | :---- |
+
+
+
+| LMS Approach | No proprietary LMS. Integrates with Coursera, Moodle, Thinkific and others |
+| :---- | :---- |
+
+
+
+
+
+| 1\. SERVICE OVERVIEW |
+| :---- |
+
+
+
+The Course Service provides a curated learning library with external provider integrations and community-created content. Users enroll using credits, track progress, and earn certificates upon completion. GrowQR does not build a proprietary LMS — all courseware delivery relies on third-party platforms and a three-phase strategy to progressively own intellectual property.
+
+
+
+## **1.1 Core Features**
+
+• Three-phase courseware strategy: External mapping → Third-party creation → GenAI IP generation
+
+• No proprietary LMS: Integration with Coursera, Moodle, Thinkific, LinkedIn Learning
+
+• Course catalog with external provider integrations and community scenarios
+
+• AI-powered recommendations based on skill gaps from Assessment, Interview, Roleplay, Q-Score
+
+• Credit-based enrolment tracking: In Progress / Completed / Abandoned
+
+• Certificate generation upon course completion (eligible courses only)
+
+• Persona-driven content mapping across 20–25 unique user profiles, industries, and life stages
+
+
+
+
+
+
+
+| 2\. THREE-PHASE COURSEWARE STRATEGY |
+| :---- |
+
+
+
+The courseware strategy follows a deliberate, staged approach that builds toward platform intellectual property (IP) through GenAI-generated, persona-driven content. Each phase unlocks the next.
+
+
+
+| PHASE 1: External Mapping & Indexing |
+| :---- |
+| • Map user personas to purchased or indexed external courses (e.g., Coursera, LinkedIn Learning, Udemy) |
+| • Users browse a curated catalog; GrowQR surfaces the most relevant content per role, industry, and Q-Score gap |
+| • Course metadata indexed: title, provider, duration, difficulty, skills covered, rating, price |
+| • AI recommendation engine selects top matches from external catalog based on skill gap analysis |
+| • Revenue model: Affiliate commissions from enrolled courses via provider APIs |
+| • No content creation required — pure aggregation and curation layer |
+
+
+
+| PHASE 2: Third-Party Creator Platform |
+| :---- |
+| • Platform opens to third parties: Heads of Departments (HODs), corporates, and subject matter experts |
+| • Creators bundle and publish their own content within the GrowQR platform |
+| • Content types: Video modules, guided projects, assessments, case studies |
+| • GrowQR provides creator tools, hosting (via Moodle / Thinkific integration), and distribution |
+| • Revenue model: Revenue share with creators; premium access tiers for corporate bundles |
+| • Quality control: Community ratings, completion rates, and AI-driven content scoring |
+| • Enables industry-specific content that external platforms do not cover |
+
+
+
+| PHASE 3: GenAI IP Generation (Intellectual Property) |
+| :---- |
+| • Full-blown personalised course generation using Generative AI |
+| • Content defined by 20–25 unique user personas, mapped to industry, role, and life stage |
+| • Each persona receives a structured, distinct learning path — not just filtered external content |
+| • GrowQR owns this content as platform IP: structured curricula, assessments, and roleplay scenarios |
+| • Life stage mapping: College student → First job → Career pivot → Leadership → Entrepreneurship |
+| • Industry mapping: Tech, Finance, Healthcare, Marketing, Operations, Creative, etc. |
+| • GenAI generates course scripts, quizzes, scenario prompts, and practice exercises on demand |
+| • This phase creates the long-term competitive moat and differentiated platform identity |
+
+
+
+
+
+
+
+| 3\. FUNCTIONS |
+| :---- |
+
+
+
+## **FUNCTION 1: Course Discovery & Catalog**
+
+**3.1.1 Course Sources (by Phase)**
+
+| Phase | Source | Description |
+| :---- | :---- | :---- |
+| Phase 1 | Coursera, LinkedIn Learning, Udemy, edX | Externally indexed courses mapped to user personas and Q-Score gaps |
+| Phase 1 | Internal Fallback / Question Bank | GrowQR-curated content when external APIs are unavailable |
+| Phase 2 | HODs, Corporates, Subject Matter Experts | Third-party content created and hosted via Moodle / Thinkific |
+| Phase 2 | Community Scenarios | User-generated learning content, peer-reviewed and rated |
+| Phase 3 | GenAI Generated (GrowQR IP) | Fully personalised courses generated from 20–25 user personas by GenAI |
+
+
+
+**3.1.2 Persona Mapping (Phase 3 Foundation)**
+
+Course content is structured around 20–25 distinct user personas. Each persona is defined by the intersection of:
+
+• Role category (e.g., Software Engineer, Product Manager, Sales Leader)
+
+• Industry (e.g., FinTech, Healthcare, E-commerce, SaaS)
+
+• Life stage (e.g., College student, Early career, Career pivot, Leadership track, Entrepreneur)
+
+• Q-Score profile (which of the 25 Q-Scores are high, low, or developing)
+
+• Motivation archetype (Technical Specialist, Strategic Leader, Creative Innovator, etc.)
+
+
+
+**3.1.3 Data Requirements**
+
+| Field | Description |
+| :---- | :---- |
+| Course ID | Unique identifier |
+| Title | Course name |
+| Provider | Coursera, LinkedIn Learning, Moodle, Thinkific, GrowQR IP, etc. |
+| Phase | 1 (External) / 2 (Third-Party) / 3 (GenAI IP) |
+| Type | Full Course / Guided Project / Micro-module |
+| Persona Tags | Array of persona IDs this course maps to |
+| Q-Score Tags | Which Q-Scores this course develops |
+| Life Stage | College / Early Career / Pivot / Leadership / Entrepreneur |
+| Duration | Estimated time to complete |
+| Difficulty | Beginner / Intermediate / Advanced |
+| Certificate Available | Boolean — awards certificate on completion? |
+| Credit Cost | Free (1 credit) / Guided Project (2 credits) / Full Course (3 credits) |
+
+
+
+
+
+## **FUNCTION 2: Course Enrolment**
+
+**3.2.1 Enrolment Flow**
+
+1\. User selects course → System checks: credits available, not already enrolled
+
+2\. Credit deducted based on course type
+
+3\. Enrolment record created: User ID, Course ID, Start date, Phase, Status (In Progress)
+
+4\. External courses: Redirect to provider platform with tracking link
+
+5\. Phase 3 / Internal courses: Delivered natively within GrowQR
+
+
+
+**3.2.2 Credit Costs**
+
+• Free courses: 1 credit to enrol
+
+• Guided Projects: 2 credits
+
+• Full Courses: 3 credits
+
+• GenAI IP courses (Phase 3): Credit cost TBD based on persona depth
+
+
+
+
+
+## **FUNCTION 3: Progress Tracking & Certificates**
+
+• Track enrolment status: In Progress / Completed / Abandoned
+
+• External courses (Phase 1): Webhook from provider OR periodic sync
+
+• Third-party courses (Phase 2): Progress tracked via Moodle / Thinkific integration
+
+• GenAI IP courses (Phase 3): Module-level completion tracked natively
+
+• Certificate issued when: Course completed AND Certificate Available \= true
+
+• Certificate includes: User name, Course title, Provider/Phase, Completion date, Certificate ID
+
+
+
+
+
+## **FUNCTION 4: AI-Powered Recommendations**
+
+**3.4.1 Recommendation Logic**
+
+• Analyse data from Assessment, Interview, and Roleplay services
+
+• Identify Q-Score gaps and map to relevant course tags
+
+• Cross-reference user persona profile (role, industry, life stage, archetype)
+
+• Prioritise: Highest-rated courses, best persona match, free courses first
+
+• Phase 3 courses prioritised for users with established Q-Score histories
+
+
+
+**3.4.2 Data Inputs**
+
+• Assessment results: Low-scoring topics and Q-Score contributions
+
+• Interview feedback: Weak areas identified
+
+• Roleplay performance: Scenarios user struggles with
+
+• User profile: Career goals, current role, life stage, archetype
+
+• Pathway data: Current week in cycle and progression phase (Learn vs. Apply ratio)
+
+
+
+
+
+| 4\. DATA SHARING WITH OTHER SERVICES |
+| :---- |
+
+
+
+| Target Service | Data Shared | Purpose |
+| :---- | :---- | :---- |
+| Assessment Service | Courses completed, topics learned | Re-test user on completed course topics to show improvement |
+| Interview Service | Course completion, skills learned | Tailor interview questions to validate learning |
+| Roleplay Service | Course completion, skills practiced | Suggest roleplay scenarios for learned skills |
+| Pathways Service | Enrolment count, completed courses, Q-Score signals | Adjust weekly cycle priorities and learning/apply ratio |
+| Dashboard Service | Enrolment count, completed courses, certificates earned | Update Q-Score, display achievements and progress |
+| Job Matchmaking | Skills learned, certifications, course completion signals | Improve opportunity match quality and relevance |
+
+
+
+
+
+| 5\. TECHNICAL REQUIREMENTS |
+| :---- |
+
+
+
+## **5.1 External API Integrations**
+
+| Provider | Phase | Integration Method |
+| :---- | :---- | :---- |
+| Coursera | Phase 1 | Coursera Catalog API \+ affiliate tracking |
+| LinkedIn Learning | Phase 1 | LinkedIn Learning API |
+| Udemy | Phase 1 | Udemy Affiliate API |
+| edX | Phase 1 | edX API |
+| Moodle | Phase 2 | Moodle REST API \+ Webhook for completion tracking |
+| Thinkific | Phase 2 | Thinkific API \+ Embed for third-party creator content |
+| GrowQR GenAI | Phase 3 | Internal LLM pipeline — on-demand course generation |
+
+
+
+## **5.2 Performance Requirements**
+
+| Operation | Target SLA |
+| :---- | :---- |
+| Course catalog load | \< 2 seconds |
+| Enrolment processing | \< 1 second (after credit check) |
+| AI course recommendation | \< 2 seconds |
+| Certificate generation | \< 3 seconds after completion |
+| External provider sync (Phase 1\) | \< 5 seconds |
+| Moodle / Thinkific sync (Phase 2\) | \< 10 seconds |
+| GenAI course generation (Phase 3\) | \< 30 seconds for full micro-module |
+
+
+
+
+
+| 6\. ACCEPTANCE CRITERIA |
+| :---- |
+
+
+
+| \# | Must Pass | Pass / Fail |
+| :---- | :---- | :---- |
+| **1** | Phase 1: All courses load from external APIs (Coursera, Udemy, LinkedIn Learning). Filters and persona mapping work. | \[ \] PASS \[ \] FAIL |
+| **2** | Phase 2: Moodle and Thinkific integrations functional. Third-party creators can publish and bundle content. | \[ \] PASS \[ \] FAIL |
+| **3** | Phase 3: GenAI generates structured micro-courses for at least 5 validated personas. Content is unique and role-specific. | \[ \] PASS \[ \] FAIL |
+| **4** | Credits deducted correctly on enrolment. Enrolment record created. External redirect works. | \[ \] PASS \[ \] FAIL |
+| **5** | Progress status updates correctly for all three phases. External sync works or shows last known state. | \[ \] PASS \[ \] FAIL |
+| **6** | Certificates generated for eligible completed courses. Download link works. | \[ \] PASS \[ \] FAIL |
+| **7** | AI recommends relevant courses based on Q-Score gaps, persona profile, and pathway cycle phase. | \[ \] PASS \[ \] FAIL |
+| **8** | Completion data and Q-Score signals shared with all connected services. Dashboard receives course count. | \[ \] PASS \[ \] FAIL |
+| **9** | Persona mapping covers minimum 20 distinct profiles across role, industry, and life stage dimensions. | \[ \] PASS \[ \] FAIL |
+| **10** | Pathway integration: Course recommendations align with current week’s learn/apply ratio in the weekly cycle. | \[ \] PASS \[ \] FAIL |
+
+
+
+
\ No newline at end of file
diff --git a/upskilling/prd/Interview_OnePager.docx.md b/upskilling/prd/Interview_OnePager.docx.md
new file mode 100644
index 0000000..b21a75a
--- /dev/null
+++ b/upskilling/prd/Interview_OnePager.docx.md
@@ -0,0 +1,76 @@
+
+
+| GrowQR Interview Service — One-PagerAvatar-Based AI Interviewers \+ Video/Voice \+ Screen Share | v3 | INTERVIEW |
+| :---- | :---: |
+
+| PURPOSE |
+| ----- |
+| AI-powered mock interviews with 4 avatar-based interviewers (Payal, Emma, John, Kapil) that speak using real-time voice synthesis. Users recorded via video/audio and can share screen for coding tests/technical demos. Comprehensive analysis across 6 metrics (Intro, Facial Expression, Body Language, Language, Voice including filler word count, Outro) \+ Technical Quality (lighting, framing, background, audio). Historical comparison tracks improvement over time. |
+
+| CORE FEATURES | |
+| :---: | :---- |
+| **1** | 4 AI Interviewer Avatars: Payal (warm, friendly), Emma (professional, structured), John (authoritative, challenging), Kapil (casual, conversational) \- each with distinct voice |
+| **2** | Real-Time Voice Synthesis: AI interviewers SPEAK all questions with personality-matched voices and natural intonation |
+| **3** | Interview Types: Warm Up (Non-technical), Coding (Programming), Role-Related (Technical), Behavioral (HR) |
+| **4** | Duration Tiers: 5 mins (1 credit), 15 mins (2 credits \- Premium), 30 mins (3 credits \- Premium) |
+| **5** | Screen Share: User shares specific window for coding tests, technical demos, presentations |
+| **6** | 7-Metric Analysis: Intro (10%), Facial Expression (20%), Body Language (20%), Language (15%), Voice (20% \- includes filler word count), Outro (10%), Technical Quality (5%) |
+| **7** | Historical Comparison: Track improvement across multiple interviews with trend analysis |
+
+| USER JOURNEY | | | |
+| :---: | ----- | ----- | ----- |
+| **Step** | **User Action** | **System Response** | **Data Captured** |
+| **1** | User configures interview | Validate: type, duration, persona, credits | Config parameters |
+| **2** | User starts interview | Deduct credits, load avatar, request permissions | Session ID, Credits deducted |
+| **3** | Avatar speaks greeting | Voice synthesis: "Hello\! I'm your AI interviewer..." | Timer starts, Recording begins |
+| **4** | User shares screen (optional) | Capture window, start screen analysis | Screen recording, Window type |
+| **5** | Avatar speaks question | Voice synthesis with lip-sync | Question logged |
+| **6** | User responds (voice/text) | Capture video/audio, analyze filler words, process screen | Transcript, Filler count, Technical quality, Screen |
+| **7** | Session ends | Stop recordings, trigger analysis | End time, Completion status |
+| **8** | Analysis completes | Calculate 7 metrics, compare to history | All metric scores \+ historical comparison |
+
+| KEY STATES TO HANDLE | | |
+| ----- | ----- | ----- |
+| **State** | **Condition** | **System Behavior** |
+| **Permission Denied** | User blocks camera/mic | Error: 'Camera/mic required. Screen share optional for coding.' |
+| **Avatar Loading** | Persona initializing | Show: 'Preparing interview with \[Name\]...' (5-10s) |
+| **Active Interview** | Session in progress | Avatar speaks, user responds, timer running |
+| **Screen Share Active** | User sharing window | Screen content captured and analyzed |
+| **AI Service Error** | AI unavailable | Show error, use fallback questions |
+| **Voice Synthesis Error** | TTS fails | Fallback: text bubbles |
+| **Analysis Processing** | Calculating metrics | Show: 'Analyzing...' (30-60s) |
+| **Results Ready** | Analysis complete | Display 7 metrics \+ screen \+ historical \+ recommendations |
+
+| ANALYSIS METRICS | |
+| ----- | ----- |
+| **Metric** | **What's Analyzed** |
+| **Intro (10%)** | Opening greeting quality, confidence, first impression, professionalism |
+| **Facial Expression (20%)** | Engagement, authenticity, eye contact, smile appropriateness, emotional state |
+| **Body Language (20%)** | Posture, Gestures, Professionalism, Fidgeting, Movement patterns |
+| **Language (15%)** | Grammar, Vocabulary, Clarity, Sentence structure, Articulation |
+| **Voice (20%)** | Tone, Pace (WPM), Volume, Filler words COUNT (um, uh, like, you know), Vocal confidence |
+| **Outro (10%)** | Closing statement, Questions to interviewer, Professionalism, Final impression |
+| **Technical Quality (5%)** | Lighting: Well-lit/Poor | Framing: Centered/Off | Background: Professional/Distracting | Audio: Clear/Noisy |
+| **Screen Content** | Code: Syntax, Structure, Logic | Presentations: Quality, Clarity | Demos: Completeness |
+
+| DATA SHARING WITH OTHER SERVICES | | |
+| ----- | ----- | ----- |
+| **Target Service** | **Data Shared** | **Purpose** |
+| **Roleplay Service** | Communication gaps, weak types, low scores, filler patterns | Suggest roleplay scenarios for weak areas |
+| **Assessment Service** | Technical gaps, low topics, code quality issues | Recommend assessments for validation |
+| **Course Service** | Skill gaps, low metrics, coding weaknesses | Recommend courses (interview prep, communication, technical) |
+| **Dashboard Service** | Interview count, scores across 7 metrics, trends, code analysis | Update Q-Score, show progress, achievements |
+
+| ACCEPTANCE CRITERIA | | |
+| :---: | ----- | :---: |
+| **\#** | **Must Pass** | **Pass/Fail** |
+| **1** | All 4 personas render correctly. Voice synthesis works with distinct voices and lip-sync. | \[ \] PASS \[ \] FAIL |
+| **2** | All interview types selectable. Premium durations tier-gated with upgrade prompts. | \[ \] PASS \[ \] FAIL |
+| **3** | Video/audio captured throughout. Stored in cloud. Download links work. | \[ \] PASS \[ \] FAIL |
+| **4** | User can share specific window. Screen recording works. Can stop/resume sharing. | \[ \] PASS \[ \] FAIL |
+| **5** | AI analyzes voice with filler word COUNT. Count displayed in feedback. | \[ \] PASS \[ \] FAIL |
+| **6** | AI analyzes technical quality: Lighting, Framing, Background, Audio. Ratings displayed. | \[ \] PASS \[ \] FAIL |
+| **7** | AI analyzes screen content: Code quality, Presentation quality, Demo completeness. | \[ \] PASS \[ \] FAIL |
+| **8** | All 7 metrics calculated correctly. Analysis completes within 60s. | \[ \] PASS \[ \] FAIL |
+| **9** | Historical comparison works: Shows previous scores with dates vs current. Includes all metrics. | \[ \] PASS \[ \] FAIL |
+
diff --git a/upskilling/prd/Roleplay_OnePager.docx.md b/upskilling/prd/Roleplay_OnePager.docx.md
new file mode 100644
index 0000000..efcd812
--- /dev/null
+++ b/upskilling/prd/Roleplay_OnePager.docx.md
@@ -0,0 +1,71 @@
+
+
+| GrowQR Roleplay Service — One-PagerAvatar-Based AI \+ Real-Time Video/Voice \+ Screen Share | v3 | ROLEPLAY |
+| :---- | :---: |
+
+| PURPOSE |
+| ----- |
+| Avatar-based AI roleplay with real-time video/audio/screen interaction. AI personas speak using voice synthesis. Users respond via voice/text and can share screen (specific window) for coding/presentation demos. System analyzes voice (including filler word count), facial expressions, body language, technical setup quality (lighting, framing), and screen content to provide comprehensive performance feedback and certificates. |
+
+| CORE FEATURES | |
+| :---: | :---- |
+| **1** | Avatar-Based AI Personas: Visual characters with voice synthesis, lip-sync, emotional expressions |
+| **2** | Real-Time Voice Synthesis: AI persona SPEAKS all questions and responses (not just text bubbles) |
+| **3** | Video/Audio Recording: Capture user's camera and microphone throughout entire session |
+| **4** | Screen Share: User shares specific window (IDE, slides, demo app) \- NOT full desktop |
+| **5** | AI Screen Content Analysis: Analyzes code quality (syntax, logic), presentation slides, demos |
+| **6** | Comprehensive Analysis: Voice (tone, pace, filler word count), Facial (engagement, eye contact), Body (posture, gestures), Technical Quality (lighting, framing, background), Screen content |
+| **7** | Performance Scoring: Voice 35%, Facial 25%, Body Language 20%, Technical Quality 10%, Content 10% |
+
+| USER JOURNEY | | | |
+| :---: | ----- | ----- | ----- |
+| **Step** | **User Action** | **System Response** | **Data Captured** |
+| **1** | User selects scenario | Load AI persona avatar, request camera/mic/screen permissions | Scenario ID, User ID |
+| **2** | Permissions granted | Initialize avatar rendering, voice synthesis, recording systems | Media access granted |
+| **3** | Session starts | Deduct 1 credit, start all recording (video/audio/screen), avatar speaks first question | Session ID, Start time, Recording streams |
+| **4** | User shares screen (optional) | Capture specific window, begin screen content analysis | Screen recording, Content type detected |
+| **5** | User responds (voice/text) | Capture response, AI analyzes voice/facial/body/technical/screen in real-time or queued | Transcript, Voice metrics (including filler count), Facial timeline, Body timeline, Technical quality (lighting/framing), Screen analysis |
+| **6** | AI persona responds | Voice synthesis speaks follow-up, avatar lip-syncs | Conversation flow |
+| **7** | Session completes | Stop all recordings, finalize analysis, calculate scores across all metrics | Overall score, Voice 88%, Facial 75%, Body 82%, Technical 90%, Screen 85% |
+
+| KEY STATES TO HANDLE | | |
+| ----- | ----- | ----- |
+| **State** | **Condition** | **System Behavior** |
+| **Permission Denied** | User blocks camera/mic/screen | Show error: 'Camera, microphone required. Screen share optional but recommended.' |
+| **Media Loading** | Avatar/voice/recording initializing | Show: 'Preparing your session...' with progress (5-10s) |
+| **Connection Unstable** | Poor network, dropped frames/audio | Degrade quality or switch to text-only mode, continue session |
+| **Voice Synthesis Error** | TTS service fails | Fallback: Display text bubbles instead of speaking, avatar remains visible |
+| **Screen Share Stopped** | User stops sharing mid-session | Continue session without screen analysis, note in results |
+| **Active Session** | Roleplay in progress | Avatar speaks, user responds, all recording/analysis systems active |
+| **Analysis Complete** | Post-session processing done | Display all scores: Voice, Facial, Body Language, Technical Quality, Screen Content (if shared), Overall |
+
+| ANALYSIS METRICS | |
+| ----- | ----- |
+| **Metric** | **What's Analyzed** |
+| **Voice (35%)** | Tone (friendly/professional), Pace (WPM), Clarity (articulation), Confidence (vocal strength), Filler words COUNT (um, uh, like, you know) |
+| **Facial Expression (25%)** | Smile frequency, Eye contact (camera gaze), Emotional state (neutral/happy/stressed), Engagement level |
+| **Body Language (20%)** | Posture (upright/slouched), Gestures (open/closed), Fidgeting, Professionalism rating |
+| **Technical Quality (10%)** | Lighting: Well-lit/Acceptable/Poor | Framing: Centered in frame/Off-center | Background: Professional/Neutral/Distracting | Audio quality: Clear/Background noise |
+| **Content Quality (10%)** | Relevance, Completeness, Accuracy of responses |
+| **Screen Content (if shared)** | Code: Syntax, structure, logic, best practices | Presentations: Slide design, clarity | Demos: Feature completeness, explanation quality |
+| **Overall Performance** | Weighted combination of all metrics with historical comparison to track improvement |
+
+| DATA SHARING WITH OTHER SERVICES | | |
+| ----- | ----- | ----- |
+| **Target Service** | **Data Shared** | **Purpose** |
+| **Interview Service** | Voice/facial/body/technical/screen scores, weak communication areas, filler word patterns | Tailor interview questions to address roleplay gaps |
+| **Assessment Service** | Topic performance, behavioral competencies, communication patterns, technical setup quality | Recommend targeted assessments for weak areas |
+| **Course Service** | Skill gaps (communication, presentation, technical), low metric scores, setup quality issues | Recommend soft skills, communication, technical courses, setup guidance |
+| **Dashboard Service** | Session count, certificates earned, performance scores (all metrics), credits remaining | Update Q-Score based on performance, show progress achievements, suggest improvements |
+
+| ACCEPTANCE CRITERIA | | |
+| :---: | ----- | :---: |
+| **\#** | **Must Pass** | **Pass/Fail** |
+| **1** | Avatar renders correctly. Voice synthesis works with lip-sync within 100ms. Fallback to text if voice fails. | \[ \] PASS \[ \] FAIL |
+| **2** | User camera/microphone captured throughout session. All recordings stored in cloud. Download links work. | \[ \] PASS \[ \] FAIL |
+| **3** | User can share specific window. Screen recorded alongside video/audio. User can stop sharing anytime. | \[ \] PASS \[ \] FAIL |
+| **4** | AI analyzes voice including filler word COUNT (um, uh, like, you know). Counts displayed in feedback. | \[ \] PASS \[ \] FAIL |
+| **5** | AI analyzes technical quality: Lighting (well-lit/acceptable/poor), Framing (centered/off-center), Background (professional/distracting), Audio quality (clear/noisy). | \[ \] PASS \[ \] FAIL |
+| **6** | AI analyzes screen content: Code quality (syntax, structure, logic) for IDEs, Slide quality (design, clarity) for presentations, Demo completeness for apps. | \[ \] PASS \[ \] FAIL |
+| **7** | All metrics calculated correctly (Voice, Facial, Body, Technical Quality, Screen Content). Overall weighted score accurate. Certificate generated for 70%+ on eligible scenarios. | \[ \] PASS \[ \] FAIL |
+
diff --git a/workflow-primitives-inventory.md b/workflow-primitives-inventory.md
new file mode 100644
index 0000000..aa554fa
--- /dev/null
+++ b/workflow-primitives-inventory.md
@@ -0,0 +1,1015 @@
+# GrowQR Workflow Primitives Inventory
+
+This document lists the basic building blocks GrowQR has available before defining sellable workflows. The goal is to separate **capabilities/primitives** from **packaged workflows**.
+
+A workflow should be composed from these primitives instead of being treated as a standalone microservice.
+
+---
+
+## 1. Product Framing
+
+GrowQR is moving from a collection of user-facing microservices to an **agentic workflow platform**.
+
+Old framing:
+
+> User buys or uses individual tools: resume builder, interview tool, roleplay tool, matchmaking, pathways, social branding, etc.
+
+New framing:
+
+> User buys an outcome workflow. The Grow Agent coordinates internal capabilities, service agents, human experts, and persistent memory to deliver that outcome.
+
+The microservices still matter, but they become internal capabilities. The product surface becomes workflows such as job search, career discovery, interview readiness, personal branding, promotion readiness, or career switching.
+
+---
+
+## 2. Platform / Architecture Primitives
+
+These are not career products by themselves, but they are the infrastructure required to run workflows reliably.
+
+### 2.1 Main Grow Agent
+
+**Purpose:** User-facing coordinator for all workflows.
+
+**Responsibilities:**
+
+- Understand user intent.
+- Select the correct workflow.
+- Break workflow into steps.
+- Call the correct service agents/tools.
+- Ask for user approvals where needed.
+- Stream progress back to the UI.
+- Persist memory and artifacts.
+- Resume interrupted workflows.
+
+**Workflow value:** This is the single conversational/product interface. Users should not need to know which microservice is being used.
+
+---
+
+### 2.2 Durable Control Plane / Actor Layer
+
+**Purpose:** Keep long-running workflow state durable and resumable.
+
+**Responsibilities:**
+
+- Per-user or per-workflow actor identity.
+- Active thread/session state.
+- Runtime lifecycle decisions.
+- Recovery pointers.
+- Workflow serialization and resume.
+- WebSocket/event streaming to frontend.
+
+**Important distinction:** Actors hold small durable state and coordination metadata. They do not hold the full execution environment.
+
+---
+
+### 2.3 Agent Runtime Sandbox
+
+**Purpose:** Disposable execution environment where the agent can reason, call tools, read/write files, and invoke service capabilities.
+
+**Responsibilities:**
+
+- Execute agent steps.
+- Call domain tools and service APIs.
+- Maintain isolated workspace/worktree.
+- Generate intermediate artifacts.
+- Emit progress events.
+
+**Workflow value:** Lets workflows be more than API chains. The runtime can plan, inspect files, revise outputs, and coordinate multi-step work.
+
+---
+
+### 2.4 Capability Manifest / Tool Registry
+
+**Purpose:** Standard way for services to advertise what they can do.
+
+**Current contract:** Services can publish capabilities at:
+
+```text
+/.well-known/growqr-capabilities.json
+```
+
+**Capability examples:**
+
+- `resume.analyze`
+- `resume.optimize`
+- `pathways.generate`
+- `matchmaking.feed`
+- `interview.configure`
+- `roleplay.review`
+
+**Workflow value:** Workflows can call capabilities by intent instead of hardcoding service-specific endpoints.
+
+---
+
+### 2.5 Event Stream / Progress Protocol
+
+**Purpose:** Real-time UI feedback during workflow execution.
+
+**Useful event types:**
+
+- Workflow started
+- Agent thinking
+- Step started
+- Step completed
+- Approval required
+- Artifact generated
+- Score updated
+- Recommendation generated
+- Error/retry
+- Workflow completed
+
+**Workflow value:** Makes long-running workflows feel alive and trustworthy.
+
+---
+
+### 2.6 Versioned Memory / Git-Backed User Memory
+
+**Purpose:** Persistent source of truth for user career context and generated artifacts.
+
+**Potential memory contents:**
+
+- Career goals
+- Resume versions
+- LinkedIn/profile rewrites
+- Job preferences
+- Application tracker
+- Interview feedback history
+- Roleplay feedback history
+- Q-Score snapshots
+- Pathway plans
+- Weekly progress logs
+- Approved/rejected content
+
+**Workflow value:** Every workflow can build on previous work instead of starting from zero.
+
+---
+
+### 2.7 Operational Database
+
+**Purpose:** Store operational metadata, indexes, status, and recovery pointers.
+
+**Likely contents:**
+
+- User records
+- Workflow run records
+- Actor/runtime pointers
+- Payment/subscription state
+- Service job status
+- Artifact indexes
+- Feed/action history
+- Provider bookings
+- Score history
+
+**Important distinction:** The database stores operational state; durable user knowledge and versioned artifacts should live in memory/files where possible.
+
+---
+
+## 3. User / Identity Primitives
+
+### 3.1 Authenticated User
+
+**Purpose:** Known user identity, session, permissions, and tier.
+
+**Sources:**
+
+- Clerk authentication
+- GrowQR user-service profile
+
+**Workflow inputs:**
+
+- User ID
+- Email/name
+- Account tier
+- Subscription/purchase status
+- Connected accounts
+- Region/location
+
+---
+
+### 3.2 User Profile
+
+**Purpose:** Base professional context.
+
+**Possible fields:**
+
+- Current role
+- Years of experience
+- Industry/domain
+- Education
+- Skills
+- Projects
+- Certifications
+- Work preferences
+- Career goals
+- Target role/company/industry
+- Location and mobility preferences
+
+**Used by:** Almost every workflow.
+
+---
+
+### 3.3 Career Goals & Preferences
+
+**Purpose:** User-stated intent and constraints.
+
+**Examples:**
+
+- Target roles
+- Target industries
+- Desired salary
+- Remote/hybrid/office preference
+- Location constraints
+- Timeline urgency
+- Fulfillment vs earnings preference
+- Work culture preferences
+- Growth priorities
+
+**Used by:** Pathways, matchmaking, resume targeting, interview prep, course recommendations.
+
+---
+
+## 4. Core Domain Service Primitives
+
+## 4.1 Pathways Service
+
+**Primitive type:** Career direction and journey orchestration.
+
+**Core capabilities:**
+
+- Ingest profile context from LinkedIn/resume/questionnaire.
+- Generate career options.
+- Group options as close match, adjacent, and stretch paths.
+- Produce career identity statement.
+- Generate visual career web data.
+- Map skill gaps per path.
+- Activate a selected pathway.
+- Generate weekly plans and tasks.
+- Produce pathway report/export.
+- Re-plan as Q-Scores and user activity change.
+
+**Inputs:**
+
+- Resume/LinkedIn/profile data
+- Questionnaire
+- Q-Score profile
+- Career goals
+- Region/labor market context
+
+**Outputs/artifacts:**
+
+- Career web
+- Career options
+- Skill gap map
+- Weekly plan
+- Pathway report
+- Pathway tasks
+
+**Workflow role:** Direction-setting engine. Determines what the user should work toward and what other services should do next.
+
+---
+
+## 4.2 Q-Score Service
+
+**Primitive type:** Measurement and scoring engine.
+
+**Core capabilities:**
+
+- Calculate user score from multiple signals.
+- Score profile/resume/education/engagement/goals.
+- Produce score breakdowns.
+- Track score changes over time.
+- Feed recommendations into Pathways and other services.
+
+**Current signal sources:**
+
+- LinkedIn profile
+- Resume/CV upload
+- Education documents
+- Engagement activity
+- Goals and self-assessment
+- Cover letter / additional career artifacts
+- Platform badges and points
+
+**Representative Q dimensions mentioned in docs:**
+
+- Social Quotient
+- Execution Quotient
+- Communication Quotient
+- Vision Quotient
+- Drive Quotient
+- Growth Quotient
+- Reputation Quotient
+- Domain Quotient
+
+The broader product vision references 25 Q-Scores.
+
+**Outputs/artifacts:**
+
+- Q-Score
+- Pillar breakdown
+- Readiness tier
+- Percentile/rank where available
+- Score trend
+- Improvement recommendations
+
+**Workflow role:** Measurement layer. It tells workflows what to prioritize and proves progress to the user.
+
+---
+
+## 4.3 Resume Builder / Resume Intelligence
+
+**Primitive type:** Resume creation, parsing, versioning, optimization, export.
+
+**Core capabilities:**
+
+- Create resumes.
+- Store resume versions.
+- Use templates.
+- Parse uploaded resumes.
+- Analyze resume quality.
+- Improve ATS compatibility.
+- Rewrite bullet points.
+- Tailor resume for roles/job descriptions.
+- Export to PDF.
+
+**Inputs:**
+
+- Existing resume
+- User profile
+- Target role
+- Job description
+- Pathway target
+- Q-Score gaps
+
+**Outputs/artifacts:**
+
+- Resume draft
+- Resume versions
+- ATS analysis
+- Keyword gap analysis
+- Role-specific resume variant
+- PDF export
+
+**Workflow role:** Converts user history into strong application material.
+
+---
+
+## 4.4 Matchmaking Service
+
+**Primitive type:** Opportunity discovery and ranking.
+
+**Core capabilities:**
+
+- Store opportunities.
+- Support multiple opportunity types.
+- Capture user preferences.
+- Rank opportunities against user profile/preferences.
+- Explain match scores.
+- Maintain feedback loop from user actions.
+- Recompute feeds.
+- Support employer/organization opportunity ownership in current slice.
+
+**Opportunity types:**
+
+1. Full-time jobs
+2. Contracts/gigs
+3. Events/meetups
+4. Board advisory roles
+5. Surveys/research
+6. Temporary earning opportunities
+7. Future pathway opportunities
+
+**Scoring components from docs:**
+
+- Skills match: 40%
+- Personality fit: 30%
+- Company culture: 15%
+- Career growth: 10%
+- Compensation: 5%
+
+**Feedback actions:**
+
+- View
+- Save
+- Dismiss
+- Apply
+- RSVP
+
+**Outputs/artifacts:**
+
+- Opportunity feed
+- Match percentage
+- Explanation scores
+- Saved/applied/dismissed history
+- Feed history
+
+**Workflow role:** Finds external opportunities that match the user and learns from their behavior.
+
+---
+
+## 4.5 Interview Service
+
+**Primitive type:** Live mock interview simulation and evaluation.
+
+**Core capabilities:**
+
+- Configure interview session.
+- Select interviewer persona and interview type.
+- Generate questions based on role/context.
+- Conduct live voice interview.
+- Transcribe candidate/interviewer turns.
+- Archive audio artifacts.
+- Generate post-interview review.
+- Score performance and recommend improvements.
+
+**Inputs:**
+
+- Target role
+- Job description
+- Resume
+- Interview type
+- Duration
+- User history/Q-Score
+
+**Outputs/artifacts:**
+
+- Interview session
+- Transcript
+- Audio artifact
+- Interview review
+- Scores
+- Recommendations
+
+**Workflow role:** Converts preparation into simulated practice and measurable readiness.
+
+---
+
+## 4.6 Roleplay Service
+
+**Primitive type:** Workplace communication simulation and coaching.
+
+**Core capabilities:**
+
+- Generate roleplay preview/plan.
+- Allow user approval before start.
+- Run live audio-first roleplay with avatar persona.
+- Support workplace scenarios.
+- Enforce timing/moderation.
+- Capture transcript/audio.
+- Generate rubric-based review.
+- Provide improvement roadmap and historical comparison.
+
+**Example scenarios:**
+
+- Sales objections
+- Customer success conversations
+- Support diagnosis
+- Stakeholder conflict
+- Salary negotiation
+- Difficult manager conversation
+- Founder/investor pitch practice
+- Custom professional scenario
+
+**Evaluation metrics:**
+
+- Voice and tone
+- Content quality
+- Scenario adherence
+- Adaptability
+- Emotional intelligence
+- Technical/session quality
+
+**Outputs/artifacts:**
+
+- Roleplay plan
+- Transcript/audio
+- Rubric scores
+- Review
+- Improvement roadmap
+- Trend data
+
+**Workflow role:** Practice layer for soft skills and workplace performance.
+
+---
+
+## 4.7 Assessment Service
+
+**Primitive type:** AI-generated assessments and grading.
+
+**Core capabilities:**
+
+- Generate assessments from text, topic, YouTube URL, or course JSON.
+- Create STAR-framework scenario MCQs.
+- Support manual assessments.
+- Grade submissions.
+- Support multiple question types including multiple choice, coding, and scenario.
+- Process jobs asynchronously.
+
+**Inputs:**
+
+- Raw text
+- Topic
+- YouTube URL
+- Course module JSON
+- Manually authored questions
+- Difficulty
+
+**Outputs/artifacts:**
+
+- Assessment
+- Questions
+- User submission
+- Score/result
+- Skill evidence
+- Completion status
+
+**Workflow role:** Diagnosis and checkpoint layer. Verifies whether user has learned or is ready.
+
+---
+
+## 4.8 Courses Service
+
+**Primitive type:** Learning recommendation and courseware layer.
+
+**Core capabilities:**
+
+- Curate/index external courses.
+- Map courses to skill gaps and user personas.
+- Track enrollment status.
+- Track progress/completion.
+- Generate certificates where eligible.
+- Support future third-party creator content.
+- Support future GenAI-generated course IP.
+
+**Three-phase courseware strategy:**
+
+1. External course mapping and indexing
+2. Third-party creator platform
+3. GenAI-generated personalized course IP
+
+**Inputs:**
+
+- Skill gaps
+- Pathway target
+- Q-Score breakdown
+- Assessment/interview/roleplay feedback
+- User persona/life stage/industry
+
+**Outputs/artifacts:**
+
+- Recommended courses
+- Learning path
+- Enrollment record
+- Completion status
+- Certificate
+
+**Workflow role:** Turns identified gaps into structured learning actions.
+
+---
+
+## 4.9 Social Branding Service
+
+**Primitive type:** Professional presence and content engine.
+
+**Core capabilities:**
+
+- Connect social/professional accounts.
+- Scrape/collect profile and engagement data.
+- Analyze profile completeness and audience alignment.
+- Calculate Brand Score.
+- Rewrite profiles.
+- Generate content calendars.
+- Generate post drafts.
+- Queue items for approval.
+- Schedule/post approved content.
+- Track performance and feed data back into RQx/Q-Score.
+
+**Target platforms:**
+
+- LinkedIn
+- Instagram
+- X/Twitter
+- YouTube
+- Git/profile surfaces where relevant
+
+**Personas from docs:**
+
+- Job seeker
+- Career transitioner
+- Thought leader
+- Founder/entrepreneur
+- Creator/consultant-style personas
+- Enterprise/company brand contexts
+
+**Brand Score components:**
+
+- Profile completeness
+- Content consistency
+- Audience growth
+- Engagement rate
+- Recruiter visibility
+- Content quality
+- Cross-platform consistency
+
+**Outputs/artifacts:**
+
+- Brand Score
+- LinkedIn/profile rewrite
+- Content strategy
+- Content calendar
+- Post drafts
+- Approval queue
+- Analytics report
+
+**Workflow role:** Makes the user externally visible and credible.
+
+---
+
+## 4.10 Marketplace Service
+
+**Primitive type:** Human expert supply layer.
+
+**Core capabilities:**
+
+- Provider onboarding and validation.
+- Provider profiles.
+- Service listings.
+- Booking flows.
+- Availability/calendar.
+- Reviews and ratings.
+- Provider categories mapped to career needs.
+- Pathway-triggered recommendations.
+
+**Provider types:**
+
+- GrowQR-certified external coaches
+- Verified senior users
+- Corporate/institutional providers
+- GrowQR in-house experts
+
+**Delivery formats:**
+
+1. Live 1:1 video session
+2. Async review
+3. Group workshop
+4. Done-for-you service
+5. Retainer package
+
+**Service categories:**
+
+- Interview preparation
+- Resume and cover letter
+- Social and personal branding
+- Career coaching
+- Job search strategy
+- Domain and industry guidance
+- Skills development coaching
+- Entrepreneurship and business
+- Academic and graduate guidance
+
+**Outputs/artifacts:**
+
+- Provider recommendation
+- Booking
+- Session notes
+- Async review result
+- Follow-up action plan
+
+**Workflow role:** Brings in human wisdom when AI is not enough or trust is required.
+
+---
+
+## 4.11 Dashboard Service
+
+**Primitive type:** User progress and home surface.
+
+**Core capabilities:**
+
+- Load user dashboard state.
+- Show recent progress.
+- Display Q-Score and updates.
+- Surface recommendations.
+- Present active workflows/pathways.
+- Show tasks, suggestions, and activity.
+
+**Outputs/artifacts:**
+
+- Dashboard summary
+- Progress cards
+- Recommendations
+- Current task list
+- Score/activity widgets
+
+**Workflow role:** The user’s command center for active workflows and progress.
+
+---
+
+## 4.12 User Service
+
+**Primitive type:** Identity, profile, and user source of truth.
+
+**Core capabilities:**
+
+- Ensure/create user record.
+- Store user profile.
+- Store account-level metadata.
+- Manage profile photo/QR-related identity surfaces.
+- Expose user state to frontend and orchestrator.
+
+**Outputs/artifacts:**
+
+- User profile
+- Account tier/pro status
+- Basic identity and preferences
+
+**Workflow role:** Baseline identity and profile context for all workflows.
+
+---
+
+## 4.13 Frontend / Client Experience
+
+**Primitive type:** User interface and approval surface.
+
+**Core capabilities:**
+
+- Chat-first interaction.
+- Generated UI cards.
+- Workflow progress display.
+- Approval/rejection/edit flows.
+- Direct page experiences for some services.
+- Realtime WebSocket session with orchestrator/actor.
+
+**Workflow role:** Where users see, approve, and trust the workflow execution.
+
+---
+
+## 5. Cross-Cutting Data / Artifact Primitives
+
+These are the reusable objects workflows can create, consume, update, and version.
+
+### 5.1 Profile Artifacts
+
+- User profile snapshot
+- LinkedIn profile snapshot
+- Social profile snapshot
+- Education documents
+- Skills inventory
+- Career goals/preferences
+
+### 5.2 Resume Artifacts
+
+- Uploaded resume
+- Parsed resume JSON
+- Resume draft
+- Resume versions
+- Job-specific resume variants
+- ATS analysis
+- PDF export
+
+### 5.3 Career Direction Artifacts
+
+- Questionnaire response
+- Career identity statement
+- Career web
+- Pathway options
+- Skill gap map
+- Activated pathway
+- Weekly plan
+- Pathway report
+
+### 5.4 Opportunity Artifacts
+
+- Opportunity record
+- Opportunity feed
+- Match score
+- Fit explanation
+- Saved/applied/dismissed actions
+- Application tracker
+- Employer/company enrichment
+
+### 5.5 Practice Artifacts
+
+- Interview config
+- Interview transcript
+- Interview review
+- Interview audio artifact
+- Roleplay plan
+- Roleplay transcript
+- Roleplay review
+- Practice trend history
+
+### 5.6 Learning / Assessment Artifacts
+
+- Course recommendation
+- Learning path
+- Enrollment record
+- Course completion
+- Certificate
+- Assessment questions
+- Assessment submission
+- Assessment result
+
+### 5.7 Branding Artifacts
+
+- Brand Score
+- Profile audit
+- LinkedIn/profile rewrite
+- Content pillars
+- Content calendar
+- Post drafts
+- Approval queue
+- Published content history
+- Engagement analytics
+
+### 5.8 Human Support Artifacts
+
+- Provider profile
+- Provider recommendation
+- Booking
+- Session notes
+- Async review
+- Follow-up plan
+
+### 5.9 Score / Progress Artifacts
+
+- Q-Score snapshot
+- Q-Score breakdown
+- Brand Score history
+- Readiness score
+- Weekly progress log
+- Workflow completion report
+
+---
+
+## 6. Approval Primitives
+
+Many workflows should not execute irreversible actions without approval.
+
+### Approval points to support
+
+- Approve resume rewrite/version.
+- Approve job applications before submission.
+- Approve recruiter outreach messages.
+- Approve social profile changes.
+- Approve social posts before publishing.
+- Approve roleplay/interview plan before session starts.
+- Approve paid human expert booking.
+- Approve pathway activation.
+- Approve final report/export.
+
+### Approval actions
+
+- Approve
+- Reject
+- Request revision
+- Edit directly
+- Save for later
+- Auto-approve rule for low-risk repeated actions
+
+---
+
+## 7. External Integration Primitives
+
+### 7.1 Professional / Social Platforms
+
+- LinkedIn
+- Instagram
+- X/Twitter
+- YouTube
+- Git/profile surfaces where relevant
+
+### 7.2 Job / Opportunity Sources
+
+- LinkedIn Jobs
+- Naukri
+- Indeed
+- Glassdoor
+- Monster
+- Company career pages
+- Employer direct posts
+- Event/meetup sources
+- Advisory/survey/gig sources
+
+### 7.3 Learning Platforms
+
+- Coursera
+- LinkedIn Learning
+- Udemy
+- Moodle
+- Thinkific
+- Other indexed course providers
+
+### 7.4 Communication / Live Session Surfaces
+
+- Live voice/video interview sessions
+- Live roleplay sessions
+- Marketplace expert sessions
+- Calendar/reminder integrations later
+
+---
+
+## 8. Commercial / Packaging Primitives
+
+These primitives help determine how workflows can be sold.
+
+### 8.1 User Tiers
+
+From Pathways docs:
+
+- Free/basic
+- One-time report purchase
+- Premium subscription
+
+### 8.2 Purchase Models
+
+Potential models:
+
+- Free diagnostic
+- One-time workflow purchase
+- Subscription workflow access
+- Premium bundle
+- Human expert add-on
+- Credit-based usage
+- Outcome-guarantee package where appropriate
+
+### 8.3 Gating Concepts
+
+- Limited free nodes/recommendations
+- Full report unlock
+- Workflow activation unlock
+- Unlimited opportunity feed for premium
+- Human marketplace add-on
+- Advanced Q-Score insights for premium
+- Longer pathway durations for subscription users
+
+---
+
+## 9. Current Service Inventory Summary
+
+| Primitive / Service | Main Role | Key Outputs |
+|---|---|---|
+| Main Grow Agent | User-facing workflow operator | Plans, tool calls, progress, artifacts |
+| Durable Actor Layer | Resumable workflow control | State, recovery pointers, event stream |
+| Runtime Sandbox | Agent execution environment | Tool execution, generated files, service calls |
+| User Service | Identity/profile source | User record, profile, tier |
+| Dashboard Service | Progress command center | Dashboard cards, recommendations, active tasks |
+| Pathways | Career direction/orchestration | Career web, pathway, weekly plan, report |
+| Q-Score | Measurement engine | Scores, breakdowns, trends, recommendations |
+| Resume Builder | Resume intelligence | Resume versions, analysis, exports |
+| Matchmaking | Opportunity discovery | Feed, match scores, feedback history |
+| Interview | Mock interview practice | Live session, transcript, review, score |
+| Roleplay | Workplace simulation | Scenario practice, transcript, rubric, roadmap |
+| Assessment | Skill/readiness testing | Assessment, graded result, evidence |
+| Courses | Learning recommendations | Course plan, enrollment, certificates |
+| Social Branding | Professional visibility | Brand Score, profile rewrite, content calendar |
+| Marketplace | Human expert supply | Provider booking, session notes, expert reviews |
+| Frontend | User interaction/approval | Chat, cards, approvals, progress UI |
+| Versioned Memory | Durable user knowledge | Files, diffs, artifacts, history |
+| Operational DB | Workflow/service metadata | Status, indexes, pointers, transactions |
+
+---
+
+## 10. Notes for Next Step: Workflow Design
+
+When defining actual workflows, each workflow should specify:
+
+- User promise
+- Target user segment
+- Required inputs
+- Services/capabilities used
+- Step sequence
+- Approval points
+- Generated artifacts
+- Success metrics
+- Pricing model
+- Memory written
+- Retry/resume behavior
+
+A workflow should be packaged around a user outcome, not around a service name.
+
+Example:
+
+```yaml
+workflow_id: job_search_apply
+promise: Find relevant jobs, tailor application material, and prepare the user to apply.
+uses:
+ - user_profile
+ - qscore
+ - resume_builder
+ - matchmaking
+ - social_branding
+ - interview
+ - marketplace_optional
+approval_points:
+ - approve_resume_variant
+ - approve_application_targets
+ - approve_outreach_messages
+outputs:
+ - curated_job_list
+ - tailored_resume
+ - cover_letter_or_message
+ - application_tracker
+ - interview_prep_plan
+```
+
+This inventory should be treated as the base map for building the actual GrowQR workflow catalog.