Apple (the big one)
- The location=switzerland-CHE slug stopped resolving; Apple silently applied
a US location, so every run from at least 2026-08-31 returned the same 21
US/intern cards and 0 Swiss roles. Now location code CHEC (from
/api/v1/refData/postlocation), result list item as the card (location
readable), pagination, settle delay, longer wait and per-element timeout.
Verified twice: 24 Swiss roles each run.
BIS
- bis.org went behind a Cloudflare challenge (403 even headless). Moved to the
Workday tenant bis.wd3.myworkdayjobs.com/External, which also carries the
office. Host alias + lower-cased jr-id keep all 9 bis.org#jr decisions
linked (applied jr100498 included).
NAV
- Search API 429s after ~9 requests and stays blocked for hours: discovery
capped at 8 searches (4s pacing). Posting text now comes from NAV's official
third-party feed (pam-stilling-feed, public rotating token), with a small,
slow website-page fallback for ads the feed lacks (~2/3). Verified live on
15 real ads; fallback path tested on fixtures.
Location filter
- EMEA leak fixed: a country allowlist without CH/DK plus a trailing region
tag is no longer Europe-remote (27 rows). Swiss/Danish segments in
multi-location strings are evaluated per segment. Regression over all
2026-10-22 rows: only the fenced rows changed.
Reputation
- Every board now has a dated verdict; kununu added as a primary source next
to Glassdoor (the one with more reviews decides; user tip). Second-source
scores now count (a low one means avoid). AVOID: BIS (Glassdoor 2.9),
BFH (kununu 3.3), Kdo Cy (federal administration kununu 3.4).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- classify_language_requirement: an ad stating only an English requirement
("communication and presentation skills in English") with no Norwegian
requirement now reads english_ok. Checked after the Norwegian patterns, so
"fluent English and Norwegian" still reads norwegian_required. Nordic
Semiconductor's ads read UNCLEAR in the first Norway run.
- Decisions from the 2026-10-22 run: Nordic Embedded Software Test Automation
Engineer `maybe` (embedded/Bluetooth experience required, coursework only -
the Kongsberg gate); Nordic ATE Test Engineer `skip`; RUAG Senior DevOps
Engineer C5I repost `skip` ("Swiss citizenship required"; a different role
from the July shortlist, whose note is carried into the new row).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Norway search (user request 2026-10-21/22: Trondheim, Bergen or similar, not Oslo)
- New location policy norway_no_oslo: keeps a role if any Norwegian location
is outside the Oslo area. Equinor and Telenor move to it.
- New `nav` adapter for the NAV national register (arbeidsplassen.nav.no):
keyword queries on a fixed request budget, paced; on HTTP 429 it stops and
returns a PARTIAL run with a warning instead of failing. Full-ad text checks
are cached in state/nav_detail_cache.json (ignored). Tested against
fixtures only: the live API was rate-limiting during the build.
- Dedicated boards where NAV was measured thin (2026-10-22: Nordic 0, DNV 2,
Equinor 2 vs ~10, NATO 0): Nordic Semiconductor (teamtailor custom domain),
DNV (new `algolia_jobs` adapter; app id/key/index read from the page each
run), Arm Trondheim (new `radancy` adapter), Microsoft Norway (pcsx).
Verified live: 7 / 6 / 7 / 6 roles outside Oslo.
- NAV rows that duplicate a dedicated board's posting are dropped
(employer alias + normalized title).
Language / citizenship check
- classify_language_requirement reads the requirement SENTENCE, not the
posting language: "norsk og/eller engelsk" is English OK, "kommunisere
godt ... på norsk og engelsk" is Norwegian required. Only an explicit
Norwegian requirement or Norwegian-citizenship requirement filters a role;
clearance is noted, never a gate. Runs on full ad text (NAV detail page,
untruncated Teamtailor/PCSX descriptions). Telenor Lead Platform Engineer
now reads NORWEGIAN REQUIRED (it read UNCLEAR on truncated text).
- Norwegian title keywords added (they all scored 0 and were never checked).
Employer reputation (user requirement 2026-10-22)
- state/employer_reputation.json (now tracked): dated Glassdoor lookups with
sources and the approved thresholds (good >= 3.8 on >= 50 reviews; ok
3.5-3.79 or thin-but-backed; avoid < 3.5; Vizrt excluded). Every report
row shows the verdict; unlooked-up employers show UNCHECKED.
Report
- Sections per region: Switzerland, Norway, Europe-remote / Denmark (user
preference); `--region=ch|no` runs one region only.
Fixes
- Microsoft links: apply.careers.microsoft.com<positionUrl>?jobId=<id>
with a host alias so all 7 logged Microsoft decisions still resolve; the
old jobs.careers.microsoft.com form redirected to a generic search page.
PCSX calls retry on 429.
CLAUDE.md corrections log: design/architecture gap (2026-10-21) and the
Microsoft link fix; the EMEA-suffix location leak stays OPEN.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
BIS
- The RSS feed carries no location, so every vacancy was stamped with
default_location "Basel, Switzerland". jr100491 (Hong Kong, BIS Asia office)
therefore passed the CH filter and reached the 2026-10-14 triage.
- fetch_rss now resolves the location per item through _rss_item_location:
the vacancy page's static "Geographical location" field
(location_page_regex), then a "based in ..." sentence in the feed
description, then default_location with a warning on stderr.
- Verified with --only=bis: 3 scraped, 2 eligible (both Basel); jr100491 now
reads "8 Finance Street, Central, Hong Kong" and is excluded.
Confluent
- IBM closed the acquisition on 2026-03-17. The Ashby board dropped from 17
jobs (2026-10-08) to {"jobs":[]} (2026-10-14), and careers.confluent.io is
behind a Vercel bot checkpoint.
- New `ibm` adapter for the open IBM careers search API
(www-api.ibm.com/search/api/v2; POST; size capped at 100, paged with
`from`). Location is built from city, country and work mode, e.g.
"United States - Remote".
- Confluent keeps its id, so seen-state and decisions still link. Verified
with --only=confluent: 84 roles, none in CH/Europe-remote scope today, and no
0-jobs warning.
CLAUDE.md corrections log: 2026-10-15 entry. Also notes that HashiCorp
(dropped 2026-06-06 for lacking a public API after the IBM acquisition) could
return through the same adapter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Second-pass review of this session's work by another agent. It corrected several
real mistakes of mine and finished F06 gaps I had left open. Reviewed, verified
and committed as-is.
THE MISS THAT MATTERS
`job_scout/state/applications.json` — the authoritative application registry
introduced by F02 — was never actually tracked. `job_scout/state/*` in
.gitignore silently excluded it, so my checkpoint commit afdef7e claimed to add
it and did not. Only `application_cohort.json`, the GENERATED projection, was
version-controlled; the source of truth and the migration history backup were
not. .gitignore now carries explicit negations for both.
MY ERRORS, CORRECTED
- "kastellaun" was in CH_LOCATION_KEYWORDS. Kastellaun is in Rhineland-Palatinate.
I took it from a Bundeswehr reserve listing and filed it under Switzerland -
precisely the class of bug F12 existed to fix.
- The F12 fix only widened the keyword list; SmartRecruiters still discarded the
structured country, which was the concrete case the review named
(city=Baar, country=CH). The adapter now preserves it, and a COUNTRY_NAMES
mapping gives country precedence over a bare town name.
- F15 was applied to Taleo and Prospective only. Greenhouse still wrote
`updated_at` into `posted`; it now uses `published_at` and carries provenance.
- My negation guard `\b(no|not|...)\b[^.;]{0,60}$` was too loose - an unrelated
"not" within 60 characters could mask a real claim. Tightened to require the
negation to govern the term.
- F18's retirement of the macro-count rule missed "Four to six compact skills
lines" in the workflow; removed now.
F06 GAPS I LEFT OPEN, NOW CLOSED
Date-format validation on education/employment periods (the 2035-99 case named
in the review), evidence-structure validation, referential integrity on evidence
source files, and the missing-identity KeyError.
F10 TAKEN FURTHER, AND RIGHTLY
I demoted the US-GPA fields to *_orientation_only. They are now removed
entirely, with grade_output_rule saying what to do instead: use the German grade
and scale, and if a recipient requires a US GPA, use THEIR method and record it.
Keeping a number derived by a non-recognised method invites its use.
Also: the Capgemini omit-preference now sits in experience_capgemini.md itself,
alongside the instruction not to fill or explain the intentional gap.
BIS BASEL - REJECTED 2026-09-11
jr100429, applied 2026-07-10, no interview, no reason given. Recorded in the
registry with a dated event and in the decision log; the "prep interview brief
when screening lands" next action is cleared. This also settles the 2026-09-04
observation that the req had vanished from the BIS board - it was a real
rejection, not just a closed posting.
VERIFICATION I RAN MYSELF BEFORE COMMITTING
49/49 tests. Validator PASS with 0 advisory warnings. Package manifest and
registry views current. All 12 F12 location cases still correct, including
Kastellaun now rejecting. The F05 counter-proof still catches all 9 violations.
SBB, NVIDIA, RUAG and Kdo Cy resumes still scan clean. Diffs are net-additive
across every reference file - the deletions are replacements, not losses.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
F15 - dates and metadata kept their meaning
- The Taleo parser stored an application DEADLINE in `posted`, so a role closing
on 30 September looked as though it had been published then - backwards for a
freshness signal. It now populates `deadline`, and `posted` stays empty
because that board genuinely publishes none.
- The Prospective adapter read unit, Lohnklasse and a named contact, folded them
into `description` for scoring, and `_process_company` then discarded
`description` - losing exactly the fields that decide level, pay and whether a
cold submit is necessary. They are now carried as fields through to the report
and the JSON dump, alongside `date_provenance`.
- Named contacts now appear in report rows. Channel is the rationed variable
since 2026-09-05, so a published, reachable name is the difference between a
cold submit being a choice and being the only option.
F16 - writes stopped destroying delivered work
- Every run of a day wrote `<date>.md`/`.json`, so a restricted run replaced the
full daily report. This is not hypothetical: it happened twice in this session
and both times the 37-company run had to be repeated by hand. Restricted runs
now write `<date>.only-kdocy.md` and say so.
- `save_seen()` ran in a `finally:` BEFORE the report was written. A failed
report write therefore left roles marked seen, so a `--new-only` retry would
hide precisely the hits that were never delivered. Seen-state is now committed
only after report and dump are on disk - and never by a restricted run, which
did not look at the whole board.
- Atomic writes used a fixed `.tmp` name; two writers could share it and
os.replace the wrong content into place. Unique temp names now.
34/34 tests pass; validated on a live 37-company run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
The scout presented a keyword count as "Strong fit" / "Medium fit". It is
neither: it measures how many profile keywords a posting echoes, and knows
nothing about his evidence, the hard requirements, the level, the language or
the commute.
- Buckets renamed to keyword relevance, with "NOT a fit judgement" in the
heading, and score_job documents the limit with the review's own example:
"Senior AI Engineer, Generative AI / LLM / RAG" scores 12 against "Senior Data
Engineer" at 3, while the second is much closer to what he can evidence.
- German job vocabulary added. Every German-language posting used to score near
zero regardless of fit, which is the real reason RUAG, SBB, BKW, PostFinance
and Kdo Cy all needed a _score_floor. The floor was a workaround; the missing
terms were the defect. "Senior Dateningenieur" 1 -> 3, level with its English
twin.
- Platform/DevOps vocabulary was simply absent: devsecops, platform engineer,
platform automation, infrastructure as code, observability, site reliability.
The Kdo Cy "ICT-System Engineer (DevSecOps / Platform Automation)" scored ZERO
before this - a posting whose requirement lines match his canonical evidence
almost line for line. It now scores 10.
- Noise is unaffected: "Office Manager:in Administration" still scores 0.
Floors were left in place so this diff stays attributable; they can likely be
reduced now that the vocabulary exists.
34/34 tests pass; validated on a live 37-company run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
These three all cost roles BEFORE a human ever read them, which is the
expensive kind of defect: a job that never reaches the report cannot be
evaluated at all.
F11 - dedupe by requisition, not title
- The old rule collapsed everything sharing a normalised title within one
employer. Two different reqs called "Senior Data Engineer" in Bern and Zurich
became one row, and different teams hiring the same title vanished.
- Requisition identity is now the key, parsed from the URL with the same
patterns the decision log uses, employer-scoped so two boards cannot collide.
- The legitimate case the old rule existed for - one role republished per
location - is a SAME-REQUISITION case, so those merge their locations.
- A shared title across different requisitions is now a warning, never a
deletion.
F12 - location filters
- Substring matching accepted "Bernau bei Berlin" as Bern. Place matching is
now whole-word.
- Thun, Zimmerwald, Baar, Olten and ~25 more Swiss towns were rejected outright
when the adapter supplied no country. Zimmerwald is the Kdo Cy site he applied
to; Thun is where he lives.
- Aarhus, Odense and other Danish cities added alongside Copenhagen.
- A stray "Europe" no longer implies remote eligibility next to an explicit
onsite marker or a single-country residence restriction.
- All 14 cases named in the review now resolve correctly.
F13 - decision identity
- The generic fallback key dropped the query string, so /vacancy?job=1 and
?job=2 were the same key and one decision silently covered both. Identifying
query parameters are now kept; tracking noise is not.
- The READ path had no slug fallback although the WRITE path got one on
2026-09-04. Every RUAG repost therefore came back undecided despite a recorded
decision - which is what happened to Lead-Architekt Network- und Richtfunk on
2026-09-10, days after 63 RUAG rule-outs were written.
- Both paths now share `lookup_decision`. Verified on a live RUAG run: 7
reposted requisitions recovered their decisions.
- A slug match is reported as RELATED with the matched URL, never applied as if
it were the same requisition: a repost can differ materially, as RUAG
demonstrated when it moved a disqualifier into a job title.
tests/test_scout_matching.py added. Full suite 34/34 pass.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
Scout
- New `prospective` adapter for ohws.prospective.ch, wired up as `kdocy`
(jobs.admin.ch, filtered to Kommando Cyber). jobs.admin.ch is an S3-hosted
SPA that returns AccessDenied to any direct fetch, headless included, so the
site cannot be scraped -- but the SPA reads a public, unauthenticated API.
All 463 federal roles in ~2.4s, against RUAG's 35s Playwright scrape.
- This board is richer than any other source: Lohnklasse, application deadline,
a named contact per posting, and the full Aufgaben/Anforderungen body, so
scoring runs against the JD text rather than the title.
- Thread `deadline` through normalization, the markdown report and the JSON
dump. A board with hard deadlines needs them on the row.
- Match `verwaltungseinheit_*` by prefix: the sub-unit key is department
specific (VBS 1083398, EFD 1083364) and hardcoding one breaks reuse.
- MANUAL_CHECK entry for the Bundeswehr Reserve portal. The data is reachable
(SAP E-Recruiting OData, SearchCategory 0022) but the portal actively blocks
automation, and getting through needs UA spoofing plus masking
navigator.webdriver. Not wired up by choice -- the operator-sanctioned
Suchauftrag/job alert is the better channel. Reasoning is in the comment.
Applications
- SBB Data Engineer 103755: interviewed 2026-09-09, WITHDRAWN by the candidate
2026-09-11. Net downgrade on four axes (41h vs 40h, 25+Brueckentage vs 28+5,
3 vs 2 office days, and Anforderungsniveau K tops out ~145k against ~135k
inside a band running to ~160k -- he would enter K at its ceiling merely to
break even). The cohort's only interview, and it ended as his no, not theirs.
- Kdo Cy DevOps Engineer III: REJECTED 2026-09-10, 14 days, no interview.
Form letter with no diagnostic content. Identical on every recorded
dimension to SBB (core / 79 / gate pass / DQ 92 / weak channel) and the two
went opposite ways -- recorded as worth watching, not as evidence for the
channel thesis.
- Citadel row cleaned up: it claimed the cohort and decision-log entries were
deliberately unwritten while its own status line read SUBMITTED. Both exist.
The next-step cell still said "ask BEFORE building the package" two weeks
after submission.
Decision log
- 69 RUAG rows -> 3 undecided. 63 title/family rule-outs, each noting that it
is not a JD read, plus three that are: Test Manager C5I, System Engineer C5I,
ICT Solution Architect. Guarded against the shared F/A-18 slug so one write
could not silently swallow the other.
Note: the K->L/Kader rule is SBB-specific and was deliberately narrowed --
Anforderungsniveau is SBB's own system and does not map onto jobs.admin.ch
(Lohnklassen), RUAG or PostFinance. Thun-area employers sit outside the Bern
salary logic entirely.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qej5SBvhcbGXHwLqNWiskM
Scout run 2026-09-04 (36 companies, 778 eligible) plus the NVIDIA package it
surfaced, and the tooling and policy fixes found along the way.
Application
- NVIDIA Senior DevOps Engineer, Zurich (JR2024256): submitted 2026-09-05.
Evidence Fit 64/100 Stretch, hard gate FAIL x2, channel Weak. Sent on an
explicit user override with the working model unresolved, so hybrid-vs-onsite
is a live screening topic. 2pp resume + 1pp cover letter, both validators
PASS, 0 boxes, 0 Tier 1 findings open.
Policy
- Drop the 7 Core / 2 Adjacent / 1 Stretch cohort caps. They had no derivation
and were overridden whenever they bound, and the cohort was confounded: it
tested fit class while holding channel constant at Weak across all six
applications. Keep the recording, drop the rationing.
- Channel replaces the slot budget as the rationed variable: no application
goes out cold when a named contact is published and reachable.
- Propagated through shared_ops, session_file_template, cohort_tracker
(counts, never counts-against-a-target) and application_cohort.json.
Tool fixes
- fetch_workday emitted 404 URLs for every Workday company (NVIDIA, Novartis,
Equinor): externalPath is site-relative and needs the locale + site prefix.
6/6 short-form 404, 3/3 long-form 200. 773 dead links repaired across 42
archived reports.
- find_decision_url silently de-linked decisions on two boards, which is why
ruled-out roles kept resurfacing as undecided. RUAG rotates its UUID on
repost; BIS migrated its vacancy URL scheme, orphaning 5 decisions including
a live application. Fixed as a two-tier match, not a slug key -- slugs
collide (two live RUAG reqs shared one).
Knowledge base
- claims.json: add Bash / shell scripting, the third canonical gap of this
shape after Ansible and Linux administration.
- bundle_data_platform: BS-4 was framed as a delivered observability stack over
what claims.json calls a proof of concept -- the defect the 2026-08-21 sweep
was told to look for.
- CLAUDE.md and AGENTS.md: correct the RUAG Data Lakehouse shortlist claim,
which the JD does not support and which both files still asserted.
- resume_template: comment-guard the missing babel/ngerman language block.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QFb8tTCig5r1KzkQiNXcYt
RUAG C5I - AI Engineer C5I (Thun, app ID 18027): SUBMITTED 2026-08-27.
Evidence Fit 74/100, fit class Stretch, title-capability hard gate FAIL
(R1 build/operate the AI-LLM platform and R2 in-house LLM/retrieval are
Adjacent, not Direct) - all knowingly accepted under the user's explicit
Phase 0 override. Consumes the cohort's sole Stretch slot: cohort is now
6/10, Stretch 1/1.
Critique ran twice. Round 1 scored the documents 85/100 and raised three
Tier 1 items; Round 2, after the fixes, scores 93/100 with truth and
provenance 24/25 and zero Tier 1 findings. Evidence Fit did not move and
was not allowed to: PP-3 is a personal project and cannot convert an
Adjacent title-capability into a Direct one.
Documents (.tex is the deliverable; PDFs are gitignored):
- resume 2pp/13 bullets, letter 1pp/295 words, both validators PASS
- headline is now the canonical title "Staff Data, Analytics & AI
Engineer", which puts the req's own word above the fold
- PP-3 added as a Projekte section - the only current Linux/hardening
evidence, since BS-6 ended Dec 2022
- the letter names the AI-platform gap in one sentence, then connects
SW-5 to C5I's stated DevSecOps model
- "governte" -> "governance-konforme"; JD term coverage 18/22 -> 22/22
claimable, with all six gap terms still correctly absent
Two defects found and fixed that the first critique missed:
- the resume never loaded babel, so a German document was hyphenated
with English patterns (Hal-bleiterfertigung, Tran-skription). Fixed
with babel[ngerman] plus a Transkription exception; this also cleared
an overfull box. Check this on every future German package -
resume_template.tex likely has the same omission.
- IBM AI Engineering had no primary-source record. Certificate read
directly (IBM via Coursera, 4 Jun 2020, verify 3ZBZFVAL6A34), recorded
as entry #8; it also proves PyTorch, now evidence: certification.
Also included: the submitted Kdo Cy DevOps Engineer III package, the
Capgemini omit rule promoted into config.md, BW-1 canonicalized in
experience_bundeswehr.md, and a scout.py comment correcting the
telenorgroup slug from "near-empty" to a claimed board serving stale
phantom listings that DEMO_TITLES would not catch.
Compensation, PSP/project eligibility and role level were never resolved
before sending and are now live screening topics.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JMcHCsTKWvVzqyLChF5ckk
Boards rewrite their own URLs between runs, so a decision recorded under one
URL was lost the next time the same req appeared. Amazon truncates the job
slug to a fixed width and that width changed, which silently resurfaced the
already-skipped Principal Delivery Consultant req at score 7 in the 08-21 run.
Adds _decision_key(): "<host>#<req-id>" via per-board ID patterns, falling
back to a normalized path. Host-scoping is deliberate — a wrong ID match can
never mark a role decided at a different company. Also collapses genuine
duplicates: Workday's /apply suffix, PostFinance's per-locale URLs, Apple's
?team= and /locationPicker variants, the same NVIDIA req under two locations.
The log file stays URL-keyed (it is hand-edited and the URL is the readable
part); lookups go through index_decisions(). --decide now updates an existing
entry when the job is already logged under a drifted URL instead of adding a
second row.
Verified against all 955 URLs in the decision log plus the 2026-08-21 report:
4 groups collapse, each inspected and correct, no false merges.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WpMtWFtYkGkjSMShuTgXiB
Probed CERN, Swiss Post, NATO NCIA and SIX Group. Two actionable results:
- CERN: SmartRecruiters board "CERN", 66 live Geneva postings with real
engineering (Deep Learning Developer, ML Engineer NGT, Full-stack SWE, Data
Storage R&D Engineer). Added — the adapter already existed. Two standing
caveats recorded in the entry: Geneva is ~1h50 from Bern so a 2-3 day hybrid
is not viable without relocation, and CERN grades sit below the 180k bar.
- NATO NCIA: nato.int is Cloudflare-blocked to headless browsers. Moved to
MANUAL_CHECK beside Oracle, with a note that NCIA is a separate pipeline from
the JWC Stavanger reqs the `nato` adapter returns.
Not added, documented instead:
- Swiss Post: real board is job.post.ch (SuccessFactors CSB), scrapable via
a[href*='/job/']. The only tech role on page 1 was served from the PostFinance
sub-board, which is already covered. Paginated, so this is page-1 evidence
only, not a whole-board verdict.
- SIX Group: SAPUI5 SPA backed by a legacy DWR RPC endpoint
(careerJobSearchControllerProxy.getInitialJobSearchData.dwr). Scrapable in
principle, brittle in practice; job rows did not render into readable text.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Pipeline:
- SDU PhD: closed, not proceeding. Prof. Jørgensen never replied to the
2026-08-02 enquiry; user dismissed it two days before the 2026-08-20 deadline.
- Google FDE III GTM: closed, not proceeding after two Google rejections. The
bar for a third attempt is now a very strong fit; this was Adjacent with an
agent-orchestration gap. Frees the Adjacent cohort slot (back to 1/2).
JD triage — 5 pulled and read, 1 survives:
- SHORTLIST AWS Senior FDE Zurich: all four basic quals pass and AI/agentic is
preferred-only, unlike the Google Senior Staff FDE where vector DB + RAG were
minimum quals. AWS is the evidenced cloud; JD names Kiro, which he uses.
- SKIP AWS ProServe Bern (clinical pharma domain gate), AWS Principal Delivery
Consultant (8+ yrs architecture leadership + VP+ exec comms), GitLab FDE EMEA
(Ruby/Go hard gate), MS 200044133 (title says FDE Data Scientist, quals are
BGP/MPLS/SD-WAN network engineering — mislabelled req).
Roster:
- Dropped Louis Dreyfus: 300 roles, all Brazil/India/Bulgaria ops, zero Swiss.
- Kept MET Group: its "0 eligible" was a filter artifact; exclusion mode reveals
real Baar/Zug commodity-trading roles.
- Kept Equinor/Telenor/NATO. Memory corrected: the Norway lane is selective, not
closed — the user still wants very good Norwegian roles.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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>
The board never carried Coinbase's own roles — only Getro portfolio companies.
Across ~3 months it surfaced 3 distinct CH-eligible roles, all from Ashby
(recruiting software, ruled out 2026-07-28) and all decided "skip". Since the
Ashby exclusion it has returned 0 jobs on every run, surfacing a false error
line in each report.
Entry replaced with a "Dropped:" note per the file's convention. fetch_getro is
retained (no caller) since it generalises to any Getro collection id.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The "dbtlabsinc" Greenhouse board started returning 404, silently dropping
a target company from every scan. getdbt.com/careers now redirects to a page
serving Fivetran's Greenhouse listings (gh_jid links) — the two companies
merged, so the roles live on board "fivetran" (239 jobs, 10 title matches).
Renamed the entry id dbtlabs -> fivetran and cleared the stale seen-state key.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Aker BP ASA — Data Product Architect (FINN 469067315): archive the finalized
resume/CL sources, JD, session and critique. Submitted 2026-07-30 ahead of the
2026-08-02 deadline; logged as applied in the scout decision log and marked
SUBMITTED in Active Sessions.
KB: record Atlassian Compass as Swisscom's metadata/catalogue platform for data
products and lineage (user-confirmed 2026-07-29). Practitioner use only —
claims.json forbids claiming administration, rollout or ownership, and it is
explicitly not a substitute claim for Purview, Collibra or Alation.
Also: close out the Google Business Home session (no interview), extend the job
scout, and allow the job-board domains used during the Aker BP research.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Tighten eligibility to CH/DK/Europe-remote (Equinor Norway-only, NATO DK+NO), add Taleo adapter, parallel API fetches, atomic state writes, and empty-board warnings. Log NATO AI Engineer as applied and Architect as skip.
Equinor (Workday) and BFH (Bern, playwright) wired up as new sources; artificial
intelligence/analytics-engineer keywords added so int'l-org listings (BIS) stop scoring
as noise. certifi-backed SSL context works around Workday certs failing verification
against a stale Windows root store.
location_matches() previously treated "remote + any single named EU country" as
CH-eligible, which let single-country residency-locked listings (e.g. Databricks'
"Remote - United Kingdom") pass as if they were open EU-wide. Now requires either a
pan-regional keyword (Europe/EMEA/Global/Worldwide) or 2+ distinct countries named.
Denmark is carved out as its own always-on relocation category (on-site or remote,
any company), replacing the previous Databricks-only opt-in.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds positive keywords (forward deployed, field engineer, resident
architect/engineer, customer engineer) and title-filter entries so
vendor deploy-to-customer roles surface — the lane matched to
user_international_mobility (intl scope from Bern, travel-OK, no
relocation). Bare "resident" stays title-filter-only to avoid
re-opening the pre-sales-SA overscoring trap.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Track per-job decisions across runs so we don't re-evaluate roles.
- state/decisions.json (keyed by URL: company/title/decision/note/date), now
git-tracked while seen_jobs.json stays local
- --decide "<url>" <status> [note] records a decision; --hide-decided gives an
undecided-only view; report tags each role inline with its decision
- usage docstring updated
- seed 18 decisions (9 shortlist, 7 skip, 1 paused, 1 maybe); flags Google Staff
FDE GenAI as the paused prior session
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add positive keywords for the core DevOps/data-platform/cloud lane and
technical-architect titles (cloud/data/platform architect) that previously
scored 0 and surfaced only via the generic "senior" term. Rebalances rankings
so hands-on engineering roles aren't buried under pre-sales "Solutions
Architect" + crypto keyword stacking.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two scoring bugs inflated the rankings:
- Substring matching: 'rag' matched sto[rag]e / tet[rag]on, 'intern'
matched inte[rnal], 'lead' matched [lead]ership. Roche's staff
restaurant and Cisco Tetragon roles scored as fits. Now keywords must
not be flanked by alphanumerics (c#/.net/c++ keep matching).
- Body boilerplate: every Kraken post mentions crypto/blockchain/trading,
so sales/PM/design roles scored as high as engineering ones. Title
matches now score full weight, body-only matches half (min 1);
negatives still count fully anywhere.
Strong-fit count drops 13 -> 5; the bogus 'intern' negatives and rag
false positives are gone. Shared _kw_in() also backs the title filter.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Dennis is interested in trading roles (energy/finance/crypto), but the
scorer had no terms for them, so trading-tech roles scored 0 and got
buried. Add a trading/quant cluster (trading, trader, quant, market
data, low-latency, FIX protocol, brokerage, commodity, execution) plus
singular "solution architect" and adjacent stack (C#, .NET).
Bitcoin Suisse's Solution Architect Trading now scores 4 (medium) on
title alone, up from 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Bitcoin Suisse's careers page is a JS-rendered Next.js SPA, but the
underlying onlyfy.jobs ATS exposes a plain HTML job list at
candidate/job/ajax_list (title + location per card). Add an onlyfy
adapter that parses it — no headless browser needed. Surfaces the 3
current Zug roles correctly (CH filter + pre-dedup location filtering
keep the Swiss posting over its Bratislava/Copenhagen cross-posts).
MANUAL_CHECK is now empty (all 22 target companies automated), so the
report's manual-check section is suppressed when the list is empty.
Coverage notes updated.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AMINA Bank rates poorly on Glassdoor and isn't worth tracking. Remove
its manual-check entry, leaving Bitcoin Suisse as the only manual source.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Coinbase cut ~14% of staff and is not actively hiring; remove its
manual-check entry. The getro Coinbase Ventures source covers portfolio
companies only, not Coinbase itself, so Coinbase is now off the radar
until they reopen. Now 2 manual sources (AMINA, Bitcoin Suisse).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add a getro adapter (POST JSON search API) and wire up the Coinbase
Ventures portfolio talent network (collection 1625), CH + eng-title
filtered. Note this covers portfolio companies (Ashby, Notion, VALR,
World, ...), not Coinbase itself, which doesn't list on its Ventures
board — Coinbase-the-employer stays in MANUAL_CHECK.
Also clean up stale comments: drop Sonova (MedTech, off-thesis, dead
scrape) from MANUAL_CHECK, remove the dangling BIS comment now that
BIS is automated via rss, and refresh the adapter-coverage notes and
module docstring to the current 21-automated / 3-manual state.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Generic RSS/RDF feed parser (handles RSS 1.0 namespaced items + RSS 2.0)
- BIS (Bank for International Settlements, Basel) promoted from manual-check
to an automated source via its vacancies RSS feed — commutable from Bern,
salary net of Swiss tax. Scout now 20 automated + 4 manual-check.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>