Structural Gates That Run Before Job Scoring in the AI-Job-Search Framework

The AI-Job-Search framework executes two mandatory pre-scoring gates—the Eligibility Gate and Language Gate—to validate legal work authorization and linguistic requirements before any numeric scoring begins.

The MadsLorentzen/ai-job-search repository implements a rigorous job evaluation pipeline that filters postings through structural gates before job scoring occurs. These gates ensure that only legally viable and linguistically compatible opportunities proceed to quantitative assessment, preventing wasted computation on ineligible positions.

The Two Pre-Scoring Structural Gates

According to the framework specification in .claude/skills/job-application-assistant/04-job-evaluation.md, two distinct gates run sequentially after a posting is fetched but before any scoring dimensions are applied.

Eligibility Gate (Work Authorization & Security Clearance)

The Eligibility Gate immediately evaluates legal work-eligibility constraints. It scans the posting text for citizenship requirements, permanent residency mandates, security clearance prerequisites, and explicit visa sponsorship language.

This gate returns a hard FAIL if it detects phrases indicating "must be a citizen of," "permanent resident," or "security clearance" requirements that the candidate cannot satisfy. Conversely, it returns PASS when explicit sponsorship language (e.g., "we sponsor" or "visa holders considered") is present. An inconclusive scan results in PROCEED with a silent flag for manual review.

Language Gate (Proficiency Verification)

The Language Gate runs directly after eligibility confirmation to verify that the candidate’s declared language proficiencies satisfy the posting’s explicit requirements. For example, if a position requires "fluent Polish" and the candidate profile lists only "conversational Polish," the gate triggers a verdict.

Unlike the binary Eligibility Gate, this gate supports three outcomes:

  • PASS – All language requirements are satisfied.
  • FAIL – A mandatory language is entirely missing from the candidate profile (hard stop).
  • FLAG – The candidate possesses the language but at a lower proficiency than required (soft issue noted for user highlight).

Gate Verdicts and Data Persistence

Both gates produce specific fields that the /rank command persists to seen_jobs.json. The framework records eligibility_gate and language_gate as top-level keys in the job entry, with values of PASS or FAIL for eligibility, and PASS, FAIL, or FLAG for language. A language_note field accompanies FLAG statuses to document the specific mismatch.

A FAIL in either gate aborts the scoring pipeline entirely. The job is barred from entering numeric evaluation, and downstream commands such as /scrape and /apply respect these vetoes by skipping the posting. This ensures that only legally and linguistically viable jobs consume downstream processing resources.

Implementation Reference and Code Examples

The gate logic is implemented by agents consuming the Markdown specifications. While the authoritative definitions reside in 04-job-evaluation.md, the expected implementation pattern follows this logical flow:

def run_eligibility_gate(posting_text, candidate_profile):
    """
    Evaluates work authorization requirements.
    Returns: (verdict, note)
    """
    if "must be a citizen of" in posting_text or "permanent resident" in posting_text:
        return "FAIL", "Citizenship/permanent-residency requirement"
    if "security clearance" in posting_text:
        return "FAIL", "Security-clearance requirement"
    if "we sponsor" in posting_text or "visa holders considered" in posting_text:
        return "PASS", "Explicit sponsorship"
    return "PROCEED", "No explicit eligibility wording"
def run_language_gate(posting_lang_reqs, candidate_langs):
    """
    Validates language proficiencies against requirements.
    posting_lang_reqs: list of tuples like [("Polish", "fluent"), ("English", "native")]
    candidate_langs: dict like {"English": "native", "Polish": "conversational"}
    """
    for req in posting_lang_reqs:
        lang, level = parse_requirement(req)
        if lang not in candidate_langs:
            return "FAIL", f"{lang} not declared"
        cand_level = candidate_langs[lang]
        if level_higher_than(level, cand_level):
            return "FLAG", f"{lang} requirement ({level}) exceeds declared ({cand_level})"
    return "PASS", "All language requirements satisfied"

Integration with the Ranking Pipeline

The framework validates gate integration through tests/test_rank_command.py, which asserts that the language_gate field is correctly produced and stored during the ranking process. Similar test coverage verifies that the eligibility_gate field behaves as a hard veto.

These structural gates serve as the foundation of the evaluation workflow documented in the repository’s README.md. By enforcing eligibility and language constraints before job scoring begins, the system maintains compliance with legal constraints and ensures application quality.

Summary

  • The framework defines two mandatory structural gates that run before job scoring: the Eligibility Gate and the Language Gate.
  • Eligibility Gate checks for citizenship, permanent residency, security clearance, and visa sponsorship constraints in .claude/skills/job-application-assistant/04-job-evaluation.md.
  • Language Gate validates declared candidate proficiencies against posting requirements, supporting PASS, FAIL, and FLAG outcomes.
  • A FAIL in either gate aborts scoring and prevents downstream /apply or /scrape processing.
  • Verdicts are persisted in seen_jobs.json as eligibility_gate and language_gate fields, verified by tests/test_rank_command.py.

Frequently Asked Questions

What happens if a job posting passes the Eligibility Gate but fails the Language Gate?

The job receives a language_gate: "FAIL" verdict in seen_jobs.json and is excluded from numeric scoring. This hard stop prevents the system from evaluating positions where the candidate lacks mandatory language skills, though FLAG statuses allow marginal cases to proceed with warnings.

Where are the structural gate rules defined in the source code?

The canonical definitions reside in .claude/skills/job-application-assistant/04-job-evaluation.md, which specifies the semantic rules for both gates. The actual execution logic is implemented by agent code that consumes these specifications, with behavior validated in tests/test_rank_command.py.

Can the gates be bypassed or disabled during job scoring?

No. According to the framework architecture, these gates are mandatory pre-conditions. The /rank command enforces evaluation of both gates before persisting any score dimensions, ensuring that downstream automation respects legal and linguistic boundaries.

How does the system handle unclear eligibility language?

When eligibility requirements are ambiguous (neither explicitly restrictive nor explicitly permissive), the Eligibility Gate typically returns PROCEED without a hard fail. However, the framework recommends flagging such cases for manual review rather than allowing them to pass silently into the scoring pipeline.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →