Replies: 1 comment
|
We posted a deeper root-cause analysis as a separate discussion, reframing this from "a single lost turn" into a read-contract gap: the projection treats a valid (aborted-turn) session log as exhausted, and proposes fix paths (distinguishable read failures, first-class aborted-turn handling, visible gap markers). Cross-linking for reference: #4795 — Why a valid session log silently becomes "no more history": a read-contract gap, not one bug 中文版我们把更深入的 root-cause 分析单独发了一帖,把这个 issue 从"丢了一轮"重定义为读契约缺口:投影把一份合法(含中断轮)的会话日志当作已耗尽,并给出修复路径(区分可读失败、把中断轮作为一等公民处理、可见的缺口标记)。在此交叉引用: #4795 —— 为什么一份合法的会话日志会静默变成"没有更多历史":这是读契约缺口,不是一个 bug |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Self-review update — correction of our own submitted bug report / 自我修正:对本人提交的 bug report 的修正 (2026-08-21)
What we originally claimed / 初版表述 (EN): history paging freezes (blank pages) when a session ends with aborted turns; data is not lost on disk, only the UI cannot reach it.
What we now state / 现修正 (EN): upgraded to the log/read-contract layer — a structurally valid, first-class log state (trailing aborted turns) cannot be served by the history read path; the failure is silently degraded to "no more history"; the session's durable progress record becomes unreachable with no error signal; the defect is a read-contract gap, not a rendering issue.
初版表述(中文): 会话以 aborted 轮次结束时,"加载更早"历史分页冻结(空白页);磁盘数据未丢,只是 UI 够不着。
现修正(中文): 升级到日志/读取契约层——一个结构合法、一等公民的日志状态(尾部 aborted 轮次)无法被历史读取路径服务;失败被静默降级为"没有更多历史";会话的持久化进度记录变得不可达、无任何报错;这是读取契约缺口,不是渲染问题。
EN / English
Observed behavior
A session log whose tail consists of one or more
abortedturns (turn/endwithreason.kind: "aborted", followed bysession/end-seed) is structurally valid: seq is contiguous from 0 and every event is present on disk. Yet the history read path (session.history) cannot serve the earlier region:dsh-client-runtime/lib/client.js:7398-7419, where empty pages continue silently, page discontinuities are logged and treated as end-of-history, and any thrown error is swallowed with a console-only log).The observable symptom (blank paging in the conversation view) is real; the defect is a read-contract failure: a valid log state that its own consumer cannot serve, with no way to tell the user the difference between "no history" and "history that failed to load".
Log / read-path mechanism (with source references)
historyCutOf(dsh-host-apiproxy/lib/index.js:2084-2098) returns the complete events array; nothing is missing on the serving side.paginate(dsh-host-apiproxy/lib/index.js:1030-1049) — so a page always carries all events in its range, including the aborted-turn region.loadOlder()(dsh-client-runtime/lib/client.js:7388-7424) then swallows any inability to fold/render that region: empty page → continue silently (:7398-7404); discontinuity →console.error+hasMore = false+ empty prepend (:7406-7411); thrown error →console.erroronly (:7418-7419).The events are all present; the read path simply has no first-class handling for a trailing aborted region, and its silent-degradation design hides that.
Impact scope (upgraded — log / session / business)
Expected behavior
The read contract must satisfy: a valid log state must be fully reproducible — or, when it cannot be, the read path must say so. Aborted turns are a normal first-class event and must be served (rendered as resumable/recoverable, or paged past); and "history failed to load" must be distinguishable from "no more history" — a failure must surface as an error, never as a silent blank.
Repro
aborted).session/end-seed.completedturn/end→ earlier history is served correctly again.Environment
@deepseek-ai/dsh0.1.0-rc.6/0.1.0-rc.7session.jsonl.zstd), strict contiguous seq from 0Evidence (sanitized event sequence + source)
dsh-client-runtime/lib/client.js:7388-7424—loadOlder(): silent degradation on empty page / discontinuity / error (console.erroronly).dsh-host-apiproxy/lib/index.js:2084-2098—historyCutOf: the full contiguous event log is served, so the data is present.dsh-host-apiproxy/lib/index.js:1030-1049—paginate: message-count paging with group cut.Authorship note: reproduced and documented by me in real-world usage; root-cause tracing and drafting assisted by AI; verification and publication by me. I have no engineering background — if any technical claim reads wrong, please call it out; I will re-verify against the toolchain and correct.
中文版 / ZH
现象
尾部由一个或多个
aborted轮次(turn/end的reason.kind: "aborted",随后session/end-seed)组成的会话日志结构合法:seq 从 0 连续、每个事件都在磁盘上。但历史读取路径(session.history)无法为更早区域提供服务:dsh-client-runtime/lib/client.js:7398-7419:空页静默继续、分页不连续仅 console 后当作历史尽头、抛错被吞掉仅 console)。界面上的空白页(可观察症状)真实存在;但缺陷是读取契约失败:一个合法日志状态,其自身消费方却无法服务,且用户无法区分"没有历史"与"历史加载失败"。
日志 / 读取路径机制(附源码引用)
historyCutOf(dsh-host-apiproxy/lib/index.js:2084-2098)返回完整 events 数组,服务端没有任何缺失。paginate(dsh-host-apiproxy/lib/index.js:1030-1049)——每页携带其区间内的全部事件,包括 aborted 区间。loadOlder()(dsh-client-runtime/lib/client.js:7388-7424)随后把任何"无法 fold/渲染该区间"的情况吞掉:空页→静默继续(:7398-7404);不连续→console.error+hasMore=false+ 空 prepend(:7406-7411);抛错→仅console.error(:7418-7419)。事件全部都在;读取路径只是对尾部 aborted 区间没有一等公民的处理,而它的静默降级设计掩盖了这一点。
影响范围(升级 —— 日志 / 会话 / 业务)
期望行为
读取契约必须满足:合法日志状态必须可完整还原——若无法还原,读取路径必须明说。aborted 轮次是正常的一等事件,必须被服务(渲染为可恢复/可继续,或跳过);"历史加载失败"必须与"没有更多历史"可区分——失败必须呈现为错误,绝不允许静默空白。
复现步骤
aborted)。session/end-seed结尾。completed的turn/end→ 更早历史恢复正常。环境
@deepseek-ai/dsh0.1.0-rc.6/0.1.0-rc.7session.jsonl.zstd),seq 从 0 严格连续证据(脱敏事件序列 + 源码)
dsh-client-runtime/lib/client.js:7388-7424——loadOlder():空页 / 不连续 / 抛错时均静默降级(仅console.error)。dsh-host-apiproxy/lib/index.js:2084-2098——historyCutOf:提供完整连续事件日志,数据确实存在。dsh-host-apiproxy/lib/index.js:1030-1049——paginate:按消息数切页、带 group cut。Original report (archived for transparency) / 初版报告(归档保留)
EN
Observed behavior (original). When a session ends with one or more
abortedturns, the conversation UI renders the recent messages normally, but "Load earlier" paging returns blank pages indefinitely — older history becomes inaccessible even though the data exists on disk.Impact scope (original). Any session whose last turns were interrupted (very common in daily use) may lose UI access to all earlier history. Data is not lost on disk — only the UI cannot reach it, which makes it look like a data-loss bug to users. Workaround found: truncating the log so it ends on the last
completedturn/endrestores paging completely.中文
现象(初版)。 会话以一个或多个
aborted轮次结束时,对话 UI 最近的几条消息能正常显示,但"加载更早"分页永久返回空白页——更早的历史明明存在磁盘上,UI 却永远访问不到。影响范围(初版)。 任何以中断轮次结尾的会话(日常使用非常常见)都可能失去 UI 对全部早期历史的访问。磁盘数据未丢失——只是 UI 够不着,给用户的感觉就像数据丢了。已找到临时方案:把日志截断到最后一个
completed的turn/end,分页即可完全恢复。署名 / About this report
EN: Reported by the OfferKuai (Offer快) Team — an AI startup building full-lifecycle job-application services, guided by the belief that "users need results, not repeated conversations." Founder: Zhaofeng (Yaming). We use DeepSeek Harness as part of our daily development workflow; this report is our way of contributing back to the ecosystem. Website: https://www.offerkuai.com/ | Contact: <contact@offerkuai.com>
ZH: 本报告由 OfferKuai(Offer快)团队提交 —— 一家专注 AI 全流程求职托管的创业团队,核心理念是「用户要的是结果,不是重复对话」。创始人:Zhaofeng(Yaming)。我们将 DeepSeek Harness 用于日常开发工作流,这份报告是我们对社区的回馈。官网:https://www.offerkuai.com/ | 联系:<contact@offerkuai.com>
All reactions