来源:#793 实施过程中的观察。不是用户今天会踩到的新缺陷,是缺一道闸 ,且下面第 2 点是个未定的设计问题,故打 finding 不排期。
现象
同一个缺陷类在一周内出现四次,每次都是有人在改别的东西时顺手撞见的:
四次都落在同一个对象附近 ,而且是逐层被别的工作带出来的:#793 是修 #765 时撞见的,#801 是修 #793 时撞见的。这不是偶发笔误,是没有任何东西在检查这条事实:文档里写的状态名/字段标签,必须就是用户在界面上看到的那个词。
#801 甲 尤其说明问题:状态名是跨页消费 的,而人工排查是按页 做的。#794 修 presented 时扫了全仓(现在全仓 grep 已呈现|已呈現 零命中,确实干净),expired 这一轮的立单只点了一页,隔壁 index 页就漏了。靠「这次记得扫全仓」维持,等于没有保障。
为什么现有闸门看不见
test/docs-drift.test.ts 钉的是 flow 里的阈值与 cron 出现在 src/docs/*.md 里;它不读 content/docs/,也不读语言包。
同文件的 dashboards 规则只比对磁贴标题 ,且按其自身注释,**Name** tile 那条散文规则只在英文页开火(docs-drift 的 **Name** tile 散文规则只在英文页开火——zh 页正文里的磁贴引用无人检查 #725 记的就是这个缺口)。
「译文保留英文页 callout 数量」那条只数 > 块——按它自己的说明,那是结构不是词汇 ,刻意不管用词。
os validate / pnpm lint 走 src/ 里的元数据,从不打开 content/docs/。
所以这条事实目前零覆盖,四次都只能靠人。
动手前要先答的两个问题
朴素形状是:从 zh-CN.ts 取某对象的 status.options.* 与字段 label,断言 zh 文档页只用这些词。但有两个真问题,不先答就写不出一道「不吵」的闸:
zh-Hant 没有语言包。 src/translations/ 只有 en / zh-CN / es-ES / ja-JP,zh-Hant 页的事实来源是 zh-CN 的繁体化写法(quotes.zh-Hant.mdx 把 expired 译成「已到期」,语言包 zh-CN.ts 是「已过期」 #793 正文已确认这一点)。要么引入简繁映射(新依赖,且一简对多繁的坑),要么这道闸只覆盖 zh-Hans——而上述四例里有三例(同一缺陷类:contacts.mdx 的传真字段/传真退订、leads.mdx 的 0-100 评分与 budget/timeline 字段,在对象声明里都不存在 #765 §3 的一半、quotes.zh-Hant.mdx 把 expired 译成「已到期」,语言包 zh-CN.ts 是「已过期」 #793 、#793 的同一缺陷类在其文件面之外还剩两处:sales/index.zh-Hant 的「已到期」,与 quotes.zh-Hans 的「过期日期」×4 #801 甲)恰恰在 zh-Hant,也就是漏掉出问题更多的那半边。
动词/机制名必须豁免。 「到期日期」是字段名要跟包,「每日到期扫描」「自动到期」「报价到期」是机制名不能动;presented 那轮同理放过了「呈现时刻」「以看板呈现」。逐字全文 grep 必然把这些全报成误报,而按 forecasting.zh-Hans/zh-Hant 相对英文页存在早于 #627 的整页漂移 —— 桶语义、承诺定义、缺失的汇总提示框需要整页重译 #736 写下的经验,指标一吵,这道闸就会被静音 。需要一个只在「该词被当作状态名或字段名使用」时才开火的判据(例如只扫状态表的单元格、以及 **加粗** 的字段/状态引用),而不是全文扫描。
在这两点定下来之前不宜动手:写一道会误报的闸,比没有闸更糟。
Refs #793 , #801 , #765 , #725
⭐ R29 更新(2026-09-03,repo:hotcrm 执行席)—— 上面第 1 问已被 #837 答掉 ,第 2 问没有
⛔ 上面「动手前要先答的两个问题」写于立单时,现在只剩一个。#837 落地(PR #1525 ,main @ 9f59f6a)带来了 test/docs-object-term-consistency.test.ts,本卡要的闸已经存在 ,范围收在「对象名」这一层。详情见本卡下方 R29 解锁评论,要点:
派发形状 :扩展点是 TERMS ledger(一个对象一条)。所以本卡不再是「设计一道闸」,而是①把 TERMS 扩到 status.options.* 与字段 label;②答第 2 问;③以本卡的四个历史案例做回归证据 ——presented/expired/expiration_date 各注入一次,守卫必须变红。⛔ ③ 不可选:本卡存在的理由就是这四次全靠人眼撞见。
来源:#793 实施过程中的观察。不是用户今天会踩到的新缺陷,是缺一道闸,且下面第 2 点是个未定的设计问题,故打
finding不排期。现象
同一个缺陷类在一周内出现四次,每次都是有人在改别的东西时顺手撞见的:
quotes.zh-Hans.mdx/quotes.zh-Hant.mdx把presented译作「已呈现/已呈現」,语言包是「已提交」(PR docs(sales): 按对象/流程/语言包重写联系人退订、线索评分与 zh 版 presented 状态名 (#765) #794 修,两页共 6 处)。quotes.zh-Hant.mdx把expired译作「已到期」,语言包是「已过期」(PR docs(sales): quotes.zh-Hant 的 expired 状态名跟语言包写作「已過期」(#793) #803 修,2 处)。sales/index.zh-Hant.mdx:44上同一个expired、同一个错词,只是在另一页上,quotes.zh-Hant.mdx 把 expired 译成「已到期」,语言包 zh-CN.ts 是「已过期」 #793 的文件面扫不到。quotes.zh-Hans.mdx把expiration_date叫作「过期日期」(4 处),语言包是「到期日期」。四次都落在同一个对象附近,而且是逐层被别的工作带出来的:#793 是修 #765 时撞见的,#801 是修 #793 时撞见的。这不是偶发笔误,是没有任何东西在检查这条事实:文档里写的状态名/字段标签,必须就是用户在界面上看到的那个词。
#801 甲尤其说明问题:状态名是跨页消费的,而人工排查是按页做的。#794 修presented时扫了全仓(现在全仓 grep已呈现|已呈現零命中,确实干净),expired这一轮的立单只点了一页,隔壁 index 页就漏了。靠「这次记得扫全仓」维持,等于没有保障。为什么现有闸门看不见
test/docs-drift.test.ts钉的是 flow 里的阈值与 cron 出现在src/docs/*.md里;它不读content/docs/,也不读语言包。**Name** tile那条散文规则只在英文页开火(docs-drift 的**Name** tile散文规则只在英文页开火——zh 页正文里的磁贴引用无人检查 #725 记的就是这个缺口)。>块——按它自己的说明,那是结构不是词汇,刻意不管用词。os validate/pnpm lint走src/里的元数据,从不打开content/docs/。所以这条事实目前零覆盖,四次都只能靠人。
动手前要先答的两个问题
朴素形状是:从
zh-CN.ts取某对象的status.options.*与字段label,断言 zh 文档页只用这些词。但有两个真问题,不先答就写不出一道「不吵」的闸:src/translations/只有 en / zh-CN / es-ES / ja-JP,zh-Hant 页的事实来源是 zh-CN 的繁体化写法(quotes.zh-Hant.mdx 把 expired 译成「已到期」,语言包 zh-CN.ts 是「已过期」 #793 正文已确认这一点)。要么引入简繁映射(新依赖,且一简对多繁的坑),要么这道闸只覆盖 zh-Hans——而上述四例里有三例(同一缺陷类:contacts.mdx 的传真字段/传真退订、leads.mdx 的 0-100 评分与 budget/timeline 字段,在对象声明里都不存在 #765 §3 的一半、quotes.zh-Hant.mdx 把 expired 译成「已到期」,语言包 zh-CN.ts 是「已过期」 #793、#793 的同一缺陷类在其文件面之外还剩两处:sales/index.zh-Hant 的「已到期」,与 quotes.zh-Hans 的「过期日期」×4 #801 甲)恰恰在 zh-Hant,也就是漏掉出问题更多的那半边。presented那轮同理放过了「呈现时刻」「以看板呈现」。逐字全文 grep 必然把这些全报成误报,而按 forecasting.zh-Hans/zh-Hant 相对英文页存在早于 #627 的整页漂移 —— 桶语义、承诺定义、缺失的汇总提示框需要整页重译 #736 写下的经验,指标一吵,这道闸就会被静音。需要一个只在「该词被当作状态名或字段名使用」时才开火的判据(例如只扫状态表的单元格、以及**加粗**的字段/状态引用),而不是全文扫描。在这两点定下来之前不宜动手:写一道会误报的闸,比没有闸更糟。
Refs #793, #801, #765, #725
⭐ R29 更新(2026-09-03,
repo:hotcrm执行席)—— 上面第 1 问已被 #837 答掉,第 2 问没有⛔ 上面「动手前要先答的两个问题」写于立单时,现在只剩一个。#837 落地(PR #1525,
main@9f59f6a)带来了test/docs-object-term-consistency.test.ts,本卡要的闸已经存在,范围收在「对象名」这一层。详情见本卡下方 R29 解锁评论,要点:zh-CN包派生;繁体孪生逐词 authored,外加一条「繁体形必须与简体形不同」的规则兜住忘记转换。⛔ 既没引入简繁映射,也没放弃 zh-Hant——本卡当初设想的两条路都没走。ALLOWED现在刻意为空,因为 [观察]crm_case在中文文档里有三种叫法:语言包「服务案例」、25 个页面「工单」、14 个页面「案例」(两页同页混用) #837 扫的 92 个中文命中全是crm_case——对象名很少和机制名撞车。状态名一定会(本卡自己的例子:「到期日期」对「每日到期扫描」)。⇒ 派发本卡时,ALLOWED会从「刻意为空」变成主要设计负担。派发形状:扩展点是
TERMSledger(一个对象一条)。所以本卡不再是「设计一道闸」,而是①把TERMS扩到status.options.*与字段label;②答第 2 问;③以本卡的四个历史案例做回归证据——presented/expired/expiration_date各注入一次,守卫必须变红。⛔ ③ 不可选:本卡存在的理由就是这四次全靠人眼撞见。