Scraper fixes: - Roche: new fetch_phenom adapter (Phenom refineSearch). The old playwright scrape of ?locationsearch=Switzerland harvested recommendation-widget cards (Shanghai, Kyiv, Bogota) while the page reported no-results. 0 -> 88 CH-eligible roles. - Apple: dropped default_location "Switzerland", which relabelled US "Various Locations" postings as Swiss (84 phantom CH rows over 4 runs). Now honestly 0. - Meta: NOT broken — metacareers reports "1 Items" for Zurich. Comment added so it is not "fixed" again. New boards: - Amazon/AWS (fetch_amazon): 32 CH roles incl. a Zurich AWS FDE req and a Bern ProServe Cloud Architect. AWS is the evidenced cloud; claims.json forbids GCP. - Axpo (teamtailor via base_url + pagination): 461 roles, opens the energy lane. Locations read from schema.org jobLocation with ISO alpha-2 expanded, so Madrid/Milan/Warsaw roles are not marked Swiss. Telenor benefits too. Title filtering now has two explicit modes. Inclusion allowlists fail closed and hide unanticipated good-fit roles, so they are now used only where volume forces it (>~200 roles). Everything else uses the shared, board-agnostic NOISE_TITLE_EXCLUDE, which fails open and leaves the final call to the scorer and the reviewer. Palantir stays unfiltered per its existing documented rationale. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
206 lines
12 KiB
Markdown
206 lines
12 KiB
Markdown
# Scout roster review — 2026-08-18
|
||
|
||
> **Status: implemented 2026-08-18.** Sections 1, 2 and 5 have been acted on; see
|
||
> "What was actually done" at the bottom, which also records two findings in this
|
||
> document that turned out to be **wrong** once the fixes were attempted.
|
||
|
||
Originally analysis only. 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.
|
||
|
||
|
||
---
|
||
|
||
# What was actually done (2026-08-18)
|
||
|
||
Implementing the recommendations disproved two of them. Both corrections are recorded here
|
||
rather than quietly edited above, because the original claims were used to justify the work.
|
||
|
||
## Correction 1 — Meta is NOT broken
|
||
|
||
Section 1 listed Meta as returning garbage. It does not. `metacareers.com` itself reports
|
||
**"1 Items"** for the Zurich office filter — the board is genuinely near-empty and the scraper
|
||
reports it accurately. No change made beyond a comment recording the verification, so it is
|
||
not "fixed" again later. Roche and Apple were real bugs; Meta was not.
|
||
|
||
## Correction 2 — inclusion filters were the wrong instrument
|
||
|
||
Section 2 recommended adding `_title_filter` allowlists to seven boards. That was implemented
|
||
and then **reversed**, on the objection that an allowlist *fails closed*: a strong-fit role
|
||
with a title nobody anticipated is dropped at fetch time, never scored, and appears in no
|
||
report and no JSON dump. The final call should sit with the scorer and the reviewer, not a
|
||
keyword gate.
|
||
|
||
Filtering is now two explicit modes:
|
||
|
||
| Mode | Behaviour | Where |
|
||
|---|---|---|
|
||
| `_title_exclude` (**default**) | Fails **open** — drops only unambiguous non-tech titles (`hausdienst`, `physiotherapie`, `violine`, `lehrstelle`, `legal counsel`…). Everything else is scored. | 14 boards |
|
||
| `_title_filter` | Fails **closed** — allowlist, used only where volume makes full scoring impractical (>~200 roles) | Databricks, Snowflake, Datadog, Elastic, Fivetran, Louis Dreyfus |
|
||
|
||
`NOISE_TITLE_EXCLUDE` is one shared, board-agnostic list. Terms that could plausibly attach to
|
||
a technical role (analyst, manager, specialist, consultant, architect, lead) are deliberately
|
||
excluded from it.
|
||
|
||
Also corrected: BKW's 61/75 match rate was blamed on the missing filter. The real cause is
|
||
`_score_floor: 2`, set deliberately because the English keyword scorer cannot read German
|
||
titles. The floor was left in place.
|
||
|
||
## Fixes shipped
|
||
|
||
- **Roche** — new `fetch_phenom` adapter (Phenom `refineSearch`). Was 40 scraped / 0 Swiss;
|
||
now **133 scraped, 88 CH-eligible, 25 matches**.
|
||
- **Apple** — removed `default_location: "Switzerland"`, which was relabelling US "Various
|
||
Locations" postings as Swiss. Now honestly reports **0 CH-eligible**.
|
||
- **Amazon / AWS** — new `fetch_amazon` adapter. **32 CH roles, 29 eligible, 13 matches**,
|
||
including the Zurich AWS FDE req and a Senior ProServe Cloud Architect in **Bern**.
|
||
- **Axpo** — `fetch_teamtailor` extended for custom domains and pagination. 461 roles.
|
||
Locations now come from the feed's schema.org `jobLocation`, with ISO alpha-2 expanded to
|
||
full country names — without that, `"Burgdorf, CH"` failed the CH keyword match, and a
|
||
forced `default_location` would have marked ~380 Madrid/Milan/Warsaw roles as Swiss (the
|
||
Apple bug again). Telenor gained real locations from the same change.
|
||
- **Filter modes** as described above, plus `artificial intelligence`, `data scientist`,
|
||
`data-driven`, `ai engineer`, `ai platform`, `ai architect`, `ai-systems`, `data science`
|
||
added to the shared allowlist. Bare `"ai"` deliberately omitted — it substring-matches
|
||
*Maintenance*, *Training*, *Chair*.
|
||
- **Palantir left unfiltered** — its entry already documents why (its target titles, e.g.
|
||
"Deployment Strategist", are not in the allowlist). The original recommendation to filter it
|
||
would have hidden exactly the roles worth seeing.
|
||
|
||
## Still open (deliberately not done)
|
||
|
||
- **Section 4 judgment calls**: MET Group + Louis Dreyfus, and the three Norway companies.
|
||
These are preference decisions, not bugs.
|
||
- **Section 7 probes**: CERN, Swiss Post, NATO NCIA, SIX Group.
|