muse-agent-example/docs/2026-07-16-升格卡改造设计.md

33 KiB
Raw Blame History

升格卡改造设计(P0 补骨架记里程碑 · P1 串链语义判重)

  • 版本:v2(2026-07-20 已实现;新增里程碑章号原文证据绑定)
  • 目标读者:创始人 + 后续实现的子代理
  • 边界:只改参考书作品面升格卡(source_type='upgrade_book')的字段骨架、抽取提示词、判重方式、上下文裁剪标注;不碰范式卡、不碰主仓。概念定义对齐 ../design-docs/(专题-06、架构-02)与源方案 docs/2026-07-14-参考书作品面数据入库方案.md,本稿是对该方案 §五「实体卡生命周期」的一次修订,不自立门户。
  • 一句话结论:给机甲/武器/力量体系这些型补上一条"从登场到结局"的演变历程明细,用真实章号当索引(不用会变的运行时窗号),并把这条上万字的明细只给一致性检查看、不给续写看(续写只看当前态和一句话梗概);再用语义判重把改了名、换了型的同一条成长线并回一起、串成前后链。

一、先说人话:这次要解决什么

升格卡 = 每本参考书里"会随剧情长大的实体卡"——人物、机甲、武器、力量体系都算。它的价值是:当 muse 学一本书时,能看清"这台生物机甲是怎么从 4 级一步步打到 7 级对决"的完整成长线。

现在这条线维护不出来。典型病例:一台生物机甲开头 4 级出场,中段 5 级 6 级,终局 7 级对决——卡里完全看不到这条演变线,只剩一个"最终态",中间全被抹平了。

这次改造分两步走:

  • 第一步(先补骨架、记里程碑):给机甲/武器/力量体系这些型补上"演变历程"字段,把每一次进化台阶记成一条条里程碑,不再被覆写抹平、不再塞错字段。
  • 第二步(再串链、上语义判重):加"前身/后继"把散落的碎卡串成一条进化链;判重从"只比名字字符串"升级到"比语义",治改名和跨型漏并。

三个硬要求贯穿全程:里程碑用真实章号索引(不用窗号);章号必须由所标章节原文短引机械证明;卡片分两层给——续写只看当前态,一致性检查才看全历史。


二、病根复述(都有真实卡为证)

以下四条病根,均从库里真实升格卡(work_id=8)抽样核实,不是推断。

病根 1:只有"人物"型有成长字段,机甲/武器/力量体系型是"骨架残缺"

库里 23 型中,只有两个型有"记录演变"的数组字段:character(成长弧线)、character_relation(演变轨迹)。机甲/武器/战舰所属的 item 型、力量体系所属的 power_system 型,以及 faction/location/event,一个演变字段都没有。

  • 铁证:机甲卡「铁头机甲(一代)」(id=1154)出场横跨 64 章(第 10 章到第 548 章),字段却只有"品阶/类别/知情范围/能力与限制",全是会被覆写的当前值。它的一句话摘要是"已退役,封存于暗龙会仓库"——这是最终态,把它 10 章出场时"崭新训练机"的样子彻底抹平了。一台陪跑全书的机甲,成长线为零。

病根 2:进阶要么被覆写抹平,要么塞进错字段成流水账

没有专门的演变字段,模型只能把"进化"硬塞进当前态字段,结果字段语义被污染:

  • 机甲卡「影杀者」(id=4935):把"被重创 → 修复 → 配合突围"这条演变线,塞进了「流转计划」(本该写未来伏笔)和「能力与限制」(本该写当前能力),还带着"本窗/前窗"这种一旦脱离运行环境就没法读的相对指代。
  • 力量体系卡「生物机甲」(id=6223,正是病例本体):把"第 420 章 V 代编队 → 477 章拦截 → 489 → 490-492 → 549-550 → 572 章"整条升级线,塞进了「戏剧作用」(本该一句话写规则)和「跨体系换算」(本该写强弱对照),写成一大段散文流水账。它的摘要同样是最终态(200% 同步率对决 VI 型领主),4 级出场的初始态被抹平。
  • 对照「机甲世代」(id=4995)的「境界阶梯」="一代 < 二代 < 三代 < 四代 < 伪 V 代"——这是静态的世界规则(一把标尺),不是某台机甲实际爬台阶的历程。说明现有字段能记"规则",但记不了"某个实体自己怎么一步步长大"。

病根 3:一条成长主线被拆成 30+ 张碎卡,跨多个型,彼此无链接

"机甲代际"这条主线,散落在:力量体系型的「生物机甲」「机甲世代」「旧联邦机甲代际」,加上 item 型的「铁头机甲」「铁卫」「枪骑士」「影杀者」等一堆具体机甲卡。它们之间没有任何链接,看不出"铁头(一代)→ 铁卫(二代)→ 枪骑士(三代)→ 影杀者(四代)→ 生物机甲(V 代)"是同一条进化链。

病根 4:判重只比名字字符串,语义判重是关着的

现在的判重(在 parse_upgrade.py 的判重步)只有三招:名字/别名精确匹配、模型自报的疑似别名、同型名字互为子串。没有接语义判重——代码里白纸黑字写着"嵌入延后:试跑期不调嵌入 API"。

后果:同一实体一旦改名(如"影杀者"→"IV 代纯机械机甲·影杀者")或跨型指代,字符串对不上就漏并,进一步加剧病根 3 的碎卡。

补充:源方案 v6 本来就设计了"名字精确 → 嵌入近邻 → AI 终判"三级判重,只是试跑期把嵌入近邻这级关掉了。所以第二步的语义判重不是发明新东西,是把 v6 已设计好、暂时关着的那一级打开。


三、方案总览

flowchart TB
    subgraph P0["第一步 P0:补骨架 + 记里程碑(治病根 1、2)"]
        A1["给 item/power_system 等型<br/>加『演变历程』数组字段"]
        A2["加进追加白名单 APPEND_FIELDS<br/>(只往后加,永不覆写抹平)"]
        A3["改抽取提示词:<br/>每次进化记一条里程碑<br/>标生命周期(登场→高光→退场→结局)<br/>当前态字段保持干净、不塞历史"]
    end
    subgraph P1["第二步 P1:串链 + 语义判重(治病根 3、4)"]
        B1["加『前身/后继』链接字段<br/>把碎卡串成一条进化链"]
        B2["判重打开语义近邻(≥0.60·小样实测校准)<br/>+ M3 终判 → 治改名/跨型漏并"]
    end
    subgraph FIX["两点硬性细化(贯穿全程)"]
        C1["① 里程碑用真实章号索引<br/>绝不用运行时窗号 [窗N]"]
        C2["② 卡片分两层披露<br/>续写只看当前态+梗概<br/>一致性检查才看全历史<br/>(复用现成的 aiContext 按用途裁剪)"]
    end
    P0 --> P1
    C1 -.贯穿.-> P0
    C2 -.贯穿.-> P0

四、第一步 P0:补骨架 + 记里程碑

4.1 加什么字段

给缺演变字段的实体型补一个统一的「演变历程」数组字段。核心是 item(机甲/武器/战舰)和 power_system(力量体系/机甲代际);faction/location/event 按需跟进(组织兴衰、地点易主、事件推进同样能用,建议同批补上,避免二次改)。

配套还要两个字段(详见第五节 schema 定义):

  • 「演变概括」——一句话说清整条线的来龙去脉(现状层,续写可见)。
  • 「前身」「后继」——串链用(第二步 P1 用,schema 一次性加齐)。

4.2 抽取提示词怎么改(要点,不写代码)

改 parse_upgrade.py 里的两段提示词:

  • 实体观察提示词(observe):新实体立卡时,如果这一窗就观察到它的登场/首个进化台阶,产出「演变历程」的第一条里程碑(带真实章号 + 生命周期标记)。
  • 卡更新提示词(update):从现在的"记新信息"改为明确的"记进化台阶 + 生命周期"——每当实体发生境界/代际/形态/能力的跃迁,或到达登场、高光、退场、结局这些节点,就追加一条里程碑,绝不覆写、绝不抹平旧台阶。同时要求:当前态字段(品阶/能力与限制/摘要)只写"现在是什么样"的干净全量值,不许把历史流水塞进来(直接治病根 2 的"塞错字段")。

提示词纪律要加两条硬约束:

  1. 每条里程碑必须带真实章号,并临时附一段来自所标章节正文的连续短引;系统按章读取原文做逐字机械核验,错章、缺证据或改写证据均拒收入库。禁止 [窗N] 窗号、禁止"本窗/近期/前段"这类相对指代——因为卡会脱离运行环境被单独阅读。证据只用于写入前校验,校验后删除,不进入正式卡体。
  2. 生命周期标记从固定枚举里选:登场 / 成长 / 高光 / 退场 / 结局。这一条直接治"铁头机甲摘要跳到已退役、中间态全丢"——有了登场和退场节点,一台机甲什么时候来的、什么时候谢幕,一目了然。

4.3 合并逻辑要跟着改

「演变历程」进 APPEND_FIELDS 追加白名单后,parse_upgrade.py 的合并/立卡/撤销逻辑(merge_card/new_card/undo_window)要从"处理带 [窗N] 前缀的字符串条目"适配为"处理带章号的里程碑条目":去重按里程碑内容、排序按章号(不再按窗号)。现有那套针对脏数据的守卫(剥前缀、剥尾部残渣、拦垃圾、拆巨型粘连)要保留并改造,别丢。

顺带清理:APPEND_FIELDS 里的「大事记」「经历」两个名字在任何 schema 里都没有定义(是孤儿字段,模型就算输出也会被字段校验裁掉)。这次统一到「演变历程」,孤儿名可保留做向后兼容但不再新用。


五、「演变历程」字段的 schema 定义

5.1 字段清单(加在 item.yaml / power_system.yaml 等型的"特有字段")

字段名 类型 说明 属哪层
演变历程 里程碑对象数组 已发生的进化台阶明细,一条一台阶,永远追加不覆写 完整历史层
演变概括 一句话文本 整条线的来龙去脉梗概(如"4 级训练机出场 → V 代编队主力 → 300% 同步率对决 VI 型领主") 现状层
前身 链接(卡号 + 名称) 这张卡的上一代/来源,指向同书另一张卡 现状层
后继 链接(卡号 + 名称) 这张卡的下一代/继承者,指向同书另一张卡 现状层

5.2 里程碑对象结构(每条演变历程条目长这样)

正式卡体使用极简三字段结构化对象,既能按章号排序/定位,又不会因字段太多让模型抽崩。抽取模型输出时临时增加第四个 证据 字段,写入前机械核验并删除:

{
  "章": 420,
  "台阶": "V代编队首战:暗星帝国出动十台生物机甲配合亡灵号,扭转多瑙星海战场局势",
  "周期": "高光",
  "证据": "所标章节正文中的连续短句"
}
  • 章:绝对章号,用于索引与排序。单章事件填整数(420);跨多章的连续事件填区间字符串("420-423")。这是"用绝对章号索引"的落点。
  • 台阶:一句话讲清"进化到什么 + 靠什么事件"。刻意把"结果 + 经过"合成一句,不再往下拆细字段,避免模型输出格式崩。
  • 周期:生命周期枚举,取值 登场 / 成长 / 高光 / 退场 / 结局。
  • 证据:仅存在于抽取传输层,必须逐字出现在「章」所指正文中;机械核验后删除,正式卡仍保持三字段。

这个结构是有真实依据的:库里关系卡「苏铭×林初雨」早期就自发用过 {状态, 章区间: "Ch.21", 转折事件} 这种带章号的结构化格式,证明模型抽得出、章号索引可行。三字段是"结构化可查询"和"模型稳定"之间的最优平衡点。

备选(若评审认为对象改造风险太大):退一步用带章号前缀的字符串条目,即把现在的 [窗2] xxx 换成 [第420章·高光] xxx。改动更小、迁移更平滑,但章号在文字前缀里,得靠正则抽取、不能直接用 SQL 过滤。推荐前者、备选后者,见第九节拍板点。

5.3 一条真实成长线改造后长什么样(以病例"生物机甲"示意)

现在(病根 2 的样子):升级史一大段塞在「戏剧作用」字段里,散文流水,摘要只剩最终态。

改造后:

  • 演变概括(现状层,续写可见):"卡依斯生物反应驱动的奇袭兵器,从 4 级机体登场,历经 V 代编队、300% 同步率解放,终局对决近帝皇级 VI 型领主。"
  • 演变历程(完整历史层,只给一致性检查):
    • {章: 332, 台阶: "生物机甲首次登场,作为突破哈姆斯要塞的核心奇袭兵器", 周期: 登场}
    • {章: 420, 台阶: "V代编队首战,配合亡灵号扭转多瑙星海战场", 周期: 成长}
    • {章: "490-492", 台阶: "苏铭精神链接同步率飙至300%,压制伪VI代、夺龙基之枪贯穿拜鲁特", 周期: 高光}
    • {章: "549-550", 台阶: "300%同步率独战近帝皇级VI型英雄级伊琳莉丝,龙基之枪刺穿其AT立场", 周期: 结局}

一条清清爽爽、按章号排序、能看出起承转合的成长线就立住了。


六、两点硬性细化的落地

6.1 细化①:真实章号索引 + 现有 [窗N] 卡的迁移办法

为什么不能用窗号:窗号([窗N])是抽取时"切正文窗"的运行产物——切窗规则是"每窗 12 章或 3.5 万字",规则一改窗号全变。它是运行时定义、会变、不该当卡的稳定属性。真实章号(第 420 章)才是永远不变的锚。

存量卡怎么迁移(一次性迁移脚本,本稿只给办法、不实现):遍历所有 upgrade_book 卡的演变类字段(成长弧线/演变轨迹等)里每一条带 [窗N] 的条目,按下面优先级把 [窗N] 换成真实章号:

  1. 优先——抽条目文字里已有的真实章号:很多条目正文里模型自己就写了"第 420 章""163 章""Ch.21",正则抽出来直接当「章」。这是最准的。
  2. 兜底——用窗到章的映射表:条目里没有内嵌章号的,查 example_upgrade_window 表(窗号 → from_chapter~to_chapter),把 [窗N] 映射成该窗的章区间(如 [窗2] → "13-24"),并打一个"章区间近似"标记,表明这是窗级近似、不是精确到章。
  3. 顺手清脏:迁移时一并清掉已知垃圾——[窗17] ['窗23 这类残片、重复条目、尾部 JSON 拼接残渣。复用 parse_upgrade.py 里现成的剥前缀/剥尾残/拦垃圾逻辑。

诚实边界:上万字的历史里,兜底那批(无内嵌章号、只能靠窗映射)会损失精度——只能定位到 12 章宽的区间。这是存量迁移的固有局限,新抽取的卡因为提示词强制带真实章号不受影响。

6.2 细化②:渐进式披露 = 现状层 + 完整历史层,接现有 aiContext 按用途裁剪

这不是新机制。本仓早就有"字段按用途可见性裁剪"的机制:每个 schema 字段有个 aiContext 标注——true 任何场景可见、false 一律不给、[用途…] 只有列出的场景可见。用途有四种:generation(续写)、detection(一致性检查)、planning(规划)、extraction(抽取判重)。read-context(组装上下文)、search(检索)、detect(一致性检查)三个 skill 都已经按这个标注干活。渐进披露就是给演变字段填对 aiContext,一行标注的事。

分两层:

  • 现状层——写作 agent 续写时默认只读这层。包括实体当前态(品阶/能力与限制/当前持有者/一句话摘要)+ 演变概括 + 前身后继。让续写者知道"这台机甲现在几级、一路怎么来的梗概、前身是谁",但不被上万字明细淹没。
  • 完整历史层——只有一致性检查(detector)读全。就是「演变历程」那个可能上万字的里程碑数组。续写用不上这么细,一致性检查却必须有它才能查出"上一章还 4 级、这一章怎么突然 7 级"这种跳级穿帮。

用途可见性分层表(这张表就是要填进各型 schema 的 aiContext 标注):

层 字段 aiContext 标注 续写
generation
一致性检查
detection
规划
planning
判重
extraction
现状层 当前态(品阶/能力与限制/当前持有者) true ✓ ✓ ✓ ✓
现状层 一句话摘要 true ✓ ✓ ✓ ✓
现状层 演变概括 true ✓ ✓ ✓ ✓
现状层 前身 / 后继 true ✓ ✓ ✓ ✓
完整历史层 演变历程(全里程碑) [detection, extraction] ✗ ✓ (可选) ✓

关键就是最后一行:把「演变历程」标成 [detection, extraction]——续写(generation)自动看不到,一致性检查(detection)和判重(extraction)才看得到。填完这一行,三件事自动发生、不用再写别的代码:

  1. detect skill 会自动把「演变历程」纳入检查项(它的规则就是"凡 aiContext 含 detection 的字段,自动成为一个检查项")——一致性检查从此多一道"演变连续性/跳级穿帮"关卡。
  2. read-context 组装续写上下文时,自动把「演变历程」裁掉——写作 agent 的上下文不会被上万字历史撑爆。
  3. search --purpose generation 检索时也自动裁掉它。

一个要讲清的区别:character 现有的「成长弧线」标的是 [planning, detection],它的语义是"计划中的变化,防抢进度剧透"——防的是"未来"。而「演变历程」是"已发生的历史",它对续写不可见的原因不是防剧透(都发生过了),而是怕上万字撑爆上下文。两者都对续写关闭,但一个防未来、一个防过载,别混为一谈。也因此,关系卡的「演变轨迹」保持 true(续写可见)是合理的——俩人现在什么关系、怎么走到这一步,对续写笔触很重要,且量不大;而机甲的上万字升级史续写用不上,只需当前几级。


七、改动清单(涉及哪些文件 / schema / prompt / skill)

全部是设计稿层面的改动点,本稿不实现、不执行、不重跑种子、不提交。

文件 改什么 属
meta/schemas/item.yaml 加「演变历程」[detection,extraction]、「演变概括」true、「前身」「后继」true 四字段 schema
meta/schemas/power_system.yaml 同上 schema
meta/schemas/faction.yaml location.yaml event.yaml 同上(建议同批补,避免二次改;见拍板点) schema
meta/schemas/character.yaml 语义对齐:明确「成长弧线」=未来计划,已发生台阶归「演变历程」(是否给 character 也加演变历程见拍板点) schema
meta/schemas/character_relation.yaml 「演变轨迹」说明里"章区间"沿用真实章号(本就如此),确认 aiContext 保持 true schema
.claude/skills/parse-book/scripts/parse_upgrade.py ①APPEND_FIELDS 加「演变历程」②observe/update 提示词改为记台阶+生命周期+真实章号+原文证据、禁窗号相对指代、当前态字段保持干净 ③合并/立卡/撤销逻辑适配里程碑对象(证据绑定、去重按内容、排序按章号)④判重步接语义近邻+M3 终判(P1) prompt + 逻辑
.claude/skills/db/scripts/seed_schemas.py 不改脚本;schema YAML 改完后需重跑一次把新字段和 aiContext 灌进库(本稿不跑,实施时跑) 种子
.claude/skills/read-context/SKILL.md Layer 2 知识卡裁剪说明里,点名"演变历程完整层仅一致性检查可见、续写不给"(机制已支持,补一句说明) skill 文档
.claude/skills/detect/SKILL.md 检查项示例表补一行"演变历程 → 演变连续性/跳级穿帮"(实际自动生成,文档补例) skill 文档
新增一次性迁移脚本(如 docs/ 或 skill scripts 下) 存量卡 [窗N] → 真实章号 + 字符串条目 → 里程碑对象 + 清脏(见 6.1) 迁移

不需要改的:数据库表结构(演变历程/前身/后继都是知识卡 JSON 里的字段,不需要 DDL 建表/改表);语义判重复用现成的 example_knowledge_embedding 向量表和 embed/search skill,不新建表。


八、第二步 P1:串链 + 语义判重(细化)

8.1 串链:前身/后继

用第五节已定义的「前身」「后继」链接字段(指向同书另一张卡的卡号 + 名称),把"铁头(一代)→ 铁卫(二代)→ 枪骑士(三代)→ 影杀者(四代)→ 生物机甲(V 代)"这条链串起来。链接机制照抄现成的做法——关系卡早就用"甲方卡号/乙方卡号"指向人物卡,一样的路子。标 aiContext: true,续写要知道"这台机甲的前身是谁"。

8.2 语义判重:打开嵌入近邻 + M3 终判

在判重步,除现有的名字精确匹配/子串外,新增(就是打开 v6 已设计、暂时关着的那级):

  1. 对候选新实体算向量(走 embed skill),用 search 召回同书同型相似度 ≥ 0.60 的近邻卡(原定 0.78,2026-07-18 零落库小样实测校准:同实体改名对余弦 0.63-0.66、不同体系对 ≤0.58,0.78 永不触发语义层;依据详见 parse_upgrade.py 阈值注释)。
  2. 召回的近邻交给 M3 终判(走 parse_llm.py 的 m3_json 入口,构造"这两张卡是不是同一实体 / 是不是前身后继关系"的判断),判定三选一:同一实体(并卡)/ 前身后继(不并卡但串链)/ 无关(各自立卡)。

这样"影杀者"和"IV 代纯机械机甲·影杀者"这种改名、以及跨型指代同一条线的,都能被语义召回并正确处理。

跨型判重要收着点:item(具体某台机甲)和 power_system(一整套体系)很容易被向量拉近却其实不是一回事(如"生物机甲体系"vs 具体机甲"伊琳娅丝")。所以跨型只做"提示 + 串链候选",不自动并卡;同型才允许自动并。


九、风险与验证办法

9.1 批量抽取的连接与恢复合同(2026-07-22 补充)

升格抽取不得在模型或嵌入调用期间持有业务数据库连接。一次窗口只保留一个可恢复的中间提交点,避免把每个更新批次都变成独立恢复协议:

  1. 无连接计算:读取正文、既有卡和 revision 后立即关闭连接;完成观察、证据修复、语义判重和全部实体更新输出。此阶段失败时没有知识写入,只把窗口留成干净失败断点。
  2. 实体短写事务:先复验模型输入快照,再复验模型所见 revision,原子写入新卡、别名、留档和实体更新;新卡 INSERT 同时返回数据库实际 revision,同窗后续更新的 CAS 必须绑定该值,不能假定初始版本。把窗口置为 processing,并在同一事务记录本书受控域的完整状态摘要。进程此后崩溃,续跑必须先复验摘要,再精确撤销本窗。
  3. 无连接关系计算:实体阶段提交后重新读取人物与关系快照,关闭连接,再生成或重整关系。首次同 pair 冲突只调用一次模型 repair;repair 仍按同 pair 拆条时,只允许机械合并关系类型、本窗演变和无字段冲突的其他维度,非空未知顶层键或同字段异值继续失败关闭,不调用第三次模型。卡片已更新后的状态仍能进入关系判断,但模型调用期间没有长事务。
  4. 关系短写事务:复验 processing 摘要、输入快照、人物 revision 和关系集合,写关系与剩余出场章;窗口仍保持 processing,原子刷新状态摘要。
  5. 严格嵌入与完成事务:在无业务数据库连接状态下计算本窗 touched 卡向量,再用短事务复验摘要和向量 owner 后落库;只有嵌入成功且摘要再次一致,窗口才置 done。普通嵌入失败也按窗口失败处理,不允许后窗在缺向量状态下继续语义判重。
flowchart LR
    R[短读: 正文/卡/revision] --> C1[无连接: 观察/证据/判重/实体更新]
    C1 --> W1[短写: 实体阶段<br/>processing + 完整摘要]
    W1 --> R2[短读: 更新后人物/关系]
    R2 --> C2[无连接: 关系生成/重整]
    C2 --> W2[短写: 复验摘要<br/>关系/出场章/刷新摘要]
    W2 --> E[无连接: 计算增量向量]
    E --> W3[短写: 复验摘要/owner<br/>落向量/done]
    E -->|失败或 owner 冲突| X[锁内复验完整摘要<br/>通过才撤销]

恢复与并发纪律:

  • 普通错误只允许同窗完整撤销后重试一次;第二次仍失败立即停止当前作品,保留断点,不跳窗、不换作品内顺序。
  • processing marker 固定为 upgrade-fence:v1:<stage>:<inputSha256>:<stateSha256>;stage 只允许 entity 或 relation。非法、缺失或版本不认识的 marker 一律写 durable 断点并停止,不能猜测恢复。
  • inputSha256 绑定实际送模输入:作品标题、窗口边界、每章 id/title/status/revision、每个 block 的 id/order/type/revision/content_text,以及实体 schema active version/字段合同、抽取合同和当前 parse_upgrade.py SHA-256。按章拼接正文的规则必须与送模文本一致;实体阶段写入前与关系阶段写入前都要重算,章域不完整、无 block 或拼接正文为空直接失败关闭。
  • stateSha256 覆盖本书卡、别名、留档、水位、审计、向量和全部窗口不变元数据;窗口自身可变的状态/错误文本不参与自引用 hash。processing 恢复和失败补偿都要在固定顺序的七域锁内复验它。
  • 任何外部确认、改版、删除或辅助域漂移都写 compensation-failed 并停止,禁止覆盖外部状态。嵌入落库与 done 在同一最终短事务完成,消除 done 已提交但向量尚未落库的崩溃缝隙。
  • 普通无 marker clean 的产物检查只豁免完整满足墓碑条件且 updater 为 upgrade-reset 或 upgrade-undo 的 alias/new_card/embedding;presence、card_state、audit 仍有行即阻断。该上下文用于识别 undo_window 合法留下的新卡墓碑,不得放宽 status、entity owner 或其他 updater。
  • 当前数据库没有所有写方共同遵守的 work 级互斥键。为保证摘要无幻读,七个受控域使用只跨短写事务的固定表锁;它会短暂串行化不同作品的写阶段,但绝不跨模型或嵌入计算。待真实耗时证明成为瓶颈后,再单独设计全系统统一的 work 级写锁,不能在本次修复里用弱锁换假安全。
  • fence 引入前的 legacy failed 窗不能自动猜测。recover-legacy-failed 是唯一恢复入口:preview 输出窗口、七域本窗产物计数与确认 hash;execute 必须取得同书锁、精确匹配 hash、确认无 processing 窗且阻断产物计数为 0,才可标成 retryable-clean。计数只豁免能机械证明来源的全书 reset 墓碑:draft 必须同时 deleted=true、updater='upgrade-reset'、status='pending';embedding 还必须 entity_id IS NULL 且自身 deleted=true;alias 必须 deleted=true 且 updater='upgrade-reset'。upgrade-undo 只属于普通 clean,在 legacy 上仍必须阻断,两种上下文不得混用。presence 没有 reset 来源标记,任何本窗行(包括软删墓碑)都阻断;其他软删、活跃行、已有 entity owner,以及任何 card_state/audit 行也都阻断。完整 stateSha 仍覆盖所有 deleted 行,不能混淆。操作人仍须先确认旧进程与数据库 backend 已结束,工具不得把“查不到已提交行”误当成“旧事务不存在”。
  • 显式 --redo-window 需要把 redo 前完整快照持久化到进程外,单靠内存快照无法承受崩溃。该持久快照协议另立设计前,命令机械拒绝;历史修正走已有全书 backup/reset/rebuild,不提供不完整的 redo。

风险

  1. 条目从字符串变对象,合并逻辑改动面不小。parse_upgrade.py 现有一大套针对字符串条目的守卫(剥前缀、剥尾残、拦垃圾、拆粘连、窗序归位),全要跟着改造成处理里程碑对象;存量卡还是字符串,迁移要兼容。→ 缓解:分两步落,先补字段和提示词(新卡受益),再做存量迁移;对象结构压到三字段降低崩坏面。
  2. 模型可能漏证据或给出错章证据。→ 缓解:卡体仍保持三字段;模型输出临时附证据,缺失时只对当前窗候选发一次有界证据修复调用;最终仍无法由所标章节原文证明的条目拒收并留审计。完整性不能优先于章号真实性。
  3. 语义判重增加调用量和跨型误并风险。→ 缓解:0.60 阈值(实测校准) + 同型才自动并 + 跨型仅提示;判重近邻可像 v6 说的那样批量做、不逐条烧。
  4. 存量迁移精度损失:无内嵌章号的条目只能靠窗映射到 12 章宽区间。→ 接受为存量固有局限,新卡不受影响。
  5. 改 schema 后必须重跑种子,否则库里字段合同和 YAML 不一致,抽取会按旧合同把新字段裁掉。→ 实施清单里钉死"改 YAML 后重跑 seed_schemas.py"这一步。
  6. 受控域表锁会压缩多作品写入并发。→ 模型调用仍可并行,表锁只覆盖短写和摘要复验;实施后记录阶段耗时与锁等待,若写阶段成为瓶颈,再以统一 work 级锁替换,禁止局部脚本自创弱互斥。

验证办法(实施后怎么确认真治好了)

  • 成长线立得住:挑病例"生物机甲"这条线(work_id=8)跑改造后的抽取,看能不能维护出"4 级登场 → V 代 → 300% 高光 → 结局对决"这条按章号排序、带生命周期的清晰台阶,以及"铁头 →…→ 生物机甲"的前身后继链。
  • 分层裁剪真生效:search --purpose generation 查一张机甲卡,确认「演变历程」被裁掉、只回现状层;--purpose detection 确认「演变历程」保留。
  • 一致性检查自动加项:对一章跑 detect,确认检查清单里自动多了"演变连续性"这一项。
  • 语义判重召回:造一个改名样例(影杀者 / IV 代纯机械机甲·影杀者),确认语义判重能召回并由 M3 判为同一实体或前身后继。
  • 章号无窗号残留:迁移后全库扫一遍,确认演变类字段里不再有 [窗N] 前缀。
  • 章号证据真绑定:用跨章窗口重抽验证,错标章节的里程碑必须拒收;正确章节原文短引通过后,正式卡只保留章 / 台阶 / 周期,不残留证据字段。
  • 连接红线:离线门禁覆盖观察、证据修复、判重、实体更新、关系生成/重整和嵌入;每次外部调用时业务数据库连接数必须为零。
  • 真实数据库恢复冒烟:在回滚事务内验证公共 example_upgrade_window 完整行的 processing marker 写入、复验和回滚;同事务把一张 upgrade_book draft 的 revision 加一,确认 marker 复验明确拒绝,最后用新连接确认窗口完整行和 draft revision 均未改变。不满足 pending 窗或无可用 draft 时明确失败。纯 fake 连接测试不能替代这项。

十、需要创始人拍板的点

✅ 已拍板(2026-07-17,创始人 4 项 + 主代理定 #4)——实现以此为准,下方原始理由留档:

  1. 里程碑卡体格式 = 结构化对象(章 / 台阶 / 周期);抽取传输临时增加原文证据,机械核验后删除。无法证明所标章号的条目拒收并留审计,不做猜测性降级。
  2. 补齐范围 = 五型全补:item / power_system / faction / location / event。
  3. character = 一起改:给人物也加「演变历程」、「成长弧线」回归"未来计划"本义,连带迁移 200+ 张存量人物卡。
  4. 演变概括 = 独立字段(主代理定:摘要管当前态、概括管轨迹,职责清晰)。
  5. 存量迁移 = 人工精确化:不接受 12 章宽近似——无内嵌章号的老条目靠再抽原文 / 人工核对精确到真实章号。
  1. 里程碑用"结构化对象"还是"带章号前缀的字符串"? 本稿推荐三字段对象(章/台阶/周期,可 SQL 按章排序、结构清晰),备选字符串前缀 [第420章·高光] …(改动最小、迁移最平滑)。取舍是"规整可查询"对上"改动小、模型稳"。
  2. 演变字段是否给全部实体型补齐? 核心必补 item/power_system。faction/location/event 建议同批补(组织兴衰、地点易主、事件推进同样用得上),避免将来二次改 schema。请拍板范围。
  3. character 型怎么处理? 现在它把"已发生历程"记在名为「成长弧线(未来计划)」的字段里,语义拧巴。是否给 character 也加「演变历程」、让「成长弧线」回归"未来计划"本义?这会牵动 200+ 张存量 character 卡的迁移,请拍板做还是暂缓。
  4. 「演变概括」是独立字段还是并进「一句话摘要」? 本稿推荐独立字段(摘要管当前态、概括管轨迹,职责清晰);也可并进摘要写法要求省一个字段(更省、但摘要职责变重)。
  5. 存量迁移的精度损失可接受吗? 无内嵌章号的老条目只能定位到 12 章宽区间。确认接受,还是要投入人工/再抽一遍把这批精确化。