DSH / Atlas
2026-09-17implementedarchitecture

Writer acquisition for blank Session reuse

复用空白 Session 时获取写锁

Two Hosts sharing Session storage can select the same blank Session when opening a Workspace. A blank Session already owns a live Agent, accepts slash commands, and can hold its writer lock after the creation checkpoint. An unowned persisted blank also carries command settings that remain useful after a Host restart.

English

Problem

Two Hosts sharing Session storage can select the same blank Session when opening a Workspace. A blank Session already owns a live Agent, accepts slash commands, and can hold its writer lock after the creation checkpoint. An unowned persisted blank also carries command settings that remain useful after a Host restart.

Decision

The Session catalog includes persisted blanks. Startup restoration selects the saved blank; ordinary Workspace navigation selects the first eligible unarchived member in catalog order. Explicit-id session.create names that Session; the Host resumes it and acquires its writer before opening history, and creates a new Session when another owner holds the writer (reuse and preset rules). Other errors propagate. A Workspace connect in one Client joins the latest in-flight connect to that Workspace only when both request the same preset. Later navigation cancels a pending startup selection.

The Agent retains the acquired handle throughout its lifetime. Checking ownership and releasing a probe lock would leave a race before resume. No PID or process identity enters persisted data or the Remote schema.

This decision extends the blank-reuse policy in the Client Session scope reference; its real-Session slash support and Provider adoption rationale remain active.

Alternatives considered

Client-only drafts. Slash commands and Session-scoped plugins require a real Session before the first prompt. Deferring creation requires a separate command lifecycle.

Release a live blank's writer lock. Blank means no turn/start, not no events. A live Agent can still append command and configuration events, so releasing its lock permits competing writers.

Hide every cold blank. This discards reusable command settings from navigation and creates another blank after every restart, even when the old writer is free.

Persist a creator PID. Kernel writer ownership already arbitrates acquisition. PID reuse and stale creator records add no authority.

Consequences

A Host can reuse its own live blank or reclaim an unowned persisted blank with its slash state. Separate Hosts create distinct blanks while existing writers remain held. A held selected blank causes fresh creation even when another blank is free; navigation does not search for another candidate. No cleanup is added. Opening the same established conversation from two Hosts can still encounter writer contention. Unknown projection hints remain visible without cold body scans; automatic reuse requires known blank metadata. A non-contention acquisition failure aborts the navigation; a hero Workspace pick or explicit draft preparation reports it as a notice and startup restoration only to the console, and a hidden blank that fails this way has no recovery action in this flow.

Verification

Navigation tests cover saved selection, opening the Session the Host returns for a held candidate, non-contention failures, overlapping acquisition, and superseding navigation. A shipped Web-composition test holds a real persistence writer, verifies fresh creation despite another free blank, and reclaims the released selected blank with its plan state. The fresh-round-trip recorded Session scenario reloads its blank before submitting the recorded prompt.

中文

Problem

两个共享 Session 存储的 Host 在打开 Workspace 时可能选中同一个空白 Session。空白 Session 已有活动 Agent,可以接受 slash 命令,并且可能在创建检查点后持有写锁。无人占用的持久化空白会话也可能带有 Host 重启后仍有用的命令设置。

Decision

Session 列表包含持久化空白会话。启动恢复选择已保存的空白会话;普通 Workspace 导航按列表顺序选择第一个符合条件且未归档的成员。显式 ID 的 session.create 指明该 Session;Host 恢复它并在打开历史前取得写锁,写锁被其他写者持有时改为新建 Session(复用与 preset 规则)。其他错误返回调用方。同一 Client 中的 Workspace 连接仅在与该 Workspace 最近一次进行中的连接请求相同 preset 时与之合并。后续导航会取消尚未完成的启动选择。

Agent 在整个生命周期内持有取得的句柄。检查占用后释放探测锁,会在恢复前留下竞态。持久化数据与 Remote schema 均不引入 PID 或进程身份。

本决策扩展 Client Session scope 参考中的空白会话复用策略;其真实 Session 支持 slash 以及 Provider 收养的理由仍然有效。

Alternatives considered

纯客户端草稿。 Slash 命令与 Session 作用域插件在首条提示词之前就需要真实 Session。延迟创建需要单独的命令生命周期。

释放活动空白会话的写锁。 Blank 表示没有 turn/start,并不表示没有事件。活动 Agent 仍可能追加命令与配置事件,因此释放其锁会允许多个写入方竞争。

隐藏所有冷空白会话。 这会让导航丢失可复用的命令设置,并且每次重启都创建另一空白会话,即使旧写锁已空闲。

持久化创建者 PID。 内核写锁已能仲裁获取操作。PID 复用与过时的创建者记录无法增加权威性。

Consequences

Host 可以复用自己的活动空白会话,也可以接管无人占用的持久化空白会话并保留其 slash 状态。现有写锁被持有时,不同 Host 创建不同的空白会话。所选空白会话被占用时,即使另有空闲空白会话也会新建;导航不再寻找其他候选。不增加清理逻辑。两个 Host 打开同一个已有对话时仍可能遇到写锁争用。未知投影提示仍可见且不扫描冷日志正文;自动复用要求已知的空白元数据。非锁争用的获取错误会中止该次导航;在 hero 中选择工作区或显式准备草稿时以提示展示该错误,启动恢复只报告到控制台,以此方式失败的隐藏空白会话在此流程中没有恢复操作。

Verification

导航测试覆盖已保存选择、为被占用候选打开 Host 返回的 Session、其他错误、重叠获取以及后续导航替代。实际 Web 组合测试持有真实持久化写锁,验证另有空闲空白会话时仍新建,并接管已释放的所选空白会话及其 plan 状态。fresh-round-trip 的录制 Session 场景在提交已录制的提示词前刷新空白会话。