github career-ops-hq/career-ops career-ops-v1.36.0
career-ops v1.36.0: Through the Filter

latest release: web-v0.14.0
6 hours ago

This release is about getting through the filter: eight more places to find openings, and a CV that applicant tracking systems read the way you wrote it.

Highlights

Your agent offers this update at the start of your next session. If it doesn't, run this once in your career-ops folder:

node update-system.mjs apply --confirm

Your CV, profile, tracker and reports are not touched.

Thank you

This release carries 211 pull requests from 68 people, 20 of them contributing for the first time.

1.36.0 (2026-10-10)

Features

  • ci: fail a PR while a dependency it names is still open (#4403) (71bb57d)
  • contacto: surface saved internal-referral contacts before cold search (#4692) (3957d70)
  • contacts: extract a recruiter/interviewer contact from a pasted reply (#4363) (1934b3e)
  • cv-facts: flag scope-verb inflation and unsourced adoption claims (#3784) (06f6452)
  • cv-templates: add atsLint, with the ATS rules as data in templates/ats-rules.yml (#3900) (6f1a74e)
  • cv: add opt-in GDPR consent footer slot ({{CONSENT}}) (#4286) (5c0e765)
  • dashboard: open the job posting from the report viewer with o (#4821) (024f059)
  • discover-ats: flag resolved boards with very few postings (#4869) (8af2aef)
  • explain evidence confidence behind evaluation scores (#4452) (1a9a76b)
  • gojobs: add offline GO Jobs HTML import (#4016) (d35cf64)
  • i18n: report structural drift across translated modes (#4643) (a8a71f5)
  • i18n: support language.modes_dir as a list of declared markets (#3798) (d31a138)
  • liveness: read Workday's 403 S22 as a withdrawn posting (#4633) (23a8ecf)
  • local-parser: pass a parser's extra job fields through (#3438) (#4697) (034ca77)
  • modes: add Singapore market mode (modes/sg/) (#4687) (963d8bf)
  • oferta/apply: surface fixed-term contract duration at apply time (#4535) (a156d4d)
  • patterns: close the discard_reasons vocabulary (#4549) (f14202f), closes #2785
  • pdf: add CV structure check; land as a warning per maintainer feedback (#3472) (f6d38b9)
  • pdf: opt-in pdf --ats emits an ATS variant alongside the styled CV (#3853) (#4909) (72650c1)
  • providers: add JazzHR zero-auth provider (#4307) (a18a644)
  • providers: add startup.jobs RSS provider (#4704) (b64b6c3)
  • providers: capture the ATS-native posting and requisition ids (#4076) (6b4cd44)
  • providers: eightfold reads PCSX tenants instead of returning zero jobs (#4297) (1601693)
  • providers: PageUp — vendor-hosted careers sites (#4693) (9493bc8)
  • registry: check pins against published releases on a schedule (#4651) (c731c69), closes #4573
  • reply-matcher: date-guarded company-wide rejections (#4826) (ccdc4d3)
  • salary-gap: relocation purchasing-power comparison (#4694) (#4696) (ef00bb0)
  • scan-ats-full: gate boards on domain relevance before title-filtering (#3304) (55694d7)
  • scan: add ADP Workforce Now provider (#3729) (b67e254)
  • scan: add Dayforce scanner (scan-dayforce.mjs, Playwright-based) (#3734) (b4de1df)
  • scan: add Gupy board-wide provider (#4550) (04a80be)
  • scan: add Taleo public career-section provider (#3743) (b922c8c)
  • scan: add UKG Pro/UltiPro provider (#3733) (76e0616)
  • scan: internationalize visa_filter sponsorship vocabulary (#4686) (c73574a)
  • scan: let a target declare which field its whitelist reads (#3438) (#4346) (4df96ab)
  • scan: record what the location and posting-age filters drop (#4321) (b17e77c)
  • scan: seed ATS sweep from application history (#3912) (43910e4)
  • scan: SmartRecruiters requisition ids and opt-in language-aware dedup (#4613) (f3846b0)
  • session-activity: advisory in-progress claims for concurrent sessions (#4536) (b02a8d6)
  • set-status: archive the JD automatically on the transition into Interview (#4524) (c3b501a)
  • templates: let a template pack declare the sections it owns (#3852) (#3916) (261d3c5)
  • templates: opt-in project_break_inside, for the one-word widow above a tech line (#4723) (023558e)
  • tracker: fix-report-links.mjs repairs rows whose report link is dead (#4750) (#4751) (24745c5)
  • tracker: render the URL column as a markdown link (#3516) (#3854) (c5e1c4f)
  • verify-pipeline: surface check-jd-archive.mjs's findings as Check 17 (#4527) (9fd8747)
  • web: add local scheduled scans (#2628) (85b67f5)
  • web: Analytics progress + insights views, read from the core (#4576) (2d38488)
  • web: preserve assistant conversations and earlier context (#4495) (f9e9139)
  • web: surface post-interview silence on the Follow-ups page (#4586) (9f0b533)
  • zero-LLM CV title-consistency check for pdf.md tailoring (#2678) (9f0eec7)

Bug Fixes

  • agent-docs: align API-first verification and CLI-only script checks (#4779) (9644e28)
  • agent-inbox: number resolve against file position, not the pending view (#2739) (93fd89a)
  • agents: scope onboarding and keep diagnostics read-only (#4428) (2aeb555)
  • apply: source form fields from the tailored CV instead of cv.md (#4412) (c2681c6)
  • archive-posting,application-answers: date records by the local calendar (#4544) (ec16f68)
  • archive-posting: refuse to save a non-content capture (login wall/404/paywall) (#4528) (91d7df9)
  • batch: merge into the locked pipeline.md instead of overwriting it with the start-of-run snapshot (#4912) (7fb9437)
  • batch: route standard and premium spend tiers to Sonnet 5.5 and Opus 5.5 (#4703) (b4e9a14)
  • ci: cover batch/ in the no-user-data guard (#4533) (0e4aeae)
  • ci: grant ci-approve.yml the contents: read it needs to check out (#4635) (49d99e4), closes #4616
  • ci: no-user-data guard blocks documents/, modes/_brief.md and other drifted user paths (#4891) (#4894) (7c19718)
  • cli: merge-tracker.mjs merges for real when --dry-run is mistyped: delegate to lib/cli-flags.mjs (#4678) (4c1a5fa)
  • cover: give {{DATELINE}} the date when an address block renders (#4069) (a800863)
  • cv-checks: read Pandoc-style cv.md; never ✅ on zero compared (#4879) (#4880) (2b3fb67)
  • cv-facts: read a spelled-out magnitude as part of the number (#4878) (ede8fe8), closes #4872
  • dashboard: DATE column shows the latest status change, not the eval date (#4817) (8675128)
  • dashboard: preserve status lifecycle side effects (#4644) (3c1aebd)
  • dashboard: render unevaluated rows as the sentinel, not "0.0" (#2760) (2511791)
  • dashboard: show explicit tracker and Notes locations (#4852) (#4863) (38d9fb3)
  • dedup-tracker: a posting-URL conflict blocks a merge (#4578) (3688b7f)
  • docker: install a Go that satisfies dashboard/go.mod (#4889) (b2d631e)
  • doctor: check that each dependency resolves, not that node_modules exists (#4782) (b5e61c4)
  • doctor: detect Playwright MCP servers configured in ~/.claude.json (#4563) (47b0d49)
  • fetch-jd: read JDs from company-careers gh_jid links and SmartRecruiters (#4673) (350bde3)
  • funnel: retain replies and historical stages across surfaces (#4374) (ead56e8)
  • gem: fold the isoCountry name into the location string (#4774) (d26fcde)
  • generate-pdf: derive workspace root before canonicalizing the tracker (#3169) (#3191) (91ee04c)
  • gitignore: ignore the .career-ops-data marker (#4663) (6a9b252)
  • gitignore: pair each anchored user-layer rule with a directory negation (#4567) (e6a0933)
  • greenhouse: resolve legacy boards.greenhouse.io careers_url (#4195) (5367abb)
  • gupy: follow the API to portal.gupy.io and send the filter names it reads (#4833) (b5ba43f), closes #4831
  • handle dead postings in batch evaluation (#4381) (bd24097)
  • harness: the web-unit batch discards its child's output, so a Windows failure names 100 files and explains none (#4767) (d31844c), closes #4766
  • higheredjobs: a walled feed is a named error, not an empty board (#4511) (388bc68), closes #3637
  • hired-share,intake: an unreadable state file is not a first run (#4540) (b9ad633)
  • hired-wall: require --rebuild or --add before writing (#4896) (#4898) (56f8ddb)
  • honor TTL ceiling for advisory session claims (#4740) (07c9bb1)
  • keyword-match: find the keyword section under the heading each mode writes (#4725) (bfdcae5)
  • keyword-match: match acronym plurals and reach their synonym groups (#4726) (181713a)
  • keyword-match: read the ## Extracted Keywords heading batch workers write (#4851) (fd659a7)
  • licenses: ship OFL text with bundled fonts and LICENSE with the npm package (#4888) (1adcdfb), closes #4886
  • liveness: a banner on its own line is not part of the line above (#4810) (880a1cb)
  • liveness: a posting that says how it will close is still open (#4771) (c0264e7)
  • liveness: poll the page while it hydrates instead of one read after a fixed 2s (#4804) (95728c6)
  • liveness: record the expired verdict so a dead posting stops resurfacing (#3905) (1a68591)
  • liveness: retry BambooHR once before calling expired (#4569) (7c81270)
  • merge-tracker: an aggregator URL is not a requisition identity (#3652) (#3653) (bdcf7a0)
  • merge-tracker: explain a failed report number that a completed row reused (#4519) (b86b33c)
  • merge-tracker: warn when a report link points at a missing file (#4749) (c9d88c3)
  • node: raise the Node floor to 22.13 and test it in CI (#4801) (#4803) (3b9bd64)
  • pdf: keep hyphenated words on one line so the PDF text keeps the term (#4911) (02bd978), closes #4908
  • pipeline-lock: make OWNERLESS_GRACE_MS env-overridable, fixing flaky test 16 (#4557) (31005eb)
  • pipeline: break sort ties on the row number, so newest-first reorders a date (#4333) (c4f2c3f)
  • pipeline: stop retrying unavailable LinkedIn job descriptions (#4641) (a39dc76)
  • pipeline: take the pipeline lock in reconcile-pipeline.mjs (#4895) (#4897) (df0d613)
  • plugins: resolve user config from data root (#4688) (7ddbd86)
  • providers: address post-merge review on startup-jobs (#4765) (08fe5d0)
  • providers: amazon lists every city of a multi-city req (#4900) (fb8e232)
  • providers: deutschebahn returns 0 postings — an unrenderable db.jobs posting blanks the first score-sorted page (#4714) (40c3739)
  • providers: end csod and avature paging on the rows the source returned (#4885) (d52a0e9)
  • providers: move // @ts-check to line 1 in six providers (#4790) (5062c3e)
  • providers: pair undici fetch with its proxy agent so trusted proxy egress works on Node 26 (#4812) (cce560f), closes #4808
  • providers: skipIds covers an explicit provider: field too (#4884) (acd9d00)
  • radancy: read a sibling job-location element in the legacy markup (#4689) (cf31a93)
  • reply-matcher: count combining marks when measuring a company name (#4542) (20897ea)
  • salary-gap: resolve column 1 as a tracker#, not a report# (#4368) (2fd2ccf)
  • scan-dayforce: report interactive challenges as a named error and stop (#4685) (2dede5c), closes #4675
  • scan: keep the first row of a headerless scan-history.tsv (#4807) (6554b64)
  • scan: make scan-history formula escaping reversible (#4778) (8fae375)
  • scan: support trusted proxy egress for provider requests (#4445) (c034621)
  • scan: verify offers via APIs before launching Chromium (#4640) (82dd887)
  • shared: let _profile.md define the archetypes, and allow "none of these" (#2690) (d4b2f8e)
  • skill-extract: count "fine-tuning" only where it names the ML skill (#4761) (23d3457)
  • skill-extract: read the other spellings of AI/ML skills a CV uses (#4755) (3bbf2ae)
  • skill: route triage, calibrate, intake and ats from the router (#4811) (#4815) (eeede80)
  • smartrecruiters: keep the configured slug in fallback job links (#4770) (2877692)
  • story-bank: stories an evaluation adds aren't invisible to npm run star anymore (#4684) (2f0e32c)
  • story-bank: three readers, three roots — and a safety gate split across two (#3985) (cbae0bd)
  • story-provenance: anchor the Provenance marker to the start of its line (#4865) (352e6d3)
  • successfactors: resolve a /go/// careers_url to the tenant root (#4659) (4e151da), closes #4655
  • templates: keep the contact separator from starting a wrapped line (#4715) (b075484)
  • templates: make job_break_inside an opt-in style token (#3789) (dc49e6b)
  • test-harness: linkRepoPackage resolves packages the way Node does, so worktrees work (#4781) (356d9d7)
  • tests: guard the sandbox node_modules link (#4406) (9085052)
  • tests: keep the fresh-install pipeline test out of a real CAREER_OPS_PIPELINE (#4707) (88a2ea1)
  • tests: keep the suite out of a real CAREER_OPS_TRACKER (#4892) (f882516)
  • tests: skip title-fit when web/ is absent (#4706) (a5e762d)
  • title-filter: treat CJK characters as word boundaries for short keywords (#4690) (7d0e312)
  • tracker: allow correcting stale notes without hand-editing (#4494) (5385f3a)
  • tracker: resolve tracker paths via resolveTrackerPath(DATA_ROOT) across CLI tools (#4087) (#4088) (151be63)
  • update-system: exempt a user-configured named template variant from the templates/ prune (#3700) (65ee5ea)
  • update-system: insert new gitignore rules before the fixtures negation (#4214) (182c28c)
  • update-system: keep protecting a customization an update preserved (#4341) (a395e67)
  • update-system: refuse manifest entries that name the user layer (#3947) (625a82c)
  • updater: apply updates on main when run from a linked worktree (#4738) (ad66a6a)
  • updater: ship user-directory scaffolds safely (#4741) (136e93f)
  • validate-profile: commented-out example sections are not unknown keys (#4705) (1d85279)
  • validate-profile: read opt-in keys the example ships commented out (#4737) (8dbf0b9), closes #4736
  • verify-ats: stop reading a white background as hidden white text (#4802) (6959490)
  • verify-cv-facts: do not read standard identifiers as count claims (#4666) (3362de5)
  • verify-pipeline: warn about a report that could not be inspected (#4814) (0b07775)
  • workable: a posting listed in several countries keeps all of them (#4806) (b07171d)
  • workday: collapse the -N disambiguator on a hyphenated requisition base (#3882) (#4409) (6a3e1eb)

web: 0.14.0

0.14.0 (2026-10-10)

Features

  • cv-templates: add atsLint, with the ATS rules as data in templates/ats-rules.yml (#3900) (6f1a74e)
  • i18n: support language.modes_dir as a list of declared markets (#3798) (d31a138)
  • templates: let a template pack declare the sections it owns (#3852) (#3916) (261d3c5)
  • web: add local scheduled scans (#2628) (85b67f5)
  • web: add route-aware loading feedback (#4338) (e049608)
  • web: Analytics progress + insights views, read from the core (#4576) (2d38488)
  • web: edit application status inline in Pipeline (#4701) (b89ef7e)
  • web: keep context during loading transitions (#4473) (e691fa6)
  • web: preserve assistant conversations and earlier context (#4495) (f9e9139)
  • web: surface post-interview silence on the Follow-ups page (#4586) (9f0b533)

Bug Fixes

  • funnel: retain replies and historical stages across surfaces (#4374) (ead56e8)
  • liveness: record the expired verdict so a dead posting stops resurfacing (#3905) (1a68591)
  • pipeline: break sort ties on the row number, so newest-first reorders a date (#4333) (c4f2c3f)
  • web/apply: never hand the planner a ref to a submit control, and guard every action by element facts (#3834) (a6637dd)
  • web: bind the dashboard to loopback by default (#3716) (7062ed5)
  • web: confirm paid assistant fan-out with cost estimates (#4746) (b3b62b4)
  • web: count cached input in usage meter (#4744) (088d0dd)
  • web: fall back from a stale saved cliId on every AI route, not just Run (#4638) (431f593)
  • web: pre-fill apply answers from the CV attached to the same form (#4404) (414ff23)
  • web: read the whole of modes/_profile.md, not just the managed block (#4008) (f4c52d1)
  • web: require confirmed worker stream completion (#4107) (7860d2f)
  • web: update vulnerable dependencies (#4670) (077ff80)
  • web: validate profile updates before writing (#4500) (b208464)

Sponsors

SerpApi sponsors career-ops through its fiscal host, Open Source Collective.

Don't miss a new career-ops release

NewReleases is sending notifications on new releases.