Commit graph

1180 commits

Author SHA1 Message Date
doxa-maps-88655c70
e1d847028d PPLR data maps (WIP): move the ten PPLR research views into plugin-designs
Not for main yet. All ten views mount on the dev server with real data and no
page errors. Left: the coverage view's status still says 'sample of 6,000',
its choropleth needs checking, and the bundle is not built or tree-verified.
2026-09-25 06:33:49 +00:00
doxa-maps-88655c70
d77efea253 Merge commit '961d9811db428fd995e7fe4c70b8bb95ab832987' into bundler-1/work
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 06:33:06 +00:00
doxa-maps-88655c70
20acc242ff Regenerate after merging main 2026-09-25 06:32:40 +00:00
doxa-maps-88655c70
961d9811db Take main
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 06:32:31 +00:00
doxa-maps-88655c70
6be1395d1f Cell C has a gate now: the composite must filter, not navigate
The claim worth testing about the composed dashboard is not that it renders. It
is that it keeps the reader INSIDE it. Standalone, "Every resource in
<language>" is a link to the tables page; composed, it must be a button that
filters in place, because navigating away throws out the map the reader just
positioned and the group they just found. Same words, two affordances, one right
in each context.

Six assertions, each a way the composite can look fine and be broken: the
control is a <button> not an <a>, the URL does not change, the table's row count
goes DOWN, it does not go to zero, the pin count survives, and nothing 4xx'd or
threw.

It picks its subject from the live source rather than by position, and that is
not a detail. The first run opened pin 0 — Abai Sungai, a group with nothing
found — so the filter correctly produced an empty table and the check failed a
working composite. The test was wrong, not the product. It now opens a tier-2
pin, so "narrowed but not emptied" is a question the subject can answer.

Measured: 2,107 pins and 50 rows before, then Telugu narrows the tables to 13
with the map intact and the URL unchanged.
2026-09-25 06:32:02 +00:00
doxa-maps-88655c70
cd24bda42a Merge commit '8caf2dde90f44b26dea67df511b343b582ae52bc' into bundler-1/work
# Conflicts:
#	public/doxa-maps/index.html
2026-09-25 06:31:59 +00:00
doxa-maps-88655c70
d61819b553 Forward urlSync to the nested panes: the guard was unreachable without it
rega measured that a Regions nested in the Research Gallery STILL rewrote the
host's #anchor and tab title after my urlSync guard landed, and named the cause
exactly: regions-mfe.vue INHERITED_PAGE_KEYS lacked `urlSync`.

They were right, and the lesson is mine. Guarding writeUrl, syncTitle and
popstate in region-dashboards.vue was necessary and NOT sufficient: a nested
pane has no leaf page of its own, so it only ever sees what this composite
forwards. Without the key the panes read cfg.urlSync as undefined and the guard
never fired. A guard you cannot reach is not a guard, and I had verified only
the half I could see from my own file.

It is the same lesson this file already records for cap-4 asset paths: page
scoped config must be forwarded explicitly. The existing filter keeps `false`,
which is the value that matters here -- it rejects undefined, null and '' only.

VERIFIED ON THE WHOLE PATH, composite -> pane -> guard, on a foreign origin
(tree on 127.0.0.1, host page on localhost) with urlSync:false and a host
#anchor: 868 nodes and 2 nested pane roots rendered, and the host's
#host-anchor-must-survive and its tab title both came through untouched.

The probe asserts the embed RENDERED before it believes the URL result, and
that guard earned itself twice: a first run used <regions-mfe> as a tag, which
is a profile of <regions-dashboard> and not an element, so nothing mounted --
7 inert nodes, with the host URL "untouched" only because no code had run.
2026-09-25 06:31:36 +00:00
doxa-maps-88655c70
8caf2dde90 Rebuild Cities with Internet and Prayer Progress on the merged main
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 06:14:53 +00:00
doxa-maps-88655c70
93dc5d14a2 Merge remote-tracking branch 'origin/main' into exp-shepherd/cities-dots
# Conflicts:
#	public/doxa-maps/index.html
2026-09-25 06:13:08 +00:00
doxa-maps-88655c70
cb6ee50e7a check:shared-reached: a bundle that never compiles the changed code is not "missing" the fix
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
ensureEngineCSS is only called by initializeMap. A bundle that imports
pieces of useMapInstance (ensureEngineScript, engineGlobal…) but never
initializeMap has ensureEngineCSS tree-shaken away, so the guard can
never appear in it and the race cannot happen there. The check counted
those bundles as missing the fix. upg100 caught it on my-upg-100-list.

The map-unmount-guard entry now also declares the unguarded shape. A
bundle is missing the fix only if it still compiles ensureEngineCSS
without the guard. With neither shape it is reported as not affected.
Entries without a staleRe behave exactly as before.

On today's tree: 7 bundles carry it, 2 are really stale
(doxa-research-map, research-dashboard), and 3 are not affected
(cities-internet, gospel-resources, my-upg-100-list). Before this, all
three were reported as stale.
2026-09-25 06:11:17 +00:00
doxa-maps-88655c70
502a4186dc Cities with Internet and the phone legend speak the page's language
Cities with Internet was English end to end: the legend title, the four bands,
the World Bank caveat, the new people-group row and the whole country sheet. Its
chrome now comes from a connectivity catalog area in all eleven locales, following
gospel-resources: i18n is optional, English from the shipped catalog is the
fallback, and carrier and platform names stay as data. The legend and the sheets
are anchored with logical insets, so in Arabic the legend sits opposite the control
rail instead of under the zoom buttons.

LegendMobile hard-coded its column labels ("Prayer Status", "Engagement Status",
…) and titles ("Legend", "Languages", …) in English. They now read
legend.colLabel.* and legend.titleBar.*, which every catalog already translates.
English is byte-identical, so other consumers are unchanged until they rebuild.

Measured in the Research Gallery tab on a served built tree, at 1280 and 390, in
en/ar/zh/ru/hi: Cities shows no English UI string (only the Mapbox and
geoBoundaries attribution); ar is right-to-left with 0 clipped and the legend
clear of the control rail.
2026-09-25 06:05:46 +00:00
doxa-maps-88655c70
e7638747f8 README: retake the Research Gallery shot from the latest doxa-maps-spa build
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 05:56:22 +00:00
doxa-maps-88655c70
40750a153e Screenshots wait for the maps to finish loading
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
readme-shots captured on a fixed timer once the page's elements existed, so
maps were caught mid-load: the Big Picture globe came out as a bare white ball
and the UPG-100 map without its resources. Every request is now tracked, and
the capture waits until nothing has been in flight for 4 s (capped at 60 s,
with a warning if the cap is hit), then 1.5 s for the last tiles to paint.

Retaken with the new wait and checked by eye: Big Picture (country shading and
people-group dots on the globe), the research map, the three prayer /
engagement / adoption presets, all people groups, the Plugin Studio and the
iframe host. The UPG-100 shots are deliberately NOT retaken yet: its owner is
still resizing that map.
2026-09-25 05:52:09 +00:00
doxa-maps-88655c70
405db377d8 Take main
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 05:51:48 +00:00
doxa-maps-88655c70
c31df9f349 IBT is the best lead on this map, and recording why it is not a pool
36 Doxa groups carry an IMB "audio Scripture exists" flag while every pool here
says nothing. Asking why rather than shrugging: most are Dagestani and Caucasus
languages — Akhvakh, Andi, Bagvalal, Botlikh, Chamalal — which the
English-centred catalogues simply do not cover. The Institute for Bible
Translation in Moscow does, and their /languages page lists 54+ projects
including every one of those, with an ordinary robots.txt that allows it.

It still cannot be a pool. The page gives a native-script name, a region and a
language family and nothing else: no ISO code, no per-language page, no
publication URL. Joining it means matching "Akhvakh (ашвалӏи мицӏцІи)" to a
code by NAME, which is the guess this build removed two commits ago when Doxa's
own API made it unnecessary — the same guess that would have handed Akha in Laos
one of three sub-varieties.

What it is worth is the other thing the Driver asked for: the people who do the
translation work, so a group with nothing can be handed to a team that already
has the linguistic work and the relationships. For the Caucasus cluster, IBT is
that team, by name. That belongs in a leads table with a human confirming each
code, never auto-joined into the index.
2026-09-25 05:51:26 +00:00
doxa-maps-88655c70
e13a8dca05 Rebuild the Research Gallery against merged main and regenerate the tree
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 05:49:02 +00:00
doxa-maps-88655c70
6d59645b37 Merge remote-tracking branch 'origin/main' into rega/research-gallery-embed
# Conflicts:
#	public/doxa-maps/index.html
2026-09-25 05:48:29 +00:00
doxa-maps-88655c70
3b8e8e21e7 Research Gallery: name the Experimental maps, in every locale
The Experimental folder's rail rows were the one part of the gallery's own
chrome still in English in every locale. They were also machine-titleized
manifest ids, so even English read "Upg Neighbor".

The six Experimental bundles known today now have proper rail names in all
11 locales (Prayer Walk Planner, UPG Neighbor, Key Cities, All People
Groups, Country Posters, Doxa Vision Card). A future bundle that isn't
listed still appears, under its manifest title. Outside English its
English manifest description is replaced by the translated generic
subtitle.

Measured on the served built tree with the folder opened (7 → 12 rows):
translated in it/de/hi/ru/ar, en "UPG Neighbor", and 0 clipped. The rail
clip sweep with the folder open (11 locales × 1400/390) is 22/22 clean.
check:spa-tab-order passes on my own served tree. check:gallery-embed:
js 13, iframe 13, neighbour 13, linked 4.
2026-09-25 05:48:21 +00:00
doxa-maps-88655c70
7999d9a876 Take main
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 05:47:29 +00:00
doxa-maps-88655c70
c980d4e576 The Deaf gap is larger than this map was treating it as, and the route is a person
Cross-checking Doxa's roster against IMB's own access flags: 122 of their 2,107
people groups are DEAF — 17.5 million people — and 92 have nothing in this index.
For 33 of those 92 IMB records that material EXISTS, much of it dated 2021 at
"Selections" or "Stories": Armenian, Bulgarian, Myanmar, Cambodian and Cuban
sign languages among them. That is a coordinated body of work this build cannot
see.

Re-probed all three hosts so nobody spends another tick on them:

  doorinternational.org   the REAL DOOR International. Cloudflare 403 "Just a
                          moment..." on every path INCLUDING robots.txt. A bot
                          shield, and this repo does not circumvent shields — it
                          reached GRN through their own public site rather than
                          around it. Out on access, never on doctrine.
  deafbible.com           still the same 3,894-byte app shell for every URL,
                          /sitemap.xml included. robots allows everything; there
                          is simply nothing served to a fetch. api.deafbible.com
                          answers 525, so their own app's API is down too.
  door.international      NOT theirs. Parked for sale on GoDaddy, and it now
                          publishes an llms.txt saying exactly that. It looked
                          like a lead precisely because it advertises an LLM
                          policy. Their real domain is the first entry above.

This is the largest identified-but-unreachable set on the map. The route is
someone asking them for access, not another agent probing the same three hosts.
2026-09-25 05:46:52 +00:00
doxa-maps-88655c70
4314f0e2f6 README for vibe coders: the Goal, pictures first, everything else folded away
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
- The Goal and Isaiah 40:3 lead the README, byte-for-byte as written on the
  public repo (driver-web-edits.patch), so the next export keeps them.
- Each of the 5 capabilities and 5 deployment methods is now a one-line
  summary, its picture, and a collapsed "More about…" dropdown. 16 dropdowns,
  none open by default, so a reader can scroll the pictures and summaries.
- WordPress / Disciple Tools and desktop say what is true in plain words: we got
  a JAMstack map running there; proven, not yet a production feature; the
  Research Gallery could become a strong desktop app. Their cards match.
- The agent-swarm section explains the problem in plain words (one shared
  library and one build means one bad change breaks every map), with a git
  glossary and the commands folded away.
- Get it running now includes your own free Mapbox token (the public copy
  ships without one), and a dropdown on changing the studio itself.
- The diagram has eight plugin nodes, main at the centre behind a padlocked
  merge-queue ring, and a plain-language "How main is protected" strip.
2026-09-25 05:44:14 +00:00
doxa-maps-88655c70
8423411757 The GRN sweep was defaulting to "none", not measuring it
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
Cross-checking IMB's own access flags against this index turned up 112 Doxa
groups where they say a resource exists and we found nothing. Nineteen of those
were gospel recordings — GRN, a pool this build had already swept — so one of the
two was wrong. Asking 5fish directly about six of them, with a real code and an
impossible one as controls: FOUR have recordings. alk Alak, nos Nisu Eastern,
jle Ngile, lma Limba East, each landing on its own numbered language page.

The fault is here. classify() read the page TITLE and its last rule was a
catch-all: any title matching neither known pattern became "none". That is a
default wearing the clothes of a finding, and it was silently losing every page
whose title was phrased in a way nobody had anticipated.

The landing decides now and the title only names. A published code lands on
/<id>?language=<name>; one they do not carry is swept to /regions — the same
discriminator already proved in band in the verifier and the rot sampler. A
request that errors leaves the code UNDECIDED rather than "none", because
recording a failed request as an absence is how this started.

GRN_RECHECK=1 re-asks the codes the old rule defaulted, and a hit can now take a
code back OUT of the none list — a recheck that could only add would be unable to
correct the thing it exists for. Proved on the six: 4 recovered, 2 confirmed
empty, controls passing.
2026-09-25 05:42:16 +00:00
doxa-maps-88655c70
ce46d92998 Composite pages hand a ?tk= or pasted token to their nested maps, and ask when there is none
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
A composite's nested Mapbox maps read window.MAP_TOKEN, not the page's
profile-config. In a tree with no baked token (the public copy), the token-free
research-map-plus-grid page mounted before reading ?tk= or a stored token, so
its map stayed blank with no prompt. Now every leaf publishes the token it
resolves to window.MAP_TOKEN, and a token-free composite with no token renders
its content plus the paste-once prompt, then reloads with the token.

Verified in a browser against a tree regenerated with no token:
  research-map-plus-grid  no token: prompt shown | ?tk=: map drawn, Mapbox 6 OK / 0 errors
  dashboard-plus-grid     no token: prompt shown | ?tk=: map drawn, Mapbox 6 OK / 0 errors
Negative control (unpatched generator): research-map-plus-grid with ?tk= never
received the token (0 Mapbox requests) and showed no prompt without one.

Also: removed a personal health note the page template wrote into every leaf
page, and the Mapbox account names from three comments. Pages regenerated on
the latest main; nested-token, sri, hygiene, drop, parse, embed-targets pass.
2026-09-25 05:35:46 +00:00
doxa-maps-88655c70
60347ec0b7 Take main
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 05:35:33 +00:00
doxa-maps-88655c70
26cd737587 All 2,107 of Doxa's groups, placed and searchable, from Doxa's own record
The map got coordinates and a language code by matching each group's NAME
against the pin dataset. That left 285 unplaceable and, worse, unsearchable: no
ISO code is no key to look them up by in any pool, so the access table could only
report them as "not searched" — nobody had been able to ask.

Doxa's own per-group endpoint carries both, and their robots.txt disallows
nothing. /api/people-groups/detail/<slug> gives primary_language and latitude and
longitude for every one: Akha to ahk, Akeu to byo, Alxa Mongols to xal, Ajja to
krs — four the name join had failed. So the name matching is not improved, it is
REMOVED. It was always a guess wearing a join's clothes: Akha in Laos sat beside
Akha Jipea, Akha Jaweuy and Akha Piso in the pins, and any pick among them would
have invented a language for a people. The publisher saying which language their
group speaks ends the guessing.

2,107 of 2,107 placed. Zero without a language code. The "not searched" rung is
gone from the access ladder because nothing is unsearched any more.

The gap grows 281 to 381, and that is the point: those 100 groups were always
without the gospel in their language, and the map could not say so because it did
not know what their language was.

The fetcher runs its controls in band both ways before trusting a record — a real
slug must return a language and coordinates, an impossible one must not — so a
site answering 200 with an empty body could not fill this table with silence.
IMB's own access and engagement fields come along beside ours, never merged into
them, because where two sources disagree that disagreement is worth seeing.
2026-09-25 05:35:11 +00:00
doxa-maps-88655c70
75073e3d83 Rebuild the plugin studio bundle: mount the element the bundle defines
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
Built from the studio change just before this commit. Rebuilt that one
bundle and re-baked its SRI; check:sri passes.
2026-09-25 05:34:18 +00:00
doxa-maps-88655c70
5bbbcc61f4 Plugin studio: mount the element the bundle defines, not the one a profile's JSDoc names
A profile's `element` in the manifest is copied from its @element JSDoc,
and that can name a tag nothing registers. country-posters-mfe's says
<country-posters-mfe>, but country-posters' index.js defines only
<country-posters-map>, so the built studio showed "never registered"
on a working plugin (gospel-dashboard had the same shape until
5418a79c). The studio now uses a profile's element only when the
bundle's `elements` (what index.js actually registers) includes it, and
otherwise the bundle's defined element.

Across all 33 manifest profiles this is the only mismatch, and its
published embed snippet already uses the right tag. Verified on the
built tree: country-posters-mfe mounts <country-posters-map> with
content (2,025 elements).
2026-09-25 05:34:16 +00:00
doxa-maps-88655c70
e8bbe77822 Rebuild my bundles on the merged main
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 05:32:32 +00:00
doxa-maps-88655c70
ca79ccb91c Merge remote-tracking branch 'origin/main' into exp-shepherd/cities-dots
# Conflicts:
#	public/doxa-maps/index.html
2026-09-25 05:23:30 +00:00
doxa-maps-88655c70
d6496bd87d Rebuild my six bundles to carry the useMapInstance unmount guard (0c1a91cd)
doxa-simple-map, cities-internet, all-people-groups, upg-neighbor,
prayer-walk-planner and demo-map compile useMapInstance in, so 0c1a91cd reaches
them only through a rebuild. check:shared-reached reports all five that use it as
carrying the guard.

cities-internet builds its map directly and never calls ensureEngineCSS, so it gets
its own guard: onMounted stops before new gl.Map if the pane unmounted during its
awaits. Removing the element 150, 400 or 900 ms after mount did not throw on either
build, so this is defensive, not a measured fix.
2026-09-25 05:23:08 +00:00
doxa-maps-88655c70
31ddd2eb87 Merge commit 'dc11cdbb6a536c7797651009851e357a532b6224' into bundler-1/work
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
2026-09-25 05:19:05 +00:00
doxa-maps-88655c70
21a0d70f07 Rebuild regions-dashboard and country-posters for studio's shared useMapInstance race fix 0c1a91cd
No code change of mine: a shared library fix is only as deployed as the last
rebuild of each consumer, and each bundle ships its own compiled copy.
check:shared-reached now reads country-posters and regions-dashboard as carrying
it.
2026-09-25 05:18:30 +00:00
doxa-maps-88655c70
dc11cdbb6a check:shared-reached: pin the unmount-guard marker to ensureEngineCSS only
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
The first regex for map-unmount-guard also matched useShadowStyles as
the current source compiles it:
  if(!n)return;const i=n.getRootNode();if(!(i instanceof ShadowRoot)||…
The freshly built plugin-studio bundle, which has no useMapInstance at
all, matched it. So any consumer rebuilt against today's useShadowStyles
would have been counted as carrying the fix whether or not it did.

The marker now requires ensureEngineCSS's early exit, "…ShadowRoot))return",
where useShadowStyles continues with "||". Proven both ways on a rebuilt
doxa-simple-map: built from the guarded source it matches, built with
the guard stripped it does not. The studio bundle no longer matches.
2026-09-25 05:17:07 +00:00
doxa-maps-88655c70
4cfe8ec5e2 Merge commit 'd989d598f18227e677f762c15c21df27013a57ad' into bundler-1/work
# Conflicts:
#	public/doxa-maps/index.html
2026-09-25 05:16:03 +00:00
doxa-maps-88655c70
07d3341c83 Poster footer becomes tape on the border, and per-row persists (Driver)
Driver: "see how the header for show on map is inline on the top of the poster
box? but the footer print options are not inline on the border or outline of the
box... we want the footer to imitate the header, by being inline like a piece of
tape, but not overlapping the poster itself".

The header manages that with .tape-h{top:-11px} -- a fixed offset that works only
because its height is fixed. The footer's height is not: it carries two to four
controls plus a select and grows with translated labels, so the old
margin-top:-14px left it hanging BELOW the edge rather than sitting on it, and
any height change moved it again. translate(-50%,-50%) at top:100% centres it on
the bottom border at ANY height, which is the same piece of tape the header
achieves and is self-correcting when a locale makes it taller.

MEASURED on a rendered card: the header's centre sits 1.0px from the card's top
edge (height 22.0) and the footer's centre is now -1.0px from the bottom edge
(height 30.0) -- tape on the border, mirroring the header. It also stays well
clear of the artwork, footer top 800.1 against a preview bottom of 557.5, which
is the rest of the Driver's rule: half the tape overlaps the card and half hangs
below, so the overlap grows only half as fast as the tape does.

Per row, also Driver: minimum 2, maximum 5, default 2, "and it needs to honour
local storage so if you change the default number it is saved in local storage
so you can reload and your default you set is persistent". Choices are now
2..5, the default is 2, and the chosen value is stored under one key for the
whole wall rather than per instance -- a preference that only survives on the
page you set it on is not a preference. A stored value outranks the `columns`
prop, because the prop is only what the page suggests before the reader has
said otherwise. Every localStorage access is wrapped: it throws outright in a
private window or with site data blocked, and a preference must never be able
to break the wall.
2026-09-25 05:15:58 +00:00
doxa-maps-88655c70
d989d598f1 Rebuild the plugin studio bundle: right-to-left, and the map unmount guard
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
Built from 7eaa4012 (studio right-to-left in Arabic) on top of 0c1a91cd
(useMapInstance unmount guard, which the studio compiles in too).
Rebuilt that one bundle and re-baked its SRI; check:sri passes.
2026-09-25 05:14:21 +00:00
doxa-maps-88655c70
4d773d6ee8 Move internal files out of the repo; fix five dead links; a fuller delegation diagram
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
Moved out (kept outside the repo, in the team's internal tracker):
- AGENT-BRIEF.md: operating rules for the team's own agents
- documentation/slide-deck-outline.md, documentation/README-longform.md:
  internal pitch material; the README and why.md cover the same ground
- plugin-designs/gospel-resources/SOURCES-CHECKED-AND-REJECTED.md: research log
- .claude/ (an editor status line), .forgejo/ (a CI workflow that never ran),
  _archive/ (a retired staging page; already gitignored but still tracked)
Seven code comments that named these files now describe the rule instead.

Fixed five dead links left from the docs/ -> documentation/ move, including
the one in template-bundle that every new plugin inherits.

The delegation diagram now shows the whole model: the Plugin Studio with the
shared library and the merge queue into main, seven production plugins with
capability badges and the Experimental shelf, one agent per plugin (a roaming
agent for the shelf), the shepherd's oversight ring, a legend, and the five
ways a build ships.
2026-09-25 05:14:10 +00:00
doxa-maps-88655c70
7eaa4012c1 Plugin studio: right-to-left in Arabic
Some checks failed
build-gate / build (push) Has been cancelled
rega's :dir(rtl) mirror for VerticalTabsLayout (5e7f73d0) compiled into
the studio, but nothing set the direction, so the studio stayed
left-to-right in Arabic. The studio now sets dir from the language
list's own dir flag, as doxa-maps-spa does.

The Explorer tree's own CSS assumed left-to-right: indentation, indent
guides, the active-row bar, the part count and the slim-rail activity
icons used left/right properties. They now use logical properties
(padding-inline, inset-inline-start, border-inline-start,
margin-inline-start), so they mirror, and a closed twisty points toward
the start of the line.

Checked at 1280x900: in Arabic the rail sits on the right, the active
bar on its right edge, the guides on the right, and doxa-simple-map
still renders its map; in English the geometry is unchanged (rail 0..256,
stage from 268).
2026-09-25 05:13:40 +00:00
doxa-maps-88655c70
0d846c3a1e Merge remote-tracking branch 'origin/main' into rega/research-gallery-embed
Some checks are pending
build-gate / build (push) Waiting to run
2026-09-25 05:09:14 +00:00
doxa-maps-88655c70
9e43332aad EMBED.md: lead with the picture and an at-a-glance table
The embed guide opened with prose and a code block. It now leads with the
existing screenshot of the gallery embedded by script on a partner page,
then a two-column table (script vs iframe): what to paste, sizing,
language, deep link, keyless maps, and what the server must send. Every
row is behaviour measured this session. Then it names the seven
production maps in their sections.
2026-09-25 05:09:09 +00:00
doxa-maps-88655c70
66750a59db The table the map is for: what each Doxa group can read, watch or hear
Some checks are pending
build-gate / build (push) Waiting to run
The Driver's question, in their words, is which of THEIR people groups have
gospel resources and which do not. Every tab here answered it for the research
corpus — 12,379 groups across 4,231 languages — which is the right scope for
finding what exists and the wrong one for working a list of 2,107. This one is
one row per group on Doxa's roster, it leads the tabs, and it exports.

The access ladder says what a person can DO, because that is what decides what
you send: read and watch 785 · watch or hear but cannot read 698 · read 53 ·
stories only 5 · nothing found 281. The second rung is the translation brief —
those groups can already receive the gospel and cannot yet study it, so the
first believers among them cannot be trained from a text that does not exist.

NO LANGUAGE CODE IS ITS OWN RUNG. The first run collapsed it into "nothing
found" and reported 566, when 281 had been searched and come back empty and 285
had never been searchable at all — no ISO 639-3, so no pool has a key to look
them up by. That would have told a mobiliser 285 peoples have no gospel in their
language when the truth is nobody has been able to ask. It is an identification
problem before it is a translation one.

CSV carries the filter and the roster: the whole table exports 2,107 rows, China
exports 154, and German exports a header and nothing else because German is not
one of Doxa's groups.
2026-09-25 05:07:53 +00:00
doxa-maps-88655c70
ebaaa9cd75 Merge remote-tracking branch 'origin/main' into exp-shepherd/cities-dots 2026-09-25 05:06:14 +00:00
doxa-maps-88655c70
299eb24a14 Cities with Internet: red people-group dots that open the people-group panel
Driver: "cities with internet map should have red dots on the map to show me
where the people groups are." Every DOXA people group is now a dot over the
connectivity shading, using the pray-tools list that Prayer Progress draws. It
carries the slug the detail panel fetches by. The dots are #e11d48 with a white
ring so they read on the "under 25%" red countries too, and the legend gains a
"people group" row with the count.

Tapping a dot opens the same PeopleGroupDetail panel Prayer Progress uses, through
useSelectedPin and the shared LegendDesktop / LegendMobile wrappers: a card on
desktop, the bottom sheet on a phone. Tapping a country still opens its carriers.

Measured on a served built tree: 2,107 dots for 2,107 groups; a tapped dot opens
the panel with the group's data at 1280 and at 390, in English and in Arabic; the
Research Gallery tab shows the same 2,107.
2026-09-25 05:06:11 +00:00
doxa-maps-88655c70
0c1a91cd02 useMapInstance: a map unmounted mid-initialise returns quietly instead of throwing
Some checks are pending
build-gate / build (push) Waiting to run
initializeMap is async. If its component unmounts while it waits (a
studio tab switch, a composite swapping views), Vue nulls containerRef
and the next dereference threw "Cannot read properties of null (reading
'getRootNode')" from ensureEngineCSS. check:studio-all hit it about 1
run in 4 (gospel-dashboard); gospel-plugin found a second site one await
later (containerRef.value.clientWidth after the animation frame).

initializeMap now checks the ref after each of its three awaits and
returns silently when it is gone, and ensureEngineCSS returns on a null
element. An unmounted pane is normal, not an error, so nothing is
logged. The ref is the only liveness signal: requiring isConnected too
would silently stop maps that mount into a subtree before it is
attached.

Proof, deterministic in both directions:
- check:map-unmount-mid-init holds mapbox-gl.js, opens a map plugin in
  the studio, switches away (destroying the pane), then releases the
  script. Before: FAIL 2/2 runs (research-map, doxa-simple-map threw
  the production error). After: PASS 2/2 across research-map,
  gospel-dashboard and doxa-simple-map.
- check:map-unmount-race (gospel-plugin's browser-free test, adopted):
  the guarded ensureEngineCSS resolves; with the guard stripped it
  throws the exact message.
- No regression: check:studio-all passes 31/31, and 19 plugins still
  create a live map canvas, as before.

check:shared-reached now tracks this change with a regex marker (a
control-flow fix has no literal that survives minification). It
reports 12 consumer bundles still to rebuild. Verified: rebuilding
doxa-simple-map moves it to "carries it".
2026-09-25 05:01:13 +00:00
doxa-maps-88655c70
c5fb3fde83 Rebuild the Research Gallery against merged main and regenerate the tree
Some checks are pending
build-gate / build (push) Waiting to run
2026-09-25 04:59:47 +00:00
doxa-maps-88655c70
debb67338a Merge remote-tracking branch 'origin/main' into rega/research-gallery-embed
# Conflicts:
#	public/doxa-maps/index.html
2026-09-25 04:59:26 +00:00
doxa-maps-88655c70
c9d04a99f8 Research Gallery: translate the shared layout's own controls
The rail's visible "Collapse" button and the layout's four aria-labels
(Toggle list, Open the list of views, Expand list, Collapse list) stayed
English in every locale. They are the shared VerticalTabsLayout's defaults.
The gallery now passes them through the layout's `labels` contract (added
by studio in 814124b3), using studio's exact wording from studio.json, so
both shells name the same buttons the same way.

Measured on the served built tree: ar طي / zh 折叠 / ru Свернуть /
hi संक्षिप्त करें, with matching aria-labels; en unchanged. All 11 locales
carry the same 34 keys. check:gallery-embed: js 13, iframe 13,
neighbour 13, linked 4.
2026-09-25 04:59:22 +00:00
doxa-maps-88655c70
5db368f94c Place 98 more of Doxa's groups by reading the misses instead of guessing at them
Some checks are pending
build-gate / build (push) Waiting to run
383 of the roster had no coordinates — 18% of Doxa's people invisible on the map
and missing from every count on it. Reading why, rather than reaching for fuzzy
matching, one class turns out to be a spelling convention: the roster puts the
qualifier first and the pin dataset puts it last, around a comma.

  Acre Arara <-> Arara, Acre        Ashkuni Nuristani <-> Nuristani Ashkuni
  Banka Samogho <-> Samogho, Banka  Butuo Nosu <-> Nosu, Butuo

Same words, same country, different order. Matching on the sorted token set
absorbs exactly that: 94 recovered, plus 4 that only needed diacritics folded,
and every one resolved to a SINGLE pin inside its own country. Spot-checked
against the languages they landed on — Ashkuni Nuristani to Ashkun [ask] in
Afghanistan, Banka Samogho to Bankagooma [bxw] in Mali — and all 94 carry a
language code, so the resource join holds.

What it refuses is the point. Doxa lists Akha in Laos; the pins carry Akha
Jipea, Akha Jaweuy and Akha Piso — a parent against three sub-varieties, and
picking one would invent a language for a people. Doxa lists Akeu in China; the
nearest pin is Ake, a different language. Two candidates is a refusal, not a
coin toss. 285 still have no candidate at all and stay unplaced, because they
need a source this build does not have rather than a looser string match.

1,822 placed now. The gap grows 268 to 281, which is the join telling the truth.
2026-09-25 04:58:37 +00:00
doxa-maps-88655c70
3b0fe80d61 Regenerate the gallery index after taking main
Some checks are pending
build-gate / build (push) Waiting to run
2026-09-25 04:50:29 +00:00
doxa-maps-88655c70
c2e8d9afed Take main
# Conflicts:
#	public/doxa-maps/index.html
2026-09-25 04:50:21 +00:00