JC → CV consumption bridge — the unbuilt high-value next step
Found 2026-06-04 while the corpus crossed ~13k. The corpus is now real and queryable, but CareerVector cannot yet pull from it. This is the natural next product step and the thing that makes the corpus worth anything.
Verified facts (live)
- JobCache holds 13k+ postings and is fully queryable:
GET https://api.jobcache.corbet.ch/api/postings?limit=N→{count, postings[]}with{fingerprint, source, url, title, company, …}per row. Confirmed real data (e.g. "Insurance Advisor … AXA Versicherungen",jobup-ch).GET /api/search?q=…&limit=N→{total, results[]}. Works.- Plus
/api/ads/lookup?url=…andPOST /api/ads/resolve.
- CareerVector's only read of JobCache is
GET /api/stats(the corpus health tile,lib/perspective-shared/src/jobcache-health.ts).JOBCACHE_SERVICE_URLis already wired inapi/wrangler.toml. - The CV→JC direction is write-only:
lib/domain/src/jobcache.tsbuildsensure_ad/submit_observationcommands so workspace-discovered ads propagate into the corpus. There is no read-back. - RADAR (
lib/domain/src/pipeline/stages/radar.ts) is single-URL scrape (given a URL → scrape/extract into the workspace). It is not corpus-driven discovery.
So: the corpus is built and queryable; nothing consumes it. The North Star's "jobs … eventually through RADAR-style automated discovery" (CLAUDE.md, Product North Star) is exactly this missing bridge.
What a consumption bridge needs — product decisions (for Julian)
These shape the product; not to be defaulted autonomously:
- Selection model — how does a workspace pick from 13k jobs?
- Manual: a search box in the dashboard ("import from corpus") hitting
/api/search, user cherry-picks rows →job.create. - Semantic: match the workspace's CV-profile / saved search against the corpus (needs embeddings or a structured filter: title, location, industry, salary).
- Standing query (RADAR-style): a saved filter the pipeline re-runs, auto-adding new matches as they enter the corpus.
- Manual: a search box in the dashboard ("import from corpus") hitting
- Auto vs. manual. Does the workspace pull continuously (a real RADAR loop)
or only on user action? (Compute economics §1 + the existing
process_requestbackend model both favor an explicit, claimable job, not a hidden cron.) - Dedup. Corpus posting → workspace job must dedup against existing jobs by
url/ad_id(the same normalize+hash already injobcache.ts). - Import mapping. Corpus row (
title, company, url, source+ facts) →job.createattributes, withactor_class='system',actor_idlikecv-internal:corpus-import, so cell-origins tint correctly (§13). - Filtering quality. A search endpoint over 13k mixed-language Swiss-board
ads needs at least location + language + freshness filters to be useful;
confirm
/api/searchsupports them or extend it.
Smallest honest first slice (if greenlit)
A manual "Import from corpus" dashboard action: search box → /api/search →
result list → multi-select → job.create (deduped). No semantic match, no auto
loop. Proves the end-to-end path and surfaces the real UX questions before
investing in standing queries / semantic match. Everything else (RADAR loop,
profile-match) layers on top.
Status: documented, not started. Gated on decision #1–#2 above.