plugin-runtime-hardening-spec-2026-06-04.md 45 KB

Plugin Runtime Hardening Spec

日期:2026-06-04 状态:草案 v1 范围:基于优秀 Claude Code 插件调研,对 webnovel-writer 的插件形态、运行时可靠性、workflow 编排、doctor 自检、hook 状态感知、eval 与发布治理做系统收束 调研样本:anthropics/claude-plugins-officialanthropics/skillsobra/superpowersSonarSource/sonarqube-agent-pluginsappwrite/claude-pluginaws-samples/sample-claude-code-plugins-for-startups、社区多插件 marketplace


1. 背景

webnovel-writer 当前已经不是普通单一 Skill,而是一个完整的长篇写作运行时插件:

  • 7 个 Skill 命令负责 init / plan / write / review / query / learn / dashboard。
  • 4 个 Agent 负责写前上下文、审查、事实提取、参考拆解。
  • Python CLI 与 data_modules 承担 Story System、commit、projection、RAG、memory、Dashboard 数据层。
  • .story-system/ 是合同与提交主链,.webnovel/* 是 projection / read-model。

优秀 Claude Code 插件的共同经验是:

  1. SKILL.md 做路由和流程,不承载全部知识。
  2. 确定性动作下沉到脚本 / runtime / MCP,而不是靠 prompt 约束。
  3. commands / skills / agents / hooks / MCP 边界清楚。
  4. hooks 只做轻量状态提示、自检或接线,不做重业务。
  5. 复杂 workflow 有可验证的输入、输出、停止条件和验收标准。
  6. doctor / integrate / setup 类环境自检入口。
  7. 有真实行为 eval,证明 agent 会按协议执行。
  8. manifest、marketplace、README、版本、LICENSE 有校验,避免漂移。

本 spec 的目标是把这些经验转化为 webnovel-writer 的下一阶段架构改造路线。


2. 一句话目标

webnovel-writer 从“强 Skill 包 + Python 工具链”升级为:

可自检、可验证、可恢复、可重放、可发版治理的长篇写作运行时插件。


3. 设计原则

3.1 Runtime First

写章、提交、投影、校验等关键链路必须由 runtime 保证,不再主要依赖 Skill 文档中的自然语言步骤。

3.2 Skill as Router

SKILL.md 保留:

  • 何时触发
  • 决策树
  • 高层流程
  • 必读/按需引用路由
  • 失败处理边界

SKILL.md 不应承担:

  • 长命令拼接细节
  • schema 校验逻辑
  • projection 修复逻辑
  • 大段题材知识
  • 可程序化验证规则

3.3 Commit Is Fact

CHAPTER_COMMIT 是写后事实,不应和 projection 执行日志混在一起。事实记录与投影执行状态要逐步解耦。

3.4 Hooks Are Advisory Guards

hooks 可以承担“自动触发的轻量守卫”,但不能成为隐藏业务流程。

允许:

  • SessionStart 项目状态摘要
  • 依赖 / 配置提醒
  • doctor 入口提示
  • dashboard / RAG / Story System 健康提示
  • skill-scoped 固定预检,且通过时静默
  • PreToolUse 对危险写入 / commit 命令做硬阻断

禁止:

  • 自动写 state / commit / memory
  • 自动安装外部依赖
  • 自动修改正文或设定
  • 注入大段创作方法论
  • 作为章节主状态机写入 step state
  • 每个步骤都用 hook 自动打点
  • 在用户不可见的情况下推进写作流程

3.5 Behavior Must Be Tested

现有 Python 单元测试继续保留,但不足以证明插件行为。必须增加 skill / agent 工作流级 eval。

3.6 UTF-8 First

本项目大量读取中文路径和中文文件名,新入口必须显式 UTF-8:

  • Python CLI 入口调用 enable_windows_utf8_stdio() 或等价逻辑。
  • 所有文本读取 / 写入显式 encoding="utf-8"
  • hook / 子进程命令优先使用 python -X utf8,或显式设置 PYTHONUTF8=1
  • doctor / project-status / write-gate / hook 脚本不得依赖系统默认编码。

3.7 Follow Official plugin-dev

后续对本插件的任何新增或修改,必须先遵循官方 plugin-dev 插件的指导:

C:\Users\lcy\.claude\plugins\marketplaces\claude-plugins-official\plugins\plugin-dev

落地约束:

  • 插件结构遵循 plugin-structure.claude-plugin/plugin.json 必须在插件根的 .claude-plugin/ 下;commands/agents/skills/hooks/ 位于插件根层级。
  • 所有插件内路径使用 ${CLAUDE_PLUGIN_ROOT},不在 manifest / hook / command 中写死本机绝对路径。
  • 新增 Skill 遵循 skill-developmentSKILL.md 必须有 name、具体触发型 description、可选 version;正文保持精简,详细规则放入 references/,确定性脚本放入 scripts/
  • 新增 Command 遵循 command-development:使用 markdown + YAML frontmatter,包含清晰 description、必要时声明 argument-hintallowed-tools
  • 新增 Agent 遵循 agent-development:frontmatter 补齐 namedescriptionmodel / tools 等字段;复杂触发场景用示例描述;修改后用 validate-agent 规则检查。
  • 新增 Hook 遵循 hook-development:插件级 hooks/hooks.json 使用 wrapper 格式,即外层包含 descriptionhooks;命令 hook 使用 ${CLAUDE_PLUGIN_ROOT};轻量确定性检查用 command hook,上下文判断才用 prompt hook。
  • 修改插件组件后,必须按 plugin-validator 思路做结构校验:manifest、commands、agents、skills、hooks、MCP、README、LICENSE、敏感信息与路径可移植性。

这条优先级高于本 spec 中任何自定义落点建议;如果冲突,以官方 plugin-dev 约束为准。


4. 非目标

本轮不做:

  • 不重写 Story System 主链语义。
  • 不引入大规模新 MCP 服务。
  • 不把 37 个题材模板拆成 37 个独立 Skill。
  • 不照搬 Superpowers 的高频 git commit 机制。
  • 不让 hook 承担写作业务。
  • 不在本轮重构 Dashboard 前端信息架构。
  • 不改变已有用户项目的数据格式,除非提供兼容读取。

5. 目标架构

5.1 组件边界

commands/ 或 Slash Skill 入口
        ↓
Skill router(流程、引用路由、失败边界)
        ↓
Claude Code Todo(过程约束,由宿主管理)
        ↓
Runtime Gates(写前 / 提交前 / 提交后批量校验)
        ↓
Agents(context / draft / review / data extract)
        ↓
Artifact Validator
        ↓
CHAPTER_COMMIT(事实主链)
        ↓
Projection Engine(state/index/summary/memory/vector)
        ↓
Dashboard / Query / Doctor(只读消费)

5.2 写章过程管理

不新增独立 resume / step mark / workflow state。Claude Code 本身已经有 Todo 和会话恢复能力,写章过程的步骤约束交给宿主 Todo 管理。

推荐 Todo 形态:

[ ] 写前预检与合同刷新
[ ] context-agent 生成写作任务书
[ ] 起草正文
[ ] reviewer 审查
[ ] blocking issue 裁决 / 定点修复
[ ] 润色与排版
[ ] data-agent 提取事实 artifacts
[ ] chapter-commit 提交事实
[ ] 验证 projection 与备份

runtime 不维护每一步状态,只提供三个自然边界的批量 gate:

  • prewrite:写前检查项目根、占位符、Story Runtime、章节合同。
  • precommit:提交前检查正文、review、fulfillment、disambiguation、extraction artifacts。
  • postcommit:提交后检查 commit、projection、summary、memory、backup。

这样一章最多增加 2-3 次确定性脚本调用,不做每一步打点。

5.3 状态感知模型

项目状态分两层:

层级 负责者 持久性 用途
会话内进度 Claude Code Task / Todo 会话级 约束本轮写作步骤、显示当前正在做什么
项目真实状态 Story System / commit / projection / artifacts 项目级 新对话、resume、doctor 判断下一步

不新增独立 workflow state。项目真实状态由 runtime 现场推导:

  • .story-system/commits/*.commit.json 判断最新 accepted/rejected 章节。
  • .story-system/MASTER_SETTING.json 和章节合同判断下一章目标。
  • .webnovel/tmp/* artifacts 判断是否已经 review / fulfillment / extraction。
  • .webnovel/projection_log.jsonl 或兼容字段判断 projection 是否失败。
  • draft 文件和 chapter artifact 判断是否存在未提交正文。

新增机器可读的项目状态入口,避免占用现有 webnovel.py status。当前 status 已转发到 status_reporter.py,语义是宏观创作健康报告;本 spec 需要的是短状态摘要,因此使用新命令:

webnovel.py project-status --format json
webnovel.py project-status --format summary

示例状态:

{
  "schema_version": "webnovel-project-status/v1",
  "project": "灵石庄",
  "latest_accepted_chapter": 12,
  "target_chapter": 13,
  "phase": "chapter_contract_ready",
  "blocking": [],
  "warnings": ["rag_vector_missing"],
  "next_action": "run /webnovel-write chapter 13"
}

phase 是一个可推导状态,不是 hook 写入的状态机。phase 词表必须只有一个权威来源,建议新增 project_phase.py,由 doctor、project-status、write-gate 共同消费。推荐最小集合:

  • no_project
  • unknown
  • init_scaffolded
  • init_ready
  • plan_in_progress
  • chapter_contract_ready
  • draft_in_progress
  • ready_to_commit
  • chapter_committed
  • projection_failed

5.4 Hook 与状态的边界

hook 只读状态、注入短上下文或阻断危险动作:

  • SessionStart:调用 project-status --format summary,在新对话、resume、clear、compact 后告诉 Claude 当前项目写到哪里。
  • PreToolUse:在 webnovel-write skill 激活期间,阻断绕过 gate 的 commit / projection 写入。
  • PostToolUse:可用于把 gate 失败原因补充给 Claude,但不能防止已经发生的副作用。

状态转换只能来自显式 runtime 命令:

  • write-gate --stage prewrite/precommit/postcommit
  • chapter-commit
  • projections retry/replay
  • 用户显式裁决 blocking issue

这保证流程推进发生在显式 skill / runtime 命令中,而不是 hook 暗中推进。


6. Phase 1:webnovel-doctor 项目体检入口

6.1 目标

新增只读体检命令,作为现有 preflight 的上位诊断入口。preflight 已经负责 CLI 环境、project_root 与 story_runtime 摘要;doctor 必须复用或吸收这些检查,不另造一套并行环境检查。

重点解决三类问题:

  1. 文件层面:目录是否规范、关键文件是否缺失、JSON / SQLite / Markdown 等内容是否符合预期。
  2. 系统配置层面:RAG API / key、Python 依赖、Dashboard 构建产物等运行条件是否完整。
  3. 错误解释与修复建议:缺失或异常时说明影响范围,并给出可执行修复命令或人工处理建议。

doctor 不负责判断一章具体该怎么写,也不替代 write-gate。它回答的是:

这个书项目和当前插件运行环境是否完整、可读、可运行;如果不完整,哪里坏了,怎么修。

6.2 入口

CLI:

python -X utf8 webnovel-writer/scripts/webnovel.py --project-root "<PROJECT_ROOT>" doctor --format json

Skill:

/webnovel-doctor

与现有入口关系:

  • preflight:保留为快速环境检查和兼容入口。
  • doctor:覆盖 preflight 的快检能力,并追加阶段感知文件清单、SQLite、RAG、Python 依赖、Dashboard、修复建议。
  • project-status:只输出短状态和下一步,不做深度体检。
  • status:保留现有 status_reporter.py 的宏观创作健康报告语义。

可选后续 hook:

SessionStart -> 打印 project-status 摘要;异常时提示运行 /webnovel-doctor

6.3 模式

默认模式必须只做本地只读检查:

webnovel.py doctor --format json
webnovel.py doctor --format text

可选深度模式才允许做慢检查或外部连通性检查:

webnovel.py doctor --deep --format json

可选章节模式用于检查指定章节相关 artifacts:

webnovel.py doctor --chapter 13 --format json

默认 doctor 禁止:

  • 写任何文件。
  • 自动修复。
  • 自动安装 Python / Node 依赖。
  • 自动启动 Dashboard。
  • 默认联网测试 RAG API。

6.4 阶段感知的期望文件清单

doctor 必须先判断项目当前阶段,再决定“这个阶段应该有哪些文件”。不能用最终态清单检查所有项目。

6.4.1 阶段推导

阶段由共享 project_phase.py 现场推导,不写任何状态文件。doctor、project-status、write-gate 必须消费同一个 resolver,避免出现多套 phase 词表:

phase 判定依据 含义
no_project project root 无效,或没有 .webnovel/state.json 尚未初始化或未绑定书项目
unknown 文件状态不足以稳定判断 只做低风险检查
init_scaffolded .webnovel/state.json、基础目录、设定集/总纲,但没有 .story-system/MASTER_SETTING.json webnovel.py init 刚结束,Story System 尚未生成
init_ready .webnovel/state.json、基础设定集、大纲/总纲.md.story-system/MASTER_SETTING.json init 完成,可进入 plan
plan_in_progress 有 MASTER_SETTING,但卷/章合同不完整 正在规划,尚不能直接写章
chapter_contract_ready 指定章节有 volume / chapter / review 合同 可进入写前上下文和起草
draft_in_progress 指定章节有正文草稿或 .webnovel/tmp artifacts 写章中或审查中
ready_to_commit review / fulfillment / disambiguation / extraction artifacts 都存在 可进入 precommit gate
chapter_committed 指定章节有 commit 章节已提交,检查 projection
projection_failed latest commit 有 projection_status.failed:* read-model 不可信,需要修复

如果无法确定阶段,返回 phase=unknown,并只做低风险文件可读性检查。

6.4.2 阶段期望清单

doctor 输出必须包含当前阶段的期望清单:

{
  "phase": "init_ready",
  "expected_profile": "after_init",
  "expected_files": {
    "required": [
      ".webnovel/state.json",
      ".webnovel/summaries/",
      "设定集/世界观.md",
      "设定集/力量体系.md",
      "设定集/主角卡.md",
      "设定集/反派设计.md",
      "大纲/总纲.md",
      ".env.example",
      ".story-system/MASTER_SETTING.json"
    ],
    "conditional": [
      "设定集/主角组.md",
      "设定集/女主卡.md"
    ],
    "not_expected_yet": [
      ".story-system/volumes/volume_001.json",
      ".story-system/chapters/chapter_001.json",
      ".story-system/reviews/chapter_001.review.json",
      ".story-system/commits/chapter_001.commit.json",
      ".webnovel/summaries/chapter_001.md",
      ".webnovel/memory_scratchpad.json"
    ]
  }
}

conditional 文件必须根据 state.json 判断。例如:

  • protagonist_structure 是多主角 / 主角组时,才要求 设定集/主角组.md
  • heroine_config 不是无女主时,才要求 设定集/女主卡.md
  • 无金手指项目不要求单独 金手指设计.md

6.4.3 init 刚结束的判定

webnovel.py init 刚结束时,合理期望是项目骨架完整,但不要求写作后产物。

必须存在:

.webnovel/
.webnovel/backups/
.webnovel/archive/
.webnovel/summaries/
.webnovel/state.json
设定集/
设定集/世界观.md
设定集/力量体系.md
设定集/主角卡.md
设定集/反派设计.md
大纲/
大纲/总纲.md
正文/
审查报告/
.env.example

如果 /webnovel-init 已完成 Story System 初始化,还必须存在:

.story-system/
.story-system/MASTER_SETTING.json
.story-system/anti_patterns.json

init 阶段不应该要求:

.story-system/volumes/volume_001.json
.story-system/chapters/chapter_001.json
.story-system/reviews/chapter_001.review.json
.story-system/commits/chapter_001.commit.json
.webnovel/summaries/chapter_001.md
.webnovel/memory_scratchpad.json
.webnovel/vectors.db

缺这些只能返回 skipinfo,不能作为 warning / blocker。

6.4.4 plan / write / commit 阶段清单

规划完成后,才开始要求:

.story-system/volumes/volume_001.json
.story-system/chapters/chapter_001.json
.story-system/reviews/chapter_001.review.json

写章中,才开始检查:

.webnovel/tmp/review_results.json
.webnovel/tmp/fulfillment_result.json
.webnovel/tmp/disambiguation_result.json
.webnovel/tmp/extraction_result.json

commit 后,才开始要求:

.story-system/commits/chapter_001.commit.json
.webnovel/summaries/chapter_001.md
.webnovel/index.db

RAG 向量库永远是增强项:

.webnovel/vectors.db

缺失或为空默认只返回 warning,并说明会降级 BM25;在用户显式要求语义检索或 --deep --require-rag 时才可升级为 blocker。

6.4.5 误报控制

doctor 的严重级别必须基于“当前阶段 + 用户目标”判断:

情况 阶段 结果
缺 commit init_ready skip / info
缺 commit ready_to_commit blocker
缺 summary init_ready skip / info
缺 summary chapter_committed 且 projection summary=done blocker
缺 vectors.db 任意默认模式 warning
缺 MASTER_SETTING init_scaffolded warning,提示运行 story-system persist
缺 MASTER_SETTING plan_in_progress 或之后 blocker

6.5 文件 / 数据结构检查

doctor 必须把“肉眼难看见”的项目文件和数据库结构变成可读报告。

6.5.1 目录结构

检查:

  • project root 是否有效,且不是插件目录本身。
  • .webnovel/ 是否存在。
  • .story-system/ 是否存在。
  • 正文/大纲/设定集/ 等书项目目录是否存在。
  • 用户项目文件是否误写入插件目录。

判定:

  • project root 无效:blocker
  • .webnovel/.story-system/blockerwarning,取决于是否是刚 init 的项目。
  • 缺正文/大纲/设定集目录:warning,并提示初始化或补建。

6.5.2 Story System 主链文件

检查:

  • .story-system/MASTER_SETTING.json 是否存在、JSON 可读、meta.contract_type 是否正确。
  • volumes/volume_*.json 是否存在、JSON 可读。
  • chapters/chapter_*.json 是否存在、JSON 可读。
  • reviews/chapter_*.review.json 是否存在、JSON 可读。
  • commits/chapter_*.commit.json 是否存在、JSON 可读。
  • latest commit 的 meta.status 是否是 accepted / rejected
  • latest commit 的 provenance.write_fact_role 是否为 chapter_commit

判定:

  • 主链 JSON 读不出来:blocker
  • 已进入写作流程但缺 MASTER_SETTING:blocker
  • latest commit schema 明显不合法:blocker
  • 新项目尚无 commit:infowarning,不能误报为错误。

6.5.3 Projection / Read-model 文件

检查:

  • .webnovel/state.json 是否存在、JSON 可读、基础字段可解析。
  • .webnovel/summaries/ 是否存在,最新 accepted 章节是否有 summary。
  • .webnovel/memory_scratchpad.json 是否存在、JSON 可读、基础结构可解析。
  • latest commit 的 projection_status 是否有 pending / failed:*

判定:

  • state.json 不可读:blocker
  • projection writer failed:blocker,因为后续查询和 dashboard 可能不可信。
  • summary / memory 缺失:通常 warning,除非对应 projection 标记为 done 但实物不存在。

6.5.4 SQLite 数据库

检查 .webnovel/index.db

  • 文件是否存在。
  • SQLite 是否可打开。
  • 关键表是否存在。
  • 关键表行数是否异常。
  • 基础查询是否能执行。

建议首批关键表:

entities
relationships
story_events
review_metrics
writing_checklist_scores
override_ledger

检查 .webnovel/vectors.db

  • 文件是否存在。
  • SQLite 是否可打开。
  • vectors 表是否存在。
  • vector 行数。
  • bm25_index / doc_stats 是否存在。

数据库报告必须显式展示表和行数,例如:

{
  "id": "db.index.tables",
  "status": "ok",
  "severity": "info",
  "path": ".webnovel/index.db",
  "tables": {
    "entities": 128,
    "relationships": 42,
    "story_events": 36,
    "review_metrics": 12
  }
}

判定:

  • index.db 不存在或打不开:blocker
  • story_events 缺失:warningblocker,取决于当前是否已经有 accepted commit。
  • vectors.db 缺失:warning,RAG 可降级 BM25。
  • vectors 行数为 0:warning

6.5.5 Reference / CSV 文件

检查:

  • references/csv/*.csv 是否存在。
  • 必要 CSV 表头是否符合预期。
  • 题材别名、题材与调性推理、反模式等核心表是否可读。
  • 明显占位符是否残留。

判定:

  • 核心 CSV 不可读或表头缺失:warning
  • 会导致 story-system 无法生成 MASTER_SETTING 的缺失:blocker

6.6 系统 / 配置检查

6.6.1 Python 依赖

检查:

  • 当前 Python 版本。
  • scripts/requirements.txt 是否存在。
  • 核心包是否可 import。

首批核心包:

pydantic
numpy
requests
fastapi
uvicorn
watchdog

判定:

  • 运行 CLI 必需包缺失:blocker
  • Dashboard 专用包缺失:warning,除非用户正在运行 dashboard skill。

6.6.2 RAG 配置

默认模式检查:

  • .env / 环境变量是否能读到 embedding 配置。
  • embed base_url / model 是否配置。
  • embed api_key 是否存在。
  • rerank base_url / model / api_key 是否存在。
  • vectors.db 是否存在且有数据。
  • 当前推断 RAG 模式:full / embed_only / bm25_only

--deep 模式才检查:

  • embed API 是否真实可调用。
  • rerank API 是否真实可调用。
  • API 返回维度是否与已有 vectors 兼容。

判定:

  • 缺 RAG key:warning,必须明确说明会降级到 BM25。
  • API 连通失败:warningblocker,取决于用户是否要求必须语义检索。
  • base_url / model 明显空缺:warning

6.6.3 Dashboard / Node

检查:

  • dashboard/frontend/dist/index.html 是否存在。
  • dashboard 后端模块是否能 import。
  • dashboard/requirements.txt 是否存在。
  • dashboard/frontend/package.json 是否存在。

默认不检查:

  • 不自动 npm install
  • 不自动启动服务。
  • 不默认检查 localhost 端口。

判定:

  • dist 缺失:warning,提示重新 build。
  • FastAPI 依赖缺失:warning

6.7 输出格式

每条检查必须包含:

  • id:稳定错误码,方便测试和 UI 展示。
  • statusok / fail / warn / skip
  • severityblocker / warning / info
  • path:相关文件路径,没有则为空。
  • expected:预期状态。
  • actual:实际状态。
  • impact:对用户有什么影响。
  • repair:修复命令或人工修复建议。

    {
    "ok": false,
    "project_root": "...",
    "mode": "default",
    "phase": "chapter_committed",
    "expected_profile": "after_commit",
    "blocking_count": 1,
    "warning_count": 2,
    "expected_files": {
    "required": [".webnovel/state.json", ".story-system/commits/chapter_001.commit.json"],
    "not_expected_yet": []
    },
    "checks": [
    {
      "id": "db.index.missing_table",
      "status": "fail",
      "severity": "blocker",
      "path": ".webnovel/index.db",
      "expected": "table story_events exists",
      "actual": "table missing",
      "impact": "无法确认 accepted commit 的事件链是否完成投影",
      "repair": {
        "command": "webnovel.py projections replay --from 1 --to latest --writers index",
        "manual": "如果 replay 尚未实现,先重新执行最近章节的 chapter-commit 或从备份恢复 index.db"
      }
    }
    ],
    "recommended_actions": [
    {
      "command": "webnovel.py rag stats",
      "reason": "vectors.db missing; semantic retrieval will fall back to BM25",
      "severity": "warning"
    }
    ]
    }
    

6.8 错误码命名

错误码按域划分:

project.root.invalid
project.phase.unknown
project.expected_file.missing
project.structure.missing_dir
story.master.missing
story.commit.invalid_json
story.commit.invalid_status
projection.status.failed
projection.file.missing
db.index.unreadable
db.index.missing_table
db.vector.empty
rag.embed.key_missing
rag.embed.api_unreachable
python.import_missing
dashboard.dist_missing
reference.csv.invalid_header
artifact.schema_error

6.9 文件落点

  • webnovel-writer/scripts/data_modules/doctor.py
  • webnovel-writer/scripts/data_modules/project_phase.py
  • webnovel-writer/scripts/data_modules/project_status.py
  • webnovel-writer/scripts/data_modules/webnovel.py
  • webnovel-writer/skills/webnovel-doctor/SKILL.md
  • webnovel-writer/scripts/data_modules/tests/test_doctor.py
  • webnovel-writer/scripts/data_modules/tests/test_project_phase.py
  • webnovel-writer/scripts/data_modules/tests/test_project_status.py
  • docs/guides/commands.md

6.10 验收

  • 空项目返回 ok=false,但不写任何文件。
  • init 刚结束时能识别 phase=init_scaffoldedphase=init_ready,并返回该阶段的 expected_files
  • init 刚结束时缺 commit / summary / memory / vectors.db 不得返回 blocker。
  • init 刚结束时缺 state.json设定集/世界观.md大纲/总纲.md 必须返回 blocker 或 warning,并给出补救命令。
  • MASTER_SETTING.jsoninit_scaffolded 阶段缺失是 warning,在 plan/write 阶段缺失是 blocker。
  • 正常项目返回 ok=true,并显示 index.db / vectors.db 的关键表和行数。
  • state.json 返回 project.structureprojection.file 类 blocker。
  • index.db 缺关键表时返回稳定错误码、影响说明和修复建议。
  • vectors.db 缺失或为空时返回 warning,并明确说明 RAG 会降级到 BM25。
  • 缺 RAG key 时返回 warning,不阻断普通写作。
  • Python 必需包缺失时返回 blocker,并提示安装 scripts/requirements.txt
  • Dashboard dist 缺失时返回 warning,并提示 build 命令。
  • latest commit projection failed 时返回 actionable command。
  • 默认模式不联网、不安装依赖、不启动服务、不写文件。
  • --deep 模式可进行 RAG API ping,但必须明确标记为 deep check。
  • preflight 仍可运行;其结果与 doctor 的快检部分不冲突。
  • 所有中文路径和中文文件读取在 Windows 下使用 UTF-8,不因默认 GBK 失败。

7. Phase 2:章节 Runtime Gates

7.1 目标

不重造一套 workflow/resume 系统。把 /webnovel-write 中最容易出错的关键边界下沉为批量校验 gate,过程顺序由 Claude Code Todo 约束。

实施顺序上,Runtime Gates 必须依赖 Artifact Validator 的统一错误语义;本节描述 gate 设计,不代表先于 validator 开工。

7.2 新增模块

建议新增 gate 外壳,但 prewrite 必须包装或迁移现有 PrewriteValidator,不得重写一套占位符和合同判断逻辑:

webnovel-writer/scripts/data_modules/write_gates/
  __init__.py
  prewrite.py
  precommit.py
  postcommit.py

已有复用点:

  • webnovel-writer/scripts/data_modules/prewrite_validator.py
  • webnovel-writer/scripts/data_modules/tests/test_prewrite_validator.py

7.3 Gate 设计

不写 .workflow.json,不维护 step state。每次 gate 根据现有项目文件和 artifacts 现场计算结果。

统一输出:

{
  "schema_version": "write-gate/v1",
  "chapter": 12,
  "stage": "precommit",
  "ok": false,
  "blocking": [
    {
      "type": "pending_disambiguation",
      "detail": "disambiguation_result.pending is not empty"
    }
  ],
  "warnings": [],
  "artifacts": {
    "review_result": ".webnovel/tmp/review_results.json",
    "fulfillment_result": ".webnovel/tmp/fulfillment_result.json",
    "disambiguation_result": ".webnovel/tmp/disambiguation_result.json",
    "extraction_result": ".webnovel/tmp/extraction_result.json"
  }
}

7.4 Gate 职责

runtime gate 负责:

  • 校验必要文件存在。
  • 校验 JSON schema。
  • prewrite 阶段复用 PrewriteValidator
  • 判定 blocking issue。
  • 判定是否允许进入下一自然阶段。
  • 输出明确的失败原因和建议命令。

runtime gate 不负责:

  • 代替 LLM 起草正文。
  • 代替 Agent 做审查。
  • 自动决定用户裁决。
  • 记录每一步进度。
  • 替代 Claude Code Todo / 会话恢复能力。

7.5 CLI 子命令

webnovel.py write-gate --chapter N --stage prewrite --format json
webnovel.py write-gate --chapter N --stage precommit --format json
webnovel.py write-gate --chapter N --stage postcommit --format json

7.6 Skill 改动

webnovel-write/SKILL.md 改为:

  1. 使用 Claude Code Todo 建立本章流程清单。
  2. write-gate --stage prewrite,通过后才写。
  3. 调 context-agent。
  4. 起草正文。
  5. 调 reviewer。
  6. blocking issue 由 Todo 记录并裁决 / 定点修复。
  7. 润色后调 data-agent。
  8. write-gate --stage precommit,通过后才提交。
  9. 调 chapter-commit。
  10. write-gate --stage postcommit,通过后才宣布完成。

7.7 验收

  • review_results.json 时不允许进入 commit。
  • reviewer 有 blocking issue 时 precommit.ok=false
  • disambiguation pending 非空时 precommit.ok=false
  • projection failed 时 postcommit.ok=false
  • gate 调用次数控制在每章 2-3 次,不做逐步 mark。

8. Phase 3:Artifact Validator

8.1 目标

统一校验所有 agent 产物,避免字段名漂移、包错外层、缺 required 字段。

8.2 校验对象

  • review_results.json
  • fulfillment_result.json
  • disambiguation_result.json
  • extraction_result.json
  • chapter_XXX.commit.json
  • projection_status

权威 schema 来源:

  • review_results.jsonfulfillment_result.jsondisambiguation_result.jsonextraction_result.json 默认以 chapter_commit_schema.py 中 commit 所需的 Pydantic model 为准。
  • review_schema.pyentity_linker.py 中同名 / 近名模型只作为上游工具局部模型,不作为 commit artifact 的最终权威。
  • 如需兼容上游局部模型输出,必须在 artifact_validator.py 显式做 normalize,并在输出中标注兼容来源。

8.3 输出错误分类

schema_error
missing_artifact
blocking_review
missed_outline_node
pending_disambiguation
commit_rejected
projection_failure
unsafe_project_root
placeholder_blocker

8.4 文件落点

  • webnovel-writer/scripts/data_modules/artifact_validator.py
  • webnovel-writer/scripts/data_modules/tests/test_artifact_validator.py
  • webnovel-writer/scripts/data_modules/write_gates/precommit.py

8.5 验收

  • extraction_result.json 外层包成 {"extraction": ...} 时返回 schema_error。
  • state_deltas 使用旧字段名时能兼容或给出明确诊断。
  • disambiguation_result.pending 非空时阻断 commit。
  • fulfillment_result.missed_nodes 非空时阻断 accepted commit。
  • ReviewResult / DisambiguationResult 等同名模型不再各自漂移,validator 明确以 commit artifact schema 为准。

9. Phase 4:Commit 不可变与 Projection Log 外置

9.1 当前问题

当前 ChapterCommitService 会:

  1. build commit。
  2. persist commit。
  3. apply projections。
  4. projection_status 写回 commit。

这让 commit 同时承担“事实记录”和“投影执行日志”两个职责。

9.2 目标

将事实与投影执行状态拆开:

.story-system/commits/chapter_012.commit.json     # 不可变事实
.webnovel/projection_log.jsonl                    # 投影执行日志
index.db.projection_runs                           # 可查询投影状态

9.3 迁移策略

Phase 4 不强制立刻删除 commit 内 projection_status,采用双写过渡:

  1. 保留 commit 内 projection_status 兼容 Dashboard。
  2. 新增 projection log。
  3. Dashboard / doctor 优先读取 projection log。
  4. 后续版本再将 commit 内 projection_status 标记 deprecated。

9.4 Projection Run Schema

{
  "run_id": "ch012-20260604T102233",
  "chapter": 12,
  "commit_path": ".story-system/commits/chapter_012.commit.json",
  "commit_hash": "sha256:...",
  "writer": "memory",
  "status": "done",
  "started_at": "...",
  "finished_at": "...",
  "error": "",
  "retry_of": ""
}

9.5 文件落点

  • webnovel-writer/scripts/data_modules/projection_log.py
  • webnovel-writer/scripts/data_modules/chapter_commit_service.py
  • webnovel-writer/scripts/data_modules/tests/test_projection_log.py
  • webnovel-writer/dashboard/app.py
  • webnovel-writer/scripts/data_modules/story_runtime_health.py

9.6 验收

  • 每个 writer 执行后都有 projection log。
  • 单 writer failed 不影响其他 writer 记录。
  • doctor 能指出 failed writer 和建议重跑命令。
  • commit 文件 hash 在 projection log 中可追溯。

10. Phase 5:Projection Replay / Retry

10.1 目标

投影失败时可以只补跑失败 writer,尤其是 vector / RAG 等外部依赖。

10.2 CLI

webnovel.py projections status --chapter N
webnovel.py projections retry --chapter N --writer vector
webnovel.py projections retry-failed --chapter N
webnovel.py projections replay --from 1 --to 20 --writers state,index,summary

10.3 约束

  • replay 只能读取 accepted commit。
  • rejected commit 只允许 state writer 更新状态。
  • writer 必须幂等。
  • retry 不得修改 commit 事实内容。

10.4 文件落点

  • webnovel-writer/scripts/data_modules/projection_runner.py
  • webnovel-writer/scripts/data_modules/event_projection_router.py
  • projection writer 幂等性测试

10.5 验收

  • 删除 summaries/chapter_012.md 后 retry summary 可恢复。
  • vector API key 缺失时 vector failed,其余 writer done。
  • 配置 key 后 retry vector 只补 vector。
  • replay 1-5 后 state/index/summary 与 commit 链一致。

11. Phase 6:Skill / Agent 契约补强

11.1 Skill Frontmatter

7 个现有 Skill 的 description 要从单句说明升级为召回规则:

  • 何时使用。
  • 典型触发词。
  • 不适用场景。
  • 是否有副作用。

示例:

description: Use when the user wants to draft, continue, rewrite, or commit a numbered webnovel chapter. Runs the full context -> draft -> review -> polish -> fact extraction -> chapter commit workflow. Do not use for pure status queries, project initialization, or dashboard-only requests.

11.2 Agent Frontmatter

所有 agent 补齐:

  • name
  • description
  • tools
  • model 可选
  • output_schema
  • failure_statuses

11.3 Agent 分工调整

现有:

  • context-agent
  • reviewer
  • data-agent
  • deconstruction-agent

建议新增或拆分:

  • continuity-reviewer:设定 / 时间线 / 人物状态 / 伏笔合规。
  • style-reviewer:文风 / AI 味 / 句式重复 / 排版。
  • reader-pull-reviewer:爽点 / 钩子 / 微兑现 / 追读力。

短期可以先不新增文件,而是在 reviewer 输出 schema 中拆维度;中期再拆 agent。

11.4 验收

  • prompt integrity 测试确认所有 Skill 有足够长的 description。
  • agent 输出 schema 可被 artifact validator 校验。
  • data-agent 文档中仍明确“不直接写 state/index/summaries/memory”。

12. Phase 7:Behavior Evals

12.1 目标

学习 Superpowers 的 headless 行为测试思路,补上“插件是否按协议执行”的验证层。

12.2 Eval 类型

新增:

evals/
  skill-triggering/
  workflow-behavior/
  agent-output-schema/
  continuity-conflict/
  memory-commit/

12.3 首批用例

Eval 目标
init_project_safety 不在插件目录生成项目,不污染 canon
plan_outputs_executable_chapter_tasks 章纲包含目标情绪、人物变化、伏笔、禁写事项
write_blocks_on_review_blocking_issue blocking issue 不进入 commit
data_agent_never_writes_projection data-agent 只产出 artifacts
commit_drives_projection accepted commit 后 projection writer 被触发
query_falls_back_explicitly 主链缺失时 query 明确说明 fallback
dashboard_readonly Dashboard API 不提供写接口

12.4 Runner

先做轻量 runner:

python webnovel-writer/scripts/run_behavior_evals.py --case write_blocks_on_review_blocking_issue

如果本地没有 Claude Code CLI,则 eval 可跳过 transcript 测试,只跑 artifact fixture 测试。

12.5 验收

  • 每个 Skill 至少有 1 个 eval。
  • webnovel-write 至少覆盖成功链路和 blocking 链路。
  • eval 输出 JSON 报告,包含 pass/fail/reason/artifacts。

13. Phase 8:Manifest / Marketplace / 发布治理

13.1 目标

防止插件元数据、README、marketplace、version 之间漂移。

13.2 校验脚本

新增:

python webnovel-writer/scripts/validate_plugin_package.py

检查:

  • .claude-plugin/marketplace.json 存在。
  • 插件 .claude-plugin/plugin.json 存在。
  • marketplace version 与 plugin.json version 一致。
  • README / 现有 CI 使用的版本位置与 plugin.json 一致;不得新增一套与既有 Plugin Version Check 冲突的 README 版本规则。
  • 每个 skills/*/SKILL.md 有 frontmatter。
  • 每个 agents/*.md 有 frontmatter。
  • LICENSE 存在。
  • Dashboard dist 存在。
  • scripts/requirements.txt 与根 requirements.txt 可解析。
  • docs 命令表与实际 Skill 名称一致。

13.3 可选 manifest 增强

如 Claude Code manifest 支持,可补:

  • commands
  • agents
  • hooks
  • mcpServers
  • user config schema
  • screenshots / assets

如果当前宿主不需要显式声明,则保持默认目录发现,避免过度配置。

13.4 验收

  • clean clone 后 validate 通过。
  • 修改 version 任一处导致 validate 失败。
  • 删除一个 Skill frontmatter 导致 validate 失败。
  • 版本校验复用或对齐现有 CI 规则,不与 README 版本表 / badge 检查互相打架。

14. Phase 9:轻量 SessionStart Hook(可选)

14.1 目标

新增可选 hook,在会话启动、resume、clear、compact 时提示项目状态。该 hook 是状态观察器,不是状态机。

14.2 输出

Webnovel Writer initialized.
  project: 灵石庄
  story runtime: mainline ready, latest chapter 12 accepted
  projections: 4 done, 1 failed(vector)
  rag: BM25 fallback; EMBED_API_KEY missing
  next: run /webnovel-doctor for details

14.3 约束

  • 只读。
  • 不安装依赖。
  • 不写任何文件。
  • 输出不超过 8 行。
  • 正常状态下只输出摘要,不输出完整 JSON。
  • 失败时给出一个下一步命令,不展开长诊断。
  • 可通过环境变量关闭:

    WEBNOVEL_DISABLE_SESSION_HOOK=1
    

14.4 文件落点

  • webnovel-writer/hooks/hooks.json
  • webnovel-writer/hooks/session_start.py
  • webnovel-writer/.claude-plugin/plugin.json 或默认 hook 发现路径
  • docs/operations/operations.md

14.5 验收

  • 无项目根时不报错,只提示未绑定项目。
  • 有项目根时调用 project-status --format summary 或 doctor summary。
  • 设置 disable env 后无输出。
  • resume 后能刷新 latest chapter / projection 状态。
  • 输出不会超过 1000 字符。

14.6 Skill-scoped 预检 Hook(可选)

/webnovel-write 这类高风险 skill,可以在 skill frontmatter 中挂轻量 hook:

  • PreToolUse(Bash):对直接运行 chapter_commit.pywebnovel.py chapter-commit 或 projection 写入命令做 best-effort 提醒 / 兜底阻断。Bash 字符串解析不能作为唯一可靠保证,真正的强保证必须在 runtime gate 和 commit 入口中实现。
  • PreToolUse(Write|Edit):如果目标路径是 .story-system/ commit、.webnovel/state.jsonindex.dbmemory_scratchpad.json 等 projection 产物,则要求走 runtime 命令。
  • hook 通过时必须静默;只在阻断时返回简短原因。

不建议把所有固定预检都放进 hook。推荐分层:

预检类型 放在哪里
新会话状态摘要 plugin-level SessionStart hook
是否能开始写本章 write-gate --stage prewrite
是否能提交本章 write-gate --stage precommit
是否能宣布完成 write-gate --stage postcommit
禁止绕过 runtime 写主链 skill-scoped PreToolUse hook
复杂修复建议 /webnovel-doctor skill

15. 推荐实施顺序

  1. project_phase + project-status + webnovel-doctor:先建立统一阶段推导、短状态和只读自检基本盘。
  2. Artifact Validator:统一错误语义。
  3. Runtime Gates:用写前 / 提交前 / 提交后批量校验约束关键边界,其中 prewrite 复用 PrewriteValidator
  4. Projection Log:事实与投影日志解耦。
  5. Projection Retry / Replay:补恢复能力。
  6. Skill / Agent 契约补强:降低 prompt 漂移。
  7. Behavior Evals:证明插件协议有效。
  8. Plugin Package Validator:发布治理。
  9. 可选 SessionStart Hook:只读状态提示。
  10. 可选 Skill-scoped PreToolUse Hook:阻断绕过 runtime 的危险写入。

16. 验收总表

能力 验收标准
Doctor 能只读报告目录/文件/数据库完整性、RAG/Python/Dashboard 配置,并给出修复建议
Project Status 能从主链和 artifacts 推导当前章节阶段,不占用既有 status_reporter.py 语义,不写 workflow state
Runtime Gates /webnovel-write 在写前、提交前、提交后三个自然边界有批量校验
Validator agent 产物 schema 漂移能被统一诊断
Commit commit 事实与 projection log 可分离追溯
Replay vector/summary 等投影失败后可单独 retry
Skills 7 个 Skill description 足够路由,长知识按需加载
Agents agent 有工具范围、输出 schema、失败状态
Evals 每个 Skill 至少 1 个行为 eval
Package manifest / marketplace / README / version 可校验
Hook 如果启用,SessionStart 只读短输出,PreToolUse 只做危险动作阻断

17. 风险

17.1 过度工程化

风险:为了学习优秀插件,把当前系统拆得太碎。 控制:先做 doctor / validator / runtime gates 三个高收益模块,不急着拆 37 个题材 Skill。

17.2 Hook 副作用

风险:hook 自动执行导致用户不信任插件。 控制:SessionStart hook 只读,PreToolUse hook 只阻断危险动作;所有修复和推进必须由 skill / runtime 显式触发。

17.3 Hook 状态机漂移

风险:如果 hook 自己写状态,可能与 commit / projection / Todo 产生三套真相。 控制:状态由共享 project_phase / project-status 现场推导;hook 不写状态;流程推进只由显式 skill / runtime 命令触发。

17.4 Commit 迁移破坏 Dashboard

风险:projection_status 外置后 Dashboard 读不到状态。 控制:先双写,Dashboard 优先读新 projection log,旧字段保留一个版本周期。

17.5 Eval 成本高

风险:headless Claude 行为 eval 慢且贵。 控制:分 fast fixture eval 和 slow transcript eval;CI 默认只跑 fast。

17.6 Skill 触发变化

风险:description 改长后触发行为变化。 控制:增加 skill-triggering eval,先验证再发布。


18. 不变量

无论如何重构,必须保持:

  1. .story-system/ 是主链真源。
  2. accepted CHAPTER_COMMIT 是写后事实入口。
  3. .webnovel/state.jsonindex.dbsummaries/memory_scratchpad.json 是 projection / read-model。
  4. data-agent 不直接写 projection。
  5. Dashboard 默认只读。
  6. RAG key 缺失必须可降级到 BM25。
  7. 用户项目文件不能写到插件目录。
  8. hook 不是项目状态真源。
  9. webnovel.py status 继续保留宏观创作健康报告语义,短状态使用 project-status

19. 第一批可开工任务

  1. 新增 project_phase.py,统一 doctor / project-status / gates 的 phase 推导。
  2. 新增 project_status.py,注册 project-status 子命令,保留现有 status 转发到 status_reporter.py
  3. 新增 doctor.py,复用现有 preflight / build_story_runtime_health()
  4. 在统一 CLI 注册 doctor 子命令。
  5. 新增 /webnovel-doctor Skill。
  6. 新增 artifact_validator.py,先包装 chapter_commit_schema.py 中的 commit artifact Pydantic schema。
  7. webnovel-write 的四类 agent artifact 增加 validator 测试 fixture。
  8. 新增 write_gates/prewrite.pywrite_gates/precommit.pywrite_gates/postcommit.py,其中 prewrite 包装 PrewriteValidator
  9. 修改 webnovel-write/SKILL.md,开始引用 write-gate --stage prewrite/precommit/postcommit,过程管理仍使用 Claude Code Todo。
  10. 先审计 5 个 projection writer 的幂等性,再新增 projection_log.py
  11. 给 7 个 Skill 补 description。
  12. 新增 validate_plugin_package.py,先对齐现有版本 CI,再校验 frontmatter / LICENSE / dist。
  13. 新增可选 SessionStart hook,只注入 project-status summary。
  14. 新增可选 skill-scoped PreToolUse hook,作为 best-effort 兜底提醒 / 阻断。

20. 最终判断

webnovel-writer 当前最大短板不是知识库不足,也不是题材模板不够,而是:

关键流程仍有一部分靠 Skill 文档和 Agent 遵守协议来保证。

本 spec 的核心就是把这些协议逐步变成 runtime 可验证机制:

  • doctor 负责知道项目文件、数据库和系统配置是否完整可用;
  • project-status 负责用统一 phase resolver 知道项目现在写到哪里;
  • runtime gates 负责知道关键边界是否可继续;
  • validator 负责知道产物是否可信;
  • projection log 负责知道 read-model 是否同步;
  • eval 负责证明 agent 真的按协议执行;
  • package validator 负责发布物没有漂移。

做到这些,webnovel-writer 才会真正具备优秀 Claude Code 插件的工程稳定性。