---
name: output-hygiene
description: 报告输出卫生检查。禁止词清单（调度元数据、占位符残留、待验证标注）、格式异常检测、参考文献完整性校验。dr-polisher 在润色最后一步必跑；dr-reporter 出稿前复查一次。
---

# 输出卫生清单（Output Hygiene Checklist）

## 目的

拦截"调度元数据"和"中间产物残留"进入最终报告。9MW1911 那份报告之所以干净，是因为过滤掉了一切过程性内容，只留最终成品。

---

## 一、禁止出现在最终报告正文中的字样（元数据黑名单）

以下字符串在 final.md / final_zh.md / final_en.md 里**一旦出现即为缺陷**，dr-polisher 必须清除：

### A. 调度元数据

- `章节定位`
- `字数配额`
- `研究员：dr-analyst`
- `研究员：dr-searcher`
- `生成时间：2026-`（Year-MM 生成日期只在版本信息页出现一次）
- `P0 核心章` / `P1` / `P2`（这些是内部分级，不给读者看）
- `dr-plan` / `dr-pm` / `dr-analyst` / `dr-verifier` / `dr-chief-editor` / `dr-editor-in-chief` / `dr-polisher` / `dr-reporter` / `dr-translator`
- `Phase 1` / `Phase 2` / `Phase 3` / `Phase 4`（除非在"方法论说明"附录讨论研究流程时）

### B. 占位符残留

- `[由 dr-reporter 自动生成]`
- `[待填]` / `[TBD]` / `[TODO]`
- `<slug>` / `<topic>` / `<N>` / `<X>` 等模板占位符
- `{{ ... }}` / `${...}` 变量语法残留

### C. 中间产物引用

- `参考信源：[src_101] –[src_120] （详见 sources.jsonl ch02 条目）`
- `详见 phase2/evidence/chXX-evidence.md`
- `详见 sources.jsonl`
- `本章信源索引：...（详见 ...）`
- `⚠️ 待验证` / `⚠️ [待验证]`（这是过程性标注；如必须保留某个"存疑观点"的提示，应改为正式语言如"该数据仅有 X 个来源支持，建议人工核实"）

### D. 研究思路泄漏

- `研究思路：`
- `核心研究问题：`
- `初步假设：`
- `预期信源：`
- `预期篇幅：`

这些是 framework.md 里给 dr-analyst 看的规划信息，不能出现在读者版。

### E. Agent 交付汇报语

- `产出：` / `完成后返回：`
- `任务：` / `硬性要求：`
- `必读 skill：`
- `章节小结：` （改为自然段落收尾）

---

## 二、格式异常检测

### F. SCQA 显式标注（已禁止的机械模式）

以下组合**不应在最终报告中成对出现**（用 grep 扫）：
- `**Situation（背景）**` + `**Complication（张力）**`
- `**S（背景）**` + `**C（挑战）**` + `**Q（问题）**` + `**A（答案）**`
- `Answer-First` 显式标注
- `**核心结论（Answer-First）**`

SCQA 要写得隐式融合（见 mckinsey-method skill）。

### G. 三级以上嵌套标题乱用

正文正式章节标题不要超过 3 级：
- `# 第 X 章` （报告级）
- `## X.Y 节` （章内节）
- `### X.Y.Z 小节` （节内小节）

禁止 `####` `#####` `######`。如果需要 4 级以上，重新组织结构。

### H. 引用格式不统一

所有引用统一 `[src_XXX]` 格式（3 位数字）。禁止混用：
- `[src_1]`（没补零）
- `[source_001]`（变形）
- `(src_001)`（圆括号）
- `[ref_1]` / `[r1]`（其他简写）

### I. 中英文标点混用

中文正文里的标点应是**中文标点**：
- `，` 不是 `,`
- `。` 不是 `.`
- `；` 不是 `;`
- `：` 不是 `:`
- `"..."` 不是 `"..."`（除了直接引用英文）
- `（...）` 不是 `(...)`

例外：行内英文术语、代码、URL、数据单位前后保持英文标点合理。

### J. Emoji（强制禁用）

**正文与表格中严禁使用任何 emoji / 彩色符号**：

禁用清单（但不限于）：
`✅ ❌ ✔ ✖ 🔶 🔷 ⭐ 🟢 🔴 🟡 🟠 ⚠️ ⚠ 💡 📌 🔑 📊 📈 📉 🔥 ✨ 🎯 🎉 ➔ ➜`

**原因**：PDF 使用的思源字体子集不包含这些字符的 glyph，渲染为空白方框（□）。

**替代写法**：
- 表格标记"有/无"：用 `✓` `×`（思源字体支持）或中文字 `是` / `否`
- 强调状态：用 `◆` `●` 等几何符号（字体支持）
- 警示：用 `注：` `警告：` `※` 等文字前缀
- 重点：用 **粗体** 或引用块，不用 emoji

扫描命令：
```bash
python3 -c "
import re
txt = open('final_zh_polished.md').read()
pat = re.compile(r'[\u2700-\u27BF]|[\U0001F300-\U0001F9FF]|[\u2B00-\u2BFF]')
hits = [(i, m.group()) for i, m in enumerate(pat.finditer(txt))]
print(f'emoji 命中：{len(hits)} 处')
for i, c in hits[:10]:
    print(f'  位置 {i}: {c!r} (U+{ord(c):04X})')
"
```

---

## 三、参考文献完整性校验（最关键）

dr-reporter 出稿前**必须**执行：

```bash
# 1. 从 final.md 提取所有引用的 src_id
grep -oE '\[src_[0-9]+\]' projects/<slug>/phase4/final.md | sort -u > /tmp/cited.txt

# 2. 从 citations.md / sources.jsonl 提取所有已登记的 src_id
grep -oE 'src_[0-9]+' projects/<slug>/phase4/citations.md | sort -u > /tmp/registered.txt
# 或从 sources.jsonl
python3 -c "
import json
with open('projects/<slug>/phase2/sources.jsonl') as f:
    for line in f:
        d = json.loads(line)
        print(d['id'])
" | sort -u > /tmp/registered.txt

# 3. 差集：cited 里有但 registered 里没有 → 严重错误
comm -23 /tmp/cited.txt <(sed 's/[][]//g' /tmp/registered.txt) > /tmp/missing.txt

# 4. 反向差集：registered 有但从未被 cited → 孤立信源，可剔除
comm -13 /tmp/cited.txt <(sed 's/[][]//g' /tmp/registered.txt) > /tmp/orphan.txt
```

### 处理规则

- 有 missing 信源（引用了但无记录）→ **致命错误**，dr-reporter 拒绝出稿，抛回上游排查
- 有 orphan 信源（有记录但未被引用）→ 警告，从 citations.md 剔除
- final.md 里的"参考文献"段落**必须包含完整的编号清单**，不能是 `[由 dr-reporter 自动生成]` 之类的占位符
- 如果 final.md 的参考文献段落是占位符 → 读 citations.md 内容回填

---

## 四、标题规范

### 章标题

- 观点型判断句，不是"概述/现状/背景"
- 长度 15-40 字（中）/ 10-25 词（英）
- 不以动词开头（如"分析/探讨/研究"），改为判断句

**反例**：
- 第 2 章 分析中国 GLP-1 市场的现状
- 第 3 章 探讨 NEB 产品的竞争优势

**正例**：
- 第 2 章 中国 GLP-1 市场 2025 年已跨越 10 亿美元门槛
- 第 3 章 NEB 的 30 年专利丛林将在 2028 年后开始瓦解

### 节标题

- 同样要求观点型
- 长度 10-25 字 / 8-15 词
- 禁止 `2.1 背景 / 2.2 现状 / 2.3 趋势` 这种模板化结构

---

## 五、图表与数据卫生

### 表格

- 表头第一行要有单位（金额 USD / 百分比 % / 年份等）
- 所有数据有来源标注（行内 [src_xxx] 或表脚注）
- 避免超过 10 列宽表（PDF 会被截断）

### 图表标题

格式：`图 X-Y：<内容描述>（数据来源：[src_xxx]）`

### 数字规范

- 阿拉伯数字 + 中文量词：`12 项研究` / `3.2 亿元`
- 大数字三位分节：`12,000` 而非 `12000`
- 百分比带 `%`，不写"百分之十二"
- 时间范围用连字符：`2020-2025 年` 不是 `2020 至 2025 年`

---

## 六、自动化检查脚本（dr-polisher / dr-reporter 必跑）

```python
# hygiene_check.py
import re, sys

BLACKLIST_ZH = [
    "章节定位", "字数配额", "研究员：dr-",
    "P0 核心章", "P1 主干章", "P2 辅助章",
    "Phase 1", "Phase 2", "Phase 3", "Phase 4",
    "dr-plan", "dr-pm", "dr-analyst", "dr-verifier",
    "dr-chief-editor", "dr-editor-in-chief", "dr-polisher",
    "dr-reporter", "dr-translator",
    "[由 dr-reporter 自动生成]", "[待填]", "[TBD]", "[TODO]",
    "详见 phase2/", "详见 sources.jsonl",
    "本章信源索引", "⚠️ 待验证", "⚠️ [待验证]",
    "**Situation（背景）**", "**Complication（张力）**",
    "**Question（问题）**", "**Answer（答案）**",
    "**S（背景）**", "**C（挑战）**",
    "Answer-First", "核心结论（Answer-First）",
    "研究思路：", "核心研究问题：", "初步假设：",
    "预期信源：", "预期篇幅：",
    "硬性要求：", "必读 skill：", "产出：",
]

path = sys.argv[1]
text = open(path, encoding='utf-8').read()
issues = []
for pattern in BLACKLIST_ZH:
    if pattern in text:
        count = text.count(pattern)
        issues.append(f"  × '{pattern}' 出现 {count} 次")

if issues:
    print(f"{path} 存在 {len(issues)} 项卫生问题：")
    for i in issues:
        print(i)
    sys.exit(1)
else:
    print(f"{path} 输出卫生检查通过")
    sys.exit(0)
```

---

## 七、硬规则

1. ✅ dr-polisher 润色的最后一步跑 hygiene_check
2. ✅ dr-reporter 出稿前再跑一次 hygiene_check + 参考文献完整性校验
3. ✅ 任何禁止词残留都必须修正，不能"放过一马"
4. ✅ 参考文献段落必须包含完整编号清单，不允许占位符
5. ❌ 禁止把"⚠️ 待验证"这种过程标注留到读者版
6. ❌ 禁止三级以上嵌套标题
