Skip to content

[decision] REQ-0006 needs +986 business-semantics and +1,395 authored-total tokens in src/sales — cutting scope does NOT avoid the question (measured), and a third route now exists #1951

Description

@os-elon-musk

Part of #1904。这是一个需要你裁的数字,不是一张施工卡。 ⛔ 在裁下来之前没有任何 PR 该去碰那两条天花板。

前身:#1928(已关,裁决「门禁 改为 多 sales 模块的门禁」)。⛔ 本卡不复用它 —— 那条裁决已执行完毕,这是新的一次。

一、实测缺口(PM 与施工席各自独立量,两边吻合)

src/sales 上跑完整的 REQ-0006(#1916),门禁 exit 1:

层 基线 087b7c5 本卡落地后 天花板 超出
business semantics 54,179 55,986 55,000 986
authored total 99,340 101,395 100,000 1,395
interaction layer 29,477 29,725 31,000 ✓ 余 1,275

本卡花费:business semantics 1,807、authored total 2,055。

三张连号卡的花费:#1914 2,041 · #1915 1,906 · #1916 2,055。⇒ 这不是一次异常,是稳定的单卡量级。

二、⚠️ 「砍范围」这条路 PM 实测过,它绕不开

施工席报「光字段那一块就已经超了」。PM ⛔ 不采信,自己做了干净隔离 —— 把 hook、view、新 flow 全部回退到 main,只留 opportunity.object.ts 的字段改动:

✗ src/sales business semantics ~55,067 (ceiling ~55,000, 超 ~67)
✗ src/sales authored total    ~100,227 (ceiling ~100,000, 超 ~227)

(施工席量到 10 / 170,PM 量到 67 / 227 —— 隔离面略有差异,结论同一。)

⇒ 即使只交付验收 1/2/5、把状态闸门整个砍掉,仍然要动天花板。 只是从「超 986」变成「超 67」。⛔ 砍范围换不来「不用裁」。

三、四条路,PM 不替你选,但把代价量给你

A · 抬两条天花板

⚠️ 用 #1928 确立的同一条算术,⛔ 不要随手挑个数。 那条规则是 anchor(reading) = ceil(reading × 1.05 / 1000) × 1000(维护者 2026-08-17 原话「给 5% 缓冲」):

层 落地后读数 anchor() 现天花板
business semantics 55,986 59,000 55,000
authored total 101,395 107,000 100,000

⚠️ 施工席建议的 57,000 / 103,000 破坏了这条规则 —— 57,000 对 55,986 只有 1.8% 缓冲,而规则要 5%。⇒ 要么按 anchor() 抬到 59,000 / 107,000,要么明确裁定「这一次不给 5% 缓冲」。⛔ 不能既说沿用规则又用一个不符合它的数。

代价:门禁设计上的正常出口。但这是同一条链上的第二次抬升 —— 上次刚抬完约 2,000,而单卡量级稳定在 ~2,000,⇒ 只要 Track A 还有卡,这个对话就会再来。

B′ · 剥冗余内联 label(PM 新量出来的一条,#1928 时不存在)

#1949 证明了「内联串 → 引用」在业务语义层是净负的。PM 去查计量面里还有没有同形状的存量:

  • src/sales/objects/*.object.ts 里 151 处内联 label:,每一处在 en 语言包里都有同一份 —— 完全冗余,而语言包不计量。
  • 净值 ≈ 859 token,同时减 business semantics 与 authored total 两本账。
  • 可行性 PM 实测过:剥掉一个字段的内联 label 后,tsc --noEmit exit 0,pnpm validate ✓ Validation passed,且⛔ 没有为该字段新增任何警告。

另有两类候选但未验证是否冗余:objects 的 description: 34 处 ≈ 870、flows/actions 的内联串 82 处 ≈ 958。⚠️ 这两类在语言包里未必有对应项 —— 若没有,剥掉就是丢内容,不是压缩。

⚠️ 这条路的真代价,PM ⛔ 不藏:棘轮存在的理由是「一个 CRM 销售模块整包装进 AI 上下文窗口」,目的是让人和 agent 读得懂这个包。剥掉 151 个内联 label 之后,一个只读 opportunity.object.ts 的 agent 看不到字段叫什么了,得再去翻语言包。

⇒ 这是拿可读性换余量,而可读性正是棘轮要保的东西。 和删注释不同(门禁 comment-stripped,删注释一个数不动),这个确实能换到数 —— 但方向可能与门禁初衷相反。要你裁的正是这个取舍。

C · 压缩付账(删真代码)

门禁 comment-stripped ⇒ 删注释一个数不动;要付账只能删真元数据 = 拿已交付功能换未交付功能。⛔ PM 不建议。

D · 把 REQ-0006 增量移出 src/sales

与 ADR-0130 R4 冲突(hook 不得挂到别的包的对象上),且 crm_opportunity 本就是 sales 对象。⛔ 不成立,列在这里只为让它被看见地否掉,而不是没人想过。

四、PM 的建议

A(按 anchor(),59,000 / 107,000)先解锁 Track A;B′ 另立一卡单独裁。

理由:B′ 问的是「棘轮到底在保什么」—— 那是个值得单独想清楚的问题,⛔ 不该在「为了解锁 #1916」的压力下顺手答掉。而且 B′ 的 859 单独也填不满 986。

⚠️ 但若你倾向「headline 数字不该再涨」,那 B′ + 一个小幅 A 的组合是可行的,PM 可以按你给的方向去量组合方案。

五、⛔ 不需要你裁的两件,PM 已经裁了(⛔ 不要把三个问题都丢给你)

施工席交了三个 open question,PM 判定其中只有天花板那一个是你的:

  1. 状态闸门用 requested_status 暂存字段的形状 —— PM 裁 采纳。理由:record_change flow 绑的是 AFTER 钩子,⛔ 无法把销售已经写下的 stage 撤回;而验收 3 要求「stage 在裁决前不变」。⇒ 让销售写请求、让批准写 stage,是这个平台上唯一能满足该验收的形状,也正是客户原文 step 13→14「审批后状态正式生效」的措辞。⛔ 不是施工席自由发挥。
  2. 验收 1 的表单渲染面(fieldGroups 派生 vs view.form.sections 枚举) —— PM 裁 按 feat(account): registration identifier, a capability gate, business profile and approval (REQ-0003) #1948 的既有先例(记录页为准,fieldGroups 成员即可),并在最终落地的 PR 里补一次浏览器验证。⛔ 不走 form.sections 枚举那条 —— 那是 AGENTS.md 为「点名的客户需求」保留的逃生口,本卡没有那个理由。

六、当前状态

查重词

source-token-ratchet 第二次抬升 · business semantics 55000 · authored total 100000 · anchor 5% buffer · REQ-0006 token gap · 内联 label 冗余


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority:p1High: required for production / M2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions