Releases: career-ops-hq/career-ops
Releases · career-ops-hq/career-ops
Release list
web: v0.9.0
0.9.0 (2026-08-31)
Features
Bug Fixes
- deps: refresh web lockfile for Next update (2ca6c00)
- web: honour language.modes_dir and language.output on web-triggered runs (#3253) (316906e)
- web: ignore nonfatal CLI stderr on clean run exit (#1974) (7f430ee)
- web: only surface follow-ups that are actually due (#2157) (82e1055)
- web: regenerate the nested web/ lockfile on postcss bumps (dba2a2e)
- web: show a cause-specific hint on job failure instead of an always-auth prompt (#2158) (d372908)
- web: show Via attribution for confidential employers (f749939)
- web: stop evaluation tables collapsing to one word per line (#3254) (b3c1e12)
- web: stop tracing runtime data paths (0a9d71f)
- web: tab label spacing and report table word-breaking (#3160) (102560b)
- web: use next/link for decision-card report link (#1931) (e7b38b3)
career-ops: v1.31.0
1.31.0 (2026-08-31)
Features
- application-answers: read the evaluation's Block H draft answers (778d5bf)
- cv: add "text" output_format — tailored markdown CV, no PDF (#3342) (13de717)
- cv: ATS-friendliness check — score a generated CV for parseability (#2064) (6d4e4c7)
- external data directory via CAREER_OPS_ROOT (#524) — lands #1444 (9159ec6)
- hired-wall: a quiet chevron with the exact remainder says the strip continues (87e3188)
- hired-wall: the audit line speaks to the person mid-search (c74dfc3)
- hired-wall: the badge is the title — self-identifying label, own share line, tighter audit line (7280a48)
- portals: profession-agnostic examples in portals.example.yml (b8614f8)
- providers: JobsDB Hong Kong via the existing jobstreet provider (6fa8279)
- web: add a global "Back to Top" button (#2821) (e5e786b)
- wire reply-watch into status-log.tsv (#1582) (f88df83)
Bug Fixes
- coverage: exclude the local-paths declaration file so a fork can commit it (280044e)
- cv-sync-check: resolve prompt paths from CODE_ROOT instead of an undefined projectRoot (d6df7a2)
- cv-sync-check: stop allowFail from excusing an uncaught crash (a19da42)
- dashboard: read job URLs from the tracker before the legacy enrichment tiers (c124fb6)
- deps: refresh web lockfile for Next update (2ca6c00)
- doctor: survive a null entry in installed_plugins.json (0a137a1)
- harness: make the syntax gate recursive, shared with npm run lint (43f846c)
- hired-share: suggest outcome.mjs's real syntax in the no-Hired-row error (4a69583)
- providers/icims: fill a missing location from the posting's JSON-LD (20ec88f)
- scan: Level 1 runs Playwright sequentially, matching the shared-session rule (77eebc9)
- scan: opt-in word:/stem: anchoring for content_filter keywords (ce3ac16)
- tests: scope the profile pin and move the last hand-registered suites (0bcd0fa)
- update-system: refuse to run when the install is not its own git toplevel (aecae53)
- updater: parse git status with -z so quoted paths and renames match real files (79152e7)
- verify-pipeline: recover a report number from a link target written with backslashes (8177808)
- web: honour language.modes_dir and language.output on web-triggered runs (#3253) (316906e)
- web: ignore nonfatal CLI stderr on clean run exit (#1974) (7f430ee)
- web: only surface follow-ups that are actually due (#2157) (82e1055)
- web: regenerate the nested web/ lockfile on postcss bumps (dba2a2e)
- web: show a cause-specific hint on job failure instead of an always-auth prompt (#2158) (d372908)
- web: show Via attribution for confidential employers (f749939)
- web: stop evaluation tables collapsing to one word per line (#3254) (b3c1e12)
- web: stop tracing runtime data paths (0a9d71f)
- web: tab label spacing and report table word-breaking (#3160) (102560b)
- web: use next/link for decision-card report link (#1931) (e7b38b3)
web: v0.8.1
0.8.1 (2026-08-27)
Bug Fixes
- 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)
career-ops: v1.30.0
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](https://github.com/santifer/career-ops/co...
web: v0.8.0
0.8.0 (2026-08-25)
Features
- web: restrict the local dashboard API to same-origin and loopback (b3974e6)
Bug Fixes
- deps: update web npm dependencies (major) (1207eae)
- web: give the methodology link a real tap target and a new-tab cue (#3023) (344a116)
- web: keep child stderr out of the status response on the crash path (#3022) (883ebec)
- web: keep the query string in the Explore dedup key so distinct postings don't collapse (#3082) (275e213)
- web: keep the run stream alive during silent agent phases (#3026) (aaeb114)
- web: report the uncapped weekly match count while keeping the render bounded (#2662) (6e9f029)
- web: stamp pipeline first_seen with the local day, not UTC (#3081) (809e93b)
career-ops: v1.29.0
1.29.0 (2026-08-25)
Features
- anti-fabrication: tier the Source-of-Truth boundary and add story-provenance-check (#2947) (498dd11)
- contacts: linkedin-join.mjs — warm-intro finder from a LinkedIn connections export (ba1a3dd)
- cv: optional url support for projects in HTML and LaTeX (93e256c)
- detect-reposts: skip multi-employer aggregator boards, and say why (d6ac988)
- pdf: declare CV section order in config/profile.yml (#2533) (c90b139)
- providers: add jobbankca, Canada's federal Job Bank (7e9feb4)
- providers: job.description for recruitee, ashby, and opt-in smartrecruiters (#3175) (83d3ac6)
- providers: mycareersfuture, Singapore's national job bank (#230) (a726f53)
- scan: add Hacker News scanner with optional AI enhancement (f93b6e9)
- scan: opt-in anchored keyword matching (82be449)
- verify-pipeline: flag a malformed follow-ups.md instead of reading it as empty (#2971) (a5ffae2)
- web: restrict the local dashboard API to same-origin and loopback (b3974e6)
Bug Fixes
- add-entry: delegate flag validation to shared validateFlags (3507239)
- agent-inbox: seed the queue under the lock, not before it (e585853)
- ashby: stop retrying a permanent failure, and honour a clamped Retry-After (#3072) (27fcd48)
- ashby: surface remote work model in the location string (878e068)
- batch: keep JD word count machine-readable under FORCE_COLOR (bf9a6ae)
- classify-tier: Associate + an academic rank is not entry-level (#3178) (ef347fb)
- cli: close the missing-operand hole for value-taking flags (#3087) (201aeca)
- cli: validate browser-extract flags and honour both value forms (cfe50c3)
- cli: validate fix-slugs flags (c4a0cc2)
- cv: honor Korean profile font theme (70a062c)
- dates: seven more today-gates resolve in UTC (2e4458e)
- deps: update web npm dependencies (major) (1207eae)
- detect-reposts: concurrent openings were reported as reposts (18ff33d)
- followup-cadence: validate CLI flags via the shared helper (#3196) (ec800a2)
- greenhouse: populate job.description from the boards API content field (#3175) (f1c1c65)
- liveness: a dead third-party host must not poison the whole verdict (1389e6c)
- liveness: add a LinkedIn rung so LinkedIn postings get a real verdict (#3179) (255bfc9)
- locks: one recovery judgment, imported by all three copies (638fdc4)
- locks: share the waiting half of the protocol with the three lock copies (39f87cd)
- pdf: name both sides when the lexical containment check fires (#3162) (98cc650)
- pdf: name canonicalization failure separately from a real workspace escape (e4a21ba)
- pdf: stop the batch-evaluate fixture leaking its tracker env (#3162) (328fd38)
- pipeline-lock: a vanished lock is not a lock you may delete (680419f)
- pipeline-lock: carry the judged directory's identity to the rm (7ada146)
- plugins: discover a plugin directory that is symlinked into a plugin root (b9fe775)
- portals.example: name the support ROLE, not the whole domain (d57a243)
- providers/lever: fold categories.allLocations into location (e3260d8)
- providers: retire echojobs, feed is gone behind bot protection (2c42733)
- providers: validate resolved addresses before connecting (DNS rebinding guard) (#3096) (d8d4d94)
- rename-sync: migrate 5 vulnerable call sites to renameSyncWithRetry (#3046) (213c281)
- salary-gap: treat a period as thousands grouping, not a decimal point (#3174) (b8e5bcb)
- set-status: resolve --report links from the Notes cell on customized layouts (#3075) (ae70a41)
- templates: extend profile font_family override to ja and zh blocks (5291cc7)
- templates: keep a project's tech line with the description above it (676efcd)
- tests: assert flag echo by substring, not by unescaped RegExp (6c2220f)
- tests: assert the flag echo with includes instead of an unescaped RegExp (743622d)
- tests: guard the web/ mirror import behind existsSync (e09e3cd)
- tests: keep the end of a failing script's output, not just the head (#3035) (a0f4622)
- tests: make the suite symlink-aware for externalized user layers (7d97d14)
- update: refuse non-canonical paths in the local declaration file ([764f20f](https://github.com/santifer/career-ops/...
web: v0.7.1
0.7.1 (2026-08-20)
Bug Fixes
- 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)
career-ops: v1.28.0
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 state...
web: v0.7.0
0.7.0 (2026-08-18)
Features
Bug Fixes
- deps: make js-yaml imports work on both 4.x and 5.x (#2656) (6466b18)
- deps: patch both HIGH advisories in web (js-yaml 4.3.1, nanoid 3.3.18) (a094ec9)
- deps: raise the js-yaml floor to ^4.3.1 and guard it (#2767) (5b18a96)
- keys: stop the dotted-I fix from collapsing Polish, Lithuanian and Maltese (5df43e7)
- keys: stop the Turkish dotted capital from splitting one employer in two (462d276)
- scan: take the shared lock for scan-history.tsv appends (#2639) (8e264c4)
- web: add Grok Build CLI to the web runtime picker (#2688) (af0d818)
- web: analytics tells an offer-holder they have 0 interviews (and nudges them to try harder) (#2410) (8f2b415)
- web: anchor the fallback stderr classifier so a word can't fail a run (#2882) (be62e3e)
- web: carry the posted: segment so web evaluations reach the POSTED column (#2899) (6eece73)
- web: detect OpenCode in its default install directory (#1794) (c10b887)
- web: emit the posting URL in the tracker-additions TSV so web runs join the dedup (#2833) (3c68721)
- web: enforce that no runtime grants itself blanket write permission (#2875) (9ba6ebf)
- web: finish Unicode company keys for explore + registry (#2668) (c294242)
- web: fold Turkish dotted capitals in status keys, and stop hand-copying the state list (#2786) (e1a0961)
- web: keep Codex JSONL + exit code authoritative for web scoring (#2102) (2d43601)
- web: let the pipeline table scroll horizontally instead of clipping on narrow screens (#2363) (632031c)
- web: make the tracker reader agree with parseTrackerRow on row shape (#2565) (4fea438)
- web: prevent Codex run jobs from waiting on stdin (#1973) (9a139a2)
- web: read target_roles with the shape it is actually written in (#2750) (5f5c06d)
- web: show the retry card, not the update-checkout panel, for runtime scan errors (#1904) (29c0d69)
- web: skip {n}-RESERVED.md sentinels when looking up reports (#1967) (5f4842e)
- web: stop the 16-chip cap from truncating the user's own portals.yml (#2749) (a5af949)
- web: strip the author letter from any lettered block, not just A-G (#2420) (630709a)
- web: take the core tracker lock in POST /api/status (#2903) (d9c4fd0)
career-ops: v1.27.0
1.27.0 (2026-08-18)
Features
- cli: add --help / -h usage block to stats.mjs (#2556) (3d8b53d)
- cli: shared flag-validation helper, migrate 3 fixed scripts, fix scan.mjs (#2778) (f05fc0f), closes #2775
- dashboard: add a POSTED column showing requisition age (#2692) (a229727)
- dashboard: add Stats analytics view with score quality & seniority mix charts (#2960) (9f0c3c3)
- intake: read documents/ locally to propose source-annotated profile additions (87abc32)
- invite-match: distinguish AI-interviewer platforms from human calls (#2676) (7fa3b1d), closes #2673
- negotiation: ROI-based salary-negotiation talking points from verified achievements (#2950) (03b440f)
- pdf: batch render path reusing one Chromium across N CVs (#2747) (7bb5c32)
- providers: Eightfold AI talent-acquisition boards (#2684) (e991d58)
- providers: extend getro with auto-resolve, salary, retry and remote-detect (#2640) (85c0928), closes #2602
- providers: senjob — the scanner's first African source, Senegal (#2962) (db9bd6a)
- rank: opt-in LLM relevance re-ranker for pipeline.md (#2579) (03fc92b)
- scan: AND-groups in title_filter.positive (#2552) (5483083)
- scan: record failed runs in scan-runs.tsv so trends exclude survivorship bias (713a6b0)
- skill-extract: recognize certifications, not just engineering tools (#2603) (4c6a1d2)
- templates: five named CV templates + a contract test for template variants (#2954) (314cbb5)
- tracker-sync-check: flag applications.md rows that active-interviews.md has already moved past (a1304a4)
- update: declare fork-local paths outside the system layer (#2793) (b082ec6)
- update: restore locally deleted system files instead of preserving the deletion (#2448) (bfcaaba)
- web: give the Apply page a way back and a way to record that you applied (#2735) (05cc972)
Bug Fixes
- add-entry: key non-Latin headings and dedup keys faithfully (#2850) (27757e4)
- add-entry: reject mistyped flags instead of reading them as data (f4c4fda)
- agent-inbox: give concurrent add() a burst-sized lock timeout (#2825) (513f07a), closes #2824
- agent-inbox: serialize concurrent adds through the shared lock (#2777) (a7f65b6)
- agent-inbox: stop dropping requests queued during an add (#2614) (ad382c0)
- archive: key JD captures to report numbers so they resolve after capture day (#2701) (81d7b06)
- assessment-log: reject unknown flags (#2802) (ce56efe)
- batch-tailor: --min-score 4.5 was silently ignored, and the worker's pdf mode path was cwd-relative (#2961) (f306801)
- batch: retry state updates and lock reservations to prevent worker silent drops (#2417) (5404185)
- build-cv-html: render numeric year/date scalars instead of dropping them (#2641) (949a690)
- build-cv-latex: numeric year/date scalars are still dropped — #2641 fixed only the HTML mirror (#2916) (94eb334)
- check-table-freshness: validate CLI flags and add a usage block (#2873) (a12dd6b), closes #2855
- ci: only greet a first-time contributor when it is actually their first (a0d45aa)
- ci: skip the upgrade leg when nothing managed changed, instead of failing (#2697) (9dcfd2f)
- classify-tier: an incidental senior word outranked an explicit intern marker (#2737) (cc2b1ce)
- cli: a one-letter typo returned a false all-clear at exit 0 in 4 reporting CLIs (#2920) (d65d024)
- company-history: record response dates via --on, not --note free text (9b17a8a)
- contacto: LinkedIn connection-request limit is 200 on free tier, not 300 (#2951) (9c242c5)
- csod: replay bootstrap session cookies and repair fetchResponse() (#2769) (7aee3b9)
- cv-facts: treat a k/M/B magnitude suffix as part of the number (#2612) (18d245a)
- cv: Korean and Traditional Chinese CVs had no font rule (#2616) (994552d)
- dedup-tracker: reject unrecognized flags instead of silently live-running ([#2746](https://github.com/santifer/career-op...