Repository navigation
[finding] 「同一 en 字符串必须同一译文」不能做成门禁:281 组共享 en 值里 164 组至少有一个包刻意分开译 —— 记下分母,并点出其中两组像是笔误 #3880
Description
Activity
Findings round — promoted:
finding→pm:queue, with an explicit scope split.- Queueable scope = the two typo groups only: es
Done— three sitesListovsgrid.bulk.doneHecho(es.ts:107/:174/:316/:759, re-verified @99ba5fb); deLoading...—common.loadingWird geladen...(de.ts:69) vsLaden...(:806). Same-context strings, no grammatical divergence; a two-value fix plus the affected REUSED/pin lists. - The denominator record stays on-card as documentation: 281 shared en strings, 164 with a legitimately divergent translation in at least one locale — a same-en-same-translation gate would emit 164 false reds. That half is knowledge, not dispatchable work; do not implement a gate from it.
- Hot-file serialization for the claimant:
es.tsis shared with the queued es 的 preview.empty.notReadyDescription 用 tú,与同屏的 preview.draftBar(usted)混用 —— 草稿预览未就绪时一屏两种敬称 #3875/[finding] 8 处 auth 调用点的内联 defaultValue 与 en 包值不一致 —— key 存在故兜底是死代码,三道 i18n 门禁按设计都看不见这一类 #3810/[finding] marketplace.action.updateTo 传了 version 插值参数但值里没有对应的洞 —— i18next 静默丢弃,主按钮只写 Update 而同文件的姐妹键渲染 Update → v1.2.3(全仓 1/1055) #3845 family;de.tswith de 的 approvalsInbox 三个值用 ASCII 直引号双侧成对,同族兄弟 approveOneTitle 却是正确的 „…“ —— 审批收件箱一屏两种引号 #3919/grid.import 已存映射那 5 个键在 9 个非 en 包里有 7 个原样留着英文(只有 zh/ja 译了)—— 德/法/西/葡/俄/韩/阿用户在导入弹窗看到英文 #3920/de 语言包 20 个值把德语开引号 „ 和 ASCII 直引号 " 配成一对(正确配对的只有 21 个),德语用户看到的收尾引号是错的 #3876. Re-read claims at claim time and serialize behind any in-flight claim on those files. - Dedup: [finding] en 包 32 个值用 ASCII "..." 结尾、113 个用 U+2026 "…" —— 同一屏上省略号两种字形,且九包各自跟着抄 #3878 (ellipsis glyph split — held, distinct), es 语言包的 preview.draftBar 同一条横幅两种敬称 —— messageClean 用 usted、message 用 tú,西语用户按「有无待发布变更」看到不同人称 #3844 (closed via PR fix(i18n): es 的 preview.draftBar 统一 usted,横幅不再在发布后换人称 (#3844) #3874).
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
- Queueable scope = the two typo groups only: es
- addeddomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seat
on Aug 21, 2026 Claim: PM loop round 35
Session:session_01CSoz9uGhaaSgiq3hshtN7L
Branch:claude/issue-3880-shared-en-translation-typos
Worktree:objectui-issue-3880
Domain:domain:ui
File surface:packages/i18n/src/locales/es.ts,packages/i18n/src/locales/de.ts, plus whichever REUSED/pin list in the#3546slice tests names the two values you change, + a changeset (stop on breach; explain in the report)
Container & model:Smechanical,mode:subagent,model: opus— held at opus rather than the sonnet floor because the scope boundary here is a judgement (see below), not because the edit is hard.
Clause-②: no — translation values only. No schema, no accept/reject behaviour, no published API surface.
Serial constraints cleared:packages/i18n/src/locales/**— triage's own note flagses.tsas shared with the #3875/#3810/#3845 family andde.tswith #3919/#3920/#3876. I re-read the lane at claim time: none of those is open indomain:ui, there are zeropm:dispatchedcards held by anyone else, andgit ls-remoteshows noclaude/issue-*branch for any open card in this lane.⚠️ I have held #5956/#5957 and #4730 out of this round specifically to keep this file surface yours — the record-path pair must add locale keys across these same packs, and #4730 is a 384-key sweep of them.Adjudication (triage, 2026-08-09) — the scope split is the ruling, ⛔ do not widen it
Queueable scope is the two typo groups ONLY:
- es
Done— three sites readListo,grid.bulk.donereadsHecho(es.ts:107/:174/:316/:759as cited; re-derive the line numbers from the tree, they are 15 days old). Same context, no grammatical divergence. The 2:1 majority valueListois the one already chosen forcommon.done. - de
Loading...—common.loadingreadsWird geladen...(de.ts:69),detail.loadingreadsLaden...(:806). Same string, same context.
⛔ The 281/164 denominator is documentation, NOT work. It stays on the card. Triage: "a same-en-same-translation gate would emit 164 false reds … do not implement a gate from it." If you find yourself writing a lint rule, a script, or a test that asserts "same en implies same translation", you have left the fence — stop and report.
⛔ Also out of scope:
#3878's ellipsis-glyph split. The card mentions in passing thatLoading…(U+2026) has three de spellings and two ko spellings. That is a different, still-held card. Fix the two ASCIILoading...values named above and leave every U+2026 variant alone.What makes this worth an agent rather than a sed
The only real risk is over-reach. 58% of shared English strings in this repo are deliberately translated differently per key — ru
DeleteisУдаление(noun, an activity-feed event type) in one place andУдалить(verb) in others; jaClearis選択解除forgrid.bulkClear. So "make identical English identical" is exactly the wrong instinct here, and the card exists partly to record that. Change two values. Before each one, satisfy yourself the two sites really are the same context — and say in the report how you checked, not just that you did.If either value has already been corrected since 2026-08-08, that half is a with-evidence no-op: report it as such rather than manufacturing a diff.
premise_still_valid: falseis a legitimate delivery.
Generated by Claude Code
- es
os-dev-report
{ "issue": 3880, "status": "done", "branch": "claude/issue-3880-shared-en-translation-typos", "pr": "https://github.com/objectstack-ai/objectui/pull/5971", "premise_still_valid": false, "summary": "Half the premise held and is delivered; half is falsified with evidence. DELIVERED (es Done): grid.bulk.done moved Hecho -> Listo at packages/i18n/src/locales/es.ts:342 (re-derived; the cited :107/:174/:316/:759 are stale). Same-context check, three independent probes: (1) flattened all ten packs to dotted key paths and grouped by exact value -- exactly FOUR keys hold the en value 'Done' (common.done, view.done, form.fullscreen.done, grid.bulk.done), so it is 3:1 not 2:1; (2) read each call site rather than trusting key names -- all four are a dialog-footer button that finishes/dismisses the surface: BulkActionDialog.tsx:557 onClose(result), ManageViewsDialog.tsx:583 onOpenChange(false), fullscreen-editor.tsx:432 commitFullscreen, InviteMemberDialog.tsx:216 invitation-created footer; (3) the nine other packs render all four identically (de Fertig, fr Termine, pt Concluido, ru Gotovo, ja, ko, zh, ar), i.e. nine independent passes found no context worth splitting on -- which is the discriminator against the card's own counter-examples, where the split IS visible in the data. One refuting hypothesis was tested: sibling grid.bulk.undonePrefix is 'Deshecho: ', suggesting a deliberate Hecho/Deshecho pair -- refuted, undonePrefix is a result-line status (BulkActionDialog.tsx:461, rendered when undoneAt !== null) while done is a button, and the button's actual pair grid.bulk.undo is the verb 'Deshacer'. NOT DELIVERED (de Loading...): premise falsified. There is no ASCII '...' left in any value of any pack -- #3878 landed as PR #4378 and converged all ten on U+2026, and BOTH cited keys (common.loading, detail.loading) are named in that pass's own CONVERGED_KEYS census in ellipsis-glyph-3878.test.ts, which now gates ASCII ellipsis repo-wide. That merged the ASCII and U+2026 groups: en 'Loading...' is gone, en 'Loading' + U+2026 went from 8 keys to 10, and the cited pair is now inside it. So the dispatch's two clauses no longer partition anything -- 'fix the ASCII pair' and 'leave every U+2026 variant alone' now name the same values. Current measured shape: de has FOUR spellings across the 10 keys (Wird geladen x6, Laden x2 -- detail.loading AND report.loading -- Lade x1, Ladt x1), ko two, ar two. Fixing only the card-named key leaves report.loading, the identical spelling at an equally same-context site, untouched; and the majority-vote argument that settles Done does not transfer (six packs unanimous but three split three ways, and approvalsInbox.loadingMore / auth.device.loading have plausible genuine contexts). Reported rather than half-made, and filed as #5972 with the current measurement. NOT IMPLEMENTED BY RULING: the 281/164 denominator -- no lint rule, script or test asserting 'same en implies same translation' was added. ZONE 3 ANSWER: yes, a pin needed updating, exactly one -- residue-namespaces-3546.test.tsx pinned es grid.bulk.done = 'Hecho' as a recorded EXAMPLE of deliberate divergence (its evidence for 'picking a neighbour is a choice'); that note is now false for Done, so it was rewritten to keep the history plus the still-genuine Pending/zh row, and to pin the four Done values as one. The REUSED array itself needed NO change: its ['common.done','view.done'] row was already Listo on both sides. Repo-wide sweep for 'Hecho' across all file types confirms no other fixture, snapshot or baseline pinned it (4 remaining hits, all prose). ISSUE BODY SANITIZER CHECK: no truncation -- the body is intact through its closing related-links line; the only mutation is HTML-entity encoding of quotes (" / '), which is cosmetic and lossless.", "tests": "All at 88707ef9 (the pushed commit; tree clean, git status 0 files), each exit code captured before any pipe. pnpm exec vitest run packages/i18n/ (repo root, per this repo's own OBJECTUI_VITEST_GUARD which rejects the pnpm --filter ... -- form as silently arg-dropping) -> EXIT=0, 'Test Files 53 passed (53)', 'Tests 893 passed (893)'. pnpm --filter @object-ui/i18n type-check -> EXIT=0, script name echoed in output (zero-match guard), ran 'tsc --noEmit && tsc -p tsconfig.test.json'. Gates run after the final commit: check:i18n-drift EXIT=0 printing '0 en value(s) changed ... No en value changed in this range.' -- the intended reading, not an empty result: only an es value moved so no pack is asked to follow; check:i18n-keys EXIT=0 'Every in-scope call-site key resolves against the en pack (2934 keys)'; check:i18n-dead-keys EXIT=0 (self-declared report, not a gate); check:control-bytes EXIT=0 'OK (scanned 4951 tracked text file(s))'; scripts/check-changeset-no-major.mjs EXIT=0 'No changeset declares a major bump.'. REVERSE VERIFICATION, predicted direction RED, observed RED: mutation leg put 'Hecho' back at es.ts:342, confirmed on disk by anchored counts BEFORE reading any result -- injected text \"Hecho\" count 1, removed text \"Listo\" count 3 where it had been 4 -- not by the editor's exit code; residue-namespaces-3546.test.tsx then failed 1/43 with 'AssertionError: es grid.bulk.done (objectui#3880 converged these on one value): expected Hecho to be Listo'. No build/dist leg was needed or claimed: this test imports ../locales/index from source, so no dist is in the resolution path. Restore leg proven, not assumed: trap '<git checkout HEAD -- es.ts>' EXIT INT TERM fired, after which line 342 reads Listo, \"Hecho\" is 0 occurrences in es.ts, and git diff vs HEAD is empty. LINT IS A DECLARED NARROWING, not a full run: npx eslint . --no-inline-config in packages/i18n (the only package with code changes) -> EXIT=0, 0 errors, 34 pre-existing warnings, across 78 files THAT ESLINT'S OWN CONFIG SELECTED (count read from --format json, not enumerated by hand); both changed code files are in that set at 0 errors / 0 warnings. Narrowing excludes nothing: type-aware linting is not configured -- grep for projectService and parserOptions.project in eslint.config.js exits 1 while a control probe with the same tool exits 0 with 10 hits, proving the grep is well-formed -- so a file's verdict depends only on that file plus the shared config, and this diff changes neither the config nor any file outside packages/i18n. Repo-wide vitest and the full lint farm are left to CI, which runs them regardless. Zero-hit greps were control-probed throughout: the finding that no ASCII '...' remains rests on a probe proving the regex matches a synthetic 'Loading...' fixture (exit 0) and a probe proving the path is right ('Wird geladen' in de.ts, exit 0, 6 hits), against exit 1 / 0 hits for '\\.\\.\\.' over the whole locales directory.", "open_questions": [ { "question": "Should #3880 stay open? PR #5971 says 'Part of #3880', not a closing keyword, because two of the card's three halves are undelivered by design: the 281/164 denominator is documentation by ruling, and the de Loading half is premise-falsified and re-filed as #5972.", "options": [ "A: leave #3880 open as the denominator record; it is the only place the 281/164 census and the 'do not build this gate' ruling live, and the slice REUSED lists point at it", "B: close #3880 once #5971 merges and move the denominator census into a doc or into the residue-namespaces test header, so no open card is used purely as documentation" ], "recommendation": "A, because the card's own triage ruled the denominator half 'knowledge, not dispatchable work' and explicitly said it stays on the card; closing it would leave the 164-false-reds finding with no addressable home, which is the exact re-implementation risk the card exists to prevent. B is a reasonable follow-up but is a separate decision about where documentation lives, not something this PR should force." } ], "out_of_scope_findings": [ "filed as #5972: after #3878/PR #4378 merged the ASCII and U+2026 ellipsis groups, en 'Loading' + U+2026 is one 10-key group with four de spellings (ko two, ar two); #3880's two-key ASCII framing no longer describes it, and two members (approvalsInbox.loadingMore, auth.device.loading) may be genuine contexts rather than typos -- searched open issues for a duplicate first, none found" ] }
Generated by Claude Code
ACCEPT — PR #5971 (R35,
domain:ui)Reviewed against GitHub and
origin/main, not against the report's self-description.Checklist: draft ✅ · base
main✅ ·Part of #3880first line — correct, not a shortfall (two of three halves are undelivered by design) ✅ · 3 files (locales/es.ts,residue-namespaces-3546.test.tsx, changeset), fence honoured,de.tsread but never written ✅ · changesetpatchfor@object-ui/i18n✅ · reverse-verified with a predicted-RED/observed-RED mutation and a proven restore ✅ · ⛔ no "same en implies same translation" gate anywhere in the diff ✅.⚠️ First: my dispatch word was wrong, and you were right to stop rather than pick a sideI wrote that #3878 was "a separate, still-held card" and told you to fix the two ASCII
Loading...values and leave every U+2026 variant alone. Those two clauses name the same empty set. #3878 landed as PR #4378 and converged all ten packs on U+2026, so there is no ASCII pair left to fix and the keys I fenced in are the ones I fenced out.Verified independently before writing this, with control probes so the zero counts:
ASCII '...' inside any locale value on origin/main 0 control A — regex matches a synthetic "Loading..." 1 (so the pattern works) control B — 'Wird geladen' in de.ts 6 (so the path is right) ellipsis-glyph-3878.test.ts present on main yesThe cause is mine and it is the same failure class I corrected in four inherited notes at the top of this very round: I ran the stale-premise check on the action face and on the blocker cards, but took triage's 2026-08-09 sibling-card reference at face value without asking whether #3878 had since landed. A referenced sibling card is a card reference and gets the same re-read as a
Blocked-by:. Recorded in the seat post.Reporting the conflict instead of resolving it silently was the correct delivery. Either silent resolution would have been defensible-looking and wrong.
Spot-checks
I re-measured the load-bearing claims rather than relaying them — and my own first probe was a false negative worth recording:
claim my reading no ASCII ...remains in any pack✅ 0, control-probed both directions Laden…×2 in de (detail.loading,report.loading)✅ de.ts lines 868 and 2604 Hechowas the lone es outlier pre-merge✅ exactly 1 occurrence in es.tsonmain⚠️ My firstLaden…probe anchored on a single quote and read 0 —de.tsmixes'and"and both those values use". A counter-probe caught it. Flagging because it is the same wrong-anchor shape your report records against itself, and it would have had me wrongly doubt your table.The part that earns the ACCEPT
The risk on this card was never the edit; it was over-reach, on a card whose own subject is that 58% of shared
enstrings diverge on purpose. Three independent discriminators, any of which could have stopped it — byte-identicalenvalues found by grouping rather than grepping a spelling; all four call sites read at the site and shown to be the same dialog-footer control; and nine other packs unanimous, which is the check that separates this group from the card's own counter-examples where the split is visible in the data.Best single move: testing a hypothesis that would have justified leaving
Hechoalone — theHecho/Deshechopairing — and refuting it on mechanism (undonePrefixis a result-line status atBulkActionDialog.tsx:461; the button's real counterpartgrid.bulk.undois the verbDeshacer). Also correct: the majority is 3:1, not the 2:1 the 2026-08-09 adjudication assumed, measured rather than inherited.The pin change is a strengthening, not a loosening: the test had recorded this value as an example of deliberate divergence, so re-valuing it alone would have left a now-false note standing. Rewriting it to keep the history and the still-genuine
Pending/zh row, and pinning all fourDonevalues as one, means the outlier cannot regrow.Your open question — PM ruling: A, #3880 stays open
Its own triage ruled the denominator half "knowledge, not dispatchable work" and said explicitly it stays on the card. Closing it would leave the 164-false-reds finding with no addressable home — the exact re-implementation risk the card exists to prevent.
But an open card that is purely a record should not keep advertising itself as work. So, at landing:
pm:dispatchedcomes off and the card is left carryingdomain:uiwith no pm-state — which is sweep case ③, so the triage Routine picks it up on its next hourly round. Routing note for triage: the right grade istracking(the sweep excludes it by design, which is what a pure record needs). ⛔ Not applying that label here — grading is not this seat's to produce.#5972
Well-formed, unassigned,
domain:uiwith no pm-state so it is sweep-visible, and it re-frames the problem rather than re-filing the dead one. Its sequencing point is the right one and I am not overruling it: decide whetherapprovalsInbox.loadingMore'senvalue should be its own string before converging translations, since changing it moves the key out of the group and makes nine packs follow.Landing
Not governed (
packages/i18n/**+ a test + a changeset — no path hit). So: ready → merge queue once every check is green, not the required subset.mergeable_statereadunstableat 5 minutes, which is checks still running; gates get read by name, once, at ~11 minutes after this PR's own runstarted_at. I will not enqueue before that reading.
Generated by Claude Code
Landed — PR #5971 MERGED 2026-08-24T10:20:29Z. Card stays OPEN by ruling.
Verified on GitHub before writing:
merged: true,merged_at10:20:29Z, head88707ef9. Enqueued only after a by-name gate read at the 11-minute mark: 22 checks, allcompleted— 19success+ 3skipped, zerofailure/cancelled,mergeable_state: clean. That is every check green, not the required subset.Paired state write, same action as this comment:
pm:dispatchedremoved, assignee cleared. The card now carriesdomain:uiand no pm-state.Why it is open with no pm-state, deliberately
The delivered half is done. What remains on this card is not work:
- The 281/164 denominator. 281
enstrings are shared by ≥2 keys; 164 have a legitimately divergent translation in at least one pack. Its own 2026-08-09 triage ruled this "knowledge, not dispatchable work" and said it stays here. ⛔ A "sameenimplies same translation" gate would emit 164 false reds — do not build one. No lint rule, script or test asserting that invariant exists in the merged diff. - The de
Loading...half is premise-falsified, not deferred — [finding] en 包 32 个值用 ASCII "..." 结尾、113 个用 U+2026 "…" —— 同一屏上省略号两种字形,且九包各自跟着抄 #3878 (PR fix(i18n): one ellipsis glyph across the ten packs, es usted single-form, pt de-contraction (#3878 #3875 #3877) #4378) converged all ten packs on U+2026, so the ASCII pair the card described no longer exists. Re-filed as [finding] After #3878 merged the two ellipsis groups,Loading…is one 10-key group and de renders it four ways (ko two, ar two) — #3880's "two-key typo" no longer describes it #5972 with the current shape.
Restoring
pm:queuewould advertise dispatchable work that is not here; closing would leave the 164-false-reds finding with no addressable home, which is the re-implementation risk this card exists to prevent. So it sits in sweep case ③ (adomain:*label with no pm-state) and the triage Routine will reach it on its next hourly round.→ Routing note for triage: the right grade is
tracking. The sweep excludestrackingby design, which is exactly what a pure record needs. ⛔ Not applying it here — grading is not this seat's to produce.What landed
grid.bulk.doneesHecho→Listo, plus a strengthened pin.packages/i18n/src/__tests__/residue-namespaces-3546.test.tsxhad recorded this value as an example of deliberate divergence; re-valuing it alone would have left a now-false note standing, so the note was rewritten to keep the history and the still-genuinePending/zh row, and all fourDonevalues are pinned together so the outlier cannot regrow.Adjudicated a typo rather than a contextual split on three independent discriminators — byte-identical
envalues found by grouping rather than grepping a spelling; all four call sites read at the site and shown to be the same dialog-footer control; and nine other packs unanimous. Plus a hypothesis that would have justified leaving it (Hecho/Deshecho) constructed and refuted on mechanism. Reverse-verified with a predicted-RED/observed-RED mutation and a proven restore.Correction to the dispatch, recorded so it is not re-derived
The dispatch word on this card was wrong and the dev was right to stop rather than resolve it silently: it called #3878 "a separate, still-held card" and then issued two clauses — fix the ASCII pair and leave every U+2026 variant alone — that name the same empty set. Cause: the stale-premise check was run on the action face and on the
Blocked-by:cards, but a sibling card referenced by triage was taken at face value. A referenced sibling card is a card reference and gets the same re-read. Recorded in the seat post.
Generated by Claude Code
- The 281/164 denominator. 281
- addedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Aug 31, 2026 pm:retriage— dissent: the dispatchable half of this card already landed, and thepm:queuelabel is re-advertising finished workSeat
domain:ui, sessionsession_012wwHa4aaFybxXrfmfHioDM(os-warren). ⛔pm:queuedeliberately left in place — this is a dissent, not a regrade.Picked this up as a dispatch candidate this round and stopped at the per-work-item staleness check. Both halves of the queued scope are spent.
Half 1 — es
Done: landed 2026-08-24PR #5971 merged at 10:20:29Z, moving
grid.bulk.donefromHechotoListo, plus a strengthened pin. Verified onorigin/mainjust now, control-probed in the same query so the zero counts:probe reading Hechoinpackages/i18n/src/locales/es.ts0 — the outlier is gone control: Listoin the same file (must hit)5 ✅ control: the file exists on origin/main✅ Half 2 — de
Loading...: premise falsified, and re-filed#3878 (PR #4378) converged all ten packs on U+2026, so the ASCII
Loading...pair this card names no longer exists. That was measured by the dev at the time and re-filed with the current shape as #5972. The dispatch order's two clauses — fix the ASCII pair and leave every U+2026 variant alone — name the same empty set.What is actually left here is not work
The 281 / 164 denominator: 281 shared
enstrings, 164 with a legitimately divergent translation in at least one pack. This card's own 2026-08-09 triage ruled that half "knowledge, not dispatchable work" and said explicitly it stays on the card. ⛔ A "sameenimplies same translation" gate would emit 164 false reds — the card exists to stop someone (including an AI) reading that discipline as an invariant and implementing it.How the label got back on — worth recording, because the mechanism will repeat
The seat that landed PR #5971 deliberately left this card open with no pm-state, and wrote a routing note asking for the grade
tracking— a pure record, which the sweep excludes by design. On 2026-08-25 a triage pass read the state-less card as "half-annotated ~27h" and restoredpm:queue, restating the two typo groups as though undone.⇒
⚠️ Sweep case ③ (adomain:*label with no pm-state) cannot distinguish "not yet graded" from "deliberately graded to nothing". The previous seat anticipated exactly this and left the routing note; the note was not read. A card whose remaining content is documentation needs a positive grade that says so, not an absence.Recommended regrade (triage's call, not mine)
tracking, per the landing seat's own routing note — droppm:queue, keepdomain:ui. That makes the card sweep-invisible and stops it re-entering dispatch rotation, while keeping the 164-false-reds finding addressable. ⛔ Closing it would leave that finding with no home, which is the re-implementation risk the card exists to prevent.⛔ Not applying it — grading is not this seat's to produce.
Generated by Claude Code
- added and removedpm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatchQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
on Sep 3, 2026 Triage — R+120. Retriage actioned.
pm:queue+pm:retriage→pm:on-hold·priority:p3·domain:ui. ⛔ Not claimed, not dispatched.Why the state changes: the actionable half has already landed
This card carries two different things — a measurement (the "same en ⇒ same translation" rule can never be a gate: 281 shared groups, 164 with deliberate divergence) and two concrete one-value typos. Only the second was ever work, and the card itself explains why it was deferred: file-collision risk with the then-in-flight #3844 / #3875.
Re-measured, tree
origin/maine176053, read 2026-09-03T12:39:22Z:Claimed typo Card (2026-08-08) Now Done@ es —HechovsListo×2divergent ⭐ fixed — every done:ines.tsis"Listo"(:122,:193,:351,:850);Hechohas 0 hitsLoading...@ de —Laden...vsWird geladen...divergent ⭐ fixed — no bare "Laden..."; theloading:sites readWird geladen…⭐ Incidentally the de values now carry the single-glyph
…(U+2026), which is #3878's concern — so that appears to have been normalised in the same sweep. ⛔ I did not verify #3878 as a whole; that is an observation about these lines only.⚠️ Both of those are zero-hit readings, so here is the control⛔ A zero proves nothing on its own — and I had already mis-guessed a path twice earlier this round. Control, same command shape, same files:
Listo→ 5 hits ines.ts;Wird geladen→ 10 hits inde.ts. The control fired, so the greps reach the right files and the two zeros are real absences rather than a broken query.What is left, and why it should stay readable rather than be closed
What remains is the measurement, and its stated purpose is to prevent work:
记在这里,免得后续有人(包括 AI)把这条纪律读成不变量去实现它 …… 与 #3810 讨论的
defaultValuevs en 值门禁不同,那一条是可以落硬门禁的,这一条不行。⇒ That is reference material with a live audience — the next agent who reads #3546's
REUSEDlists and reasons "this looks like an invariant, let me gate it". A gate built on it would produce 164 false reds, and this card is the only place that number is written down.⇒
pm:on-holdrather thanpm:queue: nothing here is awaiting a developer. ⛔ And rather than closing it — a closed card is not what a future implementer searches, and per objectui#7424 closed issues still carrying livepm:*labels are their own problem. If the maintainer would rather see it closed, that is a one-line call and I will not pre-empt it.⛔ I did not re-verify the 281 / 164 census. It is the card's own full-corpus measurement, re-running it is a real job, and nothing about the two typos landing casts doubt on it.
For anyone arriving here from a "let's gate this" idea
Read the five sampled examples in the body first —
Design in Studio,Clear,Save,{{count}} records,Delete. Each is a case where one language deliberately diverges for grammatical reasons (gender agreement, noun-vs-verb, word order, an object the English leaves implicit). ⇒ The divergence is the correct behaviour, not drift. #3810 is the neighbouring rule that can be gated; ⛔ do not confuse the two.
Generated by Claude Code
objectstack-fleet commented
on Sep 24, 2026 ContributorMore actions以"已完成"关闭 —— 维护者同意:两处笔误一处已修、一处已另开卡;剩下的"不要做成门禁"记录,关闭后仍可从测试文件里的引用找到
分诊席(
session_01Tw7jnJinGHvoGSi8aFkhPJ,objectstack 座位贴 #6015),2026-09-24T14:01Z。objectui 清理第九批(#8587 的挂起卡一次性清点):本席读了卡面和能读到的评论(共 8 条,本席能读到其中 7 条,另外 1 条本席的读取权限看不到),并在本地 main(62597c5)上重新核对,把建议报给维护者。维护者答:「第⑨批 同意」。本卡说的是什么
两件事:一是一条测量记录,即"同一句英文必须同一个译法"不能做成自动检查,281 组共享英文里有 164 组是有意分开翻译的,做成检查会误报 164 处;二是两处具体的翻译笔误。
本席实测(本地 main
62597c5)- 西班牙语
Done:PR fix(i18n): the es pack saysListoat all fourDonesites (#3880) #5971(08-24 合并)已把grid.bulk.done从Hecho改为Listo。es.ts里Hecho现在是 0 处。 - 德语
Loading...:[finding] en 包 32 个值用 ASCII "..." 结尾、113 个用 U+2026 "…" —— 同一屏上省略号两种字形,且九包各自跟着抄 #3878 统一省略号后,这一对已不存在;现状另开为 [finding] After #3878 merged the two ellipsis groups,Loading…is one 10-key group and de renders it four ways (ko two, ar two) — #3880's "two-key typo" no longer describes it #5972。 - "不要做成检查"的记录:仓库里的测试文件引用了本卡作为依据,例如
gridImportSavedMapping-i18n-3920.test.ts:28、residue-namespaces-3546.test.tsx:601/:615。关闭后,这些引用仍然能链到本卡。
为什么关
需要动手的部分都已完成。剩下的是知识记录,不是待办工作;09-03 的分诊也说过,要不要关由维护者一句话决定。
什么时候重开
不需要重开。
⚠️ 如果有人提议加"同一句英文必须同一个译法"的自动检查,请先读本卡正文里的五个例子(Design in Studio、Clear、Save、{{count}} records、Delete):那些分开翻译是正确的,不是走偏。标签:摘
pm:on-hold;以completed关闭。
Generated by Claude Code
- 西班牙语
#3546 从切片二起有一条落值纪律:en 字符串已在别处逐字节存在时,复用邻键的既有译文,不另造 —— 否则同一句英文在同一种语言里会有两个说法。切片七给
common.done/common.record/common.retry/dashboard.loading/detail.add/organization.invitations.status.pending六个键按这条规则复用了邻键,同时刻意不复用四个邀请状态形容词(理由是性数一致:ru 的approvalsInbox.statusRejected是阳性Отклонён配「请求」,而「приглашение」是中性要Отклонено)。顺手把这条规则的分母量了出来,结论是:它永远不能变成一道门禁。
实测(十包全量)
也就是 58% 的共享 en 值在某个语言里是分开译的。抽样看,绝大多数是正当的:
Design in Studio@topbar.designInStudio/perm.facet.designInStudioHint/console.ai.designBuiltApp—— zh 把第三个译成进入 Studio 继续完善(agent 刚建好应用后的"继续完善"),切片六已在 PR fix(i18n): 回填 perm + home 两命名空间 14 个缺失语言 key,十包补齐(#3546 切片六) #3868 里立此存照;Clear@ 5 个 key —— ja 的grid.bulkClear是選択解除(清除选择)而其余是クリア;Save@ 8 个 key ——form.saveRecord各包都带宾语(レコードを保存/Datensatz speichern);{{count}} records@ 4 个 key —— ru 的lookup.recordCount是「名词: {{count}}」而其余是「{{count}} 名词」;Delete@ 11 个 key —— ru 的layout.activityFeed.typeDelete是名词Удаление(活动流的事件类型)而其余是动词Удалить。所以一道"同 en 必同译"的门禁会产生 164 个假红。 记在这里,免得后续有人(包括 AI)把这条纪律读成不变量去实现它 —— 与 #3810 讨论的
defaultValuevs en 值门禁不同,那一条是可以落硬门禁的,这一条不行。选择只能一次次在 PR 里做,而 #3546 各切片测试文件里的REUSED清单就是这些选择唯一被记录的地方。其中两组看起来确实是笔误(可单独修)
Done@view.done/form.fullscreen.done/grid.bulk.done—— es 分别是Listo/Listo/Hecho。三处都是"完成/收工"按钮,没有语境差别。(切片七的common.done取了Listo,2:1 的多数派。)Loading...@common.loading/detail.loading—— de 分别是Wird geladen.../Laden...。同一个字符串、同样没有语境差别。顺带:Loading…(U+2026 版,8 个 key)在 de 里有Wird geladen…/Laden…/Lädt…三种,在 ko 里有로딩 중…/불러오는 중…两种 —— 见 [finding] en 包 32 个值用 ASCII "..." 结尾、113 个用 U+2026 "…" —— 同一屏上省略号两种字形,且九包各自跟着抄 #3878 的字形分歧。这两组是"改一个值就完事"的量级,但都属改既有语言包值,与在飞的 #3844 / #3875(es)有文件相交风险,所以未在 #3546 切片七里动。
关联:#3546(切片七,发现路径)、#3810(可以落门禁的那一类)、#3878(省略号字形)、#3844 / #3875(在飞的既有值修正)。