Exempt a region identity only while REGION_KEY still names it

studio's judgement on the nineteen REGION_OF findings: the English values are
identities, not reader text. Node ids derive from them, and every surface
that shows one translates it at render — upg-100-list.vue:440 and
poster-wall.vue:129 both read REGION_KEY[english] and call t(`poster.${…}`).

The exemption is conditional, and the condition is the whole rule. It holds
only for a name that IS a key of REGION_KEY. A region added to REGION_OF
without a matching key falls through the `|| english` arm and renders English
in all eleven locales, which is the defect upg100 already shipped once with
Americas and Europe. So the gate keeps working as the table grows rather than
blessing the file.

Deliberately not "object values" and not "legend-tree.js", as studio asked:
either would exempt the next table nobody has checked.

The parser had no newline requirement in the end, and finding out why is the
part worth keeping. The first version anchored on a closing brace at the
start of a line, so it never matched a REGION_KEY written on ONE line —
regionKeyNames returned null, the rule exited early, and BOTH two-sided cases
passed while the exemption never ran once. Poisoning the membership test
produced no failure, which is what exposed it. With the anchor gone the
poison fails, so the conditional is now proven load-bearing.

.js findings 41 -> 34.
This commit is contained in:
Doxa Maps 2026-09-29 10:13:10 +00:00
parent a3aa7dc839
commit 2f6d2f0e3b

View file

@ -351,6 +351,36 @@ function isDataComparison(node, parent) {
// resource not found means NOT FOUND in the pools checked" is a sentence that happens to be used as
// a key, and that is a real leak — gospel found twelve defects hiding in exactly that kind of
// already-classified bucket. Anything with sentence punctuation stays loud whatever its value is.
// ★ REGION IDENTITIES, EXEMPT ONLY WHILE THEY ARE TRANSLATABLE (studio's judgement, R26).
// legend-tree's REGION_OF maps a zone slug to a region NAME, and that name is an identity: node ids
// derive from it, and every surface that shows one translates it at render through REGION_KEY —
// upg-100-list.vue:440 `REGION_KEY[english] ? t(\`poster.${…}\`) : english`, poster-wall.vue:129 the
// same. So the English never reaches a reader.
//
// ⚠ THE EXEMPTION IS CONDITIONAL, AND THAT IS THE WHOLE POINT. It holds only for a name that IS a
// key of REGION_KEY. A new region added to REGION_OF without a REGION_KEY entry falls through that
// `|| english` and renders English in all eleven locales — which is precisely the defect upg100
// already shipped once with Americas and Europe. So the rule flags it, and the gate keeps working as
// the table grows instead of blessing the file.
//
// Deliberately NOT "object values" and NOT "legend-tree.js": either would exempt the next table
// nobody has checked. The membership test is what makes this safe to have at all.
function regionKeyNames(code) {
// ⚠ NO NEWLINE REQUIREMENT. The first version anchored on `\n}` and so never matched a REGION_KEY
// written on ONE LINE — regionKeyNames returned null, the rule exited early, and BOTH two-sided
// cases passed without the exemption ever running. Found by poisoning the membership test and
// seeing nothing fail.
const m = /\bREGION_KEY\s*=\s*\{([\s\S]*?)\}/.exec(code)
if (!m) return null
return new Set([...m[1].matchAll(/'([^']+)'\s*:/g)].map((x) => x[1]))
}
function isTranslatedRegionIdentity(text, code) {
const names = regionKeyNames(code)
if (!names || !names.has(text)) return false
// it must actually be used as a region identity in this file, not merely share a spelling
return /const REGION_OF\s*=/.test(code) || /regionFor\s*=/.test(code)
}
const DATA_MAP_MIN_ENTRIES = 6
function isPureDataMapKey(node, parent, grand) {
if (!parent || parent.type !== 'ObjectProperty' || parent.key !== node) return false
@ -610,6 +640,8 @@ function scanScript(code, file, out, lineBase = 0) {
if (!text.length || !isProse(text)) return // gospel: empty matches were being reported
if (!/\s/.test(text)) return // ⚠ the single-word blind spot, documented above
if (allowedBy(text)) return
// A region identity translated at render — exempt only while REGION_KEY names it.
if (isTranslatedRegionIdentity(text, code)) return
out.push({ file, kind: 'script-string', text, line: lineOf(node, lineBase) })
return
}
@ -977,6 +1009,17 @@ const RENDERED = { africa: 'A sentence the reader actually sees here', asia: 'An
// names, values that are prose a reader sees: the keys must STILL count, because this is a
// label table, not a join table. Without this case the allData guard can be removed and every
// test still passes — measured by poisoning it.
// ★ REGION IDENTITIES (studio, R26): exempt ONLY while REGION_KEY names them. A region added
// without a key falls through `|| english` and renders English in eleven locales — the defect
// upg100 already shipped once with Americas and Europe. The conditional IS the rule.
{
const KEYED = "const REGION_KEY={'Africa':'region_africa','Middle East':'region_middle_east','India':'region_india','Other':'region_other','China + Mongolia':'region_china_mongolia','Central Asia':'region_central_asia'}"
const mk = (of) => `<template><p>{{ x }}</p></template>\n<script setup>\n${KEYED}\nconst REGION_OF = ${of}\n</script>`
ok(!scanSfc(mk("{ 'west-africa': 'Africa', 'middle-east-core': 'Middle East' }"), 'rg.vue').some((f) => f.text === 'Africa'),
'QUIET on a region identity that REGION_KEY names')
ok(scanSfc(mk("{ 'west-africa': 'Africa', 'new-place': 'Antarctica Region' }"), 'rb.vue').some((f) => f.text === 'Antarctica Region'),
'COUNTS a region with NO REGION_KEY entry — it would render English through the fallback')
}
ok(scanSfc(`<template><p>{{ x }}</p></template>
<script setup>
const REGION_LABELS = { 'Andhra Pradesh': 'Southern India, sixth largest', 'Assam': 'North-east, tea country here', 'Bihar': 'Northern plains along the Ganges', 'Goa': 'West coast, smallest by area', 'Kerala': 'South-west, high literacy rate', 'Punjab': 'North-west, the five rivers' }