dsh-novel-write-engine 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1
4
+
5
+ - `novel_brief` 现在把 `fields` 一并返回,P4 可直接读取 `score_exclusions` 与 `next_tool`;非当前活跃章的 brief 请求被拒绝。
6
+ - `next.tool` 现在按当前阶段与 brief 的真实 digest 计算:任何阶段 brief 缺失或过期都先返回 `novel_brief`;P5/P6 有阻塞且 brief 当前后返回 `novel_revise`;`ready_to_archive` 在 P8 brief 当前后返回 `novel_archive`,不再形成 brief/read 死循环。
7
+ - brief digest 纳入 `min_score`,并改为在写锁内计算;配置或上下文变化后旧 brief 立即失效。
8
+ - P6 四个语义项必须使用四条不同、至少 8 字、来自不同句子且互不重叠的正文引用;同一句的滑动子串不再通过。
9
+ - PG-09 的开头/中间/结尾边界改用正文实际段落号;middle 必须来自正文内部,提交的 `paragraph` 只保留 ±1 定位提示。
10
+ - 新埋设伏笔的 summary title 与最终 title 都必须出现在正文;新地点/能力/物品必须在正文与 summary 同时出现;未知 world kind 与 detail 覆盖保留字段被拒绝。
11
+ - `novel_status` 增加 `active_chapter`;`novel_state` 的 `review`/`check` 支持按历史章读取。
12
+ - `engines.dsh` 收紧为 `>=0.2.1-rc.2 <0.3.0-0`,不再放行 `0.3.0` 预发布。
13
+ - 非法 YAML(状态文档、章节/世界 plan、注册表)统一转为 `ENGINE_SCHEMA_INVALID`;损坏的 plan 会在 brief 中报告并可由 `novel_plan_chapter` 覆盖修复。
14
+ - 同 pid 的陈旧锁只在 nonce 仍由本进程持有时视为活锁;释放失败、pid 复用与容器 PID 1 不再造成永久写锁;锁回收改为 hard-link 比较,避免三进程窗口误删活锁。
15
+ - `..foo` 合法路径不再误判逃逸;重复 staging path 在写盘前拒绝;已提交事务遗留的 staging 会被安全清理。
16
+ - `next_seq` 落后于台账、重复 ID、resolved 伏笔再次 advance/resolve、planted key 撞已有 ID 都会拒绝,不再产生重复 ID 或复活已解决线索。
17
+ - `PG-11` 按 `review` / `revise` / `check` 各自计数;review 预算耗尽不再误伤同一章的 check;耗尽时 `next` 指向 `novel_rollback`,status/panel 显示 PG-11。
18
+ - `PG-05` 的 `opening` 增加 12 字下限;互斥扣分对 `第 01 段` 与 `第 1 段` 使用同一 canonical key。
19
+ - `PG-10` 不再被换行拆短的重复段落绕过;`PG-07` 在归档边界重新应用互斥扣分。
20
+ - 归档边界重新校验阅读证明;缺少 `archive_digest` 的手写章节索引不再走幂等重放;review 内容摘要写入 pipeline,手工改写 review 后归档会被拒绝。
21
+ - 读操作的 `chapter` 参数统一校验;主动 draft 可按章导出;注册表命令缺少 root 时返回 `ENGINE_SCHEMA_INVALID`。
22
+ - `novel_status` 显示轮次;工具错误保留 `blocking` 数组的 code/detail/hint;根目录省略时的解析顺序在工具描述与 README 中如实说明。
23
+ - `EngineService.dispose()` 由 `apply()` 的 `ctx.effect` 托管,卸载幂等。
24
+
3
25
  ## 0.1.0
4
26
 
5
27
  - 新增 `EngineService` 单一写入口:22 个操作、revision、幂等重放、`KeyedMutex` + 文件锁。
package/README.md CHANGED
@@ -4,9 +4,9 @@
4
4
 
5
5
  它不是一个提示词合集,也不是独立的写作软件。它把「这一章处于什么阶段、下一步只能做什么、正文是否达标、归档要核销哪些实体」变成可执行、可回滚、可审计的引擎;模型负责写,引擎负责裁决和记账。
6
6
 
7
- > **当前版本:0.1.0** · 中文界面 · MIT
7
+ > **当前版本:0.1.1** · 中文界面 · MIT
8
8
  >
9
- > **宿主范围**:DSH `>=0.2.1-rc.2 <0.3.0`;Node `>=24.9.0`。
9
+ > **宿主范围**:DSH `>=0.2.1-rc.2 <0.3.0-0`;Node `>=24.9.0`。
10
10
 
11
11
  ---
12
12
 
@@ -70,7 +70,7 @@
70
70
  - 不是「装完就自动写完整本书」的生成器;它管流程、门禁和状态,正文仍由模型写。
71
71
  - 不是独立 CLI;必须作为 DSH 插件安装到某个 profile 才能使用。
72
72
  - 不提供云端同步、账号体系、在线书城或多人协作。
73
- - 0.1.0 只有中文界面与中文任务书,没有 `locale/`,也不读取系统语言。
73
+ - 0.1.1 只有中文界面与中文任务书,没有 `locale/`,也不读取系统语言。
74
74
 
75
75
  ---
76
76
 
@@ -96,7 +96,7 @@
96
96
  - **状态机而不是自由对话**:阶段只能按合法迁移前进;不合法操作返回 `ENGINE_STAGE_ORDER` 并告诉你当前可用操作。
97
97
  - **门控先于写盘**:写初稿、修订、归档都是先校验、后落盘;坏稿不会进入项目。
98
98
  - **评分是算术,不是感觉**:`total = 150 - Σdelta`,每个维度 `score = max - Σdelta`,不闭合就拒绝。
99
- - **阅读证明**:P4/P5 要提交三段逐字引用,P6 会重新核验这份证明;防「没读就评」。
99
+ - **阅读证明**:P4/P5 要提交三段逐字引用,P6 会重新核验这份证明;开头/结尾按实际段落判定,防「没读就评」。
100
100
  - **归档是一次事务**:P7 状态同步、P8 终审、P9 索引与交接不是三个可以半途而废的步骤。
101
101
  - **模型不分配 ID**:只写 `key`,引擎分配 `FS-*` / `TE-*` / `RL-*` 等编号并回执映射。
102
102
  - **可控修订**:`novel_amend` 是唯一的状态手工修改入口,必须带原因并写入 journal;`novel_rollback` 保留正文供参考。
@@ -129,7 +129,7 @@ P7/P8/P9 在 `novel_archive` 一次事务里完成。单章归档后状态是 `d
129
129
  | PG-06 | `SCENE_TYPE` | 场景类型合法,节奏约束满足 |
130
130
  | PG-07 | `SCORE` | 十五维齐全、算术闭合、总分达到 `minScore` |
131
131
  | PG-08 | `ISSUES_CLEARED` | 所有 blocker issue 已修复并带正文证据 |
132
- | PG-09 | `READING_PROOF` | 三段逐字引用能在正文对应位置找到 |
132
+ | PG-09 | `READING_PROOF` | 三段逐字引用能在正文对应位置找到;开头/结尾按实际段落判定 |
133
133
  | PG-10 | `CONSISTENCY` | 伏笔、时间线、资源、关系、重复段落等跨章对账 |
134
134
  | PG-11 | `ROUNDS` | 评审/修订、校验/修订均不超过 3 轮 |
135
135
  | PG-12 | `ARCHIVE_ATOMIC` | 归档事务三端一致且读回验证通过 |
@@ -159,19 +159,19 @@ P7/P8/P9 在 `novel_archive` 一次事务里完成。单章归档后状态是 `d
159
159
 
160
160
  | 项目 | 要求 |
161
161
  |---|---|
162
- | DSH | `>=0.2.1-rc.2 <0.3.0`;由 `package.json` 的 `engines.dsh` 声明,安装与启动都会检查 |
162
+ | DSH | `>=0.2.1-rc.2 <0.3.0-0`;由 `package.json` 的 `engines.dsh` 声明,安装与启动都会检查 |
163
163
  | Node.js | `>=24.9.0` |
164
164
  | pnpm | CLI 安装/卸载插件需要;建议 11.x(本仓库开发基线为 11.28.9) |
165
165
  | 宿主形态 | Web(面板 + 预设)、Desktop(面板 + 预设,插件由桌面壳管理)、headless(只有工具/命令,无面板/预设) |
166
166
  | 磁盘 | 项目根目录可写;默认 `stateDir` 可写 |
167
167
  | 网络 | 安装时需要访问 npm / Git 托管;运行插件本身不联网 |
168
- | 语言 | 0.1.0 仅中文 |
168
+ | 语言 | 0.1.1 仅中文 |
169
169
 
170
170
  检查命令:
171
171
 
172
172
  ```bash
173
173
  node --version # 应 >= 24.9.0
174
- dsh --version # 应 >= 0.2.1-rc.2,且 < 0.3.0
174
+ dsh --version # 应 >= 0.2.1-rc.2,且 < 0.3.0-0
175
175
  pnpm --version # CLI 安装插件时需要
176
176
  ```
177
177
 
@@ -269,7 +269,7 @@ dsh plugin --profile web add dsh-novel-write-engine
269
269
  固定版本:
270
270
 
271
271
  ```bash
272
- dsh plugin --profile web add dsh-novel-write-engine@0.1.0
272
+ dsh plugin --profile web add dsh-novel-write-engine@0.1.1
273
273
  ```
274
274
 
275
275
  `dsh` 不在 PATH 时,用 `npx @deepseek-ai/dsh` 代替命令开头的 `dsh`。
@@ -324,13 +324,13 @@ corepack pnpm pack
324
324
  会得到类似:
325
325
 
326
326
  ```text
327
- dsh-novel-write-engine-0.1.0.tgz
327
+ dsh-novel-write-engine-0.1.1.tgz
328
328
  ```
329
329
 
330
330
  把这个 tarball 复制到目标机器,放在一个**稳定、不会随手删除**的路径,然后:
331
331
 
332
332
  ```bash
333
- dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.1.0.tgz
333
+ dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.1.1.tgz
334
334
  ```
335
335
 
336
336
  tarball 安装不会运行源码构建,也不会要求 `allowBuilds`;包内已经包含 `lib/`、`rulepacks/`、`briefs/`、`skills/`、`presets/` 和两层 patch。它是最接近「发布产物」的安装方式。
@@ -345,9 +345,9 @@ tarball 安装不会运行源码构建,也不会要求 `allowBuilds`;包内
345
345
  2. 点 **添加插件**(或旁边的箭头 → **安装第三方插件**)。
346
346
  3. 在包名字段填入以下任一形式:
347
347
  - npm 包名:`dsh-novel-write-engine`
348
- - 精确版本:`dsh-novel-write-engine@0.1.0`
348
+ - 精确版本:`dsh-novel-write-engine@0.1.1`
349
349
  - 源码目录:`/absolute/path/to/dsh-novel-write-engine`
350
- - tarball:`/absolute/path/to/dsh-novel-write-engine-0.1.0.tgz`
350
+ - tarball:`/absolute/path/to/dsh-novel-write-engine-0.1.1.tgz`
351
351
  4. npm 包名从 npm 官方源安装;本地目录和 tarball 直接使用宿主路径。
352
352
  5. 点 **安装**,等待完成。
353
353
  6. 如果出现 **立即启用**,点它;否则安装后到「已安装插件」里把 **dsh-novel-write-engine** 打开。
@@ -438,7 +438,7 @@ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
438
438
  }
439
439
  ```
440
440
 
441
- `genre` 必须是 12 类之一,`platform` 必须是 `fanqie` / `qidian` / `qimao` / `jinjiang` 之一。`project_root` 省略时使用配置里的 `projectRoot`(默认 `./novel`,相对于 DSH 进程工作目录)。
441
+ `genre` 必须是 12 类之一,`platform` 必须是 `fanqie` / `qidian` / `qimao` / `jinjiang` 之一。`project_root` 省略时按「最近活跃项目 → 注册表 active → 配置里的 `projectRoot`(默认 `./novel`,相对于 DSH 进程工作目录)」解析;有多个项目时请显式传 `project_root`,避免写错书。
442
442
 
443
443
  ### 4. 一章的标准调用顺序
444
444
 
@@ -460,10 +460,11 @@ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
460
460
 
461
461
  关键点:
462
462
 
463
- - **每一步提交前都要先领任务书**,PG-01 会检查 digest。
464
- - `novel_review` 的 `total` 是必填的,必须等于 `150 - Σdelta`;三段阅读证明必须逐字来自正文。
465
- - `novel_check` 的 `semantic` 恰好四个语义项,每项带正文证据。
466
- - `novel_archive` 的 `state_delta` 要逐实体核销角色、伏笔、时间线、世界、关系;`no_change` 也要写原因。
463
+ - **每一步提交前都要先领任务书**,PG-01 会检查 digest。`novel_status` / `novel_pipeline` 在任务书缺失或过期时会先返回 `novel_brief`,不会让你直接撞 PG-01。
464
+ - `ready_to_archive` 在 P8 任务书当前后,`next.tool` 才返回 `novel_archive`;P5/P6 有阻塞时返回 `novel_revise`。
465
+ - `novel_review` 的 `total` 是必填的,必须等于 `150 - Σdelta`;三段阅读证明必须逐字来自正文,开头/结尾按**实际段落**判定。
466
+ - `novel_check` 的 `semantic` 恰好四个语义项,每项带至少 8 字、四条互不相同的正文引用。
467
+ - `novel_archive` 的 `state_delta` 要逐实体核销角色、伏笔、时间线、世界、关系;新伏笔标题必须出现在正文,`no_change` 也要写原因。
467
468
  - 正文改动后,旧的评审分数和 check 会失效;不要试图手工改 `state/` 绕过。
468
469
 
469
470
  ### 5. 看面板
@@ -499,8 +500,8 @@ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
499
500
  | 工具 | 阶段 | 做什么 | 写盘 |
500
501
  |---|---|---|---|
501
502
  | `novel_init` | — | 建项目:`novel.yaml` + `state/` + 目录 | 是 |
502
- | `novel_status` | 任意 | 当前章、阶段、轮次、阻塞项、下一步 | 否 |
503
- | `novel_brief` | P1–P6 / P8 | 领取阶段任务书,记录 digest | 仅任务书签收 |
503
+ | `novel_status` | 任意 | 当前活跃章、阶段、轮次、阻塞项、下一步;`chapter` 只用于字数查询 | 否 |
504
+ | `novel_brief` | P1–P6 / P8 | 领取当前活跃章的任务书,返回 `fields` 并记录 digest | 仅任务书签收 |
504
505
  | `novel_plan_world` | P1 | 提交世界观约束 | 是 |
505
506
  | `novel_plan_chapter` | P2 | 提交章节计划 | 是 |
506
507
  | `novel_write_draft` | P3 | 提交初稿;格式/字数/摘要不过整体拒绝 | 是 |
@@ -509,7 +510,7 @@ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
509
510
  | `novel_check` | P6 | 机检 + 四个语义一致性项 | 是 |
510
511
  | `novel_archive` | P7–P9 | 事务归档;必须带 `state_delta` | 事务 |
511
512
  | `novel_word_count` | 任意 | 按引擎唯一口径数字数 | 否 |
512
- | `novel_state` | 任意 | 读账本、计划、评审、检查、handoff | 否 |
513
+ | `novel_state` | 任意 | 读账本、计划、评审、检查、handoff;`review`/`check` 可按历史章读取 | 否 |
513
514
  | `novel_amend` | 任意 | 带原因修订一个状态文档 | 是,入 journal |
514
515
  | `novel_rollback` | 任意 | 回退到 P1–P6,保留正文供参考 | 是 |
515
516
  | `novel_diff` | 任意 | 与上次归档备份或两段文本比较 | 否 |
@@ -525,9 +526,9 @@ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
525
526
 
526
527
  三类错误:
527
528
 
528
- - **改参数**:`ENGINE_INPUT_INVALID`、`ENGINE_STAGE_ORDER`、`ENGINE_PROJECT_NOT_FOUND`;
529
- - **改正文**:`ENGINE_GATE_BLOCKED`、`ENGINE_SCORE_MISMATCH`、`ENGINE_READING_PROOF_INVALID`;
530
- - **查环境**:IO、schema 过新、锁超时、事务中止。
529
+ - **改参数**:`ENGINE_SCHEMA_INVALID`、`ENGINE_STAGE_ORDER`、`ENGINE_PROJECT_NOT_FOUND`、`ENGINE_PROJECT_EXISTS`;
530
+ - **改正文**:`ENGINE_GATE_BLOCKED`、`ENGINE_SCORE_MISMATCH`、`ENGINE_READING_PROOF_INVALID`、`ENGINE_DELTA_UNVERIFIED`;
531
+ - **查环境**:`ENGINE_SCHEMA_TOO_NEW`、`ENGINE_PATH_ESCAPE`、`ENGINE_LOCK_TIMEOUT`、`ENGINE_TXN_ABORTED`、`ENGINE_RULEPACK_INVALID`。
531
532
 
532
533
  ### 8.3 五条命令
533
534
 
@@ -727,7 +728,7 @@ P8.md
727
728
 
728
729
  ### 9.4 规则包不能运行期切换
729
730
 
730
- `rulepacks/default.yaml` 是随包加载的:词表、格式、标点、语义、跨章阈值、平台默认值都在里面。0.1.0 **不接受**运行期外部规则包路径。
731
+ `rulepacks/default.yaml` 是随包加载的:词表、格式、标点、语义、跨章阈值、平台默认值都在里面。0.1.1 **不接受**运行期外部规则包路径。
731
732
 
732
733
  要改规则,只有两条路:
733
734
 
@@ -827,7 +828,7 @@ dsh plugin --profile web add dsh-novel-write-engine@latest
827
828
  也可以固定版本:
828
829
 
829
830
  ```bash
830
- dsh plugin --profile web add dsh-novel-write-engine@0.1.0
831
+ dsh plugin --profile web add dsh-novel-write-engine@0.1.1
831
832
  ```
832
833
 
833
834
  升级后核对:
@@ -1049,7 +1050,7 @@ DSH bundle 的 Host 半边在 DSH 进程内执行,不受工作区沙箱限制
1049
1050
 
1050
1051
  ## 十五、已知限制
1051
1052
 
1052
- - **0.1.0 只有中文**:面板、命令、错误、任务书都是中文;没有 `locale/`,不跟随系统语言。
1053
+ - **0.1.1 只有中文**:面板、命令、错误、任务书都是中文;没有 `locale/`,不跟随系统语言。
1053
1054
  - **通过 npm 分发**:安装与升级统一使用 `dsh plugin add`;源码目录和 tarball 用于开发或离线环境。
1054
1055
  - **面板与预设只在 Web/Desktop**:headless / acp / sdk 没有 `agentPresets` 服务,也没有浏览器面板;18 个工具仍可用。
1055
1056
  - **规则包不可运行期替换**:要改词表/阈值,必须改源码、重新构建、重新安装。
@@ -1085,6 +1086,7 @@ corepack pnpm check:artifacts # 真正 import 构建后的 host / client
1085
1086
  corepack pnpm check:hygiene # v8 ignore 预算 + 假断言扫描
1086
1087
  corepack pnpm check:pack # 需先 build;检查 tarball 内容
1087
1088
  corepack pnpm check:install # 需先 build;空项目安装并加载
1089
+ corepack pnpm check:host # 需本机 dsh;真实 Web 宿主安装/面板/卸载
1088
1090
  ```
1089
1091
 
1090
1092
  预设层需要真实 DSH checkout:
@@ -1095,6 +1097,8 @@ DSH_BUNDLE_ROOT=/path/to/deepseek-harness/packages/bundle/web-app corepack pnpm
1095
1097
 
1096
1098
  `check:preset` 不伪造 bundle root;没有宿主 checkout 时它不会假装通过。
1097
1099
 
1100
+ `check:host` 使用临时 `DSH_HOME` 与临时 profile:`npm pack → dsh plugin add → --dump-config → 启动 Web → 面板 401/200 → 卸载 → 确认层消失`。它需要 PATH 里有 `dsh`(或设置 `DSH_BIN`),不会碰你的真实 profile;没有 DSH 时以退出码 2 明确失败,不伪造通过。
1101
+
1098
1102
  ### 16.3 发布前手动验证
1099
1103
 
1100
1104
  1. `corepack pnpm build && corepack pnpm pack`;
@@ -1105,6 +1109,8 @@ DSH_BUNDLE_ROOT=/path/to/deepseek-harness/packages/bundle/web-app corepack pnpm
1105
1109
  6. `dsh plugin remove`,确认层与面板消失;
1106
1110
  7. 确认项目数据未被卸载动作删除。
1107
1111
 
1112
+ `pnpm check:host` 覆盖第 1–4 与第 6 步的自动断言;第 5 步仍是人工全流程(需要可用模型)。
1113
+
1108
1114
  ### 16.4 项目结构
1109
1115
 
1110
1116
  ```text
@@ -1127,12 +1133,12 @@ tests/ # 单测、集成、falsify、e2e
1127
1133
 
1128
1134
  ### 16.5 当前验证基线
1129
1135
 
1130
- 0.1.0 在 Node 24.19 / DSH 0.2.1-rc.3 上完成过:
1136
+ 0.1.1 在 Node 24.19 / DSH 0.2.1-rc.3 上完成过:
1131
1137
 
1132
- - `corepack pnpm test` 全绿(当前树 315 项);
1138
+ - `corepack pnpm test` 全绿(当前树 348 项);
1133
1139
  - 覆盖率语句/分支/函数/行均达到门槛;
1134
1140
  - `typecheck`、`lint`、`check:hygiene`、`test:isolated`、`build`、`validate:rulepack`、`check:pack`、`check:artifacts`、`check:install` 全绿;
1135
- - 本地 tarball 安装、`--dump-config` 层出现、`remove` 后层消失均已实测。
1141
+ - `check:host` 在临时 DSH profile 中实测:插件层出现、预设可见、面板未认证 401、认证后 200、`remove` 后层消失。
1136
1142
 
1137
1143
  具体数字会随代码变化;发布前请以重新跑出的结果为准,不要把上面的历史数字当保证。
1138
1144
 
@@ -1143,7 +1149,8 @@ tests/ # 单测、集成、falsify、e2e
1143
1149
  | 文档 | 内容 |
1144
1150
  |---|---|
1145
1151
  | [DESIGN.md](DESIGN.md) | 完整设计书:架构、数据模型、规则、门控、事务、面板、预设 |
1146
- | [PLAN.md](PLAN.md) | 0.1.0 实施计划、切片、覆盖率门禁、验收 |
1152
+ | [PLAN.md](PLAN.md) | 0.1.0 实施计划(历史) |
1153
+ | [docs/0.1.1-plan.md](docs/0.1.1-plan.md) | 0.1.1 契约收口与证据加固方案 |
1147
1154
  | [docs/tools.md](docs/tools.md) | 18 个工具与命令面速查 |
1148
1155
  | [docs/states.md](docs/states.md) | 状态机、迁移表、轮次与回退 |
1149
1156
  | [docs/rulepack.md](docs/rulepack.md) | 规则包结构、编译器断言、改词表流程 |
package/briefs/P4.md CHANGED
@@ -12,7 +12,7 @@
12
12
  | `middle` | 正文中部的一处,≥12 字 |
13
13
  | `ending` | 最后两段里的一处,≥12 字 |
14
14
 
15
- 引用必须**逐字**来自正文,且段落号误差不超过 1。伪造会被 `ENGINE_READING_PROOF_INVALID` 打回。
15
+ 引用必须**逐字**来自正文。`paragraph` 允许 ±1 段定位误差,但开头/结尾边界按引文的**实际段落**判定;把中段引用写成 `paragraph: 2` 不会变成开头引用。伪造会被 `ENGINE_READING_PROOF_INVALID` 打回。
16
16
 
17
17
  ## 十五维评分(满分 150)
18
18
 
package/briefs/P5.md CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  - `content`:修订后的完整正文(不是 diff)。
17
17
  - `summary`:如果事件、伏笔、资源有变化,同步更新;没变化可省略。**如果改动前两段/opening,必须同时提交新的 summary**,否则引擎会拒绝。
18
- - `proof`:修订后正文的三个逐字引用(opening/middle/ending),每段至少 12 字;PG-09 会逐条回查,不能改写或编造。
18
+ - `proof`:修订后正文的三个逐字引用(opening/middle/ending),每段至少 12 字;PG-09 会逐条回查,开头/结尾按实际段落判定,不能改写、编造或靠提交段落号挪动边界。
19
19
 
20
20
  ## 常见返工原因
21
21
 
package/briefs/P6.md CHANGED
@@ -20,7 +20,7 @@
20
20
  ]
21
21
  ```
22
22
 
23
- 四个 id 必须各出现一次;`verdict` 只能是 `pass`/`fail`;`evidence` 至少 4 字且必须逐字出现在正文里。
23
+ 四个 id 必须各出现一次;`verdict` 只能是 `pass`/`fail`;`evidence` 至少 8 字、必须逐字出现在正文里,且四条引用必须互不相同。四项引用同一句话不算四份证据,会被 `SEMANTIC_EVIDENCE_INVALID` 拒绝。
24
24
 
25
25
  | id | 检查 |
26
26
  |---|---|
@@ -33,7 +33,7 @@
33
33
 
34
34
  ## 判定
35
35
 
36
- - 任一项 `fail` → 校验不过,调用 `novel_revise` 修订并回到 P4 重评(轮次 +1)。
36
+ - 任一项 `fail` → 校验不过,先重新领取 `novel_brief P6`(check 已改变上下文,旧 digest 会失效),再调用 `novel_revise` 修订并回到 P4 重评(轮次 +1)。
37
37
  - 全过 → 管线进入 `ready_to_archive`,先 `novel_brief P8` 领取终审任务书,再调用 `novel_archive`。
38
38
 
39
39
  ## 不许做的
package/lib/index.d.ts CHANGED
@@ -333,6 +333,8 @@ interface PipelineState {
333
333
  digest: string;
334
334
  }>;
335
335
  blocking: BlockingItem[];
336
+ /** Hash of the review document last written by submitReview/submitRevision. */
337
+ review_digest?: string;
336
338
  last_action: {
337
339
  op: string;
338
340
  at: string;
@@ -599,7 +601,10 @@ interface StatusReport {
599
601
  platform: Platform;
600
602
  root: string;
601
603
  };
604
+ /** The chapter requested for metrics; may be historical. */
602
605
  chapter: number;
606
+ /** The chapter the pipeline is currently working on. */
607
+ active_chapter: number;
603
608
  stage: Stage;
604
609
  rounds: RoundCounters;
605
610
  blocking: BlockingItem[];
@@ -929,8 +934,6 @@ declare function phaseStrip(stage: Stage, finished?: boolean): Array<{
929
934
  }>;
930
935
  /** Project a chapter row for the table; a reviewed chapter without blockers reads as passed. */
931
936
  declare function projectChapter(record: ChapterRecord): PanelChapterRow;
932
- /** Status report used by the tool and by commands; one function, three callers. */
933
- declare function projectStatus(snapshot: PanelSnapshot, next: StatusReport['next']): StatusReport;
934
937
  declare function projectSummary(snapshot: PanelSnapshot): PanelSummaryDto;
935
938
  declare function projectChapters(snapshot: PanelSnapshot): PanelChaptersDto;
936
939
  declare function projectGates(snapshot: PanelSnapshot): PanelGatesDto;
@@ -1098,6 +1101,13 @@ declare class EngineService {
1098
1101
  /** Compiled on first use so `apply()` performs no IO. */
1099
1102
  private readonly rulepackSource;
1100
1103
  private compiled;
1104
+ private disposed;
1105
+ /**
1106
+ * Release in-process caches on host teardown. The engine owns no file
1107
+ * handles, so this is deliberately synchronous and idempotent; it prevents a
1108
+ * disposed instance from keeping project stores and replay results alive.
1109
+ */
1110
+ dispose(): void;
1101
1111
  private get rulepack();
1102
1112
  private readonly onEvent;
1103
1113
  private readonly signalContext;
@@ -1266,6 +1276,14 @@ declare class EngineService {
1266
1276
  }>>;
1267
1277
  private panelSnapshot;
1268
1278
  private nextStep;
1279
+ /** A computed blocker for the retry budget the next operation would consume. */
1280
+ private roundsLimitBlock;
1281
+ /** Pipeline blockers plus budget exhaustion, so status/panel cannot say "all clear". */
1282
+ private effectiveBlocking;
1283
+ /** Whether the stored brief still signs the current snapshot. */
1284
+ private briefIsCurrent;
1285
+ /** Arguments valid for the tool `STAGE_NEXT` recommends at this stage. */
1286
+ private nextArgs;
1269
1287
  private metricsFor;
1270
1288
  private readChapter;
1271
1289
  private latestBackup;
@@ -1275,6 +1293,7 @@ declare class EngineService {
1275
1293
  private briefDigest;
1276
1294
  private briefVariables;
1277
1295
  private assertGates;
1296
+ private assertChapterParameter;
1278
1297
  private assertChapter;
1279
1298
  private load;
1280
1299
  private mutate;
@@ -1323,4 +1342,4 @@ declare const Config: Schema<Config>;
1323
1342
  * created lazily per project root.
1324
1343
  */
1325
1344
  declare function apply(ctx: Context, config: Config): void;
1326
- export { AdviceReport, ArchiveHandoff, AuditRow, BlockingItem, BriefDocument, BriefLibrary, BriefStage, ChapterPlanInput, ChapterRecord, ChapterStatusRow, ChapterSummary, ChaptersDocument, CharacterDelta, CharactersDocument, CheckDocument, Config, Deduction, DeltaAction, DiffReport, DraftInput, ERROR_CODES, EngineBlockedError, EngineError, EngineFaultError, EngineInputError, EngineService, ErrorCode, ExportChapter, ExportKind, ForeshadowDelta, ForeshadowsDocument, GENRES, GateInput, GateOptions, GateResult, Genre, HandoffDocument, LocksDocument, MachineMetrics, NovelProject, OPERATIONS, OpResult, Operation, PLATFORMS, PanelChapterRow, PanelChaptersDto, PanelDraft, PanelGatesDto, PanelSnapshot, PanelSummaryDto, PipelineState, Platform, ReadingProof, ReadingProofReference, RelationshipDelta, RelationshipsDocument, ReviewDocument, ReviewInput, ReviewIssue, RevisionInput, RoundCounters, SCENE_TYPES, SCHEMA_VERSION, SceneType, ScoreDimension, SemanticItem, Severity, Stage, StateDelta, StatusReport, TimelineDelta, TimelineDocument, Violation, Warning, WordMetrics, WorldDelta, WorldDocument, WorldPlanInput, applicableGates, apply, blockedError, briefStageFor, chapterHeading, evaluateGates, faultError, gateName, inject, inputError, loadRulepack, name, parseParagraphLocation, phaseStrip, projectChapter, projectChapters, projectGates, projectStatus, projectSummary, renderBlurb, renderCover, renderEpubChapter, renderMarkdown, renderPlainText, verifyReference };
1345
+ export { AdviceReport, ArchiveHandoff, AuditRow, BlockingItem, BriefDocument, BriefLibrary, BriefStage, ChapterPlanInput, ChapterRecord, ChapterStatusRow, ChapterSummary, ChaptersDocument, CharacterDelta, CharactersDocument, CheckDocument, Config, Deduction, DeltaAction, DiffReport, DraftInput, ERROR_CODES, EngineBlockedError, EngineError, EngineFaultError, EngineInputError, EngineService, ErrorCode, ExportChapter, ExportKind, ForeshadowDelta, ForeshadowsDocument, GENRES, GateInput, GateOptions, GateResult, Genre, HandoffDocument, LocksDocument, MachineMetrics, NovelProject, OPERATIONS, OpResult, Operation, PLATFORMS, PanelChapterRow, PanelChaptersDto, PanelDraft, PanelGatesDto, PanelSnapshot, PanelSummaryDto, PipelineState, Platform, ReadingProof, ReadingProofReference, RelationshipDelta, RelationshipsDocument, ReviewDocument, ReviewInput, ReviewIssue, RevisionInput, RoundCounters, SCENE_TYPES, SCHEMA_VERSION, SceneType, ScoreDimension, SemanticItem, Severity, Stage, StateDelta, StatusReport, TimelineDelta, TimelineDocument, Violation, Warning, WordMetrics, WorldDelta, WorldDocument, WorldPlanInput, applicableGates, apply, blockedError, briefStageFor, chapterHeading, evaluateGates, faultError, gateName, inject, inputError, loadRulepack, name, parseParagraphLocation, phaseStrip, projectChapter, projectChapters, projectGates, projectSummary, renderBlurb, renderCover, renderEpubChapter, renderMarkdown, renderPlainText, verifyReference };