Post

Job Hunter Agent: Product Planning

How Job Hunter Agent went from three articles to a live homelab app in two days, and the phases and steps that came after.

Job Hunter Agent: Product Planning

Job Hunter Agent was planned in an afternoon and built in two days, which only worked because the plan was small and the platform underneath already existed. This post records the phases as they actually happened and the steps that make each one checkable.

Product roadmap

PhaseDeliversStatus
0. PlanRead the HunterAgent articles, decide what to keep and what to refuse, write the planDone (2026-10-21)
1. Core agentAgents, truthfulness checks, review queue, UI, tests, local run against the real LLMDone (2026-10-21)
2. Homelab deployImage through the platform’s build gates, Argo CD app, Keycloak sign-in, LinkedIn sidecar, SupabaseDone (2026-10-22)
3. Daily useProfiles, schedules, run history, review-page upgrades, company facts, SlackDone (2026-10-22)
4. HardeningTracing export, alerting, retention, pacing between LinkedIn requestsNot started

Phase 1 steps

StepDoesReposDone whenStatus
1Domain models, LLM client with JSON-schema outputjob-hunter-agentA score comes back from the local modelDone (2026-10-21)
2Agents: scorer, resume optimizer, cover letter, research, contactsjob-hunter-agentA draft exists for a sample jobDone (2026-10-21)
3Truthfulness checks and the approval gatejob-hunter-agentA draft with an invented tool can’t be approvedDone (2026-10-21)
4Review UI, resume import and exportjob-hunter-agentApprove a draft and download it as DOCXDone (2026-10-21)
5Evaluation on six real postingsjob-hunter-agentdocs/evaluation.md writtenDone (2026-10-21)

Phase 2 steps

StepDoesReposDone whenStatus
6Keycloak client and secrets in OpenBaoinfra-localkv/platform/job-hunter has every keyDone (2026-10-22)
7Argo CD app, sidecar, PVC, ingress, network policyhomelab-gitopsjobs.platform.home.cloudutsuk.com redirects to KeycloakDone (2026-10-22)
8Image through the platform’s build gatesjob-hunter-agent, homelab-gitopsCI commits a signed digestDone (2026-10-22)
9LinkedIn sign-in inside the clusterhomelab-gitops--status reports a valid session after a pod restartDone (2026-10-22)
10Supabase schema on the cloud free tierjob-hunter-agentIntegration test passes against itDone (2026-10-22)

Phase 3 steps

StepDoesReposDone whenStatus
11Several search profiles, each with a resume, mode and tonejob-hunter-agentTwo profiles draft with different resumesDone (2026-10-22)
12Review page: skills table, shortlist confidence, collapsible draftsjob-hunter-agentTailored resumes are re-scoredDone (2026-10-22)
13Setup page: collapsible profiles, editable resumes, run historyjob-hunter-agentEvery run appears with its countsDone (2026-10-22)
14Evaluate / Re-evaluate per jobjob-hunter-agentA rejected job returns to pending reviewDone (2026-10-22)
15Company facts: About page, Wikidata, Google Newsjob-hunter-agentRevenue by year shows for a listed companyDone (2026-10-22)
16One scheduled job per profile; Slack run reportsjob-hunter-agent, infra-local, homelab-gitopsA test message arrives; three profiles run hours apartDone (2026-10-22)

MVP definition

The MVP was “one profile, one resume, a queue I can approve from”, running on my laptop against the real local model. It deliberately had no scheduler, no Slack and no deployment. The test of the MVP was the evaluation in step 5: six real postings, three resume modes each, and a count of how often the truthfulness checks fired. That result (skills mode was clean, keyword mode added tools I don’t have) changed the defaults before anything was deployed.

Release milestones

MilestoneDateEvidence
First draft from the local model2026-10-21Smoke script output
Evaluation report2026-10-21docs/evaluation.md
Live on the platform cluster behind Keycloak2026-10-22Argo CD Synced/Healthy, Let’s Encrypt certificate
First live LinkedIn discovery from the cluster2026-10-222 postings in 23 s, nothing stored
Scheduled per-profile runs with Slack2026-10-22Test message sent, three jobs scheduled

Backlog structure

There’s no tracker. The backlog is the conversation with myself plus three places in git: the phase tables above, docs/plan.md in the repo, and TODO callouts in these posts. That’s enough for one person. If a second contributor joined, I’d move it to GitHub Issues with one label per area of this playbook.

Prioritization approach

Use drove priority. After the first day of real runs I asked “what annoyed me today?” and built that next: the resume dropdown was empty with no explanation, discovery crashed with an out-of-memory browser, warnings read as nonsense (“Mentions Own”). Those went ahead of anything on a roadmap. Safety items (the approval gate, the truthfulness checks) were never traded away for features.

Budget and resource planning

ItemCost
LLMThe homelab’s local model; electricity only
ComputeOne pod on the platform cluster: 150m CPU and about 1.2 GiB requested, 3.8 GiB memory limit
DatabaseSupabase free tier
Company facts and newsWikidata and Google News, free
SlackExisting workspace and webhook

The real budget was my time: two days of building with an AI coding assistant, plus review.

Risk and dependency management

RiskLikelihoodImpactMitigation
LinkedIn restricts the accountMediumHighRead-only, ≤5 postings per keyword, profiles hours apart; it already happened once during testing (HTTP 429)
The model invents experienceHighHighDeterministic checks block approval
LinkedIn changes its page layoutMediumMediumDeterministic header parsing with an LLM fallback
Supabase free tier pauses the projectMediumMediumA daily upkeep job queries it every day, weekends included; an alert fires if the job stops succeeding
Local model is downLowMediumRuns fail visibly in the history and Slack

Supabase pauses a free project after a week without activity. Weekday runs alone would cover that, but not a long holiday with schedules turned off, so the daily upkeep job (retention clean-up and backup export, 03:30 every day) doubles as the keep-alive. If it fails for two days, JobHunterUpkeepFailing fires, leaving five days to fix it before the project pauses.

Change-control process

For a personal project the process is light but real:

  1. A new piece of work goes into a phase table above before it’s built.
  2. Small changes go straight to main in job-hunter-agent; anything with a database migration goes through a pull request, because the migration has to be applied to Supabase before the image deploys.
  3. Platform changes (homelab-gitops, infra-local) always go through a pull request that I merge.
  4. Each change ships with its docs: README, these posts, and a lesson when something cost real time.

Checklist

  • Phase 4 steps written with a “done when” for each
  • Every shipped feature has a row in a phase table
  • Evaluation re-run after changing prompts or the model
  • Risk table reviewed monthly, especially the LinkedIn row
  • Supabase inactivity policy checked
  • Migrations always applied before merging the code that needs them

This post is licensed under CC BY 4.0 by the author.