For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: 完成 v6 迁移剩余工作——清理 legacy 代码、落地章节状态模型、修正 spec 与实现的不一致、通过退出标准验证。
Architecture: 三条并行工作线:(A) legacy 代码删除与清理,(B) 章节状态模型新增,(C) spec/参考资料修正。A 和 C 无依赖可并行,B 是新功能需独立开发测试。
Tech Stack: Python 3.13, pytest, SQLite (state.json + index.db), Claude Code plugin (markdown skills/agents)
Spec: docs/superpowers/specs/2026-04-02-harness-v6-design.md (v6)
前置条件: Phase 1 的"创建新模块"部分已完成(reviewer.md、review_schema.py、review_pipeline.py 均已存在且通过测试)。Phase 3(memory_contract)和 Phase 4(context-agent research 模式)已完成。
| 类别 | 残留项 | 文件 |
|---|---|---|
| 旧 checker 函数 | _normalize_checker_issue, _build_timeline_gate, _aggregate_checker_results, ReviewAggregateResult |
index_manager.py:208-232, 678-808 |
| 旧 checker CLI | aggregate-review-results, materialize-review-metrics |
index_manager.py:963-969, 1318-1327 |
| 旧 checker 脚本 | 整文件 570 行 | golden_three_checker.py |
| 旧 checker 测试 | test_aggregate_checker_results_cli (L1428-1551), test_aggregate_checker_results_blocks_... (L1553-1596) |
test_data_modules.py |
| 旧 checker 测试 | test_index_aggregate_review_results_forwards_... (L173) |
test_webnovel_unified_cli.py:173-218 |
| 旧 checker 引用 | continuity-checker 在已知 checker 列表 |
test_prompt_integrity.py:247 |
| workflow 残留 | 注释引用 + 测试白名单 | webnovel.py:94, test_prompt_integrity.py:221 |
| Step 2B 残留 | 职责边界说明 | polish-guide.md:13-17 |
| legacy 引用 | continuity-checker 映射表 |
reading-power-taxonomy.md:343-348 |
| legacy 消费 | overall_score 用于低分告警 |
context_manager.py:310-318 |
| 缺失功能 | 章节状态模型 | 无(需新增到 state_manager.py) |
| spec 不一致 | "v0 接口尚未实现"但实际已实现 | spec 4.5 |
| 文件 | 原因 |
|---|---|
scripts/golden_three_checker.py |
旧 checker 模式,570 行,已被 reviewer 替代 |
| 文件 | 改什么 |
|---|---|
scripts/data_modules/index_manager.py |
删除 ReviewAggregateResult、旧 checker 函数、旧 CLI 命令 |
scripts/data_modules/context_manager.py |
overall_score 低分判断改为 severity_counts |
scripts/data_modules/tests/test_data_modules.py |
删除旧 checker 聚合测试(~170 行) |
scripts/data_modules/tests/test_webnovel_unified_cli.py |
删除旧 aggregate-review-results 转发测试 |
scripts/data_modules/tests/test_prompt_integrity.py |
清理 checker 白名单、workflow_manager 白名单 |
scripts/data_modules/webnovel.py |
清理 workflow_manager 注释 |
scripts/data_modules/state_manager.py |
新增 chapter_status 管理 |
skills/webnovel-write/references/polish-guide.md |
删除 Step 2B 边界段落 |
references/reading-power-taxonomy.md |
更新 checker 映射表 |
docs/superpowers/specs/2026-04-02-harness-v6-design.md |
修正 spec 与实现不一致 |
| 文件 | 职责 |
|---|---|
scripts/data_modules/tests/test_chapter_status.py |
章节状态模型测试 |
Files:
scripts/data_modules/index_manager.pyscripts/data_modules/tests/test_data_modules.pyModify: scripts/data_modules/tests/test_webnovel_unified_cli.py
[ ] Step 1: 从 index_manager.py 删除 ReviewAggregateResult dataclass
删除 index_manager.py 中 L208-232 的 ReviewAggregateResult dataclass 及其 to_review_metrics 方法。保留 ReviewMetrics dataclass(仍被 save-review-metrics CLI 使用)。
# 删除以下代码块(约 25 行):
@dataclass
class ReviewAggregateResult:
"""Step 3 审查聚合结果"""
chapter: int
start_chapter: int
end_chapter: int
selected_checkers: List[str] = field(default_factory=list)
checkers: Dict[str, Dict[str, Any]] = field(default_factory=dict)
issues: List[Dict[str, Any]] = field(default_factory=list)
overall_score: float = 0.0
severity_counts: Dict[str, int] = field(default_factory=dict)
timeline_gate: Dict[str, Any] = field(default_factory=dict)
# ... 及其所有方法
删除以下 3 个函数(L678-808):
# 删除这 3 个函数:
def _normalize_checker_issue(issue: object) -> dict: ...
def _build_timeline_gate(issues: ...) -> Dict[str, Any]: ...
def _aggregate_checker_results(chapter: int, raw_data: object) -> dict: ...
删除 aggregate-review-results 和 materialize-review-metrics 的 parser 注册(L963-969):
# 删除:
review_aggregate_parser = subparsers.add_parser("aggregate-review-results")
review_aggregate_parser.add_argument("--chapter", ...)
review_aggregate_parser.add_argument("--data", ...)
review_materialize_parser = subparsers.add_parser("materialize-review-metrics")
review_materialize_parser.add_argument("--chapter", ...)
review_materialize_parser.add_argument("--data", ...)
删除对应的 CLI 处理分支(L1318-1327):
# 删除:
elif args.command == "aggregate-review-results":
...
elif args.command == "materialize-review-metrics":
...
从 test_data_modules.py 删除以下测试函数(L1428-1596,~170 行):
# 删除这 2 个测试函数:
def test_aggregate_checker_results_cli(temp_project, monkeypatch, capsys): ...
def test_aggregate_checker_results_blocks_overall_pass_for_high_timeline_issue(temp_project, monkeypatch, capsys): ...
从 test_webnovel_unified_cli.py 删除旧 aggregate 转发测试(L173-218):
# 删除:
def test_index_aggregate_review_results_forwards_with_resolved_project_root(monkeypatch, tmp_path): ...
Run: cd "D:/wk/novel skill/webnovel-writer" && python -m pytest webnovel-writer/scripts -x --tb=short --no-cov
Expected: 全部通过
[ ] Step 6: 提交
cd "D:/wk/novel skill/webnovel-writer"
git add webnovel-writer/scripts/data_modules/index_manager.py webnovel-writer/scripts/data_modules/tests/test_data_modules.py webnovel-writer/scripts/data_modules/tests/test_webnovel_unified_cli.py
git commit -m "$(cat <<'EOF'
refactor: 移除旧 checker 聚合函数和 CLI
删除 ReviewAggregateResult、_aggregate_checker_results、
_build_timeline_gate、_normalize_checker_issue 及对应 CLI
和测试。reviewer + review_pipeline 已完全替代。
EOF
)"
Files:
Delete: scripts/golden_three_checker.py
[ ] Step 1: 确认无运行时依赖
Run: cd "D:/wk/novel skill/webnovel-writer" && grep -r "golden_three" webnovel-writer/ --include="*.py" --include="*.md" | grep -v golden_three_checker.py
Expected: 无命中(或仅在 test_prompt_integrity 白名单中)
[ ] Step 2: 删除文件
cd "D:/wk/novel skill/webnovel-writer"
git rm webnovel-writer/scripts/golden_three_checker.py
[ ] Step 3: 运行测试
Run: cd "D:/wk/novel skill/webnovel-writer" && python -m pytest webnovel-writer/scripts -x --tb=short --no-cov
Expected: 全部通过
[ ] Step 4: 提交
git commit -m "refactor: 删除 golden_three_checker.py(570行),已被 reviewer 替代"
Files:
scripts/data_modules/webnovel.pyscripts/data_modules/tests/test_prompt_integrity.pyskills/webnovel-write/references/polish-guide.mdModify: references/reading-power-taxonomy.md
[ ] Step 1: 清理 webnovel.py 的 workflow_manager 注释
webnovel.py:94 改为不再提及 workflow_manager:
# 旧:
# 用途:兼容没有 main() 的脚本(例如 workflow_manager.py)。
# 新:
# 用途:兼容没有 main() 的脚本。
从 KNOWN_DELETED_FILES 列表(L215-223)中添加 golden_three_checker.py(如果需要),并从任何 checker 白名单中移除 continuity-checker 等旧 checker 名称(L247)。
确认 L247 处 continuity-checker 引用的上下文,如果是"不应出现在 prompt 中"的检查,则保留;如果是"允许出现"的白名单,则移除。
删除 polish-guide.md:13-17 中关于 Step 2B 的职责边界说明:
# 删除以下内容:
与 Step 2B 的职责边界:
- Step 2B:风格转译(表达层)
- Step 4:问题修复(质量层),包括审查问题修复、Anti-AI 终检、毒点规避
若已执行 Step 2B,本步骤不重复全量句式改写,只做"必要修改"。
替换为:
职责定义:
- Step 4 同时负责风格适配(消除模板腔、说明腔、机械腔)和问题修复
- 包括审查问题修复、Anti-AI 终检、毒点规避
更新 reading-power-taxonomy.md:343-349 的旧 checker 映射表:
# 旧:
| 现有 Checker | 使用的 Taxonomy |
|--------------|----------------|
| `reader-pull-checker` | 钩子类型、钩子强度、Hard-002 |
| `high-point-checker` | 爽点模式、微兑现 |
| `pacing-checker` | Hard-003 (节奏灾难) |
| `continuity-checker` | Hard-001 (可读性底线) |
# 新:
| 审查维度 (reviewer) | 使用的 Taxonomy |
|---------------------|----------------|
| continuity | Hard-001 (可读性底线)、Hard-002 (结构完整) |
| pacing | Hard-003 (节奏灾难)、爽点模式、微兑现 |
| ai_flavor | 钩子类型、钩子强度 |
Run: cd "D:/wk/novel skill/webnovel-writer" && python -m pytest webnovel-writer/scripts -x --tb=short --no-cov
Expected: 全部通过
[ ] Step 6: 提交
cd "D:/wk/novel skill/webnovel-writer"
git add webnovel-writer/scripts/data_modules/webnovel.py webnovel-writer/scripts/data_modules/tests/test_prompt_integrity.py webnovel-writer/skills/webnovel-write/references/polish-guide.md webnovel-writer/references/reading-power-taxonomy.md
git commit -m "$(cat <<'EOF'
refactor: 清理 legacy 引用——workflow_manager 注释、Step 2B 边界、旧 checker 映射
EOF
)"
Files:
Modify: scripts/data_modules/context_manager.py
[ ] Step 1: 检查 overall_score 消费点
context_manager.py:310-318 用 overall_score < 75 判断低分告警。改为使用 severity_counts 或 notes 字段判断:
# 旧逻辑(L310-318):
for row in review_trend.get("recent_ranges", []):
score = row.get("overall_score")
if isinstance(score, (int, float)) and float(score) < 75:
low_score_ranges.append({
"start_chapter": row.get("start_chapter"),
"end_chapter": row.get("end_chapter"),
"overall_score": score,
})
# 新逻辑:
for row in review_trend.get("recent_ranges", []):
score = row.get("overall_score")
notes = row.get("notes", "")
has_issues = "blocking=" in notes and "blocking=0" not in notes
is_low_score = isinstance(score, (int, float)) and float(score) < 75
if is_low_score or has_issues:
low_score_ranges.append({
"start_chapter": row.get("start_chapter"),
"end_chapter": row.get("end_chapter"),
"overall_score": score if isinstance(score, (int, float)) else 0.0,
"notes": notes,
})
Run: cd "D:/wk/novel skill/webnovel-writer" && python -m pytest webnovel-writer/scripts/data_modules/tests/test_context_manager.py -x --tb=short --no-cov
Expected: 通过
[ ] Step 3: 提交
cd "D:/wk/novel skill/webnovel-writer"
git add webnovel-writer/scripts/data_modules/context_manager.py
git commit -m "refactor: context_manager 低分告警兼容 v6 severity_counts"
Files:
scripts/data_modules/state_manager.pyCreate: scripts/data_modules/tests/test_chapter_status.py
[ ] Step 1: 写测试
# scripts/data_modules/tests/test_chapter_status.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""章节状态模型测试"""
import json
import pytest
from pathlib import Path
@pytest.fixture
def state_project(tmp_path):
webnovel_dir = tmp_path / ".webnovel"
webnovel_dir.mkdir()
state_file = webnovel_dir / "state.json"
state_file.write_text(json.dumps({
"progress": {"current_chapter": 5}
}), encoding="utf-8")
return tmp_path
def _make_manager(project_root):
import sys
scripts_dir = str(Path(__file__).resolve().parent.parent.parent)
if scripts_dir not in sys.path:
sys.path.insert(0, scripts_dir)
from data_modules.config import DataModulesConfig
from data_modules.state_manager import StateManager
config = DataModulesConfig(
project_root=project_root,
webnovel_dir=project_root / ".webnovel",
)
return StateManager(config)
def test_get_chapter_status_default(state_project):
sm = _make_manager(state_project)
sm._load_state()
status = sm.get_chapter_status(5)
assert status is None # 未设置过
def test_set_chapter_status_drafted(state_project):
sm = _make_manager(state_project)
sm._load_state()
sm.set_chapter_status(5, "chapter_drafted")
status = sm.get_chapter_status(5)
assert status == "chapter_drafted"
def test_set_chapter_status_monotonic(state_project):
sm = _make_manager(state_project)
sm._load_state()
sm.set_chapter_status(5, "chapter_reviewed")
# 不能回退到 drafted
with pytest.raises(ValueError, match="不可回退"):
sm.set_chapter_status(5, "chapter_drafted")
def test_set_chapter_status_progression(state_project):
sm = _make_manager(state_project)
sm._load_state()
sm.set_chapter_status(5, "chapter_drafted")
sm.set_chapter_status(5, "chapter_reviewed")
sm.set_chapter_status(5, "chapter_committed")
assert sm.get_chapter_status(5) == "chapter_committed"
def test_chapter_status_persists(state_project):
sm = _make_manager(state_project)
sm._load_state()
sm.set_chapter_status(3, "chapter_drafted")
sm._save_state()
# 重新加载
sm2 = _make_manager(state_project)
sm2._load_state()
assert sm2.get_chapter_status(3) == "chapter_drafted"
[ ] Step 2: 运行测试确认失败
Run: cd "D:/wk/novel skill/webnovel-writer/webnovel-writer/scripts" && python -m pytest data_modules/tests/test_chapter_status.py -v --no-cov
Expected: FAIL — AttributeError: 'StateManager' object has no attribute 'get_chapter_status'
在 StateManager 类中添加以下方法:
CHAPTER_STATUS_ORDER = ["chapter_drafted", "chapter_reviewed", "chapter_committed"]
def get_chapter_status(self, chapter: int) -> Optional[str]:
"""查询章节状态。"""
statuses = self._state.get("progress", {}).get("chapter_status", {})
return statuses.get(str(chapter))
def set_chapter_status(self, chapter: int, status: str) -> None:
"""设置章节状态(单调递进,不可回退)。"""
if status not in self.CHAPTER_STATUS_ORDER:
raise ValueError(f"无效状态: {status},有效值: {self.CHAPTER_STATUS_ORDER}")
current = self.get_chapter_status(chapter)
if current is not None:
current_idx = self.CHAPTER_STATUS_ORDER.index(current)
new_idx = self.CHAPTER_STATUS_ORDER.index(status)
if new_idx < current_idx:
raise ValueError(
f"章节 {chapter} 状态不可回退: {current} -> {status}"
)
if new_idx == current_idx:
return # 幂等
progress = self._state.setdefault("progress", {})
chapter_status = progress.setdefault("chapter_status", {})
chapter_status[str(chapter)] = status
self._save_state()
Run: cd "D:/wk/novel skill/webnovel-writer/webnovel-writer/scripts" && python -m pytest data_modules/tests/test_chapter_status.py -v --no-cov
Expected: 5 passed
在 state_manager.py 的 CLI 部分添加 get-chapter-status 和 set-chapter-status 子命令:
# parser 注册
status_get_parser = subparsers.add_parser("get-chapter-status")
status_get_parser.add_argument("--chapter", type=int, required=True)
status_set_parser = subparsers.add_parser("set-chapter-status")
status_set_parser.add_argument("--chapter", type=int, required=True)
status_set_parser.add_argument("--status", required=True,
choices=["chapter_drafted", "chapter_reviewed", "chapter_committed"])
# 命令处理
elif args.command == "get-chapter-status":
manager._load_state()
status = manager.get_chapter_status(args.chapter)
emit_success({"chapter": args.chapter, "status": status},
message="chapter_status")
elif args.command == "set-chapter-status":
manager._load_state()
manager.set_chapter_status(args.chapter, args.status)
emit_success({"chapter": args.chapter, "status": args.status},
message="chapter_status_set")
[ ] Step 6: 提交
cd "D:/wk/novel skill/webnovel-writer"
git add webnovel-writer/scripts/data_modules/state_manager.py webnovel-writer/scripts/data_modules/tests/test_chapter_status.py
git commit -m "$(cat <<'EOF'
feat: 章节状态模型——chapter_drafted/reviewed/committed
单调递进状态机,支持 CLI 查询和设置。
用于 v6 Write 流程的充分性闸门。
EOF
)"
Files:
Modify: docs/superpowers/specs/2026-04-02-harness-v6-design.md
[ ] Step 1: 修正 memory contract v0 描述
将 4.5 节中的:
**v0(目标接口,供 Phase 1/2A prompt 重构面向编程):**
> 注:v0 接口当前尚未实现,现有实现通过 `webnovel.py` CLI 子命令(如 `state get-entity`、`index get-recent-state-changes`)充当。Phase 3 将这些 CLI 收口为以下统一契约。
改为:
**v0(已实现,当前冻结):**
> v0 接口已通过 `memory_contract.py`(Protocol + 类型)和 `memory_contract_adapter.py`(适配器)实现,CLI 入口为 `webnovel.py memory-contract` 子命令。context-agent 已在使用。
在实施路径表格中,Phase 3 和 Phase 4 的状态列加注"已完成":
| Phase 3 | 记忆模块接口契约设计 | 无 | **✅ 已完成** |
| Phase 4 | Context-agent research 模式重构 | Phase 3(契约) | **✅ 已完成** |
[ ] Step 3: 更新版本号
> 状态:草案 v7(v6 + 实现对齐修正)
[ ] Step 4: 提交
cd "D:/wk/novel skill/webnovel-writer"
git add docs/superpowers/specs/2026-04-02-harness-v6-design.md
git commit -m "docs: spec v7——修正 memory contract 状态,Phase 3/4 标记已完成"
Files: 无新文件
Run: cd "D:/wk/novel skill/webnovel-writer" && python -m pytest webnovel-writer/scripts --tb=short
Expected: 全部通过
[ ] Step 2: 退出标准逐条验证
cd "D:/wk/novel skill/webnovel-writer"
# 标准 1: 无旧 checker 运行时引用
echo "--- 标准 1: 旧 checker 引用 ---"
grep -rn "continuity-checker\|setting-checker\|ooc-checker\|high-point-checker\|pacing-checker\|reader-pull-checker" \
webnovel-writer/skills/ webnovel-writer/agents/ webnovel-writer/scripts/*.py \
--include="*.md" --include="*.py" || echo "PASS: 无旧 checker 引用"
# 标准 2: 审查路径唯一
echo "--- 标准 2: 审查路径 ---"
grep -l "reviewer" webnovel-writer/skills/webnovel-write/SKILL.md webnovel-writer/skills/webnovel-review/SKILL.md && echo "PASS: 均走 reviewer"
# 标准 3: workflow_manager 移除
echo "--- 标准 3: workflow_manager ---"
test ! -f webnovel-writer/scripts/workflow_manager.py && echo "PASS: 文件已删除" || echo "FAIL: 文件仍存在"
# 标准 4: legacy 术语(运行时路径)
echo "--- 标准 4: legacy 术语 ---"
grep -rn "timeline_gate\|_aggregate_checker\|_normalize_checker\|_build_timeline_gate" \
webnovel-writer/scripts/ --include="*.py" | grep -v "test_" | grep -v "__pycache__" || echo "PASS: 运行时无 legacy"
# 标准 6: 章节状态模型
echo "--- 标准 6: 章节状态 CLI ---"
cd webnovel-writer/scripts && python -X utf8 data_modules/state_manager.py --help 2>&1 | grep -q "get-chapter-status" && echo "PASS: CLI 已注册" || echo "FAIL: CLI 未注册"
[ ] Step 3: 如有失败项,修复后提交
cd "D:/wk/novel skill/webnovel-writer"
git add -A
git commit -m "chore: v6 迁移退出标准验证通过"