2 Commits (3b6e5cdbd4f310ce4849b2f6a3a3798c0a2bd22c)

Author SHA1 Message Date
I Luk Kim 3b6e5cdbd4 proactive: mission-driven employer scope + non-ortho specialty gate
The plan targets PSLF-eligible, mission-driven employers (government,
tribal, nonprofit, FQHC/community health, academic, public hospital).
For-profit DSOs (Smile Doctors, Sonrava, Specialty Dental Brands) had
slipped in through site: queries and auto-discovered boards, and their
pages produced off-scope leads — including Pediatric Dentist titles
that were never orthodontist jobs.

- employer_scope: rule-based employer classifier (.gov/.mil/.edu/
  .nsn.us hosts, configured public domains, government/tribal/
  nonprofit/academic/FQHC terms); private/unknown employers are
  FILTERED at verification (default-deny) and logged to
  workspace/candidates/*.employers.jsonl. Board catalogs declare
  employer_type; auto-discovered boards are written only when the
  SERP evidence classifies as mission-driven.
- roles: new other_specialty class (pediatric dentist, endodontist,
  oral surgeon, general dentist …) filtered before target matching;
  hidden dentist-title lanes at public employers stay.
- verifier: normalize ATS page titles ("Job Application for X at Y"
  -> "X") before storing; apply employer gate.
- discovery: scope filter + out-of-scope reporting; private auto
  catalog cleared (University of Utah Health kept as academic).
- closed markers: drop bare "filled" — federal boilerplate ("until
  the position is filled") marked open USAJOBS postings as CLOSED.
- urls: strip default :443/:80 ports so USAJOBS links dedupe.
3 weeks ago
I Luk Kim 555b450f0f proactive: role gate filters support/admin jobs, scoped ortho signal
Two false positives (Account Payable Specialist, Dental Assistant) were
classified ACTIVE because ortho signal was matched against whole-page
boilerplate — dental employers mention 'orthodontics' in every posting.

- roles.py: title-based role gate (target/support/non_clinical/unknown)
  with defaults + config terms; support/admin candidates are dropped at
  board fetch and SERP discovery before verification
- verifier: ortho signal now checks title + job-description container only
  (greenhouse/workday/icims/lever/smartrecruiters selectors); unknown
  titles need a dentist credential (DDS/DMD/license) to become ACTIVE
- Orthodontic Clinician is treated as support — verified against Smile
  Doctors postings ('under close supervision of an Orthodontist')
- non-target candidates are logged to workspace/candidates/*.roles.jsonl
  (30-day retention) as offline audit input
- role_audit.py + 'proactive role-audit': gemma4 reviews borderline titles
  offline and proposes terms; --write appends to sites/role_terms.auto.yaml
  (runtime stays non-AI per CLAUDE.md)
3 weeks ago