Skip to content

docs: 把 positions、STATUS 与 latest-release 三处宣称写到源上,并补齐对应守卫 (#1014 #1011 #1015) - #1020

Merged
yinlianghui merged 1 commit into
mainfrom
claude/issue-1014-1011-1015-stale-claims
Aug 7, 2026
Merged

docs: 把 positions、STATUS 与 latest-release 三处宣称写到源上,并补齐对应守卫 (#1014 #1011 #1015)#1020
yinlianghui merged 1 commit into
mainfrom
claude/issue-1014-1011-1015-stale-claims

Conversation

@yinlianghui

@yinlianghui yinlianghui commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Fixes #1014
Fixes #1011
Fixes #1015

三单同族:都是「宣称面对着今天说了错话,而本该看住它的守卫正好看向别处」。守卫落点都在 test/docs-drift.test.ts,故并单一次做完。

基线:R39 五 PR(#1006 / #1007 / #1009 / #1010 / #1013)合并后的 fresh origin/maind57124d3)。#1010 的计数守卫与 #1001 的版本守卫都已在树上,本 PR 只扩不另起。


一、premise 复核(三单都立于 R39 合并前,先按 fresh main 实测)

pnpm validated57124d3 实测:

Data: 17 Objects  344 Fields
UI: 1 Apps  14 Views  8 Pages  5 Dashboards  10 Reports  26 Actions
Logic: 24 Flows
Security: 12 Positions  6 Permissions
前提 复核结论
#1014 页面写「10 级角色层级」,实为 12 且层级已取消 成立CrmPositions 12 项;objectstack.config.ts:133-135 明写 ADR-0090 D3 取消 parent links
#1011 STATUS.md 全表过期 成立,且比 issue 记录的更旧一档:issue 写「77 files, 1830 passed」,fresh main 实测已是 79 files, 1855 passed / 1 skipped(R39 又并了五个 PR)。其余各行与 issue 表一致
#1015 whats-new「v5.0 — Latest release」是现在时宣称 成立manifest.version = 2.2.2,@objectstack/* = 17.0.0-rc.3,v5.0 两者皆非

三单前提全部成立,无一需要重新裁定。


二、#1014 —— positions 不是层级,是 12 个扁平职能分组

实测src/sharing/positions.ts 12 项;objectstack.config.ts:133-135 与 positions.ts 头注都写明 ADR-0090 D3 之后 position 之间没有 parent link,可见性不上卷,每个需要某条记录的层级由它自己的 sharing rule 点名(#488)。

改动

  • content/docs/getting-started/introduction.{mdx,zh-Hans,zh-Hant} 的那一条改为「12 个 position / 岗位 / 職位,按销售·服务·市场职能分组的扁平群体,用于分发记录访问权限;之间什么都不会上卷」。三语用词与 administration/sharing-and-security 已有的译法对齐(zh-Hans 用「岗位」、zh-Hant 用「職位」),不新造词。
  • content/docs/index.{mdx,zh-Hans,zh-Hant} 的 Security 一行同改(原写 role hierarchy)。
  • 顺带:content/docs/index* 顶部 callout 的「See what's new in v1.0 →」改为不带版本号的「See what's new →」。它是导航文案不是版本报告,而版本号写在这里既没有守卫看得住、又与我刚改正的目标页自相矛盾;移除宣称优于把宣称搬个家

守卫positions 加进 #1010 计数守卫的 REGISTEREDstack.positions.length,运行时现读,不硬编码)与 CLAIMS(三语各一条 spelling)。


三、#1011 —— STATUS.md 取裁定 A(现状页)

实测:见上表;平台包行落后两个 rc;13 Views 与实测 14 差一(issue 已指出);9 files, 97 tests 与实测 79 files 差一个数量级。

改动docs/STATUS.md):

  • 验证摘要块按 pnpm validate 现跑现读全表改正;
  • ## Current Runtime Requirements 的平台包行改 17.0.0-rc.3
  • Snapshot date 直接删除,换成一句「本页陈述的是 main 的当前状态,不是快照;能从源推导的数字都由 test/docs-drift.test.ts 钉住」。取舍理由:裁定 A 的全部意义就是「这一页按现状读」,而一个日期恰恰在邀请读者把数字打折;何况这个日期本身也是手工维护、没有任何东西能核对它,属于又一个漂移源。
  • 测试规模行改为写「verdict 而不是 size」Passes,与上面两行一致),并在表下说明为什么:N files, M tests 几乎每个 PR 都动,而没有任何东西能从这套测试内部核对描述这套测试的数字(静态数 it( 也不行 —— 这个文件本身就在 for 循环里生成用例)。写一个测不了、又天天变的数,就是把 9 files, 97 tests 这种错误再生产一次。这是本 PR 唯一一处「不照实测值写数」的地方,故在此写明。
  • 13 Actions 行:不替 「多少个 action」需要一个产品口径:文档写 13,注册进 stack 的是 26 #1012 拍板。块按 pnpm validate 实际打印的注册数 26 Actions 改,并在块下加注说明 26 是注册计数(一个动作绑五个对象注册五次)、与 README 的 13、源码树的 6 各答不同问题,口径归属是 「多少个 action」需要一个产品口径:文档写 13,注册进 stack 的是 26 #1012 的未决事项、本页不予裁定。

守卫(新增 describe:docs/STATUS.md states the current repository (#1011)):

  • 抓出首行形如 HotCRM v2.2.2 的那个 fenced 块(按内容识别而非位置,插一节不会把规则指到别的 fence),把 Data: 17 Objects 344 Fields 这类标签解析成 {Objects: 17, Fields: 344},逐项与注册 stack 比对(Fields 由各对象 fields 键数求和,实测与验证器打印一致 = 344);
  • ## Current Runtime Requirements 四行分别对 package.jsonengines.node / engines.pnpm / @objectstack/* 依赖行 / scripts.dev-p 端口断言;
  • 三条 vacuity:块解析不出来 → 红;块少了某一行 → 红(防静默减项);块里出现规则不认识的标签 → 红(验证器长出新数字时逼着扩规则,而不是让它无人看管地混进来)。

为什么不是「把 docs/STATUS.md 加进 #1010COUNT_DOCS#1010CLAIMS 是散文 spelling(17 business objects(\d+) 个仪表盘),而 STATUS.md 的数字是机器摘要(Data: 17 Objects,大写、无「business」)。把文件加进扫描面,规则在这一页上一条也匹配不到 —— 那是扩了扫描面却什么都没检查的假覆盖。故按守卫现有结构做成一条自带解析器的独立规则,并在 COUNT_DOCS 处留注说明这条分工。

26 Actions 这条断言不预判 #1012:它断言的是「一个以 pnpm validate 输出形式呈现的块,与 loader 注册的东西一致」—— 这是对转录保真的断言,而验证器按构造打印的就是注册数。#1012 无论裁到哪个口径,这条断言都不动,会动的是块周围的散文。


四、#1015 —— whats-new 取裁定 A(继续维护)

实测:该节宣称 v5.0ObjectStack 5.0@objectstack/console@5.0@objectstack/account@5.0package.json 里没有 console 这个依赖,account17.0.0-rc.3。v5.0 既不是应用版本也不是平台版本。

改动(三语 content/docs/whats-new*):

  • 该节改写为 ## v2.2.2 — Latest release(zh-Hans 「最新发布」/ zh-Hant 「最新發行」,沿用各自页面原有译词),正文写真值:应用 2.2.2、全线 @objectstack/* 运行在 17.0.0-rc.3、manifest 声明 ^17.0.0-rc.3 协议区间。
  • 不虚构中间版本历史:加一条 callout 说明「本页不维护第二张发布表」,逐版本历史在 CHANGELOG.md(由每个 PR 的 .changeset/ 编译),v1.0 与 2.2.2 之间的各版记录在那里、此处刻意不重列 —— 并点名这正是本节当初会宣称一个不存在版本的原因。三语各加一个 callout 块,blockquote 块数保持 1/1/1,不动 forecasting.zh-Hans/zh-Hant 相对英文页存在早于 #627 的整页漂移 —— 桶语义、承诺定义、缺失的汇总提示框需要整页重译 #736 的三语 callout 对等规则。
  • 原 v5.0 节下的 Sales / Service / Revenue / Marketing / AI / Analytics / Documentation 各条是以「本次发布新增/下调」句式写的增量描述(「SLA 监控每 5 分钟运行(从 15 下调)」等)。它们要么归属于一个不存在的版本,要么把 src/docs/crm_service.md 等已被守卫钉住的阈值又抄了一份到 content/docs 无人看管处。保留就必须给它们编一个版本归属,那才是虚构历史;故整体换成「产品当前形态写在哪里」的指路清单(introduction / analytics / sharing-and-security / ai-copilot),并说明那些页面各自被守卫钉住 —— 这样这一节不再新增任何无人核对的数字宣称。
  • v1.0 历史节一字未动。

守卫(挂进 #1001 版本 describe,作为 VERSION_DOCS 的自然扩展):

  • 三语 whats-new 各须恰好有一节被标记为 latest(marker 表:Latest release / 最新发布 / 最新發行)—— 0 节或 2 节都红。这条同时充当 locale 覆盖的 vacuity 保护:某语言的 marker 一旦读不到,该页计数掉到 0 直接点名报红,无需另写 probe 用例。
  • 该节标题须写出 manifest 声明的版本(2.2.2,边界匹配,12.2.2 / 2.2.22 不算数)。
  • 该节须写出 package.json 安装的平台版本;平台版本由「全部 @objectstack/* 依赖去重后恰好一个」推导,比对前先断言这一点(版本锁定,AGENTS.md §Platform Upgrades),否则半截升级会让规则要求一个谁也没装的版本。

顺带修好让 #1015 得以存活的那个豁免#1010 计数守卫把 whats-new 整页列为 HISTORICAL —— 对 v1.0 节是对的,对紧挨着的现在时节是错的,而后者正是 #1015。豁免键从文件改为文件 + 小节{ section: RegExp, reason }),只有落在匹配小节内的宣称才被豁免;三语 v1.0 标题都以 v1.0 开头,一条 pattern 覆盖三语。dead-exemption 检查同步升级为「每个被豁免的小节仍然写着计数」,所以 v1.0 节被改名或它的清单搬走时,这张许可证也会当场报红而不是继续空转。


五、验证

六门全绿(pnpm validate / typecheck / lint / hygiene / build / test):

Test Files  79 passed (79)
     Tests  1866 passed | 1 skipped (1867)

Source hygiene — 259 files under src, test, e2e, scripts; the control-byte scan adds 460 under content, .changeset
  ✓ no raw control bytes in first-party files

(基线 1855 passed,新增 11 条断言。)

反向验证:每条新断言先预判方向再跑

十个 probe,全部与预判一致。以下为真实报错原文节选。

1. positions 数字写错 —— 预判红,实测红

× every count a doc states is the count the stack registers
  content/docs/getting-started/introduction.mdx:58 says "10 positions", the stack registers 12 positions

2. 把 introduction 三语改回原文 **A 10-role hierarchy** —— 预判绿,实测绿(76 passed)

这条要写明白,因为它与「把删掉的肢体装回去应该转红」的常见预设相反,而且是本 PR 里最该被下一个读者知道的一件事:计数守卫读不懂那句旧话A 10-role hierarchy 里没有任何一个 CLAIMS 能匹配的计数 spelling,而 README 仍带着一条正确的 12 positions,所以按 kind 的 vacuity 也不会响。换言之,positions 这条扩展抓的是新写法里的错数字,抓不到被取消的旧措辞 —— 这正是 #1010 的守卫当初漏掉 #1014 的原因,issue 本身也已指出「hierarchy 这个词该不该出现不是计数守卫能管的」。措辞层要另立一条禁用词规则,且必须与仍在用该措辞的十余页一起改,已另单记录(见下)。

3. 删掉三条 positions CLAIMS —— 预判红(vacuity),实测红

× the scan finds a claim of every kind it guards
  no doc states a count for: positions — the docs were reworded and this rule now guards nothing for those kinds.

4. STATUS 转录 17 Objects 改 16 —— 预判红,实测红

× every figure the transcript states is the one the stack registers
  Objects: page says 16, the stack registers 17

5. STATUS 转录删掉 Logic: 24 Flows 整行 —— 预判红,实测红两条(预判一条,实际连 vacuity 下限一起响,两条都指向同一处减项,属正确行为)

× the validator transcript is present and parses
  ... transcript parsed 10 labelled figures ... The summary prints 11.
× the transcript states every figure the summary prints
  ... transcript no longer states: Flows.

6. STATUS 运行时表平台行改回 rc.1 —— 预判红,实测红

× every runtime requirement matches package.json
  ObjectStack packages: page says `17.0.0-rc.1`, the @objectstack/* dependency line in package.json says `17.0.0-rc.3`

7a. whats-new 标题改回 ## v5.0 — Latest release —— 预判红,实测红

× the latest-release heading states the version the manifest declares
  content/docs/whats-new.mdx: "## v5.0 — Latest release" does not state 2.2.2

7b. 三语该节内的平台版本全部替回 5.0 —— 预判红,实测三语齐红

× the latest-release section states the platform version package.json installs
  content/docs/whats-new.mdx: ... never states the installed platform 17.0.0-rc.3
  content/docs/whats-new.zh-Hans.mdx: ... never states the installed platform 17.0.0-rc.3
  content/docs/whats-new.zh-Hant.mdx: ... never states the installed platform 17.0.0-rc.3

8. 从 LATEST_MARKERS 删掉 zh-Hant 的「最新發行」—— 预判红,实测红

× every locale of whats-new marks exactly one section as the latest release
  content/docs/whats-new.zh-Hant.mdx: 0 section(s) marked latest (looking for Latest release | 最新发布; found headings: none)

9. 豁免收窄的三连(同一段文字,三种豁免形态)—— 三个方向全部与预判一致

新的 latest-release 节内植入一句错的 4 dashboards

  • 9a 小节级豁免(本 PR)—— 预判红,实测红
    × every count a doc states is the count the stack registers
      content/docs/whats-new.mdx:87 says "4 dashboards", the stack registers 5 dashboards
    
  • 9c 把豁免临时放宽回文件级(改前状态)—— 预判绿,实测绿(76 passed)。同一段文字、同一个数字,仅仅因为豁免是按文件发的就无人过问 —— 这就是 v5.0 节当初得以存活的那个洞,本 PR 把它补上。
  • 9b 同一句话改放进 v1.0 节 —— 预判绿,实测绿(76 passed)。豁免在它被授予的地方仍然照常生效,收窄没有误伤历史记录。

10. 把 v1.0 标题改名,使豁免的 section pattern 匹配不到任何小节 —— 预判红,实测红两条

× every exempt section still states a count, so no exemption is dead
× every count a doc states is the count the stack registers
  content/docs/whats-new.mdx:55 says "15 business objects", the stack registers 17 objects

即:许可证一旦悬空立刻报红,同时它原本遮着的历史数字也一并暴露 —— 两条一起响正说明这张许可证确实在起作用而不是空转。

vacuity 层复核

按要求核过 #1010 守卫的 vacuity 层在本 PR 改动之后是否需要同步调整:


六、范围外发现(只记录不修)

…urce (#1014 #1011 #1015)

Three pages made a present-tense claim that had stopped being true, and each
had a guard that was looking somewhere else.

getting-started/introduction sold "a 10-role hierarchy" in all three locales.
The stack registers 12 positions, and ADR-0090 D3 removed the hierarchy itself
— positions are flat capability-distribution groups and nothing rolls up. The
bullet and the docs-home security row now say that; `positions` joins the
count guard's REGISTERED/CLAIMS, read from the stack rather than written down.

docs/STATUS.md called itself the source of truth while every figure was stale
(16/318 objects/fields against 17/344, 4 dashboards against 5, 23 flows against
24, 13 views against 14, platform rc.1 against the installed rc.3). Its
validator transcript is now pinned against the registered stack and its runtime
table against package.json. The "Snapshot date" is gone — the page is present
tense — and the test row states a verdict, not a size no gate can check.

content/docs/whats-new announced `v5.0` on "ObjectStack 5.0" with
console@5.0 / account@5.0; the app is 2.2.2 on platform 17.0.0-rc.3 and v5.0
was never either. The section states the real versions and points at the pages
that own each area instead of keeping a second hand-copied release table; the
v1.0 record is untouched. A new rule holds any "Latest release" section, in
every locale, to the manifest version and the installed platform version.

The exemption that hid the last of these excused the whole whats-new page as a
historical record — right for the v1.0 section, wrong for the one beside it.
Exemptions are now scoped to the section they were granted for.
@vercel

vercel Bot commented Aug 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
hotcrm Ignored Ignored Aug 7, 2026 2:35am

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation ci/cd CI plumbing and the verification pipeline labels Aug 7, 2026
@yinlianghui
yinlianghui marked this pull request as ready for review August 7, 2026 03:15
@yinlianghui
yinlianghui added this pull request to the merge queue Aug 7, 2026
Merged via the queue into main with commit 7d716bb Aug 7, 2026
10 checks passed

Copy link
Copy Markdown
Collaborator Author

[PM 验收 · R40 · ACCEPT] session_01M9F2zn8vQuzduBS5t5nLxX

三单 #1014 / #1011 / #1015 验收通过,已随合并关闭(03:16Z,维护者亲合)。验收依据:

守卫净增 11 条断言(1855 → 1866 passed):positions 计数入 #1010 守卫、STATUS.md 独立解析规则(含三条 vacuity)、whats-new latest-release 版本规则(三语 marker + manifest 版本 + 平台版本)、豁免键文件级 → 小节级。

范围外发现 #1019 已分诊:具体缺陷(七处文档教已取消的可见性上卷机制,对读者是静默错误权限承诺),定 pm:queue,是否即刻派发待维护者示意(本线处于发布收尾待机姿态)。


Generated by Claude Code

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

Labels

ci/cd CI plumbing and the verification pipeline documentation Improvements or additions to documentation

Projects

None yet

2 participants