novel-consistency-guards — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited novel-consistency-guards (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
贯穿整个写作期一直在后台激活。由以下 skill 主动引用:
novel-chapter-sop 每一章 / 每一场景 写完后引用本 skill 做机械扫描novel-finalization 收口阶段引用本 skill 做全书扫描novel-ideation 的 constitution 里应该锁死这些项。本 skill 负责扫描。
典型红线(按你的 constitution 调整):
| 类别 | 红线 | 脚本检测方法 |
|---|---|---|
| 姓氏锁 | 某角色姓氏不得变(如"苏淮"不得误写成"林淮") | '林淮' in text |
| 引号类型 | 必须中文全角 " " / ' ',禁止 ASCII | '"' in text or "'" in text |
| 破折号密度 | 每章正文 ≤ 7 个 "——" | body.count('——') <= 7 |
| Markdown bold | 正文禁止 **字** | '**' in text |
| Meta "Ch N" | 正文不得出现"Ch X" / "第 X 章" 指涉 | re.search(r'Ch\s*\d+', text) |
| 超自然解释 | 禁止无物理/化学解释的超能力 | 人工+agent 审 |
| 全角引号配对 | 左右引号数量相等 | text.count('"') == text.count('"') |
# check_consistency.py
import re
import sys
def check_chapter(path):
t = open(path).read()
parts = t.split('\n\n', 2)
body = parts[-1] if len(parts) >= 3 else t
issues = []
# 机械项
wc = len(re.sub(r'\s', '', body))
dashes = body.count('——')
if dashes > 7:
issues.append(f'破折号 {dashes} 超限')
if '**' in t:
issues.append(f'markdown bold {t.count("**")} 个')
if '"' in t:
issues.append(f'ASCII 双引号 {t.count(chr(34))} 个')
if "'" in t:
issues.append(f'ASCII 单引号 {t.count(chr(39))} 个')
if t.count('"') != t.count('"'):
issues.append(f'引号不配对 {t.count("“")}/{t.count("”")}')
if '林淮' in t:
issues.append(f'禁用姓氏"林淮" {t.count("林淮")} 次')
if re.search(r'Ch\s*\d+', t):
issues.append('出现 meta "Ch N" 引用')
return wc, issues
if __name__ == '__main__':
for path in sys.argv[1:]:
wc, issues = check_chapter(path)
status = '✅' if not issues else '❌ ' + ' / '.join(issues)
print(f'{path}: {wc} 字 {status}')使用:
python3 check_consistency.py chapters/*.md每次写完 / 改完章节立刻跑。修订时特别容易引入新问题(手抖加破折号、复制粘贴带入 ASCII 引号),必须每次跑。
长篇最容易翻车的地方,不是单章写得好不好,是跨章前后不一致。维护四张表:
每个关键物件列:
## 道具链 · 青玉簪
| 章 | 位置/状态 | 变化 |
|---|---|---|
| Ch 19 | 女主发髻(家中带出) | 首次出现 |
| Ch 28 | 女主发髻 | 男主深夜所赠、贴身带着 |
| Ch 37 | 异国巷道 | 被人碰断、玉簪掉在水沟 |
| Ch 38 | 男主内袋 | 只剩半截残身 |
| Ch 39 | 女主发髻 | 归还时换上新的玉簪 |每个关键物件都维护这种表。写新章前先看表,写完后更新表。
每章开头时间戳,章间算跨度:
| 章 | 时间锚 | 距上一章 |
|---|---|---|
| Ch 28 | 正月十八下午四点 | — |
| Ch 29 | 正月十八夜九点零二分 | +5 小时 |
| Ch 30 | 正月十八夜九点三十五分 | +33 分钟 |
| Ch 31 | 正月十八夜十点前后 | +25 分钟 |
| Ch 32 | 正月十八夜十点零七分 | +几分钟 |跨天/跨月章之间算几周几个月,防止钩子说"两个月后"实际是五周这种。
同一个东西在不同章节必须用同一个名字。改任何一处,全文对齐:
| 概念 | 统一叫法 | 禁用别名 |
|---|---|---|
| 主角父亲当年灭门旧档复印件 | "父亲当年灭门那份旧档复印件" | "前世被查封笔录复印件"(歧义) |
| 关键公章 | "歪半格的那枚朱印" | "那枚章" / "旧朱印" |
| 配角护身符 | "桃木符"(前后统一) | "小木牌" / "护身符" |年龄、年份、件数、金额、比分——特别容易前后不符:
| 项 | 数值 | 出现章 |
|---|---|---|
| 主角灭门时年龄 | 8 岁 | Ch 19/30/31 |
| 前世主角死时年龄 | 28 岁 | Ch 1/29/30/32 |
| 灭门年份 | 2000 冬 | Ch 19/30/31 |
| 对决总比分 | 主角 5 胜 2 平 / 对手 0 胜 2 平 5 负 | Ch 33/34/35 |
| 反派台前刑期 | 有期徒刑 20 年 | Ch 39 |
| 反派幕后刑期 | 无期徒刑 | Ch 39 |很多 skill 和工具默认"钩子 = 章摘要",但读者读的是正文。两者口径如果不一致,发布时删了钩子会发现正文没兑现钩子里的承诺。
实战中最常见的钩子/正文冲突:
定稿前必须做一次钩子 vs 正文口径核对。
对每一章:
很多"风格问题"是主观判断,难量化。但破折号密度可以。
经验值:正文每章破折号 ≤ 7 个,读起来不碎。超过 10 个就明显有"破折号滥用"感。低于 3 个过于平实可能缺气口。
这个指标比"句子通顺与否"稳得多。写脚本统计就行,不用人工数。
| 场景 | 命令 / 动作 |
|---|---|
| 每章写完后扫一遍 | python3 check_consistency.py chapters/N.md |
| 全书批量扫 | python3 check_consistency.py chapters/*.md |
| 某个物件前后不一致 | 查"道具链表"那一行 |
| 算两章时间差 | 查"时间锚表" |
| 钩子写错数字 | 用"关键数字表"对齐 |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.