DSH / Atlas
2026-09-29implementedarchitecture

Open the Session when migration is required

需要迁移时引导打开会话

Expanding a subagent catalog or forking from the sidebar can trigger an old Session's format migration.

English

Problem

Expanding a subagent catalog or forking from the sidebar can trigger an old Session's format migration.

Decision

The WorkspaceBrowser row-menu fork request carries allowMigration: false, which the Host handles by checking stat format information before calling the original fork flow. Only a source format requiring migration is refused, with an app-wide Toast offering to open the original Session. That action only navigates and does not retry fork. Neither an absent live Session nor unopened Client history justifies refusal.

Other fork callers omit that option and allow automatic migration.

session.projections also checks the stored format first; current-format cold history still uses the original observation flow for exact projections. Success returns kind: sequenced and its real asOfSeq; required migration returns kind: migration-required hints. The Client retains that read state, and cached values cannot replace sequenced values published by history or control.

The formatStatus returned by stat carries the migration library's existing classification; header remains the current logical format. It describes the stored format, not migration-task progress or prepared in-memory history.

When migration is required and subagentCatalog is absent, Web marks the Session's row “Migration required” and keeps its history-opening actions without descendant expansion or changing its subagent mode. Opening the Session supplies its catalog through history and control projections. Available catalogs remain usable, including empty catalogs. Session-list lineage resolves navigation addresses, not missing catalog membership. Ordinary loading, cancellation, and storage errors do not become this migration branch.

Create/adopt, full-text search, and ordinary history opening allow automatic migration.

This decision adds a migration exception to catalog projection reads. Exact reads and leases in Session observations, and identity checks and cached/sequenced ordering in projection-cache reads, still apply.

Alternatives considered

Treat every cold Session as needing migration. Residency and stored format are different; this would reject otherwise valid forks and discard catalog information available on disk.

Globally forbid forks that automatically migrate on the Host. The sidebar's interaction choice does not govern other callers, so its request explicitly carries the restriction.

Automatically open and retry the sidebar fork. Opening is an explicit user action, and fork does not run automatically after migration.

Derive catalogs from Session-list parent ids. This adds a second membership derivation; explicit Session opening obtains the catalog.

Give cached hints asOfSeq: -1. Hints have no event cut in current history and cannot participate in sequence comparisons.

Consequences

Sessions requiring migration use the existing opening flow to prepare history; Sessions that need no migration remain cold-readable and forkable. Catalog hints may lag the log and yield to subsequent exact projections.

A separate follow-redirection proposal discusses future single-Session migration progress; this decision does not implement that flow.

中文

问题

展开 subagent 目录或从侧栏 fork 可能触发旧会话的格式迁移。

决定

WorkspaceBrowser 行菜单的 fork 请求携带 allowMigration: false,由 Host 在调用原 fork 流程前检查 stat 的格式信息。只有源格式需要迁移时才拒绝,并显示带“打开原会话”操作的应用级 Toast。该操作只导航,不自动重发 fork。没有 live Session 或 Client 尚未打开历史不构成拒绝理由。

其他 fork 调用者省略该选项,允许自动迁移。

session.projections 同样先检查存储格式,当前格式冷历史继续通过原观察流程读取准确投影。成功时返回 kind: sequenced 和真实 asOfSeq;需要迁移时返回 kind: migration-required 的缓存提示。Client 保留这一读取状态,缓存值不能覆盖 history 或 control 已发布的有序值。

stat 返回的 formatStatus 携带迁移库已有的分类;header 仍是当前逻辑格式。它描述存储格式,不描述迁移任务进度或内存准备缓存。

在需要迁移且缺少 subagentCatalog 时,Web 将该会话行标为“需要迁移”,保留打开历史的操作,但不能展开下级,也不改变子会话的 mode。打开会话后,历史与 control 投影提供其目录。已有目录仍可使用,包括空目录。会话列表的谱系用于解析导航地址,不用于补齐缺失的目录成员。普通加载、取消和存储错误不转换成这一迁移分支。

create/adopt、全文搜索和普通历史打开允许自动迁移。

本决策为目录投影查询增加迁移例外。会话观察的准确读取和租约,以及投影缓存读取的身份校验与缓存/有序分层继续适用。

考虑过的替代方案

把所有冷会话都视作需要迁移。 是否驻留与存储格式不同;这样会拒绝可以正常完成的 fork,并丢失能够从磁盘读取的目录信息。

Host 全局禁止自动迁移的 fork。 侧栏的交互选择不适用于其他调用者,因此限制由该请求显式携带。

侧栏 fork 自动打开并重试。 打开会话由用户明确选择,fork 不在迁移后自动执行。

按会话列表中的父 id 派生目录。 这需要第二套成员派生逻辑;显式打开会话即可获取目录。

让缓存提示携带 asOfSeq: -1。 提示没有当前历史的事件切点,不能参与序号比较。

影响

需要迁移的会话通过现有打开流程完成准备;无需迁移的会话仍可冷读和 fork。目录的缓存提示可能落后于日志,后续准确投影替换它们。

后续单会话迁移进度由独立的 follow 重定向提案讨论,本决策不实现该流程。