Delegation diagram as rings of circles; stop showing Simple Research as the mobile app
Some checks are pending
build-gate / build (push) Waiting to run

- The diagram is redrawn as concentric rings of uniform circles, not filled
  bands: the Plugin Studio ring labels itself, the seven plugins sit on the
  plugin ring, one agent per plugin sits outside it joined by a line and an
  arrow ("each plugin has one agent responsible for building it"), and one
  shepherd sits outside the agent ring. The race framing is gone. SVG source
  updated with the PNG.
- Deployment method 2: Simple Research was never built for phones, so it is
  no longer the mobile example. UPG-100 is; its screenshot lands when its
  phone layout is finished. The shot is removed from readme-shots, with the
  reason and the planned replacement in a comment.
- Retook nine screenshots that the latest bundle rebuilds had made stale.
This commit is contained in:
doxa-maps-88655c70 2026-09-24 21:08:46 +00:00
parent bb589d584e
commit 53308c546c
14 changed files with 81 additions and 83 deletions

View file

@ -12,7 +12,7 @@ capabilities, five deployment methods, one shared library, one build.
| **One app nests every map** — and each stays embeddable on its own | [capability 5](#capability-5--app-shell-the-research-gallery) · `bun run check:composite-reg` |
| **5 capabilities × 5 deployment methods** | `bun run verify:5-caps` |
| **Shared library, private plugins** — reuse without breaking each other | `bun run check:library-index` |
| **Many agents, one green `main`** | [agent swarm](#build-it-with-an-agent-swarm) |
| **One agent per plugin, one shepherd, one green `main`** | [agent swarm](#build-it-with-an-agent-swarm) |
---
@ -99,12 +99,11 @@ One `<iframe>` tag, no build step. Copy the `embed.iframe` snippet from `manifes
![Method 1 — the prayer map embedded in a host page's iframe](documentation/readme-images/deploy1-iframe.png)
### 2. Mobile app — Simple Research on a phone ✅ built
### 2. Mobile app — UPG-100 on a phone 🛠️ in progress
The Simple Research dashboard (research map + people-groups grid), shipped on its own as a
Capacitor app. `bun run check:mobile` · `bun run phone` (needs Android SDK + JDK 17)
<p align="center"><img src="documentation/readme-images/deploy2-mobile-simple-research.png" alt="Method 2 — the Simple Research dashboard at phone size" width="320"></p>
The UPG-100 list, shipped on its own as a Capacitor app. It is being finished for phones now;
its screenshot lands here when it is ready. `bun run check:mobile` · `bun run phone` (needs
Android SDK + JDK 17)
### 3. JavaScript embed — the Research Gallery on dx-life ✅ production
@ -133,11 +132,12 @@ not production-ready.
## Build it with an agent swarm
Trunk-based development with a **merge queue** — the model behind GitHub's merge queue and GitLab's
merge trains. Many agents build in parallel, each in its own worktree; changes land on `main` one
at a time, rebased and gated, so `main` stays green.
Every plugin has **one agent** responsible for building it, working in its own git worktree. The
plugins live together in the **Plugin Studio** — one repo, one shared library — and **one shepherd**
makes sure every agent is doing its job well. Changes land on `main` through a **merge queue** (the
model behind GitHub's merge queue and GitLab's merge trains): one at a time, rebased and gated.
![The delegation model: agents in their own worktrees send changes through one merge queue into main](documentation/readme-images/delegation-model.png)
![The delegation model: the Plugin Studio at the centre, a ring of plugins around it, one agent per plugin outside that, and one shepherd over all the agents](documentation/readme-images/delegation-model.png)
```bash
# one worktree + one agent per plugin
@ -154,8 +154,8 @@ flock /tmp/dx-maps-main.lock sh -c '
```
One agent owns the full build (it wipes the shared output first); everyone else checks their own
bundle with `BUNDLE=<name> bun x vite build`. A **maintainer** reviews what lands and keeps shared
code shared. Agents joining this repo: read [AGENT-BRIEF.md](./AGENT-BRIEF.md).
bundle with `BUNDLE=<name> bun x vite build`. Agents joining this repo: read
[AGENT-BRIEF.md](./AGENT-BRIEF.md).
Diagram source: [`delegation-model.svg`](./documentation/readme-images/src/delegation-model.svg).
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 175 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

View file

@ -1,68 +1,65 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="1010" viewBox="0 0 1200 1010" font-family="Inter, 'Helvetica Neue', Arial, sans-serif">
<svg xmlns="http://www.w3.org/2000/svg" width="1300" height="1300" viewBox="0 0 1300 1300" font-family="Inter, 'Helvetica Neue', Arial, sans-serif">
<defs>
<marker id="ar" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#64748b"/></marker>
<marker id="arM" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#b91c1c"/></marker>
<radialGradient id="gM" cx="45%" cy="40%"><stop offset="0" stop-color="#16a34a"/><stop offset="1" stop-color="#166534"/></radialGradient>
<marker id="ar" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#2563eb"/></marker>
<marker id="arS" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="8" markerHeight="8" orient="auto"><path d="M0,0 L10,5 L0,10 z" fill="#7c3aed"/></marker>
<path id="stLabel" d="M 526,720 A 124,124 0 0 1 774,720"/>
<path id="plLabel" d="M 342,720 A 308,308 0 0 1 958,720"/>
<path id="agLabel" d="M 184,720 A 466,466 0 0 1 1116,720"/>
</defs>
<rect width="1200" height="1010" fill="#ffffff"/>
<circle cx="600" cy="475" r="450" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2.5"/>
<circle cx="600" cy="475" r="365" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<circle cx="600" cy="475" r="262" fill="#fffbeb" stroke="#d97706" stroke-width="2.5"/>
<circle cx="600" cy="475" r="168" fill="#fef2f2" stroke="#dc2626" stroke-width="2.5" stroke-dasharray="8 6"/>
<rect x="578.0" y="297.0" width="44" height="20" fill="#fef2f2"/>
<line x1="578.0" y1="291.0" x2="578.0" y2="323.0" stroke="#dc2626" stroke-width="5" stroke-linecap="round"/>
<line x1="622.0" y1="291.0" x2="622.0" y2="323.0" stroke="#dc2626" stroke-width="5" stroke-linecap="round"/>
<text x="600.0" y="283.0" text-anchor="middle" font-size="13" font-weight="700" fill="#b91c1c">ONE GATE</text>
<line x1="600.0" y1="319.0" x2="600" y2="389" stroke="#b91c1c" stroke-width="3" marker-end="url(#arM)"/>
<text x="610" y="355.0" font-size="12" font-weight="700" fill="#b91c1c">merge</text>
<rect x="515.7941844763895" y="305.1584883484701" width="48" height="26" rx="13" fill="#ffffff" stroke="#dc2626" stroke-width="2"/>
<text x="539.7941844763895" y="323.1584883484701" text-anchor="middle" font-size="13" font-weight="700" fill="#b91c1c">#1</text>
<rect x="465.7820831295948" y="335.2087905225743" width="48" height="26" rx="13" fill="#ffffff" stroke="#dc2626" stroke-width="2"/>
<text x="489.7820831295948" y="353.2087905225743" text-anchor="middle" font-size="13" font-weight="700" fill="#b91c1c">#2</text>
<rect x="429.0638892005815" y="380.55198379861537" width="48" height="26" rx="13" fill="#ffffff" stroke="#dc2626" stroke-width="2"/>
<text x="453.0638892005815" y="398.55198379861537" text-anchor="middle" font-size="13" font-weight="700" fill="#b91c1c">#3</text>
<text x="431.7820831295948" y="328.2087905225743" text-anchor="middle" font-size="12" fill="#b91c1c" font-style="italic">waiting in line</text>
<text x="600" y="581" text-anchor="middle" font-size="16" font-weight="800" fill="#b91c1c">MERGE QUEUE</text>
<text x="600" y="599" text-anchor="middle" font-size="12" fill="#7f1d1d">one change at a time · rebased on main</text>
<text x="600" y="614" text-anchor="middle" font-size="12" fill="#7f1d1d">lands only if the gates pass</text>
<circle cx="600" cy="475" r="82" fill="url(#gM)" stroke="#14532d" stroke-width="2"/>
<text x="600" y="473" text-anchor="middle" font-size="30" font-weight="800" fill="#ffffff">main</text>
<text x="600" y="497" text-anchor="middle" font-size="13" fill="#dcfce7">trunk · always green</text>
<rect x="405.70000000000005" y="683.0" width="388.59999999999997" height="30" rx="15" fill="#ffffff" stroke="#d97706" stroke-width="1.5"/>
<text x="600" y="703.0" text-anchor="middle" font-size="14" font-weight="700" fill="#92400e">PLUGIN STUDIO · one repo, shared library/</text>
<rect x="371.3" y="777.5" width="457.4" height="30" rx="15" fill="#ffffff" stroke="#2563eb" stroke-width="1.5"/>
<text x="600" y="797.5" text-anchor="middle" font-size="14" font-weight="700" fill="#1e40af">AGENTS · one per plugin, each in its own worktree</text>
<rect x="336.9" y="867.5" width="526.2" height="30" rx="15" fill="#ffffff" stroke="#7c3aed" stroke-width="1.5"/>
<text x="600" y="887.5" text-anchor="middle" font-size="14" font-weight="700" fill="#5b21b6">MAINTAINER · reviews what lands, keeps shared code shared</text>
<circle cx="834.6174775355869" cy="195.393778261573" r="58" fill="#ffffff" stroke="#2563eb" stroke-width="2"/>
<text x="834.6174775355869" y="189.393778261573" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">Research</text>
<text x="834.6174775355869" y="206.393778261573" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">Gallery</text>
<text x="834.6174775355869" y="224.393778261573" text-anchor="middle" font-size="10.5" fill="#64748b">agent + worktree</text>
<line x1="796.0502209543945" y1="241.3564448487117" x2="711.8450440854579" y2="341.7082668972978" stroke="#64748b" stroke-width="2" marker-end="url(#ar)"/>
<circle cx="965.0" cy="475.0" r="58" fill="#ffffff" stroke="#2563eb" stroke-width="2"/>
<text x="965.0" y="469.0" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">Big</text>
<text x="965.0" y="486.0" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">Picture</text>
<text x="965.0" y="504.0" text-anchor="middle" font-size="10.5" fill="#64748b">agent + worktree</text>
<line x1="905.0" y1="475.0" x2="774.0" y2="475.0" stroke="#64748b" stroke-width="2" marker-end="url(#ar)"/>
<circle cx="858.0939751330899" cy="733.0939751330898" r="58" fill="#ffffff" stroke="#2563eb" stroke-width="2"/>
<text x="858.0939751330899" y="736.0939751330898" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">Regions</text>
<text x="858.0939751330899" y="762.0939751330898" text-anchor="middle" font-size="10.5" fill="#64748b">agent + worktree</text>
<line x1="815.667568261897" y1="690.667568261897" x2="723.0365799264592" y2="598.0365799264592" stroke="#64748b" stroke-width="2" marker-end="url(#ar)"/>
<circle cx="341.9060248669102" cy="733.0939751330899" r="58" fill="#ffffff" stroke="#2563eb" stroke-width="2"/>
<text x="341.9060248669102" y="727.0939751330899" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">UPG-100</text>
<text x="341.9060248669102" y="744.0939751330899" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">List</text>
<text x="341.9060248669102" y="762.0939751330899" text-anchor="middle" font-size="10.5" fill="#64748b">agent + worktree</text>
<line x1="384.332431738103" y1="690.667568261897" x2="476.96342007354076" y2="598.0365799264592" stroke="#64748b" stroke-width="2" marker-end="url(#ar)"/>
<circle cx="235.0" cy="475.00000000000006" r="58" fill="#ffffff" stroke="#2563eb" stroke-width="2"/>
<text x="235.0" y="469.00000000000006" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">Gospel</text>
<text x="235.0" y="486.00000000000006" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">Resources</text>
<text x="235.0" y="504.00000000000006" text-anchor="middle" font-size="10.5" fill="#64748b">agent + worktree</text>
<line x1="295.0" y1="475.00000000000006" x2="426.0" y2="475.0" stroke="#64748b" stroke-width="2" marker-end="url(#ar)"/>
<circle cx="320.39377826157306" cy="240.38252246441309" r="58" fill="#ffffff" stroke="#2563eb" stroke-width="2" stroke-dasharray="5 4"/>
<text x="320.39377826157306" y="234.38252246441309" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">your next</text>
<text x="320.39377826157306" y="251.38252246441309" text-anchor="middle" font-size="14" font-weight="700" fill="#1e3a8a">plugin</text>
<text x="320.39377826157306" y="269.3825224644131" text-anchor="middle" font-size="10.5" fill="#64748b">agent + worktree</text>
<text x="600" y="25" dy="-0" />
<text x="600" y="968" text-anchor="middle" font-size="18" font-weight="800" fill="#0f172a">Many agents build in parallel. Changes land one at a time. main stays green.</text>
<text x="600" y="992" text-anchor="middle" font-size="13" fill="#475569">Each arrow is a change entering the merge queue; only the queue writes to main.</text>
<rect width="1300" height="1300" fill="#ffffff"/>
<circle cx="650" cy="720" r="450" fill="none" stroke="#2563eb" stroke-width="1.5" stroke-dasharray="3 7" opacity=".7"/>
<circle cx="650" cy="720" r="290" fill="none" stroke="#15803d" stroke-width="2" opacity=".8"/>
<circle cx="650" cy="720" r="150" fill="#fffbeb" stroke="#d97706" stroke-width="3"/>
<text font-size="22" font-weight="800" fill="#d97706" letter-spacing="3"><textPath href="#stLabel" startOffset="50%" text-anchor="middle">PLUGIN STUDIO</textPath></text>
<text x="650" y="728" text-anchor="middle" font-size="16" fill="#92400e">one repo · one shared library</text>
<text x="650" y="752" text-anchor="middle" font-size="16" fill="#92400e">every plugin in one place</text>
<text font-size="15" font-weight="700" fill="#15803d" letter-spacing="2"><textPath href="#plLabel" startOffset="50%" text-anchor="middle">PLUGINS</textPath></text>
<text font-size="15" font-weight="700" fill="#2563eb" letter-spacing="2"><textPath href="#agLabel" startOffset="50%" text-anchor="middle">AGENTS</textPath></text>
<line x1="827.9" y1="350.6" x2="800.1" y2="408.3" stroke="#2563eb" stroke-width="2.2" marker-end="url(#ar)"/>
<circle cx="775.8" cy="458.7" r="50" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="775.8" y="455.7" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Big</text>
<text x="775.8" y="472.7" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Picture</text>
<circle cx="845.2" cy="314.6" r="38" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="845.2" y="319.6" text-anchor="middle" font-size="13" font-weight="700" fill="#1e3a8a">agent</text>
<line x1="1049.7" y1="628.8" x2="987.3" y2="643.0" stroke="#2563eb" stroke-width="2.2" marker-end="url(#ar)"/>
<circle cx="932.7" cy="655.5" r="50" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="932.7" y="652.5" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Simple</text>
<text x="932.7" y="669.5" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Research</text>
<circle cx="1088.7" cy="619.9" r="38" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="1088.7" y="624.9" text-anchor="middle" font-size="13" font-weight="700" fill="#1e3a8a">agent</text>
<line x1="970.6" y1="975.6" x2="920.5" y2="935.7" stroke="#2563eb" stroke-width="2.2" marker-end="url(#ar)"/>
<circle cx="876.7" cy="900.8" r="50" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="876.7" y="905.8" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Regions</text>
<circle cx="1001.8" cy="1000.6" r="38" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="1001.8" y="1005.6" text-anchor="middle" font-size="13" font-weight="700" fill="#1e3a8a">agent</text>
<line x1="650.0" y1="1130.0" x2="650.0" y2="1066.0" stroke="#2563eb" stroke-width="2.2" marker-end="url(#ar)"/>
<circle cx="650.0" cy="1010.0" r="50" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="650.0" y="1007.0" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">UPG-100</text>
<text x="650.0" y="1024.0" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">List</text>
<circle cx="650.0" cy="1170.0" r="38" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="650.0" y="1175.0" text-anchor="middle" font-size="13" font-weight="700" fill="#1e3a8a">agent</text>
<line x1="329.4" y1="975.6" x2="379.5" y2="935.7" stroke="#2563eb" stroke-width="2.2" marker-end="url(#ar)"/>
<circle cx="423.3" cy="900.8" r="50" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="423.3" y="897.8" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Prayer</text>
<text x="423.3" y="914.8" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Progress</text>
<circle cx="298.2" cy="1000.6" r="38" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="298.2" y="1005.6" text-anchor="middle" font-size="13" font-weight="700" fill="#1e3a8a">agent</text>
<line x1="250.3" y1="628.8" x2="312.7" y2="643.0" stroke="#2563eb" stroke-width="2.2" marker-end="url(#ar)"/>
<circle cx="367.3" cy="655.5" r="50" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="367.3" y="652.5" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Cities with</text>
<text x="367.3" y="669.5" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Internet</text>
<circle cx="211.3" cy="619.9" r="38" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="211.3" y="624.9" text-anchor="middle" font-size="13" font-weight="700" fill="#1e3a8a">agent</text>
<line x1="472.1" y1="350.6" x2="499.9" y2="408.3" stroke="#2563eb" stroke-width="2.2" marker-end="url(#ar)"/>
<circle cx="524.2" cy="458.7" r="50" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
<text x="524.2" y="455.7" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Gospel</text>
<text x="524.2" y="472.7" text-anchor="middle" font-size="13" font-weight="700" fill="#14532d">Resources</text>
<circle cx="454.8" cy="314.6" r="38" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="454.8" y="319.6" text-anchor="middle" font-size="13" font-weight="700" fill="#1e3a8a">agent</text>
<circle cx="650" cy="120" r="62" fill="#f5f3ff" stroke="#7c3aed" stroke-width="3"/>
<text x="650" y="126" text-anchor="middle" font-size="17" font-weight="800" fill="#4c1d95">shepherd</text>
<line x1="650" y1="184" x2="650" y2="228" stroke="#7c3aed" stroke-width="2.2" stroke-dasharray="6 5" marker-end="url(#arS)"/>
<text x="734" y="112" font-size="17" fill="#4c1d95">one shepherd makes sure all plugin agents</text>
<text x="734" y="136" font-size="17" fill="#4c1d95">are doing their job building the plugins well</text>
<text x="650" y="1250" text-anchor="middle" font-size="19" font-weight="700" fill="#1e3a8a">each plugin has one agent responsible for building it</text>
</svg>

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -330,12 +330,13 @@ virtualPages.set('/__readme-iframe-host.html', `<!doctype html>
await shot('deploy1-iframe', '/__readme-iframe-host.html',
{ vp: { width: 1000, height: 700 }, wait: 11000, countFrames: true, mapboxReferer: false })
// ---- DEPLOY2: mobile — the Simple Research dashboard as the phone app ----
// The mobile app ships ONE dashboard, not the whole gallery rail: research-map-plus-grid (the cap-4
// "Simple Research" composite — research map stacked over the people-groups grid), shot at a phone
// viewport. It mounts no iframe, so it keeps the Referer the map tiles need.
await shot('deploy2-mobile-simple-research', '/doxa-maps/research-map-plus-grid/research-map-plus-grid/index.html',
{ vp: { width: 390, height: 844 }, wait: 12000, dsf: 3 })
// ---- DEPLOY2: mobile — deliberately NOT shot yet ----
// The mobile example is UPG-100 (ruled 2026-09-24). Simple Research was retired as the example:
// it was never built for phones (legend, a bottom button cut off by the page edge, unreadable
// prompt). Once its phone layout is finished, add a shot named deploy2-mobile-upg100 of
// /doxa-maps/my-upg-100-list/upg-100-mfe/index.html at vp 390x844, dsf 3, and embed it in
// README.md under method 2. (Not written as code here: check:shots parses shot calls, even in
// comments, and would demand a PNG that does not exist yet.)
// ---- DEPLOY3: JS embed — the Research Gallery on a real host site ----
// The whole cap-5 gallery JS-embedded on dx-life's research page (a <script src> plus one element,