[Ecosystem] Please open the deferred session-event registration surface — 12 threads, 9+ consumers, and 0.1.2-alpha left writers no path at all #4815
Replies: 4 comments
|
The alpha.1 source diff supports the central claim here: this is no longer only a missing write-side option. I think a useful RFC should avoid making the first public surface only
“Optional” also needs a projection definition. A record can be irrelevant to model-history reconstruction while still affecting surface ordering, source references, search, or plugin UI. If any later event depends on it, it is required. A minimal registration record could carry: interface SessionEventRegistration {
type: `${string}/${string}`
owner: { package: string; version: string }
schemaVersion: number
semantics: 'optional-observation' | 'required-state'
validate(data: unknown): JsonValue
upgrade?(from: number, data: JsonValue): JsonValue
projections: {
modelHistory: 'none' | 'required'
surface: 'none' | 'optional' | 'required'
search: 'none' | 'optional' | 'required'
}
}Not proposing that exact TypeScript API, but each fact needs an owner somewhere. The runtime lifecycle matters just as much:
The compatibility matrix should include same reader, plugin disabled, uninstall/reinstall, newer/older schema, duplicate registration, HMR disposal, mixed compatible/incompatible corpus, fork, export, and search—against both physical backends and from immutable stopped-process artifacts. A ~40-line registry is valuable as a driving prototype, but a global mutable set by itself cannot validate payloads, express optionality, migrate versions, resolve ownership, or explain what uninstall means. Those are the differences between admitting a name and preserving durable semantics. I turned the source diff and this review checklist into a fuller compatibility matrix here: |
补充一个关键设计诉求:信封级 skippable 要「透传」而不是「丢弃」如果我们上一楼请愿的两个方向里,团队倾向「信封级 skippable 字段」(我们也倾向——它与 fail-closed note 指明的「在磁盘上区分必须的插件状态与真正可选的记录」完全同向),那么有一个设计决策对插件生态影响巨大,希望纳入考量: 读取器遇到「不认识但带 skippable 声明」的事件时,请把事件透传到客户端事件流,而不是静默丢弃。 为什么透传是关键插件的客户端部分(比如注册 ConversationNodeDefinition、匹配自己的事件类型来渲染)本来就是插件自由,从来不需要官方许可。整个问题只在 host 侧的持久化读取:fail-closed 让「装了插件的构建」也无法打开含自定义事件的会话。skippable 字段只需要解决读取层的「不拒绝」,剩下的解释工作交给装了插件的客户端。于是:
反过来,如果「跳过 = 丢弃」,那么即使装了插件,历史里的插件行也永远消失了——skippable 只剩「不报错」的价值,插件的回放能力实质上还是没了。早期版本的读路径曾经就是透传未知事件(core 折叠忽略它们),这个对插件最友好的行为值得以「声明制」的形式正式回归。 为什么透传不损害 fail-closed 的初衷fail-closed 要防的是「读取器默默漏掉会影响请求重建、策略状态、投影恢复的事件」。skippable 声明恰好是写入方在磁盘上的显式表态:这条记录是插件私有的呈现层/状态数据,不参与这些语义。所以:
一句话总结:fail-closed 管「会不会误解日志」,透传管「能不能被解释者接住」——两者正交,应该同时成立。 对写入方 API 形状的参考建议
这样插件生态得到一个完整的光谱:不装插件 = 优雅缺失;装了插件 = 完整体验;必须状态的插件用无声明事件 = 仍被忠实对待(或未来的注册面)。我们也愿意为信封字段这条路直接准备 PR(写入选项 + JSONL/SQLite/传输三处落盘 + 文档),并用我们真实的双端会话数据跑验证。 |
|
了解,我们正在积极考虑相关设计,让 session persistence 更好的支持插件作者 |
|
补充核查: 感谢团队在 alpha.2 恢复 当前 master 固定 SHA 的源码核查(2026-09-21)对
由此我目前只做一个窄判断:通过公开 范围说明:这是固定 SHA 的源码结论,不是当前版本的运行时复现,也没有穷尽内部或底层写入路径。本条相较本线程标题已经主张的「0.1.2-alpha 之后写端无路」,只增加「字段恢复之后、当前 master 上写端仍无路」的源码级确认,并不是一个新问题;如果这个增量对设计讨论没有帮助,请直接忽略。 请问:恢复信封字段之后,当前设计是否也计划向公开 边界:这里不声称本线程已被完整修复、当前版本运行时仍可复现、方案已采纳或已有路线图与 ETA;也不把上面的回复升级为承诺。 |
Uh oh!
There was an error while loading. Please reload this page.
Why a new thread when so many already exist
We knew about the existing discussions (census below) and deliberately did not add another voice to the pile. What changed our mind is the 0.1.2-alpha.1 update: instead of opening the deferred surface, it
Session.append(), no production writer used it, and it is now gone from the envelope, the SQLite schema, and the catalogs.For a plugin ecosystem this is the hard version of an already hard constraint: any plugin that persists its own event type makes its users session histories permanently unreadable on every official build — and there is no longer any in-protocol exit for a willing writer.
The ecosystem stake
DeepSeek Harness identity is everything is a plugin. The session log is the only first-class durable channel in this architecture, and a growing family of plugins needs it for exactly the purpose the conversation system is built around: replaying their own rows through a
ConversationNodeDefinitionwith the built-in ordering, folding, anchoring, and view filtering. Without a sanctioned path, every such plugin must either fork the harness (we did, reluctantly), invent a parallel store and re-implement replay (fragmentation the architecture explicitly avoids), or ship products whose users lose their history (the reports below).Census of existing threads
Nine-plus independent consumers spanning at least three requirement shapes: optional presentation rows, required state transitions, and compatibility layers writing foreign types. Several report real user-facing breakage.
What we ask
Session.append(...)options (closing the write-side gap analyzed in Out-of-repo plugins cannot mark session events `ignorable` — every log they touch becomes unreadable (extensibility gap + minimal fix) #1538), so a reader that does not know a type can still honor the record own skip declaration;We fully support the fail-closed goal of faithful reconstruction. The ask is purely to give willing writers a sanctioned, on-disk way to say this record is ours and skippable, so third-party plugins stop being one custom event away from bricking their users history.
All reactions