feat(applications): archive Aker BP package, add Compass evidence, extend scout

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>
This commit is contained in:
2026-08-01 10:18:07 +02:00
co-authored by Claude Opus 5
parent a22c6ff597
commit f1095a062f
14 changed files with 788 additions and 11 deletions
+59
View File
@@ -204,6 +204,21 @@ COMPANIES = [
# ops and score 0 under the English eng keyword list — keep them visible.
"_score_floor": 2,
}),
# Telenor Norge (Teamtailor) — Nordic telco; Swisscom is the direct domain analogue
# and Dennis worked in Norway before (Vizrt, Bergen). NOTE: the old Workday tenant
# telenorgroup.wd3.myworkdayjobs.com is dead (HTTP 422 on /wday/cxs, 2026-07-29) —
# Telenor migrated to Teamtailor. Slug telenorgroup is a near-empty group-HQ board;
# telenornorway is the real Norway board (redirects to careers.telenor.no).
# CAVEAT: most Telenor Norge postings require Norwegian ("norsk og engelsk") and are
# Oslo/Trondheim onsite-hybrid — verify both per role before tailoring.
# Norwegian-language titles/descriptions score ~0 under the English eng keyword
# list, so keep a score floor (same pattern as Equinor).
("telenor", "Telenor Norge", "teamtailor", {
"slug": "telenornorway",
"default_location": "Oslo/Trondheim, Norway",
"_location_policy": "norway_only",
"_score_floor": 2,
}),
# NATO civilian vacancies (Oracle Taleo). Public marketing page is
# https://www.nato.int/en/work-with-us/careers/vacancies — jobs actually live on
# nato.taleo.net career section 2. Location policy dk_no: Denmark + Norway only
@@ -232,6 +247,10 @@ COMPANIES = [
"collection": 1625,
"locations": ["Switzerland"],
"job_functions": ["Software Engineering", "IT", "Data Science"],
# User preference 2026-07-28: recruiting-software domain is not a target.
# Exclude the underlying employer here without hiding unrelated companies
# carried by the Coinbase Ventures portfolio board.
"_exclude_orgs": ["Ashby"],
"_title_filter": ENG_TITLE_FILTER,
}),
# Bitcoin Suisse (Zug) uses the onlyfy.jobs ATS. No title filter — small crypto
@@ -628,6 +647,42 @@ def fetch_rss(args):
return jobs
def fetch_teamtailor(args):
"""Teamtailor public JSON Feed (`https://<slug>.teamtailor.com/jobs.json`).
Used by Telenor. The public /jobs HTML page paginates and under-reports; the feed
returns the full board in one call, so prefer it. The feed carries no location
field, so default_location is required (Teamtailor boards are per-country anyway).
Descriptions are frequently Norwegian — see the _score_floor note on the company.
TRAP: an unclaimed slug returns Teamtailor's *demo* board (HTTP 200, plausible JSON)
instead of 404. Verified 2026-07-29: `ksat` and `akerbp` both served the seed set
below though neither company uses Teamtailor. Filtered here so phantom roles never
reach a report — if a real board is ever dropped by this, widen the fingerprint."""
DEMO_TITLES = {"sales development manager", "team lead - csm", "social media manager",
"customer success manager", "key account manager", "ux designer"}
url = f"https://{args['slug']}.teamtailor.com/jobs.json"
req = urllib.request.Request(url, headers={"User-Agent": USER_AGENT, "Accept": "application/json"})
with urllib.request.urlopen(req, timeout=30, context=_ssl_context()) as resp:
data = json.loads(resp.read().decode("utf-8", "replace"))
jobs = []
for it in data.get("items", []):
jobs.append({
"id": it.get("id") or it.get("url", ""),
"title": it.get("title", ""),
"location": args.get("default_location", ""),
"url": it.get("url", ""),
"posted": it.get("date_published", ""),
"description": re.sub(r"<[^>]+>", " ", it.get("content_html", ""))[:2500],
})
titles = {j["title"].strip().lower() for j in jobs}
if jobs and len(titles & DEMO_TITLES) >= 4:
raise RuntimeError(
f"teamtailor slug '{args['slug']}' served the demo board, not a real one "
f"({len(jobs)} placeholder ads) — the company likely uses a different ATS")
return jobs
def fetch_getro(args):
"""Getro network job-board search API (POST JSON). Powers VC portfolio talent
networks — here the Coinbase Ventures web3 network (collection 1625). Returns roles
@@ -643,6 +698,7 @@ def fetch_getro(args):
if args.get("job_functions"):
filters["job_functions"] = args["job_functions"]
jobs, page = [], 0
excluded_orgs = {name.casefold() for name in args.get("_exclude_orgs", [])}
while True:
data = http_get_json(url, method="POST", data={
"hitsPerPage": 100, "page": page, "query": "", "filters": filters,
@@ -651,6 +707,8 @@ def fetch_getro(args):
batch = res.get("jobs", []) or []
for j in batch:
org = (j.get("organization") or {}).get("name", "")
if org.casefold() in excluded_orgs:
continue
locs = j.get("searchable_locations") or j.get("locations") or []
loc_str = " | ".join(locs) if isinstance(locs, list) else str(locs)
ts = j.get("created_at")
@@ -1255,6 +1313,7 @@ ADAPTERS = {
"pcsx": fetch_pcsx,
"smartrecruiters": fetch_smartrecruiters,
"rss": fetch_rss,
"teamtailor": fetch_teamtailor,
"getro": fetch_getro,
"onlyfy": fetch_onlyfy,
"lever": fetch_lever,