Skip to content

Sandbox 测试

一个可复现的、基于证据的回答,用于回应这个问题:

Archon 的 install / update / sync / uninstall 协议在每一个支持的 IDE 与语言上,是否真的能在真实项目中端到端工作?

每个 sandbox 测试都会取一个干净的 fixture 项目(没有 .archon/, 也没有 binding 目录),运行一条 Archon 生命周期命令(通过 agent 或 CLI),并将生成的目录树与预期结果进行比对。每一次 run 都会记录日期、 manifest 版本、runner 与结果,让你可以审计真实情况,而不是承诺。

Contract 测试 的区别

层级关心的问题位于
Contract 测试"框架文件之间是否内部一致?"(文件形态、交叉引用、行数上限、禁用子串)scripts/archon-check.py,针对 .archon/contracts/governance-contract.yaml 运行
Sandbox 测试(本节)"在某个 IDE / 语言下,install 协议是否能在一个真实的全新项目上生成有效的目录树?"/zh/testing/sandbox/scenarios/ 下的 scenario 页面 —— 每个都由 fixtures/ 中的 fixture 支撑

两层都是必须的。Contract 测试是静态的,每次提交都会运行;sandbox 测试 则是 scenario 驱动的,每次发布都会运行(在新增 IDE / 语言目标时也会 按需运行)。

12 个 scenario 矩阵

第一版矩阵覆盖 生命周期阶段 × IDE × 语言,并在最常见的技术栈 (Cursor + Node + TS)上有意保留重叠,以便 update / sync / uninstall scenario 可以在 install scenario 之上链式执行。

#test-id阶段IDE语言
01install-cursor-nodeinstallCursorNode + TS
02install-claude-pythoninstallClaude CodePython
03install-codex-goinstallCodex CLIGo
04install-aider-rustinstallAiderRust
05boot-cursor-nodebootCursorNode + TS
06boot-claude-pythonbootClaude CodePython
07update-cursor-nodeupdateCursorNode + TS
08update-cli-without-cliupdate + --without=cliCursorNode + TS
09sync-cleansync(无 drift)CursorNode + TS
10sync-modifiedsync(检测到 drift)CursorNode + TS
11uninstall-preserveuninstall(保留 ledger)Claude CodePython
12uninstall-archiveuninstall(归档 ledger)CursorNode + TS

完整网格(含 fixture / 状态列)请见 Test Matrix 页面, 或跳转到 Test Fixtures 查看每个 scenario 安装目标所使用的 项目骨架。

最近一次 run 的概要

下方表格是判断 "Archon 是否可发布" 的唯一事实来源。在每一行的 最近一次 run 都对候选 manifest 版本 passing 之前,本次发布不会上线。

它由 runs/index.json 实时渲染,该文件会在每次调用 scripts/sandbox-run.mjs 时(本地 + GitHub Actions)重新生成。修改某个 scenario 后,运行下面的 命令即可刷新:

bash
node scripts/sandbox-run.mjs --runnable=cli         # CLI scenarios
node scripts/sandbox-run.mjs --runnable=agent       # agent scenarios (currently → manual)

Index generated:2026-05-06 10:24:38 UTC  ·  6 passing  ·  1 failing  ·  5 manual

ScenarioStageLatest resultManifestRunnerDurationRecorded
install-cursor-nodeinstall✅ passingv0.1.0cli231 ms2026-05-06 10:24:35
install-claude-pythoninstall⏳ manualv0.1.0manualclaude2 ms2026-05-06 10:24:38
install-codex-goinstall⏳ manualv0.1.0manualcodex1 ms2026-05-06 10:24:38
install-aider-rustinstall⏳ manualv0.1.0manualaider1 ms2026-05-06 10:24:38
boot-cursor-nodeboot⏳ manualv0.1.0manualcursor224 ms2026-05-06 10:24:38
boot-claude-pythonboot⏳ manualv0.1.0manualclaude222 ms2026-05-06 10:24:38
update-cursor-nodeupdate✅ passingv0.1.0cli353 ms2026-05-06 10:24:37
update-cli-without-cliupdate❌ failingv0.1.0cli345 ms2026-05-06 10:24:37
sync-cleansync✅ passingv0.1.0cli372 ms2026-05-06 10:24:35
sync-modifiedsync✅ passingv0.1.0cli386 ms2026-05-06 10:24:36
uninstall-preserveuninstall✅ passingv0.1.0cli367 ms2026-05-06 10:24:36
uninstall-archiveuninstall✅ passingv0.1.0cli357 ms2026-05-06 10:24:36

状态图例:✅ passing · ❌ failing · ⏳ manual(尚无 SDK adapter, 详见 KNOWN-003) · · pending(暂无 run 记录)。

failing不是 runner 噪声 —— 要么是真实的 CLI 回归,要么 是某个 scenario 的断言需要更新。无论哪种情况,在解决之前它都会 阻塞发布。

如何新增一个 scenario

  1. 找到缺口:尚未覆盖的 阶段 / IDE / 语言 组合。
  2. fixtures/ 下选择(或新增)一个 fixture —— 约定参见 fixtures/README.md
  3. template.md 拷贝到 scenarios/<test-id>.md, 填写 front-matter + steps + 预期结果。
  4. 把这一行加入 Test Matrix 以及上面的 最近一次 run 的概要 表格(状态填 pending)。
  5. (在你真正执行它之后)录制 mp4 + cast,上传到 docs/public/videos/<test-id>.mp4docs/public/asciinema/<test-id>.cast,并在同一 commit 里把状态 翻成 passing

为什么我们要让 pending 行始终可见

一个被搁置在 "我之后会写这个测试" 状态下的 scenario 页面会很快腐坏。 通过在 run 之前把页面(包含 pending 状态、预期步骤、空的录制 位)提交进来,可以发生三件事:

  1. 矩阵能诚实地反映覆盖率缺口。
  2. 预期结果在 run 之前就被固定下来,避免了让测试去迁就实际发生情况 的偏差。
  3. 任何人(包括未来的维护者)都可以接手一个 pending scenario 并执行 它,而不必从零去构思它。

依据 Apache-2.0 许可证发布。