muse-agent-example/docs/2026-08-20-skill-质量审查与复利改造清单.md
zizi 0260bcd8e2 设计文档:SoT 同步与生成物重出
- 新版设计各域 SoT 按本轮实现同步:总体架构、模块设计、接口契约、数据模型、功能规格、文件设计与决策记录。
- 接口契约生成物重新导出(openapi 与前端客户端随契约一致)。
- 实现回顾与专项检查台账保留历史结论;本轮收尾发现另见 .agents.local 下的收尾报告与审查处置。
2026-09-18 01:15:18 +08:00

246 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 导航元信息: {"内容描述": "历史审查报告", "使用场景": "追溯原阶段任务时", "使用要求": "保留原时点,不作为当前能力或运行入口"} -->
# Skill 质量审查与复利改造清单(2026-08-20)
> 性质:一次性审查记录与改造方案,不是 SoT。
> 评分口径 Owner:[`muse/lifecycle/quality/harness/specs/skill-quality-rubric.md`](../工具/维护索引.py)。
> 复利链与升格判据 Owner:[06-质量与复利领域 §6](系统架构/新版设计/模块设计/B06-审校修订.md)。
## 1. 结论摘要
分类换轴后,47 个 Skill 的机械阻断为零,但暴露出 152 条质量发现。最大的一条是**复利缺口**:43 个非平台 Skill 里 27 个(63%)`compounding = none`。人工审查另给出 15 个执行型阻断(合同与机制两张皮、功能并列)和 15 个方法型的集合路由冲突——后者不是 15 个独立质量问题,是一套未切分的方法被切成 15 个入口。
这个缺口此前被分类掩盖了。旧分类把 15 个创作方法 Skill 划为"参照 Skill"并豁免数据库合同,等于宣布它们**天然**不产生系统事实。事实是它们只是**没接线**:缺口不止那 15 个,而是横跨导入、规划、写作、检测四段的 27 个。
改造不需要新基建。仓里已有完整的复利链和一个跑通的范本。
## 2. 为什么换轴
旧分类 `class = capability | reference` 记录的是**实现成熟度**(当前有没有数据库合同),却写成了**本质类别**。后果有三:
1. **发永久豁免证**。`reference` 的定义里就写着"不要求数据库合同、失败关闭和 `meta/chains/` 登记",于是没有任何门禁会推动它们接入,成熟度差距被冻结为身份差距。
2. **口径不可比**。`reference` 的 D4 必备节是"方法索引 / 引用索引",`capability` 是"输入 / 输出 / 红线"。两套必备节让 46/47 的合同缺失长期看不见——换成统一口径后立刻显形。
3. **`craft` 一词双关**。该词同时是旧的 Skill 标签和公共范式库的**范式型**(`draft_payload->>'型' = 'craft'`,技法型,1892 张卡)。同名不同义,读者与 Agent 都会误判。
新分类四个属性全部描述可变状态:`lifecycle`(作品创建周期九段)/ `invocation` / `side_effects` / `compounding`。差距不再藏在类别里,而是由 `compounding` 明账记录、由维度 D8 计分推动。`craft` 从此在本仓只有范式型一个含义。
## 3. 复利的定义与既有范本
复利指**把"这次怎么做、效果如何"的观察沉淀成可被后续运行消费的经验资产**:范式卡、AI 味规则、声音账、`example_lesson` 登记。作品事实(实体、知识卡、正文)不算——那是内容,不是经验;搬运素材也不算。
既有闭环范本是去 AI 味五技能,它证明这条链能跑通:
```text
作品/反馈扫描 → 案例卡(shadow)→ 规则候选 → holdout 评测 → active 规则 → 生成前注入
```
可复用的承接物全部现成:
| 承接物 | 位置 | 现状 |
|---|---|---|
| 经验登记表 `example_lesson` | DDL-108 | 已建,`proposed → reviewing → promoted/rejected` 由触发器强制,`target_type` 取 pattern/skill/tool,绑 `run_id` + 候选 `sha256` |
| 六型范式卡 | `muse_knowledge_draft`,公共库 `work_id = 0` | 已建,9269 张公共卡 |
| 卡审核 | `review-knowledge-cards` 三角色审核 → 用户确认 | 已跑通 |
| 规划期绑定 | `plan-story` 的 `select_patterns` → 已确认 assembly 行的 `patternReferences` | 已建 |
| 写作期注入 | `assemble-context.load_confirmed_pattern_bindings` → writer | 已建,尺寸上限见 03-范式领域 §5 |
**改造不新建表、不新建注入路径。** 缺的只是让各 Skill 接上这两端。
## 4. 三种改造模式
### 模式 A:方法 → 范式卡(补消费侧)
适用 15 个创作方法 Skill(`story-structure`、`scene-craft`、`narration-pov` 等)。
1. 把 `references/` 里的**可操作写法单元**抽成范式卡,按内容归 `craft` / `scene_pattern` / `trope` 型,入公共库(`work_id = 0`)。
2. 走既有出卡路径:`review-knowledge-cards` 三角色审核 → 用户确认落为正式内容。单书或单章证据只能出作品级卡(非零 `work_id`),不得污染公共层。
3. `SKILL.md` 改为承载**选型判断口径**(什么场景该找哪一型、怎么判不适用),不再自己留一份方法正文;原理与例证留 `references/`。这与 03-范式领域 §7 的"升格后卡里只留链接、不留第二份执行步骤"同向。
4. 消费完全走既有链,Skill 侧不写新的注入代码。
**顺带清掉一个共性问题**:15 个里有 12 个的 `scripts/` 只装了 Markdown 清单(`structure-checklists.md`、`theme-stance-checklist.md` 等)。这些清单正是出卡原料——改造时一并处理:能变成范式卡的出卡,剩下的移到 `references/`,`scripts/` 要么放真正的机械门,要么删除。
### 模式 B:观察 → lesson 登记(补回写侧)
适用全部 `compounding = none` 的 Skill,以及 `partial` 里缺回写的那些。
1. Skill 产出时**顺带**登记观察到 `example_lesson`:`kind ∈ lesson | win`,绑 `run_id` 与候选 `sha256`,初始 `proposed`。
2. 升格按 06-质量与复利领域 §6 的既有判据:同类问题第 3 次复发即评估固化;`reviewing` → `promoted` 时必须指明 `target_type`(pattern / skill / tool)与落点。
3. 06 §9 已登记"证据自动收集未建"为待建项——模式 B 就是补这一项。关键是**产出时顺带写**,不靠人事后补登记,否则又回到自觉而非机制。
### 模式 C:平台底座豁免
5 个 `lifecycle = platform` 的 Skill(`access-database`、`call-content-model`、`execute-claude-task`、`refresh-runtime-probe`、`record-run-evidence`)不承载创作经验,D8 不适用(`compounding=none`)。但 `record-run-evidence` 是模式 B 的落点依赖,其回执与 `run_id` 是 lesson 绑定的锚。
## 5. 改造优先级
排序依据是**单位成本的复利增益**:先接已经有落库位、只差一行登记的,再做需要出卡与审核的。
| 序 | 批次 | 对象 | 模式 | 理由 |
|---|---|---|---|---|
| 1 | 效果信号接线 | `decide-candidate`、`score-content-quality`、`evaluate-frozen-replay` | B | ✅ 三技能均经 `propose_lesson_dedup` 回写;manifest=`closed_loop`;离线 mock 测试钉死 |
| 2 | 闭环补缺侧 | `prevent-ai-flavor`、`revise-ai-flavor`、`write-next-chapter`、`assemble-context`、`plan-story` | B | ✅ 五技能均已 `propose_lesson_dedup` + `closed_loop`;复利合同与离线 mock 测试对齐 |
| 3 | 方法出卡 | 15 个创作方法 Skill | A | 增益最大但成本最高:依赖审核与用户确认门,且要先有批次 1 的效果信号才能验证卡有没有用 |
| 4 | 抽取链回写 | `deconstruct-book`、`extract-work-knowledge`、`extract-chapter-knowledge`、`review-knowledge-cards` | B | ✅ 四技能均已 `propose_lesson_dedup` + `closed_loop`;离线 mock 测试钉死;`extract-work-knowledge` 补 `external_call` |
| 5 | 其余 `none` / 运维 `partial` | 平台四技能;`freeze-context`;`plan-chapter` 等 | B 或维持 | ✅ 平台五技能 `none`=模式 C(含 `record-run-evidence` 落点依赖);`import`/`clean`/`embed`/`plan-chapter`/`capture`→closed_loop;`freeze` 与写作/评测辅助槽维持 partial(回写归下游,合同已写明) |
**批次 3 不要先做。** 15 个方法 Skill 出卡是最诱人的一步,但在批次 1 的效果信号接通之前,出的卡无法证明有效,只会把 9269 张公共卡变成 9269+N 张无证据卡——正是 03-范式领域 §4 禁止的"单章、单作品或一次高分直接产生公共 active"。
## 6. 机械审计结果
`skill_harness.py` 当前:阻断 0,advisories 152。
| 代码 | 条数 | 维度 | 说明 |
|---|---|---|---|
| `required_section_missing` | 104 | D4 | 统一必备节口径后显形;46/47 至少缺 1 节 |
| `compounding_not_wired` | 27 | D8 | 见第 4、5 节 |
| `scripts_without_implementation` | 16 | D6 | 其中 12 个是方法 Skill 的 Markdown 清单误放 `scripts/` |
| `line_budget_exceeded` | 3 | D6 | `design-story-foundation` 174 行、`evaluate-frozen-replay` 147 行、`capture-ai-flavor-cases` 124 行 |
| `scripts_test_file` | 2 | D6 | `design-story-foundation/scripts` 内有测试文件,应移 `tests/skills/` |
缺节分布:输出 33、输入 28、复利合同 17、红线 14、数据边界 12。
**"缺红线"和"缺数据边界"优先于"缺输入输出"**:前两者是安全边界,后两者是可读性。14 个缺红线的里,`score-content-quality`、`review-knowledge-cards`、`clean-book-text` 都带 `db_write`,属严重级。
全量逐 Skill 结果由 `.venv/bin/python harness/skill_harness.py --json` 现场产出,本文件不复制一份会漂移的快照。
## 7. 本次已修
1. **15 个创作方法 Skill 的 `domain` / `sources` frontmatter 已移除**。这两个字段无任何代码消费:`domain` 已由 `skills.json` 的 `lifecycle` 承载,`sources`(7 本写作书的 75 个来源单元)属历史留痕,不该常驻每次加载的运行时提示词。75 条来源对照已迁入 `docs/2026-08-19-craft-distillation-trace.md` 后再删除。
2. **`sync_agent_registry.parse_frontmatter` 的解析 bug 已修**。它把任何含冒号的行当作字段名,于是 `concept-design` 描述里的"要求严格 1:1 复刻"被读成字段,`tests/skills/access-database/test_skill_catalog.py` 长期为红。改为只认顶格且键名合法的行,与 `skill_harness.py` 的解析口径一致。该测试恢复为绿。
离线套件 `run_selected.py --all-offline`:78 通过 / 1 失败 / 8 依赖阻塞。唯一失败 `tests/skills/evaluate-frozen-replay/test_run_writer_replay.py` 经 stash 比对确认早于本次改动,与分类改造无关,未处理。
## 8. 人工审查(三批合并)
三批只读审查在分类换轴之前启动。**仍有效**:D1 可发现性、D2 单一目的、D3 边界与不重叠、D5 失败关闭、D7 机制优先。**已失效、不收录**:15 个方法 Skill 按旧 `reference` 口径评的 D4(当时必备节是方法索引 / 引用索引)。D8 复利接入当时未评,以第 6 节机械发现为准。
判定计数(按当时适用维度,含阻断项直接判不可用):
| 批次 | 范围 | 不可用 | 不合格 | 可用待修 | 良好 |
|---|---|---|---|---|---|
| 1 | 16 个执行型 | 9 | 1 | 4 | 3 |
| 2 | 16 个执行型 | 6 | 3 | 5 | 2 |
| 3 | 15 个方法型 | 0 | 12 | 3 | 0 |
批次 3 零阻断,是因为当时把它们当"参照"豁免了 D5;换轴后它们与执行型共用必备节,合同缺失已由第 6 节机械门记账。批次 3 的主结论不在合同,而在**集合内路由冲突**。
### 8.1 仍有效的阻断(修复前不得继续当可靠入口)
按伤害面排序,不按批次。§8.1 原表阻断项已全部落地(含本批换窗冲突门、回放完成态断言、采集 CLI 表面、前期设计选定交接闸)。下表保留审查记录与勾选状态。
| Skill | 维 | 问题 | 改法 |
|---|---|---|---|
| `decide-candidate` | D7 | 写 Canonical 的唯一入口自称"不得由 Agent 自行触发",实际 `model_routed` | ✅ `disable-model-invocation: true`,manifest=`orchestrated` |
| `decide-candidate` | D2 | 正文确认 / 知识卡确认 / 规划确认三条独立轨 | ✅ 本 Skill 只做正文轨;知识卡=`confirm-knowledge-draft`,规划=`plan-story` |
| `access-database` | D7 | 红线禁 DDL 与物理删,命令面却提供 INSERT/UPDATE/DELETE/DDL | ✅ `exec`/`execparams` 机械拒绝 DDL 与裸 DELETE;DDL 仅 `apply` |
| `call-content-model` | D7 | 不受治理的 `chat()` 只靠散文围栏 | ✅ 默认抛错;`allow_ungoverned` / `MUSE_LLM_ALLOW_UNGOVERNED=1` / CLI `--ungoverned` |
| `rewrite-selection` | D7 | 并发覆盖防护只写在散文,无 revision 断言 | ✅ `scripts/assert_expected_revision.py` 动笔前核对 Canonical revision |
| `optimize-content-quality` | D2/D7 | 编排兼执行,且自称可直接 git 提交 | ✅ 合同已收敛为只出归因建议;禁止自行 git 提交 |
| `plan-story` | D5 | 含 `db_write` 却无失败路径 | ✅ SKILL 补失败关闭(整单不落库) |
| `review-knowledge-cards` | D5/D7 | 写库审核无失败关闭;校准门只靠散文 | ✅ 失败关闭节 + 放量写库须 `calibrate-stamp`(cal-* 批次除外) |
| `extract-chapter-knowledge` | D5 | 含 `db_write` 全文无失败路径 | ✅ 失败关闭节 + lesson 接线 |
| `maintain-work-extraction` | D2 | 备份/重置/修复/迁移并列(D2 的 0 分原型) | ✅ 已拆为 backup/reset/repair(历史项) |
| `score-content-quality` | D2 | 三套评分口径 + Gate 裁决并列 | ✅ Gate 终态归 `adjudicate-quality-gate`;本 Skill 只评分 |
| `deconstruct-book` | D2/D7 | 编排兼执行;换窗漏删已造成实测漏卡 | ✅ 换窗 `WINDOW_PLAN_CONFLICT` 失败关闭 + `--replace-windows`;编排上移仍可后做 |
| `evaluate-frozen-replay` | D2/D7 | 五类功能并列;防假绿靠叮嘱 | ✅ 完成态 `assert_run_may_complete`;入口仅 dry_run/execute;假绿测试钉死 |
| `capture-ai-flavor-cases` | D2/D7 | 采集兼规则生命周期;激活豁免只靠散文 | ✅ CLI 表面仅采集五命令;confirm/project 仅供 promote 库调用 |
| `design-story-foundation` | D2 | 编排 / 执行 / 统合并列 | ✅ `orchestrated` + 选定交接闸;统合归 merge;plan-story 红线禁偷读 |
### 8.2 方法 Skill 的集合冲突(D1/D3,批次 3 主结论)
15 份 `description` 全部堆 trigger,**没有一份把会命中的相邻 Skill 全部点名交接**,所以 D1 整列压在 1 或 0。5 份"不适用于"一个 skill 名都没有。这不是 15 个独立质量问题,是**一套未切分的方法被切成 15 个路由入口**。
**本批已落地(路由切分,尚未出卡)**:冲突对均在 `description` 点名交接;`character-presentation` 删除重复 `character-voice.md` stub(owner=`dialogue-craft`);`foreshadow-payoff` 从 trigger 去掉裸「高潮/反转」;`novel-diagnosis` 症状→专精表写入 frontmatter(模型可读);`scene-craft` / `character-design` / `story-ending` / `narrative-momentum` 补齐易混交接。出卡仍须等 §5 批次 1 效果信号。
冲突对(双方都缺交接的优先)——原审查记录:
| 对 | 冲突面 | 建议归属 | 状态 |
|---|---|---|---|
| `character-presentation` ↔ `dialogue-craft` | 各有一份 `references/character-voice.md`,教同一条 | 说话方式归 `dialogue-craft` | ✅ |
| `prose-craft` ↔ `show-and-omission` | "太抽象 / 不写他很 X、写动作"同源 | 句段修辞归前者,标签换场景归后者 | ✅(先前已交接) |
| `narration-pov` ↔ `theme-and-stance` | 同一原则 + 同一案例(撒旦访莫斯科)写了两遍 | 荒诞/间离归 `theme-and-stance` | ✅(先前已交接+指针) |
| `narrative-momentum` ↔ `story-structure` | "中段塌陷"逐字重复 | 结构成因归后者,弃读/章末钩子归前者 | ✅ |
| `concept-design` ↔ `story-planning` | 用户第一句话两边都收 | 想法→概念 / 概念→节拍表 | ✅(先前已交接) |
| `foreshadow-payoff` 吸走高潮/反转 | trigger 过宽 | 收窄到埋/收/契诃夫之枪 | ✅ |
| `novel-diagnosis` 对专精 skill 开放点名 | "等专精 skill"无法路由 | 展开成症状→skill 对照表 | ✅ |
单点严重:`dialogue-craft` 的 description 把已删除的 `MERGE_PLAN.md` 当路由目标(内部代号且文件已不存在),D1 记 0。→ ✅ 已清除(无 MERGE_PLAN 引用)。
这 15 个在接复利(第 5 节批次 3)之前,应先把路由切干净。否则出的范式卡会把同一条方法登记两次。→ **路由切分已完;出卡仍禁早于批次 1。**
### 8.3 写作执行槽的交接空洞(批次 1+2)
`expand-scene` / `rewrite-selection` / `polish-prose` 输入输出都是"一段既有正文 → 一段新正文",互不点名;`polish-prose` 还直接做去 AI 味,绕开 `diagnose-ai-flavor` 前置铁律。`plan-story` 与 `plan-chapter` 都能产 `fine_outline`。这些与 8.2 同构:切分了入口,没切分症状。
**本批已落地**:三写作槽 `description` 互指 + AI 味铁律;`polish-prose` 不再自称去 AI 味入口;`fine_outline` 写入硬门 `FINE_OUTLINE_OWNER`(仅 `--owner-skill plan-chapter`),`plan-story` 产出合同去掉 `fine_outline`。
## 9. 待办
1. ~~第 8.1–8.3 与 §5 批次 1/2/4/5(平台豁免 + plan-chapter/freeze 判定)~~ ✅。
2. ~~运维/写作槽 `partial` 合同对齐~~ ✅:`capture`→closed_loop(persist lesson);`record-run-evidence`→模式 C `none`;`optimize` / `replay-writer-gate` / `check-consistency` / `search-knowledge` / `merge` / `load-replay` / `inspect-parse` 注明「回写归下游」;写作槽与方法 Skill 先前已对齐。
3. ~~D6~~ ✅:方法 Skill `scripts/` 清单已迁走(目录已删);行预算均 ≤120;无 `scripts_test_file`。
4. **仍开放**:§5 批次 3 方法出卡(须先有批次 1 效果信号被消费的证据)。
### 9.1 批次 1 效果信号消费证据(2026-08-20 查;同日验证)
**结论:批次 3 仍禁止。** 可见性核对已由人通过;**不等于**最新生产链实测,也**不等于**效果信号已被产品侧消费。
| 检查项 | 证据 | 结果 |
|---|---|---|
| 回写侧已接线 | decide / score / replay 均 `propose_lesson_dedup`;离线 mock 绿 | ✅ 代码层 |
| 库内批次 1 行 | 历史 accept 回填 lesson **#52/#53**;丢弃 37 产生 live **#54** | 🟡 #54 为 discard 信号;尚无 live accept |
| 看板可见 | 人打开 [作品12](http://127.0.0.1:8765/works/12) 第1/2章可看正文;**内容不满意、有 AI 味**(历史生成) | ✅ 可见性通过(人确认) |
| 「最新流程实测」 | 候选 37 已 **discard**(decision_id=87);ch3 细纲修辞句已改;交互合同/复读门/人指令槽已落 | 🟡 重产进行中或待跑 |
| 消费侧 | 只读 `/lessons` + 确认通道 `:8766`;人已对 **#53** 执行 `rejected` | ✅ Web 人审链路通(驳回路径) |
| 升格落地 | 06 §9:`promoted`→范式/Skill 变更仍待建 | ❌ 升格落地未测 |
**人确认(2026-08-20)**
- 可见性:历史第1/2章在看板上可见 → **通过**。
- 经验 #53:Web **驳回**。
- #52 仍为 `proposed`(未审);#54 为丢弃 37 的 live proposed。
- accept 后口径已改:下游抽卡/案例草稿 **auto**,转正式仍须人(05 §2 / decide-candidate)。
**验证进度**
1. ✅ 看板可见性
2. ✅ 历史 accept 回填 lesson
3. ✅ Web 人审(#53 → `rejected`)
4. ✅ discard live lesson(#54)
5. ❌ live accept + 自动抽卡执行(接线待建;合同已改)
6. 批次 3 仍禁出卡
**下一步**:用当前流水线重产第 3 章(含语义门 + 人指令 + 复读门)→ 人审 → accept → 核对新 lesson。写手新设定不走补证禁写;冲突才阻断,提案交人闸。
5. `skill_harness.py --strict` 可长期开启(当前阻断与质量发现均为 0)。
### 9.3 第 3 章 live 重产现状(2026-08-20 续跑)
| run | 结果 | 证据 |
|---|---|---|
| `2da11381` | 篇幅拒绝 | 旧合同 `2800–5200`;首轮 2601 汉字,后续盲重试未形成通过候选 |
| `68a7635a` | 篇幅拒绝 | 新分层合同已生效,但旧生产提示未要求汉字自检;首轮 2601 汉字 |
| `5cda460d` | 语义 detector 失败关闭 | 加强生产提示后正文 4772 汉字;引文弯引号归一化修复前,三轮均 `SEMANTIC_DETECTOR_QUOTE_NOT_FOUND` |
| `b4c114be` | 机械拒绝 | 正文 4233 汉字;`event-3-upgrade` 未命中,候选 #119 为 `rejected` |
| `c32f1b10` | 证据缺口拒绝 | 正文 4819 汉字;机械门与语义结构通过,语义 `needs_evidence` 有 2 个低优先级缺口,**当时**生产补证未接线,未进入人闸 |
**0.1 B 补证接线(2026-08-21)**:`production_evidence_reassemble` 已接入 step2;离线 4 测绿;对 `c32f1b10` 上下文 smoke:attempt↑、sha 变、创作输入变。下一步:重跑第 3 章 step2 进入人闸。
**0.2 双通道**:只读 `:8765` + 经验 `:8766` + 候选决策 `:8767`(`dashboard/decision_channel.py` accept/discard)。
**当前有效口径**:生产写手输入 `4000–7000` 汉字、目标 `7000`;可信 adapter 接受 `3001–10000`;生成入口只落 Shadow,已由 AST 门禁止调用 `accept()`。弯引号只做一对一字形定位,绑定结果返回正文原始切片;其它内容差异仍失败关闭。
**当前阻塞**:第 3 章尚无同时满足机械门、语义 `passed`、证据完整且可进入人闸的新候选。候选 #118 的语义状态为空,候选 #119 已拒绝;`c32f1b10` 未持久化为可接受候选。批次 3 仍禁止出卡。
### 9.2 交互编排(2026-08-20)
| 项 | 状态 |
|---|---|
| 05 §2.3 交互回合合同 + §2.4 节点 Skill 矩阵 | ✅ |
| accept 授权下游 shadow 草稿(next_steps auto) | ✅ 合同;执行接线待建 |
| step2 `--instruction` 人指令槽 | ✅ |
| 机械门 `OUTLINE_PHRASE_LEAKED` | ✅ + 离线测试 |
| 候选详情决策菜单 | ✅ |
| 0.1 B 生产补证重组装 | ✅ `production_evidence_reassemble` + step2 + 离线测 |
| 0.2 可写决策通道 `:8767` | ✅ `dashboard/decision_channel.py` |
| 候选 37 丢弃并重写 | 丢弃 ✅;重产见上 |