dsh-novel-write-engine 0.2.6 → 0.2.7

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/README.md CHANGED
@@ -1,180 +1,189 @@
1
- # dsh-novel-write-engine
1
+ <div align="center">
2
2
 
3
- 把小说创作的「状态、门禁、规则、账本」从提示词搬进代码的 DeepSeek Harness 插件。
3
+ # 网文工坊
4
4
 
5
- 它不是一个提示词合集,也不是独立的写作软件。它把「这一章处于什么阶段、下一步只能做什么、正文是否达标、归档要核销哪些实体」变成可执行、可回滚、可审计的引擎;模型负责写,引擎负责裁决和记账。
5
+ **把长篇小说连载的状态、门禁、规则和账本,从提示词搬进代码。**
6
6
 
7
- 0.2.6 把“证据、台账、书籍数据”从能跑推进到可解释:语义证据改为配对冲突并统一句边界;world 新实体支持 `name + anchors`,不再逼正文写台账名;网文工坊 v6 增加书脊/当前章/人物关系/世界/伏笔/质量节奏/逐章 effort/健康恢复;同时补上 pipeline 备份恢复、summary-only 一次性 PG-01、outline restore 卷守卫与 PG-05 null 行保护。详见 [0.2.6 方案](docs/0.2.6-plan.md)。
7
+ 一个给 DeepSeek Harness 用的确定性小说创作引擎:模型负责写,引擎负责裁决、记账和兜底。
8
8
 
9
- > **当前版本:0.2.6** · 中文界面 · MIT
9
+ [![npm version](https://img.shields.io/npm/v/dsh-novel-write-engine?style=flat-square&logo=npm&label=npm)](https://www.npmjs.com/package/dsh-novel-write-engine)
10
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-novel-write-engine?style=flat-square&logo=npm&label=downloads)](https://www.npmjs.com/package/dsh-novel-write-engine)
11
+ [![CI](https://img.shields.io/github/actions/workflow/status/ThzxxArt/dsh-novel-write-engine/ci.yml?branch=main&style=flat-square&logo=github&label=CI)](https://github.com/ThzxxArt/dsh-novel-write-engine/actions/workflows/ci.yml)
12
+ [![release](https://img.shields.io/github/v/release/ThzxxArt/dsh-novel-write-engine?style=flat-square&logo=github&label=release)](https://github.com/ThzxxArt/dsh-novel-write-engine/releases)
13
+ [![Node](https://img.shields.io/badge/Node-%3E%3D24.9.0-339933?style=flat-square&logo=node.js&logoColor=white)](#1-兼容性)
14
+ [![DSH](https://img.shields.io/badge/DSH-0.2.1--rc.2%20~%200.3-6f42c1?style=flat-square)](#1-兼容性)
15
+ [![License](https://img.shields.io/github/license/ThzxxArt/dsh-novel-write-engine?style=flat-square)](LICENSE)
16
+
17
+ [快速开始](#快速开始) · [核心机制](#核心机制) · [工具手册](#工具手册) · [配置](#配置) · [数据与安全](#数据与安全) · [故障排查](#故障排查)
18
+
19
+ </div>
20
+
21
+ > [!IMPORTANT]
22
+ > 当前版本 **0.2.7**。宿主范围:DSH `>=0.2.1-rc.2 <0.3.0-0`;Node `>=24.9.0`。
10
23
  >
11
- > **宿主范围**:DSH `>=0.2.1-rc.2 <0.3.0-0`;Node `>=24.9.0`。
24
+ > 0.2.7 是通用性与发布边界版本:没有改工具、阶段、门控、schema 或规则阈值。它把产品示例、任务书和测试夹具里的具体书稿痕迹清理干净,并补上三题材归档矩阵与发布面隐私守卫。历史版本的内部方案与验收稿留在对应发布 tag,不再复制进 `main`。
12
25
 
13
26
  ---
14
27
 
15
- ## 目录
16
-
17
- - [一、它解决什么问题](#一它解决什么问题)
18
- - [二、功能全貌](#二功能全貌)
19
- - [三、兼容性与前置条件](#三兼容性与前置条件)
20
- - [四、先装好 DSH 宿主](#四先装好-dsh-宿主)
21
- - [五、安装本插件](#五安装本插件)
22
- - [六、验证安装](#六验证安装)
23
- - [七、五分钟快速开始](#七五分钟快速开始)
24
- - [八、使用方式](#八使用方式)
25
- - [九、配置](#九配置)
26
- - [十、数据、备份与状态](#十数据备份与状态)
27
- - [十一、升级](#十一升级)
28
- - [十二、卸载](#十二卸载)
29
- - [十三、故障排查](#十三故障排查)
30
- - [十四、安全与边界](#十四安全与边界)
31
- - [十五、已知限制](#十五已知限制)
32
- - [十六、开发与验证](#十六开发与验证)
33
- - [十七、文档地图与许可](#十七文档地图与许可)
28
+ ## 30 秒判断它是否适合你
29
+
30
+ | 你想要的 | 适不适合 | 原因 |
31
+ | --- | --- | --- |
32
+ | 让模型稳定写几十到几百章的长篇连载 | **适合** | 阶段、字数、评分、轮次、台账和归档都有机器裁决 |
33
+ | 每章都要可追溯:为什么被拒、改到第几轮、归档写了什么 | **适合** | journal、history、backups、audit 都是现成的 |
34
+ | 换模型、换会话后还能接着写同一本书 | **适合** | 项目状态在磁盘,不依赖聊天上下文 |
35
+ | 只想让模型一次生成一篇短故事 | **不必** | 这套引擎是为连续章节和跨章一致性准备的 |
36
+ | 想要开箱即用的桌面写作软件、云同步、多人协作 | **不适合** | 它是 DSH 插件,本地优先,没有账号体系和云端 |
37
+ | 想完全不用 DSH、单独跑一个 CLI | **不适合** | 工具、命令、面板都挂在 DSH 宿主上 |
38
+
39
+ 一句话:**它不替你写小说,它让“写小说”这件事有状态、有规则、有账本。**
34
40
 
35
41
  ---
36
42
 
37
- ## 一、它解决什么问题
43
+ ## 它解决什么问题
38
44
 
39
- 网文连载最常见的失败,不是「模型不会写」,而是:
45
+ 长篇连载最常见的失败,不是模型不会写,而是:
40
46
 
41
47
  - 写着写着忘了这是第几章、上一章结尾是什么、哪些伏笔还没回收;
42
- - 每章的字数、格式、评分标准靠模型自己记,越写越松;
43
- - 评审只给一个「87 分」,指不出扣分在哪一段,也无法核对;
48
+ - 字数、格式、评分标准靠模型自己记,越写越松;
49
+ - 评审只给一个总分,指不出扣分在哪一段,也无法核对;
44
50
  - 归档时角色、地点、时间线、关系、伏笔只更新一半,下一章开始自相矛盾;
45
- - 多个项目、多个会话之间状态漂移,换一个会话就像换了一个人。
51
+ - 多个项目、多个会话之间状态漂移,换一个会话就像换了一个人;
52
+ - 改坏一章后没有可回退的版本,只能凭记忆重写。
46
53
 
47
- 本插件把这些东西收进一个 **单一写入口 `EngineService`**:
54
+ 网文工坊把这些东西收进一个**单一写入口 `EngineService`**:
48
55
 
49
- ```text
50
- 模型 / 用户
51
- │
52
- ├── 28 个 novel_* 工具
53
- ├── 5 条 /novel* 命令(含 outline/guide/report/doctor/search 子命令)
54
- ├── 只读侧边栏「网文工坊」
55
- └── 7 份阶段任务书(briefs)
56
- │
57
- ▼
58
- EngineService(唯一写入口)
59
- │
60
- ├── 13 条门控 PG-01 ~ PG-13
61
- ├── 15 维评分 / 满分 150
62
- ├── 规则包 rulepacks/default.yaml
63
- ├── 书级蓝图/大纲/世界观(outline/)
64
- ├── 事务化归档 + journal 审计
65
- └── chapters/ 正文 + state/ 影子账本
66
- ```
56
+ - **状态机**:当前章处于 P1 到 P9 的哪一步,下一步只能做什么;
57
+ - **门控**:13 条机器可判定的检查,失败时一次返回全部阻塞项;
58
+ - **评分**:15 维、满分 150,分数必须逐项闭合;
59
+ - **账本**:角色、世界、伏笔、时间线、关系、锁、交接、章节索引;
60
+ - **事务**:归档不是“写一堆文件”,而是一次可恢复的原子提交;
61
+ - **审计**:成功、被拒、回退、恢复都留下记录。
67
62
 
68
- **最重要的架构约束**:工具、命令、面板、任务书都不能直接读改写项目文件;所有写操作都经过 `EngineService`。正文 `chapters/chapter-NNN.md` 是唯一真实来源,`state/*.yaml` 是引擎维护的影子层,不允许反向手改。
63
+ ### 它是什么
64
+
65
+ | 身份 | 说明 |
66
+ | --- | --- |
67
+ | 状态机 | 9 个命名阶段,非法迁移直接拒绝,断点可续 |
68
+ | 规则引擎 | 字数、格式、标点、词表、节奏、跨章一致性,约 30 条机检规则 |
69
+ | 账本系统 | 正文是唯一真实来源,`state/*.yaml` 是引擎维护的影子层 |
70
+ | 事务器 | staging → 校验 → 备份 → pending → rename → 读回 → committed |
71
+ | 观测面 | `novel_status`、`novel_report`、`novel_doctor`、`novel_search`、只读面板 |
72
+ | DSH 插件 | 28 个工具、5 条命令、1 个侧边栏、1 个内置 Agent 预设 |
69
73
 
70
74
  ### 它不是什么
71
75
 
72
- - 不是独立的桌面写作应用,不能脱离 DSH 运行。
73
- - 不是「装完就自动写完整本书」的生成器;它管流程、门禁和状态,正文仍由模型写。
74
- - 不是独立 CLI;必须作为 DSH 插件安装到某个 profile 才能使用。
75
- - 不提供云端同步、账号体系、在线书城或多人协作。
76
- - 0.2.x 仍是中文界面与中文任务书,没有 `locale/`,也不读取系统语言。
77
- - 不提供云端同步、多人协作、RAG/向量库或富文本编辑器;整书规划与单章流水线都在本地 YAML/Markdown 上完成。
76
+ - **不是提示词合集**:规则、门控和账本在代码里,不靠模型“记得”。
77
+ - **不是自动写书机**:它不调用 LLM,正文仍由模型写。
78
+ - **不是独立写作软件**:必须作为 DSH 插件安装到某个 profile。
79
+ - **不是数据库**:没有 SQLite/ORM,状态是 YAML + 一份 JSONL 日志。
80
+ - **不是云服务**:没有账号、同步、在线书城、多人协作。
81
+ - **不是中文以外的界面**:0.2.x 只有中文界面与中文任务书。
78
82
 
79
83
  ---
80
84
 
81
- ## 二、功能全貌
82
-
83
- | 能力 | 说明 |
84
- | ------------------------------- | -------------------------------------------------------------------------------------------- |
85
- | 28 个 `novel_*` 工具 | 书级蓝图/大纲/世界观 + 单章流水线 + 报告/体检/搜索/引导/重开/备份恢复 |
86
- | 5 条 `/novel*` 命令 | 状态、下一步、统计、导出、隐藏操作;`/novel` 内含 outline/guide/report/doctor/search 子命令 |
87
- | 1 个侧边栏面板「网文工坊」 | 只读;当前章/下一步、统计、全书规划、世界观、质量趋势、健康、最近活动、九阶段轨、章节卡、门控区 |
88
- | 1 个内置 Agent 预设「网文工坊」 | 28 个工具全开,**不挂载 bash / 文件写入工具**;会话开始后不能切换 |
89
- | 1 个入口技能 | 告诉模型什么时候该用引擎、哪些写入口是唯一的 |
90
- | 13 条门控 | 任务书、阶段、字数、格式、摘要、场景类型、大纲对齐、评分、问题清零、阅读证明、一致性、轮次、归档原子性 |
91
- | 15 维评分 | 满分 150,默认过关线 120;分数必须逐项可核对 |
92
- | 事务化归档 | staging → 校验 → 备份 → pending journal → rename → 读回 → committed journal |
93
- | 规则包外置 | 词表、格式、标点、语义、跨章阈值都在 `rulepacks/default.yaml`,代码只执行 |
94
- | 六种导出 | Markdown、纯文本、EPUB 3、大纲、世界观、书级提案;正文导出附 `cover.svg` 与 `blurb.txt` |
95
- | 整书规划层 | 书级蓝图、卷结构、章卡(严格模式)、世界观设定集;支持 Markdown/YAML/JSON 导入 |
96
- | 可观测性 | `novel_status` 书级摘要、`novel_report`、`novel_doctor`、`novel_search`、panel v6、journal 活动 |
97
- | 多项目注册表 | `stateDir/projects.yaml` 记录已知项目与面板默认 active;不影响项目目录 |
98
- | 运行期依赖极少 | 只有 `yaml` 一个运行时依赖;Host 侧不访问外部网络、不调用外部 API、不读环境变量里的密钥 |
99
-
100
- ### 关键设计
101
-
102
- - **状态机而不是自由对话**:阶段只能按合法迁移前进;不合法操作返回 `ENGINE_STAGE_ORDER` 并告诉你当前可用操作。
103
- - **门控先于写盘**:写初稿、修订、归档都是先校验、后落盘;坏稿不会进入项目。
104
- - **评分是算术,不是感觉**:`total = 150 - Σdelta`,每个维度 `score = max - Σdelta`,不闭合就拒绝。
105
- - **阅读证明**:P4/P5 要提交三段逐字引用,P6 会重新核验这份证明;开头/结尾按实际段落判定,防「没读就评」。
106
- - **归档是一次事务**:P7 状态同步、P8 终审、P9 索引与交接不是三个可以半途而废的步骤。
107
- - **模型不分配 ID**:只写 `key`,引擎分配 `FS-*` / `TE-*` / `RL-*` 等编号并回执映射。
108
- - **可控修订**:`novel_amend` 是唯一的状态手工修改入口,必须带原因并写入 journal;`novel_rollback` 保留正文供参考。
109
-
110
- ### 九个阶段
85
+ ## 核心机制
111
86
 
112
- | 阶段 | 名称 | 谁执行 | 产物 |
113
- | ---- | ---------- | --------------------- | --------------------------- |
114
- | P1 | 世界观约束 | 模型 | `plans/chNNN.world.yaml` |
115
- | P2 | 章节计划 | 模型 | `plans/chNNN.chapter.yaml` |
116
- | P3 | 初稿 | 模型 | `chapters/chapter-NNN.md` |
117
- | P4 | 评审 | 模型 | `reviews/chNNN.review.yaml` |
118
- | P5 | 修订 | 模型(有 blocker 时) | 覆盖正文 |
119
- | P6 | 一致性校验 | 引擎机检 + 模型语义项 | `checks/chNNN.check.yaml` |
120
- | P7 | 状态同步 | **引擎事务** | `state/*.yaml` |
121
- | P8 | 终审 | **引擎事务** | 三端一致性报告 |
122
- | P9 | 归档 | **引擎事务** | 章节索引 + 交接 |
87
+ ### 一张图看懂
123
88
 
124
- P7/P8/P9 在 `novel_archive` 一次事务里完成。单章归档后状态是 `done`;下一章仍从 P1 开始。只有项目配置的 `total_chapters` 全部归档,面板才显示「全书完成」。
89
+ ```mermaid
90
+ flowchart TB
91
+ U[作者 / 模型] --> T[28 个 novel_* 工具]
92
+ U --> C[5 条 /novel* 命令]
93
+ U --> P[网文工坊只读面板]
94
+ T --> S[EngineService<br/>唯一写入口]
95
+ C --> S
96
+ P -->|GET 只读| S
97
+ S --> B[7 份阶段任务书]
98
+ S --> G[13 道门控 + 15 维评分]
99
+ S --> R[rulepacks/default.yaml]
100
+ S --> X[事务 / journal / 备份]
101
+ X --> D[(chapters/ + state/ + outline/)]
102
+ ```
125
103
 
126
- ### 十三道门控
104
+ **四条通道,一个入口。** 工具、命令、面板、任务书都不能绕过 `EngineService` 直接改项目文件。正文 `chapters/chapter-NNN.md` 是唯一真实来源;`state/*.yaml` 是影子层,只能由归档事务写入,不能反向驱动正文。
127
105
 
128
- | 编号 | 名称 | 管什么 |
129
- | ----- | ---------------- | --------------------------------------------------------- |
130
- | PG-01 | `BRIEF_REQUIRED` | 当前阶段任务书已签发,digest 匹配 |
131
- | PG-02 | `STAGE_ORDER` | 只能提交当前阶段允许的产物 |
132
- | PG-03 | `WORD_COUNT` | 字数达到项目下限 |
133
- | PG-04 | `FORMAT` | 段落、标点、Markdown、标题等格式 blocker 为零 |
134
- | PG-05 | `SUMMARY_SCHEMA` | 十章摘要的十个字段齐全且类型正确 |
135
- | PG-06 | `SCENE_TYPE` | 场景类型合法,节奏约束满足 |
136
- | PG-13 | `OUTLINE_ALIGNMENT` | 有章卡时标题/场景/目标字数/cast 必须一致;严格模式无卡也拒绝;归档卡不可改 |
137
- | PG-07 | `SCORE` | 十五维齐全、算术闭合、总分达到 `minScore` |
138
- | PG-08 | `ISSUES_CLEARED` | 所有 blocker issue 已修复并带正文证据 |
139
- | PG-09 | `READING_PROOF` | 三段逐字引用能在正文对应位置找到;开头/结尾按实际段落判定 |
140
- | PG-10 | `CONSISTENCY` | 伏笔、时间线、资源、关系、重复段落等跨章对账 |
141
- | PG-11 | `ROUNDS` | 评审/修订、校验/修订均不超过 3 轮 |
142
- | PG-12 | `ARCHIVE_ATOMIC` | 归档事务三端一致且读回验证通过 |
143
-
144
- 门控按固定顺序求值,并且**收集全部失败项**,不是遇到第一个就返回——这样模型可以一次改完。
106
+ ### 九个阶段
145
107
 
146
- ### 十五维评分
108
+ | 阶段 | 名称 | 谁执行 | 产物 |
109
+ | --- | --- | --- | --- |
110
+ | P1 | 世界观约束 | 模型 | `plans/chNNN.world.yaml` |
111
+ | P2 | 章节计划 | 模型 | `plans/chNNN.chapter.yaml` |
112
+ | P3 | 初稿 | 模型 | `chapters/chapter-NNN.md` |
113
+ | P4 | 评审 | 模型 | `reviews/chNNN.review.yaml` |
114
+ | P5 | 修订 | 模型(有 blocker 时) | 覆盖正文 |
115
+ | P6 | 一致性校验 | 引擎机检 + 模型语义项 | `checks/chNNN.check.yaml` |
116
+ | P7 | 状态同步 | **引擎事务** | `state/*.yaml` |
117
+ | P8 | 终审 | **引擎事务** | 三端一致性报告 |
118
+ | P9 | 归档 | **引擎事务** | 章节索引 + 交接 |
147
119
 
148
- | 组 | 维度 |
149
- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------- |
150
- | A 核心叙事(90) | R-W-01 人设驱动 15 · R-W-02 情绪外化 10 · R-W-03 对话区分度 10 · R-W-04 爽点密度 20 · R-W-05 断章法则 15 · R-W-12 反文青病 20 |
151
- | B 商业指标(45) | R-W-11 元描写与视角侵入 10 · R-W-13 信息增量 15 · R-W-14 钩子质量 10 · R-W-15 期待值兑现 10 |
152
- | C 格式硬性(15) | R-W-06 段落长度 4 · R-W-07 去 AI 味 4 · R-W-08 硬性禁令 4 · R-W-09 字数 2 · R-W-10 标题 1 |
120
+ P7、P8、P9 在 `novel_archive` 一次事务里完成。单章归档后状态是 `done`;下一章仍从 P1 开始。只有项目配置的 `total_chapters` 全部归档,面板才显示“全书完成”。
153
121
 
154
- 合计严格 150。默认 `minScore = 120`,可在配置里改;它是 PG-07 的唯一过关线。
122
+ ### 十三道门控
155
123
 
156
- ### 类型与平台
124
+ 门控按固定顺序求值,并且**收集全部失败项**,不是遇到第一个就返回。这样模型可以一次改完,而不是来回撞墙。
125
+
126
+ | 编号 | 名称 | 管什么 |
127
+ | --- | --- | --- |
128
+ | PG-01 | `BRIEF_REQUIRED` | 当前阶段任务书已签发,digest 匹配 |
129
+ | PG-02 | `STAGE_ORDER` | 只能提交当前阶段允许的产物 |
130
+ | PG-03 | `WORD_COUNT` | 字数达到项目下限 |
131
+ | PG-04 | `FORMAT` | 段落、标点、Markdown、标题等格式 blocker 为零 |
132
+ | PG-05 | `SUMMARY_SCHEMA` | 十章摘要的十个字段齐全且类型正确 |
133
+ | PG-06 | `SCENE_TYPE` | 场景类型合法,节奏约束满足 |
134
+ | PG-07 | `SCORE` | 十五维齐全、算术闭合、总分达到 `minScore` |
135
+ | PG-08 | `ISSUES_CLEARED` | 所有 blocker issue 已修复并带正文证据 |
136
+ | PG-09 | `READING_PROOF` | 三段逐字引用能在正文对应位置找到 |
137
+ | PG-10 | `CONSISTENCY` | 伏笔、时间线、资源、关系、重复段落等跨章对账 |
138
+ | PG-11 | `ROUNDS` | 评审/修订、校验/修订均不超过 3 轮 |
139
+ | PG-12 | `ARCHIVE_ATOMIC` | 归档事务三端一致且读回验证通过 |
140
+ | PG-13 | `OUTLINE_ALIGNMENT` | 有章卡时标题/场景/目标字数/cast 必须一致 |
141
+
142
+ 补充:
143
+
144
+ - 任务书是门控输入,**每个阶段提交前先 `novel_brief`**;digest 不匹配会被 PG-01 拒绝。
145
+ - 格式先于字数:字数只在一份格式已干净的正文上判。
146
+ - P4 的评分可以低于 `minScore`,如实进入修订;`minScore` 在 P6 与归档前执行。
147
+ - 单跑 `content` 或 `integrity` 的 check 即使通过也停留 P6,必须再跑完整 scope 才能归档。
157
148
 
158
- - 类型(12):玄幻修仙、都市现代、西方奇幻、悬疑推理、科幻、游戏系统、历史架空、无限流、轻小说、军事、末世流、言情。
159
- - 平台(4):`fanqie`(番茄)、`qidian`(起点)、`qimao`(七猫)、`jinjiang`(晋江)。
149
+ ### 十五维评分
160
150
 
161
- 平台只决定规则包里的默认字数区间与对话比例;项目 `novel.yaml` 可以覆盖自己声明的那部分。
151
+ | 组 | 维度 | 满分 |
152
+ | --- | --- | ---: |
153
+ | A 核心叙事 | R-W-01 人设驱动 15 · R-W-02 情绪外化 10 · R-W-03 对话区分度 10 · R-W-04 爽点密度 20 · R-W-05 断章法则 15 · R-W-12 反文青病 20 | **90** |
154
+ | B 商业指标 | R-W-11 元描写与视角侵入 10 · R-W-13 信息增量 15 · R-W-14 钩子质量 10 · R-W-15 期待值兑现 10 | **45** |
155
+ | C 格式硬性 | R-W-06 段落长度 4 · R-W-07 去 AI 味 4 · R-W-08 硬性禁令 4 · R-W-09 字数 2 · R-W-10 标题 1 | **15** |
156
+
157
+ 合计严格 **150**。默认 `minScore = 120`,可在配置里改;它是 PG-07 的唯一过关线。
158
+
159
+ ### 关键数字
160
+
161
+ | 项目 | 数量 |
162
+ | --- | ---: |
163
+ | `novel_*` 工具 | 28 |
164
+ | `/novel*` 命令 | 5 |
165
+ | 阶段 | 9 |
166
+ | 门控 | 13 |
167
+ | 评分维度 | 15(满分 150) |
168
+ | 阶段任务书 | 7(P1–P6、P8) |
169
+ | 状态账本 | 8 |
170
+ | 导出格式 | 6 |
171
+ | 类型 / 平台 | 12 / 4 |
172
+ | 运行时依赖 | 1(`yaml`) |
162
173
 
163
174
  ---
164
175
 
165
- ## 三、兼容性与前置条件
176
+ ## 快速开始
166
177
 
167
- | 项目 | 要求 |
168
- | -------- | ---------------------------------------------------------------------------------------------------- |
169
- | DSH | `>=0.2.1-rc.2 <0.3.0-0`;由 `package.json` 的 `engines.dsh` 声明,安装与启动都会检查 |
170
- | Node.js | `>=24.9.0` |
171
- | pnpm | CLI 安装/卸载插件需要;建议 11.x(本仓库开发基线为 11.28.9) |
172
- | 宿主形态 | Web(面板 + 预设)、Desktop(面板 + 预设,插件由桌面壳管理)、headless(只有工具/命令,无面板/预设) |
173
- | 磁盘 | 项目根目录可写;默认 `stateDir` 可写 |
174
- | 网络 | 安装时需要访问 npm / Git 托管;运行期 Host 侧不访问外部网络,Web 客户端只向宿主面板发同源 GET |
175
- | 语言 | 0.2.x 仅中文 |
178
+ ### 1. 兼容性
176
179
 
177
- 检查命令:
180
+ | 项目 | 要求 |
181
+ | --- | --- |
182
+ | DSH | `>=0.2.1-rc.2 <0.3.0-0`,由 `package.json` 的 `engines.dsh` 声明 |
183
+ | Node.js | `>=24.9.0` |
184
+ | pnpm | 安装/卸载插件需要,建议 11.x;本仓库开发基线为 11.28.9 |
185
+ | 宿主形态 | Web / Desktop 有面板与预设;headless 只有工具与命令 |
186
+ | 网络 | 安装时需要 npm;运行期 Host 侧不访问外部网络 |
178
187
 
179
188
  ```bash
180
189
  node --version # 应 >= 24.9.0
@@ -182,112 +191,36 @@ dsh --version # 应 >= 0.2.1-rc.2,且 < 0.3.0-0
182
191
  pnpm --version # CLI 安装插件时需要
183
192
  ```
184
193
 
185
- 如果 `dsh` 不在 PATH 里,可以用 `npx @deepseek-ai/dsh` 代替下文的 `dsh`。但 `dsh plugin` 仍然需要本机有 `pnpm`。
186
-
187
- > 本仓库固定 pnpm 11.28.9。若本机版本不符,先执行 `corepack prepare pnpm@11.28.9 --activate`,或直接把下文的 `pnpm` 换成 `corepack pnpm`。
188
-
189
- ---
190
-
191
- ## 四、先装好 DSH 宿主
194
+ 如果 `dsh` 不在 PATH,可用 `npx @deepseek-ai/dsh` 代替命令开头的 `dsh`;但 `dsh plugin` 仍需要本机有 pnpm。
192
195
 
193
- 如果你已经在使用 DSH Web,并且 `dsh --version` 满足要求,可以直接跳到[第五节](#五安装本插件)。
196
+ ### 2. 安装
194
197
 
195
- ### 方式 A:npx 直接运行(最快)
198
+ **从 npm 安装(推荐):**
196
199
 
197
200
  ```bash
198
- # 先确保有 pnpm,因为后面安装插件要用
199
201
  corepack enable
200
202
  corepack prepare pnpm@11.28.9 --activate
201
203
 
202
- # 启动 Web UI;默认 http://127.0.0.1:3080
203
- npx @deepseek-ai/dsh web
204
- ```
205
-
206
- 不想自动打开浏览器:
207
-
208
- ```bash
209
- npx @deepseek-ai/dsh web --no-open
210
- ```
211
-
212
- ### 方式 B:全局安装 CLI
213
-
214
- ```bash
215
- npm install -g @deepseek-ai/dsh
216
- dsh web
217
- ```
218
-
219
- 升级:
220
-
221
- ```bash
222
- npm update -g @deepseek-ai/dsh
223
- ```
224
-
225
- ### 方式 C:从源码运行
226
-
227
- ```bash
228
- git clone https://github.com/deepseek-ai/deepseek-harness.git
229
- cd deepseek-harness
230
- corepack pnpm install
231
- corepack pnpm run build
232
- corepack pnpm dsh web
233
- ```
234
-
235
- ### 方式 D:Desktop
236
-
237
- 从 DSH 官方发行页安装 Desktop。Desktop 使用自己保留的 `desktop` profile,插件应在 Desktop 的「插件」页安装,**不要**用 `dsh plugin --profile web` 去改装 Desktop——那是另一个 profile。
238
-
239
- ### DSH 的 profile 与 `DSH_HOME`
240
-
241
- DSH 把不同应用形态放在 profile 里:
242
-
243
- | 启动方式 | profile | 面板 | 内置预设 |
244
- | -------------------------- | ---------- | ---------------- | ---------------- |
245
- | `dsh web` | `web` | 有 | 有 |
246
- | Desktop | `desktop` | 有 | 有 |
247
- | `dsh headless` | `headless` | 无 | 无 |
248
- | `dsh --profile <名字> web` | `<名字>` | 取决于该 profile | 取决于该 profile |
249
-
250
- profile 默认位于:
251
-
252
- ```text
253
- ~/.dsh/profiles/<profile>/
204
+ dsh plugin --profile web add dsh-novel-write-engine@0.2.7
254
205
  ```
255
206
 
256
- Windows 为 `%USERPROFILE%\.dsh\profiles\<profile>\`。如果设置了 `DSH_HOME`,则以 `$DSH_HOME/profiles/<profile>/` 为准。
257
-
258
- **结论**:插件必须装进你实际启动的那个 profile。装在 `web`、却用 `--profile myweb` 启动,是不会出现面板和预设的。
259
-
260
- ---
261
-
262
- ## 五、安装本插件
263
-
264
- 前置条件:DSH 已安装并满足版本要求,本机有 pnpm。
207
+ 安装后重启 DSH,或刷新 Web 页面。
265
208
 
266
- ### 5.1 从 npm 安装(推荐)
209
+ **验证安装:**
267
210
 
268
211
  ```bash
269
- corepack enable
270
- corepack prepare pnpm@11.28.9 --activate
271
-
272
- # 安装最新版到 web profile
273
- dsh plugin --profile web add dsh-novel-write-engine
274
- ```
275
-
276
- 固定版本:
212
+ # 1. 配置层出现插件
213
+ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
277
214
 
278
- ```bash
279
- dsh plugin --profile web add dsh-novel-write-engine@0.2.6
215
+ # 2. 新会话里应出现「网文工坊」预设
216
+ # 3. 侧边栏应出现「网文工坊」面板
217
+ # 4. 输入 /novel 应返回状态或“还没有项目”
280
218
  ```
281
219
 
282
- `dsh` 不在 PATH 时,用 `npx @deepseek-ai/dsh` 代替命令开头的 `dsh`。
283
-
284
- 安装命令会下载 npm 包、写入 `~/.dsh/profiles/web` 的依赖,并把插件加入该 profile 的 `dsh.profile.bundles`。不要用 `npm install` 代替:它只会下载包,不会把插件加入 profile。
285
-
286
- `web` 是 `dsh web` 使用的默认 profile。自定义 profile 把 `web` 换成实际名字;Desktop 使用自己的 `desktop` profile,请在桌面端插件页安装。
287
-
288
- 安装后重启 DSH,或刷新 Web 页面。
220
+ > `web` 是 `dsh web` 的默认 profile。自定义 profile 把 `web` 换成实际名字;Desktop 使用自己的 `desktop` profile,请在桌面端插件页安装,不要混用 CLI 的 `web` profile。
289
221
 
290
- ### 5.2 从源码目录安装(开发)
222
+ <details>
223
+ <summary><strong>从源码目录安装(开发/调试)</strong></summary>
291
224
 
292
225
  ```bash
293
226
  git clone https://github.com/ThzxxArt/dsh-novel-write-engine.git
@@ -298,127 +231,49 @@ corepack prepare pnpm@11.28.9 --activate
298
231
  corepack pnpm install
299
232
  corepack pnpm build
300
233
 
301
- # 把当前目录装进 web profile
302
234
  dsh plugin --profile web add "$PWD"
303
235
  ```
304
236
 
305
- PowerShell:
237
+ 源码目录是 **link** 关系,不是拷贝:修改 `src/` 后必须重新 `pnpm build` 并重启 DSH,否则宿主仍加载旧的 `lib/`。
306
238
 
307
- ```powershell
308
- git clone https://github.com/ThzxxArt/dsh-novel-write-engine.git
309
- cd dsh-novel-write-engine
310
- corepack enable
311
- corepack prepare pnpm@11.28.9 --activate
312
- corepack pnpm install
313
- corepack pnpm build
314
- dsh plugin --profile web add (Get-Location).Path
315
- ```
239
+ </details>
316
240
 
317
- 源码目录安装是 **link** 关系,不是拷贝:profile 的 `dependencies` 里出现的是 `link:/你的/源码目录`。之后修改 `src/` 必须重新 `corepack pnpm build` 并重启 DSH;否则 DSH 仍加载旧的 `lib/`。
318
-
319
- ### 5.3 从 tarball 安装(离线)
241
+ <details>
242
+ <summary><strong>从 tarball 安装(离线/可留档)</strong></summary>
320
243
 
321
244
  在能构建的机器上:
322
245
 
323
246
  ```bash
324
- git clone https://github.com/ThzxxArt/dsh-novel-write-engine.git
325
- cd dsh-novel-write-engine
326
247
  corepack pnpm install
327
248
  corepack pnpm build
328
249
  corepack pnpm pack
329
250
  ```
330
251
 
331
- 会得到类似:
332
-
333
- ```text
334
- dsh-novel-write-engine-0.2.6.tgz
335
- ```
336
-
337
- 把这个 tarball 复制到目标机器,放在一个**稳定、不会随手删除**的路径,然后:
338
-
339
- ```bash
340
- dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.2.6.tgz
341
- ```
342
-
343
- tarball 安装不会运行源码构建,也不会要求 `allowBuilds`;包内已经包含 `lib/`、`rulepacks/`、`briefs/`、`skills/`、`presets/` 和两层 patch。它是最接近「发布产物」的安装方式。
344
-
345
- 升级时用新的 tarball 重装;旧的 tarball 可以留档,便于回滚。
346
-
347
- ### 5.4 从 DSH 插件页安装
348
-
349
- 适用于你不想在终端里操作,或者 DSH 跑在另一台机器上。插件页既能装 npm 包名,也能装本地目录或 tarball;路径必须是 **DSH 宿主** 能访问的路径。
350
-
351
- 1. 打开 DSH Web,左侧栏进入 **插件**。
352
- 2. 点 **添加插件**(或旁边的箭头 → **安装第三方插件**)。
353
- 3. 在包名字段填入以下任一形式:
354
- - npm 包名:`dsh-novel-write-engine`
355
- - 精确版本:`dsh-novel-write-engine@0.2.6`
356
- - 源码目录:`/absolute/path/to/dsh-novel-write-engine`
357
- - tarball:`/absolute/path/to/dsh-novel-write-engine-0.2.6.tgz`
358
- 4. npm 包名从 npm 官方源安装;本地目录和 tarball 直接使用宿主路径。
359
- 5. 点 **安装**,等待完成。
360
- 6. 如果出现 **立即启用**,点它;否则安装后到「已安装插件」里把 **dsh-novel-write-engine** 打开。
361
- 7. 刷新页面;新开一个会话。
362
-
363
- > Desktop 的插件页管理的是 `desktop` profile,和 CLI 的 `web` profile 是两套依赖、两套锁文件。不要混用。
364
-
365
- ---
366
-
367
- ## 六、验证安装
368
-
369
- 按顺序做这四步,任何一步失败都能定位到不同层。
370
-
371
- ### 1. 看配置层
252
+ 得到 `dsh-novel-write-engine-0.2.7.tgz`,复制到目标机器后:
372
253
 
373
254
  ```bash
374
- dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
375
- ```
376
-
377
- 有 `# == dsh-novel-write-engine` 说明 bundle 层已合成。没有则是装错 profile,或安装没有成功。
378
-
379
- ### 2. 看侧边栏
380
-
381
- 重启 DSH(或刷新页面)后,左侧栏应出现 **网文工坊**。
382
-
383
- - 没有入口:当前不是 Web/Desktop profile,或 client bundle 没有加载。
384
- - 入口在但页面 404/空白:检查 DSH 版本、浏览器缓存,重启后再试。
385
-
386
- ### 3. 看会话预设
387
-
388
- 新开一个会话,在预设选择器里应出现 **网文工坊**。
389
-
390
- - 没有预设:你用的是 headless / acp / sdk profile,它们没有 `agentPresets` 服务;工具仍然可用。
391
- - 有预设但选不了:看插件页是否已启用;看 DSH 版本是否满足范围。
392
-
393
- ### 4. 看工具与命令
394
-
395
- 在任意会话里输入:
396
-
397
- ```text
398
- /novel
399
- ```
400
-
401
- 应返回状态卡或「还没有项目」的提示。也可以直接对模型说:
402
-
403
- ```text
404
- 列出你当前可用的 novel_* 工具。
255
+ dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.2.7.tgz
405
256
  ```
406
257
 
407
- 应能看到 28 个(`toolsMode=core` 时只有 10 个,见[第八节](#八使用方式))。
258
+ tarball 已包含 `lib/`、`rulepacks/`、`briefs/`、`skills/`、`presets/` 和两层 patch,不需要在目标机器重新构建。
408
259
 
409
- ---
260
+ </details>
410
261
 
411
- ## 七、五分钟快速开始
262
+ <details>
263
+ <summary><strong>从 DSH 插件页安装</strong></summary>
412
264
 
413
- ### 1. 新开一个「网文工坊」会话
265
+ 1. 左侧栏进入 **插件**;
266
+ 2. 点 **添加插件**;
267
+ 3. 填 npm 包名 `dsh-novel-write-engine`(或精确版本 `dsh-novel-write-engine@0.2.7`);
268
+ 4. 安装后启用,刷新页面,新开会话。
414
269
 
415
- 左侧栏 → 新建会话 → 预设选 **网文工坊**。
270
+ 插件页安装的是当前 profile 的依赖;Desktop 的插件页管理的是 `desktop` profile。
416
271
 
417
- 这个预设的工具是「小说专用」的:有 28 个 `novel_*` 工具、任务书、网页、待办、子智能体等,但**不挂载 bash / 文件写入工具**。正文只能经引擎写。
272
+ </details>
418
273
 
419
- ### 2. 直接说人话
274
+ ### 3. 开第一本书
420
275
 
421
- 例如:
276
+ 新开一个会话,预设选 **网文工坊**,然后直接说人话:
422
277
 
423
278
  ```text
424
279
  在 /home/me/novels/星海 开一本都市现代、番茄平台的书,
@@ -426,19 +281,7 @@ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
426
281
  先做全书蓝图、第一卷大纲和世界观设定,再写第一章的世界观约束和章节计划。
427
282
  ```
428
283
 
429
- 模型会调用 `novel_init` 建项目,然后按 `novel_guide` 的提示做书级规划;也可以跳过蓝图直接写第一章,严格大纲是可选开关。0.2.6 推荐顺序:
430
-
431
- ```text
432
- novel_init
433
- → novel_blueprint(梗概/主题/基调/视角/卷结构)
434
- → novel_outline(章卡)或 novel_outline_import(Markdown/YAML/JSON)
435
- → novel_worldbook(设定/规则/势力/地点/角色/术语/前史)
436
- → novel_brief P1 …
437
- ```
438
-
439
- ### 3. 等价的 `novel_init` 参数
440
-
441
- 如果你想自己确认字段:
284
+ 模型会调用 `novel_init` 建项目,再按 `novel_guide` 的提示做书级规划。等价的 `novel_init` 参数:
442
285
 
443
286
  ```json
444
287
  {
@@ -455,41 +298,35 @@ novel_init
455
298
  }
456
299
  ```
457
300
 
458
- `premise`、`logline`、`themes`、`tone`、`pov`、`audience`、`selling_points`、`ending` 与 `strict_outline` 都是可选的书级种子;不填也能开书,之后用 `novel_blueprint` 补。
301
+ `premise`、`logline`、`themes`、`tone`、`pov`、`audience`、`selling_points`、`ending`、`strict_outline` 都是可选书级种子;不填也能开书,之后用 `novel_blueprint` 补。
459
302
 
460
- `genre` 必须是 12 类之一,`platform` 必须是 `fanqie` / `qidian` / `qimao` / `jinjiang` 之一。对 `novel_init`,省略 `project_root` 时只使用配置 `projectRoot`,**不读会话绑定、工作区或 active**;创建成功后才绑定当前会话。其他工具省略 `project_root` 时按 0.2.2 的四层顺序解析:**当前 DSH 会话绑定 → 会话 cwd 中唯一项目 → 唯一注册项目/配置 `projectRoot`**;有多个项目且无法唯一确定时返回 `ENGINE_PROJECT_AMBIGUOUS`,需要 `/novel use` 或显式 `project_root`。`active` 只影响面板默认,不再静默决定 Agent 的工具项目。
303
+ `genre` 必须是 12 类之一,`platform` 必须是 `fanqie` / `qidian` / `qimao` / `jinjiang` 之一。对 `novel_init`,省略 `project_root` 时只使用配置 `projectRoot`,**不读会话绑定、工作区或 active**;创建成功后才绑定当前会话。其他工具省略 `project_root` 时按四层顺序解析:**当前会话绑定 → 会话 cwd 的唯一项目 → 唯一注册项目/配置 `projectRoot`**;多项目无法唯一确定时返回 `ENGINE_PROJECT_AMBIGUOUS`。
461
304
 
462
305
  ### 4. 一章的标准调用顺序
463
306
 
464
- | 步骤 | 调用 | 说明 |
465
- | ---- | --------------------------------------------- | -------------------------------------- |
466
- | 0 | `novel_blueprint` / `novel_outline` | 书级蓝图与当前章卡(严格模式必须) |
467
- | 1 | `novel_brief P1` | 领取 P1 世界观任务书,签收 digest |
468
- | 2 | `novel_plan_world` | 提交世界观约束 |
469
- | 3 | `novel_brief P2` | 领取 P2 章节计划任务书 |
470
- | 4 | `novel_plan_chapter` | 提交本章计划 |
471
- | 5 | `novel_brief P3` | 领取 P3 初稿任务书 |
472
- | 6 | `novel_write_draft` | 提交正文;格式/字数/摘要不过则整体拒绝 |
473
- | 7 | `novel_brief P4` | 领取 P4 评审任务书 |
474
- | 8 | `novel_review` | 十五维评分 + 三段阅读证明 |
475
- | 9 | 有 blocker:`novel_brief P5` → `novel_revise` | 修订后回到 P4 重评 |
476
- | 10 | 无 blocker:`novel_brief P6` → `novel_check` | 机检 + 五个语义项(含 POV) |
477
- | 11 | `novel_brief P8` | 领取终审任务书 |
478
- | 12 | `novel_archive` | 必须带 `state_delta`,一次事务归档 |
479
- | 13 | `novel_export md` | 或 `txt` / `epub` / `outline` / `worldbook` / `proposal` |
307
+ | 步骤 | 调用 | 说明 |
308
+ | ---: | --- | --- |
309
+ | 0 | `novel_blueprint` / `novel_outline` | 书级蓝图与当前章卡;严格模式必须 |
310
+ | 1 | `novel_brief P1` | 领取 P1 世界观任务书,签收 digest |
311
+ | 2 | `novel_plan_world` | 提交世界观约束 |
312
+ | 3 | `novel_brief P2` | 领取 P2 章节计划任务书 |
313
+ | 4 | `novel_plan_chapter` | 提交本章计划 |
314
+ | 5 | `novel_brief P3` | 领取 P3 初稿任务书 |
315
+ | 6 | `novel_write_draft` | 提交正文;格式/字数/摘要不过则整体拒绝 |
316
+ | 7 | `novel_brief P4` | 领取 P4 评审任务书 |
317
+ | 8 | `novel_review` | 十五维评分 + 三段阅读证明 |
318
+ | 9 | 有 blocker:`novel_brief P5` → `novel_revise` | 修订后回到 P4 重评 |
319
+ | 10 | 无 blocker:`novel_brief P6` → `novel_check` | 机检 + 五个语义项 |
320
+ | 11 | `novel_brief P8` | 领取终审任务书 |
321
+ | 12 | `novel_archive` | 必须带 `state_delta`,一次事务归档 |
322
+ | 13 | `novel_export md` | 或 `txt` / `epub` / `outline` / `worldbook` / `proposal` |
480
323
 
481
324
  关键点:
482
325
 
483
- - **每一步提交前都要先领任务书**,PG-01 会检查 digest。`novel_status` / `novel_pipeline` 在任务书缺失或过期时会先返回 `novel_brief`,不会让你直接撞 PG-01。
484
- - **坏状态不是死锁**:plan/review/check/worldPlan、八个 ledger 与 outline/worldbook 损坏时,status 返回 `state_errors` 与 `STATE_UNREADABLE`;plan/review/check 走 rollback/阶段重建,ledger/project/规划文档则 `novel_state` 返回 `raw`、`next` 指向 `novel_amend`。`novel_amend` 会为当前所有不可读状态文档豁免 journal 的既有 hash,并在同一事务里写目标文档与 `state/pipeline.yaml`(不是只写一个文件);其他可读文件的外部改动仍拒绝。P6 的 check 损坏优先于旧 revision 阻塞;归档前 `review_digest` 缺失/不匹配会回退 P4。损坏或丢失的 `novel.yaml` 也走同一条 `PROJECT_UNREADABLE` 修复路径。
485
- - **计划先校验再落盘**:P1 的 `constraints`/`characters`/`locations`/`continuity_notes` 有形状校验;P2 的标题长度读 rulepack、5–8 个非空节拍、narrator、opening/ending 都会在服务边界拒绝。P2 可选 `cast`(1–8 人),名字必须来自 P1 世界计划或角色台账。
486
- - **上下文有预算且不裁主角团**:每个 brief 的 `context.context_meta` 给出 `budget`/`used`/`truncated`/`omitted`;P1 `world_plan` 的目标/约束/连续性说明、P3/P4/P5 的本章活跃角色完整卡、P6 的 `active_cast` 与正文/当前 plan/review/check/摘要受保护;`world_plan.characters/locations` 是可裁剪的候选名单,`other_characters` 只放压缩索引。裁剪会参与 digest,升级后旧 brief 需要重新领取。
487
- - **长书读口**:`novel_state {kind:"chapters"}` 默认返回紧凑索引,`include_summary`/`chapter_range` 按需取;panel 只送最近 30 行。归档继承上一章 handoff 的 volume/volume_name;act/act_progress 从上一章推进,`handoff.act`/`act_progress` 可覆盖。
488
- - `ready_to_archive` 在 P8 任务书当前后,`next.tool` 才返回 `novel_archive`;P5/P6 有阻塞时返回 `novel_revise`。
489
- - `novel_review` 的 `total` 是必填的,必须等于 `150 - Σdelta`;三段阅读证明必须逐字来自正文,开头/结尾按**实际段落**判定;issue 的 `dimension` 必须是当前十五维之一,`location` 必须是本章实际段落。
490
- - `novel_check` 的 `semantic` 恰好五个语义项(`L2-SCENE-ANCHOR` / `L2-CHARACTER-STATE` / `L2-CAUSALITY` / `L2-VOICE` / `L2-POV`),每项带至少 8 字、五条互不相同且来自不同句子的正文引用;`scope` 默认 `content + integrity`,只跑一类时另一类不参与本次 check,且通过后仍停留 P6(`CHECK_SCOPE_PARTIAL`),不能归档。
491
- - `novel_archive` 的 `state_delta` 要逐实体核销角色、伏笔、时间线、世界、关系;新伏笔标题必须出现在正文,`no_change` 也要写原因;review 存在但 `review_digest` 缺失时拒绝归档,需重新 `novel_review`。
492
- - 正文改动后,旧的评审分数和 check 会失效;不要试图手工改 `state/` 绕过。
326
+ - **每一步提交前都要先领任务书**。`novel_status` / `novel_pipeline` 在任务书缺失或过期时会先返回 `novel_brief`。
327
+ - **坏状态不是死锁**:plan/review/check/worldPlan、八个 ledger 与 outline/worldbook 损坏时,status 返回 `state_errors`;plan/review/check 走 rollback/阶段重建,ledger/project/规划文档走 `novel_amend`。
328
+ - **正文改动后旧证据失效**:评审分数、check、正文 hash 都会对不上;不要手改 `state/` 绕过。
329
+ - **修订优先 patch**:`novel_revise` 支持整章 `content`,也支持 `patch:{expected_hash,edits}`;只改摘要可传 `summary` 做 summary-only,不动正文、不消耗修订轮次。
493
330
 
494
331
  ### 5. 看面板
495
332
 
@@ -498,205 +335,58 @@ novel_init
498
335
  - 紧凑顶栏:书名、类型、平台、当前章、阶段;
499
336
  - 首屏“当前章 / 下一步”卡与“复制续写指令”;
500
337
  - 统计条:已归档章节、总字数、平均分、待处理门控;
501
- - 双栏工作台:左侧阶段轨、门控、提示、旧数据;右侧全书规划(蓝图/严格模式、章卡进度、**全部卷**、世界观计数、质量趋势、健康度)与最近活动;
338
+ - 双栏工作台:阶段轨、门控、提示、旧数据、全书规划、质量趋势、健康度、最近活动;
502
339
  - 底部章节卡。
503
340
 
504
- 面板每 15 秒静默同步一次,也可以点刷新;它**只读**,所有写操作仍在对话/工具里。
341
+ 面板每 15 秒静默同步一次,也可以点刷新。它**只读**,所有写操作仍在对话/工具里。
505
342
 
506
343
  ---
507
344
 
508
- ## 八、使用方式
345
+ ## 安装之后:日常怎么用
509
346
 
510
- ### 8.1 三种会话形态
347
+ ### 三种会话形态
511
348
 
512
- | 形态 | 怎么进 | 工具 | 写文件能力 | 面板/预设 |
513
- | -------------------- | ------------------------------ | --------------------- | ----------------------------------- | ------------------ |
514
- | 内置预设「网文工坊」 | 新会话选预设 | 28 个全开 | 不挂 bash/fs 写入工具,正文只经引擎 | 有 |
515
- | 普通会话 | 任意标准会话 | 28 个工具在根层注册 | 可能还有 bash/fs;引擎保证会被绕过 | 有面板,无专用预设 |
516
- | headless / 自动化 | `dsh --profile headless "..."` | 28 个(或 core 10 个) | 取决于该 profile | 无面板、无预设 |
349
+ | 形态 | 怎么进 | 工具 | 写文件能力 | 面板/预设 |
350
+ | --- | --- | --- | --- | --- |
351
+ | 内置预设「网文工坊」 | 新会话选预设 | 28 个全开 | 不挂 bash/fs 写入工具,正文只经引擎 | 有 |
352
+ | 普通会话 | 任意标准会话 | 28 个工具在根层注册 | 可能还有 bash/fs;引擎保证会被绕过 | 有面板,无专用预设 |
353
+ | headless / 自动化 | `dsh --profile headless "..."` | 28 个(或 core 10 个) | 取决于 profile | 无面板、无预设 |
517
354
 
518
- **要用「引擎保证」就用「网文工坊」预设。** 普通会话里,模型仍然可以用文件工具直接改 `state/` 或正文;那时你得到的是「引擎工具 + 人工操作」的混合状态,事务、门控、审计都不再完整。
355
+ **要用“引擎保证”就用「网文工坊」预设。** 普通会话里,模型仍可用文件工具直接改 `state/` 或正文;那时你得到的是“引擎工具 + 人工操作”的混合状态,事务、门控、审计都不再完整。
519
356
 
520
357
  预设是会话类型,**会话开始后不能切换**。要换形态就新开一个会话。
521
358
 
522
- ### 8.2 28 个工具
523
-
524
- | 工具 | 阶段 | 做什么 | 写盘 |
525
- | -------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
526
- | `novel_init` | — | 建项目:`novel.yaml` + `state/` + `outline/` + 目录 | 是 |
527
- | `novel_status` | 任意 | 当前活跃章、阶段、轮次、阻塞项、`state_errors`、`manuscript_hash`、下一步;`chapter` 只用于字数查询 | 项目正文否;显式 root 写绑定 |
528
- | `novel_brief` | P1–P6 / P8 | 领取当前活跃章的任务书,返回 `fields`、`context`;`context.world_plan` 与 `context.context_meta` 在 `context` 内,并记录 digest | 仅任务书签收 |
529
- | `novel_plan_world` | P1 | 提交世界观约束;数组/对象形状在服务边界校验 | 是 |
530
- | `novel_plan_chapter` | P2 | 提交章节计划;标题长度读 rulepack、5–8 个节拍、opening/ending 非空;可选 `cast` 1–8 人 | 是 |
531
- | `novel_write_draft` | P3 | 提交初稿;格式/字数/摘要不过整体拒绝 | 是 |
532
- | `novel_review` | P4 | 十五维评分、问题清单、三段阅读证明;issue 维度/段落和 blocker waived 会被拒绝 | 是 |
533
- | `novel_revise` | P5/P6/待归档 | 提交修订;支持整章 `content` 或 `patch:{expected_hash,edits}`;`ready_to_archive` 可直接修订并回 P4;blocker 必须有正文证据,不能降级或 waived | 是 |
534
- | `novel_check` | P6 | 机检 + 五个语义一致性项;`advisories` 与 blocker 分开,可用 `acknowledge` 记录知悉;单 scope 不推进归档 | 是 |
535
- | `novel_archive` | P7–P9 | 事务归档;必须带 `state_delta`;旧 review 无 digest 时拒绝 | 事务 |
536
- | `novel_word_count` | 任意 | 按引擎唯一口径数字数 | 否 |
537
- | `novel_state` | 任意 | 读账本、计划、评审、检查、handoff、outline/worldbook、history/backups/briefs;chapters 默认紧凑,支持 `include_summary`/`chapter_range`;损坏 ledger 返回 raw | 否 |
538
- | `novel_amend` | 任意 | 带原因修订 `novel.yaml`、八个 ledger 或 outline/worldbook,带不变量与单目标 repair | 是,入 journal |
539
- | `novel_rollback` | 任意 | 只退回当前阶段或更早,保留正文供参考 | 是 |
540
- | `novel_diff` | 任意 | 与上次归档备份或两段文本比较 | 否 |
541
- | `novel_export` | 任意 | 导出 `md` / `txt` / `epub` / `outline` / `worldbook` / `proposal` | 导出目录 |
542
- | `novel_audit` | 任意 | 读追加式 journal 审计记录,含被拒 attempt;支持 chapter/op/status/since/until/cursor | 否 |
543
- | `novel_pipeline` | 任意 | 「下一步该做什么」的建议 | 否 |
544
- | `novel_blueprint` | 任意 | 写书级蓝图:梗概、主题、基调、视角、读者、卖点、结局、卷结构 | 是 |
545
- | `novel_outline` | 任意 | 按 `num` upsert 章卡、按 `title` upsert 卷;省略不删,`remove`/`remove_volumes` 显式删除,`dry_run` 预览 | 是 |
546
- | `novel_outline_import` | 任意 | 从 Markdown / YAML / JSON 导入大纲;`dry_run` 先预览 | 可选 |
547
- | `novel_worldbook` | 任意 | 增量更新世界观设定集(设定/规则/势力/地点/角色/术语/前史) | 是 |
548
- | `novel_search` | 任意 | 跨正文、摘要、大纲、世界观、台账搜索,带章号/段落号/片段 | 否 |
549
- | `novel_doctor` | 任意 | 项目体检:项目/流水线/状态、journal、正文 hash、孤立正文、大纲覆盖与漂移、旧数据审计(legacy-data)、数值事实、当前阶段产物、锁、备份、目标进度、下一步 | 否 |
550
- | `novel_report` | 任意 | 全书报告:进度、大纲、世界观、质量、节奏、角色、伏笔、时间线、关系、活动 | 否 |
551
- | `novel_guide` | 任意 | 上手引导:当前状态、已完成步骤、下一步工具、命令与提示;无项目也能用 | 否 |
552
- | `novel_reopen` | 已归档章 | 从归档备份把紧邻的上一章重开到 P3;必须带非空 `reason`,活动章未开始、备份存在时才允许 | 是 |
553
- | `novel_restore` | 活动章 | 从带 manifest 的 txid 备份恢复正文/计划/评审/校验;已归档章拒绝,先 `novel_reopen` | 是 |
554
-
555
- 工具失败时统一返回:
556
-
557
- ```text
558
- [ENGINE_XXX] 说明 — 可操作建议
559
- ```
560
-
561
- 三类错误:
562
-
563
- - **改参数**:`ENGINE_SCHEMA_INVALID`、`ENGINE_STAGE_ORDER`、`ENGINE_PROJECT_NOT_FOUND`、`ENGINE_PROJECT_EXISTS`;修订改了评审归属字段时是 `ENGINE_ISSUE_IMMUTABLE`;同内容同上下文重试是 `ENGINE_RETRY_UNCHANGED`;
564
- - **改正文**:`ENGINE_GATE_BLOCKED`、`ENGINE_SCORE_MISMATCH`、`ENGINE_READING_PROOF_INVALID`、`ENGINE_DELTA_UNVERIFIED`;
565
- - **查环境**:`ENGINE_SCHEMA_TOO_NEW`、`ENGINE_PATH_ESCAPE`、`ENGINE_LOCK_TIMEOUT`、`ENGINE_TXN_ABORTED`、`ENGINE_RULEPACK_INVALID`。
566
-
567
- ### 8.3 五条命令
359
+ ### 五条命令
568
360
 
569
- 注册的命令是 5 条:
570
-
571
- | 命令 | 作用 |
572
- | --------------- | ----------------------------------------------------- |
573
- | `/novel` | 不带参数 = 状态;`/novel status` 同义 |
574
- | `/novel-next` | 下一步工具与理由 |
575
- | `/novel-stats` | 章节数、总字数、平均分、未回收伏笔、规则包版本 |
361
+ | 命令 | 作用 |
362
+ | --- | --- |
363
+ | `/novel` | 不带参数 = 状态;`/novel status` 同义 |
364
+ | `/novel-next` | 下一步工具与理由 |
365
+ | `/novel-stats` | 章节数、总字数、平均分、未回收伏笔、规则包版本 |
576
366
  | `/novel-export` | 导出 `md` / `txt` / `epub` / `outline` / `worldbook` / `proposal` |
577
- | `/novel-admin` | `/novel-admin <op> <json>` 执行隐藏/运维操作 |
367
+ | `/novel-admin` | `/novel-admin <op> <json>` 执行隐藏/运维操作 |
578
368
 
579
369
  `/novel` 还有子命令:
580
370
 
581
371
  ```text
582
- /novel next
583
- /novel stats
584
- /novel outline
585
- /novel guide
586
- /novel report
587
- /novel doctor
372
+ /novel next | stats | outline | guide | report | doctor
588
373
  /novel search <关键词>
589
374
  /novel export md|txt|epub|outline|worldbook|proposal
590
- /novel projects
591
- /novel projects --prune [--yes]
592
- /novel current
593
- /novel use <path|title|.>
594
- /novel unbind
595
- /novel scan [--register]
596
- /novel resume
597
- /novel admin
375
+ /novel projects | projects --prune [--yes] | current
376
+ /novel use <path|title|.> | unbind | scan [--register] | resume
598
377
  /novel admin novel_state {"kind":"pipeline"}
599
378
  ```
600
379
 
601
- **`toolsMode=core` 时**只注册 10 个高频工具:
380
+ `toolsMode=core` 时只注册 10 个高频工具:
602
381
 
603
382
  ```text
604
383
  novel_init, novel_status, novel_guide, novel_brief, novel_outline,
605
384
  novel_write_draft, novel_review, novel_revise, novel_check, novel_archive
606
385
  ```
607
386
 
608
- 其余 18 个非 core 工具不消失,改走命令;`/novel admin` 可显式调用非 core 操作(core 里只有 `novel_outline` / `novel_guide` 也在 admin 表中):
609
-
610
- ```text
611
- /novel admin novel_plan_world {...}
612
- /novel admin novel_plan_chapter {...}
613
- /novel admin novel_word_count {"text":"..."}
614
- /novel admin novel_state {"kind":"pipeline"}
615
- /novel admin novel_amend {...}
616
- /novel admin novel_rollback {...}
617
- /novel admin novel_diff {...}
618
- /novel admin novel_export {"kind":"md"}
619
- /novel admin novel_audit {"limit":20}
620
- /novel admin novel_pipeline
621
- /novel admin novel_blueprint {...}
622
- /novel admin novel_outline_import {...}
623
- /novel admin novel_worldbook {...}
624
- /novel admin novel_search {"query":"..."}
625
- /novel admin novel_doctor
626
- /novel admin novel_report
627
- /novel admin novel_reopen {"chapter":2,"reason":"..."}
628
- /novel admin novel_restore {"txid":"..."}
629
- ```
630
-
631
- 多项目注册表与设定包导入**不走工具 schema**;日常发现/切换用 `/novel scan`、`/novel use`,底层登记仍可用:
632
-
633
- ```text
634
- /novel admin novel_registry_list
635
- /novel admin novel_registry_register {"root":"/abs/book"}
636
- /novel admin novel_registry_activate {"root":"/abs/book"}
637
- /novel admin novel_registry_forget {"root":"/abs/book"}
638
- /novel admin novel_import {"kind":"characters","content":{...},"dryRun":true}
639
- /novel admin novel_import {"kind":"characters","content":{...},"dryRun":false}
640
- ```
641
-
642
- `novel_import` 先预览 diff;`dryRun: true` 不写盘。`novel_registry_forget` 只删注册表行,**永远不删项目目录**。
643
-
644
- ### 8.4 侧边栏「网文工坊」
645
-
646
- - 只读 HTTP 路由:`GET/HEAD /api/novel-write-engine/panel?root=<可选>`;
647
- - 精确路由,复用 connection 的认证/Origin 闸门;未认证返回 401/403,连接层缺席返回 503;
648
- - 返回 `schemaVersion`;版本不一致时面板提示刷新;
649
- - 状态:loading(骨架)、choose(多项目先选)、missing(项目不在)、empty(显示 `novel_init`)、error(重试)、outdated(刷新)、ready;
650
- - 顶部项目选择器(`aria-label="切换项目"`);选择只影响面板 GET 的 `?root=`,写入浏览器 `localStorage`,**不调用 activate、不写会话绑定**;
651
- - 只接受注册表、active 或配置 `projectRoot` 的路径;未登记路径返回 `missing.reason="not_registered"`,不读取任意目录;
652
- - 章节超过 30 章时只渲染最近 30 张,并显示总记录数;卷列表展示全部卷,长列表在滚动容器内;
653
- - 下一步卡提供“复制续写指令”,文本与 `/novel resume` 同源,只写浏览器剪贴板;
654
- - 窄屏纵向堆叠,支持减少动态效果。
655
-
656
- 面板不是第二个写入口。它没有改名、归档、回退按钮。
657
-
658
- ### 8.5 导出
659
-
660
- 工具调用(由模型执行):
661
-
662
- ```json
663
- { "kind": "md" }
664
- { "kind": "txt" }
665
- { "kind": "epub" }
666
- { "kind": "md", "chapter": 3 }
667
- ```
668
-
669
- 对话命令(全书):
670
-
671
- ```text
672
- /novel export md
673
- /novel export txt
674
- /novel export epub
675
- /novel export outline
676
- /novel export worldbook
677
- /novel export proposal
678
- /novel-export epub
679
- ```
680
-
681
- 输出:
682
-
683
- ```text
684
- exports/
685
- ├── book.md / book.txt / book.epub # 全书
686
- ├── book-ch001.md / .txt / .epub # 单章
687
- ├── outline.md # 大纲(与导入模板同形)
688
- ├── worldbook.md # 世界观设定集
689
- ├── proposal.md # 书级提案
690
- ├── cover.svg
691
- └── blurb.txt
692
- ```
693
-
694
- - Markdown:`# 书名`、`## 第N章 标题`;
695
- - 纯文本:无 Markdown 装饰,UTF-8 无 BOM;
696
- - EPUB:EPUB 3,自写 ZIP 容器,`mimetype` 首条且 store 方式;
697
- - 封面是纯 SVG 字符串,不依赖 canvas;平台简介由模板生成,不调用模型。
387
+ 其余 18 个不消失,改走 `/novel admin <op> <json>`。多项目注册与设定包导入也不走工具 schema,只走命令入口。
698
388
 
699
- ### 8.6 多项目与会话绑定
389
+ ### 多项目与会话绑定
700
390
 
701
391
  四层选择模型:
702
392
 
@@ -717,65 +407,105 @@ exports/
717
407
  /novel resume 输出可粘贴的续写指令;只读
718
408
  ```
719
409
 
720
- - `projects.yaml` 仍是 v1,新增可选 `created_at`;`session-bindings.yaml` 只保存会话选择,删掉不会删书;
721
- - `/novel use` 成功绑定后会 best-effort 把项目加入注册表,便于随后在 `/novel projects` 与面板看到;不改变 active。`novel.yaml` 损坏时不绑定、不登记,先用显式 `project_root` 修复;
722
- - 无显式 `project_root` 时,注册/绑定文件损坏 fail-closed,不静默重建;显式 `project_root` 的读取仍可用(损坏的绑定不会被更新),写事务提交后元数据失败只回 warning;
723
- - 项目目录被删除时保留登记与绑定,返回 `ENGINE_PROJECT_MISSING`,不自动回退、不自动重建;
724
- - 原路径被另一本书占用时返回 `ENGINE_PROJECT_IDENTITY_MISMATCH`,必须显式重新 `/novel use`;
410
+ - `projects.yaml` 只记录路径、标题、可选 `created_at` 与 `active`;`session-bindings.yaml` 只保存会话选择。两者都不保存正文,删掉不会删书。
411
+ - 项目目录被删除时保留登记与绑定,返回 `ENGINE_PROJECT_MISSING`,不自动回退、不自动重建。
412
+ - 原路径被另一本书占用时返回 `ENGINE_PROJECT_IDENTITY_MISMATCH`,必须显式重新 `/novel use`。
725
413
  - `/novel admin novel_registry_activate` 只改面板默认,不切换当前会话;`forget` 不删绑定与项目。
726
414
 
727
- ### 8.7 整书规划、观测与修复
415
+ ---
416
+
417
+ ## 工具手册
418
+
419
+ 28 个工具全部是 `EngineService` 的薄适配器:参数窄化 → 一次操作 → 规范值 + render。
420
+
421
+ 工具失败时统一返回:
728
422
 
729
423
  ```text
730
- # 1. 书级蓝图与卷
731
- novel_blueprint {premise, logline, themes, tone, pov, audience,
732
- selling_points, ending, strict, volumes}
733
-
734
- # 2. 章卡;或从 Markdown/YAML/JSON 导入
735
- novel_outline {chapters: [{num: 1, ...}], volumes: [...]}
736
- # 删除:novel_outline {remove: [2]};预览:加 dry_run:true
737
- novel_outline_import {format:"markdown", content:"...", dry_run:true}
738
-
739
- # 3. 世界观设定集(按段替换)
740
- novel_worldbook {setting, rules, factions, locations, characters, glossary, backstory}
741
-
742
- # 4. 每次写章前看 guide;写完随时看 report/doctor/search
743
- novel_guide
744
- novel_report
745
- novel_doctor
746
- novel_search {query:"蜡印", scope:"all"}
747
-
748
- # 5. 已归档章要改:先重开紧邻的上一章,再走 P3→P9
749
- novel_reopen {chapter:3, reason:"结尾需要重写"}
424
+ [ENGINE_XXX] 说明 — 可操作建议
750
425
  ```
751
426
 
752
- - 严格大纲:`book.strict=true` 时 P2/P3 必须要有章卡;只要章卡存在,标题/场景/目标字数/cast 在任何模式下都受 PG-13 约束。要关闭严格缺卡检查用 `novel_blueprint {strict:false}`。
753
- - 归档卡不可直接改;`novel_reopen` 需要非空 `reason`,会从该章归档事务的备份恢复索引/台账/handoff/正文。
754
- - `novel_doctor` 只读;`novel_amend` 才是修复写入口。
755
- - 报告/体检/搜索结果都带章号与可定位片段,不是笼统摘要。
427
+ 三类错误:
428
+
429
+ - **改参数**:`ENGINE_SCHEMA_INVALID`、`ENGINE_STAGE_ORDER`、`ENGINE_PROJECT_NOT_FOUND`、`ENGINE_PROJECT_EXISTS`;
430
+ - **改正文**:`ENGINE_GATE_BLOCKED`、`ENGINE_SCORE_MISMATCH`、`ENGINE_READING_PROOF_INVALID`、`ENGINE_DELTA_UNVERIFIED`;
431
+ - **查环境**:`ENGINE_SCHEMA_TOO_NEW`、`ENGINE_PATH_ESCAPE`、`ENGINE_LOCK_TIMEOUT`、`ENGINE_TXN_ABORTED`、`ENGINE_RULEPACK_INVALID`。
432
+
433
+ ### 项目与规划(8)
434
+
435
+ | 工具 | 做什么 |
436
+ | --- | --- |
437
+ | `novel_init` | 建项目:`novel.yaml` + `state/` + `outline/` + 目录 |
438
+ | `novel_blueprint` | 写书级蓝图:梗概、主题、基调、视角、读者、卖点、结局、卷结构 |
439
+ | `novel_outline` | 按 `num` upsert 章卡、按 `title` upsert 卷;省略不删,显式 `remove`;`dry_run` 预览 |
440
+ | `novel_outline_import` | 从 Markdown / YAML / JSON 导入大纲;`dry_run` 先预览 |
441
+ | `novel_worldbook` | 增量更新世界观设定集(设定/规则/势力/地点/角色/术语/前史) |
442
+ | `novel_status` | 当前章、阶段、轮次、阻塞项、`state_errors`、`manuscript_hash`、下一步 |
443
+ | `novel_guide` | 上手引导:当前状态、已完成步骤、下一步工具;无项目也能用 |
444
+ | `novel_pipeline` | “下一步该做什么”的建议 |
445
+
446
+ ### 单章流水线(8)
447
+
448
+ | 工具 | 阶段 | 做什么 |
449
+ | --- | --- | --- |
450
+ | `novel_brief` | P1–P6 / P8 | 领取当前章任务书,返回 `fields` 与 `context`,记录 digest |
451
+ | `novel_plan_world` | P1 | 提交世界观约束;数组/对象形状在服务边界校验 |
452
+ | `novel_plan_chapter` | P2 | 提交章节计划;5–8 个节拍、opening/ending、可选 `cast` |
453
+ | `novel_write_draft` | P3 | 提交初稿;格式/字数/摘要不过整体拒绝 |
454
+ | `novel_review` | P4 | 十五维评分、问题清单、三段阅读证明;`total` 必填且必须闭合 |
455
+ | `novel_revise` | P5/P6/待归档 | 整章 `content`、`patch:{expected_hash,edits}` 或仅 `summary` |
456
+ | `novel_check` | P6 | 机检 + 五个语义一致性项;advisory 与 blocker 分开 |
457
+ | `novel_archive` | P7–P9 | 事务归档;必须带 `state_delta` |
458
+
459
+ ### 观测与维护(9)
460
+
461
+ | 工具 | 做什么 |
462
+ | --- | --- |
463
+ | `novel_state` | 读账本、计划、评审、检查、handoff、outline/worldbook、history/backups/briefs |
464
+ | `novel_search` | 跨正文、摘要、大纲、世界观、台账搜索,带章号/段落号/片段 |
465
+ | `novel_report` | 全书报告:进度、大纲、世界观、质量、节奏、角色、伏笔、时间线、关系、活动 |
466
+ | `novel_doctor` | 项目体检:journal、正文 hash、孤立正文、大纲漂移、旧数据、锁、备份、下一步 |
467
+ | `novel_audit` | 读追加式 journal 审计记录,含被拒 attempt;支持过滤与游标 |
468
+ | `novel_word_count` | 按引擎唯一口径数字数 |
469
+ | `novel_diff` | 与上次归档备份或两段文本比较 |
470
+ | `novel_amend` | 带原因修订 `novel.yaml`、八个 ledger 或 outline/worldbook |
471
+ | `novel_rollback` | 只退回当前阶段或更早,保留正文供参考 |
472
+
473
+ ### 归档后与恢复(3)
474
+
475
+ | 工具 | 做什么 |
476
+ | --- | --- |
477
+ | `novel_export` | 导出 `md` / `txt` / `epub` / `outline` / `worldbook` / `proposal` |
478
+ | `novel_reopen` | 从归档备份把紧邻的上一章重开到 P3;必须带非空 `reason` |
479
+ | `novel_restore` | 从带 manifest 的 txid 备份恢复活动章、大纲或损坏 pipeline;已归档章先 `novel_reopen` |
480
+
481
+ ### 编辑与修订的边界
482
+
483
+ - **整章重写**:`novel_revise {content, proof}`,正文 hash 与轮次一起更新。
484
+ - **局部改**:`novel_revise {patch:{expected_hash, edits}}`;hash 不匹配、锚点不唯一/越界、编辑重叠都会零写入拒绝。
485
+ - **只改摘要**:`novel_revise {summary}`;正文 hash、章文件和历史不变,不消耗修订轮次。
486
+ - **blocker 不能 waived**:blocker 必须 `fixed` 并带正文证据;只有 advisory 可 `acknowledge`。
487
+ - **归档章不能直接改**:先 `novel_reopen`,再走 P3 → P9。
756
488
 
757
489
  ---
758
490
 
759
- ## 九、配置
491
+ ## 配置
760
492
 
761
- ### 9.1 六个配置项
493
+ ### 六个配置项
762
494
 
763
- | 键 | 默认 | 说明 |
764
- | ----------------- | -------------------------------- | ------------------------------------------------------------------------- |
765
- | `projectRoot` | `./novel` | 无会话绑定/工作区/唯一项目时的兜底根;相对路径相对于 DSH 进程工作目录 |
766
- | `minScore` | `120` | PG-07 过关线,整数 0..150;唯一 owner |
767
- | `toolsMode` | `all` | `all` 注册 28 个工具;`core` 只注册 10 个,其余走 `/novel admin` |
768
- | `briefsOverrides` | 空 | 自定义任务书目录;某阶段文件缺失时回退包内 `briefs/<阶段>.md` |
769
- | `backupRetention` | `5` | 保留的归档备份目录数;只清理引擎自己创建的 `backups/<txid>` |
770
- | `stateDir` | 空 → `~/.dsh/novel-write-engine` | 多项目注册表与会话绑定位置;**不要放进项目目录** |
495
+ | 键 | 默认 | 说明 |
496
+ | --- | --- | --- |
497
+ | `projectRoot` | `./novel` | 无会话绑定/工作区/唯一项目时的兜底根 |
498
+ | `minScore` | `120` | PG-07 过关线,整数 0..150 |
499
+ | `toolsMode` | `all` | `all` 注册 28 个工具;`core` 只注册 10 个 |
500
+ | `briefsOverrides` | 空 | 自定义任务书目录;缺文件时回退包内 `briefs/<阶段>.md` |
501
+ | `backupRetention` | `5` | 保留的归档备份目录数 |
502
+ | `stateDir` | 空 → `~/.dsh/novel-write-engine` | 多项目注册表与会话绑定位置;不要放进项目目录 |
771
503
 
772
- > `stateDir` 的默认值是代码按当前用户 home 拼出的 `~/.dsh/novel-write-engine`,不跟随 `DSH_HOME`。如果你改了 `DSH_HOME`,建议显式把它设成绝对路径。
773
- >
774
- > 非法值不会静默改写:`toolsMode` 不是 `all|core`、`minScore` 越界、`backupRetention < 1` 都会让插件拒绝启动。
504
+ 非法值不会静默改写:`toolsMode` 不是 `all|core`、`minScore` 越界、`backupRetention < 1` 都会让插件拒绝启动。
775
505
 
776
- ### 9.2 在哪里改
506
+ ### 在哪里改
777
507
 
778
- 不要改 `node_modules` 里的 `cordis.patch.yml`,也不要在项目目录里放「插件配置」。正确位置是**你启动的那个 profile 的用户 patch**:
508
+ 不要改 `node_modules` 里的 `cordis.patch.yml`,也不要在项目目录里放“插件配置”。正确位置是启动 profile 的用户 patch:
779
509
 
780
510
  ```text
781
511
  $DSH_HOME/profiles/<profile>/cordis.patch.yml
@@ -787,7 +517,7 @@ $DSH_HOME/profiles/<profile>/cordis.patch.yml
787
517
  ~/.dsh/profiles/web/cordis.patch.yml
788
518
  ```
789
519
 
790
- 在文件末尾追加(如果已经有同 `id` 的覆盖项,就改那一条,不要重复):
520
+ 追加或修改同 `id` 的覆盖项:
791
521
 
792
522
  ```yaml
793
523
  - id: novel-write-engine
@@ -801,53 +531,17 @@ $DSH_HOME/profiles/<profile>/cordis.patch.yml
801
531
  stateDir: /home/me/.dsh-novel-state
802
532
  ```
803
533
 
804
- Windows 路径:
805
-
806
- ```yaml
807
- - id: novel-write-engine
808
- name: dsh-novel-write-engine
809
- config:
810
- projectRoot: D:/novels
811
- minScore: 125
812
- toolsMode: all
813
- briefsOverrides: ''
814
- backupRetention: 5
815
- stateDir: C:/Users/you/.dsh/novel-write-engine
816
- ```
817
-
818
- **patch 会替换整行 config**。因此:
819
-
820
- - 你想保留默认值的键可以省略(schema 会填默认值);
821
- - 但不要把「只改一个键」理解成深合并;
822
- - 最稳妥的写法是把你关心的键都写全;
823
- - 改完重启 DSH(或让 HMR 重载),再新开会话验证。
824
-
825
- ### 9.3 任务书覆盖
826
-
827
- `briefsOverrides` 指向一个目录,里面按阶段放:
828
-
829
- ```text
830
- P1.md
831
- P2.md
832
- P3.md
833
- P4.md
834
- P5.md
835
- P6.md
836
- P8.md
837
- ```
838
-
839
- 某个文件不存在时,该阶段回退到包内 `briefs/` 的版本;不会因为缺一个文件而整体失效。任务书内容会参与 PG-01 的 digest,改任务书等于改门控输入,最好在开新书前确定。
534
+ **patch 会替换整行 config**:想保留默认值的键可以省略;不要把“只改一个键”理解成深合并。改完重启 DSH 或让 HMR 重载,再新开会话验证。
840
535
 
841
- ### 9.4 规则包不能运行期切换
536
+ ### 任务书覆盖
842
537
 
843
- `rulepacks/default.yaml` 是随包加载的:词表、格式、标点、语义、跨章阈值、平台默认值都在里面。0.2.x **不接受**运行期外部规则包路径。
538
+ `briefsOverrides` 指向一个目录,里面按阶段放 `P1.md` 到 `P6.md`、`P8.md`。某个文件不存在时,该阶段回退到包内版本,不会因为缺一个文件而整体失效。
844
539
 
845
- 要改规则,只有两条路:
540
+ 任务书内容参与 PG-01 的 digest,改任务书等于改门控输入,最好在开新书前确定。
846
541
 
847
- 1. 改源码里的 `rulepacks/default.yaml`,重新 `corepack pnpm build`;源码目录安装重启即可,tarball 分发则重新打包/安装;
848
- 2. 等后续版本提供正式的规则包覆盖机制。
542
+ ### 规则包
849
543
 
850
- 改规则后至少跑:
544
+ `rulepacks/default.yaml` 是随包加载的:词表、格式、标点、语义、跨章阈值、平台默认值都在里面。0.2.x **不接受**运行期外部规则包路径。要改规则,只能改源码后重新构建/打包;改完至少跑:
851
545
 
852
546
  ```bash
853
547
  corepack pnpm build
@@ -859,14 +553,17 @@ corepack pnpm test
859
553
 
860
554
  ---
861
555
 
862
- ## 十、数据、备份与状态
556
+ ## 数据与安全
863
557
 
864
- ### 10.1 项目布局
558
+ ### 项目布局
865
559
 
866
560
  ```text
867
561
  <projectRoot>/
868
562
  ├── novel.yaml # 项目定义(书名、类型、平台、目标)
869
- ├── outline/ # 卷/幕/章规划
563
+ ├── outline/
564
+ │ ├── outline.yaml # 蓝图 / 卷 / 章卡
565
+ │ ├── worldbook.yaml # 世界观设定集
566
+ │ └── outline.deprecated.yaml # 上一版大纲(一级回退副本)
870
567
  ├── chapters/chapter-001.md # 正文(唯一 SSOT)
871
568
  ├── plans/chNNN.world.yaml # P1
872
569
  ├── plans/chNNN.chapter.yaml # P2
@@ -874,7 +571,7 @@ corepack pnpm test
874
571
  ├── checks/chNNN.check.yaml # P6
875
572
  ├── state/
876
573
  │ ├── pipeline.yaml # 控制流 SSOT
877
- │ ├── chapters.yaml # 章节索引
574
+ │ ├── chapters.yaml
878
575
  │ ├── characters.yaml
879
576
  │ ├── world.yaml
880
577
  │ ├── locks.yaml
@@ -882,9 +579,11 @@ corepack pnpm test
882
579
  │ ├── foreshadows.yaml
883
580
  │ ├── relationships.yaml
884
581
  │ ├── handoff.yaml
885
- │ ├── archive-digests.json # 内部归档幂等账本(journal 跟踪)
582
+ │ ├── briefs.yaml # 任务书收据(append-only)
583
+ │ ├── archive-digests.json # 内部归档幂等账本
886
584
  │ └── journal.jsonl # 追加式事务日志
887
- ├── backups/<txid>/ # 归档前快照
585
+ ├── history/ # 评审/校验/正文/计划历史版本
586
+ ├── backups/<txid>/ # 归档前快照 + manifest
888
587
  ├── exports/ # 导出产物
889
588
  └── .engine.lock # 写锁(pid + 时间戳)
890
589
  ```
@@ -895,139 +594,46 @@ corepack pnpm test
895
594
  - `journal.jsonl` 是追加式审计;`novel_audit` 读它。
896
595
  - 备份只清理引擎自己创建的 `backups/<txid>`;你自己放进 `backups/` 的文件不会被删。
897
596
 
898
- ### 10.2 多项目注册表
597
+ ### 事务与备份
899
598
 
900
- 默认:
599
+ - 归档、修订、恢复、大纲写入都走事务:staging → 校验 → 备份 → pending journal → rename → 读回 → committed journal。
600
+ - `backupRetention` 控制保留数量,默认 5;`backups/migrations/` 不参与 retention prune。
601
+ - 崩溃后引擎按 journal 恢复或拒绝半迁移;`.staging` 会清理,pending 会分类为 complete/untouched/partial。
602
+ - `novel_restore` 只恢复活动章、大纲或损坏 pipeline;已归档章先 `novel_reopen`。
603
+ - 备份是引擎事务快照,不是外部备份。磁盘损坏、误删整目录、手动 `rm -rf` 不在保护范围;重要书稿请另做文件级备份。
901
604
 
902
- ```text
903
- ~/.dsh/novel-write-engine/projects.yaml
904
- ```
905
-
906
- `projects.yaml` 只记录项目路径、标题、可选 `created_at` 与 `active`;`session-bindings.yaml` 按 DSH `SessionId` 记录显式选择。两者都**不保存正文**,删掉不会删任何书。面板用 projects/active/配置找默认项目,不读会话绑定。
605
+ ### 手工修改的边界
907
606
 
908
- ### 10.3 手工修改的边界
909
-
910
- - 正文可以读,但不建议手改;正文一改,评审分数、check、content hash 都会失效。
607
+ - 正文可以读,但**不建议手改**;正文一改,评审分数、check、content hash 都会失效。
911
608
  - `state/` 不要手改;要改就用 `novel_amend`,它要求 `reason` 并写入 journal。
912
- - 要回退阶段用 `novel_rollback`;它只允许退回当前阶段或更早,会保留正文为参考,清空轮次;任务书收据留在 state/briefs.yaml,digest 仍匹配时可复用。
913
- - plan/review/check 损坏时,status 的 `state_errors` 会指出文件;不要手改。当前阶段晚于重建点时先 `novel_rollback`;已经处在 P2/P4/P6 时直接重新取 brief,再用对应阶段工具重建。八个 ledger、`novel.yaml` 或 outline/worldbook 损坏时,`novel_state` 返回 raw,按 `next` 调 `novel_amend` 修复;当前所有不可读状态文档的 journal hash 会被豁免,其他可读文件的外部改动仍 fail-closed。
609
+ - 要回退阶段用 `novel_rollback`;它只允许退回当前阶段或更早,会保留正文为参考,清空轮次。
914
610
  - 不要在引擎运行时删 `.engine.lock`;锁由引擎回收,手删可能让两个写者同时进入。
915
611
 
916
- ### 10.4 备份与恢复
612
+ ### 安全边界
917
613
 
918
- - 归档等事务会生成 `backups/<txid>/`;
919
- - `backupRetention` 控制保留数量,默认 5;
920
- - 事务日志会记录 pending/committed;崩溃后引擎按 journal 恢复或拒绝半迁移;
921
- - 要手动保底,最稳妥的是在升级前复制整个项目目录,或在 DSH 外做文件快照。
614
+ - **运行在宿主进程里**:Host 半边在 DSH 进程内执行,不受工作区沙箱限制。安装本插件等于允许它在 DSH 进程权限下读写你给它的项目目录和 `stateDir`。
615
+ - **不向外联网**:Host 侧没有 `fetch`、HTTP 客户端或遥测;运行期依赖只有 `yaml`。它不读取环境变量里的 API Key,也不会把正文发到第三方服务。
616
+ - **面板只读**:`/api/novel-write-engine/panel` 只接受 `GET`/`HEAD`,复用 DSH connection 的认证与 Origin 校验;项目选择器只改 `?root=` 与浏览器 `localStorage`。
617
+ - **安装来源**:优先从 npm 官方 registry 安装,并核对包名、发布者与版本;离线环境用自己构建的 tarball 并记录 SHA-256。不要从聊天记录里复制来路不明的 Git 地址并给 `allowBuilds` 授权。
922
618
 
923
619
  ---
924
620
 
925
- ## 十一、升级
926
-
927
- ### 11.0 从 0.2.3 升级到 0.2.4
928
-
929
- 0.2.4 不迁移 `outline.yaml` 数据,只反转 `novel_outline` 的写入口语义:
930
-
931
- 1. `chapters` 按 `num`、`volumes` 按 `title` upsert;省略的卡保持不动,不再被删除。
932
- 2. 删除必须显式 `remove` / `remove_volumes`;活动章、归档章、不存在的卡和已完成卷会被拒绝。
933
- 3. `dry_run:true` 可预演 `would_add/would_update/would_remove`;成功返回 `added/updated/removed`。
934
- 4. `novel_outline` 正常写入会保留 `outline/outline.deprecated.yaml`;`novel_restore {txid, paths:["outline/outline.yaml"]}` 可恢复整份大纲(要求与当前章索引一致)。
935
- 5. `novel_blueprint` 的卷列表仍是 replace;删卷必须 `confirm_remove:true`。
936
- 6. 同名卷会被新写入拒绝;老项目若已有同名卷,先用 `novel_amend` 改名再提交 volumes(只读加载仍兼容)。
937
-
938
- ### 11.0 从 0.2.2 升级到 0.2.3
939
-
940
- 0.2.3 不迁移项目数据,只改变读模型、面板 wire 版本与项目卫生:
941
-
942
- 1. **面板 payload v6**:旧标签页显示刷新;刷新后是书桌式布局、分组项目选择器和独立的提示/旧数据区。
943
- 2. **report 口径**:旧章 effort 从 journal 回填,quality 每章只算最终评审;`samples` 是章数,`attempts` 是 committed 评审轮次(含历史),样本不足时 `trend` 为 `null`。
944
- 3. **briefs 按章**:`pipeline.briefs` 只显示当前章;`novel_state {kind:"briefs"}` 仍保留全书收据。
945
- 4. **归档失败**:`ready_to_archive` 可以直接 `novel_revise` 回 P4,不需要先 rollback。
946
- 5. **advisory**:同章同 code 只显示一条并合并证据;`RESOURCE_MISMATCH` 不再因中文省略符号误报。
947
- 6. **项目卫生**:`/novel projects --prune` 默认只列失效登记,`--yes` 才删登记行;`check:host` 不再写真实注册表。
948
-
949
- ### 11.0.1 从 0.2.1 升级到 0.2.2
950
-
951
- 0.2.2 不迁移项目数据,但改变多项目选择与面板契约:
952
-
953
- 1. **面板 payload v4**:旧标签页显示刷新;刷新后出现项目选择器、choose/missing 状态和复制续写按钮。
954
- 2. **`lastRoot` 删除**:工具不再跟随进程内“最近碰过谁”。A/B 会话分别绑定、重启后仍在;显式 `project_root` 成功后写入 `session-bindings.yaml`。
955
- 3. **`active` 降级**:只影响面板默认与无 Agent 调用;有 Agent 且多项目无上下文时返回歧义,不静默选 active。
956
- 4. **`novel_init` 省略 root**:只使用配置 `projectRoot`,不读会话绑定/工作区/active;创建成功后才绑定当前会话。
957
- 5. **项目删除/移动/替换 fail-closed**:返回 MISSING/IDENTITY_MISMATCH,不自动回退、不自动重建、不清登记与绑定。
958
- 6. **新增命令**:`/novel projects|current|use|unbind|scan|resume`;`scan`/`resume` 不是新工具,工具仍 28、操作仍 32。
959
- 7. **面板完整卷**:0.2.1 只显示前 8 卷的 UI 截断已修复;全部卷在滚动容器中展示。
960
-
961
- 回滚到 0.2.1 时,`session-bindings.yaml` 被旧版忽略;旧版恢复 `lastRoot` 行为。注册表新增的 `created_at` 对旧版可忽略。
962
-
963
- ### 11.0.1 从 0.2.0 升级到 0.2.1
964
-
965
- 0.2.1 不迁移项目数据,但改变几处契约:
966
-
967
- 1. **面板 payload v3**:旧标签页会显示刷新提示;刷新即可。面板根容器现在自己是滚动区,长内容不再被裁掉。
968
- 2. **P2 计划不可变**:`plans/chNNN.chapter.yaml` 不再写 `summary`;旧项目仍回退读它。新摘要/标题/场景/叙述者进入 `state/pipeline.yaml` 的 `draft`,`novel_write_draft`/`novel_revise` 后以它为准。
969
- 3. **评分与证据历史**:评审/校验/正文/废弃稿按 revision 写入 `history/`;`novel_report` 的维度样本会变多,`ChapterRecord` 保存 lifetime rounds(含 rollbacks)/final_check/archived_at,这是历史证据而不是统计错误。amend 不能改写这些字段。
970
- 4. **审计更完整**:通过参数形状校验、进入项目锁后被 gate/delta/state 拒绝的调用会出现在 `novel_audit`,状态为 `aborted`、`attempt:true` 并带 code;事务失败/崩溃恢复的 aborted 行也带 code;锁前纯参数错误不写 journal。
971
- 5. **检查文档分层**:advisory 进入 `machine.advisories`,不再混入 `violations`;用 `acknowledge` 记录知悉,blocker 不能 acknowledge。数字矛盾固定 advisory,数字事实只匹配相邻的“别名+数字+单位”。
972
- 6. **新工具 `novel_restore`**:从 `novel_state {kind:"backups"}` 列出的 txid 恢复活动章的正文/计划/世界观计划/评审/校验;P2/P4/P6 在第二次提交起会留下 pre-image。恢复本身再建备份且不 replay;已归档章先 `novel_reopen`。
973
- 7. **修订可 patch**:`novel_revise` 可传 `patch:{expected_hash,edits}` 代替整章;hash 不匹配、锚点不唯一或编辑重叠都会拒绝。
974
- 8. **字数有分解**:`total_word_count` 仍含标点;新字段 `punctuation_chars` 与 PG-03 分解让口径可见。
975
- 9. **大纲覆盖率改口径**:规划覆盖 = 章卡数 / 目标章数,归档覆盖 = 归档卡数 / 目标章数;`card_coverage` 是逐章“有 archived 卡”的比例;缺卡数单独输出。
976
- 10. **worldbook facts**:新增声明式数字事实,进入计数、brief 上下文、搜索与 P6 检查;`facts` 只做作者声明的 canon 对账,不等同外部史实库。
977
- 11. **伏笔 anchor**:可读 `title` 与逐字 `anchor` 分离,anchor 至少 8 个字符;单字子串不再能绕过校验。
978
-
979
- ### 11.0.2 从 0.1.3 升级到 0.2.0
621
+ ## 升级与卸载
980
622
 
981
- 0.2.0 新增 `outline/outline.yaml` 与 `outline/worldbook.yaml`,新增 9 个工具与 PG-13;旧项目缺少两份规划文档时按空规划读取,不会报错。新项目默认写入两份空文档;严格大纲默认关闭,`novel_outline` 首次提交才开启。P6 语义项从 4 条变 5 条(新增 `L2-POV`),旧的 4 条 check 需要重跑。面板 payload v1 → v2,旧标签页显示刷新。所有升级后第一次取 brief 会因上下文新增 `book_plan`/`outline_card`/`worldbook` 而失效,重新 `novel_brief` 即可。
623
+ ### 升级到 0.2.7
982
624
 
983
- 需要知道的行为变化:
984
-
985
- 1. **损坏台账可修**:八个 ledger 或 outline/worldbook 损坏时 status/panel 仍可读;`novel_state` 返回 `raw`,用 `novel_amend` 修复。amend 会为当前所有不可读状态文档豁免 journal 的既有 hash;真正可读文件的外部改动仍 fail-closed。
986
- 2. **chapters 不变量**:amend 不能删已归档章、不能改 `content_hash`/`archive_digest`;有章节文件时还会核对 hash。
987
- 3. **P2 cast 可选**:旧 plan 没有 `cast` 仍可读;新 plan 可传 1–8 人,P3 会把这些人物的完整卡放进上下文。
988
- 4. **chapters 查询变紧凑**:`novel_state {kind:"chapters"}` 默认不再带 summary;需要完整摘要加 `include_summary:true` 或 `chapter_range`。
989
- 5. **单 scope check 不再归档**:只跑 content 或 integrity 的 check 通过后停留 P6,并附 `CHECK_SCOPE_PARTIAL`;必须再跑完整 scope。
990
- 6. **handoff 派生**:归档不再每章重算 `ceil(chapter/20)`;volume/volume_name 继承上一章,act/act_progress 从上一章推进,`handoff.act`/`act_progress` 可覆盖。
991
- 7. **panel 上限 30 行**:长书面板只送最近 30 章,统计仍用全书总数。
992
-
993
- ### 11.0.2 从 0.1.1 升级到 0.1.2
994
-
995
- 0.1.2 不 bump schema,也不改工具名/参数;但它会主动让三类旧状态暴露出来:
996
-
997
- 1. **旧 brief 失效**:`context_meta` 进入 digest,升级后第一次调用会要求重新 `novel_brief`;这是预期行为,不是状态损坏。
998
- 2. **旧 review 无 digest**:0.1.1 之前生成、没有 `pipeline.review_digest` 的 review 会被归档拒绝;重新 `novel_review` 后再归档。
999
- 3. **损坏的 plan/review/check 不再静默**:status 会显示 `state_errors`;当前阶段晚于 P2/P4/P6 时 `next` 指向 `novel_rollback`,已经到达重建点时直接给出 brief 与阶段修复工具,不需要手改文件。
1000
-
1001
- ### 11.1 升级前
1002
-
1003
- 1. 看 [CHANGELOG.md](CHANGELOG.md) 和 DSH 的版本要求;
1004
- 2. 确认 `dsh --version` 仍满足插件 `engines.dsh`;
1005
- 3. 复制一份项目目录(或至少确认 `backups/` 完整);
1006
- 4. 升级后新开会话验证,不要指望旧会话立刻换工具定义。
1007
-
1008
- ### 11.2 从 npm 升级(正式分发,推荐)
625
+ 0.2.7 没有 schema、工具、阶段、门控、导出或配置键变更,不需要迁移项目文件。
1009
626
 
1010
627
  ```bash
1011
- # 在目标 profile 里升级到最新版
1012
628
  dsh plugin --profile web remove dsh-novel-write-engine
1013
- dsh plugin --profile web add dsh-novel-write-engine@latest
1014
- ```
1015
-
1016
- 也可以固定版本:
1017
-
1018
- ```bash
1019
- dsh plugin --profile web add dsh-novel-write-engine@0.2.6
629
+ dsh plugin --profile web add dsh-novel-write-engine@0.2.7
1020
630
  ```
1021
631
 
1022
- 升级后核对:
1023
-
1024
- ```bash
1025
- dsh --profile web --dump-config | grep -A6 '# == dsh-novel-write-engine'
1026
- ```
632
+ 升级后刷新页面、新开会话。面板教程版本从 0.2.6 升到 0.2.7;旧标签页显示“需要刷新”时刷新即可。
1027
633
 
1028
- > profile 的依赖由 pnpm 管理。不要在 `~/.dsh/profiles/web` 里直接 `npm update` 或手改 `package.json`/锁文件;那会绕开 `dsh.profile.bundles` 的激活逻辑,出现“包装了但插件没启用”。统一用 `dsh plugin remove` + `add`,或在插件页点 **更新**。
634
+ 历史版本的升级说明见 [CHANGELOG.md](CHANGELOG.md)。0.2.7 不再在 `main` 保留旧版方案与验收稿;需要溯源时使用对应发布 tag 或 Release 快照。
1029
635
 
1030
- ### 11.3 从源码目录升级
636
+ ### 从源码目录升级
1031
637
 
1032
638
  ```bash
1033
639
  cd /path/to/dsh-novel-write-engine
@@ -1038,165 +644,55 @@ corepack prepare pnpm@11.28.9 --activate
1038
644
  corepack pnpm install
1039
645
  corepack pnpm build
1040
646
 
1041
- # 先移除旧链接,再装新目录(同一路径时,remove + add 最干净)
1042
647
  dsh plugin --profile web remove dsh-novel-write-engine
1043
648
  dsh plugin --profile web add "$PWD"
1044
649
  ```
1045
650
 
1046
- 然后重启 DSH,或刷新 Web 页面并新开会话。
1047
-
1048
- ### 11.4 从 tarball 升级
1049
-
1050
- 先构建新 tarball:
1051
-
1052
- ```bash
1053
- corepack pnpm build
1054
- corepack pnpm pack
1055
- ```
1056
-
1057
- 再:
1058
-
1059
- ```bash
1060
- dsh plugin --profile web remove dsh-novel-write-engine
1061
- dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.2.6.tgz
1062
- ```
1063
-
1064
- ### 11.5 在 Web / Desktop 里升级
1065
-
1066
- 从 npm 安装的 bundle 会在插件页出现 **版本** 区块和 **更新** 按钮;源码目录(`link:`)和 tarball(`file:`)不属于这一类,页面不会给「更新」。两种路径分别是:
1067
-
1068
- **npm 安装:**
1069
-
1070
- 1. 插件页 → 打开 `dsh-novel-write-engine`;
1071
- 2. 点 **更新到 x.y.z**;
1072
- 3. 刷新页面,新开会话。
1073
-
1074
- **源码目录 / tarball:**
1075
-
1076
- 1. 插件页 → 打开 `dsh-novel-write-engine` → **卸载**;
1077
- 2. **添加插件** → 填新的目录或 tarball → 安装 → 启用;
1078
- 3. 刷新页面,新开会话。
1079
-
1080
- 插件页更新底层仍然是「移除旧版本 → 安装新版本 → 失败则恢复旧版本」。
1081
-
1082
- ### 11.6 升级配置会保留吗
1083
-
1084
- 用户配置写在 profile 的 `cordis.patch.yml`,不在包内。`remove`/`add` 不会删除它;只要新版本仍然使用 `id: novel-write-engine`,覆盖项继续生效。
1085
-
1086
- 升级后仍建议检查:
1087
-
1088
- ```bash
1089
- dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
1090
- ```
1091
-
1092
- ### 11.7 升级 DSH 本身
1093
-
1094
- - `npx`:每次运行可加 `@latest`,例如 `npx @deepseek-ai/dsh@latest web`;
1095
- - 全局:`npm update -g @deepseek-ai/dsh`;
1096
- - 源码:`git pull && corepack pnpm install && corepack pnpm run build`;
1097
- - Desktop:用官方安装包或应用内更新。
1098
-
1099
- DSH 升级后如果 `engines.dsh` 不再匹配,插件会被拒绝。此时升级插件,或把 DSH 降到兼容版本;不要用「改 package.json 绕过」当长期方案。
1100
-
1101
- ---
1102
-
1103
- ## 十二、卸载
1104
-
1105
- ### 12.1 在 Web / Desktop 卸载
1106
-
1107
- 1. 左侧栏 → **插件**;
1108
- 2. 打开 **dsh-novel-write-engine**;
1109
- 3. 点 **卸载**,确认;
1110
- 4. 刷新页面;
1111
- 5. 新开会话确认 `novel_*` 工具与「网文工坊」预设消失。
651
+ 源码目录是 link 关系,必须重新 `pnpm build` 才会加载新 `lib/`。
1112
652
 
1113
- ### 12.2 用 CLI 卸载
1114
-
1115
- 建议先停止 DSH(尤其是没有 HMR 的 profile):
653
+ ### 卸载
1116
654
 
1117
655
  ```bash
1118
656
  dsh plugin --profile web remove dsh-novel-write-engine
1119
657
  ```
1120
658
 
1121
- 如果 DSH 正在运行且 profile 支持 HMR,也可以在运行时移除;以插件页/CLI 的提示为准。若提示当前 profile 正在使用该包,停止 DSH 后重试。
1122
-
1123
- > `dsh plugin remove` 只从 profile 移除插件层,不会删除你的小说项目、`stateDir` 注册表或备份。
1124
-
1125
- 卸载会:
1126
-
1127
- - 从 profile 的 `dsh.profile.bundles` 移除该层;
1128
- - 从 `dependencies` 移除包;
1129
- - 停止并卸载它的 Host 行与 client 面板;
1130
- - **不会**删除你的小说项目、`stateDir` 注册表或备份。
1131
-
1132
- ### 12.3 清理配置覆盖
1133
-
1134
- 如果你在 profile 的 `cordis.patch.yml` 里加过:
1135
-
1136
- ```yaml
1137
- - id: novel-write-engine
1138
- name: dsh-novel-write-engine
1139
- config: ...
1140
- ```
1141
-
1142
- 卸载后把这一段删掉。否则它会成为一个指向不存在行的用户 patch;不同 DSH 版本对这种情况的提示可能不同,清掉最干净。
659
+ 卸载只会移除 profile 里的插件层、Host 行与 client 面板,**不会删除**你的小说项目、`stateDir` 注册表或备份。
1143
660
 
1144
- ### 12.4 清理数据(可选)
661
+ 如果你在 profile 的 `cordis.patch.yml` 里加过 `id: novel-write-engine` 的覆盖项,卸载后把这段删掉,避免留下指向不存在行的用户 patch。
1145
662
 
1146
- 卸载插件不会删书。确认不再需要后,再手动清理:
663
+ 确认不再需要后,可手动清理注册表(不影响书):
1147
664
 
1148
665
  ```bash
1149
- # 多项目注册表与会话绑定(只影响选择/查看,不影响书)
1150
666
  rm -rf "$HOME/.dsh/novel-write-engine"
1151
-
1152
- # 某个项目(先确认路径!)
1153
- rm -rf "/absolute/path/to/your/novel-project"
1154
- ```
1155
-
1156
- Windows PowerShell:
1157
-
1158
- ```powershell
1159
- Remove-Item -Recurse -Force "$HOME\.dsh\novel-write-engine"
1160
- Remove-Item -Recurse -Force "D:\novels\your-book"
1161
667
  ```
1162
668
 
1163
- **不要**为了卸载本插件去删整个 `~/.dsh`:那里还有 DSH 的配置、凭据、会话和其他插件。
1164
-
1165
- ### 12.5 验证卸载
1166
-
1167
- ```bash
1168
- dsh --profile web --dump-config | grep dsh-novel-write-engine
1169
- # 应无输出
1170
- ```
1171
-
1172
- 新开会话:面板入口消失,预设列表里没有「网文工坊」,`/novel` 不再被识别。
669
+ 不要为了卸载插件去删整个 `~/.dsh`:那里还有 DSH 的配置、凭据、会话和其他插件。
1173
670
 
1174
671
  ---
1175
672
 
1176
- ## 十三、故障排查
1177
-
1178
- | 现象 | 最可能的原因 | 处理 |
1179
- | --------------------------------- | -------------------------------------------------- | ----------------------------------------------------------------------- |
1180
- | `dsh plugin add` 404 / 找不到包 | 包名拼错、registry 不可达,或镜像尚未同步 | 确认 `npm view dsh-novel-write-engine version`;必要时切回官方 registry |
1181
- | `npm install` 成功但 DSH 没有插件 | `npm install` 不会把插件加入 profile | 执行 `dsh plugin --profile web add dsh-novel-write-engine`,见 5.1 |
1182
- | `dsh: command not found` | CLI 未全局安装 | 用 `npx @deepseek-ai/dsh ...`,或先 `npm i -g @deepseek-ai/dsh` |
1183
- | `dsh plugin` 报找不到 pnpm | 只装了 DSH,没装 pnpm | `corepack enable && corepack prepare pnpm@11.28.9 --activate` |
1184
- | `--dump-config` 没有插件层 | 装到了别的 profile | 用实际启动的 profile 重装;`dsh --profile <name> ...` |
1185
- | 插件页显示已安装但开关打不开 | 包不完整/版本不兼容/被更高层覆盖 | 看插件页诊断;用 tarball 重装;检查 `engines.dsh` |
1186
- | 侧边栏没有「网文工坊」 | 不是 Web/Desktop profile,或 client bundle 未加载 | 用 `dsh web` / Desktop;刷新;重启 |
1187
- | 预设列表没有「网文工坊」 | headless/acp/sdk 没有 `agentPresets`,或插件未启用 | 改用 Web;插件页启用;新开会话 |
1188
- | 会话里没有 `novel_*` 工具 | 插件未启用、旧会话未刷新、装错 profile | 新开会话;重启;`--dump-config` 核对 |
1189
- | `ENGINE_STAGE_ORDER` | 跳过了阶段或顺序不对 | `/novel` / `novel_status` 看下一步;按 `novel_brief` 领任务书 |
1190
- | `ENGINE_GATE_BLOCKED` | 门控未过 | 看 `blocking` 的 code/detail/hint;改正文或补证据;不要手改 state |
1191
- | `ENGINE_PROJECT_NOT_FOUND` | 项目根不对/未初始化 | `/novel scan` 发现项目;`novel_init`,或传正确的 `project_root` |
1192
- | `ENGINE_PROJECT_AMBIGUOUS` | 有多个项目,无法从会话/cwd 唯一确定 | `/novel use <path|title>` 或传 `project_root`;不会默认 active |
1193
- | `ENGINE_PROJECT_MISSING` | 当前会话绑定的目录被删除/未挂载 | 恢复目录后重试;或显式 `/novel use <新路径>`;不会自动换书 |
1194
- | `ENGINE_PROJECT_IDENTITY_MISMATCH`| 原路径已被另一本书占用,`created_at` 不同 | 确认后用 `/novel use` 重新绑定;旧绑定仍 fail-closed |
1195
- | 面板空白/显示没有项目 | 当前没有项目,或 active 指向旧路径 | 先 `novel_init`;多项目时用面板选择器或 `/novel use` 选择 |
1196
- | 面板显示「需要刷新」 | 浏览器缓存了旧 client bundle | 刷新页面;重启 DSH |
1197
- | 升级后仍是旧行为 | 源码目录没 `corepack pnpm build`,或旧会话未换 | 重新构建;重启;新开会话 |
1198
- | 卸载后配置项还在 | profile 的 `cordis.patch.yml` 还留着覆盖 | 删除 `id: novel-write-engine` 的段落 |
1199
- | `EACCES` / 写入失败 | 项目根或 `stateDir` 对 DSH 进程不可写 | 改权限,或换可写路径 |
673
+ ## 故障排查
674
+
675
+ | 现象 | 最可能的原因 | 处理 |
676
+ | --- | --- | --- |
677
+ | `dsh plugin add` 404 / 找不到包 | 包名拼错、registry 不可达,或镜像未同步 | `npm view dsh-novel-write-engine version`;必要时切回官方 registry |
678
+ | `npm install` 成功但 DSH 没有插件 | `npm install` 不会把插件加入 profile | 用 `dsh plugin --profile web add dsh-novel-write-engine` |
679
+ | `dsh: command not found` | CLI 未全局安装 | 用 `npx @deepseek-ai/dsh ...`,或先 `npm i -g @deepseek-ai/dsh` |
680
+ | `dsh plugin` 报找不到 pnpm | 只装了 DSH,没装 pnpm | `corepack enable && corepack prepare pnpm@11.28.9 --activate` |
681
+ | `--dump-config` 没有插件层 | 装到了别的 profile | 用实际启动的 profile 重装;`dsh --profile <name> ...` |
682
+ | 侧边栏没有「网文工坊」 | 不是 Web/Desktop profile,或 client bundle 未加载 | 用 `dsh web` / Desktop;刷新;重启 |
683
+ | 预设列表没有「网文工坊」 | headless/acp/sdk 没有 `agentPresets`,或插件未启用 | 改用 Web;插件页启用;新开会话 |
684
+ | 会话里没有 `novel_*` 工具 | 插件未启用、旧会话未刷新、装错 profile | 新开会话;重启;`--dump-config` 核对 |
685
+ | `ENGINE_STAGE_ORDER` | 跳过了阶段或顺序不对 | `/novel` / `novel_status` 看下一步;按 `novel_brief` 领任务书 |
686
+ | `ENGINE_GATE_BLOCKED` | 门控未过 | 看 `blocking` 的 code/detail/hint;改正文或补证据;不要手改 state |
687
+ | `ENGINE_PROJECT_NOT_FOUND` | 项目根不对/未初始化 | `/novel scan` 发现项目;`novel_init`,或传正确的 `project_root` |
688
+ | `ENGINE_PROJECT_AMBIGUOUS` | 有多个项目,无法从会话/cwd 唯一确定 | `/novel use <path|title>` 或传 `project_root` |
689
+ | `ENGINE_PROJECT_MISSING` | 当前会话绑定的目录被删除/未挂载 | 恢复目录后重试;或显式 `/novel use <新路径>` |
690
+ | `ENGINE_PROJECT_IDENTITY_MISMATCH` | 原路径已被另一本书占用,`created_at` 不同 | 确认后用 `/novel use` 重新绑定 |
691
+ | 面板空白/显示没有项目 | 当前没有项目,或 active 指向旧路径 | 先 `novel_init`;多项目时用面板选择器或 `/novel use` |
692
+ | 面板显示「需要刷新」 | 浏览器缓存了旧 client bundle | 刷新页面;重启 DSH |
693
+ | 升级后仍是旧行为 | 源码目录没 `pnpm build`,或旧会话未换 | 重新构建;重启;新开会话 |
694
+ | 卸载后配置项还在 | profile 的 `cordis.patch.yml` 还留着覆盖 | 删除 `id: novel-write-engine` 的段落 |
695
+ | `EACCES` / 写入失败 | 项目根或 `stateDir` 对 DSH 进程不可写 | 改权限,或换可写路径 |
1200
696
 
1201
697
  ### 仍然卡住时,提供这四样信息
1202
698
 
@@ -1209,56 +705,24 @@ dsh --profile web --dump-config | grep dsh-novel-write-engine
1209
705
 
1210
706
  ---
1211
707
 
1212
- ## 十四、安全与边界
1213
-
1214
- ### 14.1 它在宿主进程里运行
1215
-
1216
- DSH bundle 的 Host 半边在 DSH 进程内执行,不受工作区沙箱限制。安装本插件等于允许它在 DSH 进程权限下读写你给它的项目目录和 `stateDir`。只从你信任的 npm 包、源码或 tarball 安装。
1217
-
1218
- ### 14.2 它不向外联网
1219
-
1220
- Host 侧没有 `fetch`、HTTP 客户端或遥测;运行期依赖只有 `yaml`。它不读取环境变量里的 API Key,也不会把正文发到任何第三方服务。Web 客户端只会向宿主自己的只读面板路由发同源 `GET`,不访问外部地址;模型调用本身由 DSH 负责,与本插件无关。
1221
-
1222
- ### 14.3 面板是只读的
1223
-
1224
- `/api/novel-write-engine/panel` 只接受 `GET`/`HEAD`,并复用 DSH connection 的认证与 Origin 校验。项目选择器只改 `?root=` 与浏览器 `localStorage`,复制按钮只写剪贴板;它们不能改项目、注册表或会话绑定。所有写操作仍然要经过工具/命令。
1225
-
1226
- ### 14.4 状态文件不是「随便改的 YAML」
1227
-
1228
- `state/` 是引擎的影子层。手改会让 journal 哈希对账失败,后续事务可能拒绝执行。要改状态,用 `novel_amend` 并写原因;要回退,用 `novel_rollback`。
1229
-
1230
- ### 14.5 备份不是万能的
1231
-
1232
- `backups/` 保留的是引擎事务快照,不是外部备份。磁盘损坏、误删整目录、手动 `rm -rf` 都不在它的保护范围。重要书稿请另做文件级备份。
1233
-
1234
- ### 14.6 安装来源
1235
-
1236
- - 优先从 npm 官方 registry 安装,并核对包名、发布者与版本;离线环境可用你自己构建的 tarball,并记录 SHA-256;
1237
- - 不要从聊天记录里复制来路不明的 Git 地址并给 `allowBuilds` 授权;
1238
- - `allowBuilds` 等于允许包在安装时以你的用户权限执行脚本。
1239
-
1240
- ---
1241
-
1242
- ## 十五、已知限制
708
+ ## 已知限制
1243
709
 
1244
- - **书级大纲是 0.2.0 的新数据源**:`outline/outline.yaml` 与 `outline/worldbook.yaml` 由引擎读写;有章卡时 P2/P3 受 PG-13 约束,严格模式还要求章卡存在。大纲是规划层,不替代 `state/` 台账。
1245
710
  - **0.2.x 只有中文**:面板、命令、错误、任务书都是中文;没有 `locale/`,不跟随系统语言。
1246
- - **通过 npm 分发**:安装与升级统一使用 `dsh plugin add`;源码目录和 tarball 用于开发或离线环境。
1247
- - **面板与预设只在 Web/Desktop**:headless / acp / sdk 没有 `agentPresets` 服务,也没有浏览器面板;28 个工具仍可用。
1248
711
  - **规则包不可运行期替换**:要改词表/阈值,必须改源码、重新构建、重新安装。
1249
712
  - **普通会话可能绕过引擎**:只有「网文工坊」预设不挂 bash/fs 写工具;在普通会话里手动改文件,事务与门控保证不再完整。
1250
713
  - **预设会话开始后不能切换**。
1251
- - **同一物理项目请固定一个路径**:注册表按规范化路径(`path.resolve`)去重;同一本书通过符号链接和真实路径分别登记会变成两个 root,可能显示两行或报歧义。请在 `/novel use`/`project_root` 中固定使用其中一个路径。
1252
- - **单章轮次上限 3**:超过需要 `novel_rollback`,不是无限重试。
714
+ - **面板与预设只在 Web/Desktop**:headless/acp/sdk 没有 `agentPresets`,也没有浏览器面板;28 个工具仍可用。
715
+ - **同一物理项目请固定一个路径**:注册表按规范化路径去重;同一本书通过符号链接和真实路径分别登记会变成两个 root。
716
+ - **单章轮次上限 3**:超过需要 `novel_rollback`。
1253
717
  - **面板只读**:没有在面板里直接改正文/归档的按钮。
1254
718
  - **DSH 仍是 developer preview**:`0.3.0` 之前可能有破坏性变更;升级 DSH 前先看插件 `engines.dsh`。
1255
719
  - **没有云同步/多人协作/在线书城**:数据都在本机项目目录与 `stateDir`。
1256
720
 
1257
721
  ---
1258
722
 
1259
- ## 十六、开发与验证
723
+ ## 开发与验证
1260
724
 
1261
- ### 16.1 环境
725
+ ### 环境
1262
726
 
1263
727
  ```bash
1264
728
  corepack enable
@@ -1266,7 +730,7 @@ corepack prepare pnpm@11.28.9 --activate
1266
730
  corepack pnpm install
1267
731
  ```
1268
732
 
1269
- ### 16.2 常用命令
733
+ ### 常用命令
1270
734
 
1271
735
  ```bash
1272
736
  corepack pnpm typecheck # host + client 类型检查
@@ -1290,9 +754,9 @@ DSH_BUNDLE_ROOT=/path/to/deepseek-harness/packages/bundle/web-app corepack pnpm
1290
754
 
1291
755
  `check:preset` 不伪造 bundle root;没有宿主 checkout 时它不会假装通过。
1292
756
 
1293
- `check:host` 使用临时 `DSH_HOME` 与临时 profile:`build → npm pack → dsh plugin add → --dump-config → 启动 Web → 面板 401/200 → 卸载 → 确认层消失`,并断言宿主声明全部 28 个工具。它需要 PATH 里有 `dsh`(或设置 `DSH_BIN`),不会碰你的真实 profile;没有 DSH 时以退出码 2 明确失败,不伪造通过。
757
+ `check:host` 使用临时 `DSH_HOME` 与临时 profile:`build → npm pack → dsh plugin add → --dump-config → 启动 Web → 面板 401/200 → 卸载 → 确认层消失`,并断言宿主声明全部 28 个工具。它需要 PATH 里有 `dsh`(或设置 `DSH_BIN`),不会碰你的真实 profile。
1294
758
 
1295
- ### 16.3 发布前手动验证
759
+ ### 发布前手动验证
1296
760
 
1297
761
  1. `corepack pnpm build && corepack pnpm pack`;
1298
762
  2. 在临时 DSH home 里 `dsh plugin --profile web add <tarball>`;
@@ -1302,9 +766,7 @@ DSH_BUNDLE_ROOT=/path/to/deepseek-harness/packages/bundle/web-app corepack pnpm
1302
766
  6. `dsh plugin remove`,确认层与面板消失;
1303
767
  7. 确认项目数据未被卸载动作删除。
1304
768
 
1305
- `pnpm check:host` 覆盖第 1–4 与第 6 步的自动断言(含 28 个工具的宿主声明、面板 v5 字段与空态结构)。`/novel` 命令的 handler 与路由由 `tests/adapters`、`tests/smoke` 的假宿主覆盖,真实宿主命令路由仍属于第 4 步的人工确认;第 5 步也是人工全流程(需要可用模型)。
1306
-
1307
- ### 16.4 项目结构
769
+ ### 项目结构
1308
770
 
1309
771
  ```text
1310
772
  src/
@@ -1324,66 +786,31 @@ presets/ # 内置 Agent 预设 patch
1324
786
  tests/ # 单测、集成、falsify、e2e
1325
787
  ```
1326
788
 
1327
- ### 16.5 当前验证基线
1328
-
1329
- 0.2.6 在 Node 24.19 / DSH 0.2.1-rc.3 上完成:
789
+ ### 本次 0.2.7 验证
1330
790
 
1331
- - `npm test` 全绿:**90 个测试文件 / 906 项**;
1332
- - 覆盖率:**语句 93.51% / 分支 89.14% / 函数 98.12% / 行 93.51%**;`test:coverage` 与逐文件 domain/book/insight/viewmodel 门禁全过;
1333
- - `typecheck`、`lint`、`build` 通过;`check:hygiene`(155 files,0 v8 ignore)、`test:isolated`(62 源文件)、`validate:rulepack`、`check:pack`(26 files)、`check:artifacts`、`check:install`(26 packages)、`check:preset`(13 packages)、`check:host`、`check:crash` 全绿;
1334
- - M1–M7、S1–S8 与 P2/P3 硬化见 [0.2.5 验收](docs/0.2.5-acceptance.md);0.2.6 的 E1–E6 见 [0.2.6 验收](docs/0.2.6-acceptance.md);
1335
- - 真实模型:0.2.6 临时项目中 `agnes-2.5-flash` 实时完成 P1/P2/P3,公开引擎 P4/P6/P8(确定性夹具)归档成功,`stage=done`、`score=145`;`agnes-3.0-flash` 连续 HTTP 429,未产出第二份实时结果。0.2.5 的两篇真实正文也在 0.2.6 引擎离线重放通过;爸爸已确认接受 3.0 的离线重放作为唯一 3.0 证据,详见 [0.2.6 验收](docs/0.2.6-acceptance.md) 4.1 节。
791
+ 以本次发布实际跑出的结果为准:
1336
792
 
1337
- 0.2.4 在 Node 24.19 / DSH 0.2.1-rc.3 上完成:
793
+ - `corepack pnpm test`:**91 个测试文件 / 910 项全部通过**;
794
+ - 覆盖率:**语句 93.51% / 分支 89.13% / 函数 98.12% / 行 93.51%**;逐文件门禁通过;
795
+ - `typecheck`、`lint`、`build`:通过;
796
+ - `check:hygiene`(156 files,0 v8 ignore)、`test:isolated`(62 源文件)、`validate:rulepack`、`check:pack`(26 files)、`check:artifacts`、`check:install`(26 packages)、`check:preset`(13 packages)、`check:host`、`check:crash`:通过;
797
+ - 三题材矩阵:玄幻修仙、都市现代、西方奇幻各跑一遍 `init → archive`;
798
+ - 隐私守卫:`src / briefs / skills / presets / rulepacks / docs` 与根文档均无具体项目身份。
1338
799
 
1339
- - `npm test` 全绿:**80 个测试文件 / 848 项**;
1340
- - 覆盖率:**语句 93.97% / 分支 89.14% / 函数 98.00% / 行 93.97%**;`test:coverage` 与逐文件 domain/book/insight/viewmodel 门禁全过;
1341
- - `typecheck`、`lint`、`build` 通过;`check:hygiene`(143 files,0 v8 ignore)、`test:isolated`(60 源文件)、`validate:rulepack`、`check:pack`(25 files)、`check:artifacts`、`check:install`(26 packages)、`check:preset`(13 packages)、`check:host`、`check:crash` 全绿;
1342
- - 0.2.4 outline 契约、dry_run、deprecated、outline restore、volumes upsert/remove 与 blueprint confirm 见 [0.2.4 验收](docs/0.2.4-acceptance.md);
1343
- - 真实模型链路:`agnes-2.5-flash` 与 `agnes-3.0-flash` 在 0.2.4 临时项目完成 P1→P8、归档、report/doctor/panel v5、六种导出、`novel_reopen` 与重新归档;详见 [0.2.4 真实模型证据](docs/0.2.4-real-model-evidence.md)。
1344
-
1345
- 0.2.3 在 Node 24.19 / DSH 0.2.1-rc.3 上完成:
1346
-
1347
- - `npm test` 全绿:**78 个测试文件 / 836 项**;
1348
- - 覆盖率:**语句 94.12% / 分支 89.28% / 函数 97.96% / 行 94.12%**;`test:coverage` 与逐文件 domain/book/insight/viewmodel 门禁全过;
1349
- - `typecheck`、`lint`、`check:hygiene`(139 files,0 v8 ignore)、`test:isolated`(58 源文件)、`build`、`validate:rulepack`、`check:pack`(25 files)、`check:artifacts`、`check:install`(26 packages)全绿;`check:preset` 在 `DSH_BUNDLE_ROOT=/home/tianhao/deepseek-harness/packages/bundle/web-app` 下解析 13 个包;`check:crash` SIGKILL 恢复通过;
1350
- - 0.2.2 的历史基线保留在 `docs/0.2.2-evidence.md`:77 files / 772 tests,覆盖率 93.87 / 89.15 / 97.89 / 93.87。
1351
- - `check:host` 在临时 DSH profile 中实测:面板未认证 401、认证后 200(payload v5)、预设可见、headless 真实触发 `novel_init` 并落盘、`remove` 后层消失;临时 `HOME`/`DSH_HOME` 隔离后真实注册表没有新增 Host Smoke。
1352
- - 真实 `1971` 项目只读回归:effort 8/6/8/4;quality samples=2、attempts=8、trend=null;第 3 章 briefs 为空;cast 陈嘉树=protagonist;panel legacy 4 类可见(doctor 另含 LEGACY_CHECK_FORMAT,共 5 类)。详见 [0.2.3 验收](docs/0.2.3-acceptance.md)。
1353
- - 0.2.3 真实模型链路:`agnes-2.5-flash` 与 `agnes-3.0-flash` 在临时项目完成 P1→P8、归档、report/doctor/panel v5、六种导出、`novel_reopen` 与重新归档;P1/P2/P3 为真实模型输出,P4/P6 为确定性夹具。详见 [0.2.3-real-model-evidence.md](docs/0.2.3-real-model-evidence.md)。
1354
-
1355
- 具体数字会随代码变化;发布前请以重新跑出的结果为准,不要把上面的历史数字当保证。完整验收矩阵见 [docs/0.2.3-acceptance.md](docs/0.2.3-acceptance.md)。
800
+ 具体数字会随代码变化;发布前请以重新跑出的结果为准,不要把历史数字当保证。
1356
801
 
1357
802
  ---
1358
803
 
1359
- ## 十七、文档地图与许可
1360
-
1361
- | 文档 | 内容 |
1362
- | ---------------------------------------- | --------------------------------------------------------- |
1363
- | [DESIGN.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/DESIGN.md) | 完整设计书:架构、数据模型、规则、门控、事务、面板、预设 |
1364
- | [PLAN.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/PLAN.md) | 0.1.0 实施计划(历史) |
1365
- | [docs/0.2.0-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.0-plan.md) | 0.2.0 整书生命周期:蓝图/大纲/世界观/章卡/观测 |
1366
- | [docs/0.2.4-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.4-plan.md) | 0.2.4 outline upsert、显式删除、dry_run 与恢复路径的根治方案 |
1367
- | [docs/0.2.6-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.6-plan.md) | 0.2.6 语义配对、实体锚点、面板 v6、恢复与证据方案 |
1368
- | [docs/0.2.6-acceptance.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.6-acceptance.md) | 0.2.6 验收矩阵、门禁与真实项目探针 |
1369
- | [docs/0.2.7-backlog.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.7-backlog.md) | 0.2.6 审计保留到 0.2.7 的 worldbook replace 等项 |
1370
- | [docs/0.2.5-acceptance.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.5-acceptance.md) | 0.2.5 验收矩阵、真实项目回归与门禁证据 |
1371
- | [docs/0.2.5-real-model-evidence.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.5-real-model-evidence.md) | 0.2.5 agnes 2.5/3.0 正文经引擎 P3→P8/归档回执 |
1372
- | [docs/0.2.4-acceptance.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.4-acceptance.md) | 0.2.4 验收矩阵、质量门与边界 |
1373
- | [docs/0.2.4-real-model-evidence.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.4-real-model-evidence.md) | 0.2.4 两条真实模型 P1→P8 链路回执 |
1374
- | [docs/0.2.3-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.3-plan.md) | 0.2.3 可信账本、工作流、advisory、面板 v5 与项目卫生 |
1375
- | [docs/0.2.3-acceptance.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.3-acceptance.md) | 0.2.3 验收矩阵、真实项目回归与质量门证据 |
1376
- | [docs/0.2.2-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.2-plan.md) | 0.2.2 会话级项目选择、scan/resume、面板 v4 与完整卷 |
1377
- | [docs/0.2.2-evidence.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.2-evidence.md) | 0.2.2 验收矩阵与质量门证据 |
1378
- | [docs/0.2.2-real-model-evidence.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.2-real-model-evidence.md) | 0.2.2 两条真实模型 P1→P8 链路回执 |
1379
- | [docs/0.2.1-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.1-plan.md) | 0.2.1 可信账本、历史、备份、计划分权与质量门禁 |
1380
- | [docs/0.2.0-real-model-evidence.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.2.0-real-model-evidence.md) | 真实模型全链路验证回执 |
1381
- | [docs/0.1.2-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.1.2-plan.md) | 0.1.2 长书可运行性与证据闭环方案(历史) |
1382
- | [docs/0.1.1-plan.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/0.1.1-plan.md) | 0.1.1 契约收口与证据加固方案(历史) |
1383
- | [docs/tools.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/tools.md) | 28 个工具与命令面速查 |
1384
- | [docs/states.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/states.md) | 状态机、迁移表、轮次与回退 |
1385
- | [docs/rulepack.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/docs/rulepack.md) | 规则包结构、编译器断言、改词表流程 |
1386
- | [CHANGELOG.md](CHANGELOG.md) | 版本变更 |
804
+ ## 文档与许可
805
+
806
+ | 文档 | 内容 |
807
+ | --- | --- |
808
+ | [DESIGN.md](DESIGN.md) | 完整设计书:架构、数据模型、规则、门控、事务、面板、预设 |
809
+ | [CHANGELOG.md](CHANGELOG.md) | 版本变更与迁移说明 |
810
+ | [docs/tools.md](docs/tools.md) | 28 个工具与命令面速查 |
811
+ | [docs/states.md](docs/states.md) | 状态机、迁移表、轮次与回退 |
812
+ | [docs/rulepack.md](docs/rulepack.md) | 规则包结构、编译器断言、改词表流程 |
813
+ | [PLAN.md](PLAN.md) | 0.1.0 实施计划(历史) |
1387
814
  | [LICENSE](LICENSE) | MIT |
1388
815
 
1389
816
  ### 反馈