# Method

Everything here is reproducible from `tools/report_ai_desks.py` against
`data/journalists.csv.gz`, the JournalistLabs pull of 2026-09-15. The script is copied into
this folder as `report_ai_desks.py`, exactly as it ran. It asserts the row counts on every run
and exits if they differ. The outlet names, countries, types and the parent-domain exclusion
come from `tools/export.py`, imported rather than reimplemented, so they are the same strings
the site publishes. The network calls are all in the sanity check, and they go through the
Webshare rotating gateway, never from the machine's own IP.

Licence: **CC BY 4.0**. Cite as JournalistLabs, "AI in newsroom job titles", 2026-09-15.

## What is published

The person-level base, `data/journalists.csv.gz`, is **not** published. The CSVs in this folder
are the checkable grain: a job title, an outlet, an outlet domain, a country, a role, two class
assignments, two flags and a fetch date. No person name is in any file here.

## Funnel

| step | rows |
|---|---|
| rows in `data/journalists.csv.gz` | 173,133 |
| dropped, `platform_domain == 1` | 12,540 |
| dropped, `media_typed == 0` | 32,991 |
| **published base** | **127,602** |
| AI word in the job title | 63 (0.049% of the base) |
| AI word in the title or the headline | 325 (0.255% of the base) |

The base is the same one every page on the site counts from: editorial rows at outlets whose
type says news media, with the link-in-bio and social domains removed. `data/METHOD.md`
carries how the three tables were built.

## Editorial definition

Copied from `data/METHOD.md`, the rule that decides whether a row is in the base at all.

A row is editorial when its **title** matches one of: bureau chief, news director, managing
editor, editor-in-chief, sub-editor, correspondent, columnist, anchor, presenter, news host,
newsreader, photojournalist, journalist, reporter, critic, reviewer, news/newsroom/editorial
producer, producer-reporter, staff writer, feature writer, editor, editorial — **and** its
title matches nothing on the stoplist.

Stoplist (applied first, so "marketing editor" and "product editor" are out): sales, marketing,
brand, growth, advertising, ad sales/ops, media buyer, account manager/executive/director, HR,
recruiting, talent, payroll, people ops, engineering, developer, devops, QA, software, data
engineer/scientist/analyst, IT support, product manager/owner/director/designer/lead, product,
content strategist, content marketing, SEO, copywriter, content writer, technical writer,
grant/proposal/ghost/bid writer, PR and communications roles, finance, accounting, legal
counsel, paralegal, facilities, security guard, driver, customer success/support/service,
subscriptions, circulation, teacher, professor, lecturer, student.

Deliberate exclusions worth knowing about:

- Bare `producer` is **not** editorial. Media companies are full of TV and radio production
  staff; only `news producer`, `newsroom producer`, `editorial producer` and
  `producer / reporter` count.
- Writers count only as `staff writer` and `feature writer`, per the spec. That drops 10,767
  rows in round 2 whose title is bare `writer` or `senior/contributing/lead/freelance/news/
  sports/science/business/political writer`. Some of those are real newsroom jobs (WIRED's
  "Senior Writer" is one). The number is recorded so the rule can be loosened and rerun.
- Video, photo, copy and audio editors are kept and tagged in `editor_kind`. `text` is the
  residual, and is 39% of all editorial rows.

## The lexicon

```
\b(ai|artificial intelligence|machine learning|generative ai|llm|chatgpt|openai)\b
```

Matched against a lowercased string with `&` replaced by `and` and whitespace collapsed, the
same normalisation `data/classify.py` uses. Every other regex is in `lexicon.txt`.

Two match rules are reported everywhere:

- **title-only**: the lexicon matches the `title` field. 63 rows.
- **headline-inclusive**: the lexicon matches `title + " || " + headline`. 325 rows.

The headline is a free-text LinkedIn bio. It carries former jobs, side projects, university
societies and keyword stuffing, so a headline match is not a newsroom AI job. Title-only is
the strict rule and is what the report leads with.

## The hand-read passes

All 63 title-only rows were read one by one; they are printed in full in `ai_titles.csv` and
in `facts_console.txt`. The checks were AI as a personal name (Ai Weiwei), AI inside another
acronym (AIB, AIM), and the Dutch `a.i.`, which means ad interim. **No row was removed.**

A second pass ran the spelling `\ba\.?\s?i\.?\b` over the titles, because the vendor drops the
periods in "A.I." and stores it as "a i". That regex is neither a superset nor a subset of the
published lexicon:

| | rows |
|---|---|
| titles matching `\ba\.?\s?i\.?\b` | 65 |
| of those, already among the 63 | 60 |
| new, not among the 63 | 5 |
| of the 63, missed by the variant regex | 3 |

The 3 it misses spell the subject out and carry no bare `ai` token: "Artificial Intelligence
Editor" (Financial Times, United Kingdom), "Reporter Electric Vehicles, Artificial
Intelligence" (PCMAG, United States), "Artificial Intelligence & Special Projects Reporter"
(Politico, United States).

The 5 new ones, read by hand off the title and the headline:

| title as stored | outlet | country | read as |
|---|---|---|---|
| a i Projects Editor | The New York Times | United States | A.I., a real AI title |
| Associate Editorial Director, a i Initiatives | The New York Times | United States | A.I., a real AI title |
| Managing Editor a i | Hearst Magazines | Netherlands | ad interim |
| Picture Editor Art Director a i | Harper's Bazaar Netherlands | Netherlands | ad interim |
| Visual Editor a i | Vogue | Netherlands | ad interim |

So the published lexicon misses two New York Times AI titles and correctly ignores three Dutch
interim titles. Taken raw, a variant-inclusive rule gives 68 rows at 52 outlets; read by hand,
dropping the three ad interim titles, it gives 65 rows at 49 outlets, and the New York Times
has two AI titles of its 2,168 editorial rows rather than none. All of those numbers are
printed; the lexicon in the CSVs is the strict one.

## Deploying, covering, unclear

Applied to the title only, first match wins in this order:

1. **deploying**, the title names a newsroom function performed with AI:
   `innovation, development, integration, operations, adoption, validation, transcript,
   assisted, automation, accelerator, strategy, programme, program, project, intrapreneur,
   ai-hub, ai hub, news ai, editorial ai, generative video, vfx, data and ai`
2. **covering**, the title names a reporting job: `reporter, correspondent, writer,
   journalist, columnist, critic, reviewer`
3. **unclear**, neither.

Deploying is checked first because a title can carry both words. "AI Validation Journalist"
checks machine output for a broadcaster and does not file AI stories; "AI Assisted Reporter"
writes with a tool. The split is 27 deploying, 21 covering, 15 unclear of 63.

A second, broader rule is reported beside it as the `class_alt` column: any of `editor, head,
director, lead, operations, innovation, development, integration, product, strategy` counts as
deploying. That gives 35 deploying, 25 covering, 3 unclear, and it is not the published split,
because it reads "AI Editor" and "Artificial Intelligence Editor", which are desks that cover
the subject, as deployment. The 20 rows where the two rules disagree are `row_id` 1, 3, 4, 7, 10,
14, 19, 23, 25, 27, 30, 32, 34, 36, 44, 52, 53, 60, 62, 63, listed with their titles in
`facts_console.txt`; both assignments are in `ai_titles.csv`.

### `title_names_a_desk`

A third column marks the rows that are an editor title whose only qualifier is the AI subject:
"AI Editor", "Editor, AI", "Artificial Intelligence Editor", "Senior Editor for AI", "Editor
Overseeing AI Coverage". The test strips the AI words, the word `editor`, a rank prefix
(`senior, deputy, associate, executive, managing, global, chief, lead, assistant, principal,
acting`) and the joining words (`for, of, on, the, and, in, at, to, overseeing, coverage,
covering, desk`), and asks whether anything is left. "Senior Editor, AI, Tech, and World"
leaves tech and world, so it is not one. **9 of the 63 are desk-style editor titles, and all
9 are among the 15 the published rule calls unclear.** They are `row_id` 1, 14, 19, 23, 32,
36, 52, 62, 63.

### `borderline`

Five rows carry an AI word in the title but the job is a data-products or production job rather
than a news desk. They are flagged, not removed, so both figures can be stated: **63 rows, or
58 without the flagged five.**

| row_id | title as stored | outlet |
|---|---|---|
| 5 | Research Editor - Special Lists Data and Ai | Barron's |
| 17 | Ai Transcript Editor | CalMatters |
| 45 | Video Editor Vfx Ai Video Artist | Sinclair Broadcast Group |
| 57 | Research Editor (Data and Ai) | The Wall Street Journal (Dow Jones) |
| 58 | Research Editor, Pep Sco, Data & Ai, Risk and Compliance | The Wall Street Journal (Dow Jones) |

The two Wall Street Journal rows and the Barron's row are Dow Jones Risk & Compliance data
research, not the newsroom's AI coverage.

## The top-50 set

`top50_newsrooms_ai.csv` is the **50 largest publishable outlets by editorial rows**:
media-typed, not a parent domain, named, typed, with a country. That is the same ranking that
feeds the site's `/outlets/` table. The site gives its own `/outlets/` page to the first 40 of
that ranking, so **the site publishes 40 outlet pages and this set is 10 longer than the list
of published pages.**

## Rank words

14 of the 63 carry `head`, `director`, `lead`, `chief` or `senior` in the title. The per-word
counts are senior 8, director 3, head 2, lead 2, which sum to 15, one more than 14: a title can
carry two rank words, and one does. "Head of News Ai (Senior News Editor, Ai)" at the BBC is
counted under `head` and under `senior`. The distinct-row figure is 14; the per-word figures do
not add up to it and are not meant to.

## Fetch dates

`fetched_at` on the 63 AI-titled rows: min **2026-07-23**, max **2026-08-11**, median
**2026-08-06**. It is the day the profile was scraped, not the day the job started or ended,
so the 63 are titles held at some point in that window.

## Small cells

Counts below five are printed as themselves rather than as `<5`, against the site's usual
rule, because this report is a small named list: every one of the 63 rows is published with
its outlet and country, so every per-outlet and per-country count is derivable from the list
itself. No suppression would hold. Nothing person-level beyond the job title, the outlet, the
outlet domain, the country, the role and the fetch date is published anywhere in this dataset.

## The outside check

The Reuters Institute's *Journalism, Media and Technology Trends and Predictions 2026*, fetched
through the proxy on **2026-09-16**, HTTP 200:
https://reutersinstitute.politics.ox.ac.uk/journalism-media-and-technology-trends-and-predictions-2026

The sentence the check turns on, as fetched:

> Newsquest, a leading regional UK publisher, has created more than 30 'AI-assisted reporters'
> across its titles, staff who are equipped with an AI tool called News Creator to draft
> stories – up to 30 every day – which are then checked and supplemented.

### Counting Newsquest properly

The group domain `newsquest.co.uk` carries **7 editorial rows**, and the site publishes that
key under its modal company name, "Isle of Wight County Press Limited", until the hand alias
added in `names.OUTLET_NAMES` publishes it as **Newsquest**. Newsquest's mastheads each carry
their own domain, so the group domain alone is not the group.

The masthead list was built from Wikipedia's *List of newspapers published by Newsquest*,
fetched through the proxy on **2026-09-16**, HTTP 200:
https://en.wikipedia.org/wiki/List_of_newspapers_published_by_Newsquest

104 of its links are blue (128 are red links with no article). 94 of the 104 have a Wikidata
item; 71 of those carry an official website (P856). Dropping every `.gov.uk` host and three
hand-checked non-mastheads the list also links (`eu-digest.com`, `visitpembrokeshire.com`,
`northwichtc.plus.com`), and adding the group domain, that is **74 Newsquest domains**. They
are in `newsquest_domains.csv` with their Wikipedia titles.

Matched against the base by `company_domain`:

| | |
|---|---|
| Newsquest domains on the list | 74 |
| of those with at least one editorial row in the base | 6 |
| editorial rows at those domains | 42 |
| of those with an AI word in the title | **0** |

The six, by rows: thenational.scot 20, heraldscotland.com 11, newsquest.co.uk 7, edp24.co.uk 2,
dorsetecho.co.uk 1, herefordtimes.com 1.

So the outside figure of more than 30 AI-assisted reporters sits against 42 Newsquest editorial
rows on file across 6 domains, none of which has an AI word in the title. That is the shape of
the undercount: the base is thin at regional groups, and a job done with AI is often not
renamed in the person's title.

Two other checks were tried. `https://www.bbc.co.uk/supplying/working-with-us/ai-principles/`
returned HTTP 200 but carries principles and no headcount.
`https://www.bbc.co.uk/aboutthebbc/whatwedo/artificial-intelligence` and the `.com` spelling
both returned HTTP 404, so no first-party BBC page giving the size of its AI team was found.
No outlet's own AI team page has been matched against the five BBC titles here.

## Limitations

- **Titles are LinkedIn self-description.** A newsroom can run an AI team whose members keep
  the title they had; nothing in this data would see it. The count is of titles, not of work.
- **Coverage is thin below the large outlets.** 8,800 outlets have at least one editorial row
  in the base; most local and regional titles have a handful or none. Newsquest, above, is the
  worked example: 74 masthead domains, 6 of them with any row at all.
- **Not every outlet in the 63 is a general newsroom.** Amagi contributes 2 of the 63 on 8
  editorial rows in total, both reading "AI Validation Journalist"; Biotechtv, Fashionunited
  and Boston Magazine contribute one each. All are media-typed in table A and none was dropped
  by hand. Every row is printed, so a reader can drop the ones they do not accept and recount.
  Five further rows are flagged `borderline` for the same reason.
- **`country` is the person's country, not the outlet's.** A BBC row can read United States.
- **Group domains split newsrooms.** People Inc. (183 editorial rows) and Hearst Newspapers
  (18) are company domains covering several titles. The alias table does not merge a group
  into its titles, so a title's own domain undercounts its newsroom and the group domain
  carries rows that belong to no single masthead.
- **The outlet country is table A's, the person country is the vendor's.** Amagi's two rows
  read India on the person and United States on the outlet.
- **The two identical "Director, AI Editorial Operations" rows at People Inc. are two people**,
  not one row duplicated. The table B build dedupes on name, title and domain.
- **The headline-inclusive count moves with the lexicon.** The scout run
  (`tools/scout_titles.py`) used a looser first alternative, `a\.?i\.?`, and got 331 rows at
  227 outlets where the strict lexicon gets 325 at 225. The six extra rows are "A.I." spellings
  in headlines, four of them at the New York Times and USA Today. Title-only is 63 either way.
