# vibepaper onboarding prompt

Copy this prompt into Claude Code in the target project.

---

## Prompt

We are going to migrate this project's paper build to use [vibepaper](https://pypi.org/project/vibepaper/), a tool that binds paper prose to analysis outputs so numbers update automatically when the analysis reruns.

**The core idea:** analysis scripts write key results to small 1-row CSVs (called "facts CSVs"). The paper Markdown references those values by name using Jinja2 template syntax. A single `vibepaper` command renders all templates and builds the Word document.

Template syntax in paper `.md` files:
```
{{ namespace.field | filter }}
```
Where `namespace` is the CSV filename stem, `field` is a column name, and `filter` is one of:
- `commas` — integer with thousands separator: 254129 → "254,129"
- `dp` / `dp(2)` — decimal places: 9.177 → "9.2"
- `pct` / `pct(0)` — percentage: 52.2 → "52.2%"
- `fold` — fold change: 2.0 → "2.0-fold"
- `fmt('.2e')` — raw Python format spec escape hatch

Facts CSVs live in `output/facts/` (or wherever you configure). Each is a 1-row CSV where the filename stem becomes the namespace:
```
output/facts/vep_impact.csv    → {{ vep_impact.mean_tpv | dp(1) }}
output/facts/growth.csv        → {{ growth.new_transcripts | commas }}
```

For multi-row tables in the paper (supplementary tables etc.), use include-csv directives:
```html
<!-- include-csv: output/my_table.csv
  columns: [gene, count, pct]
  rename:
    pct: Percentage
  format:
    count: ",d"
  sort: [-count]
  max_rows: 20
-->
```

### Step 1 — Understand the current build

Read `build_doc.py` (or whatever the current paper build script is). Understand:
- What files it reads
- What Markdown files make up the paper
- Whether it already does any templating or number substitution
- What outputs it produces

### Step 2 — Audit the paper for hardcoded numbers

Read all `paper/*.md` files (or wherever the paper sections live). Make a list of every hardcoded number — counts, percentages, fold changes, p-values, means — and for each one identify:
- What the number represents
- Which analysis script produced it (grep the codebase for the value or a related variable name)
- What output file (CSV, TSV, parquet, printed output) currently holds it

Group related numbers under a proposed namespace (e.g. all VEP impact numbers → `vep_impact`, all transcript growth numbers → `growth`).

### Step 3 — Write facts CSVs from the analysis scripts

For each namespace identified above, modify the relevant analysis script to write a facts CSV. The pattern is:

```python
import pandas as pd
from pathlib import Path

def write_facts(output_dir: Path):
    facts_dir = output_dir / "facts"
    facts_dir.mkdir(parents=True, exist_ok=True)

    pd.DataFrame([{
        "mean_tpv_v112": mean_tpv_v112,
        "mean_tpv_v115": mean_tpv_v115,
        "fold_change": mean_tpv_v115 / mean_tpv_v112,
    }]).to_csv(facts_dir / "vep_impact.csv", index=False)
```

Rules:
- One row per CSV, one CSV per logical group of related numbers
- Store floats at 4 decimal places minimum — rounding happens in the template filter, not at storage time (storing as "4.6" causes IEEE 754 drift)
- Store raw values (counts, ratios, percentages as numbers not strings) — formatting is the template's job
- Column names become field names in the template, so make them descriptive and unambiguous

Call `write_facts()` at the end of each script's `main()` so the CSVs are always regenerated alongside the analysis outputs.

### Step 4 — Install vibepaper

Add `vibepaper` to the project's `requirements.in` and `requirements.txt`, then install:

```bash
pip install vibepaper
```

Also ensure pandoc is installed:
```bash
# Debian/Ubuntu
sudo apt-get install pandoc
# macOS
brew install pandoc
```

### Step 5 — Create paper.toml

Create `paper.toml` in the project root:

```toml
[paper]
name = "my_paper"

sections = [
    "paper/abstract.md",
    "paper/introduction.md",
    "paper/methods.md",
    "paper/results.md",
    "paper/discussion.md",
    "paper/references.md",
]

supplementary = ["paper/supplementary.md"]

facts_dir    = "output/facts"
output_dir   = "output"
```

Optional — if you have a `.bib` file and CSL:
```toml
bibliography = "paper/references.bib"
csl          = "paper/vancouver.csl"
```

Optional — if you have a Word reference document for journal formatting:
```toml
reference_doc = "paper/reference.docx"
```

### Step 6 — Replace hardcoded numbers with template references

Working through the list from Step 2, replace each hardcoded number with the corresponding template tag. For example:

Before:
```
Mean transcripts per variant increased from 4.6 to 9.2 (2.0-fold).
```

After:
```
Mean transcripts per variant increased from
{{ vep_impact.mean_tpv_v112 | dp(1) }} to
{{ vep_impact.mean_tpv_v115 | dp(1) }}
({{ vep_impact.fold_change | fold }}).
```

If a citation style uses `[REF Author Year]` placeholders, convert them to pandoc citation syntax: `[@AuthorYear]`.

### Step 7 — Verify the build

First regenerate the facts CSVs by running the analysis scripts. Then:

```bash
vibepaper
```

Watch for warnings:
- `WARNING: suspicious content` with `nan` → a facts CSV column is missing or misnamed
- `UndefinedError` → template references a namespace or field that doesn't exist in any CSV
- `WARNING: ... appears to be a stub` → a section file has no content yet (fine for placeholders)

Use `vibepaper --verbose` to see which templates are being rendered and which CSVs are loaded.

### What to do with the old build_doc.py

Once vibepaper is working, `build_doc.py` can be retired or kept as a thin wrapper that calls `vibepaper` programmatically if needed. Do not delete it until the new build is verified end-to-end.
