Autonomous job search — verify, apply, disclose
doingStop posting dead roles. Then compose a complete application per live role — CV, ten case studies, the design→code angle — and state plainly that an agent assembled it for Mihael.
Task graph
Ordered the way the dispatcher would work it. Each row shows the loop's own verdict —
this is the same computation scripts/next.mjs runs, not a second opinion.
- js-001 Liveness checker — open the page, decide if the role is still open todo
6 acceptance criteria
- scripts/job-liveness.mjs takes lead URLs and returns active / closed / unreachable per URL
- Classifies from page content, not just HTTP status — a 200 that says 'this role has been filled' is closed
- Handles the JS-rendered boards (Go Fractional, fractionaljobs.io) via headless Chromium, reusing the browser resolution from mobile-audit.mjs
- Never reports 'active' when it could not actually read the page — unreachable is its own verdict
- Records the evidence phrase that decided each verdict, so a wrong call is diagnosable
- Exits 0 with a JSON report; a run where every URL is unreachable exits non-zero
The root cause of dead leads: nothing ever opens the posting. Leads come from board index pages and search results, both of which keep stale entries for weeks.
The third acceptance criterion is the one that matters most. Distinguishing “could not read the page” from “the role is gone” is the whole value — a checker that quietly reports unreachable pages as closed would silently delete good leads, and one that reports them as active changes nothing.
Chromium is already resolved by
scripts/mobile-audit.mjs; reusefindChromium()rather than writing a second copy.Lane 1: it is a script that reads and reports. Nothing it does is outward-facing.
- js-003 Publish the CV at a stable URL todo
4 acceptance criteria
- cv-interactive.pdf resolves at a public URL on foogy.xyz and stays put
- Linked from /hire and from the site nav or footer — reachable without knowing the path
- The URL is recorded in the dossier so applications never hardcode a guess
- Filename carries no date or version that would make the link go stale
Blocking, and currently impossible to work around.
cv/cv-interactive.pdfsits at the repo root ofmfugaj/foogy.dev. Astro serves onlypublic/, which contains exactly one file —favicon.svg. The CV has no URL. Nothing can link to it, so no application can attach it.The stable-filename criterion is not fussiness: this URL will sit in sent applications for months, and
cv-2026-07.pdfguarantees a dead link in every one of them the next time the CV is updated.Runs in parallel with js-001 — different repo, no shared surface.
- js-005 The disclosure statement todo
6 acceptance criteria
- One paragraph, used verbatim in every application, stating that an autonomous system assembled it for Mihael
- Accurately describes what the system did and what Mihael did — including that he approved it before sending
- Reads as capability, not as a disclaimer or an apology
- Names what the system actually is, so a curious reader can ask about it in an interview
- Under 60 words — a paragraph nobody finishes is a disclosure that did not happen
- Published as src/docs/private-job__disclosure.md with the reasoning kept alongside it
The hardest writing in this mission and the shortest.
It has to do three incompatible-seeming things at once: be completely honest about what a machine did, avoid sounding like a legal footnote, and land as evidence of the exact skill being applied for.
Accuracy outranks impressiveness. The system verifies, composes and cites; Mihael reviews and approves every send. Overstating the autonomy to sound more impressive would be a lie told to look good at building honest systems, which is self-defeating in a way worth naming here rather than discovering later.
The 60-word cap is a real constraint. This sits in a cover note that a hiring manager reads in fifteen seconds; a paragraph they skip is worth nothing.
Runs in parallel with js-001 and js-003.
- js-002 Scout posts verified-open roles only todoneeds js-001
5 acceptance criteria
- Every role in a posted shortlist has a recorded active verdict with its checked-at timestamp
- Closed roles move to a Closed section with the evidence phrase, not deleted silently
- Unreachable roles are posted but explicitly flagged as unverified
- brain__job-search-strategy.md updated with the verification rule so the scout prompt and the strategy agree
- A shortlist with zero surviving roles says so plainly rather than padding with stale entries
Wire the checker into the daily scout and change the rules it works from.
Keeping closed roles visible with their evidence matters more than it looks. A role that silently vanishes is indistinguishable from one the scout never found, and a month of that leaves nobody able to say whether the shortlist is thorough or just lucky. The Closed section is also how the board-staleness patterns in the lead docs — “web3.career’s design board is stale” — become measurable instead of anecdotal.
The empty-shortlist criterion is deliberate. A day with no live roles is information; a day padded to look productive is noise.
- js-004 The application dossier — one canonical set of links and angles todoneeds js-003
5 acceptance criteria
- One document holding the CV URL, all ten case study URLs, and a one-line description of what each proves
- Maps role types to the two or three case studies that best answer them — design systems, marketplace, e-commerce, web3, design→code, PM
- States the design→code wedge in one sentence usable verbatim in a cover note
- Every link verified to resolve, not assumed
- Published as src/docs/private-job__application-dossier.md
Ten live case studies exist and applications currently reference one or two, chosen ad hoc. The dossier makes the choice deliberate and repeatable.
The role-type mapping is what stops every application citing Zevo because it is first in the list. A fractional PM role and a design-systems contract want different evidence, and
brain__job-search-strategyalready records the pattern worth answering: case studies that show diagnosis and decisions, not just final screens.The verify-every-link criterion exists because this document’s entire job is to be the thing nothing else has to guess at. One dead link in here propagates into every application that follows.
- js-006 Application composer — one complete application per live role todo
6 acceptance criteria
- Given a verified-open role, produces a cover note, the matched case studies with reasons, the CV link, and answers to the posting's own questions
- Names at least two specific case studies and says why those two for this role
- Carries the disclosure verbatim
- Every factual claim traces to the CV, a case study, or the vault — no invented experience, dates, employers or metrics
- Flags anything the posting asks for that Mihael does not have, rather than papering over it
- Output is a reviewable draft, never a submission
The composer. Reads a role, assembles the application, stops.
The gap-flagging criterion is the one that makes this trustworthy. A composer that quietly writes around a missing requirement produces applications that fall apart in the first interview.
brain__job-search-strategyalready records one such gap honestly — motion design is a skip, not a stretch — and that judgement has to survive into the drafts.“Never a submission” is a hard boundary in the code path, not a habit. js-007 sends; this task cannot.
- js-007 Submit — one approval per application, permanently todoneeds js-006
5 acceptance criteria
- Each submission recorded with the company, role, timestamp, and Mihael's explicit approval before sending
- Never submits a batch — one company, one approval, one send
- Where a board forbids automation or gates submission behind a CAPTCHA or login, hands over a ready-to-paste application and does not attempt a workaround
- Applied roles tracked so the same company is never applied to twice by accident
- A refused or failed submission is recorded as such, not retried silently
Permanently lane 2. No graduation path, regardless of record.
An application cannot be recalled. It reaches a real hiring manager at a company Mihael may genuinely want to work for, and a bad one costs that company permanently — there is no revert commit for a first impression.
So: one approval per application. Not a daily batch, not a digest, not “these four look fine.” The per-company granularity is the point, because the judgement being made is about that company.
Respect the boards’ terms. Where automated submission is prohibited, the answer is a complete application handed over ready to paste. Not a headless browser working around a CAPTCHA. A system whose pitch is “I build honest autonomous tooling” cannot have its first act be circumventing someone’s terms of service — and the disclosure would make that circumvention a matter of record.
The duplicate-tracking criterion is unglamorous and will save real embarrassment: the scout re-flags the same roles across weeks, and applying twice reads as carelessness by exactly the system meant to demonstrate the opposite.
The spec
Autonomous job search — verify, apply, disclose
The daily scout works and has been running since late June. Two things are wrong with it and one thing is missing.
Wrong: it posts roles that are already closed. Leads are collected from board listings and search results without ever opening the posting, so a role filled three weeks ago reads exactly like one posted this morning. Time gets spent on dead ends, and the lead docs slowly lose their authority.
Also wrong: it stops at “here is a lead, here is your angle.” Every application is still hand-assembled from scratch.
Missing: the thing that would make this more than a scraper — actually applying, with the full body of work attached, and saying openly that an autonomous system assembled it.
Two findings that shape the plan
The CV is not published. cv/cv-interactive.pdf exists in mfugaj/foogy.dev
at the repo root. Astro serves only public/, which contains exactly one file:
favicon.svg. So the CV has no URL and cannot be linked from anything. That is
task one — “link to the CV” is not possible until the CV is reachable.
Ten case studies are live and linkable at /cases/<slug>: zevo, wire,
samsung-eshop, agent4, depunks, haas, hive3, liberoverse, sancta-domenica,
traverse. They are the strongest asset here and no application currently uses
more than one or two of them.
Goal
A daily shortlist where every posted role has been confirmed open by opening the page, and a complete, ready-to-send application per role — carrying the CV, the relevant case studies, and an explicit statement that an autonomous system assembled it on Mihael’s behalf.
On the disclosure
This is not a compliance footnote bolted on at the end. It is the point.
Foogy wants companies to know he runs this daily. A designer who built an
autonomous job-search engine that verifies listings, composes applications and
cites its own sources is demonstrating the exact “design→code, ships with AI
tooling” edge that brain__job-search-strategy identifies as his wedge. The
disclosure is the portfolio piece.
Two things follow, and both are constraints rather than preferences:
- It must be accurate. If Mihael approved the application before it was sent, the disclosure says so. Claiming more autonomy than actually happened would be a lie in service of looking impressive, which defeats the entire purpose.
- It will filter him out somewhere. Some hiring managers will read “assembled by an agent” as a red flag no matter how it is worded. That is a real cost, it is being accepted deliberately, and it should not be hedged away with language so soft nobody notices the claim.
Scope
- Liveness verification on every lead before it is posted.
- The CV published at a stable URL in
mfugaj/foogy.dev. - One canonical application dossier — CV link, ten case study links, the angle per role type — that every application draws from.
- A disclosure statement, written once, used verbatim.
- Per-role application composition: tailored cover note, matched case studies, answers to the form’s questions.
- Submission, one approval at a time.
Non-goals
- No mass applying. A hundred generic applications is the opposite of the signal this is meant to send.
- No new job boards. The sources in
brain__job-search-strategyare enough; the problem is verification and follow-through, not supply. - No rewriting the case studies.
case-study-mediaowns that. - No impersonating a human reviewer. The disclosure is the mechanism; there is no version of this mission where the agent pretends not to be one.
Constraints
- Never submit an application Mihael has not approved. Each one, individually. Not a batch, not a daily digest — one company, one approval. An application is irreversible and outward-facing: it cannot be recalled, and a bad one costs that company permanently.
- Some boards prohibit automated submission in their terms, and others gate it behind a CAPTCHA or a login. Where submission is not permitted or not mechanically possible, the deliverable is a complete application ready to paste — never a workaround.
- Never invent experience, dates, employers, or metrics. Everything in an application traces to the CV, a case study, or the vault.
- Never apply to roles that fail the hard filters in
brain__job-search-strategy— remote, part-time/fractional/contract, direct (no agencies).
Acceptance (mission-level)
- Zero dead roles in a posted shortlist, verified by opening each page.
- The CV resolves at a public URL and is linked from every application.
- An application names at least two specific case studies chosen for that role, with reasons.
- The disclosure appears in every application, in the same words.
- Nothing is ever submitted without a recorded per-application approval.
The line
Verification, dossier-building and composition are lane 2 and reversible — a bad draft costs nothing but a rewrite.
Submission is permanently lane 2 with no graduation path. It is irreversible, it is outward-facing, and it represents Mihael to a company he may want to work for. Ten clean approvals do not earn the right to send the eleventh unattended. This is the same boundary as a mainnet deploy, for the same reason.