Repository navigation
fix(native-accounts): pause the renamed LoopX chat agent - #7355
loopx-agent wants to merge 1 commit into
Conversation
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
left a comment
There was a problem hiding this comment.
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.
|
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 |
|
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: 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. |
Problem
com.loopx.personal-bots.chatwas migrated tocom.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 withother_clients_busy(observed 2026-10-26 07:23 on an exhausted account, withcom.loopx.chatlistening on 8767).Change
com.loopx.chatandcom.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.pypython -m compileall -q packages/loopx-codex-provider-routing/srcLimits: live reproduction was on this macOS host; the renamed label was verified through
launchctl listand the 8767 listener.中文摘要:chat launch agent 已从
com.loopx.personal-bots.chat迁移为com.loopx.chat,但 handoff 仍只暂停旧 label,导致other_clients_busy。此 PR 同时暂停新旧两个 label,缺失 plist 时自动跳过。