- src/muse 新版全模块(装配/共享/上下文/任务运行/作品规划/故事世界/正文写作/审校修订/知识方法/作者经验/效果评测/交付连载/资料研究/正式变更/元数据/接入/基础设施/编排)+ 测试树(单元/契约/集成/架构/迁移/端到端/夹具) - 129 项功能全部实现与自动验证(功能覆盖.json/矩阵),含 W31 补齐的规则与代价/节奏安排/伏笔与承诺 - 旧实现按处置清单退出(702 条中 324 删,保护合同与未迁移条目留存有据);web/app.py 旧工作台退役,新工作台为唯一写入口 - 数据库/旧库迁移:真实旧库内容批次迁移链(端点守卫/PG作品正文映射/质量资产缺省投影) - 运行手册 docs/运行手册.md;W30 本机服务阶段一已运行(infra PG 为正式内容权威) - R2 执行证据与私有运行材料在 .agents.local/改造/R2-20260909/(不入库)
41 KiB
新版 agent-example:小说系统代码借鉴
资料状态:研究快照。正文中的“本轮”“当前”和测试结果均指原研究记录的核对时点。本次整理未重跑这些业务测试;新版目标以设计阅读指南及其主题文件为准。
研究日期:2026-09-08。用途:为新版主体的架构、实现边界和增改删决策提供代码依据;这是架构草稿的参考附件。 范围:
git/ai-novel-project/的 30 个参考仓。已核对全部当前 commit、根许可文件或 package SPDX;8 仓回到当前源码追踪重点机制,其余 22 仓仅用既有底层报告筛选。没有安装依赖、运行测试、调用模型、连接数据库或修改参考仓。以下“测试”均指本轮读到的测试源码,历史报告中的通过数不作为本轮验证结果。
1. 对新版主体最有价值的结论
- 作者界面、应用命令、领域规则、存储与模型适配分开。 StoryForge 的受控编辑器可以复用交互,整页控制器不能连同数据库与 AI 调度迁入;Openwrite 当前的界面与 HTTP 桥也支持这一区分。
- 每次生成交付候选,每次正式写入交付版本与回执。 采用 StoryForge 的来源快照、陈旧判定和采纳前重查;采用 character-arc 的分项选择,但批量操作按领域事务定义,不能把逐项成功误称为整批原子成功。
- 规划负责准备近期可写合同,上下文负责读取实际已发生事实。 AI-Novel-Writing-Assistant 的 JIT 接缝明确,值得借鉴;不能每次续写都重建作者已确认规划。
- 事实、状态、原文证据、检索索引分别建模。 webnovel-writer 的提交与投影分离、neuro-book 的两种时间坐标与可注入检索端口,比把所有内容塞进“记忆库”更清楚。
- 返修是有界的候选演进。 InkOS 保存每轮稿件与审稿结果,无净收益时停止,并可回退;其模型分数和题材规则不能直接成为新版的文学真值。
- 通用化先统一行为,不先造万能框架。 可把“准备上下文、执行任务、保存候选、作出决定、登记派生任务”做成少量稳定入口;运行账本、宿主适配与领域执行通过明确接口相连。neuro-book 的端口和回放合同可供设计参考,不要求为个人系统复制完整工作流平台。
本文的“采用”是采用机制与接口原则;直接复用第三方源码仍需按具体文件确认许可、归属和依赖。
2. 30 仓筛选表
“源码”表示本轮核对了选定当前路径;“报告”表示只完成历史证据筛选,不能据此断言当前整仓实现与旧报告完全相同。每仓名称链接到底层报告,重点当前源码见第 3 节。commit 为当前本地短哈希。
| 项目 | 当前 commit | 本轮依据 | 裁决 | 候选借鉴与适配理由 |
|---|---|---|---|---|
| 51mazi(原路径 ../../../../../docs/research/ai-novel-project/51mazi.md,已随旧实现退出,见固定基线) | 5a5f9d00 |
报告 | 仅方法 | 大纲树编辑、草稿预览、应用与撤销;不采用 renderer 校验作为正式写入保证。 |
| 91Writing(原路径 ../../../../../docs/research/ai-novel-project/91Writing.md,已随旧实现退出,见固定基线) | df3de036 |
报告 | 仅反例 | 提醒避免超大编辑页面承担 prompt、保存、解析和业务编排;显式选资料交互已有更适合的参考。 |
| AI-Novel-Writing-Assistant(原路径 ../../../../../docs/research/ai-novel-project/AI-Novel-Writing-Assistant.md,已随旧实现退出,见固定基线) | 25db3223 |
源码 | 条件采用 | 近期规划 JIT、章节合同依赖注入、作品/章节/任务文风优先级;绑定需补不可变版本,新版不继承其全书自动推进策略。 |
| AI_NovelGenerator(原路径 ../../../../../docs/research/ai-novel-project/AI_NovelGenerator.md,已随旧实现退出,见固定基线) | f9aefef9 |
报告 | 仅方法 | 分阶段产物、Pydantic 校验、多尺度上下文;不把 prompt 百分比和自由文本状态作为事实合同。 |
| Ai-Novel(原路径 ../../../../../docs/research/ai-novel-project/Ai-Novel.md,已随旧实现退出,见固定基线) | 8b85b2b6 |
报告 | 仅方法 | OutputContract、GenerationRun、上下文优先级、分段大纲与覆盖检查;服务端候选/采纳边界需另建。 |
| MaliangAINovalWriter(原路径 ../../../../../docs/research/ai-novel-project/MaliangAINovalWriter.md,已随旧实现退出,见固定基线) | 08894a21 |
报告 | 仅方法 | 上下文 provider、设定树父子关系检查、下一章纲候选;不引入内存会话作为正式状态。 |
| MuMuAINovel(原路径 ../../../../../docs/research/ai-novel-project/MuMuAINovel.md,已随旧实现退出,见固定基线) | 600be703 |
源码 | 仅方法 | API 入口验证前章完成与分析就绪;超大路由和生成结束直写正文是新版需要避免的结构。 |
| NovelForge(原路径 ../../../../../docs/research/ai-novel-project/NovelForge.md,已随旧实现退出,见固定基线) | 7c2d84ef |
报告 | 仅方法 | 结构化局部指令、工作流节点产物与恢复位置;不采用节点存在即能力可用的验收方式。 |
| OpenFic(原路径 ../../../../../docs/research/ai-novel-project/OpenFic.md,已随旧实现退出,见固定基线) | 349f154a |
报告 | 仅方法 | revision/diff 事务、上下文分层、压缩保留原始记录;审稿和正式确认需按新版合同补强。 |
| Openwrite(原路径 ../../../../../docs/research/ai-novel-project/Openwrite.md,已随旧实现退出,见固定基线) | d4443492 |
源码 | 条件采用 | 当前是 DSH 插件、工作台与 HTTP 桥;借鉴作用域客户端、作品切换屏障与失效订阅。旧 Python 管线不在当前树,不能沿旧报告迁移。 |
| PlotPilot(原路径 ../../../../../docs/research/ai-novel-project/PlotPilot.md,已随旧实现退出,见固定基线) | cbd260ba |
报告 | 仅方法 | 调用尝试、采纳、提交分开留痕,预览与正式稿分开;避免复制庞大 daemon 和建议性检查后的直接落盘。 |
| QMAI(原路径 ../../../../../docs/research/ai-novel-project/QMAI.md,已随旧实现退出,见固定基线) | 42727a99 |
报告 | 仅方法 | 结构化任务合同、认知边界、字段化上下文、修订问题单;不采用固定题材公式和启发式分数作为统一规则。 |
| WriteHERE(原路径 ../../../../../docs/research/ai-novel-project/WriteHERE.md,已随旧实现退出,见固定基线) | 817b4890 |
报告 | 暂不采用 | 递归 DAG 适合探索研究,当前需求用明确创作阶段即可表达;不为通用性引入自由拆解与聚合层。 |
| ainovel-cli(原路径 ../../../../../docs/research/ai-novel-project/ainovel-cli.md,已随旧实现退出,见固定基线) | fc178558 |
报告 | 条件采用 | 串行 Engine、纯路由、冻结正文提交和恢复包适合 CLI 保留路线;文件 saga 应转为 PG 事务与持久任务。 |
| arboris-novel(原路径 ../../../../../docs/research/ai-novel-project/arboris-novel.md,已随旧实现退出,见固定基线) | dd80c69b |
报告 | 仅方法 | 候选审阅与 finalize 后记忆分开,视角和信息预算显式;不采用简单人名匹配或默认首候选。 |
| awesome-novel-agent(原路径 ../../../../../docs/research/ai-novel-project/awesome-novel-agent.md,已随旧实现退出,见固定基线) | acbee0ff |
报告 | 仅方法 | 有序任务与产物交接、保留 partial/原稿;不迁入以 Markdown 权限与完成标记替代执行检查的调度方式。 |
| character-arc(原路径 ../../../../../docs/research/ai-novel-project/character-arc.md,已随旧实现退出,见固定基线) | 1a81dca0 |
源码 | 采用 | 变更暂存区、逐项接受/拒绝、失败项保留重试、提交回调与存储分开;新版用领域命令、事务和持久幂等承接。 |
| chinese-novelist-skill(原路径 ../../../../../docs/research/ai-novel-project/chinese-novelist-skill.md,已随旧实现退出,见固定基线) | cb6c3e7d |
报告 | 仅方法 | 中文创作阶段、人物/大纲/摘要分开;只作为 Skill 写法候选,不作为新运行架构来源。 |
| denova(原路径 ../../../../../docs/research/ai-novel-project/denova.md,已随旧实现退出,见固定基线) | d14191d8 |
报告 | 条件采用 | 变更组、base revision/CAS、事件与计划分层;只提取受控变更机制,不把通用 IDE 搬成主体。 |
| flymd(原路径 ../../../../../docs/research/ai-novel-project/flymd.md,已随旧实现退出,见固定基线) | e6f73b89 |
报告 | 仅方法 | 前章尾部与长期检索分区、计划规范化;不引入两套 RAG owner 和前端吞错路径。 |
| InkOS(原路径 ../../../../../docs/research/ai-novel-project/inkos.md,已随旧实现退出,见固定基线) | 09104838 |
源码 | 条件采用 | 有界评修循环、最佳稿回退、状态重结算与降级;需替换自动分数定胜负、检测器导向的文风规则。 |
| kimi-writer(原路径 ../../../../../docs/research/ai-novel-project/kimi-writer.md,已随旧实现退出,见固定基线) | 1a97fd56 |
报告 | 仅反例 | 最小工具循环只适合演示;避免全局活动作品变量、模型无 tool call 即完成与无版本文件写入。 |
| neuro-book(原路径 ../../../../../docs/research/ai-novel-project/neuro-book.md,已随旧实现退出,见固定基线) | b0bb642c |
源码 | 条件采用 | 模块公共入口、宿主注入端口、查询时点、运行回放指纹;自治包有独立合同,不能把包存在当作主应用集成完成。 |
| novel-creator-skill(原路径 ../../../../../docs/research/ai-novel-project/novel-creator-skill.md,已随旧实现退出,见固定基线) | a327428e |
报告 | 仅方法 | 单章锁、请求幂等、快照和 beat/scene 中间表示;不采用模板报告存在即审查完成。 |
| novel-writer(原路径 ../../../../../docs/research/ai-novel-project/novel-writer.md,已随旧实现退出,见固定基线) | e4190d40 |
报告 | 仅反例 | 命令生成器有宿主适配启发;不采用写作框架目录、脚本输出“已保存”作为运行闭环。 |
| oh-story-claudecode(原路径 ../../../../../docs/research/ai-novel-project/oh-story-claudecode.md,已随旧实现退出,见固定基线) | b446c365 |
报告 | 条件采用 | 扫榜/拆书交接、作者记忆、结构化 delta 和 tracking 检查;方法资产由新版统一运行器和正式状态消费。 |
| show-me-the-story(原路径 ../../../../../docs/research/ai-novel-project/show-me-the-story.md,已随旧实现退出,见固定基线) | ae19b1a0 |
报告 | 仅方法 | 重复失败暂停、全书工单、分层记忆;不采用自然语言 FAIL 解析及修订后直接标正式稿。 |
| StoryForge(原路径 ../../../../../docs/research/ai-novel-project/storyforge.md,已随旧实现退出,见固定基线) | cf273d50 |
源码 | 采用 | 主题与受控编辑器、候选/来源/采纳、Context Gateway、数据生命周期声明;重写页面控制器与网络接线。 |
| Vela(原路径 ../../../../../docs/research/ai-novel-project/vela.md,已随旧实现退出,见固定基线) | d2a97f3a |
报告 | 仅方法 | 正式事实注入、事件/状态/delta 原子写回;不采用自动降级严重程度即“修复”的语义。 |
| webnovel-writer(原路径 ../../../../../docs/research/ai-novel-project/webnovel-writer.md,已随旧实现退出,见固定基线) | 878ce26e |
源码 | 条件采用 | 独立提交合同、事实事件、派生路由与投影重试;新版以 PG 事务保证正式正文和已确认事实一致,不照搬多文件写入。 |
3. 重点代码:采用什么、接到哪里、还缺什么
3.1 StoryForge:编辑组件、候选提交、上下文与备份
已核对事实。 当前 cf273d50 的四个接缝具有迁移价值:
| 接缝与当前调用链 | 失败路径与测试源码 | 新版落点 |
|---|---|---|
RichEditor(value, onChange) 只输出 HTML 与纯文本,并暴露选区快照和不落盘的替换预演;PanelLayout(sidebar, children) 管理分栏。见 RichEditor:30(原路径 ../../../../../git/ai-novel-project/storyforge/src/components/editor/RichEditor.tsx:30,已随旧实现退出,见固定基线)、PanelLayout:4(原路径 ../../../../../git/ai-novel-project/storyforge/src/components/shared/PanelLayout.tsx:4,已随旧实现退出,见固定基线)。 |
测试覆盖卸载后的 editor 生命周期、精确局部预演且原正文不变:R-EDITOR3:45(原路径 ../../../../../git/ai-novel-project/storyforge/tests/regression/R-EDITOR3-rich-editor-lifecycle.test.tsx:45,已随旧实现退出,见固定基线)。 | 作者工作台/编辑器。先定义新版正文存储格式和文本位置合同,再接人工保存与候选预览;页面组件不 import 数据库和模型 SDK。 |
ChapterEditor 调 create/recover/commitProseGeneration…;正式采纳验证候选、来源与作者确认,再调 adopt(compareAndSet)。见 调用方:3181(原路径 ../../../../../git/ai-novel-project/storyforge/src/components/editor/ChapterEditor.tsx:3181,已随旧实现退出,见固定基线)、采纳命令:1023(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/agent/run/prose-generation-durable.ts:1023,已随旧实现退出,见固定基线)。 |
adopt 拒绝模型携带 owner;事务内比较字段哈希,失败不更新:adopt:63(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/registry/adopt.ts:63,已随旧实现退出,见固定基线)、事务 CAS:307(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/registry/adopt.ts:307,已随旧实现退出,见固定基线)。正文/上游变化、确认稿不一致、候选恢复反例见 R-HARNESS7:193(原路径 ../../../../../git/ai-novel-project/storyforge/tests/regression/R-HARNESS7-prose-generation-durable.test.ts:193,已随旧实现退出,见固定基线)。 |
正文与候选/作出决定。服务端命令强制携带候选版本、被审正文版本、来源快照及幂等键;PG 同事务产出正文 revision、决定记录和派生任务。 |
executeContextGatewayV1 冻结作品范围,动态权限只能收窄;必读原文检查内容哈希和预算,不够就明确拒绝。采纳前 assertContextGatewayCandidateAdoptableV1 再查来源新鲜度。见 权限收窄:151(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/context-gateway/execution.ts:151,已随旧实现退出,见固定基线)、原文完整性:433(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/context-gateway/execution.ts:433,已随旧实现退出,见固定基线)、重查:673(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/context-gateway/execution.ts:673,已随旧实现退出,见固定基线)。 |
resource-scope、policy-override、mandatory-original-incomplete、candidate-context-stale 均为显式错误。候选测试约束新合同缺少信息边界证据不得回落到旧校验:R-HARNESS7:326(原路径 ../../../../../git/ai-novel-project/storyforge/tests/regression/R-HARNESS7-prose-generation-durable.test.ts:326,已随旧实现退出,见固定基线)。 |
上下文/来源读取。规划、写作、审稿共用来源合同;预组装、工具探索、回放均通过绑定本次作品、目标章节、时点和预算的同一服务。 |
导出遍历 PROJECT_TABLES,同一只读事务采集各表;导入根据声明的引用顺序重建,并在一个写事务完成。见 导出:222(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/export/registry-export.ts:222,已随旧实现退出,见固定基线)、导入:611(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/export/registry-import.ts:611,已随旧实现退出,见固定基线)。 |
错误根、错误表类型、缺表与非当前版本被拒绝:备份测试:16(原路径 ../../../../../git/ai-novel-project/storyforge/tests/regression/R-PRODUCT1-backup-trust.test.ts:16,已随旧实现退出,见固定基线)。当前导入只接受当前版本:版本门:178(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/export/registry-import.ts:178,已随旧实现退出,见固定基线)。 | 数据管理/备份恢复。各领域声明导出内容、引用和重建方式,统一导出服务汇总;新版增加版本迁移与原始资料完整性,不能复制“只接受当前版”的限制。 |
不能照搬。 浏览器 Dexie 正式库、前端 AI client 和 adopt 数据写入都应转换为新版服务端边界。ChapterEditor 可借鉴交互而非整体迁移。普通审校按章节 ID 放在内存,未绑定正文版本;去味只取前 4000 字且解析器对维度内容没有完整校验,见 review-result:20(原路径 ../../../../../git/ai-novel-project/storyforge/src/stores/review-result.ts:20,已随旧实现退出,见固定基线)、anti-ai-adapter:64(原路径 ../../../../../git/ai-novel-project/storyforge/src/lib/ai/adapters/anti-ai-adapter.ts:64,已随旧实现退出,见固定基线)。这两段适合作为新版报告持久化和输出校验的反例,不替代 agent-example 已有去味方法。
3.2 AI-Novel-Writing-Assistant:近期规划与分层文风选择
已核对事实。 当前 25db3223 中,GenerationContextAssembler.assemble 在全书自动模式下先调用 JIT,再读取持久化后的章节;JIT 注入 loadChapter / listFacts / ensureRouteWindow / ensureChapterExecutionContract,先补近期窗口并重读,完整合同直接复用,缺失时才读取目标章之前的事实并生成。见 调用方:154(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/server/src/services/novel/runtime/GenerationContextAssembler.ts:154,已随旧实现退出,见固定基线)、接口:21(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/server/src/services/novel/planning/ChapterPlanJITService.ts:21,已随旧实现退出,见固定基线)、流程:62(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/server/src/services/novel/planning/ChapterPlanJITService.ts:62,已随旧实现退出,见固定基线)。
这段代码的接口可以独立测试,测试实际断言已有合同生成次数为零、缺失合同只加载一次事实并触发一次生成:chapterPlanJITService.test.js:35(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/server/tests/chapterPlanJITService.test.js:35,已随旧实现退出,见固定基线)。loadChapter 不存在时 JIT 自身直接返回;主调用方另做存在性检查。因此新版应在应用入口统一返回“章节不存在”,不要让不同入口分别猜失败语义。
StyleBindingService.resolveForGeneration 按作品、章节、任务收集绑定并决定生效顺序,构造可回查的生效来源及规则块;当前写前上下文确实调用该函数。见 解析:126(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/server/src/services/styleEngine/StyleBindingService.ts:126,已随旧实现退出,见固定基线)、调用:277(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/server/src/services/novel/runtime/GenerationContextAssembler.ts:277,已随旧实现退出,见固定基线)。净化文风块的测试会检查参考来源中的实体不进入正文上下文:styleGenerationSanitizer.test.js:110(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/server/tests/styleGenerationSanitizer.test.js:110,已随旧实现退出,见固定基线)。
设计建议。 迁到 作品规划/准备近期章节 与 声音偏好/解析有效约束。近期窗口大小由作品策略决定;通用规划可基于任何作品的已确认状态生成检查合同,取代样本作品章号硬编码。优先级和来源说明可借鉴,但当前绑定读取的是活动 profile,不能把它当固定版本绑定的实现;新版继续使用不可变范式/声音版本,并把生效结果冻结到运行输入。
3.3 character-arc:分项审阅与正式提交分开
已核对事实。 当前 1a81dca0 的 stage_* 工具产出进入 StagedChangesStore,保存 before/after/reason/kind/toolUseId;store 只负责暂存、选择与事件,正式写入通过注入的 StagedChangeCommitter 实施,见 输入与回调:24(原路径 ../../../../../git/ai-novel-project/character-arc/electron/main/ai/runtime-v2/staged-changes-store.ts:24,已随旧实现退出,见固定基线)。IPC 的 STAGE_ACCEPT / STAGE_REJECT / STAGE_COMMIT 分别调用选择与提交,没有把“接受某项”直接当数据库成功,见 真实入口:456(原路径 ../../../../../git/ai-novel-project/character-arc/electron/main/ai/runtime-v2/ipc.ts:456,已随旧实现退出,见固定基线)。
提交只处理 accepted 项;失败保留 accepted,成功转 committed;相同暂存项的并发提交共用一个 Promise。测试覆盖混合成功/失败、结果顺序和并发只执行一次:实现:333(原路径 ../../../../../git/ai-novel-project/character-arc/electron/main/ai/runtime-v2/staged-changes-store.ts:333,已随旧实现退出,见固定基线)、测试:100(原路径 ../../../../../git/ai-novel-project/character-arc/electron/main/ai/runtime-v2/staged-changes-store.test.mjs:100,已随旧实现退出,见固定基线)。章节正文提交另有 WHERE content = oldContent 条件更新,并把旧稿版本与修改放在同一事务;零行更新会回滚:chapter-commit.ts:17(原路径 ../../../../../git/ai-novel-project/character-arc/electron/main/ai/agent/tools/chapter-commit.ts:17,已随旧实现退出,见固定基线)。
设计建议。 迁到 作者工作台/变更审阅 与 各领域/提交命令。候选可以逐项接受,但同一项正文及它批准的事实变更要作为一致的业务包提交。跨项允许部分成功时明确列每项结果;有依赖的项需要一起验证。不能把 in-memory commitsInFlight 称为重启幂等;新版在 PG 中持久化决定命令与结果。保留领域 committer 接缝,避免复制一个覆盖人物、世界、正文、知识的巨型万能 committer。
3.4 InkOS:返修停止条件与状态恢复
已核对事实。 当前 09104838 的生产 runner 调用 runChapterReviewCycle,输入初稿、审稿/修订适配器、内容检查、使用量累加和最大轮数,见 调用方:2081(原路径 ../../../../../git/ai-novel-project/inkos/packages/core/src/pipeline/runner.ts:2081,已随旧实现退出,见固定基线)、应用接口:45(原路径 ../../../../../git/ai-novel-project/inkos/packages/core/src/pipeline/chapter-review-cycle.ts:45,已随旧实现退出,见固定基线)。
循环保存初稿和每轮稿件;审稿解析失败不自动改写,没有新稿或没有净分数收益就停止。最终选稿首先保护字数硬范围,再比较分数,必要时恢复较早版本。见 停止与快照:183(原路径 ../../../../../git/ai-novel-project/inkos/packages/core/src/pipeline/chapter-review-cycle.ts:183,已随旧实现退出,见固定基线)、回退:292(原路径 ../../../../../git/ai-novel-project/inkos/packages/core/src/pipeline/chapter-review-cycle.ts:292,已随旧实现退出,见固定基线)。测试有解析失败不修、得分更高但硬范围失败不得替换原稿、默认一轮:chapter-review-cycle.test.ts:94(原路径 ../../../../../git/ai-novel-project/inkos/packages/core/src/tests/chapter-review-cycle.test.ts:94,已随旧实现退出,见固定基线)。
章后状态校验失败时可把反馈交给结算器重算,重试仍有问题就返回 degraded,不会伪造 recovered;对应测试检查降级时冻结旧事实输出。见 恢复:75(原路径 ../../../../../git/ai-novel-project/inkos/packages/core/src/pipeline/chapter-state-recovery.ts:75,已随旧实现退出,见固定基线)、测试:138(原路径 ../../../../../git/ai-novel-project/inkos/packages/core/src/tests/chapter-state-recovery.test.ts:138,已随旧实现退出,见固定基线)。
设计建议。 迁到 审稿修订/评修循环 和 事实连续性/恢复派生状态。新版优先验证事实、保护范围、声音和回归,再把成对选择交给作者;分数仅为编辑信号。原稿胜出和零修改都应是正常结果。状态降级是否允许写下一章由本次任务所需资料决定,不能把内容已生成、正式采纳、事实已更新混成一个“完成”。
3.5 Openwrite:当前源码已经换成工作台与后端桥
已核对事实。 当前 d4443492 与历史报告不是同一种物理结构。旧报告引用的 tools/chapter_pipeline.py、tools/novel_service.py 不在当前树。当前 packages/openwrite-bridge 注册 novel_* 工具并转到独立 OpenWrite Studio HTTP 面;入口配置了 base URL、超时和工作区解析器。见 插件装配:19(原路径 ../../../../../git/ai-novel-project/Openwrite/packages/openwrite-bridge/src/index.ts:19,已随旧实现退出,见固定基线)。因此不能用历史报告证明当前 checkout 内有 Python 正文/状态回滚实现。
本轮确认的好实现是:
StudioClient.scoped(context)派生请求作用域客户端,每次请求携带工作区、会话与调用来源;HTTP、网络、非 JSON 响应转为规范错误。见 作用域客户端:119(原路径 ../../../../../git/ai-novel-project/Openwrite/packages/openwrite-bridge/src/client.ts:119,已随旧实现退出,见固定基线)、错误处理:199(原路径 ../../../../../git/ai-novel-project/Openwrite/packages/openwrite-bridge/src/client.ts:199,已随旧实现退出,见固定基线)。NovelWorkbenchStore.setContext切作品时提升 generation、取消旧请求、关旧 SSE、重置状态和 revision;新请求回包先检查 generation,旧作品迟到结果被丢弃。见 切换屏障:231(原路径 ../../../../../git/ai-novel-project/Openwrite/packages/studio-panel/src/client/WorkbenchStore.ts:231,已随旧实现退出,见固定基线)、迟到拦截:400(原路径 ../../../../../git/ai-novel-project/Openwrite/packages/studio-panel/src/client/WorkbenchStore.ts:400,已随旧实现退出,见固定基线)。- 测试验证作品切换立即清空、旧 generation 回包不写新页面、异作品失效事件不推进本作状态,以及 SSE 与轮询一致:workbench-store.test.ts:274(原路径 ../../../../../git/ai-novel-project/Openwrite/packages/studio-panel/scripts/components/workbench-store.test.ts:274,已随旧实现退出,见固定基线)。
设计建议。 迁到 作者工作台/数据查询与编辑会话、接口适配/作品作用域客户端。浏览器缓存按作品与资源版本隔离,SSE 只通知失效或状态变化,正式数据从服务端读取。UI 的 generation 屏障解决迟到响应错显示,服务端 revision 解决正式写入覆盖,两者都需要。X-… 请求头和本地写标记本身不应被当作身份验证;新版通过服务端任务身份和作品范围决定授权。
3.6 webnovel-writer:章节提交合同与派生投影
已核对事实。 当前 878ce26e 的 scripts/chapter_commit.py 是薄 CLI,调用 ChapterCommitService.build_commit → persist_commit → apply_projections;服务先用 Pydantic 验证审查、规划兑现、消歧、抽取四种输入,存在阻断问题、遗漏节点或未决消歧就构造 rejected 提交。见 入口:19(原路径 ../../../../../git/ai-novel-project/webnovel-writer/webnovel-writer/scripts/chapter_commit.py:19,已随旧实现退出,见固定基线)、提交合同:33(原路径 ../../../../../git/ai-novel-project/webnovel-writer/webnovel-writer/scripts/data_modules/chapter_commit_service.py:33,已随旧实现退出,见固定基线)。
accepted 提交先规范化事实事件,再由 EventProjectionRouter.required_writers 决定状态、索引、摘要、记忆、向量哪些需要更新;每路分别记录 done/skipped/failed,失败不会伪造已更新。见 应用过程:123(原路径 ../../../../../git/ai-novel-project/webnovel-writer/webnovel-writer/scripts/data_modules/chapter_commit_service.py:123,已随旧实现退出,见固定基线)、事件路由:27(原路径 ../../../../../git/ai-novel-project/webnovel-writer/webnovel-writer/scripts/data_modules/event_projection_router.py:27,已随旧实现退出,见固定基线)。测试覆盖 malformed artifact 拒绝、拒绝提交的状态投影及同章重放不重复累计字数:输入测试:66(原路径 ../../../../../git/ai-novel-project/webnovel-writer/webnovel-writer/scripts/data_modules/tests/test_chapter_commit_service.py:66,已随旧实现退出,见固定基线)、投影测试:94(原路径 ../../../../../git/ai-novel-project/webnovel-writer/webnovel-writer/scripts/data_modules/tests/test_projection_writers.py:94,已随旧实现退出,见固定基线)。
设计建议。 迁到 正文与候选/正式提交、事实连续性/应用增量、任务运行/派生任务。正文与经作者批准的必要事实增量必须同事务;向量、摘要、搜索视图是可恢复派生物,用 outbox/持久任务驱动。不能直接复制当前跨 JSON、事件文件、SQLite 的顺序写入;append_projection_run 异常被吞掉也不适合正式审计。Skill 只说明操作意图,服务器必须检查四类产物与本次正文版本是否一致。
3.7 neuro-book:公共接口、两种时间坐标和执行回放
已核对事实。 当前 b0bb642c 已是多个包。nb-memory 的公开入口接收 StoragePort / EmbedPort / LlmPort / IndexStorePort,内部区分原文 episode、事实、主体注册表、动态状态与索引;默认索引在内存,显式持久索引可复用向量,deferEmbedding 让原文入库与向量补齐分开。见 端口:19(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-memory/src/ports/ports.ts:19,已随旧实现退出,见固定基线)、公共入口:31(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-memory/src/index.ts:31,已随旧实现退出,见固定基线)。缺少 LLM 却调用 ingestRaw 会明确报错;跳过的抽取块有计数,原文仍保留以支持重放:ingestRaw:170(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-memory/src/index.ts:170,已随旧实现退出,见固定基线)。
它明确区分叙事推进时已经知道多少与故事时间某刻发生了什么,缺少指定时间坐标的记录不可见;倒叙与别名揭示有相应测试,见 类型:4(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-memory/src/core/types.ts:4,已随旧实现退出,见固定基线)、时间测试:59(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-memory/tests/temporal.test.ts:59,已随旧实现退出,见固定基线)。这不是把“角色知情”和“读者知情”自动建好了;新版仍要显式记录观察主体和获知依据。
nb-workflow 用 SessionPort / AgentPort 隔离宿主;活动通过输入指纹与 journal 命中重放,已记录动作不再次执行。见 端口:34(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-workflow/src/ports.ts:34,已随旧实现退出,见固定基线)、回放:101(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-workflow/src/runtime.ts:101,已随旧实现退出,见固定基线)。测试构造两个 Runner 共用 backend,第一次动作完成后抛错,第二次恢复动作次数仍为一次:activity-runtime.test.ts:21(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-workflow/test/activity-runtime.test.ts:21,已随旧实现退出,见固定基线)。但测试使用 Memory backend,不能证明真实进程崩溃或外部副作用做到恰好一次。
设计建议。 迁到 上下文/时点查询、资料知识/事实与索引、运行器/宿主端口。公开接口可以小而明确,库内不读取应用全局配置。新版先保证同任务输入快照和已完成阶段回执可重用,再决定是否需要通用脚本工作流。包的规则明确:nb-memory 不声明已接入主应用;nb-workflow 包级验证不能独立证明产品集成。见 memory 包边界(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-memory/AGENTS.md:5,已随旧实现退出,见固定基线)、workflow 包边界(原路径 ../../../../../git/ai-novel-project/neuro-book/packages/nb-workflow/AGENTS.md:5,已随旧实现退出,见固定基线)。
3.8 MuMuAINovel:借前置条件,不借大路由
已核对事实。 当前 600be703 的生成 API 调用两个确定性检查:前置章是否有正文、上一章最新分析任务是否 completed;不满足分别返回 400/409。见 检查:509(原路径 ../../../../../git/ai-novel-project/MuMuAINovel/backend/app/api/chapters.py:509,已随旧实现退出,见固定基线)、实际调用:1461(原路径 ../../../../../git/ai-novel-project/MuMuAINovel/backend/app/api/chapters.py:1461,已随旧实现退出,见固定基线)。独立上下文 builder 限定历史章号并接受记忆/伏笔服务依赖:chapter_context_service.py:237(原路径 ../../../../../git/ai-novel-project/MuMuAINovel/backend/app/services/chapter_context_service.py:237,已随旧实现退出,见固定基线)。
适配边界。 前置就绪规则可迁到 作品规划/检查可写条件;新版还应把分析来源版本与正式正文 revision 绑定,completed 字面状态不足以证明对应最新正文。当前 API 在流结束后直接更新 chapter.content 并置 completed、提交数据库,见 保存:1837(原路径 ../../../../../git/ai-novel-project/MuMuAINovel/backend/app/api/chapters.py:1837,已随旧实现退出,见固定基线)。路由文件同时容纳查询、分析、生成、保存与进度,不能作为新版 Python 组织模板。BaseAIProvider.generate_stream 只交付字符串片段:接口:24(原路径 ../../../../../git/ai-novel-project/MuMuAINovel/backend/app/services/ai_providers/base_provider.py:24,已随旧实现退出,见固定基线),新版应交付规范事件与明确终态,便于区分文本、用量、正常完成、取消与不完整输出。本轮未找到与上述前置检查对应的独立测试源码,保持未验证。
4. 应避免照搬的实现形态
| 反例 | 新版必须换成的边界 |
|---|---|
| 把所有领域放进一个 editor、router、committer 或工具注册大文件 | UI 负责交互;应用服务负责用例;领域负责合法性;数据库和模型在适配层。每个模块只暴露少量业务入口。 |
| 用“流结束”“文件存在”“completed 字段”“报告里没有问题”表达整条创作成功 | 分别记录传输完成、输出有效、候选已保存、作者已决定、正式写入、派生任务状态;每个状态由所属步骤确认。 |
| LLM 输出宽松解析后默认补空或补分数 | 保存原始输出和解析错误;严格 schema 与领域校验失败后进入失败/待人工,不制造通过报告。 |
| UI 保存、CLI、Skill 和后台任务各有一条正式写入路径 | 入口可多,正式命令共用;人工编辑和 AI 采纳各有明确命令,同样执行 revision、作用域和审计。 |
| 全局“记忆”混放设定、未来计划、读者已知、历史原文和跨书素材 | 区分类型、权威、作品、来源与时间;检索提供证据,领域事实提供已确认状态。 |
| 为升级复制整套运行框架、存储、平台插件或多产品模型 | 吸收接口与失败语义;保留 agent-example 的主体规则与已验证保护,按用例重写实现。 |
| 用几类风格分数、固定禁词或一套网文套路泛化所有中文创作 | 技术不变量固定;写作方法按题材、作品、作者与本次任务选择,带版本与效果证据。 |
5. 许可文件实读记录
本节只记录当前文件中的文字或 SPDX,不作法律结论,也不表示已经获准复制代码。实际复用前应核对具体文件、子包及所带依赖的许可和归属;只学习接口思想与直接复制实现也应在后续设计中分别记录。
| 来源 | 当前读取结果 | 文件依据 |
|---|---|---|
| StoryForge、character-arc | 根 LICENSE 为 MIT | StoryForge LICENSE(原路径 ../../../../../git/ai-novel-project/storyforge/LICENSE:1,已随旧实现退出,见固定基线)、character-arc LICENSE(原路径 ../../../../../git/ai-novel-project/character-arc/LICENSE:1,已随旧实现退出,见固定基线) |
| AI-Novel-Writing-Assistant | 根文件写明默认 AGPL-3.0-only,同时有 commercial authorization 说明 | LICENSE:1(原路径 ../../../../../git/ai-novel-project/AI-Novel-Writing-Assistant/LICENSE:1,已随旧实现退出,见固定基线) |
| InkOS、neuro-book | 根 LICENSE 为 AGPL v3;package SPDX 为 AGPL-3.0-only;neuro-book 部分子包有独立许可文件 | InkOS LICENSE(原路径 ../../../../../git/ai-novel-project/inkos/LICENSE:1,已随旧实现退出,见固定基线)、neuro-book LICENSE(原路径 ../../../../../git/ai-novel-project/neuro-book/LICENSE:1,已随旧实现退出,见固定基线) |
| MuMuAINovel、webnovel-writer | 根 LICENSE 为 GPL v3 | MuMu LICENSE(原路径 ../../../../../git/ai-novel-project/MuMuAINovel/LICENSE:1,已随旧实现退出,见固定基线)、webnovel LICENSE(原路径 ../../../../../git/ai-novel-project/webnovel-writer/LICENSE:1,已随旧实现退出,见固定基线) |
| Openwrite | 当前根未见 LICENSE;package.json 声明 Apache-2.0;内嵌 Skill 有各自 LICENSE | package.json(原路径 ../../../../../git/ai-novel-project/Openwrite/package.json:1,已随旧实现退出,见固定基线)、内嵌 Skill 许可示例(原路径 ../../../../../git/ai-novel-project/Openwrite/presets/openwrite/skills/oh-story-deslop/LICENSE:1,已随旧实现退出,见固定基线) |
| PlotPilot | 根 LICENSE 先列 Commons Clause,再列 Apache 2.0 | LICENSE:1(原路径 ../../../../../git/ai-novel-project/PlotPilot/LICENSE:1,已随旧实现退出,见固定基线) |
| flymd | 根文件写 GPL-3.0,package.json 的 SPDX 为 LicenseRef-flyMD-NC-1.0,两处不一致 | LICENSE:1(原路径 ../../../../../git/ai-novel-project/flymd/LICENSE:1,已随旧实现退出,见固定基线)、package.json(原路径 ../../../../../git/ai-novel-project/flymd/package.json:1,已随旧实现退出,见固定基线) |
| kimi-writer | 根 LICENSE 写 MIT with Attribution Requirement,并有商业归属说明 | LICENSE:1(原路径 ../../../../../git/ai-novel-project/kimi-writer/LICENSE:1,已随旧实现退出,见固定基线) |
其余仓根文件筛查结果:51mazi / 91Writing / chinese-novelist-skill / novel-writer / oh-story-claudecode / show-me-the-story 写 MIT;OpenFic / ainovel-cli / denova 写 Apache 2.0;AI_NovelGenerator / NovelForge 写 AGPL v3;QMAI / awesome-novel-agent / vela 写 GPL v3;Ai-Novel / MaliangAINovalWriter / WriteHERE / arboris-novel / novel-creator-skill 未发现根 LICENSE/COPYING。本轮未对这些非重点仓的文件级例外作完整审计。
6. 交给总体架构的实施要求
| 新版职责 | 参考实现输入 | 必须由新版实现的验收反例 |
|---|---|---|
| 正文与候选 | StoryForge 的来源/候选快照;character-arc 的分项决定 | 作者改稿后旧候选不能覆盖;相同命令重发只产生一个正文 revision;跨作品候选拒绝。 |
| 作品规划 | AI-Novel-Writing-Assistant 的 JIT 接口 | 新作品无需改代码;已确认且完整的合同不重新生成;前置变化需显式重规划或冻结读取。 |
| 上下文与知识 | StoryForge 的权限收窄;neuro-book 的时点查询 | 直接工具、预组装和回放都不能越过作品/章节/时点边界;必读证据不足不静默裁掉。 |
| 事实与连续性 | webnovel-writer 的提交/事件/投影分离 | 未采纳正文不改变正式事实;派生任务失败可单独恢复;重新执行不重复累计状态。 |
| 审稿与修订 | InkOS 的停止/快照/恢复 | 解析失败不触发改稿;硬门退步不能由高分覆盖;原稿胜出、零修改和到达上限均有正常终态。 |
| 运行与宿主 | neuro-book 的 port/journal 合同 | 测试适配器无需网络;正式适配器明确终态与错误;未知执行结果不得直接重发外部副作用。 |
| 作者工作台 | StoryForge 的受控组件;Openwrite 的切换屏障 | 切章、切作品、断网和迟到回包不丢稿、不串稿;恢复页面不隐式重新生成。 |
| 数据管理 | StoryForge 的生命周期声明 | 完整备份含原始资料、来源关系和运行证据;恢复核对数据;旧版本有明确迁移与拒绝策略。 |
上述要求是设计建议与验收目标,不表示新版实现已存在。8 个重点机制的事实仅限所列当前源码;整仓功能成熟度、真实模型效果、PG 事务适配、浏览器输入体验与数据迁移仍需在后续实施时验证。