doxa-maps/plugin-designs/research-map-plus-grid/scripts
Doxa Maps e514dd8544 check:i18n-keys-exist was blind to a translator that arrives from a composable
go-int planted T('poison_key') behind "const T = useGiT()" and this gate reported the tree clean.
That is the one failure a check is not forgiven: a red gate gets fixed, a green gate that should be
red gets believed, and this is the gate that guards goal (d).

Three independent blindnesses were stacked, and any one alone hid the key:
  1. the file never writes the word tStatic, so the precondition skipped it before anything ran;
  2. useGiT is not tStatic, so the per-file alias discovery found no alias at all;
  3. the alias is PREFIXED, because useOptionalT carries a namespace, while its call sites pass BARE
     keys -- which the full-key pattern cannot match, because it requires a dot.

A translator bound from a composable is now resolved like any other, and the namespace is READ from
the factory rather than listed here -- useOptionalT and useOptionalI18n directly, plus any
"export function useXxxT() { return useOptionalT('ns') }", which is how useNeighborT and usePplrT
are written. That keeps the next author's factory covered the day they write it, which is the same
reason the wrapper NAMES were already read per file instead of hardcoded. Because qualify() prefixes
a bare key and leaves an already-qualified one alone, one binding registers as both shapes; the two
patterns are disjoint, so nothing is counted twice.

MEASURED before and after, with the same poison on disk: the previous version PASSES it, this one
fails it as "neighbor.zzz_not_a_real_key (via nt())". Coverage went 683 -> 743 full-key and 49 -> 56
prefixed call sites, so 67 call sites were being scored as clean without being read. The tree itself
is still clean: no real key was hiding behind those 67, so there is nothing to route to any owner.

A self-test asserts all three fixes SEPARATELY and exits 3 if any one goes blind, because testing
them together would not say which was fixed -- and because this gate had already been trusted once
while lying.

Empty-namespace bare keys stay outside the model and are COUNTED rather than assumed away. Measured
at zero today: all five such sites pass fully dotted keys, so every one is checked by the full-key
pass. The counter stays because the shape is writable.

Gate and description only. No product code, no rebuild.
2026-09-27 04:14:14 +00:00
..
check-composite-locale-leaks.mjs Five more gate scripts read the tree's name from the build config 2026-09-25 16:25:22 +00:00
check-filter-multivalue.mjs Kit landing 4c-3: the facet rail follows the chip bar into the library 2026-09-27 04:14:14 +00:00
check-hover-channel.mjs D3: the bus can point at a record without choosing it 2026-09-27 02:17:35 +00:00
check-i18n-keys-exist.mjs check:i18n-keys-exist was blind to a translator that arrives from a composable 2026-09-27 04:14:14 +00:00
check-linked-vocabulary.mjs Three browser gates stop passing hollow or racing (rega's gates:post run at ded4b3c1) 2026-09-26 13:35:57 +00:00
check-no-free-identifiers.mjs A gate for the mistake I shipped: a name used but never bound 2026-09-26 03:29:51 +00:00
check-ui-strings-have-keys.mjs A gate for English typed into a template, so the ground we have won stays won 2026-09-26 13:04:15 +00:00
ui-strings-baseline.json ui-strings baseline: gospel's resources-map types the pin note's first sentence, which now has a key 2026-09-26 13:04:16 +00:00