#392·inkos

章节编号双轨导致审计误判:正常章节被判 audit-failed 并级联出摘要/快照空洞

Author: pengyzCreated Sep 15, 2026Updated Sep 15, 2026

环境

  • @actalk/inkos 1.8.0,Node v24.14.0,Linux
  • inkos.json: { "language": "zh", "llm": { "service": "deepseek", "apiFormat": "responses" } }
  • 问题成因:使用导入功能导入了之前写的章节,全程studio中操作

现象

审计员反复报出一条 critical,认为"被要求审查的章节"与"实际拿到的正文"不是同一章,因此无法完成审查

[critical] 用户要求审查第6章,但提供的正文为第5章内容……第6章的核心事件“正月十九李忠识字试探、
           王德警告、史弥远指令”在正文中完全缺失。

[critical] 审查目标与提供内容不匹配:请求审查第9章,但实际提供的是第8章“恐惧之用”。

[critical] 无法审查第11章:待审章节正文实际提供为“第010章 帝师之名”,与请求审查的“第11章”编号不一致。

章节因此被判 audit-failed但正文本身没有问题——是编号口径不一致。

根因:同一本书里并存两套章节编号

chapters/index.jsonnumber 与正文首行的 # 第N章 不一致:

index.number 正文首行 关系
1 # 楔子 坠入深渊 序章,无编号
2–11 # 第001章# 第010章 正文号 = index − 1import chapters 导入的旧稿)
12–15 # 第12章# 第15章 正文号 = index(writer 生成的章节)

序章占用了 index 1,导致导入的旧稿整体错位 −1;而 writer 生成章节时直接用了 index 号。于是同一本书里两套编号并存。

审计提示词只传 index 号、不带标题@actalk/inkos-core/dist/agents/continuity.js:525):

javascript
: `请审查第${chapterNumber}章。`

审计员于是拿 index 号去比对正文首行里的另一个号,判定"审查对象不符"。

影响:会级联,不止是误报

  1. 章节被标为 audit-failed

  2. 状态结算被跳过story/state/chapter_summaries.json 缺失该章摘要;

  3. 摘要缺失使后续章节的前置状态无来源。这一点审计员自己也指出来了:

    [warning] 状态卡与伏笔池的旧值……均停留在第13章,而本次结算为第15章;若第14章确有状态或伏笔变化,则其结算被跳过,需补记(否则第15章的部分前置状态无来源)。

  4. 快照缺口随之累积,最终与 latest-only 闸门叠加形成无解死锁resync 要求"必须是最新章"、delete 要求"快照 N−1 存在",对同一章互相排斥,CLI 与 Studio 都没有入口)。

本项目实测:5 个 audit-failed 章节中 3 个是纯假失败;把编号统一(让 index.number = 文件前缀 = 正文首行编号)后重审,这 3 章全部 passed: true

复现

bash
inkos book create --title T --genre other
inkos import chapters <book> --from <含「楔子」+「第001章」起的文本>
# 观察 chapters/index.json:number 与 正文首行「# 第N章」相差 1
inkos audit <book> <n> --json
# → critical「请求审查第N章,但实际提供的是第N-1章」

建议修复(任一即可)

最小改动 —— 审计提示词带上标题,让审计员不必靠编号比对来定位章节:

javascript
: `请审查第${chapterNumber}章(${targetMeta.title})。`

更稳的做法 —— 审计前先做一次编号一致性断言。若 index.number 与正文首行编号不一致,应明确报"数据不一致,需先修复编号",而不是把它当成内容 critical 进而判 audit-failed

顺带一处数据模型不一致 —— rebuildChapterIndexFromFilesAtstate/manager.js)明确跳过 number <= 0

javascript
if (!Number.isFinite(number) || number <= 0) return [];

看起来这是为"无编号序章"预留的约定(把序章放在 chapters/0000_*.md 是合法的)。但 import chapters 路径没有遵守它——序章被导入成了 number = 1,从而把后续所有章节挤错一位。建议两条路径统一。