Skip to content

最小工作核心真实提供方兼容性实验完整过程

日期:2026-08-21
分支演进:spike/minimal-work-corespike/real-provider-compat
性质:独立架构证伪实验;不是 Agent-Box 2.0 正式开发,也未合并到主分支。

1. 研究问题

第一轮离线实验提出并初步存活的假设是:Work-first, execution-pluggable。Work 提供稳定 identity 和 closure boundary;Harness、Workflow、Human、CI 等只是推进同一 Work 的不同 Execution。

第二轮不再增加场景数量,而是攻击真实 runtime 生命周期:真实 Codex CLI 的 native identity、非交互 turn、resume、输出、失败;以及一个真实长运行 subprocess 的 PID、cancel、不可恢复与不可达行为。问题是:这些事实是否会迫使 Work 保存 runtime state,或使 Execution 抽象退化为 provider-specific metadata。

2. 隔离和非破坏性约束

开始前工作区已有大量未提交用户修改。实验没有覆盖、rebase、reset、删除或改写它们。

第一轮成果放在 spikes/minimal_work_core/;第二轮仅增加其下的 real_providers/。正式 src/agent_box、现有 CLI/GUI、Profile 逻辑、Harness Adapter、数据库 schema 和既有测试均保持只读。默认 spike 数据路径也由 spike 局部 .gitignore 排除。

由于受限 agent 环境无法写 .git/refs,实验分支由用户在宿主终端创建;最终活动分支为 spike/real-provider-compat。这避免了通过任何非标准方式修改 Git 元数据。

3. 第一轮基线

第一轮最小 Core 保留:

  • Work:id、objective、独立 lifecycle、closure/reopen boundary;
  • Execution:work relation、provider、native ref、投影、输入/输出 refs;
  • typed Ref:type/provider/native_id/URI/受限 metadata;
  • append-only cross-system Event ledger;
  • ExtensionRegistry

它接入了 local harness、simple workflow、human、local CI 与 fake security scanner。Workflow 的 step/branch/retry 与 Human decision 都留在 provider-native store;协调逻辑留在 host/scenario。自动化测试通过,第一轮 Core schema/source mutation 为 0。

4. Codex CLI 探测

探测到:

text
binary: /home/maoqh/.npm-global/bin/codex
version: codex-cli 0.149.0

codex --help 显示 execresumequeue 等命令。codex exec --help 证实可以非交互运行,支持 --json JSONL event stream、--output-last-message--ephemeral 和 workspace sandbox。codex exec resume --help 明确接受 SESSION_ID,而且 session ID 优先于 thread name。

这为 native identity 的第一条结论提供了静态证据:Codex CLI 对可恢复的 native conversation/session 有一等标识。

5. 失败尝试及其意义

5.1 直接 CLI 和临时环境

在受限 agent 环境中直接运行 Codex,app-server client 因本地 PATH alias/app-server 写入点只读而无法初始化。用临时 CODEX_HOME 隔离配置后,CLI 真实产生了:

json
{"type":"thread.started","thread_id":"01a023d9-343c-7da1-9dac-5748a0b51d25"}
{"type":"turn.started"}
{"type":"turn.failed", ...}

随后因临时家目录不继承认证得到 401。该失败仍确认了 thread ID 的发现时机,以及失败不应被 Core 伪造为成功或 Work 失败。

另一次宿主直接运行遇到服务端 high demand 并产生 turn.failed。这同样是 provider execution failure,而不是 Work failure。

5.2 改用 Agent-Box profile launch

按实验要求,最终真实实验使用现有 Agent-Box launch 路径,而不是直接全局 Codex。只读查看 profile 后选用:

text
profile: codex-main
agent_type: codex

build_launch_plan 证实它使用 bwrap,挂载该 profile 的 .codex 配置和 spike workspace 的 project-profile overlay。受限 agent 环境中,launch() 在启动子进程后尝试记录正式 session SQLite;该数据库写入被沙箱禁止。因此不修改正式 session 逻辑,改由用户在正常宿主终端执行 launch。

这个阻塞本身验证了隔离原则:实验适配器不能为便于自身运行而改写 Agent-Box 正式 session persistence。

6. 成功的真实 Coding Work

用户通过以下路径启动:agent-box launch codex-main,启动目录限定为 spikes/minimal_work_core/real_providers/codex_workspace/

真实 JSONL 首事件为:

json
{"type":"thread.started","thread_id":"01a023dd-d221-7603-ac54-7a132cae29b0"}
{"type":"turn.started"}

Codex 读取 example.py,产生 native file_change event,只修改允许的 example.py

python
def greeting(name: str) -> str:
    return f"hello, {name}!"

随后 Codex 运行 pytest。测试因 test_example.py 明确仍期待旧值 "hello, Ada" 而失败;Codex 被指示不得修改其他文件,严格遵守了边界。它最终发出 turn.completed

这构成了重要的 Work/Execution 分离证据:Codex turn 可成功完成,而执行产物的测试判定失败;因此不能将 Execution terminal outcome 机械映射为 Work closure。Host 将此 Work 保持 open,等待人类决定测试期望是否应更新。

Core 应保留 SessionRef、WorkspaceRef、artifact/result refs 和少量 cross-system facts,不应复制 command output、pytest transcript 或文件 bytes。

7. 真实 Resume / Reconnect

同一 codex-main profile 随后执行:

text
codex exec resume --json 01a023dd-d221-7603-ac54-7a132cae29b0 ...

返回了相同的:

json
{"type":"thread.started","thread_id":"01a023dd-d221-7603-ac54-7a132cae29b0"}

新的 turn 读取已修改文件,回答其精确 return expression,未修改任何文件,并以 turn.completed 结束。

结论:Codex CLI client/turn 边界并不是 Execution identity 边界。只要同一 native SessionRef 被 resume,它应继续映射到同一个 Execution;Core 不需要也不应重放 transcript 或保存 Codex session state。

8. Provider B:真实 long-running subprocess

LangGraph 在环境中未安装;GitHub Actions 需要远程凭据、推送或 workflow mutation,不符合低侵入约束。因此 Provider B 选择真实 OS subprocess:Python 子进程长时间 sleep,以 PID 为 native identity。

它得到的实测 projection:

动作真实行为投影
startPopen 创建 PIDactive / observed
cancelSIGTERM,wait 返回terminal / cancelled / observed
运行时无法查询adapter 停止可达性unknown / unreachable
进程退出PID 不可再继续terminal;resumable=false

此 provider 与 Codex 的关键差异是:Codex thread 可在 client turn 完成后 resume,PID subprocess 不可 resume。这正好反证“terminal status 一词足够表达生命周期”的初始设计。

9. Projection 收敛

第一轮的 single status 无法同时表示:一个 Codex turn 已结束、结果成功、但同一 native session 仍可继续;也无法表示 provider query 暂时不可达。

提出 candidate structured projection:

字段作用Codex 映射Subprocess 映射
phaseactive / terminal / unknownturn 状态或查询失败poll/不可达
outcometerminal 的 succeeded/failed/cancelledturn 成果exit/SIGTERM
resumablenative continuation 是否可能SessionRef + exec resumefalse
freshnessobservation 是否可信observed/unreachableobserved/unreachable

waiting_for_human、queued、paused_at_checkpoint、rate_limited、session_idle、retrying 等拒绝进入公共 projection;它们属于 provider detail,交给 native UI、Ref 和 capabilities。

这是一次 candidate semantic/API mutation,而不是将 Codex 特有 state 加入 Core。

10. Capability model

mandatory provider contract 为:descriptor/identifycapabilities()start(work, execution)observe(native_ref)。observe 必须能报告 freshness,不能在未观察到 native 状态时编造 terminal result。

可选操作包括 cancel、resume、send_input、stream、pause、retry、approve、attach、reconnect;每项声明 supported、unsupported、provider_native 或 emulated。

Codex 的真实 exec resume SESSION_ID 为 supported;本轮未观察到文档化的非交互 exec cancel,因此终止 local CLI client 只能是 adapter/host emulation,不能宣称为 Codex native cancel。subprocess 的 SIGTERM 则是 native cancel。

11. Ref、Event 与 ownership

Ref 最小字段是 type、provider、native_id、可选 URI、受限字符串 metadata。Codex SessionRef 的 native_id 是 JSONL thread_id;一次 CLI client process/PID 如需记录,应是不同的 RunRef,不能代替 SessionRef。

Core event 只记录 authoritative cross-system facts:ExecutionCreated、DispatchRequested、NativeRefDiscovered、Started、material Observed、Cancelled、Completed/Failed、RefAttached、WorkCompleted/Reopened。逐行 JSONL、command transcript、workflow retry history 都是 native log,不应复制进 event ledger。

所有权如下:

Authority拥有内容
Work CoreWork identity/objective/closure;Execution relation/projection
Codex providerthread、turn、transcript、native capabilities
Workflow providercheckpoint、graph、node/edge、retry
Workspace providerworking tree identity 与生命周期
Artifact authorityartifact bytes、保留与访问控制
Host application编排、人工 closure、通知与调度政策

12. Mutation ledger 和 hard failures

Offline spike:Core schema/source mutation 0

Real-provider spike:schema mutation 0;candidate semantic/API mutation 1(structured projection);naming clarification 1(SessionRef 与 RunRef 区分)。没有把 candidate 回写到第一轮 core source,等待正式设计批准。

未触发以下 hard failures:provider-specific Work 字段、复制 Codex/Workflow native state、Core provider switch、Core checkpoint/retry/DAG、Ref arbitrary JSON bucket、必须修改正式 Agent-Box 才能接入 provider。真实 launch 在受限环境的 session SQLite 写入失败被记录为环境/API-consumption blocker,而非被隐瞒或通过改正式代码绕过。

13. 自动化验证

运行:

bash
python3 -m pytest spikes/minimal_work_core/tests spikes/minimal_work_core/real_providers/tests -q

结果:10 passed

覆盖范围包括 core create/attach/event/complete/reopen、四类离线 provider isolation、replacement、mixed execution、workflow opacity、fake security extension、Codex JSONL parsing、Codex completed/resumable mapping、unknown/unreachable mapping、真实 subprocess cancel。

真实 Codex 工作区测试的失败被保留为真实 execution artifact,不混入上述 prototype contract 测试;其失败原因是测试仍断言旧需求,非 adapter 失败。

14. 最终结论与建议

Verdict:B — Passed with structural change

真实 provider 没有击穿 Work-first 边界:Work 无须 runtime state;Execution 没有退化为 arbitrary provider metadata;新增 provider 不必修改 Core;Workflow 仍可保持 opaque。真实证据确实击穿了过于简单的 single status 设计,因此 projection 必须有结构化语义。

可以进入受限的正式设计阶段:先冻结 projection vocabulary、Ref governance、provider contract,并做 durable Codex adapter 的幂等、并发、授权与 crash-recovery 设计。尚不应开始正式 Agent-Box 重构、迁移数据库、替换 CLI/GUI 或合并 spike。后续还需用真实 checkpointing workflow 验证 workflow resume 的 identity 结论。

相关原始 spike 文档:

  • spikes/minimal_work_core/CORE_CONTRACT_V0.md
  • spikes/minimal_work_core/CORE_MUTATION.md
  • spikes/minimal_work_core/real_providers/REAL_PROVIDER_EXPERIMENT_REPORT.md
  • spikes/minimal_work_core/real_providers/CORE_CONTRACT_CANDIDATE_V0_1.md
  • spikes/minimal_work_core/real_providers/EXECUTION_PROJECTION_V0.md
  • spikes/minimal_work_core/real_providers/EXECUTION_PROVIDER_CONTRACT_V0.md
  • spikes/minimal_work_core/real_providers/REF_GOVERNANCE_V0.md