Skip to content

Preserve same-Turn Todo selection after quota preflight - #8275

Open
loopx-agent wants to merge 4 commits into
mainfrom
codex/prepared-quota-selection-transport-20261107
Open

loopx-agent wants to merge 4 commits into
mainfrom
codex/prepared-quota-selection-transport-20261107

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Checkpoint preflight could save and read a prepared quota decision through a symlink to its parent directory. The returned Todo selection command then passed that symlink as an output root, which the next guard rejected before admission.

Resolve the parent when allocating the original prepared capture, then bind the same-Turn selection to that physical root. The selected Todo gets a separate capture, with the original Turn identity and native context options. A caller's explicit output root still takes precedence and is subject to the existing path validation.

Verification

  • Tested 3ade877c91232f39a464009c98db2032f5d401cd with main at e58ba30bc949c29ec90c570a8362fb1e7ec9f3be. All 53 focused source tests passed. File and SQLite exercise the real checkpoint preflight, saved context-project, returned selection argv, and digest-bound readback of the selected Todo. The original bytes and Turn are preserved; an explicitly supplied symlink output root is still rejected before guard execution. Removing the parent resolution alone makes both alias cases fail again.
  • The broader run passed 354 tests and skipped 39. Its three explicit reader-window failures reproduce on the same main. The checkpoint matrix still covers delivery on/off, ordinary/replan, and both stores. The native fixture requires a real delta when source numeric spellings agree, and a complete view after compaction or when the numeric spelling changes.
  • Standard premerge: six direct checks and 17 selected checks passed. The CLI output growth check failed identically on main and this head (Turn plan growth 11,432, limit 9,300). The existing limit and merge hold remain.

This is source checkout validation with isolated fixtures. It does not qualify installed use, model adoption, or end-to-end benchmark cost. The current head awaits independent re-review.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
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)

[P2] 原 capture 可读,但目录别名会使后续选择失效。 同一私有目录仅改为通过一个 symlink 别名访问。原始 guard 成功并保存了未绑定的 capture,已有 context-project 也能读取。基线发出的选择可继续,当前 head 把别名当作 decision-output-root,File 和 SQLite 都在 guard 前返回 1,生成零份选择 capture。 从实际已接受的 capture 绑定一个经过原根验证的物理目录,保留显式 root 的优先级及独立的新 capture。回归用真实 context-project 和返回的选择 argv 覆盖物理父目录、目录别名及错误输入。 父目录推导

动机 / Motivation

旧 checkpoint preflight 已执行一次 quota guard,但操作者或 worker 仍需要在同一个 Turn 里选择 Todo。 已保存的 prepared reference 在选择前指向原 guard。后续命令如果丢失新 capture 的位置,就无法按原 native reader 路径继续读回所选结果。 改动给后续选择附上父目录和 native 参数。真实物理目录可以继续,原 guard 接受的目录别名仍会在下一步失败。 本轮核对原准入、选择、返回的路径和实际本地 capture。真实模型、正式实验及安装态采用另行验收。

改动思路 / Approach

quota emit 保留原 guard 和不可变文件。capture binder 给后续选择补现有参数,选择仍由原准入校验。 这里需要补的是选择命令的 transport。既有 TypeScript 选择规则和 admission 仍处理原 Todo 与 Turn;当前缺口是已接纳的目录别名不能复用。 在同一 capture transport helper 解析已验证的目标,保留原始 capture 和已有 CLI 的失败边界。

具体改动 / Changes

本次使用基线 97a34a4 的原 Turn 与 capture 约定。原 Turn 的选择继续走原准入;已有 capture 的恢复不重复首次 guard。 基线规范

  • same-turn-choice。 物理父目录的 prepared capture 提供同 Turn 的选择命令。在 File 和 SQLite 中执行后生成一份新 capture,原字节保留,读回绑定原 Turn 和所选 Todo。
  • accepted-path-compatibility。 同一私有目录仅改为通过一个 symlink 别名访问。原始 guard 成功并保存了未绑定的 capture,已有 context-project 也能读取。基线发出的选择可继续,当前 head 把别名当作 decision-output-root,File 和 SQLite 都在 guard 前返回 1,生成零份选择 capture。
  • capture-isolation。 8 个 checkpoint preflight 模式正例通过,覆盖打开和关闭 context delivery、普通或 replan 与两个存储后端。 原始 capture 字节保持。

首次写入由 quota emit 完成。binder 保留已有 root,后续准入入口按原规则校验。目录别名在两条路径上受到不同约束。 选择命令 根目录验证

对主干的风险 / Risks

同一私有目录仅改为通过一个 symlink 别名访问。原始 guard 成功并保存了未绑定的 capture,已有 context-project 也能读取。基线发出的选择可继续,当前 head 把别名当作 decision-output-root,File 和 SQLite 都在 guard 前返回 1,生成零份选择 capture。 当前 exact head 10 通过,独立目录别名两例失败。父目录相同的基线对照 4 通过。 Quick premerge 的 6 项直接检查和 3 项选中检查通过。 与 main 118b4c7 的本地组合保留同样结果。 基线旧测试的 4 个 native 断言还要求已经更换的 --decision-output-root;修订的真实用例核对 prepared 入口和实际后续捕获。 远端 CI 未查询。

我的整体评价 / Verdict

对 abb6760 请求修改。原 Turn、capture 独立保存与物理路径的正控制可保留。请让已经成功保存原 capture 的目录别名也可以走完同一轮选择。 安装态、真实模型与正式实验尚未纳入本轮样本。

English verdict: REQUEST_CHANGES. A prepared capture with an accepted aliased parent can no longer complete same-Turn selection.

# A prepared reference binds one immutable directory. Same-Turn
# selection uses its parent to create a fresh sibling capture.
if capture_directory is not None and getattr(args, "prepared_capture_reference", False):
capture_root = capture_directory.parent

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] 原 prepared capture 接受父目录别名,但这里把逻辑路径转成 --decision-output-root。File 和 SQLite 中,同一 context-project 在基线可继续选择,当前 head 返回 1 且 guard 未运行,新 capture 为零。请保留原选择与不可变文件,传经验证的物理父目录,再跑物理目录和别名对照。

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

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)

[P2] SessionStart 前的选择会把新捕获写进原目录,忽略调用方的显式根。 SessionStart 前,给 context-project 一个不同且已存在的私有 --decision-output-root 和 8,000 字节上限。File 和 SQLite 的当前 head 都把新捕获写到了原捕获旁,指定目录没有生成捕获。实际首读返回 12,000 字节。上一个 PR head 写到指定目录并返回 8,000 字节;当前主干已丢失两个参数,但不会在原捕获旁落盘。

动机 / Motivation

checkpoint worker 在原 guard 已保存、SessionStart 尚未到来时,需要可执行的 Todo 选择命令与可预期的输出位置和大小。 在 File 和 SQLite 上,用相同 checkpoint 预检比较普通父路径别名,并从首读取出真正执行的选择命令。 默认别名可在原 Turn 继续;显式私有根与窗口在 SessionStart 前未生效,实际落盘在原捕获旁。 改动覆盖捕获路径和当前选择参数。按实际开关、别名、显式根和恢复入口检查了全 diff。

改动思路 / Approach

在写入准备捕获前处理路径别名,继续通过已存在的 should-run 选择和 context-read 读回。SessionStart 后可用的显式覆盖应与早期的 full 路径一致。 复用既有传输合成和同 Turn 的准入 owner,消除了把正常目录别名当成不安全根的失败。准备时保存默认根后,展示路径必须把当前调用的显式覆盖送到实际执行。 本次结论针对默认别名恢复和当前选择命令的显式覆盖,完整安装和测评另有验收。

具体改动 / Changes

基线为 e58ba30bc949c29ec90c570a8362fb1e7ec9f3be。现有上下文规范约束私有输出根、显式打开窗口以及同一 capture 的恢复。RFC 规定已保存预检的原身份和投递边界。 基线规范

  • 父目录别名。 File 和 SQLite 都通过父目录别名读取原捕获。上一个 PR head 把别名当输出根,守卫前退出;当前 head 的默认选择在物理父目录生成独立捕获,读回了同一 Goal、Agent、Turn 和 Todo。当前 main 的默认别名选择也能运行,未在原捕获旁写入副本。
  • 原捕获。 两后端验证源和 guard 字节不变,选择增加一个原 Turn 回执、零扣额。
  • 显式覆盖。 SessionStart 前,给 context-project 一个不同且已存在的私有 --decision-output-root 和 8,000 字节上限。File 和 SQLite 的当前 head 都把新捕获写到了原捕获旁,指定目录没有生成捕获。实际首读返回 12,000 字节。上一个 PR head 写到指定目录并返回 8,000 字节;当前主干已丢失两个参数,但不会在原捕获旁落盘。

关键代码讲解

准备阶段把物理根写入原捕获。没有 SessionStart 时,返回的选择命令沿用这个准备阶段的根,未带当前 context-project 的显式参数。修改后的测试只在有 SessionStart 时检查字节上限,也只在该路径检查显式根。 默认物理根 · 当前覆盖的构造 · 提前投递的测试断言

对主干的风险 / Risks

旧讨论的别名拒绝已有当前 head 的正例。显式覆盖触发的是另一个失败条件。路径受控、回执身份正确仍不足以保证指定目录和工具窗口。 前次讨论 首读窗口规范

95 项通过、14 项跳过,3 项显式窗口失败在基线同样复现。另有 context-read reference 两边各 73 项通过,并对三个 revision 各自跑了 File/SQLite 选择和读回。 Quick premerge 的 6 项直接检查和 3 项选中检查通过。 主干前进只涉及 #8317 的研究页面,合并树检查通过。 两个已有显式窗口测试的命令退出 1,第三项同样拒绝 --page-bytes 组合。两边失败的是同一组三个用例,异常详情一致。 两边实际 turn plan 增长都是 11,432 字符,计算上限 9,300 + 60 × 35 = 11,400。 当前 main 与 head 用同样的 SessionStart 前设置得到 12,000 字节。前一 PR head 得到 8,000 字节。 远端 CI 未取样。

语义与 CI 对齐

沿用既有 CLI 选项和 typed capture 规则。输出根的默认选择可以变,调用方明确给出的路径和字节窗口仍约束实际命令。

我的整体评价 / Verdict

通过现有选择命令合成路径,在 SessionStart 前的 full 结果也绑定当前显式根和输出上限。已保存的物理根仅作默认值,原文件和 SHA 保持可读。如果当前投递无法兑现显式选项,返回清楚的恢复状态。补上两种后端在 SessionStart 前的显式选项用例,实际运行选择和首读,断言落盘位置、字节、回执与原身份。 普通别名恢复已证实。SessionStart 前的显式传输仍需修复。标准输出增长检查在基线与当前 head 均失败,保留为独立合并门。未验证实装、模型采纳或实际测评成本。

English verdict: REQUEST_CHANGES. The ordinary alias path now preserves the same Turn. Before SessionStart, the emitted selection writes next to the original capture despite a valid explicit root; the first read also returns 12,000 bytes when 8,000 was requested. Keep current explicit transport options in this branch.

assert (parsed.context_delivery == "on") is enabled
assert parsed.codex_context_dir == (str(native) if enabled else None)
assert parsed.max_page_output_bytes == (32000 if enabled else None)
assert parsed.max_page_output_bytes == (32000 if lifecycle else None)

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] Preserve explicit selection transport before SessionStart

SessionStart 前,给 context-project 一个不同且已存在的私有 --decision-output-root 和 8,000 字节上限。File 和 SQLite 的当前 head 都把新捕获写到了原捕获旁,指定目录没有生成捕获。实际首读返回 12,000 字节。上一个 PR head 写到指定目录并返回 8,000 字节;当前主干已丢失两个参数,但不会在原捕获旁落盘。 通过现有选择命令合成路径,在 SessionStart 前的 full 结果也绑定当前显式根和输出上限。已保存的物理根仅作默认值,原文件和 SHA 保持可读。如果当前投递无法兑现显式选项,返回清楚的恢复状态。补上两种后端在 SessionStart 前的显式选项用例,实际运行选择和首读,断言落盘位置、字节、回执与原身份。

@mergify

mergify Bot commented Nov 7, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @loopx-agent.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 7, 2026

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

needs-rebase Mergify: the pull request has merge conflicts with its base branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant