career-ops-v1.30.0

Wei-Shaw/sub2apicareer-ops-v1.30.0Aug 27, 2026by github-actions[bot]

AI Summary

career-ops v1.30.0 adds a `/calibrate` feature to check scores against real outcomes, introduces the Hired Wall ledger, and adds Vietnamese job providers (ITviec, CareerViet).

Key Highlights

  • Added `/calibrate` to check evaluation scores against real outcomes.
  • Hired Wall: a verifiable ledger of people hired using career-ops.
  • Added ITviec provider (first Vietnamese job source).
  • Added ATS-friendly single-column CV template pack.

New Features

  • Hired Wall with anonymous cards and months parsing.
  • New job providers: Torre, ITviec, CareerViet.
  • Clean-markers utility to audit hidden Unicode in outputs.

Full Release Notes

## [1.30.0](https://github.com/santifer/career-ops/compare/career-ops-v1.29.0...career-ops-v1.30.0) (2026-08-27)


### Features

* add /calibrate — check evaluation scores against real outcomes ([#3315](https://github.com/santifer/career-ops/issues/3315)) ([4934985](https://github.com/santifer/career-ops/commit/493498572b54c8fed6081281a1190690c01e3f55))
* **apply:** recover previous answers through --read --strict at the CLI seam ([75d6b2c](https://github.com/santifer/career-ops/commit/75d6b2c64315a0820b4a78b254b1c649f3386aa3))
* **artifacts:** ATS form copy-paste plain-text exporter ([#2887](https://github.com/santifer/career-ops/issues/2887)) ([9f79f09](https://github.com/santifer/career-ops/commit/9f79f0921ee0ad2a62b55ab63456057a43831168))
* clean-markers — audit/strip hidden Unicode from generated text outputs ([5fde72f](https://github.com/santifer/career-ops/commit/5fde72f80094c17a3539ecfc34b391c545b682a4))
* **cli:** add help flags to check-liveness ([#2576](https://github.com/santifer/career-ops/issues/2576)) ([4f5934b](https://github.com/santifer/career-ops/commit/4f5934b9152098f2e6bfc66d1ca57fced9d6a07e))
* **cli:** application-artifacts.mjs honours --help ([#2774](https://github.com/santifer/career-ops/issues/2774)) ([c265217](https://github.com/santifer/career-ops/commit/c265217791abf606ee206d37f12ccb687e5c1739))
* **community:** PR adoption ladder for quiet PRs ([c86841b](https://github.com/santifer/career-ops/commit/c86841b87eb4e7f6cbdfcf3bc76672d9b7af8fb8))
* **community:** the Hired Wall, a verifiable ledger of people hired with career-ops ([#3372](https://github.com/santifer/career-ops/issues/3372)) ([542491f](https://github.com/santifer/career-ops/commit/542491fb65811331057987e6dc2734783a070464))
* **cv:** add optional Interests section to the HTML CV template ([2e7f1df](https://github.com/santifer/career-ops/commit/2e7f1dfcc8a1082f9ab6a4e7c2a8ca9d86f1feab))
* **doctor:** detect personalization files still carrying template content ([#2691](https://github.com/santifer/career-ops/issues/2691)) ([0cdd935](https://github.com/santifer/career-ops/commit/0cdd935c0d8a71a58121a625e2c18f5a2b86d8f0))
* **hired-wall:** anonymous cards carry sector · location, mirroring the credited-card hierarchy ([9f226e0](https://github.com/santifer/career-ops/commit/9f226e00bf4c98cae8ad30a070ecec1b15372e37))
* **hired-wall:** verified-hires framing, one CTA line, anonymous silhouette, months parsing ([fb8d6a5](https://github.com/santifer/career-ops/commit/fb8d6a5acae19cffb53239b0f486a8407d8b00a7))
* **outcome:** add --clean-output to archive-then-remove tailored CVs ([#2653](https://github.com/santifer/career-ops/issues/2653)) ([6ab969d](https://github.com/santifer/career-ops/commit/6ab969dade42de66b5b32badcb2dd5cca2ea6b00))
* **plugins:** register career-ops-plugin-xquik (X hiring posts via Xquik, BYO-key) ([88b325c](https://github.com/santifer/career-ops/commit/88b325c13026c14ab926398f5c7d451ce62a6cd5))
* **providers/getonbrd:** scan multiple categories per entry ([#3330](https://github.com/santifer/career-ops/issues/3330)) ([2cc140a](https://github.com/santifer/career-ops/commit/2cc140a7a86d99ea7e005339295bb825770dce76))
* **providers:** add ITviec provider — first Vietnamese job source ([#230](https://github.com/santifer/career-ops/issues/230)) ([ecc9bdc](https://github.com/santifer/career-ops/commit/ecc9bdc3f20dc1e5036146ec684b38986dbb8ca6))
* **providers:** add Torre opportunity-search provider ([#3328](https://github.com/santifer/career-ops/issues/3328)) ([086c75a](https://github.com/santifer/career-ops/commit/086c75a4c3b4a032b84c1d5bb95b3bc7d0ea3681))
* **providers:** CareerViet, second Vietnamese job source ([#3378](https://github.com/santifer/career-ops/issues/3378)) ([e3d372b](https://github.com/santifer/career-ops/commit/e3d372b732424100faf39e37edc4a395e1d1dd98))
* **templates:** add ATS-friendly single-column CV template pack ([c958462](https://github.com/santifer/career-ops/commit/c9584625e860f1f3bc00b93bc202afcf52de3502))
* **templates:** discover template packs by name ([#3202](https://github.com/santifer/career-ops/issues/3202)) ([29e72bc](https://github.com/santifer/career-ops/commit/29e72bc41d16db0a66be7bdf0a14b75af020f6f4))
* **title-filter:** a stem: prefix, for the half a plain keyword gives away ([77c7007](https://github.com/santifer/career-ops/commit/77c70077c6273ab65ffbcd6dafb43bd633c19632))


### Bug Fixes

* **browser-extract:** read Workday JDs from the CXS API, and fail loudly on an empty JD ([#3256](https://github.com/santifer/career-ops/issues/3256)) ([55af9fc](https://github.com/santifer/career-ops/commit/55af9fc715eeb50825f3f710774a96a950e65726))
* **build-cv-latex:** render markdown bold in bullets as \textbf ([#3351](https://github.com/santifer/career-ops/issues/3351)) ([f1cc17b](https://github.com/santifer/career-ops/commit/f1cc17bdb7938a29fa64f5fa28ec5bbac43c3ff4))
* **calibrate:** read all 14 outcome spellings outcome.mjs writes ([#3322](https://github.com/santifer/career-ops/issues/3322)) ([9db4458](https://github.com/santifer/career-ops/commit/9db4458b8f9abba9d0f5c994e3b2a766854d0a56))
* **cli:** validate flag values in detect-reposts via the shared safeIntFlag ([50944e3](https://github.com/santifer/career-ops/commit/50944e35e174410508d3369fed075a2e4ac456ea))
* **contacto:** stop searching for contacts the mode never uses ([17f5557](https://github.com/santifer/career-ops/commit/17f55577fe315392ca557419bace93d2b2c53ff6))
* **cv,pdf:** address CodeRabbit review feedback for [#2213](https://github.com/santifer/career-ops/issues/2213) ([8c08b76](https://github.com/santifer/career-ops/commit/8c08b765fd8a4a0e77b671d8e4b2fb2c47653888))
* **dates:** weekly-digest and rejection-latency read the local day, not the UTC day ([c8200cb](https://github.com/santifer/career-ops/commit/c8200cbbd0757fe9ed7594192daac049f443add3))
* **doctor:** surface tracked .bak backup files as a warning ([228e7b8](https://github.com/santifer/career-ops/commit/228e7b8078804d82c92f2497ea2ec340b7fc0cae))
* **fact-gate:** a non-English CV inflating headcount returns 'pass' — say so instead ([#3320](https://github.com/santifer/career-ops/issues/3320)) ([fa13474](https://github.com/santifer/career-ops/commit/fa13474f5a74d3d66af5dfb57f9cdf6f8fadc39c))
* **followup:** stop reporting the candidate's own address as a contact to chase ([c0fe77e](https://github.com/santifer/career-ops/commit/c0fe77e2e497552ff1b994a79f9d7d6f9ab182d0))
* **followup:** stop truncating plus-addressed emails at the plus ([9d4817c](https://github.com/santifer/career-ops/commit/9d4817c07f944b352ffba6f68131c10b3902fe82))
* **gfi-claims:** reply when /assign is used outside the claim pool ([f0b24df](https://github.com/santifer/career-ops/commit/f0b24dfa5198d3ecf5c7394ff9777b20872b8950))
* handle quoted angle brackets while stripping HTML tags ([702a2ae](https://github.com/santifer/career-ops/commit/702a2ae4c590f28a140b5fa845818a356b57c22f))
* **hired-wall:** ellipsize single-line card rows instead of clipping at the viewBox ([61dd811](https://github.com/santifer/career-ops/commit/61dd8113a096488933603bc576a47c763b6cf97e))
* **hired-wall:** honor both permission wordings and default public stories to full credit ([f65ba5e](https://github.com/santifer/career-ops/commit/f65ba5ed0a358cd600c621234c284be162f9a670))
* **i18n:** preserve safety guardrails in localized modes ([3afc54d](https://github.com/santifer/career-ops/commit/3afc54d1f7921a0ab99fcb02b5fc383014ec956d))
* **jobbankca:** count raw entries for pagination ([#3249](https://github.com/santifer/career-ops/issues/3249)) ([19b7314](https://github.com/santifer/career-ops/commit/19b7314d06a1a03a2ab3f8bbcafd20b06d83e4c6))
* **merge-tracker:** --backfill-urls rebuilds unfillable rows to full header width ([#3381](https://github.com/santifer/career-ops/issues/3381)) ([d6435ef](https://github.com/santifer/career-ops/commit/d6435efe6e73b05629b1cddb6f4ba734c5b29191))
* **outcome:** a tracker edit forks the append-only journal, and directory order decides which half counts ([#3325](https://github.com/santifer/career-ops/issues/3325)) ([ba2b409](https://github.com/santifer/career-ops/commit/ba2b409d1dbd55160499f5f1c69731bc5bd8e61d))
* **pdf:** enforce workspace boundary in direct renderer ([a4706e3](https://github.com/santifer/career-ops/commit/a4706e3b9f6ef4ce2bc6a470ccfb1e60e56c4c82))
* **pdf:** run the CLI when reached through a symlink ([#3170](https://github.com/santifer/career-ops/issues/3170)) ([3c2fa60](https://github.com/santifer/career-ops/commit/3c2fa6083976777bd69ecb24d697d5ebc3551a09))
* **pipeline:** use browser-first LinkedIn extraction ([e0f0f33](https://github.com/santifer/career-ops/commit/e0f0f33630e713401c907e4123feb7edd070a3c8))
* **plugins:** isolate cmdRun results to the requested plugin id ([#2354](https://github.com/santifer/career-ops/issues/2354)) ([f0044f8](https://github.com/santifer/career-ops/commit/f0044f8c7890bd7069a64a61639a90130c86c67b))
* **plugins:** scale export hook timeout with tracker size ([a8cbb2d](https://github.com/santifer/career-ops/commit/a8cbb2df20ec61227dc5cd50dbeaed2526893b70))
* **portals.example:** drop retired EchoJobs block ([3254ea3](https://github.com/santifer/career-ops/commit/3254ea39d585c609dde826051237529c93ee7691))
* **providers:** a16z treats a non-positive total_pages as absent, not as one page ([002307f](https://github.com/santifer/career-ops/commit/002307f6ade85e805a486e6a9847b1014f1bb1ad))
* **providers:** total_pages outranks a short page in the a16z sweep loop ([#2547](https://github.com/santifer/career-ops/issues/2547)) ([e34be83](https://github.com/santifer/career-ops/commit/e34be83bd409c0e240aacfd4c31241472953707a))
* **reconcile-pipeline:** validate CLI flags via the shared helper ([b4384a7](https://github.com/santifer/career-ops/commit/b4384a797556250a2e73a23e40b3a0a8e13f332a))
* resolve skill paths from project root ([#3332](https://github.com/santifer/career-ops/issues/3332)) ([68bee94](https://github.com/santifer/career-ops/commit/68bee943ccd7e502807c38c5998f060cbb71cdea))
* **salary-gap:** decide which separator is the decimal point before deleting either ([17f44f9](https://github.com/santifer/career-ops/commit/17f44f977fbdd1e62a7f32241f8dc0f21aba410c))
* **scan:** three scanners stamp first_seen in UTC, the reader measures it in local ([#3070](https://github.com/santifer/career-ops/issues/3070)) ([cc241ea](https://github.com/santifer/career-ops/commit/cc241eab47dc40e6ecb7e3c5a9b25884a7ff61ae))
* **stats,calibrate:** ledger-aware funnel + calibration ([#1428](https://github.com/santifer/career-ops/issues/1428), [#1724](https://github.com/santifer/career-ops/issues/1724)) ([34e5547](https://github.com/santifer/career-ops/commit/34e5547ada30afac4b536abe2de84bb04dadc019))
* **stats,calibrate:** reject malformed status ledger rows ([#3350](https://github.com/santifer/career-ops/issues/3350)) ([0f645d2](https://github.com/santifer/career-ops/commit/0f645d2fd60f37348587f1626861da650f4887a4))
* **stats:** stop reporting a neighbouring counter when scan-runs.tsv drifts ([5eb71d5](https://github.com/santifer/career-ops/commit/5eb71d5db82ad50de20f35e14823c33bef9fcc4f))
* **story-provenance:** make the context matcher script-aware, not ASCII-only ([2d7521e](https://github.com/santifer/career-ops/commit/2d7521e9d753a6ccceadec9599d98a6c4e55811b))
* **update-system:** never prune a file the update just preserved, or an asset it references ([c8afb5d](https://github.com/santifer/career-ops/commit/c8afb5d041a5d10d4634c4d28abd20dfe8efaf58))
* **update:** drop the duplicate prune loop that deleted stale files twice ([#3208](https://github.com/santifer/career-ops/issues/3208)) ([e50fbad](https://github.com/santifer/career-ops/commit/e50fbad8ca5bc7f91ef568dc72c56c31b7285d52))
* **verify:** a check that could not run is a failure, not a warning ([5ae4337](https://github.com/santifer/career-ops/commit/5ae433780e5db2ad43a9365ae560bf3ae7a4f204))
* **web:** classify a tracker-lock filesystem failure as itself, not as contention ([#3138](https://github.com/santifer/career-ops/issues/3138)) ([cf880eb](https://github.com/santifer/career-ops/commit/cf880eb55945019663e1b423499041097cb24ccd))
* **web:** key company logos with the Unicode-aware normalizer so non-Latin names don't collide ([#3134](https://github.com/santifer/career-ops/issues/3134)) ([7b9f858](https://github.com/santifer/career-ops/commit/7b9f8588f57d3313265c49f37d2055bb533a7d08))
* **web:** salvage truncated JSON at each prefix's own depth, not one global pad ([#3142](https://github.com/santifer/career-ops/issues/3142)) ([a308bc5](https://github.com/santifer/career-ops/commit/a308bc5cc96197f3ed84ac75493d75c45a770f02))
* **web:** stop hiding an employer's whole board after one evaluation ([b56cde5](https://github.com/santifer/career-ops/commit/b56cde551d84ad5c28d7ea8b99edcc450a2b8b4c))
* **web:** stop killing evaluate runs at 285s and misreporting the kill ([#3124](https://github.com/santifer/career-ops/issues/3124)) ([8a245ed](https://github.com/santifer/career-ops/commit/8a245edd677598aa539e74c7565be44b7676e4ab))