Skip to content

v1.3.275

Choose a tag to compare

@topcheer topcheer released this 06 Nov 12:44
· 662 commits to main since this release

v1.3.275

发布日期:2026-11-06

本轮核心是会话索引的内存病理修复(#5149):长期运行时,每个 ggcode 实例都会把全机所有会话索引载入自己的内存,实测单实例峰值 4.8 GB,并导致后台任务被 3 GB 内存上限拒绝启动。

会话索引:内存上界与冷加载

  • 内存上界:共享索引服务引入机器级"解码字节预算"与 LRU 逐出——超出预算的索引不再整份解码进内存(此前单个 894 MB 的索引就会被完整读入),/status 暴露 decodedMb、evictedBytes、evictedIndexes 以便观察。
  • 冷加载:服务启动时不加载任何索引;第一次查询到某个 workspace 时才加载该 workspace 的索引;30 分钟无请求自动卸载回零,窗口内任意请求会重置计时。空闲时索引内存占用为 0。
  • 按 workspace 隔离:此前跨会话检索会返回其他项目的会话内容(工具说明却承诺"本 workspace")。现在归属依据 workspace 记录严格过滤,未记录归属的历史会话不会被静默混入。
  • 损坏索引降级:索引文件损坏时,该会话改为直接只读扫描源 JSONL 返回结果,而不是静默"搜不到";格式版本升级不会触发全机扫描风暴。
  • 排序契约:跨会话结果改为确定性顺序(最近活动优先,会话 ID 兜底),不再依赖 map 随机遍历顺序。
  • 生命周期:/status 不再重置空闲计时(此前健康探活会让服务永不退出);多实例同时启动时等待已有实例的索引服务就绪,而不是立刻各自全量加载。

安全加固

  • 会话 ID 校验:session_id 来自工具参数并被拼接为文件路径,现限制为安全字符集并拒绝 ../路径分隔符,杜绝越界读取。
  • 结果数上限:查询返回条数上限收紧,避免超大的 limit 参数造成无界内存分配。

验证

全量 CI 通过(Test 14 分 20 秒、CodeQL、Format 全绿);新增测试覆盖:超预算不准入、LRU 逐出与计数、刷新后懒重解码、损坏/过期索引分类、workspace 隔离与历史兼容、冷加载四态(静止为空/首查仅载本 workspace/空闲卸载/窗口重置)、路径注入拒绝、上限钳制。