Archived
docs: ADR-014 确定性步骤 + W05 重写设计 spec + 实施计划(第一份:平台机制)
spec 定死八条:配方驱动零工具 · 六张台账 + P-06 按结论入账 · 四态 AI 定等级规则算 · 保存即铺格 · 类型不一致硬拦 · 审核卡只有确认 · 只做真用得到的那几式。 计划十三个任务,机制先在纯函数与假端口上钉死,再去接真活动。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
@@ -0,0 +1,340 @@
|
||||
# ADR-014 确定性步骤:确定的活由引擎按声明做,不问模型
|
||||
|
||||
状态:**提案**(2026-08-28,待用户定)
|
||||
背景出处:ACT-WORK-05 差异评估九步流程盘点(§2)、`docs/ACT-WORK-05-端到端测试记录.md` 发现表 A–AE。
|
||||
关联:ADR-004(活动包 ABI:**系统不执行代码即知包为何物**)、`docs/活动开发规范.md` §4.4(自动收步)、
|
||||
`PlanStep.humanWrites`(2026-08-28 立的墙)、ADR-005(工具契约与落地预检)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 问题
|
||||
|
||||
用户 2026-08-28 的原话:
|
||||
|
||||
> 「这个不是一个确定的流程吗?根本不需要交给 ai,你直接查库不就知道有没有了吗?」
|
||||
|
||||
指的是 W05 的「逐个料号查库 → 不在库就铺骨架、发数据工单」。这一段没有任何判断余地,却写成了模型的 guide。
|
||||
不是活动作者偷懒 —— **平台里没有别的落点**:
|
||||
|
||||
| 现有机制 | 能做 | 不能做 |
|
||||
|---|---|---|
|
||||
| 纯工具(`pure`) | 算、读台账(1.2.0 起) | 写台账、发卡 |
|
||||
| 判定表(DMN) | 出结论 | 写台账、发卡 |
|
||||
| `doneWhen` | 判「办完没有」,引擎自己收步 | **做事** |
|
||||
| 哨兵(`entryCriteria`) | 判「能不能进这一步」 | **做事** |
|
||||
| 视图绑定语言 | 把台账取出来**摆到屏上** | 写回去 |
|
||||
|
||||
「读台账 + 写草稿 + 发人卡」跨了三样,没有一个机制能整段承接。而引擎这三样能力**全有**
|
||||
(`data.view` / `data.draftWrite` / `humanTool.issueExecution`)—— 缺的只是**声明面**。
|
||||
|
||||
`packages/activity-sdk/src/define.ts` 里 `run?` 的注释早就写着:
|
||||
|
||||
> 留着它是为**确定性子序列(结晶片段)**将来有个落点;不写就是不写,不是缺件。
|
||||
|
||||
这份 ADR 就是给那个落点定形。
|
||||
|
||||
**代价已经付过。** W05 的事故里,至少八条落在「本来就该是确定的」那几步上(§7 逐条验算)。
|
||||
|
||||
---
|
||||
|
||||
## 2. 盘点:W05 九步里哪些是确定的
|
||||
|
||||
| 步 | 确定的部分 | 需判断的部分 |
|
||||
|---|---|---|
|
||||
| **S0_bind** 建上下文 | 铸案号 · 查客户在不在库 · 写需求单(入参搬运+常量)· 逐料号查库写核对表 · 写结论行 | **零** |
|
||||
| **S0d_p08** 派主数据单 | 定名单 · 铺三张表骨架 · 发卡 · 人交回后改旗 | 有 datasheet 附件时从原文抽参数值 |
|
||||
| **S0d_p10** 派资料单 | 定名单 · 发卡 · 人交回后改旗 | **零** |
|
||||
| **S1** 评估输入清单 | 清单九行(四行绑定投影 + 两行固定缺口 + 三行常量默认)· 发执行单 · 把 supplement 抄进需求单 | 人补的自由文本**归纳**成技术约束 |
|
||||
| **S2** 标准化对照表 | 关系骨架 · 逐参数对照行(原 PN 参数集 × 候选同名行的 join)· 补封装/生命周期两行 | 单位换算;`constraint_type` 未标时归类(**应进 DMN,不进配方**) |
|
||||
| **S3** 逐项差异评估 | 工具串接 · 四态照抄 · 计数 · `difference_summary` · 置信取最小 | **客户原话 → 约束式** · 影响陈述 · UNKNOWN 去向与验证条件 · 推荐理由扩写 |
|
||||
| **S4** 结论审核 | 发决策卡(内容是计数投影)· approve 收步 | **读人的自由文本意见 → 定位到具体行 → 改实** |
|
||||
| **S5** 拟落账 | 分析状态推 FAE 确认 · 回写需求单五项(风险取最高档、VAL 号拼接、编号、常量三项) | 只有 summary 一句人话(可模板化) |
|
||||
| **T_release** 放行 | submit · 无分支去向 | 两条裁量判据 · 打回后修订 |
|
||||
|
||||
**agent 真正不可替代的只有四类**:①自然语言 → 结构化;②读人的意见并落到具体行;③写给人看的话;
|
||||
④非结构化来源抽取(datasheet 抽值、单位换算)。第四类在实跑中一次都没发生过(没传附件)。
|
||||
|
||||
**结论:九步里三步整个确定(S0_bind / S0d_p10 / S5),四步八成确定,只有 S3 是 agent 的主场。**
|
||||
按拍数算,一单十来拍里有七八拍在做确定性的活 —— 而每一拍都是一次采样,都有编错号、抄错行、漏一列的机会。
|
||||
|
||||
---
|
||||
|
||||
## 3. 决策
|
||||
|
||||
### 3.1 声明式配方,**不执行活动包代码**
|
||||
|
||||
`sys.activity_package.artifact`(包的 `index.js`)存了库,但**至今一次都没被执行过**。这份设计**不开这条路**:
|
||||
|
||||
- ADR-004 的立场是「系统不执行代码即知包为何物」;配方是**数据**,装进来仍然只是数据,
|
||||
可静态审、可回放、可在治理台上摆出「这一步系统会做什么」。执行代码则相反。
|
||||
- 执行第三方包要配沙箱、超时、内存墙,而 `scanArtifact` 只是文本扫描,拦不住混淆。
|
||||
- 配方要表达的形状**很窄**(§3.2 三个动词),不值得为它开一个能跑任意代码的面。
|
||||
|
||||
**代价**:表达力有上限。上限之外的**不要硬塞** —— 退回模型,或者把那一段切成独立的 agent 步(§3.4)。
|
||||
|
||||
### 3.2 三个动词,复用已有的两套求值
|
||||
|
||||
配方只有三个动词:
|
||||
|
||||
| 动词 | 做什么 |
|
||||
|---|---|
|
||||
| `project` | 从「某个来源的每一行」投影出台账行,`draftWrite` 落草稿层 |
|
||||
| `card` | 发一张人类工具的卡(执行工单 / 数据工单 / 数据录入卡),**至多一张** |
|
||||
| `say` | 一句给人看的交代(模板串,不是模型生成) |
|
||||
|
||||
条件与聚合**不发明第二套求值**:
|
||||
- 条件用 **S-FEEL**(`when`,对任务视图求值)—— 与哨兵、`doneWhen` 同一个求值器;
|
||||
- 计数/聚合用**基座读数**(`_rows` / `_missing` / `_distinct_x` / tally 计数)—— 本来就在作用域里。
|
||||
|
||||
### 3.3 `auto` 是「问模型之前先把确定的事做了」,不是「整步替代」
|
||||
|
||||
`PlanStep.auto` 是一个属性。引擎在这一步的**每一拍拍首**先跑配方,然后:
|
||||
|
||||
- 配方发了卡 → 这一拍到此为止(**零 token**,不问模型);
|
||||
- 没发卡且这一步**没有 `guide`** → 求 `doneWhen`,真了收步、进下一步(下一步若也是 auto 就接着跑);
|
||||
- 没发卡且这一步**有 `guide`** → 照常问模型(半 auto:确定的已经做完,模型只面对剩下的判断)。
|
||||
|
||||
这样老步骤一个字不改,可以一步一步搬。
|
||||
|
||||
### 3.4 作用域:**一个计划项内,到交出控制权为止**
|
||||
|
||||
配方跑到「发卡」就结束 —— 与现有 `handsOff` 语义(ask/human/decide/listen/submit 是交出控制权)对齐。
|
||||
人答回来之后,那一步若还有活,归 `guide`。
|
||||
|
||||
**推论(重要)**:一步要么确定,要么不是。**不做「一半 auto」的复杂机制** —— 判断点要先从那一步里切出去。
|
||||
例:S0d_p08 的「datasheet 抽值」应当移出这一步(归到起单读来件),这一步才变成纯 auto。
|
||||
**这条逼着活动作者把判断点想清楚,是特性不是限制。**
|
||||
|
||||
### 3.5 幂等
|
||||
|
||||
配方会被反复进入(人答卡后再 tick),必须幂等:
|
||||
|
||||
- **写**:`draftWrite` 本来就是同 PK 覆盖。值没变 → **静默跳过,不留痕、不算空转被拒**
|
||||
(「写了等于没写」那条判据是拦模型空转的,配方不是模型);
|
||||
- **发卡**:先看 `worldTouched` —— 发过就不再发。人工激活的 auto 步,**配方发卡就是启动**。
|
||||
|
||||
### 3.6 出错 = 交人,不重试、不退回模型
|
||||
|
||||
配方抛错(地址不存在、S-FEEL 算不出、卡骨架不合契约)是**活动包的 bug**:如实留痕 + 交人。
|
||||
**不重试五遍,也不退回模型** —— 退回模型就是让它去凑,那正是这份 ADR 要消灭的东西。
|
||||
|
||||
### 3.7 静态审在装的时候把住
|
||||
|
||||
`staticAudit` 扩到配方(与 `refersTo` 目标检查同款,写错地址 = 每一单都错):
|
||||
|
||||
- `into` / `each` / `lookup` / `joinRows` 的台账地址必须在 `declarations.ledger` 里(与写的授权面同一份名单);
|
||||
- `fields` 的列名必须在该对象的列声明里;
|
||||
- `when` 的 S-FEEL 必须能解析,引用的名字要绑得上(`boundNames`,已有);
|
||||
- 卡骨架的 `view` 必须在 `viewTemplates` 里;
|
||||
- 同一张表既在 `auto.project` 里又在 `humanWrites` 里 → **警告**(铺骨架合法,但要作者确认列不重叠)。
|
||||
|
||||
### 3.8 观测与度量
|
||||
|
||||
- 配方的每一笔照常进 `sys.task_memory`,`detail.auto = '<步名>#<第几笔>'`;
|
||||
工作日志三色里归**系统灰**(已有档,不必新增);
|
||||
- 治理台的活动详情能摆出「这一步系统会做什么」(配方是数据,渲染得出来)—— 这是相对提示词的一大好处;
|
||||
- **自主率的分法要认第三档**:现在两档(AI / 人),配方做的事既不是 AI 判的也不是人办的,是系统做的。
|
||||
|
||||
---
|
||||
|
||||
## 4. 声明形状
|
||||
|
||||
```ts
|
||||
// PlanStep 新增(可选,老活动一个字不改)
|
||||
auto?: AutoRecipe;
|
||||
|
||||
type AutoRecipe = {
|
||||
/** 配方级局部值:先算一遍,后面所有表达式都能引用({in:'evalRef'})—— 整单只有一个案号,靠它 */
|
||||
readonly let?: Record<string, AutoExpr>;
|
||||
/** 按序执行;每一笔可带 when(S-FEEL),假就跳过这一笔 */
|
||||
readonly do: ReadonlyArray<AutoAction>;
|
||||
};
|
||||
|
||||
type AutoAction =
|
||||
| { kind: 'project'; when?: string; into: string; from: AutoSource; fields: Record<string, AutoExpr> }
|
||||
| { kind: 'card'; when?: string; workOrder: 'execution' | 'entry'; variant?: 'data';
|
||||
title: AutoExpr; gateLedgers?: string[]; view?: string; /* 指导书等静态文本直接写 */ }
|
||||
| { kind: 'say'; when?: string; text: AutoExpr };
|
||||
|
||||
type AutoSource =
|
||||
| { once: true } // 一行
|
||||
| { rows: ReadonlyArray<Record<string, AutoExpr>> } // 固定几行(S1 的默认三项)
|
||||
| { each: string; where?: Record<string, AutoExpr>; // 'in:candidateInternalPns' | 'mine:域.对象' | 'ledger:域.对象'
|
||||
then?: { each: string; where?: Record<string, AutoExpr> } }; // 第二层,**最多两层**
|
||||
|
||||
type AutoExpr =
|
||||
| string | number | boolean // 常量
|
||||
| { in: string } // 入参 / case:* / 基座读数 / let
|
||||
| { self: true } // each 是数组时的本项
|
||||
| { col: string } | { outer: string } // 本行的列 / 外层那一行的列
|
||||
| { cat: AutoExpr[] } // 拼接
|
||||
| { fmt: AutoExpr; as: 'digits' } // 只留数字(铸号)
|
||||
| { lookup: string; by: Record<string, AutoExpr>; take: string; else?: AutoExpr } // 查另一张表的一列
|
||||
| { joinRows: string; where?: Record<string, AutoExpr>; take: string; sep?: string } // 多行一列拼成串
|
||||
| { when: string; then: AutoExpr; else: AutoExpr }; // S-FEEL 条件(可嵌套)
|
||||
```
|
||||
|
||||
**字段按声明顺序求值,已算出的字段进同一行的 S-FEEL 作用域** —— 「先 lookup 出依据,再按依据判 found/absent」
|
||||
这种写法靠它成立。
|
||||
|
||||
### 4.1 例:S0d_p10_document(整步确定,最小的那个)
|
||||
|
||||
```ts
|
||||
auto: {
|
||||
do: [
|
||||
{ kind: 'card',
|
||||
when: 'sub_eval_pn_check_exists_status_absent > 0',
|
||||
workOrder: 'execution', variant: 'data', view: 'p10-document-create',
|
||||
gateLedgers: ['parts.document'],
|
||||
title: { cat: ['数据工单 · 原厂技术资料创建(P-10):',
|
||||
{ joinRows: 'mine:sub_eval.pn_check', where: { exists_status: 'absent' },
|
||||
take: 'internal_pn', sep: '、' }] } },
|
||||
{ kind: 'say', text: '这几颗料的原厂技术资料库里查无记录,已派数据工单请你登记。' },
|
||||
],
|
||||
}
|
||||
// guide 不写。doneWhen 照旧:parts_document_rows >= parts_profile_rows and parts_document_missing = 0
|
||||
// 人在件上填完确认 → 数据即入库 → 下一拍 doneWhen 成立 → 引擎收步。**模型在这一步一次都不出现。**
|
||||
```
|
||||
|
||||
### 4.2 例:S0_bind 的铸号与存在性核对
|
||||
|
||||
```ts
|
||||
auto: {
|
||||
let: {
|
||||
digits: { fmt: { in: 'case:openedAt' }, as: 'digits' },
|
||||
evalRef: { cat: ['W05-', { in: 'digits' }] },
|
||||
requestId:{ cat: ['REQ-', { in: 'digits' }] },
|
||||
},
|
||||
do: [
|
||||
// 客户不在库 → 发数据录入卡,这一拍到此为止
|
||||
{ kind: 'card', when: 'customer_profile_rows = 0', workOrder: 'entry', /* … */ },
|
||||
{ kind: 'project', into: 'demand.request', from: { once: true },
|
||||
fields: { request_id: { in: 'requestId' }, customer_code: { in: 'customerCode' },
|
||||
requirement_version: 'V1', request_type: '技术需求',
|
||||
request_description: { in: 'requestDescription' },
|
||||
input_snapshot_ref: { cat: ['SNAP-', { in: 'evalRef' }] },
|
||||
original_internal_pn: { in: 'originalInternalPn' },
|
||||
request_status: 'pending', current_activity: 'ACT-WORK-05', current_stage: 'assessing' } },
|
||||
{ kind: 'project', into: 'sub_eval.pn_check', from: { each: 'in:candidateInternalPns' },
|
||||
fields: { eval_ref: { in: 'evalRef' }, internal_pn: { self: true }, role: 'candidate',
|
||||
found_pn_ref: { lookup: 'ledger:parts.profile', by: { internal_pn: { self: true } },
|
||||
take: 'internal_pn', else: '' },
|
||||
exists_status: { when: 'found_pn_ref != ""', then: 'found', else: 'absent' } } },
|
||||
// 原 PN 那一行同理(from: { once: true },role: 'original')
|
||||
{ kind: 'project', into: 'sub_eval.verdict', from: { once: true }, fields: { /* … */ } },
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
「在不在库」从此是一次 `lookup`,不是模型的一句断言 —— 08-27 那条「原 PN 不在库却判在库」结构性消失。
|
||||
|
||||
---
|
||||
|
||||
## 5. 引擎行为(拍内次序)
|
||||
|
||||
```
|
||||
tick 开始
|
||||
├─ ① 拍首自动收步(现有:doneWhen 为真的项,人工激活项需 worldTouched)
|
||||
├─ ② 算 current(当下在办的那一步)
|
||||
├─ ③ current.auto 存在 → 跑配方
|
||||
│ ├─ 求 let
|
||||
│ ├─ 按序执行每一笔(when 假则跳过)
|
||||
│ │ · project → 逐行 draftWrite(同 PK 覆盖;值没变静默跳过)
|
||||
│ │ · card → 先看 worldTouched,发过就跳过;发了标 worldTouched、烧 humanCalls
|
||||
│ │ · say → 进对话区
|
||||
│ ├─ 每一笔留痕(by=系统,detail.auto)
|
||||
│ └─ 抛错 → 留痕 + 交人(不重试、不退回模型)
|
||||
├─ ④ 发了卡 → status awaiting,收拍(零 token)
|
||||
├─ ⑤ 没发卡 → 重求 doneWhen;真了收步,回 ② (封顶 8 轮,与现有自动收步同款)
|
||||
├─ ⑥ 这一步有 guide → 照常问模型(半 auto)
|
||||
└─ ⑦ 无 guide、doneWhen 不成立、也没有卡在等 → **交人**(配方没做到位,是包的 bug)
|
||||
```
|
||||
|
||||
**预算**:配方不烧 token;发卡烧 `humanCalls`;配方段在同一 tick 内,不额外计 step。
|
||||
|
||||
---
|
||||
|
||||
## 6. 与现有机制的衔接
|
||||
|
||||
| 机制 | 处置 |
|
||||
|---|---|
|
||||
| `doneWhen` | 不变。auto 步几乎都该有 —— 它做的事是可验的 |
|
||||
| 哨兵 `entryCriteria` | 不变。auto 步照样要满足入场前提才在场 |
|
||||
| `worldTouched` | 配方发的卡同样标 —— 它是真发了 |
|
||||
| `humanWrites`(2026-08-28) | **配方豁免**:那道墙防的是模型即兴,配方是审过的声明。铺骨架合法,人填内容不冲突(静态审提示列不要重叠) |
|
||||
| 写三分 | 不变:配方只写**草稿层**,落正式表仍靠放行 / 数据工单确认入库 |
|
||||
| 「一单一卡」 | 不变:配方至多一张卡 |
|
||||
| 熔断 | 配方不会「被拒」,不进 `stalledTurns` |
|
||||
| 试跑 / 回放 | 配方是纯数据求值,同输入同结果 —— 可回放。**配方里没有时钟与随机**(时刻取 `case:openedAt`) |
|
||||
| 记账旗 | **该删的删,不是该 auto** —— `input_confirmed_total` 这类基座本就数得出来 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 回溯验算:历史事故有几条会结构性消失
|
||||
|
||||
| # | 事故 | 落在哪 | auto 后 |
|
||||
|---|---|---|---|
|
||||
| 1 | 编号从正式表里**别单的案号**里挑 | S0_bind 铸号 | 消失(模板铸号) |
|
||||
| 2 | 原 PN 不在库却判「在库」(发现 I) | S0_bind 查库 | 消失(lookup 现查) |
|
||||
| 3 | 数据工单派给了**在库**的那颗(发现 J) | S0d_p08 名单 | 消失(where absent) |
|
||||
| 4 | 压拍没写骨架就发卡,人打开是空表(发现 Q) | S0d_p08/p10 | 消失(配方按序) |
|
||||
| 5 | S1 清单 11 行全漏 `input_item`,人无处可填 | S1 前半 | 消失(字段声明齐全) |
|
||||
| 6 | 库里有值的参数被 S1 当缺口再问一遍(发现 AB,三次复现) | S1 前半 | 消失(清单是投影) |
|
||||
| 7 | P-10 抄**原 PN 的规格书**安在候选头上(发现 AE) | S0d_p10 | 消失(模型不出现) |
|
||||
| 8 | `finish` 撞 worldTouched 墙五拍熔断(发现 AE 同单) | S0d_p10 | 消失(那一步不问模型) |
|
||||
|
||||
**八条落在会被 auto 掉的三步半上。** 剩下的事故(工具没调、比对入参抄错、验收卡面孔、重做循环)
|
||||
不在这个范围内 —— 它们该由别的机制治,这份 ADR 不承诺。
|
||||
|
||||
---
|
||||
|
||||
## 8. 不做什么
|
||||
|
||||
- **不调工具**:工具有副作用面与预算面,先不给(S3 的 `compare → recommend` 串接留作待定)
|
||||
- **不 `finish`、不 `submit`、不发决策卡**:收步归 `doneWhen`,终局归 submit,岔路口本就是判断
|
||||
- **不写正式表**:仍走草稿层
|
||||
- **不做三层以上的嵌套**:两层(关系 × 参数)是 W05 的上限;超出就别 auto
|
||||
- **不在治理台上编辑配方**:那就成了低代码平台;配方随包走,改配方 = 升版本重装
|
||||
- **不承诺消灭 agent**:§2 的四类判断照旧归它
|
||||
|
||||
---
|
||||
|
||||
## 9. 代价与风险
|
||||
|
||||
1. **活动作者要写结构化声明,不能再靠散文。** 但那些散文本来就在(而且更长、还不能测);
|
||||
配方**能单测**(纯数据求值,包内自测钉死)。
|
||||
2. **代码错是必然的错,模型错是概率的错。** 配方写错 = 每一单都错。
|
||||
对策:静态审(§3.7)+ 包内自测 + 安装两审的回放审拿样例入参跑一遍配方。
|
||||
**但必然的错比概率的错好查** —— 这正是把它从模型手里拿走的理由。
|
||||
3. **立场要改口。** 「组织的工作定义为可编排的工作流……活动是完成一项任务的 Agent 机制」——
|
||||
加一句:**agent 只在真需要判断的地方出现,与「人只在责任点与放行点出现」是同一条原则。**
|
||||
确定的事交系统,判断交 AI,责任交人。
|
||||
4. **把有判断的地方硬写成规则的风险。** `constraint_type` 的 hard/soft 归类按品类会变 ——
|
||||
这类**进 DMN 判定表,不进配方**;配方里只许出现「取值、拼装、投影、发卡」。
|
||||
5. **现在的「确定」有一半是靠强制命名一致换来的。** S2 能纯 join,前提是「候选与原 PN 参数名一模一样」
|
||||
(P-08 建骨架时用中文名硬压 + 门上的行数对账)。**一旦料号来自外部导入**,同义归一就回来了 ——
|
||||
那是判断,是 agent 的活。**auto 化不等于永远不需要 agent。**
|
||||
|
||||
---
|
||||
|
||||
## 10. 迁移次序(每搬一步都要五案例 e2e:released + 被拒 0 才算数)
|
||||
|
||||
1. **`S0d_p10_document`** —— 最小、纯粹、刚出过事;拿它验证机制(配方 + 静态审 + 留痕 + 观测)
|
||||
2. **`S5_prepare_landing`** —— 整步确定、不发卡;验证「不发卡时接着走 doneWhen 收步」那条路
|
||||
3. **`S0_bind`** —— 整步确定、含一张录入卡的分岔;验证 `let` 铸号与 `lookup` 存在性
|
||||
4. **`S1_input_confirm` 前半** —— 清单投影 + 发卡;半 auto(收口仍归 guide)
|
||||
5. **`S0d_p08_master`** —— **先把 datasheet 抽值切出去**,再 auto
|
||||
6. **`S2_normalize`** —— 两层嵌套,最难;搬之前先确认它与比对工具的 join 是否重复(§11)
|
||||
|
||||
---
|
||||
|
||||
## 11. 待定(要用户定的)
|
||||
|
||||
1. **决策卡要不要给配方**:S4 第一张卡的 ask 内容是计数投影,确定;但决策卡是岔路口,给了会不会滑坡?
|
||||
2. **工具串接要不要做第四个动词**:S3 的 `compare → recommend` 之间模型只是转手 counts,却占掉整整一拍。
|
||||
3. **`humanWrites` 该不该细到列**:现在是表级。auto 铺骨架 + 人填内容之后,列级更准。
|
||||
4. **S2 与比对工具的 join 是否重复**:`compare-parameters` 1.2.0 起自己从台账取参数对,
|
||||
而 S2 让模型抄的 `difference_item` 对照表是**同一份 join**。一份事实做了两遍,一遍还是手抄的 ——
|
||||
要么 S2 auto 化,要么让工具的出参直接落 `difference_item`(那是另一个机制:工具出参绑台账)。
|
||||
5. **`T_release` 第三条裁量判据**「推荐等级与差异明细一致」就是工具的定级规则本身,
|
||||
让模型再裁一次是给自己盖章 —— 该删(与 08-01 在 A1 上拆掉 L4 同款)。
|
||||
Reference in New Issue
Block a user