diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index 2936ef7c9..9cb44fb8a 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -15,6 +15,135 @@ - 关联文档:相关 PRD、技术文档、提交或 Issue ``` +## 2026-09-01 独立 Rust Agent Runtime 先固化恢复边界 + +- 背景:需要一个不依赖现有 AGC/server-rs 的单 Agent 内核和通用宿主,先验证 provider、tool、context、持久化与 worker 生命周期,再决定是否接入多 Agent 或 Codex。 +- 决策:新增仓库根目录下独立的 `rust/` workspace,按 core、engine、provider、storage、MCP、skill、host、CLI 分 crate;运行租约使用 token fencing,边界 checkpoint 只允许 `provider_in_flight`、`awaiting_approval`、`tool_in_flight`、`safe` 四种阶段。排队 bundle 和终态转换在 SQLite 原子事务内同步 run、runtime、session 与 checkpoint;只有完成外部副作用核对后的 `safe` checkpoint 才能通过显式 `resume-safe` 恢复,尚未启动 worker 时重复排队幂等。Provider/工具现在有显式完整消息历史对账与 CAS 入口,但 in-flight 阶段仍不自动查询、订阅或重放未知调用。`ApprovalDecision::Ask` 保留为待决 gate,本次最小闭环只提供显式 cancel,不伪造决议或自动执行。 +- 影响范围:`/data/dsk/Genarrative-master/rust/`、`docs/README.md` 及本决策记录;不改变现有 `server-rs`、AGC runtime 或 MCP/Skill 的生产权威边界。 +- 验证方式:standalone workspace 全量测试、storage 无默认 feature 测试、Prompt/Context、SkillSource、MCP stdio/HTTP JSON/SSE、Host 工具桥接与 Provider/工具对账 CAS 专项测试、格式/编码检查、CLI background run/checkpoint/doctor/reconcile smoke;后续若接入自动恢复,必须再补 provider/tool 幂等键与外部状态查询/订阅合同。 +- 关联文档:`rust/README.md`、`rust/docs/【架构】独立Agent运行时-2026-09-01.md`、`rust/docs/【任务】Agent内核落地TODO-2026-09-01.md`。 + +## 2026-09-02 补录独立 Agent Runtime 原始 P0–P6 计划 + +- 背景:此前落地的是执行期间形成的缩减版 TODO/验收口径,原始 P0–P6 计划没有先进入仓库,导致“当前最小闭环通过”被误读成“原始计划全部完成”。 +- 决策:以 `rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md` 作为用户原始计划的唯一仓库内权威副本,按 P0–P6 逐项记录状态;缩减版文档只能描述已经实现的子集,不能改变计划或完成标准。 +- 当时记录的事实(随后已由本文件后续条目更正):P0–P4 仅部分完成,P5 Codex 外部适配器和 P6 多 Agent 扩展准备尚未开始;原始计划要求的独立 Fake Provider、真实流式/SSE、压缩/重试、MCP 重连/资源/指纹、TOML 配置及完整门禁也未全部满足。 +- 影响范围:仅补充计划与文档索引,不改变现有 Rust 实现和其他工作区代码;后续开发和验收以原始 P0–P6 清单为准。 +- 关联文档:`docs/README.md`、`rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md`、`rust/docs/【任务】Agent内核落地TODO-2026-09-01.md`、`rust/docs/【验收】Agent内核与通用程序-2026-09-01.md`。 + +## 2026-09-02 继续实现 P5/P6 与适配器边界 + +- 背景:原始计划补录后,执行继续推进了 Codex 外部适配、durable Runtime 抽取、DAG 状态基础和 MCP 配置,但不能把这些基础误报为完整 Codex/多 Agent 交付。 +- 决策:保留 `agent-runtime -> agent-storage-sqlite` 的当前具体实现,Host 通过通用 Core `ExternalBackend` 桥接外部执行器并记录 `external_sessions`;Codex 不直接编译耦合进 Host。`agent-runtime-orchestration` 只提供纯 DAG/状态/修复 API,不创建 Runtime run、不管理线程。MCP TOML 只接受环境变量认证引用,明文 header map 不进入文件配置。 +- 当前事实:本轮已实现 `agent-runtime`、`agent-codex`、Host 外部 backend bridge、`agent-runtime-orchestration`、`[[mcp.auth]]`、配置样例和独立 workspace CI 文件;Host 仍保留过渡性 Store 句柄。Approval Ask resolve/resume、UUIDv7、真实 Codex wire、自动外部查询/webhook、完整多 Agent coordinator、独立仓库远端 CI/依赖审计尚未完成。 +- 影响范围:`/data/dsk/Genarrative-master/rust/` 及其计划/架构/验收文档;不改变现有 Genarrative 生产运行时和其它工作树的既有脏文件。 +- 验证方式:workspace 全量 test、`RUSTFLAGS=-D warnings cargo check`、rustdoc、fmt、编码、diff、Core 依赖边界和 CLI smoke;未安装的 `cargo-clippy` 由独立 workspace CI 保留门禁,不能以本地未执行冒充通过。 +- 关联文档:`rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md`、`rust/docs/【架构】独立Agent运行时-2026-09-01.md`、`rust/docs/【验收】Agent内核与通用程序-2026-09-01.md`。 + +## 2026-09-02 OpenAI Provider endpoint 配置边界 + +- 背景:独立 workspace 的 OpenAI adapter 原先只读取 `OPENAI_API_KEY`,CLI 将 Responses endpoint 固定为官方地址,`OPENAI_BASE_URL` 对兼容网关不生效。 +- 决策:`OpenAiProvider` 保留 `new`/`with_endpoint` 手动入口,新增 `with_base_url`、非秘密 `OpenAiProviderConfig`、`from_config` 和环境构造;`OPENAI_ENDPOINT` 表示完整地址并优先于 `OPENAI_BASE_URL`,base 地址统一自动补 `/responses`。CLI/TOML 透传 endpoint,`OPENAI_MODEL` 可覆盖默认模型,环境变量优先于 TOML。 +- 安全与边界:配置只存 key 的环境变量名,不存 key 原文;endpoint 仅接受 http/https URL,拒绝 userinfo、fragment 和 base URL query。Responses API 协议字段仍由 adapter 负责,MCP/Skill/Kernel 不感知厂商地址。 +- 验证方式:OpenAI endpoint/config/校验单测、CLI TOML 接线单测、`-D warnings` check 和 workspace 全量测试;真实上游网络与网关兼容性仍需调用方自行验收。 +- 关联文档:`rust/README.md`、`rust/agent.toml.example`、`rust/docs/【架构】独立Agent运行时-2026-09-01.md`。 + +## 2026-09-02 独立 Runtime 状态更正 + +- 当前事实:Approval Ask 已有 pending-only 持久化决议和显式 Host/CLI resume;`agent-runtime` 新建 bundle 已使用 UUIDv7。Codex CLI supervisor 和内存 Coordinator 的配额/消息去重/节点隔离已完成;仍未完成的是真实 Codex wire 与版本特定 App Server 接线、自动外部对账、持久化多 Agent 调度、独立仓库远端 CI 和带漏洞库依赖审计。 +- 这条更正只更新共享记忆的现行口径;更早条目保留作为历史记录,遇到冲突以当前代码和 `rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md` 为准。 + +## 2026-09-02 stale-run 扫描与 MCP 重连预算边界 + +- 决策:`agent-runtime` 提供一次性 `reconcile_stale_runs(limit)`,Storage 只按固定顺序返回 `running`/`cancel_requested` 且 lease 缺失或过期的有限候选(硬上限 256);每项重新校验后才进入已有原子 reconciliation gate。扫描不启动线程、不查询外部系统、不重放未知副作用,候选与 recovery 之间的正常 lease/终态竞争会跳过,其它错误继续上抛。 +- 决策:MCP 重连策略的 `attempt_timeout` 必须沿内部握手路径传到 `initialize` 和 `notifications/initialized`;HTTP transport 用它限制响应等待,stdio 通知保持同步写入,不能声称可抢占底层 I/O。 +- 验证方式:Runtime/SQLite stale-run 边界测试、MCP 预算/超时测试及 all-features/no-default-features workspace 回归;详细证据见 `rust/docs/【测试】Agent测试集与真实Provider接入-2026-09-02.md`。 + +## 2026-09-02 Codex 窄 App Server 客户端与批量对账入口 + +- 决策:在 `agent-codex` 保留中立 fixture/channel 的同时,增加显式、窄范围的 `CodexAppServerClient`,只覆盖当前 V2 请求形状的 initialize/initialized、thread/start、turn/start 接受、通知轮询和带 `threadId`/`turnId` 的 turn/interrupt;通知队列和 JSONL frame 均有界。它不把 V2 当作发行版兼容协商,不实现 generated schema、审批/工具 handler 或后台异步 reader。 +- 决策:CLI `reconcile --stale [limit]` 通过 Host/Runtime 做一次固定排序、有界扫描(默认 256),不启动 Engine、不查询外部系统、不重放未知副作用;原有单 run `reconcile ` 保持不变。 +- 影响范围:`/data/dsk/Genarrative-master/rust/` 的 `agent-codex`、`agent-runtime`、`agent-host`、`agent-cli` 及其计划/验收文档;不改变 Core 对外部协议的依赖边界。 +- 验证方式:Codex 32 个、Runtime 12 个、Host 28 个、CLI 13 个测试及 workspace 全量回归;真实 Codex 二进制兼容性和自动外部对账仍需单独验收。 + +## 2026-09-02 外部观察端口与未知副作用超时边界 + +- 背景:显式 reconciliation 已能接收调用方提供的结果,但 Core 之前没有一个只读、通用的外部查询合同;同步外部 backend 超时也不能证明请求未发出,若按普通可重试错误处理可能重复执行副作用。 +- 决策:Core 新增有界的 `ExternalObservationRequest`、`ExternalObservation` 和 `ExternalObservationSource`。该端口只查询既有 provider/tool/external 引用并返回不透明状态/结果,不推进 checkpoint、不重排队、不自动生成消息;宿主完成协议校验后再调用现有 reconciliation API。Host 将 `ExternalErrorKind::Timeout` 映射为 `ToolErrorKind::Unknown`,禁止幂等自动重试,要求显式对账。 +- 许可证审计:本地缓存中的 `cargo-deny 0.20.2` 可离线运行并生成许可证清单,但内部 `UNLICENSED` crate 的 publish 属性及 BSL/LGPL/Unlicense 取舍尚未确认,暂不提交 `deny.toml` 或静默 allowlist。 +- 影响范围:`rust/crates/agent-runtime-core`、`rust/crates/agent-host` 及对应测试/验收文档;不改变外部系统的查询、订阅或自动恢复行为。 +- 验证方式:Core 15 个单元测试加 13 个集成测试;Host 30 个测试含 timeout Unknown 单次调用和 Runtime facade 快照回归;Codex 40 个测试;all-features/no-default workspace、stable Clippy、rustdoc、依赖边界与独立复制门禁通过;许可证正式门禁和远端 CI 仍待外部策略与 runner 证据。 +- 关联文档:`rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md`、`rust/docs/【验收】Agent内核与通用程序-2026-09-01.md`、`rust/docs/【审计】独立Agent依赖边界与CI验收-2026-09-02.md`。 + +## 2026-09-03 Runtime/Host facade 与 Codex 0.152.1 版本边界 + +- 背景:Core 的外部观察合同和 Host 的 durable 控制面已经存在,但若继续由 Host + 直接拼接 SQLite,观察、approval/session 投影和审计入口会再次形成混合层;同时 + Codex 的通用 `v2` 标签不足以证明某个发行版的 wire 兼容。 +- 决策:`RuntimeService::observe_external` 与 `AgentHost::observe_external` 只读转发 + `ExternalObservationSource`,保留 `ExternalError` 分类,不写 checkpoint、消息、 + requeue 或 reconciliation。approval、external session、run-level audit event 的 + 常用控制面使用 Runtime 窄 facade;Host 仅为跨表原子终态事务保留 SQLite 过渡句柄。 + 新增 `agent-codex::codex_0_152_1`,要求调用方先核对 `codex-cli 0.152.1`,并以 + provenance/hash 清单固定当前 typed lifecycle、通知和 server-request 子集;不把 + 它声明为任意 v2 发行版兼容层。 +- 影响范围:`/data/dsk/Genarrative-master/rust/crates/agent-runtime`、`agent-host`、 + `agent-codex` 及对应计划/架构/验收文档;不改变生产 `server-rs` 或现有 Genarrative + Runtime 的权威边界。 +- 验证方式:变更后 all/no-default workspace 测试、Runtime 17、Host 32、Codex 50 + 定向测试,`-D warnings` check/Clippy、rustdoc、fmt、依赖/manifest 预检、独立复制 + 和 Fake 测试集均通过;本机未使用真实 API key、真实 Codex 会话或远端 CI。 +- 未完成出口:独立远端仓库/CI、目标 registry 发布、正式许可证策略、自动外部对账/ + 订阅、真实 Codex 完整 generated wire 和最终 Host/Runtime 拆分仍需单独授权与证据。 +- 关联文档:`rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md`、 + `rust/docs/【验收】Agent内核与通用程序-2026-09-01.md`、 + `rust/crates/agent-codex/【审计】Codex-0.152.1协议适配-2026-09-03.md`。 + +## 2026-09-03 Host Store ownership cleanup + +- 决策:`AgentHost` 不再重复持有 `SqliteStore`;内部 durable 控制路径统一通过 + `RuntimeService`,`AgentHost::store()` 仅保留为旧导出/诊断调用的兼容委托,返回 + Runtime 所拥有的同一 adapter 句柄。取消/错误收口的私有函数也删除未使用的 Store + 参数,避免用死参数暗示 Host 仍拥有第二套持久化状态。 +- 边界:公开 `store()` 仍暴露 SQLite 具体类型,`RuntimeService` 也仍是当前 + SQLite-backed 实现;这次只收敛 Host 内部所有权,不等于完成可替换存储或远端发布。 +- 验证:变更后 workspace `cargo check --locked --all-targets --all-features` 和 + rustfmt 通过;完整测试、静态门禁及外部未完成出口继续按权威计划记录。 + +## 2026-09-03 P1/P3/P4/P5 边界收尾增量 + +- Core reducer 在事件 detail 反序列化后重新执行消息、工具调用、工具结果和运行快照 + 的构造级校验,避免公开 serde wire 绕过 Builder 把非法值写入状态;非法输入返回 + `InvalidEvent` 且不改变 revision。 +- Runtime 的泛型 `RuntimeStore` facade 使用 `StoreProtocol(StoreError)` 保留 + `StoreErrorKind`,调用方可以区分 CAS 冲突、非法快照和不可用,而不是解析字符串。 +- MCP 认证引用在高层 connect、HTTP 直接构造和 stdio 直接构造路径保持一致;Skill + 激活正文使用 `Read::take(max+1)`;通用 Codex JSON-RPC channel 提供显式 handler, + 默认仍拒绝未知请求。该增量只更新独立 `rust/` workspace,不改变 Genarrative 生产 + Runtime;当前 P0–P6 仍逐项为部分完成。 +- 验证:Core 15+14、Runtime 20、MCP 43、Skill 23、Codex 58、Engine 47 的定向回归及最新源码的 + all/no-default workspace、`-D warnings` check/Clippy、rustdoc、独立复制、Fake、编码 + 和 diff 门禁均已通过;真实 Provider/Codex 会话、远端 CI、registry 和许可证正式 + 策略仍不由本地 fixture 替代。 + +## 2026-09-03 上下文信任与 Codex Host bridge 边界 + +- 决策:`McpContextSelection` 只允许调用方显式选择 resources/prompts;选中内容以 + `ContextItem(trusted=false)` 注入。Engine 在出站组装时保留原始 item 供审计,但把 + 不可信的 system/developer/assistant 角色降为 User,避免外部正文伪装成高权限指令。 +- 决策:Host 的 `CodexHostServerRequestHandler` 仅处理中立 `item/tool/call`。已知工具先 + 复用 Engine 公共 JSON Schema 子集校验,再调用 Host 的 `ApprovalPolicy` 和 `ToolRouter`; + 未知/非法参数不会触发审批或工具副作用。该 handler 是同步低层桥,不创建第二个 + session/run,也不写 durable approval、checkpoint 或 audit;`Ask` 通过 JSON-RPC error + 返回,需由完整 Engine/Runtime 路径承接持久化审批。对已核对的 Codex 0.152.1,Host + 另提供只覆盖 dynamic-tool 子集的 typed bridge,将 `tool`/`callId` 请求返回为 + `contentItems`/`success`,仍不覆盖完整 generated wire。 +- 验证:本轮独立 workspace 计数为 Engine 48、Host 46、MCP 45、CLI 17、Codex 58、Runtime + 20、Orchestration 31、Skill 23、OpenAI 21、Fake 4;Core 15+14,Storage 默认 5+39、 + 直接 no-default-features 4+32。原始 P0–P6 仍全部为部分完成,远端仓库/CI、registry/ + 许可证、真实 Provider/Codex wire/session、自动外部对账/订阅、完整持久化多 Agent 调度和 + 最终 Host/Runtime 拆分不由本地 fixture 替代。 + ## 2026-08-30 批准 GDD 直接进入做游戏链路 - 背景:立项策划 GDD 批准后需要给用户一个进入做游戏的自然出口,产品决策改为点击按钮后直接开始建造。 @@ -7879,3 +8008,1001 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在 - `autonomous-game-build` 中,manifest `dependencies` 只作为上下文,不阻塞 ready;代码、设计、美术、音频和发布任务允许并行启动,child 不依赖固定回执顺序或固定 run 身份才能推进。 - 任务最终状态不再提前绑定平台画布、preview、static smoke 或发布产物检查;这些内容不参与该档位的完成判定,也不会因缺失而重置已完成任务。父 run 在任务图进入终态后直接收束并回复。 - 本档位仍沿用现有项目根和工具权限边界;本次调整只解除流程编排与平台产物验收前置,不新增第二套任务系统。 + +## 2026-09-02 Agent Runtime 控制面窄 facade + +- `agent-runtime::RuntimeService` 统一承接 run 查询、runtime 身份反查、lease 领取/续租/释放、取消标记查询、stale 探测,以及带 lease 的 checkpoint 读写和 reconciliation 写入。Host/CLI 只传递 opaque `WorkerLease`,不再为这些控制动作直接拼接 `SqliteStore` 的 worker/token 参数。 +- Host 仍暂时保留共享 `SqliteStore` 句柄,用于 Engine 审计事件、approval/session 投影和跨表终态 CAS;这些属于下一步拆分出口,当前 facade 不宣称已经完成 Runtime 与应用装配的最终分离。 +- Runtime facade 只协调 durable 状态,不启动线程/Engine,不查询或重放 Provider、工具、MCP 或 Skill 的外部副作用。 + +## 2026-09-02 独立 Codex App Server 进程适配器保持窄协议边界 + +- 背景:独立 Agent Runtime 需要把窄 Codex app-server 客户端接到真实 stdio 子进程, + 但不能把某个发行版的 generated schema、会话真相或后台重放逻辑塞进 Kernel。 +- 决策:`agent-codex` 提供 `CodexAppServerProcessConfig` 与 + `CodexAppServerProcess`,只接受显式 `program + args`,通过有界 reader/writer + supervisor 接入 `CodexAppServerClient`。每次操作有 deadline;取消、超时、EOF、异常 + 退出和 `Drop` 都终止受控 process group、wait/reap child 并 join 线程。适配器不解析 + shell、不自动重连或重放请求;V2 仍只是当前 DTO/wire 形状,不是具体 Codex 发行版兼容 + 承诺。 +- 影响范围:`/data/dsk/Genarrative-master/rust/crates/agent-codex` 及其独立 Runtime + 计划、架构、验收和测试文档;不改变 Runtime/Host/orchestration 的持久化边界。 +- 验证方式:本地 `sh` fixture 覆盖真实 stdin/stdout 握手、非法输出、非零退出、正常 EOF + 回收、跨线程取消和超时;`agent-codex` 测试、stable Clippy 和格式检查通过。 + +## 2026-09-02 Agent Runtime/Host Runtime-only CAS facade + +- `AgentHost` 的 RuntimeSnapshot 只读观察和 Runtime-only 事件/快照 CAS 统一经 + `agent-runtime::RuntimeService`(`load_runtime_snapshot`、 + `commit_runtime_snapshot`);Host 不再直接调用 `RuntimeStore` adapter trait。 +- 需要同时更新 run、session、lease 或 checkpoint 的跨表原子终态仍保留在 SQLite + 专用事务入口;facade 的 Runtime-only commit 不冒充全局事务,也不启动 Engine、 + worker 或外部调用。 +- 验证:Runtime facade 14 个测试、Host 30 个测试通过;新增 Host 快照观察和 + Runtime CAS 回归(该条为此前计数,最新终态 CAS 复核见后续条目)。 + +## 2026-09-02 Agent Runtime 最新边界复核 + +- Runtime 新增跨表终态窄 facade,Host 的 run/runtime/session/checkpoint/lease 收口统一 + 经 `RuntimeService`;SQLite 事务仍是唯一原子实现者,审批、外部会话和 Engine 审计 + 继续保留在 Host adapter 边界。 +- Codex App Server process 接入中立 `CodexServerRequestHandler`,并将子进程启动后及 + 请求发出后的协议/超时错误归类为 `UnknownSideEffect`,避免未知副作用被通用重试重放。 +- `run-agent-test-set.sh` 使用自身路径传入独立 workspace manifest,从 `/tmp` 或父仓库 + 调用不再误用父 Cargo workspace。终态 CAS 与 endpoint 安全回归后的当前本地计数为 + Runtime 16、Host 31、Codex 43、OpenAI 20; + 远端 CI、正式许可证策略、真实 Codex 发行版 wire、自动外部对账和完整持久化多 Agent + 调度仍未完成。 +- 验证:上述计数先由定向 Runtime/Host/OpenAI 测试确认;随后已在最终代码上重跑 + all-features/no-default-features、Rust 1.96 Clippy、rustdoc、依赖边界和独立复制门禁 + 并通过。本条早于 2026-09-02 最终门禁条目,保留为过程记录,不替代最终证据。 + +## 2026-09-02 Agent Runtime 最终本地门禁与工具链 + +- 独立 workspace `rust/` 新增自己的 `rust-toolchain.toml`,固定 Rust 1.96 并声明 + `rustfmt`/`clippy`;它覆盖父仓库的 minimal 工具链配置,但不修改父仓库文件。CI + runner 必须预装同一工具链和组件,workflow 保持 `RUSTUP_AUTO_INSTALL=0`,不依赖隐式 + 联网安装。 +- 最终 all-features 与 no-default-features workspace 测试均通过:CLI 13、Codex 43、 + Host 31、MCP 32、OpenAI 20、Runtime 16、Core 15+13、Engine 36、Orchestration 25、 + Skill 21、Storage 5+38(43);Storage 直接 no-default 为 4+31(35)。默认 Rust 1.96 + 的 Clippy 两套特性检查、`-D warnings` check、rustdoc、fmt、编码、diff、依赖边界、 + 独立复制和 Fake 测试集也通过。 +- 该证据只覆盖当前本地源码和固定锁文件;独立远程仓库/远端 CI、正式许可证策略、真实 + Codex 发行版 wire/上层 handler、自动外部对账/订阅、完整持久化多 Agent 调度和 + Host/Runtime 最终拆分仍按原始 P0–P6 计划标为未完成。 + +## 2026-09-03 Agent Runtime manifest 与 CI 门禁 + +- `rust/Cargo.toml` 的 workspace path 依赖统一补充 `version = "0.1.0"`,13 个 + crate 的 `cargo package --list` manifest 预检通过;完整 package/publish 仍需目标 + registry 按依赖顺序收录内部 crate。 +- 独立 Gitea workflow 同步增加 no-default-features 的 check、test 和 Clippy 步骤, + 与本地固定 Rust 1.96 的最终门禁一致;manifest 变更后的 all-features/no-default-features + workspace 测试和静态门禁已重新通过,远端运行记录和许可证策略仍需单独授权确认。 + +## 2026-09-03 Agent Runtime opaque lease facade + +- `RuntimeService` 的带 lease 终态入口统一接收 `&WorkerLease`,由 Runtime facade + 在内部转换为 SQLite adapter 所需的 worker/token 参数。Host 不再拆开传递两段 + fencing 身份,避免调用方把不匹配的字符串组合到同一事务;底层 SQLite API 和 + 原子事务语义保持不变。 +- 该调整是控制面类型边界收敛,不代表 Runtime 已摆脱 SQLite,也不增加自动外部 + 对账、重放或后台调度能力。 + +## 2026-09-03 Agent Runtime MCP subscription 与 OpenAI endpoint setter + +- 决策:`agent-mcp` 只为完成握手的 stdio client 提供显式独占通知订阅 + `into_notification_subscription`。订阅使用有界队列和 cooperative cancellation, + `Drop`/`join` 回收线程、reader 与 child;`join` 检查队列中的 poller 错误。Streamable + HTTP 与自定义 transport 继续只支持显式轮询,不自动应答、重连、重放或路由通知。 +- 决策:`OpenAiProvider` 增加 `set_endpoint`/`set_base_url`,复用构造阶段的 URL + 安全校验,失败不覆盖当前地址;保留已有 env/config/手动构造入口和 key 只读环境 + 引用边界。 +- 验证:MCP 37、Skill 22、OpenAI 21、Runtime 17、Host 32、Codex 50 定向测试及 + all/no-default workspace 回归通过;本地证据不替代远端 CI、registry、真实网关或 + 完整 Codex wire 验收。 + +## 2026-09-03 Agent Runtime MCP reader 非阻塞终止修正 + +- 决策:stdio reader 的超限消息和 EOF/IO 终止统一使用非阻塞 `try_send`。内部有界 + 队列已满时宁可丢弃终止错误,也不能阻塞 reader;这样 `StdioClient::Drop` 能可靠 + 终止 child 并 join,不把回收路径交给一个可能永远不消费的 sender。 +- 验证:新增满队列超限回归,`agent-mcp` 当前 38 个测试;all/no-default workspace、 + 两套 `-D warnings` check/Clippy、rustdoc、fmt、依赖/manifest、独立复制、Fake 测试集、 + 编码和 diff 门禁均通过。该修正不增加 HTTP 长连接订阅、自动应答、重连或请求重放。 + +## 2026-09-03 Agent Runtime Provider stream interruption regression + +- 决策:Engine 必须把已产生增量后返回的 Provider stream 错误视为终止边界,保留已 + 观测的 partial stream event,但不得补发 `Completed`、`ModelCompleted` 或 `Finished`, + 也不得回退重调同步 `complete`。 +- 验证:新增 `streaming_provider_error_does_not_emit_completion`,Engine 定向测试由 + 38 个增至 39 个并通过;workspace all/no-default 回归继续通过。该测试不扩大真实 + Provider 网络、重试或外部副作用结论。 + +## 2026-09-03 Agent Runtime file-backed restart recovery regression + +- 决策:P3 的文件持久化恢复至少要跨连接边界验证;新增集成测试在首个作用域写入 + `provider_in_flight` checkpoint 后关闭 SQLite 连接,第二个作用域重新打开同一路径, + 只执行显式过期 recovery。恢复必须清掉 lease/fencing、进入 `reconciling` 并保留 + checkpoint/request ID,不启动 Engine 或重放 Provider。 +- 验证:`agent-storage-sqlite` all-features 为 5+39(44),no-default 为 4+32(36), + 新增测试在两种特性下通过;该证据不扩展到自动 crash supervisor 或外部对账。 + +## 2026-09-03 Agent Runtime 当前计数口径更正(前一轮记录) + +- 本条记录对应 hard-bound 回归前的前一轮源码计数:Runtime 19、Host 32、MCP + 38、Engine 39、OpenAI 21、Skill 22、Codex 50;Storage all-features 为 44(5 + 个单元测试 + 39 个集成测试),直接 no-default-features 为 36(4 个单元测试 + 32 + 个集成测试)。此前条目中的 Runtime 17、MCP 37 等也是变更过程中的历史计数,保留作 + 时间线记录;当前 Engine 40 以紧接着的 hard-bound 条目和最新验收记录为准。 +- 该计数只代表本地源码、锁文件和 fixture/合同回归;原始 P0–P6 仍全部保持“部分完成”。 + 独立远端仓库/CI、目标 registry 发布、正式许可证策略、自动外部对账/订阅、完整 + Codex wire 及持久化多 Agent 调度和最终 Host/Runtime 拆分仍未完成。 + +## 2026-09-03 Agent Runtime Engine hard-bound 回归 + +- 决策:`agent-runtime-engine` 对从 serde 直接构造、绕过 Builder 最小值的 + `max_tool_output_bytes` 做前置拒绝。新增 + `deserialized_tiny_tool_output_budget_is_rejected_before_side_effects`,确认在 + checkpoint、Provider 调用和工具副作用之前拒绝过小预算,避免生成超过配置上限的 + 截断 envelope;Engine 定向测试由前一轮 39 个增至当前 40 个。 +- 边界:该回归只覆盖本地输入预算和副作用前置顺序,不改变真实 Provider、上游重试或 + 外部副作用结论;原始 P0–P6 仍全部保持“部分完成”,独立远端仓库/CI、registry、 + 正式许可证策略、自动外部对账/订阅、完整 Codex wire、持久化多 Agent 调度和最终 + Host/Runtime 拆分仍未完成。 + +## 2026-09-03 Agent Runtime P4/P5/P6 增量复核 + +- 决策:`agent-mcp` 的 Streamable HTTP transport 增加显式独占 GET/SSE 通知订阅。 + 订阅以有界队列承载增量事件,在私有 current-thread worker 中用 Tokio 仅实现 + 可取消的 HTTP 读取;`Drop`/`join` 会收束 worker,解析、HTTP 状态、EOF 和队列 + 溢出错误按顺序暴露。它不自动应答 server request、不自动重连,也不重放任何 + `tools/call`;自定义 transport 仍须显式覆盖订阅 hook。 +- 决策:Host 增加 Core `ProviderRegistry` 的实例/协议选择入口。`provider_id`(实例 + 身份)与 `protocol_id` 使用不同强类型;选择和 Engine 启动前都会校验协议,既有 + 直接 `with_provider` API 保持兼容并明确清除旧 target。 +- 决策:`agent-codex` 拒绝同时带 `method` 与 `result/error` 的非法 JSON-RPC envelope, + 增加 server-request 的中立类别和 dispatch 前/后的错误分类,未知请求仍不得绕过 + 上层权限策略。 +- 决策:P6 增加 `PersistentCoordinator`,将 `TaskGraph` 与 Coordinator 控制面以 + schema version + revision CAS 的单一快照保存;提供内存和原子 JSON 文件适配器, + 恢复时重建派生索引并校验活动 run 与图状态。文件适配器只保证同一实例内串行 + CAS,跨进程共享需宿主提供外部单写者/锁;它不接 SQLite、不创建 Runtime run、不 + 调度线程。 +- 验证:当前定向测试为 MCP 41、Host 35、Codex 53、Orchestration 29;all/no-default + workspace test、`-D warnings` check/Clippy、rustdoc 和 fmt 均通过。真实 MCP 服务、 + Codex 发行版完整 wire、远端 CI、registry/许可证和完整多 Agent scheduler 仍未验收。 + +## 2026-09-03 Agent Runtime Engine 输入与压缩边界 + +- 决策:Engine 在所有公开 serde 输入进入副作用前重新执行 Core 构造级校验。范围包括 + `AgentInput` 的消息/工具定义与请求字段、`ContextSource` 返回项、压缩器输出,以及 + 压缩 Provider 响应的 `request_id`/`model` 身份;压缩阶段取消后不再发起主 Provider。 +- 验证:新增五个回归,默认和 no-default-features 的 Engine 定向测试均为 45 个通过; + 该证据只覆盖本地 Engine/Provider 合同,不替代真实上游硬 I/O timeout 或自动外部 + 对账,也不改变原始 P0–P6 的部分完成状态。 + +## 2026-09-03 Agent Runtime approval export/display redaction + +- 决策:审批 binding token 仍必须保留在 Host/SQLite 内部,供参数哈希、过期时间和显式 + resume 校验;诊断 JSONL 导出和 CLI `approval list/get/allow/deny` 是对外展示边界, + 只输出递归脱敏投影,移除顶层及嵌套的 `approval_token`/`approvalToken`,不复制 bearer + 值到可移植导出或 stdout。 +- 验证:Storage 导出回归确认 token 不出现在 JSONL 且原始记录未被修改;CLI 回归确认 + 顶层/嵌套 token 不出现在展示视图并保留工具请求详情。CLI 当前 14 个测试,workspace + all/no-default-features 测试均通过。 +- 边界:这项修正不删除内部 binding,也不改变原始 P0–P6 的部分完成状态;真实外部 + 审批系统、远端 CI、registry 和自动外部对账仍需独立证据。 + +## 2026-09-03 Agent Runtime 最终本地边界增量 + +- Engine 在 Provider response 与 ToolExecutor `ToolResult` 进入事件、消息历史或下一轮 + Provider 请求前重新执行 Core 构造校验;通过 serde 绕过 Builder 的空文本、非 object + tool 参数、空 summary 或非法 metadata 会 fail-closed,并保留 in-flight checkpoint + 供宿主对账。Engine 当前 47 个测试,默认与 no-default-features 均通过。 +- Codex CLI 参数白名单改为规范化凭据键匹配,覆盖大小写、连字符、空格、access-token + 和 Authorization/Bearer 变体,同时明确保留 `--tokenizer` 等普通参数;Codex 当前 + 58 个测试。 +- SQLite `requeue_reconciled_run` 的更新时间 UPDATE 只匹配 `reconciling`;已经 + `queued + safe` 的重复 `resume-safe` 返回相同记录且不改变 `updated_at`,首次状态 + 转换仍由同一原子事务完成。 +- 影响范围:仅 `/data/dsk/Genarrative-master/rust/` 及其计划/验收记录;不改变现有 + Genarrative 生产 Runtime。原始 P0–P6 仍逐项部分完成,远端 CI、真实外部会话、 + 许可证策略、自动对账/订阅、完整多 Agent 调度和最终 Host/Runtime 拆分仍需后续证据。 + +## 2026-09-03 Agent Runtime CLI 程序 smoke + +- 验证:在独立 workspace `/data/dsk/Genarrative-master/rust` 使用 `/var/tmp` 临时 + SQLite,Fake Provider 实际完成 `doctor`、前台 JSONL `run`、后台 `run --background`、 + `inspect` 到 `completed`、`export`(8 条记录)和有界 `reconcile --stale 8`(0 条)。 +- 边界:本次 smoke 不读取真实 API key 或 Codex 会话,临时目录已清理;父仓库没有 + `Cargo.toml`,以后运行 CLI 必须进入独立 `rust/` workspace 或显式指定 manifest。 + +## 2026-09-03 Agent Runtime 恢复与适配器边界增量 + +- 决策:approval checkpoint 恢复只把当前 pending tool call 及其前缀物化到 Core; + 多工具响应后续未审批调用继续留在 checkpoint,避免 `RunReconciled` 同时看到多个 + unresolved call。新增连续两次显式审批回归。 +- 决策:MCP 所有入站 stdio、HTTP JSON/SSE 和后台 SSE 路径共用 JSON-RPC envelope + 校验,要求 `jsonrpc=2.0` 并拒绝 method/result/error 歧义;未知扩展字段仍保留。 + Host MCP bridge 对发送后 timeout、连接、协议、编码、HTTP 和远端错误返回 + `ToolErrorKind::Unknown`,防止显式 failed 重试重放未知副作用。 +- 决策:CLI `doctor` 只做本地无网络/无进程检查,但分别报告 SQLite、Provider + key/endpoint、Skill、MCP auth/transport 和 Codex 配置;Codex program 不回显路径。 +- 验证:当前 Host 37、MCP 44、CLI 16 个定向测试;原始 P0–P6 仍保持部分完成, + 远端仓库/CI、真实 Provider/Codex、许可证策略、自动外部对账和完整多 Agent 调度 + 仍需独立证据或后续实现。 + +## 2026-09-03 Agent Runtime PersistentCoordinator 隔离一致性 + +- 决策:`PersistentCoordinator::isolate_node` 释放活动 run 后同步把图节点写为 + `Waiting`,把隔离表示为可显式修复的恢复态;低层 `Coordinator::isolate_node` + 仍只维护控制面索引,不改变其轻量 API 语义。 +- 决策:编排 durable 快照采用双向一致性校验:活动 run 必须指向匹配的 `Running` + 节点,且每个 `Running` 节点必须有且仅有匹配的 active run/agent。不完整快照在 + Store 保存和 `PersistentCoordinator::from_snapshot` 两个入口均拒绝。 +- 验证:新增隔离→重载→显式 repair→再次 dispatch,以及无 active run 的 Running 快照 + 拒绝回归;Orchestration all/no-default 定向测试均为 31,check/Clippy/fmt 通过。 + 这不引入自动调度、跨进程锁或完整多 Agent Teams。 + +## 2026-09-03 Agent Runtime Host namespace 与 CLI worker 收口 + +- 决策:Host 的中立 `CodexHostServerRequestHandler` 和已核对 Codex 0.152.1 的 + `codex_01521_server_request_handler` 都不猜测 namespace 分隔符。当前没有可验证的 + namespace-to-tool resolver,因此显式非 `null` namespace 在 approval/execution 前 + fail-closed;缺省或 JSON `null` 才按全局工具名处理。该限制同时适用于 generic、typed + 和 typed trait 直连路径,避免权限条目与实际工具路由错位。 +- 决策:CLI 的 background、approval resume、resume 和 resume-safe 统一通过 + `spawn_worker_or_fail_unclaimed` 收口子进程创建失败;只有仍未被 worker claim 的 durable + run 才会原子标记为 failed,已领取的 run 不被覆盖。`doctor` 保持无网络/无外部进程检查, + 但允许按需初始化或迁移本地 SQLite/WAL。 +- 验证:当前独立 workspace all-features/no-default-features 均通过;Host 49、CLI 20、 + MCP 45、Engine 48、Codex 58、Runtime 20、Orchestration 31、Skill 23、OpenAI 21、 + Fake 4,Core 16+14,Storage 默认 5+39、直接 no-default-features 4+32。新增 + generic/typed namespace 拒绝回归确认失败发生在 approval/execution 前;原始 P0–P6 + 仍全部“部分完成”,远端仓库/CI、registry/许可证、真实 Provider/Codex wire/session、 + 自动外部对账/订阅、完整持久化多 Agent 调度和最终 Host/Runtime 拆分仍未完成。 + +## 2026-09-03 Agent Runtime namespace resolver 与 ready durable claim 更正 + +- 更正:Host 现在已经提供显式 `NamespaceToolResolver` 和内置静态映射表,不再是“没有 + resolver”。默认空映射、未知 namespace/工具、空值和冲突仍在 approval/execution 前 + fail-closed;只有调用方注册并命中 `(namespace, wire_tool) -> registered_tool` 才能进入 + 同一套工具定义、Schema、ApprovalPolicy 和 Router。resolver 不持有执行器或权限。 +- 决策:`PersistentCoordinator::plan_ready_tasks` 只读生成带 revision 的稳定、有界计划; + 宿主随后以 `claim_ready_tasks(plan, run_ids)` 做 revision-CAS 领取。全局/按 Agent 配额、 + 隔离、任务归属和 run ID 数量在领取时再次校验,编排层不生成 Runtime run、不启动线程或 + 自动 scheduler。 +- 决策:`RuntimeService`/`AgentHost` 暴露 `journal_mode`/`export_jsonl` 窄 facade,CLI + doctor/export 不再直接调用这两个 SQLite Store 方法;`store()` 仍为兼容 accessor,SQLite + 具体实现和最终 Host/Runtime 拆分未宣称完成。 +- 验证:Host all/no-default 定向测试均为 52 个,Orchestration 均为 36 个;受影响代码已 + 通过 fmt、`-D warnings` check/Clippy 和 rustdoc。全量 workspace、独立复制、Fake 测试集、 + 编码和 diff 门禁继续按最新计划记录;本机仍无 `cargo-audit`/`RUSTSEC_ADVISORY_DB`。 +- 关联文档:`rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md`、 + `rust/docs/【验收】Agent内核与通用程序-2026-09-01.md`、 + `rust/docs/【方案】多Agent通信配额与故障隔离边界-2026-09-02.md`。 + +## 2026-09-03 Agent Runtime OpenAI 本地 HTTP 回归 + +- 决策:OpenAI endpoint 的可配置入口不能只靠字符串/构造器单测证明请求可用;新增 + 只监听 `127.0.0.1` 的 fake HTTP server,complete 与 stream 测试实际检查 + `POST /v1/responses`、Authorization、Idempotency-Key、Content-Type、JSON 请求体 + 以及 Responses/SSE 映射。测试不读取真实 API key,也不访问外网。 +- 验证:`agent-provider-openai` 当前 23 个定向测试通过;真实网关兼容性、真实凭据和 + 上游网络 smoke 仍需调用方授权,不以本地 fixture 代替。 + +## 2026-09-03 Agent Runtime 编排文件快照跨进程 CAS + +- 背景:`JsonFileOrchestrationSnapshotStore` 已有进程内 Mutex、临时文件和 rename, + 但不同进程各自读取旧 revision 后仍可能同时通过 CAS,最后一次 rename 会覆盖前者。 +- 决策:在快照同目录创建不承载业务状态的 sidecar lock 文件,使用 Rust 标准库 + advisory lock 覆盖“读取 revision、CAS 校验、临时文件写入和 rename”整个写临界区。 + 这样保持现有原子替换和 revision 合同,不引入线程、Tokio、SQLite 或分布式锁服务。 +- 验证:新增两个独立 store 实例并发竞争同一 revision 的回归;一个写入成功,另一个 + 返回 `RevisionConflict`,最终文件可重新解码。Orchestration 当前 36 个定向测试, + all/no-default-features 与 `-D warnings` 检查通过。 +- 边界:sidecar 只覆盖共享文件的本机跨进程写入;自动 scheduler、Runtime run 事务、 + 跨主机协调、完整多 Agent Teams 和原始 P0–P6 的其它外部出口仍未完成。 +- 关联文档:`rust/docs/【计划】独立通用Agent内核与单Agent程序建设计划-2026-09-02.md`、 + `rust/docs/【架构】独立Agent运行时-2026-09-01.md`、 + `rust/docs/【测试】Agent测试集与真实Provider接入-2026-09-02.md`。 + +## 2026-09-03 Agent Runtime 共享存储、Skill 严格解析与 MCP 版本门禁 + +- 决策:Core 增加 `SharedRuntimeStore` 作为同一进程内的最小共享装配工具。它以 + `Arc>` 串行化 `RuntimeStore` CAS,并将锁中毒映射为 + `StoreErrorKind::Unavailable`;不改变 Core trait,不承担跨进程/跨主机 fencing 或 + SQLite 跨表事务。 +- 决策:Skill frontmatter 继续使用有界行式子集,但拒绝未闭合/不匹配引号或列表括号、 + 空列表项和空工具名,避免畸形元数据被静默解释;不引入 YAML 运行时依赖。 +- 决策:MCP initialize 在发送 `notifications/initialized` 前严格要求当前唯一支持的 + `protocolVersion=2025-06-18`;缺失、非字符串或未知版本保持连接未初始化。该项不等于 + 多版本协商或远端兼容矩阵。 +- 决策:CLI OpenAI endpoint 来源按环境完整 endpoint → 环境 base URL → TOML 完整 + endpoint → TOML base URL 解析,环境变量优先于 TOML 且同源完整 endpoint 优先于 base。 + `OPENAI_MODEL` 仍是 CLI 合同,Host 参数化 helper 不隐式读取全局环境。 +- 验证:当前定向计数为 Core 17+14、Runtime 21、MCP 47、Skill 27、CLI 21、OpenAI 23; + 相关 all/no-default 测试、静态门禁、rustdoc、依赖/manifest/独立复制、Fake 测试集、 + 编码、diff、shell 语法和临时目录卫生已在本轮最终串行复核中通过。原始 P0–P6 仍保持 + 部分完成,真实远端会话、远端 CI、许可证策略、自动外部对账和完整多 Agent 调度仍未验收。 + +- 验证补充:使用显式 `--manifest-path rust/Cargo.toml` 的 CLI 集成 smoke 将 + `OPENAI_BASE_URL` 指向回环 fake Responses 服务,实际收到 `POST /v1/responses`,并校验 + Authorization、模型字段和响应文本;临时 SQLite 已清理。该证据不替代真实网关或真实凭据。 + +## 2026-09-03 Agent Runtime MCP/Skill fixture 套件 + +- 决策:P4 的假服务器与 Skill fixture 放在各自 crate 的 `fixtures/` 下,由测试通过 + `CARGO_MANIFEST_DIR` 显式定位;fixture 只提供固定本地响应,不把网络服务、密钥或脚本 + 执行引入测试环境。 +- 验证:stdio fixture 覆盖 MCP initialize、tools/list、tools/call;有效 Skill 覆盖 + metadata-first 与显式激活,非法 Skill 覆盖未闭合 frontmatter 拒绝。当前 MCP 47、 + Skill 27 个测试,all/no-default 定向回归通过。 +- 边界:fixture 不证明真实 Streamable HTTP 兼容、自动重连/应答、外部脚本权限或原始 P4 + 全部出口;原始 P0–P6 继续保持部分完成。 + +## 2026-09-03 Agent Runtime Codex 事件桥与重开取消 + +- 决策:`CodexAppServerBackend::invoke_node_with_runtime_events` 作为显式、可选的 + request/event/result bridge,把中立 `NodeRuntimeEventMapper` 产出的 Core 事件交给 + 调用方 sink;适配器不暗中写 Host、RuntimeStore 或创建第二套会话。未知事件、ID 错配 + 和 revision 不连续都在适配器边界拒绝。 +- 决策:外部会话取消必须能在进程重开后由 durable request-id 找回原记录,但不能因找回 + 记录就自动重放或自动宣称 safe。`cancel_persisted` 与 + `AgentHost::cancel_external_request` 只做显式 cancel,并把结果记录为 + `cancel_requested`、`cancelled` 或保守的 `unknown`。 +- 验证:Codex/Host 新增 bridge、带外中断与重开取消回归;定向计数为 Codex 64、Host 54。真实 + Codex session、完整 generated wire、自动对账/订阅、远端 CI 和完整多 Agent 调度仍 + 不由本地 fixture 代替。 + +## 2026-09-03 Agent Runtime 最终门禁复核 + +- 验证:带外中断 hook 合入后,all/no-default workspace 测试、Storage 直测、 + `-D warnings` check/Clippy、rustdoc、fmt、编码、diff、shell、依赖/manifest、独立复制 + 和 Fake 测试集均通过;当前 Codex 64、Host 54、Orchestration 38、Storage 5+40/4+33。 + `rust/target` 已清理。 +- 边界:本轮没有 `RUSTSEC_ADVISORY_DB`,audit wrapper 按设计只验证缺失输入 fail-closed; + 真实 Provider/Codex session、远端 CI、registry/许可证正式策略、自动外部对账/订阅和 + 完整持久化多 Agent 调度仍未验收。 + +## 2026-09-03 Agent 测试集接入根项目门禁 + +- 决策:复用独立 `rust/tests/agent-test-set.jsonl` 与 + `rust/scripts/run-agent-test-set.sh`,在根 `package.json` 暴露 + `agent-runtime:test`,并由 `scripts/check-repository-ci.sh` 纳入仓库级 CI;不把独立 + workspace 混入 `server-rs` 或 Vitest,也不在默认门禁访问真实 Provider。 +- 临时目录边界:测试脚本默认在 `~/data/tmp/agent-test-set.*` 下放置 SQLite、中间文件 + 和 Cargo target,退出只清理本轮目录;真实 Provider 仍须显式 `--real`。 +- 验证:根命令已通过两个 Fake 用例,真实用例按设计跳过;`check:encoding`、 + `git diff --check` 和 shell 语法检查通过。外部 BFCL、SkillsBench、τ-bench 等质量/环境 + 评测保留为后续 opt-in 适配,不替代当前确定性运行时合同。 + +- 补充:新增 `rust/tests/agent-capability-set.jsonl` 与 + `rust/scripts/run-agent-capability-set.sh`,逐项引用现有 Rust 行为测试,覆盖工具参数、 + 取消、幂等重试、审批恢复、Skill 激活、SQLite/Runtime 恢复、编排隔离和重复调用防护。 + `npm run agent-runtime:test` 现同时执行 smoke 与能力回归;能力 runner 默认不接触真实 + Provider 或 API key。 + +## 2026-09-03 Agent Runtime 测试临时目录与 Codex 退出状态修正 + +- 测试脚本的默认临时父目录统一为调用方提供的 `TMPDIR`,未设置时使用 `/var/tmp`; + 本轮只清理脚本自己创建的精确子目录,不向用户 home 写入构建或测试产物。此前关于 + `~/data/tmp` 的记录是旧实现快照,不再作为当前运行规则。 +- `CodexAppServerProcess` 在 stdout EOF 先于 `try_wait` 可见的调度窗口中,先检查短暂 + 的自然退出宽限状态,再决定是否终止 process group;自然非零退出码保留为精确 + `Exit(code)`。no-default-features 目标回归重复 20 次通过,修复后双特性 workspace + 测试、Clippy 和 rustdoc 均通过。 + +## 2026-09-03 Agent Runtime Host 只读 facade 与 fixture 清理 + +- 决策:Runtime/Host 的常用只读观察统一通过窄 facade。新增 runtime 事件、session 和 + runtime JSONL 导出入口,并继续将 run-level 审计事件与 Core runtime 可重放事件分开; + Host 内部测试不再依赖 `store()`。 +- 决策:`AgentHost::store()` 标记为 deprecated,仅保留旧 SQLite 迁移调用方;它委托 + 同一个 Runtime,不得被新代码当作第二份持久化控制面。 +- 验证:编排文件重开 fixture 同步清理 sidecar advisory lock;Runtime/Host/ + Orchestration 定向测试和 `-D warnings` Clippy 通过。最终 Host/Runtime 拆分、自动调度 + 和跨主机语义仍按原始 P0–P6 计划保持未完成。 + +## 2026-09-03 Provider 实例与协议身份 + +- 决策:`ProviderInstanceId` 只表示具体配置实例,`ProviderProtocolId` 只表示 wire + 协议;`ProviderTarget` 的旧 `id`/`providerId` 仅作为输入兼容别名,输出统一为 + `instanceId`。 +- 决策:`ModelProvider::protocol_id()` 为可选 adapter 自描述端口。Registry 对自描述 + adapter 在注册和解析边界执行协议核对,descriptor 缺省时补齐;旧/自定义 adapter 返回 + `None` 时保持调用方声明,避免无谓 breaking change。 +- 验证:OpenAI Responses adapter 报告 `openai-responses`,Core/OpenAI/Host 回归通过; + endpoint 凭据 query 变体和空白 CLI TOML model 也有本地回归。真实网关协议兼容仍需 + 外部证据。 + +## 2026-09-03 Runtime feature gate 与 OpenAI HTTP 错误边界 + +- 决策:`agent-runtime` 以默认 `sqlite` feature 提供现有 durable 控制面;package-only + `--no-default-features` 只承诺 runtime-only snapshot/event CAS、`RuntimeRunHandle` + 和 `WorkerLease` 的 portable 合同。workspace 级 no-default 仍可能由 Host 的正常依赖 + 启用 SQLite,不把它写成最终 Runtime/Host 拆分完成。 +- 决策:OpenAI Responses adapter 仅将 408/429/502/503/504 归为 `Unavailable`,其余非 + 2xx 归为 `Upstream`;状态分类属于该 adapter,不改变通用 Provider 合同。adapter 不 + 读取 `Retry-After`、不执行自动 backoff/结果查询/重放,重试预算由 Engine 控制;网关不 + 支持 `Idempotency-Key` 时由调用方关闭重试。 +- 决策:测试 runner 默认使用调用方 `TMPDIR`,未设置时回退 `/var/tmp`;只有显式 + `--from-codex-config` 的真实评测才读取调用方已有 Codex 配置,默认测试不向 home 写 + 临时产物。 + +# 2026-09-03 Agent 真实 LLM 能力评测集 + +- `rust/tests/agent-llm-eval.jsonl` 是独立的真实 Provider 评测集,固定记录输入与可验证输出断言,覆盖文本、流式和 `echo` 工具闭环。 +- `rust/scripts/run-agent-llm-eval.sh --real --from-codex-config` 才会联网;从当前 Codex 配置的模型、Responses 网关和认证引用装配子进程,默认 `agent-runtime:test` 保持离线。 +- 评测只输出脱敏摘要和分数,不持久化密钥或完整响应;模型非确定性只接受短 sentinel/协议轨迹断言,不把它当开放式质量验收。 + +## 2026-09-03 Agent Runtime 取消阶段门禁与 Codex 配置校验 + +- 决策:Host/CLI 的无主取消必须经 `RuntimeService::finish_unclaimed_cancelled_if_safe`。 + 只有 queued 未启动 run,或无 lease 且处于 `safe`/`awaiting_approval` checkpoint 的 run + 可直接跨表原子收束;历史 running、cancel_requested、reconciling、缺失 checkpoint + 和 in-flight/compacting 游标一律先进入 reconciliation。过期 lease 先 stale probe。 +- 决策:保留旧 `finish_unclaimed_cancelled` 作为低层公开兼容入口,并在文档中明确它不 + 承担阶段策略;Host/CLI 不调用。移除该 escape hatch 属于后续 breaking API/Storage + contract 变更,不能用本地兼容测试冒充已经移除。 +- 决策:Codex CLI 与 App Server 的 timeout/output/frame limit 在 serde 和运行时双重拒绝 + 零值,子毫秒 timeout 与整数转换溢出也拒绝,保证 `doctor/validate` 与 child supervisor + 使用同一边界。 +- 验证:Runtime/Host/Codex 定向回归和双特性 workspace 门禁通过;当前 Codex 77、Host 60、 + Runtime 25(package-only no-default 5)。本机未提供 `RUSTSEC_ADVISORY_DB`,审计 wrapper + 按设计 fail-closed,不记作当前漏洞扫描通过。 + +## 2026-09-03 Agent Runtime 取消竞态边界 + +- 记录:Host queued 取消的快速路径需要先读状态,再调用 Runtime 的安全无主终态入口; + worker 可能在两次读取之间领取 run。Runtime 跨表事务会重新检查 lease 并 fail-closed, + 不会越权删除 checkpoint 或伪造 cancelled,但控制端该次调用可能收到 lease conflict。 +- 后续:若要消除该窗口,应新增带 expected `queued`/无 checkpoint/无 lease 条件的单事务 + Storage/Runtime 命令并补合同测试;不得通过放宽旧低层取消兼容入口来“修复”。 + +## 2026-09-04 Agent Runtime 取消原子命令与 Codex 空帧回归 + +- 决策:queued 取消的最终 predicate 下沉到 SQLite `RunFinishGuard::QueuedUnclaimed`, + 在同一 `BEGIN IMMEDIATE` 事务中检查 queued、无 `cancel_requested`、无 worker/lease、 + 无 checkpoint;竞争失败返回 typed `QueuedCancelConflict`,Runtime 映射为 `None`, + Host 随后使用 cooperative `request_cancel`。旧 `finish_unclaimed_cancelled` 的兼容 + 语义不放宽。 +- 决策:`finish_unclaimed_cancelled_if_safe` 的 queued 分支复用上述原子入口;Core 投影 + 非 `Pending` 直接报告数据裂缝,避免只更新 SQLite 而留下孤立终态。 +- 决策:Codex JSONL channel 以循环跳过空白 keep-alive 行,避免递归栈增长;8192 行 + 空帧 fixture 覆盖该边界,既有帧大小、协议版本和未知副作用分类保持不变。 +- 验证:双特性 workspace 测试、`-D warnings` check/Clippy/rustdoc、fmt、依赖/manifest/ + 独立复制、能力集 10/10、Fake 测试集、编码、diff 和 shell 语法均通过;根 Vitest + 3189/3189 通过。`RUSTSEC_ADVISORY_DB` 未提供,cargo-audit wrapper 按设计退出 1。 + +## 2026-09-04 Agent Runtime 可替换 Store 与 RustSec 审计 + +- 决策:不为标准库 `Box` 直接实现 Core trait;在 runtime crate 使用 + 本地 `DynRuntimeStore` newtype 转发 `load`/`commit`,仅把 runtime-only + snapshot/event CAS 暴露为动态适配器接缝。SQLite-backed run/session/lease/checkpoint + 的跨表事务仍由 Runtime/SQLite 专属实现负责,避免把局部抽象误写成最终拆分。 +- 验证:portable facade no-default-features 6/6、默认 feature lib 27/27,`-D warnings` + check/Clippy 与 fmt 通过。 +- 决策:RustSec wrapper 继续要求调用方显式提供 advisory DB 和工具路径,不联网、不使用 + 漂移数据库。2026-09-04 在 `~/data/tmp/` 隔离目录用 `cargo-audit 0.22.2`、advisory-db + 提交 `5a0ebedfe8bdd2e295b171f4162f8c977bcad9a5` 扫描锁定的 188 个依赖,无漏洞/warning; + `Cargo.lock` SHA-256 为 `1a3282fe963b9a53e3d9e24a1507c75f1ee19b9a8648025d4f6da25aca5464d5`, + 工具、数据库和 marker 已清理。该一次性本地证据不替代远端持续审计或正式许可证策略。 + +## 2026-09-04 Agent Runtime 输入合同与全量门禁复核 + +- 决策:Core 的 fallible Prompt/Provider 构造器和 `ToolDefinition` 注册/请求边界统一重跑 + 嵌套 `Message`、`ContentPart`、工具参数和调用 ID 校验;serde/兼容值仍可读取,但不得在 + Provider、事件、checkpoint 或工具副作用前绕过边界。Engine 压缩器遇到 summary 响应中的 + `ToolCall`/`ToolResult` 直接报错,避免伪造或静默丢失工具历史;默认 `ModelProvider::stream` + 保留 complete 响应的 tool-call delta、usage 和完成事件。 +- 验证:Core 28 个单元 + 16 个集成、Engine 52、Runtime 27(portable no-default 6)、Host + 62;SQLite Storage 当前 5 个单测 + 44 个集成,且篡改快照 load/commit 回归通过; + all/no-default workspace check/Clippy/rustdoc/test、Storage no-default、依赖/manifest、 + 独立复制、能力 10/10、Fake 2/2、fmt、编码、shell 和 diff 全部通过。隔离 target 和临时 + 目录统一位于 `~/data/tmp`,验证后已清理。 +- 边界:MCP 已取消调用的发送前门禁仍是 cooperative best-effort;同步 I/O 硬中断、真实 + Provider/Codex session、远端 CI/registry/许可证、自动外部对账和最终 Host/Runtime 拆分 + 仍需适配器能力、外部授权或后续 breaking 设计,不能以本地 fixture 宣称完成。 + +## 2026-09-04 Agent Runtime event history、Skill discovery 与 Codex process bridge + +- 决策:SQLite RuntimeStore 在 load、CAS commit 与 recovery verification 从空快照重放完整 + `runtime_events`,校验 revision 连续性和事件语义;event log 缺失、断档或语义篡改均 + fail-closed,不接受当前 snapshot,也不写入后续事件。新增 + `runtime_store_rejects_event_history_gap_on_load_and_commit`。 +- 决策:Skill discovery/list 从 discovery 阶段即执行 `max_body_bytes` 硬上限,正文超限 + 返回 `BodyTooLarge`;新增 `discovery_and_list_reject正文超过配置上限`。 +- 决策:Codex process backend runtime event bridge 只暴露显式 request→notification→result + 顺序映射与 handler 变体;新增 + `app_server_process_backend_runtime_event_bridge_maps_notification_order`。 +- 验证:Storage all-features 5+45=50、直接 no-default 4+36=40,Skill 28,Codex 80; + 这些是本地增量,不改变原始 P0–P6 仍部分完成的结论。根 Vitest `3189/3189` 为历史记录, + 本轮工作区未安装 `vitest`,尝试以退出码 127 结束,未计入当前通过项;真实 Provider/Codex + session、远端 CI/registry/许可证、自动外部对账和最终 Host/Runtime 拆分仍未完成。 + +## 2026-09-04 RuntimeService 动态 snapshot Store 接缝 + +- 决策:只在 `agent-runtime` 暴露 `RuntimeService::snapshot_store()`,返回本地 + `DynRuntimeStore` 包装的 `RuntimeSnapshotService`,让调用方通过同一 SQLite 连接使用 + Core 的 snapshot/event CAS 合同;不把该 runtime-only 接口描述成完整 durable + run/session/lease/checkpoint 的可替换实现。 +- 验证:新增 `runtime_exposes_dynamic_snapshot_store_without_adapter_handle`;Runtime + 默认 feature 28/28、package-only no-default 6/6,fmt、`-D warnings` check/Clippy + 均通过。远端仓库/CI、真实 Provider/Codex session、自动外部对账和最终 Host/Runtime + 拆分仍未验收。 + +## 2026-09-04 manifest 预检 target 隔离 + +- 决策:`check-package-manifests.sh` 未显式收到 `CARGO_TARGET_DIR` 时,使用 + `~/data/tmp`(可由 `AGENT_PACKAGE_TMPDIR` 覆盖)的精确临时目录承载 + `cargo package --list` 中间产物,并在退出时清理;显式 target 目录仍由调用方负责, + 不误删用户目录。 +- 验证:13 个 crate 的 manifest 预检和 `bash -n` 通过,脚本退出后没有 workspace + `rust/target` 或临时 target 残留。该修复不改变原始 P0–P6 的外部未完成项。 + +## 2026-09-04 ContextItem 嵌套消息校验 + +- 决策:`ContextItem::try_new` 在保存消息前复用 `Message::validate`;Core 虽保留 + `Message::new`/serde 兼容入口,上下文值对象仍在构造边界拒绝空内容和非法内容,避免 + 把坏消息交给 `ContextSource`。 +- 验证:新增 `context_item_constructor_rejects_invalid_nested_message`;Core 为 28 个 + 单元测试 + 17 个集成测试,未引入 Engine/SQLite/Tokio 或适配器依赖。 + +## 2026-09-05 Agent Runtime Core 合同与外部候选扫描 + +- 决策:Core 的 `ToolBinding`、`SkillDefinition`、`SkillActivation`、`AgentDescriptor`、 + `BackendRequest`、`BackendResult`、`ToolContext` 在公开 serde/兼容入口统一复用 + `validate`;`backend_result_as_tool` 拒绝 request/call 身份错配和未知副作用,避免把 + 外部不确定结果伪装成成功工具结果。Engine 在调用 `ContextSource` 前验证 `ContextRequest`, + Host/Engine 在工具、Skill、MCP 和外部 backend dispatch 前复用同一合同。 +- 决策:Runtime/Storage/Host 的 `list_external_sessions` 只提供固定排序、状态/run 过滤和 + 硬上限(状态 32、limit 256)的只读候选扫描;它不自动 observe、replay、requeue 或 + reconciliation,后续对账仍由显式适配器/控制命令负责。 +- 验证:Core 30 单测 + 20 个 `core_contracts` 集成 + 1 个 `tool_context_contracts` 集成, + Engine 53、Runtime 29、Storage all-features 7+45/直接 no-default 6+36、Host 65; + all/no-default workspace 测试、check、Clippy `-D warnings`、rustdoc、fmt、依赖/manifest、 + 独立复制、Fake 2/2、能力 10/10、编码、shell 和 diff 门禁均退出码 0。临时 target 和 + 复制品只写入 `~/data/tmp` 并已清理。 +- 边界:原始 P0–P6 仍部分完成;独立远端仓库/CI 持续运行、正式 registry/许可证策略、真实 + Provider/Codex wire/session、自动外部对账/订阅、完整持久化多 Agent 调度及最终 + Host/Runtime 拆分仍未验收。 + +## 2026-09-05 Engine/Codex 公共入口与测试临时目录 + +- 决策:Engine 的公开 `validate_tool_arguments` 和 `CompressionRequest` 直调用入口都在 + 扩展/Provider 副作用前复用 Core 合同;前者复验调用、定义和工具名,后者复验预算、身份 + 与嵌套消息。Codex 0.152.1 typed adapter 的 `initialize` 在序列化前复验 + `clientInfo.name/version`;`thread/start` 字段全为可选,保持原有空值语义。 +- 决策:编排、Host、Skill、SQLite Storage 测试辅助尊重显式 `TMPDIR`,未设置时统一回退到 + `~/data/tmp`;不把默认测试快照、fixture 或数据库写入系统 `/tmp`。 +- 验证:Engine 55、Codex 81、Host 65、Orchestration 38、Skill 28;受影响 crate 定向 + 测试、workspace all/no-default、`-D warnings` check/Clippy/rustdoc、fmt、依赖/manifest、 + 独立复制、能力集、编码和 diff 门禁全部通过,临时 target/复制品已清理。 +- 边界:完整 generated Codex wire/真实 session、自动外部对账、远端持续 CI/registry/许可证、 + 完整持久化多 Agent 调度及最终 Host/Runtime 拆分仍是原始 P0–P6 未完成出口。 + +## 2026-09-05 DurableStore 第一阶段接缝 + +- 决策:`agent-runtime` 新增中立 `DurableStore` trait、拥有值的 + `DurableRunBundle` command、最小 run/session view 和 lease view;`SqliteDurableStore` + 负责当前 SQLite 转换。`prepare_run*`、claim/heartbeat/release 与 runtime snapshot + load/CAS 已经过该接缝。 +- 决策:第一阶段不拆 checkpoint、approval、终态和跨表 recovery;这些必须保持 + 单次原子 command,不能由多个 trait 调用拼接。后续需先完成 `FinishRun`、 + `CheckpointCommit` 等合同,再反转 Runtime/SQLite 依赖。 +- 验证:Runtime contract 回归 31/31、workspace all/no-default、Clippy、rustdoc、fmt、 + 依赖/manifest、独立复制、能力集、编码和 diff 门禁通过;当前仍不宣称最终拆分完成。 +- 追加:`DurableStore` 现已覆盖 checkpoint fencing、approval pending-only CAS 和外部会话 + 候选查询;Runtime contract 回归当前为 33/33,取消、终态和跨表 recovery 仍保留专用原子 + facade。 + +## 2026-09-05 DurableStore command 扩展 + +- 决策:在不把 SQL、连接或事务句柄暴露给调用方的前提下,将 `DurableStore` 扩展为覆盖 + run/session 查询、lease、checkpoint fencing、approval pending-only CAS、external-session + 候选、request-cancel/stale 扫描及 runtime-aware finish/recovery command;参数继续使用 + 拥有值 command,Runtime facade 统一经 `SqliteDurableStore` 路由。 +- 决策:finish/recovery command 只包装现有 SQLite 单事务,保留 completed/failed/cancelled + 目标、queued-unclaimed guard、runtime revision/CAS 与 lease fencing;不把多个 trait 调用 + 拼接成假事务。少数历史兼容取消/终态入口暂时保留,后续以 breaking/迁移合同收敛。 +- 验证:Runtime contract 回归当前 33/33(package-only no-default portable 6);workspace + all/no-default 测试、check、Clippy、rustdoc、fmt 及既有 Storage/Host 门禁以最新复跑结果 + 为准。该增量不改变原始 P0–P6 部分完成结论,真实 Provider/Codex session、自动外部对账、 + 远端 CI/registry/许可证、完整持久化多 Agent 调度和最终 Host/Runtime 拆分仍未验收。 + +## 2026-09-05 DurableStore 控制面查询收敛 + +- 决策:在不暴露 SQL 或事务句柄的前提下,将 cancel marker 查询、run→runtime 身份反查、 + session 更新和 safe requeue 纳入 `DurableStore`;Runtime 的 stale/recovery、安全取消预检 + 和 session facade 统一经 `SqliteDurableStore` 路由。session view 保留 metadata、created_at、 + updated_at,避免中立投影丢字段。 +- 决策:`RuntimeService::store()` 与已有的 `AgentHost::store()` 一并标记为 deprecated, + 仅作为 SQLite 迁移兼容视图;新控制面不再需要借出具体 Store。 +- 边界:诊断导出和 run-level 审计仍保留 SQLite 具体入口;无 runtime 的兼容终态已通过 + DurableStore adapter 路由。这一步只是依赖边界收敛,不等于完成 Runtime/SQLite trait 反转。 +- 验证:Runtime 33/33、workspace all/no-default、package-only Runtime no-default、Storage + no-default、Clippy、rustdoc、依赖/manifest、独立复制、Fake/能力集、编码和 diff 门禁均通过。 + +## 2026-09-05 CLI Fake 端到端 smoke + +- 验证:使用隔离 `~/data/tmp` 数据库直接运行 `agent-cli run --no-stream --jsonl`,Fake Provider + 完成工具调用和第二轮文本响应;同一数据库的 `inspect` 返回 completed,`export` 输出 7 条 + 有序审计事件,checkpoint 已清理。后台取消若被已完成 worker 抢先属于预期竞态,Runtime/Host + 已有 queued-claim 原子竞态回归覆盖;本次临时数据库、WAL 和 target 均已清理。 + +## 2026-09-05 DurableRuntime generic facade + +- 决策:新增 `DurableRuntime` 拥有式 facade,完整转发 durable command/query, + 支持任意 adapter 的注入、借用和 `into_store()` 所有权取回;`RuntimeService::durable_runtime()` + 仅是 SQLite 便利装配,不复制连接或状态。 +- 验证:新增 generic 所有权/查询回归,Runtime 34/34;后续仍需真实非 SQLite adapter 与 + 迁移合同,不能把 SQLite wrapper 误报成最终 trait 反转。 + +## 2026-09-05 工具调用 durable 记录 + +- 决策:Host 在 `ToolRequested` 时通过 Runtime/DurableStore 创建 `tool_calls` 行,在 + `ToolCompleted` 时写入 `completed`/`error` 结果;相同 call identity 幂等,旧 run 缺失行时 + 允许完成事件回填。新增按 run 查询并纳入 JSONL 导出,保持工具审计与 Core runtime event 流分离。 +- 验证:Host、Runtime、Storage 定向测试和 CLI export smoke 通过;导出可观察 1 条工具调用行, + 未把未知外部副作用误标为成功。 + +## 2026-09-05 Codex session metadata sink + +- 决策:Host 新增 `CodexRuntimeSessionMetadataSink` 和 `codex_session_metadata_sink` helper, + 将 app-server thread/turn 身份按 run/session 持久化到 `external_sessions`;首次 thread 创建 + 一行,后续 turn 原地更新 external_id 和 metadata,不创建第二套会话真相。Codex 适配器仍 + 只依赖中立 sink 合同。 +- 验证:Host session sink 回归通过,Host 当前 66/66;真实 generated wire、自动重连和外部 + 对账仍保留为 P5 外部验收项。 + +## 2026-09-06 Codex/MCP 边界硬化(历史快照) + +- 决策:MCP stdio server request 不再进入 pending 空转,Host post-dispatch `Unsupported` + 归类为 `Unknown`;Codex cancel 使用 post-dispatch 错误分类,Node mapper 接受已核对的 + slash-qualified notification alias,argv 白名单拒绝空/控制前缀,Host Codex handler 在 + 审批前校验 context 并检查 cooperative cancel。 +- 验证:当时 Codex 86、Host 69、MCP 49;workspace 双特性测试、Clippy、Rustdoc、独立复制、 + 能力集、Fake、编码和 diff 门禁均通过。真实 generated wire、协议级 turn interrupt 和 + 自动外部对账仍未验收。 + +## 2026-09-06 Codex 请求生命周期 sink + +- 决策:在不让 `agent-codex` 依赖 Runtime/SQLite 的前提下,扩展中立 + `CodexSessionMetadataSink::persist_lifecycle` 默认方法。ProcessBackend 仅在 request/cancel + 收束后发送 `completed/cancelled/unknown` 观察,并携带可用的 external ID、退出码或 + 取消结果;中立 `failed` 状态为未来 pre-dispatch 观察保留,旧 metadata-only sink 保持可编译。 +- 决策:Host sink 对 SQLite `external_sessions.metadata` 采用 read/merge/write,并保留已有 + terminal 状态,防止 lifecycle/late metadata 覆盖 custom audit 或复活已完成 run。该记录是 + request-level observation,不替代自动外部对账。 +- 决策:Host `from_host` 创建的 Codex 中立/0.152.1 typed handler 复用同一 Runtime 的 + `tool_calls` durable 表;相同 call_id 的 terminal 结果直接返回缓存,in-flight 重复请求拒绝, + 工具错误写入 `error` 终态。通用 `new` 构造器保持无 Runtime 的兼容行为。 +- 决策:长连接 `thread/start`/`turn/start` accepted response 在 child 存活时写 `active`,不 + 伪造 terminal `completed`;ProcessControl 捕获自然/被终止 child 的退出码供观察,进程级 + EOF/terminate/Drop sink 仍待单独合同;该项随后已补齐中立 ProcessControl sink。 +- 决策:backend cancel 必须依据 ProcessControl 的 pending/active outcome;进程已完成后的迟到 + cancel 不写 `cancelled` lifecycle,避免与随后/既有 completed observation 产生终态反转。 +- 验证:Codex stdio fixture、Host merge/terminal 与 Codex handler durable tool-call 回归通过, + 其中 `app_server_process_lifecycle_sink_reports_timeout` 与 + `app_server_process_lifecycle_sink_distinguishes_reader_eof` 覆盖 timeout/EOF lifecycle sink; + Codex 101/101、Host 69/69, + Clippy `-D warnings` 通过。ProcessControl 自然 EOF、直接 terminate/Drop sink、协议级 turn + interrupt、真实 generated wire/session 仍需后续专用适配器或外部证据。 +- 版本证据:本机 `codex-cli` 为 0.153.4,而仓库 typed adapter 固定核对 0.152.1;本机新版本 + schema 不能证明当前适配器兼容目标发行版。 +- 进程 sink 证据:ProcessControl 的 emit-once 自然退出/显式终止/Drop 事件包含 reason 和 + exit code,并可通过 backend 转发给 session sink;`app_server_process_lifecycle_sink_reports_timeout` + 与 `app_server_process_lifecycle_sink_distinguishes_reader_eof` 覆盖 timeout/EOF,reader EOF 与 I/O 错误也有独立 reason, + 协议级 interrupt 仍未验收。 +- 通用 `JsonRpcAppServerRouter` 已提供独立的有界 pending/notification 路由、乱序 response + 分发和并发 `turn/interrupt`;`CodexAppServerProcessRouter` 已将其接入 ProcessControl 管理 + 的真实 stdio child,但真实 Codex wire/session 仍需外部证据。 + +## 2026-09-06 DurableRuntime 非 SQLite contract harness + +- 决策:新增 `agent-runtime-contracts` crate,承接 DurableStore command/view/trait; + `agent-runtime` 仍保留 SQLite adapter 过渡实现,最终 Runtime/SQLite 依赖反转尚未完成。 +- 决策:不把测试 fake 提升为生产存储或把 DurableStore 塞进 Core;在 `agent-runtime` 的 + `cfg(test)` 中加入显式 `InMemoryDurableStore`,用 `DurableRuntime` 实际覆盖 bundle、 + lease claim/release、snapshot revision CAS、safe requeue、finish 和 expired recovery。 +- 验证:Runtime 默认测试 36/36、package-only no-default 8/8;该 harness 证明 generic facade + 不依赖 SQLite,但最终生产 trait 反转仍需 contracts crate/SQLite facade 迁移。 + +## 2026-09-06 工具调用与 Runtime 事件联合事务 + +- 决策:新增 `DurableToolCallRuntimeCommit`,将 `tool_calls` 行与对应 Core runtime + snapshot/events 的提交合同放入 `agent-runtime-contracts`;SQLite adapter 在一个 + IMMEDIATE 事务内执行 run/session/lease identity、runtime CAS、事件重放和工具行写入。 + Host 的 `ToolRequested`/`ToolCompleted` 已使用该路径,旧缺行可在已核验 Core call 的 + 前提下回填;checkpoint 仍保持独立 command,不伪装成全局 run/runtime/checkpoint 事务。 +- 验证:Storage 联合事务成功、错误回滚、lease fencing、重复 identity 幂等和 legacy row + 回填测试通过;Host Fake tool loop 与 all/no-default workspace 回归通过。 + +## 2026-09-06 DurableRuntime SQLite wrapper 模块隔离 + +- 决策:保持 `agent-runtime` 的 `sqlite` feature 和既有 RuntimeService API 不变,但将 + `SqliteDurableStore` 及 SQLite 记录转换函数移到同目录 `durable_sqlite.rs`,由 `durable.rs` + 的 `sqlite_adapter` 模块按 feature 加载。通用 `DurableRuntime` 因此只与 + contracts/Core 合同同层,后续可将该文件原样迁移到独立 adapter crate;本次不引入新的平行 + Runtime API。 +- 验证:`cargo test --locked -p agent-runtime --all-features` 36/36、 + `cargo test --locked -p agent-runtime --no-default-features` 8/8;后者的依赖树不含 + `agent-storage-sqlite`,证明 generic facade 可在无 SQLite 下编译。最终 Runtime/SQLite + crate 反转和兼容 re-export 收敛仍保留为后续 P3 工作。 + +## 2026-09-06 MCP 协议版本候选协商 + +- 决策:`McpClientOptions` 增加有界、去重的 `protocol_versions` 候选列表;initialize + 仅接受候选集合中的服务端版本。明确的版本拒绝只在连接有可重建配置时重建 stdio/HTTP + transport 再尝试下一个候选,注入的自定义 transport 不假定可重放。 +- 决策:Streamable HTTP transport 在协商成功后覆盖 `mcp-protocol-version` 请求头,保证 + 后续请求/通知流使用与握手相同的协议版本;不自动应答 server request,也不自动重放工具调用。 +- 验证:MCP 候选版本重建、有界配置和 HTTP 头回归通过,定向测试从 49 增至 52;多版本扩展 + 的完整能力合同和后台自动恢复仍是 P4 未完成项。 + +## 2026-09-06 工具调用、Checkpoint 与 Runtime 联合事务 + +- 决策:新增中立 `DurableToolCallCheckpointRuntimeCommit` command,要求 worker 同时提供 + tool call、checkpoint、Core runtime snapshot/events 和 opaque lease。`DurableStore`、 + `DurableRuntime`、`RuntimeService` 只转发拥有值 command,不在 facade 层拼接多次写入;旧的 + tool/runtime command 继续保留,避免无 checkpoint 的兼容调用被迫伪装成联合提交。 +- 决策:SQLite adapter 在一个 `IMMEDIATE` 事务内执行 run/tool identity、lease fencing、 + runtime CAS/事件重放、checkpoint upsert 与工具行 insert/update;任一步失败都回滚整批。 + 重复终态要求 runtime 与 checkpoint 内容同时匹配,避免只返回工具行而掩盖状态分叉。 +- 验证:新增 create/complete 成功、错 lease 和 runtime CAS 失败回滚回归;Storage + all-features 为 7+53,直接 no-default 为 6+36,Runtime 默认/portable 测试仍通过。 +- 边界:Host checkpoint listener 和工具 trace 目前仍分别提交;本次不在缺少共同事件输入时 + 强行拼接,因此未把该 adapter 合同误报成全链路全局事务。自动外部对账、非 SQLite 生产 + adapter 和最终 Runtime/Host 拆分仍是开放项。 + +## 2026-09-06 Codex router 进程接线 + +- 决策:新增 CodexAppServerProcessRouter,复用现有 ProcessControl、进程组收束和 + reader/writer worker,但将持久化 I/O 接入通用 JsonRpcAppServerRouter;请求超时或协议 + 错误直接终止 child,不在通用层重放未知副作用。 +- 决策:router 进程入口只提供中立 JSON-RPC request、notification、turn/interrupt 和 + 生命周期观察,不自动猜测 Codex 发行版握手或 schema;具体版本 wire 仍由专用 adapter + 负责。 +- 验证:本地 sh 长连接 fixture 覆盖 request、notification、turn interrupt 和 terminate + 回收;Codex all-features 101/101、no-default-features 101/101 通过,未知发行版兼容仍未声称。 + +## 2026-09-06 Host ToolCompleted checkpoint 联合事务接线 + +- 决策:Host `persist_runtime_trace` 在处理 `ToolCompleted` 时读取当前已持久化 checkpoint; + 若 checkpoint 存在,则使用 `DurableToolCallCheckpointRuntimeCommit` 一次提交工具结果、 + checkpoint 和 Core runtime 事件。旧数据库没有 checkpoint 时保留原有 tool/runtime 兼容路径。 +- 决策:`ToolRequested` 仍使用请求专用联合事务,checkpoint listener 不被强行延迟或复用未来 + 的多工具游标;因此这一步只收紧完成边界,不宣称 Host 已有全链路全局事务。 +- 验证:Host 69 个测试、all/no-default workspace 测试、Clippy/Rustdoc/fmt 和编码检查通过。 + +## 2026-09-06 RustSec 当前锁文件审计 + +- 决策:P0 本地审计使用临时目录中的固定 `cargo-audit 0.22.2` 和 RustSec advisory-db + 提交 `5a0ebedfe8bdd2e295b171f4162f8c977bcad9a5`,通过仓库 `run-cargo-audit.sh` 的 + `--no-fetch` 路径扫描当前锁文件,不联网更新数据库,也不把工具或数据库写入仓库。 +- 验证:加载 1239 条 advisory,扫描 190 个 crate 依赖,锁文件 SHA-256 为 + `e4dccbc5848294df920676fbcf8be1fd6fef2c543647c4ea5db63cdecc7a0bdc`,退出码 0、无漏洞或 + warning;独立远端 CI、许可证策略和 registry 发布仍需外部证据。 + +## 2026-09-06 编排取消状态原子化 + +- 决策:P6 控制面新增 `Coordinator::cancel_run(graph, run_id)` 和 + `PersistentCoordinator::cancel_run(run_id)`;前者在副本中先校验图状态,再释放活动 + run,后者沿用 mutation/revision-CAS 一次提交图节点 `Cancelled`、活动索引和配额释放。 + 这样取消不会留下“任务仍 Running 但没有 active run”的恢复裂缝。 +- 边界:该操作只维护 orchestration 状态,不触发 Runtime cooperative cancel、worker + 终止、外部副作用对账或下游自动重跑;宿主仍需按 Runtime 结果显式编排后续动作。 +- 验证:低层/持久协调器取消回归和持久快照重开通过,Orchestration 当前 40/40。 + +## 2026-09-06 RuntimeService 泛型 facade ownership seam + +- 决策:`RuntimeService` 内部改为拥有 `DurableRuntime`,SQLite + convenience methods 通过 facade 访问 adapter,避免 Runtime 同时维护平行裸 store 字段。 + 既有 SQLite accessor 和记录类型暂时保留为迁移兼容,不把 facade 层伪装成非 SQLite 生产实现。 +- 决策:新增 `RuntimeService::into_durable_runtime()` 作为 Host/调度器的显式所有权交接点; + `DurableRuntime` 支持 `Clone`,仅复制 adapter 的共享句柄,不复制 durable 状态。 +- 验证:Runtime all-features 36/36 与 fmt 通过;generic facade ownership 回归覆盖消费 + convenience shell 后继续读取同一 run。最终 Runtime/SQLite crate 拆分和 Host 全量 generic + 化仍保持未完成。 + +## 2026-09-06 Runtime/SQLite 物理拆分可行性审计 + +- 决策:最终目标仍是让 `agent-runtime-sqlite` 承接 SQLite-specific RuntimeService,形成 + `runtime-sqlite -> runtime + storage-sqlite` 的无环依赖;本轮只完成源码级审计,不引入 + 平行 facade 或兼容 re-export。 +- 证据:RuntimeService 约 59 个公开方法及记录/错误/常量导出、约 1,400 行 SQLite 测试 + 位于现有 `agent-runtime`,Host 约 70 处直接调用。直接复制一个新 crate 会造成两套 + Runtime 真相,保留旧 re-export 又无法移除 SQLite 依赖,因此必须作为 breaking migration + 按“承接 → Host/CLI/测试迁移 → 删除旧实现 → 依赖门禁”四阶段执行。 +- 边界:迁移完成前,`agent-runtime` 仍是带 SQLite 过渡 adapter 的 runtime;P3 最终拆分、 + 非 SQLite 生产 adapter 和远端发布/CI 仍未验收。 + +## 2026-09-06 Runtime/SQLite 物理拆分完成 + +- 决策:按审计方案完成 breaking migration,新建 `agent-runtime-sqlite` 承接 + `RuntimeService`、SQLite records/error、`SqliteDurableStore` 和 28 个测试;Host 迁移到 + 新 crate,未保留 `agent_runtime::RuntimeService` 平行 re-export。 +- 决策:`agent-runtime` 删除 SQLite feature、`agent-storage-sqlite` 和 `rusqlite` 依赖, + 只保留 portable `DurableRuntime`、`RuntimeSnapshotService`、WorkerLease、RunHandle + 与 RuntimeError;依赖方向为 `agent-runtime-sqlite -> agent-runtime + agent-storage-sqlite`。 +- 验证:workspace all/no-default 测试、Runtime portable 8、SQLite Runtime 28、Host 69、 + Clippy `-D warnings`、rustdoc、fmt、依赖边界和 independent-copy 检查通过; + `cargo tree -p agent-runtime --no-default-features` 不含 SQLite 依赖。 +- 后续收敛:Host manifest 移除对 portable `agent-runtime` 的直接依赖,仅经 + `agent-runtime-sqlite` 获取 RuntimeService 与 opaque WorkerLease;metadata 复核显示 + Host → runtime-sqlite → runtime/storage 的单向装配。 + +## 2026-09-06 Host 终态与后台队列 metadata + +- 决策:无工具的成功纯文本运行将 assistant message event 与 `RunCompleted` event 在已有 + `complete_run_with_lease_and_runtime` 单一事务中提交;Provider/Tool in-flight、审批、多工具、 + 取消和错误路径继续保留各自安全 checkpoint,不伪造全局事务。 +- 决策:新增 `AgentHost::prepare_run_with_messages_and_metadata`,供后台 CLI 在未装配 + Provider/MCP/Skill 时写入非敏感 provider/model/providerKind 观察信息;入口要求 JSON object、 + 16 KiB 上限并递归拒绝 secret 字段,worker 随后仍按配置装配真实适配器。 +- 验证:Host 77/77、CLI 24/24、workspace all/no-default all-targets、Clippy、Rustdoc、fmt + 和能力集 10/10 通过。 + +## 2026-09-06 queued Provider metadata 防漂移 + +- 缺口:后台 CLI 先用裸 Host 创建 queued run,worker 后续才装配 Provider;如果只保存默认 + provider/model,配置可能在 claim 前静默漂移。 +- 修复:Host 新增 `prepare_run_with_messages_and_metadata`,CLI 写入非敏感 + `provider`(effective model)和 `providerKind`;带 marker 的 queued run 在 claim 前要求 + 持久化模型与当前 Host 完全一致;内置 fake/openai Host 还会核对 provider kind,错配保持 + queued、无 lease、无 Provider/tool 副作用;没有 marker 的 legacy metadata 保持兼容。metadata 有 JSON object、16 KiB 和 secret-key + 边界。 +- 验证:新增匹配、错配和 legacy 三个 Host 回归;Host 77/77、CLI 24/24、双特性全量测试、 + Clippy、Rustdoc、fmt、能力集 10/10 通过。 + +## 2026-09-06 多工具 checkpoint 游标错配修复 + +- 缺陷:Engine 只在整个工具批次结束后写入 Safe checkpoint;Host 逐个回放 `ToolCompleted` + 时,早期结果会读取已经包含后续工具结果的最终 checkpoint,并与不完整的 Core snapshot + 组成错误的三方联合提交。 +- 修复:`persist_runtime_trace` 仅在整个事件序列的最后一个 `ToolCompleted` 复用 + checkpoint/runtime/tool 联合事务;中间结果沿用 tool/runtime 事务,不重写未来游标。 + 未伪造普通 checkpoint 或未知副作用的全局事务。 +- 验证:新增 `multi_tool_trace_only_reuses_safe_checkpoint_for_final_result`,Host 77/77、 + workspace 双特性 all-targets、Clippy、Rustdoc、fmt 和能力集 10/10 通过。 + +## 2026-09-06 拆分后 Cargo.lock RustSec 复核 + +- 验证:新增 `agent-runtime-sqlite` 后重新运行固定 `cargo-audit 0.22.2` 离线审计, + advisory-db 仍为 `5a0ebedfe8bdd2e295b171f4162f8c977bcad9a5`;加载 1239 条 advisory、 + 扫描 190 个依赖,退出码 0、无漏洞/warning。Cargo.lock SHA-256 为 + `e4dccbc5848294df920676fbcf8be1fd6fef2c543647c4ea5db63cdecc7a0bdc`。 + +## 2026-09-06 agent-app 配置与装配输入边界 + +- 决策:新增无状态 `agent-app` crate,承接 CLI 与其它通用程序入口共用的 + `AgentTomlConfig`、Skill/MCP/Codex 配置结构、配置文件与环境变量优先级、OpenAI + endpoint/base URL、MCP 认证环境变量引用、effective model 和 queued metadata。 +- 边界:`agent-app` 不依赖 Host、Runtime、线程或数据库,不读取/保存 secret 原文,也不拥有 + worker、lease、run/session 或任何持久化状态;实际 Provider、MCP、Skill 和 Host 仍由调用方 + 显式装配。CLI 仅保留 command dispatch、Host/worker 生命周期与输出协议,未复制第二套运行状态。 +- 验证:`agent-app` 3 个配置回归和 CLI 24 个定向测试通过;workspace 新增后当前为 15 个 + crate,manifest/依赖边界门禁须按新数量复跑。 + +## 2026-09-06 有界外部会话对账 + +- 决策:在 Host 增加 `ExternalSessionResolver` 与固定候选状态的 + `reconcile_external_sessions(limit, resolver)`;resolver 必须显式返回已核验的完整消息 + 历史,Host 不从外部 JSON 猜测 Message,也不隐式 invoke。 +- 决策:Completed 只通过既有 checkpoint identity/消息前缀/CAS 入口推进 safe 游标,之后仍 + 由调用方显式 requeue;Pending/NotFound 只更新保守 `unknown` 状态,单条错误以结果返回, + 不阻塞同批其它候选。候选 limit 受 `MAX_EXTERNAL_SESSION_SCAN_LIMIT` 硬上限约束。 +- 验证:Host 自动对账 fake resolver 回归覆盖完成、挂起、不存在和重复扫描,定向测试 78/78; + 真实 Provider/Codex 查询、webhook、跨主机 scheduler 和远端验收继续保持开放。 + +## 2026-09-06 审批 checkpoint 联合事务 + +- 决策:新增中立 `DurableApprovalCheckpointRuntimeCommit`,Host 在 Engine 生成完整 approval + binding 后,将 pending approval、awaiting checkpoint、runtime snapshot revision 和 opaque + lease 交给 SQLite adapter 的单一 `IMMEDIATE` 事务校验/写入;不追加已由 checkpoint 边界 + 提交过的 ToolRequested Core event。 +- 边界:Engine 的 checkpoint callback 发生在 `ApprovalRequest`/token 生成之前,callback→token + 窄窗口无法安全提前原子化;失败仍进入 reconciliation/failure gate,不把该命令宣称成所有 + checkpoint、工具 trace 和终态的全链路事务。 +- 验证:`agent-runtime-sqlite` 31/31 覆盖成功、同 identity 幂等、错 lease、revision CAS 与 + checkpoint identity 失败;Host Ask 路径 78/78 通过。 + +## 2026-09-06 审批崩溃窗口与消息前缀收敛 + +- 决策:Host 将 `persist_approval_required` 放到 Engine 审计/trace 回放之前;如果审计写入 + 期间进程退出,pending approval 已先与 awaiting checkpoint/runtime 收口,不会留下无控制 + 面入口的审批游标。 +- 决策:所有工具都会先经过 awaiting checkpoint,最终 phase 不证明消息是否已经投影。 + Host 每次执行用私有事件位置/消息位置游标衔接 checkpoint 与 trace,成功提交才推进, + 不按消息内容或最终 phase 去重。压缩前消费旧上下文的工具/事件,避免摘要后旧历史回流。 +- 验收准则:Engine 输出、Runtime 消息/工具索引、存储工具结果与从零事件重放应一致; + 最终文本或“包含一条工具消息”不能证明消息恰好一次。 +- 范围准则:原始 P0–P6 明确暂缓公开许可证、不实现跨主机自动调度;registry、全量 + Codex schema 和自动 webhook 也不是原文必做项,不能用于持续阻塞本期交付。 + +## 2026-09-06 真实 Codex wire 探测 + +- 决策:增加可选 `rust/scripts/probe-codex-app-server.sh` 作为 P5 人工证据入口;脚本隔离 + `CODEX_HOME`/TMPDIR,默认只执行真实 `codex app-server --stdio` 的 initialize、initialized、 + thread/start,`--schema` 只输出 v2 schema 大小/hash,成功后主动关闭 child,不进入默认 CI。 +- 验证:本机 `codex-cli 0.153.4` 握手通过;schema 摘要 706653 bytes,SHA-256 + `e5f798fd1343c539f01fedea0e8a84a43c080fcca4615c80eb04a5edab4f7d0a`。未发送 turn/start、 + 未读取 API key;该证据不代表仓库 0.152.1 typed adapter 完整兼容 0.153.4。 + +## 2026-09-06 当前锁文件 RustSec 复核 + +- 当前 `rust/Cargo.lock` SHA-256 为 `c9b14957f7e0edda46073f1b2a0ff06e084b0d747af118a29654ca1dc1022711`; + 固定 `cargo-audit 0.22.2` 与 RustSec advisory-db `5a0ebedfe8bdd2e295b171f4162f8c977bcad9a5` + 已扫描 191 个依赖,退出码 0、无漏洞/warning。工具和数据库位于临时目录并已清理,远端 + 持续审计仍需 CI 记录。 + +## 2026-09-06 Agent Runtime P0–P6 要求级本地审计 + +- 结论:独立 `rust/` workspace 的 P0–P4、P6 本地可交付出口,以及 P5 的中立/受限协议子集,均已按原始计划逐项核对并有当前源码、fixture 和门禁证据。当前 Host 计数为 80 个单测 + 7 个消息持久化集成回归;all/no-default workspace、Clippy、Rustdoc、fmt、依赖/manifest、独立复制、编码和 diff 检查均通过。 +- 恢复语义:进程重启验收指新连接读取 durable 状态,再由调用方显式执行 stale reconciliation → 外部对账 → safe resume;未知 Provider/工具调用不自动重放。`compacting` 失败/取消保持 reconciliation 门,不能伪装为可安全继续。 +- Codex 边界:窄 process/client 接线提供显式 Host server-request handler;并发 `JsonRpcAppServerRouter` 对带 ID server request fail-closed。两条接线不能合并宣称完整发行版 App Server;真实 Codex 0.152.1 wire/session 和协议级 interrupt 仍待对应发行版证据。 +- 非目标/外部项:registry、公开许可证、全量 generated schema、跨主机自动调度、自动 webhook/查询、远端 CI 持续记录不作为本地阻塞项;需要真实发行版、凭据或部署语义的行为继续保持明确的外部证据边界。 + +## 2026-09-09 Host 外部桥接模块化 + +- 决策:把 `ExternalBackendToolExecutor`、`ActiveExternalCall`、 + `CodexRuntimeSessionMetadataSink` 及其 helper 移入 Host 私有 `external.rs`;根模块继续 + 显式 re-export 原公开类型,保持嵌入调用合同不变。 +- 边界:Codex server-request handler 仍留在根编排层,因为它同时绑定 ToolRouter、审批策略、 + Runtime durable tool-call 和版本化 wire;Engine execution/checkpoint/trace 也不搬入 Runtime。 +- 验证:Host 80/80、Runtime control 4/4、workspace 双特性测试、两套 Clippy、Rustdoc、fmt、 + 编码、依赖边界和 diff 检查通过。 + +## 2026-09-09 Host checkpoint 物理模块化 + +- 决策:将 `DurableCheckpoints`、`RuntimeTraceProgress`、checkpoint listener、runtime trace + 投影及相关 checkpoint 转换 helper 移入 Host 私有 `checkpoint.rs`;根模块保留通用 reducer + helper 和执行编排,避免移动被根测试/恢复路径共享的状态原语。 +- 边界:该模块依赖 Engine checkpoint/事件类型,但不依赖具体外部适配器;不把 Engine glue + 下沉到 Runtime,也不改公开 Host API、SQLite schema 或 Cargo.lock。 +- 验证:Host 80/80、Runtime control 4/4、workspace 双特性、Clippy、Rustdoc、fmt、编码、 + 依赖边界和 diff 检查通过。 + +## 2026-09-09 Host Codex handler 物理模块化 + +- 决策:将两个 Codex server-request handler、namespace/参数桥接和 durable tool-call helper + 移入 Host 私有 `codex.rs`;根模块显式 re-export 原公开 handler 类型。 +- 边界:handler 同时依赖 ToolRouter、审批策略、Runtime tool-call 记录和版本化 wire,因此 + 不搬入 Runtime 或通用 Codex process adapter;Engine execution/checkpoint 仍保持独立。 +- 验证:Host 80/80、Runtime control 4/4、Codex 101/101、workspace 双特性、Clippy、Rustdoc、 + fmt、编码、依赖边界和 diff 检查通过。 + +## 2026-09-09 Host 控制面拆分 + +- 决策:把不依赖 Engine/Provider/MCP/Skill/Codex 的 durable 控制逻辑迁入 + `agent-runtime-sqlite::RuntimeService`,包括 `cancel_run`、`fail_unclaimed_run`、 + `resolve_approval_decision`、`reconcile_provider_result` 和 `reconcile_tool_result`。 + Host 同名 API 保留为薄委托,避免 CLI/嵌入方发生破坏性变更。 +- 边界:Engine 执行、checkpoint listener、trace 投影、heartbeat/Cancellation worker、 + MCP/Skill/Codex/ExternalBackend 桥接仍留在 Host;`finish_cancelled` 是 Engine worker 收口 + 需要的内部 helper,不搬到 Runtime。 +- 验证:Runtime-only `tests/control.rs` 4/4、Host 80/80、workspace all/no-default、 + Clippy、fmt 和依赖边界检查通过;未改 SQLite schema、Cargo.lock 或 Core/Engine API。 + +## 2026-09-09 Host 私有模块化 + +- 决策:将 Host 的 ToolRouter/namespace resolver、MCP 工具与上下文桥、Skill 上下文源分别 + 移至 `tools.rs`、`mcp.rs`、`context.rs`;根模块显式 re-export 原公开类型,内部 helper 只用 + `pub(super)`,不使用 glob import 掩盖依赖。 +- 边界:Engine execution、checkpoint/trace、heartbeat/Cancellation worker、Codex/External + backend 生命周期继续留在根编排层;文件拆分不改变 Runtime API、SQLite schema 或公开 Host API。 +- 验证:拆分后 Host 80/80、Runtime control 4/4、workspace all/no-default、Clippy、Rustdoc、 + fmt、编码、依赖边界和 diff 检查通过。 + +## 2026-09-09 Host 执行入口模块化 + +- 决策:将 `run`、`run_existing`、streaming/cancellation 入口及 worker/lease 执行恢复编排移至 + Host 私有 `execution.rs`;根模块保留装配 facade、checkpoint/trace、Engine worker 主体和 + 跨职责终态 glue。 +- 边界:不改变 Host 公开 API、Runtime/SQLite 合同或 Engine 接口;`finish_cancelled` 等依赖 + Engine worker 的内部 helper 暂不迁移,避免为降低文件行数扩大职责边界。 +- 验证:Host 单测与 Clippy 定向通过;完整 workspace、Rustdoc、编码和 diff 门禁在提交前复跑。