关于 egm-bootstrap
egm-bootstrap 用于在代码目录树中创建和更新符合 EGM 规范的 README 合约,面向需要记录组件接口及仓库索引的开发者和 AI 助手。它仅处理文档,不修改功能源代码。
主要功能
- 01创建并修正 README 合约
- 02记录接口、不变量和副作用
- 03生成叶级与父级文档
- 04按层级遍历发现目录
- 05支持工作者处理子树
适用场景
- 01记录仓库中的组件合约
- 02保留现有备注并更新 README
- 03根据子级合约生成父级索引
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ elephant-goldfish-model --skill egm-bootstrap安装后在 Claude Code 中输入/egm-bootstrap确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
test_scenarios.yamlTEST.mdreferences/worker-return.schema.json详细介绍
EGM Peanuts and Hay Bootstrap (egm-bootstrap)
在 Codex 或 ChatGPT Work 中运行时,请先阅读 Codex 集成。
在 Claude Code 或 Cowork 中,请先阅读 ${CLAUDE_PLUGIN_ROOT}/docs/claude.md。
概览
此技能可自动创建、修正、格式化并验证目录树中符合 Elephant-and-Goldfish Model(EGM)规范的 README.md 文件。它为人类开发者和 AI 助手建立清晰的架构契约(接口、不变量和副作用)。
- Peanuts:叶级组件包 README,包含特定文件契约。
- Hay:父级仓库蓝图,将子级接口契约汇总为高层索引。
委派
Goldfish 在全新上下文中运行,不含任何对话历史。使用你的 harness 的子 Agent 工具为每个子 Agent 创建实例(Antigravity:invoke_subagent;Claude Code:Agent;Codex:spawn_agent)。每个子 Agent 都在 agents/<file>.md 中定义,其 frontmatter 中的 name(例如 egm-zoom-out)是你的 harness 注册具名子 Agent 时应请求的子 Agent 类型。否则,创建通用子 Agent,并让它先阅读对应的角色文件。逐字传递提示词,并等待报告。如果你的 harness 不支持嵌套子 Agent,请使用直接派发,而非综合器。请参阅 docs/harnesses.md。
如果你的 harness 没有子 Agent 工具,请直接内联执行侦察步骤。
输入
path:要进行引导的目标根目录路径(必填)。is_worker:内部参数。若以工作子编排器身份执行,则为true(可选,默认值:false)。sub_tree_root:分配的子树分区的根路径(可选)。target_filename:要生成或更新的目标契约文件名(可选,默认值:"README.md")。支持使用其他蓝图文件名,例如"EGM.md",以免修改已有的人工维护 README。
执行限制(重要)
- 禁止生成代码:严格限于文档工作。不得编写或重构任何功能性源代码。
- 版本控制隔离:不得执行任何版本控制提交操作(
git commit、git add)。所有文件系统变更必须使用标准文件写入工具在本地完成。跟踪和提交工作由人类用户负责。 - 临时文件隔离:共享工作区的并行工作者必须在项目仓库工作区之外、各自独立的工作者专属目录中执行所有状态跟踪、检查点记录和日志写入。
- 工具使用(重要):使用 shell、文件读取、文件写入和文件编辑工具来发现目录并生成契约/README。生成时须遵循规范的 Markdown 格式(标准标题、表格和围栏代码块)。如果仓库明确配置了项目 Markdown 格式化工具(例如
npx prettier --write),可选择运行该工具。 - 子 Agent 委派:并行创建子编排器工作者。
- 强制安全关卡(重要):如果发现超过 15 个子目录,在继续执行完整目录树操作或无限制创建子 Agent 之前,必须立即征求用户批准(如果你的 harness 有结构化提问工具,则使用该工具;否则通过普通聊天征求)。
工作流
步骤 0:生态与验证发现
- 检查仓库根目录中的包/构建清单:
- Node.js / TypeScript:
package.json->npm test(或pnpm test/yarn test) - Rust:
Cargo.toml->cargo test - Go:
go.mod->go test ./... - Python:
pyproject.toml/pytest.ini/setup.py->pytest - C/C++ / Make:
Makefile->make test - Bazel:
BUILD/BUILD.bazel->bazel test ... - 未找到:
<test-command>
- Node.js / TypeScript:
- 记录为
VerificationCommand,用于填充生成的 README 契约。
步骤 1:启动分支控制
- 检查
is_worker输入参数。 - 如果
is_worker为true,直接跳转到 步骤 4:子编排器工作流 以处理分配的sub_tree_root。 - 如果
is_worker为false或未设置,则以根编排器身份继续执行 步骤 2:增量范围界定与安全检查。
步骤 2:增量确定范围与安全门(根协调器)
-
增量广度优先搜索发现:使用目录队列,逐层(BFS)映射目标
path树,一次列出一层目录。(重要:绝不运行find或ls -R等递归搜索。)- 保留中间文件夹节点。
- 忽略符号链接,防止无限递归。
- 忽略隐藏目录和系统目录(
.git、.antigravity、node_modules、venv、dist、build、third_party)。 - 读取
.gitignore和.egmignore(如果存在),并忽略与其 glob 模式匹配的内容。 - 在发现映射中保留软件包和构建清单(
package.json、Cargo.toml、go.mod、pyproject.toml、Makefile、BUILD),以便稍后提取验证目标。
-
安全门与无上限生成审批(重要):在 BFS 循环期间,如果已发现目录总数超过 15, 立即暂停发现,并请求用户批准(如果运行环境提供结构化提问工具,则使用该工具;否则使用普通聊天),警告用户并请求批准执行完整目录树:
question:"目标目录树包含超过 15 个 子目录。执行范围较大。是否要继续进行完整目录树引导?"options:["是,继续进行完整目录树引导", "否,中止执行"]- (重要:请求批准后,必须等待用户回复,然后才能继续或生成任何工作进程。)
- 如果用户选择中止,则立即终止执行。
-
自底向上后剪枝:映射完成(并获批准)后,按自底向上顺序遍历映射树(从叶节点到根节点)。过滤掉非代码目录和仅含测试的目录:
- 源代码文件:匹配已识别的源代码、架构和契约扩展名的文件:
- 系统与编译型:
.c、.cc、.cpp、.cxx、.h、.hh、.hpp、.rs、.go、.zig、.lean - 托管型与企业级:
.java、.kt、.scala、.cs、.fs - 脚本与动态语言:
.py、.rb、.php、.lua、.sh、.bash - Web 与移动端:
.ts、.tsx、.js、.jsx、.mjs、.cjs、.swift、.m、.dart - 数据与架构 / IDL:
.sql、.proto、.graphql、.gql、.thrift、.prisma - 基础设施 / 声明式代码:
.tf、.hcl、.cue(不包括构建清单、锁文件、测试固件、文档以及.csv、.tsv、.parquet等通用数据转储文件。)
- 系统与编译型:
- 排除测试目录:排除仅包含测试代码的目录(例如名称为
tests、testing、testdata的目录,或仅包含匹配*_test.*、*Test.*、test_*.*或*.spec.*的文件的目录)。 - 非代码过滤:排除不含源代码文件且不含任何包含代码的子目录的目录。仅当空的中间文件夹包含有代码的子目录时,才予以保留。
- 源代码文件:匹配已识别的源代码、架构和契约扩展名的文件:
-
计算剪枝后的目录总数和最大深度。继续执行步骤 3:选择执行策略。
第 3 步:执行策略选择(根协调器)
-
直接执行策略(目录数量 <= 5):
- 如果剪枝后的目录总数不超过 5 个,则直接在当前线程中执行自底向上的文档编写。
- 跳转到 第 4 步:子协调器工作流程(将根协调器视为整个
path的工作器),然后继续执行 第 5 步:根节点汇总与终止。
-
无限并行子 Agent 集群策略(目录数量 > 5):
- (重要:如果目录数量 > 15,必须确认已收到用户的明确批准后才能继续。如果尚未获批,请立即请求批准,并等待用户回复后再启动工作器)。
- 使用 自适应深度分区算法,将发现映射划分为互相独立的子树分支:
- 设置
depth = 1。 - 从发现映射中提取位于当前
depth的目录节点。 - 如果
depth上的节点数量在 3 到 5 之间,则将这些节点选作子树分区根节点。 - 如果
depth上的节点数量 < 3,则递增depth(最大为 3),并重复步骤 2。 - 如果
depth上的节点数量 > 5,则按嵌套文件夹总数将最大的分支分组为 3 到 4 个独立分区,将剩余的小型分支合并为一个回退分区子树,并将这些分区选作根节点。 - 回退方案:如果
depth达到 3 时节点数量仍 < 3,则选取根目录的直接子目录(或回退到顺序执行)。
- 设置
- 启动无限数量的子协调器:对于每个分区子树根节点,使用运行框架的子 Agent 工具启动并行工作器:
- 子 Agent:
egm-bootstrap-orchestrator(agents/bootstrap_orchestrator.md)(或通用子 Agent) Prompt:“运行 egm-bootstrap,参数为 path=[path]、 is_worker=true、sub_tree_root=[partition_root]、 target_filename=[target_filename]。”
- 子 Agent:
- 无限并行执行:在不施加人为并发限制的情况下并行启动所有子协调器(经用户在安全检查阶段授权后)。
- 转为空闲状态,等待所有工作器子 Agent 返回其 JSON 子树索引载荷。跳转到 第 5 步:根节点汇总与终止。
第 4 步:子协调器工作流程
-
侦察 Agent 注册:使用只读的
goldfish-explorer侦察 Agent。如果运行框架支持在运行时定义子 Agent,则按以下方式注册:name:goldfish-explorerdescription:只读代码库探索侦察 Agent。system_prompt:>- 你是一个只读代码库探索 Agent。你的任务是分析目标目录中的源文件,并返回简洁、客观的摘要。不要写入或修改任何文件。返回一个 JSON 对象,其中包含符合以下架构的目录公开符号(接口)、不变量和副作用:{"interface": [], "invariants": [], "side_effects": []}。enable_write_tools:falseenable_subagent_tools:false
-
后序遍历:按后序遍历分配的
sub_tree_root(或path)(先处理最深层的叶节点)。对于每个目录D:-
修正与修改策略:检查
D中是否已存在target_filename(默认值:README.md)。- 如果
target_filename存在,不要将其完全覆盖。而应读取其现有内容。 - Scout 扫描要求:无论
target_filename是否存在,始终使用goldfish-explorerscout 扫描源代码,以获取D的真实代码符号边界。 - 提取并修正旧内容:如果
target_filename存在,请使用以下提示词调用推理 LLM:> "Analyze the following unstructured documentation content. Extract all public symbol names, classes, interfaces, invariants, and side effects. Format your response strictly as a JSON object matching the following schema: { "interface": string[], "invariants": string[], "side_effects": string[] }." 将提取出的符号与 scout 扫描得到的代码符号合并。使用文件编辑工具(或文件写入工具)修正并更新现有契约文件,使其符合 EGM,同时保留开发者备注和说明。
- 如果
-
Scout 的生成与限制:为
D生成goldfish-explorerscout。- Scout 限制:每个目录读取的数据总量上限为 50,000
字节。每个实现文件和架构文件最多读取 300 行。如果目录大小超过 50 KB,请按以下优先级选择文件:
- 接口、架构、IDL 和头文件(
.h、.hh、.hpp、.proto、.graphql、.gql、.thrift、.prisma、.sql架构/DDL 定义、接口类)完整读取。 - 模块入口文件(
main.*、index.*、lib.*、mod.*、__init__.py或与目录同名的文件)最多读取 300 行。 - 按字母顺序排列的生产代码和配置文件,在达到上限前最多读取 300 行。
- 完全忽略测试文件。
- 接口、架构、IDL 和头文件(
- 测试文件过滤:对于同时包含生产文件和测试文件的混合包目录,确保 scout 过滤掉测试文件(
*_test.*、*Test.*),并忽略其中的符号。 - 子任务容错:如果 scout 失败或超时,请记录警告,使用占位值
["(Details pending/documentation failed)"],并继续执行。
- Scout 限制:每个目录读取的数据总量上限为 50,000
字节。每个实现文件和架构文件最多读取 300 行。如果目录大小超过 50 KB,请按以下优先级选择文件:
-
父级上下文传递:处理父目录
P时,获取其直接子目录的已编译接口摘要。- 传递启发规则:
- 如果子目录在本次运行中已生成文档,直接从内存执行缓存中获取其公共接口。
- 如果子目录已修正/修改(修正策略),则使用合并后的旧内容提取符号。
- 调用
P的 explorer scout 时,将这些子目录符号块作为提示词上下文传入。
- 传递启发规则:
-
验证命令目标查找:使用发现的
VerificationCommand填写“验证”部分。- 如果项目使用 Bazel/BUILD 文件:检查
D或最近的祖先目录中是否存在BUILD文件,并引用bazel test/bazel build。 - 如果项目使用其他清单文件(
package.json、Cargo.toml、go.mod、pyproject.toml、Makefile),则填写相应的测试运行器命令。 - 如果未找到验证命令,则省略该项或使用占位值。
- 如果项目使用 Bazel/BUILD 文件:检查
-
目录分类与模板生成:根据
D的分类,使用文件写入工具或文件编辑工具生成或修正target_filename。- 组件包(Peanut):
D包含直接源代码 文件。使用组件包 README 模板。(如果还包含子目录,则在接口部分加入指向其契约的相对链接)。 - 仓库蓝图(Hay):
D不包含直接源代码 文件,但包含带有代码契约的子目录。使用 中间蓝图 README 模板。 - 链接格式策略(关键):包契约文件必须采用
混合链接格式,以兼顾可移植性和清晰度:
- 仅为现有文件使用相对链接:对于同一代码库子系统内的子级
契约和同级文件引用,使用相对路径
(例如,
./child/${target_filename}或../sibling/${target_filename})。(关键:仅当子目录存在于精简后的subtree_index中,且其中包含实际的${target_filename}时,才生成[Child](./child/${target_filename})链接。如果子目录包含SKILL.md或其他非契约资源,则直接链接到./child/SKILL.md,或将其格式化为不带链接的 项目符号。切勿输出指向不存在契约文件的推测性 链接。) - 绝对链接:引用包子系统之外的文件时 (例如,跨包依赖),使用标准 URL 或仓库路径。
- 仅为现有文件使用相对链接:对于同一代码库子系统内的子级
契约和同级文件引用,使用相对路径
(例如,
- 组件包(Peanut):
-
Markdown 格式:在
D中写入或更正target_filename后,立即确保 Markdown 格式规范(标题、 表格和代码围栏有效)。如果仓库中配置了项目 Markdown 格式化工具(例如,npx prettier --write), 可以对target_filename执行该工具。
-
-
工作器报告:分配的子树遍历完成后,编制
subtree_index数组,为每个已处理目录包含path、summary、interface、invariants和side_effects。 -
如果
is_worker为true,请相对于此技能目录读取 Worker Return Interface Schema,然后向 Root Orchestrator 返回符合要求的 JSON 负载并终止。如果is_worker为false(顺序模式),则直接进入步骤 5:根目录 汇总与终止。
步骤 5:根目录汇总与终止(Root Orchestrator)
-
接收工作器负载:收集所有并行子 Orchestrator 返回的 JSON
subtree_index负载。- 根级容错:如果并行工作器失败或超时,记录
警告,在根蓝图的子目录索引中插入占位警告链接(
[Subtree Root] (Documentation failed / Subagent execution timeout)),并完成剩余汇总。 (工作器失败后留下的部分文件作为增量进度功能处理;更正策略允许在后续 运行中继续。)
- 根级容错:如果并行工作器失败或超时,记录
警告,在根蓝图的子目录索引中插入占位警告链接(
-
中间目录文档:识别根
path与已划分的子树根之间的所有 中间目录。- 自底向上依次处理这些中间目录。
- 使用工作器返回的汇总信息,生成中间蓝图契约文件。
- 确保每个中间蓝图契约文件格式规范,且相对链接有效。
-
根目录文档:执行的目标根
path始终 分类为仓库根目录(蓝图 / Hay)。- 检查
target_filename是否已存在于path中。如果存在,请遵循 Correction & Modification Policy,读取并保留根契约文件顶部现有的 标题、元数据和架构概述。 - 检查
path本身是否包含任何直接源文件。如果包含,请针对path启动一个goldfish-explorer侦察 Agent,以提取本地符号和不变量, 并将其附加到可选的## Local Interface & Invariants部分下。 - 使用 Repository Root Blueprint
Template 编译最终的根
target_filename,汇总所有顶层子目录边界。 - 使用文件写入工具编写根
target_filename。
- 检查
-
最终正确性验证(关键):在结束工作之前,必须对
subtree_index中所有新建和已修改的契约文件进行最终验证(包括所有子包契约文件,如pkg1/${target_filename}和pkg2/${target_filename}),以检查正确性。必须明确读取每个新建或已修改的契约文件,以验证其内容。不得跳过任何子契约文件。请验证:- EGM 合规性:确保
Interface、Invariants和Side Effects部分均存在且内容完整。 - Markdown 语法:确保标题格式整洁、表格有效,且代码块围栏正确。
- 有效且可解析的链接(关键):确保所有子目录和
同级链接均使用有效的相对路径(
./subdir/${target_filename}或./subdir/SKILL.md),并明确验证每个引用的目标文件在文件系统中确实存在。移除或修正任何失效的相对引用。 - 有效的目标:验证目标与项目测试配置一致。
- EGM 合规性:确保
-
可选的偏差审查(关键):验证后,询问用户(如果运行环境提供结构化提问工具,则使用该工具;否则通过普通聊天询问)是否要对生成的文档更新运行偏差报告:
question:"Do you want to run the EGM Drift Report on the generated contract updates to check for consistency with the codebase?"options:["(Recommended) Yes, run drift report on modified contracts", "No, skip drift review"]- 如果用户选择“Yes”,则运行
egm-drift-report技能,针对已修改的契约检查文档是否准确反映当前代码库状态。(注意:虽然egm-drift-report通常用于设计文档,但也可以作为一种变体应用于符合 EGM 规范的契约。)
-
成功终止执行。
模板
📄 组件包(Peanuts)README 模板
# [Component Name]
## Overview
[Prose overview of the component's architectural role and goals]
## Interface
- [Public classes, functions, and symbols]
- [Subdirectories list and relative links to their contracts (e.g., `./subdir/README.md` or `./subdir/${target_filename}`)]
## Invariants
- [State and call invariants that must be preserved by developers/agents]
## Side Effects
- [State mutations, network calls, disk access, locks, or external side effects]
## Verification
- Run: `<test-command>`
📄 仓库根目录(Blueprint / Hay)README 模板
# [Repository Name] Blueprint
## System Overview
[High-altitude architectural overview of this subsystem]
[Optional section if the root directory contains direct source files]
## Local Interface & Invariants
- [Direct symbols, invariants, and side effects of files in the root folder]
## Subdirectories & System Boundaries
- [Subdirectory Name]: [Relative link to existing child contract file (e.g., `./subdir/README.md` or `./subdir/${target_filename}`) or `./subdir/SKILL.md`] - [Summary of child contract/role]
## Global Invariants
- [System-wide constraints that cross component boundaries]
## Global Side Effects
- [Shared resources, databases, or external integrations affected by this subsystem]
## System Verification
- Run: `<test-command>`
📄 中间 Blueprint README 模板
# [Directory Name]
## Overview
[Factual overview of the subdirectories and systems grouped under this directory path]
## Subdirectories & Boundaries
- [Subdirectory Name]: [Relative link to existing child contract file (e.g., `./subdir/README.md` or `./subdir/${target_filename}`) or `./subdir/SKILL.md`] - [Summary of child contract/role]