$npx -y skills add QinghongLin/data2story-skill --skill ideationFront stage for /data2story-pro when the reader has no dataset — only a vague idea. Converges the idea into a concrete, data-backed topic through a sparring-partner dialogue (anti-sycophantic, feasibility-pressure-tested), then acquires a REAL dataset through find-data, with a us
| 1 | # Ideation — from a vague idea to a data-backed topic + a real dataset |
| 2 | |
| 3 | The `/data2story-pro` orchestrator routes here in **IDEA MODE**: the reader handed over a hunch, a |
| 4 | question, or a half-formed angle instead of a dataset. Your job is to turn that into a concrete |
| 5 | topic that *real, findable data* can support, fetch that data, and hand a validated folder back to |
| 6 | the pipeline. You do this WITH the reader, not for them — two real checkpoints, no railroading. |
| 7 | |
| 8 | You are not a pipeline role (no `*_NN` provenance prefix, no place in the 7 teams). You run once, |
| 9 | before Detective, and produce nothing that reaches the HTML except the dataset + a `story_brief`. |
| 10 | |
| 11 | ## Inputs |
| 12 | - `$1` = the reader's raw idea text (may be empty → open by inviting it). |
| 13 | - `$2` = `DATA2STORY_ROOT` (resolved by the orchestrator; where `data/<slug>/` will live). |
| 14 | |
| 15 | ## Return contract (how the orchestrator continues) |
| 16 | - **Success:** emit a final line `DATA_DIR=<absolute path to the validated dataset folder>`. The |
| 17 | `story_brief.json` sits at `<DATA_DIR>/meta/story_brief.json`. The orchestrator sets |
| 18 | `DATA_DIR`/`DATA_NAME` from this and enters the normal pipeline (Detective → … → Inspector). |
| 19 | - **Abort:** emit `IDEATION_ABORTED: <one-line reason>` (reader stopped, or no real dataset supports |
| 20 | the idea after the bounded loop). The orchestrator halts honestly and runs NO pipeline. Never |
| 21 | fabricate data to manufacture a success. |
| 22 | |
| 23 | ## The flow — 3 steps, 2 checkpoints |
| 24 | |
| 25 | **Interaction style — let the reader CHOOSE, don't make them compose.** Drive the convergence |
| 26 | and BOTH checkpoints with `AskUserQuestion`: frame the angles / scope / data-forks as options the |
| 27 | reader clicks, not paragraphs they must write — picking is far lower-friction and each question |
| 28 | doubles as a micro-checkpoint. ALWAYS keep the **Other / free-text** escape open: the menu is your |
| 29 | framing, and the reader's own off-menu angle is often the best one, so never let it cage the |
| 30 | brainstorm. (This is NOT the cold opening questionnaire `sparring-partner` warns against — it is |
| 31 | choice-driven convergence *after* you have framed the space: lead the very first turn with |
| 32 | substance + an open invite, then switch to options.) |
| 33 | |
| 34 | ### Step 1 — Converge the idea (reuse `sparring-partner`) |
| 35 | Run the brainstorming dialogue by following **`Skill sparring-partner`** with the mission in |
| 36 | [`references/sparring_brief.md`](references/sparring_brief.md): drive the reader from a vague idea to |
| 37 | ONE concrete data-story topic. Two non-negotiables on top of sparring-partner's normal process: |
| 38 | - **Anti-sycophancy** (its core stance) — do not rubber-stamp the first pretty idea. |
| 39 | - **A feasibility pressure-test** — relentlessly ask *does this data actually exist? at what |
| 40 | granularity? who publishes it? for which years/places?* A beautiful idea with no obtainable data |
| 41 | is a **failure** of this step, not a success. Steer toward a nearby idea the data CAN support. |
| 42 | |
| 43 | The terminal of the dialogue is the **`story_brief`** (contract: [`references/schema.json`](references/schema.json)) — |
| 44 | topic, angle, audience, the questions the data must answer, a structured `data_needs` spec, any |
| 45 | **real** candidate sources surfaced, and the exact `find_data_invocation.query`. Reply in the |
| 46 | reader's language (sparring-partner's rule). |
| 47 | |
| 48 | ### CHECKPOINT 1 — confirm the brief |
| 49 | Show the reader the assembled `story_brief` (at least `topic`, `angle`, `data_needs`, and |
| 50 | `find_data_invocation.query`). Use `AskUserQuestion` (approve · edit · abort) or a plain confirm. |
| 51 | Loop back into Step 1 on edits. Do not proceed until the reader approves the brief. On abort → |
| 52 | return `IDEATION_ABORTED: reader stopped at brief`. |
| 53 | |
| 54 | ### Step 2 — Acquire a REAL dataset (reuse `find-data`, web-first) |
| 55 | Derive a kebab-case `slug` from `story_brief.topic`; set `OUT_DIR` to the ABSOLUTE path |
| 56 | `$2/data/<slug>` (resolve `$2` to an absolute path first). Then follow **`Skill find-data`** with the |
| 57 | brief's query and ALWAYS pass that explicit `--out OUT_DIR` — never rely on find-data's bare default |
| 58 | (its default is `DATASETS_ROOT/<name>`, a DIFFERENT root: `./datasets/<name>`, not `data/<slug>`). |
| 59 | An explicit `--out` always wins, so the dataset is guaranteed to land at the path ideation chose: |
| 60 | |
| 61 | ``` |
| 62 | Skill find-data "<story_brief.find_data_invocation.query>" --out OUT_DIR [--mode <single|theme>] [other flags] |
| 63 | ``` |
| 64 | |
| 65 | find-data searches (web-first on an open-source machine |