Commit graph

5 commits

Author SHA1 Message Date
Doxa Maps
37aaf69c24 rega's four notes on the card, all four mine
1 THE CHIPS SAID "unchecked" ON VERIFIED LINKS. Card mode never fetches the verification table,
so every chip understated the evidence behind it — caught on central-sama, whose Scripture and
film are both verified. Each shard now carries the states for its OWN urls, keyed by url exactly
as linkVerify is, so vchip() and vtitle() work unchanged. Shards grew 8.0 KB to 14.0 KB mean,
29 KB worst; against 6,051 KB for the map that is a price worth paying for not lying about
evidence.

2 MY GATE'S FALSE NEGATIVE, which cost rega a round: it asserted
text.includes(slug.split('-')[0]) — "abai" against a rendered "Abai Sungai". A slug fragment is
not a name. It compares the roster's name, case-folded, anywhere in the card.

3 THE EMPTY GREY BAND. The sheet is a bottom panel capped at 62% of the map; in card mode there
is no map under it, so a phone showed 285px of grey above it. Full height in card mode, and the
border radius goes with it.

4 THE CLOSE BUTTON with nothing behind it — hidden in card mode, both instances of it.

gates:pre 11/11, LINK-COVERAGE 12,292 unchanged, SFC-PARSE PASS. rega spot-checks after landing
per dx-shepherd; the render claim is still not mine to make.
2026-09-27 19:26:29 +00:00
Doxa Maps
8c99bbe611 One normalizer for the card and the map, not two that agree by hand
Third report of a blank card, and the root cause was never a missing field — it was two code
paths producing "the same" object. build-field-cards.mjs copied groupAt()'s 39 fields by hand
and missed door43, which exists only in that normalizer, so the sheet's
`!selectedGroup.door43.length` threw on undefined. I fixed a value, then a timing, then would
have added door43 and waited for the fourth.

The shard now ships the RAW INPUTS the map itself holds — the pin row, the whole code record,
the country name and the two bridge records — and the leaf's groupFrom() normalizes both
paths. groupAt(i) is a three-line wrapper over it. A field added to the sheet reaches the card
with no second edit, and forgetting one is no longer possible. The code record is passed WHOLE
rather than picked over, because picking fields is exactly the mistake above. Shards got
smaller doing it: mean 8.0 KB against 9.1.

Two sheet-level sources the card fetches nothing for are seeded from the shard: the prayer page
(prayIndex) and the SUN block. Both matter most to this persona — a catalyst with a Deaf group,
or one handing someone a prayer page — and both were silently absent while the card "worked".

Verified statically, since I cannot render: every one of the 28 fields the sheet reads off
selectedGroup is produced by groupFrom, so the two paths cannot disagree about any of them.
rega has the render.
2026-09-27 19:11:42 +00:00
Doxa Maps
3cf20a237c The Scripture chip stops saying "none found" to people who have a Bible
The sheet tested scripture_url alone, so for every code whose readable text is NOT at c.s it
rendered "Scripture · none found". 887 codes keep theirs elsewhere — on the Faith Comes By
Hearing record, on Scripture Earth, or in a Door43 translation — and 332 field cards carry
one. A catalyst reading that chip was told there is nothing to read while the link existed.

The chip now links `sx` and NAMES its source, because a reader deserves to know they are
being sent to an audio site to read: "Scripture · checked (Faith Comes By Hearing)". The
verification state and title come from the same record as any other link, so nothing here is
claimed that the link record does not already support. The card carries sx for the same
reason — the tier that promises Scripture and the panel that shows it must agree.

Two placement mistakes of mine, both caught by checking the DATA rather than the diff: the
first edit matched `credit: c.cr || null` in the bridge helper instead of the card object, and
a str.replace with no match is a silent no-op that reports success. The card had no sx and
said so when I looked for it, which is why the second attempt asserted its anchor.
2026-09-27 19:01:05 +00:00
Doxa Maps
c9e8a3c604 The card waits for its data before it renders
Second failure on the same feature, and the cause was timing rather than values: the sheet
mounted on cardMode ALONE, so it read selected.country before the shard fetch had set it.
My previous fix put the right value in the right place and left it arriving too late.

The sheet now appears when there is DATA — v-else-if="selected || showGapList", with cardMode
removed from that condition entirely, because a card that has arrived sets both. A wait box
stands in until then and shows the error if the shard 404s, so a loading card looks like one
and a failed card says so instead of showing nothing.

And the card now carries the BRIDGE's own links. In card mode the pin index is never fetched,
so bridgeResources() found nothing and a tier-0 card would have named a way in with no way to
follow it — the single most important thing on that group's card. Derived in the builder
exactly as the leaf derives it, FCBH text fallback included, because a group's readable
Scripture is sometimes only on the audio record. Verified in the data: abai-sungai's card
carries Indonesian with its Scripture, film and Zume links.

NOT LANDING THIS until rega has rendered it on the branch. I have now shipped this feature
blank twice on checks that passed, and the missing check was always the same one: that it
renders. I cannot run a browser, so the claim is not mine to make.
2026-09-27 18:30:51 +00:00
Doxa Maps
f0798a675e A field card: one group, one fetch, a link you can send
BUILD-FIELD-RESOURCE-CARD. For the catalyst standing with the group on a phone. Seeing ONE
group used to cost the engine, the world boundaries, the basemap tiles and the 2.3 MB pin
index before a single link appeared.

?card=<slug> renders the group's sheet alone — no engine, no boundaries, no tiles, no pin
index. Measured from the served files: the map transfers 7,942 KB plus a ~700 KB engine and
unbounded tiles; the card transfers 678 KB worst case, of which 661 KB is the bundle itself
and 17 KB the largest shard. 92% fewer bytes before tiles are counted at all. The bundle is
now the floor, and splitting it is a separate job I have not done.

SHARDED BY A STABLE HASH, after two measured failures: first two letters of the slug gave a
120 KB worst shard because every "Deaf <people>" lands in "de"; three letters left 110 KB
because those slugs all begin "dea". djb2 low byte gives 255 even shards, mean 9 KB, max
17 KB, and the leaf recomputes the key so there is no index and one request. The identical
function lives in both files: if either drifts the card 404s rather than serving somebody
else's group.

Flat filenames, card-<key>.json, because internal/generate-tree.mjs stages tables/*.json as
files and throws EISDIR on a subdirectory — shared build machinery, not mine to change for
one plugin.

Share uses navigator.share where it exists (it offers whatever the catalyst already has) and
falls back to the clipboard, with a cancelled share treated as the non-event it is. The link
carries doxa.life's own slug, so what arrives reopens this card rather than a search — the
slug now reaches the sheet from a tapped pin too, so sharing works from the map as well.

Honesty unchanged: 1,738 cards carry something in the group's own language, 369 carry
nothing and say so with the way in. Checked 400 roster rows resolve to a card, 0 missing;
a tier-0 and a tier-2 card both carry what they should.
2026-09-27 17:58:05 +00:00