Auto-detect ATS from a bare company slug or careers URL — companies now
accepts str | CompanyEntry, so a legacy {atsType, companySlug} object,
a bare slug (concurrent 3-way probe), or a full careers/ATS URL (regex
extraction, zero probes) can all be mixed in one run.
ResultRow schema changes: source_ats → ats, description →
description_html, dropped employment_type, added team, salary_min,
salary_max, salary_currency (Ashby only — Greenhouse and Lever don't
expose structured salary). New input filters: departmentFilter,
locationFilter, remoteOnly, applied before maxItemsPerCompany.
Migrated the HTTP layer from httpx to curl-cffi with browser
impersonation and rotation on 403/429 (ADR-0002 compliance fix — v0.1's
httpx client was an undocumented violation; none of the three ATS hosts
are on the httpx allowlist). Retry status set widened to
{408, 429, 500, 502, 503, 504}.
Fixed a stale README/promo.json claim: Ashby's job-board API is REST
(api.ashbyhq.com/posting-api/job-board), not GraphQL. Removed a
brand-voice violation from promo.json ("no anti-bot, fast and reliable").
Cloud QA: pending (T19, not yet run as of this entry).
Initial release. Greenhouse, Lever, and Ashby scrapers via public JSON APIs. Normalised ResultRow schema with title, location, department, employment type, remote flag, and description. Pay-Per-Event pricing at $0.0015/result.
Cloud QA: PASS — runId iedkkN08dIydfE7BJ, 9 records, PPE charges actor-start=1, result=9.