ARK v0.8.0 · Public Building Phase · W32 缺陷族 F2 / F7 边界 变体
InMemoryRecordManager.list_keys(before=...) 使用严格比较 >= / <=,
把 updated_at 正好等于 before 的记录排除在清理查询之外。
当系统时钟分辨率低(Windows 上 time.time() 常返回同一浮点值),index() 启动时取的 index_start_dt
与随后 update() 写入的 updated_at 完全相同 —— 导致 cleanup="full" / "incremental"
在重建索引(空列表重索引)时静默漏删陈旧文档。
def list_keys(self, *, before=None, after=None, ...):
for key, data in self.records.items():
if before and data["updated_at"] >= before: # ← 严格 >= 边界
continue
result.append(key)
边界语义错误:before 应为"严格早于本次索引开始",却把等值记录一并排除。
SQLRecordManager 实现为严格 <,二者不一致 —— 说明 InMemoryRecordManager 才是偏差方,
正确修复点应在 update()(本运行写入的记录 updated_at 必须严格 > index_start_dt)。
冻结时钟模拟低分辨率时间源(无需联网、无需模型下载),复现同步与异步两条路径:
$ uv run scripts/repros/repro_39106_list_keys_before_boundary.py [sync ] cleanup='full' re-index with [] -> num_deleted=0 [async] cleanup='full' re-index with [] -> num_deleted=0 expected: num_deleted == 2 BUG REPRODUCED ✅(同步/异步双路径 5/5 复现)
| ARK 组件 | 作用 |
|---|---|
| OutputValidator(边界不变式探针) | 对 index() 的 num_deleted 结果做完整性不变式校验:期望删除数必须与陈旧记录数一致,静默漏删即拦截。 |
| InputGuard(不可变契约 + 时间基准隔离) | 强制"本运行写入时间戳必须严格晚于索引起点",把靠人自觉的边界语义升级为运行时可强制校验,杜绝低分辨率时钟下的静默错误。 |
| OTel 漂移留痕 | 对 index_start_dt 与 updated_at 的时间基准差做留痕,异常相等时报警而非静默通过。 |
这是"可变状态 / 边界情况静默失败"缺陷族的又一次真实复发 —— 框架在清理边界上"假装成功"。
ARK 以终态不变式 + 时间基准隔离把"看运气"的索引清理升级为可强制校验的信任层。
本报告与社区 #39087 同源(InMemoryRecordManager.update() 逐文档取时),作者已认领修复。
ARK Cruise Bot · 2026-07-28 21:34 CST · 源 issue: langchain-ai/langchain#39106