Follow-up to #14268 (PR #14575), filed by the domain:devx execution seat (session session_01WLJQhde67SeTccsmnBVarV, seat post #6023) from that card's out_of_scope_findings; unassigned, for triage.
#14268's ruling named THREE rules; after PR #14575 those three (validate-object-references.ts, validate-sortable-fields.ts, validate-widget-bindings.ts) import suggestName / nearestName from object-graph.ts, which now carries the one shared "Did you mean?" helper (containment pre-pass, then edit distance with budget max(2, floor(len/3))). The consolidation stopped at the ruling's three, but packages/lint/src still carries five more private copies of the same suggest + distance pair and two deliberately different neighbours. Line numbers below are on origin/main f60ab90ae (pre-#14575 merge; the file:line for these files do not move with that PR).
Tier 1 — byte-for-byte the same shape as the three just consolidated (same Levenshtein, same budget, same message shape). Pure rewire to suggestName, delete the copy:
validate-action-name-refs.ts:84 distance, :101 suggest (budget at :111)
validate-chart-bindings.ts:83 distance, :100 suggest (budget at :110)
validate-searchable-fields.ts:289 distance, :275 suggest (budget at :285)
Tier 2 — same budget + message, plus a one-line pre-pass that should stay in the rule and wrap the shared helper (prefix/namespace check first, then suggestName):
validate-ai-tool-references.ts:70 distance, :87 suggest — :93 first tries known.has(prefix + target) (a missing tool-name prefix), then the same Levenshtein budget (:105-106).
validate-translation-references.ts:159 distance, :186 suggest — :191 first tries a namespace-segment match, then the same budget (:202-203).
Not the same thing — listed so the follow-up does not over-reach; leave them unless triage rules otherwise:
validate-react-page-props.ts:167 nearestKnown — fixed budget <= 2 (not max(2, floor(len/3))), null return, own editDistance. Same idea, different contract; consolidating changes which typos get a hint.
validate-rule-schema-formats.ts:266 nearestRegisteredFormat — exported, budget min(3, floor(len/2)), case-insensitive on the authored side, alphabetical tie-break "so the suggestion is stable", with its own docblock justifying each choice against ajv's case-sensitive lookup. A different helper on purpose.
Why it matters (same argument as #14268): the containment pre-pass is now the shared helper's behaviour for every caller, so the five Tier 1/2 rules once again give "a different quality of hint depending on which rule you tripped" — amount → sum_amount is suggested by widget bindings and not by chart bindings, one file over. That is the drift #14268 was opened to end.
Suggested shape if promoted: pm:queue, one PR, @objectstack/lint patch changeset; Tier 1 rewire + Tier 2 wrap; ⛔ no change to object-graph.ts's helper (already ruled in #14268); ⛔ validate-react-page-props.ts and validate-rule-schema-formats.ts out of scope unless triage says otherwise. Serial: after PR #14575 lands (it is in CI now); no other open PR touches these five files at filing time.
Dedup: no open issue matches did you mean / suggest / levenshtein / nearest in its title except #14268 itself (481 open issues scanned 12:5xZ).
Generated by Claude Code
Follow-up to #14268 (PR #14575), filed by the
domain:devxexecution seat (sessionsession_01WLJQhde67SeTccsmnBVarV, seat post #6023) from that card'sout_of_scope_findings; unassigned, for triage.#14268's ruling named THREE rules; after PR #14575 those three (
validate-object-references.ts,validate-sortable-fields.ts,validate-widget-bindings.ts) importsuggestName/nearestNamefromobject-graph.ts, which now carries the one shared "Did you mean?" helper (containment pre-pass, then edit distance with budgetmax(2, floor(len/3))). The consolidation stopped at the ruling's three, butpackages/lint/srcstill carries five more private copies of the samesuggest+distancepair and two deliberately different neighbours. Line numbers below are onorigin/mainf60ab90ae(pre-#14575 merge; the file:line for these files do not move with that PR).Tier 1 — byte-for-byte the same shape as the three just consolidated (same Levenshtein, same budget, same message shape). Pure rewire to
suggestName, delete the copy:validate-action-name-refs.ts:84distance,:101suggest(budget at:111)validate-chart-bindings.ts:83distance,:100suggest(budget at:110)validate-searchable-fields.ts:289distance,:275suggest(budget at:285)Tier 2 — same budget + message, plus a one-line pre-pass that should stay in the rule and wrap the shared helper (
prefix/namespace check first, thensuggestName):validate-ai-tool-references.ts:70distance,:87suggest—:93first triesknown.has(prefix + target)(a missing tool-name prefix), then the same Levenshtein budget (:105-106).validate-translation-references.ts:159distance,:186suggest—:191first tries a namespace-segment match, then the same budget (:202-203).Not the same thing — listed so the follow-up does not over-reach; leave them unless triage rules otherwise:
validate-react-page-props.ts:167nearestKnown— fixed budget<= 2(notmax(2, floor(len/3))),nullreturn, owneditDistance. Same idea, different contract; consolidating changes which typos get a hint.validate-rule-schema-formats.ts:266nearestRegisteredFormat— exported, budgetmin(3, floor(len/2)), case-insensitive on the authored side, alphabetical tie-break "so the suggestion is stable", with its own docblock justifying each choice against ajv's case-sensitive lookup. A different helper on purpose.Why it matters (same argument as #14268): the containment pre-pass is now the shared helper's behaviour for every caller, so the five Tier 1/2 rules once again give "a different quality of hint depending on which rule you tripped" —
amount→sum_amountis suggested by widget bindings and not by chart bindings, one file over. That is the drift #14268 was opened to end.Suggested shape if promoted:
pm:queue, one PR,@objectstack/lintpatchchangeset; Tier 1 rewire + Tier 2 wrap; ⛔ no change toobject-graph.ts's helper (already ruled in #14268); ⛔validate-react-page-props.tsandvalidate-rule-schema-formats.tsout of scope unless triage says otherwise. Serial: after PR #14575 lands (it is in CI now); no other open PR touches these five files at filing time.Dedup: no open issue matches
did you mean/suggest/levenshtein/nearestin its title except #14268 itself (481 open issues scanned 12:5xZ).Generated by Claude Code