# Methodology — "The Horniest Cabinet in History"

## 1. Cabinet list

- Source of truth: the GOV.UK content API for the ministers page
  (`https://www.gov.uk/api/content/government/ministers`), the machine-readable
  version of https://www.gov.uk/government/ministers.
- Pulled: **2026-07-21 12:22 UTC** (gov.uk page last updated
  2026-07-21 13:14 BST). Appointments were still ongoing on 20–21 July 2026;
  the pipeline is re-runnable and will pick up changes on the next run.
- We include the 23 people gov.uk lists under "Cabinet ministers"
  (`ordered_cabinet_ministers`). Ministers who "also attend Cabinet" are
  excluded. One member (Baroness Smith of Basildon) sits in the Lords.
- Where gov.uk still showed a member's pre-reshuffle post alongside the new
  one (a normal transition artifact), we used the most recently started
  current role.
- Cross-checked against news coverage of 20–21 July 2026 (ITV News,
  LabourList live blog); no discrepancies.

## 2. Member identification

- IDs resolved via the UK Parliament Members API
  (`https://members-api.parliament.uk/api/Members/Search`), disambiguated by
  party (Labour / Labour Co-op), current membership and house.
- Service history from `/api/Members/History?ids=…`: every Commons/Lords
  membership period, first election, and gaps > 90 days.
- **Years in Parliament** = the sum of all membership periods (both houses)
  up to 21 July 2026. Dissolution periods (~5 weeks per election) are
  excluded for everyone, so the denominator treats all members equally.
  Notable gaps the metric corrects for:
  - Andy Burnham: out of the Commons 3 May 2017 → 18 Jun 2026
    (Mayor of Greater Manchester; re-entered at the Makerfield by-election
    on 18 Jun 2026 per the Members API).
  - Heidi Alexander: 9 May 2018 → 4 Jul 2024 (Deputy Mayor of London).
  - Douglas Alexander: 30 Mar 2015 → 4 Jul 2024 (lost seat).
  - Baroness Smith: Commons 1997–2010 as Angela Smith (Basildon), Lords
    2010–present; both houses counted.

## 3. Hansard searching

- Source: the official Hansard API (`https://hansard-api.parliament.uk`),
  endpoint `/search/contributions/Spoken.json`, parameters
  `queryParameters.searchTerm`, `.memberId`, `.startDate`, `.endDate`,
  `.orderBy=SittingDateAsc`, `.skip`, `.take=100`. Spoken contributions only —
  no written questions/answers.
- Searches run: **21 July 2026, 12:30-14:30 UTC**. All raw responses cached to disk
  (`raw_responses/`); the run is reproducible without re-fetching.
- The API's result-count fields (`SpokenResultCount`) are broken (always 0),
  so we paginated every query until a short page.
- **The search engine does not stem**: "nipple" and "nipples" are different
  queries. Every term was searched as an explicit variant set (see table
  below); multi-word variants were sent as quoted phrases. Every hit was then
  re-verified against a word-boundary regex on the contribution text;
  API hits that failed regex verification are kept in the dataset flagged
  `unverified` and excluded from all counts.
- **Pre-2005 records are unattributed in the API** (MemberId = −1; speaker is
  a free-text `AttributedTo` string). Member-filtered searches therefore only
  reliably cover ~2005 onwards. To cover older service (five cabinet members
  were first elected 1992–2001), we additionally swept every term unfiltered
  across **9 Apr 1992 – 31 Dec 2005** (window starts at the earliest first
  election in the cabinet: Angela Eagle) and attributed hits by matching the
  `AttributedTo` string against each member's names-over-time and
  constituency history from the Members API, validated against their service
  dates. Matches are labelled by confidence (`name+seat`, `name_only`,
  `seat_only`); ambiguous matches were dropped and counted in the QA log,
  not silently.
- Overlap between the sweep and member-filtered queries is deduplicated on
  `ContributionExtId` per (member, term).
- Politeness: single-threaded, ≥0.4 s between requests, retry with backoff.

### Term variants searched

| Term | Tier | Search variants |
|---|---|---|
| viagra | 1 | viagra, viagras |
| orgasm | 1 | orgasm, orgasms, orgasmic |
| brothel | 1 | brothel, brothels |
| dogging | 1 | dogging |
| threesome | 1 | threesome, threesomes |
| erectile | 1 | erectile |
| libido | 1 | libido, libidos |
| aphrodisiac | 1 | aphrodisiac, aphrodisiacs |
| foreplay | 1 | foreplay |
| nipple | 1 | nipple, nipples |
| g-spot | 1 | "g-spot", "g spot" |
| kama sutra | 1 | "kama sutra", kamasutra |
| strip club | 1 | "strip club", "strip clubs" |
| lap dance | 1 | "lap dance", "lap dances", "lap dancing", "lap dancer", "lap dancers", "lap-dancing" |
| sex toy | 1 | "sex toy", "sex toys" |
| onlyfans | 1 | onlyfans |
| blue balls | 1 | "blue balls" |
| gigolo | 1 | gigolo, gigolos |
| dominatrix | 1 | dominatrix, dominatrixes, dominatrices |
| chastity | 1 | chastity |
| erection | 2 | erection, erections |
| intercourse | 2 | intercourse |
| climax | 2 | climax, climaxes |
| stimulation | 2 | stimulation |
| bondage | 2 | bondage |
| missionary | 2 | missionary, missionaries |
| prostitute | 2 | prostitute, prostitutes |
| escort | 2 | escort, escorts |
| frenulum | 2 | frenulum |
| rectum | 2 | rectum, rectums |
| genitals | 2 | genitals |
| member | 2 (gag) | count-only via /search.json overview |

- **"member" (Tier 2 gag)**: searching this per-member and harvesting text is
  infeasible (it appears in a large share of all parliamentary speech —
  "the hon. Member for…"). We report, per member, the number of **spoken
  contributions containing the word "member"** from the Hansard overview
  endpoint (`/search.json`, `TotalContributions`). It is a count of
  contributions, not occurrences, covers only the attributed era (~2005+),
  and is reported as its own column, outside the leaderboard score.
- Deliberate scope choices, for transparency: "lap dance" was expanded to
  include "lap dancing/dancer(s)" (the form Parliament actually uses, e.g.
  licensing debates); "prostitute" does **not** include "prostitution";
  "escort" does not include the verb forms "escorted/escorting"; "genitals"
  does not include "genitalia"; "orgasm" includes "orgasmic".

## 4. Counting and cleaning

- The headline unit is **mentions** (occurrences of the term in the text of a
  spoken contribution), not contributions; a speech using "brothel" three
  times counts three. Contribution counts are also reported.
- Deduplication: unique on (member, term, ContributionExtId).
- **Tier 2 classification**: every hit was classified by a rule-based
  context pass over a ±150-character window around each occurrence:
  - *escort*: false positive if police/prison/military/naval/convoy/patient
    transport context; relevant if escort agency/service, sex-work context.
  - *erection*: false positive for erection of buildings/statues/masts etc.;
    relevant for erectile/penile/sexual context.
  - *intercourse*: false positive for social/commercial/diplomatic
    intercourse (common in older debates); relevant for sexual intercourse.
  - *stimulation*: false positive for economic/fiscal/nerve/brain etc.
  - *climax*: false positive for "climax of the debate/campaign" metaphors.
  - *bondage*: false positive for debt bondage/bonded labour/slavery.
  - *missionary*: false positive for religious context; relevant only for
    "missionary position"/sexual context.
  - *prostitute*: relevant by default (it is literally sex-related);
    false positive only for the "prostituting a principle" metaphor.
  - *frenulum, rectum, genitals*: always relevant (anatomical — the gag).
  - Rows matching neither direction are flagged **review** for manual
    checking. **Nothing is deleted**: every row keeps its classification and
    the dataset reports raw vs cleaned counts side by side.
- **Tier 1 caveat we discovered and did not hide**: "dogging" is *not*
  unambiguous in parliamentary English — "problems dogging the industry" is
  a routine metaphor. "Chastity" also occasionally appears as fiscal
  metaphor. Both received the same context classification as Tier 2 terms;
  Tier 1 totals exclude their false positives, and raw Tier 1 counts are
  reported alongside.
- Mentions occurring inside what looks like a quoted **legislation title**
  are flagged (`in_legislation_title`) and kept, per the editorial rule:
  exclude only if misleading, otherwise footnote.

## 5. Scores

- `tier1_mentions` — cleaned Tier 1 mentions (all service, both eras).
- `tier2_cleaned_mentions` — Tier 2 raw minus rule-classified false
  positives (review-flagged rows are **included**, so manual review can only
  lower these counts; the review column is published).
- `combined_score` = tier1 + tier2 cleaned.
- **`mentions_per_year`** (headline) = combined_score / years in Parliament.
- The "member" contribution counts are a separate gag column, not scored.

## 6. Known caveats

1. **Departmental brief inflation.** Ministers answering on Health, Home
   Office, Justice, Care or Women & Equalities briefs discuss sexual-health
   and sex-industry policy as their job. The leaderboard column
   `relevant_briefs_held` (from the Members API biography endpoint) lists
   every such post per member with dates — disclose alongside the ranking.
   This materially affects, above all, **the leaderboard winner**: every
   one of Alan Campbell's 46 cleaned mentions dates from 2008–10, when he
   was the Home Office minister (Crime Reduction) taking the Policing and
   Crime Bill — lap-dancing club licensing and prostitution offences —
   through the Commons. Also relevant: Burnham (Health Secretary 2009–10,
   earlier Health minister), Cooper (Home Secretary 2024–25, now Health),
   Streeting (Health Secretary 2024–26), Kinnock (Care Minister 2024–26),
   Mahmood (Home Secretary 2025–, Justice 2024–25), Norris (Home Office
   2025–26), Eagle (Home Office minister twice), and Phillipson (Women &
   Equalities 2024–).
2. **Attribution era asymmetry.** Post-2005 coverage is exact
   (member-ID-filtered). 1992–2005 coverage relies on text attribution of
   the sweep; it is high-precision but could miss oddly formatted
   attributions, so pre-2005 counts are a floor. This mainly concerns
   Eagle, Cooper, Healey, Campbell, D. Alexander, Bryant, Burnham and
   Baroness Smith.
3. **Occurrence counting is text-based** on the API's contribution text;
   column-number markup was stripped before counting.
4. **Contribution ≠ utterance**: Hansard is the edited official record.
5. **The "member" gag count** covers ~2005+ only and counts contributions,
   not occurrences (see §3).
6. **Link checking**: all data came from the Hansard API
   (hansard-api.parliament.uk), which is unrestricted. The public website the
   quote links point to (hansard.parliament.uk) blocks requests from the
   data-collection server (CDN bot protection, HTTP 403), so the links could
   not be click-tested from here. However, every debate GUID used in
   top_quotes.md was verified against the API's /debates/debate/{id}.json
   endpoint and matches the linked title and date exactly; the URLs follow
   Hansard's canonical pattern. A quick click-through in an ordinary browser
   before print is still recommended.
7. Hansard content is used under the **Open Parliament Licence v3.0**;
   quotes carry attribution and links.

## 7. Fallback

- TheyWorkForYou was held in reserve; the official Hansard API worked for
  every member, so **no member's data comes from TheyWorkForYou**.

## 8. Data quality log

- Total unique (member, term, contribution) hits: **66**
  (38 relevant, 28 false positives — all retained and flagged in
  contributions.csv; 0 unresolved 'review' rows: every rule-flagged row was
  hand-adjudicated, see manual_classifications.json).
- 11 rows hand-adjudicated after rule flagging; 2 pre-2005 rows hand-attributed
  from surname-only follow-up lines and 5 rejected (manual_attributions.json —
  includes two 'Lord Burnham' rows that are a hereditary peer, not Andy
  Burnham, and two 'Mr. Smith' rows that are John Smith and Chris Smith).
- 2,815 unfiltered 1992-2005 sweep rows scanned; 3 attributable to current
  cabinet members; 0 ambiguous matches dropped.
- 1,362 API requests, 0 unrecoverable failures. The /search.json overview
  endpoint 500-errors for 7 member IDs on whole-history queries; their
  'member' gag counts were computed by summing 4-year windows instead.
- The API's SpokenResultCount field is broken (always 0) — pagination-based
  counting used throughout, hence exact.
- 'anti-climax' matches the word-boundary regex for climax; both such hits
  were classified false positive by hand.
- Burnham's only near-hits are 'escort' (airport security / police-escort
  jibe at Andrew Lansley) and 'stimulation' (spinal cord, pain treatment) —
  all false positives. The Prime Minister scores zero.
- Zero hits in all of Hansard for any cabinet member: viagra variants aside
  from Bryant's, orgasm, threesome, libido, aphrodisiac, foreplay, nipple,
  g-spot, sex toy, onlyfans, blue balls, gigolo, dominatrix, chastity,
  dogging, bondage (sexual sense), missionary (sexual sense), frenulum,
  rectum. Parliament is less fun than hoped.
