Skip to content

ADR-0011: Per-scraper inheritance via parent_lei / operating_arm_lei

Status: Accepted
Date: 2026-05-20
Supersedes:
Superseded by:
Related: ADR-0008 (hard-exclusion flags), ADR-0009 (GICS classification), docs/design/holdings-vs-subsidiary-framework-memberships.md

Context

Screening sources track companies at different corporate levels. PAX Don't Bank on the Bomb names the group/holdings entity ("HSBC" meaning HSBC Holdings plc). The Principles for Responsible Banking lists the signing entity (the operating bank — DBS Bank Ltd, not DBS Group Holdings Ltd). This produces concrete mismatches in the v1.5 pilot:

  1. INST-0009 HKSC — PAX names HSBC Holdings. HKSC (a subsidiary) is in the pilot; HSBC Holdings is also in the pilot as INST-0004. When evaluating HKSC's PAX signal by its own LEI/name, HKSC appears CLEAR. The correct read is that PAX flags the group and HKSC inherits that flag.

  2. INST-0019 DBS Group Holdings Ltd — PRB lists DBS Bank Ltd (the operating bank). DBS Group Holdings is in the pilot; DBS Bank Ltd is not. Without inheritance, DBS Group appears as a non-PRB-signatory. The correct read is PRB membership through the operating bank.

The methodology note docs/design/holdings-vs-subsidiary-framework-memberships.md (cycle 2.6B) established the decision principle: signals apply at the entity level the source naturally tracks at, with provenance when inheritance applies.

Decision

Inheritance is implemented per-scraper, not globally. Each scraper module explicitly opts in to one of two inheritance patterns:

parent_lei inheritance (PAX pattern)

Used by scrapers that track at the group/holdings level. When a direct lookup finds no match AND institution.parent_lei is set:

  1. Resolve the parent institution from the pilot using parent_lei.
  2. Check whether the parent would match the source (using the scraper's own matching logic against its own LEI/name).
  3. If yes: the institution inherits the parent's signal. Flag and watchlist entries are written with provenance (source_finding_id carries -via-parent; title and summary document the inheritance chain).

Guard: if both parent and subsidiary are in the pilot AND both match the source directly, each gets an independent signal. No inheritance fires between two pilot entities that both match — that would produce duplicate signals at the same group under two LEIs.

operating_arm_lei inheritance (PRB pattern)

Used by scrapers that track at the operating-entity level (signatory databases, certification registers). When a direct LEI and name lookup finds no match AND institution.operating_arm_lei is set:

  1. Look up the operating arm's LEI in the source's member map.
  2. If found: the institution inherits the signal. The raw_value field carries JSON provenance: { "inherited_via": "<lei>", "inherited_from_name": "<name>", "inheritance_reason": "PRB lists operating bank, not holding" }.

No global inheritance rule

Scrapers that are not listed below do not perform inheritance. If a new source surfaces a concrete parent-vs-subsidiary mismatch, that scraper opts in at that point with an explicit decision recorded in its module header and a backlog item.

Scrapers with inheritance (cycle 3)

Scraper Type Pattern Case
PAX-WEAPONS (src/scrapers/pax.js) parent_lei Group-level HKSC via HSBC Holdings
PRB-SIGNATORIES (src/scrapers/prb.js) operating_arm_lei Signatory entity DBS Group via DBS Bank Ltd

Scrapers without inheritance (cycle 3)

NZBA, SBTi, BankTrack, BHRRC, CBI, BoCC, UK-MSA, UK-GPG — strict LEI/name match only. Inheritance opt-in deferred until a concrete mismatch surfaces in pilot runs.

Schema

-- institution table (migration 019)
ALTER TABLE institution ADD COLUMN parent_lei TEXT;
ALTER TABLE institution ADD COLUMN operating_arm_lei TEXT;

Both columns are NULL for 19 of 22 pilot institutions. Populated only for: - INST-0009 HKSC: parent_lei = MLU0ZO3ML4LN2LL2TL39 (HSBC Holdings plc) - INST-0019 DBS Group: operating_arm_lei = ATUEL7OJR5057F2PV266 (DBS Bank Ltd)

Population principle (from 2.6B design note): populate only where a concrete source-level mismatch has been observed across pilot runs. Do not populate speculatively.

Deferred cases

Seven additional institutions have known group/operating-bank LEI splits that could require operating_arm_lei, but no concrete PRB or other source mismatch has been observed through run 18:

  • INST-0010 AIB Group → Allied Irish Banks p.l.c.
  • INST-0011 Bank of Ireland Group → Governor and Company of the Bank of Ireland
  • INST-0015 ING Groep N.V. → ING Bank N.V.
  • INST-0017 JPMorgan Chase & Co. → JPMorgan Chase Bank, N.A.
  • INST-0018 Citigroup Inc. → Citibank, N.A.
  • INST-0020 Goldman Sachs Group → Goldman Sachs Bank USA / Goldman Sachs & Co. LLC
  • INST-0021 MUFG → MUFG Bank, Ltd.

Populate per institution when a concrete mismatch surfaces. Parked in backlog.

Consequences

Positive

  • INST-0009 HKSC now correctly shows flag_weapons=tripped via PAX parent-group inheritance. Previously CLEAR despite being operationally part of HSBC group.
  • INST-0019 DBS Group now correctly shows PRB membership (boolean=1) via operating arm inheritance. Previously non-signatory despite DBS Bank Ltd being a founding PRB member.
  • Provenance is explicit and auditable: watchlist titles show "via parent group", raw_value JSON documents inherited_via / inherited_from_name.
  • Inheritance is per-scraper, not global — no risk of unintended signal propagation from scrapers that weren't designed for it.

Negative

  • run.js must include parent_lei, operating_arm_lei in the institution SELECT. If a future scraper needs these fields, they're already fetched.
  • Manual parent_lei / operating_arm_lei population requires maintenance when new institutions are added. Current scale (2 populated of 22) makes this trivial.

Neutral

  • v2 path: replace manual lookups with GLEIF-derived parentage (ultimate parent / direct parent) when scale demands it. GLEIF Level 2 data covers most listed entities.

Amendment — cycle 9a: NF-/FIN- sector-scope differentiation pattern

Established 2026-05-21.

The NF-G4 / G7 split (cycle 9a, ADR-0010 amendment 3) is the first instance of a recurring pattern: a universal rule (UN- prefix, applicable_sectors='ALL') that structurally overlaps with an existing financial-sector rule, resolved by scoping the universal rule to non-financials only and renaming it to NF-.

This is named here as the sector-scope differentiation pattern. When a universal rule duplicates existing sector-specific coverage for one sector, the resolution is: - Narrow applicable_sectors to the sectors where the rule adds new coverage. - Rename from UN- to NF- (or a future FIN- prefix) to reflect the actual scope. - The narrowed rule's rule_type and sub-rule structure remain unchanged.

This is not a commitment to systematically fork all UN- rules into sector-specific pairs. It applies only where structural overlap with an existing sector-specific rule is confirmed (as it was for UN-G4 / G7). Future instances should be decided case-by-case; record the decision in the ADR covering the affected rule, not here.

References

  • docs/design/holdings-vs-subsidiary-framework-memberships.md — methodology decision
  • Migration 019 (src/db/migrations/019_gics_inheritance.sql)
  • src/scrapers/pax.js — parent_lei implementation
  • src/scrapers/prb.js — operating_arm_lei implementation
  • ADR-0010 amendment 3 (docs/adr/0010-amendment-3-un-g4-g7-overlap.md) — first instance of the sector-scope differentiation pattern
  • docs/design/berkshire-hathaway-direct-screen-note.md — cycle 15d: direct-screen of BRK as a single listed entity; apparent-overlap note (BRK holds BoA shares; not a double-count)
  • docs/design/orit-physical-asset-infrastructure-carve-out.md — cycle 15d: physical-asset infrastructure trust carve-out from screen-the-manager default; carve-out boundary definition