Correct the record: the dead bundle was my merge, not a duplicate import
dx-shepherd's verifier traced it. Merge 52ab6089 from this worktree committed
public/doxa-maps/gospel-resources/gospel-resources.js with 21 conflict markers —
both sides concatenated, 1.13 MB — and that is what threw "Identifier Ge has
already been declared" and killed every gospel leaf.
My diagnosis last commit was wrong. I blamed a module imported twice and
re-routed the import; that change was harmless but it was not the cause. The
REBUILD that came with it is what repaired the file. A plausible cause that a fix
appears to confirm is the easiest kind of wrong answer to believe.
THE ACTUAL CAUSE IS A LANDING SCRIPT I WROTE. On a conflict it resolves the one
file it expects — public/doxa-maps/index.html — and then runs "git add -A
public", which stages every OTHER file under public/ including the ones still
holding markers. One line of convenience turning a conflict git correctly refused
to guess at into a committed artefact.
So: a check that names the real condition. It scans every tracked file for an
unresolved marker, is built from character codes so it can never trip itself, and
carries a poison arm. It runs FIRST in check:gospel-all, because there is no
point measuring anything else about a tree that is mid-merge.
Also verifies the 8 links the GRN recheck recovered, which check:gospel-all
caught as shipped-but-unverified on its very first run — psi, alk, nos, jle, lma
and three more, all now confirmed landing on their own 5fish language pages.
This commit is contained in:
parent
beb13da3da
commit
59e9695aaa
7 changed files with 261 additions and 22 deletions
|
|
@ -4991,7 +4991,7 @@
|
|||
"religion": "Islam - Sunni",
|
||||
"population": 5500,
|
||||
"people_praying": 0,
|
||||
"people_committed": 0,
|
||||
"people_committed": 1,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -16751,7 +16751,7 @@
|
|||
"religion": "Islam - Sunni",
|
||||
"population": 57500,
|
||||
"people_praying": 2,
|
||||
"people_committed": 0,
|
||||
"people_committed": 1,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -34055,7 +34055,7 @@
|
|||
"religion": "Hinduism",
|
||||
"population": 700,
|
||||
"people_praying": 1,
|
||||
"people_committed": 2,
|
||||
"people_committed": 3,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -34319,7 +34319,7 @@
|
|||
"religion": "Islam - Folk",
|
||||
"population": 12000,
|
||||
"people_praying": 1,
|
||||
"people_committed": 4,
|
||||
"people_committed": 3,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -43463,7 +43463,7 @@
|
|||
"religion": "Islam - Sunni",
|
||||
"population": 23000,
|
||||
"people_praying": 0,
|
||||
"people_committed": 1,
|
||||
"people_committed": 2,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"meta": {
|
||||
"title": "Gospel resource link verification",
|
||||
"generated": "2026-09-25T03:43:08.467Z",
|
||||
"generated": "2026-09-25T09:56:59.860Z",
|
||||
"method": "HEAD, redirects followed. verified = HTTP 200. broken = 404/410. unknown = unreachable, an ambiguous status, or a URL shape that cannot be checked by fetch.",
|
||||
"scope": "Every URL in data/tables/people-group-pins.json, deduplicated.",
|
||||
"states": {
|
||||
|
|
@ -96,12 +96,12 @@
|
|||
]
|
||||
},
|
||||
"summary": {
|
||||
"records": 8516,
|
||||
"checkedThisPass": 3,
|
||||
"records": 8524,
|
||||
"checkedThisPass": 8,
|
||||
"carriedForward": 74,
|
||||
"pruned": 0,
|
||||
"broken": 74,
|
||||
"verified": 8437,
|
||||
"verified": 8445,
|
||||
"unknown": 5
|
||||
},
|
||||
"byHost": {
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
"verified": 921
|
||||
},
|
||||
"fivefish.org": {
|
||||
"verified": 1022
|
||||
"verified": 1030
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -42726,6 +42726,46 @@
|
|||
"state": "verified",
|
||||
"detail": "HTTP 200 (via https://www.jesusfilm.org/watch/the-savior.html/arabic-najdi.html)",
|
||||
"at": "2026-09-25T03:43:07.944Z"
|
||||
},
|
||||
"https://fivefish.org/lma": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/12954?language=Limba%2C%20East (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:55:49.572Z"
|
||||
},
|
||||
"https://fivefish.org/nev": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/23092?language=Nyaheun (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:55:59.632Z"
|
||||
},
|
||||
"https://fivefish.org/ngt": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/23045?language=Kriang (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:09.574Z"
|
||||
},
|
||||
"https://fivefish.org/alk": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/23050?language=Alak (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:19.687Z"
|
||||
},
|
||||
"https://fivefish.org/nos": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/4976?language=Nisu%2C%20Eastern (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:29.456Z"
|
||||
},
|
||||
"https://fivefish.org/lbo": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/12797?language=Laven (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:39.531Z"
|
||||
},
|
||||
"https://fivefish.org/jle": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/14912?language=Ngile (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:49.486Z"
|
||||
},
|
||||
"https://fivefish.org/psi": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/15537?language=Pashai%2C%20Southeast (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:59.503Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
86
internal/check-gospel-all.mjs
Normal file
86
internal/check-gospel-all.mjs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* check-gospel-all.mjs — everything this bundle owns, in one command.
|
||||
*
|
||||
* WHY THIS EXISTS. gospel-resources has ten gates of its own and every one of them was
|
||||
* hand-run. That is how a dead bundle shipped: a duplicate module killed all five leaves,
|
||||
* and the one gate I happened to run that day was pointed at the map. `check:no-orphan-gates`
|
||||
* was right that they were all reachable — reachable is not the same as run.
|
||||
*
|
||||
* It is NOT wired into gates:pre/post on purpose. Three of these need a browser, the shared
|
||||
* wave holds browser gates under load, and a bundle owner should not be able to slow every
|
||||
* other agent's build by adding to a list they do not own. This is the bundle's own front
|
||||
* door instead: one command, honest about what it could not measure.
|
||||
*
|
||||
* STATIC FIRST, THEN BROWSER. The static gates are sub-second and catch most drift, so they
|
||||
* run first and a failure there stops the run before a browser is launched — there is no
|
||||
* point spending a scarce browser slot to confirm a table is inconsistent.
|
||||
*
|
||||
* NOT MEASURED IS NOT PASS. A browser gate that cannot get a slot exits 75 and is reported
|
||||
* as NOT MEASURED, never folded into the pass. Anything else would turn a busy machine into
|
||||
* a green tick.
|
||||
*/
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import { resolve, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const HERE = dirname(fileURLToPath(import.meta.url))
|
||||
const REPO = resolve(HERE, '..')
|
||||
const SLOT = resolve(HERE, 'browser-slot.sh')
|
||||
|
||||
const STATIC = [
|
||||
['check:no-conflict-markers', 'nothing tracked is mid-merge'],
|
||||
['check:no-conflict-markers:poison', '...and that check can fail'],
|
||||
['check:coverage-consistent', 'the surfaces agree about who has what'],
|
||||
['check:coverage-consistent:poison', '...and that check can fail'],
|
||||
['check:surfaces-read-the-tier', 'one place decides "this group has nothing"'],
|
||||
['check:stale-sweep-claim', 'no caveat outliving its truth'],
|
||||
['check:click-sheet', 'the country sheet resolves, links are absolute'],
|
||||
['check:snapshot-guard', 'no fetcher writes around the guard'],
|
||||
]
|
||||
const BROWSER = [
|
||||
['check:leaves-mount', 'all five leaves actually mount'],
|
||||
['check:leaves-mount:poison', '...and that check can fail'],
|
||||
['check:composed-filters', 'the composite filters instead of navigating'],
|
||||
]
|
||||
|
||||
const run = (script, viaSlot) => {
|
||||
const cmd = viaSlot ? SLOT : 'bun'
|
||||
const args = viaSlot ? ['bun', 'run', script] : ['run', script]
|
||||
const r = spawnSync(cmd, args, { cwd: REPO, encoding: 'utf8' })
|
||||
return { code: r.status ?? 1, out: `${r.stdout || ''}${r.stderr || ''}` }
|
||||
}
|
||||
|
||||
const failed = []
|
||||
const notMeasured = []
|
||||
let passed = 0
|
||||
|
||||
for (const [script, what] of STATIC) {
|
||||
const r = run(script, false)
|
||||
if (r.code === 0) { passed++; console.log(` ok ${script.padEnd(34)} ${what}`) }
|
||||
else { failed.push([script, r.out.trim().split('\n').slice(-3).join(' | ')]); console.log(` FAIL ${script.padEnd(34)} ${what}`) }
|
||||
}
|
||||
if (failed.length) {
|
||||
console.error(`\nGOSPEL-ALL: FAIL — ${failed.length} static gate(s); not launching a browser to confirm it.`)
|
||||
for (const [s, tail] of failed) console.error(` ${s}: ${tail}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
for (const [script, what] of BROWSER) {
|
||||
const r = run(script, true)
|
||||
if (r.code === 0) { passed++; console.log(` ok ${script.padEnd(34)} ${what}`) }
|
||||
else if (r.code === 75) { notMeasured.push(script); console.log(` -- ${script.padEnd(34)} NOT MEASURED (no browser slot)`) }
|
||||
else { failed.push([script, r.out.trim().split('\n').slice(-3).join(' | ')]); console.log(` FAIL ${script.padEnd(34)} ${what}`) }
|
||||
}
|
||||
|
||||
console.log('')
|
||||
if (failed.length) {
|
||||
console.error(`GOSPEL-ALL: FAIL — ${failed.length} gate(s) red, ${passed} green, ${notMeasured.length} not measured.`)
|
||||
for (const [s, tail] of failed) console.error(` ${s}: ${tail}`)
|
||||
process.exit(1)
|
||||
}
|
||||
if (notMeasured.length) {
|
||||
console.log(`GOSPEL-ALL: INCOMPLETE — ${passed} green, ${notMeasured.length} NOT MEASURED (${notMeasured.join(', ')}).`)
|
||||
console.log(' Not a pass. Re-run when a browser slot is free.')
|
||||
process.exit(75)
|
||||
}
|
||||
console.log(`GOSPEL-ALL: PASS — ${passed} gate(s), static and browser.`)
|
||||
68
internal/check-no-conflict-markers.mjs
Normal file
68
internal/check-no-conflict-markers.mjs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* check-no-conflict-markers.mjs — nothing tracked may carry an unresolved merge.
|
||||
*
|
||||
* THE INCIDENT. A merge commit from this worktree landed the BUILT bundle
|
||||
* public/doxa-maps/gospel-resources/gospel-resources.js with 21 conflict markers in it —
|
||||
* both sides concatenated, 1.13 MB. The browser threw "Identifier Ge has already been
|
||||
* declared" and every gospel leaf rendered dead, while the SRI hash still matched, every
|
||||
* request still returned 200, and no probe could see an error.
|
||||
*
|
||||
* THE CAUSE WAS A LANDING SCRIPT, NOT A BAD MERGE. The loop resolved the one file it
|
||||
* expected to conflict and then ran `git add -A public`, which stages EVERY file under
|
||||
* public/ — including the ones still holding markers. A one-line convenience that turns a
|
||||
* conflict git correctly refused to guess at into a committed artefact.
|
||||
*
|
||||
* AND THE FIRST DIAGNOSIS WAS WRONG. I attributed the duplicate identifier to a module
|
||||
* imported twice and re-routed an import to "fix" it. That change was harmless but it was
|
||||
* not the cause; the rebuild that came with it is what repaired the file. A plausible cause
|
||||
* that a fix appears to confirm is the easiest kind of wrong answer, and the only defence is
|
||||
* a check that names the real condition.
|
||||
*
|
||||
* THE RULE, for a BUILT file especially: never hand-merge, never take both. Take either
|
||||
* side, REBUILD, commit the rebuild. Then run this before pushing.
|
||||
*/
|
||||
import { execSync } from 'node:child_process'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve, dirname } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const HERE = dirname(fileURLToPath(import.meta.url))
|
||||
const REPO = resolve(HERE, '..')
|
||||
const POISON = process.argv.includes('--poison')
|
||||
|
||||
/* Built from char codes so this file never contains a marker and never trips itself. */
|
||||
const OPEN = String.fromCharCode(60).repeat(7)
|
||||
const MID = String.fromCharCode(61).repeat(7)
|
||||
const CLOSE = String.fromCharCode(62).repeat(7)
|
||||
const MARKER = new RegExp('^(' + OPEN + '|' + MID + '$|' + CLOSE + ')', 'm')
|
||||
const scan = (text) => MARKER.test(text)
|
||||
|
||||
if (POISON) {
|
||||
const fake = 'a\n' + OPEN + ' HEAD\nmine\n' + MID + '\ntheirs\n' + CLOSE + ' other\n'
|
||||
if (!scan(fake)) {
|
||||
console.error('NO-CONFLICT-MARKERS: SELF-TEST FAIL — a textbook conflict was not detected.')
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('NO-CONFLICT-MARKERS: SELF-TEST PASS — a textbook conflict is detected.')
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const tracked = execSync('git ls-files -z', { cwd: REPO, maxBuffer: 1 << 28 })
|
||||
.toString('utf8').split(String.fromCharCode(0)).filter(Boolean)
|
||||
|
||||
const hits = []
|
||||
for (const f of tracked) {
|
||||
let text
|
||||
try { text = readFileSync(resolve(REPO, f), 'utf8') } catch { continue }
|
||||
if (text.indexOf(String.fromCharCode(0)) >= 0) continue
|
||||
if (scan(text)) hits.push(f)
|
||||
}
|
||||
|
||||
if (hits.length) {
|
||||
console.error('NO-CONFLICT-MARKERS: FAIL — ' + hits.length + ' tracked file(s) carry an unresolved merge:')
|
||||
for (const f of hits.slice(0, 10)) console.error(' ' + f)
|
||||
console.error(' For a BUILT file: take either side, REBUILD the bundle, commit the rebuild.')
|
||||
console.error(' Never "add -A" a directory mid-merge — it stages the markers with everything else.')
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('NO-CONFLICT-MARKERS: PASS — ' + tracked.length + ' tracked file(s), none mid-merge.')
|
||||
|
|
@ -197,7 +197,10 @@
|
|||
"app:start-page": "node internal/set-app-start-page.mjs",
|
||||
"check:app-start-page": "node internal/set-app-start-page.mjs --check",
|
||||
"check:leaves-mount": "node internal/check-gospel-leaves-mount.mjs",
|
||||
"check:leaves-mount:poison": "node internal/check-gospel-leaves-mount.mjs --poison"
|
||||
"check:leaves-mount:poison": "node internal/check-gospel-leaves-mount.mjs --poison",
|
||||
"check:gospel-all": "node internal/check-gospel-all.mjs",
|
||||
"check:no-conflict-markers": "node internal/check-no-conflict-markers.mjs",
|
||||
"check:no-conflict-markers:poison": "node internal/check-no-conflict-markers.mjs --poison"
|
||||
},
|
||||
"//scripts": {
|
||||
"_": "What each script does. These notes used to sit inside the command strings as trailing \"# …\" comments, which made the shell discard any arguments passed after \"--\" (so a gate given --url silently measured its hardcoded default port — possibly another agent's server). Keep notes here, never in a command.",
|
||||
|
|
@ -297,7 +300,9 @@
|
|||
"check:vision-card-numbers": "the DOXA Vision Card must show the numbers the DATA gives: independently recomputes all four funnel steps (and DOXA-in-frontier) from people_groups.csv + the saved DOXA list, compares with vision-funnel.json, and with --url also with the numbers painted in the card. A typed-in number, a stale funnel file or a rendering bug fails it.",
|
||||
"check:map-embed-cells": "PRODUCTION-MATRIX cells B (iframe) and C (script embed) for the seven Research Gallery maps on a genuinely foreign origin (tree on 127.0.0.1, partner page on localhost). C passes the HOST a distinct token and fails if any Mapbox request uses another. --only bundle/profile,… --cell B|C.",
|
||||
"check:gallery-embed:live-cors": "the Research Gallery on a foreign page under the LIVE static layer's CORS rule (Access-Control-Allow-Origin on files inside the tree's folders, NOT on the root manifest.json, measured on nuxtbase): it must still boot every tab, by reading the CORS-readable manifest copy generate-tree writes beside its bundle.",
|
||||
"check:leaves-mount": "DID THE ELEMENT ACTUALLY MOUNT, on all five gospel leaves. Exists because a ReferenceError thrown during setup dies INSIDE the custom-element boundary: the page loads, every asset returns 200, pageerror fires zero times, and the element sits there with an empty shadow root. A healthy-looking dead page. This asks the cheap unambiguous question the rich gates are too slow to ask on every leaf — is anything there — in five steps that each name their own failure: tag defined, host present, shadowRoot attached, shadow root non-empty, visible text rendered. It does NOT trust the absence of console errors; zero errors is not the same as working. --poison for the negative test."
|
||||
"check:leaves-mount": "DID THE ELEMENT ACTUALLY MOUNT, on all five gospel leaves. Exists because a ReferenceError thrown during setup dies INSIDE the custom-element boundary: the page loads, every asset returns 200, pageerror fires zero times, and the element sits there with an empty shadow root. A healthy-looking dead page. This asks the cheap unambiguous question the rich gates are too slow to ask on every leaf — is anything there — in five steps that each name their own failure: tag defined, host present, shadowRoot attached, shadow root non-empty, visible text rendered. It does NOT trust the absence of console errors; zero errors is not the same as working. --poison for the negative test.",
|
||||
"check:gospel-all": "EVERYTHING gospel-resources owns, in one command. Its ten gates were all hand-run, which is how a dead bundle shipped: a duplicate module killed all five leaves and the one gate run that day was pointed at the map. check:no-orphan-gates was right that they were reachable — reachable is not run. Deliberately NOT in gates:pre/post: three need a browser, the shared wave holds browser gates under load, and a bundle owner should not be able to slow everyone else's build by adding to a list they do not own. Static gates run first and stop the run on failure, so a scarce browser slot is never spent confirming a table is inconsistent. Exit 75 = NOT MEASURED, never folded into a pass.",
|
||||
"check:no-conflict-markers": "Nothing tracked may carry an unresolved merge. Exists because a merge from this worktree committed a BUILT bundle with 21 conflict markers - both sides concatenated, 1.13MB - and every gospel leaf rendered dead while the SRI hash matched and every request returned 200. The cause was a landing script that resolved one expected file then ran \"git add -A public\", staging every other file including the ones still holding markers. For a built file: take either side, REBUILD, commit the rebuild, then run this before pushing. --poison for the negative test."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/android": "^7.6.9",
|
||||
|
|
|
|||
|
|
@ -4991,7 +4991,7 @@
|
|||
"religion": "Islam - Sunni",
|
||||
"population": 5500,
|
||||
"people_praying": 0,
|
||||
"people_committed": 0,
|
||||
"people_committed": 1,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -16751,7 +16751,7 @@
|
|||
"religion": "Islam - Sunni",
|
||||
"population": 57500,
|
||||
"people_praying": 2,
|
||||
"people_committed": 0,
|
||||
"people_committed": 1,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -34055,7 +34055,7 @@
|
|||
"religion": "Hinduism",
|
||||
"population": 700,
|
||||
"people_praying": 1,
|
||||
"people_committed": 2,
|
||||
"people_committed": 3,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -34319,7 +34319,7 @@
|
|||
"religion": "Islam - Folk",
|
||||
"population": 12000,
|
||||
"people_praying": 1,
|
||||
"people_committed": 4,
|
||||
"people_committed": 3,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
@ -43463,7 +43463,7 @@
|
|||
"religion": "Islam - Sunni",
|
||||
"population": 23000,
|
||||
"people_praying": 0,
|
||||
"people_committed": 1,
|
||||
"people_committed": 2,
|
||||
"adopted_by_churches": 0,
|
||||
"mapped": true,
|
||||
"matched_by": "doxa detail",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"meta": {
|
||||
"title": "Gospel resource link verification",
|
||||
"generated": "2026-09-25T03:43:08.467Z",
|
||||
"generated": "2026-09-25T09:56:59.860Z",
|
||||
"method": "HEAD, redirects followed. verified = HTTP 200. broken = 404/410. unknown = unreachable, an ambiguous status, or a URL shape that cannot be checked by fetch.",
|
||||
"scope": "Every URL in data/tables/people-group-pins.json, deduplicated.",
|
||||
"states": {
|
||||
|
|
@ -96,12 +96,12 @@
|
|||
]
|
||||
},
|
||||
"summary": {
|
||||
"records": 8516,
|
||||
"checkedThisPass": 3,
|
||||
"records": 8524,
|
||||
"checkedThisPass": 8,
|
||||
"carriedForward": 74,
|
||||
"pruned": 0,
|
||||
"broken": 74,
|
||||
"verified": 8437,
|
||||
"verified": 8445,
|
||||
"unknown": 5
|
||||
},
|
||||
"byHost": {
|
||||
|
|
@ -142,7 +142,7 @@
|
|||
"verified": 921
|
||||
},
|
||||
"fivefish.org": {
|
||||
"verified": 1022
|
||||
"verified": 1030
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -42726,6 +42726,46 @@
|
|||
"state": "verified",
|
||||
"detail": "HTTP 200 (via https://www.jesusfilm.org/watch/the-savior.html/arabic-najdi.html)",
|
||||
"at": "2026-09-25T03:43:07.944Z"
|
||||
},
|
||||
"https://fivefish.org/lma": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/12954?language=Limba%2C%20East (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:55:49.572Z"
|
||||
},
|
||||
"https://fivefish.org/nev": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/23092?language=Nyaheun (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:55:59.632Z"
|
||||
},
|
||||
"https://fivefish.org/ngt": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/23045?language=Kriang (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:09.574Z"
|
||||
},
|
||||
"https://fivefish.org/alk": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/23050?language=Alak (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:19.687Z"
|
||||
},
|
||||
"https://fivefish.org/nos": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/4976?language=Nisu%2C%20Eastern (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:29.456Z"
|
||||
},
|
||||
"https://fivefish.org/lbo": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/12797?language=Laven (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:39.531Z"
|
||||
},
|
||||
"https://fivefish.org/jle": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/14912?language=Ngile (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:49.486Z"
|
||||
},
|
||||
"https://fivefish.org/psi": {
|
||||
"state": "verified",
|
||||
"detail": "5fish redirected to its language page https://fivefish.org/15537?language=Pashai%2C%20Southeast (the site answers 200 for any path)",
|
||||
"at": "2026-09-25T09:56:59.503Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue