claw-code 源码详细分析:Bootstrap Graph——启动阶段图式化之后,排障与扩展为什么会变简单?

涉及源码src/bootstrap_graph.pysrc/setup.pysrc/system_init.pysrc/runtime.pysrc/main.pytests/test_porting_workspace.py


1. Bootstrap Graph 是什么:一份"运行时故事"的最小公共语言

bootstrap_graph.py 给出一个非常短的阶段列表(字符串元组),并提供 as_markdown() 输出:

python 复制代码
# 16:26:src/bootstrap_graph.py
def build_bootstrap_graph() -> BootstrapGraph:
    return BootstrapGraph(
        stages=(
            'top-level prefetch side effects',
            'warning handler and environment guards',
            'CLI parser and pre-action trust gate',
            'setup() + commands/agents parallel load',
            'deferred init after trust',
            'mode routing: local / remote / ssh / teleport / direct-connect / deep-link',
            'query engine submit loop',
        )
    )

它不是"精确调用栈",而是把启动过程压缩成可讨论的阶段节点 :任何人在排障或扩展时,都可以先回答"我现在卡在哪个阶段"。这会把讨论从"你那边怎么跑的"变成"我们在 deferred init after trust 之前就挂了"。


2. 为什么图式化会让排障简单:把故障面切成可观测的段

在 claw-code 的 Python 端,几条子命令本身就是"阶段探针":

  • bootstrap-graph:只输出阶段图(最小故事)。
  • setup-report:只跑 setup/预取/延迟初始化(启动中段的可观测切片)。
  • bootstrap:跑"从 context + setup + route + shim + query + persist"的一轮全链路报告。
  • remote-mode/ssh-mode/...:跑"mode routing"族的模拟分支探针(见 result/13.md)。

这样排障时你不需要一次性复现"整套系统",而是可以按阶段逐段缩小范围:

  1. 只看阶段图是否对齐bootstrap-graph
  2. 只看 setup 是否健康setup-report:预取与 deferred init 的输出)
  3. 再看全链路是否能跑通bootstrap:输出路由、shim、turn、落盘)

这也是为什么"阶段图"本身虽然短,但很值钱:它让你能把 CLI 报告组织成分段可运行的诊断面板


3. 阶段图如何与实际实现互相印证(不是空口)

3.1 "setup() + commands/agents parallel load" 在代码里的对应物

setup.pyWorkspaceSetup.startup_steps() 明确列出:加载命令/工具快照、准备 parity hooks、信任门后的 deferred init:

python 复制代码
# 19:27:src/setup.py
def startup_steps(self) -> tuple[str, ...]:
    return (
        'start top-level prefetch side effects',
        'build workspace context',
        'load mirrored command snapshot',
        'load mirrored tool snapshot',
        'prepare parity audit hooks',
        'apply trust-gated deferred init',
    )

system_init.py 把这些 steps 打进 # System Init 报告里,并同时打印已加载的 command/tool 数量:

python 复制代码
# 8:23:src/system_init.py
def build_system_init_message(trusted: bool = True) -> str:
    setup = run_setup(trusted=trusted)
    commands = get_commands()
    tools = get_tools()
    lines = [
        '# System Init',
        '',
        f'Trusted: {setup.trusted}',
        f'Built-in command names: {len(built_in_command_names())}',
        f'Loaded command entries: {len(commands)}',
        f'Loaded tool entries: {len(tools)}',
        '',
        'Startup steps:',
        *(f'- {step}' for step in setup.setup.startup_steps()),
    ]

这意味着:当你怀疑"清单没加载 / 环境不对 / deferred init 未触发",不必看日志大海,直接看 System Init 段落即可。

3.2 "query engine submit loop" 的最小可复现

bootstrap_session 把 route、shim、QueryEnginePortstream_submit_message / submit_messagepersist_session 串成一份 Markdown:

python 复制代码
# 109:152:src/runtime.py
def bootstrap_session(self, prompt: str, limit: int = 5) -> RuntimeSession:
    context = build_port_context()
    setup_report = run_setup(trusted=True)
    ...
    matches = self.route_prompt(prompt, limit=limit)
    ...
    stream_events = tuple(engine.stream_submit_message(...))
    turn_result = engine.submit_message(...)
    persisted_session_path = engine.persist_session()
    ...

排障时你只要跑 python3 -m src.main bootstrap "<prompt>",就能看到:

  • 路由命中了哪些条目(Routed Matches)
  • shim 说"会怎么执行"(Command/Tool Execution)
  • 流式事件顺序与 stop_reason(Stream Events)
  • 会话是否落盘(Persisted session path)

阶段图让人知道该从哪一节看起:例如怀疑"路由不对",就停在 Routed Matches;怀疑"引擎没写入",就看 Stream Events / Turn Result。


4. 为什么图式化会让扩展简单:新增能力先决定"插在哪一段"

扩展新能力时,最容易混乱的是:你不知道该把逻辑挂在启动哪一层,导致:

  • 初始化散落在各处(难以复现、难以测试)
  • 安全/信任门绕过(高风险)
  • 运行时状态不一致(某入口有,另一入口没有)

阶段图提供了一种强制对齐的决策框架

  • 新增预取 (例如读取某配置、扫描仓库索引)→ 挂在 top-level prefetch side effectssetup() 里,并在 setup-report 暴露。
  • 新增安全检查 (环境变量、系统保护)→ 对应 warning handler and environment guards / pre-action trust gate
  • 新增插件/技能加载 → 对应 deferred init after trust,把"不可信时不执行"的语义写死。
  • 新增连接模式 (例如新的 remote transport)→ 对应 mode routing: ...,先做 *-mode 探针,再注入 bootstrap。
  • 新增会话行为 (压缩、结构化输出、审计事件)→ 对应 query engine submit loop,优先保持 TurnResult / stream event 形状稳定。

也就是说:扩展不是"把代码塞进去就行",而是先选阶段节点,再写实现。这会天然把 PR 讨论聚焦到"你为什么把它放在 deferred init 而不是 setup"。


5. 工程化配套:阶段图 + 测试门禁

bootstrap-graph 有专门 CLI,且测试只断言标题存在,确保"文档节点"长期不丢:

python 复制代码
# 239:244:tests/test_porting_workspace.py
graph_result = subprocess.run([sys.executable, '-m', 'src.main', 'bootstrap-graph'], check=True, capture_output=True, text=True)
...
self.assertIn('Bootstrap Graph', graph_result.stdout)

同理:setup-reportbootstrap、各 mode 的模拟子命令也都有测试门禁,形成"阶段探针"体系。阶段图越稳定,这套门禁越能持续发挥作用。


6. 小结

  • Bootstrap Graph 用极短的阶段列表,把启动过程变成"可讨论的图节点",给排障与扩展提供最小公共语言。
  • 通过 setup-report / bootstrap / *-mode阶段探针式 CLI,你可以逐段缩小故障范围,而不必复现整套系统。
  • 对扩展而言,阶段图强迫你先回答"插在哪段",从而减少初始化散落、信任门绕过与入口不一致。

相关推荐
Kel2 小时前
从Prompt到Response:大模型推理端到端核心链路深度拆解
人工智能·算法·架构
Felven2 小时前
D. Matryoshkas
算法
悟空瞎说2 小时前
深度解析:Vue3 为何弃用 defineProperty,Proxy 到底强在哪里?
前端·javascript
leafyyuki2 小时前
告别 Vuex 的繁琐!Pinia 如何以更优雅的方式重塑 Vue 状态管理
前端·javascript·vue.js
Amos_Web2 小时前
Solana开发(1)- 核心概念扫盲篇&&扫雷篇
前端·rust·区块链
17(无规则自律)2 小时前
DFS连通域统计:岛屿数量问题及其变形
c++·算法·深度优先
Hooray2 小时前
AI 时代的管理后台框架,应该是什么样子?
前端·vue.js·ai编程
ZC跨境爬虫3 小时前
极验滑动验证码自动化实战(ddddocr免费方案):本地缺口识别与Playwright滑动模拟
前端·爬虫·python·自动化
某人辛木3 小时前
nodejs下载安装
开发语言·前端·javascript