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

> Discover structural gates like Eligibility and Language Gates in the AI-Job-Search framework. These gates validate requirements before job scoring, ensuring efficient and compliant candidate matching.

- Repository: [Mads Lorentzen/ai-job-search](https://github.com/MadsLorentzen/ai-job-search)
- Tags: internals
- Published: 2026-08-31

---

**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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/04-job-evaluation.md), the expected implementation pattern follows this logical flow:

```python
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"

```

```python
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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/seen_jobs.json) as `eligibility_gate` and `language_gate` fields, verified by [`tests/test_rank_command.py`](https://github.com/MadsLorentzen/ai-job-search/blob/main/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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/.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`](https://github.com/MadsLorentzen/ai-job-search/blob/main/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.