Skip to content

authz(ADR-0099): P0–P2 落地 — posture 成为分级裁决唯一输入(Layer 0 豁免门 + Layer 1 级判定收敛) #3211

Description

@os-zhuang

背景

ADR-0099(PR #3109,merged 2026-07-17)是 ADR-0095 posture 阶梯的裁决收尾篇:阶梯派生了(B2/B4,#2938)、#2956 把 rung 挂上了 ExecutionContext、explain 侧已收敛读 ctx.posture#2949)——但 enforcement 侧没有任何分级裁决读它,每个判定站点仍从 capability 位重新推导主体等级。这类「多站点独立派生」已在一个发布周期里踩出两次分叉 bug:#2946 Finding 2(org admin 越租户墙)、#2949(explain 与 enforcement 的 posture 标签漂移)。

本 issue 承接 ADR-0099 的 P0 → P1 → P2′ 实现;从 tracking #2920(已收口)移交。

修订说明

v1.1(2026-07-18):经落点级复核,P1 由原文「小改动、行为保持」修正为「fail-safe 方向的收窄,但确有行为变更」——探针与 rung 的证据不同源,P0 等价门预期不会全绿,其产出是需逐条裁决的 delta 名单。

v1.2(2026-07-18):加入完整开发计划(里程碑 PR 拆分 + 两个 maintainer 决策门、验证矩阵、风险与回滚、发布节奏)。

v1.3(2026-07-18,M3 裁决):M2 合并后、动 M3 前的核实推翻了「M3 纯行为保持」——Layer 1 短路的 tier 判据(持超级位)是每主体×每对象的委派原语(自定义集给非管理员岗授某对象 viewAllRecords = 审计员模式 = Salesforce 对象级 View All 同款),posture(每主体一个 rung)结构上无法表达;严格照 D2 收敛会让该位条件性失效(ADR-0049 禁止的 declared-but-unenforced 类)并砍掉主流委派能力。maintainer 四视角综合裁决(主流平台 / 长期架构 / 业务 / AI 防错,见 issue 讨论):选 B+ —— 原 P2 否决,ADR-0099 修正为两轴模型(posture=边界轴管阶梯两端,per-object 位=范围轴管 Layer 1 tier,「单一裁决输入」精化为「每轴单一权威」,新增不变量 I7)。ADR 修正已出 PR #3245;原 M3 方案作废,替换为下方 M3′。

进度


开发计划(v1.3 修订后)

已完成里程碑(存档)

M3′ — P2′:两轴模型钉住格(≤1 PD,前置 PR #3245 合并)

性质:纯测试 + 已随 #3245 的 ADR 修正。零行为变更。

落点与内容

  1. ADR-0099 两轴 AmendmentPR feat(authz): ADR-0099 two-axis model — Layer 1 tier stays the per-object scope bit; amendment + P2′ pins (#3211 M3/M3′) #3245(D2 Layer 1 行修正、每轴单一权威、I7、I2 澄清、P2 superseded 标记)。
  2. 矩阵钉住格authz-matrix-gate.test.ts):
    • 种子等价格:种子面「持超级位的主体 ⟺ posture ≥ TENANT_ADMIN」一致(两轴在种子面重合的显式断言,未来漂移报警);
    • 委派格(核心):MEMBER + 自定义集对某 private 对象授 viewAllRecords → 组织内全行可见 被 Layer 0 墙住(I7)——把「合法委派」钉进 CI,防未来任何「posture 收敛清理」静默砍掉它;
    • I7 格:同一委派主体供异租户 organization_id 的写被拒(若 M2 既有格已覆盖则引用注明)。
  3. advisory lint 后续 issue(独立小项,不阻塞收口):member 可达权限集在 private 对象上授 viewAllRecords/modifyAllRecords 时的授权期提示(复用 describeHighPrivilegeBits)。

判据:零行为变更;plugin-security 全套绿;docs 门绿。

G2 — 收尾核查

非目标

  • P3(EXTERNAL rung 激活):demand-gated(ADR-0090 follow-up Migrate from npm to pnpm #6 / Permission Model v2 — named follow-up ADRs (post-ADR-0090 parking lot) #2776 item 6)。
  • Layer 1 tier 收敛(原 P2)已否决(G-M3,ADR-0099 Amendment 记录在案)。若未来要重启,须另立 ADR 面对「废掉对象级 view-all 委派」这一 breaking 并给出迁移路径——不是本 issue 范围。
  • 显式 deny/muting:ADR-0099 D4 已 Rejected。
  • 运行时开关:能调宽租户墙豁免的开关即 D4 否决之物;回滚 = revert PR。

执行约束

  1. worktree-first(Prime Directive Migrate documentation site to Fumadocs with monorepo structure and shared content #11)。
  2. 每里程碑独立 PR;M3′ 待 feat(authz): ADR-0099 two-axis model — Layer 1 tier stays the per-object scope bit; amendment + P2′ pins (#3211 M3/M3′) #3245(ADR 修正)合并后落,保持「先定规范再落格」的顺序。
  3. 两轴模型给 AI 作者的规则一句话:位定对象内行范围,posture 定租户边界——所有后续文档/skill 以此口径。

关联

ADR-0099 / #3109 · #3218(M1/P0)· #3226(M2/P1)· #3245(两轴 Amendment)· ADR-0095 · #2956 · #2949 · #2946 Finding 2 · #2937 · ADR-0049(declared-but-unenforced 禁令,G-M3 裁决依据)· tracking #2920(已收口)· #2776 item 6(EXTERNAL 产品轨)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions