Skip to content

finding(i18n): check-i18n-dead-keys demotes 13 pack keys to NEEDS-REVIEW on evidence about a DIFFERENT key — textFootprint's full-key probe is a plain substring test #8701

Description

@baozhoutao

Filed by the objectui#8388 dev (session_01FhBNJcLRZLe8M87VcUgpKr, PR #8699) — measured while extending that script to a second corpus. ⛔ Not claimed, and ⛔ deliberately not fixed in PR #8699.

The defect

textFootprint() in scripts/check-i18n-dead-keys.mjs decides the CONFIRMED / NEEDS-REVIEW split with

const literal = content.includes(key);

Pack keys are dotted and densely prefix-nested, so ns.group.leaf is a substring of ns.group.leaf.detail. A candidate that is a strict prefix of a longer, live sibling therefore collects the sibling's call-site line as its own "textual hit" and is demoted out of CONFIRMED — on evidence about a different key.

The report then sends a human to a line that never mentions the key they are hunting. That is the exact failure the file's own PROPERTY_CHAIN_HIT_SUFFIX comment already worries about for the chain probe, and the guard it introduced for that leg (occursAtPropertyBoundary, next character may not continue an identifier) is not applied to the full-key probe — and would not be sufficient there anyway, because a . is not an identifier character, so ns.group.leaf followed by .detail passes it.

Measured on da5e4f69e

Pack sweep as it ships today: 114 CONFIRMED / 247 NEEDS-REVIEW.

Re-running textFootprint() over exactly those 247 keys with a key-boundary requirement (a match must be bounded on both sides by a character that is not one of [A-Za-z0-9_$.-]) leaves 13 with no textual evidence at all:

appDesigner.noNavItems      console.objectView.groupBy   home.recent
appDesigner.separator       console.objectView.toolbar   home.starred
approvals.reject            dashboard.removeWidget       home.subtitle
marketplace.pricing.free    form.addItem                 sidebar.help
… 13 total

⇒ each of those 13 is in NEEDS-REVIEW only because a longer sibling key is spelled somewhere. The count is identical whether the property-chain probe stays on or off, so this is the boundary artefact alone and not an interaction with that leg.

⚠️ The direction matters: the demotion is towards safer, so nothing is currently mis-deleted. What it costs is the tier's meaning — CONFIRMED is documented as "the tier to READ FIRST", and 13 keys with no evidence against them are sitting outside it.

Why PR #8699 did not fix it

That PR adds the boundary as an opt-in keyBoundary option, defaults it off, and turns it on only for the new designer-table corpus (where the artefact was severe — 4 of 7 NEEDS-REVIEW entries were pure prefix noise). The pack half is left byte-for-byte as it was, deliberately:

  • objectui#4658's dispatch ruling rests on a measured false-positive rate for the pack sweep, taken with the current behaviour. Silently re-tiering 13 keys inside an unrelated PR would move that reading without anybody re-measuring it.
  • The right change is a small one (flip the default, or pass keyBoundary: true from sweep()), but it needs its own sampled check of the 13 — some may be genuinely dead, in which case this also finds work rather than only tidying a tier.

Dedup

One targeted search_issues was run and is declared rather than hidden: check-i18n-dead-keys textFootprint substring match demotes a pack key that is a prefix of a longer sibling key to NEEDS-REVIEW. Nearest neighbours are objectui#7592 (helper-built key templates putting LIVE keys in CONFIRMED), objectui#6666 (property-access pack readers, same direction), and objectui#4964 (template families prefix-checked in the FORWARD, call-site direction) — all closed, all a different class. No duplicate found.

Related

objectui#8388 / PR #8699 (the second corpus, where this artefact was measured) · objectui#4658 (the pack sweep and its false-positive-rate ruling)

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repofindingpm:dispatchedtooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions