deepseek-harness/.agents/notes/implemented/architecture/2026-08-30-retain-ignorable-external-session-events.zh.md
Turtle bec6805d6a refactor(session-persistence)!: handle-based seam with a lifecycle-owned write path
The persistence seam is now create/open/stat/list returning per-session
SessionHandles (read/append/flush/close); every log read and write flows
through the owning handle. The seam package exports only the service and
handle contracts, consumer-visible errors, and pure durable-data
validation helpers; each backend owns its complete storage runtime, and
the shared contract suites pin equivalent observable behavior. The
backend routes published sessions' live events by id into the active
write handle; agent-loop only acquires, seeds, and closes the handle.
Resume appends interruptedTurnClosers through its write handle;
session-query owns the revision-keyed cold cache. Legacy-only surfaces
are removed in the same swap: locate/readRaw/supportsRawArtifacts, the
legacy event-shape read migration, zstd torn-frame salvage,
DSH_SESSION_JSONL, and hook transcript_path population; a torn final
zstd frame is discarded whole; the session-list cold blank probe returns
on stat metadata (eventCount derived from the last physical row,
sizeBytes). The WebUI ZIP export serializes the logical log from a read
handle, so both backends export identically.

Refs #3245
2026-09-01 23:19:02 +08:00

2.7 KiB
Raw Blame History

Agent Note: 为外部插件保留可忽略会话事件

Status: implemented

English | 中文

问题

会话事件信封包含 ignorable?: true,读取器因此可以接受不认识的信息性事件,而不必把每次词汇增加都视为新的会话格式。PR #3087 在没有发现第一方生产方后删除了该字段,并把每个未知事件都改为读取必需项。

该生产方清单没有覆盖当前依赖此字段的一个第三方插件。没有 ignorable 时,第一方读取器会拒绝包含该插件信息性事件的已存会话,因为该事件不在仓库生成的 KNOWN_SESSION_EVENT_TYPES 中。插件没有可替代的注册或版本机制,因此在替代机制存在前删除该字段会破坏当前外部消费方。

决定

标准 SessionEvent 信封保留 ignorable?: true,每种表示都保留它:seed 校验、JSONL、API 传输、生成目录与测试 fixture。持久化 seam 的已存事件校验(validateStoredEvents)继续拒绝未知事件,除非已存信封显式带有 ignorable: true;字段不存在时仍表示读取必需。

只有替代机制在事件生产、持久化、重新加载与传输中都支持当前第三方插件,并为已包含该标记的会话提供显式切换方案后,才能删除此字段。Session log 版本决策继续定义默认读取必需的安全规则与格式版本策略。

曾考虑的替代方案

要求读取所有未知事件。 不予采用,因为当前第三方插件会发出仓库生成词汇之外的信息性事件。即使省略该事件是安全的,第一方重新加载仍会拒绝该会话。

先删除字段,以后再设计替代机制。 不予采用,因为该顺序会立刻产生兼容缺口,而且插件及其已存会话都没有迁移或切换路径。

把所有仓库外事件都视为可忽略。 不予采用,因为读取器无法推断未知持久事件是否属于信息性事件。外部事件可能改变后续重建或插件自有状态。

把已挂载插件的事件名称注册为已知。 不作为删除机制采用,因为只注册事件名称无法判定缺失该事件是否安全,而且接受结果会依赖读取器的当前组合,而不是已存记录。

影响

第三方信息性事件的已存记录带有显式标记时可以继续重新加载,未知必需事件则仍会明确失败。在替代机制满足切换条件前,该字段继续属于公开事件信封、JSONL 表示、传输类型、生成引用及其测试。