Tailors a résumé, a match analysis and a cover letter to a specific posting — and refuses to fabricate a single line of it.
The challenge
Tailoring an application properly takes thirty to forty minutes, which is why almost nobody does it and almost everybody sends the same résumé eighty times. The obvious fix — point a language model at it — creates a worse problem. A model asked to make a candidate look like a good fit will happily invent an employer, stretch a date, or claim a skill. That gets people fired after they are hired, and it makes the product that did it to them a liability.
What we built
A FastAPI service over SQLAlchemy with a tracked application pipeline
(saved → tailored → applied → interview → offer → rejected), plus a
self-contained dashboard served from the same app.
The anti-fabrication guardrail is the product. The engine reorders, reframes
and rewords what the candidate actually did. It never adds an employer, a date or
a skill. Genuine gaps surface as missing_keywords with an honest
recommendation. Output is schema-constrained JSON validated straight into
Pydantic models, and signup requires accepting a versioned Truthfulness &
Accuracy Attestation, recorded per document version in a consent table.
Matching is two-stage on purpose. A fast, explainable score — skill coverage 75%, title match 25% — pre-filters every posting; only candidates clearing a ≥75 gate reach the model. That keeps the unit economics survivable at volume.
Job sources are legitimate APIs only. Remotive, Arbeitnow, The Muse and Greenhouse ATS boards need no key; USAJobs, Adzuna and JSearch add breadth. We declined to scrape LinkedIn or Indeed — it violates their terms and gets users’ accounts banned. For the same reason, auto-submit is not built: applications are pre-filled for a human to review and send.
The security model is the boring, correct one. PBKDF2 password hashing,
opaque bearer sessions with an enforced expires_at (a token with no expiry is
treated as expired — fail closed), password change revoking every session
immediately, and self-scoped /me/* endpoints so a user can only ever see their
own data. Rate limiting covers every anonymous-reachable endpoint, with per-IP
budgets counting all attempts and the per-account login budget spent only by
failures.
Capabilities this demonstrates
- AI & Automation — structured outputs, hard guardrails, cost-aware two-stage design
- Secure Software Engineering — session expiry, threat-aware rate limits, self-scoped endpoints, versioned consent

