Repository navigation
fix(context): return executable recovery for missing selections - #7940
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: actor_kind=model_agent; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=max.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
在 quota context-read 中补读 normal/replan capture、遇到字段缺失或数组地址错误的 Agent 与 CLI 使用者。 错误虽能报告原 --select 参数和 token 序号,调用者仍需手工重建同 capture 的父节点 discovery 命令;normal/replan 布局或标量节点会使重建更容易出错。 缺失成员或错误数组索引返回可执行 recovery_command,指向原输入中最近的已验证容器、同一 capture 摘要与原分页预算;执行目录后可读取修正路径,不重复 admission 或结算。 不自动执行 recovery、不新增 CLI flag、共享错误 schema、权限或状态 owner;不宣称真实模型已采用、安装版成功、token/benchmark 或长程净收益。 真实宿主/模型如何使用该恢复提示及其完整成本仍由既有 native context/runtime owner 验收;本次仅资格化源码 CLI 与本地 typed runtime 旅程。
改动思路 / Approach
复用现有 TS lookup 和 EffectRuntimeRequestError,只增加本模块的 typed subclass 与位置字段;Python 不遍历 payload 或解析 reason。命令、引用、分页和原值读取继续复用既有 owner,不另造通用错误协议或 UI。 本 PR 闭合既有 context-read 的错误→目录→修正读取旅程;TS 仍是唯一 pointer lookup owner,Python 只把已验证 token 数转回原转义前缀并复用命令 encoder。 原 source、执行权限和失败/恢复 owner 不变,不新增用户确认或状态副本。用下面的实际对照与文字解释局部变化,无需另加未验证渲染的图。
具体改动 / Changes
规范依据是先读的不可变 base 107e9e32e8f3df29f63b94524250f4044cc01a80 中 Selected capture details / 按需读取捕获详情:缺失或无效选择须整批拒绝,保留原参数位置、完整 capture/selection 摘要与原值,通过最近的已知容器恢复,不重放 admission 或 settlement。 当前 criterion 映射为 implemented;这是 independently usable 的 justified_increment,改过的文档不是自身验收 oracle。
关键代码讲解
capturedContextSelection只在显式 boolean true 时将本模块 SelectionLookupError 变为位置型 rejection;omitted/false仍抛原错误,其他 runtime/语法错误不被误收养。resolveSelection在 canonical sort/dedup前保存原参数编号;查找途中记录最近 object/array 的 token 数,标量/null不被当作容器,不返回部分 selection 或源值。read_context_capture先验证完整原 capture;仅从原 escaped pointer 截取已验证前缀,复用既有 encoder输出相同摘要/预算、offset0的新目录命令,不在Python另遍历或解析 reason。
独立完整六模块 181 PASS/46 conditional native SKIP;完整四 TS 模块 91 PASS/0 SKIP,typecheck/Ruff PASS。另在真实 CLI 对同样 normal/replan capture,执行 explicit/reference ×4种地址共16场景:base有正确原子拒绝但无 executable recovery;head 16/16 可执行,目录后 corrected whole value 与原值一致。覆盖 scalar/null、空数组、转义键、错误根 /、重复参数仍标 argument3,1024字节页/8192字节输出预算保留;随后篡改原文件,所有返回命令均拒绝,未创建 registry/runtime,未准入或扣额。
对主干的风险 / Risks
恢复命令刻意重复调用方原地址前缀,不能把整个返回包当作无路径公开日志;位置型 reason 仍不回显 keys/values,拒绝批次不交付源值。目录从 offset0开始,既不是失败 selection 的 continuation,也不证明正文/全量模型保留。语法错误仍要先修语法,坏 capture/其他 runtime 故障走原分类,不把未知失败猜成 selector 问题。46项 native skip不等于安装版或真实模型采用;本轮只资格化现有源码CLI/typed runtime恢复旅程。
Standard premerge6directPASS;19selected=18PASS+1inherited ratchet advisory,0blocking/skip/manual hold; full semantic and five-path public boundary checks pass. Raw ratchet remains FAIL. 原始 ratchet 在107e和两head的393字节stdout/空stderr逐字相同,完整因果 machine_section_projection.py未变,判为 pre_existing_unrelated;原FAIL保留。没有查询、轮询或等待CI,也没有把 unknown CI作为缺证或批准依据;当前改动不变量由独立本地证据建立。review、独立质量门、讨论/readiness和 merge权限分别判断。
语义与 CI 对齐
复用既有词汇与 typed owner,diff-scoped advisory之后跑完整语义检查;零 candidate不代替语义判断。CLI 的显式 selection/list 启用本地 recover_selection_errors 传输选项;普通 TS caller 省略或设 false 时保留原 lookup exception,initial-read/full read 沿原路。新字段明确只接受 boolean;位置型 reason 不含 keys/values,恢复命令则明确只重复 caller 已提供的前缀。 Applied: local typed lookup error replaces a potential prose parser or second Python traversal. A shared runtime error schema, new flag or generic recovery framework is unnecessary. 未删除必读、身份、完整性或结算义务,guidance不自动执行。
我的整体评价 / Verdict
对 7940@c4347e3b2e8c49a460cc95549bdb00e99521633c 为 APPROVE,未发现当前改动的有效 blocker。long_horizon=preserved、user_experience=improved;不可变 base 的同 capture/原子选择契约和实际恢复后正确读取,证明这条有界接续无需新的 admission 或 effect;不把它当作模型理解或长期效果证明。 沿原 CLI 一次错误响应直接拿到可执行的同源修复路径,无需重建已知文件、摘要或预算,也不需要用户确认;当前恢复仍由调用方决定,目录可见不冒充正文已读。 恢复命令会重复调用方提供的路径前缀,属于与原命令相同的私有上下文,不能把整个错误包当作无路径的公开日志。没有自动 discovery 或新执行轮次;本轮实测目录和修正读取,不推断模型成本节省。 本 PR 闭合既有 context-read 的错误→目录→修正读取旅程;TS 仍是唯一 pointer lookup owner,Python 只把已验证 token 数转回原转义前缀并复用命令 encoder。 已检查完整5路径和现有 CLI/JSON/Markdown 消费入口;没有渲染页、布局、首屏或设置控件变化。 没有视觉改动需截图;已安装 Host/真实模型采用未在此验证。 真实宿主/模型如何使用该恢复提示及其完整成本仍由既有 native context/runtime owner 验收;本次仅资格化源码 CLI 与本地 typed runtime 旅程。 作者同账号用 COMMENTED承载批准结论,不冒充正式自批准;旧失败、讨论与合并门继续独立保留。
English verdict: APPROVE the reviewed exact head; independent local evidence covers the changed invariants, with disclosed cost, failures and unverified adoption retained and no merge or quality-gate waiver.
|
This pull request has merge conflicts with Choose the remote for the base repository, not an out-of-date fork. 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 HEADFor a same-repository clone whose Keep the DCO |
…on-recovery-20261103 Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com> # Conflicts: # loopx/control_plane/quota/context_selection.ts
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: actor_kind=model_agent; model=gemini-4-argon-high; provider=Google; reasoning_effort=high; declaration_source=runtime_reported
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
在 quota context-read 中按需补读 normal/replan capture 时,若调用方遇到字段缺失(context_selection_missing_pointer)或数组索引无效(context_selection_invalid_index),原有错误虽能报告 --select 参数位置与 token 序号,但调用方仍需手工拼接同一 capture 的父节点 --list 命令;当路径停在标量、null 或含 RFC 6901 转义段(~0 / ~1)时更容易拼错。本 PR 在保持整批原子拒绝、不回显源正文的前提下,直接返回指向最近已验证容器的 recovery_command,复用同一 capture 摘要与分页预算。
改动思路 / Approach
保持 TypeScript 控制面 loopx/control_plane/quota/context_selection.ts 作为唯一 RFC 6901 pointer lookup owner,引入局部 SelectionLookupError 记录 argumentIndex 与 parentTokenCount,并在 recover_selection_errors: true 时返回 rejected_selection;Python CLI 适配器 loopx/cli_commands/quota_capture.py 仅从原 escaped pointer 截取已验证前缀并复用 context_capture_read_command 构造 --list --offset 0 恢复命令,不在 Python 侧二次遍历 payload 或解析错误文本。本次同步主干 origin/main(9bfa71c679f58d8b19a533956b627c96343616e5),无损合并 context_selection.ts 中新增的 coalescedInitialPointers 与 SelectionLookupError。
具体改动 / Changes
loopx/control_plane/quota/context_selection.ts:新增SelectionLookupError记录argumentIndex与最近对象/数组容器的parentTokenCount,并与主干coalescedInitialPointers干净合流;当recover_selection_errors === true时将缺失指针与无效数组下标转化为结构化rejected_selection返回,指针语法错误与非布尔参数继续 fail-closed。loopx/cli_commands/quota_capture.py:在非--initial-read的显式 selection/list 读取中启用recover_selection_errors=True,遇到rejected_selection时截取原--select参数的已验证父前缀,生成带相同 capture 摘要与分页预算的recovery_command。docs/reference/required-work-context.md、tests/control_plane_ts/context_selection.test.ts与tests/control_plane/test_context_capture_selection.py:同步中英文文档说明,并覆盖 TS 与 CLI 在 normal/replan、显式文件/reference 文件、转义键、标量父容器及篡改后 fail-closed 的恢复契约。
关键内容讲解
当路径在标量或 null 之后继续深入时,parentTokenCount 保留最后一个非空对象/数组容器深度,因此 /a~1b/~0/0/leaf/deeper 会回退到 /a~1b/~0/0 而非标量 leaf;同时失败批次不返回任何 content,也不会触发新的 guard、admission 或 spend。
对主干的风险 / Risks
改动收敛在 context_selection.ts 与 quota_capture.py 的显式 selection 失败恢复分支,不改变 --initial-read、成功读取分页或 capture 完整性校验。验证已通过:
node --test tests/control_plane_ts/context_selection.test.ts(14 passed)uv run --extra test python -m pytest tests/control_plane/test_context_capture_selection.py -q(54 passed)uv run --extra test ruff check loopx/cli_commands/quota_capture.py tests/control_plane/test_context_capture_selection.py(All checks passed)
语义与 CI 对齐
合并 origin/main 后 SelectionLookupError 与 coalescedInitialPointers 各自保持独立职责,显式 --select 恢复与 --initial-read 父节点合并互不干扰;docs/reference/required-work-context.md 中英文段落及公开边界均已对齐。
我的整体评价 / Verdict
该 PR 通过单一 TS 控制面 lookup owner 与轻量 CLI 恢复命令拼接,在保持原子拒绝和零正文泄露的前提下消除了手工重建父容器 --list 命令的摩擦,并与最新 origin/main 干净合流、测试全绿,符合直接合并标准。
English verdict: APPROVE — Clean conflict resolution against origin/main; TS and Python context-selection recovery contracts and regression tests are verified on exact head e675ea86c54fd43c4bfb2ad54f5cbcb88fbf78e7.
A missing selected field currently reports its argument/token position but leaves the reader to reconstruct a usable discovery command. This is especially error-prone when normal and replan captures expose different fields, or traversal reaches a scalar. Return an executable, digest-bound
recovery_commandthat lists the nearest verified container from the original request; the caller then retries its corrected selection.The existing TypeScript selector remains the only lookup owner. An internal opt-in returns positional rejection data without partial selections, keys or values; legacy runtime callers keep their thrown errors. The CLI uses the caller’s escaped prefix and existing command encoder, preserving quoting, capture identity and page budgets. Malformed syntax, unreadable/tampered captures and unrelated runtime failures retain their existing paths. The command repeats a caller-supplied prefix, so it must be treated as private context like the original command. No automatic discovery, admission, consumption receipt or permission change is introduced. English and Chinese reference guidance is updated.
Validation on
c4347e3b2e8c49a460cc95549bdb00e99521633c:/) and an absent top-level field against an immutable capture. Both returned a runnable same-capture root-index recovery command, which succeeded without an admission or model request; an index is not full-read evidence.Scope review: the active consumer is the existing
quota context-readCLI/host recovery path. The local typed-error extraction is the bounded refactor; no shared runtime error schema, new CLI flag, authority provider or separate UI is added. This proposal does not alter currently running experiments. Independent exact-head review remains required.