# KMC + KAP CI 硬门槛评估报告（深度审计）

- 评估日期：2026-08-25 10:20–11:10（本机实测）
- 评估对象：KMC = `/data/workspace/kais-hermes-skills`（github.com/kaiger666888/kais-hermes-skills, master）；KAP = `/data/workspace/kais-aigc-platform`（origin=kaiger666888/kais-aigc-platform, upstream=HBAI-Ltd/Toonflow-app fork, master）
- 方法：全部结论基于本机实测命令输出；工具 radon 5.1.0 / mypy 1.x / ruff（本机已有）/ trufflehog3 / lizard 1.24 / jscpd（npx）/ c8（npx）均为临时安装于 pipx 或 npx 缓存，未动两仓与全局 venv
- 重要现场观察：**评估期间 KAP 工作区正被并发编辑**（10:36 `npm run lint` 0 错 → 10:52 复跑出现 TS1192 且 esbuild 打包失败，`src/router.ts` 有 654 行未提交 diff）。这本身就是「无门禁 + 老司机活跃开发」现状的活证据。

---

## 0. 执行摘要

| 层 | 门槛 | KMC | KAP |
|---|---|---|---|
| 基础 | 1 编译/构建 | **GO**（轻量：AST 语法 + pytest 收集，<3s） | **GO**（必须含 esbuild 真打包；已抓到现行失败） |
| 基础 | 2 自动化测试 | **GO但降级**（先修 3 个可移植性地雷） | **GO但降级**（重新定义测试面：src 单测+离线 verify:*） |
| 基础 | 3 Lint | **GO但降级**（ruff bug 类先清 28 个） | **GO**（tsc --noEmit 现状即门禁，2.4s） |
| 基础 | 4 类型检查 | **NO-GO 暂缓**（mypy 132 错，动态构造多） | **GO**（= #3，tsc strict 已开；补 packages/） |
| 红线 | 5 圈复杂度 ≤10 | **NO-GO**（硬上限必炸：25.7% 函数超）→ 降级为新函数 ratchet | **NO-GO**（9.7% 超）→ 同左 |
| 红线 | 6 覆盖率下限 | **GO但降级**（pipeline 78.3% 好；plugins 14.6% 不设线） | **NO-GO 暂缓**（src 仅 7/294 文件有测试，先建 runner） |
| 红线 | 7 重复率上限 | **NO-GO**（实测 1.20% 已优，门禁无增量价值） | **GO但降级**（7.89%，冻结防恶化） |
| 红线 | 8 文档-代码一致性 | 通用自动化 **NO-GO**；已有的 `verify_skill_references --strict` **GO但降级** | 通用自动化 **NO-GO**；离线 `verify:*` 契约脚本 **GO**（抽 3–5 个进 CI） |
| 安全 | 9 依赖漏洞 | **NO-GO 暂缓**（无依赖清单，9 个隐性依赖先显性化） | **GO但降级**（周扫；high+可修才拦，2 个无修复需 allowlist） |
| 安全 | 10 敏感信息 | **GO**（500 commit 实测无泄露，可全绿上线） | **GO**（同左；需配排除清单） |

一句话总结：**基础底线两仓都该上且成本极低（KAP 3 分钟、KMC 5 分钟内跑完）；质量红线里只有「KMC pipeline 覆盖率 ratchet」和「KAP 重复率冻结」值得做，复杂度硬上限和通用文档门禁不值得；安全两项密扫立即可上、依赖扫描只上 KAP 且降级为周扫。** 拓扑上：**本地 pre-push 硬拦 + GitHub Actions 兜底**——纯远程 CI 在「直推 master、从不看 PR」的模式下已被实证形同虚设。

---

## A. 两仓现状盘点（CI 就绪度基线）

### A1. KMC（kais-hermes-skills）

| 维度 | 实测数据 | 证据 |
|---|---|---|
| 管线代码 | 63 个 .py，48,488 LOC（F1 ✓）；最大 runner.py 4,350 行，p09_shot_breakdown 2,900、p11b_final_render 2,862 | `find pipeline -name '*.py' \| wc -l`；`wc -l` 排序 |
| plugins 代码 | 154 个 .py，55,150 LOC，6 个子目录（review_gates/kais_aigc/…）——**比管线本体还大 14%** | `find plugins` |
| 测试资产 | 227 个 test_*.py、68,539 LOC（测试代码 > 被测代码）；干净可收集 **2,858** 个测试 | 见下「收集三雷」 |
| 全量通过率 | 隔离环境全量：**11 failed / 2,833 passed / 14 skipped，176.3s**；11 个失败 = 9 个隔离环境伪失败（ltx 系列在原生环境 16/16 过）+ 1 个**真红**（test_p11c_video_qc::test_ensure_llm_kap_allocate_fallback，原生环境也挂，`assert (False or False)`，tests/test_p11c_video_qc.py:362）+ 1 个套件规模自检（test_v50_regression 断言总测试数基线，因评估忽略 2 文件而触发） | `/tmp/covenv` 全量跑；原生复跑 |
| 抽样（按任务书 24+6 个文件） | 30 文件 465 测试：全过（1 skip= e2e_real 自跳过），最快 1.97s/413 个 | 随机种子 42 抽样 + 定向 |
| 覆盖率（全量实测） | **pipeline/ 78.3%；plugins/ 14.6%；合并 42.5%**（35,604 stmts） | pytest-cov term 报表 |
| 静态检查现状 | 无任何配置（无 pytest.ini/pyproject/setup.cfg/.github）。ruff 默认规则 **101 错**（E402×29、F401×26、F841×26、F541×16…），bug 类子集（F/E9/F82）**28 错含 1 个 F821 undefined-name**（`_resolve_episode_genre_cached`）+1 个 F811；mypy **132 错**；AST 语法 **0 错 / 0.4s**（217 文件） | ruff/mypy/pipx 实测 |
| 已有 CI 资产 | `.pre-commit-config.yaml` **存在且合法**（2 个 hook：manifest 契约三件套 pytest + check_manifest_no_bare_except.py），但 **未安装**（.git/hooks 仅 sample）→ 纯摆设。scripts/ 下 2 个检查脚本：check_manifest_no_bare_except.py（AST 扫 _manifest.py 裸 except）、verify_skill_references.py（movie-experts SKILL.md 幽灵引用检测，自带 `--strict` CI 模式 exit 1；当前非 strict 跑出 findings 含 `wan22_video` @ visual_executor/SKILL.md:309，exit 0） | Read 文件；pre-commit validate-config OK |
| git 状态 | 1,449 commits；本地领先 origin/master **20 commits**（昨日有 push）；无分支保护问题谈不上——根本没有 CI | `git rev-list --count origin/master..master` |

**收集三雷（pytest --collect-only 实测）**：
1. `tests/test_structured_output.py` 是自执行脚本（模块级跑测试+`sys.exit`，tests/test_structured_output.py:186）→ pytest 9.1.1 收集直接 INTERNALERROR（exit 3）。裸 `pytest` 从 skill 根跑还会捞到 `scripts/test_parser_resilience.py` 同类问题。
2. `tests/test_feedback_translator.py` 的 sys.path hack 指向 skill 根，但 `plugins/` 其实在仓根（skills/kais-movie-pipeline/plugins 不存在）→ 只在 CWD=仓根时碰巧能跑。
3. 依赖闭包未声明：隔离 venv 实测需 **9 个包**（pytest, pyyaml, httpx, pyjwt, pydantic, ruamel.yaml, requests, rich, numpy——numpy 藏在 p09b_shot_audit.py:329 函数级 import，违背 CLAUDE.md「stdlib only」约束）+ **两个源码树在 PYTHONPATH**（本仓 + hermes-agent）。且 import 链 `runner.py:48 → phases/__init__.py:39 → plugins.review_gates → plugins.kais_aigc/tools.py:20 → from tools.registry import …`（tools = **隔壁 hermes-agent 仓**）。更毒的是：两仓都有顶层 `plugins/`，hermes-agent 的是 regular package（有 __init__.py），KMC 的是 namespace package → **顺序敏感遮蔽**，两仓还有同名 `formula_library` 插件。

### A2. KAP（kais-aigc-platform）

| 维度 | 实测数据 | 证据 |
|---|---|---|
| src 代码 | 294 个 .ts，59,990 LOC（F4 ✓）；另有 packages/ 三个子项目（infinite-canvas、flowgraph-v3、portal，自带 vitest+tsc） | find |
| 测试资产 | **src/ 内 7 个 *.test.ts**（node:test runner，逐文件 `node --import tsx --test` 跑，无统一 runner；实测 reviewBridge 3/3 过 176ms）+ packages/ 46 个 vitest 测试 + Makefile 的 test-unit/test-integration **只覆盖 vendored docker/hermes-agent**（`PYTEST = cd docker/hermes-agent && python3 -m pytest`）+ test/e2e-pipeline.ts（playwright）。**F7 部分不成立**：src 不是零测试，但 7/294≈2.4% 文件覆盖，且无聚合脚本 | find + 实跑 |
| c8 覆盖率（4 个 lib 测试文件对其模块） | 86.77% stmts / 78.28% branch（generationConfig 94.5%、gpuVramManager 93.8%、reviewBridge 74.7%）——但仅限被测模块 | npx c8 实测 |
| lint/类型 | `lint = tsc --noEmit`，strict=true + noImplicitAny=true，**2.4s**（复跑 4.1s）内跑完；10:36 时 0 错（评估窗口内 WIP 后来引入 TS1192）。tsconfig 排除 packages/、docker/hermes-agent/_hermes_source/**、data/** | package.json + 实跑 |
| 构建 | `build:server` = esbuild 打包 src/app.ts → data/serve/app.js。**复刻实测失败**（0.64s exit 1）：`src/router.ts:59` default-import 只有具名导出的 `minimax-h3/promptAnchor.ts`（该文件仅 export const I2VA_ANCHOR_LINE / FL2VA_ANCHOR_LINE / withFirstFrameAnchor）。属未提交 WIP（654 行 diff），但**说明当前流程没有任何东西在打包前拦它** | esbuild 复刻至 /tmp |
| verify 脚本 | 38 个 npm scripts，~30 个 verify:phase-41..65 + canvas 系列。抽测 3 个全过且离线：verify:schema-drift 10/10；verify:manifest-contract（**跨仓跑 KMC 的 manifest 套件 135 测试 0.81s**，硬编码 sibling 路径 /data/workspace/kais-hermes-skills）；verify:phase-65 29/29 | npm run 实测 |
| 依赖 | 46 prod + 16 dev；playwright ^1.61.1 在 **dependencies**（怪味）。npm audit（官方源，tmp lockfile）：**7 漏洞 = 6 high + 1 moderate**：@huggingface/transformers（*，无修复）、puppeteer-core 19.8.4–24.43.1、sharp<0.35、@puppeteer/browsers≤2.13.2、extract-zip（*，无修复）、undici≤6.27.0；moderate: @ai-sdk/provider-utils | npm audit 实测 |
| 现有 CI（F5 复核） | ① `debug.yml`「构建测试」：push **main/dev** + PR main + 手动。**实际开发分支是 master → 常规 push 永不触发**。仅 6 平台打包上传 artifact，无测试步骤。② `release.yml`：仅 tag v*，打包+发布，无测试。③ `hermes-integration-test.yml`：PR 到 master **且路径命中 docker/hermes-agent/**、docker-compose 起容器跑 pytest——**门禁语义是真的**（末步 exit 1，无 continue-on-error），但只护 vendored 目录。**实证死亡**：`gh run list` 最近 15 个 run 全是 2026-04~06 的 Build and Release；**最后一次 run 是 2026-06-08（v1.1.8），至今 2.5 个月零触发**；master 分支保护 404（Branch not protected） | Read 3 个 workflow + gh |
| git 状态 | 2,244 commits；本地领先 origin **75 commits**；13 个脏文件；评估期间被并发编辑 | git |

### A3. 密钥扫描实测（trufflehog3，--depth 500 历史 + 工作区）

- **KMC：无真实泄露**。仅 2 个 LOW 误报（skills/orchestration/*/scripts/project-manager.js 中 .env.example 模板里的 `postgresql://app:dev@localhost`）。
- **KAP：797 findings / 5 HIGH，全部为 vendored/构建产物噪音**（docker/hermes-agent/_hermes_source/agent/redact.py 的测试夹具 RSA、node_modules/dotenv README 示例 key、.venvs PIL 二进制熵误报、data/web/index.html 打包产物里的 Facebook OAuth Token 模式）。**一方源码（src/、scripts/）零命中**。
- 结论：两仓历史干净，密扫门禁可「全绿 baseline」即刻上线；但必须带排除清单（node_modules/、.venvs/、_hermes_source/、data/web/、docker/comfyui*/custom_nodes）。

---

## B. 逐门槛评估（10 项 × 2 仓）

### B1. 编译/构建通过

- **KMC：GO（轻量定义）** — Python 无构建，等价物 = AST 全量语法（217 文件 0 错 0.4s）+ pytest 干净收集（1.3s）。「构建失败」形态主要是 ImportError/收集爆，两者都已被覆盖。落地：CI 里 `python -m compileall` 式检查或直接靠收集步骤。工作量 0.5h。误伤风险：无。
- **KAP：GO，且必须包含 esbuild 真打包** — 实证：tsc 类型绿 ≠ 能打包（本次 WIP 中 tsc 与 esbuild 先后红、且 esbuild 是更严的那个；strict interop 下 TS1192 出现说明 tsc 也能抓，但没有任何流程在跑它们）。落地：CI 加一步 `esbuild → /tmp` 校验（0.64s，零产物污染）。工作量 1h（写 ci.yml）。误伤风险：几乎无；注意 data/serve/app.js 在仓内，CI 打包输出要指到 /tmp 或加 .gitignore。

### B2. 自动化测试全部通过

- **KMC：GO但降级** — 资产质量好（测试代码 68.5K LOC > 被测代码，全量 176s，99.6% 通过率），**但不能直接上门禁**：先修三雷（① test_structured_output.py 自执行脚本改名/挪走；② 补 pytest.ini 固定 rootdir+testpaths+pythonpath，消掉 CWD 依赖；③ 把 9 个隐性依赖写进 requirements-dev.txt 并解决 plugins namespace 遮蔽——最小方案是 conftest 里把仓根插到 sys.path 最前）。三雷修完全量 176s 可接受为 push 门禁；不想等就分两层（fast tier = manifest 三件套 0.81s + 抽样；full tier 后台跑）。**已知 1 个真红测试（p11c）必须先修或显式 xfail**，否则门禁第一天就是红的。工作量：三雷约 4–6h + ci 配置 2h。误伤：e2e_real 类已自 skip，无需处理；GPU/ComfyUI/KAP:10588 依赖的测试实测全部走 mock/注入（test_e2e_degraded、test_canvas_auto_sync 等离线全过），CI 可跑。
- **KAP：GO但降级（重新定义测试面）** — 把「测试」定义为：src 的 7 个 node:test 文件（<2s）+ 抽 3–5 个离线 verify:*（各 <10s）+ packages/ vitest（有 test 脚本，未实测时长，标「待验证」）。Makefile 的 hermes-agent 集成套件继续走 hermes-integration-test.yml（PR 触发）或降为 nightly——它测的是 vendored 代码，不是本仓 src，每 push 跑属于错配。工作量 2–3h。误伤：verify:phase-* 部分可能连真服务（只实测 3 个离线），需逐个标注分类（~1h 人工）。

### B3. Lint/静态检查零错误

- **KMC：GO但降级** — 现状无任何 lint。ruff 默认规则 101 错会被秒拦，故分两步：先上门禁的是 bug 类子集 `--select E9,F63,F7,F82,F4`（28 错，其中 F821 undefined-name 是真 bug 候选、F811 有 1 个 SchemaValidationError 重定义）→ 清零后冻结；E402（29 个，sys.path hack 风格产物）等风格类降级为警告。ruff 单仓秒级。工作量：清 28 错 2–4h + 配置 1h。误伤：E402/F841 大多是管线动态构造风格的副产品，别用默认全量规则上门禁。
- **KAP：GO（现状即门禁）** — tsc --noEmit 2.4s、strict 已开、当前基线 0 错（WIP 期间短暂出现过 TS1192，恰证明门禁价值）。注意 tsconfig 排除了 packages/，三个子项目要各自加 typecheck 进 CI（infinite-canvas/flowgraph-v3 自带 `tsc --noEmit` 脚本）。工作量 1h。误伤：无。

### B4. 类型检查通过

- **KMC：NO-GO（暂缓）** — mypy 实测 **132 错**（Optional 处理类为主：`Item "None" of Any|dict`、`str|None → str` 参数），且管线大量动态构造（phase run() 巨函数 + dict 流转）、无 pyproject 承载配置。硬上门禁 = 先还 132 错债。建议 Phase 2 起对新文件 mypy（增量 `--follow-imports=silent` + per-module strict），总量 ratchet。若要修：抽样看前 10 类错误均为机械修（`assert x is not None` / 类型收窄），估 3–5 人日，但收益低于测试/ruff，排后。
- **KAP：GO** — 就是 B3 的 tsc（strict）。无需另做。唯一补丁：packages/ 三子项目纳入。

### B5. 圈复杂度上限 ≤10

- **KMC：NO-GO（这个数字的硬门禁）** — radon 实测 pipeline/ 732 函数中 **188 个（25.7%）cc>10**；top 违规全是架构性的：p11b_final_render.run cc=115、p10_voice.run cc=112、p11a0_iframe_qc.run cc=103、runner.run_episode cc=97…「一个 phase 一个巨型 run()」就是这套管线的架构风格，拆 188 个函数 = 重写。plugins/ 反而健康（2068 函数仅 5.0% 超），但藏了 cc=204 的 canvas_sync._extract_artifacts（canvas_sync.py:4325，该文件本身就是巨兽）。
- **KAP：NO-GO（同理）** — lizard 实测 3,334 函数 avgCCN 3.7，**9.7%（~335 个）>10**；热点 planGroups cc=213、ingestAssets 匿名函数 cc=176、canvasReducer.reduce cc=115。
- **两仓共同替代方案（GO但降级）**：不做存量上限，做「新函数 ratchet」——radon/lizard 输出当前清单做 baseline，CI 只对**本次 diff 新增/修改的函数**要求 cc≤（KMC 20 / KAP 15，高于均值留余量），并把 top-20 热点列表挂为可视化产物而非失败条件。工作量 3–4h（写 baseline diff 脚本）。这是防恶化的 80/20，不是还债。

### B6. 测试覆盖率下限（增量 ≥70%）

- **KMC：GO但降级** — 实测基线：**pipeline/ 78.3%**（好于直觉，测试资产确实扎实）、plugins/ 14.6%（canvas_sync 巨兽基本裸奔）、合并 42.5%。落地：只对 pipeline/ 设 ratchet（当前 78%，冻结下限，月度 +1pt），plugins/ 不设线只出报告；「增量 ≥70%」用 pytest-cov + diff-cover 对 pipeline/ 生效。工作量 3h。误伤：runner.py 4,350 行的 episode 编排分支靠 e2e mock 覆盖，增量 70% 对纯重构类 commit 可能误伤——允许 `# pragma: no cover` 白名单或对 refactor 类降 50%。
- **KAP：NO-GO（暂缓）** — src 2.4% 文件有测试，谈数字门槛没有意义，先做前置：① 统一 runner（package.json 加 `"test": "node --import tsx --test src/**/*.test.ts"` 或迁 vitest）；② 新代码必测约定（配套 CLAUDE.md 规则，因为多数代码是 agent 写的）；③ 半年后再谈 ratchet。已有测试质量不错（c8 显示被测模块 86.8% stmts、且测试注释里有「防假绿」设计），说明作者会写好测试，缺的是覆盖面不是能力。

### B7. 重复代码率上限

- **KMC：NO-GO（不值得）** — jscpd 实测 **1.20%**（48 clones / 580 行，min-tokens 70）。已经优秀，上门禁的边际收益≈0，还多一个 40s 的 CI 步骤。可选：季度手动跑一次留档。
- **KAP：GO但降级** — jscpd 实测 **7.89%**（234 clones / 4,976 行）。中等偏高（惯例阈值 5% 上下），主要来自路由/验证样板。落地：基线冻结 7.89%（round 到 8%），jscpd 只对新 duplicate 增量报警（`--exitCode` + baseline diff），或降为周检出报告。工作量 2h。全量修复估 2–3 人日且收益一般，不急。

### B8. 文档-代码一致性检查

- **通用自动化（两仓都）NO-GO** — 「接口/参数/配置变了文档必须同步」的全自动检查需要解析 markdown 里的代码引用，误报率会高到把门禁变成静音器。KMC 是 skills(markdown)+python 混合仓，SKILL.md 与代码双维护是固有成本，自动门禁挡不住。
- **KMC 特例 GO但降级**：仓里已经有现成的 `scripts/verify_skill_references.py`（幽灵模型/工具引用检测，专门治「fabricated token 静默上线」，与「假成功」同族），自带 `--strict` exit 1。当前非 strict 模式仍有 findings（如 wan22_video），**先清零再上门禁**，约 2–4h 人工核对。
- **KAP 特例 GO**：~30 个 verify:phase-* 本质就是「接口变更必须同步」的机器化契约（schema-drift、manifest-contract 都是文档/镜像 vs 源码的一致性断言）。抽 3–5 个离线脚本进 CI 即可，其中 verify:manifest-contract 还免费送跨仓（KMC↔KAP）契约保护。工作量 1–2h。
- 替代方案确认有效：两仓 CLAUDE.md/测试注释已经在用「约定 + 契约测试」模式（reviewBridge.test.ts 的「防假绿」注释、test_v50_regression 的套件规模基线），这是比通用文档门禁更符合本生态的做法。

### B9. 依赖漏洞扫描（高危拦截）

- **KMC：NO-GO（暂缓）** — 号称 stdlib-only，无 requirements 文件，pip-audit 无对象。且实测已破约（numpy 函数级 import 等 9 个隐性依赖）。前置动作：把 9 个依赖显性化为 requirements-dev.txt 并锁版本，之后 pip-audit 才有意义。注意：真正要 audit 的其实还有隔壁 hermes-agent 仓（KMC 测试环境 import 它），那不在本次范围。
- **KAP：GO但降级** — 实测 7 漏洞（6 high）。落地要点：① **scheduled 周扫**（cron）而非每 push——audit 依赖外部 registry（本机默认 npmmirror 还不支持 audit 端点，需指官方源），慢且结果随上游 advisory 波动，放 push 路径上会随机红；② 「高危直接拦」要改成「high 且有 fix 才拦」：transformers(*) 和 extract-zip(*) **无修复版本**，硬拦会永久红，只能 allowlist+跟踪；sharp/puppeteer-core/undici 可升级修复；③ playwright 放在 dependencies 里的怪味顺手修（挪 devDeps）。工作量 2h（含 allowlist）。

### B10. 敏感信息泄露检查

- **两仓都 GO（可即刻上线，全绿起步）** — 500 commit 历史 + 工作区实测：无真实密钥。落地：gitleaks（下载被本机网络策略挡了，实测用 trufflehog3 等效）配 `.gitleaksignore`/排除清单（KAP 必须：node_modules/、.venvs/、_hermes_source/、data/web/、packages/*/node_modules；KMC：无特殊），本地 pre-push 跑全量（<30s KMC / 数分钟 KAP——KAP 大，建议只扫 staged diff + nightly 全量）。历史 baseline：无需 rotate、无需 rewrite history（没扫到真东西）；策略 = 现在全绿快照，**只拦新增**。工作量 1–2h。

---

## C. 工具链与运行环境决策

### C1. 拓扑：本地 pre-push 硬拦 + GitHub Actions 兜底（不是二选一）

决定性实证：
1. 迭代模式是**直推 master**（KMC 本地领先 origin 20、KAP 75），不开 PR → 任何 PR 触发的 workflow 不会跑；
2. KAP `debug.yml` 触发分支写的是 main/dev，master push **结构性地永不触发**；`gh run list` 实证 2.5 个月零运行、master 无分支保护（404）；
3. 「CI 只在 GitHub 上跑而开发者从不看 PR」——在这个工作流里答案是**是，形同虚设**，且不是假设，是已发生的事实。

推荐拓扑：
- **本地 pre-push（硬拦层）**：两仓各一条 push 前 3–5 分钟的快速链。批量 commit 模式下 pre-commit 会烦（老司机一轮改 20 个文件commit多次），**pre-push 更贴合**——commit 自由、push 前一次性验。KMC 的 .pre-commit-config.yaml 已有 2 个 hook，补 ruff bug 类 + AST + fast 测试层；KAP 新写 pre-push 脚本（tsc + esbuild + src 单测 + 3 个 verify）。`--no-verify` 逃生口保留（应急），但 CLAUDE.md 写明用了要在 commit message 里登记原因。
- **GitHub Actions（兜底/可见层）**：KAP 新增 `ci.yml`（push master 触发 lint+build+src 单测+离线 verify，~3min），同时**修正或删除 debug.yml 的触发错配**；KMC 的难点见 C2。
- **不做**分支保护强拦（单人直推模式下纯添堵），Actions 失败靠通知（如 commit message 里的 review 登记习惯已在用）。

### C2. KMC 的特殊性：CI runner 选型

KMC 测试对环境有结构性依赖：PYTHONPATH 需要本仓 + **hermes-agent 兄弟仓**（源码级 import tools.registry），且两仓顶层 `plugins/` namespace 冲突要求顺序敏感；9 个 pip 依赖未声明。三条路：
1. **本机 self-hosted runner（推荐起步）**：环境即现有开发环境，零额外工程；代价是「CI 跑在开发机上」的可信度折扣（本地绿≠干净环境绿）。半人日可通。
2. GitHub hosted runner + checkout hermes-agent（私有仓需 PAT/同 org）+ requirements 固定 + conftest 明确 sys.path 顺序：干净、可信，但要先修三雷 + 处理两仓 plugins 冲突（比如给 KMC plugins 加 __init__.py 转 regular package）。估 1–1.5 人日。
3. 只把「环境无关子集」（manifest 三件套 + ruff + AST + verify_skill_references）放 hosted runner，全量留本地。折中，起步最快。

### C3. 运行时长预算（全部实测或推算标注）

| Gate | KMC | KAP |
|---|---|---|
| 语法/构建 | AST 0.4s | tsc 2.4s + esbuild 0.64s |
| Lint | ruff ~1s | （并入 tsc） |
| 快测层 | manifest 三件套 0.81s | src 7 文件 ~2s |
| 全量测试 | 176s（修雷后可全量上 push） | packages vitest「待验证」 |
| verify 契约 | verify_skill_references ~5s | 抽 3 个 ~20s |
| 复杂度基线 diff | radon ~2s | lizard ~30s |
| 重复率 | jscpd ~40s | jscpd ~2min（建议周检） |
| 密扫 staged | <10s | <30s（全量历史另计，nightly） |

**push 前总预算：KMC ≈ 3–4 分钟（含全量 pytest）、KAP ≈ 1 分钟**。都可接受；嫌重就分层（fast 拦 push，slow 进 nightly）。

### C4. 密钥 baseline 策略（实测答案）

两仓 500 commit 窗口**没有放过真 API key**（KMC 2 个 LOW 模板误报；KAP 797 findings 全部 vendored/产物噪音，一方源码零命中）。因此：不需要 history rewrite、不需要 rotate；策略 = 今日全绿快照为 baseline + 排除清单 + 只拦新增。KAP 要注意 data/web/ 打包产物入仓这个习惯本身（bundle 里混入 OAuth token 形状字符串），建议把构建产物移出 git 或加入扫描排除。

---

## D. 分阶段路线图 + 最终建议

### Phase 0（本周，零风险高收益，合计 ~1 人日内每仓）
1. **KAP：新增 ci.yml**（push master：tsc + esbuild→/tmp + src 单测 + verify:schema-drift/manifest-contract/phase-65），~3min。同时改掉或删除 debug.yml 的 main/dev 触发错配。
2. **KAP：修当前 WIP 的 router.ts TS1192**（评估期间已红）。
3. **KMC：`pre-commit install`**（配置文件已存在且合法，装上即激活 manifest 契约三件套 0.81s + bare-except 检查）。
4. **KMC：pre-push 加 ruff bug 类 + AST 语法**（新配置，不碰存量 101 风格错）。
5. **两仓：gitleaks/trufflehog3 + 排除清单**，全绿 baseline，pre-push 拦新增。
6. **KMC：修 test_structured_output.py 自执行**（改名 scripts/ 或删 sys.exit）+ xfail/修复 p11c 真红测试 —— 这两个是测试门禁的前置。

### Phase 1（ratchet 型红线，2–4 周）
- KMC：requirements-dev.txt 显性化 9 依赖；pytest.ini（rootdir/testpaths/pythonpath 固定）；ruff bug 类 28→0 后冻结；pipeline 覆盖率 ratchet 78% 起步（diff-cover 增量 70%）；新函数 cc≤20 ratchet；可选 self-hosted runner 全量 176s。
- KAP：jscpd 冻结 7.89%；packages/ 三子项目 typecheck+vitest 纳入；新函数 cc≤15 ratchet；npm audit 周扫 + allowlist（transformers、extract-zip）+ 升级 sharp/puppeteer-core/undici；统一 `"test"` runner 脚本。
- KMC：verify_skill_references findings 清零后 `--strict` 上门禁。

### Phase 2（高成本项，先论证再动）
- mypy（KMC）：132 错，只对新文件启用，存量不还。**通用文档一致性门禁：不做**，用已有 verify 工具 + CLAUDE.md 约定 + 季度抽查替代——两仓已有的契约测试文化（verify:phase-*、防假绿测试注释）证明这条路在这生态里更有效。
- KMC plugins/ canvas_sync.py（cc=204、7.9K 行级巨兽、14.6% 覆盖）：这是**重构项不是门禁项**，门禁能做的是防止它继续恶化（复杂度 ratchet + 新增逻辑要求带测试）。

### 对「该不该加」的分层回答
- **基础底线（1–4）：该上，两份成本都低到没有理由不加。** KAP 侧甚至已经有全套零件（tsc/esbuild/verify），缺的只是「有人在你 push 时跑它们」。KMC 侧测试资产好到超出预期（78.3% pipeline 覆盖），不上门禁是浪费。
- **质量红线（5–8）：部分该上。** 该上的是 KMC pipeline 覆盖率 ratchet、KAP 重复率冻结、两仓新函数复杂度 ratchet；**不值得的是复杂度硬上限 ≤10（两仓存量 25.7%/9.7%， architectural）和通用文档一致性自动化**（已有 verify 工具是更好答案）。
- **安全防线（9–10）：10 两仓立即上（免费且全绿）；9 只上 KAP、降级为周扫且必须 allowlist 无修复项**；KMC 等依赖显性化之后再谈。
- 最后提醒一个非技术前提：门禁拦的是「批量改码后 commit」的**最后一米**。两仓历史上的「假成功」「delivered=false 桥诚实化」类回归，多数形态是「验证脚本存在但没人跑」——本报告 Phase 0 的全部 6 条都是在激活已有资产，而不是新建检查，这正是最低成本最高命中率的做法。

---

## 附录 1：F1–F8 复核表

| # | Hermes 声称 | 复核结果 |
|---|---|---|
| F1 | KMC pipeline 63 py ~48.5K LOC | ✅ 精确吻合（63 / 48,488） |
| F2 | 227 test_*.py；无 pytest 配置、无 .github、无 CI | ✅ 227 个；收集**不能**干净通过（自执行脚本 INTERNALERROR）；干净基线 2,858（隔离）/2,872（原生口径） |
| F3 | 有 check/verify 脚本 | ✅ 仓根 5 个脚本中 2 个（check_manifest_no_bare_except、verify_skill_references）；注意 skill 内 scripts/ 另有 26 个 py |
| F4 | KAP src 294 ts | ✅ 294 个 / 59,990 LOC |
| F5 | 3 workflow | ✅ 但**均非有效门禁**：debug.yml 触发 main/dev（master 永不触发）、release 仅 tag、integration 仅 PR+路径过滤；2.5 个月零 run 实证 |
| F6 | lint=tsc；build:server=esbuild；~30 verify；playwright 在 deps | ✅ 全对；tsc 2.4s 基线 0 错（WIP 期间出 TS1192）；verify 抽测 3/3 过；playwright ^1.61.1 在 dependencies |
| F7 | src 无单测，Makefile 只测 vendored | ⚠️ **部分不成立**：src/ 有 7 个 *.test.ts（node:test，无统一 runner）；Makefile 只测 vendored 的部分 ✅ |
| F8 | 两仓无 hooks、有 GitHub origin | ✅（且 KMC 有未安装的 .pre-commit-config.yaml；KAP 另有 local remote 指向 /home/kai/workspace） |

## 附录 2：主要实测命令与产出位置
- radon：`~/.local/bin/radon cc pipeline|plugins -j -s` → /tmp/kmc_radon_*.json
- mypy：132 错（--ignore-missing-imports）
- ruff：`ruff check pipeline --statistics`（101 / bug 子集 28）
- jscpd：`npx jscpd … --min-tokens 70`（KMC 1.20% / KAP 7.89%）→ /tmp/jscpd_*/
- lizard（KAP TS）：3,334 函数 avgCCN 3.7，>10 占 9.7%
- trufflehog3：`--depth 500 --no-entropy` → /tmp/th_kmc.json、/tmp/th_kap.json
- KMC 全量+覆盖率：/tmp/covenv（隔离 venv，PYTHONPATH=本仓:hermes-agent）→ 11F/2833P/14S，176.32s；pipeline 78.3% / plugins 14.6%
- KAP：tsc/esbuild/verify/npm audit（/tmp/kap_audit 临时 lockfile，官方 registry）/c8
- KMC 原生抽样：30 文件全绿（p11c 例外单测复跑仍红，为真红）

## 附录 3：评估副作用披露
- 未修改两仓任何被跟踪文件、未 push、未装全局包（radon/mypy/trufflehog3/lizard 经 pipx 至 ~/.local，jscpd/c8 经 npx 缓存，均属任务书允许范围）。
- **KMC 全量 pytest 执行产生了测试自身写出的状态文件变更**（`.pipeline-state.json`、`.planning/.../perf-evidence.json`、`episodes/.../blackboard.json` 等 3–4 个，评估前已有 1 个脏文件）。这是被测管线的副作用，未回滚（回滚可能覆盖并发编辑）。
- 「待验证」清单：KAP packages/ vitest 实际时长；KAP 其余 ~25 个 verify:* 是否全离线；KMC mypy 修复人时；jscpd KAP 全量修复收益。
