name: review-explorer-mdim-mapping
description: >-
Generate a self-contained HTML to review an explorer → MDIM view mapping
side-by-side, with approve/flag controls and browser-persistent decisions.
Consumes the output of the map-explorer-to-mdim skill (mapping_proposal.csv
+ mapping_rules.py + multidim_*_views.csv) and renders a single shareable
HTML in ai/. Trigger after map-explorer-to-mdim when a human needs to
verify the proposed explorer→MDIM correspondence chart-by-chart, or when the
user asks to "review the explorer→MDIM mapping", "build a review tool for
the migration", or "make a side-by-side HTML so can sign off".
metadata:
internal: true
Review an explorer → MDIM mapping (side-by-side HTML)
When an explorer is being retired in favour of one or more MDIMs, map-explorer-to-mdim
produces a proposed mapping (one explorer view → one MDIM view per row). This skill turns
that proposal into a shareable, self-contained HTML where a human steps through every
pair, sees both charts side by side, and clicks Approve / Flag (with notes).
Everything is saved automatically in the reviewer's browser, with an optional file
auto-save and Import for cross-machine recovery.
The HTML is a single file — no server, no dependencies. Just send the .html to the
reviewer.
When to trigger
- After
map-explorer-to-mdimhas producedai/<slug>-mdim-mapping/. - When the user asks for a review/verification UI for an explorer → MDIM migration.
- When the user mentions sharing the proposed redirects with a topic owner or colleague for sign-off before redirects are wired up.
If ai/<slug>-mdim-mapping/mapping_proposal.csv doesn't exist yet, stop and tell the
user to run map-explorer-to-mdim first (or do that as a prerequisite). This skill does
not produce the mapping itself.
Inputs you'll need
- The mapping directory —
ai/<slug>-mdim-mapping/, the output ofmap-explorer-to-mdim. Must contain at leastmapping_proposal.csvandmapping_rules.py.multidim_<short>_views.csvfiles are also used by the coverage report. - The explorer slug — matches the live URL, e.g.
natural-disastersforhttps://ourworldindata.org/explorers/natural-disasters. - The published Grapher slug per MDIM — one per MDIM short name listed in
mapping_rules.MDIMS. This is the slug that appears in/grapher/<slug>on the host, not the catalogPath. The skill cannot derive it without DB access, so ask the user (or look it up viamulti_dim_data_pages.slugif you have DB access).
If the user hasn't told you the published MDIM slugs and you can't query the DB, stop and ask — they're required to build the right-hand iframe URLs.
Usage
.venv/bin/python .claude/skills/review-explorer-mdim-mapping/scripts/build_review.py \
--mapping-dir ai/<slug>-mdim-mapping \
--explorer-slug <slug> \
--mdim-slug <short_1>=<grapher_slug_1> \
--mdim-slug <short_2>=<grapher_slug_2> \
[--host https://ourworldindata.org] \
[--output ai/<slug>_view_review.html] \
[--no-coverage]
Concrete example for natural-disasters:
.venv/bin/python .claude/skills/review-explorer-mdim-mapping/scripts/build_review.py \
--mapping-dir ai/natural-disasters-mdim-mapping \
--explorer-slug natural-disasters \
--mdim-slug deaths=natural-disasters-deaths \
--mdim-slug affected=natural-disasters-people-affected \
--mdim-slug economic_damages=natural-disasters-economic-damages
The script prints a coverage summary (rows, distinct MDIM targets, many-to-one collapses, unresolved rows, MDIM views never targeted) before writing the HTML. Read it: it's the fastest way to spot a mapping gap the reviewer can't see by eye.
What the reviewer sees
- One pair at a time — old explorer (left) vs proposed MDIM view (right), both rendered in iframes against the configured host.
- Selection chips above each chart (e.g.
Disaster Type: Floods · Impact: Deaths · …andtype: flood · timespan: annual · …) and the full URL underneath, with "open ↗". - Approve ✓ / Flag ⚠ / Clear, optional note, prev/next + a jump dropdown, filters (All / To review / Approved / Flagged), live counts.
- Keyboard:
←/→nav,aapprove,fflag,cclear. - Persistence: every action auto-saves to
localStorage(survives refresh & close). Auto-save to file (Chrome/Edge File System Access) mirrors each change to a JSON on disk. Import restores/merges from any exported JSON — the cross-machine recovery path and the way two reviewers merge their decisions. - Export CSV / JSON at any time for the verified mapping artifact.
Sharing the HTML with the team
The generated file is fully self-contained — you can just send it (Slack DM, email, etc.) and the reviewer opens it locally. For a link the whole team can hit without passing a file around, publish it to vibe.owid.io (OWID's internal site for sharing self-contained webapps).
The OWID vibe-app plugin skill handles the publish (scaffolds the entry in owid/vibe-webapps and ships it to vibe.owid.io). It is not installed by default in this repo — if vibe-app isn't in the user's skills list, tell them to install it once via /plugin in the Claude Code shell (it lives in the OWID Claude plugins marketplace). The typical follow-up after this skill produces ai/<slug>_view_review.html is:
"Publish
ai/<slug>_view_review.htmlto vibe.owid.io as a vibe app."
…which Claude routes to /vibe-app. Don't try to reproduce its behaviour here — keep the two concerns separate (this skill builds the HTML; vibe-app publishes it).
After the reviewer is done
They'll either:
- Send back the auto-saved JSON or an exported one, which contains every row with its
status(approved/flagged/ blank) andnote, plus the explorer/MDIM URLs. Use it to finalize the redirects (rows withstatus == "approved"are ready to wire up;flaggedrows need a second pass with the user). - Or just signal "looks good" — at which point the verified mapping artifact is the exported JSON / CSV.
Caveats / gotchas
- Reviewer's
localStorageis per-browser and per-file path. Refreshes don't lose work, but switching browser or machine does — that's why Auto-save to file / Import exist. If the reviewer shares decisions, ask them to Export JSON and send it. - Single-choice MDIM dimensions are pruned from URLs (and from the
mapping_proposal.csvwide block) — the skill respects that, so you should not manually add e.g. ametricparam for an MDIM whosemetrichas only one active choice. - Explorer URL params are display names, not slugs (e.g.
Disaster Type=Floods, notdisaster_type=floods).map-explorer-to-mdim'sdimension_1..Ncolumns already hold display values, andEXPLORER_DIMENSIONSnames them in order. hideControls=trueis appended to both URLs to hide each side's own selector chrome (the selection is shown as chips above the chart). Click "open ↗" to see the view with controls.- The MDIM must be reachable on the configured host. Defaults to production; for a
staging branch's MDIMs use
--host https://staging-site-<branch>(or have the reviewer edit Settings in the HTML). - The colleague's CSV is not the same format. If a mapping was hand-made in a custom
schema (e.g. multi-block header CSV), it must be converted to
mapping_proposal.csv+mapping_rules.pyfirst, or you can write a quick one-off adapter script inai/and point this skill at the produced folder.