Skip to content

feat(talentos): real Genkit-powered job-context extraction (kills mock-keyword charging path)#3

Merged
tikidragonslayer merged 1 commit into
mainfrom
claude/talentos-real-job-context
May 3, 2026
Merged

feat(talentos): real Genkit-powered job-context extraction (kills mock-keyword charging path)#3
tikidragonslayer merged 1 commit into
mainfrom
claude/talentos-real-job-context

Conversation

@tikidragonslayer
Copy link
Copy Markdown
Owner

Summary

Replaces the mock keyword-heuristic in TalentOS's "AI Job Context Builder" with a real Genkit-powered extraction flow. The prior implementation charged 1 OS Credit per call and returned canned 4-line analysis from `transcript.toLowerCase().includes('remote'|'fast'|'ship'|'mentor')` heuristics behind a 1.5s setTimeout — same output regardless of transcript content.

This is Tier 1 stub-architecture queue item #2 per Codex's `stubbed-feature-build-architecture-for-claude.md` §2.

Stub evidence (pre-fix)

`src/app/actions/job-context-actions.ts:73-95`:

  • 1.5s simulated delay
  • 4 keyword heuristics
  • Returns identical analysis whether the transcript is real or empty
  • Charges `CREDIT_COSTS.JOB_CONTEXT_EXTRACTION` (1 OS Credit) regardless

UI flow (`src/components/jobs/active-job-context-builder.tsx`) calls this from the public "AI Job Context Builder" component on `/employer/jobs/new` and `/employer/jobs/[jobId]/edit`.

What ships

  • New `src/ai/flows/extract-job-context.ts` — Genkit flow mirroring the existing `anonymize-job-description.ts` pattern. Structured Zod output schema (`cultureAnalysis`, `hiddenRequirements[2-6]`, `teamDynamic`, `recommendedKeywords[3-8]`). Prompt grounded in the transcript with the same injection-defense framing as `match-candidate-to-job.ts`.
  • Action wired to `extractJobContext()`. When AI is unavailable (`GOOGLE_GENAI_API_KEY` missing or upstream failure), the action fails closed: refunds the credit, surfaces the error message. No canned-data fallback.

Why fail-closed (not deterministic fallback like other flows)

Other flows (`anonymizeJobDescription`, `matchCandidateToJob`) have real deterministic algorithms to fall back to — regex anonymization, skill-overlap + ZIP-prefix scoring. `extractJobContext` had only fake data; there's no honest deterministic version. Per Codex's no-mocks-in-production doctrine, fail closed is the correct posture.

Out of scope (separate slices)

  • `src/components/jobs/active-job-context-builder.tsx:55` — "Simple mock conversation flow" — chat UI hardcodes 1 follow-up question. Needs a real conversation generator.
  • `src/lib/firebase-admin.ts:34-37` — production fallback to `mock-project-id` / `mock@example.com`. Should fail closed in prod.
  • Employer "verification coming soon" badge.

Verification

  • `npx tsc --noEmit` shows 0 new errors from changed files. 4 pre-existing Stripe API version errors on `main` (`apiVersion '2025-04-30.basil'` vs installed types `'2025-02-24.acacia'`) — not touched per surgical-changes principle, but worth a separate fix; they currently break `npm run build`'s final typecheck step (compile itself succeeds in 24.3s).

Test plan

  • Deploy to App Hosting with `GOOGLE_GENAI_API_KEY` set
  • `/employer/jobs/new` → AI Job Context Builder → submit a real transcript → verify `cultureAnalysis` reflects actual transcript content (not generic "Structured, methodical engineering culture.")
  • Unset `GOOGLE_GENAI_API_KEY` → repeat → verify credit refund + error toast
  • Verify Firestore `users/{uid}.osCredits` decrements only on success and is correctly refunded on failure

🤖 Generated with Claude Code

…k-keyword charging path)

Public claim: "AI Job Context Builder — chat with our agent to extract
Job DNA and hidden requirements" — charges 1 OS Credit per call.

Stub evidence (pre-fix):
src/app/actions/job-context-actions.ts:73-95 returned canned text from
`transcript.toLowerCase().includes('remote'|'fast'|'ship'|'mentor')`
heuristics behind a 1.5s setTimeout. Same 4-line analysis was returned
regardless of transcript content. Charged the credit.

Build slice:
- New src/ai/flows/extract-job-context.ts — Genkit flow mirroring the
  existing anonymize-job-description.ts pattern. Structured Zod output
  schema (cultureAnalysis, hiddenRequirements[2-6], teamDynamic,
  recommendedKeywords[3-8]). Prompt grounded in transcript with
  injection-defense framing matching match-candidate-to-job.ts.
- Action wired to extractJobContext(). When AI is unavailable
  (GOOGLE_GENAI_API_KEY missing) the action FAILS CLOSED, refunds the
  credit, and surfaces the error message — no canned-data fallback.

Pattern follows Codex's no-mocks-in-production doctrine
(stubbed-feature-build-architecture-for-claude.md §2). Different from
existing flows that fall back to deterministic algos: this one had no
real algorithm to fall back to, only fake data.

Out of scope (separate slices):
- src/components/jobs/active-job-context-builder.tsx:55 "Simple mock
  conversation flow" — chat UI hardcodes 1 follow-up question; needs
  real conversation generator
- src/lib/firebase-admin.ts:34-37 — production fallback to
  mock-project-id / mock@example.com — should fail closed in prod
- Employer "verification coming soon"

Verification:
- npx tsc --noEmit shows 0 new errors in changed files. 4 pre-existing
  Stripe API version errors on main (apiVersion '2025-04-30.basil' vs
  installed types '2025-02-24.acacia') NOT touched per surgical-changes.
- npm run build: compile step succeeded in 24.3s; build's final
  typecheck fails on the same 4 pre-existing Stripe errors. Worth a
  separate fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tikidragonslayer tikidragonslayer merged commit f1158a2 into main May 3, 2026
@tikidragonslayer tikidragonslayer deleted the claude/talentos-real-job-context branch May 3, 2026 03:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant