Skip to content

Validate checkpoint capture routes before quota admission - #8407

Open
loopx-agent wants to merge 1 commit into
mainfrom
codex/guard-checkpoint-capture-route
Open

loopx-agent wants to merge 1 commit into
mainfrom
codex/guard-checkpoint-capture-route

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

An agent can pass its persistent context directory as the output root of a checkpoint decision. The listener rejects that route after the quota guard has already committed, leaving the caller to recover a Turn whose response could not be handed back.

The checkpoint Host now records its wake's capture root beside the private socket. Heartbeat rendering and quota capture preparation verify that binding before admission. Older Hosts retain their existing listener checks, and the wire format and listener verification stay the same.

A regression test uses the real quota CLI, an isolated SQLite authority and the original Unix listener. An incorrect root produces neither a receipt nor a capture. The correct invocation for the same Turn produces one receipt and the listener releases its exact capture.

Validation: the focused real-path test passed in the change worktree. The checkpoint, decision capture and external scheduler suites passed with 234 tests and four Linux-only cases skipped on macOS. Ruff passed for the changed Python files.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent, gpt-6.1-sol, OpenAI, runtime_reported, reasoning_effort=max

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

动机 / Motivation

错误的 checkpoint 捕获路径会在 Host 放行之前留下已提交的 quota guard。对照真实 CLI 和 Unix listener,验证正确路径、错传目录,以及绑定后父目录变成符号链接。当前提交能提前拒绝直接错传的目录,但路径字符串未变时仍会留下回执和捕获。此次使用隔离的 File/SQLite 与真实 Host listener,没有调用模型。父目录漂移仍需在准入前拒绝。

改动思路 / Approach

沿用同一个私有 socket、捕获目录和原 Host 放行协议。预检只约束当前 wake 的捕获路由。由 Host 写入有大小和权限约束的 sidecar,heartbeat 和 quota 共同读取;老 Host 缺少 sidecar 时保留原回读。当前两条预检都只比对字符串,没有复核读到的根目录是否仍指向同一物理路径。

具体改动 / Changes

评审 d2e56f5,基线 71190b6,5 个文件,+106/−4。原 checkpoint 契约 保留 Host 对原捕获的路径、digest 和放行验证。direct-mismatch-preflight、valid-and-legacy-parity 通过;physical-root-drift-preflight 未达成;live-benchmark-qualification 另验。

关键代码讲解

  • Host 绑定 先校验物理路径,再写私有 sidecar。准入预检 只比较已存字节和当前路径字符串。
  • 原 listener 仍会检查当前物理路径,因此能拒绝已经到达 socket 的错误捕获。

对主干的风险 / Risks

P2:先在正常目录绑定 Host,再把捕获目录的父目录挪走,并在原位置放指向新位置的 symlink。最后一层目录本身仍正常,旧路径字符串也完全相同。File/SQLite 的候选与基线各留一份 guard 回执和一份捕获,Host 拒绝放行。直接传错目录和非私有 sidecar 的候选均是零回执、零捕获;正常 root 和显式目录只提交一次且按原 digest 放行。234 项相关测试通过、4 项 Linux writer 专项跳过;6 项直接及 18 项自动预合并检查通过,另有 benchmark 人工门。

我的整体评价 / Verdict

请求修改。新检查修复了常见的参数错传,但还不能保证路径漂移时在写入前拒绝。请在当前 sidecar 路由的共享预检中核对实际物理路径,并保留老 Host 与最终 listener 检查。复评应验证该反例两种权威库均无回执、无捕获。

English verdict: REQUEST_CHANGES. A bound capture path can still become nonphysical before admission, leaving a committed guard and saved capture that the Host refuses to release.

return # Earlier Hosts still validate the capture when accepting it.
except (OSError, ValueError) as exc:
raise QuotaCommandValidationError(f"invalid decision handoff binding; no guard was run: {exc}") from exc
if bound_root != os.fsencode(requested_root):

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 在 guard 写入前核对已绑定根的物理路径

Host 写完绑定后,把 capture root 的父目录移走并在原位置建一个指向新目录的 symlink。请求字符串仍等于 sidecar,末级目录也不是 symlink,因此 File 和 SQLite 都各写了一份 guard 回执和捕获,随后原 Unix listener 以 “decision capture root must be a physical absolute directory” 拒绝放行。请在共享预检里确认请求根的严格解析结果仍等于绑定的物理路径;保留缺少 sidecar 的旧 Host 路径和最终 listener 验证。回归用例应要求零回执、零捕获。

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant