Skip to content

Commit de198d9

Browse files
committed
fix(devx): check:i18n fails on an undeclared authoring key, not just on bundle drift (#4804)
The #4167 unknown-authoring-key lint saw all nine offending `scripts/i18n-extract.config.ts` files that #4736 later cleaned. It printed `stack.name: 'name' is not a declared stack key, so its value is dropped at load` once per package, on every run — inside a fully green `check:i18n`, so it read as noise nine times running. #4736 removed the symptom; nothing stopped the tenth copy. Two things made the warning unenforceable, and both are fixed here: 1. The lint writes to **stderr**, and the gate used `execFileSync`, which surfaces stderr only on the throw path. On a zero-exit run the stream went straight to the terminal — seen by nobody, judged by nothing. Now `spawnSync`, so both streams are read on both paths; stderr lines that are not the lint signature are re-emitted, so capturing costs no diagnostics. 2. The gate judged bundle drift only. It now also fails on the unknown-authoring-key signature, in its own verdict. Option A per the issue: the failure lands in the gate script. `os i18n extract` keeps its exit code (B would write an internal hygiene rule into the public CLI contract) and `ObjectStackDefinitionSchema` stays non-strict (C would silence the lint itself — see `metadata-authoring-lint.ts`). The two verdicts never merge. Drift keeps its section and its remedy (`--write`); the new class gets its own, naming the package, the config path, the key, and the consequence that matters — the value is dropped at load, so whatever it was meant to configure is not in effect and never was. Regenerating bundles does not fix it, and the message says so. Coverage needs no manifest: `findConfigs` walks `packages/`, so the tenth config is gated the day it lands. Proven able to go red, not merely observed green — the failure mode of #4690. `--self-test` (now wired into `check:i18n` ahead of the real run) drives both classifiers over recorded CLI output, asserts the drift text produces no key finding and the key text produces no drift finding, and pins the exact ffab803^ stderr line so a reworded message breaks the test rather than disarming the gate. A reworded signature that still matches the weak pattern fails as `unattributed` instead of passing. Reverse-verified against the nine configs restored from ffab803^: all nine reported, exit 1. Fixes #4804 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018iARDqtrhQgz6fVHDeDkbQ
1 parent c4ab50b commit de198d9

3 files changed

Lines changed: 328 additions & 37 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
---
3+
4+
chore(devx): `pnpm check:i18n` now FAILS on an undeclared authoring key, not just on bundle drift
5+
6+
Releases nothing — the change is confined to `scripts/check-i18n-bundles.mjs` and
7+
the root `check:i18n` script. No package source, no published behaviour, and
8+
deliberately **not** the `os i18n extract` exit code (that would write an internal
9+
hygiene rule into the public CLI contract).
10+
11+
#4736 cleaned nine `scripts/i18n-extract.config.ts` files that all opened their
12+
`defineStack({ … })` with the same undeclared `name:` key. Nine, because the same
13+
mistake was copied from the first one — and nothing stopped any of them. The
14+
#4167 unknown-authoring-key lint *saw* every single one: it printed
15+
`stack.name: 'name' is not a declared stack key, so its value is dropped at load`
16+
on stderr, once per package, on every run. But the CLI exited 0 and the gate only
17+
judged bundle drift, so those nine warnings appeared inside a **fully green**
18+
`check:i18n` and were read as noise nine times. A warning that nine authors
19+
filtered out is not a control; #4736 cleaned the symptom, this closes the hole.
20+
21+
**What changed.** The gate now reads the extractor's **stderr** — which it
22+
previously let flow straight through to the terminal, seen by nobody and judged by
23+
nothing — and fails on the unknown-authoring-key signature. Coverage needs no
24+
manifest: `findConfigs` walks `packages/`, so the tenth config is gated the day it
25+
lands.
26+
27+
**The two verdicts stay separate.** Bundle drift keeps its own section and its own
28+
remedy (`--write`); the new class gets its own, naming the package, the config
29+
path, the key, and the consequence that matters — *the value is dropped at load,
30+
so whatever it was meant to configure is not in effect and never was*.
31+
Regenerating bundles does not fix it, and the message says so.
32+
33+
**The gate is proven able to go red**, not merely observed green — the failure
34+
mode of `check:react-declaration-parity` (#4690), which exited 0 with nothing to
35+
check. Two proofs: `node scripts/check-i18n-bundles.mjs --self-test` (now wired
36+
into `check:i18n`, ahead of the real run) drives both classifiers over recorded
37+
CLI output, including a case asserting neither verdict matches the other's output;
38+
and the gate was run against the nine configs restored from `ffab8033b^`, the
39+
commit before #4803 deleted the keys, where it reports all nine and exits 1.
40+
41+
Fixing an offending config means deleting the key at the producer. If a key is
42+
genuinely wanted it gets declared in `packages/spec` deliberately — not
43+
accommodated by a consumer-side fallback, and not silenced by making
44+
`ObjectStackDefinitionSchema` strict (which would mute the lint itself; see
45+
`metadata-authoring-lint.ts`).

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"objectui:clean": "rm -rf packages/console/dist .cache/objectui-*",
3131
"lint": "eslint . --no-inline-config",
3232
"i18n:extract": "tsx packages/cli/bin/run-dev.js i18n extract packages/platform-objects/scripts/i18n-extract.config.ts --locales=zh-CN,ja-JP,es-ES --fill=default --out=packages/platform-objects/src/apps/translations",
33-
"check:i18n": "node scripts/check-i18n-bundles.mjs",
33+
"check:i18n": "node scripts/check-i18n-bundles.mjs --self-test && node scripts/check-i18n-bundles.mjs",
3434
"check:i18n-coverage": "node scripts/check-i18n-coverage.mjs",
3535
"check:nul-bytes": "node scripts/check-nul-bytes.mjs",
3636
"check:doc-authoring": "node scripts/check-doc-authoring.mjs",

0 commit comments

Comments
 (0)