本文件是治理 Hook 的输入、输出与退出码契约。修改协议必须同步测试。
{
"session_id": "宿主会话标识",
"cwd": "/项目或 worktree 根",
"tool_name": "apply_patch|Write|Edit|MultiEdit|Bash|Shell|WriteFile|StrReplaceFile",
"tool_input": {"file_path": "...", "command": "..."},
"tool_response": {"exit_code": 0, "output": "..."}
}session_id缺失时尝试conversation_id,最后回退default。cwd缺失时回退进程工作目录。- Codex 文件补丁使用
tool_name=apply_patch,补丁正文位于tool_input.command;从Add File、Update File、Delete File、Move to标记提取全部受影响路径。 - Kimi Code CLI 使用
Shell、WriteFile、StrReplaceFile等工具名,PostToolUse 的结果位于tool_output;FlowGuard 与Bash/Write/Edit共用动作判定,但不会从纯文本结果猜测退出码。 - stdin 非法或 Hook 自身异常:exit 0 并尽力输出 WARNING,避免宿主被插件故障锁死。
- 已识别的写入/命令工具若缺少路径、命令或
tool_input形状错误,按潜在code_write校验,不能因参数缺失直接放行。 - 文件写入路径先按实际目标规范化,再区分
docs/、测试与业务代码;../或符号链接不能把业务文件伪装为规格/测试文件。显式写入目标超出当前 Git worktree 时返回governance_write_target_mismatch。 - 治理事实明确缺失时,PreToolUse 使用 exit 2 阻断。
| 脚本 | 事件 | 职责 | 输出 | exit |
|---|---|---|---|---|
flowguard_status_summary.py |
SessionStart | 只读发现 SDD、恢复上下文、提示冲突/待分类 | stdout 摘要 | 0 |
flowguard_prompt_guard.py |
UserPromptSubmit | 提醒智能体重新判断任务、范围与事实源 | stdout 提醒 | 0 |
flowguard_gate.py |
PreToolUse | 校验业务写入、Git commit、发布;拒绝越出 worktree 的写入 | stderr 诊断 | 0 / 2 |
flowguard_artifact_check.py |
PostToolUse | 观察 docs/ 阶段文档是否失效;在有明确 exit_code 时记录检查结果 |
stdout JSON systemMessage;stderr 兼容提示 |
0 |
flowguard_artifact_check.py |
Kimi PostToolUseFailure(Shell) | 明确的测试工具失败记 FAIL,覆盖同一指纹的旧 PASS;不把错误文本当成功摘要 | stdout JSON systemMessage |
0 |
flowguard_stage_summary.py |
Stop | 汇总上下文、缺失提交证据和下一步 | stdout JSON systemMessage |
0 |
Stop 对 CodeReview 建议性 warning 必须说明可信放行依据尚缺、提交继续阻断;只能引导重新审查或选择可信策略,不得提示手工登记语义审查 PASS。测试与静态分析的恢复建议仍分别指出需要真实检查结果。
| 输入 | 治理动作 |
|---|---|
.specify/、openspec/、docs/ 下的阶段文档与原生规格 |
spec_write |
| tests/test/tests 或测试命名文件 | test_write |
其它 Write/Edit/MultiEdit/WriteFile/StrReplaceFile,以及 apply_patch 涉及的全部文件 |
按受影响路径中最严格的动作判定;业务代码 code_write 要求 01—07 阶段满足 |
Bash/Shell 中单条直接 git commit,目标在当前 worktree(可用同 worktree 的 git -C) |
git_commit,要求 01—09 阶段及有效检查证据;跨 worktree、Shell 包装器或改写 Git 目录的全局选项拒绝 |
Bash/Shell 中常见发布动词(Maven/Gradle/npm/pnpm/Yarn/Cargo/Docker/Helm/Twine/Make、gh release create/upload) |
release,允许无副作用的全局选项,要求全部十阶段、发布证据与用户验收;通过 --prefix、--repo、--manifest-path 等切换项目目标时拒绝 |
| 包含提交/发布的复合命令或 Shell 包装器 | 拒绝并要求拆成独立直接工具调用,避免弱门禁掩盖另一个动作 |
| 单条已识别只读命令 | 放行;包括常见只读文件命令与 Git 状态查询 |
单条 Spec Kit/OpenSpec 命令,或指向插件自带 scripts/flowguard_state.py 的 Python 命令 |
spec_write;同名脚本或仅在参数中出现该文件名不算 FlowGuard CLI |
| 单条已识别测试命令 | test_write;允许 TDD 先补测试 |
| 含重定向/管道/串联等 Shell 运算符,或无法证明只读的其它 Bash | code_write;缺少 01—07 阶段时阻断 |
明确只读或只修改宿主任务列表的工具(Read、ReadFile、ReadMediaFile、Glob、Grep、LS、ToolSearch、TodoWrite、SetTodoList、update_plan) |
放行,不变更项目流程状态 |
mcp__codeguard__list_languages、mcp__codeguard__analyze_java_impact |
已核对为只读,放行;仅匹配 MCP 服务器名为 codeguard 的精确工具名 |
mcp__codeguard__check_code_style |
test_write;必须显式传入属于当前 Git worktree 的 path;仅在 PostToolUse 逐语言结构化检查全部 PASS 时登记静态分析 PASS |
mcp__codeguard__auto_fix |
code_write;同样要求显式同 worktree path,再校验 01—07 阶段 |
| 未分类的本地或 MCP 工具 | Git 项目中拒绝;先补工具副作用分类及回归测试,不能按名称猜测其只读性 |
宿主会话缓存(上下文/锁)位于仓库外的宿主状态目录,写入目标越出当前 Git worktree 返回 governance_write_target_mismatch;docs/ 阶段机器区(阶段状态表、证据表)只能经 FlowGuard CLI 变更,直接手改会因指纹不匹配而失效。
CodeGuard MCP 的宿主配置若使用其他服务器名,本表不自动匹配;需按实际工具名另做审计和测试。精确名字分类只是副作用路由,不是 MCP 来源认证或结果可信度证明。
拒绝输出至少包含:
ERROR: <message>
Fix: <fix>
Missing: <missing...>
Allowed: <allowed_actions...>
[flowguard] code=<code>
- 输入不是 JSON 对象时输出空诊断信封并退出 0,不把畸形宿主载荷解释为检查通过。
- 只有宿主返回明确整数
exit_code时才可能记录 Bash/Shell 测试 PASS。Kimi 的tool_output若只提供字符串或没有明确退出码,已识别的测试命令记 WARNING 而非 PASS,覆盖同一指纹旧 PASS;PostToolUseFailure是宿主明确的失败事件,针对可识别的单条测试命令记 FAIL。当前宿主实际载荷仍须安装后验收。 - 仅识别单条明确执行测试的命令;
echo pytest、版本/收集模式、跳过测试参数及 Shell 复合命令不自动生成 PASS。退出码为 0 仍须核对 unittest、pytest、Maven、Gradle、Cargo 或 Jest/Vitest 风格摘要中的非零执行/通过数;零用例、全跳过、缺失或未知摘要记 WARNING,不作为提交门禁 PASS。非零退出码记 FAIL。命令输出本身仍是协作式观察证据,不是不可伪造的 CI 回执。 - CodeGuard 静态检查和 CodeReview 语义审查不能仅凭命令文本与退出码 0 自动生成 PASS。对服务器名精确为
codeguard的 MCPcheck_code_style/auto_fix,PostToolUse 解析 CodeGuard 逐语言结构化回执;非空、范围一致且每项status=PASS、passed=true、exit_code=0才登记静态分析 PASS。 - CodeGuard MCP 的 FAIL、UNVERIFIED、空结果、报错或无法解析的回执,登记 FAIL 或 WARNING 并覆盖此前的 PASS;跨 worktree 目标不登记。证据只保存摘要和回执哈希,不保存完整日志。宿主工具名与 MCP 回执形状的真实加载仍需分别验收;这不是 MCP 身份认证。
- 对单条
python3 <...>/codereview.py evidence [--request <文件>]命令,只在明确退出码为 0、JSON 协议 v1、会话/worktree/common_dir/HEAD/暂存区指纹与当前任务相符时消费报告。问题必须指向当前暂存文件;有问题记semantic_review=fail,合法零问题报告记warning,因为 CodeReview v0.1.0 的success仅是建议性结果且coverage_status=limited,不会自动生成 PASS。回执错误、空暂存区或过期只可记 WARNING;跨 worktree 回执不登记。 - 若提交时测试和静态分析已满足、唯一缺失的是语义审查,而当前有效 CodeReview 回执仍为
warning,返回governance_semantic_review_advisory并保持阻断。不得提示智能体把建议报告手工改写为 PASS。当前本地证据登记仍是协作式接口,不能把人工填写的 PASS 当作不可伪造回执;可信放行依据与宿主/CI 独立门禁完成前,不宣称对抗性生产门禁。 - 不保存原始命令和输出,只保存命令 SHA-256 摘要、类型、生产者和退出码,避免泄漏凭据。
- 命令成功只产生对应证据,不自动推进原生 SDD 阶段,也不产生用户验收。
- 证据行含
context_id;没有上下文归属的旧行留在文档作历史记录,但不参与门禁。全部门禁证据随代码、当前任务及父级绑定的原生规格正文、当前任务及父级的 01—07 阶段正文变化过期;项目级 02/07 也参与指纹。未绑定的其他 Spec Kit、OpenSpec 或 Superpowers 产物不应误使本任务证据过期。证据表追加、阶段状态和批准依据元信息不参与正文指纹,避免登记自身使证据过期。不能用 CLI 关闭过期规则。 - 项目级 10 发布验收以发布内容表中列出的全部功能为范围,并绑定 07 编码规范与各功能 09 文档的验收指纹;任一列入功能 09 失效、重验或变更,10 即失效。空白、重复或非法功能清单不能构成已验收的发布范围。
- 阶段推进、项目文档初始化、旧项目迁移和证据登记共用宿主状态锁。
docs/阶段文档更新采用同目录临时文件替换并保留原权限;新建采用排他式原子创建,不覆盖已有目标。锁冲突或替换失败应保留旧文档。迁移若中途失败,已创建文档保留供人工核对,不回滚删除可能被外部编辑的文件。外部编辑器不受本锁约束,仍需靠正文指纹与人工协作避免并发冲突。 - Git 差异或未跟踪文件读取失败时,证据指纹不可用;提交和发布返回
governance_git_state_unavailable拒绝,不以空差异沿用旧 PASS。读取、补规格、补测试和修复代码的路径保持可用。 - 带未知 Git 全局选项的
git ... commit不能降级为普通code_write;若无法验证目标 worktree,返回governance_git_target_mismatch。merge、cherry-pick、revert、rebase、am、commit-tree、update-ref等可能隐式生成提交或移动引用的直接命令返回governance_git_history_mutation_unverified;用户授权的历史操作需单独设计可验证路径,不以 01—07 写码放行代替提交审查。 - 未明确分类的 Git 子命令(包括可能配置为提交别名的命令、
git push和git tag)返回governance_unclassified_tool,不能默认按code_write放行。已识别的只读命令保持可用,git add、git apply、git mv仍作为写码动作检查。远端发布与特殊 Git 流程需要单独定义目标、授权和证据策略后才能放开。 - 指纹只读取 Git 跟踪或未忽略的文件;无首个提交的仓库也通过 Git 列表判定范围。符号链接只计入链接目标路径字符串,不解引用仓库外文件内容。
apply_patch应检查补丁中每个文档路径,不能只读取file_path;发现失效时通过单个 JSONsystemMessage通知宿主。
| 宿主 | 声明方式 | 约束 |
|---|---|---|
| ZCode | hooks/hooks.json 约定发现 |
.zcode-plugin/plugin.json 不写 hooks |
| Kimi | kimi.plugin.json 以内联 Hook 监听五类主事件与 Shell 的 PostToolUseFailure,并通过 sessionStart.skill=flowguard 加载编排主技能 |
Hook 使用 ./hooks/... 相对路径;安装加载仍须真实验收 |
| Codex / Claude | hooks/hooks.json |
${CLAUDE_PLUGIN_ROOT} 由宿主展开 |
- 非 Git 且无旧 FlowGuard 状态时放行。
- Git 项目无上下文时允许读取和补规格,阻止业务写入。
- 旧非 Git 测试夹具继续走十阶段兼容门禁。
- 新流程的十阶段文档存于
docs/;宿主侧缓存不应被当作仓库规格事实源。 - 机器证据不替代用户批准或用户验收。
- 已知的文件路径穿越/符号链接、跨 worktree 文件写入、Shell 重定向写码、复合提交/发布、带全局选项的常见发布命令和跨 worktree
git -C提交有 Hook 回归测试;嵌套提交因目标不可验证被拒绝。这不等于完整 Shell 语义隔离或完整发布命令枚举。别名、外部脚本、其它发布工具、禁用 Hook、伪造 CLIactor或approval_ref仍可能绕过本层;上线前需真实宿主回执、可信批准来源和 Git/CI 独立门禁。 PreToolUse/PostToolUse使用*匹配宿主支持的全部本地工具;宿主未走 Hook 路径的专用工具或不支持通配符的宿主仍属未验证边界。