24 · 排错、测试证据与进一步练习¶
24.0 用检查点定位自己的第一个失败¶
| 本地观察 | 先打开哪个证据 | 进一步定位 |
|---|---|---|
| 阶段0没有完成 | stderr与summary是否生成 | CLI版本、dist、PATH、profile启动 |
| 阶段1只收到摘要 | requests.json的call-2结果 | read工具参数/执行结果,而非先改prompt |
| 阶段3仍有全文 | 第3请求指定call-2的tool_result | notes-policy是否激活、是否命中ID |
| 阶段4显示completed | 请求数、step/start、turn/end | maxSteps配置是否整份覆盖生效 |
| 阶段5读不到数据 | close是否成功、home路径、官方reader错误 | writer drain、generation/codec,不靠sleep |
| reason completed但任务没完成 | summary.acceptance与taskStatus | 缺证据、缺引用或只是runtime-only |
在修改源码后先build;测试读的是dist,运行旧编译文件会制造“代码改了却不生效”的假象。下面按启动、输入、模型、工具和业务结果继续缩小范围。
24.1 优先看失败发生在哪一层¶
Client Promise resolve、root idle、tool result 与文件flush是不同层次。排查前保留durable events与最小错误信息,输出凭据/header会制造新的问题。
24.2 常见问题对照¶
| 现象 | 优先核对 | 修法 |
|---|---|---|
| 找不到dsh | npm安装、PATH、公开dsh_bin是否可执行 | 用同版本launcher,别指向无shebang/nonexecJS |
| plugin导入失败 | dist是否build、module绝对路径、ESM类型 | npm run build后用new URL/fileURLToPath生成路径 |
| 自写tool未出现 | inject服务、provider激活、注册scope、实际profiledump | 核对tree,别只看源文件存在 |
| baseURL未生效 | 大小写、rowconfig整体替换、环境endpoint | 使用实际config键baseURL;不要靠fallback掩盖typo |
| API401但run返回 | turn/end reason与assistant/attempt | 归类error,别将idle/空answer当success |
| 被预算阻止 | maxSteps、同turn计数、pre-stepdecision | 检查blocked并决定业务失败/显式后续动作 |
| 重试比step多 | llm retryattempt不再进入pre-step | 加独立attempt/elapsedbudget,别误计step |
| tool报错但文件已改 | body/observer/postgate发生顺序 | 检查现实副作用,不盲目重试非幂等动作 |
| SDK结束还找不到session文件 | writerflush时点和真实session路径 | 正常close后再读;生产要明确durableack |
| Python导入失败 | interpreter路径、requirements、vendor路径 | 安装依赖并设置DSH_COURSE_PYTHON |
| Python看到宿主env | SDKenv合并与Python父环境 | 宿主先allowlist启动Python |
| 中文搜索没结果 | 搜索separator、索引载入、浏览器error | 看search_index和真实输入,不只验证asset200 |
| Mermaid显示源代码 | 浏览器runtime、fencehook、mermaidSVGerror | 检查本地脚本与实际SVG |
| 下载不符本地 | CDNcache、revision、服务器发布目录 | 对公网字节算SHA,不只看200 |
24.3 实际执行范围¶
本轮21项测试与六阶段实验的实际输出在labs下载重建。本轮增加检查点、业务gate与冷读验证,行为证据见20章和research/astra;旧版18项计数仅属于历史记录,不能覆盖新代码。单独的typecheck、build、TSdemo/Pythondemo、归档比对也在交付记录中。真实模型命令未运行;示例的所有正常/恶意工具选择都来自可重复fixture。
还有一些在08章介绍的toolruntime分支属于源码分析,不是本轮检查已经全部跑过:无人approval的ask、timeoutbody最终收敛、caller取消不能被wrapper覆盖、boundedparallel上下文提交顺序、conclude成功、scopeoverride/restrict、durablereplaypresentation等。要依赖这些分支应单独增加针对真实契约的测试。
npm audit针对实验安装树运行,研究记录公布实际finding和版本,不把npmci成功写成“全部依赖无漏洞”。不要把这份小实验的audit扩大成官方14,000多文件monorepo的安全审计。本轮实际auditJSON
24.4 从失败测试学设计¶
pre-execute拒绝测试用counter证明body未执行,post-executeblock测试则证明已经执行且不会回滚。这两个断言不是工具内部实现的镜像,而是宿主最容易误判的边界。bash越权测试检查真实文件不存在,失败模型调用测试检查durableerrorreason,步骤预算测试检查真实HTTPrequest数量。
单元测试可以验证一个插件自己的纯数据规则;componenttest要使用真实Cordis激活/卸载与工具runtime;integrationtest要经过真实CLI/SDK/protocol。每层用它能证明的事情,不用手写fakeContext/fakeSDK然后宣称官方路径跑通。
24.5 建议你亲手做的下一轮实验¶
- 用相同NoteStore实现一个数据库provider,保留toolconsumer,测试错误、取消、分页和tenant过滤。
- 加一个会写业务记录的tool,先定义idempotencykey和commitreceipt,再测试pre/post拒绝与重试。
- 阶段5已实现持久home与冷读;下一步选ACP/Web控制器实现真正冷继续,并核对同一Session generation与writer lease。
- 给宿主整体deadline和costledger,分别统计admittedsteps、HTTPattempts和tokenusage,检查某一限额耗尽后的收尾。
- 用真实模型做固定问答评估,将来源正确率与错误完成率保存下来,再决定是否引入PTC/MCP/subagent。
这些扩展仍是练习;其中阶段5的正常关闭/冷读已有实际证据,但冷继续尚未实现。引入外部服务/真实账户时要把认证、资源所有权和业务成功定义写进同一个评估计划。
本轮依赖审计记录¶
2026-10-04对当前实验lockfile运行 npm audit --json,注册表返回16项(7 moderate、9 high),原始JSON保存在 research/astra/npm-audit.json。这说明通过运行测试不等于依赖安全审查通过。实验保留精确rc.2来保证API/SDK/runtime一致,没有自动audit fix或混装alpha;计划产品部署时应逐项判断受影响路径及经过复核的升级方案。该结果是查询时点的依赖树报告,不是整个上游monorepo的安全审计。