diff --git a/.task/fix-pal-component-delivery-pins.md b/.task/fix-pal-component-delivery-pins.md index 0e3807ce..122a59aa 100644 --- a/.task/fix-pal-component-delivery-pins.md +++ b/.task/fix-pal-component-delivery-pins.md @@ -19,6 +19,16 @@ - 已核实基线(合入前):Dev main 钉 `modules/backend=dfb31da`(不含生命周期内容,差 27 文件/1379 行)、`modules/frontend=113103f`(即 U6 交付头,随 Dev 交付但未入 Frontend main)、RDM pin `c6304224`(2026-10-13,落后 RDM main 918 提交,早于 #454)。 - 非目标:不改 U1–U5 的规格语义;不部署(C16 另起,需 pin 就位后进行);不处理 `feature/rdm-two-trees-followup`(PR #635)的范围。 +## 决策记录 + +- **D1(role cap 是否受 R3 carve-out 约束)——用户裁决 2026-10-21,选 A1。** RDM 的 `evalPerm` 有两层不同的覆盖:role cap(`switch` 的 `RoleReasonCapDenied` 与 legacy 的 `!defined || !capAllowed`)与项目覆盖层(末尾 `ps.OverrideFor`)。计划 R3 原文只约束后者(原文用词为 per-action member/project **overrides**)。 + - 裁决内容:**只让项目覆盖层不再撤销创建者权威本身授予的权限**;role cap 维持现状、继续阻断创建者。覆盖层的「授予」方向也不变。平台上限、账号停用、职位停用、Linked.Conflicts、归档/结项状态守卫、对非创建者的拒绝全部不变。 + - 实现:`internal/rdmapp/perms_api.go` 的 `evalPerm` 末尾,`creatorGranted := base && relation == perms.RoleOwner && p.CreatedBy == actor && isManagementAction(act)`;`if set && (override || !creatorGranted)`。 + - 该裁决曾以「Decision A1」写进 `plugins/rdm/system_projects_test.go` 的注释,但当时未在任何仓内决策记录中留痕——这是本卡补记的原因。 +- **D2(archive/restore 授权门不得被 R3 收敛吞掉)——由计划原文直接决定,非新决策。** U2 第 219 行:「Do not change archive/restore, which remains a separate lifecycle.」故 `canManageProject` 按 act 分流:`ActProjectArchive` 沿用 main 的「创建者或显式授权」门,其余走 R3 的 `requireProjectManagement`。 +- **D3(ArchivedAt 守卫必须还原,ClosedAt 不设)——由计划原文与 R6 共同决定。** 归档属 Out of scope,main 的只读守卫必须恢复(含创建者);结项属 U4/R6,R6 明文「The creator can still use project-management actions needed to reopen or administer the project.」,故 ClosedAt 刻意不设守卫。 +- **D4(平台上限对创建者同样生效)——由领域规则与 SR-G9 决定。** 「system.grants 与平台上限写入门禁保持 system.permissions.manage,不得因 R13 放宽」;`perms.SetCap` 注释「所有业务主体均受约束」;SR-G9 创建者「仍受有效角色与平台 cap」。故 `requireProjectManagement` 带 act 参数并恢复 `CapAllows`。 + ## Agent 实施收据 路由与 fail-stop 规则见根目录 AGENT-EXECUTION.md 与 policy/delivery.md;每次尝试一行,原始日志留在源码外收据路径。