Experiment planning, protocols, and results for iPSC screens — one folder per experiment, plus the skill that generates them.
GitHub Pages serves reports at
https://maggiesychen.github.io/lab-experiments/experiments/<slug>/.
lab-experiments/
README.md
lab-defaults.csv canonical measurements + assumptions (snapshot)
docs/
ADAPTING.md how to use the skill on a different protocol
skills/
vic-screen/ the skill: SKILL.md, references/, scripts/
experiments/
2026-08-vic-genome-wide/
plan/ calculator.csv, timeline.svg, protocol-draft.html
results/ counts, flow data (after the run)
index.html the report (generated by report mode)
One repo with a folder per experiment, not a repo each. The point of this tooling is comparing a new plan against what past runs measured, so past experiments need to be directories you can read — not separate repos behind an API.
Two modes.
Plan mode — before the experiment. Reads a planning doc and the source protocol being cloned, then produces:
- a reagent calculator (CSV → Google Sheet, live formulas, editable inputs)
- a timeline (SVG) flagging weekend and holiday collisions
- a cloned protocol draft (HTML → Google Doc) with every changed number tabled
- a findings summary — the part that matters
Report mode — after. Assembles the executed protocol, results, and conclusions
into an interactive report, and harvests new measurements into lab-defaults.csv.
The arithmetic is the easy part. The reason this exists is to catch where a plan's stated assumptions diverge from what past runs actually measured.
Worked example, from the first real use: the planning deck assumed 2–3 million VICs per 10 cm plate at D9. The source protocol had recorded 160,000 — a 12.5× gap, and enough to sink a 14-day experiment. Visible only by reading both documents and comparing them.
So lab-defaults.csv keeps MEASUREMENT and ASSUMPTION rows strictly separate,
each with conditions attached. "160k per plate" is meaningless without "no
fibronectin". Every measurement carries its source document and date.
- The calculator is the single source of numeric truth. The protocol and
timeline render its values; they never recompute.
build_protocol.pyenforces this by looking every amount up from the evaluated calculator, and exits non-zero rather than guessing. - Verification is mandatory and fails loudly.
verify.pymust pass before anything is shown. It caught three real bugs, including a weekend counter that silently returned 0 instead of 4 — a plausible number with no error, which would have hidden a Sunday sort date. - Never overwrite a calculator. Its input cells are the user's data. New file, date-stamped.
- Cloned protocols are drafts until a human has read the change table.
- Marginalia is evidence, not instruction. Past-run notes are preserved verbatim under a dated heading, never merged into the steps.
cd skills/vic-screen/scripts
pip install formulas openpyxl # LibreOffice OOMs; use this
python3 build_calculator.py params.json calculator.csv
python3 verify.py calculator.csv params.json # must pass
python3 build_timeline.py params.json timeline.svg
python3 build_protocol.py params.json protocol_source.json calculator.csv protocol.htmlparams.example.json and protocol_source.example.json are complete worked
examples from the VIC genome-wide screen, not stubs.
Validated on one protocol shape. build_protocol.py, build_timeline.py and
verify.py port to other protocols unchanged; build_calculator.py is currently
VIC-specific and needs a refactor to a declarative block spec first. See
docs/ADAPTING.md, which works through the lentivirus production
protocol as a concrete second case.
Report mode is specified but not yet exercised against a real run.