Files
Neo-ZQYY/docs/audit/changes/2026-05-05__wave1_f2_1b_defense_hooks.md
Neo a99bbd9a74 chore(hooks): OpenAPI 抓取 + Prompt 同步 提醒 hook (W1 / F2-1B)
历史教训 (F2-1A): OpenAPI 抓取脚本 2026-04-06 commit 779b2f6 被
Claude Opus 4.6 在批量清理 1155 个废弃文件时误归档到
_DEL/_DEL/scripts/ops/, 导致 docs/contracts/openapi/backend-api.json
28 天 stale (137 paths -> 实际 167 paths, 缺 30 端点)。
Neo 反馈: 建立机制不要让类似事件再发生。

F3-2C 配套需求: 建立 docs/ai/system-prompts/ 独立 MD 体系后,
维护流程依赖 3 步同步 (元信息日期 / 同步历史 / _INDEX.md 状态表),
容易遗漏造成漂移。

新增 2 个 PostToolUse hook (Edit|Write matcher, timeout 5s):
- post_edit_openapi_reminder.py: 改 apps/backend/app/routers/*.py
  提醒重抓 OpenAPI 具体命令
  (.venv/Scripts/python.exe scripts/ops/_export_openapi.py)
- post_edit_prompt_sync_reminder.py: 改 docs/ai/system-prompts/app*.md
  提醒 3 步同步 (元信息 / 同步历史 / _INDEX.md 状态表)

settings.json 注册 2 个 hook 条目 (PostToolUse 末尾追加)。

spec-close.md 步骤 5 文档同步表:
- OpenAPI 行升级为具体命令 (避免手工同步漂移描述)
- 新增 docs/ai/system-prompts/app*.md 同步行

验证: stdin 模拟测试 3 场景全部符合预期 (匹配 router 输出 OpenAPI 提醒;
匹配 system-prompts MD 输出 prompt 同步提醒; 不匹配静默)。

详见 docs/audit/changes/2026-05-05__wave1_f2_1b_defense_hooks.md
2026-05-05 02:03:43 +08:00

5.7 KiB

Wave 1 F2-1B — OpenAPI 抓取 + Prompt 同步 防御机制 hook

字段
日期 2026-05-05
Wave 1 / Day 5 收尾(F2-1B + F3-2C 配套机制)
范围 加 2 个 PostToolUse hook;升级 .claude/commands/spec-close.md L45 为具体命令
文件改动 新增 2 hook + 修改 settings.json + 修改 spec-close.md + 1 审计

一、起因

F2-1A 历史教训(2026-04-06 commit 779b2f6)

OpenAPI 抓取脚本 scripts/ops/_export_openapi.py 被 Claude Opus 4.6 在批量清理 1155 个废弃文件时误归档_DEL/_DEL/scripts/ops/,导致:

  • docs/contracts/openapi/backend-api.json 28 天未更新(2026-04-06 → 2026-05-04)
  • 实际 router 已增 30 端点,但静态导出仍是 137 paths
  • W1-T7 admin-web API PRD 总览基于 stale json 误写"151 端点"
  • F2-1A 5/4 已恢复脚本 + 重抓(137 → 167 paths,详见 2026-05-04__wave1_f2_1_openapi_script_restored.md)

Neo 反馈:"建立机制不要让类似事件再发生" — 即 F2-1B。

F3-2C 配套需求(2026-05-05)

F3-2C 建立了 docs/ai/system-prompts/ 独立 MD 体系,但维护流程依赖:

  • 改某 APP MD 后须同步 §一 元信息"最后同步" + §同步历史 + _INDEX.md §四
  • 上述步骤容易遗漏,造成同步状态表与文件实际内容漂移

需要 hook 在改 system-prompts/app*.md 时自动提醒上述同步。

二、产出

2.1 新增 hook 1:post_edit_openapi_reminder.py

.claude/hooks/post_edit_openapi_reminder.py(38 行)

触发:Edit / Write 匹配 apps/backend/app/routers/*.py 输出:提醒重抓 OpenAPI 的具体命令 .venv/Scripts/python.exe scripts/ops/_export_openapi.py

2.2 新增 hook 2:post_edit_prompt_sync_reminder.py

.claude/hooks/post_edit_prompt_sync_reminder.py(36 行)

触发:Edit / Write 匹配 docs/ai/system-prompts/app*.md 输出:提醒 3 步同步动作(元信息日期 / 同步历史 / _INDEX.md 状态表)

2.3 修改 .claude/settings.json

PostToolUse 新增 2 个 hook 条目(matcher 都是 Edit|Write,timeout 5s)。

2.4 修改 .claude/commands/spec-close.md

§步骤 5 的文档同步表第 3 行升级:

-| `docs/contracts/openapi/backend-api.json` | 新增/修改 API 端点时 |
+| `docs/contracts/openapi/backend-api.json` | 新增/修改 API 端点时 — 执行命令重抓:`.venv/Scripts/python.exe scripts/ops/_export_openapi.py`(避免手工同步漂移;hook `post_edit_openapi_reminder.py` 会在改 router 时自动提醒) |

并新增第 4 行:

+| `docs/ai/system-prompts/app*.md` | 从百炼控制台同步 system prompt 时 — 改 §一 元信息"最后同步"+ §同步历史追加一行 + 同步 `_INDEX.md` §四 状态表(hook `post_edit_prompt_sync_reminder.py` 会自动提醒) |

三、验证

模拟 stdin 测试 hook(echo '{...}' | python <hook>.py):

场景 预期 实际
apps/backend/app/routers/admin_ai.py OpenAPI 提醒 输出提醒 JSON
docs/ai/system-prompts/app3_clue.md Prompt 同步提醒 输出提醒 JSON
README.md(不匹配) 静默 无输出

四、设计取舍

为什么是 PostToolUse 提醒而不是阻断?

提醒(additionalContext)比阻断(exit 2)合理:

  • Hook 无法判断"是否新增/修改/删除端点"(只看 file_path),粗粒度阻断会误伤格式调整、注释修改
  • 提醒强度足够:Claude 在下一轮看到 additionalContext,会按提醒执行重抓命令
  • 阻断风格的 hook 应留给"绝对不能动"的场景(如 _archived/ 目录 / apps/demo-miniprogram/)

为什么不在 CI 加 OpenAPI 一致性检查?

Neo F2-1 反馈"没有启动 Gitea Actions 的打算"(Wave 1 findings 第二轮),CI 加检查留 Wave 5 F2-2(tests/ 入仓 Gitea 简版)再考虑。当前阶段 hook 提醒 + spec-close.md 兜底已够用。

为什么不加月度对照云端 prompt 的定时机制?

定时提醒需要外部调度器(cron / Windows 任务计划),与 Claude Code 当前架构不衔接。可选项已在 _INDEX.md §八 标记"(可选)搭定时机制",留给后续 Wave。

五、关联

六、风险与回滚

风险 回滚
2 个新 hook 极低 — 仅 PostToolUse 提醒,不阻断;失败时 try/except 静默 sys.exit(0) 删除 hook 文件 + settings.json 对应 entry
settings.json 改动 低 — 加 2 个 entry,不动现有 8 个 entry git checkout 还原
spec-close.md 改动 低 — 仅升级文档表格,加具体命令 + 1 行 git checkout 还原

七、commit 建议

chore(hooks): 加 OpenAPI 抓取 + Prompt 同步 提醒 hook (W1 / F2-1B)

历史教训(F2-1A): OpenAPI 抓取脚本 2026-04-06 被误归档,
导致 docs/contracts/openapi/backend-api.json 28 天 stale。
F3-2C 建立 system prompt 独立 MD 体系后,同步状态表也需要
机制保证不漂移。

新增 2 个 PostToolUse hook:
- post_edit_openapi_reminder.py: 改 backend router 提醒重抓 OpenAPI
- post_edit_prompt_sync_reminder.py: 改 system-prompts/app*.md
  提醒同步 §一 元信息日期 / §同步历史 / _INDEX.md §四 状态表

settings.json 注册 2 个 hook(matcher Edit|Write, timeout 5s)。

spec-close.md §步骤 5:
- OpenAPI 行升级为具体命令(避免手工同步漂移)
- 新增 system-prompts/app*.md 同步行

详见 docs/audit/changes/2026-05-05__wave1_f2_1b_defense_hooks.md