Stop the country sheet calling 729 reached groups unreached

The country sheet split a country's groups into "with resources" and
"no resource found" using its own hand-listed field set, which never
learned about Scripture Earth or GRN. Measured: 729 people groups —
77.9 million people — were filed under "no resource found" while this
same map's pin sheet offered them a working link. Chad alone had 107
groups with something and showed fewer.

It now reads the tier the pin index computed, carried onto the mapped
row. Chad reports 150 groups, 107 with a resource, 43 without, which
is what the tier says.

This is the FOURTH time this bundle has re-derived that decision
somewhere, and the gate written for it missed this one: the gate
looked for negated c.* fields on a line naming "none", and this was a
positive predicate named hasAny over the mapped row.

Widening it took three attempts and the first two were worse than the
bug. "Three OR-ed resource fields" flags canHear(), which ORs media
precisely because it must exclude text. "Spans text and media" flags
`!!c.s || !!(c.au && /text/…)`, because c.au is text or audio
depending on a qualifier and a `|| ''` default inflates the operator
count. Both were confident false findings — the failure this repo has
now met in a forced token, a swallowed flag and a class extractor, and
a gate that cries wolf gets switched off.

So it asks one question it can actually answer: a predicate NAMED for
"has anything" is deciding the tier by definition and must read it.
Verified against the real pre-fix line, not a synthetic one.
This commit is contained in:
doxa-maps-88655c70 2026-09-24 22:10:03 +00:00
parent 0d394e9924
commit de3b34beb5
10 changed files with 66 additions and 26 deletions

View file

@ -34,14 +34,45 @@ const POISON = process.argv.includes('--poison')
const FIELD = String.raw`!\s*c\.(?:s|f|au|bv|se|ga|z|gp|d)\b[^\n]{0,40}`
const HANDROLLED = new RegExp(`${FIELD}&&\\s*${FIELD}&&\\s*${FIELD}`)
/**
* THE SECOND SHAPE, and the one that got through. The first pattern only caught NEGATED c.*
* fields joined by &&. The country sheet wrote the positive form over the MAPPED row —
* `const hasAny = (r) => !!(r.scripture_url || r.film_url || r.audio || ...)` — so neither
* the keyword filter nor the field pattern saw it. It was stale by 729 groups and 77.9
* million people before this caught it.
*
* WHY THIS IS A NAME RULE AND NOT A CLEVERER PATTERN. Two broader patterns were tried first
* and BOTH produced confident false findings on honest code: "three OR-ed resource fields"
* flags canHear(), which ORs media precisely because it must EXCLUDE text; "spans text and
* media" flags `!!c.s || !!(c.au && /text/…)`, because c.au is text OR audio depending on a
* qualifier, and a `|| ''` default inflates the operator count. A detector that cannot see
* how the expression is constructed reports the wrong thing confidently — the same failure
* this repo has now met in a forced token, a swallowed flag and a class extractor.
*
* So this asks one narrow question it can actually answer: a predicate NAMED for "has
* anything" is deciding the tier by definition, and must read it. Narrow and true beats
* broad and wrong.
*/
const ANYTHING_PREDICATE = /\b(?:hasAny|hasAnything|hasResources|hasRes|anyResource)\b/
function offendersIn(src, label) {
const out = []
const lines = src.split('\n')
for (let i = 0; i < lines.length; i++) {
const line = lines[i]
/* Only lines that are actually deciding emptiness, not e.g. a render guard. */
if (!/\bnone\b|\bgap\b|\bnothing\b|hasNothing/.test(line)) continue
if (HANDROLLED.test(line)) out.push(`${label}:${i + 1} ${line.trim().slice(0, 90)}`)
const namesEmptiness = /\bnone\b|\bgap\b|\bnothing\b|hasNothing/.test(line)
if (namesEmptiness && HANDROLLED.test(line)) {
out.push(`${label}:${i + 1} ${line.trim().slice(0, 90)}`)
continue
}
/* A predicate named for "has anything" IS the tier question; it must read the tier.
Only its DEFINITION is judged — call sites mention the name and decide nothing — and
`_tier` counts, since a mapped row carries it under that name. */
const defines = new RegExp(`(?:const|let|function)\\s+${ANYTHING_PREDICATE.source}`).test(line)
if (defines && !/_?\btier\b|\b_tier\b/.test(line)) {
out.push(`${label}:${i + 1} ${line.trim().slice(0, 90)}`)
}
}
return out
}
@ -53,8 +84,11 @@ if (!surfaces.length) {
}
if (POISON) {
/* Both real shapes, so the self-test proves the check against the two defects it exists
for rather than one — the second is the line that actually got through. */
const INJECT =
' none: !c.s && !c.f && !c.au && !c.bv && !c.z && !(c.d && c.d.length),'
' none: !c.s && !c.f && !c.au && !c.bv && !c.z && !(c.d && c.d.length),\n' +
' const hasAny = (r) => !!(r.scripture_url || r.film_url || r.audio || r.bible_video)'
let caught = 0
for (const f of surfaces) {
const poisoned = `${readFileSync(resolve(DIR, f), 'utf8')}\n${INJECT}\n`

View file

@ -534,6 +534,8 @@ function groupAt(i) {
const c = pinCodes.value[r[4]] || {}
return {
_i: i,
// The tier the pin index computed, carried so no consumer re-derives "has anything".
_tier: r[6],
people_group: r[0],
language: c.l || '',
iso639_3: r[4] || '',
@ -566,8 +568,12 @@ function groupAt(i) {
// scripture/film/door43, 559 people groups covering 61M people were filed under "No
// resource found" in the country view while their own pin sheet showed a live audio
// Scripture link — one map contradicting itself depending on which way you opened it.
const hasAny = (r) => !!(r.scripture_url || r.film_url || r.audio || r.bible_video || r.zume_url ||
(r.door43 && r.door43.length))
// READ THE TIER. This listed the resource fields by hand and went stale every time a source
// was added — the FOURTH time this shape has appeared in this bundle. Measured before the
// fix: 729 groups, 77.9 million people, were filed under "no resources found" in the country
// sheet while the pin sheet offered them a working link, because Scripture Earth and GRN
// were missing from the list. The pin index already decides this and a gate guards it.
const hasAny = (r) => r._tier !== 0
// Resources first — a standing decision, not a default — then largest population inside
// each block.

View file

@ -26,7 +26,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -26,7 +26,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -40,7 +40,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -26,7 +26,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

View file

@ -29,7 +29,7 @@
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
<!-- Bundle IIFE — registers the <gospel-resources-map> custom element. -->
<script src="../gospel-resources.js" integrity="sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL" crossorigin="anonymous"></script>
<script src="../gospel-resources.js" integrity="sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY" crossorigin="anonymous"></script>
<script>
// Mapbox token resolution — the A3 ladder, in precedence order:

File diff suppressed because one or more lines are too long

View file

@ -596,7 +596,7 @@
"bundle": "gospel-resources",
"scriptUrl": "./gospel-resources/gospel-resources.js",
"output": "doxa-maps/gospel-resources/gospel-resources.js",
"integrity": "sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL",
"integrity": "sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY",
"elements": [
"gospel-resources-map"
],
@ -616,7 +616,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/charts/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"charts\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -630,7 +630,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/data-tables/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"data-tables\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -644,7 +644,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/gospel-dashboard/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"gospel-dashboard\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -658,7 +658,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-list/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-list\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
},
{
@ -672,7 +672,7 @@
"scriptUrl": "./gospel-resources/gospel-resources.js",
"embed": {
"iframe": "<iframe src=\"./gospel-resources/resources-map/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-tGmkizI0wLvGvK/ymOr0w5iXns+os1816InhYBq+759yZd9GZCzYLIgIGTmItyXL\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-resources/gospel-resources.js\" integrity=\"sha384-Efc6hgd36i6v0HtBZX+Y8Arw4U+rasZP7JTnS4Hnt1s8MMKLF3Ds3uLjWLy+z0FY\" crossorigin=\"anonymous\"></script>\n<gospel-resources-map profile-config='{\"profile\":\"resources-map\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-resources-map>"
}
}
]