Commit graph

837 commits

Author SHA1 Message Date
Doxa Maps
f4833def5b Rebuild doxa-vision-card, 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-26 01:14:53 +00:00
Doxa Maps
8e49ec41d6 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps 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-26 00:52:04 +00:00
Doxa Maps
b5068166ac The theme toggle picks a style the running engine can load
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
The map booted correctly under ?provider=maplibre and then went blank
the first time a reader touched the light/dark toggle: handleToggleTheme
called setStyle with a hardcoded mapbox:// URL, which MapLibre cannot
load at all. The boot path two hundred lines below already did this
properly — resolveNamedStyle('paper', upgProvider) — so the file
disagreed with itself about how a style is chosen.

The registry names the same INTENT for both engines: 'paper' is light
(mapbox light-v11 / OpenFreeMap positron), 'ink' is dark (dark-v11 /
OpenFreeMap dark).

BEHAVIOUR-PRESERVING ON MAPBOX, and checkable rather than asserted:
resolveNamedStyle returns URLs byte-identical to the literals this
replaces — 'paper' -> light-v11, 'ink' -> dark-v11. Only the MapLibre
branch changes, from an unloadable URL to a real one.

⚠ A STRING-PRESENCE GREP CANNOT PROVE THIS LANDED, which is worth
recording because it nearly satisfied me. The built bundle already
contained openfreemap.org/styles/dark BEFORE the change — the registry
is compiled in for the boot path — so "is the MapLibre URL in the
bundle" answers yes either way. The falsifiable question is what the
CALL SITE references, and at the compiled layer:

  before  setStyle(f.value?"mapbox://…/dark-v11":"mapbox://…/light-v11")
  after   setStyle(f.value?vi("ink",s).style||"mapbox://…/dark-v11"
                          :vi("paper",s).style||"mapbox://…/light-v11")

where vi is the minified resolveNamedStyle(name, provider). Measured by
building both ways.

The `||` fallbacks keep the old literals as a last resort if a name ever
stops resolving, matching the boot path's own guard rather than
inventing a second policy.
2026-09-26 00:47:51 +00:00
Doxa Maps
c534781bac MapLibre region fills drew nothing: the worldview clause filtered out every feature
rega measured it by eye at b0cd3140 on the built tree: regions-mfe under
?provider=maplibre draws the basemap and 2,107 pins, the boundary geojson returns
200, and the fill layer holds 0 features. Mapbox draws 156. A filter that admits
nothing looks exactly like data that never arrived.

countryFilter() is two clauses ANDed. The ISO half was fine — the field bridge
three lines above it already copies iso3 -> iso_3166_1_alpha_3 onto every geojson
feature before setData, so one name is read everywhere. The WORLDVIEW half has no
bridge and cannot have one: it exists because the Mapbox tileset repeats a country
once per worldview and the highlight would otherwise draw two or three times over.
The geojson has no such duplication and carries no worldview property at all, so
both sides of the `any` were false on every feature and the `all` emptied the
layer. It is Mapbox-only, not something to translate, so MapLibre now gets the ISO
clause alone.

I NEARLY FIXED THE WRONG HALF. Reading the RAW geojson I saw { iso3, shapeGroup,
shapeName }, concluded the ISO key was wrong too, and branched it — adding a
second name for a fact the bridge already normalises. The bridge was three lines
above the filter I was editing. Reverted; the ISO clause is untouched.

Proven headless, fail-first, by EVALUATING both filters against the real 162
features with MapLibre's own parser after applying the bridge:
  OLD filter admits   0 / 162   <- rega's bug, reproduced without a browser
  NEW filter admits  14 / 14    <- every requested country
  Mapbox path unchanged: still 14/14, and still drops a duplicate worldview copy
The control asserts the OLD filter still admits 0, so the check reports when it
has stopped demonstrating the bug it was written for.

Needs eyes: rega to re-shoot row 13 on this sha.
2026-09-26 00:38:15 +00:00
Doxa Maps
4bb0dbed47 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-3/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-26 00:37:30 +00:00
Doxa Maps
e02f50ad41 Rebuild cities-internet key-cities country-posters, 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-26 00:34:05 +00:00
Doxa Maps
b0cd3140bd Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps 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-26 00:19:52 +00:00
Doxa Maps
0f839f1071 MapLibre: reading the projection threw, so a region dashboard never framed
Driver, on MapLibre: opening a region dashboard does not zoom to the region the
way Mapbox does. This is why.

fitTheirWay read `m.getProjection().name` OUTSIDE its try. The two engines
disagree about both halves of that API:
  Mapbox    getProjection() -> { name: 'globe' }    setProjection('mercator')
  MapLibre  getProjection() -> { type: 'globe' } | undefined
                                                  setProjection({ type: 'mercator' })
MEASURED in maplibre-gl@5's own source, which we load from jsDelivr:
Map.getProjection() returns `this.stylesheet?.projection`, and the OpenFreeMap
style we hand MapLibre declares no projection key at all — its top level is
version, sources, sprite, glyphs, layers. So getProjection() is UNDEFINED there
and `.name` threw a TypeError.

Because the read sat outside the try, the throw escaped fitTheirWay AND escaped
applySubject(), of which it is the last statement. The camera was never framed:
the map stayed wherever it was instead of flying to the region.

The read is now defensive and accepts both shapes, and the WRITE is
engine-correct: Mapbox takes the bare string, MapLibre reads e?.type, so handing
it a string would set undefined rather than fail loudly.

It was wrong in a second way worth recording: on a MapLibre style that DOES set
globe, the old read returned null and silently skipped the mercator correction
that exists to stop the fit pulling back. So it both crashed on one shape and
under-corrected on another.

Proven headless per the Playwright policy, with the old expression run against
the same stubs as the control: it THROWS TypeError on the real MapLibre shape and
returns null where it should see globe, while the new one returns 'globe',
'mercator', 'globe', null, null across the five engine shapes. A check that
cannot be shown to fail proves nothing, so the check fails if the old expression
ever stops throwing.

Needs eyes: MapLibre, region dashboard — does it now fly to the region.
2026-09-26 00:19:26 +00:00
Doxa Maps
15d9d47a05 Rebuild pplr-data-maps, 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-26 00:17:24 +00:00
Doxa Maps
2be2debe47 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-3/work 2026-09-26 00:16:45 +00:00
Doxa Maps
c5fbb24aba Gospel list: name the translator on the language rows too
The map sheet and both bridge panels say who produced the Scripture; the language
list was the one surface a reader can arrive at that still answered "where"
without "who". 757 of the 5,067 rows now carry the organisation and year beside
the language.

A name rather than a link, for the same reason as everywhere else: the doctrine
screen is an allowlist, and a publisher must not enter this map as a side effect
of a data refresh. Measured after the change — 16,963 links, unchanged, and not
one credit contains a URL.

It needs no catalogue entry because an organisation's name is the same in every
locale. That is also why it can sit beside the translated labels around it
without leaving a hole in them.
2026-09-26 00:16:22 +00:00
Doxa Maps
8dcd407e29 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps 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-26 00:10:55 +00:00
Doxa Maps
2070b0c6f1 Gospel leaves: one active-tab colour, and it is the house one
#10b981 is Tailwind emerald and is not in this product's palette. Worse, the four
gospel leaves did not agree with each other: the map's active mode button was
near-black while the list, the tables and the charts were emerald, so the same
control looked like two different controls depending on which tab you were on.

Light is now the house dark on white, dark is the house sage on near-black, and
all four leaves share it. Contrast measured rather than eyeballed, since this
cannot be checked in a browser here: 9.86:1 and 7.89:1, both well past AA for
12px bold. Sage with #3b463d text was the obvious pairing and was rejected at
4.20:1, under the 4.5 this size needs.

The chart COLOURS are deliberately untouched. They encode meaning — scripture,
film, found, nothing, unresolved — and have to stay distinguishable from each
other, which is a different constraint from matching a palette. Recolouring them
is a judgement about legibility and belongs in its own change with someone
looking at it.
2026-09-26 00:09:22 +00:00
Doxa Maps
7f707807d6 Merge remote-tracking branch 'origin/main' into rega/research-gallery-embed
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-26 00:05:06 +00:00
Doxa Maps
8f5bd5efb4 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-3/work 2026-09-25 23:57:06 +00:00
Doxa Maps
13e0e02c9d Rebuild the consumers main left stale (build owner, README rule 5)
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
check:composite-freshness found stale on main: none. Rebuilt, tree + SRI
regenerated; the landing precondition (fresh, one folder, SRI) passed in main-capture scan.
2026-09-25 23:49:02 +00:00
Doxa Maps
3ab1d7aad5 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-3/work 2026-09-25 23:41:23 +00:00
Doxa Maps
a8eb431c2f Merge remote-tracking branch 'origin/main' into rega/research-gallery-embed 2026-09-25 23:41:19 +00:00
Doxa Maps
f6571ed4ea Research Gallery: PPLR Data Maps and Wall of People Groups are named in all 11 languages
The two discovered Experimental tabs fell back to their English bundle titles in every
locale (Arabic rail: 'Pplr Data Maps', 'Wall Of People Groups'). Only doxa-maps-spa's own
bundle is rebuilt; its SRI refreshed in both manifests.
2026-09-25 23:41:17 +00:00
Doxa Maps
c97876b3da Gospel access: the translator's name travels with the exported row
The sheet names who translated the Scripture, and a team printing posters or
building QR codes exports the CSV and never opens the sheet. A lead that only
exists on screen is a lead that does not reach the people doing the work, so
"Translated by" and the year are columns now: 864 of the 2,107 rows carry a named
body across 33 organisations.

Left empty rather than filled where the catalogue names a licence instead of a
translator. The column says who to ask; "public domain" answers a different
question and would read as an answer to this one.

Two pools were considered and deliberately not attributed. Faith Comes By
Hearing puts the producer inside a free-text version name — "Okpe, Delta - Bible
Society of Nigeria" has it, "Malkus Mawyon" does not — and splitting on the dash
would invent an organisation for the rows that have none; its own API, which
would answer properly, needs credentials this build does not have. Door43's URL
owner IS authoritative but is frequently a catalogue or a language namespace
rather than a body, so "translated by Door43-Catalog" would be false for 116
entries. A name nobody can act on is worse than a blank.
2026-09-25 23:41:11 +00:00
Doxa Maps
d8a9811a4e Rebuild regions-dashboard after resolving artifact conflicts 2026-09-25 23:39:33 +00:00
Doxa Maps
9272f1f9b7 Gospel map: name the people who translated it
The brief asks for real leads — real translators, the real organisations that do
the work — and the map had only URLs. A mobiliser who finds a neighbouring
language already has Scripture wants to know who produced it, because that
organisation has the linguists, the relationships and very often a team already
in that country. The link answers where; this answers who to ask.

eBible publishes its catalogue with a copyright line on every row and the join is
exact: 964 of the 964 eBible links in this index match a catalogue row by
translation id, none unmatched. 929 resolve to a named body across 137
organisations — Wycliffe Bible Translators, The Word for the World, Biblica,
Pioneer Bible Translators, the Seed Company, World Bible Translation Center. It
shows on the group sheet and on both bridges, where "who do I ask about this
language" is the sharpest question on the page.

NAMES ONLY, NO NEW LINKS. The catalogue also carries each publisher's domain, and
shipping it would put hosts into this map that the doctrine screen has never
seen — the screen is an allowlist precisely so a new publisher cannot arrive as a
side effect of a data refresh. Measured after the change: 16,963 links scanned,
the same count as before, and not one credit contains a URL.

A licence is not a translator. 35 rows reduce to "public domain", which says how
the text may be used and nothing about who made it; answering "who to ask" with a
legal status would be worse than saying nothing, so those are dropped and counted
separately from the rows that have no catalogue entry at all.
2026-09-25 23:38:12 +00:00
Doxa Maps
6f66625e88 Map controls were unclickable: the scroll strips sat on top of them
Driver, on Mapbox: the region dashboard zooms and draws correctly, but zoom in,
zoom out and fullscreen cannot be pressed at all.

CAUSE. .map-scroll-edge is a 40px full-height strip down each side with
pointer-events:auto and z-index:2 — the affordance that lets a vertical drag
scroll the PAGE instead of panning the map. Both engines place their control
groups in the very corners those strips cover, and at equal z-index the element
later in the DOM wins. The strips are rendered after the map container, so they
covered every control.

The strips must keep their pointer events, or the scroll affordance dies with
them, so the controls are lifted above the strips instead of the strips being
made inert.

ALL FOUR CORNERS AND BOTH ENGINE PREFIXES, deliberately: the left strip covers
the two left corners exactly as the right covers the right, a control can sit in
any of them, and naming mapboxgl- and maplibregl- together is what makes this
survive a provider swap — which is the whole point of the provider prop.

Proven headless, per the new Playwright policy: the shipped bundle carries the
rule for both prefixes and the strips still carry
touch-action:pan-y;pointer-events:auto. Whether the buttons are now clickable is
a drawn behaviour and goes out as needs-eyes.

NOT LANDED YET — main is held for studio's freshness rebuild.
2026-09-25 23:37:52 +00:00
Doxa Maps
1008001ea5 Gospel map: publish a tier per language, so a language with no pin still has one
Gazan Arabs — 2,315,000 people, the second largest population this map draws —
was painted red as "nothing found" while the index held a Scripture Earth PDF and
a Zume course in South Levantine Arabic, and the access table beside it already
said "read". Because of that stale zero it was also the one group on the map
shown as having nothing AND no way in.

The cause is structural, not a typo. The tier existed only ON A PIN, and `codes`
is keyed from the resource pools while `pins` comes from the people-group
dataset, so a language can be fully researched and carry no pin at all: zero pins
speak ajp. With no tier to read, the map fell back to the roster's stored copy,
captured when that file was written and never refreshed since.

So the tier is computed for every code the index knows and published as `tiers`,
from one definition that also tiers the pins. The map reads it. It does not
re-derive a tier from the resource fields — that is the drift the surfaces gate
exists to stop, and a roster keeping its own copy is the same drift with extra
steps.

The gap is 369, not 370, and not one of them is left without a way in — so the
legend now says "every one of those 369" rather than "369 of those 369", which
read like a coincidence. Both halves still hold: every group has somewhere to
start, and none of them has the gospel in their own language.
2026-09-25 23:32:33 +00:00
Doxa Maps
eff0ee13c5 Rebuild the consumers main left stale (build owner, README rule 5)
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
check:composite-freshness found stale on main: all-people-groups
big-picture
cities-internet
country-posters
dashboard-plus-grid
demo-map
doxa-research-map
doxa-simple-map
key-cities
my-upg-100-list
people-groups-grid
pplr-data-maps
prayer-walk-planner
regions-dashboard
research-dashboard
research-map-plus-grid
template-bundle
upg-neighbor
wall-of-people-groups. Rebuilt, tree + SRI
regenerated; the landing precondition (fresh, one folder, SRI) passed in main-capture scan.
2026-09-25 23:31:56 +00:00
Doxa Maps
229921c94f Gospel map: the Arabian peninsula gets an Arabic bridge, not Urdu
Five countries fell back to the weak pins proxy, and Saudi Arabia fell back to
URDU. The reason is a join asking for a code no publisher uses: CLDR reports
Arabic (ara) at 100% of Saudi Arabia, 81% of Oman, 74% of Libya and 100% of
Kuwait, but ara is a MACROLANGUAGE and nothing is published under it — the
Scripture and the film sit under arb. Taiwan had the same shape: zho empty, the
resources under cmn. The five countries this hit are among the least reached on
earth, which is where a wrong bridge costs the most.

Resolved through SIL's own macrolanguage membership, never by name, reusing the
table already read for the related-variety note. Every one of the 1,175
candidates now comes from published language data and none from the proxy; 211
resolve through a macrolanguage.

The share keeps the name it was measured under. CLDR measured Arabic, not
Standard Arabic, so the sheet says Arabic is spoken by 100% of this country and
that Scripture and the JESUS Film are published in Standard Arabic. Claiming the
percentage for the variety would be a figure CLDR never produced.
2026-09-25 23:24:42 +00:00
Doxa Maps
58326f2d82 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-3/work
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
# Conflicts:
#	internal/check-gospel-rtl-shaping.mjs
2026-09-25 22:55:49 +00:00
Doxa Maps
5238c36573 Gospel map: the country gap list says where to start
The rows under "No resource found" carried a name, a language and a population
and nothing else, so the question a mobiliser opens a country to answer — what do
I do about these? — cost one click per group. 369 of the 370 groups with nothing
have a way in, and it was reachable only by opening each pin in turn. Mali's two
now read "way in: French"; Benin's one reads "way in: SUN (signed)".

Text rather than a link, and it could not be otherwise: these rows are button
drill-ins and HTML forbids an anchor inside a button — the parser hoists it out
and it stops being a link, which is why the rows that DO have resources are plain
containers instead. The row still opens the group sheet, and the sheet carries the
bridge's real links.

It names the bridge and claims nothing further. "Bambara" here does not say
Bambara reaches this group; that stays the local question the sheet spells out.
It turns a list of dead ends into a list with a first move against each one.
2026-09-25 22:49:05 +00:00
Doxa Maps
32a3bcf36a Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps 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 22:28:19 +00:00
Doxa Maps
ce42977c8e Rebuild the consumers main left stale (build owner, README rule 5)
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
check:composite-freshness found stale on main: all-people-groups
cities-internet
demo-map
doxa-research-map
doxa-simple-map
key-cities
people-groups-grid
pplr-data-maps
research-dashboard
template-bundle
upg-neighbor
wall-of-people-groups. Rebuilt, tree + SRI
regenerated; the landing precondition (fresh, one folder, SRI) passed in main-capture scan.
2026-09-25 22:22:51 +00:00
Doxa Maps
69d787cb15 Gospel map: say how many of the gap groups have somewhere to start
"Nothing found 370" is where the legend stopped, and it reads as a wall. Every
one of those groups but a single uncoded row now has somewhere to start — a
curated bridge, a language their own country actually speaks, or SUN for a Deaf
group — and none of it was visible without opening 370 pins one at a time.

It says "a possible way in", not "reached". A bridge has to be learnt, it is not
Scripture in their language, and the red dot means exactly what it meant before.
Counted in the same pass as the tier numbers, from the same rows, so the two can
never drift apart.

Also drops a link-pruning pass added earlier in this change and then removed. It
was written on the belief that 74 links recorded broken were still being served;
they are not — the builder has pruned them from the index for some time, and it
reports the count on every run. The measurement that looked alarming was a
verification record listing URLs that had already left the index. Nothing was
wrong, so nothing needed fixing, and a second implementation of a working rule is
worse than none.
2026-09-25 22:21:03 +00:00
Doxa Maps
216fa292d4 Pin popup: render the description their site renders, not a field that is 99% empty
Their CountryMap binds `description: p.imb_people_description ?? ''` and asks for
that field in PIN_FIELDS (master, :89 and :114). The doxa-maps-build branch this
repo's DX-life checkout is parked on still says location_description, and that is
what we cloned — I even kept it deliberately last commit, reasoning that "the
popup needs it", which was true of the branch and false of their site.

MEASURED against the prayer API over 2,107 people groups:
  non-empty location_description      35   (1%)   <- what our popup rendered
  non-empty imb_people_description  2107   (100%) <- what theirs renders
So this was not the wrong paragraph, it was NO paragraph: roughly 2,072 groups
opened a popup with a blank description where doxa.life shows prose.

Nothing caught it because the popup did open, with a name, population and
religion — my own pin probe asserts that a popup APPEARS, never that it says
anything. An element can be present and empty, and "it opened" is not "it is
right".

The verification queued behind this: _probe-popup-description-field.mjs clicks a
pin, reads the group's NAME out of the popup, asks the API for BOTH candidate
fields for that exact group, and asserts the popup contains
imb_people_description and NOT location_description — the second half is the
control, since "the popup has a description" passes with either field. It reports
UNPROVEN when the two fields happen to be equal for that group. Browser slots
have been saturated for fifteen minutes, so what is proven here is the data path:
the shipped bundle requests imb_people_description, carries no
location_description at all, and the two fields demonstrably differ in the API.

Built only regions-dashboard.
2026-09-25 22:15:36 +00:00
doxa-maps-88655c70
2b3d0a6c35 Rebuild regions-dashboard after resolving artifact conflicts
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 21:48:25 +00:00
doxa-maps-88655c70
dcdb23d773 Stop cloning a hidden element DX-life's master has deleted
The shared root-dx-life checkout is parked on doxa-maps-build (9305706, Sept 17),
not DX-life's master (fc4d622, today) — so every file I have read for a RULE 1
port came from a divergent branch, not only the translated strings.

I checked the nine sources I had ported from. Six are identical on master, and
the three that differ are identical in the exact rules I relied on: the uupg
country-and-bloc markup line I matched this morning, the whole .country-map
block, and the .uupg__card 576px reflow. So the clone conclusions hold.

One thing did not. That branch renders <p class="uupg__content"> with
location_description and then hides it with display:none; master has removed the
markup, the rule and the field. We had cloned the hidden version faithfully,
which meant asking the API for location_description on every list request purely
to fill an element nobody can see. All three are gone here too.

The pin POPUP still needs that field and still asks for it — that is
region-dashboards.vue's own FIELDS (:176), a different request, and their
CountryMap really does render it. It is not a search key either
(SEARCH_KEYS is their list verbatim), so nothing else was reading it.

Nothing visible changed, and that is the point: the census still measures 42
strings against their 42 on the country page, 0 unaccounted, 0 omissions.
check:sri PASS. Built only regions-dashboard.

_qa-cycle/02-builder-cycle/dxlife.sh now reads DX-life from github/master via
git show, never from the shared working tree, and exits 75 NOT MEASURED if it
cannot resolve master rather than silently falling back to the stale one.
2026-09-25 21:44:20 +00:00
doxa-maps-88655c70
13f5f3a3a2 Rebuild the Prayer Walk Planner: main carried a bundle its source no longer builds
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
A library change merged into main reached the planner without a rebuild (main's own source
builds 0042dda2..., main committed 0b695f70...). Only the planner is rebuilt (its owner);
its SRI is refreshed in the manifest AND the gallery's cross-origin manifest copy, which
fix:sri alone leaves behind.
2026-09-25 21:42:40 +00:00
doxa-maps-88655c70
d38488d799 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-3/work
# Conflicts:
#	internal/check-gospel-rtl-shaping.mjs
#	public/dx-maps/assets/tables/country-languages.json
#	public/dx-maps/doxa-maps-spa/manifest.json
#	public/dx-maps/gospel-resources/charts/index.html
#	public/dx-maps/gospel-resources/data-tables/index.html
#	public/dx-maps/gospel-resources/gospel-dashboard/index.html
#	public/dx-maps/gospel-resources/gospel-resources.js
#	public/dx-maps/gospel-resources/resources-list/index.html
#	public/dx-maps/gospel-resources/resources-map/index.html
#	public/dx-maps/manifest.json
2026-09-25 21:38:20 +00:00
doxa-maps-88655c70
56dffd1af8 Gospel map: ask what the country speaks, not what the unreached speak
The bridge candidate — the "possibly a way in" offered to a group with nothing —
was chosen from Doxa's own pins: the biggest language among the UNREACHED groups
in that country that has Scripture and the film. That is not the language a
community shares with its neighbours. For Syenara Senufo in Mali it proposed
Minianka, one people group. Mali's vehicular language is Bambara.

The number beside it was worse than the pick. "8.8% of this country's mapped
population" is a share of Doxa's unreached pins, and a reader takes a percentage
for a share of the country. A percentage measured against a denominator nobody
can see is not a caveat, it is a wrong number.

CLDR publishes what each territory speaks and by what share, joined to ISO 639-3
through SIL's own Part1 column, and pinned rather than tracked from a moving
branch. 1,161 of 1,175 candidates now come from it; the remaining 14 keep the old
proxy and say on the row that their count is of this map's groups and not of the
country. Mali now reads French at 46% and official.

Where two languages are within five points the map names BOTH and says it will
not choose. Mali is exactly that: French 46% and official, Bambara 46% and not —
one is the administrative language and the other is what people share in a
market, and which bridges better depends on whether you are handing over a
booklet or starting a conversation. A tie-break would have quietly answered a
question nobody asked it. Both carry their own links, for the same reason the
first one does.

Two field lists were a field short, the same shape twice. The candidate filter
and the link resolver both read c.s for "has a readable Scripture" and forgot
that Faith Comes By Hearing carries text on the audio record — which excluded
Bambara from Mali's candidates entirely, and then, once it was named, offered it
the film while a full 66-book text sat one field away. There is now one
predicate.

The RTL gate read a hardcoded tree path. It reads the build config instead, and
was re-run against its baseline before the result was trusted.
2026-09-25 21:34:38 +00:00
doxa-maps-88655c70
d1af039ac4 Rebuild the consumers main left stale (build owner, README rule 5)
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
check:composite-freshness found stale on main: big-picture
country-posters
dashboard-plus-grid
gospel-resources
my-upg-100-list
research-map-plus-grid; also rebuilt: regions-dashboard. Rebuilt, tree + SRI
regenerated; the landing precondition (fresh, one folder, SRI) passed in main-capture scan.
2026-09-25 21:29:35 +00:00
doxa-maps-88655c70
7fd75a0965 Merge branch 'main' of https://git.nuxtbase.app/doxa-life/doxa-maps into bundler-1/work 2026-09-25 21:23:22 +00:00
doxa-maps-88655c70
bd75f609da Arabic: their people-group vocabulary, and the list leaf reads ?lang= too
Two defects, both invisible to an English diff because both sides were English.

1. THE LIST LEAF NEVER GOT THE ?lang= FIX. I repaired languageCode in
region-dashboards.vue and stopped; regions-list.vue has the same computed and the
same comment block describing the same defect, and it still read only props and
profile-config. So a shared /regions-list/?lang=ar link rendered "المناطق" as its
heading and then listed all 41 countries as "Angola", "Benin", "Cameroon".

2. OUR ARABIC WAS NOT THEIRS. Ten strings used vocabulary doxa.life does not use:
"مجموعة بشرية" where they say "مجموعة شعبية" for a people group, "مُخْدُومَة"
where they vowelise it "مَخْدُومَة", and for unengaged an invented
"غير مبشرة" / "الهدف هو القضاء على…" where they simply say "غير مَخْدُومَة".
Each replacement is a string read off their live /ar/ pages in this session, with
our placeholders re-inserted where their rendered page carried the values —
copied, not translated, which is what the brief asks for and what I can defend.

MEASURED, by the census in Arabic: 190 unaccounted additions and 8 omissions
before, 9 and 8 after the leaf fix, 0 and 0 after the vocabulary. The English
census reported a perfect clone throughout, which is exactly why the locale
dimension was worth running.

The sanctioned list now resolves through our own catalogue, so a permission
granted in English is the same permission in Arabic: "عرض ملصقات الدولة" is
recognised as the Driver's country-poster toggle instead of being reported as an
invention. Hardcoding its Arabic would only have moved the problem to zh.

Also repaired every probe URL for the dx-maps rename — 180 paths across 153 files
were still pointing at /doxa-maps/, which now 404s, so the whole measurement
apparatus was aimed at a tree that no longer exists. Replaced only the
slash-delimited segment, leaving doxa-maps-spa and the repo URL untouched, and
proved the repair by re-running the English census to its known-good baseline
before trusting anything else.

Built ONLY regions-dashboard (rule 5: studio owns the full build). This touches
library/i18n/locales/ar/regions.json, so other bundles need a consumer rebuild —
messaging studio with the sha.
2026-09-25 21:22:44 +00:00
doxa-maps-88655c70
9006a8eabd Merge main into bundler-2/work
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
# Conflicts:
#	public/dx-maps/index.html
2026-09-25 21:14:43 +00:00
doxa-maps-88655c70
d1f9264016 The dashboard's search header follows the engine it was given
It fetched the Mapbox geocoder from api.mapbox.com whatever the provider, and
never passed `provider` to the GeocoderComponent it mounts — so a partner who
chose MapLibre, the keyless engine picked precisely so that no Mapbox key and no
Mapbox traffic is involved, still sent every visitor's IP to Mapbox and still
got the Mapbox geocoder. It now resolves the provider through the usual ladder
and, under MapLibre, preloads nothing: GeocoderComponent already fetches the
MapLibre plugin itself, so the right amount of work here is none.

★ AND THIS DOES NOT FIX THE LEAK THAT WAS REPORTED, WHICH IS WORTH SAYING PLAINLY.
The audit named this file, and this file was wrong. But research-dashboard.vue:23
says in as many words that DashboardSearchHeader "remains available in the kit
but is not mounted here" — so nothing this dashboard renders was ever affected by
it. Measured on the built leaf at ?provider=maplibre, the four requests it makes
to api.mapbox.com are all tags in the GENERATED LEAF PAGE:

    mapbox-gl.css · mapbox-gl.js · mapbox-gl-geocoder.css · mapbox-gl-geocoder.min.js

The leaf ships Mapbox GL and the Mapbox geocoder to every visitor regardless of
the engine asked for. That belongs to the leaf generator, not to this plugin,
and it has gone to studio as a finding.

So what lands here is a component made correct for whoever mounts it, and a gate
that names the real cause. The gate is deliberately NOT in gates:post: it cannot
pass until the leaf stops shipping those four files, and a red gate about another
lane's file teaches everyone to ignore it. Run it by name.
2026-09-25 21:14:19 +00:00
doxa-maps-88655c70
a191bee38a Rebuild regions-dashboard after resolving artifact conflicts 2026-09-25 21:12:18 +00:00
doxa-maps-88655c70
bc4d1f54bd Arabic: their people-group vocabulary, and the list leaf reads ?lang= too
Two defects, both invisible to an English diff because both sides were English.

1. THE LIST LEAF NEVER GOT THE ?lang= FIX. I repaired languageCode in
region-dashboards.vue and stopped; regions-list.vue has the same computed and the
same comment block describing the same defect, and it still read only props and
profile-config. So a shared /regions-list/?lang=ar link rendered "المناطق" as its
heading and then listed all 41 countries as "Angola", "Benin", "Cameroon".

2. OUR ARABIC WAS NOT THEIRS. Ten strings used vocabulary doxa.life does not use:
"مجموعة بشرية" where they say "مجموعة شعبية" for a people group, "مُخْدُومَة"
where they vowelise it "مَخْدُومَة", and for unengaged an invented
"غير مبشرة" / "الهدف هو القضاء على…" where they simply say "غير مَخْدُومَة".
Each replacement is a string read off their live /ar/ pages in this session, with
our placeholders re-inserted where their rendered page carried the values —
copied, not translated, which is what the brief asks for and what I can defend.

MEASURED, by the census in Arabic: 190 unaccounted additions and 8 omissions
before, 9 and 8 after the leaf fix, 0 and 0 after the vocabulary. The English
census reported a perfect clone throughout, which is exactly why the locale
dimension was worth running.

The sanctioned list now resolves through our own catalogue, so a permission
granted in English is the same permission in Arabic: "عرض ملصقات الدولة" is
recognised as the Driver's country-poster toggle instead of being reported as an
invention. Hardcoding its Arabic would only have moved the problem to zh.

Also repaired every probe URL for the dx-maps rename — 180 paths across 153 files
were still pointing at /doxa-maps/, which now 404s, so the whole measurement
apparatus was aimed at a tree that no longer exists. Replaced only the
slash-delimited segment, leaving doxa-maps-spa and the repo URL untouched, and
proved the repair by re-running the English census to its known-good baseline
before trusting anything else.

Built ONLY regions-dashboard (rule 5: studio owns the full build). This touches
library/i18n/locales/ar/regions.json, so other bundles need a consumer rebuild —
messaging studio with the sha.
2026-09-25 21:11:38 +00:00
doxa-maps-88655c70
ca548b37ba Gospel map: the Deaf groups get their way in on the map, not only in the table
SUN reached the access table and the CSV first, and the map — the surface a
mobiliser actually opens — still showed Deaf groups a panel that explained their
situation honestly and then left them with nothing to do. That is the largest
population on this map with nothing: 93 groups, 17.5 million people, and
structurally so, because a spoken bridge cannot reach a Deaf community and there
was no other kind.

Clicking Deaf Beninese now offers the SUN New Testament, the SUN Bible stories
and the language itself, and says that SUN is already being taught in Benin by
Mission Évangélique des Sourds — a named local Deaf church rather than a
resource with nobody attached to it. It is offered only where the group has
nothing, because a group with Scripture in its own sign language does not need
to learn a second one, and it says on its face that it is a bridge which has to
be learnt and closes no gap in their own language.

Carried in the pin index beside the spoken bridges rather than fetched by the
leaf, so the sheet and the access table cannot disagree about what exists. It is
one small object, not a per-language join, because SUN is one signed language
for all of them.

The doctrine scan reads it too. Those URLs live in a new top-level block that the
per-language loop cannot see, so they were added to the scan in the same change
rather than found missing later, the way the access table was.
2026-09-25 21:00:44 +00:00
doxa-maps-88655c70
42b3105fed Rebuild the consumers main left stale (build owner, README rule 5)
Some checks are pending
Deploy to GitHub Pages / build (push) Waiting to run
Deploy to GitHub Pages / deploy (push) Blocked by required conditions
check:composite-freshness found stale on main: dashboard-plus-grid; also rebuilt: plugin-studio. Rebuilt, tree + SRI
regenerated; the landing precondition (fresh, one folder, SRI) passed in main-capture scan.
2026-09-25 20:49:01 +00:00
doxa-maps-88655c70
acb837ff02 Gospel charts: the titles and the counts inside them are translatable
The three chart titles, subtitles and axis units were the last inline English in
this leaf. The subtitles carry a count, so they are held whole in the catalogue
with a placeholder and the number arrives as a parameter — a sentence built by
gluing a number between two fragments cannot be translated, because word order
differs and several of these locales put the number where English does not.

The fallback interpolates too. Without that, a host that never installed i18n
would render the placeholder literally on screen, which is worse than the English
sentence the fallback exists to protect.

The leak gate could not have caught any of this. Whole-label equality is the
right unit for a fixed label and blind to a sentence carrying a number: the
catalogue holds "Across all {n} languages in the corpus." and the screen shows
"Across all 5,067 languages in the corpus." Those are never equal, so three
subtitles could have shipped untranslated in eleven locales with the gate
reporting PASS. A placeholder is now a wildcard and those keys are compared by
pattern; everything else stays equality, which is what keeps a word inside a
sentence from impersonating a label. Comparison went from 2,100 pairs to 2,244.
2026-09-25 20:39:19 +00:00
doxa-maps-88655c70
c53367f920 Merge main into bundler-2/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 20:31:17 +00:00
doxa-maps-88655c70
a9add45656 Rebuild every bundle after resolving artifact conflicts
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 20:21:29 +00:00
doxa-maps-88655c70
ee46ff0610 Merge main into bundler-2/work
# Conflicts:
#	public/dx-maps/dashboard-plus-grid/dashboard-plus-grid.js
#	public/dx-maps/dashboard-plus-grid/dashboard-plus-grid/default/index.html
#	public/dx-maps/dashboard-plus-grid/dashboard-plus-grid/index.html
#	public/dx-maps/doxa-maps-spa/manifest.json
#	public/dx-maps/manifest.json
2026-09-25 20:16:05 +00:00