Skip to content

feat: add visa sponsorship module for international job seekers in the US #182

Open
minwoo-data wants to merge 3 commits intosantifer:mainfrom
minwoo-data:feat/visa-module
Open

feat: add visa sponsorship module for international job seekers in the US #182
minwoo-data wants to merge 3 commits intosantifer:mainfrom
minwoo-data:feat/visa-module

Conversation

@minwoo-data
Copy link
Copy Markdown
Contributor

@minwoo-data minwoo-data commented Apr 11, 2026

Why this matters

Over half of U.S. tech job seekers are international students or workers who need visa
sponsorship. For them, "will this company sponsor?" is the #1 filter before anything else -
yet most job boards don't surface this signal. This module makes career-ops immediately
useful to that majority by answering the sponsorship question upfront, before wasting time
on dead-end applications.

Summary

  • Add visa-friendliness scoring to the evaluation pipeline for F-1 OPT/STEM OPT holders
  • Three standalone scripts: JD keyword classifier, USCIS H-1B history lookup, composite 1-5
    scorer
  • Three modes: hard_filter (auto-SKIP), score_penalty (A-F penalty), info_only
    (display only)
  • Integrates non-invasively: Block G added to oferta.md, batch pre-filter, scanner
    indicator column

What's included

Category Files
Core scripts sponsorship-detect.mjs, h1b-lookup.mjs, visa-score.mjs,
visa-cache.mjs, download-uscis.mjs
Config config/sponsorship-keywords.yml, config/employer-aliases.yml
Pipeline integration modes/oferta.md, modes/_shared.md, modes/scan.md,
batch/batch-prompt.md
Docs docs/VISA.md (usage guide), README feature tables (all 6 languages)
Tests 40 built-in tests across 3 scripts + test-visa-cache.mjs

Design decisions

  • Additive, not invasive -- existing evaluation flow unchanged; visa is a new Block G
    inserted before Draft Answers
  • Offline-first -- USCIS data downloaded once, cached 90 days
  • No new dependencies -- uses existing Node.js + Playwright stack
  • Data contract respected -- user config in config/visa.yml (user layer), keywords in
    system layer

Test plan

  • node sponsorship-detect.mjs --test (8 tests)
  • node h1b-lookup.mjs --test (17 tests)
  • node visa-score.mjs --test (15 tests)
  • node test-all.mjs passes
  • End-to-end: paste JD with "visa sponsorship available" → Block G appears in report

minwoo-data and others added 2 commits April 11, 2026 00:45
Add three standalone scripts that integrate into the evaluation pipeline:
- sponsorship-detect.mjs: JD keyword classifier (WILL/WONT/UNKNOWN)
- h1b-lookup.mjs: USCIS employer H-1B history with caching
- visa-score.mjs: composite 1-5 visa-friendliness score

Pipeline integration:
- Block G (Visa Analysis) added to oferta.md evaluation mode
- Batch pre-filter skips WONT_SPONSOR in hard_filter mode
- Scanner shows [SPONSOR]/[NO-SPNS]/[?] indicators
- Three sponsorship modes: hard_filter, score_penalty, info_only

Includes 40 built-in tests, sample USCIS data, and docs/VISA.md guide.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 2 fixes:
- CR-01: Path traversal guard in visa-cache.mjs cacheGet
- CR-02: Local alias override file support in h1b-lookup.mjs
- WR-01: CSV content validation before writing in download-uscis.mjs
- WR-02: Cache key source sanitization in visa-cache.mjs
- WR-03: Prototype pollution guard in alias loader
- WR-04: Visa health checks in doctor.mjs
- WR-05: Renamed file handling in update-system.mjs git status parsing

Phase 3 fixes:
- CR-01: Prototype pollution guard in sponsorship-detect.mjs YAML parser
- CR-02: Quote-aware CSV parser in h1b-lookup.mjs (handles commas in fields)
- WR-01..04: visa-score.mjs consistency, clamping, validation, regex fixes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants