Source document

docs/editorial-process.md

Served verbatim from the project repository. Internal working document conventions apply: documents may reference file paths, branch names, and findings-ledger anchors from the repo.

The nine-pass editorial process

Every "deep dive" story (the long ones with charts and a full data analysis) goes through nine review passes before it's considered done. The passes alternate between five specialist agents, each with a fixed lens. The pattern lets each agent push the work without any one of them owning it end-to-end — the editor pulls toward readability, the expert pulls toward contextual accuracy, the quant pulls toward statistical rigor, the plain- language agent pulls toward accessibility, the AI-writing filter pulls toward Hemingway and away from chatbot rhetoric, and the pattern surfaces friction between those goals.

The aim is publishable, defensible, interesting, reader-friendly, and human-sounding writing — five things that often pull in different directions.

The agents

Each agent has a persona file (their fixed lens) and a knowledge file (what they've learned across stories). The knowledge files are append-only across sessions and become more useful over time.

AgentPersonaKnowledge
Editoragents/editor.mdagents/editor-knowledge.md
Education expertagents/education-expert.mdagents/education-knowledge.md
Quantitativeagents/quantitative.mdagents/quantitative-knowledge.md
Plain-languageagents/plain-language.mdagents/plain-language-knowledge.md
AI writing filteragents/ai-writing-filter.mdagents/ai-writing-filter-knowledge.md

The nine passes

Pass 1: Editor              — first pass, get the bones of the prose right
Pass 2: Education expert    — domain check, fill missing NYC context
Pass 3: Quantitative        — statistical rigor check
Pass 4: Editor              — second pass, reconcile what 2 + 3 added
Pass 5: Education expert    — second domain pass, anything new uncovered?
Pass 6: Quantitative        — second rigor pass, anything new to verify?
Pass 7: Editor              — final structure / polish, ship-ready prose
Pass 8: Plain-language      — final rewrite for accessibility
Pass 9: AI writing filter   — strip the chatbot mannerisms

Why this order? The editor goes first because if the prose is unreadable the other passes are working on the wrong thing. The expert then adds domain context the editor can't add. The quant then checks whether the expert's claims survive contact with the numbers. Then it loops — editor to clean up, expert to verify, quant to verify again — and finishes the substance with a final editor pass.

Plain-language is second-to-last because it's pointless to translate jargon you'll have to re-translate after the quant adds a caveat or the expert corrects a fact. It goes after the substance is settled.

The AI writing filter is last because it operates on the final reader-facing prose. It doesn't need to know what was substantively true; it just needs to recognize when a sentence sounds like a chatbot ("not X, it's Y", "Both lists are real lists", earnest tricolon closers). Once it's done, the story is done.

The editor gets three passes because the editor is the only one responsible for the final reader experience as a piece of prose. The expert and quant get two each, because their domains are deep but bounded. The plain-language and AI-writing-filter agents get one pass each, because the work is mechanical once the substance is settled.

What each pass produces

Every pass produces:

  1. Edits to the story's answers.ts entry. Either content changes or notes added in the form of new sections / sentences / caveats / chart captions. Substantive — not just typo fixes.

  2. A log entry in docs/agents/pass-log/<story-id>.md. What the agent changed, why, and what they flagged for downstream passes.

  3. Optional updates to the agent's knowledge file. Anything the agent learned that's likely to apply to future stories — a recurring pattern, a phrase to avoid, a sanity-check that catches a common error.

Passes don't undo each other's substantive work; they refine it. If pass 2 contradicts pass 1, pass 2 should explain why in the log so pass 4 (the editor) can adjudicate.

How a pass actually runs

The agent doing the pass:

  1. Reads the current state of the story in data/stories/answers.ts (the relevant entry by id).
  2. Reads their own persona file (to remember what they're looking for).
  3. Reads their own knowledge file (to remember what they've learned).
  4. Reads the most recent pass log for this story (to see what's been said).
  5. Reviews the story through their lens. Identifies issues. Makes edits.
  6. Writes a log entry summarizing what they changed and what they flagged.
  7. Updates their knowledge file if the pass surfaced anything reusable.

Scope of changes per pass

PassTypical changes
1 (editor)Trim wordy passages, fix awkward leads, flag legal risks, rework muddy paragraphs
2 (expert)Add missing NYC context, correct domain errors, flag missing comparisons
3 (quant)Verify sample sizes, flag overstated causation, add error bars or qualifications
4 (editor)Integrate 2+3 additions cleanly, kill new bloat, restructure if needed
5 (expert)Verify expert's earlier additions still make sense; add anything new
6 (quant)Verify earlier statistical claims still survive the new prose; check residuals
7 (editor)Polish only — caption tweaks, paragraph order, final lead
8 (plain-language)Replace jargon with plain words; spell out every acronym on first use; size numbers; define our own internal terms inline; never cut substance
9 (AI writing filter)Kill chatbot mannerisms: "not X, it's Y" parallels; earnest closing tricolons; "Both X are real X" emphatic closers; em-dash chains; over-frequent "real" / "actual"; performative balance

The plain-language formula

A reader-first checklist the plain-language agent runs against every paragraph. If a paragraph fails any item, rewrite.

Hard rules (no exceptions)

  1. Spell out every acronym on first use — including "ELL" (English Language Learners), "SWD" (Students with Disabilities), "NYS" (New York State), "NYSED" (NY State Education Department), "DOE" (Department of Education), "ENL" (English as a New Language), "ICT" (Integrated Co-Teaching), "ARP" (American Rescue Plan, the federal pandemic-relief funding), "NAEP" (National Assessment of Educational Progress, the federal test that's the same in every state). Once the long form has appeared, the short form is okay.
  2. Define our own internal vocabulary inline on first use. "Proclivity decile" → "the 1-to-10 ranking we use to group schools by how much challenge their student body faces." "Residual" → "the gap between what the school actually scored and what we'd expect given its student body." "Peer-group percentile" → "where the school sits compared with the ~40 schools that look most like it." Either define inline or replace.
  3. Bare numbers get a sizing comparison. "+32 points" alone is meaningless; "+32 points — the size of three letter grades" is legible. "n=779 schools" → "779 schools, which is most of NYC's public elementaries."
  4. Maximum two numbers per sentence. If a sentence carries three, it's a re-read. Break or move one to a table or chart caption.
  5. No Latin or technical connectives. Replace "i.e.," with "that is,"; "e.g.," with "for example,"; "vs." with "compared with"; "n.b.," with nothing — just say it.

Soft rules (re-write if it doesn't harm precision)

  1. Prefer concrete to abstract. "The 50 schools doing the most work" beats "the top 50 residual cases." "The hardest-to-serve group of schools" beats "decile 10."
  2. Prefer specific examples to general claims. "P.S./M.S. 4 in the South Bronx went from 32% of fifth-graders proficient in math in 2017 to 98% in 2024" beats "PS 4 has the largest gain in the data."
  3. Use active voice. "The state rebuilt the scoring scale in 2022-23" beats "the scoring scale was rebuilt in 2022-23."
  4. Define what every percentage measures. "60% of students proficient" beats "60% proficient." "60% of fifth-graders who took the test scored 'proficient' or better" beats both, if the precision matters.
  5. Reader-empathy test on every paragraph: would a smart curious person who isn't in education-data-world finish this paragraph feeling they understood it? If they'd skim past, blink at a term, or feel talked-around, rewrite.

The translation table

The plain-language agent's persona file (agents/plain-language.md) carries a running translation table. As new jargon comes up across stories, add the term and its plain replacement to that table. The table is the project's working glossary.

What plain-language never does

  • Cut findings or numbers
  • Soften caveats added by the quant
  • Remove named schools or named people
  • Replace specific facts with vague ones ("about a third" instead of "33%" is worse, not better)
  • Use exclamation marks, em-dash chains, or sentence fragments for effect

The plain-language pass changes the words around the substance, not the substance itself.

When to break the process

Don't break it on the first five stories — they're the proving ground. After story five, audit the knowledge files. If the same kind of edit keeps showing up in pass 4 that should've happened in pass 1, the editor persona file gets stronger and that error class moves earlier in the pipeline.

Reserved exceptions:

  • If a pass finds a factual error that invalidates the story's thesis, the pass stops and flags it. The story goes back to the data team before continuing.
  • If passes 2 and 3 both pass without changes, the story is probably ready earlier than seven passes. The editor still does passes 4 and 7 for consistency, but passes 5 and 6 can be skipped with a brief log entry.