If you ask an AI to "tailor my resume to this job description without making anything up," it still tries to help you a little too much.

While building an open-source resume editor, I kept seeing models do things like:

  • Rounding a 38% speedup up to 40%
  • Dropping Intern from Software Engineer Intern
  • Taking a real number (10M requests) and attaching it to something else (10M users)
  • Stretching an internship date range by an extra month

None of these look like obvious lies when you skim the output. You usually only find out when an interviewer asks a follow-up question about a number you never actually hit.

After getting ghosted through fall recruiting as a second-year CS student, I built ResumeForge (GitHub, MIT). Here is how I stopped the AI from sneaking in exaggerated edits before anything can apply or export to PDF.

Why "don't lie" in the prompt isn't enough

Telling the AI to stick to the truth helps, and in ResumeForge every AI edit has to link back to an Evidence Bank of real bullets you added—or flag an honest Gap when you're missing a skill the job wants.

Still, prompts alone don't stop models from rounding 38% to 40%. And using a second AI call to check the first one adds wait time, costs extra tokens, and can miss the exact same small edits.

Instead, every AI suggestion runs through a plain code check against your original resume and Evidence Bank before you can apply or export it.

What the code check actually looks for

1. Rounded numbers and swapped topics

First, the checker pulls out every number, its unit (%, ms, s, k, M, $, users, etc.), and the word right after it from both your original resume and the AI's new version.

Then it checks that the exact number and unit actually exist in your real experience:

const valueUnitMatches = masterFacts.metrics.filter((m) => { if (m.isTrivial) return false; const sameUnit = m.unit.toLowerCase() === candMetric.unit.toLowerCase(); const sameValue = Math.abs(m.value - candMetric.value) < 0.001; return sameUnit && sameValue; }); if (valueUnitMatches.length === 0) { violations.push({ kind: "metric", severity: "HARD", field: "metrics", message: `Unverified or inflated metric claim "${candMetric.raw}" not supported by master evidence.`, }); } 

If 38% turns into 40%, valueUnitMatches comes back empty and the edit is blocked. It also checks the noun after the number, so the AI can't take a real 10M requests stat and turn it into 10M users.

2. Upgraded job titles

Models love nudging your title closer to the job posting. To block that, the checker compares the words in your title using two simple rules:

  1. The AI can't add new title words that weren't in your original title (which blocks adding Senior, Staff, Lead, etc.).
  2. If your real title includes words like Intern, Co-op, or Junior, the AI isn't allowed to drop them.

So shortening Full Stack Software Engineer to Software Engineer is allowed, while turning Software Engineer Intern into Software Engineer gets blocked.

3. Stretched dates

Start and end dates (May 2022 - Aug 2023, Jun 2024 – Present) are compared against your original resume. The AI can never push a start date earlier, push an end date later, or change a finished job to Present.

4. Honest gap flags

When a job description asks for a tool you don't have in your resume or Evidence Bank, the AI is required to list it as an Explicit Gap instead of sneaking it into a bullet. If a new skill still shows up in an edit, the app flags it and asks you to confirm whether you actually know it.

What still slips through right now

Plain code rules are fast and free, but they still have a few blind spots I'm working on next:

  • Small plain numbers from 0 to 10 without units (like changing team of 3 to team of 5—skipped right now so normal wording doesn't get falsely blocked, though 3x, 5%, and 12 are checked).
  • Spelled-out numbers like "forty percent".
  • Adding a + sign (40% -> 40%+), since + currently gets stripped when reading the unit.

Try it out (no login or API key needed)

ResumeForge is built with Next.js, TypeScript, PostgreSQL/Prisma, CodeMirror, and in-browser Typst WASM for live PDF previews. Outside of the pre-loaded demo mode, you can plug in your own API key (BYOK) without your key ever being saved on the server:

If you spot a clever way an AI could sneak a fake claim past these checks, let me know, I'd love to test it and patch the gap.