dsh-novel-write-engine 0.2.2 → 0.2.3

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,29 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.3
4
+
5
+ ### Changed
6
+
7
+ - **报表账本**:`novel_report.effort` 对旧章按 committed journal 回填 `submitReview`/`submitRevision`/`runCheck`/`rollback` 与 `archived_at`,旧 `final_check` 从 check 文档补读;`quality` 改为每章一份最终评审,新增 `samples`(章数)、`attempts`(committed 评审轮次,含历史)与 `trend_basis`,样本不足时 `trend` 为 `null` 而不是伪造 0。
8
+ - **简报按章隔离**:`state/briefs.yaml` 仍是全书 append-only 审计,但 `pipeline.briefs` 与 `getBrief` 只取当前章收据;重复领取同一章同一阶段直接 replay,不写 journal、不升 revision;仍取项目写锁做 journal 一致性检查,避免误恢复其他写者的 pending 事务。
9
+ - **角色与伏笔**:旧 `extra` 角色可从 worldbook/P1 或叙述者修正;伏笔 `resolved` 同步写 `advance_log`,记录章节、note 与 new_info。
10
+ - **归档失败可直接修订**:`ready_to_archive` 增加 `submitRevision` 回 P4,不必先 `novel_rollback`;P5 任务书与所有 brief 暴露 `manuscript_hash`/patch 示例。
11
+ - **P8 契约**:brief 带最小 `state_delta` schema、每段示例和 `worldbook_facts_empty`;delta 错误回显 expected 形态;`ENGINE_ISSUE_IMMUTABLE` 区分“格式错”和“评审归属不可改”。
12
+ - **提示降噪**:advisory 按 code 每章一条并合并去重后的证据;`LOCKED_DETAIL_DRIFT` 带 expected/actual 片段,重复段带阈值;`RESOURCE_MISMATCH` 只在正文明确写反向符号时报,不再把中文省略符号当矛盾。strict 模式下 `facts` 为空时 doctor 提醒;同段“数量×单价/人数×单价”算式不一致会报 advisory;中文句密度上限校准为 10/100 字。
13
+ - **失败重试**:有 key 的写操作在 journal 记录 `retry_key`/`retry_context`;与上次被拒尝试内容、brief、stage、revision 完全相同时返回 `ENGINE_RETRY_UNCHANGED`,防止原样重试浪费事务;换 brief 或改内容后放行。
14
+ - **默认规则包 1.0.1**:`period_density.max` 8→10(中文短句校准),并加入同段乘式/人数×单价算式 advisory。
15
+ - **面板 v5**:紧凑顶栏、首屏“当前章/下一步”、双栏工作台、统计条;项目选择器按写作/待修复/失效分组,失效默认折叠、可搜索、同名用父目录区分;advisories 与 legacy 独立展示;payload v5,旧标签页刷新。
16
+ - **项目卫生**:`check:host` 同时隔离 `HOME`/`DSH_HOME`,用临时注册表正控证明 `novel_init` 确实写入了隔离行,并回查真实 `projects.yaml` 未新增 Host Smoke;新增 `/novel projects --prune [--yes]`,默认只列失效登记,`--yes` 才删登记行,不删项目目录。
17
+ - **升级审计**:doctor 新增 `legacy-data`,只读标出旧 check、缺 rounds/archived_at、extra 角色、pre-0.2.3 无 anchor 伏笔、stale `pipeline.briefs`;`state/briefs.yaml` 的跨章历史收据是正常 append-only 审计,不误报;不自动改历史。新伏笔用 `format_version:1` 区分合法 anchorless 条目。
18
+ - **发布前复核**:`ready_to_archive` 的可修订归档阻断改推荐 P5→revise;锁定细节、资源归属、千分位/枚举算式、重复段证据定位修正;quality `attempts` 补齐 journal 缺口;`check:host` 在创建临时 home 前验 DSH、保留隔离正控;`check:artifacts` 校验 `dsh.client` 清单。
19
+
20
+ ### Tests
21
+
22
+ - 新增 0.2.3 报表回填、quality 样本/attempts、briefs 按章、brief replay、ready_to_archive 直接修订、P5 hash、doctor legacy、面板分组/advisory/legacy、`projects --prune` 与 advisory 去重测试。
23
+ - 质量:78 个测试文件 / 836 项测试全绿;覆盖率 94.12 / 89.28 / 97.96 / 94.12,逐文件门禁通过;typecheck、lint、build、pack、artifacts、install、preset、host、crash、hygiene、isolated、rulepack 全过。
24
+ - 真实模型:`agnes-2.5-flash`(275 字 / 6 段)与 `agnes-3.0-flash`(373 字 / 8 段)在临时项目完成 P1→P8、归档、report/doctor/panel v5、六种导出、reopen 与重新归档;P1/P2/P3 真实,P4/P6 确定性夹具,详见 [0.2.3 真实模型证据](docs/0.2.3-real-model-evidence.md)。
25
+ - 版本升 0.2.3;`REMOTE_VERSION` 4 → 5;工具 28、服务操作 32、核心工具 10、门控 13、语义项 5、导出 6 均不变。
26
+
3
27
  ## 0.2.2
4
28
 
5
29
  ### Changed
package/README.md CHANGED
@@ -8,7 +8,9 @@
8
8
 
9
9
  0.2.2 把多项目选择从“进程最近一次工具调用”改为**会话级持久绑定**:显式 `project_root` 成功后会记住当前 DSH 会话;同一工作区的 A/B 会话不再串书。面板 v4 增加项目选择器与 choose/missing 状态,`/novel scan` 用于发现项目,`/novel resume` 与面板复制按钮共用同一份续写指令;项目被删除/移动/替换时 fail-closed,不静默换书。
10
10
 
11
- > **当前版本:0.2.2** · 中文界面 · MIT
11
+ 0.2.3 把“账本说真话”补到旧项目:`report` 从 journal 回填旧章 effort,quality 每章只算最终评审并区分 `samples`/`attempts`;briefs 按当前章隔离;归档失败可直接修订;advisory 按章去重并带证据;面板 v5 改为书桌式工作台,项目选择器分离写作/待修复/失效;`check:host` 不再污染真实注册表。
12
+
13
+ > **当前版本:0.2.3** · 中文界面 · MIT
12
14
  >
13
15
  > **宿主范围**:DSH `>=0.2.1-rc.2 <0.3.0-0`;Node `>=24.9.0`。
14
16
 
@@ -86,7 +88,7 @@
86
88
  | ------------------------------- | -------------------------------------------------------------------------------------------- |
87
89
  | 28 个 `novel_*` 工具 | 书级蓝图/大纲/世界观 + 单章流水线 + 报告/体检/搜索/引导/重开/备份恢复 |
88
90
  | 5 条 `/novel*` 命令 | 状态、下一步、统计、导出、隐藏操作;`/novel` 内含 outline/guide/report/doctor/search 子命令 |
89
- | 1 个侧边栏面板「网文工坊」 | 只读;Hero、统计、全书规划、世界观、质量趋势、健康、最近活动、九阶段轨、章节卡、门控区 |
91
+ | 1 个侧边栏面板「网文工坊」 | 只读;当前章/下一步、统计、全书规划、世界观、质量趋势、健康、最近活动、九阶段轨、章节卡、门控区 |
90
92
  | 1 个内置 Agent 预设「网文工坊」 | 28 个工具全开,**不挂载 bash / 文件写入工具**;会话开始后不能切换 |
91
93
  | 1 个入口技能 | 告诉模型什么时候该用引擎、哪些写入口是唯一的 |
92
94
  | 13 条门控 | 任务书、阶段、字数、格式、摘要、场景类型、大纲对齐、评分、问题清零、阅读证明、一致性、轮次、归档原子性 |
@@ -95,7 +97,7 @@
95
97
  | 规则包外置 | 词表、格式、标点、语义、跨章阈值都在 `rulepacks/default.yaml`,代码只执行 |
96
98
  | 六种导出 | Markdown、纯文本、EPUB 3、大纲、世界观、书级提案;正文导出附 `cover.svg` 与 `blurb.txt` |
97
99
  | 整书规划层 | 书级蓝图、卷结构、章卡(严格模式)、世界观设定集;支持 Markdown/YAML/JSON 导入 |
98
- | 可观测性 | `novel_status` 书级摘要、`novel_report`、`novel_doctor`、`novel_search`、panel v4、journal 活动 |
100
+ | 可观测性 | `novel_status` 书级摘要、`novel_report`、`novel_doctor`、`novel_search`、panel v5、journal 活动 |
99
101
  | 多项目注册表 | `stateDir/projects.yaml` 记录已知项目与面板默认 active;不影响项目目录 |
100
102
  | 运行期依赖极少 | 只有 `yaml` 一个运行时依赖;Host 侧不访问外部网络、不调用外部 API、不读环境变量里的密钥 |
101
103
 
@@ -278,7 +280,7 @@ dsh plugin --profile web add dsh-novel-write-engine
278
280
  固定版本:
279
281
 
280
282
  ```bash
281
- dsh plugin --profile web add dsh-novel-write-engine@0.2.2
283
+ dsh plugin --profile web add dsh-novel-write-engine@0.2.3
282
284
  ```
283
285
 
284
286
  `dsh` 不在 PATH 时,用 `npx @deepseek-ai/dsh` 代替命令开头的 `dsh`。
@@ -333,13 +335,13 @@ corepack pnpm pack
333
335
  会得到类似:
334
336
 
335
337
  ```text
336
- dsh-novel-write-engine-0.2.2.tgz
338
+ dsh-novel-write-engine-0.2.3.tgz
337
339
  ```
338
340
 
339
341
  把这个 tarball 复制到目标机器,放在一个**稳定、不会随手删除**的路径,然后:
340
342
 
341
343
  ```bash
342
- dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.2.2.tgz
344
+ dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.2.3.tgz
343
345
  ```
344
346
 
345
347
  tarball 安装不会运行源码构建,也不会要求 `allowBuilds`;包内已经包含 `lib/`、`rulepacks/`、`briefs/`、`skills/`、`presets/` 和两层 patch。它是最接近「发布产物」的安装方式。
@@ -354,9 +356,9 @@ tarball 安装不会运行源码构建,也不会要求 `allowBuilds`;包内
354
356
  2. 点 **添加插件**(或旁边的箭头 → **安装第三方插件**)。
355
357
  3. 在包名字段填入以下任一形式:
356
358
  - npm 包名:`dsh-novel-write-engine`
357
- - 精确版本:`dsh-novel-write-engine@0.2.2`
359
+ - 精确版本:`dsh-novel-write-engine@0.2.3`
358
360
  - 源码目录:`/absolute/path/to/dsh-novel-write-engine`
359
- - tarball:`/absolute/path/to/dsh-novel-write-engine-0.2.2.tgz`
361
+ - tarball:`/absolute/path/to/dsh-novel-write-engine-0.2.3.tgz`
360
362
  4. npm 包名从 npm 官方源安装;本地目录和 tarball 直接使用宿主路径。
361
363
  5. 点 **安装**,等待完成。
362
364
  6. 如果出现 **立即启用**,点它;否则安装后到「已安装插件」里把 **dsh-novel-write-engine** 打开。
@@ -428,7 +430,7 @@ dsh --profile web --dump-config | grep -A8 '# == dsh-novel-write-engine'
428
430
  先做全书蓝图、第一卷大纲和世界观设定,再写第一章的世界观约束和章节计划。
429
431
  ```
430
432
 
431
- 模型会调用 `novel_init` 建项目,然后按 `novel_guide` 的提示做书级规划;也可以跳过蓝图直接写第一章,严格大纲是可选开关。0.2.2 推荐顺序:
433
+ 模型会调用 `novel_init` 建项目,然后按 `novel_guide` 的提示做书级规划;也可以跳过蓝图直接写第一章,严格大纲是可选开关。0.2.3 推荐顺序:
432
434
 
433
435
  ```text
434
436
  novel_init
@@ -497,12 +499,11 @@ novel_init
497
499
 
498
500
  归档后打开左侧 **网文工坊**:
499
501
 
500
- - Hero:书名、类型、平台、当前章、阶段;
501
- - 统计:已归档章节、总字数、平均分、待处理门控;
502
- - 全书规划:蓝图/严格模式、章卡进度、**全部卷**(滚动列表)、世界观计数、质量趋势、健康度;
503
- - 九阶段轨;
504
- - 下一步卡与“复制续写指令”;
505
- - 章节卡、门控区与最近活动。
502
+ - 紧凑顶栏:书名、类型、平台、当前章、阶段;
503
+ - 首屏“当前章 / 下一步”卡与“复制续写指令”;
504
+ - 统计条:已归档章节、总字数、平均分、待处理门控;
505
+ - 双栏工作台:左侧阶段轨、门控、提示、旧数据;右侧全书规划(蓝图/严格模式、章卡进度、**全部卷**、世界观计数、质量趋势、健康度)与最近活动;
506
+ - 底部章节卡。
506
507
 
507
508
  面板每 15 秒静默同步一次,也可以点刷新;它**只读**,所有写操作仍在对话/工具里。
508
509
 
@@ -527,13 +528,13 @@ novel_init
527
528
  | 工具 | 阶段 | 做什么 | 写盘 |
528
529
  | -------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
529
530
  | `novel_init` | — | 建项目:`novel.yaml` + `state/` + `outline/` + 目录 | 是 |
530
- | `novel_status` | 任意 | 当前活跃章、阶段、轮次、阻塞项、`state_errors`、下一步;`chapter` 只用于字数查询 | 项目正文否;显式 root 写绑定 |
531
+ | `novel_status` | 任意 | 当前活跃章、阶段、轮次、阻塞项、`state_errors`、`manuscript_hash`、下一步;`chapter` 只用于字数查询 | 项目正文否;显式 root 写绑定 |
531
532
  | `novel_brief` | P1–P6 / P8 | 领取当前活跃章的任务书,返回 `fields`、`context`;`context.world_plan` 与 `context.context_meta` 在 `context` 内,并记录 digest | 仅任务书签收 |
532
533
  | `novel_plan_world` | P1 | 提交世界观约束;数组/对象形状在服务边界校验 | 是 |
533
534
  | `novel_plan_chapter` | P2 | 提交章节计划;标题长度读 rulepack、5–8 个节拍、opening/ending 非空;可选 `cast` 1–8 人 | 是 |
534
535
  | `novel_write_draft` | P3 | 提交初稿;格式/字数/摘要不过整体拒绝 | 是 |
535
536
  | `novel_review` | P4 | 十五维评分、问题清单、三段阅读证明;issue 维度/段落和 blocker waived 会被拒绝 | 是 |
536
- | `novel_revise` | P5/P6 | 提交修订;支持整章 `content` 或 `patch:{expected_hash,edits}`;blocker 必须有正文证据,不能降级或 waived | 是 |
537
+ | `novel_revise` | P5/P6/待归档 | 提交修订;支持整章 `content` 或 `patch:{expected_hash,edits}`;`ready_to_archive` 可直接修订并回 P4;blocker 必须有正文证据,不能降级或 waived | 是 |
537
538
  | `novel_check` | P6 | 机检 + 五个语义一致性项;`advisories` 与 blocker 分开,可用 `acknowledge` 记录知悉;单 scope 不推进归档 | 是 |
538
539
  | `novel_archive` | P7–P9 | 事务归档;必须带 `state_delta`;旧 review 无 digest 时拒绝 | 事务 |
539
540
  | `novel_word_count` | 任意 | 按引擎唯一口径数字数 | 否 |
@@ -549,7 +550,7 @@ novel_init
549
550
  | `novel_outline_import` | 任意 | 从 Markdown / YAML / JSON 导入大纲;`dry_run` 先预览 | 可选 |
550
551
  | `novel_worldbook` | 任意 | 增量更新世界观设定集(设定/规则/势力/地点/角色/术语/前史) | 是 |
551
552
  | `novel_search` | 任意 | 跨正文、摘要、大纲、世界观、台账搜索,带章号/段落号/片段 | 否 |
552
- | `novel_doctor` | 任意 | 项目体检:项目/流水线/状态、journal、正文 hash、孤立正文、大纲覆盖与漂移、当前阶段产物、锁、备份、目标进度、下一步 | 否 |
553
+ | `novel_doctor` | 任意 | 项目体检:项目/流水线/状态、journal、正文 hash、孤立正文、大纲覆盖与漂移、旧数据审计(legacy-data)、数值事实、当前阶段产物、锁、备份、目标进度、下一步 | 否 |
553
554
  | `novel_report` | 任意 | 全书报告:进度、大纲、世界观、质量、节奏、角色、伏笔、时间线、关系、活动 | 否 |
554
555
  | `novel_guide` | 任意 | 上手引导:当前状态、已完成步骤、下一步工具、命令与提示;无项目也能用 | 否 |
555
556
  | `novel_reopen` | 已归档章 | 从归档备份把紧邻的上一章重开到 P3;必须带非空 `reason`,活动章未开始、备份存在时才允许 | 是 |
@@ -563,7 +564,7 @@ novel_init
563
564
 
564
565
  三类错误:
565
566
 
566
- - **改参数**:`ENGINE_SCHEMA_INVALID`、`ENGINE_STAGE_ORDER`、`ENGINE_PROJECT_NOT_FOUND`、`ENGINE_PROJECT_EXISTS`;
567
+ - **改参数**:`ENGINE_SCHEMA_INVALID`、`ENGINE_STAGE_ORDER`、`ENGINE_PROJECT_NOT_FOUND`、`ENGINE_PROJECT_EXISTS`;修订改了评审归属字段时是 `ENGINE_ISSUE_IMMUTABLE`;同内容同上下文重试是 `ENGINE_RETRY_UNCHANGED`;
567
568
  - **改正文**:`ENGINE_GATE_BLOCKED`、`ENGINE_SCORE_MISMATCH`、`ENGINE_READING_PROOF_INVALID`、`ENGINE_DELTA_UNVERIFIED`;
568
569
  - **查环境**:`ENGINE_SCHEMA_TOO_NEW`、`ENGINE_PATH_ESCAPE`、`ENGINE_LOCK_TIMEOUT`、`ENGINE_TXN_ABORTED`、`ENGINE_RULEPACK_INVALID`。
569
570
 
@@ -591,6 +592,7 @@ novel_init
591
592
  /novel search <关键词>
592
593
  /novel export md|txt|epub|outline|worldbook|proposal
593
594
  /novel projects
595
+ /novel projects --prune [--yes]
594
596
  /novel current
595
597
  /novel use <path|title|.>
596
598
  /novel unbind
@@ -925,7 +927,18 @@ corepack pnpm test
925
927
 
926
928
  ## 十一、升级
927
929
 
928
- ### 11.0 从 0.2.1 升级到 0.2.2
930
+ ### 11.0 从 0.2.2 升级到 0.2.3
931
+
932
+ 0.2.3 不迁移项目数据,只改变读模型、面板 wire 版本与项目卫生:
933
+
934
+ 1. **面板 payload v5**:旧标签页显示刷新;刷新后是书桌式布局、分组项目选择器和独立的提示/旧数据区。
935
+ 2. **report 口径**:旧章 effort 从 journal 回填,quality 每章只算最终评审;`samples` 是章数,`attempts` 是 committed 评审轮次(含历史),样本不足时 `trend` 为 `null`。
936
+ 3. **briefs 按章**:`pipeline.briefs` 只显示当前章;`novel_state {kind:"briefs"}` 仍保留全书收据。
937
+ 4. **归档失败**:`ready_to_archive` 可以直接 `novel_revise` 回 P4,不需要先 rollback。
938
+ 5. **advisory**:同章同 code 只显示一条并合并证据;`RESOURCE_MISMATCH` 不再因中文省略符号误报。
939
+ 6. **项目卫生**:`/novel projects --prune` 默认只列失效登记,`--yes` 才删登记行;`check:host` 不再写真实注册表。
940
+
941
+ ### 11.0.1 从 0.2.1 升级到 0.2.2
929
942
 
930
943
  0.2.2 不迁移项目数据,但改变多项目选择与面板契约:
931
944
 
@@ -995,7 +1008,7 @@ dsh plugin --profile web add dsh-novel-write-engine@latest
995
1008
  也可以固定版本:
996
1009
 
997
1010
  ```bash
998
- dsh plugin --profile web add dsh-novel-write-engine@0.2.2
1011
+ dsh plugin --profile web add dsh-novel-write-engine@0.2.3
999
1012
  ```
1000
1013
 
1001
1014
  升级后核对:
@@ -1037,7 +1050,7 @@ corepack pnpm pack
1037
1050
 
1038
1051
  ```bash
1039
1052
  dsh plugin --profile web remove dsh-novel-write-engine
1040
- dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.2.2.tgz
1053
+ dsh plugin --profile web add /absolute/path/to/dsh-novel-write-engine-0.2.3.tgz
1041
1054
  ```
1042
1055
 
1043
1056
  ### 11.5 在 Web / Desktop 里升级
@@ -1281,7 +1294,7 @@ DSH_BUNDLE_ROOT=/path/to/deepseek-harness/packages/bundle/web-app corepack pnpm
1281
1294
  6. `dsh plugin remove`,确认层与面板消失;
1282
1295
  7. 确认项目数据未被卸载动作删除。
1283
1296
 
1284
- `pnpm check:host` 覆盖第 1–4 与第 6 步的自动断言(含 28 个工具的宿主声明、面板 v4 字段与空态结构)。`/novel` 命令的 handler 与路由由 `tests/adapters`、`tests/smoke` 的假宿主覆盖,真实宿主命令路由仍属于第 4 步的人工确认;第 5 步也是人工全流程(需要可用模型)。
1297
+ `pnpm check:host` 覆盖第 1–4 与第 6 步的自动断言(含 28 个工具的宿主声明、面板 v5 字段与空态结构)。`/novel` 命令的 handler 与路由由 `tests/adapters`、`tests/smoke` 的假宿主覆盖,真实宿主命令路由仍属于第 4 步的人工确认;第 5 步也是人工全流程(需要可用模型)。
1285
1298
 
1286
1299
  ### 16.4 项目结构
1287
1300
 
@@ -1305,17 +1318,17 @@ tests/ # 单测、集成、falsify、e2e
1305
1318
 
1306
1319
  ### 16.5 当前验证基线
1307
1320
 
1308
- 0.2.2 在 Node 24.19 / DSH 0.2.1-rc.3 上完成过:
1321
+ 0.2.3 在 Node 24.19 / DSH 0.2.1-rc.3 上完成:
1309
1322
 
1310
- - `npm test` 全绿:**77 个测试文件 / 772 项**;
1311
- - 覆盖率:**语句 93.87% / 分支 89.15% / 函数 97.89% / 行 93.87%**,高于 0.2.1 基线(93.86 / 89.04 / 97.81 / 93.86);`test:coverage` 与逐文件 domain/book/insight/viewmodel 门禁全过;
1312
- - `typecheck`、`lint`、`check:hygiene`(138 files,0 v8 ignore)、`test:isolated`(58 源文件)、`build`、`validate:rulepack`、`check:pack`(25 files)、`check:artifacts`、`check:install`(26 packages)全绿;
1313
- - `check:preset` 从真实 bundle 解析 13 个 packages;
1314
- - `check:host` 在临时 DSH profile 中实测:面板未认证 401、认证后 200(payload v4)、预设可见、headless 真实触发 `novel_init` 并落盘、`remove` 后层消失;
1315
- - `check:crash` 在真实子进程 SIGKILL 后恢复 pending journal:目标项目仍可读,无遗留 pending 事务;
1316
- - `agnes-2.5-flash` 与 `agnes-3.0-flash` 在临时项目完成 P1→P8、归档、report/doctor/panel v4、history/backups、六种导出、`novel_reopen` 与重新归档;P1/P2/P3 为真实模型,P4/P6 为确定性夹具,详见 [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)。
1323
+ - `npm test` 全绿:**78 个测试文件 / 836 项**;
1324
+ - 覆盖率:**语句 94.12% / 分支 89.28% / 函数 97.96% / 行 94.12%**;`test:coverage` 与逐文件 domain/book/insight/viewmodel 门禁全过;
1325
+ - `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 恢复通过;
1326
+ - 0.2.2 的历史基线保留在 `docs/0.2.2-evidence.md`:77 files / 772 tests,覆盖率 93.87 / 89.15 / 97.89 / 93.87。
1327
+ - `check:host` 在临时 DSH profile 中实测:面板未认证 401、认证后 200(payload v5)、预设可见、headless 真实触发 `novel_init` 并落盘、`remove` 后层消失;临时 `HOME`/`DSH_HOME` 隔离后真实注册表没有新增 Host Smoke。
1328
+ - 真实 `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)。
1329
+ - 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)。
1317
1330
 
1318
- 具体数字会随代码变化;发布前请以重新跑出的结果为准,不要把上面的历史数字当保证。完整验收矩阵见 `docs/0.2.2-evidence.md`。
1331
+ 具体数字会随代码变化;发布前请以重新跑出的结果为准,不要把上面的历史数字当保证。完整验收矩阵见 [docs/0.2.3-acceptance.md](docs/0.2.3-acceptance.md)。
1319
1332
 
1320
1333
  ---
1321
1334
 
@@ -1326,6 +1339,8 @@ tests/ # 单测、集成、falsify、e2e
1326
1339
  | [DESIGN.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/DESIGN.md) | 完整设计书:架构、数据模型、规则、门控、事务、面板、预设 |
1327
1340
  | [PLAN.md](https://github.com/ThzxxArt/dsh-novel-write-engine/blob/main/PLAN.md) | 0.1.0 实施计划(历史) |
1328
1341
  | [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 整书生命周期:蓝图/大纲/世界观/章卡/观测 |
1342
+ | [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 与项目卫生 |
1343
+ | [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 验收矩阵、真实项目回归与质量门证据 |
1329
1344
  | [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 与完整卷 |
1330
1345
  | [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 验收矩阵与质量门证据 |
1331
1346
  | [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 链路回执 |
package/briefs/P5.md CHANGED
@@ -12,12 +12,33 @@
12
12
 
13
13
  ## 提交
14
14
 
15
- 调用 `novel_revise`:
15
+ 调用 `novel_revise`,二选一:
16
+
17
+ **推荐:patch 模式**(只传改动,省 token):
18
+
19
+ ```json
20
+ {
21
+ "chapter": 3,
22
+ "patch": {
23
+ "expected_hash": "任务书 fields.manuscript_hash 的值",
24
+ "edits": [{ "old_text": "原文里的唯一片段", "new_text": "替换后的片段" }]
25
+ },
26
+ "proof": { "opening": {}, "middle": {}, "ending": {} }
27
+ }
28
+ ```
29
+
30
+ - `expected_hash` 必须是当前正文的 SHA-256;`fields.manuscript_hash` 就是它。
31
+ - `old_text` 默认必须在当前正文中唯一;重复出现时用 `occurrence` 指定第几次。
32
+ - 多处编辑不能重叠;hash 不匹配、锚点不唯一都会零写入拒绝。
33
+
34
+ **整章模式**:
16
35
 
17
36
  - `content`:修订后的完整正文(不是 diff)。
18
37
  - `summary`:如果事件、伏笔、资源有变化,同步更新;没变化可省略。**如果改动前两段/opening,必须同时提交新的 summary**,否则引擎会拒绝。
19
38
  - `proof`:修订后正文的三个逐字引用(opening/middle/ending),每段至少 12 字;PG-09 会逐条回查,开头/结尾按实际段落判定,不能改写、编造或靠提交段落号挪动边界。
20
39
 
40
+ `ready_to_archive` 阶段也允许直接 `novel_revise`:正文会退回 P4 重新评审,不需要先 `novel_rollback`,也不会多写一份废稿快照。
41
+
21
42
  ## 常见返工原因
22
43
 
23
44
  - 只改了措辞,没解决 issue 指出的信息缺口。
package/briefs/P8.md CHANGED
@@ -28,11 +28,77 @@
28
28
  - `timeline` 的键是 `summary.events` 的下标(字符串)。
29
29
  - `relationships` 的键是 `"甲|乙"`;每项至少 `{ "action": "created", "type": "关系类型", "description": "..." }`,缺 `type` 会被拒绝。
30
30
  - `characters` 的键是人物名;`world` 的键是新地点/能力/物品名;`foreshadows` 的键是 summary 里的 planted key 或已分配的 `FS-xxx`。
31
+ - `foreshadows` 的 `summary.foreshadows.resolved` 里列出的 key,delta 必须写 `action: "updated"`;引擎会把 `resolved_at` 写成当前章,并把 `note`/`new_info` 追加到 `advance_log`。示例:`"FS-002": {"action":"updated","note":"欠条被收回,债清了","new_info":true}`。
32
+
33
+ ## 最小 schema
34
+
35
+ ```json
36
+ {
37
+ "characters": {
38
+ "<人物名>": {
39
+ "action": "created|updated|no_change",
40
+ "reason": "no_change 必填;其余建议写",
41
+ "role": "protagonist|supporting|antagonist|extra(可选)",
42
+ "profile": {},
43
+ "current_state": { "resources": { "<资源名>": 0 } },
44
+ "growth": { "change": "string", "status_change": "string" }
45
+ }
46
+ },
47
+ "foreshadows": {
48
+ "<planted key 或 FS-xxx>": {
49
+ "action": "created|updated|no_change",
50
+ "title": "可读标签",
51
+ "anchor": "正文逐字原句,至少 8 字",
52
+ "description": "string",
53
+ "note": "resolve/advance 时写清如何兑现",
54
+ "new_info": true
55
+ }
56
+ },
57
+ "timeline": {
58
+ "<summary.events 下标>": {
59
+ "action": "created",
60
+ "story_time": "Day 3 清晨",
61
+ "description": "string",
62
+ "location": "string",
63
+ "characters": ["人物名"]
64
+ }
65
+ },
66
+ "world": {
67
+ "<新地点/能力/物品名>": {
68
+ "action": "created|updated|no_change",
69
+ "kind": "location|ability|artifact|faction|rule",
70
+ "description": "string"
71
+ }
72
+ },
73
+ "relationships": {
74
+ "<甲|乙>": {
75
+ "action": "created|updated|no_change",
76
+ "type": "关系类型(created 必填)",
77
+ "description": "string",
78
+ "note": "updated 时写变化"
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ 错误会带上 `expected` 形态和收到的字段值,例如 `characters.陈嘉树.current_state must be an object; expected {"resources":{"港币":-3},...}`。不要猜字段名,按报错补齐即可。
85
+
86
+ ## summary 与 delta 的联动(归档前必核)
87
+
88
+ `novel_archive` **不接受 summary**;它校验的是 P3/P5 已经固定的 draft summary。delta 必须与这份 summary 对齐:
89
+
90
+ - `characters` 里每个 `action:"created"` 的人物名,必须出现在 draft `summary.characters_appeared`。
91
+ - `world` 里每个 `action:"created"` 的 location / ability / artifact,必须出现在 draft `summary.new_elements` 的对应数组,且 `kind` 一致;`faction` / `rule` 只需正文出现并按 kind 写入,`summary.new_elements` 没有对应数组。
92
+ - `timeline` 的键必须是 draft `summary.events` 的下标(字符串)。
93
+ - `relationships` 的两端必须已在 `characters` 里声明(本章 created 或台账已有),否则先声明人物。
94
+
95
+ 如果 summary 与本章事实不符,**不要直接改 delta 硬凑**:先 `novel_brief P5` → `novel_revise` 修正正文和 summary,再重走 P4/P6/P8。归档阶段没有第二次 summary 入口。
96
+
31
97
  - **伏笔的 title 是可读标签,anchor 才是校验证据**:`title` 可以写「船费债」这样的短语;要归档,请把正文原句放进 `anchor`(summary 的 planted 项或 delta 项都行,至少 8 个字符)。没有 `anchor` 时,`title` 必须逐字出现在正文里,否则 `ENGINE_DELTA_UNVERIFIED`。示例:`{"action":"created","title":"船费债","anchor":"三百蚊的船费先欠着","description":"欠船费三百蚊"}`。
32
98
  - 归档失败的报错会指出字段、值和缺失的锚点;不要把 title 改成碎片来“凑命中”,补 `anchor` 即可。
33
99
  - 第一人称的叙述者若在 `narrator` 里声明为 `陈默(第一人称「我」)`,正文用「我」也视为出现,但角色键仍写 `陈默`。
34
100
  - 每个新实体至少写 `action: "created"`;已存在且没变化写 `action: "no_change", reason: "..."`。
35
- - `world` 新实体还要写 `kind: "location"|"ability"|"artifact"` 和 `description`。
101
+ - `world` 新实体还要写 `kind: "location"|"ability"|"artifact"|"faction"|"rule"` 和 `description`。
36
102
  - `state_delta` 可以是对象,也可以是 JSON 字符串;引擎两者都接受。
37
103
  - 未知伏笔 key、未声明角色、`no_change` 缺原因都会被 `ENGINE_DELTA_UNVERIFIED` 拒绝,引擎不会猜。
38
104
  - 不要传正文、不要传评分、不要传轮次。`handoff` 可选,用于覆盖卷/幕/进度。