Repository navigation
Replies: 2 comments
EN / EnglishEvidence (source)
if (current === void 0) {
throw new Error(`goal ${change.operation} requires a current goal`);
}applies verbatim to
and no assistant output followed. A sibling session carrying a different goal had a full
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. Reported by the OfferKuai Team — Founder: Zhaofeng (Yaming). Website: https://www.offerkuai.com/ | Contact: contact@offerkuai.com 中文版 / ZH证据(源码)
if (current === void 0) {
throw new Error(`goal ${change.operation} requires a current goal`);
}对
且无任何 assistant 输出。另一条携带不同 goal 的姊妹会话有完整
协作说明:本文由我在真实使用中复现并记录;根因与成文由 AI 协助完成,我负责校验与发布。我非工程背景,技术表述如有错误,欢迎指出——我会回去用工具链重新验证后更正。 本报告由 OfferKuai(Offer快)团队提交 —— 创始人:Zhaofeng(Yaming)。官网:https://www.offerkuai.com/ | 联系:contact@offerkuai.com |
EN / EnglishProposed fix (directions, not a patch)1. Tolerance guard (minimal, addresses the failure class). In } else {
const current = state.goal;
if (current === void 0) {
// orphan <operation> — no persisted create. Skip + warn (degrade, don't throw)
emitWarning(`goal ${change.operation} without a current goal — skipping`);
return; // keep replay alive; session stays responsive
}
validateSnapshotTransition(state, change, current);
}2. Persistence hardening (addresses the lost-write window). The Why degrade instead of throw (the pattern this thread is part of): the same "strict consumer throws on a shape the lenient consumer accepts, with no self-healing" gap shows up across DSH — #4910 (format v0 hard-refuse, no migration), #4795 (valid-but-unreadable), #5692 (assembler fatal-throw on boundary-cut turns). Each time the fix is the same shape: isolate the failure, keep building, report instead of abort. The goal driver is one more instance. 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. Reported by the OfferKuai Team — Founder: Zhaofeng (Yaming). Website: https://www.offerkuai.com/ | Contact: contact@offerkuai.com 中文版 / ZH建议修复(方向,非补丁)1. 容错守卫(最小改动,针对失败类)。 在 } else {
const current = state.goal;
if (current === void 0) {
// 孤儿 <operation> — 无持久化 create。跳过 + 告警(降级,不抛错)
emitWarning(`goal ${change.operation} without a current goal — skipping`);
return; // 保持重放存活;会话保持响应
}
validateSnapshotTransition(state, change, current);
}2. 持久化加固(针对写入丢失窗口)。 为什么降级而非抛错(本线程所属的模式): 同一个"严格消费者对宽松消费者接受的形状抛错、无自愈"缺口在 DSH 中反复出现——#4910(格式 v0 硬拒无迁移)、#4795(合法但不可读)、#5692(assembler 对边界切分 turn 的 fatal-throw)。每次修复都是同一形态:隔离失败、继续构建、报告而非中止。 goal 驱动是又一个实例。 协作说明:本文由我在真实使用中复现并记录;根因与成文由 AI 协助完成,我负责校验与发布。我非工程背景,技术表述如有错误,欢迎指出——我会回去用工具链重新验证后更正。 本报告由 OfferKuai(Offer快)团队提交 —— 创始人:Zhaofeng(Yaming)。官网:https://www.offerkuai.com/ | 联系:contact@offerkuai.com |
Uh oh!
There was an error while loading. Please reload this page.
EN / English
Found earlier in our daily usage; re-verified against the current npm line (through
0.1.3-alpha.2) before posting — still present. We publish one topic per report so each can be tracked independently; more findings will follow in the same form. (0.1.5-alpha.1 rewrites the goal package into a typert-layered layout; that line carries packaging regressions, so this report verifies against the stable npm line instead.)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.
Summary
A session can become permanently unresponsive: the user sends a message, the goal driver replays the session log on
sync(), and the replay throwsgoal complete requires a current goal— every send then fails before any assistant output. Root cause is a goal event-chain gap with no tolerance:goal/changecreateevent was never persisted to the session log (the create append happens before a flush/fsync window — if the process dies or the write is interrupted, the create is lost while later events survive);completeevent was persisted;applyGoalEventdemands create → … → complete → clear ordering, so acompletewith no current goal throws instead of degrading — while the lenient projectionapplyGoalProjectionshows the goal normally. Two consumers, two verdicts on the same log, and no self-healing once the create is lost.We hit this on a session chain in production testing: every message send after the loss triggered
[goal-round-driver] could not disarm agent …: goal complete requires a current goal, and the agent produced no output. Backups from before any repair confirmed thecreatewas never on disk — this is a lost write, not a repair artifact. A sibling session carrying a different goal had a full create+complete pair, so the write path exists; the loss is intermittent.Trigger Condition
ctx.goals.create()runs while the session log flush window is open (crash/interruption between append and flush)createis lost; the latercompleteis persistedsync()replay:applyGoalEventprocessescompletewithcurrent === void 0→ throwsgoal complete requires a current goalEvidence
complete(nocreate) — verified across backups predating any repairapplyGoalChangeguard (still present on the current line,@deepseek-ai/dsh-goalrc.1,lib/index.js:252):if (current === void 0) throw new Error(\goal ${change.operation} requires a current goal`)— verbatim forcomplete/clear/pause/resume/block`Proposed Fix
createoperations (complete/clear/pause/resume/block) withcurrent === void 0should skip with a warning instead of throwing — an orphancompletemust not take down the whole sessioncommit()appends thecreate, confirm the flush before returning (avoid losing events to the crash window)Related
Environment
@deepseek-ai/dsh-goal0.1.1-rc.2 (audited against 0.1.2-rc.1 — guard unchanged)session-526f1835and its forksession-668f9166Detailed evidence chain (source lines) and the root-cause analysis + proposed fix follow in the comments below.
Reported by the OfferKuai Team — Founder: Zhaofeng (Yaming). Website: https://www.offerkuai.com/ | Contact: contact@offerkuai.com
中文版 / ZH
早前在日常使用中发现;发帖前已对照当前 npm 线复核(截至
0.1.3-alpha.2)——仍存在。我们一帖一主题,便于独立追踪;更多发现将陆续以同形式发布。(0.1.5-alpha.1 将 goal 包重构为 typert 分层布局;该线有打包回归,本报告改以稳定 npm 线为核验对象。)协作说明:本文由我在真实使用中复现并记录;根因与成文由 AI 协助完成,我负责校验与发布。我非工程背景,技术表述如有错误,欢迎指出——我会回去用工具链重新验证后更正。
摘要
会话可能变得永久无响应:用户发消息 → goal 驱动在
sync()时重放会话日志 → 重放抛goal complete requires a current goal→ 之后每次发送都在任何 assistant 输出之前失败。根因是 goal 事件链缺口且无容错:goal/change的create事件从未持久化进会话日志(create 的 append 发生在 flush/fsync 窗口之前——若进程在此间退出或写入被中断,create 丢失而其后的事件存活);complete事件成功持久化;applyGoalEvent要求 create → … → complete → clear 顺序,因此无当前 goal 的complete抛错而非降级——而宽松投影applyGoalProjection正常显示该 goal。同一份日志,两个消费者两种结论,且 create 一旦丢失无任何自愈机制。我们在生产测试的一条会话链上命中:丢失后每次发消息都触发
[goal-round-driver] could not disarm agent …: goal complete requires a current goal,agent 无任何输出。修复前的最早备份证实create从未落盘——这是写入丢失,不是修复造成的痕迹。另一条携带不同 goal 的姊妹会话有完整的 create+complete 对——说明写入路径存在,本次是偶发丢失。触发条件
ctx.goals.create()在会话日志 flush 窗口开启时执行(append 与 flush 之间发生崩溃/中断)create丢失,之后的complete持久化成功sync()重放:applyGoalEvent处理complete时current === void 0→ 抛goal complete requires a current goal证据
complete(无create)——经修复前多份备份验证applyGoalChange守卫(当前版本仍在,@deepseek-ai/dsh-goalrc.1,lib/index.js:252):if (current === void 0) throw new Error(\goal ${change.operation} requires a current goal`)`——对 complete/clear/pause/resume/block 逐字生效建议修复
current === void 0时应带 warning 跳过而非抛错——孤儿 complete 不应让整个会话崩溃commit()append 完create后确认 flush 再返回(避免事件在崩溃窗口丢失)相关
环境
@deepseek-ai/dsh-goal0.1.1-rc.2(对照 0.1.2-rc.1 复核——守卫未变)session-526f1835及其 forksession-668f9166完整证据链(源码行号)、根因分析与建议修复见下方跟帖。
本报告由 OfferKuai(Offer快)团队提交 —— 创始人:Zhaofeng(Yaming)。官网:https://www.offerkuai.com/ | 联系:contact@offerkuai.com
All reactions