This repository has been archived on 2026-09-13. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BPOS-TMP-REPO/docs/数据域字段说明-W05.md
xcsandClaude Opus 5 8586f7dac8 docs(w05): 重写收口 —— 头注核正、字段说明按现状重写、规范补四条 auto 纪律、CLAUDE.md 记战果
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
2026-08-30 11:22:56 +08:00

35 KiB
Raw Permalink Blame History

数据域字段说明 —— ACT-WORK-05 差异评估

对应设计中心 → 数据域「ACT-WORK-05 · 差异评估」分组。字段以活动清单的台账声明为准 (activities/part-substitution-assessment/src/manifest.ts 的 declarations.ledger)。 2026-08-29 整体重写(design spec docs/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 的那条纪律)。

重点字段(按重要程度)

  1. type_id ★ 主键 · 自增 —— 声明成 text 而不是 integer(见文档头注),写入时按 「现有最大 + 1」续号,不进表单、只读态摆「系统生成」
  2. type_name ★【人填】必填 —— 新建类型时件上现填,已有类型从下拉挑
  3. 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(为什么要紧)一起交给模型判四态。

重点字段(按重要程度)

  1. type_id ★【人填,选择】主键之一 · 引用 parts.chip_type.type_id
  2. param_name ★【人填】主键之一 —— 参数名
  3. param_desc ★【人填】必填 —— AI 分析时读的就是它:参数名本身说不清「它为什么要紧」, 写成参数名的复述等于没写
  4. constraint_type ★【人填,选择】必填 · 取值域 hard/soft —— 硬约束 = 不满足就不能用 (烧芯片 / 超温域 / 装不上);软约束 = 影响表现但可权衡(功耗 / 噪声)
  5. 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 必填意味着「在库但还没归类型的老料」也会被拦住——那一格回填出来是 空的,人得先给它选一个类型。人不必在件上「加一行」:要建哪两颗料是启动参数定死的事, 行由配方摆好,他只填格子。

重点字段(按重要程度)

  1. internal_pn ★ 主键 —— 全链路只认它;值随两颗料由启动参数定,件上虽挂 data-col (行的钥匙)但人正常操作不改它
  2. chip_type_id ★【人填,选择】必填 · 引用 parts.chip_type.type_id —— 两颗料必须 归到同一个类型,sub_eval.part.chip_type_id 的 distinct 判据钉着这一条
  3. brand_name ★【人填】必填
  4. lifecycle_status ★【人填,选择】必填 · 取值域 active/nrnd/eol/discontinued/risk
  5. manufacturer_name ★【人填】建议填
  6. specification_description ★【人填】建议填
  7. 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 与件上摆的是同一处来源,不允许分叉。

重点字段(按重要程度)

  1. internal_pn ★ 主键之一 · 引用 parts.profile.internal_pn —— 挂 data-col 是因为它是 行的钥匙,不是人正常操作会去改的格子
  2. param_name ★ 主键之一 —— 同上,由配方按字典铺,不是人填的自由文本
  3. param_value ★【人填】必填 —— 差异评估逐项比对的唯一输入;原厂规格书查不到就留空, 留空会被红带点名,但编一个值比留空坏得多(说明书明写的禁令)
  4. param_unit ★ 建议填 —— 恒等于字典值,配方每拍覆盖,手改也会在下一拍被盖回去
  5. 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,行会在下一拍被这张表原样重铺。

重点字段(按重要程度)

  1. exists_status ★ 必填 · 取值域 found/absent —— 存在性核对的核心结论,S1 收步与 S2 入场哨兵都读它(sub_eval_part_exists_status_found = 2 才算「两颗都在库」)
  2. internal_pn ★ 主键之一
  3. eval_ref ★ 主键之一 —— 本单案号,W05- + 开案时刻 14 位数字,串联本活动自持的两张 工作台账
  4. role ★ 必填 · 取值域 original/candidate
  5. chip_type_id ★ 必填 · 去重计数(distinct)—— 「两颗料是不是同一个类型」从此是 基座数得出来的数(sub_eval_part_distinct_chip_type_id),S1 收步与 S2 入场的硬门
  6. 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(供落账确认页的结论卡摘要)。

重点字段

  1. eval_ref ★ 主键 —— W05- + 开案时刻 14 位数字(与引擎注给模型铸主键用的 case:openedAt 同一函数,跨单唯一)
  2. gate_reason ★ —— 摆在数据工单件上给人看的那句话;when 链逐级判断此刻缺什么 (两颗料没填全 / 有料号查无记录 / 有料号没归类型 / 两颗料类型不一致 / 还有必填格空着), 都不缺时是空串。这一笔排在铺骨架那两笔(parts.profile/parts.parameter)之后 不是随手写的次序——它读的 parts_profile_missing/parts_parameter_missing 是骨架刚建出来的基座读数,排前面会读到刷新之前的旧数(详见 docs/活动开发规范.md §4.6 新增纪律)
  3. chip_type_id ★ —— 本单锁定的芯片类型(原料那一颗的),供 S2 组装入参时 lookup
  4. summary ★ —— 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 改的是差异明细的四态,这一行跟着重算,人不直接改这张表本身。

重点字段(按重要程度)

  1. substitution_relation_id ★ 主键 —— SUB-<案号>
  2. eval_ref ★ 必填 —— 本活动新增列(基线没有),串联本单
  3. recommendation_level ★ 必填 · 取值域 recommended/conditional/not_recommended (旧设计还有 alternate 档,新设计的判定分类三分,这一档随之退役)—— 配方按 §3.5 的 规则算:有硬约束不符必 not_recommended,否则有 UNKNOWN/CONDITIONAL/软约束不符任一 即 conditional,全一致才 recommended
  4. original_internal_pn / candidate_internal_pn ★ 必填 · 引用 parts.profile.internal_pn
  5. risk_level ★ 必填 · 取值域 low/medium/high —— 随 recommendation_level 联动算
  6. verification_requirement ★ 条件必填(recommendation_level=conditional 时)
  7. rule_version ★ 必填 —— 随结论落账,锁定 R-2026.07
  8. validation_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 去向可就地改,其余(参数项 / 说明 / 约束 / 原值 / 候选值 / 单位)只读。

重点字段(按重要程度)

  1. substitution_relation_id ★ 主键之一 · 去重计数 · 引用 substitution.relation.substitution_relation_id —— 「几条关系已经有明细」就是数它的不同值(恰应为 1)
  2. difference_item_id ★ 主键之一
  3. difference_status ★ 必填 · 取值域 match/mismatch/unknown/conditional —— S2 那一次 AI 判定的核心出参
  4. judgement_class ★ 必填 · 取值域 match/soft_mismatch/hard_mismatch/unknown/conditional —— 合成列(先认 difference_status,mismatch 再按 constraint_type 分硬/软): 「硬约束不符有几条」不是任何单列 tally 数得出来的数,recommendation_level 的判据 全靠这一列
  5. impact_statement ★ 必填 —— MATCH 写「无」,其余写「换上去会不会比现在差、差在哪儿」 (不复述参数值)
  6. evidence_note ★ 必填 —— 判断依据
  7. unknown_disposition ★ 条件必填(difference_status=unknown 时)—— UNKNOWN 的去向
  8. 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)。

重点字段(按重要程度)

  1. validation_id ★ 主键 —— VAL-<案号>
  2. eval_ref ★ 必填 —— 本活动新增列(基线没有)
  3. validation_internal_pn ★ 必填 · 引用 parts.profile.internal_pn —— 恒为候选料号
  4. validation_status ★ 必填 —— 恒 not_started
  5. next_validation_action ★ 必填 —— 要测什么、什么条件;没有待验项写「本轮无待验项」
  6. validation_type ★ 必填 · 取值域(基线六档,本活动只写 parametric)
  7. 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 的件上直接改

十一、在数据域里看这些表时的几条提醒

  1. sub_eval.part / sub_eval.case 是本活动自持的工作台账(domain sub_eval,与 E04 crm_coverage.*、I01 content_brand.* 同一类地位),其余七张是共享主数据的物理表 —— 但截至这次重写,只有 W05 声明并读写它们(全仓 grep domain: 'parts' / 'substitution' / 'validation' 唯一命中处就是这个包),称「共享」容易让人以为另有 活动在用,这份文档统一改称「W05 唯一读写者」。

  2. 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 对应大注释。

  3. 基线物理表里普遍还留着旧九步版本的列(见各表小节末尾的提醒框)——add-column 合并不删旧列,记录浏览里看到它们空着是正常的;判断一列还算不算数,以活动清单当前 这份声明为准,不以物理表结构为准。

  4. substitution.relation.customer_approval_status 等四列是只读边界,不是本活动没做完—— 由独立审批流维护,本活动的声明里没有写权(禁令 no-customer-approval-write)。

  5. 试跑单默认也落真库:与 E04 / I01 同一个开关(sys.task.land_master,测试台起单 默认打开)——跑一遍活动,新建的芯片类型 / 料号 / 参数都会真的进正式表;要它不落, 起单时显式关掉(脚本化 e2e 要求自己传 false)。

  6. 本活动全程无 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台账字段细化与统一方案》。