tailoring · git:20261006.61d50fe · 2026-10-06 · sha256 5c8e528a16f1d697
tailoring git:20261006.61d50feA
Immutable. This exact content never changes and is served at /api/v1/blob/5c8e528a16f1d697.
---
name: tailoring
description: Turns a job ad into a tailored CV and cover letter. Reads the ad (pasted text, a link or a file), checks how well it fits the user's profile, writes a CV and letter in the ad's language from confirmed facts only, verifies every number, renders both to PDF and logs the application. Use when the user pastes or links a job ad, names a company or role they want to apply to, or asks for a CV, cover letter, Anschreiben or application, and for later edits to one ("make the letter shorter", "more technical").
allowed-tools: Read, Write, Edit, Glob, Grep, WebFetch, WebSearch, Bash(npm run pdf:*), Bash(npm run check:*)
---
# Tailoring
One job ad in, a tailored CV and cover letter out, built only from `profile/experience.md`.
## Before starting
The onboarding Quick start must be complete (`profile/onboarding.md`); if not, use the
onboarding skill first. Read `profile/experience.md`, `profile/targeting.md`,
`profile/voice.md` (if it exists) and `guide/format.md`.
## Flow
1. **Get the ad.** Pasted text, a link, or a file (PDF, screenshot). Fetch links; if the page
needs a login or comes back empty, ask the user to paste the text. Save the ad verbatim to
`applications/ads/<Company>.md` with the date and link: ads vanish, and the user will want
it again before the interview.
2. **Fit check**, per [references/fit-check.md](references/fit-check.md). Show the verdict and
ask whether to go ahead. Never write for a weak fit or a dealbreaker without a clear yes.
3. **Company research** for the letter's opening: one or two pages of the company's own site.
Find something specific and true. If nothing turns up, ask what draws the user to them.
4. **CV**: `applications/CV_<Company>.md`, per [references/cv.md](references/cv.md).
5. **Letter**: `CoverLetter_<Company>.md` (English) or `Anschreiben_<Company>.md` (German),
per [references/letter.md](references/letter.md). Skip only if the user wants no letter.
6. **Check the numbers**: `npm run check -- <Company>`. For every flag, remove the number, or
ask the user and record it with its source in `experience.md`. Repeat until clean.
7. **Render**: `npm run pdf -- <Company>`. Fix every warning and render again.
8. **Log it** in `applications/tracker.md` (copy `.claude/skills/tailoring/templates/tracker.md`
the first time), status "drafted".
9. **Hand over**: file names and page counts, the fit in one line, and the before-sending list
(end of fit-check.md). Update the tracker whenever the user reports what happened.
Edits later ("shorter", "more technical", "another angle"): change the markdown, then repeat
steps 6 and 7.
## Rules
- **Only facts from `experience.md`.** No skill, tool, title, number or achievement that isn't
there. A must-have the user lacks is never added; it goes into the fit check as a gap.
- **Their words, where true.** Use the ad's exact terms for things the user really has done.
Applicant tracking systems match exact words.
- **Titles stay exact.** Role headings use the titles in `experience.md`. The line under the
name is positioning ("Product Designer · B2B SaaS"), never a title the user didn't hold.
- **Numbers:** copy each one from the same claim in `experience.md`; only with a `[source: …]`;
estimates phrased as estimates; the same value in every document.
- **The user's voice** (`voice.md`). No generic enthusiasm ("excited to apply", "passionate",
"team player"). No em dashes.
- **Honest about gaps.** Never apologise for them in the letter; never hide them from the user.
- **Language follows the ad** unless the user says otherwise. When the profile is in another
language, translate the meaning, not the words: write as a native speaker would.
- **Summaries in the chat** (fit check, hand-over) are held to the same facts as documents.
## Gotchas
- Tailoring pulls towards impressive invented numbers ("cut costs by 40%"). → Numbers only
from `experience.md`, and `npm run check` before every render.
- The check matches numbers, not claims: a confirmed "35%" from one role lets an unconfirmed
"35%" in another pass. → Copy numbers claim by claim; the check is a safety net, not proof.
- Openings drift to generic enthusiasm. → The first sentence says something specific and true
about the company (step 3).
- Links from LinkedIn and job portals often need a login or JavaScript and fetch as nothing
useful. → Ask for the pasted text rather than guessing from the title.
- Letters run long: a third of real letters tested went over one page. → Aim for 250 to 350
words. The renderer fits small overruns; bigger ones need cutting.
- Letters ending without a sign-off, German closings with a comma. → Closing plus name,
always; "Viele Grüße" takes no comma.
- German ads often ask for "Gehaltsvorstellung" and "frühestmöglicher Eintrittstermin". →
Salary from `targeting.md`; the start date isn't in the profile, so ask.
- The ad's job title drifts into the CV as if the user held it. → Titles from `experience.md`.
- "Over 25 years" is derived from dates, so no source exists yet and the check flags it. →
Derive from the confirmed timeline, round down, record once (see cv.md).
- The user's own words, translated literally, read as foreign: "invest in that personally"
became "investiere persönlich darin", which in German sounds like money. → Keep the meaning,
phrase it natively ("nehme mir bewusst Zeit dafür").
- The fit check said the user built something "yourself" where the profile says "alongside my
co-founder"; the letter got it right. → Chat summaries drift looser than documents; hold
them to the profile too.
- Pasted ads often leave out the company name (it sits in the page header). → Ask for it;
the file names and the letter need it.