ats-check · git:20261023.580eef2 · 2026-10-23 · sha256 23a9159d16d49c7d
ats-check git:20261023.580eef2A
Immutable. This exact content never changes and is served at /api/v1/blob/23a9159d16d49c7d.
--- # GENERATED by scripts/kernel/sync.py from skills/ats-check/SKILL.md - do not edit name: ats-check description: "Use after every resume PDF render, before the editorial verdict is signed, when a vendor parse (Workday, Greenhouse, Lever, Ashby, iCIMS, Taleo, SuccessFactors) is in doubt, or when the owner asks whether a resume will parse." --- # ATS check Owner: resume-tailor (runs it); resume-editor and the Recruiter re-run it as gate checks. Tier: T0 (the script writes only its report files). Script: `scripts/ats_check.py`. ## Procedure 1. Work from the user's data folder (`$JAJA_DATA`); V = the resume folder; the PDF name comes from the renderer's `meta.yaml`: `python3 -c "import sys, yaml; print(yaml.safe_load(open(sys.argv[1]))['pdf'])" V/meta.yaml`. 2. Run (variant; drop `--jd` for a base): `python3 scripts/ats_check.py check --pdf <PDF> --jd <the fullest JD: the role-analyst's snapshot in research/targets/evidence/ when one exists, else applications/SLUG/jd.md> --vendor <ats_vendor if greenhouse, lever, ashby, workday, icims, taleo or successfactors, else unknown> --contact-email <the owner's address, default identity.emails[0]> --taxonomy profile/skills-taxonomy.yaml --source V/resume.yaml --out V` Exit 0 = pass, 1 = a hard check failed, 2 = usage error (wrong path). 3. Read `V/ats-report.md` (summary) and `V/ats-report.json` (`passed`, `pages`, `checks[]`, `failures[]`, `keywords`, `vendor_warnings`, `extractors`, `fonts`). 4. Act on failures (hard checks: text_layer, reading_order, contact_email, headings, dates, glyphs, em_dashes, split_words, layout, page_count, probes): | Failure | Usual cause | Fix | |---|---|---| | contact_email | an extractor splits the address | re-render; check the template's header | | reading_order, layout | columns or a table | remove table-like content; never two columns | | em_dashes | only checked when `style.no_em_dash` is set | replace with a comma, colon or parentheses | | split_words | a hyphenated compound broke across lines | reword or let the renderer box it | | glyphs | ligatures or icon fonts | stay on the template's font; no icons | | page_count | over the page limit | cut the lowest-relevance bullets | 5. Keywords: `covered` is fine; `missing_evidenced` may be added only through an evidenced bullet; `missing_unevidenced` is the "must NOT add" list, never added, whatever the JD says. Low must-have coverage with nothing evidenced to add is a fit question for the Recruiter, not a writing task. 6. Vendor warnings never fail the check but are acted on: Workday → render the DOCX; iCIMS → no serif body under 11 pt (avoid the serif LaTeX fallback); Greenhouse → no auto-score, a human reads it; Lever → spell out abbreviations once; Ashby → canonical headings only; Taleo → the JD's exact wording where the work is real (no aliases such as K8s); SuccessFactors → standard skill names and a Skills section. Vendor table: `resumes/templates/README.md`. 7. PDFKit: when `extractors.pdfkit.available` is false (not macOS), write "PDFKit copy test not run" in `NOTES.md`; a macOS run of the same command closes it. ## Output `V/ats-report.md`, `V/ats-report.json`; a reply: pass or fail, failures, keyword lists, warnings. ## Stop conditions Exit 2 (fix the path); a failure that needs content you do not have; the contact email wrong in the source (fix `profile/facts.yaml` through the Recruiter, never in the resume only). ## Worked example Variant for a Workday employer: exit 0; `vendor_warnings`: "Workday: submit the DOCX; company line above title". Keywords: `missing_evidenced` = ["langsmith"] (its evidence is single-source and the bank bullet is tagged to confirm, so it stays out); `missing_unevidenced` = ["kubernetes", "spark"] (never added). Next: `build-resume-pdf` with `--docx`, then the editor.