How `/rank` Batch-Scores Multiple Job Postings Against the Fit Framework
The /rank command performs a lightweight, triage-only scoring pass over job postings using the same four-dimension fit rubric as /apply, but without company research or salary lookups—processing jobs in parallel groups of approximately five via general-purpose agents.
The /rank command in the MadsLorentzen/ai-job-search repository bridges bulk-scraped job pools and deep-dive evaluations. It enables efficient batch-scoring of multiple job postings against a consistent fit framework, helping users prioritize which positions deserve further attention through the /apply command.
Input Parsing: Determining Which Postings to Score
The command supports four input modes controlled by arguments in /.claude/commands/rank.md:
- No arguments — Scores all jobs with status
newinjob_scraper/seen_jobs.json - Focus term (e.g.,
/rank data science) — Filters to jobs whose title or stored fit-notes contain the term --all— Re-scores every non-applied job, useful after profile updates--top <N>— Defines shortlist size (default 5)
State Loading and Exclusion Logic
Before scoring begins, /rank loads two data sources to build its working set. First, it reads job_scraper/seen_jobs.json; if this file is missing, the command prompts the user to run /scrape first. Second, it reads job_search_tracker.csv to construct an exclusion set of already-applied-to company + role pairs. The system then filters new entries against this exclusion set and any provided focus term.
Framework and Profile Loading
The scoring rubric and candidate profile are loaded once at the start of each /rank invocation. These come from two files in the Claude skills directory:
.claude/skills/job-application-assistant/04-job-evaluation.md— Contains the four-dimension scoring framework.claude/skills/job-application-assistant/01-candidate-profile.md— Defines candidate constraints and preferences【/claude/commands/rank.md†L28-L31】
This single load ensures consistency across all jobs in the batch.
Batch Fetch and Parallel Scoring
Jobs are grouped into batches of approximately five and distributed to parallel general-purpose agents. Each agent receives inline:
- The job list (title, company, URL)
- The compact rubric extracted during framework loading
Agents use WebFetch to retrieve posting content and score only from that fetched content. Dead or redirected URLs are marked expired rather than scored. The returned JSON for each job includes:
| Field | Description |
|---|---|
scores |
Raw scores for four dimensions (technical, experience, behavioral, career) |
location |
Verdict (PASS/FAIL/FLAG) against location constraints |
deadline |
Application deadline if detected |
strengths |
Candidate-role alignment points |
gaps |
Missing qualifications or experience |
language |
Detected posting language |
【/claude/commands/rank.md†L44-L56】
Aggregation, Weighting, and Ranking
Back in the main context, /rank computes an overall score using weights defined in 04-job-evaluation.md:
- Technical: 30%
- Experience: 25%
- Behavioral: 15%
- Career: 30%【/claude/commands/rank.md†L67-L68】
Scores map to verdict bands: Strong Fit (≥75), Good Fit (60-74), Moderate Fit (45-59), Weak Fit (30-44), and Poor Fit (<30). Two critical modifiers apply:
- Location veto:
FAILremoves the job from the shortlist;FLAGkeeps it with a warning - Deadline urgency: Jobs with deadlines ≤7 days receive a 🔥 marker and win tie-breakers; past-due jobs become
expired
The final list sorts by overall score descending, with urgency as the tie-breaker【/claude/commands/rank.md†L70-L73】.
State Update and Persistence
After processing, seen_jobs.json updates in-place with:
{
"status": "ranked",
"rank_score": 78,
"rank_verdict": "Strong Fit",
"rank_date": "2026-07-14"
}
Expired or past-deadline jobs receive "status": "expired"【/claude/commands/rank.md†L78-L82】. The job_search_tracker.csv remains untouched—it only records actual applications, not ranking results.
Command Usage Examples
# Rank all new postings
$ claude /rank
# Only titles or fit-notes containing "data science"
$ claude /rank data science
# Re-score everything, return top 10
$ claude /rank --all --top 10
Example Agent Response Structure
{
"key": "12345",
"status": "scored",
"scores": {
"technical": 82,
"experience": 75,
"behavioral": 68,
"career": 90
},
"location": "PASS",
"deadline": "2026-08-01",
"strengths": ["Implemented CI pipelines", "Led a 5-person team"],
"gaps": ["No cloud-native experience"],
"language": "en"
}
Output Presentation
/rank renders a markdown table summarizing three categories: shortlisted jobs, below-threshold jobs, and excluded items. The output explicitly states that numbers represent triage scores from posting text only, and prompts the user to invoke /apply for any selected job for deeper evaluation【/claude/commands/rank.md†L87-L101】.
Summary
/rankbatch-scores multiple job postings against the fit framework using parallel agent processing- Scoring stays shallow by design: no company research, salary lookups, or fabricated data
- Four-dimension rubric with weighted aggregation (Technical 30%, Experience 25%, Behavioral 15%, Career 30%)
- Location constraints can veto jobs; deadline urgency affects ranking and visual markers
- Results persist to
seen_jobs.jsonwithrankedorexpiredstatus - Output explicitly distinguishes triage scores from deep
/applyevaluations
Frequently Asked Questions
What is the difference between /rank and /apply in the ai-job-search system?
/rank performs lightweight batch-scoring of multiple postings using only fetched job content, while /apply conducts deep-dive evaluations including company research, salary benchmarking, and tailored application materials. /rank is designed for triage; /apply is designed for execution on selected opportunities.
How does /rank handle jobs that fail location constraints?
Jobs receiving a FAIL location verdict are removed entirely from the shortlist. Jobs with a FLAG verdict are retained but displayed with a warning. This veto system prevents wasted time on positions that violate hard constraints like geographic requirements or visa sponsorship needs.
Can I re-score jobs after updating my candidate profile?
Yes. Use the --all flag to re-score every non-applied job against your updated profile. This reads the fresh candidate profile from 01-candidate-profile.md and applies current rubric weights from 04-job-evaluation.md to all previously scraped positions.
Why does /rank use groups of five jobs for parallel processing?
The ~5-job batch size balances parallelism against context window limitations. Each agent receives the full rubric and job list inline, so smaller batches keep individual agent contexts manageable while still achieving meaningful throughput across multiple parallel workers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →