diff --git a/job_scout/ROSTER_REVIEW_2026-08-18.md b/job_scout/ROSTER_REVIEW_2026-08-18.md new file mode 100644 index 0000000..60c9262 --- /dev/null +++ b/job_scout/ROSTER_REVIEW_2026-08-18.md @@ -0,0 +1,136 @@ +# Scout roster review — 2026-08-18 + +Analysis only. No changes made to `COMPANIES`. Every claim below was verified by probing the +live endpoint; unverified candidates are listed separately as *probe-worthy*, not as recommendations. + +Method: aggregated the scan-stats tables from the four most recent full runs (2026-07-14, 07-27, +08-07, 08-18), cross-referenced `state/decisions.json` (253 decisions), and live-probed candidate +ATS endpoints. + +--- + +## 1. Three scrapers are silently broken + +Same failure class as the dbt Labs 404 fixed earlier today, but worse: these return HTTP 200 and +plausible-looking rows, so the report shows "0 matches" and nothing looks wrong. **A company that +scrapes garbage is indistinguishable from a company with no openings.** + +| Company | What it actually returns | Verified | +|---|---|---| +| **Roche** | Shanghai, Kyiv, Petaling Jaya, Bogota, Berlin, Mannheim, Penzberg. **Zero Swiss roles** despite Basel HQ — the `locationsearch=Switzerland` URL param is being ignored and an unfiltered default page is scraped. | live scrape, 10/10 rows non-CH | +| **Meta** | **1 row**: "Research Scientist Intern, AI/ML, Core Ads Growth (PhD)". Meta Zurich is a real engineering office. The `offices[0]=Zurich` filter or the lazy-load scroll is failing. | live scrape, 4 jobs across 4 runs | +| **Apple** | 21 rows, **all** internships, "Where we're hiring", and "US - Specialist: Seasonal, Part-time". Zero actual engineering reqs. | live scrape, all 21 rows | + +**This invalidates a conclusion in the yield data.** Apple shows 21 decisions, all `skip`, 0 signal — +that reads as "Apple is a bad fit" but it is really "the scraper only ever saw the internships page." +Don't drop Apple on that evidence; fix the scrape first, then judge. + +## 2. Seven boards have no title filter at all + +`_title_filter` is absent on **BKW, SBB, BFH, PostFinance, Swissgrid, Novartis, Palantir**. This is +why reports drown in *Mitarbeiter/in Hausdienst*, *Financial Accountant*, *Studiengangsleiter Master +Physiotherapie*, *SAP Consultant Treasury*. + +| Company | Eligible → match ≥2 (4 runs) | Reading | +|---|---|---| +| BKW | 61 / 75 scraped | 81% of the entire board "matches" | +| SBB | 27 / 27 | 100% — filter is doing nothing | +| BFH | 29 / 48 | 60% | +| Novartis | 105 eligible → 21 match | 23 skips vs 3 shortlists | + +**These need a title filter, not removal.** BKW/SBB/BFH/PostFinance/Swissgrid are the Bern/Thun +WLB-exception tier where below-bar comp is deliberately accepted — the lane is intentional, the +noise is not. RUAG already carries a 29-term filter and behaves (13 eligible → 7 match); it is the +model to copy. + +## 3. The yield metric in the decisions log is confounded + +Raw decision counts reward boards with *no* title filter — more rows surfaced means more `skip` +rows recorded. Normalising to signal (`shortlist`+`applied`+`maybe`) per eligible role inverts the +ranking: **Snowflake** (5 decisions → 1 applied, 1 shortlist, 1 maybe off 14 eligible) is a far +better board than **Novartis** (31 decisions → 3 shortlists off 105 eligible). Worth keeping in +mind before reading the decisions log as a quality signal. + +## 4. Dead lanes + +- **MET Group + Louis Dreyfus: 1,464 roles scraped across 4 runs → 0 eligible, 0 matches. Ever.** + Both are title-filtered correctly; they simply have no CH/remote-CH engineering roles. LDC is + Geneva/Rotterdam-anchored (French). The commodity-trading lane is configured and producing nothing. +- **Norway (Telenor, Equinor, NATO JWC Stavanger)** — three of 34 companies on a lane your own notes + call mostly closed: comp below the 180k bar, Norwegian at A2, no clearance. Equinor just came back + rejected at 79 days. Consolidation candidate, though NATO JWC has an open application pending. + +--- + +## 5. Verified adds — both confirmed live + +### Amazon / AWS — the single biggest gap + +`https://www.amazon.jobs/en/search.json?normalized_country_code[]=CHE` → clean public JSON, **32 CH roles**. +Among them, live right now: + +- **Senior Forward Deployed Engineer, AWS Forward Deployed Engineering — Zurich** +- Sr. Delivery Consultant – AI/ML, Professional Services — Zurich +- Sr Specialist SA – GenAI, Specialists Team Germany/Switzerland — Zurich +- Senior Security Assurance Solutions Architect, AWS Security Assurance — Zurich + +Why this matters more than any other candidate: **AWS is the primary cloud in the evidence base** +(SW-1 migration, the Swisscom data products). `claims.json:274` marks GCP `evidence: unverified, +output: forbidden` — which is exactly what hard-gated the two Google GenAI FDE reqs this morning. +An AWS-native FDE req in Zurich is the same lane without the cloud gap. Clears the comp bar. +No adapter work needed beyond a thin JSON fetcher. + +### Axpo — the energy-trading lane, finally live + +`https://careers.axpo.com/jobs.json` — Teamtailor on a custom domain. **400 roles, 98 tech-ish.** +Note the feed is JSON Feed format keyed `items`, not `jobs`, so the existing `fetch_teamtailor` +needs a small tweak (and the demo-board fingerprint guard still applies). + +Live right now: **"Forward Deployed AI Engineer (f/m/d)"**, plus Senior Application Manager/Solution +Architect, Quantitative Modeller, Junior/Financial Data Analyst, Leiter/in IT Division Hydroenergie. + +Memory (`user_role_targeting_energy_trading`) names Axpo and Alpiq explicitly as targets — data/ +platform engineering *inside* a trading shop, not ETRM or quant. Only MET was ever configured, and +MET has produced nothing. Axpo is German-speaking (Baden/Zurich), which fits the DE/EN profile that +rules out the Geneva traders. + +## 6. Verified negative — do not add + +- **Coinbase proper.** Greenhouse board `coinbase` is live (169 jobs) but has exactly **2 EMEA-remote + roles, both non-engineering** (Business Controller, Threat Assessment Manager). The Ventures board + removed earlier was portfolio-only, so Coinbase was never really covered — but covering it properly + gains nothing. Crypto lane stays Kraken + Bitcoin Suisse. +- **Alpiq, Glencore, Swiss Re, Sunrise** — no SmartRecruiters, Greenhouse, Ashby or Lever board found. + Careers sites are bespoke/JS-rendered with no discoverable JSON API in a network trace. Not worth + Playwright maintenance on spec. +- **The remote-EU data-infra tier as a category** (ClickHouse, MongoDB, Redis, Temporal, Airbyte, + Starburst…). Skipping this deliberately: Grafana is already on the roster and memory flags it as + **below-bar geo-fenced comp**. These firms band EU-remote salaries the same way, so the whole tier + fails the 180k bar regardless of role fit. Elastic/Confluent/Grafana already cover the archetype. + +## 7. Probe-worthy — not yet verified, do not add on my word + +- **CERN** (`careers.cern/jobs`) — has dedicated "Data Science, AI & Analytics" and "Information + Technologies" fields of work. English-working international organisation in CH, i.e. the same lane + as the BIS Basel application. Needs a scrape-mechanics check. Best remaining unverified candidate. +- **Swiss Post** (`career.post.ch`) — Bern-headquartered, has an "Informatik und Digital Services" + category, fits the Bern WLB tier alongside PostFinance (already scraped, and a Swiss Post company). + My probe timed out on `networkidle`; needs a retry with a laxer wait. +- **NATO NCIA** (`ncia.nato.int/careers.html`) — the current `nato` adapter returns 4 reqs, all JWC + Stavanger. NCIA is NATO's actual technology arm (Brussels/The Hague/Mons) and is a separate + pipeline. Worth checking whether it is separately scrapable — it would be the one way to keep a + NATO lane without the Norway constraints. +- **SIX Group** — fingerprinted as SuccessFactors (`career_company=sixgroupse`). Zurich financial- + market infrastructure. Endpoint pattern is known; content unverified. + +--- + +## Suggested order of work + +1. **Fix Roche / Meta / Apple** — restores three companies that currently contribute nothing while + appearing healthy. Highest value per unit effort, and it's a correctness bug, not a preference. +2. **Add Amazon/AWS** — trivial adapter, an on-profile Zurich FDE req live today. +3. **Add Axpo** — small `fetch_teamtailor` tweak for the `items` key; opens the energy lane. +4. **Add title filters** to BKW, SBB, BFH, PostFinance, Swissgrid, Novartis, Palantir. +5. **Decide on MET/LDC and the Norway three** — a judgment call, not a bug. +6. Probe CERN, Swiss Post, NATO NCIA, SIX.