mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-09-17 00:26:26 +00:00
* 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.
4.1 KiB
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.mdbefore 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.mdfor 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>.texwith 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
/applyStep 6b (.claude/commands/apply.md) exactly: same header, same match-then-update rule, samedraftedrow, same prohibition on touchingjob_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_fileare the paths written in Steps 2 and 3 here, andsourceis the posting URL from Step 1. - This step exists here because
/scrapeStep 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