Skip to content

administration/state-machines 还剩两处 #920 没枚举到的行为性主张::79-84 的四条「The system also enforces」(审批阈值写成 $500K,实际入口是 $100K)、:114-122 的 Copilot 一节在 src/ 里零支撑 #940

Description

@yinlianghui

来源:#920 / PR #939 实施过程的顺带发现(改 :8 / :86-94 / :106 / :110-112 / :133-134 时逐条回源核对同页其余的行为性主张)。基线 origin/main = 4855d50b(平台 17.0.0-rc.3),行号为 fresh main 上的行号,三语同址。

与 #920 / #921 的边界:#920 的裁定面是「状态机会拦下非法转换」那一族,逐行枚举为 :8 / :82-88(现 :86-94)/ :106 / :110 / :111 / :134,PR #939 已按该枚举清空;#921 是状态词表。下面两处都不在这两份枚举里,也不由 PR #939 的改动导致。

两处证据强度不同,刻意分开写,请分别裁。

一、:79-84「The system also enforces」四条 —— 强证据,其中一条是数字错

The system also enforces:

- **Close Date is required** before moving to *Proposal*.
- **Amount is required** before moving to *Negotiation*.
- **Won/Lost reason is required** when entering *Closed Lost* or *Closed Won*.
- **Approval may be required** to enter *Closed Won* if amount > $500K and discount approval hasn't been granted.
页面主张 src/ 实况
Close Date 在进入 Proposal 前必填 opportunity.object.ts:122-124 的 close_date 是无条件 required: true —— 从建单第一秒就必填,不存在「进入 Proposal 前」这个时点。页面把一条更强的约束描述成了阶段性的
Amount 在进入 Negotiation 前必填 同上,opportunity.object.ts:82-84 的 amount 也是无条件 required: true
赢单/丢单原因在进入 Closed Won / Closed Lost 时必填 ✅ 属实,且机制真实:win_reason 的 requiredWhen 是 record.stage == "closed_won"(:303),loss_reason 是 closed_lost(:327)
金额 > $500K 且未获折扣审批时「可能需要审批」 数字错。opportunity-approval.flow.ts:88 的 START 条件是 record.amount > 100000 —— $100K 就进审批,走 Sales Manager 一档;$500K 是 :235 那条更高的 Sales Director 加签档(vars.oppRecord.amount > 500000)。页面把二档阈值写成了入口阈值,于是一个 $200K 的单子按页面读是「不需要审批」,实际会进审批

前两条是「描述得比实际更宽松」,第四条是具体数字与源码不符,代表读者会据此错判一笔真实交易要不要走审批。第三条正确,不要顺手改掉。

另注:这一节的小标题「The system also enforces」在这里是成立的 —— required 与 requiredWhen 确实会拒绝保存(与状态机那族不同),所以本条不是 #920 的延续,不要套用 PR #939 的「advice, not a gate」口径去改它。

二、:114-122「State machines and the AI Copilot」—— 证据只到「本仓零支撑」,判不了平台侧

The Copilot understands the state machine. When suggesting an action:

- *"Qualify this lead"* → only suggested if status is *Working*.
- *"Convert this lead"* → only suggested if status is *Qualified*.
- *"Mark this opportunity Closed Won"* → only suggested if win conditions are met (...).

This prevents the Copilot from suggesting illegal transitions.

本仓侧实测:grep -rniE "state.?machine|transition|legalNext" src/skills/ src/actions/ 零命中 —— 六个 *.skill.ts 与全部 *.actions.ts 没有任何一处提到转换表、状态机或 legalNextStates。技能的 instructions 里也没有任何一条把状态/阶段的合法后继写进提示词(grep -rniE "qualified|status|stage" src/skills/ 只命中 Customer 360° 与 Revenue Forecasting 里读取字段的说明)。

能证的到此为止。 剩下的部分证不了:平台侧的 agent 在装载对象元数据时是否会把 validations[] 里的 state_machine 一并读进上下文并据以收窄建议,是 @objectstack/runtime / agent 侧的行为,不是本仓能从源码断言的。所以这一条既没被证实也没被证伪,PR #939 因此刻意没动它 —— 同一 PR 里我自己写的初稿有一句「Copilot 只建议转换表允许的那些转换」,正因为证不了而被删掉重写。

要闭合这一条,需要的是一次平台侧探针(起一个 agent 会话,在一条 qualified 的线索上问「Qualify this lead」,看建议是否出现),而不是再读一遍 src/。若探针证明平台不读转换表,那么与 :110(下拉零实现)同型;若证明它读,那这一节是本页唯一真正改变用户所见的地方,应当在 PR #939 改写过的「What a state machine buys you」一节里被点名。

影响

第一处::83 的 $500K 会让读者对一笔 $100K–$500K 的交易做出相反的判断(以为不用审批,实际会被拦进审批流并锁字段)。前两条程度较轻,属于「约束比描述的更严」,读者不会因此漏做什么,但会疑惑为什么建单时就被要求填。

第二处:如果平台确实不读转换表,那么它与 :110 / :111 / :134 是同一批「文档说有、实际没有」的说法,只是躲过了 #920 的枚举。

边界

Refs #920 #921 #575

Activity

  1. added
    documentationImprovements or additions to documentation
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 6, 2026
  2. self-assigned this
    on Aug 6, 2026
  3. yinlianghui commented on Aug 6, 2026

    @yinlianghui
    CollaboratorAuthor

    🔒 已随 #921 并单认领(/pm-dispatch R30,session session_01VHrPAGEgFDoHjphqYG4BMa,分支 claude/issue-921-940-state-machines-truth)——裁定与文件面见 #921 认领评论。


    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

Labels

documentationImprovements or additions to documentationpm:dispatchedDispatched to a dev agent by /pm-dispatch

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions