| 1 | # App 会话命令所有权 |
| 2 | |
| 3 | [English](APP_SESSION_OWNERSHIP.md) |
| 4 | |
| 5 | 显示身份、有序快照、分页及恢复见[会话显示投影](TRANSCRIPT_PROJECTION.zh-CN.md)。 |
| 6 | |
| 7 | 会话操作在调用时捕获来源。后续切换标签页不能把尚未完成的发送、取消、审批、 |
| 8 | 模型修改或导航结果转交给新会话。命令只在布局提交后获得执行权限;替换会话代次 |
| 9 | 或卸载会撤销旧异步续体。后台取消使用规范控制器目标,不使用界面标签标识; |
| 10 | 目标缺失或已替换时返回过期结果。 |
| 11 | |
| 12 | 订阅作用域先撤销排队通知,再释放注册。终端输出使用引用计数租约,旧清理不能 |
| 13 | 释放新订阅。AppRuntime 将所有权模块接入 AppRuntimeView。App.tsx 仅保留组合入口;页面树 |
| 14 | 接收已提交的命令与展示数据,不创建第二套会话权限。 |
| 15 | |
| 16 | ## 本地历史可读与运行时就绪 |
| 17 | |
| 18 | 本地导航发布目标标签身份后,独立于控制器激活启动有界历史读取。运行时尚在准备时, |
| 19 | 历史窗口可以先显示;草稿输入框保持挂载并允许编辑,发送和控制操作仍受运行时就绪 |
| 20 | 门禁约束。运行时失败保留已经读到的历史,不能把尚未完成的历史读取标记为成功的空 |
| 21 | 会话。远程切换保留原有展示门禁。 |
| 22 | |
| 23 | 导航解除渲染器订阅,并在现有 store 预算内保留历史;显式关闭会驱逐缓存。正文懒加载 |
| 24 | 最多交接到同一个驻留 owner 的下一代,驱逐或关闭后重开会终止旧读取。缓存仍在内存 |
| 25 | 不代表导航一定命中:canonical 历史 generation 与旧版标签指纹属于不同身份域,新的 |
| 26 | 标签绑定还需明确协调所有权。浏览器 mock 首屏耗时不能证明原生后端延迟或跨绑定复用。 |
| 27 | |
| 28 | ## 验证 |
| 29 | |
| 30 | `pnpm test:app-lifecycle` 覆盖来源捕获、提交发布、替换、A→B→A 导航、规范后台 |
| 31 | 取消、卸载、订阅清理及内存协议反例。`pnpm test:app-browser` 通过真实界面验证 |
| 32 | 本地/远程导航、发送/停止、三种布局以及 Composer/Workspace 节点身份。 |
| 33 | `pnpm test:all` 发现并运行其余前端回归测试。 |
| 34 | |
| 35 | ## 独立内存筛查 |
| 36 | |
| 37 | 工作流对指定干净提交只构建一次。普通前端 PR 使用一个短进程,执行 32 次 full、 |
| 38 | 32 次 windowed、32 次 safety 和 128 次 mixed 往返。涉及 App 生命周期、Transcript、 |
| 39 | 导航、订阅所有权、内存夹具和 CI 路由的改动使用三个进程的完整协议。推送到 |
| 40 | `main-v2`、每日定时任务和手动触发也运行完整协议,每进程执行 128 次 full、 |
| 41 | 128 次 windowed、128 次 safety 和 512 次 mixed 往返。 |
| 42 | |
| 43 | 汇总要求全部检查点与堆快照、唯一分片、相同工作流执行批次、源码与构建摘要、 |
| 44 | Node/平台/架构、夹具配置、浏览器版本和声明的档位。缺失、取消、身份或档位不一致 |
| 45 | 及失败的分片都不能产生通过结果。结果通过 `screeningLevel` 区分短筛查与完整验收。 |
| 46 | |
| 47 | 前端及未知路径会触发工作流,明确独立的后端和文档改动可跳过 mock 前端长测; |
| 48 | 现有平台 CI 继续覆盖这些路径。最终 `app-memory` 检查会核验跳过条件和依赖任务 |
| 49 | 状态,不能通过意外 skipped 隐藏失败。 |
| 50 | |
| 51 | `SHARD_PASS` 只代表一个完整进程。汇总 `PASS` 代表自动筛查通过,不代表整个 App |
| 52 | 不存在内存泄漏;堆保留链分析及主分支对照仍是独立归因工作,报告持续保留待归因 |
| 53 | 状态。PR head 的证据也不替代最新目标分支集成检查和原生平台验证。 |
| 54 | |
| 55 | ## 远端恢复失败的原子完成 |
| 56 | |
| 57 | 远端恢复被拒绝时,会话身份、标题、路由、待处理提示和运行态必须先恢复,错误才能对外可见。HTTP 拒绝、忙碌、列表失败、目标不存在及传输失败后回查旧会话,共用同一个失败完成入口,并复核 tab、client、代际、选择与路由权限。 |
| 58 | |
| 59 | 代际安装/退役、重连、主机挂起和显式关闭使用同一个 tab 发布顺序;不会在持全局 map 锁时等待发布锁,网络握手和 pump 等待仍在锁外。 |
| 60 | |
| 61 | 在 desktop 模块执行 `go test -race . -run 'TestRemoteResumeFailure|TestOpenRemoteProjectTabRejectedResumeRestoresPreviousIdentity|TestRemoteRejectedResume'`,覆盖错误可见时的完整身份、所有拒绝路径、旧请求失权,以及错误发布期间重连/退役/关闭的交错。 |
| 62 | |
| 63 | ## 远端启动锁交接 |
| 64 | |
| 65 | 远端服务持有者可能在竞争方排他 mkdir 失败与 Stat 之间释放目录。获取入口允许对这个缺失观测重新竞争一次,仍须通过排他 mkdir 才能成为持有者。只有 Exists 或结构化 SFTP v3 通用失败允许此路径;权限、传输与取消保持终止。连续第二次缺失会保守报错,因为协议不能区分重复竞争和永久通用失败;确实观察到存活锁后恢复原有受 context 控制的等待。此修复不改变独立的过期锁回收策略。 |
| 66 | |
| 67 | 根模块执行 `go test -race ./internal/remote/bootstrap`,覆盖释放交错、永久错误有限退出、取消及并发客户端只启动一次服务。 |
| 68 |