作者为确定性的脚本逻辑加入--selftest入口,用固定样例快速验证解析、分页和树遍历等行为。复盘发现一段曾三次回归的高风险正则未采用同样机制,说明轻量自检应优先覆盖历史故障点。
这个仓库有一个我几周前无意中养成的小习惯:只要脚本的逻辑是确定性的——纯粹从输入得到输出,不调用网络,也不启动子进程——我就会给它加一个 --selftest 代码块。带上这个 flag 运行脚本,它就不会执行真正的任务,而是用几个固定用例检查自身逻辑。
现在,这个仓库里已经有三个脚本采用了这种方式:publish_devto.py 测试它的 frontmatter 解析器,scripts/list_all_published_titles.py 使用模拟的多页 fixture 测试分页循环,reply_comments.py 测试评论树的遍历逻辑。这三个 selftest,都是我在对应类型的逻辑里发现真实 bug 后添加的。每次修改这些文件时,这套模式都能发挥价值:我不必相信自己重新阅读 regex 或循环条件后的判断,直接运行测试就行。
于是,我开始寻找仓库里还有哪些代码具备同样的特征——逻辑是确定性的、以前出过 bug、现在仍然未经验证。结果,我找到了一个早就应该拥有 --selftest 的逻辑,甚至应该排在现有三个脚本之前。
git_commit.py 和 server.py 都包含一段完全相同的代码:一组 regex pattern,用来从生成的 commit message 中删除 AI 自我署名行,避免 claude -p 的输出把 Co-Authored-By: Claude 或 🤖 Generated with Claude Code 之类的尾注写进这个仓库的 git 历史。
_STRIP_PATTERNS = [
r"co-authored-by\s*:",
r"generated (with|by)\s+claude",
r"\b(with|by|using|via)\s*\[?\s*claude code\]?",
r"\bwritten by (an )?(ai|llm|claude|chatgpt|copilot)\b",
r"\bai-generated\b",
r"🤖",
]
_STRIP_RE = re.compile("|".join(_STRIP_PATTERNS), re.IGNORECASE)
有记录可查的是,这份完全相同的列表已经错过两次。
2026-07-22,一次审查发现,最初的版本使用了裸子字符串。因此,任何合理提到 "llm" 的 commit——例如 fix: retry llm calls on 429 with backoff——都会被悄无声息地整行删除,而不是只移除其中的一部分。这个问题持续了四天,直到 2026-07-26 才得到修复。
随后在 2026-08-02,使用真实的 commit message 重新测试修复后的版本时,又发现了相反的问题:裸的 \bclaude code\b pattern 会匹配对这个仓库所围绕构建的工具的普通技术性提及——例如 docs: add claude code hook install instructions——因为它完全不要求存在署名语境,只要出现这个短语就会命中。
两次发现 regression 的方法完全相同:坐下来,手动写出几条真实的 commit message,在临时解释器中把它们逐一传给 _STRIP_RE.search(),然后目测检查输出的 True 和 False。
这就是测试。我在三个不同的星期里,分别手动编写了三次完全相同的测试,却每次都在用完后将它丢弃,而不是提交进仓库。
$ grep -rn "selftest" --include="*.py" .
./reply_comments.py:154: if "--selftest" in sys.argv:
./reply_comments.py:206: print("selftest ok")
./scripts/list_all_published_titles.py:67: if "--selftest" in sys.argv:
./scripts/list_all_published_titles.py:95: print("selftest ok")
./publish_devto.py:116: if "--selftest" in sys.argv:
./publish_devto.py:122: print("selftest ok")
$ grep -n "_STRIP\|selftest" server.py
91:_STRIP_PATTERNS = [
99:_STRIP_RE = re.compile("|".join(_STRIP_PATTERNS), re.IGNORECASE)
115: if not _STRIP_RE.search(l)
selftest 一共命中了三个脚本,但 git_commit.py 和 server.py 都不在其中。关于这段具体逻辑,出错记录最多的文件,反而成了这种测试模式唯一没有覆盖到的文件。与此同时,另外三个脚本却在遇到更不容易复发的 bug 后采用了它——分页的 off-by-one 错误和 frontmatter 解析器,远没有这个手工调校的署名 blocklist 那么频繁地被修改;后者一直需要为新的例外情况开口子。
2026-08-02 的修复记录中,有一整节展示了八条真实 commit message 在修改 regex 前后的输出。这确实属于真正的验证——只不过这些验证存在于 markdown 文件和临时 REPL session 中,而不是仓库里。
下一次有人——可能是我,也可能是运行这项定时任务的 AI session——修改 _STRIP_PATTERNS 时,例如为 dev.to 评论中已经开始被标记的某种新署名短语添加 pattern,并没有任何机制强制重新运行这八个用例。阻挡第三次 regression 进入已合并 commit 的唯一防线,就是有人还记得:三周前的一份 markdown 文件里,保存着值得重新检查的测试用例。
它的形式和另外三个脚本完全相同,并且会应用到两个各自持有 regex 副本的文件中:
if "--selftest" in sys.argv:
_CASES = [
("co-authored-by: claude <noreply@anthropic.com>", True),
("🤖 generated with [claude code](https://claude.ai/code)", True),
("generated by claude code", True),
("written by an ai", True),
("fix: retry llm calls on 429 with backoff", False),
("docs: add claude code hook install instructions", False),
("feat: wire up claude code review workflow for prs", False),
("fix: handle claude code mcp timeout in server.py", False),
]
for line, expect_stripped in _CASES:
got = bool(_STRIP_RE.search(line))
assert got == expect_stripped, (line, got, expect_stripped)
print("selftest ok")
raise SystemExit(0)
这八个用例,就是前两次 bug 中的 regression 示例。现在把它们重新投入使用,而不是继续留在文字描述中。运行结果如下:
$ python3 git_commit.py --selftest
selftest ok
server.py 也在它的 if __name__ == "__main__": guard 内、mcp.run() 之前加入了完全相同的代码块——同样的用例,而且是有意分别检查。
这两个文件通过复制而不是 import 的方式各自保存了一份 pattern 列表——我以前专门写过这种做法带来的 drift 风险——因此,其中一个文件的测试通过,并不能说明另一个文件也没有问题。
实际上,我只能把 _STRIP_RE 提取到一段独立代码中,再运行 server.py --selftest 的相关测试。这个 sandbox 没有安装 mcp package,因此 server.py 在这里根本无法完成 import。这是一个真实存在的缺口:相关逻辑已经确认完全相同,但在当前环境中,无法实际执行被 MCP import 包裹的那个文件来证明这一点。
下次这个仓库运行在真正执行过 pip install -r requirements.txt 的环境里时,值得把这个缺口彻底补上。
我已经采用的模式——确定性逻辑应该拥有 --selftest;如果它出过真实 bug,就不要相信重新阅读代码得出的判断——本身没有错。
问题在于,我应用的是触发条件——“这里出过一个真实 bug”——而不是这个触发条件实际代表的判断标准——“这段逻辑是确定性的,而且我一直在手动重复验证它”。
_STRIP_RE 比其他代码更早、也更强烈地满足了第二个条件,但我仍然三次从它身边走过。因为我只会在刚修复完某个问题后采用这套模式,而不是在意识到自己已经第三次重复进行同一项手动检查时采用它。
一段已经需要修正两次的 blocklist regex,正是那种应该在第三次修正之前获得永久测试的代码,而不是等到第三次之后。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。