Measured while fixing #10907, on a real run rather than by reading.
The shape
groupFailuresByCause() in scripts/check-i18n-coverage.mjs exists to enforce #5217's rule — one cause must not be reported as N results. It keys the grouping on the conclusion:
constkey=JSON.stringify([f.reason,f.fix]);
That holds for the classified branches of explainConfigFailure(), whose fix is a constant (WORKSPACE_BUILD_FIX / INSTALL_THEN_BUILD_FIX). It does not hold for the fallback branch, whose fix is
functionrerunFix(configPath){return`node ${CLI} lint ${configPath} --json`;}— a string that embeds the config path. So every config that lands in the fallback branch gets a unique key, and one shared cause is split into one group per config: exactly the shape the grouping was written to prevent. The same applies to the two other failures that use rerunFix (empty output, non-JSON output).
Measured
On an unbuilt worktree, with the gate invoked from a cwd where its CLI probe defers, all twelve configs fail for one environment fact and the report reads:
check-i18n-coverage: COULD NOT MEASURE - 12 of 12 config(s) failed to lint (12 distinct causes)
Cause 1 of 12 - 1 config(s):
examples/app-crm/objectstack.config.ts
why: `os lint` produced no output at all - no JSON payload to count
...
Twelve blocks, twelve identical why: lines, one actual cause. The report's own closing paragraph then asserts the opposite in prose: "a cause shared by several configs is stated once, not once per config (#5217)".
Direction (not a decision)
The reason line already carries the whole conclusion; the rerun command is a per-config remedy detail, not part of the identity of the cause. Candidates: key the group on reason alone and render the rerun command per config inside the block, or normalise the config path out of the key. Either keeps the classified branches grouping exactly as they do today.
Out of scope for #10907, whose ruled surface was the same file but whose subject was path anchoring; filed rather than folded in so the change is judged on its own evidence.
Refs
#10907 (where this was measured) · #5217 (the rule this branch escapes)
Generated by Claude Code
Measured while fixing #10907, on a real run rather than by reading.
The shape
groupFailuresByCause()inscripts/check-i18n-coverage.mjsexists to enforce #5217's rule — one cause must not be reported as N results. It keys the grouping on the conclusion:That holds for the classified branches of
explainConfigFailure(), whosefixis a constant (WORKSPACE_BUILD_FIX/INSTALL_THEN_BUILD_FIX). It does not hold for the fallback branch, whosefixis— a string that embeds the config path. So every config that lands in the fallback branch gets a unique key, and one shared cause is split into one group per config: exactly the shape the grouping was written to prevent. The same applies to the two other failures that use
rerunFix(empty output, non-JSON output).Measured
On an unbuilt worktree, with the gate invoked from a cwd where its CLI probe defers, all twelve configs fail for one environment fact and the report reads:
Twelve blocks, twelve identical
why:lines, one actual cause. The report's own closing paragraph then asserts the opposite in prose: "a cause shared by several configs is stated once, not once per config (#5217)".Direction (not a decision)
The reason line already carries the whole conclusion; the rerun command is a per-config remedy detail, not part of the identity of the cause. Candidates: key the group on
reasonalone and render the rerun command per config inside the block, or normalise the config path out of the key. Either keeps the classified branches grouping exactly as they do today.Out of scope for #10907, whose ruled surface was the same file but whose subject was path anchoring; filed rather than folded in so the change is judged on its own evidence.
Refs
#10907 (where this was measured) · #5217 (the rule this branch escapes)
Generated by Claude Code