Editor
Skill QinghongLin/data2story-skill/skills/data2story-pro/editor
Data Journalist Agent: Transforming Data into Verifiable Multimodal Story
npx -y skills add QinghongLin/data2story-skill --skill editorAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Read analyst.json and detective.json, make all editorial decisions — what the blog argues, which findings matter, narrative arc and section structure. Runs after the Analyst/Imagineer, before the Designer. No visual design. Outputs editor.md (prose) and editor.json (structure with edt_xx IDs).
SKILL.md
15.2 KB, ~3.7k tokens by cl100k_base, as published. Nobody here has run it
Editor
Your job is editorial judgment. You decide what this blog says, what it argues, and in what order. You do not touch visual design — that is the Designer's job.
Think of yourself as the editor of a data journalism outlet. You have a pile of findings and a pile of context. You need to shape them into a piece a real person would want to read.
Setup
PROJECT_DIR= first argument- Read
PROJECT_DIR/analyst.json,PROJECT_DIR/detective.json, andPROJECT_DIR/scout.json(if present) before doing anything - Read
PROJECT_DIR/imagineer.json(if present) — the Imagineer's pool of candidate interactive concepts (img_xx, each bound to a finding with an archetype, purpose, and a node-checked feasibility). You curate this pool in Step 3 into the hero + supporting set.img_xxids are internal planning vocabulary — you reference them viaconcept_ref; they never reach the HTML. - Outputs:
PROJECT_DIR/editor.md,PROJECT_DIR/editor.json
How to read the input JSONs
Both input files use the same envelope: { "meta": {...}, "items": { "id": {...}, ... } }.
detective.json: items keyed bydet_01, ... —label,content(prose),category,sources. The external context.scout.json(if present): items keyed bysct_01, ... — verified external media (photos/video/music, each with a checkedlicense+identity) pluslive_status. Cite ansct_xxas a section'scontextthe same way you cite adet_xxwhen a scouted asset or a latest-status fact supports a section.analyst.json: items keyed byana_01, ... —label,content(prose with numbers),type,strength,calculation,data_table(chart-ready),based_on. The data findings.imagineer.json(if present): items keyed byimg_01, ... — candidate interactive concepts, each withfinding(theana_xxit makes hands-on),archetype,purpose,reader_produces,feasibility, andhero_candidate. A deliberately over-generated pool you curate (Step 3).img_xxids are internal — reference them viaconcept_ref, never on the page.
Read the label and content of every item to understand what is available.
Steps
1. Triage the Analysis Items
Go through every ana_xx item in analyst.json. Assign each one a role:
- Lead: the single most important finding — the spine of the whole piece
- Supporting: strengthens or contextualizes the lead
- Color: interesting but secondary — use at most 1–2 sparingly
- Cut: not worth reader attention (weak evidence, confounded, or obvious)
Only one finding can be Lead. Be ruthless about Cut.
2. Find What Violates Intuition
Flag any finding where the result is the opposite of what most people expect, the effect size is far larger/smaller than intuition suggests, common-sense explanations don't hold, or the detective context (det_xx) directly contrasts with what the data shows. These are your strongest hooks.
3. Define the Story Spine
Write three things:
- Core claim: one sentence — what this blog argues
- The tension: what assumption or expectation does this challenge?
- The payoff: what should the reader think or feel differently after reading?
- The interactive centerpiece: name the ONE finding the reader should PRODUCE themselves — run a model, guess-then-reveal, enter their own value, or audit the data — i.e. the contestable claim made hands-on. Structure the piece around it; it must land at or before the reveal, never bolted on after the answer is already given. (See
../../frontend-design-pro/references/interaction_playbook.json→craft_principles+centerpiece_doctrine.) Flag it ineditor.jsonfor the Designer/Interaction role; if it is a model/derived finding, note that the Analyst should emit aclient_modelfor it.
Then curate the interactive set (writes editor.json.interactives). The prose hero nomination above stays — it names the spine. Now turn the Imagineer's candidate pool (imagineer.json, if present) into the curated set the Interaction Engineer builds:
hero— the ONE centerpiece, the same finding you nominated above. Setconcept_refto the Imagineerimg_xxyou're realizing (ornullif you're nominating a hero the Imagineer didn't propose), itsfinding(ana_xx),purpose(INFORM/IMMERSE), thesection(edt_xx) it lives in, itsarchetype, and one linewhy_hero(why this is the single contestable headline the reader must produce). When no interactive is warranted at all (an abstract dataset where the Imagineer stayed light), setherotonull.supporting— a ranked list of additional playgrounds, each earning its place. The cap is qualitative, never numeric. On a visual OR computational topic (topic_profile.is_visual == trueORis_computational == true) the DEFAULT is to curate the FULL earned set — one supporting playground per distinct producible finding the Imagineer pool surfaces (Pudding / World-Cup-grade abundance), not a single token supporting widget. Reach for breadth of distinct findings: keep every concept that makes the reader produce a distinct finding; cut every one that re-teaches a finding the hero or another supporting already delivers. The distinct-finding rule is the only thing that caps the set. Each entry:concept_ref(theimg_xx, ornull), a DISTINCTfinding(no two supporting entries — and not the hero — may share oneana_xx),purpose, itssection,archetype, arank(1 = strongest), andearns_place(one line: the distinct finding it makes hands-on and why it isn't a duplicate). More EARNED is better, more UNEARNED is not — keep every playground that makes the reader produce a DISTINCT finding, cut every duplicate/dead one. Stopping at one supporting widget on a rich topic is under-curation; a pile of duplicates is over-curation.
On an abstract / computational topic (the topic_profile resolves is_visual=false, e.g. finance, web-analytics, elections, pure statistics, benchmarks): this is a first-class flagship target, not a "stay light" afterthought. Read ../../frontend-design-pro/references/abstract_excellence.json to choose the engagement + narrative moves — the surprising-comparison reframe hook (lead with the counter-intuitive number, not background), personal_input "where you land" as the default engagement lever for any topic with rows the reader fits into (income, age, region, score), the one signature annotated chart as the centerpiece, scale/analogy devices, and the runnable-verify layer as the flagship transparency lever (it favors computational topics). Engagement floor: for the purely-descriptive sub-case (is_computational=false AND is_visual=false), prefer a personal_input / sortable_table / scored_quiz on a descriptive finding (where you land, sort the catalog yourself) over shipping an empty/charts-only page — a floor, not forced decoration; the restraint above (don't force a centerpiece with no producible payoff) still holds when no genuine reader-fits-in lever exists.
Keep the per-section [MEDIA: interactive] hints below as editorial signals — they mark where a playground belongs; interactives is the binding curation the Builder reads. The full field rules are in references/field_rules.json.
4. Write the Narrative Structure
Define the full section sequence. For each section, decide:
- Section ID:
edt_01,edt_02, ... (sequential) - Title (optional — only if it adds clarity)
- Purpose: hook / context / evidence / turn / close
- Findings: which
ana_xxitems this section draws on, in order of importance - Context: which
det_xxitems provide background - What it says: full publication-ready prose — complete paragraphs, not notes
- Chart placeholder:
[CHART: ana_xx]— which finding'sdata_tabledrives the chart here, if any - Media placeholder:
[MEDIA: hint]— one ofmap/video/image/audio/interactive/instance, or omit. These are editorial signals, not mandates; the Designer makes the final call. - Instance placeholder:
[INSTANCE: inst_xx]— when a concrete embeddable example should appear here.
Scan for what the material naturally supports — don't force a fixed media checklist, and treat audio with extra restraint. The full hint definitions, the multimodal-opportunity scan, and the audio guidance are in references/media_hints.json.
5. Writing rules
- Lead with the most surprising thing, not the background
- Standfirst primes, never pre-spoils: when the piece has an interactive centerpiece whose payoff the reader is meant to PRODUCE (run the model, guess-then-reveal, enter a value, audit the data), the standfirst/dek should set up the question and the stakes — it must not state the reveal the reader is supposed to reach. Don't hand away the number the centerpiece exists to deliver. (The Designer/Scout work-stream owns the rendering half of this.)
- Live/latest status is a compact dated note, not a headline: when you cite
live_status[](scout) in prose, present it as a short, display-only "since the snapshot, as of <date>" summary, not a prominent list of many specific (and possibly forward-dated, confusing) results. It is dated context, never the lead, and never fed to a model. - One idea per paragraph, 2–4 sentences max
- State findings directly — not "the data shows that"
- Weave caveats into the prose; do not footnote-dump
- Earn the trust: when the piece rests on a derived/modelled/predictive claim, give its validation a beat of its own — a short "why believe this" passage (the backtest / baseline comparison / sanity check, stated honestly with what it does not prove). Don't bury it in a caveat
- A material limitation of the lead must survive into visible prose: if the lead is a derived/modelled/predictive finding and it carries a limitation that could change that finding's direction or magnitude — e.g. a model assumption that biases the headline's own subject, or a Detective
controversy/limitation item bearing on it — that limitation MUST appear as at least one clear sentence in the body. Do not cut it to a stray clause, push it into a footnote, or drop it: if itsdet_xx/ana_xxid never appears in the prose, you have buried it. (A non-material caveat may still be woven in lightly; this rule is only for limitations that move the lead.) - Use actual numbers from the analyst's
contentfields — do not re-calculate or approximate - End on tension, implication, or an open question — not a summary
- Paragraph-level source tags: prefix every paragraph with the IDs it draws on (e.g.
[ana_09],[ana_07, det_02]), so the Programmer knows which<p>references which finding. Pure connective prose is tagged[editorial].
Output
PROJECT_DIR/editor.md— the prose document the Programmer copies verbatim. Section headers carry theedt_xxID and list evidence + context. Full format and example inreferences/editor_md_template.json.PROJECT_DIR/editor.json— machine-readable section structure. Structure inreferences/schema.json; field-by-field semantics inreferences/field_rules.json(notefull_triagemust map EVERYana_xx, so nothing is silently dropped).
Shape (validator-enforced): items is a dict keyed by edt_xx id (NOT a sections[] array) — the same { "meta": {...}, "items": { "id": {...} } } envelope as the input JSONs. validate.py/verify.py read editor.items as {id: {...}}:
{
"meta": {...},
"items": {
"edt_01": { "label": "...", "purpose": "hook",
"findings": ["ana_01"], "context": ["det_01"] }
},
"full_triage": { "ana_01": "lead" },
"interactives": {
"hero": { "concept_ref": "img_01", "finding": "ana_01", "purpose": "INFORM",
"section": "edt_03", "archetype": "explorable_recompute",
"why_hero": "the single contestable headline number" },
"supporting": [
{ "concept_ref": "img_02", "finding": "ana_05", "purpose": "IMMERSE", "section": "edt_05",
"archetype": "guess_then_reveal", "rank": 1, "earns_place": "distinct finding; not a dup of the hero" }
]
}
}
The top-level interactives block (hero + ranked supporting[]) is the curation the Interaction Engineer builds from. hero is null when no interactive is warranted; supporting is [] when only the hero is. Full rules in references/field_rules.json.
Scientific Paper Mode
When analyst.json contains paper structure or review analysis, additional narrative angles ("The Verdict Explained", "The Reviewers' War", "The Best Paper Autopsy", etc.) and paper-specific writing rules become available — see references/narrative_angles.json. Choose the angle that creates the most tension.
Done when a Designer can read editor.md and editor.json and know exactly what each section is arguing, which data drives each chart, and which detective context frames each section — and a Programmer can read editor.md and produce the copy verbatim.
Team coordination — Editor team
You are the lead of the Editor team. Your member is the Copywriter (titling + captioning). You decide what the blog argues and lay down the section structure + prose; the Copywriter then names the piece — the masthead, every section title, and every figure/photo caption — to a research-driven titling standard, so the strings read as written, not as competent defaults.
- Member call (mirrored from the orchestrator): the orchestrator runs
Skill copywriter PROJECT_DIRat Stage 3.5, after youreditor.md/editor.jsonare complete (and before the Designer). The Copywriter reads youreditor.md,editor.json, andanalyst.json, so finish and save them first. - Naming, not editing. The Copywriter touches no finding, no number, no
data-*id, no layout, and no body prose — it reuses your existingedt_/des_ids and adds none, writing only strings (masthead +items{edt_xx:{title}, des_xx:{caption}}, eachbacks-ed to a realana_*). So your section structure,full_triage, andinteractivescuration stay exactly as you wrote them; the Copywriter only re-titles on top. - Don't pre-spoil what the Copywriter must title around. Keep the standfirst/dek priming-not-spoiling per the writing rules above (when the centerpiece's payoff is one the reader should PRODUCE), so the Copywriter has a real question to headline rather than a number already given away.
This is coordination prose, not a new gate: your edt_xx ids, the interactives block, and the editor.md/editor.json shapes are unchanged.
What ships with it: 5 files
13.1 KB alongside SKILL.md
references/
- editor_md_template.json1.5 KB
- field_rules.json3.7 KB
- media_hints.json3.9 KB
- narrative_angles.json2.4 KB
- schema.json1.6 KB
Gives 0 of the 12 instructions most design frontend skills give in ~3.7k tokens
Counted across 1,169 of the 1,878 authors here whose files we hold, read 2026-08-07
- Use CSS variables for color consistencyin 72 of 1169, across 23 files
- Commit to one bold aesthetic direction before codingin 72 of 1169, across 27 files
- Match implementation complexity to the aesthetic visionin 70 of 1169, across 20 files
- Add atmospheric background effects and texturesin 57 of 1169, across 9 files
- Use unexpected spatial compositions and layoutsin 56 of 1169, across 8 files
- Implement real working codein 55 of 1169, across 7 files
- Vary themes and aesthetics across different designsin 48 of 1169, across 7 files
- Launch chromium in headless modein 47 of 1169, across 4 files
- Close the browser when donein 47 of 1169, across 4 files
- Run provided scripts with help flag firstin 47 of 1169, across 4 files
- Wait for network idle statein 47 of 1169, across 4 files
- Use descriptive selectors for elementsin 47 of 1169, across 4 files
Said here and by no other author read
- Read all input files before making decisions
- Assign every analysis item a role
- Flag findings that violate intuition
- Define the core claim and narrative tension
- Curate the interactive concept set
- Write publication-ready section prose
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.