Job Search Dispatch
A local job-search workspace that turns a captured job ad into an evidence-grounded application draft, with the applicant in control of every decision and submission.
Built and iterated as a personal project · 2026 · Private source repository
The problem: continuity between finding a job and applying
A job-search workflow crosses several disconnected surfaces: the job board, a record of past work, a model conversation, an application draft and a follow-up list. The difficult part is carrying the right facts and decisions between them without losing the original ad or letting a fluent draft overstate the applicant's experience.
I developed Job Search Dispatch from an AI-generated React MVP into an integrated local application. The work spans a Node.js server, a Chrome browser bridge, reusable evidence records, model routing and the review experience. A ticket holds the job, the model's recommendation, the applicant's decision and the resulting materials together.
One ticket, from capture to review
- 01
Capture the job the applicant is already reading
For SEEK, the extension reads visible metadata and the complete job description from a matching open tab. LinkedIn first tries a credential-free public request, then falls back to the bridge. Imported text remains editable; the applicant confirms whether the ad is still open.
Open job tab → browser bridge → editable job ticket
- 02
Separate a recommendation from a decision
Triage returns structured job details, fit, gaps and an APPLY, NETWORK or SKIP suggestion using confirmed candidate records. The applicant chooses the route. Pipeline queues surface tickets awaiting a decision, drafts in progress and follow-ups due.
Confirmed evidence → model suggestion → human route choice
- 03
Draft with evidence, then check the result
Application drafting uses confirmed evidence explicitly allowed for that purpose. The cover-letter writer is followed by a separate verifier call and deterministic validation. A hard validation failure permits one targeted repair; a result that still fails is not saved as the new letter.
Writer → verifier → validation → at most one repair
- 04
Keep the last mile human
The applicant can inspect paragraph evidence, edit the letter, review model-call details and copy clean text. Submission stays manual. The workspace keeps the ticket and next action available for the follow-up.
Review → edit → copy → manual submission
Decisions I can defend
Read an existing browser tab instead of building a crawler
The applicant already has the rendered job page. A narrowly scoped extension can bring that content into the same Fetch from URL flow while preserving an editable full description and a shared trace ID for failures.
Tradeoff accepted: The extension must be installed and a matching job tab must remain open. It does not open pages, crawl in the background, autofill forms or submit applications.
Make candidate evidence an explicit drafting input
Each evidence record carries confirmation, permitted uses and a claim boundary. Triage matches are intersected with confirmed application-draft evidence before entering the cover-letter prompt. Reusable fragments must resolve to that same allow-list.
Tradeoff accepted: Preparing evidence takes effort. Valid references establish eligibility, not whether every sentence is true; model verification and final human review still have distinct jobs.
Treat model calls as operations that can fail
Stage and trace diagnostics, server-owned deadlines and cancellation make a long-running call inspectable. Failed or cancelled attempts preserve existing work. Writer, verifier and optional repair receipts explain which calls ran and what cost information is available.
Tradeoff accepted: A successful cover-letter run uses two model calls, or three with repair. The fixed Anthropic review route requires its own credential even when the writer uses a custom provider; available cost figures are estimates rather than invoices.
A concrete iteration: whose number is it?
A job ad can contain numbers that say nothing about the applicant's achievements. The numeric check needed to distinguish a number present in the ad from one supported by the evidence cited in a letter paragraph. I tightened the check so numeric support comes from that paragraph's cited, confirmed application-draft evidence claims, rather than the job description or unrelated profile text.
I also made a failed generation explain its stage and blocking checks instead of leaving the user with a generic failure. Numeric findings identify the paragraph, sentence and unsupported token while keeping the previous saved letter intact. Regression cases cover the source boundary and the failure diagnostics.
This remains a deterministic token check, not a proof of meaning: finding the same number in an eligible claim does not establish that a generated sentence describes it correctly. That distinction is why the verifier and human review remain part of the workflow.
Where the data goes
- Canonical candidate records live in a versioned profile file outside the repository, with owner-only storage and backups. Tickets, provider settings, keys and a capped model-attempt history persist in browser localStorage.
- Model calls leave the machine: the local server sends the selected credential and operation-specific job context plus eligible candidate data to the relevant provider. Local storage does not make generation an offline operation.
- Prompt builders exclude contact details, raw attachments and full extracted résumé text. Operation-specific evidence selection happens in the browser; it is not a separate server-authoritative projection service.
- Attempt history can contain generated personal application text. It retains at most 50 attempts and excludes full prompts and API keys; the user can export or clear it explicitly.
What I verified
For this case study, I ran npm run verify against an isolated copy of the committed source on 8 September 2026: all 210 deterministic tests passed. The suite covers evidence eligibility, provider routing, cancellation and timeout behavior, cover-letter validation, failure receipts and fixture isolation.
The portfolio screenshot shows the running application's built-in synthetic fixture data. Its example companies, ticket counts and fit scores illustrate the interface; they are not real applications or outcome metrics. Fixture mode prevents model calls and persistent writes.
Current scope and limitations
- This is a personal local application with a private source repository. No user-adoption, interview-conversion or time-saved result is claimed.
- The verification above does not establish live model quality or re-test SEEK and LinkedIn extraction against current job-board pages. Provider responses and page structures can change.
- Later human edits are not semantically re-verified. Every final claim still needs review before the applicant uses it.
- There is no automatic submission, cloud sync or résumé upload/parser workflow. React and Babel load from a CDN, so the no-build local runner still needs internet access.