ATS Verification Steps to Ensure Clean CV Text-Layer Extraction

To guarantee your CV passes Applicant Tracking Systems, extract the PDF text layer using pdftotext -layout, inspect for (cid:*) markers or replacement characters, confirm contact details appear as literal text, validate the reading order matches the visual layout, and verify keyword coverage without stuffing.

When you compile a LaTeX CV to PDF, Applicant Tracking Systems (ATS) ignore the visual formatting and read only the embedded text layer. According to the MadsLorentzen/ai-job-search repository, a single corrupted glyph or misplaced text block can trigger automatic rejection. The repository defines a rigorous verification protocol in CLAUDE.md that ensures the extracted text is clean, searchable, and structurally sound.

Extract the PDF Text Layer

The foundation of ATS verification begins with extracting the raw text content from your compiled PDF. In CLAUDE.md lines 30-33, the repository specifies using pdftotext -layout to preserve the document's column alignment during extraction:

pdftotext -layout path/to/cv.pdf > cv_extracted.txt

The -layout flag maintains the spatial structure of the text, making it easier to detect reading-order problems that standard extraction might obscure. This output file serves as the ground truth for all subsequent verification steps.

Detect Stray Glyph Codes

Font embedding errors manifest as cryptic glyph codes that break ATS parsing. According to CLAUDE.md lines 31-34, you must verify the extraction contains no (cid:*) markers or `` replacement characters. These artifacts indicate that the PDF font subsetting failed, leaving the ATS unable to map character codes to readable text.

Run this diagnostic to catch these errors:

grep -nE '(cid:|)' cv_extracted.txt || echo "No stray glyphs found"

If the grep returns any matches, rebuild your PDF using different font embedding options or LaTeX packages before submitting to an ATS.

Verify Literal Contact Information

Contact details must appear as literal text in the extraction, not as vector icons or hyperlink metadata. As documented in CLAUDE.md lines 33-35, email addresses and phone numbers hidden behind graphical elements or interactive PDF features are invisible to ATS parsers.

Validate contact visibility with:

grep -iE 'mailto:|@|[0-9]{3}[-. ][0-9]{3}[-. ][0-9]{4}' cv_extracted.txt \
  && echo "Contact info visible" || echo "Missing contact info"

Avoid using \icon{phone} or similar LaTeX constructs that render as untextifiable graphics.

Validate Document Reading Order

The sequence of text in the extracted file must match the visual reading order. CLAUDE.md lines 34-36 warn that multi-column layouts or floating text boxes can scramble the extraction, causing the ATS to read your sidebar before your job history.

Perform a quick sanity check on the extraction boundaries:

head -n 20 cv_extracted.txt   # Verify header content

tail -n 20 cv_extracted.txt   # Verify footer content

The repository recommends using single-column templates (such as the default moderncv style) to eliminate ordering ambiguities.

Check Keyword Coverage Honestly

Keyword validation ensures your content aligns with the job posting without resorting to "stuffing." As noted in CLAUDE.md lines 35-36, you should verify that required terms are either present or honestly marked as absent, never artificially stuffed into the document.

Automate coverage validation against your target keywords:

while read -r kw; do
  if grep -iq "$kw" cv_extracted.txt; then
    echo "✔ $kw"
  else
    echo "✘ $kw (absent or needs honest note)"
  fi
done < keywords.txt

This loop provides reproducible evidence that your CV contains relevant terms naturally rather than through hidden text or excessive repetition.

Document Verification Results

The final step requires marking each checklist item as passed or failed in your verification report. This documentation creates an audit trail proving the CV was validated against the CLAUDE.md protocol before submission. Store the cv_extracted.txt file and grep results alongside your source files for reference.

Source Files and Pipeline

The verification process operates on outputs from specific source templates in the repository:

  • CLAUDE.md: Contains the complete Verification Checklist and ATS guidelines referenced above.
  • cv/main_example.tex: Example LaTeX CV template compiled to PDF for verification.
  • cover_letters/cover_example.tex: Companion cover letter template using the same PDF generation pipeline.

These files form the complete chain: LaTeX source → PDF compilation → pdftotext extraction → ATS verification.

Summary

  • Extract with layout preservation: Use pdftotext -layout to create a text representation that maintains structural alignment.
  • Hunt for glyph corruption: Search for (cid:*) markers and `` characters that indicate font embedding failures.
  • Demand literal text: Ensure emails and phone numbers appear as plain text, not icons or hyperlink metadata.
  • Verify sequential logic: Confirm the text extraction order matches visual reading order using head/tail checks.
  • Validate honestly: Check keyword presence against job requirements without stuffing artificial terms.
  • Create audit trail: Document each verification step in a final report before submission.

Frequently Asked Questions

What is a (cid:*) marker and why does it break ATS parsing?

A (cid:*) marker appears when the PDF contains a Character ID that cannot be mapped to a Unicode character due to incomplete font subsetting. According to the CLAUDE.md verification protocol, these markers render as unreadable codes in the text extraction, causing the ATS to see gibberish instead of your content. You must rebuild the PDF with proper font embedding to eliminate these artifacts.

ATS parsers extract only the raw text layer and do not execute PDF interactive features or render vector graphics. If your email or phone number is embedded behind a \href command or rendered as an icon font, the extraction will show nothing. The CLAUDE.md checklist explicitly requires contact details to appear as literal text in the pdftotext output to ensure visibility.

How does pdftotext -layout differ from standard PDF extraction?

The -layout flag instructs the tool to maintain the physical layout of the document, preserving whitespace and column alignment. Standard extraction might concatenate multi-column text into a single stream, destroying the logical reading order. For ATS verification, the layout option is essential to detect whether the text flow matches the visual structure, as specified in CLAUDE.md lines 30-36.

Should I stuff keywords to pass ATS verification?

No. The verification protocol in CLAUDE.md lines 35-36 explicitly forbids keyword stuffing. Instead, run a grep-based check to confirm that terms from the job posting are either naturally present in your experience or honestly noted as absent. Artificially inserting keywords creates a poor candidate experience and may trigger anti-spam filters in modern ATS platforms.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →