Skip to content

Decision: where does the intake-captured payment arrangement F9 reads actually live? #14

Closed

Description

@hotlong

Raised by card 05 (#13) rather than guessed at. Three statements in DESIGN.md cannot all hold; card 05 shipped the only shape that is implementable today and left the choice here.

The three statements

  1. §06 F9 contract_activate — on entering active: 「…发起时填了付款安排则生成 clm_payment_plan;…」. So F9 reads a payment arrangement captured at intake and materialises the rows on activation.
  2. §03 clm_contract field list — has nowhere to put it. There is no payment-arrangement field, and clm_payment_plan is a controlled_by_parent child, not a scalar.
  3. §04 permission matrix — clm_payment_plan | clm_requester: R(本人合同). The launching requester may read instalments, not create them.

F1 is the launch form every employee uses (§05「我的合同(所有人)· 发起合同」). So the one actor who fills the intake form is the one actor who may not write the object F9 expects intake to have filled.

Measured, not inferred

On @objectstack/spec 17.3.0, as a user holding only clm_requester, each with its positive control:

POST /api/v1/data/clm_payment_plan   (requester)      403 PERMISSION_DENIED
    {"error":"You do not have permission to perform this action.
      Contact your administrator if you need access.",
     "code":"PERMISSION_DENIED","object":"clm_payment_plan"}
POST /api/v1/data/clm_payment_plan   (legal counsel)  201    <- control, §04 grants legal RC

The consequence in the flow was worse than a clean refusal. An earlier draft of contract_intake asked for a first instalment on its last screen and created the row. Driven through the action door as a requester with every input supplied:

POST /api/v1/actions/clm_contract/launch_contract
  -> {"code":"FLOW_FAILED","message":"Flow 'contract_intake' failed:
       Node 'create_payment_plan' failed: create_record(clm_payment_plan) failed:
       You do not have permission to perform this action. ..."}

create_payment_plan is the last substantive node, so the run had already committed the contract and its version 1. It left NDA-2026-0010 behind as an orphan: status: draft, version_count: 1, never submitted, with a permission error as the toast.

What card 05 did in the meantime

Removed the instalment capture from F1. Step 5 is now the submit toggle alone. This is also what §06 F1 itself specifies — its steps end at 「建合同(draft)与版本 v1 → 可选一键提交」 and never mention a payment schedule; the schedule appears only in F9. Nothing about payment capture is invented, so no path is silently half-built.

Open: F9 still says 「发起时填了付款安排」. Today nothing at intake can fill it.

Options

A. Intake does not capture it; F9 drops the clause. Payment plans are created after activation by finance (§04 gives finance RCU), on the contract's own tab. Cheapest, no schema change. Cost: an editorial change to §06 F9, and whoever launched the contract has to hand the schedule to finance out of band.

B. clm_contract carries the arrangement as a scalar the requester may write — e.g. payment_arrangement json or a small first_instalment_* trio — and F9 expands it into clm_payment_plan rows under its own runAs: 'system'. Honours F9 as written and keeps §04 intact, because the requester writes a field on their own contract rather than a row on a reserved object. Cost: new fields in §03 (governed surface), and one more shape for the importer and the detail page to know about.

C. Widen §04 to give clm_requester C on clm_payment_plan. Smallest diff, and F1 goes back to creating the row directly. Cost: it hands every employee the ability to create payment rows on any contract they can reach, which is exactly the split §04 drew deliberately (finance owns money). Not recommended.

Recommendation: B. It is the only option that keeps §06 F9 true as written and §04 unweakened, and it puts the captured intent where the state machine can already see it. A is a legitimate simplification if the maintainer would rather F9 lose the clause than §03 gain a field — that is a product call, not an engineering one, which is why this is a card and not a commit.

Blocks nothing today: card 05 ships without it. Card 09 (F9 contract_activate) is the card that needs the answer.

Activity

  1. zhuangjianguo commented on Sep 9, 2026

    @zhuangjianguo
    Collaborator

    维护者速读

    ⚠️ 拟稿,不是裁决。 总监席本场服役档 claude-opus-5 ≠ CONTRACT_REVIEW_TIER(claude-fable-5-1,scripts/pm/dispatch-gates.mjs:10446,精确比较),四职停放,⛔ 不裁不清标。本评论只补这张卡入箱时欠的四棱块与速读,把它变成可决的形状。标签一动未动。

    事情:设计方案第 6 章 F9 说「发起时填了付款安排则生成付款计划」,但第 3 章的字段清单里没有任何地方放这个付款安排,而第 4 章又只给发起人「读」付款计划的权限。所以 F9 要读的东西,今天既无处存,填它的人也无权写。

    卡 05 照实处理了:把付款捕获从发起表单里撤掉(这也正是 §06 F1 自己写的步骤 —— F1 从头到尾没提付款计划,只有 F9 提)。没有半建成的路径。

    这里最值得你看一眼的,是撤掉之前发生了什么:早先的草稿在发起流程最后一屏创建了付款行,以发起人身份实测跑下来 ——

    POST /api/v1/actions/clm_contract/launch_contract
      -> FLOW_FAILED: Node 'create_payment_plan' failed: PERMISSION_DENIED
    

    而 create_payment_plan 是最后一个实质节点,合同和版本 v1 已经落库了。留下 NDA-2026-0010 一个孤儿:draft、version_count: 1、永不提交、界面上只有一句权限错误。这就是不修会发布出去的形态。

    你要做的:回一个字母,A、B 或 C。

    四棱分析

    卡片正文(英文,卡 05 所写)推荐 B。我按四棱重算,结论偏 A,分歧点写在下面,请你据此拍板。

    实际业务需求 — 偏 A,且这一棱要求实测。判据是「谁在写这个键、谁在读」。今天:没有人写(F1 不采集),F9 读一个不存在的东西。CLM 买家确实常要求发起时录商务条款,但那是「读起来像有用」;这张卡拿不出具名拉动,卡片自己也写着 Blocks nothing today。按不扩散那一轴的 implementation-first 处置,无拉动的声明面从紧。

    项目长远合理性 — 偏 A。这是协议内部自相矛盾(§06 F9 对 §03 字段清单),不是 spec 与代码不一致,所以「改代码对齐协议」选不出边。往长远看:B 让付款意图有两个住处(合同上的标量 + clm_payment_plan 子行),靠一个 flow 维持两者一致 —— 这正是 §01 严禁的跨缝重复字段的形状。A 让钱只有一个写手(财务,§04 已给 RCU),单写手是更干净的架构。

    防 AI 写错 — 最偏 A,差距也最大。今天 §06 F9 就是一个运行时不兑现的声明:文档说发起时能填,系统里没有任何地方能填。这恰恰是「声明即强制,绝不让 AI 声明一个运行时不兑现的能力」要防的东西,也正是 ADR-0049 enforce-or-remove 的判据形状。A 是删掉那句不兑现的声明(响亮方向)。B 反而新增一个标量,其与子行的关系由 flow 维持 —— 下一个 AI 作者写一个 flow 兑现不了的付款安排,没有任何闸门会拦。

    创业阶段不扩散 — 明确偏 A。A 零新增。B 要在 §03(受管面)加字段,还要让导入映射与详情页各多认一种形状。C 被卡片自己否决,理由我同意:它把「财务管钱」这条 §04 刻意画的线抹掉。

    结论:四棱同向 A,防错那一棱差距最大。拟推荐 A —— F9 删掉「发起时填了付款安排」那半句,付款计划由财务在合同自己的页签上于生效后创建。

    若你更想要 F9 字面成立,B 也自洽,但请注意它的真实代价不是「加个字段」,是给付款意图开第二个住处;那种情况下建议同时明写标量与子行的唯一方向(标量只作 F9 的输入、生成后即只读),否则两处会漂。

    落地与关联

    不阻塞在途卡片。消费者是卡 09(F9 contract_activate),尚未派发。#6、#10、#31 同样卡在卡 09 上,四张一起回可让卡 09 一次派发到位;#6 与 #10 还与本卡同碰 contract.hook.ts 与 §03,一并回答就是一次编辑。

    ⚠️ 前提新鲜度:本卡的 403 读数取自 @objectstack/* 17.3.0。但那个 403 是 §04 刻意授的权,不是平台限制,所以本卡的前提基本不受 17.4 影响 —— 与 #11/#19/#20/#28/#31 不同,这张可以现在决定。


    Generated by Claude Code

  2. zhuangjianguo commented on Sep 9, 2026

    @zhuangjianguo
    Collaborator

    裁定:A —— 第 6 章 F9 删掉「发起时填了付款安排」,付款计划由财务在生效后建

    维护者裁决,2026-09-09,常设决裁批第 1 批,逐字:

    第 1 批 平台的问题去平台修,业务的问题按照你的意见。

    本卡是业务问题(设计方案第 6 章对第 3 章的内部矛盾 + 谁写钱的产品取舍,与平台能力无关)⇒ 按席位推荐 A。

    ⚠️ 记录在案:这条裁定采纳的是席位推荐 A,不是卡片正文的 B。 分歧理由已写在本卡 2026-09-09 的四棱拟稿里,核心是防错轴 —— 今天第 6 章 F9 是一个运行时不兑现的声明,A 删掉它(响亮),B 新增一个靠流程维持一致的标量,其失败是静默的(界面正常,直到财务对不上账)。

    Governing text(录裁前重跑):DESIGN.md §06 F9「…发起时填了付款安排则生成 clm_payment_plan;…」;§03 clm_contract 字段清单(无付款安排字段);§04 权限矩阵 clm_payment_plan | clm_requester: R(本人合同)。

    鲜度门:正文最后编辑 2026-09-07T17:09:18Z;其后一条评论(2026-09-09T14:34Z)是本席自己补的四棱拟稿,无第三方新前提。

    裁后执行

    1. §06 F9 编辑(随折叠的设计文档 PR,链首 [Decision] DESIGN.md §03 requires a termination reason but declares no field for it #6):删去「发起时填了付款安排则生成 clm_payment_plan」这半句。F9 生效时不再声称读取任何发起期付款意图。
      ⚠️ §06 不在受管面(受管面是 §01–§04),但它与本批的 §03/§04 编辑同 PR,所以整个 PR 仍走受管面路径交维护者合并。
    2. §03 不动:A 的全部价值就是不加字段。
    3. §04 不动:财务的 RCU 权限已经在矩阵里,发起人保持只读。
    4. 卡 09 据此写 F9:生效流程不展开付款计划。⛔ 不留任何「以后可能要读发起期付款安排」的挂钩或注释 —— 那会把刚删掉的声明以另一种形式留下。
    5. 卡片正文列的 C(放宽权限让发起人建付款行)明确否决,理由记在案:它抹掉 §04 刻意画的「财务管钱」这条线。

    状态转换:needs-user-decision → pm:queue(同一笔标签写入)。

    ⚠️ 置信缺口照录:我呈报时说过,看不见发起人与财务今天实际怎么交接付款安排。裁定取 A 之后,这个交接在系统外(口头、邮件、或合同摘要)。若将来发现这是个真实断点,那时的正确形态仍是 B,而不是 C —— 记在这里,免得下一个人从头论证一遍。


    Generated by Claude Code

  3. self-assigned this
    on Sep 9, 2026
  4. zhuangjianguo commented on Sep 9, 2026

    @zhuangjianguo
    Collaborator

    Claim: PM loop round 2 (seat repo:hotclm) — member of a folded family dispatch; chain head is #6.

    Session: session_01R3n3GGzobdegM4HUzah1iR
    Branch: claude/issue-6-design-rulings (shared with #6 and #10 — named for the chain head)
    Worktree: hotclm-issue-6
    Domain: repo:hotclm
    File surface: DESIGN.md §06 F9 only — deleting the intake-payment clause
    Container & model: S, mode:subagent, model: default judgement tier
    Clause-②: no
    Thread-read: 5604414891 (this seat's ruling comment on this card, 2026-09-09T15:0xZ)
    Serial constraints cleared: see the chain-head claim on #6 for the full check and the five folding gates. In flight alongside: #39 (card 09), file-surface disjoint.

    This card's share of the shared PR: §06 F9 loses 「发起时填了付款安排则生成 clm_payment_plan」. §03 gains nothing — the whole point of ruling A is that no field is added. The code half (F9 not expanding any payment arrangement, and ⛔ leaving no hook or TODO anticipating one) lands in #39, so the PR here carries Refs #14, ⛔ not Fixes.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions