Pillar 2 · How we talk about it · Methodology

How we measured the talk

We read 14,577 paragraphs with an AI model, checked it against our own hand coding, corrected for its mistakes, and then looked for lasting shifts. This page explains each step, the numbers behind it, and what we had to assume.

  1. 00The pipeline at a glance
  2. 01The texts
  3. 02What we coded
  4. 03The hand-coded check set
  5. 04Choosing the coder
  6. 05Adjusting for coding errors
  7. 06Finding lasting shifts
  8. 07Explaining the shifts
  9. 08Limits and AI use
00 · The pipeline at a glance

Seven steps, from raw text to a dated shift.

Every step was fixed in writing before we saw its results: the plan, the scoring rule and the random seeds.

01 · The texts

Two streams, nine sources, one keyword filter.

We wanted what EU institutions say and what the wider press says. Everything is in English and runs from Russia’s invasion of Ukraine (24 Feb 2022) to 9 Oct 2026.

Why these sources

EU institutions covers anything EU bodies or their members publish or say: Commission press material, Parliament speeches, questions and resolutions, and formal Commission documents. Parliamentary questions react within weeks, which makes them useful for timing.

The press is the English-language international press: the Guardian through its free API, and Reuters, the Financial Times and Euractiv exported by hand from Factiva through the Sciences Po library. Factiva’s licence bans bulk downloading, so no script touched it.

We dropped think tanks and academic work because their publication delays make dates unreliable. The Council could not be collected: its site blocks automated access, and we did not get around that.

The filter

We split documents into paragraphs and kept those that mention graphite, battery, lithium, cobalt, critical / strategic raw materials, or export controls together with China. We dropped paragraphs under 15 words and boilerplate, and removed exact and near duplicates (paragraphs sharing 80% of their five-word sequences) within each source.

Very long EU documents were capped at 30 paragraphs each so that one impact assessment could not swamp a month.

Is the filter any good?

We hand-checked a random sample of kept and dropped paragraphs. 76–82% of kept paragraphs are on topic (precision). The filter finds 76–85% of the relevant paragraphs (recall); the worst case consistent with our sample is 37%. Off-topic paragraphs that slip through are mostly other uses of “battery”, and the coder marks them as “no claim”.

SourceStreamWhatAccessParagraphs
Commission press cornerEU institutionsPress releases, speeches, statementsOpen dataset (Zenodo) + Press Corner API2,869
EP plenary speechesEU institutionsDebate speeches (67% machine-translated)PlenaryEP corpus (to Apr 2026)1,519
EP questions and answersEU institutionsWritten and oral questions, Commission answersEP Open Data API + Word files814
EP adopted textsEU institutionsResolutions and reports (max 30 paragraphs each)EP Open Data API428
Commission documentsEU institutionsCOM communications and staff working documentsEUR-Lex (CELLAR)205
The GuardianThe pressArticles naming Europe and ChinaGuardian Open Platform API2,968
ReutersThe pressNews wireFactiva, exported by hand2,935
Financial TimesThe pressArticlesFactiva, exported by hand1,798
EuractivThe pressBrussels policy newsFactiva, exported by hand1,041

Plenary speeches given in other languages use the corpus’s English machine translation (1,021 paragraphs, 7% of the total); every one carries a flag. Months with fewer than 30 EU paragraphs (9 of 57) are marked as thin in the monthly charts.

02 · What we coded

For each paragraph: does it say Europe depends on someone, and where in the chain?

The unit is one paragraph. The coder answers in three steps, using a written codebook (version 2, frozen 16 Oct 2026).

Three steps

  1. Is there a dependency claim? Does the paragraph say Europe depends on, relies on, or is exposed to someone? Explicit words count (depend, reliance, vulnerable, chokepoint), and so do implicit ones (supply-chain resilience, de-risking, diversifying imports). Future demand on its own does not. If no, code No claim.
  2. Where does the dependency sit? Mark every stage the paragraph names as the place of the dependency. A stage that is only mentioned gets nothing.
  3. No stage named? A claim with no stage is coded No stage named.

Located vs mentioned

We also coded which stages a paragraph mentions at all. The gap between the two is a result: packs and vehicles are mentioned in 31% of paragraphs but are the place of dependency in only 5% of those.

Hard cases, decided in advance

  • “China controls 90% of graphite supply”, with no stage verb: no stage named. With “mines”: mining. With “produces”: refining.
  • “The battery value chain” with no stage: no stage named. Batteries as a product: packs & vehicles. A battery production step: components.
  • Recycling, technology and “manufacturing” on their own are not stages.
  • The UK counts as Europe; another country on its own does not.
CodeMeansIllustrative example
Mining (Tier I)Extraction, ore, mines, deposits, concentrates.“Europe imports almost all its graphite ore from China.”
Refining (Tier II)Turning a raw material into a purer form of itself: refining, processing capacity, battery-grade chemicals, spherical graphite. Also a country producing a material.“China refines 90% of the world’s graphite.”
Components (Tier III)The material becomes a battery part: active materials, precursors, electrodes, cells, gigafactories, battery production.“European cell makers rely on Chinese anode material.”
Packs & vehiclesFinished products: battery packs, modules, EVs, batteries bought as a product.“Europe depends on imported EV batteries.”
No stage namedA dependency is claimed but no stage is named. Generic “critical raw materials” counts here.“We must cut our reliance on China for critical raw materials.”
No claimThe paragraph does not say Europe depends on anyone. It must stand alone.“Lithium demand will triple by 2030.”

A paragraph can carry several stage codes. “No claim” must stand alone. The full codebook, with every edge-case rule and its history, is in the data folder.

03 · The hand-coded check set

150 paragraphs, coded blind by us, are the yardstick.

We never checked the model’s answers: we coded first, then compared. No check paragraph was ever shown to the model as an example.

How the 150 were drawn

  • 75 from EU institutions and 75 from the press, split between the Guardian and Factiva in proportion to their size.
  • About 25 per stream in each period (Before Dec 2023 · Dec 2023 – Sep 2025 · From Oct 2025), so we can see whether accuracy changes over time.
  • At most two or three paragraphs from any one document, because paragraphs from the same debate are not independent.
  • Paragraphs likely to be about components were over-sampled, since they are rare. Each paragraph is weighted back to its share of the corpus when we estimate error rates.

A separate set of 100 paragraphs (a 40-paragraph pilot and 60 more) was used to write the rules and to pick the worked examples in the prompt. It never touched the scoring.

Do two humans agree?

A second coder coded 40 of the 150 blind. Agreement is measured with Krippendorff’s alpha (0 = chance, 1 = perfect). It is moderate: 0.56 on the full set of codes and 0.61 on the main question. We then settled disagreements together, which changed 13 of 150 codes. This is the ceiling against which the model should be read.

What the two coders agree onAlpha
Is there a claim, and does it name a stage?0.61
Full set of codes0.56
No claim0.70
No stage named0.65
Packs & vehicles0.61
Refining0.29
Mining, componentsabout 0 (1–3 positives; not informative)
Hand-coded positives

Mining 12 · Refining 12 · Components 8 · Packs & vehicles 16 · No stage named 34 · No claim 81.

Precision of the check set

About ±6–7 points on overall accuracy, ±11–12 points per stage.

04 · Choosing the coder

Three methods competed on the check set. Claude won on every code.

The rule was fixed on 9 Oct, before scoring: the highest average F1 wins; within 0.03, the more transparent method wins.

The three candidates

A word list. Terms for each stage, extended with frequent word pairs from the corpus (“needle coke”, “battery grade”). A stage only counts as the place of dependency if it sits in the same sentence as a dependency word. Free and fully transparent.

Sentence similarity. A free sentence-embedding model (all-mpnet-base-v2) compares each paragraph with short model sentences such as “The EU relies on Chinese refineries to process graphite.” It catches synonyms but measures what a text is about, not what it claims.

Claude. Claude Sonnet 5.5 through the Batch API, given the full codebook, the edge-case rules, worked examples from the pilot set and a strict JSON answer format, 25 paragraphs per call. It also returns a short quote as evidence and an “unsure” flag.

How we scored them

F1 combines how many of the true cases a method finds (recall) with how many of its hits are right (precision); 0 is useless, 1 is perfect. We averaged it over the six codes and got 95% ranges by resampling the check set within its sampling groups (2,000 times).

Checks on the winner

  • Another model: Claude Opus 5.5 scored 0.72 and gave identical codes on 92.7% of paragraphs; most errors are shared, so they come from hard cases, not from one model.
  • The unsure flag holds 74% of errors. On the paragraphs it was sure about, the score is 0.82.
  • By stream: 0.74 on EU texts, 0.67 on the press. By period: 0.68, 0.79, 0.66.
  • Direction of errors: mostly over-claiming (seeing a claim where there is none), which the next step corrects.
MethodAverage F1 (95% range)Exact matchRole
Claude Sonnet 5.5 with the codebook0.71 (0.63–0.77)74%Chosen
Word list (dictionary)0.53 (0.45–0.60)52%Robustness check
Sentence similarity (embeddings)0.33 (0.25–0.41)45%Robustness check

Claude leads the word list by 0.18 (paired range 0.10–0.26). With paragraphs weighted to the corpus the lead is 0.10 (−0.01 to 0.21); the ranking does not change. Per-code scores are charted on the “more charts” page.

05 · Adjusting for coding errors

Correcting for the coder’s mistakes cuts claims by about a third. The trends survive.

If a coder over-claims by a known amount, you can work backwards to the true share. We did that for every month, stream and period.

How it works

From the check set we estimate how often Claude puts a paragraph of each true kind (no claim, no stage named, names a stage) into each box. That gives a 3 × 3 table of error rates, weighted to the corpus. Inverting it turns observed shares into corrected ones. This is the matrix version of the Rogan–Gladen correction used for imperfect medical tests. The corrected stage share is then split across stages in the proportions Claude used.

Uncertainty. We redraw the check set and the paragraphs 1,000 times and repeat the correction each time. The 95% ranges on the site come from these runs. Changes between periods are computed within each run, so the shared uncertainty about error rates cancels out; that is why changes are much tighter than levels.

Documents, not only paragraphs

For document-level figures, each paragraph gets a simulated “true” code drawn from the same error rates, and a document counts as a claim if any paragraph is one (1,000 runs, 5,489 documents). If errors were fully linked within a document, levels would be 1–3 points lower and changes almost the same.

Mentions

Mentioned stages were scored against a second hand-coded set of 150 paragraphs (agreement 0.74–0.90 by stage) and corrected one stage at a time, with the same 1,000-run ranges.

What the correction assumes

  • Error rates are the same over time, across streams and across materials.
  • The rate of false claims rests on four randomly drawn check paragraphs, which is why level ranges are wide.
  • The two charts of stage combinations use codes as recorded.

Before and after the adjustment

Share of all 14,577 paragraphs, whole period

  • As coded by Claude
  • Adjusted for coding errors

Claude-coded paragraphs · 3 × 3 error table from the check set

Claude’s error rates (weighted to the corpus)Rate
A paragraph with no claim is coded as a claim12%
…of which, coded “no stage named”9.2%
A no-stage claim is coded as naming a stage5.6%
A stage-naming claim is coded as “no stage named”8.2%
A real claim is missed0%
Stage mentionedAgreement (kappa)As codedAdjustedChange after Oct 2025, points
Mining0.7916.2%13.0%−3.9 (−5.5 to −2.3)
Refining0.7612.7%17.0%+0.3 (−2.2 to +2.6)
Components0.9013.1%22.0%−9.3 (−21.7 to −5.2)
Packs & vehicles0.7431.2%44.0%−9.9 (−16.6 to −6.5)
06 · Finding lasting shifts

A shift counts only when two different methods find it in the same place.

We looked for months when a line settles at a new level and stays there for at least six months, with no dates given in advance.

Two methods, one rule

  • PELT scans the series for the set of break points that best splits it into flat segments, with a penalty for each extra break (2σ² ln n).
  • Bai–Perron fits the best set of up to five breaks by least squares and picks how many with the BIC.
  • A break is confirmed when both find it within two months of each other. Each break gets a 95% range for its date (Bai 1997). We also halved and doubled the PELT penalty to see which breaks hold.

We ran this on monthly shares (no claim, no stage named, names a stage, and each stage) for all texts, EU institutions and the press, and quarterly for lithium and cobalt. Because the correction is linear, break dates are the same on adjusted and as-coded series.

Eras

As a cross-check we grouped neighbouring months with similar mixes of stages (Ward clustering, where only adjacent months may merge). It produced no clear eras.

Why each shift happened

For every break we built a file of the paragraphs either side, the topics that moved and the events nearby. Claude drafted a cause for each of 31 breaks in 9 episodes; we reviewed each one against the event dates and the paragraphs before it went on the site.

Confirmed: all texts

Jun 2025

Claims naming no stage rise by 8.7 points (date range Nov 2024 – Jan 2026).

Confirmed: the press

Oct 2025

Claims naming no stage rise by 8.8 points.

Confirmed: all claims

Sep 2022 · Jan 2024 · Jun 2025

Up, down, up.

Confirmed: one stage

May & Nov 2023

Press talk on packs & vehicles, during the UK–EU rules-of-origin dispute.

07 · Explaining the shifts

Topics, attention and word networks tell us what moved around each shift.

None of these is an outcome. They help read the coded series.

Topics

24 topics (NMF)

A topic model on all 14,577 paragraphs (word weights, single words and pairs). The number of topics was set by a rule fixed in advance that balances how coherent and how stable topics are, over 8 to 25. Topic names are ours, written from top words and example paragraphs.

Attention

Share of all output

Relevant documents divided by everything a source published that month. This separates “more talk about stages” from “everything else fell”. Reuters, the FT and Euractiv are left out (no monthly totals).

Word networks

Which words travel together

400 key words (lemmatised with spaCy). Two words are linked when they share paragraphs more than chance (NPMI above 0, at least five paragraphs). A filter keeps each word’s strongest links (disparity filter, α 0.05). Clusters by Louvain, 50 runs. Changes tested by shuffling documents between periods 1,000 times, with a false-discovery correction (q 0.10).

Materials

Graphite, lithium, cobalt

Each paragraph carries material tags. Graphite has 448 paragraphs (71 after Oct 2025), so it is read by period, not by month. Lithium is read by quarter.

Word cloud

54 words, chosen by hand

Built only from the 3,893 paragraphs coded as a claim. Singular and plural are merged and procedural words removed. The map of Europe behind it is decoration.

Reproducibility

Frozen before running

Every analysis had a written plan, saved with a hash before the results existed. Seeds are fixed (e.g. 20261020, 20261021, 20261030). Notebooks are numbered in run order in the data folder.

08 · Limits and AI use

What the numbers cannot tell you, and where AI did the work.

Levels are approximate; changes over time are more reliable. That is the single most important caveat.

Limits

  • English only. National debates in other languages are missing, except plenary speeches in translation.
  • No Council texts. Member states speak only through Parliament and Commission sources.
  • The press is four outlets. It stands for the international English-language conversation, not Brussels insiders or national papers. The Guardian search required Europe and China, so UK-only articles are under-counted.
  • After Oct 2025 the check set has almost no stage examples (0 refining, 0 components, 1 mining). Stage accuracy after that date is carried over from earlier periods.
  • Error rates are assumed constant across time, streams and materials; the check set is too small to estimate them separately.
  • Thin cells. Graphite after Oct 2025 (71 paragraphs) and some lithium quarters are fragile and shown with hollow markers.
  • Human agreement is moderate (0.56), so the line between “no stage named” and a stage is partly a judgement call.
  • Data gaps. 10% of parliamentary questions failed to download; plenary speeches stop in Apr 2026; Oct 2026 is a partial month.

How we used AI

  • Coding. Claude Sonnet 5.5 coded every paragraph. Claude Opus 5.5 recoded the check set as a cross-check. Model, prompt version and dates are logged.
  • Relevance check. Claude labelled a random sample of 500 paragraphs; we hand-checked 70.
  • Writing code. Claude wrote the collection, analysis and chart scripts; we ran and checked them.
  • Interpretation. Claude drafted topic names, cluster names and the causes of each shift. We reviewed every one.
  • What humans did. Wrote and froze the codebook; coded the 150 check paragraphs and the mentions set blind; set every decision rule before seeing results; approved the choice of coder.
  • This website was built with Claude from our results.