Skip to content

fix(quota): omit private capture budget on unqualified hosts - #7993

Merged
huangruiteng merged 1 commit into
mainfrom
codex/settlement-budget-platform-20261103
Nov 3, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/settlement-budget-platform-20261103

Conversation

@cocolord

@cocolord cocolord commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Goal / source

Owner-generated settlement commands appended --max-page-output-bytes, but private capture
must fail closed unless the host has POSIX identity support (os.name == "posix" and a
callable os.getuid). A generated command that requests the bounded-output path on an
unsupported host can fail before settlement and block the ordinary lifecycle.

Current repair · 2026-11-04

Head: a5b742f198a6758d4aeb04f90efabbb5066a5444. Base: current main
477df45d9036414a4a7f5a558ef2ef1e38e08c75.

Current main already omits the budget arg on non-POSIX hosts, so this PR no longer carries
its original duplicate implementation. The remaining gap is that main checks only
os.name == "posix", while the actual reader also requires a callable os.getuid.

  • Add one private_capture_supported() predicate at the private-capture IO owner.
  • Reuse that predicate from private_capture_uid() and owner-generated settlement command
    rendering. POSIX-looking hosts without getuid now receive the full-result command.
  • Preserve explicit caller behavior: explicit --max-page-output-bytes still fails closed
    before settlement on unsupported hosts.
  • Cover Windows, POSIX-without-getuid, and qualified POSIX in one test table; the command
    test proves the generated suffix follows the shared predicate.

Validation

  • New platform/command tests: 4 passed.
  • test_quota_settlement.py: 81 passed, 1 skipped, 1 failed; the unchanged
    test_in_flight_validation_conditions_completion_on_original_deliverable fails in the
    same way on pristine main because an existing assertion expects lower-case keep.
  • Bounded-result and decision-capture suites: 60 passed.
  • Ruff, changed-Python compilation, CLI import/help, git diff --check, and bilingual RFC
    checks passed.
  • loopx canary premerge --from-git-diff --git-diff-base origin/main: passed, including
    4 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.

loopx-agent
loopx-agent previously approved these changes Nov 3, 2026

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

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

动机 / 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 以生成命令、实际执行和拒绝无副作用三个观察实现该约定,不把完整原目标或真实平台资格算作完成。

关键代码讲解

完整 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.

@mergify

mergify Bot commented Nov 3, 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, @cocolord.

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 3, 2026
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>
@huangruiteng
huangruiteng force-pushed the codex/settlement-budget-platform-20261103 branch from ae4c72f to a5b742f Compare November 3, 2026 17:34
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 3, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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 均因既有大小写断言 keep vs Keep 失败,签名相同且本 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.

@huangruiteng
huangruiteng merged commit fc7e72e into main Nov 3, 2026
10 of 31 checks passed
@huangruiteng
huangruiteng deleted the codex/settlement-budget-platform-20261103 branch November 3, 2026 17:38
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.

3 participants