# AccessLens Job Matching v3 — high recall and evidence-based ranking

## Install

Back up the currently deployed repository first. Copy `server.py`, `matching.py`, `discovery.py`, and `jobs.html` to the **repository root**, preserving any production environment variables. Do not upload the ZIP as a single file. `test_v3.py` is optional but recommended. Commit to GitHub, then redeploy Render. Do not replace unrelated authentication, dashboard, or Supabase files.

## What changed

- Search expansion now uses title-family queries for QA Manager, Senior QA Manager, Director QA, Senior Director QA, Head of QA, and IC engineering roles.
- Search breadth 1/2/3 generates 1/3/7 distinct queries, respectively. **Broad** can consume significantly more JSearch quota.
- Domain classification distinguishes software QE evidence, non-software domains, and uncertain roles. Missing descriptions require review instead of earning a verified match.
- Response includes `funnel` with retrieved, unique, software-QE-evidence, eligible, strong, potential and needs-review counts. UI displays this breakdown.
- Existing API keys, Supabase integration, saved jobs and application features are not deliberately changed.

## Validation

Run `python -m unittest -v test_v3.py` and `python -m py_compile server.py matching.py discovery.py`. In deployed UI, test Director QA, QA Manager, Senior QA Manager, Senior Director QA and Head of QA with both Bengaluru-only and India-remote modes. Compare with a hand-labelled sample of 30+ postings. Check JSearch quota and Render logs for errors.

## Known limitations

This is a **first implementation**, not a trained or empirically validated ranking algorithm. Domain detection is heuristic and may produce false positives or false negatives. Search still depends on JSearch results plus any already configured employer feeds; it does not scrape Google Jobs or guarantee full market coverage. Ranking weights remain inherited from v2; the 30/30/20/10/10 proposal is **not** implemented as a new calibrated formula in this package. The UI's score labels are heuristic, not hiring probabilities. For real-world accuracy, build a labelled evaluation set and tune rules and thresholds against it.
