Files
ai-job-search/.claude/skills/job-application-assistant/SKILL.md
T
Oscar Madera e09d3eb37b fix(workflow): define tracker status enum once in /outcome, normalise readers (#299)
* fix(workflow): define tracker status enum once in /outcome, normalise readers (#298)

The tracker CSV status column had no single authoritative definition.
Six command files restated it with inconsistent spellings, producing two
concrete bugs:

- /outcome Step 4 wrote
o response and offer declined (spaces).
  /html-report normalised only the underscore forms, so those rows matched
  no bucket and were silently dropped from the rejection-rate denominator.
- /gmail-sync Step 2 hardcoded the final-status set with space spellings,
  so a row written with underscores was never recognised as final and the
  sync kept chasing closed applications.
- /html-report included interview_only in its tracker bucket map; that
  value belongs to the archive outcome.md Status: field, not the CSV
  status column.

Fix: add a '## Tracker status vocabulary' block in /outcome (the only
CSV writer) defining the canonical underscore spellings once.  Every
reader now references that block or explicitly lists both spelling forms
as read-tolerance for existing trackers.  /outcome Step 4 writes
no_response and offer_declined.  /html-report loses interview_only and
gains offer declined as a read-tolerance variant.  /notion-sync Step 3
Status select options are aligned to the canonical spellings.

Pinned by tests/test_tracker_status_vocab.py (9 new cases following the
DraftedMeansDraftedToEveryReader CASES-table pattern).  All 205 tests pass.

framework_version: 1.3.0 -> 1.3.1

* fix(workflow): address review findings on the tracker status enum (#298)

Follow-up to ca40df2, incorporating the maintainer and issue-author reviews.

Blockers fixed:
- CHANGELOG: the #298 entry had replaced the opening line of the #286 robots
  entry, leaving its body dangling under the new fork heads-up. Restored the
  deleted line and made the #298 entry self-contained above it (MadsLorentzen).
- /notion-sync Step 4 now normalises legacy space spellings to the canonical
  underscore forms before setting the Status property. A raw push would
  auto-create a separate Notion select option per unique string, splitting
  closed applications across two filter buckets in an existing database
  (MadsLorentzen).

Issue-author findings:
- The vocabulary block now states that the space spellings are the same
  values as the underscore forms, not separate statuses, equally Final.
  Previously a reader applying the Open/Final lists literally landed on
  "not Final, not Open, undefined" for `offer declined`, and /apply Step 6b
  would refresh a closed application's row instead of appending (jakob1379).
- The block moved below Step 1's closing --- as its own section: it was
  splitting Step 1's numbered list and silently truncating section-scoped
  reads of Step 1 to item 1 (jakob1379).
- Open is derived by exclusion from the one explicit Final list, so a new
  status needs updating in a single place (jakob1379).
- /html-report's bucket map gains a case-insensitive catch-all that maps
  unrecognised values to Rejected/Closed and names them once in the status
  breakdown - the #298 failure mode with a different input (jakob1379).
- /apply Step 6b and /interview Step 0 anchor their final/open decisions to
  the vocabulary block (jakob1379).
- /gmail-sync and /html-report drop their local restatements of the
  read-tolerance rule (jakob1379).

Tests: html-report bucket assertions scoped to the Step 1 section; new pins
for the equivalence clause, open-by-exclusion, block placement, the Notion
normalisation, and the apply/interview anchors.
2026-08-07 20:47:24 +02:00

4.1 KiB

name, description, allowed-tools, framework_version
name description allowed-tools framework_version
job-application-assistant Assists with job applications: evaluating job postings, tailoring CVs, writing cover letters, and preparing for interviews. Triggers on keywords like: job posting, job application, CV, cover letter, resume, interview prep, job fit, career, application, apply, ansøgning, stilling Read, Glob, Grep, WebFetch, WebSearch, Bash, Edit, Write, AskUserQuestion 1.3.1

Job Application Assistant


Workflow

When the user provides a job posting (URL or text), follow this workflow:

Step 1: Research & Evaluate Fit

  • Fetch the job posting content (use WebFetch for URLs). A 403 is not a dead end - follow the escalation order in 09-web-research.md before concluding a page is unavailable, and prefer the employer's own careers posting over an aggregator listing
  • Analyze the posting for required competencies, keywords, and priorities
  • Research the company (website, LinkedIn, mission, recent news), per 09-web-research.md
  • Score the posting against the candidate's profile using the framework in 04-job-evaluation.md
  • Present the evaluation table and verdict
  • Suggest whether the candidate should call the employer before applying (see 04-job-evaluation.md for guidance)
  • Ask the user if they want to proceed with an application

Step 2: Tailor CV

  • Read the most relevant existing CV variant from cv/ as a starting point
  • Follow the guidelines in 05-cv-templates.md
  • Create cv/main_<company>_<role>.tex with tailored content
  • Adjust: profile statement, skills section, experience bullet emphasis, section order

Step 3: Write Cover Letter

  • Follow the writing style rules in 03-writing-style.md (critical: no em-dashes, no cliches)
  • Follow the template structure in 06-cover-letter-templates.md
  • Create cover_letters/cover_<company>_<role>.tex
  • Ensure the letter connects specific experience to the role requirements

Step 3b: Record the Application

  • Run this once both documents exist. A CV or cover letter drafted alone is not yet an application.
  • Follow /apply Step 6b (.claude/commands/apply.md) exactly: same header, same match-then-update rule, same drafted row, same prohibition on touching job_scraper/seen_jobs.json. It is stated there once so the two paths cannot drift. Two of its values are named in /apply's own terms: cv_file/cover_letter_file are the paths written in Steps 2 and 3 here, and source is the posting URL from Step 1.
  • This step exists here because /scrape Step 5 routes straight into this skill. Without it, that path writes two documents and records nothing.

Step 4: Interview Preparation

  • Follow the framework in 07-interview-prep.md
  • Prepare STAR-format answers for likely questions
  • Identify role-specific talking points
  • Draft questions the candidate should ask the interviewer

Reference Files

File Purpose
01-candidate-profile.md Education, experience, skills, publications, awards
02-behavioral-profile.md Behavioral assessment, strengths, ideal environments
03-writing-style.md Tone, structure, do's and don'ts
04-job-evaluation.md Scoring framework for job fit
05-cv-templates.md LaTeX CV structure and tailoring rules
06-cover-letter-templates.md LaTeX cover letter structure and tailoring rules
07-interview-prep.md STAR examples, tough questions, roleplay guidelines
08-application-forms.md Portal free-text fields: self-introduction, project entries, character-limited pitches
09-web-research.md Fetching postings and company pages: trust boundary, the WebFetch 403 fallback, escalation order, claim verification

Quick Commands

The user may also ask for individual steps without the full workflow:

  • "Evaluate this job posting" - Step 1 only
  • "Write a CV for [company]" - Step 2 only
  • "Write a cover letter for [role] at [company]" - Step 3 only
  • "Help me prepare for an interview at [company]" - Step 4 only
  • "What jobs should I look for?" - Career strategy discussion using profile + evaluation framework