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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions