Check the shipped answer, not the code that wrote it

The same drift has now appeared six times, each spelled differently:
negated fields on a line naming "none", a positive hasAny over a
mapped row, a predicate inside a build script, and — found this tick —
a pair of columns no pass had ever touched. A source-level pattern has
to guess how the next one will be written.

Clause N does not guess. It compares the shipped ANSWER against the
pin tier, so it catches the seventh however it is phrased. Measured
when written: people-group-resources.any_resource_found disagreed with
the tier on 194 rows, and its no_resource_found pair contradicted
ITSELF on 7 more, because neither column was in the refresh at all.
Both now move together, 195 and 202 corrected, and the table agrees
with the tier on all 2,103 judgeable rows.

A code with no pin is SKIPPED, not guessed. The tier lives on pins, so
an unpinned code cannot be judged this way — judging it anyway
reported ajp as a defect on the first run, when the row was right and
the check was wrong. That is the failure this repo keeps meeting, so
it is written into the clause rather than left as a comment.

Also corrected there: the table's own note still told readers GRN
answers 403 to every request and had never been searched.
This commit is contained in:
doxa-maps-88655c70 2026-09-24 22:24:24 +00:00
parent 337a1a863b
commit cc3ab8b822
4 changed files with 851 additions and 798 deletions

File diff suppressed because it is too large Load diff

View file

@ -54,6 +54,7 @@ import { fileURLToPath } from 'node:url'
const REPO = resolve(dirname(fileURLToPath(import.meta.url)), '..')
const POISON = process.argv.includes('--poison')
let poisonStale = false
let poisonTable = false
const read = (p) => JSON.parse(readFileSync(resolve(REPO, p), 'utf8'))
let pins, table, verif
@ -91,6 +92,7 @@ if (POISON) {
codes.zzk = { l: 'Ships a known-dead link', f: 'https://jesusfilm.org/watch/jesus/4101' } // K
poisonStale = true // L
codes.zzm = { l: 'Claims a pool nobody swept for it', ck: 'ebible, grn', s: 'https://ebible.org/zzm/' } // M
poisonTable = true // N
}
const SPECIAL = (c) => c === 'und' || c === 'mul' || c === 'mis' || c === 'zxx' || (c >= 'qaa' && c <= 'qtz')
@ -291,13 +293,56 @@ if (verif && verif.links) {
}
}
/* ── N: a shipped table's "has anything" column agrees with the pin tier ─────────────────
THE COMPLEMENT TO THE SOURCE-LEVEL GATE, and the reason it exists: the same drift has now
appeared SIX times, each spelled differently — negated fields on a "none" line, a positive
hasAny over a mapped row, a predicate in a build script, a column nobody refreshed at all.
A source pattern has to guess how the next one will be written. This does not: it compares
the shipped ANSWER against the tier, so it catches the seventh however it is phrased.
Measured when written: people-group-resources.any_resource_found disagreed on 194 rows and
its no_resource_found pair contradicted ITSELF on 7 more, because no pass had ever touched
either column.
A code with no pin is SKIPPED, not guessed. The tier lives on pins, so an unpinned code
cannot be judged this way — judging it anyway produced a false finding on `ajp` the first
time this was run, which is the failure mode this repo keeps meeting. */
{
const hasPin = new Set()
const reached = new Set()
for (const r of rows) {
if (!r[4]) continue
hasPin.add(r[4])
if (r[6] !== 0) reached.add(r[4])
}
const TABLES = [
['gaps-and-opportunities', 'heart_iso639_3', 'heart_has_any'],
['people-group-resources', 'iso639_3', 'any_resource_found'],
['deaf-gap', 'iso639_3', 'has_any_resource'],
]
for (const [file, codeKey, anyKey] of TABLES) {
let t
try { t = read(`data/tables/${file}.json`) } catch { continue }
const off = []
for (const r of t.rows || []) {
const c = r[codeKey]
if (!c || !(c in codes) || !hasPin.has(c)) continue
const said = poisonTable ? !(r[anyKey] === true) : r[anyKey] === true
if (said !== reached.has(c)) off.push(c)
}
if (off.length) {
add('N', `${file}.${anyKey} disagrees with the pin tier on ${off.length} row(s) (e.g. ${off.slice(0, 3).join(', ')}) — rerun scripts/refresh-legacy-resource-flags.mjs`)
}
}
}
const clauses = new Set(fails.map((f) => f.slice(3, 4)))
if (POISON) {
// D is included deliberately: it is the clause that would have caught the 506
// resources dropped from a table titled "every link", and the most valuable clause is
// the worst one to leave unproven. The injected codes above (und, zzq) are absent from
// the table, so they poison D as well as A and B.
const want = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M']
const want = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']
const caught = want.filter((c) => clauses.has(c))
console.log(`COVERAGE-CONSISTENT --poison: ${caught.length}/${want.length} clause(s) caught their injected defect (${caught.join(',')})`)
if (caught.length !== want.length) {
@ -324,3 +369,4 @@ console.log(' I row type agrees with its host J approximate never reads as c
console.log(' K every shipped link is verified, and none known-broken ships')
console.log(' L the verification record is current, not merely consistent')
console.log(' M a pool named as checked was really searched for that code')
console.log(' N a table\'s has-anything column agrees with the pin tier')

View file

@ -111,8 +111,15 @@ const bump = (k) => { changed[k] = (changed[k] || 0) + 1 }
// THREE-STATE, never false. See the header.
const a = hasAudio(c) ? true : 'unknown'
if (r.has_audio !== a) { r.has_audio = a; bump('has_audio') }
// THE PAIR NOBODY WAS REFRESHING. These two columns say whether the group has anything
// at all, and no pass had ever touched them — so 194 rows still read
// any_resource_found=false for groups the index can now reach. They are a complementary
// pair and must move together, or the table contradicts itself row by row.
const any = hasAny(c)
if (r.any_resource_found !== any) { r.any_resource_found = any; bump('any_resource_found') }
if (r.no_resource_found !== !any) { r.no_resource_found = !any; bump('no_resource_found') }
}
j.meta = { ...(j.meta || {}), resource_flags_refreshed: new Date().toISOString().slice(0, 10), has_audio_note: 'true where Faith Comes By Hearing publishes audio Scripture; "unknown" otherwise, never false — GRN is the main audio pool and answers 403 to every request.' }
j.meta = { ...(j.meta || {}), resource_flags_refreshed: new Date().toISOString().slice(0, 10), has_audio_note: 'true where Faith Comes By Hearing publishes audio Scripture; "unknown" otherwise, never false. GRN is the other main audio pool and IS now searched, through their 5fish site, a batch at a time at the crawl delay they ask for — it appears as gospel audio rather than in this column, because Words of Life is gospel messages and Bible stories, not a translation.' }
writeSnapshot(resolve(REPO, 'data/tables/people-group-resources.json'), `${JSON.stringify(j, null, 1)}\n`,
(x) => (x.rows || []).length, 'people-group-resources rows')
}

File diff suppressed because it is too large Load diff