Task 12 的非走查部分(浏览器走查卡在登录、归人工,不在本次范围)。 ① index.ts 头注仍写着旧的「三条技能 + 五张模版」,重写后是 0 技能 3 张件,核正 (Ruling H25);包内其余「三条技能/五张/两枚工具/九步」等提法逐处核过,均为带日期的 「从…改成…」历史叙述,不是失实断言,未动。 ② docs/数据域字段说明-W05.md 整篇重写(不是打补丁)。旧文档写的是重写前的十张表 (customer.profile/parts.document/demand.request 与 sub_eval 三张旧单据,本活动这次 重写已不再声明),现按 manifest.ts 的 declarations.ledger 逐表核对重写:9 张表、66 列、 20 人填列。写入者词表另定一套(人(件上)/AI(S2 唯一一次 analyze)/配方(project 算出来 的)/基座)——E04/I01 那套多轮 agent 编排的词表在这里说不清楚。逐个 data-edit 核对过 report.ts 才确认写入者归属:S3 的四态等列改成人在件上直接编辑(不再是「人写意见→AI 改」), sub_eval.part/case、substitution.relation、validation.record 四张表没有任何人工编辑 入口、全部配方算。顺手核了 seed-mvp-data.ts 的基线物理列,注了每张表里这次重写不再 声明的旧列(旧九步版本留下的痕迹),并记下 type_id 这条身份链路是本仓唯一一处 integer→text 加宽声明。 ③ docs/活动开发规范.md §4.6 补四条纪律(六条→十条):jsonb 会重排 fields 键序、字段 求值改按依赖拓扑排序不能拿书写顺序当依赖顺序;跨笔顺序仍要自己排(一笔读的是另一笔 写出来的数就要排后面);两笔方向相反的依赖拆两笔写中间夹子表;gateLedgers 同时管 「闸要求非空」与「确认时并进正式表」两件事,漏想一半会悬空引用或永久卡死。§6.5 补第 9 条「测试要能咬住」(镜像测试与读真文件测试证明的是两件事;变异测试本身可能是空的; 能 import 真东西就别手抄)。§7 补两行排障(reset-runs 前先捞证据;dev 进程可能在跑 几小时前的代码,连 tsup --watch 监视进程本身都可能已死)。八条内容逐条去任务报告核过 原始事故与提交号,没有凭印象转述。 ④ CLAUDE.md 现状快照追加一条:四步全 auto、两张类型字典、三张件、退役清单;e2e 三例 released 被拒 0(候选缺库/都在库/原PN缺库,模型调用恰 1 次);类型不一致那例撞上已记 debt.md 的 prune 死锁,两颗都缺库那例卡在「答完卡不推进」、真因未定位如实记录; judgement_class 7/7 逐行核对通过;jsonb 键序地基缺陷的发现与修法(拓扑排序,6636abf)。 顺手核正文档地图里 W05 那一行的旧字段数(十张/110列→九张/66列,与②同步)。 pnpm gates 退出码 0(2447 passed | 34 skipped),与 Task 11 最后一轮记录一致,无回归。 未碰 manifest.ts 里那处与本任务无关的未提交版本号改动(2.1.5→2.1.6,疑似上一个卡在 登录的浏览器走查会话留下)。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
35 KiB
数据域字段说明 —— ACT-WORK-05 差异评估
对应设计中心 → 数据域「ACT-WORK-05 · 差异评估」分组。字段以活动清单的台账声明为准 (
activities/part-substitution-assessment/src/manifest.ts的declarations.ledger)。 2026-08-29 整体重写(design specdocs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md) 把九步案例模型砍成四步、全程零guide(行为改由PlanStep.auto声明式配方接管,ADR-014), 台账从旧的十张收成九张:两张原有的三单据(sub_eval.pn_check/sub_eval.input_gap/sub_eval.verdict)与三张外域表(customer.profile/demand.request/parts.document) 一并退役 —— 本活动这次重写不再声明、不再碰这五张表;它们的存在性核对与录入不再是 这个活动的事(manifest.ts 头注原话)。老文档(见 git 历史)里那几张表的段落已随重写整篇撤下, 不是遗漏。九张里有七张(除
sub_eval.part/sub_eval.case两张本活动自持的工作台账外)的物理结构 由平台基线apps/api/src/app/seed-mvp-data.ts的MASTER_OBJECTS物化,声明合并对基线 基本是纯 add-column:活动只追加自己要用的列与标记(required / expect / tally / refersTo / requiredWhen / distinct / auto),不改基线已有列的语义。唯一的例外是type_id这条身份链路 (parts.chip_type.type_id/parts.type_param.type_id/parts.profile.chip_type_id/sub_eval.part.chip_type_id/sub_eval.case.chip_type_id/substitution.relation.chip_type_id六列同源同改)——声明把基线原本integer的这几列加宽成了text,理由与 PG 类型转换 细节见 manifest.ts 该处的大注释与本文「怎么读这份文档」倒数第二条。那份声明同时是 授权面:没声明的列写不进去,也不会出现在件上、判据里、数据域的活动分组里。
怎么读这份文档
- ★ = 重点字段。每张表挑 5–8 个,在「重点字段」小节里按重要程度从高到低排; 数据结构表里在列名后打 ★。字段少于 5 个的表(字典、案卷)全部列入重点。
- 【人填】= 人在活动过程中亲手填、提交后入库的字段(数据工单的件上编辑)。这类字段 一律进重点:它们是这一单里唯一不能靠配方补出来的事实。S3 审核卡的四态/影响说明/ 判断依据/UNKNOWN 去向不带这个标记——那四格的初值是 AI 判出来的,人只是「审核时可以 就地改」,不是「唯一不能靠 AI 补出来的事实」;两者含义不同,详见各自表格的写入者说明。
- 这个活动的「写入者」词表与
docs/数据域字段说明-E04-I01.md不同,单独在这里定义—— E04/I01 全程多轮 agent 编排,W05 重写后全程零guide、AI 只在 S2 出场恰好一次, 中间没有「模型每拍决定写什么」这件事,套用旧词表反而说不清楚:- 人(件上) —— 工作区那份 HTML 上点「编辑」改的格子,保存即落草稿层(与 E04/I01 同义)
- AI —— 整个活动唯一一次模型调用(S2 的
analyze)的出参,系统按lookup: result:items原样抄进台账;S3 人可在件上就地改 - 配方 ——
auto.do里project动作按声明(遍历 /lookup现值 /when链 / 字面量) 算出来的值,不经模型,每一拍都会重新求值一遍(幂等,值不变则不产生写入痕迹) - 基座 —— 平台自己生成,不问人也不经模型(自增序号等)
- 没有「人(录入卡)」「AI(据人的意见改)」「承继」—— 本活动没有录入卡,也没有
「人写自由文本意见 → AI 读意见改具体行」这一步:S3 要改结论,人直接在件上改那一行;
T_release 全只读,打回重做要改的只有
sub_eval.case(且它也是配方算的,不是人填的)。
- 「约束」一栏的词表与
docs/数据域字段说明-E04-I01.md「怎么读这份文档」是同一套 (主键 / 自增 / 必填 / 建议填 / 取值域 / 引用 / 去重计数 / 脱敏),不重复抄一遍。requiredWhen类字段统一写「条件必填 ·<字段>=<值>时」。 refersTo拒得很硬:值必须在目标表里真实存在,查无此值draftWrite当场拒 (不是留到验收才发现)。装包时静态审核也会核refersTo目标地址本身是否存在。
一览
| 全景 | 台账地址 | 人读名 | 性质 | 本活动用到的列 | 人填列 |
|---|---|---|---|---|---|
| — | parts.chip_type |
芯片类型字典 | 主数据 · W05 唯一读写者 | 3 | 2(新建类型时,件上) |
| — | parts.type_param |
芯片类型核心参数字段 | 主数据 · W05 唯一读写者 | 5 | 5(新建类型 / 追加字段时,件上) |
| P-08 | parts.profile |
芯片主数据 | 主数据 · W05 唯一读写者 | 8 | 7(在库回填现值 · 缺库从零填,件上) |
| P-08 子 | parts.parameter |
标准化参数集 | 主数据 · W05 唯一读写者 | 5 | 2(值 · 说明,件上;主键两列虽挂 data-col 但由配方铺,人正常操作不改) |
| — | sub_eval.part |
本单两颗料(存在性与类型核对) | 本活动工作台账 | 6 | 0(配方每拍按入参与 parts.profile 现查重算,件上没有它的编辑入口) |
| — | sub_eval.case |
本单案卷 | 本活动工作台账 | 4 | 0(全部配方算) |
| P-11 | substitution.relation |
替代关系主记录 | 主数据 · W05 唯一读写者 | 13 | 0(配方按规则算,人不直接改) |
| P-11 子 | substitution.difference_item |
差异明细 | 主数据 · W05 唯一读写者 | 15 | 4(S3 就地改四态/影响说明/判断依据/UNKNOWN 去向;AI 先判,人可改) |
| P-06 | validation.record |
芯片验证记录 | 主数据 · W05 唯一读写者 | 7 | 0(配方按四态分布算) |
四步(全 auto,零 guide,AI 只在 S2 出场恰好一次):
S1_inputs(核对两颗料在不在库 / 是否归了同一芯片类型 / 参数是否齐,缺什么才发一张
数据工单——五条样例里「都在库·同型·齐备」那一条走的是零卡直通,不是特例)→
S2_assess(整个活动唯一一次模型调用:逐条核心参数判 MATCH/MISMATCH/UNKNOWN/CONDITIONAL
四态;推荐等级 / 风险 / 摘要 / 验证要求全部由配方按规则算,AI 不参与、不改一字)→
S3_review(结论审核,人工激活,件上就地改四态与三个自由文本格,可循环打回重做)→
T_release(落账放行,人工激活,全只读,签字后正式落账并发口 assessment-released,
可循环打回重做)。三道入场哨兵全读基座数(sub_eval_part_* / substitution_*_rows /
_missing),案例模型里一面记账旗都没有——「机检只读基座数」这条纪律在本仓被违反过
六次,W05 重写从设计上就不给它第七次机会。
一、parts.chip_type 芯片类型字典
按芯片类型(而不是按料号)标一次「这一类芯片要比哪几个核心参数、每个参数的说明与硬软
约束」——同一类型下两颗料从此结构上共用同一套参数名与约束档,不必再靠说明书措辞去
硬逼「两颗料对齐同一套参数名」(旧设计靠 parts.parameter.param_name 自指引用墙撑着,
测三次都没拦住,这次直接把墙的存在理由从结构上抹掉了)。件①型下拉里没有合适的,人在
input-supplement 的件②a 块现造一个;S1 配方选中之后原样自投影一遍(不论新建还是
挑既有类型都投,幂等、不产生多余写入),保证这一单的草稿层里恒有这一行——这既是
「保存即铺格」的前提,也是数据工单确认落地时不留悬空引用的前提(见 docs/活动开发规范.md
§4.6 关于 gateLedgers 的那条纪律)。
重点字段(按重要程度)
type_id★ 主键 · 自增 —— 声明成text而不是integer(见文档头注),写入时按 「现有最大 + 1」续号,不进表单、只读态摆「系统生成」type_name★【人填】必填 —— 新建类型时件上现填,已有类型从下拉挑description★【人填】建议填 —— 这个类型是什么(供选型参考)
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
type_id ★ |
类型编号 | text | 主键 · 自增 | 基座(续号) | 基线原为 integer,声明加宽为 text(见头注) |
type_name ★ |
类型名称 | text | 必填 | 人(件上) | 新建类型时填 |
description ★ |
类型说明 | text | 建议填 | 人(件上) |
二、parts.type_param 芯片类型核心参数字段
一类芯片一套字段清单,复合主键 type_id + param_name。新建类型(或给已有类型追加字段)时,
人在 input-supplement 的件②b 块逐条定下字段名 / 说明 / 硬软约束 / 参考单位;S1 配方同样
把选中类型此刻的字段清单原样自投影一遍(与 parts.chip_type 同一条道理、同一次修正 ——
挑已有类型时这张表天然可能零行,不投一遍会被「零行 = 没干完」的闸误判)。这张表是 S2
唯一一次 AI 调用的入参来源:逐条参数连同 param_desc(为什么要紧)一起交给模型判四态。
重点字段(按重要程度)
type_id★【人填,选择】主键之一 · 引用parts.chip_type.type_idparam_name★【人填】主键之一 —— 参数名param_desc★【人填】必填 —— AI 分析时读的就是它:参数名本身说不清「它为什么要紧」, 写成参数名的复述等于没写constraint_type★【人填,选择】必填 · 取值域hard/soft—— 硬约束 = 不满足就不能用 (烧芯片 / 超温域 / 装不上);软约束 = 影响表现但可权衡(功耗 / 噪声)param_unit★【人填】建议填 —— 参考单位;S1 铺参数骨架、S2 判定都直接抄它 (不是回填每颗料自己记的单位)——同一类型下两颗料必须按同一个单位比,这是这次比对的基准
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
type_id ★ |
所属类型 | text | 主键之一 · 引用 parts.chip_type.type_id |
人(件上,下拉选) | 基线原为 integer,声明加宽为 text |
param_name ★ |
参数名 | text | 主键之一 | 人(件上) | |
param_desc ★ |
参数说明 | text | 必填 | 人(件上) | AI 判定时读它 |
constraint_type ★ |
约束类型 | text | 必填 · 取值域 | 人(件上,下拉选) | 从 parts.parameter 搬到这里按类型标一次(旧设计每颗料各标一次,同一参数两颗料标法不一致就成了可能) |
param_unit ★ |
参考单位 | text | 建议填 | 人(件上) | parts.parameter 铺骨架 / S2 判定均直接抄它 |
三、parts.profile 芯片主数据(P-08)
一颗料一行。S1 配方按启动参数(originalInternalPn / candidateInternalPn)给两颗料各铺
一行骨架:在库的那颗回填此刻的现值(人不必重填,但看得到、能改),要建的那颗全空
等人填。chip_type_id 必填意味着「在库但还没归类型的老料」也会被拦住——那一格回填出来是
空的,人得先给它选一个类型。人不必在件上「加一行」:要建哪两颗料是启动参数定死的事,
行由配方摆好,他只填格子。
重点字段(按重要程度)
internal_pn★ 主键 —— 全链路只认它;值随两颗料由启动参数定,件上虽挂data-col(行的钥匙)但人正常操作不改它chip_type_id★【人填,选择】必填 · 引用parts.chip_type.type_id—— 两颗料必须 归到同一个类型,sub_eval.part.chip_type_id的distinct判据钉着这一条brand_name★【人填】必填lifecycle_status★【人填,选择】必填 · 取值域active/nrnd/eol/discontinued/riskmanufacturer_name★【人填】建议填specification_description★【人填】建议填datasheet_ref/datasheet_version★【人填】建议填(成对)—— 证据回链
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
internal_pn ★ |
内部料号 | text | 主键 | 配方(按入参铺行) | 在库的沿用现值,不在库的等人填别的格子后自然成立 |
chip_type_id ★ |
芯片类型 | text | 必填 · 引用 parts.chip_type.type_id |
配方(在库回填现值)/ 人(件上,下拉选) | 基线原为 integer,声明加宽为 text |
brand_name ★ |
品牌名称 | text | 必填 | 配方(在库回填现值)/ 人(件上) | |
lifecycle_status ★ |
生命周期状态 | text | 必填 · 取值域 | 配方(在库回填现值)/ 人(件上,下拉选) | |
manufacturer_name ★ |
制造商名称 | text | 建议填 | 配方(在库回填现值)/ 人(件上) | |
specification_description ★ |
规格描述 | text | 建议填 | 配方(在库回填现值)/ 人(件上) | |
datasheet_ref ★ |
Datasheet 引用 | text | 建议填 | 配方(在库回填现值)/ 人(件上) | |
datasheet_version ★ |
Datasheet 版本 | text | 建议填 | 配方(在库回填现值)/ 人(件上) |
基线物理表里还留着这次重写不再声明的旧列(
customer_pn/normalized_parameter_set/package/process_technology/eol_pcn_status/application_scenarios/pin_to_pin_relation_ref)——那是同一张表被本活动更早的旧九步版本用过的痕迹 (封装/工艺这次已经变成按类型标在字典里,不再是主记录上单独一列),不是别的活动在共享它; add-column 合并不删旧列,记录浏览里看到它们空着是正常的,判断一列还算不算数,以 当前这份声明为准。
四、parts.parameter 标准化参数集(P-08 子表)
一颗料一个核心参数一行,复合主键 internal_pn + param_name。S1 配方按「这两颗料 ×
选中类型的字段清单」铺骨架(prune:true,换类型会把不再相关的陈旧参数行清掉):
param_value/param_note 若在库已有记录就回填现值,没有就留空等人填;param_unit
永远从 parts.type_param 字典直接复制,不回填每颗料自己记的单位、也不可编辑
(与块①/②b 不同,这一列连孪生输入框都不给)——同一类型下两颗料必须按同一个基准单位比,
S2 判定用的 unit 与件上摆的是同一处来源,不允许分叉。
重点字段(按重要程度)
internal_pn★ 主键之一 · 引用parts.profile.internal_pn—— 挂data-col是因为它是 行的钥匙,不是人正常操作会去改的格子param_name★ 主键之一 —— 同上,由配方按字典铺,不是人填的自由文本param_value★【人填】必填 —— 差异评估逐项比对的唯一输入;原厂规格书查不到就留空, 留空会被红带点名,但编一个值比留空坏得多(说明书明写的禁令)param_unit★ 建议填 —— 恒等于字典值,配方每拍覆盖,手改也会在下一拍被盖回去param_note★【人填】建议填 —— 值的说明
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
internal_pn ★ |
所属料号 | text | 主键之一 · 引用 parts.profile.internal_pn |
配方(按字典 × 两颗料铺骨架) | 挂 data-col 只为行的钥匙 |
param_name ★ |
参数名 | text | 主键之一 | 配方 | 同上 |
param_value ★ |
值 | text | 必填 | 配方(在库回填现值)/ 人(件上) | 查不到留空,不许估、不许拿别的参数的值顶替 |
param_unit ★ |
单位 | text | 建议填 | 配方(恒抄 parts.type_param 字典) |
只读,连孪生输入框都不给 |
param_note ★ |
说明 | text | 建议填 | 配方(在库回填现值)/ 人(件上) |
基线物理表里还留着一列这次重写不再声明的
constraint_type(旧设计每颗料各标一次约束, 这次已搬到parts.type_param按类型标一次)——同一条「add-column 不删旧列」的道理。
五、sub_eval.part 本单两颗料(存在性与类型核对,本活动工作台账)
S1 配方每一拍都重算的一张表(不是「写一次就不再动」):按启动参数铺两行(role
恰有 original/candidate 各一行),found_pn_ref 现查 parts.profile 是否已有这个
internal_pn、exists_status 据此判 found/absent、chip_type_id 现查在库现值。
这张表没有任何人工编辑入口——它是「要评估什么」那张件的行来源
(data-rows="mine:sub_eval.part" data-edit="parts.profile"),人在件上改的是
parts.profile,行会在下一拍被这张表原样重铺。
重点字段(按重要程度)
exists_status★ 必填 · 取值域found/absent—— 存在性核对的核心结论,S1 收步与 S2 入场哨兵都读它(sub_eval_part_exists_status_found = 2才算「两颗都在库」)internal_pn★ 主键之一eval_ref★ 主键之一 —— 本单案号,W05-+ 开案时刻 14 位数字,串联本活动自持的两张 工作台账role★ 必填 · 取值域original/candidatechip_type_id★ 必填 · 去重计数(distinct)—— 「两颗料是不是同一个类型」从此是 基座数得出来的数(sub_eval_part_distinct_chip_type_id),S1 收步与 S2 入场的硬门found_pn_ref★ 条件必填(exists_status=found时)· 引用parts.profile.internal_pn—— 「在库」是一次lookup的结果,不是一句断言;判found就必须拿得出一个基座查得到 的料号
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
eval_ref ★ |
评估案号 | text | 主键之一 | 配方 | |
internal_pn ★ |
内部料号 | text | 主键之一 | 配方(按启动参数铺) | |
role ★ |
角色 | text | 必填 · 取值域 | 配方 | original 恰一行 / candidate 恰一行 |
found_pn_ref ★ |
在库核对依据 | text | 条件必填 · exists_status=found · 引用 parts.profile.internal_pn |
配方(现查 parts.profile) |
查无此值 exists_status 判 absent |
exists_status ★ |
在库状态 | text | 必填 · 取值域 found/absent |
配方 | 每拍现算,不设 created 档、不靠谁记账 |
chip_type_id ★ |
芯片类型 | text | 必填 · 去重计数 | 配方(现查 parts.profile) |
基线原为 integer,声明加宽为 text |
六、sub_eval.case 本单案卷(本活动工作台账)
一单一行的案卷,挂着摆给人看的一句话(gate_reason)与收口摘要(summary)。没有一面
记账旗——完成与否全部由别处的基座读数(sub_eval_part_* / substitution_*_rows /
_missing)判定,这张表只是「说清此刻是什么状况」的一处落点。由两步接力写:S1 每拍
写 eval_ref/chip_type_id/gate_reason(供数据工单卡面的「还差什么」摆),T_release
再补一笔 summary(供落账确认页的结论卡摘要)。
重点字段
eval_ref★ 主键 ——W05-+ 开案时刻 14 位数字(与引擎注给模型铸主键用的case:openedAt同一函数,跨单唯一)gate_reason★ —— 摆在数据工单件上给人看的那句话;when链逐级判断此刻缺什么 (两颗料没填全 / 有料号查无记录 / 有料号没归类型 / 两颗料类型不一致 / 还有必填格空着), 都不缺时是空串。这一笔排在铺骨架那两笔(parts.profile/parts.parameter)之后 不是随手写的次序——它读的parts_profile_missing/parts_parameter_missing是骨架刚建出来的基座读数,排前面会读到刷新之前的旧数(详见docs/活动开发规范.md§4.6 新增纪律)chip_type_id★ —— 本单锁定的芯片类型(原料那一颗的),供 S2 组装入参时lookupsummary★ —— T_release 写的收口一句话(<候选PN> 替代 <原PN>:<差异摘要>),落账 确认页「结论卡」的摘要来源
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
eval_ref ★ |
评估案号 | text | 主键 | 配方(S1,按开案时刻铸) | |
chip_type_id ★ |
本单锁定的芯片类型 | text | — | 配方(S1) | 供 S2 lookup 用 |
gate_reason ★ |
入参未就绪原因(件上摆的就是它) | text | — | 配方(S1,when 链) |
都不缺时是空串;S1 发卡条件读的正是「非空」 |
summary ★ |
结论摘要 | text | — | 配方(T_release) | <候选PN> 替代 <原PN>:<差异摘要> |
七、substitution.relation 替代关系主记录(P-11)
一单一行(旧设计是「一个未放弃的候选一条」,新设计一次评估恰一对一候选,不再有
「多候选、部分放弃」)。S2 与 S3 共用同一份投影(RELATION_PROJECTION):S2 首算,
人在 S3 就地改了差异明细的某条四态之后,同一份投影重算一遍——两处各写一份早晚分叉,
分叉的那一刻屏上会同时摆着两个互相矛盾的等级。推荐等级 / 风险 / 摘要 / 理由 / 验证
要求全部由规则与模板拼,不让 AI 编——于是不会出现「有硬约束不符却写着推荐」这种事;
人在 S3 改的是差异明细的四态,这一行跟着重算,人不直接改这张表本身。
重点字段(按重要程度)
substitution_relation_id★ 主键 ——SUB-<案号>eval_ref★ 必填 —— 本活动新增列(基线没有),串联本单recommendation_level★ 必填 · 取值域recommended/conditional/not_recommended(旧设计还有alternate档,新设计的判定分类三分,这一档随之退役)—— 配方按 §3.5 的 规则算:有硬约束不符必not_recommended,否则有 UNKNOWN/CONDITIONAL/软约束不符任一 即conditional,全一致才recommendedoriginal_internal_pn/candidate_internal_pn★ 必填 · 引用parts.profile.internal_pnrisk_level★ 必填 · 取值域low/medium/high—— 随recommendation_level联动算verification_requirement★ 条件必填(recommendation_level=conditional时)rule_version★ 必填 —— 随结论落账,锁定R-2026.07validation_id★ —— 关联验证ID(VAL-<案号>)
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
substitution_relation_id ★ |
替代关系ID | text | 主键 | 配方 | SUB-<案号> |
eval_ref ★ |
评估案号 | text | 必填 | 配方 | 本活动新增列(基线没有) |
original_internal_pn ★ |
原内部料号 | text | 必填 · 引用 parts.profile.internal_pn |
配方 | |
candidate_internal_pn ★ |
候选内部料号 | text | 必填 · 引用 parts.profile.internal_pn |
配方 | |
chip_type_id ★ |
芯片类型 | text | 必填 | 配方 | 基线原为 integer,声明加宽为 text |
recommendation_level ★ |
推荐等级 | text | 必填 · 取值域 | 配方(按规则算) | 不让 AI 编 |
recommendation_reason |
推荐理由 | text | 必填 | 配方(按规则拼句) | |
difference_summary |
差异摘要 | text | 必填 | 配方(按规则拼句) | 「共 N 项核心参数:X 项一致 / … 」句式 |
risk_level ★ |
替代风险等级 | text | 必填 · 取值域 | 配方(按规则算) | |
verification_requirement ★ |
验证要求 | text | 条件必填 · recommendation_level=conditional |
配方 | |
validation_id |
关联验证ID | text | — | 配方 | VAL-<案号> |
analysis_status ★ |
分析状态 | text | 必填 | 配方 | 恒 fae_confirmed(基线其余档位本活动不写) |
rule_version ★ |
差异规则版本 | text | 必填 | 配方 | 锁定 R-2026.07 |
只读边界:基线在这张表上还建了
customer_approval_status/customer_approval_at/customer_approval_ref/customer_feedback四列,由独立审批流维护;本活动的声明 里没有这四列的写权(禁令no-customer-approval-write)。基线物理表里还留着这次重写 不再声明的request_id/project_code/bom_position/substitution_type/analysis_report_ref/confidence_score——那是旧九步版本用过的列,同一条 「add-column 不删旧列」的道理。
八、substitution.difference_item 差异明细(P-11 子表)
一颗料的一条核心参数一行,主键 substitution_relation_id + difference_item_id;行由
parts.type_param 字典 each 出来(prune:true)——字段清单由字典给,AI 的出参只是
拿 param_name 去 lookup 的一张查表,它漏一条,那一行的四态就是空,required 立刻
变成 _missing > 0,提交闸与放行门当场拦住(不会像「AI 出参驱动行」那样漏两条就少两行、
每一行看着都合规)。S3 是这张表唯一的人工编辑入口:四态 / 影响说明 / 判断依据 /
UNKNOWN 去向可就地改,其余(参数项 / 说明 / 约束 / 原值 / 候选值 / 单位)只读。
重点字段(按重要程度)
substitution_relation_id★ 主键之一 · 去重计数 · 引用substitution.relation.substitution_relation_id—— 「几条关系已经有明细」就是数它的不同值(恰应为 1)difference_item_id★ 主键之一difference_status★ 必填 · 取值域match/mismatch/unknown/conditional—— S2 那一次 AI 判定的核心出参judgement_class★ 必填 · 取值域match/soft_mismatch/hard_mismatch/unknown/conditional—— 合成列(先认difference_status,mismatch再按constraint_type分硬/软): 「硬约束不符有几条」不是任何单列tally数得出来的数,recommendation_level的判据 全靠这一列impact_statement★ 必填 —— MATCH 写「无」,其余写「换上去会不会比现在差、差在哪儿」 (不复述参数值)evidence_note★ 必填 —— 判断依据unknown_disposition★ 条件必填(difference_status=unknown时)—— UNKNOWN 的去向constraint_type★ 必填 · 取值域hard/soft—— 承自parts.type_param字典这一行本身
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
substitution_relation_id ★ |
替代关系ID | text | 主键之一 · 去重计数 · 引用 substitution.relation.substitution_relation_id |
配方 | 隐藏在件上(.rowkey),仅供 resolveRowKey 凑主键 |
difference_item_id ★ |
差异明细ID | text | 主键之一 | 配方 | <关系id>-<参数名> |
parameter_name |
标准参数名 | text | 必填 | 配方(抄字典) | |
parameter_desc |
参数说明 | text | 建议填 | 配方(抄字典) | 归档件不必回查字典,快照一份 |
constraint_type |
约束类型 | text | 必填 · 取值域 | 配方(抄字典) | |
original_value |
原物料参数值 | text | 必填 | 配方(lookup parts.parameter) |
|
candidate_value |
候选物料参数值 | text | 必填 | 配方(lookup parts.parameter) |
|
parameter_unit |
参数单位 | text | 建议填 | 配方(抄字典) | |
difference_status ★ |
差异状态 | text | 必填 · 取值域 | AI(S2 analyze 出参) |
|
judgement_class ★ |
判定分类 | text | 必填 · 取值域 | 配方(合成列) | 由 difference_status × constraint_type 算 |
impact_statement ★ |
影响说明(MATCH 写「无」) | text | 必填 | AI / 人(件上,S3 可改) | |
evidence_note ★ |
判断依据 | text | 必填 | AI / 人(件上,S3 可改) | 基线里这一列旧名是 evidence_ref,本活动改用新名 evidence_note(不写 P-10 了,AI 能给的是依据不是文件引用) |
unknown_disposition ★ |
UNKNOWN 去向(验证任务号 / 补来源动作) | text | 条件必填 · difference_status=unknown |
AI / 人(件上,S3 可改) | |
risk_level |
风险等级 | text | 必填 · 取值域 | 配方 | hard_mismatch→high,match→low,其余 medium |
rule_version |
差异规则版本 | text | 必填 | 配方 | 锁定 R-2026.07 |
基线物理表里还留着两列这次重写不再声明的旧列:
evidence_ref(已被evidence_note取代,不是同一列改名,是新声明了一列、旧列作废不写)与confidence(AI 置信度,旧设计 的工具出参字段,新设计没有这个概念)。
九、validation.record 芯片验证记录(P-06)
事实类表:本活动只在 S2/S3 给每单挂一行固定的「验证要求」占位
(validation_status 恒 not_started,validation_type 恒 parametric)——它不是实测
结果,不许虚构实测;真正测完、写测试结果是另一件事(下游或线下流程的事)。一单固定
一条,即使全部参数都 MATCH、没有待验项,也要写「本轮无待验项」而不是不写这一行
(验收判据 validation-landed 钉着 validation_record_rows = 1)。
重点字段(按重要程度)
validation_id★ 主键 ——VAL-<案号>eval_ref★ 必填 —— 本活动新增列(基线没有)validation_internal_pn★ 必填 · 引用parts.profile.internal_pn—— 恒为候选料号validation_status★ 必填 —— 恒not_startednext_validation_action★ 必填 —— 要测什么、什么条件;没有待验项写「本轮无待验项」validation_type★ 必填 · 取值域(基线六档,本活动只写parametric)test_condition★ 建议填 —— 有待验项才写测试条件,否则「无」
数据结构
| 列名 | 人读名 | 类型 | 约束 | 写入者 | 说明 |
|---|---|---|---|---|---|
validation_id ★ |
验证ID | text | 主键 | 配方 | VAL-<案号> |
eval_ref ★ |
评估案号 | text | 必填 | 配方 | 本活动新增列(基线没有) |
validation_internal_pn ★ |
验证内部料号 | text | 必填 · 引用 parts.profile.internal_pn |
配方 | 恒为候选料号 |
validation_type ★ |
验证类型 | text | 必填 · 取值域 | 配方 | 恒 parametric(本活动只挂这一种) |
validation_status ★ |
验证状态 | text | 必填 | 配方 | 恒 not_started |
test_condition |
测试条件 | text | 建议填 | 配方 | 有 UNKNOWN/CONDITIONAL 才写,否则「无」 |
next_validation_action ★ |
后续验证动作 | text | 必填 | 配方 | 没有待验项写「本轮无待验项」 |
基线物理表里还留着这次重写不再声明的一批旧列(
request_id/customer_code/test_parameters/test_result/issue_risk/sample_version/sample_lot/evidence_ref)——那批列是「真验证发生后才有的事实」(测试参数、测试结果、样品批次), 本活动只写「验证要求」占位阶段,不写实测结果,同一条「add-column 不删旧列」的道理。
十、人填字段总表(按人办事的那一屏)
| 活动 · 屏 | 卡的形式 | 落进哪张表 | 人亲手填的列 |
|---|---|---|---|
S1_inputs · 数据工单「差异评估的输入还差几格」(条件发卡,零卡直通是常态路径之一) |
执行工单(零输入卡,件上编辑 + 增删行) | parts.chip_type(新建类型时)/ parts.type_param(新建类型 / 追加字段时)/ parts.profile / parts.parameter |
chip_type:type_name/description;type_param:type_id(选)/param_name/param_desc/constraint_type(选)/param_unit;profile:chip_type_id(选)/brand_name/lifecycle_status(选)/manufacturer_name/specification_description/datasheet_ref/datasheet_version;parameter:param_value/param_note |
S3_review · 差异评估结论审核(可循环打回重做) |
决策卡(decide,variant:'review')+ 件上就地改 |
substitution.difference_item |
difference_status(选)/impact_statement/evidence_note/unknown_disposition(AI 先判,人核对后可改) |
T_release · 落账放行(可循环打回重做) |
终局验收工单(签字,人工验收清单五条) | 无(全只读) | 无 —— 人只签字或打回重做。这一步本身不提供改内容的手段(writes 只声明了 sub_eval.case,且这张表没有人工编辑入口、全由配方算);要改结论内容,退回 S3_review 的件上直接改 |
十一、在数据域里看这些表时的几条提醒
-
sub_eval.part/sub_eval.case是本活动自持的工作台账(domainsub_eval,与 E04crm_coverage.*、I01content_brand.*同一类地位),其余七张是共享主数据的物理表 —— 但截至这次重写,只有 W05 声明并读写它们(全仓 grepdomain: 'parts'/'substitution'/'validation'唯一命中处就是这个包),称「共享」容易让人以为另有 活动在用,这份文档统一改称「W05 唯一读写者」。 -
type_id这条身份链路是本仓唯一一处「integer 加宽成 text」的声明(六列同源:parts.chip_type.type_id/parts.type_param.type_id/parts.profile.chip_type_id/sub_eval.part.chip_type_id/sub_eval.case.chip_type_id/substitution.relation.chip_type_id)。原因是平台的自增续号器只认「整数型主键走一条路、 字符串型主键走另一条路」,而「auto:true又是integer的主键」这个组合会撞上两处 平台级坑(resolveRowKey抢跑续号 /coerceToColumn按Number()解析掉前导零导致refersTo比对失配)——声明层加宽成text绕开,不是修复那两处平台代码(它们仍带着 坑,见docs/debt.md)。字段说明详见parts.chip_type.type_id那一行与 manifest.ts 对应大注释。 -
基线物理表里普遍还留着旧九步版本的列(见各表小节末尾的提醒框)——
add-column合并不删旧列,记录浏览里看到它们空着是正常的;判断一列还算不算数,以活动清单当前 这份声明为准,不以物理表结构为准。 -
substitution.relation.customer_approval_status等四列是只读边界,不是本活动没做完—— 由独立审批流维护,本活动的声明里没有写权(禁令no-customer-approval-write)。 -
试跑单默认也落真库:与 E04 / I01 同一个开关(
sys.task.land_master,测试台起单 默认打开)——跑一遍活动,新建的芯片类型 / 料号 / 参数都会真的进正式表;要它不落, 起单时显式关掉(脚本化 e2e 要求自己传false)。 -
本活动全程无 agent 多轮编排,零技能、零工具——
contract.resources.tools与declarations.tools都是[],assets.skills也是[](旧两枚工具、两张 DMN、三条 技能戳已随重写整体退役)。全部行为写在PlanStep.auto声明式配方里,详见docs/活动开发规范.md§4.6。
字段口径以 activities/part-substitution-assessment/src/manifest.ts 的
declarations.ledger 为准;七张共享主数据的基线物理结构见
apps/api/src/app/seed-mvp-data.ts 的 MASTER_OBJECTS;四步剧本与配方见
activities/part-substitution-assessment/src/case-model.ts 的 ASSESSMENT_STEPS 与
NARRATIVE;确定性步骤(auto 五动词)的通用机制见 docs/adr/ADR-014-deterministic-steps.md
与 docs/活动开发规范.md §4.6;业务设计源见 docs/SS02-ACT-WORK-05-html/
(活动流程与工单说明)、docs/superpowers/specs/2026-08-29-act-work-05-rewrite-design.md
与《SS02-SS03-SS04_Demo台账字段细化与统一方案》。