English · Français
An agent skill for building résumés and CVs in Typst that pass both filters: automated screening (ATS — Applicant Tracking Systems — and AI screeners) and the human 30-second scan.
Status: beta (0.5) — the method is battle-tested, but the skill's file layout and script interfaces may still change before 1.0.
Battle-tested method distilled from a real end-to-end résumé project that went through six simulated adversarial hiring reviews (recruiter, hiring manager, ATS expert, bank, startup, consulting firm) and a native-speaker language review — then hardened by adversarial reviews of the skill itself (execution, open-source, recruiting-expert) and cross-field integration simulations (a French nurse's CV, a UK analyst's CV) run by agents using only these files.
- Exact page control: 1-page and 2-page versions, deterministic page breaks, no section ever split across pages — enforced by unbreakable blocks and verified on the rendered PDF by the gate, not by eye.
- Measured page fill: last-ink target derived from the actual margins, verified by a pixel measurement script — with an explicit anti-filler rule.
- Machine-parseable layout: linear skill lines, month+year dates, clean
pdftotextextraction, verified per build; covers legacy positional parsers and the newer semantic/LLM ATS layer. - Honesty-first content rules: no invented facts (the rule outranks every layout guideline), no unproven keywords, no interview-fatal verb inflation, protected-title compliance.
- Regional & multilingual: paper size, photo policy (CV vs LinkedIn), verb and spelling conventions, section names, title law per market — six region files (Canada/Québec, USA, France, UK/Ireland, Germany/Austria/Switzerland, Indonesia, Malaysia, Singapore, the Philippines, Vietnam, Thailand, Morocco, Algeria, Tunisia), and a verify-don't-guess rule for everything else.
- Adversarial review loop: parallel reviewer personas, invented-but- realistic job postings per market segment, findings applied only when they survive cross-examination.
- Field packs: the generic method plus per-field depth;
references/field-software-dev.mdships first — contributions welcome for other fields. - Anti-clone design system: fourteen design families across four
registers (modern, neutral, classic, creative) anchored in real design
currents, drawn deterministically per candidate (
scripts/pick_design.py); generative palettes validated for contrast (scripts/gen_palette.py); font pairs drawn from open-license pools — so the tool never converges on one recognizable look. The creative register is never in the default draw pool — unlocked by a creative target field or an explicit request, and capped back out by a conservative market. One family (gutter-rail) carries a second lock on top of that one: its ruled gutter is a code gutter, so it also requires a technical target field, and the creative unlock alone never draws it for a non-technical trade. Reference implementations of all fourteen families live intemplates/families/. - Academic CV mode: a separate track for the exhaustive multi-page genre
(faculty applications, tenure/promotion, qualification dossiers) — its own
neutral gabarit (
templates/academic/), no fill target or design draw, and its own gate (scripts/verify_academic.py) checking a different invariant ("no entry straddles a page break" instead of "no section is ever split"), round-tripped against the declaredFAITS.md-derived TOML data file rather than the résumé fill/separation thresholds. - Cover letters: one per posting, never a generic one, from
templates/letter.typ— a reduced letterhead reusing the same CV's accent, font and name/contact line, three paragraphs (why this employer, proofs fromFAITS.md, availability), gated byscripts/verify_letter.py(one page; employer and exact job title both present in the extracted text). - Optional companion deliverables (job-search guide, LinkedIn checklist) via
references/companion-guide.md.
Fourteen reference implementations, one per family, live under
templates/families/<name>/, across four categories (neutral, classic,
modern, creative). Full recipes (heading device, header composition, fonts,
boundary treatment) are in references/design.md; full-page renders of all
fourteen are in GALLERY.md.
The creative register (hard-edge, avant-poster, gutter-rail) is never
drawn by default — see § Design families in references/design.md.
templates/academic/** (the academic-CV mode's gabarit) is out of this
industry calibration: the fill targets, section-separation devices, and the
fourteen-family roster above describe industry résumés only and say nothing
about academic dossiers.
Copy this folder into the directory your agent loads skills from, either user-wide or per-project:
<skills-dir>/vitae/
Consult your agent's own documentation for where that directory is. Nothing
here is tied to one vendor: SKILL.md is the entry point and the rest is
Typst templates plus Python scripts, so an agent with no skills directory at
all can simply be pointed at SKILL.md.
Just ask naturally — the skill triggers on résumé/CV work:
> Rebuild my CV from ~/old_cv.pdf and my LinkedIn, targeting backend roles in
Toronto. One-page and two-page versions, English.
The agent will collect facts, pick the regional conventions, draft from the
template, verify page count / fill / extraction mechanically, and offer an
adversarial review pass before delivering PDFs + editable .typ sources.
typst (0.13+) and Python 3 with Pillow for the fill measurement.
pdfinfo/pdftotext (poppler-utils) recommended; falls back to pypdf
automatically when only that is installed. Run python3 scripts/verify.py --doctor (any platform) to diagnose — read-only, prints the right install
command per platform, official repos first. LibreOffice/soffice is optional,
only needed to generate editable copies (.docx/.odt) derived from the
compiled PDF.
Platform notes:
- Linux / macOS: works as-is (Apple Silicon handled).
- Windows (baseline: Windows 11+, up to date):
python scripts\verify.py --doctorruns directly, no PowerShell doctor involved; typst viawinget install --id Typst.Typst; poppler viachoco install popplerorscoop install poppler— or use WSL/Git Bash and follow the POSIX path (scripts/verify.sh, a wrapper aroundverify.py) instead. - pip-only environments (no package manager, no admin rights):
pip install typst pypdf Pillowcovers everything —typstcompiles PDF and PNG through its Python API (no CLI),pypdfcounts pages and gives an indicative text extraction. Seereferences/ats.mdfor the commands and the known pypdf caveat.
SKILL.md # workflow + non-negotiable rules (agent entry point)
references/design.md # design system + page-fill tuning loop
references/ats.md # parsing rules + verification commands
references/regional.md # regional router: universal rules + matrix
references/regional/*.md # per-market depth, loaded only for the target market
references/reviews.md # adversarial review protocol
references/field-software-dev.md # field pack: software development
references/field-academic.md # field pack + workflow for the academic-CV mode (replaces industry rules, not layered)
references/typst-primer.md # minimal Typst syntax for agents that don't know it
references/companion-guide.md # optional job-search guide recipe; also the cover-letter doctrine
references/fonts.md # font provenance: Google Fonts URLs, licences, both install routes
templates/resume.typ # annotated starting template
templates/lib.typ # shared verified mechanics (devices stay per-family); hand-off is these two files
templates/icons.typ # EMPTY fallback marks (committed); a harvest writes the CV folder's copy, never this one
templates/letter.typ # cover-letter gabarit: reduced letterhead copied from the same posting's CV, verified by scripts/verify_letter.py
templates/academic/ # academic CV mode: neutral gabarit, no design draw
cv.typ # annotated starting template for the academic genre
lib-academic.typ # mechanics specific to academic entries (publications, funding, teaching, service)
faits-academique.example.toml # example declared-facts data file verify_academic.py round-trips against
templates/families/<family>/ # REFERENCE IMPLEMENTATIONS of all fourteen design families
resume.typ # font pair A — the family's primary draw
resume-pair-b.typ # font pair B — the SAME family on its second font pair, to prove
# the recipe survives a different pair (not a page 2)
lib.typ # symlink to ../../lib.typ — one source of truth, no copies
icons.typ # symlink to ../../icons.typ — the empty fallback, so every family compiles offline
templates/families/swiss-grid/resume-2page.typ # the worked 2-page sample (runhead, deliberate break, both pages measured)
scripts/pick_design.py # deterministic design draw: family, fonts, section labels, list markers; --emit-typ prints the ready-to-paste Typst preamble for the drawn recipe
scripts/gen_palette.py # generative, contrast-validated palettes (duotone included)
scripts/measure_fill.py # ink-coverage measurement
scripts/harvest_icons.py # fetches contact/platform icon path data into a generated icons.typ at CV-build time (never overwrites the committed empty fallback)
scripts/verify.py # gate + doctor: compile + pages + fill + extraction, any platform; --tune bisects #set par(leading:, spacing:) to the fill target (does not replace the gate — run it after)
scripts/verify_academic.py # academic-mode gate: entry-level page-break check + declared vs. extracted counts/order, round-tripped against the TOML data file (reuses verify.py's plumbing only, none of its fill constants)
scripts/verify_letter.py # cover-letter gate: exactly one page, employer and exact job title both present in the extracted text
scripts/verify.sh # POSIX wrapper around verify.py (2 lines)
assets/example-1page.png # rendered template example
Issues and PRs welcome — field packs (nursing, finance, trades…) and regional
matrix rows are the highest-value contributions. Keep every claim verifiable;
validate with npx skills-ref validate . (Agent Skills spec);
this skill's culture is "measured, not eyeballed".
MIT — see LICENSE.
Third-party. None ships here. The contact and platform marks (LinkedIn,
GitHub, email, phone, pin, website) are path data owned by their icon
projects — Bootstrap Icons,
Tabler Icons,
Phosphor, all MIT — so this repo
stores the address, not the drawing: scripts/harvest_icons.py <cv folder>
fetches them from the Iconify API into an
icons.typ in the deliverable folder, beside the lib.typ copied there,
at the moment a CV is built. The templates/icons.typ in this repo is the
committed fallback with every mark EMPTY, so #import "icons.typ": * always
resolves — a clone with no network and no script run still compiles. Nothing
to vendor, nothing to keep in sync with upstream, and no tag to track. When
the API is unreachable the script says so on stderr and writes empty marks:
the CV compiles with no icons and its contact URLs in plain text — still
valid, still ATS-readable. Note that a licence covers the
drawing, never the trademark: using a logo on a CV is nominative use, a
separate question from redistributing the path. No font binaries ship either:
the pools name faces packaged by common Linux distributions or available from
Google Fonts under the SIL Open Font License 1.1 — see
references/fonts.md for provenance and installation.
