1.30.0 (2026-08-27)
Features
- add /calibrate — check evaluation scores against real outcomes (#3315) (4934985)
- apply: recover previous answers through --read --strict at the CLI seam (75d6b2c)
- artifacts: ATS form copy-paste plain-text exporter (#2887) (9f79f09)
- clean-markers — audit/strip hidden Unicode from generated text outputs (5fde72f)
- cli: add help flags to check-liveness (#2576) (4f5934b)
- cli: application-artifacts.mjs honours --help (#2774) (c265217)
- community: PR adoption ladder for quiet PRs (c86841b)
- community: the Hired Wall, a verifiable ledger of people hired with career-ops (#3372) (542491f)
- cv: add optional Interests section to the HTML CV template (2e7f1df)
- doctor: detect personalization files still carrying template content (#2691) (0cdd935)
- hired-wall: anonymous cards carry sector · location, mirroring the credited-card hierarchy (9f226e0)
- hired-wall: verified-hires framing, one CTA line, anonymous silhouette, months parsing (fb8d6a5)
- outcome: add --clean-output to archive-then-remove tailored CVs (#2653) (6ab969d)
- plugins: register career-ops-plugin-xquik (X hiring posts via Xquik, BYO-key) (88b325c)
- providers/getonbrd: scan multiple categories per entry (#3330) (2cc140a)
- providers: add ITviec provider — first Vietnamese job source (#230) (ecc9bdc)
- providers: add Torre opportunity-search provider (#3328) (086c75a)
- providers: CareerViet, second Vietnamese job source (#3378) (e3d372b)
- templates: add ATS-friendly single-column CV template pack (c958462)
- templates: discover template packs by name (#3202) (29e72bc)
- title-filter: a stem: prefix, for the half a plain keyword gives away (77c7007)
Bug Fixes
- browser-extract: read Workday JDs from the CXS API, and fail loudly on an empty JD (#3256) (55af9fc)
- build-cv-latex: render markdown bold in bullets as \textbf (#3351) (f1cc17b)
- calibrate: read all 14 outcome spellings outcome.mjs writes (#3322) (9db4458)
- cli: validate flag values in detect-reposts via the shared safeIntFlag (50944e3)
- contacto: stop searching for contacts the mode never uses (17f5557)
- cv,pdf: address CodeRabbit review feedback for #2213 (8c08b76)
- dates: weekly-digest and rejection-latency read the local day, not the UTC day (c8200cb)
- doctor: surface tracked .bak backup files as a warning (228e7b8)
- fact-gate: a non-English CV inflating headcount returns 'pass' — say so instead (#3320) (fa13474)
- followup: stop reporting the candidate's own address as a contact to chase (c0fe77e)
- followup: stop truncating plus-addressed emails at the plus (9d4817c)
- gfi-claims: reply when /assign is used outside the claim pool (f0b24df)
- handle quoted angle brackets while stripping HTML tags (702a2ae)
- hired-wall: ellipsize single-line card rows instead of clipping at the viewBox (61dd811)
- hired-wall: honor both permission wordings and default public stories to full credit (f65ba5e)
- i18n: preserve safety guardrails in localized modes (3afc54d)
- jobbankca: count raw entries for pagination (#3249) (19b7314)
- merge-tracker: --backfill-urls rebuilds unfillable rows to full header width (#3381) (d6435ef)
- outcome: a tracker edit forks the append-only journal, and directory order decides which half counts (#3325) (ba2b409)
- pdf: enforce workspace boundary in direct renderer (a4706e3)
- pdf: run the CLI when reached through a symlink (#3170) (3c2fa60)
- pipeline: use browser-first LinkedIn extraction (e0f0f33)
- plugins: isolate cmdRun results to the requested plugin id (#2354) (f0044f8)
- plugins: scale export hook timeout with tracker size (a8cbb2d)
- portals.example: drop retired EchoJobs block (3254ea3)
- providers: a16z treats a non-positive total_pages as absent, not as one page (002307f)
- providers: total_pages outranks a short page in the a16z sweep loop (#2547) (e34be83)
- reconcile-pipeline: validate CLI flags via the shared helper (b4384a7)
- resolve skill paths from project root (#3332) (68bee94)
- salary-gap: decide which separator is the decimal point before deleting either (17f44f9)
- scan: three scanners stamp first_seen in UTC, the reader measures it in local (#3070) (cc241ea)
- stats,calibrate: ledger-aware funnel + calibration (#1428, #1724) (34e5547)
- stats,calibrate: reject malformed status ledger rows (#3350) (0f645d2)
- stats: stop reporting a neighbouring counter when scan-runs.tsv drifts (5eb71d5)
- story-provenance: make the context matcher script-aware, not ASCII-only (2d7521e)
- update-system: never prune a file the update just preserved, or an asset it references (c8afb5d)
- update: drop the duplicate prune loop that deleted stale files twice (#3208) (e50fbad)
- verify: a check that could not run is a failure, not a warning (5ae4337)
- web: classify a tracker-lock filesystem failure as itself, not as contention (#3138) (cf880eb)
- web: key company logos with the Unicode-aware normalizer so non-Latin names don't collide (#3134) (7b9f858)
- web: salvage truncated JSON at each prefix's own depth, not one global pad (#3142) (a308bc5)
- web: stop hiding an employer's whole board after one evaluation (b56cde5)
- web: stop killing evaluate runs at 285s and misreporting the kill (#3124) (8a245ed)