## 现象(欠账) memory 写路径修复(`fix/memory-write-path`)让链路跑通,但遗留一项"已声明、未兑现"的本金欠账: 1. **SSE 原则未贯彻**:`model.ts` 采用 `RESPONSE_TIMEOUT = 5 分钟`墙钟作为"最后兜底",与用户确认的原则冲突——"模型持续流式输出时不应判超时"。真正的逐 chunk 存活判定(streaming 消费 + 连接/首 chunk 超时 + chunk 间 idle 超时,任何 chunk——含 reasoning delta——到达即重置)尚未实现(设计门 H3)。 2. **锁纪律仅覆盖 checkpoint 路径**:周期 prepare 路径仍在 fence+lock 下内联跑 maintain(长持锁);search 仍跨 match 持锁(为保留同查询合并的刻意取舍,需在规格中显式声明而非隐式保留)。 ## 证据 - `packages/opencode/src/memory/model.ts`:`RESPONSE_TIMEOUT = Duration.minutes(5)`,注释自认 "This is not an activity budget"。 - `packages/opencode/src/memory/memory.ts`:`kickMaintenance`/`backgroundMaintain` 仅被 `checkpointUnsafe` 调用;`prepareUnsafe` 的 due 分支仍在 fence+lock 下运行 maintain。 - 本地代理 SSE 探测:一次 17.2s 生成期间收到 2051 个 chunk(连续 reasoning_content delta)——chunk 级存活判定在该上游可行。 ## 修法选项 - memory 模型调用改为流式消费,实现 connect/首 chunk 超时 + chunk 间 idle 看门狗(任何 chunk 到达即重置);退役墙钟兜底,仅保留"连接建立零响应"作为非响应判据。 - 将后台 maintain + 锁纪律扩展到周期 prepare 路径,并同步调整其钉住的"周期维护同步"测试语义。 - 保留 search 的同查询合并行为(`coalesces concurrent identical queries` 测试不变)。 ## 验收 - 长时间流式 maintain 调用在 chunk 持续到达期间永不被杀;仅"零 chunk / 静默超窗"的连接被中止。 - 发版后 live 验收:`/compact` → `~/.local/share/opencode/memory/projects/<hash>` 话题文件落盘 → `memory_search` 可召回。 - `test/memory/` 全套绿(含 fix/memory-write-path 已加的两个回归)。 ## 关联 - 前序修复:`fix/memory-write-path`(json 词保证 + reasoning 预算 + 墙钟移除 + checkpoint 异步维护)。
Activity
LeXwDeX commentedon Aug 18, 2026
状态更新(随 graphagent-v1.0.25 发布):
generateObject→streamObject,每个到达的 part 重置 idle 看门狗,活跃流不再被墙钟误杀;connect/idle 为纯"无响应"检测器)。已随 dev→main(release: dev -> main — MEMORY write-path repair + DAG gate hardening batch #332)合入并发布为 v1.0.25。LeXwDeX commentedon Aug 18, 2026
PR #333 偿付 debt 2 的 prepare 路径:周期维护在 fence 之后后台运行(镜像 checkpoint 形状),due-only 轮次不再读 store/拿锁;search 的同查询合并按验收要求保留,取舍已在代码注释与 CONTEXT.md 显式声明(MEM-02)。回归测试
keeps the fence and project lock free while background maintenance streams钉住新纪律。debt 1 此前已由 PR #329 偿付(逐 chunk 存活,无墙钟),本 PR 复核确认。fix(memory): extend background-maintenance lock discipline to the per…
LeXwDeX commentedon Aug 18, 2026
PR #333 二轮(/code-review 修订,2f0b6ffeb):
fence.withLiveIdentity,已退役 identity 不再触发维护模型调用(并恢复clearSession);shouldMatch 分支的 kick 同样加 fence 门,与 checkpointUnsafe 注释声明对齐。prepareUnsafe唯一的else,改早返回;kick 参数对象在分支间复用单绑定。hookRuns(fixturestate.maintenance已计数同一事件);裸Effect.timeout换awaitWithTimeout(失败带消息)。验证:typecheck ✅;test/memory + memory-search 96 pass ✅;httpapi-memory-wiring + session/system 10 pass ✅。
fix(memory): extend background-maintenance lock discipline to the per…
fix(memory): extend background-maintenance lock discipline to the per…
LeXwDeX commentedon Aug 18, 2026
PR #333 三轮(cfb42e89c)——二轮 /code-review 发现的 C1 阻塞项与配套修正:
checkpointUnsafe的 kick 在 render fence 释放后无存活门,退役 identity 可烧穿两次维护模型调用,且与 CONTEXT.md:54 新不变量及自身注释矛盾。修法:存活门移入kickMaintenance内部(fence.withLiveIdentity包住原子占槽+fork,返回 Option),三处调用点统一为Option.isNone(...)→clearSession,规则单一定义。MaintenanceInput命名类型收敛 Data Clump;searchUnsafe 注释压至 5 行指向 CONTEXT.md;修正误导性 "(see checkpointUnsafe)" 交叉引用;测试 join fork 出的 prepare fiber、恢复 helper 默认超时。applyUpdate自身 fence 拒。验证:typecheck ✅;memory + memory-search 96 pass ✅;消费方 10 pass ✅;新免锁测试连跑 3 次稳定。
LeXwDeX commentedon Aug 18, 2026
第四轮双轴复审(cfb42e89c)结论——代码 ship-ready:
!due && shouldMatch时多构建一次,可忽略;Option.isNone(...)clearSession 三次出现是锁纪律惯用法非重复。)backgroundMaintain丢弃applyUpdate的 Option(退役拒提交静默结束)。测试复核:memory 44 pass、memory 全套 96 pass、消费方 15 pass。
Merge pull request #333 from LeXwDeX/fix/memory-lock-discipline
LeXwDeX commentedon Aug 18, 2026
完成:PR #333 已合并到 dev(merge commit 1d087ff)。
交付内容(dev 分支生效):
kickMaintenance单一定义,prepare/checkpoint 三处同形遗留 follow-up(不属本 issue 范围):MEM-03 剩余半(维护失败的暴露通道);
backgroundMaintain丢弃applyUpdateOption 的静默退役提交(可观测性)。见 #issuecomment-5323787153。