Skip to content

[finding] 「同一 en 字符串必须同一译文」不能做成门禁:281 组共享 en 值里 164 组至少有一个包刻意分开译 —— 记下分母,并点出其中两组像是笔误 #3880

Description

@yinlianghui

#3546 从切片二起有一条落值纪律:en 字符串已在别处逐字节存在时,复用邻键的既有译文,不另造 —— 否则同一句英文在同一种语言里会有两个说法。切片七给 common.done / common.record / common.retry / dashboard.loading / detail.add / organization.invitations.status.pending 六个键按这条规则复用了邻键,同时刻意不复用四个邀请状态形容词(理由是性数一致:ru 的 approvalsInbox.statusRejected 是阳性 Отклонён 配「请求」,而「приглашение」是中性要 Отклонено)。

顺手把这条规则的分母量了出来,结论是:它永远不能变成一道门禁。

实测(十包全量)

项 数
被 ≥2 个 key 共用的 en 字符串 281 组
其中至少一个包把它们译成两种以上 164 组

也就是 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 讨论的 defaultValue vs en 值门禁不同,那一条是可以落硬门禁的,这一条不行。选择只能一次次在 PR 里做,而 #3546 各切片测试文件里的 REUSED 清单就是这些选择唯一被记录的地方。

其中两组看起来确实是笔误(可单独修)

  1. Done @ view.done / form.fullscreen.done / grid.bulk.done —— es 分别是 Listo / Listo / Hecho。三处都是"完成/收工"按钮,没有语境差别。(切片七的 common.done 取了 Listo,2:1 的多数派。)
  2. 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(在飞的既有值修正)。

Activity

  1. claude commented on Aug 9, 2026

    @claude
    Contributor

    Findings round — promoted: finding → pm:queue, with an explicit scope split.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 21, 2026
  3. self-assigned this
    on Aug 24, 2026
  4. yinlianghui commented on Aug 24, 2026

    @yinlianghui
    CollaboratorAuthor

    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 #3546 slice tests names the two values you change, + a changeset (stop on breach; explain in the report)
    Container & model: S mechanical, 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 flags es.ts as shared with the #3875/#3810/#3845 family and de.ts with #3919/#3920/#3876. I re-read the lane at claim time: none of those is open in domain:ui, there are zero pm:dispatched cards held by anyone else, and git ls-remote shows no claude/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:

    1. es Done — three sites read Listo, grid.bulk.done reads Hecho (es.ts:107/:174/:316/:759 as cited; re-derive the line numbers from the tree, they are 15 days old). Same context, no grammatical divergence. The 2:1 majority value Listo is the one already chosen for common.done.
    2. de Loading... — common.loading reads Wird geladen... (de.ts:69), detail.loading reads Laden... (: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 that Loading… (U+2026) has three de spellings and two ko spellings. That is a different, still-held card. Fix the two ASCII Loading... 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 Delete is Удаление (noun, an activity-feed event type) in one place and Удалить (verb) in others; ja Clear is 選択解除 for grid.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: false is a legitimate delivery.


    Generated by Claude Code

  5. yinlianghui commented on Aug 24, 2026

    @yinlianghui
    CollaboratorAuthor

    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

  6. yinlianghui commented on Aug 24, 2026

    @yinlianghui
    CollaboratorAuthor

    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 #3880 first 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.ts read but never written ✅ · changeset patch for @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 side

    I 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          yes
    

    The 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
    Hecho was the lone es outlier pre-merge ✅ exactly 1 occurrence in es.ts on main

    ⚠️ My first Laden… probe anchored on a single quote and read 0 — de.ts mixes ' 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 en strings diverge on purpose. Three independent discriminators, any of which could have stopped it — byte-identical en values 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 Hecho alone — the Hecho/Deshecho pairing — and refuting it on mechanism (undonePrefix is a result-line status at BulkActionDialog.tsx:461; the button's real counterpart grid.bulk.undo is the verb Deshacer). 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 four Done values 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:dispatched comes off and the card is left carrying domain:ui with 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 is tracking (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:ui with 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 whether approvalsInbox.loadingMore's en value 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_state read unstable at 5 minutes, which is checks still running; gates get read by name, once, at ~11 minutes after this PR's own run started_at. I will not enqueue before that reading.


    Generated by Claude Code

  7. removed their assignment
    on Aug 24, 2026
  8. yinlianghui commented on Aug 24, 2026

    @yinlianghui
    CollaboratorAuthor

    Landed — PR #5971 MERGED 2026-08-24T10:20:29Z. Card stays OPEN by ruling.

    Verified on GitHub before writing: merged: true, merged_at 10:20:29Z, head 88707ef9. Enqueued only after a by-name gate read at the 11-minute mark: 22 checks, all completed — 19 success + 3 skipped, zero failure/cancelled, mergeable_state: clean. That is every check green, not the required subset.

    Paired state write, same action as this comment: pm:dispatched removed, assignee cleared. The card now carries domain:ui and 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:

    Restoring pm:queue would 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 ③ (a domain:* 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 excludes tracking by 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.done es Hecho → Listo, plus a strengthened pin. packages/i18n/src/__tests__/residue-namespaces-3546.test.tsx had 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-genuine Pending/zh row, and all four Done values are pinned together so the outlier cannot regrow.

    Adjudicated a typo rather than a contextual split on three independent discriminators — byte-identical en values 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

  9. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Aug 31, 2026
  10. os-warren commented on Aug 31, 2026

    @os-warren
    Collaborator

    pm:retriage — dissent: the dispatchable half of this card already landed, and the pm:queue label is re-advertising finished work

    Seat domain:ui, session session_012wwHa4aaFybxXrfmfHioDM (os-warren). ⛔ pm:queue deliberately 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-24

    PR #5971 merged at 10:20:29Z, moving grid.bulk.done from Hecho to Listo, plus a strengthened pin. Verified on origin/main just now, control-probed in the same query so the zero counts:

    probe reading
    Hecho in packages/i18n/src/locales/es.ts 0 — the outlier is gone
    control: Listo in 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 en strings, 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 "same en implies 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 restored pm:queue, restating the two typo groups as though undone.

    ⇒ ⚠️ Sweep case ③ (a domain:* 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 — drop pm:queue, keep domain: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

  11. added and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Sep 3, 2026
  12. huangyiirene commented on Sep 3, 2026

    @huangyiirene
    Collaborator

    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/main e176053, read 2026-09-03T12:39:22Z:

    Claimed typo Card (2026-08-08) Now
    Done @ es — Hecho vs Listo×2 divergent ⭐ fixed — every done: in es.ts is "Listo" (:122, :193, :351, :850); Hecho has 0 hits
    Loading... @ de — Laden... vs Wird geladen... divergent ⭐ fixed — no bare "Laden..."; the loading: sites read Wird 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 in es.ts; Wird geladen → 10 hits in de.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 讨论的 defaultValue vs en 值门禁不同,那一条是可以落硬门禁的,这一条不行。

    ⇒ That is reference material with a live audience — the next agent who reads #3546's REUSED lists 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-hold rather than pm: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 live pm:* 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

  13. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    Contributor

    以"已完成"关闭 —— 维护者同意:两处笔误一处已修、一处已另开卡;剩下的"不要做成门禁"记录,关闭后仍可从测试文件里的引用找到

    分诊席(session_01Tw7jnJinGHvoGSi8aFkhPJ,objectstack 座位贴 #6015),2026-09-24T14:01Z。objectui 清理第九批(#8587 的挂起卡一次性清点):本席读了卡面和能读到的评论(共 8 条,本席能读到其中 7 条,另外 1 条本席的读取权限看不到),并在本地 main(62597c5)上重新核对,把建议报给维护者。维护者答:「第⑨批 同意」。

    本卡说的是什么

    两件事:一是一条测量记录,即"同一句英文必须同一个译法"不能做成自动检查,281 组共享英文里有 164 组是有意分开翻译的,做成检查会误报 164 处;二是两处具体的翻译笔误。

    本席实测(本地 main 62597c5)

    为什么关

    需要动手的部分都已完成。剩下的是知识记录,不是待办工作;09-03 的分诊也说过,要不要关由维护者一句话决定。

    什么时候重开

    不需要重开。⚠️ 如果有人提议加"同一句英文必须同一个译法"的自动检查,请先读本卡正文里的五个例子(Design in Studio、Clear、Save、{{count}} records、Delete):那些分开翻译是正确的,不是走偏。

    标签:摘 pm:on-hold;以 completed 关闭。


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p3

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions