test(i18n): extend the Chinese term guard to status names and field labels - #1529
Merged
Merged
Conversation
…abels #837 landed the mechanism scoped to object names. This extends `TERMS` to `status.options.*` and field `label`s — the four defects #802 was filed on — and answers that card's open question 2: mechanism prose is spared by ledger granularity (the complete term), not by syntactic position. Measured, not assumed: 71 lines carry 到期 and 14 carry 呈现 across the 134 Chinese pages; zero carry 已到期, 过期日期 or 已呈现. The narrowing the card proposed (status-table cells plus `**bold**` refs) would have missed six of the nineteen historical defect sites, which carried no markup at all. The extension found one live defect: `crm_quote.crm_contact.help` in the zh-CN pack quoted 「已呈现」, a status the console does not show — introduced by #1017 (landed as #1068) after #794 had swept the repo clean of that spelling. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019hUuCQStzXGMFSX4dzww5t
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
os-sales
marked this pull request as ready for review
September 3, 2026 08:42
This was referenced Sep 3, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #802
Extends the Chinese term guard from object names to
status.options.*and fieldlabels, answers the card's open question 2, and corrects the one live defect the extension found.#837 built the mechanism (
test/docs-object-term-consistency.test.ts) and scoped it to object names. #802 was filed on four defects one level down —presentedwritten 已呈现/已呈現 (#765 §3),expiredwritten 已到期 on two separate pages (#793 and #801 甲),expiration_datewritten 过期日期 (#801 乙) — every one of them caught by a human reading a page, none by a machine.Question 2, answered: word grain, not markup position
The card would not be dispatched until this was settled, because a status term collides with prose in a way an object name does not: 到期日期 is a field label and must follow the pack, while 每日到期扫描, 自动到期, 报价单到期, 即将到期 and 到期日 are mechanism names that must not be touched. The card proposed narrowing the scan to status-table cells and
**bold**references. That narrowing was measured and rejected as the weaker rule.It is not needed for quiet. The collision is always on the ROOT, never on the whole retired spelling. Measured across the 134 Chinese pages on
9f59f6a:A status name and a field label are complete words, so a ledger of complete words discriminates on its own.
ALLOWEDstays empty — re-measured after the extension, not inherited.It is not safe. Reconstructed from the three fix commits (
483dbb4d,5596c6cc,36765f21), six of the nineteen historical defect sites carried no markup at all:不要更改已呈现报价上的定价——它会让客户困惑。(both scripts)超過有效期的報價每晚會被自動標記為已到期。系统会将任何过期日期已过的报价标记为**已过期**— the defect is in the unmarked half of the line✅ 检查有效期(过期日期)是否与你的业务周期相匹配。| **条款与有效期** | 报价日期、过期日期、付款条款、运输条款 |Narrowing by position would have dropped about a third of the defects the guard exists for, and #801 甲 is on record that this class is consumed across pages rather than within one.
The boundary is pinned, not promised. A
SPAREDledger names the mechanism prose thepresentedandexpiredsweeps had to leave alone, requires each phrase to still be in the corpus, and requires no retired spelling to be a substring of any of them. Retire a bare 到期 or 呈现 and the failure lands there, on legitimate prose, instead of landing in CI across the whole corpus — the noisy-gate-gets-silenced outcome #736 recorded and this card was held for.The live defect the extension found
src/translations/zh-CN.ts, one word, and that is a declared deviation from the dispatched file surface (which named the pack read-only). Flagging it rather than burying it, because the PR does not stand without it:crm_quote.crm_contact's help text told Chinese users a quote had to reach 「已呈现」 — a status the console has never shown. The pack's ownstatus.options.presentedsays 已提交, thirteen lines above the sentence contradicting it. No source-of-truth value is changed here: the option value already said 已提交, and the prose is moved onto it, not the reverse.It is the fifth instance of this card's defect class, and it is the strongest argument on the card. #794 swept the repository clean of 已呈现 and said so. The sentence above was introduced after that sweep, by a feature PR (#1017, landed as #1068), and has been on screen ever since. A careful grep is right on the day it runs; this is what a standing gate is for.
Cross-locale, zh-CN was the only pack whose help text disagreed with its own option value —
ensays Presented/Presented,ja-JPsays 提示済み/提示済み. (es-ESsays Presentado against options Presentada/Aceptada; filed separately, ⛔ not touched here.)Reverting that one line makes this PR red. It is not a drive-by nicety that can be dropped; if the maintainer wants the pack change to travel on its own card, the guard's
presentedpin has to travel with it.Acceptance evidence: each historical defect injected, guard observed red
⛔ Not optional per the card — it exists because this class was caught four times by human eyes and zero times by machine. Each injection asserts it landed on disk (blob-hash change plus anchored counts on the removed and injected text) before any red or green is trusted, and each restore is proved by hash equality plus an empty
git diff HEAD.presented→ 已呈现 (#765 §3)from every zh-Hans pageexpired→ 已到期 (#793)from every zh-Hant pageexpiration_date→ 过期日期 (#801 乙)from every zh-Hans pageexpired→ 已到期 on a second page (#801 甲)from every zh-Hant pagegit diff HEADemptyThe fourth row is the #801 甲 regression specifically: the same word on
sales/index.zh-Hant.mdx, the page a per-page human sweep missed.The pack defect was observed the same way, before it was corrected: on the first run of the extended guard the tree was red on exactly one assertion,
src/translations/zh-CN.ts:543: 已呈现, with 32 of 33 passing.grep -con a pattern holding**and|, which BRE swallowed: the counts read 0 → 0 while the blob hash moved, so the script refused the reading rather than reporting it. Re-run withgrep -cF, all four landed and all four were re-measured. ThetraponEXIT INT TERM— not the inline path — is what restored the file that aborted mid-run.Smaller mechanics
fields.status.options.presented) and the path is resolved, not trusted, so a typo cannot quietly produce a pin that guards nothing.hant: nulldeclares a term identical in both scripts (已提交 and 到期日期 share every character) and the declaration is verified by requiring the Simplified spelling to appear on the Traditional pages. It is also the one value the mistakehant !== hansexists to catch cannot produce — filling the column in wrongly yields a string, notnull.crm_quote's ledger list is[]because it was measured: notest/**ledger writes 报价单 at all. An object must still have an entry, so adding aTERMSrow forces that look.crm_case在中文文档里有三种叫法:语言包「服务案例」、25 个页面「工单」、14 个页面「案例」(两页同页混用) #837's five, holding the same anti-vacuity line: every pinned path resolves, every row retires at least one spelling somewhere, and the corpus still carries the roots the criterion has to discriminate against.Not in this PR
scripts/check-source-token-ratchet.mjsis untouched — it is Pin the two declined-re-anchoring figures in the ratchet header — #1341 reflowed them into worked rows on purpose, and the pin belongs beside the existing header-table pin, not in a second parser #1344's edit target, andstripCommentsneeded no behaviour change.es-EShelp/option mismatch is the same defect class in another locale; filed separately and deliberately not carried here.Verification
pnpm verifygreen on this tree: 158 test files, 3330 passed / 1 skipped,✓ source hygiene clean,✓ source token ratchet clean,✓ i18n lint gate: 0 i18n/missing-* issues. Re-run on headd46ab561(tree5a9081e5, working tree clean).🤖 Generated with Claude Code
https://claude.ai/code/session_019hUuCQStzXGMFSX4dzww5t
Generated by Claude Code