ECC 使用指南:装了什么、哪些机制真的在跑、哪些说法别照信
一次 npx 之后,你的 AI 编程助手旁边会多出 292 个技能、68 个专家子代理、24 条钩子、122 个规则文件。这篇回答三件事:它们分别是什么、哪些真的在跑、哪些官方说法我核对不上。
📅 更新于 2026-09-13
本文校对于 affaan-m/ECC @ 2.2.1 · 官方源:github.com/affaan-m/ECC(取数日 2026-09-13)
0030 秒速览:先记住三句话,再按处境挑一条路
读完这一篇,你能做三个判断:这套东西该不该装、装哪一条路、以及哪些功能你以为装上了其实没在跑。下面三句是主心骨,后面每一节都在给它们补细节。
① 它不是帮你写代码的东西,而是给你已经会写代码的助手加一套制度——价值在约束,不在能力。
② 它里面只有一种东西能真的拦住模型,就是钩子(hook);技能和规则都只是「请你遵守」。
③ 它最像卖点的那个功能(让助手越用越懂你)出厂是关着的,而且官方自己承认在原生 Windows 上开了也不干活。
按你现在的处境,直接照这张表走
| 你现在的状态 | 直接做这件事 | 为什么 |
|---|---|---|
| 刚听说它,想先看它长什么样 | 读 01 与 05,别急着装 | 它会往你的配置目录写文件、注册钩子;先知道写了什么再决定 |
| 已经在用 Claude Code,想装上试试 | npx ecc-universal@2.2.1 setup | 官方首选路径,装完还能用同一条命令升级、换作用域(03) |
| 同时用 Claude Code 和 Codex | npx ecc-universal@2.2.1 install --guided | 一次把两边都配好,写盘之前先做预检(03) |
| 不用 Claude Code,用的是 Cursor / Gemini / Kimi 等 | ./install.sh --profile minimal --target <你的助手> | 其余 14 个目标走这条;先 git clone(03) |
| 只想让规范管住某一个仓库 | ./install.sh --profile minimal --target claude-project | 装进项目里的 .claude/,不污染全局(03) |
| 装的动机是「让它自己学我」 | 先读 12 再决定 | 观察器默认关闭;Windows 原生另有未修缺陷 |
| 装完了,但怀疑没生效 | npx ecc-universal@2.2.1 doctor,然后故意撞一次钩子 | 三层验证法在 04 |
| 只想要几个技能,不想装一整套 | --profile minimal 起步,再用 consult 问该加什么 | 292 个技能是「可选项清单」,不是「安装清单」(09) |
最小上手路径:五步,十分钟
通用安装器要 Node.js ≥ 18;Claude Code 插件路径要 Claude Code 命令行 ≥ 2.1.0(原文见 03)。低于这两条,绝大多数「装不上」都不是 bug。
Claude Code 用 npx ecc-universal@2.2.1 setup;别的助手用 ./install.sh --profile minimal --target <目标>。同一个助手不要叠加两种装法——技能、命令、钩子都会变成两份。
npx ecc-universal@2.2.1 doctor 看它认为自己写了哪些文件、钩子配置对不对。
这是唯一能证明「钩子真的在跑」的办法——比如在不是 tmux 的终端里让它起 dev server,看它是否被拦下(完整例子在 04)。
/ecc:plan "给已有项目加上用 OAuth 登录" → 确认或改计划 → 让 tdd-workflow 接管 → /code-review 复核。全过程在 11。
读完你应该能
- 说清它是什么:给你的 AI 编程助手(harness)加装的一套工程制度,由文件、角色和钩子组成,不碰模型本身。
- 选对安装路径:知道四条路各自适用谁,以及为什么同一个助手只能走一条。
- 分清软硬:知道 292 个技能 / 122 个规则是「请求模型遵守」,24 条钩子才是「模型不遵守也得停」。
- 预判最常见的三个翻车点:钩子被装两遍、技能被嵌套安装导致一个都不生效、把「持续学习」当成开箱即用。
- 自己核对官方数字:拿到一组命令,能在 clone 出来的仓库上把 292 / 68 / 94 / 122 / 24 这些数逐个数一遍(19)。
关键数字先给量级
SKILL.md01它到底是什么:不是提示词合集,是装在助手外面的一套制度
先把最容易错的那一步说清楚:ECC 不是「一大包提示词」,也不是某个模型或某个命令行工具。它是一个装在你现有 AI 编程助手旁边的目录集合——装完之后,你的 Claude Code / Codex / Cursor 里会多出一些技能、专家子代理、钩子和规则文件。这里先解释两个马上要用到的词:harness 指承载模型的编程助手外壳(Claude Code、Codex、Cursor、OpenCode 都是),模型指真正生成文字的那部分大脑;ECC 完全工作在 harness 这一层,不训练也不代理模型。
它自己的定位原话是(README.md:127,逐字抄自官方仓库):
Your agent can write code, but ECC gives it a coordinated engineering
system and toolbox: it plans before it builds, verifies changes with tests,
reviews its own work from a fresh context, remembers what matters, and turns
repeated wins into reusable skills and workflows.
换成中文:它补的不是「模型会不会写代码」,而是「模型写完代码之后有没有制度约束」。模型本来就能写代码,问题在于它容易把计划丢在聊天记录里、把测试留到最后、自己审自己的代码、每次会话从零开始。ECC 的做法是把这些环节外化成文件与钩子——计划变成磁盘上的 *.plan.md 文件,测试先变红才有资格改生产代码,复核交给一个新上下文的子代理,质量检查交给钩子而不是靠模型记性。
它不是什么(先做一遍负向定义)
- 不是模型:它不训练、不微调,也不代理你的接口调用。你用哪个模型它不管——官方明确说钩子、技能、命令、规则都与模型供应商无关。
- 不是一堆常驻服务:它曾经捆绑 6 个默认 MCP 连接器,2026 年 6 月审计后砍到只剩 1 个(
chrome-devtools)。MCP 在这里指一种让助手调用外部工具的插件协议,你可以先理解成「给助手插的外设」。现在的 ECC 主体是纯文本与 Node.js 脚本。 - 不是运行时框架:没有常驻进程、没有需要你装进项目的依赖树。安装的本质就是把文件放进你的助手目录。
- 不是只给 Claude Code 的,但也没到「处处功能对齐」:官方支持矩阵里只有 Claude Code 是稳定主力,Cursor / OpenCode 是测试版,GitHub Copilot 只有「指令文本」这一层(矩阵全文在 14)。
ECC 把自己称作 harness 的「操作层」。一个好的对照:模型是一个很能干但记性短、又有点讨好你的工程师;ECC 是贴在墙上的流程看板、门口的闸机,以及一本会自动长出来的团队手册。这个类比到这里就不准了——看板不会自己写内容,而 ECC 里的 instincts 机制确实会把你的纠正写成文件;所以它不是纯被动的东西。
它的全部主张可以压成七个词
这条链在仓库里有一个更短的写法,出现在 README.md:130:
plan -> test -> implement -> review -> verify -> remember -> improve
后面 06 会把这条链逐环拆开,说清每一环由哪个文件、哪个子代理、哪条钩子在真正兜底,以及哪几环其实只是「建议」。这里先记住一件事:ECC 的七成内容是在为这七个词服务,而不是在堆功能。
它的主目录是 ~/.claude(~ 是你在 macOS / Linux 上的用户主目录)或项目里的 .claude/;换一个 harness 就换成对应的目录(Codex 是 ~/.codex,Cursor 是项目里的 .cursor/)。15 个目标的完整对照表在 03。
02三个名字,用错就装不上
这是新手第一天最容易踩的坑,而且官方专门写了一节解释它为什么不统一。三个名字指向同一个项目,但分别用在三个地方,互相不能替换:
| 名字 | 它是什么(这里先解释:市场=助手内建的插件商店,插件标识符=插件名@市场名) | 什么时候用 / 用错会怎样 |
|---|---|---|
affaan-m/ECC |
GitHub 源仓库(也是市场的来源地址) | 用于 git clone 与 /plugin marketplace add https://github.com/affaan-m/ECC。用错:把 npm 包名当地址填,市场加不上。 |
ecc@ecc |
Claude 插件标识符(插件名@市场名,斜杠前面的 ecc 是插件名,后面的 ecc 是市场名) | 用于 /plugin install ecc@ecc 与 enabledPlugins。用错:只写 ecc,或写成旧的长名,安装器会报市场冲突。 |
ecc-universal |
npm 包名(命令行与安装器都在这个包里) | 用于 npx ecc-universal@2.2.1 setup。用错:以为 ecc-install 是一个独立发布的包。 |
官方对「为什么不统一」的解释很实在:npm 那边保持 ecc-universal 不动,是为了让包管理器安装与市场安装故意用不同的名字;插件侧用 ecc@ecc,是为了让工具名与斜杠命令的命名空间短到能通过严格的校验器。
| 你会搜到的说法 | 实际情况 | 对你意味着什么 |
|---|---|---|
npx ecc-install --profile minimal --target claude | 官方 README 明确劝退这条:说 ecc-install 只是 ecc-universal 里的一个二进制名,不是单独发布的包 | 命令里的名字对不上包名,照抄会失败;请改用 npx ecc-universal@2.2.1 … |
仓库 package.json 里有没有 ecc-install | 有:它是一条正式入口,指向 scripts/install-apply.js(实测 2026-09-13) | 所以「劝退」与「仍在提供」并存——这是文档跑得比代码快的典型一处 |
| 旧的超长插件名 | README 说那是遗留别名,只作兼容 | 新写的配置一律用 ecc@ecc |
把三个名字读成一句话:从 GitHub(affaan-m/ECC)装一个 Claude 插件(ecc@ecc),它由 npm 包(ecc-universal)投递。三个名字分别是「来源 / 宿主标识 / 投递方式」,本来就不该长一样。
还有一条关于版本号的口径
官方说明:npm 版本是按版本标签切的,不是按提交切的,所以 ecc-universal 跟的是发布版本(2.1、2.2……),而不是 main 分支上的每一次提交。你要「最新」就用 git 装;要「可复现」就钉死 @2.2.1。这两件事别混(16 的坑 4)。
03怎么装:四条路,每个助手只能选一条
官方在这个问题上罕见地强硬:不要叠加安装方式。原文逐字如下:
**Do not stack install methods.** Installing ECC twice into the same harness
can duplicate skills, commands, hooks, or configuration; installing it once
into multiple harnesses does not.
路一:包管理器向导(Claude Code 首选)
npx ecc-universal@2.2.1 setup
它会先盘点官方市场与每一个原生 Claude 安装作用域(作用域=这份配置只对你个人生效、只对这个项目生效、还是只在当前目录生效),再安装 / 更新 / 迁移 ecc@ecc 到你选的那一档。以后升级、换作用域、改钩子档位,都是重跑同一条命令。
npm view ecc-universal version
pnpm dlx ecc-universal@2.2.1 setup
yarn dlx ecc-universal@2.2.1 setup # 需要 Yarn 2 及以上
bunx ecc-universal@2.2.1 setup
Yarn 1(Classic)没有 dlx 子命令,用 npx 或全局安装,或者升级 Yarn。
官方自己提醒:写死 @2.2.1 只是选定了版本,不是安全审计或完整性校验。要跑包里的代码之前,先看发布源与注册表的完整性——不确定就用一份审过的本地检出,而不是随手 npx。
路二:多助手向导(一次配好 Claude Code + Codex + Kimi)
npx ecc-universal@2.2.1 install --guided
它让你选任意组合,先展示每个目标的安装通道与落地目录,并在第一次写盘之前做预检,最后只问一次总确认。三个目标在向导里的行为并不一样:
| 目标 | 向导里装成什么 | 你要额外知道的 |
|---|---|---|
| Claude Code | 原生 ecc@ecc 插件,带一个作用域(用户 / 项目 / 本地)和一个 ECC 钩子档位 | 作用域选错会导致「有的项目有、有的项目没有」 |
| Codex | Codex 原生的市场 / 插件流程 | 钩子的审查与信任归 Codex 管,ECC 不接管 |
| Kimi Code | 项目里的 ./.kimi-code 受管文件 | 不配置 ECC 钩子、模型 / 供应商设置与认证 |
自动化场景把所有选择显式写出来:
npx ecc-universal@2.2.1 install --guided \\
--harness claude --harness codex --harness kimi \\
--claude-scope local --claude-hooks standard \\
--profile core --yes
想先看不落盘的结果,加 --dry-run:
npx ecc-universal@2.2.1 install --guided --harness codex --dry-run
npx ecc-universal@2.2.1 install --profile core --target kimi --dry-run
按下回车之后,磁盘上到底发生了什么
答案不是「把仓库复制到 ~/.claude」,而是三层结构:① install.sh 自己不装任何东西,它的头注释写着自己只是「旧版入口」,实际动作是把参数交给 scripts/install-apply.js(顺带处理 Windows 路径转换);② manifests/ 里的 JSON 声明「源路径」(实测 37 个模块 / 7 个档位 / 84 个组件),再给每个平台一个适配器,把源路径翻译成「目标路径 + 策略」;③ 装完之后写一份 install-state,记住自己写了哪些文件。
| 搬运策略(实测 5 种) | 它对文件做什么 | 什么时候会遇到 |
|---|---|---|
preserve-relative-path | 整目录保持结构复制 | 最常见,规则与技能目录走这条 |
flatten-copy | 拍平目录、可能改名 | Cursor / Antigravity 把 typescript-security.md 变成 typescript-security.mdc 时 |
merge-json | 合并进已有的 JSON 文件 | 写平台配置时——你原有的键会被保留 |
merge-hook-ids | 按稳定 ID 合并钩子条目 | 写 ~/.claude/settings.json 时;它不是整文件覆盖,所以 ECC 写的那些能被安全卸载,你的设置不被清掉 |
sync-root-children | 同步根目录下的子项 | 少数平台适配器用它补齐根级文件 |
这套设计里最值得记的推论是:卸载只删 install-state 里属于 ECC 的文件(官方原话:"ECC only removes files recorded in its install-state. It does not claim unrelated files in your harness directories.")。反过来也成立——你手抄进 ~/.claude/rules/ 的文件 ECC 不知道也不管,卸载时必须自己删。
选了 Codex 的话,还有一套原生命令
Codex 这一路除了走向导,也可以直接在 Codex 命令行里装(这两条命令是幂等的,重复跑不会出问题):
codex plugin marketplace add affaan-m/ECC
codex plugin add ecc@ecc
codex plugin list --json
node scripts/codex/check-plugin-cache.js
# 以后刷新:先升级市场,再重新 add
codex plugin marketplace upgrade ecc
codex plugin add ecc@ecc
两点差异要记住:Codex 没有 Claude 那套「用户 / 项目 / 本地」作用域(它只存一份启用状态),而且它的原生钩子需要你显式信任,不走 Claude 的四档钩子档位。旧的 scripts/sync-ecc-to-codex.sh 同步流已经降级为兼容选项,只有你确实需要「把配置拷进 ~/.codex 并合并」时才用它。
路三:在 Claude Code 里敲原生插件命令
/plugin marketplace add https://github.com/affaan-m/ECC
/plugin install ecc@ecc
这条路的边界要说清:这两条命令是 Claude Code 自带的,报错也归它管——市场已存在、作用域冲突这类错误 ECC 拦不到,只能自己解决冲突后再试,不要在同一份配置上再叠一次手动安装。
如果你更习惯改配置文件,可以声明式地写进 ~/.claude/settings.json,效果与上面两条命令相同:
{
"extraKnownMarketplaces": {
"ecc": {
"source": { "source": "github", "repo": "affaan-m/ECC" }
}
},
"enabledPlugins": { "ecc@ecc": true }
}
路四:源码 / 手装(其余助手走这条)
先克隆仓库,再按目标选。下面是官方 README 里逐个目标给出的命令(我原样抄下来,你按自己用的那行取一条):
git clone https://github.com/affaan-m/ECC.git
cd ECC
./install.sh --profile minimal --target cursor # 项目里的 .cursor/
./install.sh --profile minimal --target gemini # 项目里的 .gemini/
./install.sh --profile minimal --target zed # 项目里的 .zed/
./install.sh --profile minimal --target antigravity # 落到 .agents/,不是 .antigravity/
./install.sh --profile minimal --target qwen # ~/.qwen/
./install.sh --profile minimal --target hermes # ~/.hermes/
./install.sh --profile minimal --target openclaw # ~/.openclaw/
./install.sh --profile minimal --target kimi # 项目里的 .kimi-code/
./install.sh --profile minimal --target codebuddy # 项目里的 .codebuddy/
./install.sh --profile minimal --target joycode # 项目里的 .joycode/
./install.sh --profile minimal --target opencode # 见下方注意事项
./install.sh --profile full # 完整手装(Claude)
.\\install.ps1 --profile full # Windows 对等物
官方 README 里 OpenCode 的推荐命令是 npm install && npm run build:opencode && ./install.sh --profile full --target opencode --enable-hooks。早期版本的文档漏掉了末尾的 --enable-hooks,而那会撞上硬闸门:full 这个档位包含钩子运行时,只要没同时给 --enable-hooks 或 --no-hooks,安装器就会在写盘之前直接报错停住(源码位置 scripts/lib/install/hook-consent.js)。我核对时(2026-09-13)文档已经补上了这个开关——照现在的 README 抄就能跑通。
装之前先决定:要不要钩子
装钩子这件事是一条同意闸门,不是默认行为。任何会让钩子运行时被装到磁盘上的选择,都必须给出一个明确决定:
# 要钩子:显式打开
./install.sh --target claude --modules hooks-runtime --enable-hooks
# 不要钩子:显式关掉(两种写法等价)
./install.sh --profile core --without baseline:hooks --target claude
./install.sh --profile core --no-hooks --target claude
# 低上下文起步:minimal 档位故意不含钩子运行时
npx ecc-universal@2.2.1 install --profile minimal --target claude
没给这两个开关时,安装器会先把钩子能干什么打印出来,然后停下,不写任何文件。多助手向导会交互式地问你这个选择。
Windows 上的一条对等命令
pwsh -File .\\install.ps1 --target claude --modules hooks-runtime --enable-hooks
Windows 上 Claude 的配置根目录是 %USERPROFILE%\\.claude。
允许与禁止的组合(官方原表)
| 组合 | 结论 | 为什么 |
|---|---|---|
| Claude 插件 + Codex 原生插件 | ✅ 可以 | 两个助手各自独立,互不覆盖 |
| Claude 插件 + Codex 旧同步流 | ✅ 可以 | 旧同步只是兼容层,不碰插件缓存 |
| Claude 插件 + Claude 全量手装 | ❌ 禁止 | 同一个助手里的技能 / 命令 / 钩子会变成两份 |
| Codex 同步 + Codex 市场插件 | ❌ 禁止 | 同一份配置进两条通道 |
装错了怎么退:先诊断,再修,最后才卸
ECC 对「装了两遍」给出的处理顺序不是重装,而是先看它自己认为装了什么:
npx ecc-universal@2.2.1 list-installed # 先看它认为自己装了什么
npx ecc-universal@2.2.1 doctor # 体检
npx ecc-universal@2.2.1 repair # 修(通常不需要重装)
npx ecc-universal@2.2.1 uninstall --dry-run
npx ecc-universal@2.2.1 uninstall
源码检出的对等命令是 node scripts/ecc.js list-installed / doctor / repair / uninstall,直接卸源码那份则用 node scripts/uninstall.js --dry-run 与 node scripts/uninstall.js。--dry-run 是全局旗标(几乎所有子命令都能加),作用是把计划打印出来但不写盘。
如果你确实叠加装过,官方给的清理顺序是四步:先移除 Claude 插件安装,再从装过的那份受管状态所在目录跑卸载命令,然后自己删掉手工拷过、现在不要的规则目录,最后只用一个路径重装一次。
04装完怎么知道它在干活:三层验证,第三层最能说明问题
「装完了」和「在干活」是两件事。区别在于:技能和规则是请模型遵守的建议,模型不理它们你也看不出来;只有钩子是外部程序,它有没有跑,可以用一次故意违规来验证。
第一层:看插件状态
/plugin list ecc@ecc
这一步回答「装上了没有、装在哪个作用域」。如果这里就是空的,后面两层不用看了,回到 03 检查你是不是叠加安装或装错了作用域。
第二层:体检 + 看它认为自己写了什么
npx ecc-universal@2.2.1 list-installed
npx ecc-universal@2.2.1 doctor
list-installed 打印的是它记录的受管文件清单(这份清单的文件名是 install-state,见 05 里的解释);doctor 检查安装状态与钩子配置是否对得上。两者不一致时,先 repair,不要直接重装。
第三层:故意撞一次闸门
这是唯一能证明「钩子真的在跑」的办法,因为它不依赖任何人的自我报告。挑一条已知会被拦的行为,看它是否真的被拦下:
git commit --no-verify。若钩子在跑,会被 block-no-verify.js 以退出码 2 拦下,你会看到阻断信息而不是提交成功。config-protection.js 会拦住对已存在配置文件的修改(第一次创建放行)。[Hook] BLOCKED: Dev server must run in tmux for log access。理由很实在:不在 tmux 里,日志就拿不到(tmux 是一个把终端会话保持在后台的工具)。三条里任一条被拦下,说明钩子这层是活的。三条都没反应,就按 16 的坑 1、坑 2 排查:多半是钩子被装了两遍(反而冲突),或者你装的是 minimal 那种故意不含钩子的档位。
顺手记下装完之后从哪儿看钩子的档位
export ECC_HOOK_PROFILE=standard # off | minimal | standard | strict,默认 standard
export ECC_DISABLED_HOOKS="pre:bash:tmux-reminder,post:edit:typecheck"
export ECC_SESSION_START_MAX_CHARS=4000 # 默认 8000
export ECC_SESSION_RETENTION_DAYS=14 # 默认 30;设 0 / off 表示不清理
export ECC_SESSION_START_CONTEXT=off # 完全关掉会话开始时的附加上下文
这几条环境变量的细节、以及插件里对应的开关(hooks_enabled、hook_profile),在 07 展开。
05装完多了什么:五件套实测盘点
ECC 把自己的内容分成五类。下面每个数字都是我在 2026-09-13 取下的完整仓库文件树上实际数出来的,核对命令一并给出,你可以自己复核:
| 五件套 | 实测数量 | 核对的命令 / 怎么理解它 |
|---|---|---|
| 技能 skills | 292 个目录,292 份 SKILL.md | find skills -mindepth 2 -maxdepth 2 -name SKILL.md | wc -l;目录与文件 1:1、无嵌套,用到才加载 |
| 子代理 agents | 68 个 .md | find agents -maxdepth 1 -name '*.md' | wc -l;可被主代理委托的专家角色 |
| 命令 commands | 94 个 .md | find commands -name '*.md' | wc -l;官方定位是「迁移期的兼容入口」 |
| 钩子 hooks | hooks.json 里 24 条条目 / 7 类事件;scripts/hooks/ 另有 53 个文件 | 用 JSON 解析 hooks.json 逐类累加;钩子是在模型之外强制执行的 |
| 规则 rules | 122 个文件 = 1 份 README + 10 个通用 + 111 个语言 / 框架规则(21 个语言目录) | find rules -type f | wc -l;每次会话都进上下文,所以要少而准 |
schemas/)scripts/hooks/)docs/ 下的文件数先接受一个反直觉的前提:多不是优点
官方路线图原话:"Catalog in this source snapshot: 68 agents, 291 skills, 94 legacy commands. The count is a liability as much as an asset. Overlapping and unreferenced skills exist."——确实存在内容重叠、并且没人引用的技能。所以正确的心态不是「越多越好」,而是把它当仓库用:查目录、按需装、只留自己在用的。
这些数字和官方文档对不上,差在哪
光「有多少个技能」这一个问题,官方同一时期的材料里就有五个答案。我把它们并列出来,因为它示范了这类项目该怎么读文档:
| 出处 | 它写的技能数 | 为什么会有这个数 |
|---|---|---|
README 正文(README.md:139、:144) | 292 | 与仓库当前目录数一致——这是最接近现状的一个 |
README 目录树注释(README.md:797) | 292 | 同一份文件里已同步 |
README 的 2.0.0 版本回顾段(README.md:1663) | 281 | 这是 2.0.0 发布时的历史数字,讲历史却被读成现状最容易误导 |
路线图 docs/ROADMAP.md | 291 | 它的口径是「2.2.1 源码基线」,比 main 分支落后一个技能 |
插件清单 .claude-plugin/plugin.json | 292 | 插件的自我描述,与当前目录一致 |
结论不是「它在骗人」,而是:同一份仓库里同时存在历史数字、发布基线数字和分支现状数字,而它们都长得像「当前值」。所以本文一律用 目录数 作口径——它是唯一能由你自己复现的一种:官方数字随文档更新漂移,而 find | wc -l 不会。这也是 14 那几种说法能站得住的原因:它们全是文件系统的可复核事实,不是观点。
06核心闭环七个环节:哪一环是硬的,哪一环只是建议
plan → test → implement → review → verify → remember → improve 这七个词是 ECC 的骨架。下表把每一环对应到具体文件 / 角色,并标出它是硬的还是软的——这张表能回答很多营销话术回答不了的问题。
| 环节 | 谁在兜底 | 它是硬的还是软的 / 什么时候不适用 |
|---|---|---|
plan 计划 | planner 子代理 + 计划工件(*.plan.md) | 软:靠流程约定,不是钩子拦。适合有设计歧义的任务;一行改动别走这步 |
test 先写测试 | tdd-workflow 技能 + tdd-guide 子代理 | 半硬:技能里的措辞是命令式的("Do not edit production code until…"),但最终仍由模型执行;真正的硬约束得靠你的持续集成(CI) |
implement 实现 | 主代理(或按语言委派的子代理) | 钩子在这里做事后检查(格式 / 类型),拦不住「写错方向」 |
review 复核 | code-reviewer 等 68 个子代理 | 软,但结构性有效:新上下文天然看不到你的自我辩护 |
verify 验证 | verification-loop / eval-harness 技能 | 软:官方路线图自己承认,隔离执行与分级门禁跑目前是关闭的(证据见 19) |
remember 记住 | 记忆钩子 + memory vault | 半硬:会话摘要与状态保存确实由钩子写盘;但「记住的内容有没有用」没人管 |
improve 改进 | instincts → /evolve → 技能 / 命令 / 子代理 | 默认关闭:观察器 enabled: false(见 12) |
「ECC 能不能保证我的代码有测试?」不能。它能做的是:把测试优先写成带证据要求的流程、让复核换一个上下文、并在模型试图改静态检查配置或跳过 git 钩子时物理拦截。真正的强制只能来自你的 CI——把这条说清楚,比任何营销话术都有用。
它还有一条更长的流水(orch-pipeline)
仓库里另有一套更正式的工作流引擎(skills/orch-pipeline/SKILL.md),把上面这条链扩成七个阶段、两个人工闸门:
0 Intake → 1 Research & Reuse → 2 Plan (→ GATE 1) → 3 Scaffold
→ 4 Implement (TDD) → 5 Review → 6 Commit (→ GATE 2)
五个薄封装(orch-add-feature、orch-change-feature、orch-fix-defect、orch-refine-code、orch-build-mvp)按「改动面积 / 新依赖 / 设计歧义」把任务分成 trivial / small / standard / large 四档,再决定跑哪几个阶段——它承认「小改动不该走完整流程」,这比一刀切的流程实用。
07hooks:唯一能物理拦住模型的部件
如果只能记住 ECC 的一个部件,我建议记钩子。原因很直接:技能与规则是「请模型遵守」,钩子是「模型不遵守也得停」。官方定义原文(hooks/README.md):
Hooks are event-driven automations that fire before or after Claude Code tool
executions. They enforce code quality, catch mistakes early, and automate
repetitive checks.
它是怎么回事:模型每动一次手,外面就有人看一眼
钩子不是模型的一部分,而是harness 在调用工具前后去执行的外部程序。这里「工具」指模型能发起的动作——读文件、改文件、执行命令都算。所以钩子能做一件提示词做不到的事:它可以让这次动作失败。这就是「物理」两个字的含义:不是劝,是拦。
实测结构:7 类事件、24 条条目
| 事件 | 条目数 | 它能在什么时候做什么 |
|---|---|---|
PreToolUse(工具调用之前) | 9 | 唯一能阻断的:以退出码 2 拦住这次工具调用 |
Stop(模型回答结束) | 7 | 学习 / 总结类逻辑多挂这里 |
SessionStart / SessionEnd | 2 / 1 | 会话生命周期的两端:加载上下文、保存状态 |
PostToolUse / PostToolUseFailure | 2 / 2 | 只能分析、不能阻断(动作已经执行完了) |
PreCompact(压缩上下文之前) | 1 | 压缩之前抢救状态 |
结构上还有一个细节值得知道:钩子在 hooks.json 里是内联的 node -e "..." 单行脚本,本体只是一层薄壳,真正的逻辑在 scripts/hooks/ 的 53 个文件里。被引用最多的两个入口是转发器 run-with-flags.js(20 次)与 plugin-hook-bootstrap.js(14 次)。
它们到底拦什么:三个真实例子
block-no-verify.js:覆盖 commit / push / merge / cherry-pick / rebase / am 六个子命令,命中 --no-verify 或 -c core.hooksPath= 时退出码 2。(--no-verify 是「跳过 pre-commit 检查直接提交」的旗标——正是模型赶时间时最爱加的那一个。)config-protection.js:eslint / prettier 全家桶在保护名单里,改已存在的配置文件直接阻断,首次创建放行。pre-bash-dev-server-block.js:输出 [Hook] BLOCKED: Dev server must run in tmux for log access——理由很实在:不在 tmux 里,日志就拿不到。设计意图在这些脚本的注释里写得很直白(config-protection.js 开头,逐字):
* Blocks modifications to linter/formatter config files.
* Agents frequently modify these to make checks pass instead of fixing the
actual code. The hook steers the agent back to fixing the source.
翻成中文:模型经常去改静态检查配置来让检查通过,而不是真去修代码——这条钩子就是把这条路堵掉。同理,block-no-verify.js 的存在理由被它自己写在注释里:防止 AI 代理跳过提交前检查的钩子。
四档严格度与开关
插件安装时对应两个选项:hooks_enabled(布尔,默认开)与 hook_profile(默认 standard,非法值安全回退到 standard)。源码检出方式则用环境变量:
export ECC_HOOK_PROFILE=standard # off | minimal | standard | strict
export ECC_DISABLED_HOOKS="pre:bash:tmux-reminder,post:edit:typecheck"
export ECC_SESSION_START_MAX_CHARS=4000 # 默认 8000
export ECC_SESSION_RETENTION_DAYS=14 # 默认 30;0/off 表示不清理会话临时文件
以为钩子是让模型「更自觉」的建议,于是嫌它啰嗦就把 hooks_enabled 关掉,只留技能与规则。
结果:你关掉的恰好是唯一不依赖模型自觉的那层——剩下的全是「请遵守」。
打开 hooks/hooks.json(或插件的 hook_profile 选项)逐条看它拦什么,用 minimal / standard / strict 调严格度,用 ECC_DISABLED_HOOKS 关掉个别条目。
判断依据:官方语义是「四档 + 逐条开关」,不是「开 / 关」两态。
MCP 也要单独管:别一次全开
MCP 在这里指一种让助手调用外部工具的插件协议;每个 MCP 都会把自己的工具清单塞进模型能看到的上下文里,所以它是开销最大的一类插件。官方给的经验线是每个项目 MCP 少于 10 个、活跃工具少于 80 个,并且明确提醒:全开会把 20 万 token 的窗口压到约 7 万。
| 你想做的事 | 用什么 | 边界在哪 |
|---|---|---|
| 临时停掉某个 MCP 服务器 | Claude Code 的 /mcp 命令(选择结果存在 ~/.claude.json) | 这是 Claude Code 自己的开关,不是 ECC 的 |
| 让 ECC 的安装 / 同步流程跳过它自带的那个连接器 | export ECC_DISABLED_MCPS="chrome-devtools" | 它只过滤 ECC 生成的安装与同步配置,不是运行时开关——改了它不会在会话里立刻停掉一个活着的 MCP |
| 给某个项目加 MCP | 从 mcp-configs/mcp-servers.json 拷需要的定义到项目级 .mcp.json | ECC 只默认带 1 个连接器(chrome-devtools),其余都得自己 opt-in |
「ECC 有多少条钩子」为什么没有唯一答案
按 hooks.json 数:24 条条目,引用 23 个脚本。按 scripts/hooks/ 数:53 个文件。真实可执行的钩子数量介于两者之间——取决于你把转发器和共享库算不算;README 与 hooks/README.md 都没有定义口径。遇到别人说「它有 50 多条钩子」,先问一句按什么数。
顺带把「省 token」的那份配置也核一遍
官方建议改 ~/.claude/settings.json 里的三处:
{
"model": "sonnet",
"env": {
"MAX_THINKING_TOKENS": "10000",
"CLAUDE_CODE_SUBAGENT_MODEL": "haiku"
}
}
| 它声称省多少 | 能不能自己验 | 核对结果 |
|---|---|---|
| 思考预算 31,999 → 10,000,隐藏思考成本降约 70% | ✅ 能,纯算术 | (31999−10000)/31999 = 68.75%。说「~70%」略高于实算值,但方向与量级都对——这是这套建议里唯一能独立复现的数字 |
| 模型 opus → sonnet,成本降约 60% | ❌ 不能 | 文档没给推导。真实降幅取决于输入 / 输出比例与当日定价,不是 60% 这个常数;方向没错(便宜模型确实更便宜) |
| 子代理换 haiku,便宜约 80% | ❌ 不能 | 同上,没有推导过程。可验证的部分是它确实生效:68 个子代理里已有 6 个把 model 直接写死在文件里 |
两条比百分比更有用的硬建议:① MCP 是上下文重灾区——每个项目少于 10 个、活跃工具少于 80 个;② 压缩要看时机——strategic-compact 技能建议在逻辑断点上压,并明确列出不要压的时候(实现到一半时压缩,你会丢掉变量名、文件路径和半截状态)。
08agents:把脏活扔出主上下文,只把结论拿回来
一个子代理就是一段带元数据的系统提示 + 一份工具白名单。工具白名单的意思是这个角色只被允许用列出来的那几个动作(比如只许读、不许写)。它解决的问题是上下文被污染:让一个只读文件、只跑测试的角色去干脏活,主代理只拿到结论,省下大量来回。
直接点名,或者让主代理按描述自动委托:
# 直接点名(Claude Code 中的常见写法)
/ecc:plan "Add user authentication with OAuth" # → planner
/code-review # → code-reviewer
/build-fix # → build-error-resolver
一个子代理的定义长这样(agents/code-reviewer.md 开头六行的结构):
---
name: code-reviewer
description: Expert code review specialist. ... MUST BE USED for all code changes.
tools: Read, Grep, Glob, Bash
model: sonnet
---
- 需要新上下文来复核刚写的东西(同一个上下文里既写又审,那是盲区不是复核)。
- 需要按语言 / 领域分工:仓库里有
go-reviewer、python-reviewer、rust-build-resolver、harmonyos-app-resolver、mle-reviewer这类专门角色。 - 想让某类活跑在便宜模型上:68 个子代理的
model字段分布是 sonnet 58 / haiku 6 / opus 4。
name/description/model/tools四个字段是 68/68 全都有的(即事实上的必填),color只有 5 个有。- 每个子代理正文开头都带同一段
## Prompt Defense Baseline:不许改身份、不许泄密、把 unicode 与零宽字符当可疑输入。这是提示层的防注入,不是沙箱(见 19 的证据边界)。 - 委托不是免费的:每个子代理都开一个新上下文,消耗是独立计费的。简单顺序任务用子代理反而更贵。
它还带一个社区工具桥:multi-* 命令与 ccg-workflow
仓库里有五条名字带 multi- 的命令:/multi-plan、/multi-execute、/multi-backend、/multi-frontend、/multi-workflow。它们不在基础安装范围内——要让它们跑起来,你得另外装第三方运行时 ccg-workflow 并初始化它,这些命令依赖的外部文件包括 ~/.claude/bin/codeagent-wrapper 与 ~/.claude/.ccg/prompts/*。
# multi-* 五条命令的前置:必须另外装并初始化 ccg-workflow(上游安装指南在 README 里给了链接)
# 缺少它时,这五条命令不会正确运行
ls ~/.claude/bin/codeagent-wrapper ~/.claude/.ccg/prompts/ # 自查这两个外部依赖在不在
README 明确写:选择并审阅一个确切的发布版本再初始化,ECC 既不捆绑 CCG,也不声明某个版本与之兼容或经过审计。所以这五条命令属于「你自己评估后再用」,缺了运行时它们跑不对。
注意 code-reviewer 的工具是 Read, Grep, Glob, Bash——没有 Edit、没有 Write。这不是随手写的:一个只能读的复核者没法「顺手改一下让它通过」。挑子代理时先看这一行,比看描述有用。
09skills:默认工作流面,但 292 个不是安装清单
skills/。一个技能 = 一份会被按需加载的指令包。跟规则的差别全在成本模型上:规则是每次会话都进上下文(所以它只有 122 个文件、还得按语言挑),技能是用到才进(所以能堆 292 个)。这里「上下文」可以理解成模型能同时记住的内容总量——塞满了它就会丢前面的东西,这就是这两类内容数量差一个数量级的原因。
# 方式一:让模型按 description 自己选(推荐,默认就是这样)
# 方式二:手动点名一个技能目录
./install.sh --target claude --skills tdd-workflow,security-review
# 方式三:先问顾问该装哪些
node scripts/ecc.js consult "security reviews" --target claude
# 按能力装(2.2 新增的写法)
node scripts/ecc.js install --profile minimal --target claude --with capability:machine-learning
tdd-workflow——测试优先主流程,含计划交接、RED 闸门、Git 检查点、证据报告。security-review——安全清单,用FAIL: NEVER Do This/PASS: ALWAYS Do This成对呈现。configure-ecc——装完之后的重新配置向导(注意:它只能在装好之后用,不能替代第一次安装)。
- 技能头部字段出现频次实测:
name292、description292、metadata265、license18…… 也就是说事实上只有name+description强制,其余全可选。 - 往
~/.claude/skills/手装时不要嵌套:Claude Code 只发现直接子目录,把技能放进~/.claude/skills/ecc/下面它扫不到(README 专门用注释写了这一条)。 - 292 个技能里官方自己承认存在重叠与无人引用的情况——别把整个目录当默认选项。
「按语言精确装」这个粒度目前是假的
官方文档建议用 --with lang:python 这样按语言装。但清单文件 manifests/install-components.json 里,19 个语言 / 框架组件的 modules 字段全都指向同一个 framework-language 模块——它们的描述里自己写着 "Currently resolves through the shared framework-language module"。
| 你敲的组件 | 它实际装进来的模块 | 所以会发生什么 |
|---|---|---|
lang:typescript / lang:python / lang:go / lang:java / lang:cpp / lang:c / lang:csharp / lang:fsharp / lang:rust / lang:kotlin / lang:perl / lang:ruby / lang:arkts | framework-language(同一个) | 装哪个语言,结果都一样——精确按语言裁剪这件事目前做不到 |
framework:angular / react / vue / nextjs / django / springboot | framework-language(同一个) | 同上;quarkus 额外挂 security |
lang:swift | swift-apple(已独立) | 这是少数已经拆开的例外 |
# 这两条命令装出来的东西是一样的——不是 bug,是清单还没拆开
./install.sh --profile minimal --target claude --with lang:python
./install.sh --profile minimal --target claude --with lang:typescript
少数例外已经开始拆:lang:swift 指向独立的 swift-apple,framework:quarkus、lang:perl、lang:ruby、framework:rails、framework:laravel 额外挂了 security。结论:别指望用 --with lang:* 做精确裁剪,要精确就用 --skills 点名。
10rules:总是占着上下文,而且插件给不了你
规则是总是加载的标准——这是它与技能最本质的差别,也是它数量少一个数量级的原因(122 vs 292)。结构很规整:
| 目录 | 文件数 | 什么时候用 / 注意什么 |
|---|---|---|
rules/common/ | 10 | 语言无关的通用原则,建议永远装上:agents.md、code-review.md、coding-style.md、development-workflow.md、git-workflow.md、hooks.md、patterns.md、performance.md、security.md、testing.md |
| 21 个语言 / 框架目录 | 111 | 按你的技术栈只挑一个:angular、arkts、cpp、csharp、dart、fsharp、golang、java、kotlin、nuxt、perl、php、python、react、react-native、ruby、rust、swift、typescript、vue、web |
rules/README.md | 1 | 结构与安装说明 |
每个语言目录通常是 5 个文件(coding-style / hooks / patterns / security / testing),例外是 python(6)、web(7)、react-native(8)。
官方原话:"Claude Code plugins cannot distribute rules, so add only the rule packs you actually want." 也就是说:装了插件 ≠ 有了规则,规则必须自己拷:
git clone https://github.com/affaan-m/ECC.git
cd ECC
mkdir -p ~/.claude/rules/ecc
cp -R rules/common ~/.claude/rules/ecc/
cp -R rules/typescript ~/.claude/rules/ecc/ # 换成你自己的技术栈
而这条手动路径有个必须记住的后果:这些文件不在 install-state 里,卸载 ECC 不会替你删。官方只说「只删它自己记录的」。
只想管住一个仓库:把规则拷进项目
cd your-project
mkdir -p .claude/rules/ecc
cp -R /path/to/ECC/rules/common .claude/rules/ecc/
cp -R /path/to/ECC/rules/typescript .claude/rules/ecc/
手动拷技能与命令(不想走安装器时)
每个组件都被设计成互相独立,所以你也可以只拷自己要的那一块:
# 只拷 agents
cp agents/*.md ~/.claude/agents/
# 技能:Claude Code 只发现 ~/.claude/skills 的直接子目录,所以不要嵌套
mkdir -p ~/.claude/skills
cp -r .agents/skills/* ~/.claude/skills/
cp -r skills/search-first ~/.claude/skills/
# 命令(迁移期的斜杠入口兼容层,可选)
mkdir -p ~/.claude/commands
cp commands/*.md ~/.claude/commands/
手动拷贝时的一条硬规矩
官方专门写了一条:拷整个语言目录,不要拷目录里的单个文件,否则相对引用会断、文件名会撞。这条看起来琐碎,但它解释了为什么 rules/ 的单位是「目录」而不是「文件」。而且因为规则是每次都吃上下文的常驻成本,官方建议从 common 加一个你真正在用的包开始,别一口气全拷。
11最小例子:给已有项目加「用 OAuth 登录」
不讲概念了,走一遍最小可用流程。场景:你有一个已有项目,要加一个 OAuth 登录(OAuth 是一种「不把密码交给第三方、而是跳转去授权」的登录方式)。ECC 装好了,钩子是 standard 档。
/ecc:plan "Add user authentication with OAuth" → 由 planner 产出一份实现蓝图,落到磁盘上成为可编辑的工件,而不是留在聊天记录里。官方对这一点给的理由是一句对照:"Plans disappear into chat history" 对 "Plans become editable artifacts before implementation starts"。
由 tdd-guide 接手,先写一个会失败的测试。这一步的规矩是硬的,技能原文:
Do not edit production code until this RED state is confirmed.
它甚至预先堵了一个很常见的借口:"Do not treat the plan as permission to skip TDD. The plan supplies intent and task structure; the RED/GREEN cycle supplies proof."——计划不是免测通行证。
只写让测试通过的最少代码。此时 PostToolUse 那类钩子会在你编辑文件之后跑格式 / 类型检查(只能提醒,不能阻断,因为文件已经改完了)。
/code-review → code-reviewer 带着 Read, Grep, Glob, Bash 进来找回归与盲区。它不是同一个上下文,这正是它能看出问题的原因。
会话结束时,学习链会把「你纠正过的做法」写成一条 instinct(见 12)。注意:这条链开箱是关闭的,你得先开。
这条流程在官方文档里有一段一模一样的流水,可以直接对照:
/ecc:plan "Add usage-based billing alerts"
-> confirm or edit the plan
-> activate tdd-workflow
-> capture RED evidence before implementation
-> implement until GREEN
-> review from fresh context
-> fix findings with regression tests
-> verify build, lint, types, and tests
不是写测试,是「capture RED evidence」——把「测试确实红过」留下证据。因为「我写了测试」和「测试真的先失败过」是两回事:只有后者能证明测试测的是新行为,而不是被实现牵着写出来的(写完代码再补一个必然通过的测试,是模型最常见的偷懒方式)。
同一件事的入口速查:你现在想干什么
| 你想做的事 | 敲这个 | 背后是谁在干 |
|---|---|---|
| 给新功能写计划 | /ecc:plan "Add auth" | planner 子代理 |
| 设计系统架构 | /ecc:plan + 架构子代理 | architect |
| 测试优先地写代码 | 技能 tdd-workflow | tdd-guide |
| 复核刚写的代码 | /code-review | code-reviewer(只读工具) |
| 修一个失败的构建 | /build-fix | build-error-resolver |
| 跑端到端测试 | 技能 e2e-testing | e2e-runner |
| 找安全漏洞 | /security-scan | security-reviewer |
| 删掉没人用的代码 | /refactor-clean | refactor-cleaner |
| 更新文档 | /update-docs | doc-updater |
| 看上下文压力 | /context-budget | 上下文预算顾问 |
| 结束一个长会话 | /save-session 或 /learn-eval | 会话保存钩子 |
| 下次接着做 | /resume-session | 会话恢复 |
| 审计自己这套 agent 配置 | /security-scan,或已安装的 agentshield scan --path . | AgentShield(独立包) |
插件的命令用带命名空间的形式(/ecc:plan);手动安装有时会暴露更短的兼容形式(/plan)。不确定装了哪些,用 /plugin list ecc@ecc 看。
12instincts:把你纠正过它一次,变成下次自动生效
这是 ECC 最有辨识度、也最容易被误解的机制。先说结论:它设计得很讲究,但开箱是关闭的,而且文档里 v1 / v2 两代并存。三层都讲清。
instinct 可以直译成「本能」:它不是规则、也不是技能,而是一条带置信度的小行为约定,由系统在你干活的过程中观察出来、写上置信度、下次会话开始时按置信度挑几条塞进上下文。
一条 instinct 长什么样
它是「一段元数据 + 一段正文」,正文里必须有 ## Action(没有的话会在注入阶段被丢掉)。下面是仓库里唯一一份真实数据文件中的一条(逐字):
---
id: everything-claude-code-conventional-commits
trigger: "when making a commit in everything-claude-code"
confidence: 0.9
domain: git
source: repo-curation
source_repo: affaan-m/everything-claude-code
---
# Everything Claude Code Conventional Commits
## Action
Use conventional commit prefixes such as `feat:`, `fix:`, `docs:`, `test:`,
`chore:`, and `refactor:`.
## Evidence
- Mainline history consistently uses conventional commit subjects.
- Release and changelog automation expect readable commit categorization.
这个文件里一共 8 条 instinct(按行首的 id: 数就是 8):领域分布是 workflow ×4、git ×2、code-style ×1、testing ×1,置信度区间 0.8–0.9。但有一条很关键:8 条全部是 source: repo-curation——也就是人工写的,不是「会话里学出来的」。这一点值得单独记住,因为它说明了这个机制的现实形态。
闭环四步
四个步骤的关键参数(都能在 README 的环境变量表里核对):
- 注入阈值:
confidence ≥ 0.7(环境变量ECC_INSTINCT_CONFIDENCE_THRESHOLD),最多注入 6 条(ECC_MAX_INJECTED_INSTINCTS),且只注入## Action的第一行——为了省上下文。 - 排序不是纯置信度:分数 = 置信度 + 加成,项目作用域加、技术栈命中也加。注释里给了理由:这样「本项目 0.7 的本能」能压过「别处 0.9 的无关本能」。可用
ECC_INSTINCT_RELEVANCE_RANKING=off关掉。 - 置信度怎么涨跌(观察者角色定义里的原文数值):观察 1–2 次给 0.3、3–5 次 0.5、6–10 次 0.7、11 次以上 0.85;此后每次确认 +0.05、被反驳 −0.1、每周没被观察到衰减 −0.02。
- 项目隔离:v2.1 起 instinct 默认项目作用域,存到
${XDG_DATA_HOME:-~/.local/share}/ecc-homunculus/projects/<项目哈希>/;只有在两个以上项目里都出现、且均值 ≥ 0.8 时才通过/promote升为全局。待定状态的 instinct 还有 30 天保质期。
skills/continuous-learning-v2/config.json 里是 "observer": { "enabled": false }——「持续学习」默认不运行(我 2026-09-13 核对,仍是 false)。要它工作,你得显式打开观察器。
更值得知道的是平台差异:官方支持矩阵里写明,原生 Windows 上 continuous-learning v2 的观察者守护进程与 memory-vault 写入有未修缺陷(挂着 issue #2489 与 #2626),而技能文档自己承认在原生 Windows 上把 observer.enabled 设成 true 实际是 no-op——进程会随钩子退出被杀掉。也就是说:这个卖点在两个主流平台上分别是「默认关」和「开了也不工作」。
v1 的实现(挂 Stop 钩子、产物是完整技能、落到 ~/.claude/skills/learned/)已于 2026-04-28 标记 DEPRECATED,它的 SKILL.md 里甚至写着 "Do not invoke v1"——但目录、配置、脚本全部还在,README 的能力清单里也仍把它和 v2 并列。另外,v2 文档里留了一句解释它为什么要改用钩子:"v1 relied on skills to observe. Skills are probabilistic -- they fire ~50-80% of the time based on Claude's judgment."——技能是概率性的,钩子是 100% 触发的。
导出端定义的规范字段是 9 个(id, trigger, confidence, domain, source, scope, project_id, project_name, source_repo);但仓库里那份唯一真实数据文件的 8 条全都没有 scope / project_id / project_name(它还是 v2.1 之前的格式)。另外 commands/evolve.md、commands/instinct-status.md 里的存储路径仍写着旧的 ~/.claude/homunculus/,而代码解析的现行路径已经是 ~/.local/share/ecc-homunculus/——照着旧文档去 ls 会找不到文件。
13memory:一份「是背景资料、不是指令」的记忆库
ECC 里有两套记忆,第二套是 memory vault(可以理解成「一个只往里存事实、不往里存命令的档案柜」)。它和 instincts 的分工可以一句话概括:instincts 记「怎么做事」,memory 记「发生了什么、决定了什么」。设计文档自己用的说法(docs/design/ecc-memory-vault.md,逐字):
- A memory is context, not an instruction.
| 维度 | instincts | memory vault | 为什么要分清 |
|---|---|---|---|
| 存储位置 | …/ecc-homunculus/instincts/** | <仓库>/.ecc/memory/**、~/.ecc/memory/** | 备份 / 清理策略完全不同:一个在用户目录,一个在仓库里 |
| 格式 | 元数据 + ## Action,一个文件可多条 | 一文件一条,格式标识 ecc.memory.v1 | instinct 便于批量策展,memory 便于逐条检索 |
| 信任状态 | 按 confidence 数值决定是否注入 | 只有 unreviewed 一个取值(未复核) | 没有「已审阅」这个状态,意味着没有任何东西会被自动当成规则 |
| 能否晋升 | 能:/evolve 成技能,/promote 成全局 | 不能:它对外只暴露读写接口,没有复核 / 晋升工具 | 这是两者最根本的差别,也是官方刻意的设计取舍 |
其余约束:记忆种类 8 种(context / decision / fact / handoff / lesson / note / preference / runbook),作用域 3 种(project / team / user,默认检索只覆盖 project + team),状态 3 种(active / rejected / superseded)。写入前会跑 10 条密钥正则(OpenAI sk-、Stripe、npm、HuggingFace、GitHub gh[pors]_、Google AIza、Slack xox*、AWS AKIA/ASIA、PEM 私钥)——命中就拒绝写入。正则在这里就是「按模式匹配的一段规则」,你可以理解成查重用的模板。
MCP 在这里的角色:只是一个读写口,不是通道
scripts/memory-mcp.mjs 是一个手写的标准输入输出服务(669 行、零框架),只暴露 4 个工具:memory_save、memory_search、memory_read、memory_doctor。设计文档用一句话锁死了它的边界:"It has no review or promotion tool."
还有一条实用信息:它默认不启用——根目录 .mcp.json 只声明了 chrome-devtools 一个,而 mcp-configs/mcp-servers.json 里那一条的说明直接写着 Not enabled by default.(我 2026-09-13 核对,两处都仍是如此)。
instincts 可以变成规则(会自动影响模型行为),memory 永远只是「被检索出来的背景资料」。把「能自我修改行为的东西」和「只提供事实的东西」分成两套,并给前者加置信度与晋升闸门——这是 ECC 里少见的、值得直接抄走的设计。
14四种说法我核对不上,实测是什么
这一节示范怎么用可复核的方式检验一个项目的宣称:把文档里的每个说法都拿去仓库或注册表里数一遍。八条旧发现逐条重核后,四条仍然成立,四条已修掉或换了形态。
仍然对不上的四条
第 4 条牵涉它最核心的一条自述,所以我把官方原文逐字抄在这里,你可以直接对着看:
The root is the source of truth. Platform adapters package or map these same
workflows instead of maintaining separate copies.
| # | 文档说 | 实测(2026-09-13) |
|---|---|---|
| 1 | 同一个项目的技能数有多个版本:README 正文与目录树写 292;2.0.0 回顾段写 281;路线图写 291 | 实际 skills/*/SKILL.md = 292。三个数字并非版本差异能解释:281 是历史段、291 是发布基线、292 是分支现状,它们在这份仓库里同时存在,而且都长得像「当前值」 |
| 2 | README 表里的 Cursor:钩子事件 15、规则 34(9 通用 + 25 语言);另一处还写 Cursor 子代理 48 | 实测 .cursor/rules/ = 39 个文件(9 通用 + 30 语言,多出 kotlin 一整组 5 个文件)——规则数确实对不上;事件数 15 是对的(.cursor/hooks.json 里就是 15 类);而 .cursor/agents/ecc-*.md 那 48 个子代理在仓库里找不到产物,只能标「未能确认」 |
| 3 | Codex 表:MCP 服务器 6 个(GitHub、Context7、Exa、Memory、Playwright、Sequential Thinking);.agents/skills/ 有 32 个技能 |
.mcp.json 只有 1 个(chrome-devtools)——变更日志 2.2.0 明说其余 6 个已在 2026 年 6 月审计后退役;.agents/skills/ 实测 39 个目录。照那张表去准备 6 个 MCP 的密钥,是白做工 |
| 4 | README 说「仓库根是唯一真相源,平台适配器只是打包 / 映射同一批工作流,不维护各自的副本」 | 机制上确实如此(我实测:一份 rules/<语言>/security.md 会被 15 个适配器各自翻译落盘)。但仓库里同时检入了手工维护的分叉副本:.agents/skills/ 39 个、.cursor/skills/ 11 个、.cursor/rules/ 39 个,它们与源不一致,且不在安装器的产出路径上。正确说法是:机制一源,仓库两份真相 |
已经修掉或换了形态的四条
| # | 旧版记的问题 | 现状 |
|---|---|---|
| 5 | README 里的 OpenCode 安装命令缺钩子开关,会撞硬闸门报错 | 已补:现行命令末尾带 --enable-hooks。硬闸门本身没变——没给 --enable-hooks / --no-hooks 仍然会在写盘前停住 |
| 6 | README 推荐 npx ecc-install … 而它与劝退说明冲突 | 仍然并存:劝退段落还在,package.json 里 ecc-install 也仍是正式入口(指向 scripts/install-apply.js)。只是它现在不算「当前推荐写法」,所有推荐命令都改用了 ecc-universal@2.2.1 |
| 7 | 发布说明写的状态比注册表落后(仓库说「进行中」,注册表已经发布) | 依旧:注册表 latest = 2.2.1,发布于 2026-09-08;而 docs/releases/2.2.1/patch-execution.md 第 3 行仍写 "Status: in progress, 2026-09-07"。想知道到底发了哪个版本,查注册表比读仓库文档可靠 |
| 8 | 同一份 token 建议,README 片段有 3 个环境变量、配套文档只有 2 个 | 依旧:README 的 JSON 含 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE,docs/token-optimization.md 不含;后者还留着一条社区注记说这个覆盖值可能只能调低阈值(即可能反而更早压缩),建议改用人工 /compact。README 推荐它,官方文档怀疑它——以文档里的注记为准更安全 |
这些不一致不说明 ECC 是骗局——恰恰相反,官方路线图自己写着「数量既是资产也是负债」「有重叠和无人引用的技能」,发布说明也主动记录未修缺陷与 issue 号。真正的问题是文档规模跑得比维护速度更快(README 2,012 行、8 种语言的翻译),于是同一份文档里留下了不同时代的数字。对你的实际做法是:仓库里的文件比文档里的数字可信;要哪个数字,自己数。
把这四条自己验一遍的命令
git clone --depth 1 https://github.com/affaan-m/ECC.git && cd ECC
# 1) 技能数:数目录,不数文档里的字
find skills -mindepth 2 -maxdepth 2 -name SKILL.md | wc -l
# 2) Cursor 三个数:规则文件、钩子事件、有没有 48 个子代理
find .cursor/rules -type f | wc -l
python3 -c "import json;print(sorted(json.load(open('.cursor/hooks.json'))['hooks']))"
find .cursor -name '*agent*' | wc -l
# 3) MCP 与 .agents/skills 的真实数量
python3 -c "import json;print(list(json.load(open('.mcp.json'))['mcpServers']))"
find .agents/skills -name SKILL.md | wc -l
# 4) 「不维护副本」是否成立:源与副本逐目录比对
for d in .agents/skills/*/; do n=$(basename $d); diff -q "$d/SKILL.md" "skills/$n/SKILL.md" >/dev/null 2>&1 || echo "不同: $n"; done
# 5) 版本:注册表才是事实
npm view ecc-universal version time.2.2.1
15安全:它把自己当攻击面,也承认自己不是沙箱
ECC 的安全观有一句很像样的话(官方 README,逐字):
Hooks can run shell commands, MCP servers can hold credentials, and project
instructions can enter an agent's context. Treat all three as executable
configuration.
中文:钩子会执行系统命令、MCP 服务器会存凭据、项目说明会进上下文——这三样都应当当成「可执行配置」对待。这句话的意思是:装了 ECC 之后,你机器上多了一份会被执行的配置,它和代码一样需要被审视。
它提供了四层防线,但只有一层能真的拦
| 真实的控制(实测) | 在哪一层生效 | 它的实际强度 |
|---|---|---|
| GateGuard(破坏性命令门禁) | 钩子层,命令执行前 | 硬:能直接阻断。rm、强制 / 带路径的 git checkout、破坏性 find -exec;2.2.1 补上了破坏性 PowerShell 命令的识别,以及「用变量赋值掩盖未解析调用」这类绕过手法 |
供应链 IOC 扫描(scripts/ci/scan-supply-chain-iocs.js;IOC=「已发现的入侵痕迹」这类特征标记) | 持续集成层 | 中等:它是定点检查而非全仓扫描(跳过 docs、tests,只放行有限的依赖文件名)。作用是盯住几个高危落点 |
Unicode 安全检查(scripts/ci/check-unicode-safety.js) | 持续集成层 | 这是唯一真正针对「提示注入 / 同形字走私」的检测:显式覆盖零宽字符与 Hangul filler(U+115F / U+1160 / U+3164)这类常被滥用的码位。(同形字=长得一模一样但编码不同的字符,用来骗过人和工具。) |
| memory vault 写入前的字符校验 | 写入时 | 硬:正文含控制字符或双向格式字符直接抛错,写不进去 |
三处「看着像控制、其实不是」
- 仓库里有
.gitleaksignore,但没有任何流程调用 gitleaks。(gitleaks 是一个扫描仓库、防止把密钥误提交进去的工具。)我实测:.github/workflows/下 12 个 workflow、scripts/与package.json里对gitleaks的引用是零;那份 ignore 文件里只有一条「文档中的示例 API key」的豁免。它是一份没人执行的文件——就密钥扫描这件事,别把它算进 ECC 的能力。 - 提示层的防注入是散文,不是机制。
CLAUDE.md的 Prompt Defense Baseline(把 unicode、同形字、不可见字符、紧急感、权威声明,以及用户提供的工具或文档内容里夹带的指令都当可疑)写得确实到位,68 个子代理里也各带一份;但它的效力完全取决于模型是否遵守——这正是钩子存在的理由,也是这一层不该被当成防线的原因。 the-security-guide.md是一篇引用外部研究的科普长文,不是实现文档。想判断「ECC 到底防住了什么」,读代码比读它有用。
它自己对「安全工作」的定义很克制,这点值得学
关于 AgentShield 这个扫描器的运行器来源,官方写了一段罕见的诚实说明:这些命令要求你已经装好并审阅过的 AgentShield 二进制;要记录你选的版本、审阅过的源码与校验过的包完整性;仅仅「发在包注册表上」不等于经过审计,而且官方明说 "ECC does not supply an audited AgentShield pin here"——它不在这里给你一个已审计的版本锚点,也别用不带版本号的一次性下载代替。
漏洞响应流程也给的是具体承诺(SECURITY.md):48 小时内确认、7 天内初步评估、影响受支持版本且跨真实信任边界时 14 天内给出关键修复或缓解;并明确要求报告里写清「利用是否需要本地 shell、恶意仓库、恶意包、远程未认证攻击者,还是维护者凭据」——按攻击路径分类,而不是笼统说「有安全问题」。
这一点必须原样引用,因为它是理解整条验证链的关键。官方路线图在讲评估框架时写道(逐字):
Candidate execution and staged gate runs are disabled: no actual OS
containment exists. Offline validation and a receipt signature do not
establish safe execution or promotion authority.
中文:候选执行与分级门禁跑是关闭的,没有真正的操作系统级隔离;离线校验与回执签名都不能证明执行安全或拥有晋级权限。换句话说,ECC 的钩子与门禁是流程层的护栏,不是沙箱——一个足够复杂或恶意的仓库仍然可以在你的机器上做它能做的事。
「装了带钩子的 ECC,所以让 agent 直接跑陌生仓库里的脚本也没关系。」
问题:钩子拦的是已知模式(rm、--no-verify、改静态检查配置),不是能力隔离。官方明说没有操作系统级隔离。
用 ECC 的钩子减少低级事故(绕过 git 钩子、偷改配置、乱删文件),同时用真正的隔离兜底:容器 / 虚拟机跑陌生代码,密钥不进环境变量,AgentShield 只当「额外一双眼睛」而且版本要自己审。
判断依据:SECURITY.md 的信任边界分类 + 路线图的 containment 声明。
16八个坑,每个都给改法
坑 1:叠加安装方式
理由通常是「怕插件装得不全」。结果是技能 / 命令 / 钩子各来两份,钩子被触发两次,还会出现跨平台的钩子冲突。
Claude Code 就一条;想同时用 Codex,那是另一个助手,允许并行。已经叠了就先诊断,而不是重装:list-installed → doctor → repair。
坑 2:插件装完再把钩子抄进 settings.json
hooks/hooks.jsonClaude Code 2.1+ 会自动加载插件里的钩子文件,抄第二份就是重复执行。仓库自己那份插件清单也故意不写 hooks 字段——写了会触发「检测到重复钩子文件」。
要手装钩子就用 bash ./install.sh --target claude --modules hooks-runtime --enable-hooks——它会把命令路径改写正确,并按稳定 ID 合并进 ~/.claude/settings.json。仓库根那份 hooks/hooks.json 是给插件 / 仓库用的,不是给你抄的。
坑 3:把技能嵌套安装
~/.claude/skills/ecc/ 这个写法是错的
Claude Code 只发现 ~/.claude/skills/ 的直接子目录。把技能放进 skills/ecc/ 里它扫不到——你会以为「装了 292 个技能却一个都没生效」。正确做法是拷进 ~/.claude/skills/<技能名>/。
坑 4:指望「持续学习」开箱可用
如果你买的是「它会自己越用越懂我」这个概念:先看 skills/continuous-learning-v2/config.json 里的 enabled: false,再看平台矩阵里 Windows 原生的两条未修缺陷(#2489、#2626)。它设计得不错,但默认不跑。
坑 5:把仓库根当成发布版
官方原话:npm 版本按版本标签切,不是按提交切,所以 main 上会有版本号里没有的东西。你要「最新」就 clone main;要「可复现」就钉死 @2.2.1。我这次取数就撞上了这件事:main 上技能目录是 292 个,而路线图里记的发布基线是 291 个。
坑 6:拿别人的技能数字当自己该装的量
官方路线图承认存在重叠与无人引用的技能。正确做法是先用 consult 顾问问、再 --profile minimal 起步、按需用 --skills 加。
坑 7:把 ECC 当沙箱
钩子拦的是已知模式(rm、--no-verify、改静态检查配置),不是能力隔离。官方路线图明说没有真正的操作系统级隔离。
用钩子减少低级事故,同时用真正的隔离兜底:容器 / 虚拟机跑陌生代码,密钥不进环境变量,AgentShield 只当「额外一双眼睛」而且版本要自己审。
坑 8:以为「支持很多助手」等于功能等价
Claude Code 是稳定主力;Codex 有原生插件但钩子要你显式信任、且不用 Claude 那套档位;Cursor / OpenCode 是测试版;Copilot 只有指令文本,没有钩子、没有运行时子代理、没有技能发现。在最后一档上,它对你就是「一份可读的工程规范」。完整矩阵见 04 与官方 README 的 Platform Support 一节。
八个坑速查:症状 → 真因 → 改法
| 你看到的现象 | 真因 | 一句话改法 |
|---|---|---|
| 钩子触发两次 / 报跨平台钩子冲突 | 坑 1、坑 2:叠加安装,或插件装完又手抄了钩子 | 只留一条安装路径;钩子交给安装器按稳定 ID 合并 |
| 提示「检测到重复钩子文件」 | 坑 2:插件的 plugin.json 一旦写了 hooks 字段就会触发 | 别动插件清单;要手装就用 --modules hooks-runtime --enable-hooks |
| 装了 292 个技能,一个都没触发 | 坑 3:嵌套安装,Claude Code 只认直接子目录 | 拷进 ~/.claude/skills/<技能名>/,不要多一层 |
| 用了一阵,它还是不懂我的偏好 | 坑 4:观察器默认关闭;原生 Windows 上开了也是空操作 | 先确认 observer.enabled,再确认平台 |
| 「我明明装的是新版本,行为却像旧的」 | 坑 5:以为 clone 了 main 就等于发布了版本 | 要最新用 git,要可复现钉 @2.2.1 |
| 上下文很快被塞满 | 坑 6:把整个目录当默认清单,规则与 MCP 都堆满了 | --profile minimal 起步,规则从 common + 一个语言包开始 |
| 以为有钩子就安全了 | 坑 7:把已知模式的护栏当成能力隔离 | 陌生代码用容器 / 虚拟机跑,密钥不进环境变量 |
| 在 Cursor / Copilot 上照 Claude 教程走,处处不对 | 坑 8:把「支持」当成功能等价 | 先在支持矩阵里定位档位,再决定投入多少期望 |
装乱了的标准修法(照顺序做)
# 1) 看它认为自己装了什么、体检、修
npx ecc-universal@2.2.1 list-installed
npx ecc-universal@2.2.1 doctor
npx ecc-universal@2.2.1 repair
# 2) 决定要卸:先看不写盘的后果
npx ecc-universal@2.2.1 uninstall --dry-run
# 3) 真卸(源码检出用 node scripts/ecc.js uninstall)
npx ecc-universal@2.2.1 uninstall
卸载只删它自己在 install-state 里记录过的文件;你手工拷进 ~/.claude/rules/ 的那些不在保护范围内,要自己删。官方给的叠加安装清理顺序是四步:移除插件 → 从受管状态所在目录跑卸载 → 删掉手工拷的规则目录 → 只用一个路径重装一次。
17你大概会问的六个问题
--profile minimal 起步(它故意不含钩子运行时),再用 node scripts/ecc.js consult "你的诉求" --target claude 让顾问告诉你该加哪些组件,最后 --skills a,b,c 点名装。理由:官方自己承认目录里有重叠与无人引用的技能。/plugin list ecc@ecc 看插件状态;② npx ecc-universal@2.2.1 doctor 看受管文件与钩子配置;③ 故意做一件会被拦的事(非 tmux 环境起 dev server,或带 --no-verify 提交),看钩子是否给出阻断信息。第三层最能说明问题,展开在 04。CLAUDE.md / 规则共存吗?confidence ≥ 0.7 的前 6 条的 ## Action 首行塞进上下文。可读、可改、可删——仓库里唯一那份真实数据(8 条)全部是人工策展的,这本身就说明了它的现实形态。18术语对照表
| 术语 | 定义 | 为什么重要 / 何时用 · 别当什么用 |
|---|---|---|
| harness | 承载模型的编程助手外壳(Claude Code、Codex、Cursor、OpenCode…) | ECC 的定位就是「harness 的操作层」——它不碰模型,只往 harness 里放文件。别把 harness 和模型混为一谈:换模型不影响 ECC 的安装,换 harness 才影响 |
| skill(技能) | 按需加载的可复用工作流(292 个目录,各一份 SKILL.md) |
ECC 的主工作流面,官方说新逻辑应该先落这里。别当提示词库用——它带脚本、参考文件与测试,是「有附件的工作流」 |
| subagent / agent(子代理) | 带工具白名单与模型档位的专家角色(68 个) | 用来把探索挪出主上下文。何时用:需要新上下文复核、或需要按语言分工。别当免费资源——每个都新开上下文,消耗独立计费 |
| hook(钩子) | 绑定在工具 / 生命周期事件上的外部程序(7 类事件、24 条条目) | ECC 里唯一能「物理阻断」的机制(PreToolUse 退出码 2)。别当成「更聪明的提示词」——它就是外部代码 |
| rule(规则) | 总是加载的标准(122 个文件,10 个通用 + 111 个语言规则) | 用于「每次都该守」的纪律。何时用:语言 / 项目级规范。别多装——它是每次都吃上下文的常驻成本 |
| instinct(本能) | 小的学习行为:元数据(confidence 0.3–0.9)加 ## Action 正文 |
用来把「你纠正过它一次」变成下次自动生效。何时用:项目里有反复出现、你又反复纠正的约定。别当真理——它有置信度、会衰减、还要过 0.7 才注入 |
| confidence(置信度) | instinct 的把握程度数值(0.3 暂定 → 0.9 近乎确定) | 决定「这条本能会不会进上下文」(阈值 0.7)。涨跌规则:观察次数定初值,确认 +0.05、反驳 −0.1、每周 −0.02。别把它读成概率,它是一套人为设定的权重 |
| memory vault(记忆库) | 陈述性记忆库,格式标识 ecc.memory.v1,一文件一条 |
用来跨会话保留「发生了什么、决定过什么」。关键区别:它永远 unreviewed、没有晋升通道——memory 是背景资料,不是指令 |
| install-state(安装状态清单) | 记录「ECC 写了哪些文件」的清单(如 ~/.claude/ecc/install-state.json) |
决定卸载的安全边界:只删自己记录的。何时关心它:想干净卸载、或怀疑装了两遍。别以为手抄的文件也在保护范围内——它们不在 |
| profile(安装档位) | 安装档位(7 个:minimal / opencode / core / developer / security / research / full) | 用来控制「一次装多少」。何时用:第一次装建议 minimal。没有 --minimal 这个旗标,它是 --profile 的值 |
| scope(作用域) | 配置生效范围:user(对你所有项目)、project(只对这个项目)、local(只在这个目录) | 决定「为什么我另一个项目里没有」。何时用:只想管一个仓库就选 project。别指望装完自动到处都有 |
| MCP | 让助手调用外部工具的一种插件协议;ECC 现在只默认带 1 个连接器 | 用之前先想上下文成本:每个 MCP 的工具描述都占额度。别一次全开——官方给的经验线是每个项目少于 10 个、活跃工具少于 80 个 |
| GateGuard | 在命令执行前拦破坏性操作的机制(rm、强制 git checkout、破坏性 find -exec) |
它挡的是已知危险模式,不是能力隔离。别当沙箱用 |
| AgentShield | 独立仓库 / 独立 npm 包的扫描器,审计 agent、钩子、MCP、权限、密钥面 | 用来审「你给自己装的这套配置」本身是否安全。注意官方声明:不提供已审计的版本锚点,版本与完整性要自己审 |
| ccg-workflow | 第三方运行时,multi-* 那五条命令的外部依赖 |
何时用:你确实需要多模型协同。别以为装了 ECC 就有——官方不捆绑也不担保它,缺了命令跑不对 |
| legacy shim(退役占位命令) | 把旧短命令(如 /tdd、/verify)转发到新技能的兼容文件,共 12 条,在 legacy-command-shims/ |
用来救老教程里的写法。何时用:你确实需要旧名字。它不随基础安装给你,要显式取;别把「命令不存在」当成装坏了 |
19参考来源、我实测了什么、证据边界
用到的来源(都可点开复核)
- github.com/affaan-m/ECC——官方仓库(本文所有逐字引用与文件数字的来源;取数日 2026-09-13,取的是
main分支的完整文件树,最新提交8321021) - npmjs.com/package/ecc-universal——官方 npm 包(版本历史与发布时间取的这里:
latest= 2.2.1,发布于 2026-09-08) - npmjs.com/package/ecc-agentshield——AgentShield 包
- ecc.tools——项目官网(README 里链接的定价 / Pro 页面入口);GitHub 公开 API 的星标 / fork / 创建时间等统计,也取自这里(取数日 2026-09-13:星标 25.7 万、fork 3.8 万、仓库创建于 2026-01-18)
- 仓库内一手文档:
README.md(2,012 行)、SECURITY.md、CHANGELOG.md、docs/ROADMAP.md、docs/token-optimization.md、docs/releases/2.2.1/patch-execution.md、hooks/README.md、skills/continuous-learning-v2/SKILL.md、skills/continuous-learning-v2/agents/observer.md、docs/design/ecc-memory-vault.md、manifests/install-*.json
我这次实测出来的东西(可自己复核)
- 目录计数:
skills292、agents/*.md68、commands/*.md94、rules/122、scripts/hooks/53、hooks.json24 条条目 / 7 类事件、仓库总文件 3,716、schemas/13、legacy-command-shims/12 条命令、安装适配器 15 个。 - 自算数据:思考预算从 31,999 降到 10,000 的削减率是 (31999−10000)/31999 = 68.75%(文档写「~70%」——方向与量级都对,但略高);
docs/各语言目录的文件数(ja-JP 521、zh-CN 416、es 142、tr 142、ko-KR 64、zh-TW 58、pt-BR 47、de-DE 2,ru / th / uk-UA / ur / vi-VN 各 1)——语言栏里列了 13 种语言,其中 5 种只有一个文件。 - 清单级发现:
--with lang:*与--with framework:*里的 19 个组件全部指向同一个framework-language模块(只有lang:swift例外);装卸策略实测 5 种(preserve-relative-path/flatten-copy/merge-json/merge-hook-ids/sync-root-children)。
- 时效:本文校对于 2.2.1,数字取自
main分支 2026-09-13 的文件树。这个项目的发布节奏是每周级,数字与文件路径都可能在下个版本变化——这也是本文把learn:shelf-life标为evolving的原因。 - 没做的事:我没有真的安装这套东西并让 Claude Code 跑一遍——所有结论来自源码、配置与官方文档的静态核对。「安装后实际体验如何」本文不提供证据,请在非关键项目上自行验证。
- 不能确认的:README 里 Cursor 表的「Agents 48」在仓库中找不到对应产物,只能标「未能确认」;
.kiro/(153 个文件)、.trae/(4 个文件)两套独立安装脚本我只核对了它们在安装器的目标列表之外(15 个适配器里没有它们,README 支持矩阵里也没有它们),没有逐行核对它们复制了什么。 - 口径说明:文中所有「实测」= 在上面的文件树上执行命令得到;所有逐字引用都标了文件(多数带行号或小节名),你可以直接搜出来对照。
99一句话总结
ECC 是给 AI 编程助手加装的一整套工程制度——292 个技能、68 个专家子代理、94 条兼容命令、122 个常驻规则,外加 24 条能在模型之外拦人的钩子,以及一套把「你纠正过它一次」写成带置信度的 instinct、下次会话按 0.7 阈值注入前 6 条的学习闭环;它的真正价值不在数量而在几个结构选择(计划落成工件、复核换新上下文、钩子物理拦截、记忆只当背景资料不当指令),它的风险也不在恶意而在文档比维护跑得快——同一个技能数在同一份仓库里有 292 / 291 / 281 三个版本、Codex 表里还挂着 6 个早已退役的 MCP、「不维护副本」被自己检入的 39 个分叉文件推翻,而最像卖点的「持续学习」开箱是关闭的。