ADR-0003: Source Register and Methodology Page
Status: Accepted (2026-05-19) Supersedes: — Superseded by: —
Context
The screening system's defensibility — to internal users, to clients, and to future-us — depends on being able to answer two questions clearly:
- What does each rule actually measure, and where does the data come from?
- Is each source live and working, or is it broken/pending/deprecated?
In May 2026 the system has three live scrapers (NZBA, SBTi, PRB), several deferred/planned sources (BHRRC, BankTrack, PAX, UK MSA Registry, UK GPG Registry, Ethical Consumer, Profundo, IFRS S2 / corporate disclosure scraping), and one removed source (TCFD, disbanded Oct 2023). This state lives partly in the source DB table, partly in scattered scraper code, partly in Slack handoffs. There is no single, queryable, user-visible record of "what does the system know about itself."
This ADR records the decision to make source transparency a structural part of the UI, not an afterthought document.
Decision
Build a Methodology page (/methodology in the UI, see ADR-0002) generated from the database. It exposes three things in a single screen:
-
How the score works — short prose explanation of coverage-weighted scoring (per ADR-0001), pillar weights, peer comparison logic, RAG bands (per ADR-0004). Three to four paragraphs, links to relevant ADRs for full detail.
-
Source register — table of every data source, generated from a join of
source× latestscrape_run. Columns: - Source name (link out to original — e.g. clicking "NZBA-MEMBERS" goes to
unepfi.org/net-zero-banking) - Type (membership list / regulatory register / NGO database / news / corporate disclosure / commercial report)
- Access mechanism (free HTML / free API / free PDF / paid subscription / RSS)
- Rules it feeds (list of rule IDs)
- Status (live / pending / planned / deprecated)
- Last successful run (timestamp + record count)
-
Last error (if any, with truncated error message)
-
Rule catalogue — every rule the system applies, grouped by pillar and sub-criterion. Columns:
- Rule ID (e.g. E1.1)
- What it measures (one-line description)
- Source(s) that feed it
- Scoring logic type (boolean / 0–100 direct / deduction)
- Status (live / pending / planned)
Design principles for the page.
- All sources link out to their origin. No black-box claims. If we say "Barclays is in NZBA," the user can click through to UNEP FI's published list and verify.
- Source status is honest. "Last successful run" and "last error" are surfaced, not hidden. A broken scraper appears as broken on the Methodology page — the new scoring model (ADR-0001) already prevents silent base-value substitution from masking breakage; the Methodology page reinforces this visibly.
- Each rule shows its lineage. Rule E1.1 → fed by source NZBA-MEMBERS → scraped via
src/scrapers/nzba.js→ last successful run #3 / 13 May / 642 records. This is the audit trail that makes the score defensible. - The page is alive. Adding a new scraper or rule updates the Methodology page automatically via DB join, with no hand-edited content to maintain.
Source register, initial state
The following sources should be present in the source table at v1 launch, with statuses as below. Sources beyond this list will be added per their own ADRs or via straightforward scraper-implementation tickets.
| Code | Name | Type | Access | Feeds | Status |
|---|---|---|---|---|---|
NZBA-MEMBERS |
UNEP FI Net-Zero Banking Alliance | membership list | free HTML | E1.1 | live |
SBTI-VALIDATED |
Science Based Targets initiative | membership list | free HTML | E1.5 | live |
PRB-SIGNATORIES |
UN Principles for Responsible Banking | membership list | free HTML | G3-PRB.1 | live |
BHRRC-RESOURCE-CENTRE |
Business & Human Rights Resource Centre | NGO database | free HTML + RSS | S2, S5, E7, G5 + watchlist | planned · priority 1 |
UK-MSA-REGISTRY |
UK Modern Slavery Act Registry | regulatory register | free HTML | S2.1 | planned · priority 2 |
UK-GPG-REGISTRY |
UK Gender Pay Gap Service | regulatory register | free HTML | S3.1 | planned · priority 3 |
BANKTRACK-BOCC |
BankTrack "Banking on Climate Chaos" | NGO database | free PDF + data | E5.1 | planned · priority 4 |
PAX-DBOTB |
PAX "Don't Bank on the Bomb" | NGO database | free HTML + PDF | E6.1 | planned · priority 5 |
ETHICAL-CONSUMER |
Ethical Consumer ratings | NGO database | mixed (paid for detail) | watchlist only — see note | planned · priority 7 |
PROFUNDO-REPORTS |
Profundo published research | commercial reports | free PDF | E5, E6, S5 | planned · priority 10 |
IFRS-S2-CORP |
Corporate sustainability disclosure (IFRS S2) | corporate disclosure | corporate PDF | E4.1 | planned · priority 8 |
TCFD-SUPPORTERS |
TCFD supporters list | membership list | — | E4.1 (historical) | deprecated · task force disbanded Oct 2023 |
Note on Ethical Consumer. Used as a watchlist source only, not a score input. Their published ratings are valuable as third-party context but their methodology is opinionated (e.g. blanket negative treatment of fossil and tax-haven exposure) — folding their judgements into our composite would make our screen a thin veneer over theirs. The Methodology page should display Ethical Consumer ratings alongside our own in a "Third-party views" panel, not blend them.
Note on Profundo. Lower priority because each report is a one-off PDF parse, and the underlying data often overlaps with BankTrack. Useful for deep enrichment on specific issues, not for headline coverage growth.
Consequences
Positive. - Source transparency becomes a structural feature, not a copy item. - A new scraper adds itself to the Methodology page on commit — no documentation drift. - "Why is Barclays scored this way?" has a UI-traceable answer at all times. - Client-facing summaries can reference the Methodology page as a defensible explanation of what we measure and don't. - Forces honest treatment of source breakage. A scraper that fails for 3+ runs appears red on the Methodology page; the team sees it without needing to read logs.
Negative.
- The Methodology page becomes a place where ugly truths show up. A run with 4/10 scrapers broken will look bad. This is the intended honesty, but it means the page should probably stay internal-only at first; a sanitised client-facing version can be a v1.5 surface.
- Requires source and scrape_run tables to be the canonical source of truth. Any "manual" sources (e.g. red flags entered at intake) need a corresponding source record so they show up in the register too.
Implementation.
- source table likely needs new columns: type, access_mechanism, status, external_url, priority, feeds_rules (JSON array of rule IDs).
- Migration 012_source_register_columns.sql.
- Backfill the table from the list above.
- /methodology route renders via three DB joins (source register, rule catalogue, per-rule signal counts).
- Status updates: a nightly job sets a source's effective status based on its last scrape_run outcome (live if last 3 successful, degraded if 1–2 failures in last 5, broken if 3+ consecutive failures).
Alternatives considered
- Static methodology doc. Easier to write, immediately stale. Rejected.
- Methodology page hand-written but with a separate "Source status" page generated from DB. Splits concerns the user wants together. Rejected.
- No methodology surface at all, just rely on per-rule tooltips in the institution detail page. Insufficient for client defensibility, and no way to see "what's the system's overall coverage situation" at a glance.
References
- ADR-0001 (coverage-weighted scoring) — Methodology page explains the scoring approach
- ADR-0002 (UI architecture) —
/methodologyroute lives here - v0.4 workbook,
Sourcessheet (initial seed for the source register) - Migration
012_source_register_columns.sql - Scraper priority list, 2026-05-19 chat handoff