ADR-0094: Brand-directed operating-subsidiary discovery
Date: 2026-07-06 Status: Accepted Deciders: Adrian (Soft4U), Claude Opus 4.8
Context
The EVOI network scan (ADR-0019/0025) discovers related entities by following NorthData
relatedCompanies, which models control / ownership. Ownership flows upward from a
holding SPV to its ultimate owners. Verified live during the OB Holding 1 OÜ validation run:
the network scan reached the full Luxembourg holding chain (Odyssey / Hippocrate / Noal SPVs)
and the Estonian operating parent (Olympic Entertainment Group AS) — but the scanned roster was
LU (6) / EE (3) / MT (1), zero LT. A direct NorthData query confirmed why:
Olympic Entertainment Group AS's relatedCompanies returns only its LU parents and its
auditor (PwC) — it does not list its operating subsidiaries. So the Lithuanian operating
casino, where the €8.4m AML fine sits, is never discovered. It shares a brand (OlyBet /
Olympic Casino) with the subject, not a direct ownership edge, so no amount of deeper ownership
traversal reaches it.
The same NorthData, queried by name search for the brand, returns the operating entities (15 hits for "OlyBet"). The gap is therefore a discovery-modality gap, not a depth or budget one: ownership traversal cannot find a sibling that is linked by brand, not by an ownership edge.
This closes the analytical half of issue #170's "corporate-group recall" follow-up (the recall half is ADR-0093 Tier-B).
Decision
Add a brand-directed discovery pass (app/agents/brand_discovery_phase.py,
run_brand_directed_discovery, with the pure gating in
app/services/brand_directed_discovery.py) that runs AFTER the network phase and BEFORE the
Tier-B adverse-recall pass. It derives the group's brand tokens (reusing
_derive_brand_tokens), keeps only distinctive ones, runs a bounded NorthData name search
per token, filters the hits, and appends the survivors to the network roster as
brand_discovered entries — which then flow into Tier-B per-entity adverse-media recall.
Because these entities feed the risk pipeline, the pass is conservative by construction:
- distinctive-token gating — only coined tokens (≥5 chars, not a generic corporate word: "olympic", "casino", "holding", "europe", "group", "entertainment" are all filtered) trigger a search. Searching a generic word returns thousands of unrelated entities (the IOC, every "… Casino …"); "olybet"/"odyssey" survive.
- vertical gating — only runs for verticals where a cross-jurisdiction operating graph is compliance-material (gambling/gaming/casino/betting).
- two-lane attribution (ADR-0078) — a brand-name match is an
unverified_candidate(never subject risk on a shared word; ADR-0073 R9), promoted toverifiedonly when a shared director or registered address corroborates a real corporate link. The name-as-identifier guard rejects a reg-no that equals the name. - token cap (
brand_directed_discovery_max_tokens, default 3).
Dark launch: settings.brand_directed_discovery_enabled defaults False — a no-op until
a live validation run confirms precision and cost, at which point the flag is flipped (a
Calibration-Review-gated change, since discovered entities feed the deterministic escalator).
Decision context:
- Latency: none while off. When on, ≤
max_tokensNorthData searches (€0.008 each) + the Tier-B adverse-media recall on any survivors — bounded and vertical-gated. - Dependency surface: no new packages; a pure gating module + an orchestration phase + a
one-call hook; reuses
_derive_brand_tokens,NorthDataService.search_company, and the Tier-B roster path. - Debuggability: the gating/attribution are pure functions with 8 unit tests; the phase is
guarded (non-fatal) and records
brand_discovery_coverage. - Reversibility: single flag flip; the code path is additive.
- Blast radius: off by default → zero change until enabled. When on, a discovered entity can only ADD scrutiny, and the two-lane guard prevents a brand-name match from reaching subject risk on its own.
- Alternative considered: increase EVOI network depth — rejected (NorthData does not list the operating subsidiaries at any depth; a deeper ownership traversal cannot find a brand sibling).
Consequences
Positive
- Closes the discovery-modality gap: a group's operating subsidiaries in other jurisdictions are found by brand and fed into per-entity adverse-media recall, where the OB Holding LT fine lives.
- Reuses the existing brand-token + two-lane-attribution machinery; no new external dependency.
- Conservative: vertical- and distinctive-token-gated, dark-launched, and never escalates the subject on a shared brand word alone.
Negative
- Brand search has an inherent false-positive surface (common words) — mitigated by the distinctive-token filter, the brand-in-name check, and the unverified-candidate default, but not eliminated; this is exactly why it is dark-launched and calibration-gated.
- Discovered entities are screened for adverse media (Tier-B) but not yet run through the full network sanctions/PEP scan — a follow-up.
- Real external-API spend when enabled.
Neutral
- The pass mutates the network roster in place; discovery coverage is recorded separately from the Tier-B recall coverage.
Alternatives Considered
Alternative 1: Increase EVOI network depth / budget
- Scan more of the ownership graph, deeper.
- Why rejected: the live NorthData check shows the operating subsidiaries are simply not in the ownership graph at any depth (Olympic Entertainment lists only parents + auditor). More depth spends budget climbing further up the ownership chain, away from the operating siblings.
Alternative 2: Enable immediately (no dark-launch flag)
- Ship it on by default.
- Why rejected: it feeds the deterministic escalator and has a real false-positive surface (brand words); flipping it on without a live precision/cost validation risks over-discovery. The flag lets the code land, be unit-tested, and be enabled deliberately after review.