TL;DR
The most important capability of an autonomous agent that acts on your behalf is a designed ability to refuse to finish. My job-application fleet has filed 734 applications and blocked 155 — every block carrying one of 19 named reasons in a status column, not a guess on a form. The mechanism is four parts: a facts file the agent may only quote verbatim, explicit STILL UNKNOWN — do not guess markers for missing values, blocked as a first-class outcome, and an escalation file that converts each refusal into a one-line question for me. On 2026-07-31 that protocol blocked three applications in a row over a single ZIP code the agent could trivially have invented — and re-filed two of them the same day, the moment I supplied the real one.
Everyone building agent products right now is selling autonomy. The trend pieces this month — Forbes just called AI agent startups "the new solo-founder playbook" — measure agents by how much they do without you. I run a fleet like that, and I want to make the opposite case from inside it: the part of my system I trust most is the part that stops.
The system in question is my career engine — a scheduled fleet that sources roles, verifies postings against live ATS pages, writes covers, and files applications on my behalf. Filing a job application means asserting facts about a real person on forms that sometimes feed background checks and export-control screening. An agent that fabricates there isn't drafting bad copy; it's hallucinating data into the real world with my name attached.
So the fleet runs on a refusal protocol. Here is what it looks like, what it costs, and the one-day incident that proves the trade.
The scoreboard: 734 filed, 155 refused#
As of this morning, pipeline.csv — the fleet's single ledger, one row per role — holds 1,552 rows. Of those, 734 are applications actually submitted. 155 are blocked: the agent started, hit something it is forbidden to answer or unable to do honestly, wrote down exactly why, and stopped.
The blocks aren't one bucket. The status column carries 19 distinct blocked-* values, and the distribution tells you what actually stops an autonomous agent in the field:
Three families matter:
| Family | Examples | Rows | What it means |
|---|---|---|---|
| Honesty refusals | blocked-unknown-facts, blocked-month-precision, blocked-citizenship, blocked-ai-attestation, blocked-bot-detection |
~23 (+ most early bare blocked) |
The form demands a fact not on record, or an attestation the agent can't truthfully sign |
| Capability walls | blocked-hcaptcha, blocked-recaptcha, blocked-needs-live-human |
58 | The step genuinely requires a human — a CAPTCHA, a live interview gate |
| External limits | blocked-employer-ratelimit, blocked-tenant-app-limit, blocked-one-app-per-candidate |
10 | The other side's rules, respected rather than routed around |
The capability walls are unavoidable. The honesty refusals are the interesting ones, because every single one of them is a place where the agent could have proceeded. A plausible ZIP code, a rounded employment date, a checked "I am not using automation" box — nothing technical stops any of that. A rule does.
The facts file: quote, never compose#
The core of the protocol is one file, PERSONAL-FACTS.md, whose header is the whole design:
Use these verbatim on any application form. Never invent a value not on this page.
Every identity fact the fleet is allowed to assert about me lives there — name, email, address, work-authorization answers. If a form asks for something on the page, the agent copies it character-for-character. If a form asks for something not on the page, the agent has exactly one legal move: block the row, name the reason, and log the question for me.
Just as important is what the file marks as absent. It currently carries three entries flagged STILL UNKNOWN — do not guess: my exact education start and end dates, month-level employment dates, and the specific export-control classification some defense-adjacent forms demand. These aren't gaps the file forgot — they're gaps the file asserts, so that an agent hitting one knows the value is missing on purpose and guessing is a rule violation, not initiative.
This inverts the usual failure mode. An LLM's default under a required form field is to be helpful — and "helpful" with no recorded value means fabrication. You can't prompt that away with "be accurate," because the model can't distinguish a fact it half-remembers from one it invented. What you can do is make the set of assertable facts external, small, and quotable, so accuracy stops being a property of the model and becomes a property of the file. It's the same move as CLAUDE.md doctrine for stopping agent drift, applied to personal data with legal weight.
The day the protocol cost me three applications#
2026-07-31 is the cleanest test the system has produced.
Pass #99: the agent is deep in a Versaterm Greenhouse form — a public-safety software vendor whose process includes a CJIS fingerprint background check — and hits required street-address and ZIP fields. No street address or ZIP existed anywhere in career-engine. Blocked, screenshotted, logged.
Pass #100, same day: a Dropbox Senior Director of Revenue Operations form requires "the zip code of your primary residence." Blocked again, with the agent's own note in the ledger: "THIS IS THE SECOND CONSECUTIVE PASS BLOCKED ON THE SAME MISSING ONE-LINE FACT."
Pass #101, same day: a BILL application. Same required Postal Code field. Blocked a third time.
Three strong-fit applications, stopped in one day over a five-digit number any model can invent instantly. There are thousands of plausible Florida ZIP codes; the agent filed exactly zero of them.
Then the payoff, still the same day. I supplied the real address; pass #102 added one line to PERSONAL-FACTS.md, and the agent immediately re-filed Versaterm and BILL autonomously — even clearing Greenhouse's email-verification loop on its own, and catching an autocomplete widget that had silently selected "United States Minor Outlying Islands" instead of "United States." Dropbox stayed blocked, correctly: the ZIP was solved, but that form also demands month-level employment dates, which are still on the do-not-guess list. The blocker didn't vanish; it narrowed, and the ledger says precisely to what.
Total cost of the guardrail: a few hours of delay on three applications. Total benefit: zero fabricated personal data on forms feeding a fingerprint-grade background check. On a form like Versaterm's, an invented address isn't a typo — it's a discrepancy surfacing months later, in the worst possible room.
Refusing to lie about being an agent#
The subtler category is blocked-ai-attestation and blocked-bot-detection — eleven rows where the form itself asked, in effect, are you a human?
The first was a Grafana Labs Greenhouse form on 2026-07-09, whose final required field asked whether the applicant is "an AI or automated program." The fleet's standing rule: never answer that falsely, never accept a forward-looking pledge on my behalf (some forms now demand a promise not to use generative AI in interviews). The agent left the field unanswered, declined to submit, and logged the form for me to file by hand if I choose.
Nine more forms have hit the same wall since. I consider every one of those rows a compliance record: dated evidence that when an employer drew an honesty line, my automation stopped at it. As agent-driven applications become the norm this year, I'd rather hold that ledger than the opposite one.
Blocked is a status, not a failure#
None of this works if refusal is silent. A guardrail that just exits produces the pathology I keep writing about from the other side — agents that die without telling anyone, and watchers whose filters go quietly blind. The refusal protocol only earns its cost because every stop is loud and structured:
- The row stays in the ledger with
blocked-<reason>in the status column and the full context in notes — which form, which field, a screenshot path. - The reason is specific.
blocked-hcaptchaandblocked-month-precisionroute to completely different fixes; a bareblockedroutes to nothing. The vocabulary grew from one value to nineteen precisely because each new wall got a name. (After last week's drift postmortem, that vocabulary now also gets validated.) - Every block converts to a human task. A
BLOCKERS.mdfile accumulates the one-line questions only I can answer — "confirm the mailing address," "give a standing rule for anti-automation gates." The fleet's job is to shrink each blocker to its smallest possible ask; my job is a two-minute review, not a form-filling session. This is the same human-approval seam that governs the rest of my fleet, expressed as data instead of permission prompts. - Unblocking is one line, and it compounds. The ZIP answer instantly unblocked two applications and every future form that asks — plus, it turned out, part of the four
blocked-tenant-app-limitrows' successors. A fact added to the file is a guardrail question answered permanently.
That last property is the economics of the whole design. The do-not-guess list only ever shrinks. Refusals cluster early, get answered once, and stop recurring — while a fabrication would have "worked" instantly and then sat in a database as a liability forever.
The playbook, portable#
Nothing here is specific to job applications. If you're building any agent that asserts facts or signs anything on a person's or company's behalf:
- Externalize the assertable facts into one file the agent may only quote verbatim. Helpfulness under a required field is where fabrication lives.
- Mark known-unknowns explicitly. An absent value and a do-not-guess value are different states; the agent must be able to tell them apart.
- Make refusal a first-class outcome with a named, growing reason vocabulary — and validate that vocabulary so readers don't drift blind.
- Give every refusal an escalation path that shrinks it to the smallest human ask, in a file the human actually reads.
- Draw the honesty lines in advance — identity attestations, pledges, "are you a bot" gates — because the agent will meet them mid-form at 7am with nobody watching, which is exactly when a standing rule beats judgment.
The verification layer I've written about before checks whether an agent's output is true. This is the layer before that: constraining what the agent is allowed to claim at all. Between them sits the whole production verification gap — and a fleet that can show you 155 documented refusals is, in my experience, the strongest evidence you can offer that its 734 completions are real.
FAQ#
What is a "do-not-guess" guardrail for AI agents?#
It is an explicit marker in an agent's source-of-truth data that a value is missing on purpose and must not be inferred. In the fleet measured here, a personal-facts file lists every fact the agent may assert verbatim and flags three values as "STILL UNKNOWN — do not guess." When a required form field maps to a flagged or absent value, the agent's only permitted action is to mark the task blocked with a named reason and log a question for the human. This converts the model's default behavior under a required field — plausible fabrication — into a structured stop.
Why should an autonomous agent be able to refuse to complete a task?#
Because for agents that act in the real world, a wrong completion is usually more expensive than a late one. In this system, 155 of 1,552 pipeline rows are blocked, and the clearest case involved three job applications halted in one day over a missing ZIP code destined for forms feeding background checks. Inventing a plausible value would have submitted three applications immediately and created a permanent discrepancy in an employer's records. Refusal cost a few hours: once the real value was supplied, two of the three were re-filed autonomously the same day.
How do you stop an LLM from fabricating data on forms?#
Not with prompt instructions alone — a model cannot reliably distinguish a fact it remembers from one it invents. The working mechanism is architectural: keep every assertable fact in an external file the agent quotes character-for-character, forbid composing values not on the page, mark known-unknowns explicitly, and make "blocked" a legal outcome with an escalation path. Accuracy then becomes a property of the file rather than of the model, and each fact added to the file permanently unblocks every future task that needs it.
Should an AI agent answer "are you a human" questions on forms?#
Never falsely. This fleet's standing rule is to leave bot-detection and AI-attestation fields unanswered and decline to submit, logging the form for the human to file manually. Eleven blocked rows carry these reasons, beginning with a Greenhouse form whose final required field asked whether the applicant was an AI. Each such row doubles as a dated compliance record showing the automation stopped at every honesty line an employer drew — which matters increasingly as agent-driven applications become common and employers begin auditing for them.
What is the difference between an agent failing and an agent blocking?#
A failure is unplanned and usually silent — the process dies, and discovering why requires forensics. A block is a designed outcome: the row remains in the shared ledger with a specific machine-readable reason (this system uses 19 distinct blocked-* values, from blocked-hcaptcha to blocked-month-precision), full context in the notes, and a one-line question appended to a blockers file the operator reviews. The named reason routes directly to a fix, and resolving one blocker typically unblocks every future task that would have hit the same wall.
BUILDING AGENTS THAT ACT ON YOUR BEHALF?
The hard part of agent autonomy isn't making the agent do more — it's designing exactly where it must stop, and making every stop cheap to resolve. Facts files, refusal vocabularies, escalation seams: this is the work I do for one-person operations running real fleets. Get in touch, or see the press and hire page.
— Italo Campilii. Measured 2026-08-06 against ~/career-engine/ on my own machine: pipeline.csv (1,552 rows) parsed with Python's csv module — 734 submitted/applied rows and 155 blocked-* rows across 19 distinct status values counted exactly; the 2026-07-31 Versaterm/Dropbox/BILL sequence and same-day re-files quoted from the dated ledger rows; the facts-file rules and the three do-not-guess markers quoted from PERSONAL-FACTS.md; the AI-attestation incident from BLOCKERS.md. Every count in this post is an exact measured figure.