5 Commits (0fda8383ea2bf117937ee2f31ef28950488d4edc)

Author SHA1 Message Date
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)
4 weeks ago
I Luk Kim 2d98afd062 proactive: give board candidates first verify slots, tighten matching
Board results were appended after every SERP result, so with the fixed
verify budget (60 pages) they were never verified — the summary showed
'thousands of board matches, zero new leads'. Verification now
interleaves board and SERP candidates, boards first, so hidden ATS jobs
(e.g. Smile Doctors, Sonora, Specialty Dental Brands) actually get
classified and persisted.

Also strip employer names before board keyword matching — 'Account
Payable Specialist at Specialty Dental Brands' no longer matches on the
company name ('Dental').
4 weeks ago
I Luk Kim a80bdaf06c proactive: auto-discover ATS boards from site: searches
Weekly deep scan now grows the employer catalog automatically:
site:{ats} SERP queries → parse Workday/ICIMS/Greenhouse/Lever/
SmartRecruiters URLs → probe public APIs → write verified boards
(min 1 dental match) to sites/employers.auto.yaml, which
ProactivePlan.load() merges with the curated employers.yaml.

Also fixes hidden-job coverage on existing boards:
- iCIMS: RSS feeds are retired — parse the iframe search page
- Workday: per-keyword searches (limit 20; tenants reject 50)
- SmartRecruiters: per-keyword API queries instead of newest 100

CLI: proactive discover-boards [--write] [--source] [--limit]
4 weeks ago
I Luk Kim 217071741f proactive: add reverify pass, cross-source dedup, and outreach list
- reverify: new 'proactive reverify' command re-opens CLOSED/STALE leads and
  transitions reopened ones via the normal ledger path (doc §15.3)
- dedup: merge cross-source duplicates by (title, employer), preferring the
  official ATS URL and storing alternates in secondary_urls (doc §19)
- outreach: new 'proactive outreach' command discovers private-practice sites
  and extracts contact email/phone into a direct-outreach report (doc §25)
- repo.get_inactive, SearchResult.secondary_urls, OutreachConfig wiring
- README + tests (repo, dedup, outreach)
4 weeks ago
I Luk Kim 5264e321fb proactive: add hidden-title state lane and direct ATS board crawling
Phase 1 — query matrix:
- every state now also gets a hidden-title query on a rotation window (doc §4)
- national pool gains recruitment-phrasing variants
- budget 80->100 queries/day, verify cap 40->60
- state_for_query picks longest state name (fixes DC/West Virginia shadowing)

Phase 2 — hidden jobs via ATS boards:
- new boards.py: Greenhouse/Lever/SmartRecruiters/Workday/ICIMS/USAJOBS adapters
  over public feeds/APIs; keyword filter -> SearchResult; graceful skip on failure
- new sites/employers.yaml: employer catalog (verified endpoints only)
- engine._discover now crawls boards, feeding candidates into verify->ledger
- USAJOBS uses USAJOBS_API_KEY/EMAIL from .env (skips until key approved)
- cli summary shows ATS board matches
4 weeks ago