首页
/ 使用 /instinct-status 检视 ECC 项目级与全局级学习直觉:命令原理与输出深度解读

使用 /instinct-status 检视 ECC 项目级与全局级学习直觉:命令原理与输出深度解读

2026-09-07 22:36:03作者:裘晴惠Vivianne

/instinct-status 是 ECC 的 Continuous Learning v2.1 体系中用于「盘点已学行为」的诊断命令,它把当前项目作用域与全局作用域中累积的 instincts(小型可复用行为)一次性列出,并按领域分组、附置信度条。本文以命令定义文档为骨架,结合仓库内 instinct-cli.pyresolve-ecc-root.jshomunculus-dir.sh 等源码,讲清它的执行链路、数据存放位置、输出格式的每个字段含义,以及如何据此决定后续的演化(/evolve)或提升(/promote)动作。读完你将能熟练解读一条 status 输出,并能在直觉文件缺失、遗留数据存在等异常场景下快速定位原因。

一、/instinct-status 在 ECC 学习体系中的定位

ECC(Everything Claude Code)以 continuous-learning-v2 技能承载"基于直觉的学习系统":通过 hooks 100% 可靠地观察会话,产出带置信度评分的原子化 instincts,再把它们聚类演化成 skills / commands / agents(详见 SKILL.md)。v2.1 引入了项目作用域直觉,让 React 的模式留在 React 项目里、Python 约定留在 Python 项目里,只有"总是校验用户输入"这类普适模式才进入全局。

在此体系中,与直觉生命周期相关的斜杠命令共六条,而 /instinct-status 是所有其余动作的前置体检:

命令 职责
/instinct-status 展示当前项目 + 全局全部直觉及其置信度(本文主题)
/evolve 将相关直觉聚类为 skill / command / agent
/instinct-export 按 scope / domain 过滤导出直觉
/instinct-import 带作用域控制地导入直觉
/promote 把项目直觉提升为全局直觉
/projects 列出已知项目及其直觉计数

对应实现文件为 commands/instinct-status.md 与其他同名命令定义文件。文档对其功能的概括只有一句话:"Shows learned instincts for the current project plus global instincts, grouped by domain"——把当前项目与全局直觉合并后,按 domain 分组展示。

二、命令解析:为什么先解析 ECC 根目录

/instinct-status 的"Implementation"一节强调了一个关键设计:运行 instinct CLI 之前,先以与 hooks/hooks.json 以及其他斜杠命令(/sessions/skill-health完全相同的方式解析出当前生效的 ECC 插件根目录。这是因为当 CLAUDE_PLUGIN_ROOT 未设置、而旧的 ~/.claude/skills/continuous-learning-v2/ 目录仍然存在时,直接调用会产生"跑错副本"的分叉问题(文档标注 issue #2037)。

文档给出的完整命令如下(保持原样,可直接执行):

ECC_ROOT="${CLAUDE_PLUGIN_ROOT:-$(node -e "var r=(function(){var p=require('path'),f=require('fs'),o=require('os');var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var d=p.join(o.homedir(),'.claude');function L(x){try{return require(p.join(x,'scripts','lib','resolve-ecc-root')).resolveEccRoot()}catch(_){return null}}var r=L(d);if(r)return r;var s=['ecc','ecc@ecc','marketplaces/ecc','everything-claude-code','everything-claude-code@everything-claude-code','marketplaces/everything-claude-code'];for(var i=0;i<s.length;i++){r=L(p.join(d,'plugins',s[i]));if(r)return r}try{var g=['ecc','everything-claude-code'];for(var j=0;j<g.length;j++){var c=p.join(d,'plugins','cache',g[j]);var O=f.readdirSync(c);for(var k=0;k<O.length;k++){var q=p.join(c,O[k]);var V=f.readdirSync(q);for(var m=0;m<V.length;m++){r=L(p.join(q,V[m]));if(r)return r}}}}catch(_){}return d})();console.log(r)")}"
python3 "$ECC_ROOT/skills/continuous-learning-v2/scripts/instinct-cli.py" status

这一段内嵌的单行 JS 是对 resolve-ecc-root.jsresolveEccRoot() 的压缩内联版本。为什么把这段逻辑塞进每条命令而不是外部脚本?代码注释给出的原因是:旧版把完整搜索逻辑(约 700 字符)复制到约 80 处命令文件中,其中的数组展开(spread)写法会因 shell 引号问题在 Windows 上执行失败(issue #2368)。现在的压缩形式不含 spread、不含嵌套数组字面量、不含转义双引号,因此能安全穿越 node -e "..." 在任意 shell 中的引号包裹。

resolveEccRoot() 本身按五级优先级探测:

  1. CLAUDE_PLUGIN_ROOT 环境变量——插件式安装下由 Claude Code 为 hooks / commands 注入,命中即返回(envRoot.trim() 直接作为根);
  2. 标准安装位 ~/.claude/——当该目录同时存在脚本树探针 scripts/lib/utils.js 与哨兵技能 skills/continuous-learning-v2 时才认定是完整根,避免"只拷了脚本没拷技能"的半安装被误判为可用根(issue #2544);
  3. ~/.claude/plugins/ 下的已知插件根——依次探测 eccecc@eccmarketplaces/ecc 以及历史名 everything-claude-code 等六种布局,保留向后兼容;
  4. 插件缓存自动探测——扫描 ~/.claude/plugins/cache/{ecc,everything-claude-code}/ 下的 <org>/<version> 目录,适配 marketplace 安装;
  5. 回退 ~/.claude/——以上全部失败时的原始行为。

对 status 命令而言,resolveEccRoot() 只负责定位到根,真正的技能脚本路径再拼接 skills/continuous-learning-v2/scripts/instinct-cli.py,最后以 status 子命令调用 Python CLI。这也解释了为什么 CLAUDE_PLUGIN_ROOT 的一致性如此重要:任何一条命令用旧路径解析出的 ECC_ROOT,都会指向一个过时或无内容的目录,导致读不到当前累积的直觉。

三、status 子命令的完整执行链路

运行 python3 instinct-cli.py status 后(入口 main()args.command == 'status' 分支,见 instinct-cli.py),cmd_status() 按文档"Usage / What to Do"列出的五步执行:

第 1 步:探测当前项目上下文(git remote / 路径哈希)

detect_project() 返回一个含 idnameroot、各子目录路径的字典,探测优先级如下:

  1. 环境变量 CLV2_NO_PROJECT=1 时直接返回全局兜底项目(id="global");
  2. CLAUDE_PROJECT_DIR 显式指定目录——即便该目录不是 git 仓库也按其绝对路径哈希成项目身份(与 detect-project.sh 保持一致);
  3. 否则用 git rev-parse --show-toplevel 取仓库根;若仓库无 remote,则回退到 git worktree list --porcelain 定位主工作树路径;
  4. 以上全部失败(非 git 目录、git 超时 5 秒、git 不存在)时落入 global 兜底。

项目 ID 的生成值得注意:优先取 git remote get-url origin 的 URL——先剥离凭证(_strip_remote_credentials)、去掉 :// 协议前缀与 .git 后缀、统一小写(_normalize_remote_url),再对结果做 SHA-256 并截取前 12 个字符(_project_hash)。这意味着同一仓库在不同机器上会得到相同的项目 ID,直觉数据可以跨机延续;只有完全没有 remote 时才退回用机器相关的路径哈希。ID 冲突时 status 只依赖哈希寻址,无需用户干预。

第 2、3 步:读取项目直觉与全局直觉

load_all_instincts(project) 按目录加载。项目侧(project["id"] != "global" 时)依次读取 instincts_personalinstincts_inherited 两个子目录;全局侧读取 GLOBAL_PERSONAL_DIRGLOBAL_INHERITED_DIR(关于这些目录的落盘位置见第五节)。目录扫描器 _load_instincts_from_dir() 只认扩展名 .yaml.yml.md(常量 ALLOWED_INSTINCT_EXTENSIONS),文件统一按 UTF-8 读取,并给每条直觉附加 _source_file_source_type_scope_label 三个内部标记;若 frontmatter 未写 scope 字段,则按所在目录的 scope_label 补默认值。

第 4 步:按优先级合并(project 覆盖 global)

这是 v2.1 作用域模型的核心语义:先收集项目直觉的 ID 集合,再遍历全局直觉,凡 ID 已被项目直觉占用的全局条目一律丢弃,从而保证"ID 冲突时项目直觉胜出"。测试 test_load_all_project_overrides_global 验证了这一点:同名直觉在项目中置信度 0.9、全局 0.3,合并后只剩项目版本且 scope 标记为 project

第 5 步:分组渲染

合并结果进入渲染阶段:项目条目归入 PROJECT-SCOPED 区块、全局条目归入 GLOBAL 区块,各自内部再按 domain 聚类、按置信度降序排列。

四、输出格式逐字段解读

文档给出了典型输出骨架,这里完整保留并加注:

============================================================
  INSTINCT STATUS - 12 total
============================================================

  Project: my-app (a1b2c3d4e5f6)
  Project instincts: 8
  Global instincts:  4

## PROJECT-SCOPED (my-app)
  ### WORKFLOW (3)
    ███████░░░  70%  grep-before-edit [project]
              trigger: when modifying code

## GLOBAL (apply to all projects)
  ### SECURITY (2)
    █████████░  85%  validate-user-input [global]
              trigger: when handling user input

对照 instinct-cli.pycmd_status()_print_instincts_by_domain() 的实现,各段含义如下:

  • 头部横幅INSTINCT STATUS - N totalN 为项目与全局合并去重后的总数(len(instincts));
  • 项目与计数行:显示 Project: 名称与 12 位项目哈希 ID,以及 Project instincts / Global instincts 各自数量。注意括号中的哈希正是"同仓库跨机器一致"的那个 _project_hash 结果;
  • ## PROJECT-SCOPED (my-app) / ## GLOBAL (apply to all projects):由 _scope_label 切分的两大区块,分别调用 _print_instincts_by_domain()
  • ### DOMAIN (N):domain 取直觉 frontmatter 的 domain 字段,缺省为 general,按名称升序;每个 domain 下的直觉再按 confidence 降序排列;
  • 置信度条 ███████░░░ 70%_confidence_bar() 把置信度换算为 10 格条(filled = int(confidence * 10),截断到 [0,10])。若当前 stdout 编码无法表达 / (如 Windows cp1252),自动退化为 # / . 的 ASCII 形式,保证渲染不崩溃;
  • [project] / [global] 标签:来自直觉的 scope 字段或目录推导值;
  • trigger::直觉的触发条件,来自 frontmatter trigger
  • action: 行(实际输出的增强信息):实现还会用正则 ## Action\s*\n\s*(.+?) 从正文中抽取 Action 小节的首行,截断到 60 字符展示,帮助一眼看出该直觉"要做什么"。文档示例省略了该行,实际 CLI 会打印。

输出不止于此。cmd_status() 还会在区块之后追加三类运维信息:

  1. 观测统计:若当前项目存在 observations.jsonl,会打印 Observations: N events logged 及其文件路径;
  2. 待审直觉(pending):若存在 pending 目录且有待审文件(_collect_pending_instincts() 全局 + 各项目逐一扫描),打印 Pending instincts: N awaiting review;数量 ≥ 5 时警告未审直觉将在 30 天后自动删除(PENDING_TTL_DAYS = 30);对剩余寿命不足 7 天(PENDING_EXPIRY_WARNING_DAYS = 7)的条目逐条列出 (Nd remaining)
  3. 遗留数据警告_warn_legacy_data() 检测旧路径 ~/.claude/homunculus/ 是否仍含实质性文件(活动目录已迁走时),若存在则以 ! 横幅提示运行迁移脚本 migrate-homunculus.sh 或设置 CLV2_HOMUNCULUS_DIR 指向旧路径。

若当前没有任何直觉,则输出兜底提示 No instincts found. 以及项目名 / 哈希、项目与全局数据目录的绝对路径——这一分支由测试 test_cmd_status_no_instincts 覆盖。因此,看到 status 输出变空时,先查这两条路径是否正确、有没有被误设的环境变量改写过。

五、直觉数据的落盘位置与目录解析优先级

值得注意的是,命令定义文档"Usage / What to Do"第 2、3 步写的是读取 ~/.claude/homunculus/projects/<project-id>/instincts/~/.claude/homunculus/instincts/。但从 v2.1 的源码与 SKILL.md 的"Data Directory"一节可以确认:活动数据目录已从 ~/.claude/homunculus 迁移到 XDG 布局,旧路径只是供迁移读取的遗留位置。迁移原因在 SKILL.md 中有说明:把观测数据放到 ~/.claude 之外,可以避免 Claude Code 的敏感路径防护误拦截后台 instinct 写入。

活动目录按以下优先级解析(Python 侧见 _resolve_homunculus_dir(),shell 侧见 homunculus-dir.sh,两侧规则一致):

  1. CLV2_HOMUNCULUS_DIR(设为绝对路径时优先生效,相对路径会被忽略并告警);
  2. $XDG_DATA_HOME/ecc-homunculus(同样要求绝对路径);
  3. 兜底 $HOME/.local/share/ecc-homunculus

status 渲染用到的实际目录因此是:

${XDG_DATA_HOME:-~/.local/share}/ecc-homunculus/
├── instincts/
│   ├── personal/          # 全局自动学习直觉
│   └── inherited/         # 全局导入直觉
├── observations.jsonl     # 全局观测兜底
├── projects.json          # 项目哈希 → 名称/路径/remote 注册表
└── projects/
    └── <project-hash>/
        ├── observations.jsonl
        ├── instincts/
        │   ├── personal/  # 项目专属自动学习直觉
        │   └── inherited/ # 项目专属导入直觉
        └── evolved/       # /evolve 产物(skills/commands/agents)

status 判断 scope 时并不看文件在"哪个用户的个人目录",而是看它落在 projects/<hash>/instincts/(project)还是顶层 instincts/(global)。老用户只需执行一次迁移即可把 ~/.claude/homunculus 数据搬入新布局:

bash skills/continuous-learning-v2/scripts/migrate-homunculus.sh

迁移前不妨先跑一次 /instinct-status——若末尾出现 LEGACY DATA DETECTED 横幅,正是告诉你旧路径仍有余留数据待迁移,或可通过 CLV2_HOMUNCULUS_DIR=~/.claude/homunculus 继续使用旧路径。

六、一条直觉在磁盘上长什么样

status 展示的每一条直觉,磁盘上就是一个独立文本文件。解析器 parse_instinct_file() 以成对 --- 作 YAML frontmatter 边界切分(正文如需水平分隔线,应使用 ***___ 以免被误判为边界),并要求每个切片带有 id 字段,否则整条丢弃(对应测试 test_parse_no_id_skipped)。一个典型文件如下(示例出自 SKILL.md):

---
id: prefer-functional-style
trigger: "when writing new functions"
confidence: 0.7
domain: "code-style"
source: "session-observation"
scope: project
project_id: "a1b2c3d4e5f6"
project_name: "my-react-app"
---

# Prefer Functional Style

## Action
Use functional patterns over classes when appropriate.

## Evidence
- Observed 5 instances of functional pattern preference
- User corrected class-based approach to functional on 2025-01-15

与 status 输出直接对应的字段是:

  • confidence——解析为浮点数(0.01.0),决定置信度条的格数与排序;畸形值回退为默认 0.5(对应测试 test_parse_confidence_is_float);
  • domain——决定归入哪个 ### DOMAIN 分组,缺省 general
  • scope——projectglobal,决定渲染在哪个大区块,缺省按所在目录推导;
  • trigger——frontmatter 引号会被剥离,落在 trigger: 行;
  • 正文 ## Action 小节——其首行被提取为 action: 行。

所谓"instinct 原子性",就是这类文件始终"一个 trigger、一个 action、一份证据";status 只是把它们摊开成一张可按 domain 检索的清单。

七、测试如何为 status 的正确性背书

仓库以 pytest 覆盖 CLI 关键路径,测试文件 test_parse_instinct.py(通过 importlibinstinct_cli 模块名加载带连字符的 instinct-cli.py)中与 status 相关的断言包括:

  • test_cmd_status_no_instincts——空数据时输出 No instincts found. 且返回码为 0;
  • test_cmd_status_with_instincts——写一个项目直觉 + 一个全局直觉后,输出含 INSTINCT STATUSProject instincts: 1Global instincts: 1PROJECT-SCOPEDGLOBAL 等关键段;
  • test_cmd_status_returns_int——cmd_status 恒返回整数(正常路径 0);
  • test_confidence_bar_uses_unicode_when_supported / test_confidence_bar_uses_ascii_when_stream_rejects_block_glyphs——UTF-8 流输出 ×8 + ×2,cp1252 流退化为 ########..
  • test_print_instincts_by_domain_is_cp1252_safe——把 stdout 替换为 cp1252 包装流后渲染不抛异常且不含块形字符;
  • test_load_all_project_overrides_global——项目直觉同 ID 覆盖全局的合并语义。

这些用例从"合并优先级""空态兜底""跨编码渲染健壮性"三个维度锁定了 status 的行为边界,也解释了为何在 Windows 原生终端里置信度条会以 #/. 形态出现——这是有意为之的降级,而非乱码。

八、看完 status 之后:从检视到演化的下一步

/instinct-status 是只读诊断命令,它本身不修改任何直觉,但它的输出直接决定后续动作:

  • 同一 domain 下出现多条高度相似的直觉 → 用 /evolve 聚类成 skill / command / agent(产物写入 projects/<hash>/evolved/ 或全局 evolved/);
  • 某条 [project] 直觉已在多个项目以高置信度反复出现 → 用 /promote 提升为 [global](自动提升门槛为:同一 ID 出现在 2+ 项目且平均置信度 ≥ 0.8,常量 PROMOTE_MIN_PROJECTS = 2PROMOTE_CONFIDENCE_THRESHOLD = 0.8);
  • 想跨机器或团队共享某领域直觉 → 用 /instinct-export 导出、在目标侧用 /instinct-import 导入(对应命令定义见 instinct-export.mdinstinct-import.md);
  • 输出末尾提示 N pending instincts awaiting review 且临近 30 天 TTL → 及时评审或用 /prune 清理过期待审项(prune.md);
  • 想了解哪些项目被登记、各自有多少直觉 → 用 /projectsprojects.md)。

上述命令定义、技能文档与可执行脚本均在本仓库中:入口技能见 continuous-learning-v2,CLI 实现见 instinct-cli.py,根目录与数据目录解析分别见 resolve-ecc-root.jshomunculus-dir.sh。实际使用前,建议先执行一次 /instinct-status 核对项目哈希与两个 scope 的计数是否符合预期——它是整个学习循环里成本最低、信息量最高的健康检查。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391