← the lab · the atelier

Sheet 60 · agent systems

jobsys

The system I use to write job applications: it finds postings, scores them against a fixed rubric, drafts the CV and letter from my own profile, checks each claim against its source and tracks what was sent.

Question

Can a job application be written without a single invented sentence?

The job market is rough right now. A lot of people around me are looking for work, and the search takes up most of their time. I had also started to notice that a lot of hiring is screened by AI, so I thought: why not use AI to help with the job search too?

My first version collected job postings and was meant to turn the good ones into applications. When I audited it, the biggest gap was that it could not tell a true claim from an invented one: its reviewer read the drafts without ever seeing my profile. So I rebuilt it from scratch.

Approach

Profileone numbered row perfact about meJob postingthe only source forfacts about the companyDraftCV, cover letter, shortmessage; model with notools or webGroundingevery sentence mustcite a row; codeapplies four fixedrulesRewriteflagged sentences, fromthe profile onlyCold reada reviewer playing ahiring manager, fortoneGrounding againsame rules, on thereviewed textPDF checkpage count, readabletext, the Turkishletters in my namethe model names rows, codedecidesflaggedflagged again?Profileone numberedrow per factabout meJob postingthe only sourcefor facts aboutthe companyDraftCV, coverletter, shortmessage; modelwith no toolsor webGroundingevery sentencemust cite arow; codeapplies fourfixed rulesRewriteflaggedsentences, fromthe profileonlyCold reada reviewerplaying ahiring manager,for toneGroundingagainsame rules, onthe reviewedtextPDF checkpage count,readable text,the Turkishletters in mynamethe modelnames rows,code decidesflaggedflaggedagain?
FIG. 1The drafting chain and its grounding gate. One application moving through the chain. The four rules: a sentence with no source is an error; a fact about me must point to a row cleared for outside use; a fact about the company may only point to the posting; every number in a sentence must appear in a row it cites.
Source: jobsys sheet, Approach; jobsys apply/chain.py order and apply/grounding.py rules (sources.md)

The new system, jobsys, has one source of facts: a profile file with one numbered row per fact about me. Old CVs no longer count.

A large hosted model drafts from those rows and the job posting. The step the system is built around is grounding, which ties every sentence back to a source. The model names the rows each sentence rests on, but plain code makes the call. A number that is not in a cited row fails even when the model calls it supported.

Results

found in the first draftfound after the cold readErrors flagged, by the pass that found them02468Run 1 · 23 Oct3 found · 0 leftRun 2 · 23 Oct4 found · 0 leftRun 3 · 24 Oct3 found · 0 leftRun 4 · 2 Nov7 found · 0 leftevery error fixed before the last checkfound in the first draftfound after the cold readErrors flagged, by the pass that found them02468Run 1 · 23 Oct3 found · 0 leftRun 2 · 23 Oct4 found · 0 leftRun 3 · 24 Oct3 found · 0 leftRun 4 · 2 Nov7 found · 0 leftevery error fixed before the lastcheck
FIG. 2Errors grounding caught in each full run. In three of the four runs, text reworked during the cold read still had errors (hatched). 0 left means the rules found nothing more, not that a person read every line.
Source: jobsys run.json x4, grounding passes and errors_remaining, read 2026-11-05 (sources.md)

I have run the full chain four times. Every flagged error was fixed before the last check, which passed every time. Later edits to the documents fall outside these numbers.

What I learned

Run 1123last round's changes went in unreviewedRun 2123sameRun 3123sameRun 4123samecap: 3 roundsa review roundRun 1123last round's changes went in unreviewedRun 2123sameRun 3123sameRun 4123samecap: 3 roundsa review round
FIG. 3The review loop never ended on its own. Each square is one review round. The exit rule ended none of the four runs; all of them stopped at the three-round cap.
Source: jobsys run.json x4, review.rounds_run and review.exit (sources.md)

The model never wrote a clean draft, so the check is what makes the documents usable. It works because code, not the model, decides what counts as an error. Every rewrite needs checking again.

The review loop did not work as planned: its exit rule never ended a run, so the last round's changes went in unreviewed. Keeping the reviewer away from fact-checking is still deliberate: a reviewer that never sees the sources cannot catch invention, which is where the old pipeline failed.

Open questions

  • For someone who builds evals: grounding reports what it catches, not what it misses. Would planting false claims in drafts be a cheap way to measure the misses?
  • For someone who designs agent loops: the reviewer hit its cap every time. Is the exit rule wrong, or should a cold-read reviewer have no exit rule at all?

← PInspect · all lab sheets · Myna →