Repository navigation
fix: preserve Lark private steward configuration across setup and upgrades - #7371
Conversation
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
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.
APPROVE — 精确头 e0ecbdd21074a953b1717a8e27b8836b52517f69。本范围没有阻塞发现;下面保留独立验证、作者主张和未资格边界。
动机
已经连接飞书群监听、希望继续使用本人私聊与本机原会话的使用者。
旧版把已保存的 App ID 与设置页的配置名当成不同入口,私聊会静默漏路由或要求用户找旧 selector;升级还可能更换工作区、或因运行时目录不明确而无法安全生效。新头复用同一已核验 App 的唯一监听,保留原工作区,并固定实际运行时目录供原升级栅栏检查。
已用真实 HTTP/Core 和冷发现验证别名保存后可回读同一私有路由,身份改变被拒绝;当前升级夹具验证工作区及运行时目录在后续发布目录和旧参数迁移后保持,原activation guard仍保护未完成请求。
本次不认证新的群权限、远程委托、SSH/真实账号投递、已安装 WebView 或模型效果,也不授予安装、生产操作或合并权限。
更广的已安装/远程交办与完整打包浏览器资格仍由原接受流程承担;作者注明的旧并发 drain 和未变 elapsed-label 场景不因本轮通过而改称已解决。
用户的普通任务是“已连接的App继续本人对话,升级后仍在原工作区继续”。只显示配置成功或listener就绪不能证明这件事;本轮用保存后的Core状态、冷发现及同输入base/head反例判断,未把作者的真实账号/远程叙述当独立验收。
改动思路
复用现有 provider 配置发现、Core conversation binding、唯一 consumer/App lease 和安装脚本,即可修复同一身份的别名与升级连续性;无需新 provider、配置同步层或会话权威。
本 PR 的完整切片是配置名/App ID 发现与唯一共享监听、发布前 App/owner 重核验,以及原工作区和实际运行时目录的升级保存;复用原activation guard,无新能力、UI 布局或远程执行授权。
发现层从当前完整profile库存推导App-ID fallback,显式配置名优先。设置POST对照实际App身份,在唯一同App旧consumer上继续;Core在持久化前再次核对App和owner,provider只提供观察。工作区是既有用户选择,安装脚本按现有环境、plist、旧CLI参数恢复,未配置时固定原bounded目录一次;它不是新工作区授权。
| 情况 | 改前独立观察 | 当前独立观察 |
|---|---|---|
| 配置名指向旧App-ID listener | 合法保存400 | 原selector保存成功,冷发现仍唯一 |
| 初次核验后owner变化 | 新身份被200保存 | 400拒绝,原binding不变 |
| 升级换发布目录 | implicit目录可能跟随变化 | 保存原目录;丢失则拒绝恢复 |
表格解释当前HTTP/Core及installer证据,不替代真实账户、安装态或远程采用。
具体改动
完整基线 5cff2b9fa57bd846f0005dfe9dbaf47340d49917 到 e0ecbdd21074a953b1717a8e27b8836b52517f69 共9路径 +182/-23,三处Lark/Core行为、安装脚本、双语RFC/使用文档和两组验证。过程中先由 4895929854bd3fc1cd90d5397b4d68d3ea40a9da 更新到 0c63a68885808d472af2735b4b018629a242e07e(仅pytest fixture的F811注解),再加入当前三文件runtime-pin改动。完整新diff和两次delta均已读;Core/HTTP及调用方11路径blob/AST不变后,仅复用239项与HTTP证据。旧installer证据明确失效,在新头重跑升级与75项activation/update测试及标准premerge,没有沿用旧批准或把新生产改动叫成注解。
规格依据 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,改前接受版本固定为 5cff2b9fa57bd846f0005dfe9dbaf47340d49917。Settings → Lark 的当前App/owner、工作区和executor选择已通过真实HTTP验证;One machine/App lease 的别名唯一consumer与群/私有受众分离已验证;missing roots 的工作区丢失/改绑不得静默替代由既有检查和升级smoke保留。新RFC文本与中文镜像同PR更新,描述当前有限checkpoint,没有自行宣称更广R1–R3完成。
关键代码讲解
LarkPrivateConversations.profiles从配置名→App ID库存派生合法App-ID selector,用setdefault保证显式同名profile优先。只有enabled且当前App identity匹配的Core binding进入发现;App移除、指向另一App或读取失败不能借旧路由,发现本身不授予conversation权限。_private_conversation_connect使用新鲜App观察寻找唯一现有listener,拒绝歧义或不兼容受众。若用户选择的是别名,会再次observe原选择,再交原selector给Core;原群grant与consumer不改成另一套。ChatConversationBindings.configure增加可选expected_operator_ref,与已有expected_provider并列。只有最终观察的App和owner都相同才进入原锁、typed Core transition、持久写入和独立readback;省略新参数的旧调用仍使用原契约,没有新的权限或schema。resolve_chat_scan_paths恢复旧plist的--scan-path/--scan-root,把未配置的bounded包目录只固定一次。同文件resolve_chat_options复用Chat实际的registry codec与resolve_runtime_root固定缺省数据目录,保留原env/plist/CLI显式选择。原runtime_activation._chat_runtime_root可以从生成命令读到同一目录;未完成请求仍由原锁/guard延迟重启,不通过猜测其他空store来放行。列表长度、JSON大小、绝对目录和控制字符限制保留;原工作区丢失时仍拒绝替代。
对主干的风险
最强反例是保存看起来成功,却在listener冷重建后仍无法找到私有binding,或核验与发布之间owner已变化。本轮同一HTTP测试程序在不可变base执行为 2 failed:别名400、owner变化返回200;在修复头为 2 passed:合法别名保存并冷发现,owner变化400且旧Core binding保持。provider IO用synthetic实现,但真实HTTP、Core持久化、原typed owner和runtime refresh均执行;未mock“保存成功”这个待验证后置条件。
完整私聊/兼容性suite 239 passed,包含移除App、selector冲突、App/owner重定向、群/私有分流、单路解绑及两App隔离。当前macOS LaunchAgent smoke独立通过,覆盖后继release、工作区/runtime保持及legacy参数迁移。新头activation/update 75 passed /3 platform skips,覆盖queued/starting/running/completing/interrupting未完成请求不重启、未知/损坏route拒绝、idle允许、竞争admission锁与部分restart真实结果;launchctl是隔离stub,没有操作实际服务。相同当前installer测试程序在不可变base于 _chat_runtime_root 复现 chat_service_route_unresolved;当前头通过,不把旧未固定root悄悄放行。fixture lint注解独立检查通过且保持未变;最终标准premerge 6 direct +10catalog +8risk +1public 全部通过、exit0、无manualhold。没有改变原10秒drain deadline,也未根据后来的绿色run宣称作者先前并发超时已根治;更广elapsed-label场景仍是其原范围的资格缺口。
此前按包release变化的implicit工作区现在一次固定,这是有意默认变化,使用文档双语已披露,并要求丢失原目录时恢复而非替代。不增加filesystem scope,不创建隐藏Goal,不重放既有历史缺口,不把私聊owner授权扩展到群或远程Agent。现有Core/lease/observer保持独立责任,回滚与恢复仍是原owner,不需要新增同步或运行时抽象。
语义与 CI 对齐
这复用现有App/owner identity与conversation binding词汇;selector是精确配置映射,没有substring/prose分类。新参数是本地发布前观察约束,不是新通用生命周期协议。拒绝检查由机器执行,文档未把它称为可忽略建议。当前head的注解仅处理pytest注入的lint,未删除断言、放宽超时或扩大测试根。原生required gate与双语/公开边界通过;没有查询、轮询或等待CI,批准代码与合并权限/readiness仍分开。
我的整体评价
APPROVE at e0ecbdd21074a953b1717a8e27b8836b52517f69,本切片是 justified_increment:long_horizon:improved,原绑定、路由与工作区在冷重建/升级后可继续;user_experience:improved,用户沿原设置选择已知App即可,不需要寻找旧selector、重述上下文或新增确认回合。安全检查拒绝身份变化的同时也实际接受合法别名,未只证明“更严格”。
检查了完整9路径及未变 PrivateConversationPanel/设置API:继续使用既有选择器、连接列表与错误读回;没有修改渲染布局、样式或首屏内容结构。原App ID显示沿用既有字段,未新建界面。
本轮未独立操作已安装 App/WebView、真实飞书或远程主机,也未重跑完整浏览器场景;真实HTTP/Core夹具仅替代provider IO。
复用现有 provider 配置发现、Core conversation binding、唯一 consumer/App lease 和安装脚本,即可修复同一身份的别名与升级连续性;无需新 provider、配置同步层或会话权威。 本 PR 的完整切片是配置名/App ID 发现与唯一共享监听、发布前 App/owner 重核验,以及原工作区和实际运行时目录的升级保存;复用原activation guard,无新能力、UI 布局或远程执行授权。
本次独立证据资格是源码HTTP/Core、冷发现和隔离installer夹具。作者的真人私聊、已安装续接及SSH操作仅作其原声明保留;未把这些转为本轮独立证明,也不认证模型理解、远程权限迁移、完整打包场景或结果效益。无需为这个已完整交付的局部修复另造仪式性后继;更大产品接受由原任务/维护者继续。批准不会触发merge、安装、发布或撤回他人review。
English verdict: APPROVE — e0ecbdd21074a953b1717a8e27b8836b52517f69. The complete nine-file slice preserves existing Lark/Core owners while resolving App-ID listener reuse, workspace continuity and an explicit runtime route for the existing upgrade fence. The same HTTP/Core probe fails twice on the immutable base and passes on the fix. Core evidence (239 cases) is reused only after source/AST invalidation checks; the newly changed installer is revalidated separately, including 75 activation/update cases, three platform skips and the current upgrade smoke. Final standard premerge passes. Installed, remote, full-browser and model-benefit claims remain separate.
Private steward setup could appear connected while inbound messages were dropped: existing group listeners retained an App-ID selector, but private discovery recognized only profile names. Saving the named profile also required users to discover that legacy selector themselves. A release-directory change could independently replace an implicit Chat workspace and invalidate its conversation context.
This change discovers configured App-ID selectors with explicit-name precedence, reuses one listener only after verifying the same App and private owner, and rechecks both identities before publishing the binding. The macOS installer preserves saved workspace paths and legacy CLI arguments; an implicit package workspace is pinned once rather than changed on each upgrade. This changes the previous implicit-workspace default without broadening filesystem scope. Removed Apps, retargeted identities, ambiguous consumers and incompatible audiences remain rejected.
The signed commits cover selector discovery, configuration alias reuse, workspace/data-route persistence, and a fixture lint correction. They reuse the existing Lark provider and Core binding owners; the bounded refactor pass found no need for a new shared abstraction. Existing frontend settings consume the same API and the installed packaged conversation UI was exercised; no UI layout or new capability is introduced.
Validation (initial conversation qualification at
4895929854bd3fc1cd90d5397b4d68d3ea40a9da; final installer refinement ate0ecbdd210):An earlier concurrent run missed the existing 10-second long-result drain deadline; the complete serial rerun passed without changing that timeout. Native WebView interaction and remote-host mutation were not qualified by this change. Local runtime state, account identifiers, screenshots and raw logs are excluded. This is a locally installed candidate, not a merged or released build; merge readiness and maintainer approval remain pending.
Follow-up validation: the full CI lint command now passes locally after correcting the fixture-injection annotation. The earlier release browser job also timed out in the unchanged
conversation-activityelapsed-label scenario; that browser qualification remains unverified. Current-head CI has been restarted by the follow-up push. SSH upgrade, exact remote host observation, private-scope configuration and an isolated remote Goal create/write/stop journey were also exercised through the installed steward; existing project authority-migration gaps remain separate from this transport fix.The final installer refinement also pins the runtime directory Chat actually resolves, so the existing activation guard can fence that exact store on later upgrades. It does not loosen the guard to guess a runtime from mutable registry state. The LaunchAgent smoke verifies the generated plist is accepted by that guard and retains its root across release paths. Activation/update tests: 75 passed, 3 platform-dependent skips; LaunchAgent smoke passed. The unchanged conversation-activity elapsed-label timeout reproduced in the focused packaged-browser rerun and remains a CI hold.