Language Gate Criteria and Persistence in the AI Job Search Framework
The Language Gate evaluates job postings against your declared language skills in the MadsLorentzen/ai-job-search framework, producing PASS, FAIL, or FLAG verdicts that are persisted as language_gate and language_note fields in seen_jobs.json to track eligibility across the workflow.
The Language Gate operates as a pre-scoring eligibility filter that runs before any skill-based evaluation occurs. According to the ai-job-search repository, it checks job posting requirements against your Languages table defined in CLAUDE.md to prevent wasting time on positions requiring undeclared languages or higher proficiency levels than you possess.
What Is the Language Gate?
The Language Gate is implemented in .claude/skills/job-application-assistant/04-job-evaluation.md as a structured eligibility check that executes prior to the five main scoring dimensions. Its sole purpose is to validate that you meet the linguistic requirements stated in a job posting before the framework calculates skill fit scores or generates application materials.
This gate references your candidate profile—specifically the Languages section in CLAUDE.md—to determine whether you have declared the required languages and whether your proficiency level meets or exceeds the posting's requirements.
Language Gate Evaluation Criteria
The gate produces three distinct verdicts based on how your declared language skills compare to the job requirements.
FAIL Verdict (Required Language Not Declared)
When a job posting requires a language that does not appear in your Languages table, the gate returns a FAIL verdict. According to the logic defined at line 35 of 04-job-evaluation.md, this result treats the posting the same as a location-based FAIL, excluding it entirely from your shortlist regardless of how well your other skills match the position.
FLAG Verdict (Proficiency Level Mismatch)
If you have declared the required language but the posting demands a higher proficiency level than you possess, the gate returns FLAG. The job remains in your shortlist but displays a warning symbol (⚠), and the specific mismatch is stored in the language_note field. This allows you to see opportunities where you might still apply if you can demonstrate equivalent competency through other means.
PASS Verdict (Requirements Met)
When your declared language proficiency meets or exceeds the posting's requirements, or when the posting does not specify language constraints, the gate returns PASS. This verdict imposes no veto, allowing the job to proceed immediately to normal scoring across the five evaluation dimensions.
How Language Gate Results Are Persisted
Persistence of Language Gate results ensures downstream tools can explain inclusion or exclusion decisions and maintain state across workflow sessions.
The language_gate and language_note Fields
As documented in .claude/commands/rank.md at line 53, each evaluated job record contains two critical fields:
language_gate: An enumerated string containingPASS,FAIL, orFLAGlanguage_note: A descriptive string explaining the verdict, particularly for FLAG cases (e.g., "German – required fluent, candidate B1")
These fields are written to the persisted job record during the Step 4 persistence phase, as verified by regression tests in tests/test_rank_command.py at line 225.
Integration Across Workflow Commands
The persistence mechanism operates consistently across three primary commands:
/rank: Records the verdict and note inseen_jobs.jsonafter evaluation/scrape: Surfaces the gate result in the scraper's output table; an undeclared required language forces the entry to be marked Low regardless of skill fit, as noted in.claude/skills/job-scraper/SKILL.mdat line 127/apply: Extracts the posting's required language and feeds it through the same gate logic to ensure consistency
Line 87 of .claude/commands/rank.md emphasizes that persisting these fields is critical for debugging and generating "why was this excluded" explanations when reviewing your job history.
Working with Language Gate Data
You can programmatically inspect Language Gate results from your persisted job data to analyze filtering patterns or audit exclusions.
# Example: Extracting the Language Gate result from a ranked job entry
import json
with open("seen_jobs.json") as f:
jobs = json.load(f)
for job in jobs:
gate = job.get("language_gate") # "PASS" | "FAIL" | "FLAG"
note = job.get("language_note") # explanatory text or None
if gate == "FAIL":
print(f"Excluded – language requirement not met: {note}")
elif gate == "FLAG":
print(f"Flagged – level gap: {note}")
When creating entries during the ranking process, the framework structures the data as follows:
# Example: How /rank stores the fields (simplified)
ranked_entry = {
"status": "ranked",
"language_gate": "FLAG",
"language_note": "German – required fluent, candidate B1",
# … other ranking fields …
}
# The entry is later persisted to `seen_jobs.json`
Key Source Files and Implementation Details
The complete Language Gate implementation spans four critical files in the repository:
| File | Role |
|---|---|
.claude/skills/job-application-assistant/04-job-evaluation.md |
Defines the Language Gate criteria and execution order before scoring dimensions |
.claude/commands/rank.md |
Documents the language_gate and language_note fields and their impact on ranking |
.claude/skills/job-scraper/SKILL.md |
Implements Language Gate integration during scraping, overriding skill fit for undeclared languages |
tests/test_rank_command.py |
Contains regression tests verifying correct persistence of gate fields in seen_jobs.json |
These files collectively demonstrate the full lifecycle—from evaluation logic in 04-job-evaluation.md to persistence verification in the test suite.
Summary
- The Language Gate acts as a pre-scoring filter that compares job language requirements against your declared skills in
CLAUDE.md. - Three verdicts exist: FAIL (excludes job), FLAG (warns but keeps job), and PASS (proceeds to scoring).
- Results persist as
language_gateandlanguage_notefields inseen_jobs.jsonduring Step 4 of the ranking workflow. - The scraper command uses these fields to mark entries Low when required languages are undeclared.
- Downstream debugging and exclusion explanation tools rely on this persistence to justify why specific jobs were filtered from your shortlist.
Frequently Asked Questions
What happens when a job requires a language not in my profile?
The Language Gate returns a FAIL verdict and excludes the posting from your shortlist entirely, treating it similarly to a location-based exclusion. This prevents you from wasting time on positions you cannot linguistically fulfill, and the exclusion is recorded in seen_jobs.json with the language_gate field set to FAIL.
How is the FLAG verdict different from FAIL?
A FLAG verdict indicates you have declared the required language but lack the specific proficiency level demanded (for example, the job requires fluency but you listed B1). Unlike FAIL, the job remains in your shortlist with a warning symbol and explanatory text in language_note, allowing you to decide whether to apply anyway or improve your skills.
Where are Language Gate results stored?
The results persist in the seen_jobs.json file as two fields: language_gate containing the verdict string (PASS, FAIL, or FLAG) and language_note containing descriptive text about the mismatch. These fields are written during the Step 4 persistence phase of the /rank command and are accessible to all downstream tools in the workflow.
Can I override a Language Gate FAIL verdict?
The framework does not provide a direct override mechanism for Language Gate FAILs within the automated scoring pipeline. However, because the gate runs before skill scoring, you could manually edit seen_jobs.json to change the language_gate value or add the required language to your Languages table in CLAUDE.md and re-run the evaluation if you believe the language requirement is negotiable or incorrectly parsed.
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 →