Skip to content

fix(native-accounts): pause the renamed LoopX chat agent - #7355

Closed
loopx-agent wants to merge 1 commit into
mainfrom
codex/native-chat-agent-rename-20261026
Closed

loopx-agent wants to merge 1 commit into
mainfrom
codex/native-chat-agent-rename-20261026

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Problem

com.loopx.personal-bots.chat was migrated to com.loopx.chat (the old plist no longer exists). Handoff still paused only the old label, so the live chat transport kept its codex app-server attached to the GPT home and the switch failed with other_clients_busy (observed 2026-10-26 07:23 on an exhausted account, with com.loopx.chat listening on 8767).

Change

  • Pause both com.loopx.chat and com.loopx.personal-bots.chat, skipping labels without a plist so older installs keep working.

Verification

  • native_host_smoke.py, native_host_clients_smoke.py, codex_provider_routing_smoke.py, recovery_contracts_smoke.py, operator_smoke.py
  • python -m compileall -q packages/loopx-codex-provider-routing/src

Limits: live reproduction was on this macOS host; the renamed label was verified through launchctl list and the 8767 listener.

中文摘要:chat launch agent 已从 com.loopx.personal-bots.chat 迁移为 com.loopx.chat,但 handoff 仍只暂停旧 label,导致 other_clients_busy。此 PR 同时暂停新旧两个 label,缺失 plist 时自动跳过。

The chat launch agent was migrated from com.loopx.personal-bots.chat to
com.loopx.chat, so handoff paused a job that no longer exists and the live
chat transport kept the GPT home attached (other_clients_busy). Pause both
labels, skipping whichever plist is absent. Bump 0.12.5.

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; effort=max

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

动机

已授权自动换号及客户端重启的用户,在当前账号额度耗尽后继续原有 GPT 工作。旧版只识别旧服务名,新 Chat 仍占用原生账户目录而使换号停住;修订版暂停经归属核实的新服务,换号后恢复它,免去手动停服务。同一原生换号入口能处理新旧服务名,并在成功、暂停超时和恢复失败后保留准确恢复状态。此 PR 不新增换号、强关或重启授权,不重放业务任务,也不更换登录事务或模型路由。

改动思路

最小边界是修改既有服务白名单,继续由 NativeHost 核验进程归属、固定服务定义并恢复,由原生账户 owner 完成受锁保护的换号。本 PR 完成已授权换号流程中的服务改名兼容;实际用户账户切换和安装后持续运行仍须由部署 owner 单独验收。继续只接受既有重启授权:服务名必须精确命中,已加载进程及其后代必须真正持有目标目录,进程身份和原生选择必须仍一致。暂停前先写恢复意图;成功或失败都由原有 finally 恢复,恢复不了则保留原意图供下一请求处理。替换掉旧名称会破坏独立升级的旧安装,新增扫描器又会扩大范围;沿同一列表兼容两个名称更合适。

具体改动

本次完整范围为三条路径,基线 b95223532af1cc3cc6bd9558f96750c79f581e1b,精确提交 1142d501963b839ba266143d31dc340f8733727d;两个版本字段一起从0.12.4到0.12.5,生产行为只有服务白名单扩展。没有增加 credential writer、策略选择器、队列或状态 schema。

规范依据为 packages/loopx-codex-provider-routing/NATIVE.md,固定版本 b95223532af1cc3cc6bd9558f96750c79f581e1b。same-home-chat:已实现,同目录归属不符、未知 PID、假冒 plist Label 和未列出的服务都不能触发暂停。restart-permission:已实现,关闭重启时对照无信号、无服务卸载、无新恢复 journal。durable-chat-recovery:已实现,单服务及同时存在新旧服务的成功、第二次暂停已生效但回复超时、恢复拒绝后重入,均沿原意图处理;恢复不重复换号。

关键代码讲解

  • packages/loopx-codex-provider-routing/src/loopx_codex_provider_routing/native_host.py:41 的 CHAT_AGENTS 保留旧名称并加入当前名称,使用精确标识,不把任意名称相似的服务当作产品客户端。
  • 同文件 NativeHost.pause_chat_agents(364行)检查原有 plist、加载 PID、同目录持有者及其父进程链,并在 bootout 前固定定义摘要和恢复 owner。调用仍来自 switch 的已授权分支。
  • NativeHost.resume_chat_agents(434行)逐一处理同一恢复表,只重新加载未变化的定义;有失败继续保留该项,随后请求可恢复,不能重做已提交的账户事务。

对主干的风险

主要风险是新名称扩大了可暂停对象,或两个服务中后一个暂停失败时遗留前一个。本人用相同夹具在不可变基线和当前源各执行24种状态:基础版本的新名称场景是 other_clients_busy 且零换号,当前源完成一次换号并恢复;旧名称、缺 plist、其他目录、未知服务、未知进程、定义不符及关闭权限的边界保持。另执行双服务正常路径和第二服务暂停超时,两个服务均恢复,失败场景零换号。其中文件和恢复 journal 是真实实现,进程、launchctl 和账户事务使用合成观察,未操作真实登录或生产服务。

五个声明的源级 smoke、编译和 standard premerge 的五个 direct checks 通过;本次原生选择器没有额外 catalog 项或人工 hold。最初直接运行 operator smoke 缺少可选包导入;显式加入同一提交的包源后通过,没有更改产品代码。私有临时目录别名被真实安全读取拒绝,改为规范化路径后对照通过;原失败记录保留。按当前评审策略未读取或等待 CI。回滚前须先恢复尚未结清的新名称 journal,不能让较旧程序处理不认识的待恢复项。

我的整体评价

结论为 APPROVE,仅绑定 1142d501963b839ba266143d31dc340f8733727d。在本次有界验证中,长程继续与用户体验均改善:既有授权流程能越过改名造成的忙占死路,失败后仍可恢复,用户不需新增一次手动停服务。最小边界是修改既有服务白名单,继续由 NativeHost 核验进程归属、固定服务定义并恢复,由原生账户 owner 完成受锁保护的换号。本 PR 完成已授权换号流程中的服务改名兼容;实际用户账户切换和安装后持续运行仍须由部署 owner 单独验收。代码量与故障相称,旧名称兼容有独立部署及持久恢复依据,没有值得强制增加的抽象;可在原 smoke 中参数化两种名称,避免另建测试框架。

本次只改变 native_host 的服务名称白名单及包版本;已检查既有设置调用路径,没有页面、布局或呈现内容变化。本次未执行真实账户切换、安装后 App 旅程或持续运行;进程/launchctl 观察为合成,文件与恢复 journal 使用真实实现。新字符串是既有 provider 局部服务列表的扩展,没有新通用状态词汇。代码批准不授予合并、安装或真实账户操作权限。

English verdict: APPROVE — 1142d501963b839ba266143d31dc340f8733727d repairs the current Chat service label through the existing scoped pause/recovery owner. Full three-path review, paired 24-case baseline/head checks, dual-service recovery, five source smokes, compile and standard premerge passed. Live account switching and installed adoption remain unqualified.

@mergify

mergify Bot commented Oct 26, 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 Oct 26, 2026
@loopx-agent

Copy link
Copy Markdown
Collaborator Author

Superseded by the already merged implementation in #7356, #7358 and #7361. Closing this duplicate without merging the older 0.12.5 bump.

The original renamed-service fix is retained and generalized: current native_host discovers loaded same-home services from verified process ownership, validates their loaded plist/PID/start identity, saves restoration intent before unload, waits for acknowledged unload to finish, and restores through the original manager. This includes renamed labels and different plist filenames rather than depending on a fixed chat-service list. The old recovery format remains readable.

Reviewed source: 0e47330fe57ce5ea1101dae67ee19b836869ef4e, provider 0.12.8. Current service discovery and pause path. Native host/client/recovery smokes cover renamed services, ownership changes, another home, disabled restart, multiple services, unload delay/timeout and restore retry without a second account swap. #7361 additionally qualifies shared settings/CLI policy and one active observer; its exact-head review records the unrelated legacy App-quit mock failures instead of inheriting this PR's old CI or approval.

The existing two local interpreter entrypoints now contain the same 0.12.8 wheel (all 15 Python/TypeScript source files compared), and the original managed services have adopted the reviewed Core revision. Existing policy and conversation bindings are retained; one exclusive automatic observer is independently read back. No real account swap was triggered to demonstrate installation, and unverified unmanaged holders remain holds. There is no remaining source increment here to rebase or downgrade into main.

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