@orion-agents/orion-code 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +45 -18
  3. package/README.zh-CN.md +39 -18
  4. package/dist/commands/model-command-handlers.d.ts.map +1 -1
  5. package/dist/commands/model-command-handlers.js +59 -14
  6. package/dist/commands/model-command-handlers.js.map +1 -1
  7. package/dist/commands/types.d.ts +6 -0
  8. package/dist/commands/types.d.ts.map +1 -1
  9. package/dist/commands/types.js.map +1 -1
  10. package/dist/commands/workflow-command-handlers.d.ts +1 -1
  11. package/dist/commands/workflow-command-handlers.d.ts.map +1 -1
  12. package/dist/commands/workflow-command-handlers.js +42 -3
  13. package/dist/commands/workflow-command-handlers.js.map +1 -1
  14. package/dist/commands/workflow-commands.d.ts.map +1 -1
  15. package/dist/commands/workflow-commands.js +2 -2
  16. package/dist/commands/workflow-commands.js.map +1 -1
  17. package/dist/core/tool-artifacts.d.ts +2 -0
  18. package/dist/core/tool-artifacts.d.ts.map +1 -1
  19. package/dist/core/tool-artifacts.js +27 -1
  20. package/dist/core/tool-artifacts.js.map +1 -1
  21. package/dist/runtime/agent-runtime-controller.d.ts +16 -2
  22. package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
  23. package/dist/runtime/agent-runtime-controller.js +116 -8
  24. package/dist/runtime/agent-runtime-controller.js.map +1 -1
  25. package/dist/runtime/agent-runtime-protocol.d.ts +7 -0
  26. package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
  27. package/dist/runtime/agent-runtime-protocol.js.map +1 -1
  28. package/dist/runtime/agent-runtime-runner.d.ts +8 -0
  29. package/dist/runtime/agent-runtime-runner.d.ts.map +1 -1
  30. package/dist/runtime/durable-tool-receipt-reader.d.ts +32 -0
  31. package/dist/runtime/durable-tool-receipt-reader.d.ts.map +1 -0
  32. package/dist/runtime/durable-tool-receipt-reader.js +130 -0
  33. package/dist/runtime/durable-tool-receipt-reader.js.map +1 -0
  34. package/dist/runtime/legacy-thread-materializer.d.ts +14 -1
  35. package/dist/runtime/legacy-thread-materializer.d.ts.map +1 -1
  36. package/dist/runtime/legacy-thread-materializer.js +44 -5
  37. package/dist/runtime/legacy-thread-materializer.js.map +1 -1
  38. package/dist/runtime/orion-session-runner.d.ts +4 -0
  39. package/dist/runtime/orion-session-runner.d.ts.map +1 -1
  40. package/dist/runtime/orion-session-runner.js +15 -0
  41. package/dist/runtime/orion-session-runner.js.map +1 -1
  42. package/dist/runtime/plan-review.d.ts +38 -0
  43. package/dist/runtime/plan-review.d.ts.map +1 -0
  44. package/dist/runtime/plan-review.js +173 -0
  45. package/dist/runtime/plan-review.js.map +1 -0
  46. package/dist/runtime/product-bootstrap.d.ts.map +1 -1
  47. package/dist/runtime/product-bootstrap.js +28 -6
  48. package/dist/runtime/product-bootstrap.js.map +1 -1
  49. package/dist/runtime/product-orion-runtime.d.ts.map +1 -1
  50. package/dist/runtime/product-orion-runtime.js +14 -35
  51. package/dist/runtime/product-orion-runtime.js.map +1 -1
  52. package/dist/runtime/protocol/runtime-protocol-v1.d.ts +73 -0
  53. package/dist/runtime/protocol/runtime-protocol-v1.d.ts.map +1 -1
  54. package/dist/runtime/protocol/runtime-protocol-v1.js +37 -0
  55. package/dist/runtime/protocol/runtime-protocol-v1.js.map +1 -1
  56. package/dist/runtime/release-receipts.d.ts +8 -3
  57. package/dist/runtime/release-receipts.d.ts.map +1 -1
  58. package/dist/runtime/release-receipts.js +88 -4
  59. package/dist/runtime/release-receipts.js.map +1 -1
  60. package/dist/runtime/session-composer-control.d.ts +136 -0
  61. package/dist/runtime/session-composer-control.d.ts.map +1 -0
  62. package/dist/runtime/session-composer-control.js +532 -0
  63. package/dist/runtime/session-composer-control.js.map +1 -0
  64. package/dist/runtime/thread-event-store.d.ts +62 -9
  65. package/dist/runtime/thread-event-store.d.ts.map +1 -1
  66. package/dist/runtime/thread-event-store.js +363 -31
  67. package/dist/runtime/thread-event-store.js.map +1 -1
  68. package/dist/runtime/thread-projection.d.ts +17 -0
  69. package/dist/runtime/thread-projection.d.ts.map +1 -1
  70. package/dist/runtime/thread-projection.js +87 -0
  71. package/dist/runtime/thread-projection.js.map +1 -1
  72. package/dist/runtime/thread-session-index.d.ts +84 -0
  73. package/dist/runtime/thread-session-index.d.ts.map +1 -0
  74. package/dist/runtime/thread-session-index.js +503 -0
  75. package/dist/runtime/thread-session-index.js.map +1 -0
  76. package/dist/runtime/thread-session-view.d.ts +31 -13
  77. package/dist/runtime/thread-session-view.d.ts.map +1 -1
  78. package/dist/runtime/thread-session-view.js +116 -61
  79. package/dist/runtime/thread-session-view.js.map +1 -1
  80. package/dist/runtime/thread-ui-adapter.d.ts.map +1 -1
  81. package/dist/runtime/thread-ui-adapter.js +18 -58
  82. package/dist/runtime/thread-ui-adapter.js.map +1 -1
  83. package/dist/runtime/tool-detail-repository.d.ts.map +1 -1
  84. package/dist/runtime/tool-detail-repository.js +23 -19
  85. package/dist/runtime/tool-detail-repository.js.map +1 -1
  86. package/dist/runtime/tool-receipt-validator.d.ts +21 -0
  87. package/dist/runtime/tool-receipt-validator.d.ts.map +1 -0
  88. package/dist/runtime/tool-receipt-validator.js +157 -0
  89. package/dist/runtime/tool-receipt-validator.js.map +1 -0
  90. package/dist/runtime/ui-events.d.ts +6 -1
  91. package/dist/runtime/ui-events.d.ts.map +1 -1
  92. package/dist/runtime/ui-events.js.map +1 -1
  93. package/dist/services/redaction.d.ts +4 -0
  94. package/dist/services/redaction.d.ts.map +1 -1
  95. package/dist/services/redaction.js +63 -0
  96. package/dist/services/redaction.js.map +1 -1
  97. package/dist/services/session-index.d.ts +16 -0
  98. package/dist/services/session-index.d.ts.map +1 -1
  99. package/dist/services/session-index.js +45 -36
  100. package/dist/services/session-index.js.map +1 -1
  101. package/dist/services/session-storage.d.ts +36 -0
  102. package/dist/services/session-storage.d.ts.map +1 -1
  103. package/dist/services/session-storage.js +80 -7
  104. package/dist/services/session-storage.js.map +1 -1
  105. package/dist/services/workspace-registry.d.ts +42 -0
  106. package/dist/services/workspace-registry.d.ts.map +1 -0
  107. package/dist/services/workspace-registry.js +222 -0
  108. package/dist/services/workspace-registry.js.map +1 -0
  109. package/dist/web/errors.d.ts +6 -0
  110. package/dist/web/errors.d.ts.map +1 -0
  111. package/dist/web/errors.js +13 -0
  112. package/dist/web/errors.js.map +1 -0
  113. package/dist/web/event-hub.d.ts +4 -0
  114. package/dist/web/event-hub.d.ts.map +1 -1
  115. package/dist/web/event-hub.js +81 -11
  116. package/dist/web/event-hub.js.map +1 -1
  117. package/dist/web/file-read-service.d.ts +64 -0
  118. package/dist/web/file-read-service.d.ts.map +1 -0
  119. package/dist/web/file-read-service.js +409 -0
  120. package/dist/web/file-read-service.js.map +1 -0
  121. package/dist/web/git-read-model-service.d.ts +85 -0
  122. package/dist/web/git-read-model-service.d.ts.map +1 -0
  123. package/dist/web/git-read-model-service.js +657 -0
  124. package/dist/web/git-read-model-service.js.map +1 -0
  125. package/dist/web/protocol.d.ts +205 -1
  126. package/dist/web/protocol.d.ts.map +1 -1
  127. package/dist/web/protocol.js +229 -1
  128. package/dist/web/protocol.js.map +1 -1
  129. package/dist/web/review-service.d.ts +38 -0
  130. package/dist/web/review-service.d.ts.map +1 -0
  131. package/dist/web/review-service.js +74 -0
  132. package/dist/web/review-service.js.map +1 -0
  133. package/dist/web/server.d.ts.map +1 -1
  134. package/dist/web/server.js +312 -29
  135. package/dist/web/server.js.map +1 -1
  136. package/dist/web/terminal-manager.d.ts +156 -0
  137. package/dist/web/terminal-manager.d.ts.map +1 -0
  138. package/dist/web/terminal-manager.js +760 -0
  139. package/dist/web/terminal-manager.js.map +1 -0
  140. package/dist/web/terminal-server.d.ts +8 -0
  141. package/dist/web/terminal-server.d.ts.map +1 -0
  142. package/dist/web/terminal-server.js +275 -0
  143. package/dist/web/terminal-server.js.map +1 -0
  144. package/dist/web/workbench-controller.d.ts +71 -18
  145. package/dist/web/workbench-controller.d.ts.map +1 -1
  146. package/dist/web/workbench-controller.js +1187 -178
  147. package/dist/web/workbench-controller.js.map +1 -1
  148. package/dist/web-client/assets/DiffViewer-eaQNsnCh.js +5 -0
  149. package/dist/web-client/assets/FilesPanel-DYs1MhoM.js +2 -0
  150. package/dist/web-client/assets/GitPanel-CnU4XVr7.js +1 -0
  151. package/dist/web-client/assets/ReviewPanel-BDxG670T.js +1 -0
  152. package/dist/web-client/assets/TerminalPanel-DLuoa74B.css +1 -0
  153. package/dist/web-client/assets/TerminalPanel-Q5mSSsoK.js +23 -0
  154. package/dist/web-client/assets/index-BWV5sIvw.css +1 -0
  155. package/dist/web-client/assets/index-VVUKj6FE.js +17 -0
  156. package/dist/web-client/index.html +2 -2
  157. package/docs/architecture/agent-mode-permission-contract.md +87 -0
  158. package/docs/architecture/v0.3.0-web-api.yaml +44 -13
  159. package/docs/architecture/v0.3.1-web-api.yaml +2338 -0
  160. package/docs/architecture/v0.3.2-web-api.yaml +3029 -0
  161. package/docs/migration/v0.3.0-to-v0.3.1.md +88 -0
  162. package/docs/migration/v0.3.1-to-v0.3.2.md +94 -0
  163. package/docs/plan/v0.3.0-web-workbench-plan.md +58 -7
  164. package/docs/plan/v0.3.1-web-workbench-professional-shell-plan.md +848 -0
  165. package/docs/plan/v0.3.2-web-workbench-layout-and-composer-plan.md +869 -0
  166. package/docs/readme.md +20 -0
  167. package/docs/test/v0.3.1-web-workbench-e2e-plan.md +140 -0
  168. package/docs/test/v0.3.2-web-workbench-e2e-plan.md +100 -0
  169. package/npm-shrinkwrap.json +185 -354
  170. package/package.json +21 -4
  171. package/dist/web-client/assets/index-BAEO71Gp.css +0 -1
  172. package/dist/web-client/assets/index-DSkFy7gM.js +0 -13
@@ -0,0 +1,88 @@
1
+ # Orion Code v0.3.0 → v0.3.1 Web Workbench 迁移说明
2
+
3
+ v0.3.1 将 Web Workbench 从固定三栏升级为多项目导航和专业工程面板,同时保持单一 active
4
+ Workspace/Runtime。迁移不会复制 Session、重写 Thread history,也不会把 terminal 变成 durable Session。
5
+
6
+ ## 升级前准备
7
+
8
+ 1. 停止正在运行的 `orion web` Host,并确认重要终端任务已经结束;浏览器终端不会跨 Host 重启恢复。
9
+ 2. 备份 `$ORION_CODE_CONFIG_DIR/orion.json` 与现有 Session/Thread 数据目录。
10
+ 3. 记录当前活动 Workspace 和 Session;不要在问题报告中粘贴绝对路径、凭据或 terminal 输出。
11
+ 4. 使用受支持的 Node 22.12+、24 或 26。Node 20 不属于 v0.3.1 发布合同。
12
+
13
+ ## 多项目注册表
14
+
15
+ 首次运行时,Host 会从当前工作区和已有 Session project metadata 幂等导入 WorkspaceRegistryV1。
16
+
17
+ - 注册表只保存规范化项目身份、显示标签、最近使用时间和 pin 顺序;
18
+ - 它不会复制项目文件、删除 Session 或同时启动多个 Agent Runtime;
19
+ - 不存在或不可访问的项目显示 unavailable,可从注册表移除;移除不删除磁盘目录或历史;
20
+ - 展开 inactive project 只读取轻量 Session page/Git summary,不激活 Runtime;
21
+ - 点击另一个项目的 Session 通过一次 `workspaceId + sessionId + expectedContextRevision` 原子切换。
22
+
23
+ 陈旧 Context guard 返回 `409 context_revision_conflict`,Host 保持原 context,且不得投递命令、
24
+ 创建 PTY、读错 workspace 或产生其他副作用。客户端应重新读取 bootstrap 后显式重试。
25
+
26
+ ## 布局偏好
27
+
28
+ 右侧 Work panel 的桌面宽度默认 420px,可用 IDE 式鼠标指针在 320–720px 间拖动调整,双击
29
+ 分隔条复位。
30
+
31
+ - 精细调宽没有键盘入口;键盘用户可以展开/折叠面板,并在 drawer 中访问全部功能;
32
+ - 窄屏自动切换 drawer,不覆盖桌面宽度偏好;返回桌面时恢复;
33
+ - 无效或越界旧值会被 clamp/忽略,不阻止 Workbench 启动;
34
+ - 当前面板、折叠态和桌面宽度是 UI preference,不是 Runtime 或 Session 权威状态。
35
+
36
+ ## 文件、Git 与审阅
37
+
38
+ 这些面板都是 Host 管理的只读投影:
39
+
40
+ - 文件操作使用 opaque id;Host 每次读取都重新检查 canonical workspace containment;
41
+ - sensitive file、workspace 外 symlink、non-regular path 和 stale revision 均 fail-closed;
42
+ - Git 只使用 argv 执行 bounded status/log/diff,不提供 checkout、reset、stage、commit 或 push;
43
+ - binary 文件只返回 metadata,文本和 Diff 采用 revision-bound 分页并在 Host 端脱敏;
44
+ - “发送到 Composer”只把用户选择的安全文本加入草稿,不直接修改文件。
45
+
46
+ ## 真实终端
47
+
48
+ v0.3.1 terminal 是显式用户启动的真实本地 PTY,是高权限、非 durable 表面:
49
+
50
+ - 仅在 active workspace 启动,环境变量经过 allowlist/scrub;
51
+ - attach ticket 单次使用且短时有效,只能放在 WebSocket 首个 JSON 消息中;
52
+ - 刷新页面时,只要原 Host 仍存活可申请新 ticket 并按 sequence reconnect;
53
+ - 输出缓冲已经截断时返回明确 gap;不补造丢失字节;
54
+ - Host 重启后旧 terminal 显示 lost,不从 Session、日志或 snapshot 恢复;
55
+ - close、workspace switch 和 Host shutdown 会终止拥有的进程树。
56
+
57
+ terminal 字节不会进入 Workbench SSE、Thread transcript、diagnostics、release stdout/stderr 或持久设置。
58
+
59
+ ## API 客户端变化
60
+
61
+ 自定义 v0.3.0 Web 客户端升级时应改用
62
+ [`v0.3.1 OpenAPI`](../architecture/v0.3.1-web-api.yaml):
63
+
64
+ - active workspace/session/resource 请求携带 `workspaceId` 和 `expectedContextRevision`;
65
+ - mutation 的 `requestId` 是 UUID;session command 仍携带 `expectedSessionId`;
66
+ - 新增 Workspace registry/session summary、files、Git、review、terminal REST 资源;
67
+ - terminal 使用独立 `orion-terminal-v1` WebSocket,不能从 SSE 读取 terminal output;
68
+ - `workspace_resource_invalidated` 只提示按 revision 重取,不携带文件、Diff 或 terminal 内容。
69
+
70
+ 不要在 409 后盲目重放旧 body;先获取新 bootstrap,确认用户仍希望对同一目标执行,再生成新的
71
+ context-bound mutation。只有 byte-equivalent body 才能复用原 requestId。
72
+
73
+ ## 回滚到 v0.3.0
74
+
75
+ 1. 关闭浏览器并停止 v0.3.1 Host,等待所有 terminal 进程退出;如有异常,先核对进程所有权再处理。
76
+ 2. 保留一份 v0.3.1 WorkspaceRegistry/layout preference 备份以便排查;v0.3.0 不依赖这些数据。
77
+ 3. 使用升级前备份恢复 `orion.json`(如果升级期间修改过 Settings)。
78
+ 4. 安装并启动确切的 v0.3.0 artifact,再显式选择原 Workspace/Session。
79
+ 5. 验证 Thread history、当前模型、Goal/Plan 和 pending approval;不要从 terminal 输出重建历史。
80
+
81
+ 回滚不会自动恢复已关闭或 lost 的 terminal,也不应删除 v0.3.1 创建的项目文件。WorkspaceRegistry
82
+ 和布局偏好不是 Session 权威源;旧版本忽略它们不代表数据被删除。
83
+
84
+ ## 升级验证
85
+
86
+ 按 [`v0.3.1 Web E2E 资格计划`](../test/v0.3.1-web-workbench-e2e-plan.md)执行
87
+ WEB31-P0-01..12。只有 source-clean exact-tarball、真实 Chrome、Node 22.12/24/26 和最终 receipt
88
+ 均为 GO,才能把当前候选标记为发布完成。
@@ -0,0 +1,94 @@
1
+ # Orion Code v0.3.1 → v0.3.2 Web Workbench 迁移说明
2
+
3
+ v0.3.2 在 v0.3.1 专业工作台基础上增加可调左侧项目栏、Composer Control Center、
4
+ Session 级模型与权限、可解释 Context、结构化引用、durable Plan review、队列编辑和
5
+ Session 草稿恢复。升级保留现有 Workspace、Session、Thread、Goal、Settings 和项目文件。
6
+
7
+ ## 升级前准备
8
+
9
+ 1. 停止旧 `orion web` Host;如有活动 terminal,先在页面中关闭并确认子进程已退出。
10
+ 2. 备份 `$ORION_CODE_CONFIG_DIR/orion.json` 和 Session/Thread 数据目录。
11
+ 3. 记录当前 Workspace、Session、模型与项目默认权限。不要把绝对路径、凭据或真实 terminal
12
+ 输出粘贴到问题报告。
13
+ 4. 使用 Node 22.12+、24 或 26;安装后执行 `orion --version` 与 `orion doctor`。
14
+
15
+ ## 布局偏好迁移
16
+
17
+ v0.3.2 将旧布局偏好迁移为 `WorkbenchLayoutPreferenceV2`:
18
+
19
+ - 左栏展开宽度默认 280px,可用鼠标指针在 240–480px 范围拖动,双击分隔条复位;
20
+ - 左栏可折叠为 48px rail;右栏继续使用 320–720px 桌面宽度;
21
+ - 中央对话区最小 560px,空间不足时先收缩右栏,再切换为 drawer;
22
+ - `<=760px` 时左右栏是互斥 drawer,窄屏不会覆盖保存的桌面宽度;
23
+ - 旧值无效或越界时会被 clamp/忽略,不会阻止 Workbench 启动。
24
+
25
+ 精细调宽只有鼠标指针入口;键盘仍可展开、折叠、打开 drawer 并操作全部内容。
26
+
27
+ ## Composer Control Center
28
+
29
+ 原先独立的 BUILD/PLAN/AUTO 按钮改为 Composer 下拉控制,并新增权限、模型、Effort 和
30
+ Context 入口。Host 是 current/last-good/pending/error 的权威源,浏览器不会自行推断运行态。
31
+
32
+ - **模式**:BUILD、PLAN、AUTO 是工作流模式;不等同于权限。
33
+ - **权限**:Session 可选 project default、Ask、Allow 或 Deny。Allow 需要风险确认,且不会绕过
34
+ hard policy、sandbox、capability 或 workspace containment。
35
+ - **模型**:模型和 Effort 是 Session 偏好;active turn 中的变更延迟到下一个 logical request。
36
+ - **Context**:显示 Runtime 提供的 token 使用量、容量和来源;estimated 数据带 `~`,模型切换后
37
+ 不沿用旧模型容量。
38
+ - **Compact**:切换到更小上下文模型前,Host 先执行可验证 compact;失败时模型、Effort、
39
+ Session metadata 和下一次请求保持原值。
40
+
41
+ 模式与权限是两个独立轴。AUTO 不能覆盖显式 Deny,也不能把权限提升为全局设置。
42
+
43
+ ## Durable Plan review
44
+
45
+ 这是 v0.3.2 最重要的行为变化:PLAN 提交后不再自动开始实现。
46
+
47
+ 1. Runtime 提交 PlanReceipt,并写入 `awaiting_review` 的 durable review state;
48
+ 2. 浏览器显示 exact plan digest;刷新或 Host restart 后仍可恢复;
49
+ 3. “批准并进入 BUILD”只接受当前 exact digest,并创建独立 BUILD logical request;
50
+ 4. “继续规划”要求反馈并创建新的 PLAN request;
51
+ 5. “取消”结束 review,不产生执行副作用;
52
+ 6. stale revision/digest 返回 409,客户端不得自动重放。
53
+
54
+ TUI、slash command 与 Web 共享同一 Plan review authority;UI 文案不是审批真源。
55
+
56
+ ## Context 引用、队列和草稿
57
+
58
+ - `+` 可添加 workspace 文件/目录、Review hunk、历史 Session 和 Skill 引用;
59
+ - 引用只传 opaque id、revision 和 digest,Host 在组装 prompt 时重新验证 containment、敏感文件、
60
+ stale revision 与预算;单引用最大 64KiB,总引用最大 256KiB;
61
+ - 队列项可编辑、移动和删除,每次 mutation 需要 item revision;冲突返回 409 且零副作用;
62
+ - Steer 与 follow-up 保持不同 admission 语义;队列使用执行时的最新 Composer 控制;
63
+ - 未发送草稿按 Session 存在当前 tab 的 `sessionStorage`,切换/刷新可恢复,发送或显式清除后删除;
64
+ 草稿不是 durable Session history,也不会跨浏览器重启恢复。
65
+
66
+ ## API 客户端变化
67
+
68
+ 自定义 Web 客户端应升级到
69
+ [`v0.3.2 OpenAPI`](../architecture/v0.3.2-web-api.yaml)并遵守以下规则:
70
+
71
+ - composer control mutation 携带 `requestId`、`expectedSessionId`、`expectedContextRevision` 和
72
+ control revision;
73
+ - queue edit/move/remove 携带 queue revision 与 item revision;
74
+ - Plan review 携带 exact plan digest/revision,不接受 last-write-wins;
75
+ - Context reference 是 discriminated union,未知类型和未知字段 fail-closed;
76
+ - replay reset 是硬屏障;matching active snapshot 恢复前 Composer 保持禁用;
77
+ - 409 后先重新读取 bootstrap/snapshot,再让用户确认目标,不自动重放高风险操作。
78
+
79
+ ## 回滚到 v0.3.1
80
+
81
+ 1. 停止 v0.3.2 Host,并关闭所有显式启动的 terminal。
82
+ 2. 备份 v0.3.2 布局偏好、Session composer preference 和 Thread events 供排查。
83
+ 3. 安装 exact v0.3.1 artifact,并显式选择原 Workspace/Session。
84
+ 4. v0.3.1 会忽略新的布局/Composer 投影,但不会删除项目文件或旧 Thread history。
85
+ 5. 不要在 v0.3.1 中批准 v0.3.2 创建的 pending Plan review;需要继续时重新在 v0.3.2 打开,
86
+ 或明确取消后再回滚。
87
+
88
+ 回滚不会恢复已关闭/lost terminal,也不会把浏览器 `sessionStorage` 草稿写入 Session。
89
+
90
+ ## 升级验证
91
+
92
+ 按 [`v0.3.2 Web E2E 资格计划`](../test/v0.3.2-web-workbench-e2e-plan.md)执行
93
+ WEB32-P0-01..12。只有 source-clean `@orion-agents/orion-code@0.3.2` exact tgz、真实 Chrome、
94
+ Node 22.12/24/26 和最终 digest-bound receipt 全部 GO,才能把候选标记为发布完成。
@@ -82,7 +82,13 @@ Loopback Web Host (node:http)
82
82
  - Every mutation, including workspace/session transitions, settings changes and runtime commands,
83
83
  has a client-generated `requestId`. A bounded result cache keyed by both `requestId` and request
84
84
  digest makes exact retries idempotent for the lifetime of the server process; reuse with a
85
- different body returns `409 Conflict`.
85
+ different body returns `409 Conflict`. Accepted IDs are never evicted: after 4,096 distinct
86
+ mutations the Host fails new IDs closed with `503 mutation_capacity_exhausted` until restart,
87
+ instead of risking duplicate side effects.
88
+ - Every runtime command also carries `expectedSessionId`. The Host compares it with the active
89
+ Session in the same synchronous admission step as dispatch; a concurrent Session transition or
90
+ mismatch returns `409 active_session_changed`/`runtime_busy` without executing or replaying the
91
+ command.
86
92
  - Settings are a compare-and-swap resource. Reads return `revision`; writes carry both `requestId`
87
93
  and `expectedRevision`, and a stale revision returns `409 Conflict` without applying any field.
88
94
  - Durable events have increasing cursors and are replayed after reconnect. Ephemeral deltas may be
@@ -90,8 +96,11 @@ Loopback Web Host (node:http)
90
96
  - Every event envelope includes `sessionId` and `threadId`. Runtime events require both keys but
91
97
  allow either value to be `null` before a session/Thread exists; committed Thread events require
92
98
  both identities to be non-null.
93
- - Collection reads use bounded cursor pagination. Page cursors are opaque and distinct from the
94
- monotonically increasing numeric SSE cursor.
99
+ - Collection reads use bounded, revision-bound keyset pagination. The opaque cursor binds route
100
+ scope, the complete ordered collection digest and the last stable item key. If the collection
101
+ changes, the Host returns `409 collection_cursor_stale`; the browser reloads page one instead of
102
+ risking duplicate or skipped items. These cursors are distinct from the monotonically increasing
103
+ numeric SSE cursor.
95
104
 
96
105
  ### HTTP read and mutation surface
97
106
 
@@ -110,13 +119,30 @@ The session snapshot follows `WebSessionSnapshotV1` exactly: nullable `threadId`
110
119
  `threadCursor` and `eventCursor`, optional `projectionDigest`/`activeTurnId`, `threadStatus`, a
111
120
  cursor-paged `TranscriptPage`, the runtime view, pending approvals, nullable TurnCommit Goal and
112
121
  three-field Plan projections, and `recoveryDiagnostics`. A legacy snapshot has `threadId: null` and
113
- `threadStatus: legacy`; the Web client must not synthesize a Thread identity.
122
+ `threadStatus: legacy`; the Web client must not synthesize a Thread identity. A v2 transcript cursor
123
+ binds the Thread identity and immutable transcript-manifest revision. A newer Thread makes an older
124
+ cursor fail with `409 transcript_cursor_stale`, requiring a fresh tail snapshot.
114
125
 
115
126
  Tool details are workspace/project-scoped because the current artifact metadata records artifact
116
127
  identity, tool name and byte size but no `sessionId`. The API resolves only against the active
117
- workspace and never exposes the artifact path, but it cannot claim or prove that an artifact
118
- belongs to a particular session. Session-scoped routes require a future provenance-bearing artifact
119
- format and are not part of the v0.3.0 contract.
128
+ workspace and never exposes the artifact path. Byte ranges address a pre-sanitized derivative,
129
+ never the raw artifact, so an arbitrary offset cannot skip a sensitive-field label. The API still
130
+ cannot claim or prove that an artifact belongs to a particular session. Session-scoped routes
131
+ require a future provenance-bearing artifact format and are not part of the v0.3.0 contract.
132
+
133
+ ### 2026-08-29 — long-session paging closure
134
+
135
+ - Added a persisted, digest-bound Thread head and immutable transcript page manifest. A healthy
136
+ fresh-process v2 snapshot reads the requested page directly and does not reopen the full
137
+ projection or replay the JSONL log; missing, stale or corrupt derived state falls back to one
138
+ authoritative rebuild.
139
+ - The browser now loads one bounded page for Workspaces, Sessions, Skills, MCP and tool-detail
140
+ summaries. Additional pages require an explicit user action; it no longer drains every page into
141
+ memory during bootstrap.
142
+ - Collection continuations and transcript continuations now have separate stale-cursor contracts,
143
+ both fail closed with 409, and both have Host/client/reducer regression coverage.
144
+ - The verification figures below predate this storage evolution. A fresh exact-tarball browser and
145
+ Node 22/24/26 release matrix must be generated before this newer candidate can be called complete.
120
146
 
121
147
  ### Runtime ownership
122
148
 
@@ -323,3 +349,28 @@ Node 22/24/26 matrix. Historical 20/22/24 receipts do not satisfy the current co
323
349
  artifact still records a dirty source tree, so a source-clean commit must generate a new tarball and
324
350
  obtain digest-bound remote receipts before publication. This plan does not itself claim a commit,
325
351
  push, tag, GitHub Release or npm publication.
352
+
353
+ ### 2026-08-29 — composer dock, recovery and paging quality closure
354
+
355
+ - The center column is now an explicit header/transcript/composer grid. Transcript history scrolls
356
+ independently while pending approvals, the follow-up queue and the composer remain in a bounded
357
+ bottom dock; the mobile Steer action remains reachable. Drafts are keyed by Session, and streaming
358
+ growth is observed without forcing users who scrolled upward back to the tail.
359
+ - Snapshot recovery now rejects inactive or mismatched Session state, treats `replay_reset` as a
360
+ terminal barrier, and binds every Session command to the expected active Session. Collection
361
+ continuations and transcript continuations use separate revision-bound cursors; the browser loads
362
+ only the first page until the user explicitly asks for more.
363
+ - Large tool output is served only from a pre-sanitized browser derivative. The derivative byte
364
+ offset is the paging authority, so arbitrary offsets cannot bypass label-based redaction in the
365
+ raw artifact.
366
+ - The exact local candidate tgz, bound to the receipt stored outside the package payload, passed the
367
+ complete system Chrome 152 journey, 22/22 scenarios, on Node 22.22.3. The run records
368
+ `layout.composer_docked=true`, zero console errors/warnings, zero page errors, zero HTTP 5xx, zero
369
+ secret findings and zero dropped events.
370
+ - The same source passed 289/289 Jest suites and 3,620 tests, with 5 existing platform-conditioned
371
+ skips. The generated client contains 44 modules (277.19 kB JavaScript and 54.45 kB CSS before
372
+ gzip).
373
+
374
+ This remains a dirty local development candidate. A source-clean commit must produce a new SHA and
375
+ obtain the required Node 22/24/26 receipts before push, release tagging or npm publication can be
376
+ described as complete.