Repository navigation
[Decision] DESIGN.md §04 makes clm_requester every employee's default, but a set that grants clm_requester.access cannot bind to everyone #11
Description
Activity
第二问(PM 追加):六个动作门控挂在哪些权限集上
§04 列出了六个动作门控,但没说哪个权限集持有哪个。卡 04 只能推导,推导结果在 PR #12 里。这一条落在「安全与权限边界」上,按规矩归你,不归我。
维护者速读:下面这张表里只有最后一行需要你多看一眼——「审批合同」这个门控挂在了发起人这个权限集上,看起来像「人人都能审批」。实际不是:审批阶梯的第一级就是直接主管,而主管在系统里就是个普通员工,只持有发起人权限集。不给他这个令牌,第一级永远没人能点。持有令牌不等于能审批任何合同,能审批哪一份由审批流程指派。
动作门控 推导出的持有者 依据 维护审批矩阵 管理员 §04 矩阵里只有管理员对审批规则有写权限 维护条款库 法务、管理员 §04 矩阵:条款对法务是 RCU 登记执行、归档 档案与记录、管理员 §04 矩阵:签署记录与归档字段归档案岗 终止合同 法务、管理员 终止是法律动作,§04 矩阵里业务承办对生效合同无写权限 审批合同 发起人、法务、财务、管理员 §06 F5 第一级是直接主管,主管只持有发起人权限集 选项:
- A(推荐):接受这张表。每一行都由 §04 矩阵或 F5 的阶梯结构推出来,最后一行是唯一能让第一级审批工作的挂法。
- B:你改动其中若干行,改法是
src/profiles/里的一行编辑,不影响其他任何东西。
你要做的:和本卡第一问一起回,比如「A A」。
Both questions on this card are one-line reversible edits and neither blocks M1 — PR #12 is merged and the acceptance run staffed its personas through the Setup path. Card 07 is the first consumer of question 1 (it gates the 我的合同 navigation group on
clm_requester.access); question 2's only consumer is card 06's approval ladder.
Generated by Claude Code
- added a commit that references this issue
on Sep 7, 2026 zhuangjianguo commented
on Sep 9, 2026 CollaboratorMore actions第一问裁定:A —— 接受分发模型,缺口报到平台
维护者裁决,2026-09-09,常设决裁批第 1 批,逐字:
第 1 批 平台的问题去平台修,业务的问题按照你的意见。
第一问的阻塞源是平台缺陷(平台的高权限判定把应用自己声明的能力令牌与平台系统权限一视同仁,粗于 ADR-0066 的能力模型)⇒ 走「去平台修」,而选项 A 恰好就是这个形状:应用侧保持现状、把缺口报到平台、平台修好后删一行绑定即可恢复自动默认。
⛔ 因此 B 与 C 明确不采纳:两者都是把平台今天的粗糙固化进设计文本,且不可逆。
Governing text(录裁前重跑):
DESIGN.md§04「Permission set 五个:clm_requester(所有员工默认)…导航分区的门控能力由权限集systemPermissions授予:clm_requester.access…」;AGENTS.md→ Platform gaps → report, never patch。鲜度门:正文最后编辑 2026-09-07T14:00:44Z;其后一条评论(2026-09-07T14:05:46Z,前任 PM 追加的第二问)—— 见下,它改变了本卡的状态转换。
⚠️ 第二问未裁,本卡因此不离开决策箱本卡带两问。前任 PM 在 2026-09-07T14:05:46Z 追加了第二问(六个动作门控分别挂在哪些权限集上),并写明「和本卡第一问一起回」。
我在第 1 批只呈报了第一问。 这是我的呈报缺漏,不是你的遗漏 —— 你说「业务的问题按照我的意见」,而第二问我从未给过意见,你无从背书一个不存在的推荐。
而且第二问不能由我代裁:它自己写明落在「安全与权限边界」上,而安全/权限边界是代裁的人工地板,任何自裁通道都够不到它。第二问的实质是「审批合同」这个门控挂在了发起人权限集上 —— 表面像「人人都能审批」,实际是因为审批阶梯第一级是直接主管、而主管在系统里只是普通员工。这个取舍必须你亲自看一眼。
⇒ 状态转换:本卡维持
needs-user-decision。 第一问的落地作为搭车项(Refs #11,⛔ 非Fixes)随设计文档 PR 走;第二问随下一批呈给你,届时我补齐它的四棱与推荐。裁后执行(仅第一问)
- §04 编辑(受管面,随折叠的设计文档 PR,链首 [Decision]
DESIGN.md§03 requires a termination reason but declares no field for it #6):加一句 ——clm_requester由管理员授予未持岗位的员工;持岗位者随岗位绑定。 - 代码零改动:卡 04(Positions, permission sets, sharing rules, FLS,
onEnablebindings (card 04, M1) #4 / PR Positions, permission sets, sharing rules, FLS,onEnablebindings (card 04, M1) #12)实现的就是这个分发模型,七个岗位各自额外绑定clm_requester,已在 main 上。 - 平台缺口卡已立:见下方本席的立卡回链。按跨仓规矩 file-at-destination,普通卡、无 assignee、待分诊。
- 平台修好后的收回动作(预写在此,免得将来重新论证):把
clm_requester标isDefault: true,删掉src/security/bind-position-sets.ts里那七行额外绑定。
与 #28 的耦合,现已解开
#28 明写「先回 #11 第一问,这一张的答案就基本定了」。第一问裁 A ⇒ dev admin 永远看不到「我的合同」分区 ⇒ #28 的选项 C 自动出局,剩下 A(维持现状,操作员手工建号)与 B(让
pnpm demo自己建三个演示账号)二选一。#28 在第 2 批,届时按这个已定的前提呈报。
Generated by Claude Code
- §04 编辑(受管面,随折叠的设计文档 PR,链首 [Decision]
objectstack-fleet commented
on Oct 9, 2026 ContributorMore actionsEvidence for this card's second question · 2026-10-09T16:01Z — measured by the #82 dev (PR #85, Acceptance notes), identical on 17.4.0 and 17.7.0.
A
clm_adminholder cannot edit a contract pastsubmitted:PATCH /api/v1/data/clm_contract/ID→403, and editing its child review is refused with "master not editable … row-level security". Cause, as measured: every position also bindsclm_requester(the workaround for theeveryoneanchor this card is about), and that set's using-onlycontract_requester_edit_windowis the only update policy that applies — so the requester's edit window caps the administrator too. README saysclm_admin"holds full reach over every CLM object".Not filed as its own card: its cause is the binding this card's open question decides. Whichever permission sets hold
clm_requesteronce Q2 is ruled, this is the case that ruling must not leave behind.
Generated by Claude Code
维护者速读
事情:
DESIGN.md§04 说clm_requester是「所有员工默认」的权限集,同时又说导航分区的门控能力clm_requester.access由这个权限集的systemPermissions授予。平台的规则是:带任何systemPermissions的权限集属于高权限集,不能挂到everyone锚点(ADR-0090 D5/D9)。运行时在启动时拒绝绑定并打警告,os lint直接报错(security-anchor-high-privilege)。所以「默认给所有员工」在这个平台版本上没有自动机制,卡 04 只能把它做成「分发」:七个岗位各自额外绑定clm_requester(法务、财务、档案、管理员、两级领导都同时是发起人),没有岗位的普通员工由管理员在 Setup 里逐人授予。为什么现在问你:改法有两个方向,一个改 §04 措辞,一个向平台提需求;两者都不是开发 agent 能定的。今天不定不阻塞 M1(验收测试用管理员逐人授予跑通了),但卡 07 要按
clm_requester.access门控「我的合同」分区,到那时普通员工看不看得到这个分区,取决于这个决定。选项:
clm_requester由管理员授予未持岗位的员工;持岗位者随岗位绑定」。零改代码;同时向 objectstack 报一个平台缺口:应用自己声明的capability(scope: 'org')不该被算作高权限位。平台修好后,把clm_requester标成isDefault就能自动给所有人,这边只需删一行绑定。clm_requester.access从systemPermissions拿掉,clm_requester标成isDefault: true自动绑到everyone;「我的合同」分区改为只要登录就可见(§04 与 §05 都要改一句)。clm_employee,绑定clm_requester,管理员给每个员工发岗位。§04「岗位七个」要改。代价:A 多一步管理员操作(每个新员工),文档改一句,等平台修好可以收回;B 少一个门控能力,导航分区退化成「登录即见」,但和 §04 的 access 令牌体系不一致;C 多一个岗位,仍然要逐人发,只是从「发权限集」变成「发岗位」。
你要做的:回一个字母,A、B 或 C。
Context
DESIGN.md§04, verbatim:The platform's only mechanism for "the set every authenticated member holds" is
isDefault: trueon the set, which auto-binds it to the built-ineveryoneposition at boot (ADR-0090 D5). That binding is gated bydescribeHighPrivilegeBits(@objectstack/spec/security), whose first rule is: any non-emptysystemPermissionsmakes the set high-privilege. Measured on 17.3.0:plugin-securitybindBaselineToEveryone:refusing to bind fallback set to everyone — high-privilege bits { offending: "system permissions" }— a boot warning, and no binding.@objectstack/lintsecurity-anchor-high-privilege(severity error):isDefault:true suggests binding this set to the 'everyone' audience anchor, but it carries system permissions — the runtime will refuse the binding (ADR-0090 D5/D9).So §04's two sentences cannot both be satisfied automatically on this platform version. Card 04 (#4) implemented the distributed reading without editing §04:
src/security/bind-position-sets.tsbinds every one of the seven positions toclm_requesteras well as to its own set (12 rows; measured on a running app);sys_user_permission_setrows written by the seeded admin — the Setup path.Governing text:
DESIGN.md§04 (the two sentences above);AGENTS.md→ Delivery process → a code PR never touchesDESIGN.md§01–§04 without aneeds-user-decisionfirst; → Platform gaps → report, never patch.Options
A — keep the tokens, state the distribution, report the platform gap. §04 gains one sentence;
objectstackgets an issue proposing that an app-declaredcapabilitywithscope: 'org'(ADR-0066 D1) not count as a high-privilege bit for theeveryoneanchor —manage_usersandclm_requester.accessare not the same kind of thing. When that lands,isDefault: trueonclm_requesterrestores the automatic default and the seven extra bindings can go.B — drop
clm_requester.access, make the setisDefault. The "我的合同" navigation group (§05) is then gated by authentication alone. Consistent with the platform today; inconsistent with the five-token*.accessscheme §04 and §05 build the navigation on.C — an eighth position,
clm_employee. Keeps every token; changes "Position 扁平,七个" and turns the per-employee admin step into a position assignment rather than a set grant.四棱分析
实际业务需求 — A 或 C。业务上「所有员工都能发起合同」是产品定位(§01),门控能力是卡 07 导航分区的基础;B 把「我的合同」分区退化成登录即见,短期无害,但一旦客户要按员工类型(例如外包、实习)收窄「谁能发起」,B 没有开关。A 保留开关。
项目长远合理性 — A。矛盾在平台的高权限判定粗于 ADR-0066 的能力模型(应用能力令牌与平台系统权限被一视同仁),根因应回到平台修;应用侧 A 的代码在平台修好后可整体收回,B 与 C 都是把平台的粗糙固化进设计文本。
防 AI 写错 — A。三个方案里只有 A 不改
systemPermissions的语义;B 让「一个权限集既是默认又不带令牌」成为惯例,下一个 AI 作者会在别的分区照抄,门控能力体系逐渐空心化;C 引入一个只为绑定而存在的岗位,与 ADR-0090「岗位是分发点」勉强相容,但七变八的理由是平台限制而非业务,容易被下一个读者当成业务岗位再挂规则。创业阶段不扩散 — 三者都不扩散能力面。A 增加一步管理员操作与一条上游 issue;B 删一个令牌;C 加一个岗位。A 的成本最低且可逆。
结论:四棱同向 A。推荐 A。
Impact if deferred
M1 is not blocked: card 04's acceptance run staffed the requester accounts through Setup-equivalent grants and every refusal was observed. Card 07 (views/app) gates the "我的合同" group on
clm_requester.access; an employee without the grant will not see it. Deciding before card 07 is dispatched avoids a second pass over the navigation.