发现于 #4984 的实现过程(那一单只修被拒别名的读法,这条是覆盖面问题,按 Prime Directive #10 单独记账)。
事实
packages/lint/src/validate-org-axis-red-lines.ts 的 ORG_AXIS_CROSS_ORG_BU_GRANT(D6 ②)只对一种收件人类型判红:
const recipientType = str(sharedWith?.type);
if (recipientType !== 'business_unit') return;
而 ShareRecipientType 里有两个业务单元收件人:
business_unit —— 正好一个 BU 的成员(无子树);
unit_and_subordinates —— 一个 BU 加上其全部后代单元的成员(ADR-0057 D5 子树扩张)。
ADR-0105 D6 ② 的原文点名的恰恰是后者:
Every BU mechanism — unit_and_subordinates sharing, adminScope delegation, depth scopes — operates within one organization. There is no cross-org tree.
后果
在 tenancy.enabled: false(或 systemFields.tenant: false)的平台级对象上:
| 收件人 |
现状 |
sharedWith: { type: 'business_unit', value: 'bu_x' } |
判红 ✅ |
sharedWith: { type: 'unit_and_subordinates', value: 'bu_x' } |
放行 ❌ |
两者的缺陷完全相同 —— 平台级对象没有 organization 列可供 Layer 0 收口,授权跨到库里每一个 organization —— 而漏掉的那个授权面更大(整棵子树而非单个单元)。规则自己的文档注释也只写了 business_unit,所以这不像是有意的取舍,更像是照着一个收件人写完就没回头看枚举。
注:#4984 之前这条规则读的是被拒别名 sharedTo/recipient,所以 ② 对任何 spec 合法的 stack 都从不触发;#4984 修好键名后这个覆盖面缺口才第一次变得可观察。
建议
把判定改为收件人类型 ∈ { business_unit, unit_and_subordinates },并在 message 里保留具体类型名。这是 error 级门禁的扩张,所以没有随 #4984 一起做 —— 需要先确认没有真实元数据踩中。
已核查(#4984 分支上):examples/app-showcase、examples/app-crm 的全部 sharing rule 中只有一条 unit_and_subordinates(share_new_inquiries_with_field_ops → showcase_inquiry),而 showcase_inquiry 没有 tenancy.enabled: false / systemFields.tenant: false,仓库里也没有任何对象关掉 tenancy —— 因此按上述扩张改完,现有真实元数据不会产生新红。
相关:#4984、ADR-0105 D6、ADR-0057 D5。
发现于 #4984 的实现过程(那一单只修被拒别名的读法,这条是覆盖面问题,按 Prime Directive #10 单独记账)。
事实
packages/lint/src/validate-org-axis-red-lines.ts的ORG_AXIS_CROSS_ORG_BU_GRANT(D6 ②)只对一种收件人类型判红:而
ShareRecipientType里有两个业务单元收件人:business_unit—— 正好一个 BU 的成员(无子树);unit_and_subordinates—— 一个 BU 加上其全部后代单元的成员(ADR-0057 D5 子树扩张)。ADR-0105 D6 ② 的原文点名的恰恰是后者:
后果
在
tenancy.enabled: false(或systemFields.tenant: false)的平台级对象上:sharedWith: { type: 'business_unit', value: 'bu_x' }sharedWith: { type: 'unit_and_subordinates', value: 'bu_x' }两者的缺陷完全相同 —— 平台级对象没有 organization 列可供 Layer 0 收口,授权跨到库里每一个 organization —— 而漏掉的那个授权面更大(整棵子树而非单个单元)。规则自己的文档注释也只写了
business_unit,所以这不像是有意的取舍,更像是照着一个收件人写完就没回头看枚举。注:#4984 之前这条规则读的是被拒别名
sharedTo/recipient,所以 ② 对任何 spec 合法的 stack 都从不触发;#4984 修好键名后这个覆盖面缺口才第一次变得可观察。建议
把判定改为收件人类型 ∈
{ business_unit, unit_and_subordinates },并在 message 里保留具体类型名。这是 error 级门禁的扩张,所以没有随 #4984 一起做 —— 需要先确认没有真实元数据踩中。已核查(#4984 分支上):
examples/app-showcase、examples/app-crm的全部 sharing rule 中只有一条unit_and_subordinates(share_new_inquiries_with_field_ops→showcase_inquiry),而showcase_inquiry没有tenancy.enabled: false/systemFields.tenant: false,仓库里也没有任何对象关掉 tenancy —— 因此按上述扩张改完,现有真实元数据不会产生新红。相关:#4984、ADR-0105 D6、ADR-0057 D5。