1You're the recruiter. You've hired for this role; these 12 weren't progressed. Click Close role.
2Click any applicant to open their feedback. Try Aroha (normal), Ahmed (held), Sam (edit the message).
3In an open applicant, switch to What they see to compare with today's template rejection.
Closing role
Junior Frontend Developer
Kauri Labs · Auckland CBD · Full-time · 147 applicants
✓ Hired: a candidate with 1 year of commercial React + TypeScript experience at a SaaS startup.
No API key, so Close role replays a recorded run: a real, unedited run from 29 Oct 2026, with its measured timings. to run it live, re-draft or check edits.
Would be ghosted
12
today
Personal feedback ready
0
checked by critic
Held for your review
0
nothing flagged
Time
–
vs ~1.6h by hand
How it works
The model judges. Code decides.
Two Gemini models do the work: a writer (2.5 Flash, fast) and a critic (3.8 Flash, stronger, for the safety judgement). Everything that decides what can be sent is plain code: every quote checked against the CV, every job checked to exist, every status set by rules, and a human approves each message.
Recruiter
Closes the role
One click. Optional private note per applicant: the real reason.
Gemini · writer
Drafts feedback
Each requirement checked against the CV, with quotes. Show-it / build-it next step. Better-fit ZEIL roles.
Code
Verifies
Every quote must be word-for-word in the CV. Job IDs must exist. No links. Fails → sent back.
Gemini · critic
Reviews
Human Rights Act grounds and proxies, made-up claims, template filler, false promises, the note, CV manipulation.
Code
Decides status
Problems → one rewrite → re-check. Ready · fixed · needs review · held. Unlawful reason → held, never reworded.
Does it work? Measured, not claimed
8–12%
wording shared between messages
a template shares 100%
~7
CV facts cited per message
every one verified by code
27/27
critic eval cases passed
bias, proxies, made-up claims, notes
0/5
CV prompt-injection attacks worked
5/5 flagged to the recruiter
Source: eval/RESULTS.md in the repo; every script runs against the live API.
What I changed my mind about
The idea
Started with detecting hidden prompts in CVs. Dropped it: already solved by applicant tracking systems, and it rarely works on current models. Ghosting is a problem people actually live with.
Where the risk is
I expected the AI to write biased reasons. It never did. 4 of 12 recruiter notes were unlawful, and the writer covered for one with an invented reason. So: check notes and edits, and hold, never reword.
Thinking mode
Assumed the critic needed to think to catch subtle proxies. The eval said no: same or better accuracy (27/27 vs 26/27) at 3× lower latency, and thinking was over-cautious. Switched it off.
When the shared key stalled
At lunch the hackathon's shared Gemini key took 40s+ per call, so closing a role took 5 minutes. I measured the options and split the work: writer on Gemini 2.5 Flash (no thinking, ~5s), critic on Gemini 3.8 Flash (~2s). Re-ran every eval: still 27/27, still 0/5 attacks. Now ~14s for all 12.
Next, inside ZEIL
A “close listing” action, with messages delivered in-app and one-swipe apply on suggested roles. ZEIL gets a metric it can't see today, closure rate: the share of applicants who heard back, per employer.
This tab runs the models live on your role and CVs, so it needs .
Step 1 · The role
Paste the job ad
Step 2 · Applicants not progressed