]## Inspiration

A role that used to draw 30 applicants now draws 500, and the tools built to cope with that have a common shape: a black-box fit score. The recruiter sees 87%, can't see why, and can't change what produced it.

We think the score is the problem. A recruiter already knows what the role needs. What they lack is a way to ask a thousand resumes the same specific question and get an answer they can inspect.

So Candidate Explorer has no fit percentage, no weighted formula, and no keyword bonus. Ranking comes from exactly one Jev question about relevance to a role brief the recruiter approved. Everything else is an attribute you can read, filter on, or switch off.

What it does

Import a pool of resumes as JSON, CSV, or plain text. Paste a job description. An LLM proposes six to ten screening questions drawn from that JD, each one carrying the exact quotation it came from, whether the JD marked it required or preferred, and any transferable alternatives it suggests. Nothing is active until the recruiter approves it.

Approved criteria compile into a role brief, shown before anything runs. Jev then evaluates the pool and sorts candidates by the raw score from a single relevance question — judged against the brief, explicitly ignoring writing polish and AI-like style.

From there you refine in natural language. "Python used on a finance project, not Python somewhere and finance somewhere else" becomes a constrained, previewable plan: filter existing answers, add a question, or change a role criterion. You see the interpretation with Apply, Edit, and Cancel before it runs. Filters on stored answers cost nothing; only genuinely new questions trigger evaluation.

Click a candidate and you get their original resume, the literal question instructions, the native answer with its probability distribution and confidence, and an on-demand passage lookup that shows the supporting text or says plainly that none was found.

A general question library evaluates against resume text alone, so those answers cache and carry across every job you screen for.

How we built it

Next.js App Router, TypeScript, Tailwind, local files under an ignored data directory. Jev through @typesafe-ai/sdk for every candidate assessment. OpenRouter with structured outputs for question generation and search interpretation only — the generative model never ranks a candidate.

Questions sharing the same state are bundled into one request. Resumes process with bounded concurrency. Results cache on resume hash, question version, role revision, and model version, so changing one criterion doesn't re-evaluate the pool.

Natural-language requests compile to an allowlisted JSON schema and run through our own interpreter. No generated SQL, no generated JavaScript, nothing executed.

Challenges we ran into

Resisting the score. Every instinct says to combine sixteen answers into one number. We kept them separate. Relevance ranks; everything else describes. The moment you sum them you've invented weights the recruiter never agreed to and can't see.

Not fabricating negatives. A resume that fails to parse, or that has too little detail to assess, is not a zero — it's unknown, and it stays visible. An assessability question separates "can't be judged" from "judged and weak." Silent zeros are how real candidates disappear.

Keeping writing diagnostics out of ranking. Formulaic-phrasing detection is in the library, labeled experimental, and structurally barred from relevance. Style-based AI detection has a documented false-positive bias against non-native English writers, so it can inform a recruiter's read and never move a rank.

Revisions. Change a criterion and old answers become stale rather than silently mixing with new ones. Getting that right meant versioning every question and role brief.

What we learned

Jev turned out to be the right shape for this specifically because it doesn't write prose. Typed answers with probabilities are inspectable and cacheable. There's no explanation to trust or distrust — just a rubric position, a distribution, and confidence. When we wanted evidence, we asked a separate question for a passage ID and checked it against the real text rather than letting a model narrate.

We also learned that "no hidden weights" is a constraint that improves the product rather than limiting it. Every time we wanted a shortcut, it was a shortcut that would have hidden a judgment from the recruiter.

What's next

Durable background processing, so a large pool survives a closed tab. Evidence linking to public work. And calibration: our rubrics are reasoned prototypes, not validated hiring measures, and we'd rather label them that way than imply otherwise.

Built With

  • jev
  • next.js
  • node.js
  • openrouter
  • tailwindcss
  • typesafe-ai
  • zod
Share this project:

Updates

Submission history