Unified Resident Runtime Implementation Plan¶
Goal: 桌面、OH、CLI 使用同一登录身份、任务记录与后台调度器,关闭桌面后已授权任务继续执行。
Architecture: 独立 Node daemon 持有本机唯一运行时和 profile。桌面通过仅主窗口可调用的 Rust 私有桥接连接 daemon,OH 复用桌面服务入口。已有校园 UI 客户端从可信接口恢复同一会话;成功登录、切换账号、退出登录均带 epoch 栅栏移交,后台成为认证与任务状态的权威来源。
Tech Stack: TypeScript/Node SDK、HTTP JSON-RPC loopback、Tauri/Rust、React/OneGUI。
决策与边界¶
- 采用后台统一所有者。共享文件但保留两个调度器会产生竞态;关闭桌面时临时搬任务会在退出异常时丢失交接。这两种方案均增加故障路径。
- 本机标准 profile 沿用
OneTHU CLI,现有独立 CLI 可直接使用;用户显式--data-dir创建的隔离 profile 保持隔离。 - Node 随桌面 macOS/Windows 安装资源分发,校验平台、架构和官方 Node 校验和。Android 保留原有应用内运行时。
- GUI 不获得 daemon 发现令牌;主窗口 Rust 桥接从私有发现文件读取。认证快照只经可信本机
desktop.*接口,MCP/插件服务目录不暴露该接口。 - 持久 epoch 和明确登出标记阻止旧 GUI 缓存复活登录。bootstrap 仅用于首次移交;明确登录可在核验账号后切换。密码继续遵守已有存储策略,不复制到独立会话快照。
- 旧任务按 ID、执行历史、已发送/下载账簿迁移,记录迁移来源;冲突保留两侧数据并返回问题。桌面停止调度后才由后台运行,绝不同时启动两个 manager。
- OH/CLI 执行权限由同一设备策略控制;关闭窗口不改变授权。撤销授权、退出账号立即停止在途任务。
- 现有 IM 通知凭据迁移只用于后台出站通知,本轮不再启动一套并发 IM 入站轮询。绑定收件人参与通道标识,迁移核验目标一致。
实施与验证¶
- SDK:
src/node/session.ts、src/index.ts、任务与通知模块,增加可信桌面接口、身份导入/导出、迁移幂等与持久登出;测试旧快照、跨账号、并发登出、去重历史、目标绑定。 - CLI:
src/daemon.mjs私有 desktop 方法分派与协议/构建身份探测;测试 MCP 不可访问快照/配置、未知方法拒绝、截止时间与断连取消。 - 原生桥接:
apps/desktop/src-tauri/src/cli_daemon.rs主窗口限定、发现文件权限校验、独立进程启动与版本协调;构建资源包含自足 Node+CLI。 - 桌面:
state/cliTasks.ts桌面分支统一代理,lib/clients.ts恢复/登录/登出接入,state/cliRuntime.ts共享策略,OneGUI 展示实际后台状态;Android 保留现有路径。 - 旧任务/IM 配置迁移:迁移成功后记完成,失败保留原始存档与错误;已有后台冲突不静默覆盖。
- 完成 SDK/CLI/native/desktop 相关检查,重新构建 dev 与后台,验证同一任务从 GUI 与 CLI 可见、App 退出后 daemon PID/任务历史仍可用,并重新打开桌面恢复同一账号。
- 更新中英文使用文档和记忆,明确实机验证范围。无版本发布、无实际预约/邮件/IM 测试发送。
实施结果(2026-10-25)¶
- 私有桥接与协议版本 1 已接通。macOS dev 已编译并加载配套后台,使用标准安装目录内经校验的独立 Node。macOS LaunchAgent 配置已更新为 bundled Node,下次系统登录生效,本次后台持续运行。
- CLI 安装器与 launcher 优先桌面附带 Node;已有桌面运行时仅更新 launcher,避免覆盖活动后台。macOS 临时目录验证覆盖中文/空格路径、PATH 无 Node、活动 profile 拒绝覆盖与原文件保留;Windows 脚本完成静态修改,真机待验收。
- 桌面、OH 的任务 API 统一代理到后台;Android 保持应用内运行时。首次迁移保留执行与去重记录,通知目标不匹配时保留旧记录并显示待移交。任务迁移失败不阻挡已移交任务的查看、暂停或删除。
- 会话加入跨账号 epoch、登出标记、离线登出意图和同 epoch 的验证码完成追踪。同账号换 Cookie 会取消旧网络请求、清理 CSRF/Info 缓存,保留任务身份;写请求结果未知时不重放。
- 开关变更串行消费最后一次用户意图,避免快速关→开时旧响应覆盖新选择。App 退出只关闭图形服务桥接,保持后台授权。
- 早期开发联调中发现接管失败误清旧桌面会话,已改为保留原快照和原 Cookie,并补 3 类失败回归。本机旧会话已在修补前丢失,已向用户说明并请求在现有 dev 重新登录;真实账号接管仍待完成验收。
验证证据¶
- SDK 全量 164/164;CLI 原有及私有桥接/安装服务测试 71/71;新增独立进程移交测试通过。
- 前端共享运行时 17/17、服务边界 48/48、登录状态 67/67、任务集成 8/8;桌面 TypeScript 检查通过。
- 原生桥接测试 6/6;Windows ACL/PID 辅助代码交叉类型检查通过,Windows 真机安装与常驻仍待验收。
- i18n handoff/check:7638/7638、errors 0;Android 62 项词条模板一致。
- 独立进程验收:真实 daemon HTTP 协议和打包 SDK,前台替身移交合成会话和一次性只读任务后退出;后台在约 15 秒后的实际调度周期完成任务,重连和后台重启后 history/inbox 均保持 1 条。所有外网调用由夹具拒绝,未使用真实账号或发送真实 IM。
- 实机 GUI 验收工具曾按显示名称误开
/Applications/OneTHU.app,已精确关闭该实例;后续仅绑定~/Library/Caches/onethu/OneTHU.app,屏幕捕捉仍有工具错误,不作为 UI 验收通过的依据。
本次不发布、不推送、不替换渠道安装包。上述早期验证之后的真实账号结果见下节。
AUTH_HANDOFF_UNVERIFIED 修复与实机续验(2026-10-25)¶
死机重启后外置盘恢复挂载,继续保留原工作区修改。原生桥接已重新编译,继续使用 ~/Library/Caches/onethu/OneTHU.app dev wrapper。
已确认的原因与修补¶
- SDK 曾过滤全部
wengine_vpn_ticket;其中wrdvpn1-前缀也会用于有效 HTTP 会话。现在保留服务器与可信快照中的网关票,并以学校只读身份接口核验账号。 - Info 的 Cookie 接口在首次打开该服务前可能返回空正文。核验增加一次只读入口预热,随后重取 Cookie;无法核验时保留原会话。
- Info 刷新正文与 HTTP Cookie 曾写入不同路径,旧应用路径值会压过新的根路径值。InfoClient 与身份核验现在共用解析器,更新逻辑域和 WebVPN 应用路径,正文无法覆盖网关票或注入 Cookie 属性。
- GUI 原先只导出 JavaScript Cookie,遗漏原生网络层的完整状态;恢复时又清空原生仓。新增仅主窗口可用的完整导出、按版本校验的原子导入,原生写盘成功后再更新两份 JS jar 与本地会话镜像。
- 学校登录成功与后台移交状态分开处理。待移交意图持久化,临时后台失败保持 GUI 登录并允许无密码重试;明确登出、账号变化以版本栅栏淘汰旧意图。后台延迟恢复成功后强制完成界面水合。
- 实机首次调用
learn.courses进一步暴露了移交后 CSRF 尚未准备的问题。补充统一、可重试的只读 Learn 初始化;不重放业务写操作。进程退出以关闭标志和网络取消隔离旧请求,账号版本保持持久稳定。
实机证据¶
- 备份会话通过只读身份验证,核验结果与快照账号一致;随后实际 dev 登录成功,独立 daemon 也为 ready。
- 桌面与 CLI 查询同一个临时任务,ID 一致。关闭真实 dev 进程后,daemon PID 保持不变,并完成一次
user.info学校查询,状态 succeeded、历史 1 条、无通知外发。 - 原始脱敏记录:
output/unified-resident-acceptance/live-result.json。只保存时间、计数、测试任务 ID 与执行结果,不含账号、Cookie、学校正文或令牌。 - 已载入最终后台构建
8aac1d1e563dc2cb8b1f9ec173863a4574dc6c34842b270803b44afba0051d94,daemon ready、GUI 会话账号一致。 - 独立 CLI 与 dev 服务分别调用
learn.courses,均返回 11 门真实课程,课程 ID 集合一致。 - dev 重开和后台升级后,原测试任务 ID 与成功历史 1 条保持一致,没有重复执行。已通过任务 API 删除临时任务并检查列表;此前为恢复创建的两份私有会话备份也已删除。
- 最终 SDK 全量 178/178、前端 handoff 8、共享运行时 19、Cookie 边界 15、登录状态 67、登录准备 7、会话策略 4 项通过;core/SDK/desktop 类型检查、原生 dev 构建及 i18n 7639/7639(errors 0)通过。原生会话桥接 4 项测试此前已通过,最后修改已完成编译验证。
- 验收脚本末尾曾调用不存在的
LocalClient.close(),发生在真实后台成功及证据写入之后。随后移除该无效收尾调用,独立完成重开、课程、历史与清理验收,最终记录为 passed。 - Windows 真机与真实 IM 通道仍未验收;本轮没有修改或发送真实学校业务数据。