Understanding the /rank Command and Batch-Scoring Workflow in AI Job Search
The /rank command batch-scores newly scraped job postings against a candidate's fit framework to produce a ranked shortlist, serving as the critical bridge between the data collection and detailed application analysis stages.
The MadsLorentzen/ai-job-search repository automates the end-to-end job search pipeline through a series of Claude commands. The /rank command operates as the intelligent filtering layer that transforms raw scraped data into a prioritized queue, enabling efficient prioritization before deeper evaluation.
What Is the /rank Command?
The /rank command sits between the scrape stage (which gathers raw job postings into job_scraper/seen_jobs.json) and the apply stage (which conducts deep single-job analysis). Its primary function is to batch-score all newly scraped postings against the candidate's fit framework defined in .claude/skills/job-application-assistant/04-job-evaluation.md.
By evaluating multiple postings simultaneously, the command generates a ranked shortlist that users can feed into /apply for detailed preparation. This batch-processing approach ensures that only the most relevant opportunities advance to the resource-intensive application preparation phase.
The 5-Step Batch-Scoring Workflow
According to the command specification in .claude/commands/rank.md, the workflow follows a strict 6-step pipeline:
Step 0: Parse Input Arguments
The command first interprets CLI arguments to determine scope. Users can specify:
--all: Force re-scoring of all non-applied jobs--top <N>: Return the top N results (default: 5)- Focus keywords : Filter for specific domains like "data science" or "backend"
These parameters determine which entries in job_scraper/seen_jobs.json enter the processing queue.
Step 1: Load State and Build Exclusion Set
The system loads two critical state files:
job_scraper/seen_jobs.json: Contains scraped job postingsjob_search_tracker.csv: Tracks already-applied or manually-tracked jobs
The command builds an exclusion set from the tracker, ensuring already-processed jobs are ignored unless --all is specified.
Step 2: Batch-Fetch and Score with Parallel Agents
This is the core processing stage. The workflow dispatches general-purpose agents in parallel, assigning approximately 5 jobs per agent to balance concurrency with token budget constraints.
Each agent receives inline context containing:
- Job list (title, company, URL)
- Scoring rubric from
04-job-evaluation.md
For each assigned job, agents perform:
- WebFetch retrieval with retry logic defined in
.claude/skills/job-application-assistant/09-web-research.md - Dimension scoring across four categories: technical, experience, behavioral, and career
- Veto evaluation for
location_verdictandlanguage_gate - Deadline extraction and parsing
Agents return a structured JSON object containing scores, verdicts, strengths, gaps, and metadata.
Step 3: Aggregate, Weight, and Rank
The orchestrator aggregates agent outputs and calculates weighted overall scores:
- Technical : 30%
- Experience : 25%
- Behavioral : 15%
- Career : 30%
Jobs map to verdict bands:
- Strong Fit : ≥ 75
- Moderate Fit : 50-74
- Weak Fit : 30-49
- Poor Fit : < 30
Veto rules apply strictly: FAIL on location or language excludes the job entirely, while FLAG entries remain in the pool but carry warning markers. The system also performs an expiry sweep, marking overdue deadlines as expired and adding urgency indicators (🔥) to approaching deadlines.
Step 4: Update State in seen_jobs.json
The command writes additive fields back to job_scraper/seen_jobs.json for each processed job:
{
"status": "ranked",
"rank_score": 78.5,
"rank_verdict": "Strong Fit",
"rank_date": "2024-09-01",
"location_verdict": "PASS",
"language_gate": "FLAG",
"deadline": "2024-09-10",
"strengths": ["Kubernetes experience", "Remote-first culture"],
"gaps": ["No TypeScript", "No AWS certifications"]
}
Expired jobs receive status: "expired". Notably, the system makes no changes to job_search_tracker.csv during this phase.
Step 5: Present the Shortlist
Finally, the command emits a human-readable table displaying the ranked results. The default view shows the top 5 entries (configurable via --top), highlighting urgency markers, veto flags, and application URLs for immediate action.
Batch-Scoring Mechanics and Architecture
Parallel Agent Processing
The workflow achieves scalability through job batching. By splitting dozens of postings into groups of approximately five, the system leverages parallel processing while respecting API token limits. This architecture prevents the pipeline bottleneck that would occur with sequential single-job scoring.
Data-Only Evaluation Scope
Unlike the /apply command, /rank performs data-only scoring. Agents evaluate strictly on posting text and candidate profile alignment. No external company research, salary lookups, or cultural deep-dives occur during batching—these resource-intensive operations remain the domain of the individual application preparation phase.
Idempotency and Re-Ranking
The command implements idempotent behavior by default. Subsequent runs without --all skip jobs already carrying status: "ranked", preventing redundant API calls. When candidates update their profiles or evaluation rubrics, the --all flag forces a full re-score of the entire pipeline, ensuring rankings reflect current fit criteria.
Why the Batching Workflow Matters
Scalability: Scraping often returns dozens of new postings; sequential one-by-one scoring would create prohibitive latency. Parallel batching reduces total evaluation time by 80-90%.
Consistency: All jobs score against the same snapshot of the evaluation rubric. This ensures that a "Strong Fit" designation on Tuesday uses identical criteria to one assigned on Friday, enabling fair comparison across time-shifted scraping sessions.
Traceability: The persistent storage of veto fields, strengths, and gaps in seen_jobs.json creates an audit trail. Later commands like /upskill or /apply can reference these stored justifications to explain why specific jobs reached the shortlist or were excluded.
Command Usage and Output Examples
CLI Invocation Patterns
# Rank all new postings (default top 5)
> /rank
# Rank only “data science” related postings
> /rank data science
# Re-rank every non-applied job after profile update
> /rank --all
# Return a larger shortlist
> /rank --top 15
Sample Agent Output Structure
The JSON returned by scoring agents in Step 2 follows this contract:
{
"key": "12345-abcde",
"status": "scored",
"scores": {
"technical": 78,
"experience": 65,
"behavioral": 52,
"career": 81
},
"location_verdict": "PASS",
"language_gate": "FLAG",
"language_note": "Requires fluent German (candidate B1)",
"deadline": "2024-09-10",
"strengths": ["Works with Kubernetes", "Remote-first culture"],
"gaps": ["No TypeScript experience", "No AWS certifications"],
"language": "en"
}
Summary
- The
/rankcommand filters scraped jobs through a weighted scoring framework (Technical 30%, Experience 25%, Behavioral 15%, Career 30%) to generate prioritized shortlists. - It processes jobs in parallel batches of ~5 per agent, fetching posting content via WebFetch with retry logic defined in
09-web-research.md. - Veto rules (
location_verdict,language_gate) automatically exclude or flag jobs before they reach the final shortlist. - State persistence occurs exclusively in
job_scraper/seen_jobs.json, leavingjob_search_tracker.csvunchanged during ranking operations. - The workflow supports idempotent re-ranking via the
--allflag, allowing candidates to recalibrate scores after profile updates. - All scoring rubrics and evaluation criteria derive from
.claude/skills/job-application-assistant/04-job-evaluation.md.
Frequently Asked Questions
How does the /rank command differ from the /apply command?
The /rank command performs batch evaluation on many jobs simultaneously using only posting text and profile alignment, producing a prioritized list. The /apply command conducts deep single-job analysis, incorporating external company research, salary data, and tailored application strategy for one specific posting. Use /rank to decide which jobs deserve attention; use /apply to prepare how to approach them.
What happens if a job fails the location or language veto?
Jobs receiving a FAIL verdict in location_verdict or language_gate are automatically excluded from the final shortlist and marked accordingly in seen_jobs.json. Jobs receiving a FLAG verdict remain in the pool but carry warning annotations visible in the output table, allowing users to manually review borderline cases.
Can I re-rank jobs after updating my candidate profile?
Yes. By default, /rank skips jobs already marked as "ranked" to save API costs. To force a complete re-evaluation after profile updates or rubric changes, invoke the command with the --all flag. This overrides the idempotency check and re-scores every non-applied job in the pipeline against your current criteria.
How many jobs does each agent process in parallel?
Each general-purpose agent processes approximately 5 jobs per batch. This batch size balances parallel throughput with API token budget constraints, as defined in the orchestration logic within .claude/commands/rank.md. The system dynamically groups jobs to maximize concurrency while ensuring each agent receives sufficient context window for comprehensive evaluation.
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 →