$npx -y skills add Aperivue/medsci-skills --skill generate-codebookGenerate a citable data dictionary / codebook from a tabular dataset (CSV/TSV/Excel/Parquet/Stata/SAS). Profiles every variable — role, type, units placeholder, level frequencies, range/quantiles, missingness — and emits codebook.md + codebook.json. Flags coded variables whose le
| 1 | # Generate Codebook Skill |
| 2 | |
| 3 | You help a medical researcher turn a raw tabular dataset into a structured, |
| 4 | **citable** data dictionary (codebook). This is the *generator* side of the |
| 5 | dictionary-first workflow: it produces the artifact that `/define-variables` and |
| 6 | dictionary-first QC later consume. You generate code and review output — you do |
| 7 | **not** invent the meaning of coded values. |
| 8 | |
| 9 | ## Communication Rules |
| 10 | |
| 11 | - Communicate with the user in their preferred language. |
| 12 | - Variable names, codebook fields, and report output are in English. |
| 13 | - Medical terminology is always in English. |
| 14 | |
| 15 | ## Philosophy |
| 16 | |
| 17 | A codebook describes *what is in the data*, not *what the codes mean*. Column |
| 18 | distributions, types, and missingness are observable and safe to profile. The |
| 19 | **meaning** of a coded value (`fatty_liver_grade = 0`) is NOT observable from the |
| 20 | data — it lives in the authoritative data dictionary. This skill profiles the |
| 21 | former deterministically and explicitly flags the latter as `[NEEDS DICTIONARY]` |
| 22 | so a human fills it from the source. This is the generator counterpart to the |
| 23 | dictionary-first rule that `/define-variables` enforces on consumption. |
| 24 | |
| 25 | ## Reference Files |
| 26 | |
| 27 | - **Schema + role rules**: `${CLAUDE_SKILL_DIR}/references/codebook_schema.md` — the |
| 28 | codebook.json schema, the role-inference heuristics, and how the output threads |
| 29 | into `/define-variables` and dictionary-first QC. Read this before interpreting output. |
| 30 | |
| 31 | ## Deterministic Script |
| 32 | |
| 33 | Run the bundled profiler rather than describing columns from memory: |
| 34 | |
| 35 | ```bash |
| 36 | python "${CLAUDE_SKILL_DIR}/scripts/generate_codebook.py" data.csv --out-dir . |
| 37 | ``` |
| 38 | |
| 39 | Supports `.csv/.tsv/.xlsx/.parquet/.dta/.sas7bdat`. Flags: `--max-levels N` |
| 40 | (categorical cutoff, default 20), `--json-only`, `--md-only`. The script is |
| 41 | pandas-only, runs locally, and never sends data anywhere. |
| 42 | |
| 43 | ## Workflow |
| 44 | |
| 45 | ### Step 1: Profile (deterministic) |
| 46 | |
| 47 | Run `generate_codebook.py` on the dataset. It writes `codebook.json` (machine- |
| 48 | readable) and `codebook.md` (review table), reporting per variable: role |
| 49 | (id / continuous / categorical / binary / date / text), dtype, missingness, |
| 50 | unique count, level frequencies or quantile summary, and a `needs_dictionary` flag. |
| 51 | |
| 52 | ### Step 2: Review with the researcher (gate) |
| 53 | |
| 54 | Present `codebook.md` and walk the user through it. **Gate:** the user confirms |
| 55 | the inferred roles (e.g., an integer-coded scale mis-read as continuous, or an id |
| 56 | column). Do not proceed to definition work until the user approves the role |
| 57 | assignments. |
| 58 | |
| 59 | ### Step 3: Resolve [NEEDS DICTIONARY] items (gate) |
| 60 | |
| 61 | For every variable flagged `needs_dictionary: true`, the level codes are |
| 62 | uninterpretable without the authoritative source. **Gate:** ask the user to |
| 63 | supply the meaning of each code from the real data dictionary (file/sheet/row), |
| 64 | or to confirm none exists. Fill `label`, `units`, and per-level meanings into the |
| 65 | codebook **only** from that source — never from inference. If the user cannot |
| 66 | supply it, leave the `[NEEDS DICTIONARY]` marker in place; do not erase it. |
| 67 | |
| 68 | ### Step 4: Hand off |
| 69 | |
| 70 | The completed `codebook.json` becomes the input dictionary for `/define-variables` |
| 71 | (operationalization) and the citation source for dictionary-first QC. **Gate:** |
| 72 | confirm with the user that no `needs_dictionary` flags remain unresolved before |
| 73 | the codebook is treated as authoritative for downstream analysis. |
| 74 | |
| 75 | ## Scope Limitations |
| 76 | |
| 77 | ### Supported |
| 78 | - Tabular files: CSV, TSV, Excel, Parquet, Stata (`.dta`), SAS (`.sas7bdat`). |
| 79 | - Per-variable profiling, role inference, missingness, level/range summaries. |
| 80 | |
| 81 | ### NOT Supported |
| 82 | - Inventing or guessing the meaning of coded values (that is `[NEEDS DICTIONARY]`). |
| 83 | - Cleaning or transforming data — use `/clean-data`. |
| 84 | - De-identification — use `/deidentify` before sharing. |
| 85 | - Operationalizing exposure/outcome definitions — use `/define-variables` (this skill feeds it). |
| 86 | |
| 87 | ## Cross-Skill Integration |
| 88 | |
| 89 | - **/define-variables** consumes `codebook.json` as its data dictionary input. |
| 90 | - **/clean-data** profiles + cleans; this skill produces a durable dictionary artifact instead. |
| 91 | - **/deidentify** should run on the raw data before a codebook is shared externally. |
| 92 | |
| 93 | ## Output Format |
| 94 | |
| 95 | `codebook.json` (schema in references) and `codebook.md` (review table with a |
| 96 | "Columns requiring dictionary lookup" section). Summarize the counts |
| 97 | (rows, columns, `needs_dictio |