1.28.0 (2026-08-20)
Features
- application-answers: parse a rendered section back into a snapshot (3313515)
- batch: native Node.js batch evaluator for Gemini (#1650) (153414f)
- company-history: emit no-response-friction signal per RFC #1506 schema v1 (#2787) (a74237e)
- cv: make Work Experience an optional section (#2504) (74dc716)
- discover-ats: probe the long-tail ATS vendors, not just the big three (2d6f188)
- doctor: emit the Gemini Node 20+ verdict instead of leaving it in prose (#3032) (e98bc6b)
- followups: export withFollowupsLock so other writers can share the lock (fba3bb2)
- oferta: AI-screening disclosure signal — Block G Signal 15 (#2892) (537b687)
- portals: add Wellfound search queries to the example template (12db45e)
- providers: add yourator job board provider (c664576)
- reports: add reports_to to the Machine Summary schema (8cf3dac)
- scan-ats-full: optional title_filter_full override for the full-board sweep (#3089) (442084c)
- titles: let the mode retire a keyword, not only add one (#2751) (0cb2d70)
Bug Fixes
- add-entry: exact-match dedup keys so a prefix cannot false-positive (f3ae221)
- archive-posting: reject mistyped flags via the shared helper (#2977) (84f152c)
- batch-runner: curl pre-fetch JD file to avoid empty $jd_file fallback (#2492) (46dc0f4)
- batch-runner: emit the JD word count color-independently (#3097) (6b61dee)
- classify-tier: validate CLI flags and add a usage block (#2870) (010ccc5)
- consider: perform GET /jobs CSRF handshake before the POST (#2764) (f058fbe)
- contacts: add -h/--help and reject unrecognized flags (#2829) (0aa3299)
- cover-letter: preserve --out subdirectories inside the output root (2cc0682)
- cv: an empty Skills section no longer deletes the sections after it (199b7d6)
- funnel-velocity: validate CLI flags via the shared helper (b6ebe08)
- intake: treat a nonzero version probe as present, not missing (c1df672)
- liveness: read same-origin iframes so embedded postings aren't false negatives (#2884) (bd36aa5)
- locks: the other two copies of the protocol had the same Windows bug (#3033) (1f73f2e)
- merge-tracker: don't let an unscoreable (N/A) re-eval overwrite a real score (#2803) (3c66092)
- merge-tracker: write rows at the header's actual width on customized trackers (8668ac1)
- pipeline-lock: an unreadable owner stamp is not an ownerless lock (bb537c6)
- pipeline-lock: time out a wedged holder, not an unlucky waiter (098bad0)
- pipeline: serialize browser-backed extraction so workers never share a session (#2551) (3bc0053)
- portals: block German student and support postings in the example title filter (6a3dbc2)
- portals: refresh example board URLs after ATS migrations (44e8a69)
- providers: raise inter-page pacing to 250 ms on the eight providers still at 150 (#3095) (3416f64)
- providers: senjob was the fifth private entity decoder, and the weakest — it emitted C0 controls (aa21e92)
- scan: add block_hard tier so always_allow cannot discard an explicit block (9073af7)
- set-status: rejects today's date east of UTC, logs tomorrow's west of it (2461b3b)
- stats: validate CLI flags via the shared helper (#3003) (9002602)
- test-all: tolerate Windows EPERM on fixture cleanup so a green run stays green (b21bf47)
- tracker: treat Windows rename contention as contention, not death (#2777) (474ffc4)
- trust-validator: a company with an accent in its name is flagged for being on its own domain (5adc39f)
- updater: detect tree drift and prune retired system files (#2630, #2532) (6242527)
- updater: parse git status paths from untrimmed output (5091202)
- upskill: validate CLI flags via the shared helper (841390c)
- verify-cv-facts: catch fabricated headcounts outside software (5cdb445)
- verify-portals: --add probes slugs that cannot exist for an accented company name (8bd65eb)
- web: block_hard survives the Explore round-trip — type, URL params, seed and serializer (#3102) (89d6b1b)
- web: persist the only installed CLI so jobs can start (#2966) (e80bf7e)
- web: resolve 27 unmapped states.yml aliases and fix the Turkish status fold (#2918) (360ce49)
- web: resolve company logos by name, not one guessed domain (#2942) (6096fc9)
- web: safe Codex AI-search exec with mtime-keyed capability cache (#2361) (699f506)
- web: stop first-run from claiming no setup (#2965) (f028012)
- web: take the core followups lock so web writes cannot race the seeder (#3034) (3b761b0)
- web: Today primary action opens the report (#2967) (74781e6)
- workspace: keep artifacts and PDF metadata in the tracker's workspace (d3dbd63)