
02 · Systems · Automation
Internship Discovery & Application Tracker
Finds internship postings, scores each one with written reasons, and tracks every application from mailbox updates. It never submits anything.
Public demo: 16 fictional records scored by the real scoring code. My own applications never leave my machine.
01Problem
Internship postings are scattered across company career boards. Keeping a spreadsheet in step with an inbox full of receipts, assessments and rejections is slow and error-prone.
02What I built
I designed and built the whole system, and I use it for my own search. A scheduled GitHub Actions job polls Greenhouse, Lever, Ashby, company pages and the Simplify list, then scores every posting against a profile with written reasons. On my Mac, a local agent sends notifications, a Flask dashboard replaces the spreadsheet, and a 15-minute Apple Mail sync moves each application to its new stage.


03Data flow
- Public job boards
- Actions poller: dedupe, score
- JSON review queue
- Mac agent + mail sync
- Local dashboard
04Decisions
Place work by privilege
Credential-free polling runs on short-lived cloud runners. Anything that needs mailbox or notification permissions stays on my machine. The two halves only exchange JSON files, so neither can break the other’s schedule.
Explainable scoring over ML
Scores come from a deterministic rule engine, so every score and every rejection carries a stated reason I can audit.
Merge order must not matter
Apple Mail’s locale-formatted dates once sorted “Thursday” after “Tuesday” and let older statuses overwrite newer ones. Every event is now normalized to an ISO date, and the merge gives the same result in any order.
05Validation
- A 13-case fault-injection suite found four failures. All are fixed and kept as regression tests.
- Fixed a dedupe key that merged distinct requisitions with identical titles (about 19% of listings on one run).
- Frontend tests compare all 128 demo record/status combinations against the Python merger.
06Limits
Mail coverage is limited to the Inbox, Archive and job-named folders. JSON interchange works at hundreds of rows but would be the first thing to replace at scale. Status precedence is hard-coded.