/** * 活动包清单 —— ACT-WORK-05 差异评估(案例活动)。 * * **2026-08-29 整体重写(@2.0.0)**:从「九步、两枚工具、全程 agent 驱动」改成「四步、零工具、 * 零 `guide`、AI 出场恰好一次」。设计权威: * `docs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md`(下称「spec」)。 * 用户原话立的场:「不是把所有东西都丢给 ai 来处理…一定是系统先确定性的从数据库中取出数据后交给 * ai 分析」——`docs/ACT-WORK-05-端到端测试记录.md` 的 A–AE 发现表里,八条事故都落在 * 「本来就该是确定的」那几步(编号抄别单、判在库判错、数据工单派给在库的料…), * 真正需要判断的只有一件事:**这一条参数,候选跟原厂比算不算事**。 * * 这份清单是 Task 2 的产物,只动 `declarations.ledger` 与 `contract` 两段,以及 `assets` * 里已经不自洽的那几处(spec §8 的退役清单前移到这一步,见「计划裁定 G3」)。**案例模型 * (`case-model.ts`)还是旧的九步、旧的 `guide` 文本** —— 下一个任务(Task 3)才整体重写成 * spec §4 的四步(`S1_inputs` / `S2_assess` / `S3_review` / `T_release`)+ 四道哨兵 + 零 `guide` * (行为改由 `PlanStep.auto` 声明式配方接管)。旧剧本引用本次删掉的台账地址而导致的包内自测红, * 已按台账逐条 `it.skip` 并注明「Task 3 会补回」,不删测试(§12.5 铁律)。 * * ## 九张台账声明(spec §3) * 两张新字典(`parts.chip_type` / `parts.type_param`,Task 1 已物化 + 播种)承接「约束类型按类型 * 标一次」;P-08 主记录 `parts.profile` 撤 `createOnly`(在库老料要能补上 `chip_type_id` 这一格)、 * 封装与工艺退休(它们本来就是「核心参数」,该以类型字段的身份出现在字典里);P-08 子表 * `parts.parameter` 撤 `constraint_type` 与参数名自指引用(名字对不对由 S1 配方铺格子这件事本身 * 保证,不必再靠一堵测三次都没拦住的墙)。原来的三张单据(`pn_check` / `input_gap` / `verdict`) * 由两张顶掉:`sub_eval.part`(**一单恰两行** —— 配方 `each` 遍历「哪几颗料要建」的唯一数据源, * 拆成两行的理由见 spec §3.3「为什么非拆成两张不可」)与 `sub_eval.case`(一单一行的案卷, * 挂入参未就绪的原因与结论摘要)。P-11 明细加合成列 `judgement_class`(约束类型 × 四态的合成, * 因为「硬约束不符有几条」不是任何单列 `tally` 数得出来的数)。P-01 需求主记录 / P-10 原厂资料 / * 客户档案**本活动不碰**(它们的存在性核对与录入不再是这个活动的事)。 * * ## 契约(spec §4.1/§4.5/§7) * 启动只剩 `originalInternalPn` / `candidateInternalPn` 两格(单数,一次评估恰一对一候选), * 都选填 —— 缺了由第一步的配方派数据工单补。零工具:`contract.resources.tools` 与 * `declarations.tools` 都是 `[]`,这是这次重写的立场,不是疏漏(四态改 S2 唯一一次 `analyze` * 判定,推荐等级改配方按 spec §3.5 的规则算)。判据全部改读基座数(`域_对象_rows` / `_missing` / * `_distinct_列` / tally 计数),没有一条读活动自己写的汇总列。 */ import type { ActivityManifest } from '@contracts'; import { activityIdSchema } from '@contracts'; import { CMMN_XML, NARRATIVE, ASSESSMENT_PHASES, ASSESSMENT_STEPS } from './case-model.ts'; import { LEDGER_BOARD, LEDGER_BOARD_DATA } from './views/ledger-board.ts'; import { ACTIVITY_ID_TEXT, D } from './constants.ts'; export { D, RULE_VERSION } from './constants.ts'; const ACTIVITY_ID = activityIdSchema.parse(ACTIVITY_ID_TEXT); /** 字段声明的短写(与 E04 同一套写法:显式 primaryKey / masked,其余按需) */ type F = { name: string; type: 'text' | 'number' | 'integer' | 'boolean' | 'date' | 'timestamp' | 'json'; label: string; primaryKey?: boolean; required?: boolean; expect?: boolean; tally?: string[]; auto?: boolean; distinct?: boolean; refersTo?: string; requiredWhen?: { column: string; value: string } }; const col = (f: F) => ({ primaryKey: false, masked: false, ...f }); export const manifest: ActivityManifest = { identity: { activityId: ACTIVITY_ID, name: 'ACT-WORK-05 · 差异评估', /* 重写不是改 —— 同版重装是 no-op(静默丢失,踩过) */ packageVersion: '2.0.0', category: '需求分析与方案匹配', sdkVersion: '0.1.0-m5', checksum: 'dev-checksum-part-substitution-assessment', }, /* ── 契约七件 ────────────────────────────────────────────────── */ contract: { activityId: ACTIVITY_ID, version: '1.0.0', input: { /* * 两格,都选填(spec §4.1):库里有就选,没有就自己写一个新的 —— 启动后由第一步的 * 配方核对存在性、缺了就派数据工单补齐。运营端启动表单渲染这两格为 * 「选择 + 新增」下拉(`x-control: combo`),候选从 `parts.profile.internal_pn` * 现读(`x-options`);`x-order` 定表单次序(清单存在 jsonb 里,书写顺序到不了运营端)。 * requestDescription / candidateInternalPns(数组)/ datasheets 三键已随重写撤下 —— * 这一版没有「需求主记录」「N 候选并行」「预填 datasheet」这几件事。 */ data: { type: 'object', required: [], properties: { originalInternalPn: { type: 'string', title: '原内部料号', description: '差异评估基准料号;库里有就选,没有就自己写一个新的,启动后由第一步派数据工单补齐。', examples: ['LM2596S-5.0'], 'x-control': 'combo', 'x-options': { ledger: 'parts.profile', value: 'internal_pn', label: 'internal_pn' }, 'x-order': 1, }, candidateInternalPn: { type: 'string', title: '候选内部料号', description: '被评估的候选料号;库里有就选,没有就自己写一个新的,启动后由第一步派数据工单补齐。', examples: ['XL2596S-5.0'], 'x-control': 'combo', 'x-options': { ledger: 'parts.profile', value: 'internal_pn', label: 'internal_pn' }, 'x-order': 2, }, }, }, messageAllowed: true, messageHint: 'FAE 可在此说明客户的应用边界或验证条件', }, output: { /* 单一必发口:签下去 P-11 落账、P-06 落账;载荷是已落地的事实,不是待办 */ mandatory: [ { name: 'assessment-released', description: '差异评估结论已落账(P-11 替代关系主记录 + 差异明细、P-06 验证记录)—— 载荷即已落地的事实', payload: { type: 'object', required: ['evalRef', 'relationId', 'originalPn', 'candidatePn', 'recommendationLevel', 'matchTotal', 'mismatchTotal', 'unknownTotal', 'conditionalTotal', 'validationId'], properties: { evalRef: { type: 'string', title: '评估案号' }, relationId: { type: 'string', title: '替代关系ID' }, originalPn: { type: 'string', title: '原内部料号' }, candidatePn: { type: 'string', title: '候选内部料号' }, recommendationLevel: { type: 'string', title: '推荐等级' }, matchTotal: { type: 'integer', title: 'MATCH 条数' }, mismatchTotal: { type: 'integer', title: 'MISMATCH 条数' }, unknownTotal: { type: 'integer', title: 'UNKNOWN 条数' }, conditionalTotal: { type: 'integer', title: 'CONDITIONAL 条数' }, validationId: { type: 'string', title: '关联验证ID' }, }, }, }, ], selective: [], }, /* 一份成果常不止一张表:差异评估结论由明细 + 关系两张共同承载,落账内容由关系 + 验证记录承载 */ requiredDeliverables: [ { key: 'difference-items', label: '差异评估结论', ledger: 'substitution.difference_item', ledgers: ['substitution.difference_item', 'substitution.relation'], editableAtRelease: [] }, { key: 'landing', label: '落账内容', ledger: 'substitution.relation', ledgers: ['substitution.relation', 'validation.record'], editableAtRelease: [] }, ], /* * 验收判据(spec §7)—— 五条机检 L1/L2 全读基座数,两条 L4 裁量,一条 L5 责任关(不上卡)。 * `input-ready` 的谓词与 S1(Task 3 待写)的 `doneWhen` 同构:两颗都在库、类型一致、参数不缺 —— * **不写「参数行数 = 字段数×2」**,那不是基座数得出来的数(`parts_type_param_rows` 数的是 * 本单写下的字段行,不是整本字典;给判据编一个数不出来的数,是这个仓踩过六次的同一个坑)。 */ acceptanceCriteria: [ { key: 'input-ready', label: '评估输入已就绪:原 PN 与候选都在库、归了同一个芯片类型、主数据与参数值都不缺必填', level: 'L1', predicate: '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', }, { key: 'every-param-judged', label: '每条核心参数都有明确状态:每条差异明细都是 MATCH / MISMATCH / UNKNOWN / CONDITIONAL 之一,没有一条缺必填', level: 'L2', predicate: 'substitution_difference_item_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', }, { key: 'level-by-rule', /* §3.5 的规则原样译成析取式:推荐等级只有一种取值能配上当前的 judgement_class 分布,规则说了算不是话术说了算 */ label: '推荐等级与判定分类一致:有硬约束不符的候选不能是「推荐」,等级由规则算,不由措辞改判', level: 'L2', predicate: '(substitution_relation_recommendation_level_not_recommended = 1 and substitution_difference_item_judgement_class_hard_mismatch > 0) or ' + '(substitution_relation_recommendation_level_conditional = 1 and substitution_difference_item_judgement_class_hard_mismatch = 0 and ' + '(substitution_difference_item_judgement_class_unknown > 0 or substitution_difference_item_judgement_class_conditional > 0 or substitution_difference_item_judgement_class_soft_mismatch > 0)) or ' + '(substitution_relation_recommendation_level_recommended = 1 and substitution_difference_item_judgement_class_hard_mismatch = 0 and ' + 'substitution_difference_item_judgement_class_unknown = 0 and substitution_difference_item_judgement_class_conditional = 0 and substitution_difference_item_judgement_class_soft_mismatch = 0)', }, { key: 'unknown-has-disposition', label: '每个 UNKNOWN 都有去向:去向、影响说明、判断依据没有一条缺', level: 'L2', predicate: 'substitution_difference_item_missing = 0', }, { key: 'validation-landed', label: '验证记录已落账:P-06 恰有一行且不缺必填(全推荐也要写「本轮无待验项」)', level: 'L2', predicate: 'validation_record_rows = 1 and validation_record_missing = 0', }, { key: 'evidence-credible', label: '证据链可信:每条差异的影响说明与判断依据站得住', level: 'L4' }, { key: 'values-traceable', label: '参数值与原厂资料对得上:候选与原 PN 的取值来源可追溯', level: 'L4' }, /* L5 是责任关:那张卡本身就是这道关,卡面上不摆它(基座统一滤) */ { key: 'gate03-release', label: 'ACT-GATE-03 评审放行:签下去 P-11 落账、P-06 落账,结论供下游消费', level: 'L5' }, ], revisableAtRelease: [], prohibitions: [ { key: 'no-fabricated-parameter', statement: 'UNKNOWN 是一等公民:查不到的参数值必须显式写「未披露」并记去向,不得伪造、不得用估计值或空串冒充' }, { key: 'no-override-hard-mismatch', statement: '硬约束 MISMATCH 不得被任何措辞改判 MATCH;要改只能补证据后重比' }, { key: 'no-customer-approval-write', statement: '客户批准状态由独立审批流维护,本活动不写 customer_approval_status(没有这一列的写权)' }, { key: 'no-commercial-judgement', statement: '本活动只答技术可替代性:不做数量、价格、交期、采购判断' }, ], authorization: { discretion: [], preauthorizedActions: [], /* 调人三次(补数据 / 审核 / 放行);零工具、AI 只出场一次 —— 预算随之从 16/90 步收紧到 8/40 步 */ humanCallBudget: 8, }, resources: { tools: [], skills: [], models: ['deepseek-v4-flash'], roles: ['FAE/RI'], budget: { steps: 40, tokens: 300_000, activeMinutes: 60, humanCalls: 8 }, }, }, /* ── 声明 ────────────────────────────────────────────────────── */ declarations: { models: ['deepseek-v4-flash'], /* 零工具 —— 这是这次重写的立场,不是疏漏(见头注) */ tools: [], ledger: [ /* ── 两张类型字典(parts 域,与 P-08 同域;Task 1 已物化 + 播种)── */ { domain: 'parts', object: 'chip_type', kind: 'master', label: '芯片类型字典', fields: [ col({ name: 'type_id', type: 'integer', label: '类型编号', primaryKey: true, auto: true }), col({ name: 'type_name', type: 'text', label: '类型名称', required: true }), col({ name: 'description', type: 'text', label: '类型说明', expect: true }), ], }, { domain: 'parts', object: 'type_param', kind: 'master', label: '芯片类型核心参数字段', fields: [ col({ name: 'type_id', type: 'integer', label: '所属类型', primaryKey: true, refersTo: 'parts.chip_type.type_id' }), col({ name: 'param_name', type: 'text', label: '参数名', primaryKey: true }), /* AI 分析时读它 —— 这一格说清「这个参数是什么意思」,是 S2 唯一一次 analyze 出场的入参之一 */ col({ name: 'param_desc', type: 'text', label: '参数说明', required: true }), /* 约束类型按类型标一次,长在这里(不在每颗料的 `parts.parameter` 上)—— 见该表的头注 */ col({ name: 'constraint_type', type: 'text', label: '约束类型', required: true, tally: ['hard', 'soft'] }), col({ name: 'param_unit', type: 'text', label: '参考单位', expect: true }), ], }, /* * P-08 芯片主数据 —— 声明后为八列,物理表其余列本活动不碰。`createOnly` 撤掉 * (spec §3.2):它当初是为了拦模型凭空建料,而配方现在按本单两颗料铺行, * 凭空建在结构上已不可能;撤掉它换来一件必需的事 —— 给在库的老料补上 * `chip_type_id` 这一格(迁移前建的行没有类型,不许改就永远补不了)。 * package / process_technology / eol_pcn_status / application_scenarios 不声明: * 封装和工艺本来就是「核心参数」,该以类型字段的身份出现在字典里,不在主记录上另开一列。 */ { domain: 'parts', object: 'profile', kind: 'master', label: '芯片主数据(P-08)', fields: [ col({ name: 'internal_pn', type: 'text', label: '内部料号', primaryKey: true }), col({ name: 'chip_type_id', type: 'integer', label: '芯片类型', required: true, refersTo: 'parts.chip_type.type_id' }), col({ name: 'brand_name', type: 'text', label: '品牌名称', required: true }), col({ name: 'lifecycle_status', type: 'text', label: '生命周期状态', required: true, tally: ['active', 'nrnd', 'eol', 'discontinued', 'risk'] }), col({ name: 'specification_description', type: 'text', label: '规格描述', expect: true }), col({ name: 'manufacturer_name', type: 'text', label: '制造商名称', expect: true }), col({ name: 'datasheet_ref', type: 'text', label: 'Datasheet 引用', expect: true }), col({ name: 'datasheet_version', type: 'text', label: 'Datasheet 版本', expect: true }), ], }, /* * P-08 子表:标准化参数集,一行一参数。`createOnly` 撤掉(理由同上一张:在库那颗料的 * 现值要能回填进草稿层,只许建新就写不进去)。两处退休(spec §3.2): * `constraint_type` 搬去 `parts.type_param`(同一个参数在两颗料上标法不一致这件事从结构上 * 消失);`param_name` 的自指引用墙与 `distinct` 一并退休 —— 它当初是为了硬逼两颗料用同一套 * 参数名,而字段清单现在由类型字典给、行由配方按字典铺,名字对不上根本不可能发生。 */ { domain: 'parts', object: 'parameter', kind: 'master', label: '标准化参数集(P-08 子表)', fields: [ col({ name: 'internal_pn', type: 'text', label: '所属料号', primaryKey: true, refersTo: 'parts.profile.internal_pn' }), col({ name: 'param_name', type: 'text', label: '参数名', primaryKey: true }), col({ name: 'param_value', type: 'text', label: '值', required: true }), col({ name: 'param_unit', type: 'text', label: '单位', expect: true }), /* 值说明,AI 也读它(spec §3.2) */ col({ name: 'param_note', type: 'text', label: '说明', expect: true }), /* * **约束类型不在这里** —— 它长在 `parts.type_param`(按类型标一次)。 * 从前每颗料各标一次,同一个参数在两颗料上标法不一致就成了可能; * 而比对是逐参数对着比的,两边约束档不同,判出来的四态就没有意义。 */ ], }, /* * ── 活动自持两张(spec §3.3,顶掉退休的 pn_check / input_gap / verdict 三张)── * `sub_eval.part` 是配方唯一能拿来遍历「哪几颗料要建」的数据源(`each: 'mine:sub_eval.part' * where exists_status = absent`)—— 挤进一行案卷里就没法 `where` 过滤,而不能过滤就会给 * 已经在库的那颗料也铺一遍空参数行,这是非拆成两张不可的理由。 */ { domain: D, object: 'part', kind: 'record', caseKey: 'eval_ref', label: '本单两颗料(存在性与类型核对)', fields: [ col({ name: 'eval_ref', type: 'text', label: '评估案号', primaryKey: true }), col({ name: 'internal_pn', type: 'text', label: '内部料号', primaryKey: true }), col({ name: 'role', type: 'text', label: '角色', required: true, tally: ['original', 'candidate'] }), /* * **「在库」是一次 lookup 的结果,不是一句断言**(spec §3.3):判 found 就必须拿得出 * 一个基座查得到的料号,`refersTo` 让查无此值当场拒。`exists_status` 与这一列**每一拍 * 由配方重算**(不设 created 档、不靠谁记账)—— 人把料建好之后自己变 found。 */ col({ name: 'found_pn_ref', type: 'text', label: '在库核对依据', refersTo: 'parts.profile.internal_pn', requiredWhen: { column: 'exists_status', value: 'found' } }), col({ name: 'exists_status', type: 'text', label: '在库状态', required: true, tally: ['found', 'absent'] }), col({ name: 'chip_type_id', type: 'integer', label: '芯片类型', required: true, /* * **`distinct`**:「两颗料是不是同一个类型」从此是基座数得出来的数 * (`sub_eval_part_distinct_chip_type_id`)—— 不同取值恰好 1 种才算一致。 * 这一条是 S1 收步与 S2 入场的硬门:两边字段清单不是同一套,逐项比对无从谈起。 */ distinct: true, }), ], }, { domain: D, object: 'case', kind: 'record', caseKey: 'eval_ref', label: '本单案卷', fields: [ col({ name: 'eval_ref', type: 'text', label: '评估案号', primaryKey: true }), col({ name: 'chip_type_id', type: 'integer', label: '本单锁定的芯片类型' }), col({ name: 'gate_reason', type: 'text', label: '入参未就绪原因(件上摆的就是它)' }), col({ name: 'summary', type: 'text', label: '结论摘要' }), ], }, /* * P-11 替代关系主记录 —— 一单一行。退休三列(spec §3.4):`substitution_type`(新流程里没有 * 它的定夺人)、`confidence_score`、`analysis_report_ref`;`recommendation_level` 的 * `alternate` 档一并退休(原 D02 的 configurable 来路已不存在,只剩三档)。 */ { domain: 'substitution', object: 'relation', kind: 'master', label: '替代关系主记录(P-11)', fields: [ col({ name: 'substitution_relation_id', type: 'text', label: '替代关系ID', primaryKey: true }), col({ name: 'eval_ref', type: 'text', label: '评估案号', required: true }), col({ name: 'original_internal_pn', type: 'text', label: '原内部料号', required: true, refersTo: 'parts.profile.internal_pn' }), col({ name: 'candidate_internal_pn', type: 'text', label: '候选内部料号', required: true, refersTo: 'parts.profile.internal_pn' }), col({ name: 'chip_type_id', type: 'integer', label: '芯片类型', required: true }), col({ name: 'recommendation_level', type: 'text', label: '推荐等级', required: true, tally: ['recommended', 'conditional', 'not_recommended'] }), col({ name: 'recommendation_reason', type: 'text', label: '推荐理由', required: true }), col({ name: 'difference_summary', type: 'text', label: '差异摘要', required: true }), col({ name: 'risk_level', type: 'text', label: '替代风险等级', required: true, tally: ['low', 'medium', 'high'] }), col({ name: 'verification_requirement', type: 'text', label: '验证要求', requiredWhen: { column: 'recommendation_level', value: 'conditional' } }), col({ name: 'validation_id', type: 'text', label: '关联验证ID' }), /* 固定 fae_confirmed —— 分析状态与客户批准状态分离,本活动只写这一层 */ col({ name: 'analysis_status', type: 'text', label: '分析状态', required: true }), col({ name: 'rule_version', type: 'text', label: '差异规则版本', required: true }), ], }, /* * P-11 差异明细子表 —— 一参数一行。`evidence_ref` 改名 `evidence_note`「判断依据」: * 不写 P-10 了,AI 能给的就是依据不是文件引用,名字得说实话(spec §3.4)。 */ { domain: 'substitution', object: 'difference_item', kind: 'master', label: '差异明细(P-11 子表)', fields: [ col({ name: 'substitution_relation_id', type: 'text', label: '替代关系ID', primaryKey: true, distinct: true, refersTo: 'substitution.relation.substitution_relation_id' }), col({ name: 'difference_item_id', type: 'text', label: '差异明细ID', primaryKey: true }), col({ name: 'parameter_name', type: 'text', label: '标准参数名', required: true }), /* 字段说明快照,归档件不必 join 回字典 */ col({ name: 'parameter_desc', type: 'text', label: '参数说明', expect: true }), col({ name: 'constraint_type', type: 'text', label: '约束类型', required: true, tally: ['hard', 'soft'] }), col({ name: 'original_value', type: 'text', label: '原物料参数值', required: true }), col({ name: 'candidate_value', type: 'text', label: '候选物料参数值', required: true }), col({ name: 'parameter_unit', type: 'text', label: '参数单位', expect: true }), /* AI 判:逐参数比对,S2 唯一一次 analyze 出场的出参之一 */ col({ name: 'difference_status', type: 'text', label: '差异状态', required: true, tally: ['match', 'mismatch', 'unknown', 'conditional'] }), /* * **`judgement_class` 是合成列**:推荐等级要数的是「**硬约束**不符有几条」, * 而基座读数只会数单列 —— 把「约束类型 × 四态」先合成一列,规则才算得出来。 * 由配方按 §3.5 的 when 链算,不是 AI 出的。 */ col({ name: 'judgement_class', type: 'text', label: '判定分类', required: true, tally: ['match', 'soft_mismatch', 'hard_mismatch', 'unknown', 'conditional'] }), col({ name: 'impact_statement', type: 'text', label: '影响说明(MATCH 写「无」)', required: true }), col({ name: 'evidence_note', type: 'text', label: '判断依据', required: true }), col({ name: 'unknown_disposition', type: 'text', label: 'UNKNOWN 去向(验证任务号 / 补来源动作)', requiredWhen: { column: 'difference_status', value: 'unknown' } }), col({ name: 'risk_level', type: 'text', label: '风险等级', required: true, tally: ['low', 'medium', 'high'] }), col({ name: 'rule_version', type: 'text', label: '差异规则版本', required: true }), ], }, /* P-06 验证记录:一单一行,关联的是本单案号(P-01 不在本活动里,顶掉 request_id) */ { domain: 'validation', object: 'record', kind: 'master', label: '芯片验证记录(P-06)', fields: [ col({ name: 'validation_id', type: 'text', label: '验证ID', primaryKey: true }), col({ name: 'eval_ref', type: 'text', label: '评估案号', required: true }), col({ name: 'validation_internal_pn', type: 'text', label: '验证内部料号', required: true, refersTo: 'parts.profile.internal_pn' }), col({ name: 'validation_type', type: 'text', label: '验证类型', required: true, tally: ['pin_to_pin', 'functional', 'reliability', 'certification', 'retest', 'parametric'] }), /* 固定 not_started */ col({ name: 'validation_status', type: 'text', label: '验证状态', required: true }), col({ name: 'test_condition', type: 'text', label: '测试条件', expect: true }), col({ name: 'next_validation_action', type: 'text', label: '后续验证动作', required: true }), ], }, ], listeners: [], harness: { memoryWindow: 24, stallAfter: 'PT4H', nudge: [{ after: 'PT2H', action: 'nudge' }], retry: { times: 2, backoff: 'PT30S' }, }, }, /* ── 资产初始版 ──────────────────────────────────────────────── */ assets: { /* * DMN 判定表已退役:D01(逐参数四态)改由 S2 唯一一次 analyze 判定;D02(推荐等级)的规则 * 搬进配方的 when 链(spec §3.5)—— 规则只许有一处真源,再留一份 DMN 就是同一件事两处 * 各存一份。Task 3 会把 `steps` 换成四步、`guide` 全部清空(auto 配方接管行为)。 */ businessModel: { cmmnXml: CMMN_XML, narrative: NARRATIVE, dmn: { drd: [], tables: [] }, steps: ASSESSMENT_STEPS, phases: ASSESSMENT_PHASES }, /* 三条技能已随重写退役(全程无 agent,没有临场编排可言);skills.ts 的删除排在 Task 10 */ skills: [], /* * 五张旧局面全部作废(它们绑的九步与旧台账地址已经不存在),**暂时只留运营中心那张看板** —— * 三张新件(`input-supplement` / `difference-review` / `landing-confirm`)由 Task 7–9 各自加回; * 中途(Task 2–Task 9 之间)包不装,不会被静态审拦下。看板自己的 `data` 声明现在也引着已经 * 不存在的台账地址(`sub_eval.pn_check` 等)——Task 9「运营中心看板重绑」会把它换成新九张表。 */ viewTemplates: [{ name: 'activity-ledger', html: LEDGER_BOARD, data: LEDGER_BOARD_DATA }], cardSchemas: {}, /* 蒸馏钩子撤空:它是给 agent 在终态回看轨迹用的,而这个活动全程无 agent(AI 只出场一次、答一份结构化判断,没有可供归纳的多轮轨迹) */ distillHooks: [], }, /* * ── 样例集:五条形状真不同(常备案例即验收案例)── * 本任务不改样例(它们仍是旧九步 / 旧入参形状的素材,Task 3 重写案例模型时一并核对)。 * 库里只播了 LM2596S-5.0 / LM2596S-ADJ 两颗(见 seed-mvp-data.ts),XL2596S-5.0 / CN-DCDC-32V / LM2596S-3.3 刻意不在库。 */ samples: [ { name: '候选缺库·派数据工单', input: { customerCode: 'CU-0142', requestDescription: '工业电源项目在用 LM2596S-5.0(TI,12V→5V),原厂 PCN 转 NRND,客户要求验证替代料;应用 12V→5V、工业温域、输入上限 40V', originalInternalPn: 'LM2596S-5.0', candidateInternalPns: ['XL2596S-5.0', 'LM2596S-ADJ'], }, expect: { ports: ['assessment-released'] }, }, { name: '都在库·常路', input: { customerCode: 'CU-0142', requestDescription: 'LM2596S-5.0 转 NRND,客户先评估同族可调版 LM2596S-ADJ 能否替代(愿意改外围);应用 12V→5V、工业温域', originalInternalPn: 'LM2596S-5.0', candidateInternalPns: ['LM2596S-ADJ'], }, expect: { ports: ['assessment-released'] }, }, { name: '原PN缺库·硬阻塞', input: { customerCode: 'CU-0142', requestDescription: '客户另一块板在用 LM2596S-3.3(3.3V 固定版),同批 PCN,要求评估 LM2596S-ADJ 替代;应用 12V→3.3V', originalInternalPn: 'LM2596S-3.3', candidateInternalPns: ['LM2596S-ADJ'], }, expect: { ports: ['assessment-released'] }, }, { name: '三候选·含硬约束不推荐', input: { customerCode: 'CU-0142', requestDescription: '工业电源 12V→5V,输入上限 40V,工业温域;三个候选:XL2596S-5.0、LM2596S-ADJ、国产 CN-DCDC-32V(输入上限只有 32V)', originalInternalPn: 'LM2596S-5.0', candidateInternalPns: ['XL2596S-5.0', 'LM2596S-ADJ', 'CN-DCDC-32V'], }, expect: { ports: ['assessment-released'] }, }, { name: '新客户·先建档', input: { customerCode: 'CU-9001', customerName: '深圳恒星电源有限公司', requestDescription: '新客户口述:工业电源 12V→5V 在用 LM2596S-5.0,想评估 LM2596S-ADJ', originalInternalPn: 'LM2596S-5.0', candidateInternalPns: ['LM2596S-ADJ'], }, expect: { ports: ['assessment-released'] }, }, ], entry: { file: 'index.js', checksum: 'dev-entry-part-substitution-assessment' }, };