Repository navigation
fix(quota): omit private capture budget on unqualified hosts - #7993
Conversation
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
动机 / Motivation
使用原生命令等待完成并结算一次工作的 CLI 用户,在不支持私有捕获读取的平台会收到无法直接执行的扣额命令。 原来生成命令总带私有捕获预算参数,Windows 或缺少可调用 getuid 的宿主会在结算前被拒绝;现在这些宿主收到同一身份的完整结果命令,合格 POSIX 保留原预算参数。 已在模拟宿主资格边界的真实 SQLite CLI 上验证:原生成命令可完成一次结算,重放不追加,显式私有请求仍在副作用前拒绝。 本 PR 只调整输出传输参数,不授予工作、文件隐私或结算权限,不启用 Context Delivery,也不宣称已完成真实 Windows 安装或 PowerShell 验证。 真实 Windows/PowerShell 仍未验证;五个既有测试失败与严格 CQR 合并限制保持开放。
改动思路 / Approach
保留单一结算 owner,只在共享命令生成处选择输出参数。可用私有读取器的宿主继续得到64000字节预算;不支持的宿主使用既有完整结果 API。资格判断与现有 private_capture_uid() 的 POSIX/可调用 getuid 条件一致,完整结果并非新增授权或静默扣额回退。省略全部平台的参数会丢掉现有 POSIX 有界输出;新建配置、持久标志或第二结算机制都没有必要。当前边界是传输可用性修复,身份、写回顺序和扣额决策仍由原有 TS 与日志 owner 负责。
具体改动 / Changes
规范依据 docs/reference/required-work-context.md,固定版本 1dc98eb8739777a65102e18553658dc70e0f0044,现有 Bounded settlement results 明确:省略选项使用原完整结果 API;不支持私有验证的平台,显式选项必须在结算前拒绝。本 head 以生成命令、实际执行和拒绝无副作用三个观察实现该约定,不把完整原目标或真实平台资格算作完成。
关键代码讲解
_settlement_capture_budget_arg:179只在 POSIX 且 getuid 可调用时返回原预算后缀,其他宿主返回空串。build_turn_scoped_cli_settlement_plan:190用这个后缀构造扣额命令,原 Goal/Agent/Turn、来源、步骤与写回前置条件不变。handle_native_context_command:991未改动,显式私有预算仍先经private_capture_uid();拒绝时返回appended=false、registry_mutated=false,不会先执行再隐藏错误。
完整 diff 两个文件、+38/-1;生产改动是本地 transport helper 与一处命令替换,其余为三个参数化验证用例。24份完整计划对比覆盖两种 API、Todo/重规划身份、具体/变量 Turn 和三种宿主资格:8份 POSIX 计划完全相同,16份不支持的计划只删对应输出参数,全部指引、控制和其他命令保持一致。提交 DCO 已核对。
对主干的风险 / Risks
最大反例是为了绕过输出错误而削弱隐私检查,或修复命令生成却仍无法结算。PASS:同一合成 fixture 在实际 SQLite CLI 走 bootstrap、claim、guard、writeback、原生成命令和重放,head 三种资格视图均只追加一次;base 的两种不支持视图会在原生成命令处拒绝,POSIX 两端均通过。guard 明确选择合法完整输出模式;模拟仅限两个模块的 OS 能力视图,真实 CLI/TS/存储与结算日志都在运行。另行显式请求私有预算仍失败,拒绝前后 Goal runtime 文件内容一致;没有真实 Windows、模型或付费 provider 执行。
PASS:Ruff、premerge6项直接及13项选中检查。FAIL:扩展套件 head85通过/5失败/1跳过,base82通过/5失败/1跳过;同一陈旧 validation 文案断言和四个 guard 未解读 context navigation 而缺 normal_delivery_allowed 的失败均在改动前的语义路径发生。相关 TS、CLI capture 和 SQLite 测试源码未变;本次真实 CLI 反例另行覆盖了被修改的后续结算。既有94语句/61决策点维护性建议在两端相同。严格 CQR 仍 FAIL,最终 premerge 因 quality_invalid_receipt 保持合并限制,没有将基线相同改成通过。未查询或等待 CI。
我的整体评价 / Verdict
未发现当前 PR 引入的阻塞问题,APPROVE。长期工作路径判定 improved,仅指已验证的原身份恢复与一次结算;用户体验判定 improved,生成命令直接使用已允许的完整 API,省去人工删除无效选项,没有新增确认。改动维持已有词汇和决策 owner,不新增持久状态、默认功能开关或权限。没有渲染页面改动,视觉评审不适用;真实 Windows/PowerShell、安装采用和完整成本仍未验证,五项既有失败与严格质量限制保留。当前证据支持这个完整、可回滚的源码修复切片,不替代合并授权或更广的平台验收。
English verdict: APPROVE at ae4c72f0e54bb9cceb521ee1aa5278837ba5416c. Native CLI evidence supports the scoped transport repair and preserves explicit privacy refusal and once-only settlement; strict quality holds remain.
|
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 |
Render the owner-generated settlement budget only when the private capture reader can actually run. Reuse one host-qualification helper for command generation and capture execution so POSIX-looking hosts without getuid also receive the full-result command. Signed-off-by: huangruiteng <huangrt01@163.com>
ae4c72f to
a5b742f
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · GPT-5 · OpenAI · self_reported
动机 / Motivation
需要完成一次 Turn 结算的 CLI 用户与生成 settlement command 的 control-plane 调用方,可能遇到生成命令和不支持私有捕获的平台能力判断不一致。--max-page-output-bytes 只有在 POSIX 且 getuid 可调用时才可执行;如果命令生成只看 os.name == "posix",一个缺少 getuid 的限制型宿主仍会收到无法直接运行的命令。
这个 PR 把“生成命令”和“真正执行私有 capture”统一到同一个 host qualification。可观察结果是:Windows 与缺少 getuid 的 POSIX-like 宿主收到不带预算参数的完整结果命令,合格 POSIX 保留 64,000 字节预算;调用方若仍显式请求预算,原有隐私拒绝继续在副作用前发生。
当前 main 已修复普通 Windows 分支,因此本 PR 的剩余价值是有界语义收敛,而不是重做完整平台支持。真实 Windows/PowerShell 与不常见 POSIX-like 宿主没有在本机执行;边界仅覆盖纯平台资格谓词与命令渲染,完整平台安装不属于本次增量。
真实 Windows/PowerShell 和真实缺少 getuid 的平台没有运行;这属于平台 fixture 的环境缺口,不是当前纯 predicate 分支的未执行代码。
改动思路 / Approach
入口仍是唯一的 build_turn_scoped_cli_settlement_plan()。它以 Goal、Agent、Todo/Replan、Turn 和原结算步骤为权威输入,仅在 QUOTA_SPEND command template 中决定是否附加输出预算。新的 private_capture_supported() 位于 private capture IO owner,并由 private_capture_uid() 与 settlement renderer 共用;因此资格来源、命令生成和执行拒绝不再各自维护近似条件。
正向路径是:构造 settlement plan → 共享 helper 判断宿主资格 → 合格 POSIX 添加预算参数,否则保留既有完整结果 API → 原 quota CLI 仍按 private_capture_uid() 检查显式预算。反例路径是:平台看似 POSIX 但无 getuid,helper 返回 false,生成命令不附加预算;显式调用者仍收到现有 fail-closed 错误,结算和 registry 不被修改。
架构判断采用 retain:只把一处 policy predicate 收敛到私有 capture owner,不新建配置、持久状态或第二结算器。当前 PR 边界是一个可逆的 runtime transport 修复;权限、身份、写回顺序、评分和结算决策仍由原 owner 负责。
The shared predicate is a private-capture invariant consumed by settlement rendering, with no second policy owner or default expansion. 仅收敛 private-capture 平台资格并调整 owner-generated output suffix;不实现新的平台 ACL reader。
具体改动 / Changes
精确 head a5b742f198a6758d4aeb04f90efabbb5066a5444,base 477df45d9036414a4a7f5a558ef2ef1e38e08c75。diff 为三个文件、+32/-9:production +9/-4,tests +23/-5。仓库规范 docs/reference/required-work-context.md,固定版本 477df45d9036414a4a7f5a558ef2ef1e38e08c75。
Bounded settlement results — implemented: 规范要求没有合格 POSIX private-capture 验证的平台在结算前拒绝预算选项,并允许移除该选项后使用同一 Turn 的完整结果 API。本 head 让 owner 生成的命令只在资格成立时携带预算,同时保留显式调用者的 fail-closed 行为。
关键代码讲解
private_capture_supported:作为单一资格谓词,只返回os.name == "posix"且os.getuid可调用;没有文件写入或结算副作用。private_capture_uid:先复用该谓词,不支持时保留原有ValueError,支持时再取得真实 UID;显式预算的拒绝语义不变。build_turn_scoped_cli_settlement_plan:仅在 helper 返回 true 时渲染--max-page-output-bytes 64000,Goal/Agent/Turn、来源、写回和其余命令内容完全不变。
测试把 nt + getuid、posix + no getuid 与 posix + getuid 三种能力视图放在同一 oracle 下,并分别验证 command suffix 的 false/true 分支。它覆盖了当前 main 只看 os.name 时会漏掉的第二个 unsupported 形态。
对主干的风险 / Risks
没有发现当前 head 的 blocking finding。最强反例是“为了生成可执行命令而放宽私有 capture”:本 PR 没有让 unsupported host 通过私有路径,只让依赖输出预算的 owner-generated command 使用规范已允许的 full-result API;显式 --max-page-output-bytes 仍在 effect preparation 前拒绝,并由既有 bounded-spend 测试覆盖。
- PASS:三种平台资格视图与 command true/false 分支,共 4 个聚焦测试通过。
- PASS:bounded-result 与 decision-capture 套件 60 项通过;Ruff、changed-Python compilation、CLI import/help 和 diff hygiene 通过。
- PASS:仓库原生 premerge 通过,包含 4 个 direct checks、8 个 catalog canaries、8 个 risk-profile smokes;零失败、零 manual hold。
- FAIL(pre-existing):
test_quota_settlement.py为 81 passed、1 skipped、1 failed;test_in_flight_validation_conditions_completion_on_original_deliverable在 pristine base 与当前 head 均因既有大小写断言keepvsKeep失败,签名相同且本 PR 未修改该文案或路径。 - UNVERIFIED:真实 Windows/PowerShell 和真实缺少
getuid的平台没有运行;这属于平台 fixture 的环境缺口,不是当前纯 predicate 分支的未执行代码。
语义与 CI 对齐
没有新增共享 vocabulary、权限字段、持久状态或默认策略。本 diff 复用现有 private-capture owner 和 Bounded settlement results 约定;唯一运行时变化是省略一个本来无法执行的输出参数。按 packet 的 wait_for_ci=false,本轮没有等待或轮询远端 CI,远端 policy/merge readiness 另行读取。
我的整体评价 / Verdict
APPROVE 当前 head 的有界 runtime transport 修复。 problem_context 为 justified_increment:它保留 POSIX 有界输出、恢复 unsupported host 的 owner-generated full-result 命令,并消除了当前 main 中命令生成与真实 capture 的两套近似资格判断。long_horizon 与 user_experience 均判为 improved,范围限于原 Turn 的可执行结算命令与 truthful privacy rejection;没有扩大到平台 ACL 实现或默认权限。
repository_reuse 为 reused,architecture assessment 为 retain:private capture owner 提供唯一谓词,settlement renderer 只消费该判断。改动与已证实的残余缺口相称,新增测试足以覆盖本切片的正反分支;真实不常见平台没有执行,但代码路径不依赖 OS 私有 API,且既有显式预算拒绝由独立测试保护。视觉评审不适用,因为本 PR 没有渲染页面或产品界面变更。
合并权限由用户本轮显式授权;仍需 exact-head review、approval closeout 与 merge readiness。该结论不授予新的平台支持声明、运行权限或扩大默认预算。
English verdict: APPROVE at a5b742f198a6758d4aeb04f90efabbb5066a5444. One shared platform predicate now gates both generated settlement output and private capture, preserving explicit fail-closed budget requests; focused tests and all 16 local premerge checks pass. A same-signature pre-existing text assertion remains, and real nonstandard-platform execution is unverified.
Goal / source
Owner-generated settlement commands appended
--max-page-output-bytes, but private capturemust fail closed unless the host has POSIX identity support (
os.name == "posix"and acallable
os.getuid). A generated command that requests the bounded-output path on anunsupported host can fail before settlement and block the ordinary lifecycle.
Current repair · 2026-11-04
Head:
a5b742f198a6758d4aeb04f90efabbb5066a5444. Base: currentmain477df45d9036414a4a7f5a558ef2ef1e38e08c75.Current
mainalready omits the budget arg on non-POSIX hosts, so this PR no longer carriesits original duplicate implementation. The remaining gap is that
mainchecks onlyos.name == "posix", while the actual reader also requires a callableos.getuid.private_capture_supported()predicate at the private-capture IO owner.private_capture_uid()and owner-generated settlement commandrendering. POSIX-looking hosts without
getuidnow receive the full-result command.--max-page-output-bytesstill fails closedbefore settlement on unsupported hosts.
test proves the generated suffix follows the shared predicate.
Validation
test_quota_settlement.py: 81 passed, 1 skipped, 1 failed; the unchangedtest_in_flight_validation_conditions_completion_on_original_deliverablefails in thesame way on pristine
mainbecause an existing assertion expects lower-casekeep.git diff --check, and bilingual RFCchecks passed.
loopx canary premerge --from-git-diff --git-diff-base origin/main: passed, including4 direct checks, 8 catalog canaries and 8 risk-profile smokes; zero failures and zero
manual holds.
Boundary
This is a provider/runtime transport correction. It adds no scoring, permission, protocol,
persisted-state, migration or default behavior change. The owner-generated command omits only
an unsupported output-presentation option; identity, writeback ordering and settlement remain
with their existing owners.