Skip to content

feat(codex): ship subscription-first OpenAI API fallback with one native owner - #7783

Merged
loopx-agent merged 19 commits into
mainfrom
codex/openai-key-configuration
Nov 1, 2026
Merged

loopx-agent merged 19 commits into
mainfrom
codex/openai-key-configuration

Conversation

@loopx-agent

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

Copy link
Copy Markdown
Collaborator

Author architecture hold: Background hosting reuse is being reassessed before merge. HostedWorker currently shares thread start/close and outer failure retry; polling, waits and provider health/readback remain in their existing owners. This is a limited lifecycle refactor, not evidence of a unified persistent background-service capability. Reconcile the shared responsibility and its maintenance value before removing this hold. The single packaged credential/launcher owner and dependent dotfiles imports remain the substantive account-IO reuse. Existing CI holds also remain.

Outcome

Ship subscription-first OpenAI API fallback with one native credential/launcher owner. The optional loopx-codex-provider-routing 0.13.0 package owns account IO; dotfiles PR10 imports it. Merge/update the owner before that consumer.

  • API use requires a separate explicit opt-in and fresh measured exhaustion of all authorized subscriptions. Unknown/stale/auth-failed observations cannot authorize paid fallback. Recovered subscriptions regain priority at the existing cooldown/idle boundary.
  • Settings → Model provider supports masked key add/remove, explicit connection checks, opt-in/revocation, subscription quota and actual request/rate-window observations. Project-key billing balance stays unknown; a connection check does not establish quota.
  • Persisted enabled intent is reconciled after startup, status and successful or rejected configuration. A stale disable can no longer stop still-authorized observation. Only the elected owner writes its heartbeat; stale/old/missing ownership is visible independently of quota.
  • Three existing continuous consumers share HostedWorker: native observation through Core, manager returns/queued-source recovery, and Lark private delivery. The 59-line Python thread host owns idempotent start, cooperative close and explicitly enabled host-loop retry. Normal completion is terminal. Providers retain authorization, locks, journals, cursors/backoff and ambiguous-write recovery; request/model work is never replayed by the host.

Boundaries And Compatibility

The accepted native contract is packages/loopx-codex-provider-routing/NATIVE.md before this feature at 834c4d7e8280f391d34289273161d1b4c00f31b4. Automatic targets remain allowlisted, fresh and available; install/save/check does not grant handoff, restart, force or paid API permission. Disable and journal recovery remain available. Additive diagnostics do not become authority.

The standalone wheel needs neither dotfiles nor Core for account/launcher IO. Legacy profile paths, locks, refreshed credentials and history are reused in place through the same packaged owner. Core injects the shared thread host when available and retains compatibility with the installed older optional provider until its upgrade.

The existing merge-readiness command now works without a Goal for standalone delivery; it performs no Goal write. Goal-managed callers retain their configuration. Exact-head review, CI, unresolved-thread and authorization checks are unchanged.

Public source and bundle scans reuse the existing credential-value classifier. Latest-main strict unlabeled provider-token rules remain intact, including exact handling of the documented AWS example. No raw logs, credentials, private runtime state or generated captures are committed.

Validation At Reviewed Head

Head: 04bf974e0f02784a367482234f38de84372adc3b, target: loopx-project/loopx:main (integrated 62390312506d0087b4bd9433e59ef24c01ea6235). Written by: model_agent, OpenAI Codex.

  • PASS: current premerge gate, all 19 selected checks plus six direct checks, including install/update, packaged Codex CLI, review-command, semantic/placement, public boundary, compile, bilingual RFC and diff hygiene.
  • PASS: 317 credential/public-boundary tests after integrating the stricter main rules; public share-bundle literal/mixed/unknown-expression negatives; complete bundle smoke.
  • PASS: current 17 shared-host/native health checks, two real manager recovery checks, and two production Lark start/close checks. Normal completion/failed once never replay; queued-source probe backoff survives host recovery; slow readback preserves independent stop, four in-flight replies and no executor backlog.
  • PASS: 14 TS policy tests, packaged Chat build, real HTTP/store/TS settings smoke (two API→subscription transitions, uncertain-write readback, authorized subset, paused/empty-key revocation and overdue heartbeat recovery), and the main-compatible delegation search browser journey.
  • Reused with source boundary: clean Python 3.11 native/account suites (166 passed and 19 subtests), broader manager/Lark integration (140 and 302 passed), independent-wheel and consumer lock/transaction suites. Later lifecycle tests and current packaged paths requalify the changed host wiring. Old failed-disable reproductions remain recorded as failures, not relabeled passes.
  • Real disposable launchd drill: terminate only its test process; KeepAlive starts a new process, heartbeat recovers, policy revision/scope and native effect count remain unchanged. Synthetic native IO; no active account/service state corrupted.

Remote exact-head CI is a separate merge gate. Current open failures: research display keyboard expansion timeout, Windows research-job concurrent-status assertion, and a 1267.7ms loaded lens switch above the frozen 1s budget. The research cases pass locally; a same-Mac packaged base/head 200-item comparison gives 73–111ms / 74–123ms, retaining the original budget and Linux miss. These local results do not clear remote platform qualification. Python shards await their shared lanes behind another current valid candidate. Wait for successful exact-head checks and ready merge-readiness before merge. Installed adoption/readback follows owner→consumer merge; synthetic exhaustion does not prove real account exhaustion or billing balance.

Observer Health Evidence

Captured at 168a5dde83d6493b486069f15c117385e149511e: packaged Chat, real owner HTTP/files/TS/observer, synthetic native/OpenAI IO. The subsequent shared-host refactor changes lifetime wiring, not layout; the complete packaged recovery scenario passed again at 04bf974e0f02784a367482234f38de84372adc3b.

The page contains long repeated key names, three subscriptions, mixed/unknown quota states and 21 process holders behind the existing disclosure. Desktop 1512×982 and narrow 390×844 retain the red overdue status, last heartbeat and recheck in one group; recovered health and quota remain separate. These are synthetic package acceptance views, not installed-account screenshots.

openai-observer-overdue-desktop openai-observer-overdue-narrow openai-observer-healthy-desktop

Frontend / Visual Evidence

Earlier review-correction evidence at 0850b12d3: packaged UI with synthetic data, real owner HTTP/store and injected native/OpenAI IO. Desktop 1512×982 and narrow 390×844 show API permission still cancellable while automatic routing is off; the last view shows the empty-key case. The earlier before/after captures below retain the original feature context.

openai-api-revoke-paused-desktop openai-api-revoke-paused-narrow openai-api-revoke-no-keys-desktop

UI impact: changed. Synthetic data only; packaged Chat assets with the real owner-local HTTP/store backend and synthetic native/OpenAI IO. Before: bc8658523; after: original API UI capture at c1bf31edaf9c8bd83517058454fecccfffc8187f; later unchanged panels reuse this evidence rather than relabeling it. Desktop 1200×900 and narrow 390×844; additional browser-smoke desktop views are 1512×982. No public preview is deployed.

Before After
openai-before-desktop openai-after-desktop
openai-before-narrow openai-after-narrow
Empty keys, active API with observed rate-window counts, and uncertain-write recovery openai-keys-empty-desktop openai-fallback-active-desktop openai-keys-populated-narrow

Attention/craft review: one provider page groups key actions and opt-in above the existing native accounts. Masked names, mixed connection states, unknown balance, bounded response observations and direct recovery controls remain visible. Long repeated names wrap on narrow screens without horizontal overflow. Existing spacing, separators, controls and status glyphs are reused; no new card hierarchy or color system.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
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; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max

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

发现 3 个 P2 阻塞项。 审查 head c1bf31edaf9c8bd83517058454fecccfffc8187f。

  1. 保留独立的订阅授权子集。 API onToggle 把 status.slots(全部已登记账号)写回 policy.slots。我在 exact-head 打包页接真实 owner HTTP/store,设置已登记 [a,b,c]、获准 [a],只勾选 API fallback,回读变成 [a,b,c]。这会让后续自动路由使用原来未获准的订阅。API-only 编辑应保留 status.policy.slots;补充已登记但未授权账号的回归场景。

  2. 允许在自动路由关闭时撤销已授予的 API 权限。 checkbox disabled 条件 对已勾选项也要求 automatic 为真。我先开启 API,再关闭订阅自动切换,看到 API 仍被勾选却无法取消;后端在保持 enabled=false 时接受 api_fallback=false,所以这是 UI 阻止了安全撤销。只对“开启”应用自动路由/Key/owner 前提;空闲时允许关闭已勾选权限。验证自动路由关闭及最后一把 Key 删除后的撤销路径。

  3. 让新 CLI 子进程测试具备独立的导入环境。 新测试 用 sys.executable -m loopx_codex_provider_routing.native,而 fixture 只修改父进程 sys.path。干净的 root uv sync --frozen --extra test 后,该项报 ModuleNotFoundError;这套所选 Python 测试为 157 passed、1 failed、19 subtests passed。仅给同一测试的子进程提供当前包源码 PYTHONPATH,对照即通过。请显式准备隔离的 child 环境或安装 wheel,使 root 声明的测试安装方式可以复现。

动机 / Motivation

需要在同一 GPT 客户端和历史中保持订阅优先、并自主控制 API 付费接续权限的用户。

以前原生账号事务依赖外部安装;本提案将事务 owner 随扩展交付,并在所有获准订阅都确认耗尽时才允许 API 接续。实际设置页仍会扩大订阅授权范围,并阻止已授权用户在自动接续关闭时撤销 API 权限。

独立 wheel 可完成合成账号事务和回滚;真实设置页可管理脱敏 Key,但两处授权缺陷和一项新测试失败阻止当前 head 验收。

本审查不调用付费模型、不更换真实账号、不证明生产账单余额或外部 dotfiles 消费者已部署,也不授予合并权限。

剩余缺口:修复授权子集保持、关闭状态下撤销权限和 CLI 子进程测试,再以真实拥有者验收;真实付费推理仍未验证。

改动思路 / Approach

可安装原生事务属于扩展 provider IO,订阅与 Key 策略仍由 TS 判定,Core 只组合 HTTP;无需额外通用框架,但当前 UI 必须守住独立授权。

当前边界是独立安装 owner 与显式 API 接续的完整路径;须在本 PR 修复两处授权和测试缺陷,外部 launcher 部署及真实付费推理保持未验证。

订阅选择与 API Key 轮换是两种不同决策。前者判断所有获准订阅是否有新鲜且明确的耗尽证据;后者只在一个已经获准的 API 请求遇到确定的输出前拒绝时选择下一把 Key。账号文件、启动与恢复属于平台 IO;Core 提供本机 HTTP 接口和结果投影。把这些机制留在既有扩展,比新增通用付费路由或复制 Goal 权限模型更贴合当前问题。

机制 验证到的边界
订阅优先 可用订阅优先;未知观测不作为耗尽
API relay 本机 token/Origin 校验;保留请求模型和内容;已开始输出不重放
原生事务 独立 wheel 中真实文件/SQLite 历史保持及回滚;不覆盖后续修改
UI 授权 发现独立授权被扩大、撤销被禁用,须修改

具体改动 / Changes

本次共 30 个文件,+2854/-59,覆盖独立安装 owner、原生事务/启动、TS 策略、私有 Key store、loopback relay、Core HTTP 配置、设置页、版本与文档,以及安装/进程/事务/HTTP/浏览器验证。外部 Personal Apps 依赖被包内原生 owner 取代;可信 legacy locator 延用原 vault/lock 路径,指纹变化需明确 reconnect。上游 Key 与本机 relay token 分开保存,Core 原有操作者凭据用途不同,不应混为同一个授权源。

关键代码讲解

  • CodexAccountSettings 的 API onToggle:用现有 revision 调用同一 configure owner,但错误地以账号发现清单替换授权子集;CAS 能阻止旧版本写入,不能修正这个新的错误意图。
  • OpenAIKeySettings:负责脱敏列表、连接检查、增加/移除和不确定写入后的回读。当前 checkbox 的前提同时挡住了撤销;应保留独立的关闭权限路径。
  • Accounts.transaction:持有 credential lock,记录备份与 journal,提交后核验;回滚验证文件摘要,拒绝覆盖后来修改。独立 wheel 测试和合成 SQLite 历史验证覆盖了真实存储边界。
  • RelayHandler.do_POST:先验证 token、Origin、启用状态和当前 API 槽位,再转发原始请求。明确的输出前拒绝可以轮换 Key;未知传输结果和中断的流保持失败,不重放或伪造 completion。

实际浏览器验证使用 exact-head chat bundle 和真实 Core HTTP/private store/TS,原生进程与 OpenAI IO 使用合成数据。长名称双 Key、连接权限错误、添加取消、丢失响应后回读均走了真实设置组件。丢失响应时只增加了一条 Key、密码框清空;观测到两次 HTTP 尝试和 revision-conflict 提示,故不能声称传输层绝不重试。这个结果与模型流“不重放已开始输出”的独立测试分开保留。

验收基准是变更前的 packages/loopx-codex-provider-routing/NATIVE.md,spec_revision=834c4d7e8280f391d34289273161d1b4c00f31b4。审查标准逐项对应如下,head 中改写的说明不能自行证明这些旧要求已满足。

  • Availability and continuation:Automatic targets must be allowlisted and freshly available; unknown is never exhaustion. 未满足;API opt-in submits all registered slots rather than prior policy.slots.
  • Prerequisites and activation:Installation grants no automatic handoff/restart/force permission; these are independent opt-ins. 已验证;4paired base/head default-off cases;13TS policy tests
  • Disable, upgrade and rollback:Disable remains available and an in-flight transaction finishes safely rather than being abandoned. 未满足;Checked API permission becomes disabled after automatic routing is turned off.
  • Qualification boundary:Synthetic tests distinguish package/store/transport qualification from actual installed-account use. 已验证;wheel transaction/history/rollback passed; actual model execution unverified

对主干的风险 / Risks

当前主干风险集中在授权而非渲染:一个独立 API 开关改变未来自动选择的账号集合;另一个禁用条件要求用户重新开启自动路由才能取消付费权限。这两条反例在真实打包 UI 和真实 owner 回读中成立,现有全账号 fixture 很容易掩盖第一条。修改应落在当前两个 callsite,保留同一配置 owner,不新增重复的授权状态。

本地结果:所选 Python 为 157 PASS、1 FAIL,19 subtests PASS;失败是上面的新 CLI 测试。13 项 TS policy、安装 wheel、事务/历史/回滚、真实 loopback HTTP 的 unknown/partial stream、chat typecheck/build 均已覆盖。最初 build 缺 React 开发依赖,安装锁定依赖后通过;保留原失败而非称首次即通过。相同输入的四组 base/head 默认关闭及订阅路径比较,动作、policy、文件与调用相同,只有明确增加的 api_active=false、api_fallback_supported=false 投影字段。

相关 Python 生产/新增测试 Ruff 通过;原浏览器 fixture 的两条 E402 在不可变 base 和 head 同样存在,行号随增加两行移动,作为旧诊断保留。公共边界扫描通过并保留非字面量 credential 命中的 warnings。未查询或等待远端 CI。真实付费推理、真实账号切换和外部 launcher 部署没有被这套合成验证证明;这些边界不能用 settings 可见、wheel 通过或文档改写替代。

我的整体评价 / Verdict

REQUEST_CHANGES。独立 owner 与原有 TS 决策的拆分有明确用途,但当前两处授权缺陷及新增必需测试失败必须在本 PR 修复。CQR 诚实记录了非通过结果。已目视检查 exact-head 打包设置页的桌面首屏、390×844 窄屏、长名称双 Key、权限错误、展开帮助和下方账号恢复区;层级与换行可读,授权交互缺陷另列阻塞。 未验证范围:真实用户账号、生产额度排序/新鲜度与付费推理未验证;原生进程和上游 IO 为合成边界。 修复后应重新核验整个 exact head 的授权、包安装、错误恢复与 UI 回读,不能仅修改三个断言或引用旧的通过记录。

English verdict: REQUEST_CHANGES — head c1bf31e. Fix subscription allowlist expansion, blocked API revocation, and the new CLI test import failure. Local evidence includes packaged UI and native tests; CI not consulted.

…iguration

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

Copy link
Copy Markdown
Collaborator Author

已修复审查中的 3 项 P2,当前 head:0850b12d3a15a7d6b23dd5f1babe00b68ad3a95b。

  1. 保留订阅授权范围(58dd0b288):API、重启/强关权限及重新连接均保留 policy.slots;关闭/重新开启自动接续也保留已有授权子集。真实 owner 回归以“登记 [a,b,c]、授权 [a]”操作并核对响应及持久化结果,保持 [a]。
  2. 撤销不依赖开启条件(58dd0b288):自动接续关闭、最后一把 Key 移除后,已勾选的 API 权限仍可取消;开启时继续校验自动路由、owner 和 Key 前提,忙碌保护保留。桌面/窄屏及空 Key 状态证据已补入 PR 描述。
  3. 独立 CLI 子进程环境(47eb0ba03):显式传入当前扩展源码的 PYTHONPATH,并在临时工作目录执行。已先复现干净环境的导入失败,再验证仅安装 root test extras 的 Python 3.11、3.14 环境各 159 passed + 19 subtests passed。

同时修复原生重开 CI fixture 的 spec 参数并断言原 profile;公共静态导出复用原有 credential-value 分类器,运行时变量字段与字面量分开检查,字面量、混合内容及未知表达式仍被拒绝。原分类器/边界/披露回归 116 passed,完整公开导出、五项包 CI 合约及安装入口 schema 验证通过。

新 head 的权限/恢复浏览器回归、13 项 TS 策略、70 项 dotfiles 消费者测试及 quick premerge 均通过。旧 CI 中失败的三个打包界面场景在更新主干后重跑通过;远端新 head CI 仍在运行。丢失响应验证限定为应用层不重新提交、CAS 保证只提交一次配置,不再将其表述为传输层绝不重试。

请基于新 head 复审;尚未合并。

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

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

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

mergify Bot commented Nov 1, 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 1, 2026
…ices

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

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

# Conflicts:
#	apps/presentation/dashboard/smoke/delegation-search-browser-smoke.mjs
#	loopx/contract.py
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 1, 2026

@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; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机 / Motivation

需要在同一 Codex 客户端持续工作的用户。

以前订阅耗尽后要手动换号,而且已开启的开关无法证明后台仍在观测;现在订阅优先、API 独立授权,并分别读回额度与服务心跳。

打包页面已经验证 API 接续、订阅恢复、权限撤销和心跳故障恢复,配置冲突不会再静默停止仍获授权的观测。

本审查不证明项目 Key 的账单余额,不授予新账户权限,也不把合成额度或进程验证称为实际账号部署。

尚待按依赖顺序合并、更新安装并读回实际服务与额度;这是本次交付的后续步骤。

改动思路 / Approach

原生观测、manager 回传/排队恢复、Lark 私有投递共同使用 59 行 HostedWorker 管理线程生命周期;各自保留授权、锁、游标、journal 和等待语义。保留唯一扩展 owner:TS 决定选择与健康分类,Python 执行私有文件和进程 IO,Core 恢复已保存的授权并传输结果,UI 只投影;无需另装账号守护进程或复制授权;共享宿主不能重放已完成的工作或失败的一次性请求。

同域的三处持续后台循环使用同一线程宿主,普通完成终止、显式选定错误重试、协作关闭。当前 PR 交付可独立安装的账号 owner、订阅优先 API 接续、可恢复的后台观测与状态页,以及不依赖 Goal 的同一合并检查入口。

订阅切换与 API Key 轮换保持两种职责:前者必须先证明所有获准订阅耗尽,后者只处理同一个请求在输出前遇到的明确拒绝。单独重建一个 plist 无法修复授权与实际观测不一致;本次沿用受监督的 Chat 服务、已有 kernel lock 和事务恢复,不再复制一套守护策略。心跳只是运行观察,不能成为付费或结束进程的授权。

触发 判定与结果
所有获准订阅耗尽,API 已授权 原生事务进入本机 relay;保留原模型和请求
订阅恢复 沿原冷却与安全边界返回订阅
关闭请求版本冲突 拒绝修改,并按实际保存的 enabled 意图恢复 observer
心跳缺失、过期或旧版本 展示未确认/异常;不抢锁,不伪装额度健康

此表是对当前 head 的源码解释;执行证据见下文。

具体改动 / Changes

审查整个 base-to-head,而非只检查最后的修复。扩展交付独立原生 vault/锁/事务与 App IO,私有 Key store、TS 策略和 loopback Responses transport;Core 只承接本机 API 与观察器生命周期;设置页完成添加、脱敏回读、检查、独立授权、撤销及异常恢复。消费端由 dotfiles PR10 单向 import,升级 owner 前不部署该消费者。公共 bundle 检查复用既有 credential-value 分类器,仍拒绝字面量、混合内容与未知表达式。

关键代码讲解

  • NativeAccounts.tick:先读显式范围与新鲜额度,再调用 TS 判定。健康订阅保持优先,未知观测不能触发 API,恢复订阅沿原事务切回。
  • Accounts.transaction:同一锁内保存备份、journal、原子提交与读回;拒绝覆盖之后的登录修改,保留原会话及刷新后的 token。扩展安装不依赖 dotfiles。
  • RelayHandler.do_POST:固定官方上游,保留模型/body;每把 Key 每请求至多尝试一次。未知网络效果与已开始的流均不重放。
  • CodexAccountService._reconcile_observer:从保存的授权恢复 worker;configure 失败也执行协调,服务显式关闭后保持停止。心跳只由锁持有者写入,读取不能刷新它。
  • CodexAccountSettings:API、重启和重新连接保留 policy.slots;暂停/空 Key 时仍能撤销 API。服务健康、额度与最近心跳分开显示,错误可在原处重查。

共享后台宿主还逐项检查了三个真实消费者:HostedWorker 只拥有启动、协作关闭和显式失败重试,普通完成与未选重试的失败均终止,重复 start 不会重放。manager 的 run_executions 保留同一个 QueuedSourcePump,异常恢复不会重置 next_probe/backoff;真实回传恢复测试验证原结果只发送一次。Lark 的 start 只把私有投递线程交给宿主,原四个并发 Future、无额外队列、独立 stop 与 journal 防重发继续由原 owner 执行。native 独立 wheel 继续直接运行进程入口,通过 Core 注入宿主时也不增加包依赖。

另外,standalone merge-readiness 使用原有 head、review、CI、线程完整性和授权检查,只省去无关的 Goal 绑定/写入;已托管任务继续使用自己的 Goal 配置。真实 CLI smoke 验证了两种入口的相同拒绝条件。

规范基准:packages/loopx-codex-provider-routing/NATIVE.md,spec_revision=834c4d7e8280f391d34289273161d1b4c00f31b4。以变更前的文本逐项映射,不以本 PR 改写的说明自行证明。

  • Availability and continuation:已实现;授权子集保持,未知/过期额度不视为耗尽,订阅优先与恢复回切均已验证。
  • Prerequisites and activation:已实现;独立 opt-in 保留,安装/存 Key/连接检查不触发付费使用。
  • Disable, upgrade and rollback:已实现;暂停与空 Key 可撤销,旧版配置冲突停观测的反例已修复,线程及服务重启保留授权和事务恢复。
  • Qualification boundary:已实现;独立 wheel、真实文件/锁、HTTP/TS、一次性 launchd 已验证;真实账号部署仍是后续读回。

对主干的风险 / Risks

最强反例是“开关开着、HTTP 服务正常、observer 已退出”,普通成功 tick 与旧的 ready 字段会掩盖它。我先在旧实现复现 2 个失败,再验证配置冲突恢复、线程退出/异常重试、服务重启、旧 build、过期/损坏 marker 和无锁状态。一次性 launchd drill 只终止其唯一测试进程,确认 KeepAlive 拉起新 PID、健康心跳恢复、策略 revision 与范围不变,并清理测试 job;没有终止实际工作或更改真实账户。

PASS:clean Python 3.11 的 166 项测试及 19 subtests;当前 107 项 Core/更新/审查/健康 companion 检查;14 项 TS 策略;真实打包 UI 的 API→订阅、丢失响应回读、授权子集、撤销及心跳过期→恢复;chat build、current premerge (19 selected and six direct checks)、Ruff、diff、双语 RFC 与公开边界检查。既有 scanner/边界116项及五项独立包合约沿未变 owner 复用,并明确保留最初失败。当前 head 已重新通过 317 项公共凭证/边界测试、17 项宿主/健康检查、两项 manager 恢复和两项真实 Lark 启动/关闭检查、14 项 TS 策略及完整 bundle 导出。原 140/302 项完整 owner 回归按未变业务代码复用。packaged Chat build、委托搜索与公共 bundle smoke 通过;fresh 0.13.0 wheel 已核对源码成员,Core-free 安装合约再次通过。

当前远端 CI 有三项未通过:research-display-language 键盘展开等待超时、Windows research-analysis 并发状态断言,以及 goal-workspace-m2 的一次切换 1267.7ms 超过冻结的 1s 预算。相同研究页与 HTTP 用例在本机当前源码通过;同机、同 Node/Chromium、同一 200 项夹具的 packaged 主干/当前提交对照分别为 73–111ms / 74–123ms,均未触及原预算。该对照不构成 Linux 或 Windows CI 的通过证明,保留全部原失败并等待原平台复验,不改断言或预算。完整 Python 分片还在仓库共享队列等待当前有效候选完成;不取消其他候选的精确 head。

语义与 CI 对齐

ObserverHealthState 和 heartbeat schema 属于扩展局部诊断词汇;既有 native policy 只增加独立 API 意图,未把服务健康升级成执行授权。default-off 的五组旧/新输入在原动作、policy、文件与 native 调用上相同;新增健康字段是明确披露的投影。上游错误按 HTTP/结构化 code 判定,未知不作耗尽或安全重试。没有为了变绿取消原限额、原断言、scope 或流重放拒绝。

我的整体评价 / Verdict

APPROVE 当前提案;无剩余实现阻塞项。旧审查的三项 P2 已分别由授权子集、暂停/空 Key 撤销和干净子进程导入验证解决。长期连续性判断为 preserved:原事务、安全等待、重试与不重放边界保留;用户体验为 improved:同一页面可配置并辨认实际异常,独立交付无需额外 Goal 操作。尚不把它称为已完成本机部署。

已目视检查完整设置区域:长名称多 Key、错误与未知额度、21 个占用者的折叠入口、三个订阅卡片及恢复区;过期心跳以清楚的红色提示出现,健康状态和额度分开,390 像素窄屏可读。

未验证范围:真实账户额度耗尽及恢复、真实账单余额和安装后的服务接续;截图中的原生与 OpenAI IO 为合成边界。

原生观测、manager 回传/排队恢复、Lark 私有投递共同使用 59 行 HostedWorker 管理线程生命周期;各自保留授权、锁、游标、journal 和等待语义。保留唯一扩展 owner:TS 决定选择与健康分类,Python 执行私有文件和进程 IO,Core 恢复已保存的授权并传输结果,UI 只投影;无需另装账号守护进程或复制授权;共享宿主不能重放已完成的工作或失败的一次性请求。

同域的三处持续后台循环使用同一线程宿主,普通完成终止、显式选定错误重试、协作关闭。当前 PR 交付可独立安装的账号 owner、订阅优先 API 接续、可恢复的后台观测与状态页,以及不依赖 Goal 的同一合并检查入口。

合入当前主干时保留了新的未标记 provider-token 严格检查:只有 AWS 官方示例被精确允许,placeholder 字样藏在 token 内仍被拒绝;提取 value classifier 没有放宽该规则。委托分页 smoke 沿主干 Load next page 交互与 loading 断言,只修正动作等待。

代码体量主要是必要的 provider IO 和独立验证;已删去消费者重复 writer/launcher,复用公共 classifier 与现有 Chat supervision。授权/未知/恢复状态保持 typed、provider-local;共享的是已有 Python 循环的线程生命周期,不新增策略或 Agent 调度框架。后续按当前 head 的 CI/readiness 合并并验证安装,再判断实际服务接续结果。

English verdict: APPROVE — head 04bf974. The prior grant, revocation and CLI-import findings and the enabled-but-stopped observer defect are resolved with real-owner validation. Remote CI and installed deployment remain separate gates.

@loopx-agent
loopx-agent merged commit 789694f into main Nov 1, 2026
39 of 66 checks passed
@loopx-agent
loopx-agent deleted the codex/openai-key-configuration branch November 1, 2026 11:20

@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; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max

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

Post-merge audit — REQUEST_CHANGES for the background recovery boundary

[P2] 在原有线程池作用域内恢复 scanner。 _reconcile_private 的整个循环处于 ThreadPoolExecutor context 中,外层 HostedWorker 只能在它退出后重试。新反例使用精确原 scanner 源码:四个已接纳的合成写入仍阻塞时,注入一次 scanner 异常,扫描未能在释放这些写入前恢复。这里需要共享单步驱动保留 pool、pending futures 与 journal,而不是重建整个 target。修正提案 #7816 必须独立验证,不能反向算作旧 head 已通过。

动机 / Motivation

需要在同一 Codex 客户端持续工作的用户。

以前订阅耗尽后要手动换号,而且已开启的开关无法证明后台仍在观测;现在订阅优先、API 独立授权,并分别读回额度与服务心跳。

新反例在原 head 复现:四个合成写入仍在进行时,scanner 异常会先等待线程池退出,外层重试无法继续扫描。

本审查不证明项目 Key 的账单余额,不授予新账户权限,也不把合成额度或进程验证称为实际账号部署。

原生账号功能已具备源代码和打包验证;共享后台循环在保留进行中任务时的恢复仍有缺口,修正位于后续 PR #7816。

这是同一 head 因新的具体架构疑问而进行的完整复核,保留原审查与证据,并修正过宽的后台复用结论。GitHub 已记录该 PR 合并;该生命周期事实不会清除当前反例或证明 CI 成功。

改动思路 / Approach

保留现有 TS 策略、Python provider IO 和 Chat 进程生命周期;后台共享需要在原有资源作用域内驱动单步、等待与异常恢复。59 行外层线程包装不能证明这条恢复链。

本次是对已合并 head 的复核:账号 owner、API 接续及原生健康投影仍有通过证据;后台作用域恢复缺口必须由 #7816 的独立精确 head 验证修正,不能用另一提交替原 head 判通过。

账号与开窗的 owner 迁移是真正的单实现复用:独立扩展保存原 vault、锁、凭据事务及 App IO,消费者只做路径/命令适配。订阅优先与 API 轮换仍属不同授权和重试边界。新的问题集中在后台宿主:普通 target 返回终止、不自动重放,这些约束正确;但循环内部异常不能要求先结束进行中的写入才能恢复。

具体改动 / Changes

完整复核原 52 个变更文件。私有 Key/CAS、固定 loopback Responses relay、TS 原生/API 规则、单份 native store/launcher、Core 本机 HTTP、设置页、standalone readiness 和公共 scanner 均沿原 source-bound 证据保留;没有把主干变动或修正提案算成旧 head 的代码。

关键代码讲解

  • NativeAccounts.tick 仍要求所有获准订阅的新鲜耗尽观测,未知不转 API,订阅恢复沿安全边界回切。
  • Accounts.transaction 仍在同一锁与 journal 内提交/回读/恢复,保留较新的凭据和本地历史;这是实质复用。
  • HostedWorker._run 在 target 外捕获失败;它无法穿过尚未结束的 executor context,所以 failed-once 的简单线程测试不足以证明真实 scanner 恢复。
  • CodexAccountService._reconcile_observer 对失败配置按实际保存授权恢复 observer;原生心跳仍由锁持有者写入,这个根因修复没有被本次 finding 否定。

规范基准:packages/loopx-codex-provider-routing/NATIVE.md,spec_revision=834c4d7e8280f391d34289273161d1b4c00f31b4。继续按变更前的原生契约映射:

  • Availability and continuation:原生部分按之前记录 implemented;本次不把共享 scanner 的反例掩盖为原生授权或额度故障。
  • Prerequisites and activation:原生部分按之前记录 implemented;本次不把共享 scanner 的反例掩盖为原生授权或额度故障。
  • Disable, upgrade and rollback:原生部分按之前记录 implemented;本次不把共享 scanner 的反例掩盖为原生授权或额度故障。
  • Qualification boundary:原生部分按之前记录 implemented;本次不把共享 scanner 的反例掩盖为原生授权或额度故障。

额外的共享后台恢复目标来自当前交付需求,尚不能用这些原生条件替代。standalone readiness 的无 Goal 调用仍保留原 CI/review/线程与授权门;它不授予合并权限。

对主干的风险 / Risks

原 head 的原生/Key/relay、14 项 TS、独立包、打包页面、公共边界以及原生健康用例仍是通过证据。新反例专门覆盖已有测试遗漏的“异常时仍有进行中任务”:精确旧 scanner 未恢复,新提案保留一个 pool 和四个原请求后恢复。这里用真实线程、executor 与临时文件,外部 IO 为合成,不发送实际消息,不运行模型,不操作真实账号。

原远端 CI 有研究页键盘等待、Windows 并发任务状态和冻结 1s 切换预算的失败记录;本地对照不等于原平台通过,合并也不改变历史失败。长程约束 preserved 仅指已验证的原生事务/权限/不重放边界,共享后台连续性仍有缺口;原生设置体验 improved,不代表全局后台健康已统一。

我的整体评价 / Verdict

已目视检查完整设置区域:长名称多 Key、错误与未知额度、21 个占用者的折叠入口、三个订阅卡片及恢复区;过期心跳以清楚的红色提示出现,健康状态和额度分开,390 像素窄屏可读。

未验证范围:真实账户额度耗尽及恢复、真实账单余额和安装后的服务接续;截图中的原生与 OpenAI IO 为合成边界。

REQUEST_CHANGES 这个已合并 head 的后台恢复实现。保留原生功能和真正的 owner 复用;收敛单步、等待与异常恢复,同时保留 lease、pool、cursor、journal 和 provider 的健康判断。原先仅在正文中写 author hold 不会撤销既有 APPROVE,这次用精确 head 的复核结论记录新发现,而不删除历史审查。

保留现有 TS 策略、Python provider IO 和 Chat 进程生命周期;后台共享需要在原有资源作用域内驱动单步、等待与异常恢复。59 行外层线程包装不能证明这条恢复链。

本次是对已合并 head 的复核:账号 owner、API 接续及原生健康投影仍有通过证据;后台作用域恢复缺口必须由 #7816 的独立精确 head 验证修正,不能用另一提交替原 head 判通过。

English verdict: REQUEST_CHANGES — head 04bf974. The exact old scanner fails recovery while four admitted writes remain blocked; the outer thread wrapper retries only after its live executor scope drains. Native feature evidence remains valid. Correction PR7816 and installed acceptance require independent qualification.

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