Four screens, clickable. A user drops an export folder, reads what fits and what does not, maps one domain column by column, and reviews the configuration change it writes back into their own study repository.
A sponsor has a Phase 2 study running in an EDC, with central labs from a vendor. They fork the study-repo template, and they have a folder.
An EDC extract as CSV, a central-lab SAS transport, a site list somebody keeps in Excel, and a define.xml. Column names are SDTM-ish upper case. The lab file’s subject identifier is site-prefixed; the demographics file’s is not.
Counted from demo-301/workflows/1_mappings/. Findings and events are lower-case SDTM-adjacent (lbstresn, aeterm); subject, site and enrolment are operational-EDC shaped (invid, agerep, enrollyn, subject_nsv). Neither SDTM nor ADaM arrives fitting.
og_validate() prints which file and column is missing. Fixing it means opening fourteen workflow files and adding source_col: lines — a key that exists, works, and is documented nowhere a user of open.gismo would look.
Click the numbered steps. The third screen is live: change a mapping and the preview, the readiness line and the diff on screen four all move with it.
open.gismo copies what you give it into input/ as plain CSV and leaves the originals alone. The project folder stays a folder of text files you can read, diff and review.
11 files read · 9 placed · 1 ambiguous · 1 ignored
| File | Reads as | Why open.gismo thinks so |
|---|---|---|
| dm_2026-08-20.csv | Raw_SUBJ | 13 of 15 spec columns present after case-folding · one row per SUBJID |
| ae.csv | Raw_AE | 16 of 16 present after case-folding |
| lb_central.xpt | Raw_LB | SAS transport, converted on import · 13 of 14 present |
| lb_local.csv | Raw_LB ◐ second candidate | Also fits Raw_LB. Stack the two files or choose one — open decision D7 |
| eg.csv | Raw_EG | 9 of 10 present · egblfl absent |
| pd.csv | Raw_PD | 6 of 6 present |
| enroll.csv | Raw_ENROLL | 7 of 7 present |
| queries_20260820.csv | Raw_QUERY | 4 of 5 present · subject_nsv absent |
| sites.xlsx | Raw_SITE | Sheet 1, converted on import · 9 of 9 present |
| study.csv | Raw_STUDY | 6 of 15 present — the rest is protocol metadata, not an extract → study card |
| define.xml | — | Ignored. open.gismo reads no define.xml today — open decision D6 |
Nothing has been written yet. The next screen is the last one before anything lands in the repository.
Fourteen domains the mapping workflows read. What this screen adds to today’s og_validate() is the last two columns: whether the identifiers actually join, and what a domain costs if you go without it.
| Domain | Source | Rows | Columns | Keys join? | State |
|---|---|---|---|---|---|
| Raw_SUBJ | dm_2026-08-20.csv | 1,012 | 13 of 15 · 2 renamed | spine | ✓ Ready |
| Raw_AE | ae.csv | 2,904 | 16 of 16 · 16 renamed | 612 of 612 ✓ | ✓ Ready |
| Raw_LB | lb_central.xpt | 58,412 | 13 of 14 · 13 renamed | 0 of 812 ✗ | ✗ Needs attention |
| Raw_EG | eg.csv | 9,140 | 9 of 10 · egblfl absent | 764 of 812 ◐ | ◐ Needs a decision |
| Raw_ENROLL | enroll.csv | 1,012 | 7 of 7 | 1,012 of 1,012 ✓ | ✓ Ready |
| Raw_PD | pd.csv | 488 | 6 of 6 · 5 renamed | 301 of 301 ✓ | ✓ Ready |
| Raw_SITE | sites.xlsx | 46 | 9 of 9 · 6 renamed | 46 of 46 ✓ | ✓ Ready |
| Raw_QUERY | queries_20260820.csv | 3,377 | 4 of 5 · subject_nsv absent | — | ◐ Needs a decision |
| Raw_STUDY | study.csv + form | 1 | 6 of 15 · 9 to type | — | ◐ Needs a decision |
| Raw_DATACHG | — | — | — | — | — Going without |
| Raw_DATAENT | — | — | — | — | — Going without |
| Raw_SDRGCOMP | — | — | — | — | — Going without |
| Raw_STUDCOMP | — | — | — | — | — Going without |
| Raw_IE | — | — | — | — | — Going without |
SUBJECT maps cleanly onto subjid: right type, no missing values, 812 distinct. But the lab vendor prefixes the site — "0301-S036" — and the demographics extract does not — "S036". LB.yaml inner-joins Raw_LB to Mapped_SUBJ on subjid, so the mapped domain would come out empty and six of the nine safety charts, the Hy’s Law candidate metric and the Grade 3+ Lab Abnormality Rate would all render with no data and no error.
Fix it on the next screen, or run anyway and accept the hole.
| Raw_DATACHG | kri0008, kri0011, cou0008, cou0011 · no charts |
| Raw_DATAENT | kri0010, cou0010 · no charts |
| Raw_SDRGCOMP | kri0007, cou0007 · no charts |
| Raw_STUDCOMP | kri0006, cou0006, qtl0002, the QTL report |
| Raw_IE | qtl0001, the QTL report |
Declining is recorded in the study config, not swallowed as a warning, so the site can say a KRI is absent because you declined the domain — rather than leaving a gap the reader has to explain.
The left column is what the mapping spec requires and who downstream needs it. The right column is your file. open.gismo proposes a match and says why; you confirm or change it. Nothing is applied silently.
Sample values are illustrative. The target column names, their types and their downstream consumers are read from demo-301/workflows/.
Not session state, not a hidden database row — a diff against the study’s own configuration, in the study’s own repository. One commit, one review, one thing to point at when somebody asks how a number was produced.
source_col: is an existing, exercised key in the gsm mapping spec — gsm.mapping’s own shipped workflows use it to read Rave column names such as subjectname and protocol_number. The rename half of this screen needs no engine change at all.
The spec has exactly two column keys: type and source_col. There is no key that transforms a value — so stripping a site prefix off an identifier, or recoding a baseline flag, has nowhere declarative to live. Fix either of the highlighted rows on screen three and the amber lines appear: those are a proposal, not a feature.
The commit is the mapping. Re-running the study a year later reproduces it because the mapping is in the repository next to the data, not in whoever’s browser did it.
Screen three is live — change any of the three highlighted rows and screens three and four both update. The other screens are fixed.
Transport files, Excel and CSV all come in the front door and are written out as CSV into input/. The conversion happens once, at import, so the project folder keeps being the plain, diffable, forkable thing the whole product rests on.
Today’s validation asks whether the columns are there. This asks whether the study will produce anything: do the identifiers join, and what do you lose by going without a domain. Both are answerable before a pipeline runs and neither is asked today.
A user cannot map to a spec they cannot see. Putting the required column, its type and its downstream consumer next to their own column with a proposed match and a stated reason is the whole surface. It is a grid, not a wizard.
Every commercial platform with a real mapping surface keeps the result inside itself. safetyGraphics — our own ancestor — is the one surveyed tool that hands the mapping back as code. This goes one step further and makes it a reviewed file in the study repository.