Perf: pipeline throughput ~12x on large runs (5K postings 64.6 s -> 5.2 s) - per-shingle sha1 memoised in simhash64 (bit-identical output) and the shingle-set hash switched to FNV-1a (membership-only; containment verified numerically equivalent on the calibration corpus). Dedup thresholds untouched.
Glassdoor: attempted, paused, hidden. (Owner call 2026-08-20, after the smokes below.) The source is removed from the input schema enum, the store title/description and the README until a working access path exists; the adapter, its tests and the operator kill switch stay in the build so nothing has to be rebuilt when one does. Original note: The adapter is complete and tested, but the 0.6.0 smokes showed Glassdoor serving a Cloudflare managed challenge to every exit reachable from the platform (built-in residential in any country, the auto group, the container egress) on the first request, while a consumer IP is served normally. The operator kill switch JOBS_FEED_DISABLE_GLASSDOOR is set in Console, so selecting glassdoor yields sourceHealth.status: disabled and costs nothing. It is re-enabled when a working path exists (own proxy via proxyConfiguration.proxyUrls, or a browser fallback after its own cost/class decision). Details: docs/deploy-checklist.md.
Indeed search is now robots-compliant (behaviour change). Our search URLs put start last, so Indeed's Allow: /*&start=0& … /*&start=90& never matched and the blanket Disallow: /*&start= applied - every search request, page 1 included, was disallowed. searchUrl() now emits ?q=…&start=N&sort=date (+ l=/fromage=) and pagination stops at the real allowance of 10 pages, down from 30. Consequence for users: up to 100 listings per search term instead of 300, ordered by date rather than relevance. For a delta feed (what changed since the last run) this is close to neutral; for a first backfill it is a genuine reduction. /viewjob is disallowed and is emitted as a link only - we never fetch it.
Robots watch in the daily canary. tools/robots/check.js re-asserts, for glassdoor.com and indeed.com, every access fact our adapters were designed against; it runs in the source-health workflow and fails the run when a rule we depend on moves. Snapshots in docs/robots/; tests/unit/robots.adapters.test.js checks every URL the adapters can construct against them, so CI fails too. Assertion-based, so cosmetic edits stay quiet.
Research outcome: TrueUp / Lenny's Jobs is not built - the only lawful access door is their $1,000/month data licence; there is no unsigned public job surface, and both robots.txt and the Terms exclude automated agents by name.
Glassdoor (opt-in guest source, spec 2026-08-20 S1). First search page per query × location × datePosted window (30-day ceiling when unset), up to 30 jobs each; never paginates and never opens detail pages (both robots-disallowed - asserted in tests against the stored snapshot); snippet descriptions; p10-p90 salary with estimated; easyApplyFlag. Contributes no removal evidence. Kill switch JOBS_FEED_DISABLE_GLASSDOOR. Locations resolve through a small hand-maintained token table (data/glassdoor-locations.json); unknown locations fall back to a United States search filtered by the card location (GLASSDOOR_LOCATION_UNMAPPED). New codes GLASSDOOR_CHALLENGED, GLASSDOOR_SLICE_TRUNCATED, GLASSDOOR_LOCATION_UNMAPPED.
Sources enum order now encodes the basis hierarchy: ATS trio, then Indeed → Glassdoor → LinkedIn.