This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is the Item Response Warehouse (IRW) website — a Quarto-based static documentation site published at https://itemresponsewarehouse.org/. It is not an R package; it is a publication-focused website with embedded R data analysis.
Project map: ARCHITECTURE.md in ben-domingue/irw — which repo owns
what, where the data lives, and which document is authoritative when two disagree.
quarto render # Full site build → _site/
quarto preview # Dev server on port 4200
quarto render vignettes/cfa.qmd # Render a single fileThe site is published by GitHub Actions (.github/workflows/quarto_publish.yaml) to gh-pages. Pushing to main still does not deploy — there is no push trigger. Trigger a publish by hand — gh workflow run quarto_publish.yaml, or the "Render and Publish" workflow in the Actions UI.
Since 2026-09-08 there is also a daily scheduled rebuild at 14:30 UTC, conditional on main having moved since the last publish (the decide job compares the two branches' commit timestamps and skips the render otherwise). So a commit to main reaches the live site within a day without anyone asking; it is a safety net, not a replacement for dispatching when you want it now. Note it watches this repository only: a new irw_meta release changes what the live-queried pages would say without changing anything here, and that direction is reported by the drift report in ben-domingue/irw (#1940) rather than triggering a render.
This project uses renv for reproducible R environments:
renv::restore() # Install all pinned packages from renv.lockData is fetched live from Redivis using REDIVIS_API_TOKEN (required env var for data pages). Pages without Redivis calls render without it.
Some vignettes execute Python, not just R. quarto render of the whole site
will fail on vignettes/irt_python.qmd with ModuleNotFoundError: No module named 'mirt' unless the Python that Quarto resolves has them installed:
pip install mirt girth scipy matplotlib pandas jupyter
pip install irwThat is the same list .github/workflows/quarto_publish.yaml installs, so CI
always has it and a fresh maintainer machine usually does not.
irw comes from PyPI now rather than from git+, which is a change in kind
worth knowing: a render installs the last released version, not whatever is on
Python-pkg's main. So a fix that has been merged but not tagged will not
reach the site. That is the more honest default — the site should show what
pip install irw actually gives a reader — but it means shipping a Python-pkg
fix to the site now takes a release, not a merge. A full local
render is therefore not a reliable pre-flight check for CI — it can fail for a
reason CI does not have, and a local pass is no guarantee either. Rendering a
single page (quarto render data.qmd) is unaffected and is usually what you
want while iterating.
Note also that _quarto.yml declares a post-render step
(landing/emit_landing_pages.R, which generates the per-table pages under
_site/tables/). Post-render runs only after a successful render, so a
broken vignette silently means no landing pages are emitted.
- Root
.qmdfiles are top-level pages (index, about, data, standards, etc.) vignettes/— standalone analysis tutorials; some have companion*_compute.R+.Routfiles for pre-computed heavy outputscomponents/— reusable Quarto includes:_hist.qmd(Observable histogram),_interval.qmd(range slider),_tol.qmd(tolerance slider),_style.qmd(CSS setup for data explorer),_source-links.qmd(per-vignette "Source code for this page" links, backed bycomponents/source_links.R, which is where the GitHub URL pattern lives)- Partial files prefixed with
_are included via{{< include >}}in other pages
Data pages combine two languages:
- R — fetches metadata from Redivis (
_load-data.qmd) and does preprocessing; results are passed to OJS viaojs_define() - OJS (Observable JavaScript) — drives all interactive UI: the filterable dataset table, the Observable Plot charts, and the filter components
The data explorer is data.qmd. Its OJS lives inline in that file — the filter
inputs, the Inputs.table call, the plots, and the info/code-snippet callouts are
all chunks in data.qmd itself, not in separate partials. The only includes are
_load-data-explore.qmd (the R side: Redivis fetch, tag preprocessing,
ojs_define()) and the reusable widgets under components/ (_interval.qmd,
_hist.qmd, _tol.qmd, _style.qmd). So changes to filter logic or table display
go in data.qmd; changes to what data reaches OJS go in _load-data-explore.qmd.
Heavy statistical computations are offloaded to a companion *_compute.R script that writes .rds cache files (e.g., vignettes/2pldata/2pl_across_datasets_results.rds). The vignette .qmd then loads the cache with readRDS(...) instead of re-running the model. When adding a new computation-heavy vignette, follow this pattern: create vignettes/<name>_compute.R, run it locally to produce the cache, commit both the script and the .rds, then reference the cache in the .qmd.
All code runs with echo: false, message: false, warning: false, error: false — the site is reader-facing, not a teaching document. Don't change these defaults for new pages. Individual vignettes may override locally (e.g., echo: true in tutorial-style pages like imv.qmd).
- Base theme: Cosmo
- Custom SCSS:
resources/scss/main.scss(main styles, data explorer layout) andscss/global.scss(callout margins) - Body width: 1200px, no sidebar
- Custom CSS classes for interactive components:
.panel-input,.filters-container,.plot-container,.sparkbar,.pullout
redivis— data accessmirt— IRT modelingimv— InterModel Vigorishplotly,ggplot2— visualizationarrow— Parquet supportlme4,BradleyTerry2,elo— statistical modelinglavaan— SEM/CFA modeling
- Do more with
construct_name(measure description) from the tags sheet — it is dropped by theselect(-construct_name)in_load-data-explore.qmd'stag_valspipeline, so it never appears in filters or the table. Options: (1) add it to theinfoobject behind the "Information on selected dataset" callout indata.qmd, (2) add a free-text search filter for it, (3) show it as a column in the dataset table
Vignette-branch status, merge history, and the survey-vignette harmonization scaffold/checklist are tracked in Claude's memory, not here — see project_vignette_harmonization_2026_07_21.md and project_vignette_branches_status.md.