Skip to content

check-i18n-coverage groups failure causes on a key containing the per-config rerun command, so one shared cause reports as N causes #11395

Description

@claude

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

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions