越界发现,来自 objectui#3888 的实施(objectui ADR-0036 收窄服务端 fault 策略那一句)。按 PD #10 立案,未认领、未定级 。观察类:今天没有用户会撞到它,而且被引用的规则本身是真的 —— 不成立的只是那个决策锚点 。
事实 server enforces, client is courtesy 这条规则在本仓被稳定地引作 ADR-0057 D10 。但本仓 ADR-0057 有两份文档(#5992 已记录这个撞号),两份里都没有一个内容对得上的 D10:
objectstack origin/main @ 23abe2782:
事实 位置 0057-erp-authorization-core-business-units-and-scope-depth.md 有 D1–D12,其 D10 = "Setup-nav surfacing follows the capability (ADR-0029 K2); the object stays open" docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md:422同文件 D9 / D11 / D12 分别是 edition tiering、team 命名撞号、primary_business_unit_id,均非本条 :404、:444、:4600057-system-data-lifecycle-and-retention.md没有任何 D 编号决策 (它的决策是 P0–P4)全文 `^#{2,3} (D
而引用它的地方(部分):
引用点 位置 ADR-0057 D10 (server enforces, client is courtesy) is whypackages/objectql/src/validation/rule-validator.ts:115ADR-0057 D10 puts enforcement on the server同文件 :575 ADR-0057 D10 ("server enforces, client is courtesy") resolves the disagreementpackages/lint/src/validate-expressions.ts:702作者可见诊断文案 Per ADR-0057 D10 the server is the one that decides 同文件 :766 UI absence alone is a client courtesy; the server is the authority (ADR-0057 D10)docs/qa/platform-checklist/RUNNER.md:66anchor 记录的 invariant 正文:A declared field lock is the SERVER's to enforce (ADR-0057 D10 — the client grid is courtesy),而 adrs 只声明裸 ADR-0057 scripts/adr-anchors/packages__objectql__src__validation__rule-validator.ts.json:7 / :3-6
git grep -l "ADR-0057 D10" origin/main 共 20 个文件(含 dogfood skill、docs/qa/platform-checklist/areas/*.json 六份、objectql/lint/formula/platform-objects 的 CHANGELOG 与测试)。
为什么 check-adr-anchors 没有看见 scripts/check-adr-anchors.mjs 检查的是编号 层:文件存在、编号不指向两个决策(#5992 那一条)、tombstone 不可锚定(#7329 )。它不校验 invariant / 注释里写的决策字母 是否真的是被引 ADR 的一个标题。所以 ADR-0057 D10 在编号层是绿的(adrs: ["ADR-0057", "ADR-0058"]),D 锚点错到别的决策上没有任何门会红 —— 这正是 #8386 (ADR-0066 把 D5 的内容记错)那一族的失败模式,只是这次错在 D 号本身而非 D 号的内容。
顺带:同一 anchor 的 adrs 里写的是裸 ADR-0057。按 #5992 的结论,裸编号在这个号上无法消歧,而这条 invariant 讲的是权限/enforcement 归属 ,两份 0057 里更接近的是 ERP authorization 那份 —— 但那份的 D10 恰好是 Setup-nav,所以"猜哪一份"这一步也解不出来。
影响与不影响 不影响 规则的正确性:server enforces, client is courtesy 在本仓 prose 里被独立表述过(RUNNER.md:66 就是完整的一句),rule-validator.ts:606-612 的 fail-CLOSED 行为也自证。影响 的是可追溯性:读者按 D10 去 ADR-0057 会读到 Setup-nav 那条,与手上的代码毫无关系,于是要么以为自己找错了 ADR,要么以为代码引错了 —— 两条路都到不了那条规则真正被决定的地方(如果它确实在某份 ADR 里被决定过)。
它还在外扩 :objectui 已经继承了这个引用两次(objectui#3828 / PR objectui#3887 的 packages/core/src/evaluator/fieldRules.ts 模块头,以及 objectui#3888 的 ADR-0036)。objectui#3888 这一版把它写成了归属式 表述("the rule the framework cites … as ADR-0057 D10")而不是断言 D 锚点可解,并在本单落地后不再进一步扩散 —— 但下一个复制它的人不会知道要这么小心。
建议修法(留给分诊,不自选) 定位真正的决策并改引用 :确认 server enforces, client is courtesy 落在哪份 ADR 的哪个决策(可能需要新记一条),然后把 20 处引用与 anchor invariant 一次改到那个可解的锚点上,顺带把 anchor 的 adrs 从裸 ADR-0057 改成消歧后的写法。只修 anchor 与两处代码注释 ,QA / CHANGELOG / skill 里的引用留待自然衰减。把门下移一层 :让 check-adr-anchors 校验 invariant 与被锚定文件注释里出现的 ADR-NNNN Dk 中的 Dk 确实是该 ADR 的一个标题。能一次性防住这一族(ADR-0066 credits ADR-0094 D5 with "retire implicit managed_by-guessing" — D5 never says that, and the cite now sends readers to a RETIRED section; authorization.mdx:190 inherited it #8386 是同族的另一个实例),但会先红出一批既有引用。不动,记录为已知边界。 倾向 1 + 3:1 是这一条的修法,3 是让它不再复发的那半 —— 但 3 会立刻红出一批,拆单更稳。
查重 仓内四次检索:ADR-0057 D10 citation does not resolve、ADR-0057 D10 server enforces client is courtesy numbering collision、git grep "ADR-0057 D10"(20 文件,全部是引用方,无立案)、以及 ADR 引用族既有单核对 —— #5992 (0010/0019/0057 撞号,已关)记的是编号 层,不含 D 锚点;#8386 (已关)是 D5 内容记错、非 D 号错;#8531 / #9072 (开)是 ADR-0081 跨仓标签;#8811 (开)是 ADR-0056 D10 矩阵缺行,与本条同名不同事。无同题单。
Refs: #5992 (编号撞号)、#8386 (同族:D 引用与 ADR 正文不符)、#7329 (anchor 层的 tombstone 检查)、objectui#3888、objectui#3828。
越界发现,来自 objectui#3888 的实施(objectui ADR-0036 收窄服务端 fault 策略那一句)。按 PD #10 立案,未认领、未定级。观察类:今天没有用户会撞到它,而且被引用的规则本身是真的 —— 不成立的只是那个决策锚点。
事实
server enforces, client is courtesy这条规则在本仓被稳定地引作 ADR-0057 D10。但本仓ADR-0057有两份文档(#5992 已记录这个撞号),两份里都没有一个内容对得上的 D10:objectstack
origin/main@23abe2782:0057-erp-authorization-core-business-units-and-scope-depth.md有 D1–D12,其 D10 = "Setup-nav surfacing follows the capability (ADR-0029 K2); the object stays open"docs/adr/0057-erp-authorization-core-business-units-and-scope-depth.md:422team命名撞号、primary_business_unit_id,均非本条:404、:444、:4600057-system-data-lifecycle-and-retention.md没有任何 D 编号决策(它的决策是 P0–P4)而引用它的地方(部分):
ADR-0057 D10 (server enforces, client is courtesy) is whypackages/objectql/src/validation/rule-validator.ts:115ADR-0057 D10 puts enforcement on the server:575ADR-0057 D10 ("server enforces, client is courtesy") resolves the disagreementpackages/lint/src/validate-expressions.ts:702Per ADR-0057 D10 the server is the one that decides:766UI absence alone is a client courtesy; the server is the authority (ADR-0057 D10)docs/qa/platform-checklist/RUNNER.md:66A declared field lock is the SERVER's to enforce (ADR-0057 D10 — the client grid is courtesy),而adrs只声明裸ADR-0057scripts/adr-anchors/packages__objectql__src__validation__rule-validator.ts.json:7/:3-6git grep -l "ADR-0057 D10" origin/main共 20 个文件(含 dogfood skill、docs/qa/platform-checklist/areas/*.json六份、objectql/lint/formula/platform-objects 的 CHANGELOG 与测试)。为什么
check-adr-anchors没有看见scripts/check-adr-anchors.mjs检查的是编号层:文件存在、编号不指向两个决策(#5992 那一条)、tombstone 不可锚定(#7329)。它不校验 invariant / 注释里写的决策字母是否真的是被引 ADR 的一个标题。所以ADR-0057 D10在编号层是绿的(adrs: ["ADR-0057", "ADR-0058"]),D 锚点错到别的决策上没有任何门会红 —— 这正是 #8386(ADR-0066把 D5 的内容记错)那一族的失败模式,只是这次错在 D 号本身而非 D 号的内容。顺带:同一 anchor 的
adrs里写的是裸ADR-0057。按 #5992 的结论,裸编号在这个号上无法消歧,而这条 invariant 讲的是权限/enforcement 归属,两份 0057 里更接近的是 ERP authorization 那份 —— 但那份的 D10 恰好是 Setup-nav,所以"猜哪一份"这一步也解不出来。影响与不影响
不影响规则的正确性:
server enforces, client is courtesy在本仓 prose 里被独立表述过(RUNNER.md:66就是完整的一句),rule-validator.ts:606-612的 fail-CLOSED 行为也自证。影响的是可追溯性:读者按 D10 去 ADR-0057 会读到 Setup-nav 那条,与手上的代码毫无关系,于是要么以为自己找错了 ADR,要么以为代码引错了 —— 两条路都到不了那条规则真正被决定的地方(如果它确实在某份 ADR 里被决定过)。它还在外扩:objectui 已经继承了这个引用两次(objectui#3828 / PR objectui#3887 的
packages/core/src/evaluator/fieldRules.ts模块头,以及 objectui#3888 的 ADR-0036)。objectui#3888 这一版把它写成了归属式表述("the rule the framework cites … as ADR-0057 D10")而不是断言 D 锚点可解,并在本单落地后不再进一步扩散 —— 但下一个复制它的人不会知道要这么小心。建议修法(留给分诊,不自选)
server enforces, client is courtesy落在哪份 ADR 的哪个决策(可能需要新记一条),然后把 20 处引用与 anchor invariant 一次改到那个可解的锚点上,顺带把 anchor 的adrs从裸ADR-0057改成消歧后的写法。check-adr-anchors校验 invariant 与被锚定文件注释里出现的ADR-NNNN Dk中的Dk确实是该 ADR 的一个标题。能一次性防住这一族(ADR-0066 credits ADR-0094 D5 with "retire implicit managed_by-guessing" — D5 never says that, and the cite now sends readers to a RETIRED section; authorization.mdx:190 inherited it #8386 是同族的另一个实例),但会先红出一批既有引用。倾向 1 + 3:1 是这一条的修法,3 是让它不再复发的那半 —— 但 3 会立刻红出一批,拆单更稳。
查重
仓内四次检索:
ADR-0057 D10 citation does not resolve、ADR-0057 D10 server enforces client is courtesy numbering collision、git grep "ADR-0057 D10"(20 文件,全部是引用方,无立案)、以及 ADR 引用族既有单核对 —— #5992(0010/0019/0057 撞号,已关)记的是编号层,不含 D 锚点;#8386(已关)是 D5 内容记错、非 D 号错;#8531 / #9072(开)是ADR-0081跨仓标签;#8811(开)是 ADR-0056 D10 矩阵缺行,与本条同名不同事。无同题单。Refs: #5992(编号撞号)、#8386(同族:D 引用与 ADR 正文不符)、#7329(anchor 层的 tombstone 检查)、objectui#3888、objectui#3828。