Skip to content

fix(menubar): pin multi-argument catalog keys to positional specifiers - #1370

Closed
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:fix/localization-positional-specifiers
Closed

ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:fix/localization-positional-specifiers

Conversation

@ozymandiashh

Copy link
Copy Markdown
Collaborator

Closes #1331.

The drift class

LocalizationCatalogTests compared the specifier lists of each key across locales. A key whose placeholders are all %@ passed even when the Chinese value bound the arguments into the wrong slots — exactly what shipped in the three early-reset keys, caught only by rendering real data bilingually.

Catalogs

  • All 42 multi-argument keys in both en and zh-Hans now use positional specifiers (%1$\@, %2$lld, …). String(format:) binds them identically to before, so rendered output is unchanged; the 60 call-site literals moved in lockstep with their keys.
  • The parity check now compares slot → verb: Chinese word order may reorder slots freely (that is what positional form is for), while a slot changing type is still a failure.
  • New test: any key with two or more arguments that is not positional, in either locale, fails with the offending tokens named.

Scanner

The source scanner stopped being blind to the three shapes the issue names — each puts copy on screen looking like machinery to a first-character check:

  • ternary branches: Text(isEarly ? "Came early" : "On time")
  • concatenation: .help(prefix + " and counting")
  • a literal bound to a let and passed by name: let tip = "…" then .help(tip) (a binding whose right-hand side is L("…") is treated as routed)

Text(verbatim:) is the explicit do-not-localize opt-out and stays exempt. Running the new rules over mac/Sources surfaced exactly four real violations — the Text(usage.plan ?? "Kimi Code")-style provider fallbacks in HeatmapSection — now routed through the catalog as verbatim entries per the provider-names policy.

Verification

This host cannot run swift test (no Testing module in the CLT toolchain), so beyond swift build:

  • a standalone swiftc harness exercises the scanner's old and new rules against snippets plus the real mac/Sources tree (9/9 pass, 0 findings on the tree)
  • a python replica of the catalog tests validates key parity, en identity, positional form, slot parity, %% parity, and that every L(…) key exists in the table (all pass; 623 keys per locale, 623 requested keys)

CI (swift test --package-path mac) is the authoritative gate.

The catalog comparison matched specifier lists, so a key whose
placeholders are all %@ passed even when the Chinese value bound the
arguments into the wrong slots — the drift that shipped in three
early-reset keys and was only caught by rendering real data bilingually
(getagentseal#1331).

All 42 multi-argument keys in both tables now use positional specifiers
(%1$@, %2$lld, ...); the parity check compares slot to verb so Chinese
word order stays free while each slot keeps its type; a new test fails
on any multi-argument key that is not positional.

The source scanner closes its three expression gaps: ternary branches,
concatenated literals, and let-bound literals passed by name.
Text(verbatim:) stays the explicit opt-out; the four provider-name
fallbacks the new rules surfaced in HeatmapSection route through the
catalog as verbatim entries.

Closes getagentseal#1331
@github-actions

Copy link
Copy Markdown

Closing for now: you already have 9 pull requests open (#940, #1013, #1326, #1339, #1347, #1351, #1352, #1364, #1365), and we review at most 5 per contributor at a time. Reopen this one when one of them is merged or closed. Issues are always welcome.

@iamtoruk

Copy link
Copy Markdown
Member

Merged as #1435 (your commit rebased onto main, authorship unchanged). Verified by rendering every multi-argument string in both languages against main: no visible change. Thanks.

@iamtoruk iamtoruk closed this Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

localization: catalog test cannot see argument-order drift when specifiers share a type

2 participants