🟡 进阶

ECC 使用指南:装了什么、哪些机制真的在跑、哪些说法别照信

一次 npx 之后,你的 AI 编程助手旁边会多出 292 个技能、68 个专家子代理、24 条钩子、122 个规则文件。这篇回答三件事:它们分别是什么、哪些真的在跑、哪些官方说法我核对不上。

📅 更新于 2026-09-13

本文校对于 affaan-m/ECC @ 2.2.1 · 官方源:github.com/affaan-m/ECC(取数日 2026-09-13)

292 / 68 / 94
技能 / 子代理 / 命令(本文实数的目录)
24 条
钩子条目,分布在 7 类事件上
12 条
我核对不上的官方说法
3,716
仓库文件总数(比官方 README 里的表更细)

0030 秒速览:先记住三句话,再按处境挑一条路

读完这一篇,你能做三个判断:这套东西该不该装、装哪一条路、以及哪些功能你以为装上了其实没在跑。下面三句是主心骨,后面每一节都在给它们补细节。

🔑 先记住这三句

① 它不是帮你写代码的东西,而是给你已经会写代码的助手加一套制度——价值在约束,不在能力。
② 它里面只有一种东西能真的拦住模型,就是钩子(hook);技能和规则都只是「请你遵守」。
③ 它最像卖点的那个功能(让助手越用越懂你)出厂是关着的,而且官方自己承认在原生 Windows 上开了也不干活。

按你现在的处境,直接照这张表走

你现在的状态直接做这件事为什么
刚听说它,想先看它长什么样读 01 与 05,别急着装它会往你的配置目录写文件、注册钩子;先知道写了什么再决定
已经在用 Claude Code,想装上试试npx ecc-universal@2.2.1 setup官方首选路径,装完还能用同一条命令升级、换作用域(03)
同时用 Claude Code 和 Codexnpx 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)

最小上手路径:五步,十分钟

1
先对版本

通用安装器要 Node.js ≥ 18;Claude Code 插件路径要 Claude Code 命令行 ≥ 2.1.0(原文见 03)。低于这两条,绝大多数「装不上」都不是 bug。

2
选一条路,只选一条

Claude Code 用 npx ecc-universal@2.2.1 setup;别的助手用 ./install.sh --profile minimal --target <目标>。同一个助手不要叠加两种装法——技能、命令、钩子都会变成两份。

3
体检一次

npx ecc-universal@2.2.1 doctor 看它认为自己写了哪些文件、钩子配置对不对。

4
故意撞一次闸门

这是唯一能证明「钩子真的在跑」的办法——比如在不是 tmux 的终端里让它起 dev server,看它是否被拦下(完整例子在 04)。

5
跑一遍最小闭环

/ecc:plan "给已有项目加上用 OAuth 登录" → 确认或改计划 → 让 tdd-workflow 接管 → /code-review 复核。全过程在 11。

读完你应该能

关键数字先给量级

292技能目录,各一份 SKILL.md
68专家子代理文件
94命令入口(官方定为过渡期兼容层)
122规则文件(总是占上下文)
24 / 7钩子条目 / 事件类型
3,716仓库文件总数

这些数字都是我在 2026-09-13 把仓库完整文件树取下来逐个数的,每个都配了核对方式,写在 05 与 19。

01它到底是什么:不是提示词合集,是装在助手外面的一套制度

先把最容易错的那一步说清楚: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 文件,测试先变红才有资格改生产代码,复核交给一个新上下文的子代理,质量检查交给钩子而不是靠模型记性。

它不是什么(先做一遍负向定义)

🧭 一句话抓住它

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 首选)

1
一条命令,之后升级也用它
npx ecc-universal@2.2.1 setup

它会先盘点官方市场与每一个原生 Claude 安装作用域(作用域=这份配置只对你个人生效、只对这个项目生效、还是只在当前目录生效),再安装 / 更新 / 迁移 ecc@ecc 到你选的那一档。以后升级、换作用域、改钩子档位,都是重跑同一条命令。

2
npm 报版本或缓存错时先确认
npm view ecc-universal version
3
用别的包管理器(同一件事的四个写法)
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 钩子档位作用域选错会导致「有的项目有、有的项目没有」
CodexCodex 原生的市场 / 插件流程钩子的审查与信任归 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 对等物
🚫 OpenCode 那条命令必须带上钩子开关

官方 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 钩子
让它执行 git commit --no-verify。若钩子在跑,会被 block-no-verify.js 以退出码 2 拦下,你会看到阻断信息而不是提交成功。
🔒
试着改静态检查配置
让它「把 eslint 规则放宽一点让检查过」。config-protection.js 会拦住对已存在配置文件的修改(第一次创建放行)。
🖥️
在非 tmux 环境起 dev server
会看到 [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 取下的完整仓库文件树上实际数出来的,核对命令一并给出,你可以自己复核:

五件套实测数量核对的命令 / 怎么理解它
技能 skills292 个目录,292 份 SKILL.mdfind skills -mindepth 2 -maxdepth 2 -name SKILL.md | wc -l;目录与文件 1:1、无嵌套,用到才加载
子代理 agents68 个 .mdfind agents -maxdepth 1 -name '*.md' | wc -l;可被主代理委托的专家角色
命令 commands94 个 .mdfind commands -name '*.md' | wc -l;官方定位是「迁移期的兼容入口」
钩子 hookshooks.json 里 24 条条目 / 7 类事件;scripts/hooks/ 另有 53 个文件用 JSON 解析 hooks.json 逐类累加;钩子是在模型之外强制执行的
规则 rules122 个文件 = 1 份 README + 10 个通用 + 111 个语言 / 框架规则(21 个语言目录)find rules -type f | wc -l;每次会话都进上下文,所以要少而准
3,716仓库文件总数
13JSON Schema(schemas/)
53钩子实现文件(scripts/hooks/)
1,507docs/ 下的文件数
1214 个语言目录里只有 1 个文件的

先接受一个反直觉的前提:多不是优点

⚠️ 「292」既是资产也是负债——这是官方自己写的

官方路线图原话:"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.md291它的口径是「2.2.1 源码基线」,比 main 分支落后一个技能
插件清单 .claude-plugin/plugin.json292插件的自我描述,与当前目录一致

结论不是「它在骗人」,而是:同一份仓库里同时存在历史数字、发布基线数字和分支现状数字,而它们都长得像「当前值」。所以本文一律用 目录数 作口径——它是唯一能由你自己复现的一种:官方数字随文档更新漂移,而 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 / SessionEnd2 / 1会话生命周期的两端:加载上下文、保存状态
PostToolUse / PostToolUseFailure2 / 2只能分析、不能阻断(动作已经执行完了)
PreCompact(压缩上下文之前)1压缩之前抢救状态

结构上还有一个细节值得知道:钩子在 hooks.json 里是内联的 node -e "..." 单行脚本,本体只是一层薄壳,真正的逻辑在 scripts/hooks/ 的 53 个文件里。被引用最多的两个入口是转发器 run-with-flags.js(20 次)与 plugin-hook-bootstrap.js(14 次)。

它们到底拦什么:三个真实例子

🛑
拦住绕过 git 钩子
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 全家桶在保护名单里,改已存在的配置文件直接阻断,首次创建放行。
🖥️
拦住 tmux 外的 dev server
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.jsonECC 只默认带 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:把脏活扔出主上下文,只把结论拿回来

agents/
子代理定义(68 个 .md)
模型可自动委托
每个文件是一个「有名字、有工具箱、有模型档位」的专家角色。主代理可以把任务委托给它,从而把探索过程挪出主上下文。
是什么 / 解决什么问题

一个子代理就是一段带元数据的系统提示 + 一份工具白名单。工具白名单的意思是这个角色只被允许用列出来的那几个动作(比如只许读、不许写)。它解决的问题是上下文被污染:让一个只读文件、只跑测试的角色去干脏活,主代理只拿到结论,省下大量来回。

怎么用(最小可用示例)

直接点名,或者让主代理按描述自动委托:

# 直接点名(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/   # 自查这两个外部依赖在不在
⚠️ 官方对 ccg-workflow 的立场:不捆绑、也不担保

README 明确写:选择并审阅一个确切的发布版本再初始化,ECC 既不捆绑 CCG,也不声明某个版本与之兼容或经过审计。所以这五条命令属于「你自己评估后再用」,缺了运行时它们跑不对。

🧩 tools 字段是安全边界的一部分

注意 code-reviewer 的工具是 Read, Grep, Glob, Bash——没有 Edit、没有 Write。这不是随手写的:一个只能读的复核者没法「顺手改一下让它通过」。挑子代理时先看这一行,比看描述有用。

09skills:默认工作流面,但 292 个不是安装清单

skills/
可复用工作流(292 个目录,每个一份 SKILL.md)
主工作流面,按需加载
官方反复强调的一句话是:技能是主要的工作流面,命令只是兼容入口。新工作流按官方约定应该先落进 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——装完之后的重新配置向导(注意:它只能在装好之后用,不能替代第一次安装)。
注意事项与边界
  • 技能头部字段出现频次实测:name 292、description 292、metadata 265、license 18…… 也就是说事实上只有 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:arktsframework-language(同一个)装哪个语言,结果都一样——精确按语言裁剪这件事目前做不到
framework:angular / react / vue / nextjs / django / springbootframework-language(同一个)同上;quarkus 额外挂 security
lang:swiftswift-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.md1结构与安装说明

每个语言目录通常是 5 个文件(coding-style / hooks / patterns / security / testing),例外是 python(6)、web(7)、react-native(8)。

🚫 Claude Code 插件分发不了 rules(官方明说)

官方原话:"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 档。

1
先要计划,而且要能改

/ecc:plan "Add user authentication with OAuth" → 由 planner 产出一份实现蓝图,落到磁盘上成为可编辑的工件,而不是留在聊天记录里。官方对这一点给的理由是一句对照:"Plans disappear into chat history" 对 "Plans become editable artifacts before implementation starts"。

2
激活测试优先技能,先拿到「红」

由 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."——计划不是免测通行证。

3
写最小实现,直到变绿

只写让测试通过的最少代码。此时 PostToolUse 那类钩子会在你编辑文件之后跑格式 / 类型检查(只能提醒,不能阻断,因为文件已经改完了)。

4
用新上下文复核

/code-review → code-reviewer 带着 Read, Grep, Glob, Bash 进来找回归与盲区。它不是同一个上下文,这正是它能看出问题的原因。

5
沉淀:让它下次不用你再说一遍

会话结束时,学习链会把「你纠正过的做法」写成一条 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-workflowtdd-guide
复核刚写的代码/code-reviewcode-reviewer(只读工具)
修一个失败的构建/build-fixbuild-error-resolver
跑端到端测试技能 e2e-testinge2e-runner
找安全漏洞/security-scansecurity-reviewer
删掉没人用的代码/refactor-cleanrefactor-cleaner
更新文档/update-docsdoc-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——也就是人工写的,不是「会话里学出来的」。这一点值得单独记住,因为它说明了这个机制的现实形态。

闭环四步

① 观察
工具调用前后写入 observations.jsonl
→
② 沉淀
后台小模型观察者识别模式
→
③ 晋升
/evolve 聚类成技能,/promote 升为全局
→
④ 用上
会话开始时按置信度注入前 6 条

四个步骤的关键参数(都能在 README 的环境变量表里核对):

🚫 最重要的一条:开箱是关的,而且原生 Windows 上开了也不干活

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 与 v2 并存,文档口径不一

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% 触发的。

⚠️ 文档 schema(9 字段)与仓库里唯一实例(6 字段)不一致

导出端定义的规范字段是 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.
维度instinctsmemory vault为什么要分清
存储位置…/ecc-homunculus/instincts/**<仓库>/.ecc/memory/**、~/.ecc/memory/**备份 / 清理策略完全不同:一个在用户目录,一个在仓库里
格式元数据 + ## Action,一个文件可多条一文件一条,格式标识 ecc.memory.v1instinct 便于批量策展,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 个,它们与源不一致,且不在安装器的产出路径上。正确说法是:机制一源,仓库两份真相

已经修掉或换了形态的四条

#旧版记的问题现状
5README 里的 OpenCode 安装命令缺钩子开关,会撞硬闸门报错已补:现行命令末尾带 --enable-hooks。硬闸门本身没变——没给 --enable-hooks / --no-hooks 仍然会在写盘前停住
6README 推荐 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 写入前的字符校验写入时硬:正文含控制字符或双向格式字符直接抛错,写不进去

三处「看着像控制、其实不是」

它自己对「安全工作」的定义很克制,这点值得学

关于 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 当沙箱

「装了带钩子的 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.json

Claude 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:指望「持续学习」开箱可用

⚠️ 观察器默认关闭,Windows 上另有未修缺陷

如果你买的是「它会自己越用越懂我」这个概念:先看 skills/continuous-learning-v2/config.json 里的 enabled: false,再看平台矩阵里 Windows 原生的两条未修缺陷(#2489、#2626)。它设计得不错,但默认不跑。

坑 5:把仓库根当成发布版

⚠️ npm 按标签发版,main 分支不是发布版

官方原话:npm 版本按版本标签切,不是按提交切,所以 main 上会有版本号里没有的东西。你要「最新」就 clone main;要「可复现」就钉死 @2.2.1。我这次取数就撞上了这件事:main 上技能目录是 292 个,而路线图里记的发布基线是 291 个。

坑 6:拿别人的技能数字当自己该装的量

⚠️ 292 个技能不是「安装清单」,是「可选项清单」

官方路线图承认存在重叠与无人引用的技能。正确做法是先用 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你大概会问的六个问题

我只是想要几个好用的技能,必须把 292 个全装上吗?
不必,而且不建议。用 --profile minimal 起步(它故意不含钩子运行时),再用 node scripts/ecc.js consult "你的诉求" --target claude 让顾问告诉你该加哪些组件,最后 --skills a,b,c 点名装。理由:官方自己承认目录里有重叠与无人引用的技能。
它会不会改我的代码、或者偷偷联网?
不会偷偷联网:官方明确写「ECC 从不自动上传诊断信息」,反馈走的是一个公开的 GitHub issue 表单。至于代码——钩子只拦不改(拦下改静态检查配置正是为了防止「让检查通过」式修改),真正的代码写入仍然由模型通过正常工具完成。
装完之后怎么确认它真的在工作?
三层:① /plugin list ecc@ecc 看插件状态;② npx ecc-universal@2.2.1 doctor 看受管文件与钩子配置;③ 故意做一件会被拦的事(非 tmux 环境起 dev server,或带 --no-verify 提交),看钩子是否给出阻断信息。第三层最能说明问题,展开在 04。
它能和我已有的 CLAUDE.md / 规则共存吗?
能,而且这是设计目标之一:钩子按稳定 ID 合并进设置文件,ECC 只管理它自己写过的文件(install-state),现有设置与钩子会被保留。官方还说明「无法证明属于自己」的旧文件会被保留并报告给你复核,而不是直接删。
我不用 Claude Code,值得装吗?
看你在哪一档。Codex 有原生插件路径(钩子要显式信任、且不用 Claude 那套档位);Cursor / OpenCode 是测试版;Copilot 只有指令层。如果你的助手只在最后一档,建议只挑几个技能目录手工适配,别走完整安装。
「instincts」听起来像会自动变聪明的黑魔法,真的吗?
不是黑魔法,是一组 YAML 文件加一套置信度算术(YAML 是一种给人读的配置文件格式)。它的输入是你自己的纠正(1–2 次给 0.3、11 次以上给 0.85),注入时只把 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参考来源、我实测了什么、证据边界

用到的来源(都可点开复核)

我这次实测出来的东西(可自己复核)

📏 证据边界(请连同结论一起读)
  • 时效:本文校对于 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 个分叉文件推翻,而最像卖点的「持续学习」开箱是关闭的。

⌂