Archived
fix(w05): 终审两条 Critical + 地基缺陷的另一半 + 文档与欠账收口
**C1 新建芯片类型会改写既有字典行(共享主数据被静默污染)**
链条逐行复核成立:件上种子行漏挂 data-col → barred 与 isSeq 双保护同时失效
(isSeq 那条是因为 Task 7b 把 type_id 从 integer 改成了 text)→ 落进「全表一致」,
而 H35 的自投影恰好保证这张表只有一行 → 人新建的类型被认成既有 type_id=1 →
确认时随范围放行把既有字典行改名并落进正式表,屏上只说「改了 1 行」。
三条各自成立的裁定叠出来的静默污染。
修法:种子行改成 disabled 的真实 <input data-col=type_id>(desk.ts 零改动),
格子里摆「由系统生成」——不能一声不吭地拿掉,那样人会以为这张档少了一格。
测试不止断言结果:另加两条用**真实 resolveRowKey** 重放病灶/修法两种 cells 形状,
直接证明因果机制。平台根治(全表一致应排除 auto 列)记 debt。
**C2 两个启动参数都选填 → 留空则整单永久无解**
gate_reason 说「在下面把两格补上」,而块① 没有加一行、也不在 gateLedgers ——
一句指向空气的指路。改为必填;第一档改口为唯一真无解的那条路径(两格填了同一个号)。
**I1 地基缺陷只修了一半:recipe.let 同样按对象键序求值**
与 fields 是一模一样的假设,同样住 jsonb 列、同样被 PG 重排;今天不炸只因 W05 那五条
互不引用,而 ADR-014 是给后续所有活动用的。新增 orderLets/letReferences
(把 {in:X} 视为依赖 —— 语义与 fields 不同,故单独实现),auto-runner 与静态审同步接入。
**I2 审核卡按「重做」照样收步推进** —— 坐实为真实平台缺陷(「卡答过了就收步」快道不看裁决),
并证明活动侧加选项救不了、chosenGuidance 那条也救不了(那是喂模型的提示词,
而这条快道存在的目的就是跳过模型)。按裁定只留复现测试,平台未改。
**I4** 同一堵墙撞第二次即发兜底执行工单交人 + 立监听(头一次软化留痕),
不再空转到 exhausted 而人无处可改。
debt +4(C1 根治 / modules→app / thead-after-tbody / data-by 落回外层),
并补写此前被两处引用却从不存在的「refersTo 传递闭包」条目。
文档:ADR-014:201「按声明顺序求值」改对(照它写配方的人会重犯本轮的地基缺陷)、
陈旧注释四处、spec 四处分叉逐条判断处置、端到端测试记录标为历史、
CLAUDE.md 纠正「新建类型端到端通了」那句(它没通过真人路)并更新版本与文档表。
包版本 2.1.9(已装,SQL 直查库内 version/required/gate_reason/视图 HTML 四项核实)。
pnpm gates 退出码 0(2476 通过 / 34 跳过);E04 92/92、I01 55/55 无回归。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LKMZDwMbyKzjw6Hembwvet
This commit is contained in:
@@ -261,6 +261,17 @@ doneWhen sub_eval_part_exists_status_found = 2
|
||||
- 人点「提交」= 数据工单确认 → **`chip_type` / `type_param` / `profile` / `parameter` 当场进正式表**
|
||||
(平台 2026-08-27 的范围放行)。它们是主数据,该立刻可用,不等整单放行。
|
||||
|
||||
> **2026-08-30 补记**:实现是**八笔**,不是上面写的六笔 ——「提交」那一句已经点出原因:
|
||||
> `chip_type` / `type_param` 要跟着数据工单一起进正式表(范围放行只并 `gateLedgers`
|
||||
> 名单上的表,见 `docs/debt.md`「范围放行没有对 `refersTo` 做传递闭包」),而它们此刻
|
||||
> 只在人新建类型时才有草稿行——挑一个已有类型时天然零行,闸拿「零行」误判成没干完。
|
||||
> Ruling H35(e2e 真跑撞见)在②③之间插了两笔**自投影**(原样把选中的类型字典行 / 字段
|
||||
> 清单行抄回自己身上,值不变、幂等,唯一目的是让 `mine:` 不再天然为空),使这两张表
|
||||
> 能安全回到 `gateLedgers` 上。次序变成:①两颗料 → ②类型字典自投 → ③字段清单自投 →
|
||||
> ④主数据骨架 → ⑤参数骨架 → ⑥案卷 → ⑦卡 → ⑧交代(与上面①③④⑤⑥对应,原④⑤⑥ 顺移成
|
||||
> ⑥⑦⑧)。这两笔**不带 `prune`**(与③节 §11.4 那条改口同一个理由:字典/字段清单是共享
|
||||
> 的,历史选型的陈旧行留着不算错)。详见 `case-model.ts` 该两笔头上的大注释。
|
||||
|
||||
### 4.3 S2 差异分析 —— 纯系统 + AI 唯一一次出场
|
||||
|
||||
```
|
||||
@@ -313,14 +324,22 @@ doneWhen substitution_difference_item_rows > 0
|
||||
|
||||
### 4.4 S3 结论审核 —— 一张验收工单,人就地改
|
||||
|
||||
配方只有一笔:`card` 审核卡(`variant: 'review'`,件 `difference-review`,**单一选项「确认通过」**,
|
||||
带人工验收清单四条)。
|
||||
**2026-08-30 改口**:这一节写下时以为配方只有一笔(`card`),下一段自己就说漏了 ——
|
||||
真正的配方是**五笔**:①差异明细**重算笔**(2026-08-30 task-12「结论纹丝不动」缺陷补的,
|
||||
见下)→ ②③ 复制自 S2 的 `RELATION_PROJECTION`/`VALIDATION_PROJECTION`(同一个对象引用,
|
||||
不是抄了两份)→ ④ `card` 审核卡(`variant: 'review'`,件 `difference-review`,**单一
|
||||
选项「确认通过」**,带人工验收清单四条)→ ⑤ `say`。
|
||||
|
||||
人在件上改四态 / 影响 / 依据 → 保存 → tick → 配方重跑 → S2 的第③笔把推荐等级、摘要、风险
|
||||
**重算一遍**(同 PK 覆盖)→ 件刷新。改几次都行,**不重跑 AI**。
|
||||
人在件上改四态 / 影响 / 依据 → 保存 → tick → 配方重跑 → **①重算笔**先把人改的
|
||||
`difference_status` 转译成 `judgement_class`/`risk_level`(这一步的存在理由:走查发现⑤
|
||||
逮到的真实缺陷——最初的设计只复制了②③,人改的四态没有任何一笔把它转成
|
||||
`judgement_class`,②③读到的 tally 纹丝不动,人在件上改了却什么都没变;`docs/debt.md`
|
||||
已记「S3 存在的全部意义就是让人纠正 AI;纠正流不下去,S3 就是摆设」)→ ②③把推荐等级、
|
||||
摘要、风险**重算一遍**(同 PK 覆盖)→ 件刷新。改几次都行,**不重跑 AI**。
|
||||
|
||||
> 重算发生在 S2 那一步的配方里,而 S2 已收步 —— 所以 S3 的配方里**复制一份 ③④ 两笔**
|
||||
> (纯投影、幂等),不去回退步骤。这是刻意的:一步一份配方,不做跨步回跳。
|
||||
> ②③ 复制的是 S2 那一步配方**同一个对象引用**(纯投影、幂等),不去回退步骤 —— S2 已
|
||||
> 收步,S3 不能跨步回跳,只能在自己的配方里再摆一份同样的投影逻辑。这是刻意的:
|
||||
> 一步一份配方,判定分类/风险等级的 `when` 链只许有一处真源(共用引用而非各写一份)。
|
||||
|
||||
这一步**不给 `doneWhen`**(它触达世界),人点了「确认通过」即收步。
|
||||
|
||||
@@ -499,7 +518,7 @@ tick
|
||||
|
||||
| key | level | 谓词大意 |
|
||||
|---|---|---|
|
||||
| `input-ready` | L1 | 两颗都在库 · 类型一致 · 参数行数 = 字段数×2 · 参数值不缺 |
|
||||
| `input-ready` | L1 | 两颗都在库 · 类型一致 · 主数据与参数值都不缺必填(**不写**「参数行数 = 字段数×2」——2026-08-30 与实现一起改口:那不是基座数得出来的数,§4.2 doneWhen 尾注已经讲过同一条道理,这里当时漏改) |
|
||||
| `every-param-judged` | L2 | `substitution_difference_item_missing = 0` 且四态四档计数之和 = `_rows`(AI 漏一条 → 那行四态为空 → 两边都不成立) |
|
||||
| `level-by-rule` | L2 | 推荐等级与 `judgement_class` 计数一致(硬不符>0 必须是「不推荐」…) |
|
||||
| `unknown-has-disposition` | L2 | `substitution_difference_item_missing = 0` |
|
||||
@@ -574,7 +593,15 @@ tick
|
||||
而判断正是人在 S3 要核的东西。
|
||||
3. **类型字典会被建脏**(同一类型建两遍、字段名不一致)。件上下拉优先选已有、新建是次选;
|
||||
MVP **不做去重合并**,记 debt。
|
||||
4. **`prune` 会撤本单草稿层的行** —— 只在 S1 参数骨架这一笔用,别处不许用。静态审可以只放行这一处。
|
||||
4. **`prune` 会撤本单草稿层的行**(2026-08-30 改口:这一条与实现一起对照过 —— 实际用在**三处**
|
||||
`project`,不是一处:S1 的 `parts.profile`(④ 主数据骨架)/ `parts.parameter`(⑤ 参数骨架)、
|
||||
S2 的 `substitution.difference_item`(②,§4.3)。§4.2/§4.3 的伪码从写下那一刻起就是这三处
|
||||
都带 `prune`,这里当时漏改成了「只一处」。真正的约束不是「只许一处」,是**只许用在
|
||||
「这一笔的数据源就是这张表在本单该有的全部」这一类骨架/明细投影上**——H35 后来新增的
|
||||
`parts.chip_type`/`parts.type_param` 两笔**自投影**(4.2 节之外,原样抄字典行那两笔)
|
||||
就**刻意不带** `prune`:它们写的是共享字典/字段清单,不是这一单独占的骨架,历史选型的
|
||||
陈旧行留着不算错,带 `prune` 反而会在人改选类型后把已经落地的陈旧行撤成死锁——静态审
|
||||
要放行的是「哪一类数据源」,不是「哪一个固定笔数」)。
|
||||
5. **保存一次 = 一拍**。人反复保存十几次会吃步数,预算给到 40。
|
||||
6. **表达力有上限**。上限之外的不要硬塞 —— 退回模型,或者把那一段切成独立的 agent 步。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user