归档存储结构补齐:collection+分条化写入/读取API #166
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/156-archive-collection-split"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #156
实现内容
issue #156(ADR-0009"归档拆分",issue #108 grill Q6 拍板"现在实现")实现期核实:
arise_archive_collection自代码写下第一天起(2026-07-08 引入)就只是占位名字,从未被创建、写入、召回过——不是"episodic 与 archive 混同一 collection 需要拆分",而是"archive 这条存储路径要从零建"。ADR-0009"背景"节描述的"归档器把 ~60 条原文拼成单 blob 整块召回"是立项前研究对照的旧 dxkuma 实现缺陷,不是本仓库自己的历史状态。新增
archive.py模块(仿events.py/skill.py先例):ArchiveCandidate(写入前)/ArchiveEntry(已落盘)——刻意不带sensitive/source_ctx字段,理由:产出方结构上永远没有 LLM 分类信号可用(触发条件本身就是 LLM 调用失败),"按 chat_id(+ 知情 sender 私聊)收窄、不存在非敏感→全局可见分支"是这个 collection 的结构性不变量,不是某条记录的可选属性。用一个恒为True的字段反而是死列反模式。ArchiveStoragePort:write_archive(chat_id, entries: list[tuple[ArchiveCandidate, list[float]]]) -> list[ArchiveEntry](对齐search_events/resolve_similar_skill的元组配对先例)+get_archive_entries(chat_id) -> list[ArchiveEntry](对齐get_knowledge(chat_id)先例)PersistentStorage(Qdrant 实现)+SentLog(内存测试实现)两侧补齐,ensure_vector_schema新增第 4 个 collectionArchiveCandidate= 1 个独立 Qdrant point),不做任何跨条聚合范围调整
本票只交付存储结构(collection + 分条化写入/读取 API),不接入三因子/四因子召回的打分/排序逻辑——在没有真实产出方之前接召回是没有产出方可验证的死代码。真正触发写入的产出方(delta 压缩连续失败→整批转存低置信度记录的降级路径,ADR-0009 2026-07-08 更新节设计、2026-07-30 更新节确认"没有实现",需要新增跨重启失败计数机制)拆到独立的 issue #165。CONTEXT.md/design.md/ADR-0009 已同步标注这一范围调整。
两轴 review 修复
get_archive_entries单次scroll(limit=1000)会在 chat 归档超过 1000 条时静默截断,与ArchiveStoragePortdocstring 承诺的"取回该 chat 已归档的全部条目"矛盾(不像list_skills()有get_skill(id)式的补偿读法,archive 是唯一读接口)——已改成基于next_page_offset的真分页,并补了 1001 条条目的回归测试验证。测试
全部 1948 个测试通过(含 14 条新增的 archive 存储测试,双参数化覆盖
SentLog/PersistentStorage两侧实现);ruff check/lint-imports/ty check干净。新增逻辑(chat_id 隔离、id 唯一性、1:1 分条化、分页读取)均做过 mutation testing 确认能被现有测试捕获。(
test_debounce_e2e.py里一条撤回通知相关用例在全量跑时出现过一次失败,单独重跑和第二次全量重跑均通过——是与本票改动无关的既有时序型 flaky 测试,不是回归。)