完善Agent Runner恢复与真实进程验收
增加Linux临时端口耗尽时的高位loopback安全回退 修复Runner重启恢复的逐投影幂等与完整身份失败关闭 为Runtime JSONL尾部和进程恢复审计增加修复与冲突校验 强化Runner强杀E2E的分层证据与非ENOENT错误处理 阻止模型最终回复复述私有PTY输出及短值 补齐恢复回归测试、真实Provider验收与技术文档
This commit is contained in:
@@ -87,7 +87,7 @@ Runner 从显式 AppData 目录读取 `game-creator.config.json`,API Key 不
|
||||
|
||||
### 本地协议
|
||||
|
||||
- Runner 只监听随机 `127.0.0.1` 端口。
|
||||
- Runner 只监听随机 `127.0.0.1` 端口。正常启动先使用 `bind(127.0.0.1:0)`;Linux 仅在该调用因 `AddrInUse` 失败后,才读取并严格解析 `/proc/sys/net/ipv4/ip_local_port_range`、`ip_unprivileged_port_start` 与 `ip_local_reserved_ports`。候选限定在 61000-65535 高位段,排除当前临时范围、低于实际非特权起点和显式 reserved ranges,再按当前 boot 随机化起点并跳过已占用端口。任一 sysctl 缺失/非法、候选耗尽或出现非占用类错误必须失败关闭,不得停止现有服务、绑定非 loopback 地址或回退到无 token IPC。
|
||||
- AppData endpoint 文件权限收紧为当前用户,保存 `protocolVersion / pid / bootId / port / token / heartbeatAt`。
|
||||
- 请求使用 `u32` 长度前缀加 UTF-8 JSON,单帧最多 1 MiB。
|
||||
- 每个请求必须携带私有 token、`requestId` 和协议版本。
|
||||
@@ -591,12 +591,22 @@ process record 已升级为 v3:只在 `SANDBOX_READY` 后执行 revision / ver
|
||||
|
||||
process-session child 在 `SANDBOX_READY` 后阻塞等待父侧显式 `COMMIT_EXEC / ABORT_LAUNCH`,不设置独立短 commit timeout;durable mutation 超过 3 秒仍保持 target 零执行,父侧失败时显式 abort 并回收 wrapper 树。target 在 child pre-exec 内暂时屏蔽 SIGTTOU,完成 `setpgid + tcsetpgrp` 并恢复信号掩码后才 exec,避免目标以后台组立即读取 PTY 而停在 SIGTTIN。`command.terminate` 经 Runtime bridge 和 trampoline 私有控制帧只向 target group 发 SIGTERM;即使 direct leader 先退出,trampoline 仍在 800ms 宽限内等待同组后代完成清理,wrapper / bwrap 继续承载 PTY 与控制链,超时后才强杀外层 containment group。正常 EOF 写入成功后即使可信 terminal 先于状态落盘,也按成功返回而不是误标 reconciliation;Windows legacy start 的 durable callback 只在同 action首次创建时执行,ready/exec/started 使用同一时间点避免跨秒倒序。
|
||||
|
||||
本地确定性测试已覆盖真实 PTY stdin/echo/EOF/terminate、direct leader 先退出后同组后代完成 400ms SIGTERM 清理、3.2 秒慢 durable callback、workspace sandbox后代、commit callback失败目标零执行、target exec failure、fast exit 0/7、wrong nonce/peer/乱序、v1/v2 active/terminal迁移、v3 非法组合、旧 boot launching及同 action replay、live record 缺失门禁、start Agent DB 审计失败、start cursor零消费和控制材料不进入 transcript。该实现完成 V1.11.1 本地 Runtime 链路,但真实 Provider `process-session` 与 Runner kill 套件仍须按新协议重跑;在它们通过前,不新增 Provider PASS、统计条数或整体“已验收”结论。
|
||||
本地确定性测试已覆盖真实 PTY stdin/echo/EOF/terminate、direct leader 先退出后同组后代完成 400ms SIGTERM 清理、3.2 秒慢 durable callback、workspace sandbox后代、commit callback失败目标零执行、target exec failure、fast exit 0/7、wrong nonce/peer/乱序、v1/v2 active/terminal迁移、v3 非法组合、旧 boot launching及同 action replay、live record 缺失门禁、start Agent DB 审计失败、start cursor零消费和控制材料不进入 transcript。真实 Provider 结果必须继续由下述独立 `process-session` 与 Runner kill 套件证明,不能用本地用例替代。
|
||||
|
||||
2026-07-14 最新真实 `gpt-5.5` `llm-runtime` 已按新增 metadata 门禁通过:123 条 task、208 条 event、220 条 Agent DB、15 次成功工具执行、2 次 `command.exec`(先失败后成功)、1 次 `project.verify`、3 个隔离实例、双视口浏览器验证、唯一 completed / assistant;Runner 强杀后 run / session 身份稳定恢复,重复、副作用重放、密钥和诱饵泄漏均为 0。保留现场独立核对 2 条 command.exec 和 1 条 project.verify 审计均为 `bubblewrap / workspace-write / disabled / workspace-v1` 后按 sentinel 清理。
|
||||
|
||||
同日追加的 `process-session` Provider 复验未计为通过:前三轮模型以不同 actionId / fingerprint 主动重复 start;收紧策略后的旧 E2E 又暴露 V1.10 fixture 与 V1.11 sandbox 契约冲突,fixture 在 readiness 前写 `.agent`、启动 namespace 内 loopback 并把 namespace PID/端口当宿主事实,而 V1.11 正确隐藏 `.agent` 且隔离 pid/network namespace,因此 `process-transcript-interaction-evidence-missing` 不能直接归因于模型抄错 challenge。修复方向是纯 PTY fixture:不写 `.agent`、不启动 TCP、不跨 namespace 读取 PID/端口,以唯一 process record/start/readiness、连续 cursor、stdin hash、精确 echo、stopped 和宿主项目 cwd 进程清零作为事实。最新一次重跑在零工具计划阶段连续收到 Provider 502,只记外部瞬态失败,不用于判断 Runtime。新的纯 PTY Provider 套件 PASS 前,不更新 V1.10 历史结论,也不把本次失败描述成已验收。
|
||||
|
||||
2026-07-14 后续真实 `gpt-5.5` 已在纯 PTY 与 process record v3 门禁下完成最终复验。`process-session` 为 PASS:41 条 task、75 条 event、63 条 Agent DB、8 条 receipt,唯一 start、3 次连续 poll、唯一 stdin / terminate、3 次 cursor 推进、唯一 terminal / completed / assistant;side-effect replay、重复 action / message / receipt,以及 task / event / Agent DB / receipt / conversation / activity / output / report 的私有进程正文、Provider Key 和诱饵泄漏均为 0。`process-session-runner-kill` 为 PASS:13 条 task、19 条 event、19 条 Agent DB,readiness 后真实 SIGKILL owning Runner,项目 cwd 进程归零,新 boot 恢复同一 run / session,只形成 1 条 reconciliation,reconnect / stdin / terminate / completed / assistant / replay / 泄漏均为 0;两套 disposable 项目都按 sentinel 自动清理。
|
||||
|
||||
真实复验同时补齐两项独立 Runner 恢复能力。Linux 在 `bind(127.0.0.1:0)` 因临时端口池耗尽返回 `AddrInUse` 时,懒读取临时范围、实际非特权起点和 reserved ranges,只从剩余 61000-65535 高位 loopback 候选选择端口;当前 32768-60999 被约 2.8 万连接占满的主机上真实选到范围外端口并完成两套测试。
|
||||
|
||||
新 boot 执行 `runtime.resume` 时,先全局拒绝指向未知 Agent 的 reconciliation record,再在每个 Agent lane 锁内主动处理所属旧 boot active process record;恢复前逐条核对 record 与 task 的 Agent、run、task 和 conversation session 身份,不同 owning run 或任一身份冲突都失败关闭。命中后按 task / state+queue / event / Agent DB 四个持久步骤逐项补齐 `needs-reconciliation`:task 只追加一次,state 和 queue 每次从 ledger 重建,event 与 Agent DB 绑定原 start action identity。task/event 通用 JSONL 追加和 Agent DB 专用入口都先锁内修复截断尾行;同键记录必须核对 Agent/task/session/run/process/owner boot,冲突报错而不是当成完成。任何步骤后再次崩溃都不能阻止下次 resume 补齐其余投影;重复完整 resume 不产生第二条 task、event 或 audit。整个路径禁止恢复 LLM、按 PID 重连或重放 start。
|
||||
|
||||
Runner-kill E2E 不再以 latest task 或单个 process record 推断整体恢复成功,而是分别要求全量 task、event、Agent DB、runtime state 和 process record 中专用 reconciliation 精确一次,并保持 reconnect 为 0。runtime state 是必需证据并加入公共正文泄漏扫描;可选 activity / output 或证据目录仅在 `ENOENT` 时视为空,权限、I/O 或 JSON 损坏必须直接让验收失败。
|
||||
|
||||
`command.poll` 私有正文虽然必须进入 owning Agent context 供后续交互,但模型 prompt 不是持久化隔离边界。后台 finalization 在创建 assistant journal 前检查当前 run 的成功 poll observation;只要存在非空输出,就把模型最终回复整体收束为固定安全完成摘要,再计算 response fingerprint 并写 conversation/event/Agent DB。该边界不按长度猜测 token,因此 challenge、ready/echo/stopped 行和短 PIN 的局部回显都不能扩大到公共持久面;没有私有 poll 正文的普通回复保持原样。
|
||||
|
||||
## 验收命令
|
||||
|
||||
- `npm run ai-game-creator-shell:typecheck`
|
||||
|
||||
@@ -34,7 +34,9 @@ V1.11 的受保护仓库控制目录同时包含 `.git / .agent / .agents / .cod
|
||||
|
||||
2026-07-14 V1.11.1 第一切片:`command.exec / project.verify` 已共用受信任 trampoline launcher。bwrap 的 `child-pid` 只推进 child-created,`--block-fd` 放行后仍须收到 `SANDBOX_READY`;Runtime 完成 revision / verification durable callback 后才发送 `COMMIT_EXEC`,收到 `EXEC_ESTABLISHED` 后才计算业务 timeout。当前不把这套 stdin 私有控制通道用于 PTY;`command.start` 与 process record v3 仍是下一切片,相关链路完成前 V1.11.1 保持进行中。
|
||||
|
||||
2026-07-14 V1.11.1 第二切片:`command.start` 已通过 PTY 外 abstract Unix socket bridge 接入同一 ready/commit/exec 状态机,process record 升级 v3;真实 target 的 PTY stdin 由 trampoline 复制已验证的 fd 1 slave,不向 target 泄漏 fd 0控制通道。pending launch和 live registry共同参与 capacity/shutdown/idle/final门禁,旧 v1/v2 active record迁入 reconciliation,target exec failure和fast exit保留同一 processId。child 等待父侧显式 commit/abort,不以短 timeout 猜测持久化失败;target 在 pre-exec 内原子进入 PTY 前台进程组,graceful terminate 只给 target group 发信号,direct leader 先退出后仍给同组后代保留清理宽限。v3 状态组合和时间顺序失败关闭,旧 boot launching及同 action replay降级为 launch-unknown,Windows 同 action replay 不重复执行 durable mutation且使用单一 launch 时间点。确定性测试通过后,V1.11.1 仍等待真实 Provider `process-session` 和 Runner kill复验,不提前标记整体已验收。
|
||||
2026-07-14 V1.11.1 第二切片:`command.start` 已通过 PTY 外 abstract Unix socket bridge 接入同一 ready/commit/exec 状态机,process record 升级 v3;真实 target 的 PTY stdin 由 trampoline 复制已验证的 fd 1 slave,不向 target 泄漏 fd 0控制通道。pending launch和 live registry共同参与 capacity/shutdown/idle/final门禁,旧 v1/v2 active record迁入 reconciliation,target exec failure和fast exit保留同一 processId。child 等待父侧显式 commit/abort,不以短 timeout猜测持久化失败;target 在 pre-exec 内原子进入 PTY 前台进程组,graceful terminate只给 target group发信号,direct leader先退出后仍给同组后代保留清理宽限。v3 状态组合和时间顺序失败关闭,旧 boot launching及同 action replay降级为 launch-unknown,Windows 同 action replay不重复执行 durable mutation且使用单一 launch时间点。Linux Runner 的 port 0 因临时端口池耗尽失败时,只从系统临时范围外选择非特权 loopback端口。新 boot resume 先全局拒绝未知 Agent record,再在 Agent lane 锁内核对 process record 与 task 的 Agent/run/task/session 身份,并逐项补齐 task、state/queue、event 和 Agent DB reconciliation;task/event/Agent DB 截断尾行可修复,event/audit绑定原 start action 并对同键身份冲突失败关闭。任一步后再次崩溃都可继续修复,完整重复 resume 不重复投影。不同 owning run 或身份冲突时不恢复 LLM、按 PID 重连或重放 start。后台 finalization 只要看到当前 run 的非空私有 poll 正文,就在 assistant journal 前把模型回复整体收束为固定安全摘要。Runner-kill 验收分别从全量 task、event、Agent DB、runtime state 和 process record 取证,并只把可选证据文件/目录的 `ENOENT` 当作空面。
|
||||
|
||||
2026-07-14 V1.11.1 最终真实验收:发布 AppData 的真实 `gpt-5.5` `process-session` 形成 41 条 task、75 条 event、63 条 Agent DB 和 8 条 receipt,唯一 start、3 poll、唯一 stdin / terminate、3 次 cursor 推进及唯一 terminal / completed / assistant全部通过;Runner kill套件形成 13 条 task、19 条 event、19 条 Agent DB,真实 SIGKILL后项目 cwd进程清零、新 boot保持同 run / session并只形成 1 条 reconciliation。两套的 reconnect、重放、重复 action / message / receipt、公共进程正文、密钥和诱饵泄漏均为 0,disposable项目均自动清理;V1.11.1 持久进程链路据此完成验收。
|
||||
|
||||
2026-07-12 真实验收:发布 AppData 中的真实 `gpt-5.5` 已通过最终安全收紧后的 `llm-runtime` 套件,覆盖 Runner 强杀恢复且 run/session 身份稳定、仓库上下文、checkpoint/精确修改、失败命令诊断与修复复验、6 套确认生命周期、项目验证、桌面与移动非空画布证据、3 个隔离实例并行和唯一 all-join;95 条 task、161 条 event、137 条 Agent DB、13 条合法工具协议、副作用判重、终态投影、assistant audit、消息、回执和密钥泄露均以结构化落盘事实验收。`full` 套件仍要求 External Editor API 配置,缺失时必须返回 `BLOCKED(editorApi)`,不得记为通过。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user