test: prove the failure delivery itself, not only the unsubscription (#354 r1-M1)

The r1 reviewer cut the listener loop in the production registry and all
three #354 units stayed green — the subscription unit was the same class of
decoy the issue itself fights. The fan-out now lives in an exported
notifyLanguageLoadFailures(code); the unit drives it directly and asserts
real delivery, partial unsubscription and silence after the last listener
leaves; the contract unit additionally pins the runtime wiring
(`loadFailed` → notifyLanguageLoadFailures) in source. A new registry
mutant `locale-failure-delivery-cut` replays the reviewer's exact cut and
is killed by the unit. The r1 Low is taken too: both USER-GUIDEs now
mention the toast in the German-failure paragraph.

Issue: #354
User-Visible: no
This commit is contained in:
Codex
2026-08-28 18:08:27 +03:00
parent 4e10f69cfb
commit c1356fae18
23 changed files with 188 additions and 161 deletions
+13 -6
View File
@@ -645,14 +645,10 @@ const MUTANT_DEFINITIONS = [
+ ' LANGUAGE_REGISTRY,\n'
+ ' BUILD_FINGERPRINT,\n'
+ ' console.warn,\n'
+ ' (code) => {\n'
+ ' for (const listener of languageLoadFailureListeners) listener(code);\n'
+ ' },\n'
+ ' notifyLanguageLoadFailures,\n'
+ ');',
replace: 'const twin = new LanguageRuntime(LANGUAGE_REGISTRY, BUILD_FINGERPRINT, '
+ 'console.warn, (code) => {\n'
+ ' for (const listener of languageLoadFailureListeners) listener(code);\n'
+ '});\n'
+ 'console.warn, notifyLanguageLoadFailures);\n'
+ 'export const LANGUAGE_RUNTIME: LanguageRuntimeContract = {\n'
+ ' state: (code) => twin.state(code),\n'
+ ' dictionary: (code) => twin.dictionary(code),\n'
@@ -660,6 +656,17 @@ const MUTANT_DEFINITIONS = [
+ '};',
}],
},
{
id: 'locale-failure-delivery-cut',
guard: 'node --test --test-name-pattern="#354" test/i18n-runtime.test.mjs',
because: 'cutting the listener loop leaves subscribeLanguageLoadFailures a decoy — the unit '
+ 'must prove real code delivery, not only unsubscription (#354 r1-M1)',
patches: [{
file: 'src/i18n/registry.ts',
find: ' for (const listener of languageLoadFailureListeners) listener(code);',
replace: ' void code;',
}],
},
{
id: 'locale-failure-toast-dropped',
guard: 'node demo/smoke_german_locale.mjs',