On-demand Scout service (replaces the nightly aggregator): - FastAPI agent-mesh service; card name "matchmaking-service" (HTTP /a2a/tasks + Redis-stream worker matching the sibling-service pattern) - run_search: parallel multi-board sweep (Naukri/blackfalcondata + Foundit + LinkedIn), city-filtered at the board, cheapest-per-result first - per-board adapters + normalizers -> ScoutJob with rich read-only details and offsite apply links; recall mode + MVQ guard - result cache for dev replay ($0); per-board cost knobs; retry-on-5xx - research/: engine design, board cost economics, India-actor shortlist, POC
11 KiB
Scout UI — Lean Finalization Spec
Screen-by-screen "what we surface" decisions for the Scout UI, made against what the engine + deployed agents can actually produce (see
ENGINE_DESIGN.md,SIGNAL_AUDIT_V2.md,agent-capabilityevidence). Work happens in-place indashboard-ui/scout(no rebuilds). Written 2026-06-16.
Guiding principles
- Don't fake it; lock it. Features that are real later are shown as a tasteful "coming soon" locked tile, never with fabricated data. Nothing here is a lie.
- Personas stay only where backed. Mira = real (resume-builder parsed/tailored an existing résumé) → keep. The bubble-journey "Nova" is being replaced wholesale (see Configure) → gone.
- Cut the three never-backed claims everywhere: "live status", "in-network", invented deadlines.
Summary tab (two states)
First-time view → UNCHANGED
Onboarding doorway (hero + 4-step "how it works" + CTA). Locked as-is — "812 live roles" reads as market scale, not a corpus claim; "Mira" is backed. No edits.
Returning view (metrics dashboard) → leaned
- KEEP (producible today): Streak · Monthly report · Readiness·QX (qscore + assessment) ·
Matches found · Top match · Salary band · Competition (avg applicants from listings) · Match range/
distribution · Momentum / Readiness trend (qscore over time) · What your agents did (logged) ·
Application funnel =
Matches → Viewed → Shortlisted → Applied, all user-activity (Viewed = jobs the user opened, Shortlisted = saved) · Your Apply window (freshness-based urgency from listing posting-age, replaces generic "Golden window") · Your rank = activity percentile from Scout activity only (searches/views/saves/applies in the matchmaking DB; "top X% by how much you're working your search" — honest engagement, not a quality claim) · Search stage. - 🔒 LOCK (coming soon): Expert / human review.
- CUT: Search plan ("as you sleep") · Proof-ready · Market value · Response·tracked (no recruiter callback) · Warm intros (no referral agent).
Configure tab → ~90% intact (the strongest screen)
| Section | Decision |
|---|---|
| Hero "Here's the search I'd run for you" | ✅ keep |
| Profile summary ("parsed by Mira", title/seniority/industry/city/years) | ✅ keep — real (resume-builder + LinkedIn) |
| "Matching you on N signals" transparency bar | ✅ keep, but fix the list to match SIGNAL_AUDIT_V2: keep Role&level + Skills + What-you-value; Market context is now BACKED via Perplexity (keep); add verified-LinkedIn / QScore / course-behavior; drop any item with no source |
| "Also matching on · derived" (comp/stage/availability/deal-breakers/dream cos/hide-employer) | ✅ keep — real preference/filter inputs |
| Video intro | ✅ KEEP — reuse the existing VideoResumeBuilder.tsx; persist via interview-service's MinIO blob storage (record → store). Drop the "rides with in-network" copy |
| "What are you after?" (More like this / step up / new) | ✅ keep — FIT vs STRETCH core |
| "What matters most?" (pick 2) | ✅ keep — ranking weights |
| "How far should I reach?" (Safe/Balanced/Reach) | ✅ keep — reach band |
| "Work mode" | ✅ keep — hard filter |
| The must-haves bubble box ("Fine-tune everything") | ✅ KEEP the box, swap the engine → reuse course BubblePicker + useBubbleField (physics: grow-on-like +6 / love +12, live repack). "Add your own" on EVERY row (crucial) — esp. Where/location (tier-2/3 cities typed → real preferred-location bubble). AI suggestions via onGenerateMore but STRIP the "ai" badge — untagged, indistinguishable from presets. Replaces ScoutBubbleJourney/Nova |
| Location (the "Where" row, lives in the bubble box) | ✅ feeds the ported location-fit logic (SIGNAL_AUDIT_V2): substring city match, Remote→100, Anywhere→open. Add-your-own + that scoring = location finally handled right |
| Footer "Scout never applies without you" | ✅ keep — honest consent |
Net Configure: keep almost everything; the only real changes are (1) fix the signal-transparency
list to the true set, (2) reuse VideoResumeBuilder for video-intro, (3) replace the bubble journey
with the course bubbler (add-your-own + untagged AI), (4) wire the ported location logic.
Action tab → leaned, with an honest apply flow
A) Loader (JobMatchingLoader) — rework copy to the on-demand truth: "Looking in 3+ job
boards · Scanning 100+ roles" → normalize skills → score against your signals → rank. Drop the fake
"812 corpus scan." ("fresh by construction — pulled seconds ago.")
B) Filter bar — ✅ keep (the hard filters + active chips + Clear all).
C) Match card (MatchCard):
| Element | Decision |
|---|---|
| match % + QX breakdown | ✅ keep — but it IS the engine's match breakdown: the white-box signal dimensions (skill match, experience, location-fit, course-behavior, QScore competence, market context). "Why we matched you," powered by the real engine, not gamified QX |
| title · ₹pay · applicants | ✅ keep (from listings) |
| "Closes in N days" | ❌ removed → "posted Nd ago" (no real deadline data) |
| "+N QX on apply" · "Proof-ready" · "In-network · live status" | ❌ cut |
| "Video intro ✓" | ✅ keep (reuse Video Resume; drop in-network gating) |
| "Warm intro · can refer you" | ❌ cut (no mentor/referral agent) |
| "light on {gap} → 15-min mock / Expert mock / {course}" | ✅ keep (interview/roleplay/course are real) |
| "Why Scout picked this" + tags | ✅ keep — wire to the TRUE signals |
D) Swipe controls (Pass / undo / info / Save) — ✅ keep. These emit the VIEW / SAVE / PASS events that feed the funnel + activity rank.
E) Apply flow (the hand-off) — make it honest and concrete:
- Approve once — the single consent tap (keep).
- Per-job résumé tailoring — for each saved role, resume-builder tailors the résumé + cover letter. NEW UX: a per-job spinner ("Tailoring your résumé for {company}…") — this step had no UI.
- Auto-apply — the master-key engine submits (tier-aware: public-ATS/India-ATS = autonomous; login-gated = staged handoff).
- Result — split, with proof:
- ✅ Applied (auto): show the captured confirmation screenshot per role — verified, not assumed (the engine already screenshots the success page).
- ⚠️ Couldn't auto-apply (login_required / no_form / failed / spam-flagged): list these with "Apply manually →" + the live link, so the user finishes them by hand.
Net Action: real bones kept (match + engine breakdown + why + mock/course boosts + apply), the recurring cuts applied (in-network/live-status, +QX framing, warm-intro/referral, add-to-pathway, deadlines), loader made honest, and the apply flow gains the resume-tailoring spinner + proof screenshots + manual-apply fallback for failures.
BUILD PROGRESS — as shipped on branch job-ui-final (updated 2026-06-17)
Built in-place in dashboard-ui/scout (+ components/job-matching). Committed/pushed:
job-ui-final (head 780e09e+). All states compile; /scout serves clean. The build went
further than this spec in places — recorded here so the spec stays the source of truth.
Honesty check: every divergence is a cut or an improvement; nothing surfaces a claim the engine
can't back (re-verified against ENGINE_DESIGN.md).
Configure (most changed):
- ✅ Bubble box swapped to the ported course physics —
components/scout/bubble/{useBubbleField,ScoutBubbleField}; like/love grow+repack, add-your-own + untagged "Suggest more" on taste rows. (ScoutBubbleJourneyrewired off Nova/NovaBubbles.) - ✅ Location upgraded beyond spec: cascading Country→City picker (
LocationPicker.tsx, ported from the old matchmakingFilterBar— flags, searchable city, "select country first"). Stored as"City · Country"; the deck matcher now scores city AND country (filterSortScoutJobs). Feeds Tier-Apreferred_locations. - ✅ Profile card is now editable in place ("Edit details" ↔ "Done") + a "Fine-tune" orange pill (header) and "Fine-tune everything" (bottom) → the bubble journey. All dropdowns are one shared searchable
CustomSelect(type-your-own → "Use 'X'") with an "Any" option that maps to no constraint for the engine. - ✅ No-resume / nothing-selected state (NEW, not in original spec): card opens in edit mode, every field defaults to "Any", headline "What are you looking for?", an "Add a resume to pre-fill" action (simulated Mira parse). This is the UI face of engine §3.3 (sparse profile → coverage renormalizes, never fabricates). Preview toggle to view both states.
- ⚠️ DIVERGENCE — "Matching you on N signals" bar: REMOVED (text-light pass), not "kept + fixed" as spec said. Signals still feed the engine; just not surfaced. Re-add a 1-line honest version if we want the credibility back.
- ⚠️ DIVERGENCE — Video intro: REMOVED from card + chip (Tier-C, not wired). Spec wanted keep.
- ⚠️ DIVERGENCE — dream-companies + hide-employer editing dropped (kept comp/stage/availability/deal-breakers as read-only chips → editable inline).
- ✅ Removed the lame "Use my résumé instead" shortcut everywhere.
Summary:
- ✅ 9 headline cards (activity-led) + 3 behind "More metrics"; Expert/human review locked "coming soon" (Mira/Vera hand-offs stay live).
- ✅ Market signals trimmed to producible set (dropped layoff/funnel/hiring-velocity).
- ⚠️ DIVERGENCE — Readiness·QX assessment card REMOVED (+8 QX reward theatre gone). QScore/assessment remain real Tier-B engine signals; "Readiness trend" still in More-metrics. Spec wanted keep.
- ⚠️ PENDING — "Golden apply window" not yet renamed to the freshness/posting-age "Apply window" (§6.1).
Action / match:
- ✅ Loader honest:
Looking across 3+ job boards · Scanning 100+ live roles · Scoring · Ranking; MATCH_SCOPE 812→120. - ✅ Video-intro chip removed from
MatchCard. - ✅ Swipe card action-bar overlap fixed — card now renders in normal flow (
AnimatePresence popLayout), so expanding the QX breakdown grows the page and Pass/Undo/Info/Save stay below it (removed the brittle absolute+ResizeObserver container). - ⚠️ DIVERGENCE — Action-tab filter bar + chips +
ScoutFilterSheet: REMOVED. Configure is the single source of search criteria; empty deck → "Adjust in Configure". Spec wanted keep. - 🔧 PENDING (needs engine): apply-flow proof screenshots + auto/failed→manual split; per-job resume-tailoring spinner. These wait on engine apply-result statuses.
Text/polish: all accented "résumé" → plain "resume"; "Pick 2" casing.