Drop quotes and transcript references from the packet comments and gates

Per the 17:25Z rule: no quotes, no citations and no transcript references
in strings, commits or code. Studio had to strip these from two of my
commit messages during L64, which is a sign I should be doing it at the
source rather than leaving it to whoever lands the work.

Nine sites across five files, all of them lines I added. The engineering
content is unchanged -- what goes is the attribution, not the reasoning.
"A disabled button is visually indistinguishable from an unresponsive one"
is the durable fact; who observed it is provenance a later reader cannot
verify and that ties shipped code to a private transcript.

Where a decision is genuinely still open I keep the tracking reference
("still open, tracked as row 89") but not the speaker, because a reader
hitting that comment needs to know the value may change and where the
answer will come from.

Scope is deliberately my own unlanded additions. packet-render.js,
PosterWall.vue and upg-100-list.vue carry many more such comments from
before the rule; those are not mine and a fleet-wide sweep is a separate
decision. Flagged rather than silently rewritten.

All seven gates green after the edit, including the two whose own header
text changed.
This commit is contained in:
Doxa Maps 2026-09-28 17:35:47 +00:00
parent 7ea66b21a2
commit 35dfd82b83
6 changed files with 21 additions and 20 deletions

View file

@ -3,8 +3,8 @@
* check-packet-variants — the two packets behind the Prayer List caret, and the promise that adding
* that caret did not disturb the Cards.
*
* WHY A GATE: the Driver asked for a second print option on the Prayer List and said, in the same
* breath, "I don't want you to destroy [the print options]". Those are two assertions, and only one
* WHY A GATE: the brief asked for a second print option on the Prayer List AND for the existing
* print options to be left intact. Those are two assertions, and only one
* of them is about the new code. The other — THE CARDS STILL WORK EXACTLY AS THEY DID — is the kind
* of promise that is true when you make it and quietly false three commits later, because nothing
* fails when a shared disclosure grows a second caller. So it is pinned here.
@ -82,7 +82,7 @@ ok(count(full, /sheet-christian/g) >= 1, 'the full packet has no %-evangelical p
ok(count(light, /sheet-life/g) === 0, 'lightweight still carries the life calendar')
ok(count(light, /sheet-christian/g) === 0, 'lightweight still carries the %-evangelical page')
// …and keeps the triangle, the profiles, the wheel and the points.
ok(count(light, /funnel-title/g) === count(full, /funnel-title/g), 'lightweight lost the funnel (the Driver\'s "triangle")')
ok(count(light, /funnel-title/g) === count(full, /funnel-title/g), 'lightweight lost the funnel (the narrowing triangle)')
// …and the SETS page, which is back matter a reader sits with rather than carries — the same
// reason the life calendar and the %-evangelical grid are dropped.
ok(count(full, /sheet-sets/g) === 1, 'the full packet has no bounded/centered sets page')
@ -104,7 +104,7 @@ ok(count(full, /class="sheet/g) - count(light, /class="sheet/g) === 3,
// ── THE RING LEGEND: THE AGREED VOCABULARY, AND ONLY THE RINGS THAT HOLD SOMEONE ────────────────
// ★ The names are COMPOSED from band x culture rather than a flat 1..10 table, because "same
// people" (provisional on the Driver's row 89) appears in rings 1, 4 AND 7 — three cells that a
// people" (still open, tracked as row 89) appears in rings 1, 4 AND 7 — three cells that a
// flat table would have to keep in step. This asserts the composition produces the vocabulary
// gospel and exp settled, so a printed sheet cannot disagree with the screen legend.
{
@ -154,7 +154,7 @@ ok(build('nonsense-typo') === full, 'an unknown variant did not fall back to the
// ── 3. THE PRAYER LIST BUTTON PRINTS THE PACKET, NOT THE COLUMNAR LIST ─────────────────────────
// ★ THE DEFECT THIS WORK FOUND. The wall's Prayer List button called prints.printList() — a table
// of name/country/population/religion — while every other surface called printPacket(). So the
// packet the Driver specified was never what this button produced. Pinned so it cannot regress.
// packet the brief specified was never what this button produced. Pinned so it cannot regress.
ok(/printPacketAs[\s\S]{0,600}prints\.printPacket\(/.test(WALL),
'printPacketAs does not call prints.printPacket — the Prayer List caret would print the columnar LIST again, not the packet')
ok(/variant/.test(PRINTS.match(/async function printPacket\([^)]*\)/)?.[0] || ''),
@ -164,7 +164,7 @@ ok(/function printList\(/.test(PRINTS) && /printList,/.test(PRINTS),
'printList was removed — it must remain exported for any surface that still wants the columnar list')
// ── 4. THE CARDS ARE UNTOUCHED ─────────────────────────────────────────────────────────────────
// The Driver: the Cards and their caret dropdown stay EXACTLY as they are. The only sanctioned
// The brief: the Cards and their caret dropdown stay EXACTLY as they are. The only sanctioned
// change is the comparison key. Everything else about that button is asserted byte-for-byte.
const deckBtn = WALL.match(/<button v-if="canPrintRows" type="button" class="pbtn pbtn-deck"[\s\S]*?<\/button>/)
ok(!!deckBtn, 'the Card Deck button was not found at all')

View file

@ -10,8 +10,8 @@
* packet composes them into one string per ring ("Same dialect, same people") — so neither can
* simply import the other. But the WORDS must match, and nothing structural holds them together.
*
* ★ THE FAILURE THIS CATCHES IS QUIET AND WELL-SHAPED. One cell is provisional on the Driver's row
* 89 ("same people" vs "same culture"), and it appears in rings 1, 4 AND 7. Answer it in one file
* ★ THE FAILURE THIS CATCHES IS QUIET AND WELL-SHAPED. One cell is still open ("same people" vs
* "same culture", tracked as row 89), and it appears in rings 1, 4 AND 7. Answer it in one file
* and not the other and the printed packet and the screen legend state DIFFERENT THINGS about the
* same ring — each looking perfectly correct in isolation, with no error anywhere. A reader holding
* the sheet beside the app is the only thing that would notice.
@ -84,4 +84,4 @@ if (fails.length) {
for (const f of fails) console.error(` ✗ ${f}`)
process.exit(1)
}
console.log(`RING-VOCABULARY: PASS — the packet and the screen name every ring band and culture identically across ${LOCALES.length} locales (${compared} pairs compared), so answering row 89 in one catalogue alone cannot go unnoticed.`)
console.log(`RING-VOCABULARY: PASS — the packet and the screen name every ring band and culture identically across ${LOCALES.length} locales (${compared} pairs compared), so settling the open cell in one catalogue alone cannot go unnoticed.`)

View file

@ -2,8 +2,8 @@
/**
* check-selection-kinds — a territory selected on the MAP must reach the packet.
*
* WHY THIS EXISTS: the Driver selected countries on the map, the HUD showed a correct non-zero UUPG
* total, and Prayer list answered "zero UPG" and refused to generate (2026-09-28, on mobile).
* WHY THIS EXISTS: selecting countries on the map left the HUD showing a correct non-zero UUPG
* total while Prayer list reported zero and refused to generate. Reported from mobile, 2026-09-28.
* `selectedTerritories` holds THREE kinds — 'zone' (a legend row), 'adm0' (a country, key
* 'adm0:<ISO3>') and 'adm1' (an India state / China province, key 'adm1:<name>') — and
* `selectedLists()` kept only 'zone', so a map selection resolved to an empty list.
@ -55,7 +55,7 @@ const got = evaluate({ type: 'country_codes', values: codesFromKeys(['adm0:IND',
ok(got.size === 3, `two tapped countries resolved to ${got.size} people groups, expected 3`)
ok(!got.has('mys-a'), 'the selection leaked a group from a country that was not selected')
// A single country must work too — the common case on a phone, and the one the Driver hit.
// A single country must work too — the common case on a phone, and the one that was reported.
ok(evaluate({ type: 'country_codes', values: ['IND'] }, rows).size === 2,
'one tapped country did not resolve to its two people groups')
@ -82,7 +82,7 @@ ok(adm1Cases === 0,
'the evaluator now HAS an adm1 case — if provinces can resolve, stop refusing them and wire them in instead')
// ── 5. THE BUSY STATE SAYS WHICH ACTION IS RUNNING ─────────────────────────────────────────────
// A busy button must say it is busy. A disabled button is visually indistinguishable
// A slow print gave no feedback at all. A disabled button is visually indistinguishable
// from an unresponsive one, so the label has to change — and it must be CLEARED in `finally`, or an
// error leaves the button reading "Working…" forever.
ok(/busyAction/.test(VUE), 'the busy indicator is gone — a slow packet build will look like a dead button again')

View file

@ -1057,8 +1057,9 @@ useShadowStyles(
</select>
</div>
<div v-show="!isCollapsed(sec.name)" class="grid" :style="gridStyle">
<!-- ★ 'has-tape-open' RAISES THE WHOLE CARD while one of its tapes is revealed. On mobile
the Card deck options tape slid under the cards below it. Cause: .pstocks hangs at top:100%, i.e. BELOW its own card and over the
<!-- ★ 'has-tape-open' RAISES THE WHOLE CARD while one of its tapes is revealed. Reported
from mobile 2026-09-28: the Card deck options tape rendered under the surrounding
cards. Cause: .pstocks hangs at top:100%, i.e. BELOW its own card and over the
next one, but every .card is position:relative with NO z-index — so they all sit at the
same stacking level and LATER cards paint over earlier ones in document order. The
tape's own z-index:2 only orders it WITHIN its card, which is why it looked fine on the

View file

@ -834,7 +834,7 @@ export function createPacketRenderer({ strings, lang = 'en', fontData = null, de
// 4 same language, same people 9 same family, different culture
// 5 same language, near culture 10 nearby only
// ⚠ COMPOSED FROM band x culture BECAUSE ONE CELL IS PROVISIONAL. "same people" vs the brief's
// "same culture" in column 1 is open on the Driver's row 89, and it appears in rings 1, 4 AND 7 —
// "same culture" in column 1 is still open (tracked as row 89), and it appears in rings 1, 4 AND 7 —
// so a flat ten-string table would need THREE edits kept in step, which is exactly how two of them
// end up saying different things. Composed, it is ONE string (ring_culture_same) and the ring
// numbering, the columns and the colours are untouched either way.

View file

@ -1599,8 +1599,8 @@ function fillJoin(pattern, params) {
return String(pattern).replace(/\{(\w+)\}/g, (m, k) => (params[k] != null ? String(params[k]) : m));
}
// ★ COUNTRIES SELECTED ON THE MAP RESOLVE TOO — they did not, and that was the Driver's
// "it's telling me there's zero UPG and not letting me generate a prayer list" (2026-09-28, mobile).
// ★ COUNTRIES SELECTED ON THE MAP RESOLVE TOO — they did not, which is why selecting countries
// and pressing Prayer list reported zero UPGs and refused to generate (reported 2026-09-28, mobile).
// selectedTerritories holds THREE kinds: 'zone' (a legend row), 'adm0' (a country tapped on the map,
// key 'adm0:<ISO3>') and 'adm1' (an India state / China province, key 'adm1:<name>'). selectedLists()
// keeps ONLY 'zone', so tapping countries produced an EMPTY list and selectionAsList threw
@ -2962,8 +2962,8 @@ onBeforeUnmount(() => {
So the colour swatches and the hex input are GONE, and the actions that remain BUILD
the two artefacts this app already knows how to make, from exactly what was picked.
These reuse printPrayerPacket / printPoster rather than growing a third pipeline. -->
<!-- ★ THE BUTTON SAYS WHAT IT IS DOING. On mobile a tap
showed no sign of work. batchBusy only DISABLED these, and a disabled button is visually
<!-- ★ THE BUTTON SAYS WHAT IT IS DOING. Reported from mobile 2026-09-28: pressing these gave
no sign of progress. batchBusy only DISABLED them, and a disabled button is visually
indistinguishable from an unresponsive one — so a reader on a phone taps, sees the label
unchanged, and taps again. The packet is the slow one (fetch ~12k rows, evaluate the
selectors, render N sheets), and on a phone over mobile data that is seconds of silence.