Skip to content

Releases: lza6/clawd-code

v0.90.1

Choose a tag to compare

@github-actions github-actions released this 31 Oct 15:22

v0.90.1 — 容器镜像补丁:v0.90.0 的镜像在 Linux 上启动即崩

为什么发这个补丁(不想粉饰):v0.90.0 的 tag 打在最后一个容器修复之前,
于是已发布的 ghcr.io/lza6/clawd-code:v0.90.0 镜像里仍然是"/app 属 root、进程 UID 1000"
的版本 —— 在 Linux 上 clawd serve 写端口文件时 PermissionError: [Errno 13] /app/.clawd_host_port 冒到顶层,Host 直接退出,/healthz 000。
本机 Docker Desktop 不复现该权限问题,所以只有 CI 的 Linux runner 把它照出来了。

按"不 force push / 不改已发布历史"的规则,不移动 v0.90.0 的 tag,而是补 patch 版本。

修正内容(v0.90.0 之后的 4 个提交)

项 说明
容器权限 Dockerfile 改 chown -R 1000:1000 /app(原先只 chown 了 logs/.clawd)
端口文件容错 run_host 写端口文件失败降级为 logger.warning,服务继续提供 /healthz /readyz(端口文件只是"自动发现"的便利机制,不该把服务带走)
测试隔离 tests/brain/test_world_model_complex.py 的并行用例改为断言「本用例的 dependency_graph.build 经 to_thread 恰好一次且 parallel=True」,不再数全局 to_thread 调用(全局 patch 会被其他用例的索引任务污染,CI 3.10 实测 "Called 21 times")
风格 isort 导入排序、文件结尾恰好一个换行(pre-commit 收口)

验证(GitHub 真机 CI,commit 75b8cdc 前身 / 本补丁发布前)

  • CI Pipeline 整条 success:Security Scan · Lint & Type Check(含新的启动预算门禁)
    · Test 3.10 / 3.11 / 3.12 · Docker Build Test(真探活)
  • 容器探活实测输出:Clawd Code v0.90.0 ·
    /healthz {"status":"ok","version":"0.90.0"} · /readyz {"status":"ready",...} ·
    docker inspect Health.Status=healthy
  • Quality Checks(pre-commit + 覆盖率门槛)success

v0.90.0

Choose a tag to compare

@github-actions github-actions released this 31 Oct 12:17

v0.90.0 — 剩余高阶提案落地:探针/错误字典/存储体检/状态迁移/轨迹回放/启动预算/发布流水线/交互四态

承接 v0.89.1,本轮把《下一步改进指南》§7 里还没落地的高阶提案做完,并且先修掉三个
"看起来有、实际上是假的"运维基础设施缺陷 —— 它们的共同点是:没有信号,所以从来没被发现。

先说修掉的真缺陷(都是"假闭环")

缺陷 现象 根因 修法
健康检查恒真(3 处) 容器里什么都没跑,docker ps 仍显示 healthy docker-compose.yml 与 Dockerfile 的 healthcheck 分别是 python -c "sys.exit(0)" 与"import 一个模块就 exit 0" 新增 /healthz 存活端点,两处 healthcheck 改真打 HTTP
没有存活端点 运维探 /health 得到 403 Forbidden,看起来像鉴权问题 该路径不存在,请求掉进静态托管,被 mime 白名单(无后缀 → ctype=None)判成 403 新增 /healthz(免 token,不含路径/密钥)与 /readyz(数据目录可写 + LLM 已配置,不就绪 503);无后缀路径与未知 /api/* 一律 404 JSON
服务容器不服务 声明 8765:8765 端口与健康检查,但端口没人监听 镜像默认 CMD ["chat"] 是交互式命令 默认改 serve;compose 显式 command: serve --port 8765
镜像里没有代码 容器启动即 ModuleNotFoundError: No module named 'src' 构建阶段 pip install . 在还没有源码的目录执行 → 装出一个空的 dist-info 先 COPY src / COPY prompts 再装自身
依赖漏装 + 端口出不了容器 修好上一条后变成 No module named 'typer';容器 healthy 但宿主机连不上 ①装自身时加了 --no-deps(typer 只在 pyproject,不在 requirements.txt);②run_host() 硬编码 host="127.0.0.1",AGENT_SERVER_HOST 对 clawd serve 完全无效 ①去掉 --no-deps(以 pyproject 为准);②新增 resolve_bind_host()(env 优先、默认仍 loopback),端口文件写客户端可连地址
深度诊断缺失 "面板空白 / 越用越慢"只能靠猜 没有存储体检,doctor 只看环境 clawd doctor --deep:SQLite integrity_check + 表行数 + 体积 top10 + 可回收空间与 VACUUM 建议

新增能力(X-3 / X-6 / X-8 / X-9 / X-10 / X-11 / X-12)

  • X-8 中文错误字典:src/core/errors_catalog.py 覆盖全部 53 个 ErrorCode
    (zh_title / zh_message / next_step / doc_url / severity),入口 clawd errors [码] [--json];
    未登记的码不报错、给兜底说明。文案单一来源,docs/troubleshooting-errors.md 只做索引。
    测试同时用两条独立断言守"枚举成员 ⊆ 词条"(防函数自身有 bug 时假绿)。
  • X-10 存储健康自检:src/core/storage_health.py(只读连接 file:...?mode=ro,
    单库损坏不中断整体、不静默),接进 doctor --deep。
  • X-9 状态根单一入口 + 迁移:data_dir 支持 CLAWD_HOME 别名(CLAWD_DATA_DIR 优先,
    describe() 如实标出生效变量)、state.json 布局版本(读到更高版本抛错而非静默读写)、
    clawd migrate-state --from --to [--apply](默认演练;不覆盖同名文件;可重复执行)。
  • X-3 轨迹录制 + 回放:src/eval/trajectory.py + clawd trajectory record|replay|show。
    回放固定 observation,断言工具序列/action-observation 配对/失败后原地重试/verify 覆盖;
    一条都没判定时 exit 3 拒绝给结论(不许空集合假绿)。
  • X-6 启动预算门禁:scripts/startup_budget.py 断言 -m src --version、
    import src.cli.entrypoint、已加载模块数、doctor --json 四项上界;接进 CI
    (CLAWD_STARTUP_BUDGET_FACTOR=1.8 只放大时间项,模块数不放大)。本机实测
    0.669s / 0.694s / 761 模块 / 4.119s。
  • X-11 桌面端交互四态:withBusy() / inlineError() / 全局 unhandledrejection + error
    兜底 toast(5 秒去重),覆盖 provider 保存、添加项目、pickFolder、用量/context 面板加载失败。
    真浏览器 E2E 31/31(desktop/ui_feedback_e2e.mjs)。
  • X-12 发布流水线:.github/workflows/release.yml(tag → 三处版本一致性 → CHANGELOG 抽说明
    → 构建 → 装进干净 venv 冒烟 → 幂等发布)+ scripts/changelog_notes.py
    (取不到说明就 exit 2,不发空壳 release)。

测试

  • 新增测试文件 12 个 / 290 条用例(收集 5469 → 5759,0 errors)。
  • 新增 tests/scripts/test_workflows.py:工作流 YAML 语法 + 关键门禁存在的结构锁
    (本轮实测就抓到 release.yml 被 heredoc 破坏成非法 YAML —— 这类错误不跑结构检查
    就要等推送后才发现;历史上 .pre-commit-config.yaml 也是这么常红的)。
  • 新增 tests/scripts/test_docker_config.py:把"先 COPY 再装""不许 --no-deps""容器绑 0.0.0.0"
    "CI docker 冒烟不许 || true"四条钉死。
  • 新增 tests/server/test_health_endpoints.py(真实 HTTP):探针不泄密、未知 API 404、
    静态托管与目录穿越无回归、AGENT_SERVER_HOST 真正生效。

已知边界(不粉饰)

  • 正式代码签名仍需 CA 证书(现为自签名,Status=UnknownError 属预期)。
  • 启动预算的默认值来自本机 Windows 实测,CI 用宽松系数 —— 它抓得住"量级退化",
    抓不住 CI 上 10% 级别的抖动。

v0.89.1 — CI Linux 矩阵清零(35 failed + 4 errors → 0)

Choose a tag to compare

@lza6 lza6 released this 30 Oct 23:54

主题

CI Linux 测试矩阵清零:35 failed + 4 errors → 0,并把两条真被掩盖的安全缺陷修掉。

为什么会有这个版本

v0.89.0 的 quality-checks 已绿,但 ci.yml 的测试矩阵跑在 Linux 上。
一批只在 Linux 暴露、Windows 本机完全看不见的缺陷在那里一直红着
(历史上被当作"存量 flaky"忽略)。本次逐条查实根因后修复。

产品缺陷(8 条)

# 缺陷 严重性
1 FileReadTool 在子线程用 signal.alarm(asyncio.to_thread 下必崩)→ 所有读文件工具失效(9 个测试) P1
2 platform_command 在 Linux 上 os.altsep is None → None in command TypeError(探活/which 全崩) P0
3 循环符号链接 a→b→a 被判安全(stat() ELOOP 被静默吞掉 → 循环检测失效)= 沙箱逃逸面 P0
4 损坏符号链接被判合法(resolve(strict=False) 假成功) P1
5 WorktreeManager.__init__ 对只读路径 mkdir → GitManager("/nonexistent") 构造即抛 P1
6 生成的 config.toml 在 Windows 非法(\p 是保留转义)→ 任何合规 TOML 解析器读不了 P1
7 CLAWD_CONFIG_DIR 被静默忽略(features.json 恒空) P2
8 codex 后端 available() 假 True(裸命令名被当路径校验) P2

测试自身缺陷(5 条)

git commit 无身份(4 ERROR)· rich 按终端宽度断行导致 --resume 子串断言假红 ·
Z:/... 在 Linux 是合法相对路径 · usage --json 取最后一行拿到 stderr 横幅 ·
顶层 import git 污染整文件收集。另 dev extras 补 pathspec。

验证(全部实跑)

  • Linux 容器(python:3.11-slim + git,复刻 ci.yml 矩阵):原失败集 464 passed / 0 failed
  • Windows 本机:全量非 slow 5441 passed / 0 failed(378.51s)
  • 装机 E2E(v0.89.1 安装包):0 失败 —— STEP1 版本/内嵌 host/prompts · STEP2 API×5 + 无 token 403 ·
    STEP2b 真浏览器 UI E2E 32/32 · STEP2c 重启持久化 · STEP3 残留 0 · STEP4 卸载 exit 0 · STEP5 注册表 0
  • 收集 5464 / 0 errors · IMPORT-FAIL 0 · 可达 503 · 生产可达未降
  • 静默吞异常 155 → 154(path_guard 的 except OSError: pass 消除),门禁同步收紧(只降不升)
  • ruff 硬指标(全仓)0 错误

产物

  • Clawd Desktop Setup 0.89.1.exe / ClawdDesktop-Portable-0.89.1.exe(自签名验证管线)
  • 本 tag 同时用于重新触发 ghcr 镜像构建(v0.89.0 的镜像因 opentelemetry-instrumentation-logging>=0.50.0
    这个永远无解的版本约束(PyPI 只有 0.xxb0 预发布版)而构建失败;该约束已修)。

已知边界(如实)

  • 正式 CA 代码签名仍需外部证书 → 已确认保持自签名并列为外部阻塞(SmartScreen 会提示未知发布者)
  • 真实视觉对话仍需支持 image_url 的端点(scripts/probe_vision_endpoint.py 可复现)

附注

  • 本 tag 内容里的 tests/scripts 基线断言(静默吞异常阈值 154)由紧随其后的提交 8ace867 修正;
    该文件只影响仓库内测试门禁,与安装包运行时行为无关。
  • 安装包与镜像均以本 Release 的产物为准。

v0.89.0 — CLI --json 全覆盖 + R6 + P3 清零

Choose a tag to compare

@lza6 lza6 released this 30 Oct 19:13

主题

查询类 CLI 命令全部接入 --json 契约(X-7 收尾)+ 视觉降级轮内重试(R6)+ P3 台账五项清零。

亮点

  • CLI:explore / pipeline / ralplan / quality-gate / config / permissions / agent list·show·keywords·intent / autonomy list·log / role show / eval 全部支持 --json(契约 {ok, code, ...},退出码=code,错误也是合法 JSON);--json 时日志改道 stderr,\| jq 永不崩
  • R6:带图请求失败的自动降级改为轮内原地重试,不再消耗 max_iterations(修"max_iterations=1 时降级等于没生效")
  • P3 五项:工具签名接生产调用方(config --generate → tool_signatures.json)、git 只读清单单一来源、删死参数 cwd、fast_mode 截断必告知、litellm 兜底缓存写价
  • 工程化:装机 E2E 入库 scripts/e2e_desktop_install.ps1(可重复、有退出码)

验证(全部实跑)

  • 全量非 slow:5440 passed / 0 failed;收集 5464 / 0 errors
  • 覆盖率 66.27%(门禁 60);静默吞异常 155(未回升);生产可达 503(未降)
  • 真实端点:e2e_smoke 5/5 · e2e_production 8/8
  • 压测(本地 Host):200 并发 QPS 2514 / P99 15.6ms / 错误率 0%
  • verify_audit_p1 28/28 · doc_drift 全一致 · 版本三处一致 0.89.0

边界(如实)

  • 正式代码签名仍需 CA 证书;真实视觉对话需支持 image_url 的端点
  • 交互式/长驻命令(chat/run/serve/collaborate/workflow *)故意不提供 --json

完整变更见 CHANGELOG.md。
回滚:git checkout v0.88.10(数据目录与安装目录分离,回滚不影响用户数据)。

v0.61.0 — 超级智能体增强 + DSH 式桌面端

Choose a tag to compare

@lza6 lza6 released this 27 Oct 22:15

🚀 亮点

超级智能体能力

  • MCP 桥接: stdio + Streamable HTTP 双传输、工具签名+检疫审批(防 tool poisoning)
  • 推理模式: reflexion / plan-execute / lats / debate 四种反推循环(clawd reason CLI)
  • 逆向工具集: Ghidra HTTP 桥、strings/熵分析/hexdump、objdump/binwalk 等 8 个原生工具
  • 安全工具目录: YAML 数据驱动,scope 授权门禁 + 命令注入拦截 + 危险工具双重确认
  • 逆向知识库: 51 个场景 SKILL.md(固件/Ghidra/IDA/恶意软件/协议/pwn/CTF)
  • 插件体系: 万物皆插件(manifest + DI Context + 工具/Prompt/UI 接入面 + 插件市场)

桌面端(DSH 模式)

  • Python Host: clawd serve — WS + 端口文件发现 + 同端口 Web UI 托管
  • DSH 设计规范 UI: 三阶深灰 + #536dfe 品牌蓝、侧栏工作台、插件市场毛玻璃弹窗、工具调用实时折叠行
  • Electron 壳: spawn Host / 托盘 / 单实例 / 崩溃自愈 / TF 定制图标
  • 发行形态: NSIS 安装程序 + Portable 免安装 exe + electron-updater 自动更新
  • 首次配置引导: 首次启动图形化收集 API 配置

✅ 验证

  • 205+ 单元/集成测试全绿;契约测试 39 passed
  • 真实 API E2E: 引擎工具链路 PASS + 推理模式 PASS
  • Playwright UI E2E: 真实对话+工具调用 PASS
  • 安装版真机终测 PASS(配置引导→连接→真实对话)
  • 压测: 200 并发 / QPS 1418 / P95 10.5ms / 错误率 0%

📦 产物

  • Clawd Desktop Setup 0.1.0.exe(164MB,NSIS 安装程序)
  • ClawdDesktop-Portable-0.1.0.exe(164MB,免安装)

🔧 关键修复

  • system prompt 注入工具参数 schema(修模型猜参数名)
  • 原生 function calling 默认开启(文本 协议被现代模型无视)
  • 事件实时广播(sync handler 调度修复)
  • CLI 双入口同步铁律(Typer/argparse 三处一致)

⚠️ 已知限制

  • 更新源为占位域名(docs/RELEASE_UPDATES.md 有配置说明)
  • js-reverse-skill 上游未声明 LICENSE,商用分发前需确认
  • 17 个存量测试失败为 Windows 环境问题(缺 bash/echo、redis),与功能无关

Full Changelog: 1f84498...1261b64

v0.59.0 — pipeline 阶段去占位、验证目录修正

Choose a tag to compare

@lza6 lza6 released this 18 Oct 18:08

概述

独立审查(review-d)判定 REQUEST_CHANGES。两条阻塞项复现后修复;
处理过程中又发现两个从未能工作的占位阶段。

1. ralplan / team-exec 是占位实现却报 SUCCESS

两个阶段此前不调用任何引擎,直接返回 "<未实现>" 并把阶段标成 SUCCESS ——
调用方会以为"计划已产出、worker 已执行"。

现接真实引擎:

阶段 真实实现 失败语义
ralplan RalplanEngine.run(),产物 plan/prd/tasks/confidence 异常 → FAILED
team-exec SwarmEngine.run(),产物 execution_result/errors swarm 失败 → FAILED

2. precontext-intake 导入不存在的模块

from .intake import IntakeGate —— src/workflow/intake.py 从未存在,
异常被捕获后仍返回 SUCCESS,等于永远"成功"地什么都没做。

改为真实的最小扫描:统计目标目录的 .py 文件数/行数、列出最大的若干文件;
失败返回 SKIPPED(不是 SUCCESS)。

3. stages/ralph_verify_stage.py 用错验证目录(审查阻塞项)

Path(self._config.cwd) 默认 ".",忽略 ctx.cwd —— 若挂进管道会在
进程当前目录跑测试,可能对另一个项目报 passed。

改为 Path(ctx.cwd);并把"失败后原样重试同一命令最多 10 次"改为不重试
(没有重新实现步骤,重试没有意义)。

4. search_replace 修复补齐回归测试(审查阻塞项)

此前 28 个用例都不进入 git 策略,43 passed 证明不了该分支有效。新增 7 条:

  • 普通策略异常 → 返回失败,且 error 带异常类型(不再一律"未找到匹配")
  • MemoryError / RecursionError → 仍向上抛(资源级问题不得降级)
  • 非 git 目录 → 回退矩阵不中断

5. 其他

  • 非法 CLAWD_VERIFY_COMMAND(未闭合引号)→ 返回 status="error",不再穿透
  • pipeline.py 工厂 docstring 声称"持久循环"但只跑一次 → 更正
  • docs/MAINTENANCE.md 的"验证阶段是桩 / 覆盖率 ~20%" → 同步真实状态

验证

pytest tests/ -q                                  → 3095 passed / 0 failed
ruff --select F821,F811                           → All checks passed
scripts/import_sweep.py                           → 0 缺陷(640 模块)
scripts/reachability.py                           → 431 生产可达
真实 pipeline E2E(intake + ralph-verify)         → completed;扫到 1 文件;verified=True

仍未闭合

覆盖率 46.15%(目标 60%)· 死模块 135 · 静默吞异常 101 · CLI 启动剩余 ~20s ·
容器部署与线上热更新(缺 Docker / 部署目标与凭证)。

🤖 Generated with Claude Code

v0.58.0 — 验证阶段真实现、覆盖率口径修正、编辑核心修复

Choose a tag to compare

@lza6 lza6 released this 18 Oct 12:56

概述

三个实质变化:验证阶段从“诚实”变成“真的会验证”、修正了长期错误的覆盖率口径、修掉编辑核心两处真实缺陷。

1. 验证阶段真的会验证了

新增 src/workflow/verification_runner.py:

  • 默认命令:<cwd>/tests/ 存在 → python -m pytest -q --tb=short tests
  • CLAWD_VERIFY_COMMAND 可覆盖(Windows 引号/反斜杠已处理)
  • 以退出码判定,保留命令、耗时、输出尾部作为证据
  • passed / failed / timeout / error / not_configured
  • 未配置时返回 not_configured,绝不冒充通过

接线:

  • pipeline.py 的 ralph-verify:passed→SUCCESS,failed/timeout/error→FAILED,not_configured→SKIPPED
  • stages/ralph_verify_stage.py:未通过返回 failed(此前恒返回 completed),未配置时提前结束迭代

2. 所有 pipeline 阶段真实执行时崩溃(P0)

4 个内嵌阶段类都用 self._logger,但基类 PipelineStage 没有该属性 ——
真实执行第一个阶段就 AttributeError。此前只测注册与构造,从未真正跑过阶段。

修复后做了真实端到端验证:构造含 ralph-verify 的 pipeline,实际执行,verified=True。

3. 编辑核心两处真实缺陷

位置 问题 后果
udiff_parser._directly_apply_hunk 从 search_replace 导入不存在的 SearchTextNotUnique(该名字定义在本模块) apply_hunks 的直接应用分支永远 ImportError
search_replace.try_strategy 只捕获 (ValueError, IndexError, OSError);InvalidGitRepositoryError 穿透 非 git 目录下多策略回退矩阵中断,编辑失败

新增 tests/tools_runtime/test_udiff_parser.py(15 用例)。

4. 覆盖率口径修正

文档长期写“~20%”,来自 2026-10-15 的陈旧 coverage.json。全量 pytest --cov=src 实测:

覆盖率  46.15%(25,877 / 56,072 行)

仍低于 fail_under = 60,但 v0.53 目标(≥35%)已达成。
README / 指南 / workflow_status 中的旧数字已更正。

新增 scripts/coverage_gap.py:只对「生产可达」模块看覆盖缺口,
避免给死代码刷覆盖率数字。

5. 部署验证边界

  • 本地安装已验证:pip install -e . 成功;clawd.exe --version / agent keywords / catalog reload 全部实跑通过
  • 容器部署未验证:本机未安装 Docker,docker compose build/up 无法执行;
    docs/MAINTENANCE.md 已写清缺失条件与恢复验证步骤,不冒充已部署
  • 本项目是 CLI/库,无常驻服务进程;“线上热更新”没有可验证的落地路径

验证

pytest tests/ -q                     → 3079 passed / 0 failed
ruff --select F821,F811              → All checks passed
scripts/import_sweep.py              → 0 缺陷(640 模块)
scripts/reachability.py              → 431 生产可达(新增 verification_runner 与 verifier)
真实 pipeline 端到端(ralph-verify)  → SUCCESS, verified=True
pip install -e . + clawd.exe         → 通过

仍未闭合

覆盖率 46.15%(目标 60%)· 死模块 135 · 静默吞异常 101 · CLI 启动剩余 ~20s ·
容器部署与线上热更新(缺 Docker / 部署目标与凭证)。

🤖 Generated with Claude Code

v0.57.3 — pipeline 命令修复与静默失败清理

Choose a tag to compare

@lza6 lza6 released this 17 Oct 22:59

概述

v0.57.2 发布后继续处理审查报告里的补充项。最要紧的一条:clawd pipeline 也是“注册成功但运行即崩”。

clawd pipeline 三处错位,运行即 TypeError

PipelineConfig(use_team=..., use_ralph=..., budget=...)   # 三个参数都不存在
PipelineOrchestrator(Path.cwd(), config)                  # 参数顺序反了
await orchestrator.execute(goal)                          # 方法不存在

重写为真实 API:

stages = [create_ralplan_stage(), create_team_exec_stage(), create_ralph_verify_stage()]
config = create_autopilot_pipeline_config(task=goal, stages=stages, cwd=cwd)
result = await PipelineOrchestrator(config, cwd=cwd).run()

--budget 在编排器上未实现,命令明确提示不生效(而不是静默忽略)。
新增 wiring 测试,断言命令体不抛错且确实把 goal 交给编排器。

锁文件损坏不再静默覆盖

LockStore.acquire() 解析失败时 except Exception: pass,随后直接覆盖写 ——
两个 owner 可能同时认为自己持锁,正是锁要防的事。
现改为 logger.error + 将损坏文件隔离为 *.corrupt-<ts> 再重建(可见且不 deadlock)。
release() 失败也不再静默吞掉。

其他

  • HookPluginDispatchResult.duration_ms 声明两次(后者把必填字段静默改成可选)→ 去重
  • sanitize_plugin_id() 用 str.replace(r"...") 做“正则清洗”,实为字面量替换,
    完全不生效 → 改为 re.sub。实测 My Plugin!@#.py → my-plugin
  • memory_server.search() 读到损坏 JSON 静默跳过 → 增加带路径的 logger.warning

验证

pytest tests/ -q                     → 3051 passed / 0 failed
pytest tests/cli tests/workflow tests/core -q → 1081 passed
ruff --select F821,F811              → All checks passed
python -m src pipeline --help        → 正常
python -m src catalog list / reload  → 正常

仍未闭合

覆盖率 ~20% · 死模块 135 · 静默吞异常 101 · CLI 启动剩余 ~20s · 验证阶段仍是桩。

🤖 Generated with Claude Code

v0.57.2 — 修复独立审查发现的 5 个阻塞项

Choose a tag to compare

@lza6 lza6 released this 17 Oct 21:48

概述

独立审查线程回传 REQUEST_CHANGES,5 个阻塞项全部复现并修复。
最刺眼的一条:“注册成功”不等于“命令可用”。

1. workflow 组四个命令“注册成功但运行即崩”

clawd workflow --help 能列出 ralph / ralplan / team / autopilot,
但四个命令一执行就 ImportError —— 函数体引用的是从未存在的符号:

命令 原引用 真实 API
ralph SwarmOrchestrator.execute_task()、RalphLedger SwarmEngine.run()、RalphProgressLedger
team SwarmOrchestrator.coordinate_task() SwarmEngine.run()
ralplan RalplanWorkflow.execute() RalplanEngine.run()
autopilot from .workflow_commands import create_autopilot_pipeline_config(从自身模块导入从未定义的名字) workflow.pipeline_orchestrator

四个命令体全部重写。ralph --verify 不再假装验证通过 —— 本项目验证阶段仍是桩,
命令会明确打印这一点。

新增 tests/cli/test_workflow_commands_wiring.py:用替身驱动命令体,
断言“不抛 ImportError/AttributeError、退出码正确、产物落盘”。

2. explore 只读引擎必然失败

导入不存在的 src.tools_runtime.tool_manager.create_readonly_tool_manager;
且 AgentEngine.__init__ 根本不接受 tool_manager(内部自建)。
改为构造期注入 APPROVAL_MODE=plan(真实只读门禁,拒绝一切 write/exec),
构造后还原;门禁未生效时显式告警。

3. catalog list/reload 运行即崩

  • manifest.py:111 给 SkillDefinition 传了不存在的 internal_required=True
  • CatalogManifest.get_counts() 从未存在
    修复后实测:catalog list 正常;catalog reload 输出
    “技能数 39(活跃 23)/ Agent 数 30(活跃 18)”。

4. 断点续跑从未生效(三处叠加)

  1. run() 先 start_mode()(写 index=0)再 can_resume() → 永远读到 0
  2. _complete_pipeline("failed") 写 active=False + phase "failed",
    被 can_resume() 排除 → 失败后永不可恢复
  3. 失败阶段写 index=i+1 → 恢复会跳过失败阶段

修复后恢复测试实测:calls s1=1, s2=2, s3=1(s1 不重跑、s2 重试、s3 首次执行)。

5. PipelineState 往返丢字段

save 写 pipeline_stages 但 load 不读回 → load→save 后 can_resume
由真变假;artifacts 两边都不处理。已补双向持久化 + artifacts JSON 归一化
(阶段把 ctx.cwd 放进 artifacts 时不再让整份状态写入失败)。

同时修复(审查的非阻塞项)

  • BudgetGuard 跨轮状态泄漏:复用实例后第二次 run() 继承上轮
    accumulated_cost/is_exhausted/start_time → 新增 reset_for_run()
  • _resolved_dimensions 在本次未配置维度时未清空
  • create_pipeline(cwd=...) 只影响阶段、不影响状态目录 → 对齐
  • memory_server 文档仍称“语义搜索”(实为子串匹配,score 恒 1.0)→ 如实修正
  • types.py 去重后残留 4 个孤立 @dataclass;测试未使用 import

验证

pytest tests/ -q                     → 3050 passed / 0 failed
pytest tests/cli tests/workflow tests/core -q → 1080 passed
ruff --select F821,F811              → All checks passed
scripts/import_sweep.py              → 0 缺陷(639 模块)
scripts/reachability.py              → 429(与基线一致)
python -m src catalog list / reload  → 正常
scripts/verify_html_report.py        → 10 题全部通过(真实浏览器)

仍未闭合

覆盖率 ~20% · 死模块 135 · 静默吞异常 101 · CLI 启动剩余 ~20s · 验证阶段仍是桩。

🤖 Generated with Claude Code

v0.57.1 — 启动耗时 50s→8s、修复被掩盖的循环导入

Choose a tag to compare

@lza6 lza6 released this 17 Oct 17:53

概述

v0.57.0 之后继续追可用性,修了两个问题:CLI 启动要等几十秒,以及一个被导入顺序掩盖的循环导入。

启动耗时

litellm 单次导入实测约 34 秒(连带 openai / httpx / pydantic 的大量子模块),
它原本在 litellm_singleton 模块顶层导入。导入链:

src.main → cli_handlers → workflow.cli_handler → workflow
  → experience_bank → core.experience_bank → enterprise_ltm
  → litellm_singleton → litellm

结果是 clawd --version 也要等几十秒。四处改为惰性(PEP 562 保持
from ... import 兼容):

文件 改法
src/llm/litellm_singleton/__init__.py 顶层不 import litellm
src/__init__.py 公开符号按需导入,__version__ 仍即时
src/agent/__init__.py 整个 Agent 栈按需导入
src/main.py cli_handlers / cost_estimator 移入使用点

实测:import src 6.8s → 1.6s;import src.main 50.9s → ~8s。

import src.cli.entrypoint 仍有 ~20s:剩余成本来自 src.core.__init__
与 src.llm.__init__ 的急切再导出,需把约 60 个再导出惰性化,属独立工程。

被掩盖的循环导入(P0)

惰性化后暴露:

src.utils → diff_utils → src.core.__init__ → core.telemetry
  → tracing_utils → src.rag.__init__ → rag.text_indexer
  → from ..utils import get_logger        ← utils 尚未完成初始化

受影响的是以 from src.utils import ... 作为进程第一个导入的任何调用方,
包括 CodeGraph.build 的 ProcessPoolExecutor 子进程 —— 实测抛
BrokenProcessPool。

修复两步:

  1. src/utils/__init__.py 在 from . import ... 之前只提前绑定 get_logger。
    不能把整行 logger 导入提前:随后导入 .debug 子模块会把 utils.debug
    覆盖成模块对象,调用时报 TypeError: 'module' object is not callable
    (第一版修复踩了这个坑,全量测试 56 红)。
  2. core/args_parser.py / evolution.py / memory_guard.py 改为直接从
    ..utils.logger 导入。

静态可达性

惰性导出会让 scripts/reachability.py(AST 建图)看不见这些模块,
生产可达数从 429 掉到 427。在两个 __init__ 中加 TYPE_CHECKING 块显式列出
来源模块:运行时零成本,静态 AST 仍可见。实测恢复 429。

确定性测试

tests/performance/test_rag_pressure.py 原断言
inc_duration < scan_duration * 0.2 依赖墙钟,在满载机器上随机失败
(全量跑红、单独跑绿,已复现)。改为统计 SymbolExtractor.extract
调用次数,断言增量扫描重解析数为 0 —— 确定性且更贴近该优化的真实语义。

验证

ruff --select F821,F811        → All checks passed
scripts/import_sweep.py        → 0 缺陷(639 模块)
scripts/reachability.py        → 429(恢复)
pytest tests/ -q               → 3042 passed / 0 failed
pytest 受影响子集               → 892 passed
from src.utils import get_logger(首导入)→ OK
CodeGraph.build                → OK(子进程不再 BrokenProcessPool)

🤖 Generated with Claude Code