Archived
feat(w05): 案例模型换成四步 —— 零 guide、零工具、零记账旗
九步砍成四步:校验入参 / 差异分析 / 结论审核 / 落账放行。 三道入场哨兵全读基座数,caseFileModel 里一面记账旗都没有 —— 旗是活动自己写的数,而「机检只读基座数」这条在本仓被违反过六次。 审核与放行触达的是人:标人工激活、不给 doneWhen。 说明书瘦成「整单的事」,示例一律占位形 —— 模型会把示例当成这一单的值。 manualActivation 未照 brief 给的 planItem+definitionRef 写法(与本仓 cmmn-parse.ts 不兼容,会解析出错误的计划项 id):改用本仓既有的单元素写法 —— <humanTask id="..." manualActivation="true">,与 steps.test.ts 给定的 RED 测试、 E04/I01/旧九步 W05 的既有约定一致。 顺带恢复 Task 2 遗留的两条「Task 3 补回」skip(读写面 ⊆ 台账声明 / 工具 ⊆ 声明工具, 后者按零工具的新立场做了修正而非照抄旧断言);第三条(T_release judge criterion 逐字对应 acceptanceCriteria label)调查后判定为结构性不可恢复 —— 它检查的「guide 散文里嵌 judge criterion 给模型执行」这套机制随零 guide 重写整体撤掉,继续保留 skip 并订正注释说明原因。 四步重写让 activity.test.ts 的「案例模型与清单的对齐」组里 7 条既有(未 skip)断言 硬编码了旧九步结构,不改不可能 pnpm gates 绿:仍然成立的按新模型更新数字/名单 (四计划项 / 两处不给 doneWhen / 三段阶段);检查对象已被撤掉机制的转 skip 并写明 原因(P-08/P-10 双视图已合并进单一 S1_inputs;决策卡 JSON 骨架已从说明书散文挪进 配方的结构化 card 声明)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
@@ -1,688 +1,191 @@
|
||||
/**
|
||||
* ACT-WORK-05 差异评估的案例模型 —— **双表示同版本**:CMMN XML(机器面)与案例说明书(叙事面)。
|
||||
*
|
||||
* 业务出处:`docs/SS02-ACT-WORK-05-html/ACT-WORK-05-活动流程与工单说明.md`(步骤 0.5 + 5 步,
|
||||
* 1 数据(条件)+ 1 执行 + 2 验收)与《SS02-SS03-SS04_Demo台账字段细化与统一方案》(字段口径)。
|
||||
* **2026-08-29 整体重写(Task 3,spec `docs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md` §4)**:
|
||||
* 九步砍成四步 —— `S1_inputs`(校验入参与补数据)→ `S2_assess`(逐项差异分析)→
|
||||
* `S3_review`(结论审核,人工激活)→ `T_release`(落账放行,人工激活)。三道入场哨兵全读基座数,
|
||||
* `caseFileModel` 里**一面记账旗都没有**——旗是活动自己写的数,「机检只读基座数」这条纪律在本仓
|
||||
* 被违反过六次,每次都是同一种事故(见 `docs/ACT-WORK-05-端到端测试记录.md` A–K 发现表)。
|
||||
*
|
||||
* 文档六步收成 9 个案例模型项(0.5 那一步因 view 各不相同拆成两项 —— 引擎里剧本声明的
|
||||
* view 恒压过模型当拍报的 say.view,一个计划项只能绑一份画面,P-08 与 P-10 各自要一份可编辑的
|
||||
* 工作区件,不能共用同一个 view):
|
||||
* 启动期 → S0_bind(AI:铸案号、建 P-01 V1、锁规则版本、逐个 PN 查库、写存在性核对表)
|
||||
* 0.5a 等待数据(建主数据)→ S0d_p08_master(人:数据工单 P-08,件上表 1 主记录 + 表 2 标准化
|
||||
* 参数子表 `parts.parameter`;候选总数 ≥2 时缺库先决策卡;
|
||||
* 都在库时哨兵不开,这一项与下一项都不会进「当下可为」)
|
||||
* 0.5b 等待数据(建资料)→ S0d_p10_document(人:数据工单 P-10;都在库时同样不会进「当下可为」)
|
||||
* 1 建立评估上下文 → S1_input_confirm(人:执行工单 01,评估输入清单,件上补缺口)
|
||||
* 2 读取并标准化 → S2_normalize(AI:P-11 主记录骨架 + 差异明细对照行)
|
||||
* 3 逐项差异评估 → S3_assess(AI + 两枚工具:四态 / 风险 / 证据 / 影响 / 推荐等级 / 验证任务)
|
||||
* 4 FAE/RI 审核 → S4_review(人:验收工单 01 = 决策卡循环,驳回则 AI 改台账再发)
|
||||
* 5 提交评审放行 → S5_prepare_landing(AI:analysis_status 推 fae_confirmed、回写 P-01)+ T_release(人:验收工单 02,终局放行)
|
||||
* **全程零 `guide`**:四步的行为改由 `PlanStep.auto` 声明式配方接管(ADR-014)—— 这一份只搭骨架
|
||||
* (每步 `auto` 先各放一笔 `say` 占位),配方的实体在 Task 4–6 逐步填进去;`view` 这一步不写
|
||||
* (它是可选的,Task 7–9 各自补上自己那一张)。
|
||||
*
|
||||
* 五处不给 doneWhen:S0d_p08_master / S0d_p10_document(触达人)、S1(交人补缺口)、
|
||||
* S4(拍板且可循环)、T_release(签下去)。
|
||||
* 触达世界的两步(`S3_review` 审核、`T_release` 放行)标了人工激活且**不给 `doneWhen`**——
|
||||
* 完成与否不该由数据形状推出来。`ASSESSMENT_STEPS` / `ASSESSMENT_PHASES` 不用 `as const`
|
||||
* (与 E04 / I01 同款):它会把 `writes`/`reads` 这类数组字面量收窄成只读元组,
|
||||
* 装配进 `manifest.ts` 的 `businessModel.steps`(类型是可变的 `PlanStep[]`)时会因为
|
||||
* `ReadonlyArray` 缺 `push` 等方法而过不了类型检查。
|
||||
*/
|
||||
/*
|
||||
* `TOOL_COMPARE` / `TOOL_RECOMMEND` 退役(见 constants.ts 头注)—— 下面几处原本 `${TOOL_COMPARE}`
|
||||
* / `${TOOL_RECOMMEND}` 的插值已就地换成同样的字面量,文字与结构一字不改。Task 3 整体重写本文件
|
||||
* (四步、零工具)时会把这些引用连同工具调用一起撤掉,这里只是维持包能编译的最小机械改动。
|
||||
*/
|
||||
import { D, RULE_VERSION } from './constants.ts';
|
||||
import { RULE_VERSION } from './constants.ts';
|
||||
|
||||
export const CMMN_XML = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<definitions xmlns="http://www.omg.org/spec/CMMN/20151109/MODEL">
|
||||
<case id="part-substitution-assessment">
|
||||
<!--
|
||||
案卷项的 id 就是任务视图里的键名。入参顶层字段(customerCode / customerName / requestDescription /
|
||||
originalInternalPn / candidateInternalPns / datasheets)不进这份 caseFileModel —— 谓词里只用
|
||||
count(candidateInternalPns)。其余全是基座读数(行数 / 缺必填 / 按值计数 / 工具调用数)与
|
||||
sub_eval.verdict 里的三面记账旗(每面旗都配着一半基座数)。
|
||||
案卷项的 id 就是任务视图里的键名 —— **全是基座读数**(本单草稿写下的行数 / 缺必填数 /
|
||||
按值计数 / 不同值个数)。这一版里**一面记账旗都没有**:旗是活动自己写的数,
|
||||
而「机检只读基座数」这条纪律在本仓被违反过六次,每次都是同一种事故。
|
||||
-->
|
||||
<caseFileModel>
|
||||
<caseFileItem id="demand_request_rows" name="本单写下的需求主记录行数(基座现数)"/>
|
||||
<caseFileItem id="demand_request_missing" name="需求主记录缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_pn_check_rows" name="存在性核对行数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_pn_check_missing" name="存在性核对缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_pn_check_exists_status_absent" name="仍不在库的料号数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_pn_check_exists_status_abandoned" name="已放弃的候选数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_verdict_rows" name="结论行数(基座现数)"/>
|
||||
<caseFileItem id="parts_profile_rows" name="本单建的芯片主数据行数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_pn_check_exists_status_created" name="经数据工单建好的料号数(基座现数)"/>
|
||||
<caseFileItem id="parts_profile_missing" name="本单建的芯片主数据缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="parts_parameter_missing" name="本单建的标准化参数集缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="parts_document_missing" name="本单建的资料记录缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="parts_document_rows" name="本单建的资料记录行数(基座现数)"/>
|
||||
<caseFileItem id="parts_parameter_rows" name="本单建的参数行数(基座现数)"/>
|
||||
<caseFileItem id="parts_parameter_distinct_param_name" name="本单用到的不同参数名个数(基座现数不同值)"/>
|
||||
<caseFileItem id="input_confirmed_total" name="评估输入已确认(人环凭据)"/>
|
||||
<caseFileItem id="sub_eval_input_gap_rows" name="评估输入清单行数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_input_gap_missing" name="评估输入清单缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="substitution_relation_rows" name="替代关系行数(基座现数)"/>
|
||||
<caseFileItem id="substitution_relation_missing" name="替代关系缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="substitution_relation_analysis_status_fae_confirmed" name="分析状态已 FAE 确认的关系数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_part_exists_status_found" name="两颗料里已在库的个数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_part_missing" name="本单两颗料缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="sub_eval_part_distinct_chip_type_id" name="两颗料用到的不同类型个数(基座现数不同值)"/>
|
||||
<caseFileItem id="parts_profile_missing" name="本单碰过的芯片主数据缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="parts_parameter_missing" name="本单碰过的参数行缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="substitution_difference_item_rows" name="差异明细行数(基座现数)"/>
|
||||
<caseFileItem id="substitution_difference_item_missing" name="差异明细缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="substitution_difference_item_distinct_substitution_relation_id" name="有明细的关系数(基座现数不同值)"/>
|
||||
<caseFileItem id="substitution_difference_item_difference_status_match" name="MATCH 条数(基座现数)"/>
|
||||
<caseFileItem id="substitution_difference_item_difference_status_mismatch" name="MISMATCH 条数(基座现数)"/>
|
||||
<caseFileItem id="substitution_difference_item_difference_status_unknown" name="UNKNOWN 条数(基座现数)"/>
|
||||
<caseFileItem id="substitution_difference_item_difference_status_conditional" name="CONDITIONAL 条数(基座现数)"/>
|
||||
<caseFileItem id="tool_part_substitution_assessment_compare_parameters_calls" name="比对工具成功调用次数(基座现数)"/>
|
||||
<caseFileItem id="tool_part_substitution_assessment_recommend_calls" name="定级工具成功调用次数(基座现数)"/>
|
||||
<caseFileItem id="review_approved_total" name="差异结论已审核通过(仅通过时置一)"/>
|
||||
<caseFileItem id="decision_last" name="最后一张决策卡人选的值(基座按留痕数)"/>
|
||||
<caseFileItem id="landing_prepared_total" name="拟落账已备好(S5 写完时置一)"/>
|
||||
<caseFileItem id="substitution_relation_rows" name="替代关系行数(基座现数)"/>
|
||||
<caseFileItem id="substitution_relation_missing" name="替代关系缺必填的行数(基座现数)"/>
|
||||
<caseFileItem id="validation_record_rows" name="验证记录行数(基座现数)"/>
|
||||
<caseFileItem id="validation_record_missing" name="验证记录缺必填的行数(基座现数)"/>
|
||||
</caseFileModel>
|
||||
<casePlanModel id="plan" name="差异评估" autoComplete="true">
|
||||
<!-- ① 已绑定且真有料号不在库:需求主记录与存在性核对都写下了、至少一颗还 absent —— 数据工单那一项的入场前提 -->
|
||||
<sentry id="s_bound">
|
||||
<onPart id="op_b" caseFileItemRef="sub_eval_pn_check_exists_status_absent"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_b"><condition>demand_request_rows > 0 and sub_eval_pn_check_rows > 0 and sub_eval_pn_check_exists_status_absent > 0</condition></ifPart>
|
||||
<!-- ① 入参齐备:两颗都在库、都归了类型、且是同一个类型、主数据与参数都不缺 —— 分析那一步的入场前提 -->
|
||||
<sentry id="s_inputs_ready">
|
||||
<onPart id="op_i" caseFileItemRef="sub_eval_part_exists_status_found"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_i"><condition>sub_eval_part_exists_status_found = 2 and sub_eval_part_missing = 0 and sub_eval_part_distinct_chip_type_id = 1 and parts_profile_missing = 0 and parts_parameter_missing = 0</condition></ifPart>
|
||||
</sentry>
|
||||
<!-- ②′ 芯片主数据已建齐(表 1 主记录 + 表 2 参数子表都不缺必填)—— 补资料那一步的入场前提(基座现数) -->
|
||||
<sentry id="s_p08_created">
|
||||
<onPart id="op_p8" caseFileItemRef="parts_profile_rows"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_p8"><condition>parts_profile_rows > 0 and parts_profile_missing = 0 and parts_parameter_missing = 0</condition></ifPart>
|
||||
</sentry>
|
||||
<!--
|
||||
② 料号全部落定:原 PN + 每个候选各一行核对,没有一颗还「不在库」,放弃的少于候选数,
|
||||
本单建的主数据 / 参数子表 / 资料不缺必填 —— 评估输入确认那一步的入场前提。全是基座现数。
|
||||
-->
|
||||
<sentry id="s_pns_resolved">
|
||||
<onPart id="op_pr" caseFileItemRef="sub_eval_pn_check_exists_status_absent"><standardEvent>update</standardEvent></onPart>
|
||||
<!--
|
||||
**标了 created 的每一颗都要有一行主数据**(2026-08-27 e2e 两轮各现一形):
|
||||
「没写过 ≠ 写了 0 行」(2026-08-01 A1 立的那一课,在这里以新形状复现):
|
||||
\`_missing\` 只数**已有行**缺不缺格子 —— 一行都没写时它是 0,门就开了。
|
||||
实测:模型压拍没写骨架就把两张数据工单发了出去、人也「交」了,
|
||||
\`parts_profile_missing = 0\` 成立,这一步照过,而库里那颗料根本不存在。
|
||||
第一刀写成「created ≥ 1 就得有行」还是太松:三候选那单里模型把**第二颗**也标成 created
|
||||
却只建了第一颗,一行足以让门开着,直到 S2 写关系时才被引用检查拦下。
|
||||
改成**逐颗对账**:\`parts_profile_rows >= created\` —— 标了几颗建好,就得有几行。
|
||||
-->
|
||||
<!--
|
||||
**不再等模型把 absent 改成 created**(2026-08-27 晚):那面旗是模型记的账,忘了记就永远开不了门
|
||||
(「机检只读基座数」的哨兵形)。「一颗 absent 都不剩」的基座事实 = 要建的每一颗(absent + created)
|
||||
主数据、参数、资料都落了且必填不缺;created 仍可写(说明书照旧让它记),但门不靠它。
|
||||
-->
|
||||
<ifPart id="if_pr"><condition>sub_eval_pn_check_rows = count(candidateInternalPns) + 1 and sub_eval_pn_check_missing = 0 and sub_eval_pn_check_exists_status_abandoned < count(candidateInternalPns) and parts_profile_missing = 0 and parts_parameter_missing = 0 and parts_document_missing = 0 and parts_profile_rows >= sub_eval_pn_check_exists_status_absent + sub_eval_pn_check_exists_status_created and parts_document_rows >= sub_eval_pn_check_exists_status_absent + sub_eval_pn_check_exists_status_created and parts_parameter_rows = parts_parameter_distinct_param_name * (sub_eval_pn_check_exists_status_absent + sub_eval_pn_check_exists_status_created)</condition></ifPart>
|
||||
</sentry>
|
||||
<!-- ③ 评估输入已确认(旗 + 清单有行且必填齐)—— 标准化那一步的入场前提 -->
|
||||
<sentry id="s_input_confirmed">
|
||||
<onPart id="op_ic" caseFileItemRef="input_confirmed_total"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_ic"><condition>input_confirmed_total > 0 and sub_eval_input_gap_rows > 0 and sub_eval_input_gap_missing = 0</condition></ifPart>
|
||||
</sentry>
|
||||
<!-- ④ 对照表已铺好:每个未放弃的候选一条关系、每条关系都有明细 —— 逐项评估的入场前提 -->
|
||||
<sentry id="s_normalized">
|
||||
<onPart id="op_n" caseFileItemRef="substitution_difference_item_rows"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_n"><condition>substitution_relation_rows > 0 and substitution_relation_rows = count(candidateInternalPns) - sub_eval_pn_check_exists_status_abandoned and substitution_difference_item_rows > 0 and substitution_difference_item_distinct_substitution_relation_id = substitution_relation_rows</condition></ifPart>
|
||||
</sentry>
|
||||
<!-- ⑤ 逐项评估已完成:明细与关系必填齐、四态之和 = 明细行数、两枚工具都真调过 —— 审核的入场前提 -->
|
||||
<!-- ② 结论已成形:逐条明细、一条关系、一条验证记录都写下了且不缺 —— 审核那一步的入场前提 -->
|
||||
<sentry id="s_assessed">
|
||||
<onPart id="op_a" caseFileItemRef="substitution_difference_item_missing"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_a"><condition>substitution_difference_item_missing = 0 and substitution_relation_missing = 0 and substitution_difference_item_difference_status_match + substitution_difference_item_difference_status_mismatch + substitution_difference_item_difference_status_unknown + substitution_difference_item_difference_status_conditional = substitution_difference_item_rows and tool_part_substitution_assessment_compare_parameters_calls > 0 and tool_part_substitution_assessment_recommend_calls > 0</condition></ifPart>
|
||||
<onPart id="op_a" caseFileItemRef="substitution_difference_item_rows"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_a"><condition>substitution_difference_item_rows > 0 and substitution_difference_item_missing = 0 and substitution_relation_rows = 1 and validation_record_rows = 1</condition></ifPart>
|
||||
</sentry>
|
||||
<!-- ⑥ 审核已通过 —— 拟落账的入场前提 -->
|
||||
<sentry id="s_reviewed">
|
||||
<onPart id="op_r" caseFileItemRef="review_approved_total"><standardEvent>update</standardEvent></onPart>
|
||||
<!--
|
||||
审核通过与否**不由模型自写的旗说了算**(2026-08-27 实测:人两次答「重做」,模型照拒回的指引写了旗,
|
||||
S4 被收掉一路推到放行)。\`decision_last\` 是基座按 card-reply 数出来的:人最后一次真点了 approve 才开门。
|
||||
旗留着记账,但它单独说了不算。
|
||||
-->
|
||||
<ifPart id="if_r"><condition>review_approved_total > 0 and decision_last = "approve" and substitution_difference_item_missing = 0</condition></ifPart>
|
||||
</sentry>
|
||||
<!-- ⑦ 拟落账已备好:每条关系都到 FAE 确认、P-01 回写五项齐 —— 放行门的入场前提 -->
|
||||
<sentry id="s_landing_ready">
|
||||
<onPart id="op_l" caseFileItemRef="landing_prepared_total"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_l"><condition>landing_prepared_total > 0 and substitution_relation_analysis_status_fae_confirmed = substitution_relation_rows and substitution_relation_missing = 0 and demand_request_missing = 0</condition></ifPart>
|
||||
<!-- ③ 放行的入场前提与 ② 同源:审核那一步收没收由人答卡决定,不在这儿判 -->
|
||||
<sentry id="s_reviewable">
|
||||
<onPart id="op_r" caseFileItemRef="substitution_relation_rows"><standardEvent>update</standardEvent></onPart>
|
||||
<ifPart id="if_r"><condition>substitution_relation_rows = 1 and substitution_relation_missing = 0 and validation_record_missing = 0</condition></ifPart>
|
||||
</sentry>
|
||||
|
||||
<!-- 启动期:铸案号、建需求 V1、锁规则版本、逐个料号查库(能算的不问人) -->
|
||||
<humanTask id="S0_bind" name="建立评估上下文:绑定四项、新建需求、存在性核对"/>
|
||||
<!-- 1 校验入参与补数据:核对两颗料在不在库、归没归同一类型、参数齐不齐;缺什么派数据工单让人补(全 auto,doneWhen 收步) -->
|
||||
<humanTask id="S1_inputs" name="校验入参与补数据"/>
|
||||
|
||||
<!-- 0.5a 等待数据(建主数据):P-08 数据工单;人工激活,doneWhen 只在人答过卡之后求(入库事实);都在库时 s_bound 不开,不进「当下可为」 -->
|
||||
<humanTask id="S0d_p08_master" name="数据工单:补建芯片主数据(P-08)">
|
||||
<entryCriterion id="ec_s0d8" sentryRef="s_bound"/>
|
||||
<itemControl><manualActivationRule id="m_s0d8"/></itemControl>
|
||||
<!-- 2 逐项差异分析:核心参数逐条比对,四态、推荐等级、风险由系统按规则算(全 auto,doneWhen 收步) -->
|
||||
<humanTask id="S2_assess" name="逐项差异分析">
|
||||
<entryCriterion id="e_assess" sentryRef="s_inputs_ready"/>
|
||||
</humanTask>
|
||||
|
||||
<!-- 0.5b 等待数据(建资料):P-10 数据工单;人工激活,doneWhen 只在人答过卡之后求(入库事实);都在库时 s_p08_created 不开,不进「当下可为」 -->
|
||||
<humanTask id="S0d_p10_document" name="数据工单:补建原厂技术资料(P-10)">
|
||||
<entryCriterion id="ec_s0d10" sentryRef="s_p08_created"/>
|
||||
<itemControl><manualActivationRule id="m_s0d10"/></itemControl>
|
||||
<!-- 3 结论审核**触达的是人**:标人工激活,且不给 doneWhen —— 完成与否不该由数据形状推出来 -->
|
||||
<humanTask id="S3_review" name="差异评估结论审核" manualActivation="true">
|
||||
<entryCriterion id="e_review" sentryRef="s_assessed"/>
|
||||
</humanTask>
|
||||
|
||||
<!-- 1 建立评估上下文:交 PW 在件上补缺口(执行工单 01)—— 不给 doneWhen -->
|
||||
<humanTask id="S1_input_confirm" name="评估输入与资料补齐确认">
|
||||
<entryCriterion id="ec_s1" sentryRef="s_pns_resolved"/>
|
||||
<itemControl><manualActivationRule id="m_s1"/></itemControl>
|
||||
</humanTask>
|
||||
|
||||
<!-- 2 读取并标准化资料(纯 AI) -->
|
||||
<humanTask id="S2_normalize" name="标准化参数对照表:P-11 主记录骨架 + 差异明细对照行">
|
||||
<entryCriterion id="ec_s2" sentryRef="s_input_confirmed"/>
|
||||
</humanTask>
|
||||
|
||||
<!-- 3 逐项差异评估(AI + 两枚工具) -->
|
||||
<humanTask id="S3_assess" name="逐项差异评估:四态、风险、证据、推荐等级、验证任务">
|
||||
<entryCriterion id="ec_s3" sentryRef="s_normalized"/>
|
||||
</humanTask>
|
||||
|
||||
<!-- 4 FAE/RI 审核:决策卡循环,通过或驳回 + AI 改台账重发 —— 不给 doneWhen -->
|
||||
<humanTask id="S4_review" name="差异评估结论审核:通过或驳回(驳回则 AI 修订重提交)">
|
||||
<entryCriterion id="ec_s4" sentryRef="s_assessed"/>
|
||||
<itemControl><manualActivationRule id="m_s4"/></itemControl>
|
||||
</humanTask>
|
||||
|
||||
<!-- 5(前半)拟落账:分析状态推到 FAE 确认、回写 P-01(不触达世界,给 doneWhen) -->
|
||||
<humanTask id="S5_prepare_landing" name="拟落账:P-11 分析状态 → FAE 确认,回写 P-01">
|
||||
<entryCriterion id="ec_s5" sentryRef="s_reviewed"/>
|
||||
</humanTask>
|
||||
|
||||
<!-- 5(后半)提交 ACT-GATE-03:终局唯放行,必须人工激活 -->
|
||||
<humanTask id="T_release" name="评审放行与落账确认(ACT-GATE-03)">
|
||||
<entryCriterion id="ec_rel" sentryRef="s_landing_ready"/>
|
||||
<itemControl><manualActivationRule id="m_rl"/></itemControl>
|
||||
<!-- 4 落账放行**触达的是人**:标人工激活,且不给 doneWhen —— 签字这件事只能由人做 -->
|
||||
<humanTask id="T_release" name="落账放行" manualActivation="true">
|
||||
<entryCriterion id="e_release" sentryRef="s_reviewable"/>
|
||||
</humanTask>
|
||||
</casePlanModel>
|
||||
</case>
|
||||
</definitions>`;
|
||||
|
||||
/**
|
||||
* 案例说明书 —— **只写整单一以贯之的事**(逐步做法归剧本)。
|
||||
* 卡骨架住在这里而不是剧本里(模型会压拍,压过之后只有说明书还在 —— A1/A6/I01 同一课)。
|
||||
* 案例说明书 —— **只写整单一以贯之的事**,不讲逐步做法(逐步做法归配方,而配方不是给模型看的,
|
||||
* 是引擎按声明确定性执行的数据)。四步全部 `guide: ''`,这份说明书理论上不会再被任何一拍摊开给
|
||||
* 模型看 —— 留着它是因为 `narrative` 契约仍要求非空,且它仍是给人读的活动说明。
|
||||
*
|
||||
* **示例一律占位形**(`<料号>` / `<参数名>`),不写具体料号与参数名 —— 本仓 2026-08-27 复现过三次:
|
||||
* 关思考的模型会把示例里的具体值当成这一单的值照抄。
|
||||
*/
|
||||
export const NARRATIVE = `§0 开案:**判断候选料号在技术上能不能替代原料号,逐参数给出可复核的差异结论,审核后落账**。
|
||||
入参:
|
||||
· \`customerCode\` —— 客户编码(L-02);\`customerName\` 只在客户不在库时给。
|
||||
· \`requestDescription\` —— 客户需求原话,据它新建 P-01 需求主记录(版本 V1)。
|
||||
· \`originalInternalPn\` —— 原内部料号;\`candidateInternalPns\` —— 候选内部料号数组(≥1,逐个评估、各一条 P-11)。
|
||||
· \`datasheets\` —— 选填的真文件,基座已读成文本(每件 \`{name, text?, note}\`);有就拿它在数据工单里预填,没有就人全填。
|
||||
export const NARRATIVE = `§0 本活动只回答一件事:**候选内部料号在技术上能不能替代原内部料号**——逐条核心参数给出可复核的
|
||||
差异结论,人审核通过后落账。不做数量 / 价格 / 交期 / 采购判断;客户批准状态由独立审批流维护,
|
||||
本活动没有那一列的写权。
|
||||
|
||||
**本活动只回答一件事:技术上哪种料能替**。不做数量 / 价格 / 交期 / 采购判断;客户批准状态由审批流维护,你没有那一列的写权。
|
||||
入参两格,都选填:原内部料号、候选内部料号(如 <料号>)——库里有就用,没有就自己写一个新的,
|
||||
启动后由第一步核对补齐,不必人先建好档。
|
||||
|
||||
**四项绑定后不可改**(客户 / 需求 / 原 PN / 候选数组):绑错只能退回启动人重新启动。
|
||||
**四步各自的产出**:
|
||||
① 校验入参与补数据(S1_inputs)—— 核对两颗料在不在库、是否归了同一个芯片类型、核心参数
|
||||
(如 <参数名>)是否齐备;缺什么就派数据工单让人补。产出:两颗料的存在性与类型核对、
|
||||
补齐的芯片主数据与标准化参数。
|
||||
② 逐项差异分析(S2_assess)—— 把两颗料的核心参数逐条比对,判定 MATCH / MISMATCH / UNKNOWN /
|
||||
CONDITIONAL 四态,依规则算出推荐等级与风险。产出:替代关系一行 + 差异明细逐参数一行 +
|
||||
验证记录一行(全推荐也要写「本轮无待验项」)。规则版本 ${RULE_VERSION} 随结论一并锁定。
|
||||
③ 结论审核(S3_review,人工激活)—— 交人核对:参数比对对不对、硬约束有没有被含糊带过、
|
||||
UNKNOWN 有没有去向、判断依据站不站得住;可就地改四态与影响说明,改到没问题为止。
|
||||
④ 落账放行(T_release,人工激活)—— 把这一签下去会落哪几张表、几行摆清楚,人签字后正式落账,
|
||||
发射 assessment-released。
|
||||
|
||||
**能算的不问人也不自己判**:四态(MATCH / MISMATCH / UNKNOWN / CONDITIONAL)与推荐等级
|
||||
(推荐 / 条件推荐 / 备选 / 不推荐)全由两枚工具算 —— \`part-substitution-assessment.compare-parameters\`、\`part-substitution-assessment.recommend\`,
|
||||
一批一次。你负责对照表、证据引用、影响说明、UNKNOWN 的去向。**规则版本 \`${RULE_VERSION}\` 随每条结论落账**。
|
||||
|
||||
**UNKNOWN 是一等公民**:查不到的参数值写「未披露」,不许估、不许留空串冒充;每个 UNKNOWN 必须写去向
|
||||
(挂验证任务号或补来源动作)。硬约束 MISMATCH 不许改判,要改只能补证据后重比。
|
||||
|
||||
**存在性检查与数据工单**:启动时逐个料号在 \`parts.profile\` 里查(原 PN + 每个候选)。查无记录 = 「完全没有」,
|
||||
要人从零建整条主数据(表 1 主记录 + 表 2 标准化参数子表 \`parts.parameter\`)—— 发**数据工单**(一张单:P-08 一张、P-10 一张);
|
||||
PN 在库但个别字段缺 = 「有而不全」,归执行工单 01 补。**查无记录的一律派数据工单,不问人**(2026-08-27 用户定:
|
||||
「只要有缺失就要自动派数据工单,不需要人选择」)—— 原 PN 缺是硬阻塞、候选缺同样直接建,**没有「放弃这颗候选」这个岔路口**。
|
||||
**库里都有的话这两项的入场前提本就不成立**(此单不走这条),不会出现在你的「当下可为」里,别发空单。
|
||||
|
||||
**六步走**:绑定与存在性核对 → (等待数据)→ 人补评估输入 → 标准化对照表 → 逐项评估 → 人审结论(可循环)→ 拟落账 → 人放行。
|
||||
|
||||
【本单会用到的卡,全部照下面的骨架发,别自己另编】
|
||||
|
||||
① 新客户建档(只在 \`customerCode\` 在 \`customer.profile\` 里查无时,S0_bind 里发;编码用入参给的那个,人核名):
|
||||
{"kind":"entry","itemId":"S0_bind","ask":"客户 <customerCode> 不在客户档案里,请核对建档信息后确认",
|
||||
"ledger":"customer.profile","key":{"customer_code":"<customerCode>"},
|
||||
"fields":[
|
||||
{"key":"name","label":"客户名称","value":"<customerName,没有就整格不写 value>","required":true},
|
||||
{"key":"industry","label":"所属行业"},
|
||||
{"key":"region","label":"区域"}
|
||||
],
|
||||
"basis":[{"k":"触发原因","v":"按客户编码 <customerCode> 查客户档案,查无记录"},
|
||||
{"k":"这一单要评估的","v":"原 PN <originalInternalPn> → <N> 个候选"},
|
||||
{"k":"确认之后","v":"这家客户落进本单草稿层,评估照常往下走"}]}
|
||||
**\`basis\` 这三行必须给**:不给的话基座会兜上「这一步 / 当下可为 / 目标缺口」那几行内部家具 ——
|
||||
把九个计划项的全名摆到人脸上,他一个字也用不上(2026-08-27 实测)。
|
||||
人确认那一下基座已把这一行落进草稿层,**你不许再 write 一遍 customer.profile**。
|
||||
|
||||
② (已退役)候选缺库不再问人 —— 2026-08-27 用户定「只要有缺失就自动派数据工单」;所有查无记录的料号直接进③那张卡。
|
||||
|
||||
③ 数据工单 · P-08(所有要建的料号一起,一张单;零输入,填报全在工作区的件上)——
|
||||
**发这张卡之前,\`parts.profile\` 与 \`parts.parameter\` 必须先有骨架行**(名单里每颗料各一行 + 它的参数各一行)。
|
||||
不管这一拍是不是顺手把上一步收掉的(压拍常发生,那时这一步的剧本还没摊开),写骨架与发卡都得在同一串里,顺序不能反 ——
|
||||
件上一行都没有的话,人打开是一张空表、什么也补不了,而这一单的主数据从头到尾不会存在
|
||||
(实测走到 S2 才被引用检查拦下,那时两张数据工单都已经「办完」了)
|
||||
{"kind":"human","itemId":"S0d_p08_master","workOrder":"execution","card":{"variant":"data",
|
||||
"title":"数据工单 · 芯片主数据创建(P-08):<料号列表,顿号分隔>",
|
||||
"ask":"这些料号在芯片主数据里查无记录,请在工作区的件上把整条记录建齐(一颗一行,可加行)。",
|
||||
"steps":["表 1 每一行:品牌、规格描述、封装、生命周期状态为必填,缺一格确认不了",
|
||||
"表 2 一行一个参数:所属料号、参数名、值、单位、约束(硬/软)必填,说明是只读注释;原厂未披露的值写「未披露」,它会进入 UNKNOWN 并挂验证任务",
|
||||
"有 datasheet 的把引用与版本一起填(成对);制造商与品牌不一致时分开写",
|
||||
"改完保存,回这张卡确认 —— 确认后这批主数据即入库,活动从等待数据唤醒"],
|
||||
"standard":"每颗料号表 1 一行,必填列全齐;表 2 至少含输入电压范围 / 输出电压 / 输出电流 / 工作温度 / 封装相关的硬约束项各一行。",
|
||||
"gateLedgers":["parts.profile","parts.parameter"],
|
||||
"basis":[{"k":"触发原因","v":"按 internal_pn 查 P-08 查无记录(完全没有,不是字段缺失)"},
|
||||
{"k":"AI 预填","v":"<有 datasheet 就写「已按 datasheet 预填 N 项,请核对」,没有写「未上传 datasheet,请全填」>"}]}}
|
||||
**\`gateLedgers\` 必须给**:这是零输入卡,基座不知道这一张要人补哪几张表 ——
|
||||
不给它就回落到必交付物那几张(与这张卡无关),于是件上红带点着「缺品牌名称」而提交钮照样绿,
|
||||
空手交卷一路放行(2026-08-27 实测)。给了之后,闸与红带、放行门读的是同一个数。
|
||||
|
||||
④ 数据工单 · P-10(同一批料号的资料记录,一张单;在 P-08 那张确认之后再发)——
|
||||
**与③同一条:发这张卡之前 \`parts.document\` 必须先有骨架行**(名单里每颗料至少一行,
|
||||
key 是 {internal_pn, doc_seq:"01"});一行都没有的话人打开是空表、什么也补不了,
|
||||
提交闸会如实拦住(「这一单还一行都没有」),这一单就卡在这儿了(2026-08-27 实测)。
|
||||
{"kind":"human","itemId":"S0d_p10_document","workOrder":"execution","card":{"variant":"data",
|
||||
"title":"数据工单 · 原厂技术资料创建(P-10):<料号列表>",
|
||||
"ask":"请把这些料号的 datasheet / 承诺函等资料记录补进原厂技术资料库(一份资料一行,可加行)。",
|
||||
"steps":["资料类型、标题、版本、文件链接、资料状态为必填;证据定位写页码或章节,差异评估的证据引用会指向它",
|
||||
"同一料号多份资料就多加几行,序号 01/02… 自己续",
|
||||
"改完保存,回这张卡确认 —— 确认后这批资料记录即入库,活动接着往下办"],
|
||||
"standard":"每颗料号至少一行 datasheet 记录,必填列全齐。",
|
||||
"gateLedgers":["parts.document"],
|
||||
"basis":[{"k":"触发原因","v":"按 internal_pn 查 P-10 查无记录"}]}}
|
||||
|
||||
⑤ 执行工单 01 · 评估输入与资料补齐确认(S1_input_confirm;零输入)——
|
||||
**发它的前提:所有料号都已落定** —— \`${D}.pn_check\` 里**一颗 absent 都不剩**(每颗要么 found、要么经数据工单 created、
|
||||
要么人点了放弃 abandoned),且建过的那几颗在 \`parts.profile\` 里真有行。还有 absent 就**回去把它们办完**
|
||||
(候选总数 ≥2 的逐颗发决策卡问、原 PN 与独苗候选直接建),别先发这张卡:
|
||||
硬发出去人也补不成 —— 后面写替代关系时会被引用检查逐颗拦下,而那时数据工单都已经「办完」了(2026-08-27 实测两轮)。
|
||||
**有几颗 absent 就要办几颗**,办完第一颗别忘了还有第二颗。
|
||||
**发这张卡之前,\`${D}.input_gap\` 必须先有行**:清单为空的卡就是让人对着一张空表签字,他补不了任何东西。
|
||||
不管这一拍是不是顺手把上一步收掉的(压拍常发生,那时 S1 的剧本还没摊开),写清单与发卡都得在同一串里,顺序不能反:
|
||||
已绑定四项(customer / request / original_pn / candidate_N,status="ok")、待补两项(application_scenario / bom_position,status="gap")、
|
||||
默认三项(substitution_type / rule_version / owner,status="default")、每颗候选的「未披露」参数各一行(status="gap")、原 PN 资料版本(status="ok");
|
||||
逐列口径见这一步的剧本。
|
||||
{"kind":"human","itemId":"S1_input_confirm","workOrder":"execution","card":{
|
||||
"gateLedgers":["${D}.input_gap"],
|
||||
"title":"评估输入与资料补齐确认:<原 PN> → <N> 个候选",
|
||||
"ask":"启动绑定的四项已锁定。请在工作区的件上补齐「待补」行的补充内容,默认值可改可确认。",
|
||||
"steps":["应用场景、BOM 位是启动时未收的:必须补(写在「补充内容」列)",
|
||||
"每颗料每个参数此刻的值摆在件上的「候选参数现值」表里(只读参考);原厂未披露的参数这里不用补 —— 差异评估会把它判成 UNKNOWN 并挂验证任务",
|
||||
"替代类型 / 规则版本 / 负责人期限三行是系统默认,可改可不改",
|
||||
"加一行 = 补充 AI 没列出的资料项;删一行 = 该项不适用;已绑定的四项不可改",
|
||||
"改完保存,回这张卡提交"],
|
||||
"standard":"每一条「待补」行的补充内容都有;补不了的写明理由。",
|
||||
"basis":[{"k":"已绑定","v":"客户 <customerCode> · 需求 <request_id> V1 · 原 PN <原 PN> · 候选 <N> 颗"},
|
||||
{"k":"缺口","v":"<N> 项待补"}]}}
|
||||
|
||||
⑥ 验收工单 01 · 差异评估结论审核(S4_review;决策卡循环,不是终局验收)—— 发之前先在轨迹里找有没有已答过、还没处理的 \`[card-reply]\`:
|
||||
· \`value\` 是 \`"approve"\` → 写 \`${D}.verdict.review_approved_total = 1\`,finish 这一项,别再发卡;
|
||||
· \`value\` 是 \`"reject"\` 或以 \`"custom:"\` 开头 → 都算驳回:\`"reject"\` 没写意见,**不许再发卡追问**;\`"custom:"\` 的 \`note\` 就是他的意见,
|
||||
按意见改 \`substitution.difference_item\` / \`substitution.relation\`(同 PK 覆盖写,不开新行),意见要挂验证的写一行 \`validation.record\`,
|
||||
然后**换一种问法**再发一张(措辞不换会被当成同一张卡静默吞掉);
|
||||
· 没有 → 才发第一张:
|
||||
{"kind":"decide","itemId":"S4_review","allowCustom":true,
|
||||
"ask":"差异评估结论已算出:<N> 个候选、共 <M> 条参数比对(MATCH a / MISMATCH b / UNKNOWN c / CONDITIONAL d),推荐等级 <逐候选一句>。请审核。",
|
||||
"options":[{"value":"approve","label":"通过","recommended":true},
|
||||
{"value":"reject","label":"驳回(不写具体意见)"}]}
|
||||
三个 \`value\` 只有 \`"approve"\` / \`"reject"\` / \`"custom:"\` 开头三种,别造第四种。
|
||||
|
||||
【一路上要说话】每一拍带一句 say,说业务的话:查了几颗料、缺几颗、对照了几项、四态各几条、推荐等级各是什么。到了要找人的那一拍,先说清这一轮办完了什么、为什么现在需要他。用件上那三个词(必填 / 建议 / 选填)说缺口,只说事实。
|
||||
|
||||
【怎么把一项干完 · 一拍连做】write 和 tool 都不会自动收步 —— 做完用 finish 宣告(有 doneWhen 的项引擎自己收)。
|
||||
动作排进同一拍的 actions 串一口气给;只有发卡 / 提交(挂起)必须停拍;tool 之后同拍其余动作作废。
|
||||
**常路 9–12 拍收口**(候选缺库那条路多两张数据工单、多两拍)。
|
||||
|
||||
§Z 结案:FAE/RI 在验收单上签字,系统把草稿合并进 P-08 / P-10 / P-01 / P-11 / P-06 正式版并发射 \`assessment-released\` 口。`;
|
||||
**三条不许**:
|
||||
· 不伪造参数值——查不到就显式写「未披露」,不许估、不许拿别的料号或别的参数的值顶替;
|
||||
· 硬约束 MISMATCH 不许被措辞改判成 MATCH,要改只能补证据后重比;
|
||||
· 不写客户批准状态——那是独立审批流的事,本活动只答技术可替代性。`;
|
||||
|
||||
/**
|
||||
* 步骤剧本 —— 一个计划项一条;`doneWhen` 是「成果已存在」的判据,不是「该不该做」。
|
||||
* 五处不给 doneWhen:S0d_p08_master / S0d_p10_document(发数据工单触达人)、S1(交人补缺口)、
|
||||
* S4(拍板且循环)、T_release(签下去)。
|
||||
* 步骤剧本 —— 一个计划项一条。四步**全程零 `guide`、零工具**:行为改由 `auto` 配方接管
|
||||
* (ADR-014),这一份只放骨架 —— 每步 `auto.do` 先各摆一笔 `say` 占位,配方的实体
|
||||
* (`project` / `analyze` / `card` / `submit`)在 Task 4–6 逐步填进去。
|
||||
*
|
||||
* 两处不给 `doneWhen`:`S3_review`(人拍板且可循环)、`T_release`(签下去)——
|
||||
* 判据不许摆在还欠一张卡的那一步眼前(会诱使它去凑判据,2026-08-28 用户实测逼出的立墙)。
|
||||
*/
|
||||
export const ASSESSMENT_STEPS = [
|
||||
{
|
||||
item: 'S0_bind',
|
||||
intent: '铸案号、建需求 V1、锁规则版本、逐个料号查库、写存在性核对表',
|
||||
writes: ['demand.request', `${D}.pn_check`, `${D}.verdict`, 'customer.profile'],
|
||||
reads: ['customerCode', 'customerName', 'requestDescription', 'originalInternalPn', 'candidateInternalPns', 'datasheets', 'case:openedAt', 'customer.profile', 'parts.profile'],
|
||||
view: 'eval-input-list',
|
||||
tools: [],
|
||||
/*
|
||||
* 「该有几行」也进判据:原 PN + 每个候选各一行核对(count(candidateInternalPns) + 1);
|
||||
* 少一行 = 一颗料从这一单里凭空消失。count() 对未绑定名回 1 —— candidateInternalPns 是必填入参,恒绑定。
|
||||
*/
|
||||
doneWhen:
|
||||
`demand_request_rows > 0 and demand_request_missing = 0 and ${D}_verdict_rows > 0 and ` +
|
||||
`${D}_pn_check_rows = count(candidateInternalPns) + 1 and ${D}_pn_check_missing = 0`,
|
||||
guide: `第一件事:**把这一单的上下文立起来**,一拍连做(客户不在库时多一张录入卡、多一拍)。
|
||||
|
||||
【先铸案号】\`eval_ref = 'W05-' + case:openedAt 按 YYYYMMDDHHmmss 格式化\`(\`case:openedAt\` 形如 "2026-08-26 21:03:15",去掉分隔符即得);
|
||||
\`request_id = 'REQ-' + 同一串数字\`;\`input_snapshot_ref = 'SNAP-' + eval_ref\`。**不许从正式表里别单的案号里挑**,整单只有这一个 eval_ref。
|
||||
|
||||
【客户在不在库】在 \`customer.profile\` 里找 \`customerCode\`:在 → 直接用;不在 → 照说明书①发数据录入卡(名字用 \`customerName\`),
|
||||
发完这一拍结束;人确认后这家客户就在草稿层里了,下一拍接着做。**客户不在库也不许自己 write customer.profile**。
|
||||
**那一拍只发卡,别顺手写 \`demand.request\`** —— 需求行的客户编码有引用检查(客户还没落草稿层,写下去当场被拒);
|
||||
等人确认完,下一拍再写需求行与核对表,一次写齐。
|
||||
|
||||
【写 \`demand.request\` 一行(V1)】request_id、customer_code(= customerCode)、requirement_version = "V1"、request_type = "技术需求"、
|
||||
request_description(入参原话,不改写)、input_snapshot_ref、original_internal_pn、request_status = "pending"、current_activity = "ACT-WORK-05"、
|
||||
current_stage = "assessing"。application_scenario / bom_position **这一步不写**(启动时未收,S1 由人补)。
|
||||
|
||||
【逐个料号查库,写 \`${D}.pn_check\`】\`parts.profile\` 整表在你的作用域里,按 \`internal_pn\` 逐个核对:原 PN 一行(role = "original"),
|
||||
每个候选一行(role = "candidate");在 → exists_status = "found" **且 \`found_pn_ref\` 填你在 \`parts.profile\` 里真找到的那一行的 internal_pn**
|
||||
(与本行 internal_pn 一模一样);不在 → exists_status = "absent"、\`found_pn_ref\` 留空(**等数据工单确认后再改成 created**)。
|
||||
一颗都不能少:数组里点了几颗候选,就写几行 + 原 PN 一行。note 选填(如「PCN 转 NRND」)。
|
||||
|
||||
**「在库」这句话基座要拿去查**:\`found_pn_ref\` 声明了引用 \`parts.profile.internal_pn\`,写下去那一刻基座就去主数据里查,
|
||||
**查无此值当场拒**。被拒不是让你换个号去顶 —— 那说明这颗料真的不在库,把这一行改成 absent(依据留空),数据工单那一步的门自己会开。
|
||||
判 found 却填不出依据也走不动:这一步的收步条件里有「核对表不缺必填」。**别凭料号长得像就判在库,名单里没有就是没有。**
|
||||
|
||||
【写 \`${D}.verdict\` 一行】eval_ref、request_id、rule_version = "${RULE_VERSION}"、original_internal_pn、candidate_total = 候选数组长度。
|
||||
|
||||
写完这一项就结束。有 absent 的 → 下一项是 S0d_p08_master(数据工单),照常往下办。
|
||||
**都在库的话你什么都不用做** —— 数据工单那两项的入场前提本就不成立,它们不会出现在你的「当下可为」里,
|
||||
下一拍你会直接看到「评估输入与资料补齐确认」那一步。**任何时候都不要对计划项用 \`disable\`**:
|
||||
本引擎里 \`Disabled\` 只能从 \`Enabled\` 来,而普通计划项一直停在 \`Available\`,disable 一定被拒。`,
|
||||
},
|
||||
{
|
||||
item: 'S0d_p08_master',
|
||||
/* 这一步派的是数据工单 —— 由剧本声明,模型抄不抄 variant 都一样(2026-08-27 实测它丢了) */
|
||||
cardVariant: 'data' as const,
|
||||
intent: '料号不在库:派 P-08 数据工单让人从零建芯片主数据 + 标准化参数子表 —— 查无记录一律派,不问人',
|
||||
writes: ['parts.profile', 'parts.parameter', 'parts.document', `${D}.pn_check`],
|
||||
reads: [`${D}.pn_check`, 'candidateInternalPns', 'originalInternalPn', 'datasheets', 'parts.profile', 'parts.parameter', 'parts.document'],
|
||||
view: 'p08-master-create',
|
||||
tools: [],
|
||||
/*
|
||||
* 人工激活:发卡就算启动。doneWhen 只在**人答过卡之后**才由引擎求(2026-08-27 晚,harness 立此规矩):
|
||||
* 要建的每一颗(absent + created)主数据与参数都落了、必填不缺 —— 值是人在件上填的,引擎数得出来,
|
||||
* 不再靠模型记得 finish(剧本写了两处它照样忘,两步同时 Active、件停在 P-08)。名单里还有没建的料时它为假,
|
||||
* 「再发一张 P-08」那条路照旧走得通。
|
||||
*/
|
||||
doneWhen: `parts_profile_rows > 0 and parts_profile_rows >= ${D}_pn_check_exists_status_absent + ${D}_pn_check_exists_status_created and parts_profile_missing = 0 and parts_parameter_missing = 0 and parts_parameter_rows = parts_parameter_distinct_param_name * parts_profile_rows`,
|
||||
guide: `这一项只在 \`${D}.pn_check\` 里有 absent 行时走 —— 都在库时入场前提本就不成立,这一项与下一项 S0d_p10_document 都不会进你的「当下可为」。**先分岔,再动作**:
|
||||
|
||||
【名单】= \`${D}.pn_check\` 里 **exists_status = "absent" 的每一行**,不管它是原 PN 还是候选 —— **一律建,不问人**
|
||||
(2026-08-27 用户定:只要有缺失就自动派数据工单;从前那张「派数据工单还是放弃这颗候选」的决策卡已退役,别再发)。
|
||||
**exists_status = "found" 的一行都不建** —— 那几颗的主数据本来就在库里,给它们派数据工单等于让人把已有的东西再填一遍,
|
||||
而真正缺的那颗还是没人建、单子照样卡死。**这三张表在本单只建不改、且只建核对表里核过的料号**:在库的料号写下来(哪怕只是一行空骨架)会被当场拒,
|
||||
凭空拼出来的料号(2026-08-27 实测:模型写了一颗不存在的 XL2596S-ADJ,把两个候选的名字拼在了一起)也会被当场拒;
|
||||
真写了就用 drop 撤掉那一行,别留在件上让人去填。**名单只有一个来源:pn_check 里 absent 的那几行,一个字都别改。**名单为空(一行 absent 都没有)这一项根本不会出现在你的「当下可为」里。
|
||||
**名单里的料号全放进同一张 P-08 卡**(标题列全料号,件上一颗一行,参数各归各的料号)—— 别一颗一张。
|
||||
|
||||
【「建」的名单定了 → 写骨架行,发 P-08 数据工单(一张单,件上两张表)】
|
||||
1. 给名单里每颗料写一行 \`parts.profile\` 骨架(表 1):key {internal_pn},patch 只带你确有依据的列 —— 有 \`datasheets[].text\` 就从里面读
|
||||
brand_name / specification_description / package / lifecycle_status(active/nrnd/eol/discontinued/risk 之一)/ datasheet_ref + datasheet_version;
|
||||
没有 datasheet 就只写 internal_pn 这一列(其余留给人填,**别编**)。
|
||||
2. 同一拍给每颗料写标准化参数集骨架(表 2,\`parts.parameter\`,一行一参数):
|
||||
**参数名一律用中文,与库里既有料号的那几行同名**(输入电压范围 / 输出电压 / 输出电流 / 开关频率 /
|
||||
静态电流 / 工作温度…)—— \`param_name\` 是主键的一半,写成 \`input_voltage_range\`
|
||||
与写成「输入电压范围」**不是同一行**:原 PN 那边是中文、候选这边是英文,比对时两套名字对不上,
|
||||
逐条判成 UNKNOWN,结论就废了(2026-08-27 实测:27 条里 14 条 UNKNOWN)。
|
||||
封装、工艺、生命周期这些**不是参数**,它们在表 1,别往表 2 里塞。
|
||||
**建几颗料就用同一套名字**:门上有一条对账 —— 参数行数 = 不同参数名数 × 建过的料数,
|
||||
只有每颗料的名字集合一模一样时才成立;混着写(这颗中文那颗英文、或同一颗写两套)这一步就过不去。有 \`datasheets[].text\` 就从里面读出典型参数
|
||||
(如输入电压范围 / 输出电压 / 输出电流 / 开关频率 / 静态电流 / 工作温度等,按品类而定)各写一行,
|
||||
key {internal_pn, param_name},patch 带 param_value / param_unit / constraint_type(hard/soft)/ param_note(一句话说清这项为什么要卡,
|
||||
**param_value 的写法**:范围写「下限~上限」(如 1~10、-20~+60 —— 这表示一整段,比对工具按范围读),单位放 param_unit 不写进值里,
|
||||
定值只写一个数;
|
||||
如「须覆盖客户输入上限」);原厂没写的值写「未披露」(它会进入 UNKNOWN 并挂验证任务)。没有 datasheet 就只写
|
||||
internal_pn + param_name 骨架(把你判断这颗料该评估的参数名列出来,**param_value 留空给人填,别编**)。
|
||||
3. 同一拍**给名单里每一颗料各写一行** \`parts.document\` 骨架(两颗就两行,别只写一行 ——
|
||||
门上有一条对账:建好几颗就得有几行资料记录;少一行,那颗料的资料工单人打开是空的):key {internal_pn, doc_seq: "01"},patch {document_type: "datasheet", document_status: "pending",
|
||||
brand_name 有就写}(这一行是骨架,下一项 S0d_p10_document 会把它填成正式记录)。
|
||||
4. 同一拍发说明书③那张 P-08 数据工单(title 里列全料号),发完这一拍结束(挂起)。
|
||||
|
||||
**\`created\` 认的是「那张卡交回来了」,不是「表里有行」** —— **写骨架 ≠ 建好了**:
|
||||
骨架是**你**铺的(只有料号和参数名),值是**人**在件上填的。骨架一铺就把 pn_check 改成 created,
|
||||
等于替人宣布他已经办完了:接着你会以为数据工单收工、去 finish 这一项,而卡根本没发出去 ——
|
||||
撞上「这一单里从没给它发过卡」,连撞五拍熔断(2026-08-27 实测,整单白跑)。
|
||||
**顺序只有一个**:写骨架 → **发卡** → 这一拍结束 → 人交回 → 这时才把那几颗改成 created。
|
||||
门上还有一条逐颗对账(建好几颗就得有几行主数据、几行资料),标了却没建,这一步照样过不去。
|
||||
|
||||
【P-08 那张确认回来了】**先看名单里还有没有 absent 的料号**(\`${D}.pn_check\` 现读):
|
||||
· **还有** → **这一项千万别 finish**。把还 absent 的那几颗的骨架写好(profile + parameter,有 datasheet 就预填),
|
||||
再发一张 P-08 卡(标题列上它们的料号)—— 不问人,直接建;同一个计划项可以先后发好几张卡。
|
||||
**收掉了就回不去了**:这一项一旦 Completed,再想给它挂第二张卡会被拒「这一步已经办完收掉了」,
|
||||
而那颗料从此没人建,后面写替代关系时被引用检查逐颗拦下(2026-08-27 实测,一单连拒四次)。
|
||||
· **一颗都不剩了** → 才走下面这两步。
|
||||
|
||||
这一拍的动作串:① \`finish S0d_p08_master\`(建好的料主数据与参数都已入库、必填不缺时引擎也会自己收这一项 ——
|
||||
你 finish 一下更省一拍,忘了也不会卡住);② 照说明书④发 P-10 数据工单 —— 下一项是 S0d_p10_document,同一批料号接着补资料记录。
|
||||
|
||||
【这张卡一单只发一次】人交回来之后不许再发;答复里没有值(空 values)也算答过 —— 人在件上填的东西已随确认**入了正式表**
|
||||
(轨迹里有一条「数据工单确认入库」的痕点名哪几张表各几行;试跑单不落主数据时那条痕会如实写「只留在活动缓存」)。
|
||||
这几颗料从此在库:**别再往 \`parts.profile\` / \`parts.parameter\` 写它们的键**(在库的键会被当场拒),也别去 drop 它们
|
||||
(那是本单自己建好的行,撤不掉);值要改由人在件上改。`,
|
||||
},
|
||||
{
|
||||
item: 'S0d_p10_document',
|
||||
/* 这一步派的是数据工单 —— 由剧本声明,模型抄不抄 variant 都一样(2026-08-27 实测它丢了) */
|
||||
cardVariant: 'data' as const,
|
||||
intent: '料号不在库:派 P-10 数据工单让人从零建原厂技术资料',
|
||||
/* parts.document 归人填(见下面 humanWrites)—— 这一步只改核对表的旗 */
|
||||
writes: [`${D}.pn_check`],
|
||||
reads: [`${D}.pn_check`, 'parts.profile', 'parts.document'],
|
||||
view: 'p10-document-create',
|
||||
tools: [],
|
||||
/*
|
||||
* **资料记录归人填**(2026-08-28 用户实测):标题 / 版本 / 链接只可能从人那儿来 ——
|
||||
* 模型手边唯一「像样」的资料就是台账里原 PN 那一行,实测它逐字抄了过来安在候选头上,
|
||||
* 而这份假证据会直接喂进差异比对当「硬约束有证据支持」。骨架(键 + 类型 + 状态)
|
||||
* 上一步 S0d_p08_master 已经铺好,这一步不需要写它;写就当场拒,drop 仍可撤。
|
||||
*/
|
||||
humanWrites: ['parts.document'],
|
||||
/* 人工激活:发卡就算启动。doneWhen 同 P-08 的道理:人答过卡之后,建过的每颗料都有一行资料记录且必填不缺 → 引擎自己收 */
|
||||
doneWhen: `parts_document_rows > 0 and parts_document_rows >= parts_profile_rows and parts_document_missing = 0`,
|
||||
guide: `这一项只在 \`${D}.pn_check\` 里有 absent 行时走(要走到这一步,S0d_p08_master 已经收完 —— 引擎按入库事实自己收);都在库时入场前提本就不成立,
|
||||
这一项与 S0d_p08_master 都不会进你的「当下可为」。
|
||||
|
||||
**资料记录那三格(标题 / 版本 / 文件链接)由人在件上填,你写不进去**(写了当场拒)——
|
||||
别拿原 PN 或别的料号的规格书顶上:那是另一颗料的资料,后面会被当成这颗料的证据用。骨架上一步已经铺好了。
|
||||
|
||||
【发 P-10 数据工单】「建」的名单就是 \`${D}.pn_check\` 里仍是 exists_status = "absent" 的那几行(候选总数 ≥2 时被放弃的那些,
|
||||
S0d_p08_master 那一步已经把它们改成 "abandoned",不在这份名单里)。同一拍照说明书④发那张 P-10 数据工单(title 里列全料号,只发一次),
|
||||
发完这一拍结束(挂起)。
|
||||
|
||||
【P-10 那张确认回来了】把名单里每颗料的 \`${D}.pn_check\` 改成 exists_status = "created"(同 PK 覆盖写,记账用),然后 finish 这一项
|
||||
(资料记录都入库、必填不缺时引擎也会自己收)。S1_input_confirm 的入场前提认的是**入库事实**(要建的每颗料主数据 / 参数 / 资料都落了且不缺必填),
|
||||
不等这面旗 —— 缺必填由提交闸兜着,卡回来时一定是齐的。
|
||||
|
||||
【这张卡一单只发一次】人交回来之后不许再发;答复里没有值(空 values)也算答过 —— 人在件上填的东西已随确认**入了正式表**
|
||||
(轨迹里有一条「数据工单确认入库」的痕)。这几份资料记录从此在库:**别再往 \`parts.document\` 写它们的键**(会被当场拒),也别去 drop 它们。`,
|
||||
},
|
||||
{
|
||||
item: 'S1_input_confirm',
|
||||
intent: '评估输入清单:绑定四项只读核对,缺口行交 PW 在件上补',
|
||||
writes: [`${D}.input_gap`, `${D}.verdict`, 'demand.request'],
|
||||
reads: [`${D}.input_gap`, `${D}.pn_check`, 'demand.request', 'parts.profile', 'parts.parameter', 'parts.document', 'candidateInternalPns', 'originalInternalPn'],
|
||||
view: 'eval-input-list',
|
||||
tools: [],
|
||||
/* 交人补缺口,不给 doneWhen;人工激活:发卡就算启动 */
|
||||
guide: `料号全部落定了,**该 PW 补评估输入了** —— 这是本活动唯一的执行工单,零输入。**先分岔**:【当前这一步】那行引擎事实说
|
||||
「从没给它发过卡」→ 走【发卡】;说「人已经被问过了」→ 走【收口】。
|
||||
|
||||
【发卡】先把评估输入清单写下来(\`${D}.input_gap\`,一行一项),一拍连做。
|
||||
**每一行六列都要写,一列都不能少**:item_key(英文短键)/ input_item(人读名,就是下面每行「」里那几个字)/ source_ledger(来源台账)/
|
||||
status / detail / origin = "ai"。input_item 是必填列 —— 漏了它,件上红带会点名「缺输入项」,人对着一张没有名字的清单什么也补不了,
|
||||
卡就此交不回来(2026-08-27 实测:11 行全漏了 input_item,人把别的格填满也过不了闸)。
|
||||
· 已绑定四项(status = "ok",detail 写绑定值):item_key = customer「客户」(source_ledger = "L-02")/ request「客户需求」(source_ledger = "P-01")/
|
||||
original_pn「原 PN」(source_ledger = "P-08")/ 候选多颗就 candidate_1「候选 1」、candidate_2「候选 2」… 一颗一行(source_ledger = "P-08",detail 写料号与在库状态);
|
||||
· 待补两项(status = "gap",detail 写「启动时未收」):application_scenario「应用场景」(source_ledger = "P-01")、bom_position「BOM 位」(source_ledger = "P-09");
|
||||
· 默认可改三项(status = "default",detail 写默认值,source_ledger = "GOV"):substitution_type「替代类型」= "Pin-to-Pin"、rule_version「规则版本」= "${RULE_VERSION}"、owner「负责人 / 期限」= "按客户线默认 · 1 个工作日";
|
||||
· **候选参数一行都不写**:原厂未披露的参数不是这份清单的事 —— 差异评估那一步(S3)会把它判成 UNKNOWN 并挂验证任务;
|
||||
件上另有一张只读的「候选参数现值」表(P-08 标准化参数集,一颗料一张,基座从台账现读),人看得见每颗料每个参数此刻的值。
|
||||
这份清单里**不许出现任何参数行**(item_key 不许以 unknown_ 开头)—— 参数值有没有,是台账里的事实,不由你在这里替它宣布
|
||||
(2026-08-27 实测三次:人在 P-08 填好的参数被这份清单当成缺口再问一遍);
|
||||
· 齐备项(status = "ok"):original_doc_version「原 PN 资料版本」(source_ledger = "P-10",detail 写 datasheet 版本)。
|
||||
发卡前自己核一遍:\`${D}_input_gap_missing\` 这个读数必须是 0(它只该等 supplement 那一列由人来填;不是 0 就是你漏写了必填列,回去补写再发)。
|
||||
写完同一拍照说明书⑤发执行工单,发完这一拍结束(挂起)。
|
||||
|
||||
【收口】人交回之后只做三件事,然后 finish:
|
||||
① 读 \`${D}.input_gap\` 现值:把 application_scenario / bom_position 两行的 supplement 抄进 \`demand.request\`(同 PK 覆盖写这两列;
|
||||
supplement 写「补不了」「UNKNOWN」之类的,这两列不写);人加的行(origin = "human-added")同等作数,写进 technical_constraints 一句汇总。
|
||||
② 写 \`${D}.verdict.input_confirmed_total = 1\`。
|
||||
③ finish 这一项。**别在这一拍做对照表** —— 那是下一步的活。
|
||||
|
||||
【这张卡一单只发一次】人交回来之后不许再发;缺必填有提交闸兜着。`,
|
||||
},
|
||||
{
|
||||
item: 'S2_normalize',
|
||||
intent: '读取并标准化:每个未放弃的候选一条 P-11 主记录骨架 + 逐参数对照行',
|
||||
writes: ['substitution.relation', 'substitution.difference_item'],
|
||||
reads: ['parts.profile', 'parts.parameter', 'parts.document', 'demand.request', `${D}.pn_check`, `${D}.input_gap`, `${D}.verdict`, 'candidateInternalPns', 'originalInternalPn'],
|
||||
view: 'difference-review',
|
||||
item: 'S1_inputs',
|
||||
intent: '核对两颗料在不在库、归没归同一个类型、参数值齐不齐;缺什么就派一张数据工单让人补',
|
||||
guide: '',
|
||||
writes: ['sub_eval.part', 'sub_eval.case', 'parts.profile', 'parts.parameter'],
|
||||
reads: ['originalInternalPn', 'candidateInternalPn', 'case:openedAt', 'parts.profile', 'parts.parameter', 'parts.chip_type', 'parts.type_param'],
|
||||
tools: [],
|
||||
doneWhen:
|
||||
`substitution_relation_rows > 0 and substitution_relation_rows = count(candidateInternalPns) - ${D}_pn_check_exists_status_abandoned and ` +
|
||||
'substitution_difference_item_rows > 0 and substitution_difference_item_distinct_substitution_relation_id = substitution_relation_rows',
|
||||
guide: `输入齐了,**把多来源资料整成可比对的对照表**,一拍连做(先写关系,再写明细 —— 明细引用关系 id,顺序反了会被拒)。
|
||||
|
||||
【每个未放弃的候选一条 \`substitution.relation\` 骨架】(\`${D}.pn_check\` 里 exists_status 是 found / created 的候选;abandoned 的不写)
|
||||
substitution_relation_id = "REL-<案号数字串>-01/02…"(按候选数组顺序)、eval_ref、request_id、original_internal_pn、candidate_internal_pn、
|
||||
substitution_type = "pin_to_pin"(人在评估输入清单里改了替代类型就照改:功能替代 → functional、参数替代 → parametric)、
|
||||
analysis_status = "ai_draft"、rule_version = "${RULE_VERSION}"、bom_position(照 demand.request 现值抄,没有不写)。
|
||||
recommendation_level / recommendation_reason / difference_summary / risk_level **这一步一格都不写**(S3 的活)。
|
||||
|
||||
【每条关系逐参数写 \`substitution.difference_item\` 对照行】骨架按**原 PN 在 \`parts.parameter\` 里的那几行**(它是独立子表,一行一参数,
|
||||
按 internal_pn 归属):原 PN 有的每个参数一行 —— difference_item_id = "<关系id>-P01/P02…"、parameter_name(取原 PN 那一行的 param_name)、
|
||||
original_value(取原 PN 那一行的 param_value)、candidate_value(候选在 \`parts.parameter\` 里同 param_name 那一行的 param_value;
|
||||
候选没有这个参数 → 写「未披露」)、parameter_unit(以原 PN 那一行的 param_unit 为准;候选单位不同先换算,
|
||||
换算不了原值照写、evidence_ref 里注明)、constraint_type(取原 PN 那一行的 constraint_type;没标的按口径:封装 / 工艺 / 电压 / 电流 / 温度 / 阈值 hard,其余 soft)、
|
||||
rule_version = "${RULE_VERSION}"、evidence_ref(值从哪来:「P-08 · P-10 <版本>」;本单数据工单建的料号写「人工录入 · 数据工单 · P-08」)。
|
||||
另加两行**封装**与**生命周期**(constraint_type = hard / soft,值分别取 \`package\` 与 \`lifecycle_status\`)。
|
||||
difference_status / compare_result / risk_level / impact_statement / unknown_disposition **这一步不写**。
|
||||
|
||||
**缺参数不得伪造**:候选那一侧查不到就写「未披露」。写完引擎自己收这一项(每条关系都有明细行才算)。`,
|
||||
'sub_eval_part_exists_status_found = 2 and sub_eval_part_missing = 0 and ' +
|
||||
'sub_eval_part_distinct_chip_type_id = 1 and parts_profile_missing = 0 and parts_parameter_missing = 0',
|
||||
auto: { do: [{ kind: 'say' as const, text: '正在核对两颗料的在库状态与参数齐备情况。' }] },
|
||||
},
|
||||
{
|
||||
item: 'S3_assess',
|
||||
intent: '逐项差异评估:四态与推荐等级由工具算,证据 / 影响 / UNKNOWN 去向由你写',
|
||||
writes: ['substitution.relation', 'substitution.difference_item', 'validation.record', `${D}.verdict`],
|
||||
reads: ['substitution.relation', 'substitution.difference_item', 'demand.request', `${D}.input_gap`, `${D}.verdict`],
|
||||
view: 'difference-review',
|
||||
tools: ['part-substitution-assessment.compare-parameters', 'part-substitution-assessment.recommend'],
|
||||
item: 'S2_assess',
|
||||
intent: '把两颗料的核心参数逐条交给模型判四态,系统按规则算推荐等级、风险与验证要求',
|
||||
guide: '',
|
||||
writes: ['substitution.difference_item', 'substitution.relation', 'validation.record'],
|
||||
reads: ['parts.type_param', 'parts.parameter', 'sub_eval.part', 'sub_eval.case'],
|
||||
tools: [],
|
||||
doneWhen:
|
||||
'substitution_difference_item_missing = 0 and substitution_relation_missing = 0 and ' +
|
||||
'substitution_difference_item_difference_status_match + substitution_difference_item_difference_status_mismatch + ' +
|
||||
'substitution_difference_item_difference_status_unknown + substitution_difference_item_difference_status_conditional = substitution_difference_item_rows and ' +
|
||||
'tool_part_substitution_assessment_compare_parameters_calls > 0 and tool_part_substitution_assessment_recommend_calls > 0',
|
||||
guide: `对照表铺好了,**固定三拍**:比对 → 定级 → 写盘。**工具调用后同拍其余动作作废**,别把工具和写台账串在一起;两枚工具各只调一次。
|
||||
|
||||
【第一拍:只调 \`part-substitution-assessment.compare-parameters\`,别的什么都不写】**只报料号与客户约束,一个参数值都不抄** —— 参数、封装、生命周期、证据引用
|
||||
由工具自己从台账现读(parts.parameter / parts.profile / parts.document,本单刚建的也算),每一对都是台账原值:
|
||||
{"originalInternalPn":"<原 PN>","candidates":[{"candidateInternalPn":"<候选>","requirements":{"<参数名>":"<约束>"}}, …]}
|
||||
· 全部候选一次打包;
|
||||
· **requirements 只写客户在需求 / 应用场景里给了边界的参数**(如客户说输入上限是某个电压 → 输入电压范围写 ">= <那个数>";
|
||||
说工业温域 → 工作温度写 "-40~85");客户没给边界的参数**不写**,不要替客户编约束;
|
||||
· evidenceRef 不用给(工具从候选的 P-10 资料记录取);资料记录真没有时硬约束会退成 CONDITIONAL —— 那正是要的。
|
||||
调完这一拍结束。出参 items 里每一项带 originalValue / candidateValue / unit / constraintType / evidenceRef 与四态,写盘照抄。
|
||||
**值的读法(工具与你必须一致)**:「下限~上限」是**范围**—— 如 1~10 是 1 到 10 的整段,-20~+60 是 -20 到 60 的整段,**不是两个数、
|
||||
不是「1 或 10」**;两颗写着同一段就是一致。出参每项的 readAs 写着工具把两边各读成了什么(范围 / 定值 / 单边界 / 文本),
|
||||
写 impact_statement 时按它说,别自己重新解释一遍值。
|
||||
|
||||
【第二拍:只调 \`part-substitution-assessment.recommend\`,别的什么都不做】把第一拍出参里每个候选的 counts 原样打包传进去:{"candidates":[{"candidateInternalPn":"…","counts":{…}}, …]}。调完这一拍结束。
|
||||
**推荐等级只能由它算**——你自己填一个进 \`substitution.relation.recommendation_level\`,数据面看着像对的,机制上却是你拍的;
|
||||
而且这一步的收步判据数着这枚工具的调用次数,不调它这一步永远收不掉。
|
||||
|
||||
【第三拍:写盘前先自检,再一拍连做写盘,一次都不再调工具】
|
||||
动手写之前,先在局面的基座读数里找这两个数:\`tool_part_substitution_assessment_compare_parameters_calls\` 与
|
||||
\`tool_part_substitution_assessment_recommend_calls\`。**两个都必须 > 0 才能写盘**。若 \`recommend\` 那个还是 0,
|
||||
说明第二拍没调成——**回去调它**(入参就是第一拍出参里每个候选的 counts),不要往下写、更不要自己拍推荐等级。
|
||||
这一步的收步判据里就有这两个数,**不调够,写多少行都收不了步**。
|
||||
① 逐条 \`substitution.difference_item\` 同 PK 覆盖写:parameter_name / original_value / candidate_value / parameter_unit / constraint_type /
|
||||
evidence_ref / difference_status / compare_result / risk_level 照第一拍出参**一字不改**(值是台账原值,不是你记忆里的;
|
||||
compare_result 也照抄,别换成自己的词);
|
||||
impact_statement(MATCH 写「无」;其余说清对应用 / 验证 / 报价的影响,引出参里的具体数值与工具 note 的措辞 —— note 说「需求边界」的,
|
||||
影响就写「需求边界与在用料的差距,请核对需求」,不写成候选的短板);
|
||||
difference_status = unknown 的行**必须**写 unknown_disposition(「挂验证任务 VAL-<案号数字串>-01:实测<参数名>」或「向原厂补来源」);confidence(0~1)。
|
||||
② 每个 UNKNOWN 写一行 \`validation.record\`:validation_id = "VAL-<案号数字串>-01/02…"、request_id、validation_internal_pn(候选)、
|
||||
validation_type = "pin_to_pin"、validation_status = "not_started"、next_validation_action(要测什么、什么条件)、test_condition。
|
||||
③ 逐条 \`substitution.relation\` 同 PK 覆盖写:recommendation_level / risk_level 照第二拍出参、recommendation_reason(工具 reason 扩写成人话,
|
||||
引具体参数)、difference_summary(「7 项比对:4 MATCH / 1 MISMATCH / 1 UNKNOWN / 1 CONDITIONAL」)、analysis_report_ref = "RPT-<案号数字串>"、
|
||||
confidence_score(取该候选各行 confidence 的最小值);recommendation_level = conditional 的行**必须**写 verification_requirement(列出 VAL 号)、validation_id。
|
||||
④ \`${D}.verdict\` 同 PK 覆盖写:relation_total、recommended_total / conditional_total / alternate_total / not_recommended_total(数关系表)。
|
||||
写完引擎自己收这一项;下一项是审核(S4),**这一拍不要发卡**。
|
||||
|
||||
**不许把工具的结论改成别的**:不推荐就是不推荐;要改只能补证据后重比。`,
|
||||
'substitution_difference_item_rows > 0 and substitution_difference_item_missing = 0 and ' +
|
||||
'substitution_relation_rows = 1 and validation_record_rows = 1',
|
||||
auto: { do: [{ kind: 'say' as const, text: '正在逐条比对两颗料的核心参数。' }] },
|
||||
},
|
||||
{
|
||||
item: 'S4_review',
|
||||
/* 中间审核摆成验收工单的样子(机制是可循环的决策卡);由剧本声明,模型抄不抄都一样 */
|
||||
item: 'S3_review',
|
||||
intent: '把逐条结论摆给人过目,他就地改四态与影响说明,改到没问题为止',
|
||||
guide: '',
|
||||
writes: ['substitution.difference_item', 'substitution.relation', 'validation.record'],
|
||||
reads: ['substitution.difference_item', 'substitution.relation'],
|
||||
tools: [],
|
||||
cardVariant: 'review' as const,
|
||||
/* 人工验收清单(2026-08-27 用户定):FAE/RI 拿着「差异评估结论审核」这份件要亲自核的步骤,固定 */
|
||||
/* 人工验收清单:一条一句他拿着这份工单要**亲自核**的动作,不是系统判的判据 */
|
||||
acceptanceChecklist: [
|
||||
'逐个候选核对结论汇总:推荐程度、风险级别与它下方明细表的四态分布吻合(有硬约束 MISMATCH 或悬空 UNKNOWN 的候选没有给「推荐」)',
|
||||
'逐条核对差异明细:每个候选的每个参数都有 MATCH / MISMATCH / UNKNOWN / CONDITIONAL 之一,没有漏项',
|
||||
'核对 UNKNOWN 项的去向:每个 UNKNOWN 都挂了验证任务或写明补来源动作,没有悬空',
|
||||
'核对证据引用:每项结论能追溯到 P-08 / P-10 / P-06 的记录或本单数据工单的创建记录;硬约束的 MATCH 都有证据支持',
|
||||
'逐条对过原料与候选料的参数值,没有把需求边界写成候选料的问题',
|
||||
'硬约束那几条逐条看过,没有一条是「没证据也判了 MATCH」',
|
||||
'判 UNKNOWN 的都写了去向:实测哪一项、回填到哪儿',
|
||||
'影响说明站得住:说的是「换上去会不会比现在差」,不是复述参数值',
|
||||
],
|
||||
intent: '差异评估结论审核:决策卡循环,通过或驳回 + AI 按意见改台账重发',
|
||||
writes: ['substitution.relation', 'substitution.difference_item', 'validation.record', `${D}.verdict`],
|
||||
reads: ['substitution.relation', 'substitution.difference_item', 'validation.record', `${D}.verdict`],
|
||||
view: 'difference-review',
|
||||
tools: [],
|
||||
/* 要人拍板,且这一项内部可能循环 —— 不给 doneWhen */
|
||||
guide: `结论算出来了,**该 FAE/RI 审核了** —— 这是验收工单 01,走决策卡(不是终局验收)。**先分岔,再动作**:
|
||||
轨迹里找这一项已答过、还没处理的 [card-reply]:
|
||||
· 没有 → 照说明书⑥发第一张决策卡(ask 里把候选数、比对条数、四态各几条、逐候选推荐等级说全),发完这一拍结束。
|
||||
· "approve" → 写 \`${D}.verdict.review_approved_total = 1\`,finish 这一项。别再发卡。
|
||||
· "reject" / "custom:…" → **驳回**。**不许写 review_approved_total、不许 finish** —— 下一步的门读的是基座数
|
||||
\`decision_last\`(人最后一次真点了 approve 才开),写了旗也开不了门,只会把自己绕进死循环。按意见改台账(同 PK 覆盖写,不开新行、不改行数):
|
||||
· 意见点名某个参数 → 改那一行 \`substitution.difference_item\` 的 impact_statement / unknown_disposition / evidence_ref;要挂验证的补一行 \`validation.record\`;
|
||||
· 意见说推荐理由站不住 → 改 \`substitution.relation.recommendation_reason\`(等级**不许自己填** —— 它只能由工具算;写清楚为什么维持);
|
||||
· 意见说**某条判定本身错了**(客户约束译错、或原 PN 自己也不满足的客户线被记在候选头上)→ 改对 requirements
|
||||
(值不归你改:参数是台账原值,工具自己读),再**重新调 \`part-substitution-assessment.compare-parameters\` 与 \`part-substitution-assessment.recommend\`**(这一轮各再调一次,
|
||||
工具调用后同拍其余动作作废,下一拍照出参覆盖写四态、风险、备注与推荐等级 —— 这是等级唯一合法的改法);
|
||||
· 没写具体意见("reject")→ 自己挑最站不住的一处改实(证据最含糊的那条 evidence_ref、去向最空的那条 unknown_disposition),**至少改对一处**;
|
||||
然后**换一种问法**再发一张决策卡 —— **ask 的开头必须写明这一轮改了什么**(与上一张字面不同;
|
||||
字面一样的卡会被当成同一张吞掉,连吞两次就算被拒),发完结束。
|
||||
**基座对着字面比对意见与草稿**:观察里点名了哪一行,就改那一行,不挪到别的行头上。`,
|
||||
},
|
||||
{
|
||||
item: 'S5_prepare_landing',
|
||||
intent: '拟落账:P-11 分析状态推到 FAE 确认,回写 P-01 五项',
|
||||
writes: ['substitution.relation', 'demand.request', `${D}.verdict`],
|
||||
reads: ['substitution.relation', 'substitution.difference_item', 'validation.record', 'demand.request', `${D}.verdict`],
|
||||
view: 'landing-confirm',
|
||||
tools: [],
|
||||
doneWhen:
|
||||
'landing_prepared_total > 0 and substitution_relation_analysis_status_fae_confirmed = substitution_relation_rows and ' +
|
||||
'substitution_relation_missing = 0 and demand_request_missing = 0',
|
||||
guide: `审核通过了,**把拟落账的内容备好**,一拍连做:
|
||||
① 每条 \`substitution.relation\` 同 PK 覆盖写 analysis_status = "fae_confirmed"(只推分析层;客户批准状态你没有写权,别碰)。
|
||||
② \`demand.request\` 同 PK 覆盖写五项 + 状态:risk_level(取各候选 risk_level 里最高的一档)、verification_requirement(把所有 VAL 号与要测什么列全;
|
||||
没有 UNKNOWN 写「无需验证」)、output_ref = "RPT-<案号数字串>"、next_action = "提交 ACT-GATE-03 评审放行"、current_activity = "ACT-WORK-05"、
|
||||
current_stage = "gate03"、request_status = "responded"。
|
||||
③ \`${D}.verdict\` 同 PK 覆盖写:landing_prepared_total = 1、summary 一句人话(几个候选各什么等级、挂了几个验证任务)。
|
||||
写完引擎自己收这一项,下一项是放行。**这一拍不要 submit**。`,
|
||||
auto: { do: [{ kind: 'say' as const, text: '差异结论已备好,请过目。' }] },
|
||||
},
|
||||
{
|
||||
item: 'T_release',
|
||||
intent: '拟落账内容已备好,提交 ACT-GATE-03 交 FAE/RI 放行;被打回就改台账再交',
|
||||
/* 人工验收清单(2026-08-27 用户定):FAE/RI 拿着「评审放行与落账确认」这份件要亲自核的步骤,固定 */
|
||||
intent: '把这一签下去会落哪几张表、几行摆清楚,人签字后落账并发口',
|
||||
guide: '',
|
||||
/* 人工验收清单:一条一句他拿着这份工单要**亲自核**的动作,不是系统判的判据 */
|
||||
acceptanceChecklist: [
|
||||
'核对拟写 P-11 的每条替代关系:推荐等级与差异明细一致(有 UNKNOWN / CONDITIONAL 的候选没有给「推荐」),推荐理由与差异摘要说得通',
|
||||
'核对分析状态:每条只写分析层(分析状态 = FAE 确认),客户批准状态保持「未提交」,不由本单产生',
|
||||
'核对规则版本:每条结论都带本次锁定的 GOV 差异规则版本(R-2026.07)',
|
||||
'核对拟回写 P-01 的五项:风险等级、验证要求、输出链接、下一步动作、当前阶段都填了,且与结论一致',
|
||||
'核对验证任务:每个 UNKNOWN 对应的验证记录都在,要测什么、什么条件写清楚了',
|
||||
'推荐等级与四态分布对得上:有硬约束不符的没给「推荐」',
|
||||
'待验项清单认可:该实测的都列出来了,没有该验而漏掉的',
|
||||
'落账内容核对过:进哪几张表、各几行,与屏上摆的一致',
|
||||
'参数值来源可追:每一条都能说出它是库里既有的还是这一单补录的',
|
||||
'签下去就发给下游,这一步之后本活动不再改动这些行',
|
||||
],
|
||||
/* 被打回重做时要改的就是这几张 —— 不声明就写不进去 */
|
||||
writes: ['substitution.relation', 'substitution.difference_item', 'validation.record', 'demand.request', `${D}.verdict`],
|
||||
reads: ['substitution.relation', 'substitution.difference_item', 'validation.record', 'demand.request', `${D}.verdict`],
|
||||
view: 'landing-confirm',
|
||||
writes: ['sub_eval.case'],
|
||||
reads: ['substitution.relation', 'substitution.difference_item', 'validation.record', 'sub_eval.case'],
|
||||
tools: [],
|
||||
/* 放行触达世界,必须人按一下 —— 引擎不自动收它 */
|
||||
guide: `落账确认那一屏摆着拟写 P-11 主记录与拟回写 P-01。**这一步不发执行工单、不发决策卡**:放行卡由 submit 发
|
||||
(基座预检后自己发验收卡),发执行工单等于把同一件事问人两遍(2026-08-27 实测:先一张执行单、人答完才 submit 又一张验收单)。
|
||||
**先看轨迹里有没有「验收被打回重做」**:
|
||||
有 → 这一拍不是再提交一遍。照意见改**台账本身**(同 PK 覆盖写,不开新行):
|
||||
· 他说推荐等级与明细不符 → 核对 \`substitution.relation.recommendation_level\` 与该关系明细的四态计数,不符的把 recommendation_reason 改实、把漏挂的验证要求补上;
|
||||
· 他说 P-01 回写不全 → 补 \`demand.request\` 那五项;
|
||||
· 他说证据不可信 → 改那几行 \`substitution.difference_item.evidence_ref\`(指到具体资料版本与页码);
|
||||
· 没写具体意见 → 自己挑最站不住的一处改实,至少改对一处;
|
||||
改完这一拍再 judge + submit。**基座那道闸:打回之后台账一个字没改就不许再提交。**
|
||||
|
||||
没被打回(或已改过)→ 先裁三条裁量判据,然后 submit,同一拍连做:
|
||||
· judge criterion="证据链可信:每条结论都能追溯到 P-08 / P-10 / P-06 的具体记录,或本单数据工单的创建记录(人工录入)" —— 逐条看 evidence_ref 指不指得到具体记录;
|
||||
· judge criterion="硬约束项未被自动判 MATCH:封装 / 工艺 / 电气边界等硬约束的 MATCH 都有证据支持" —— 看 hard 且 match 的行 evidence_ref 是否非空且具体;
|
||||
· judge criterion="推荐等级与差异明细一致:存在 UNKNOWN / CONDITIONAL 的候选没有给「推荐」" —— 逐候选核对;
|
||||
**裁成不满足照样能提交** —— 理由连着卡一起交给签字的人。criterion 照判据名整句原样抄。
|
||||
这一单没有分支去向,只发一口 \`assessment-released\`,不必你选出口。终局唯放行:你不能自己宣布完成。`,
|
||||
auto: { do: [{ kind: 'say' as const, text: '拟落账内容已备好,请核对后签字。' }] },
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 阶段 —— 进度条的刻度,只给人看。除放行外每个计划项恰属一个阶段;
|
||||
* 放行那一格由基座统一加,人看到的是 **x/6** —— 与文档的步骤 0.5 / 1 / 2 / 3 / 4 / 5 六步逐格对齐:
|
||||
* 0.5 启动与存在性检查(等待数据)· 1 建立评估上下文 · 2 读取并标准化 · 3 逐项差异评估 · 4 FAE 审核与补证(含拟落账)· 5 提交评审放行(基座那格)
|
||||
* 放行那一格由基座统一加(与 E04 / I01 同款),人看到的是 **x/4**。
|
||||
*/
|
||||
export const ASSESSMENT_PHASES = [
|
||||
{ name: '启动与存在性检查', items: ['S0_bind', 'S0d_p08_master', 'S0d_p10_document'] },
|
||||
{ name: '建立评估上下文', items: ['S1_input_confirm'] },
|
||||
{ name: '读取并标准化资料', items: ['S2_normalize'] },
|
||||
{ name: '逐项差异评估', items: ['S3_assess'] },
|
||||
{ name: 'FAE 审核与补证', items: ['S4_review', 'S5_prepare_landing'] },
|
||||
{ name: '校验入参', items: ['S1_inputs'] },
|
||||
{ name: '差异分析', items: ['S2_assess'] },
|
||||
{ name: '结论审核', items: ['S3_review'] },
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user