[1.153.0] — 2026-08-12
Jobvite scanner migrated to the public XML feed (parent-sync). The parent career-ops retired the Jobvite JSON API (it now 302-redirects and returns zero jobs); web-ui's jobvite source used that same dead endpoint, so any tracked Jobvite company silently scanned empty. This ports the parent's fix (#2623) into the web-ui source contract: the source now reads the public per-tenant XML feed on a different host, keyed by an opaque companyEId.
Fixed
- Jobvite returned zero jobs — the source fetched
https://jobs.jobvite.com/api/company/{slug}/jobs(retired). It now fetcheshttps://app.jobvite.com/CompanyJobs/Xml.aspx?c={companyEId}and parses the XML<result><job>…payload (CDATA + entity-decode,detail-urlpreferred overapply-url,http:→https:on display-only per-job URLs).
Changed
- companyEId resolution — the tenant key changed from the vanity slug (
tylertech) to an opaquecompanyEId(q6NaVfwI) not present in the careers URL. Resolution order: (1)company_eid:on the portal entry, (2) thec=param of an explicitapi:URL, (3) board-page discovery (scrapecompanyEIdfrom the inline JS). Prefer (1) inportals.yml— one line, survives board redesigns, skips a request. server/lib/http-json.mjs—fetchTextnow attaches.location/.retryAfterto the thrown non-ok error (read-only; lets jobvite tell an empty board — aNoJobs.htmredirect — from a retired tenant, without ever following the redirect). Backward-compatible: both fields arenullfor a plain error, so existingredirect:'error'callers are unaffected.
CI
- Pages deploy no longer flips the status badge on a superseded build —
deploy-pages.ymlusedconcurrency.cancel-in-progress: true, so when a merge touchingdocs/help/**auto-fired a Pages build and a manual dispatch raced it, the older run was cancelled and surfaced as a red "check" ("Some checks were not successful") even though the site deployed fine. Switched tocancel-in-progress: false(GitHub's recommended Pages pattern) so a second run queues instead of cancelling — the status stays green.
Notes
- Security — the source pins two hosts (
jobs.jobvite.comfor discovery,app.jobvite.comfor the feed) viaassertJobviteUrlbefore every fetch: https-only, strict-hostname allowlist, no redirect ever followed (redirect:'error'for discovery,redirect:'manual'for the feed — the 3xx is read but never chased). ThecompanyEIdis only ever a?c=query value; feed/board URLs are rebuilt from the resolved slug/eId, never fetched verbatim from user input. Registry source count unchanged (meta.value='jobvite'preserved). - Parent-sync: this was the only web-ui-relevant change in the 17 parent commits since parentVersion 1.26.0 (the others — an LLM re-ranker,
verify-cv-facts,liveness-core, and twoweb/fixes — have no web-ui mirror). - Suite: 2396 tests (+4:
tests/sources-jobvite.test.mjsrewritten for the XML contract — config/c=/discovery eId resolution, XML parse, the two-host guard, empty-feed handling).