Commit Graph

180 Commits

Author SHA1 Message Date
小唯 995e93598a fix(tests): 修 pre-existing 测试失配,恢复 make test 全绿 (t_8496e8b6)
四处均为本任务之前就存在的测试漂移(与优化B 无关,但让 go test ./... 无法通过):

1. selfoptimize: ae73982 给 NewGapDetector 增加了 (emb, ldb) 两个参数,
   8 处测试调用点未跟进,整包 test 构建失败。测试只用到 RecordMiss/Close/List,
   不需要真实依赖,传 nil, nil 即可。
2. integration_test.go:296 selfoptimize.NewGapDetector() 同上。
3. integration_test.go:323 InMemoryGraph.Navigate 新增 relFilter 参数,补 nil。
4. integration_test.go:339 /api/v1/triggers/fire 的夹具用了 "t1"(那是 executor
   内部编号),routes.Triggers 的真实 ID 是 t_decay/t_distill/t_merge 等,
   导致 Fire 返回 404 trigger not found。夹具改用 t_decay。

验证: go vet ./... 无输出; go test ./... -count=1 全部 ok(根包 8.1s)
2026-09-12 18:07:40 +08:00
小唯 b9107fa925 docs+test(recall): 修正批量更新注释(delta 分组,非 CASE WHEN)+ 补 IPC 只读校验用例 (t_8496e8b6)
- recall_write_buffer.go / lancedb_ipc.go: 注释与实现对齐 —— lance 不支持 CASE WHEN,
  Rust 侧按 delta 分组、每组一次 update 提交;整批版本数 = 不同 delta 的个数(通常 1 个)
- batch_ipc_integration_test.go: +TestBatchIPCScanReadOnly(只读扫 socket 校验 recall_count 真落盘)

实测(临时 sidecar,/tmp/mw-verify-180517):
  VERSION_ACCOUNTING: 批量3条 → 1 个版本 | 逐条3次 → 3 个版本
  BATCH_IPC_OK id=ep_1786982837511335732 recall_count 0 → 3
  SCAN_READONLY: 总 1814 条, recall_count>0 的 742 条, 最大 828
2026-09-12 18:07:30 +08:00
小怡 2e04adf054 perf(recall): 累积延迟更新治理写放大 — 读路径零逐条写 + 单事务批量落盘 (t_8496e8b6)
根因: recall 读路径对每条结果同步 lancedb.Update,LanceDB MVCC 每次提交=1 版本
      实测 15 版本/分钟 / _versions 17.7G(真实数据 22M)

改动:
- Go: 新增 RecallWriteBuffer(窗口合并+阈值触发+优雅退出落盘);recall.go 读路径改 Record();RustLanceDBClient.UpdateRecallBatch
- Rust: lancedb_update_batch IPC — 按 delta 分组,每组一次 update(`recall_count + delta` + id IN (...)) 提交
- 单测 6 个 + IPC 端到端版本计数测试;bench_test.go 修 NewReranker 签名失配(阻塞包测试)

实测: 批量 3 条 → 1 个版本;逐条 3 次 → 3 个版本 (lance 不支持 CASE WHEN,已按 delta 分组规避)
2026-09-12 17:57:31 +08:00
xiaowei 38c31eeede fix(recall): 笔记知识对召回不可见 —— 补搜 wiki-curator-main
问题: wiki_curator 把「笔记→知识」写进 namespace=wiki-curator-main,
而 recall 只搜 req.Namespace 与 shared ⇒ 33+ 条笔记知识长期在盲区,
用户问"笔记里的资料"永远召回不到。

改动: internal/api/routes/core.go 在 shared 补搜之后增加额外命名空间补搜
(wiki-curator-main), 去重 + 降权 0.45 (不挤掉主记忆但能被看到)。

踩坑: 初版条件写成 len(results) < req.Limit 才补搜 —— 主库记忆充足时
该条件永不成立, 补搜形同虚设。改为无条件补搜后生效。

验证: 部署后实测 recall「Hermes平台核心配置文件」→ 11 条,
含笔记知识「Hermes平台的核心配置文件包括SOUL.md、AGENTS.md…」

已知未修(预先存在, 与本次无关): selfoptimize/storage 的 bench_test.go
调用签名已变更的 NewGapDetector/NewReranker 导致 test build failed。
2026-09-11 21:22:22 +08:00
小唯 2504174a75 fix(security): 写入侧凭证过滤 — 密钥不再进记忆/图谱/Obsidian 镜像
背景(2026-09-10 mc P0 事故):某轮蒸馏把含真 Tailscale 预授权 key 的原始对话
当事实入库 → 知识图谱按其文本建实体 → ObsidianSyncer 用实体标题当文件名/正文,
把 tskey-auth-… 落成可读镜像文件,又被 git 跟踪并推送 Gitea。
本提交在三个写入边界统一加脱敏。

新增 internal/redact(唯一真源):
- SecretPattern 覆盖 sk- / tskey- / github_pat_ / ghp_ / nvapi- / AKIA
- Go RE2 不支持 lookbehind,故"前一字符是否属于更长标识符"手工判定(isTokenByte)
- sk- 段只吃 [A-Za-z0-9],避免误伤 URL 里的 task-driven 片段(事故中的假阳性来源)
- RedactSecrets 幂等;ContainsSecret 供"直接丢弃"场景用

四处接入:
- distill/quality.go       IsQualityFact 判定前脱敏 + FilterQualityFacts 返回值脱敏
- governance/graph_auto.go cleanEntityName 命中→空串;UpdateFromDistill 只对有效实体
                           建节点/建边;extractEntitiesFromText 过滤;含凭证的 fact 不建节点
- api/routes/obsidian.go   sanitizeFilename 入参脱敏 + PushToObsidian 镜像正文脱敏
- api/server.go            蒸馏直写记忆库路径(绕过 FilterQualityFacts 的那条)同步脱敏

测试:13 条新用例(redact 5 / distill 3 / governance 4 / routes 1),
含 URL 假阳性回归与幂等性断言。全部使用构造的假密钥,不含任何真实凭证。
证据:go build ./... OK;
go test -count=1 ./internal/redact/ ./internal/distill/ ./internal/governance/ ./internal/api/routes/ 全绿。

顺带修既有 test 腐化(否则 governance 包根本无法编译测试,非本任务引入):
governance_test.go isContradiction→IsContradiction、Navigate 补 relFilter 参数;
bench_test.go 同。仅测试文件,无生产行为改动。
2026-09-11 00:41:59 +08:00
小唯 e9a07cd678 fix(obsidian-sync): 文件名 slug 不再把中文替换成下划线 + rune 级截断 + 撞名消歧
根因(kanban t_5f9c56ef):ObsidianSyncer.PushToObsidian 生成的镜像文件名全废 —
sanitizeFilename() 逐个 rune 判断 "是否 ASCII",非 ASCII(含全部中文)一律替换为 _,
于是 "修复了respond重复声明问题" 变成 "____respond______.md";实测 mc vault
小唯/07-Wiki/织忆 1628 个文件 + 小唯/02-Memory 59 个文件全是这种名字,Obsidian 里无法按名浏览。

改动:
- sanitizeFilename: 只替换文件系统非法字符(/ \ : * ? " < > | 控制符等),
  保留 Unicode 字母/数字(中文正常入名);连续非法字符折叠成一个 _;trim 首尾 " ._-"
- 去掉 content[:30] 的字节切片(会把多字节字符切半个 → 乱码),改用 truncateRunes()
- truncate() 从字节计数改为 rune 计数(H1 标题行同样会被切出乱码)
- 撞名消歧:同一批推送里 base 重名时补 8 位内容哈希后缀,不再静默互相覆盖
- 删除已无用的 minz()

顺带修复(原本就让整个 routes 包测试编译不过,不修则无法验证):
- routes_test.go: selfoptimize.NewGapDetector() 缺参 → (nil, nil)
- routes_test.go: 删掉引用已移除的 SSEBus/SSEMessage/PushMemoryCommitted/PushGapFound 的用例,
  改为按当前 WebSocket API 验证全部 Push* helper 不 panic
- routes_test.go: TestTriggers_List 期望 4 → 8(triggers.go 实际注册 8 个)

验证:go build ./... 通过;go vet ./internal/api/routes/ 通过;
go test ./internal/api/routes/ 全绿(此前 build failed)。
新增 obsidian_test.go 锁死回归:中文标题不得出现连续下划线、截断结果必须合法 UTF-8、同名不覆盖。
实际落盘文件名样例:
  LanceDB 已设天花板_不会再膨胀到 35G.md / 修复了 respond 重复声明问题.md /
  同一段开头的内容 abcdefghijklmnopqrstu.md / 同一段开头的内容 abcdefghijklmnopqrstu-4bad72a0.md

⚠️ 未部署:需重建 /home/muc/bin/zhiyid-new 并重启 zhiyid.service 才生效(另开任务卡跟踪)。
2026-09-10 23:15:01 +08:00
小唯 3872294045 fix(graph-cleanup): CleanupNoiseNodes NULL-id panic + 新增 scoped 卫安/A03/A04 测试污染清理端点 (t_1dfaaa4a)
- graph_sqlite.go CleanupNoiseNodes: row[id] 为 NULL(daemon-distill pattern 模板行)时直接
  .(string) panic → HTTP 连接被关(HTTP=000);改为 nil 安全跳过
- 新增 CleanupScopedNodes(dryRun, namespaces, nameContains):namespace+名称子串精确圈定,
  清理 2026-06 多 agent 测试污染(openclaw-main/a06-main/hermes-main 的 A03/A04/卫安 节点)
- graph_cache.go: cachedGraphStore 透传(inner 可选接口断言,非 SQLite 后端静默 0)
- server.go: GET/POST /api/v1/graph/cleanup/scoped?dry_run=&namespace=&name=
  实际执行后 InvalidateAll 保证 graph_cache 一致性 —— 禁外部 SQL 的官方通道
2026-09-08 09:02:35 +08:00
小唯 4714efaab9 fix(distill-quality): 严格质量门槛 1b (t_cc07ef4b) — <20字/纯疑问句/状态汇报拒绝; 20-50需实体或动词
方案B 严格版(替代 946f0c9 宽松版): quality.go IsQualityFact 重写
- <20字一律拒绝(无用户信号豁免, 与质量看门狗 FRAG_LEN=20 对齐 → AC-2 碎片率<10%)
- 纯疑问句拒绝(带?/?、疑问前缀+吗呢么、无陈述主语短问句)
- 状态汇报型拒绝(无主状态句/健康检查/桥接/reflection/完成重启类)
- 20-50字需含实体(织忆/hermes/牧尘/大写词/数字)或动词短语才入库
engine.go: distillOne 源头过滤(图谱/AAAK/记忆库同源干净) + fallbackSingle 过滤
server.go 写回 IsQualityFact 双保险(同一函数自动变严格)

单测 quality_test.go + quality_engine_test.go (mock LLM 短对话episode → 0碎片入库)
AC-1 dev 验证: 构造含短对话episodes → 蒸馏后碎片不入库 
2026-09-07 21:50:37 +08:00
xiaowei 4130e6b668 feat(memory-quality): 方案B写时质量门槛+方案C provenance 标注
方案B: distill 结果写 memories 前 IsQualityFact 过滤(碎片<8字拒/8-20字需用户信号/噪声前缀拦)+完全重复查重跳过
  - quality.go: 与 LightMem 保留细节哲学兼容(咖啡偏好保留), 拦进程噪声/桥接/reflection
  - 单测 8/8 通过
方案C: distill MemoryRecord 标 Source=llm_distill(provenance); volatile_flag 降权已确认生效(×0.5)
  - ContentMD5/VersionHistory 字段已在, bi-temporal valid_to 加列缓行(风险高)
2026-09-07 21:50:37 +08:00
xiaowei a5b5e217f3 fix(forgetting): 遗忘机制方案A — 碎片快速道+episodes/长内容保护+stats修正
- governance.go: recall加成 0.05→0.005(防 recall_count 500+ 虚高保命); decayRate 试 0.03 误删长内容后回滚 0.015
- server.go decay: 碎片快速道(<30字&>20天→auto_forget_fragment); episodes 不参与遗忘(曾误删67条对话已恢复); >200字长记忆保护
- admin.go Forget: 同步三保护
- rust lancedb_ops.rs: tombstone_count 数 is_deleted=true(移植 f6c4383+类型修)

验证: admin forget 触发 tombstone 0→210(碎片清除); episodes/长内容 0 误删; stats 真实计数
2026-09-07 21:50:37 +08:00
小唯 1bf23c42e8 fix(stats): count_rows filter 类型修正 Option<&str> -> Option<String>
f6c4383 的 count_rows(Some("is_deleted = true")) 编译失败(E0308: 此 lance 版本
签名 Option<String>)。修正为 .to_string()。实测 stats tombstone_count=830
(memories 表 is_deleted=true 行数, 之前恒 0)。
2026-09-06 09:25:27 +08:00
小唯 f6c4383f98 fix(stats): tombstone_count 统计源修正 — 数 memories is_deleted=true 行
SoftDelete 持久化语义 = memories 表内标记 is_deleted=true(不写独立 tombstones 表),
但 Rust stats() 的 tombstone_count 数的是空 tombstones 表 → 恒 0(指标失真)。
修正:stats() 对 memories 表 count_rows(Some("is_deleted = true")) 作为 tombstone_count。
验证: DELETE 一条记忆后 stats tombstone_count 应 >0。
2026-09-06 09:22:49 +08:00
xiaowei f6cd93fbd7 fix(forgetting): P2 候选源升级 — Rust scan 全表替代纯缓存遍历
GetCandidatesForForgetting 原实现只遍历进程内 _local.memories 缓存
(commit/recall/search 才触碰), 重启后缓存空 → decay scanned=3 扫不全,
9-25 到期记忆若不在缓存则永远无法被遗忘(闭环断)。

安全版 scan_for_forgetting (防 febc2c9 风暴复发):
- 强制 limit (IPC 钳制硬上限 5000, decay 侧 2000)
- 不读 vector 列 (1024维×3000条≈12MB+, IPC JSON 会卡)
- 真读 last_recalled_at 列 (scan_all 旧实现 String::new() 恒空 → 遗忘判定失真)
- 消费方截断护栏已就位 (merge 桶500 / conflict 500 / sanity 1000)
- IPC 失败/空 → fallback 缓存遍历 (保持可用)

验证: [decay] scanned=3 → 2000 (重启即扫全表), CPU 0%, 无 panic
2026-09-06 02:32:58 +08:00
xiaowei 6c1c21fadf perf(pagerank): O(V+E) 累加实现替代 O(V²) 全源遍历
旧实现每目标节点遍历全部源节点找边匹配 (943-961):
- 17628 nodes × 20 迭代 = 6.2亿次内层操作 → 单次 PageRank ~3 分钟
- 重启后多套触发器零值连锁 fire full consolidation → CPU 100% 持续 10+ 分钟

新实现先归一化每源节点总权重, 再沿出边把贡献累加到目标 (O(V+E)):
- 17628 nodes PageRank + 图谱维护: 3分钟 → <1 秒
- 重启风暴从 10+ 分钟 CPU 100% → 秒级无感

实测: 01:16:40 图谱维护开始 → 01:16:41 PageRank 更新 17628 nodes 完成
2026-09-06 01:20:21 +08:00
xiaowei e67f0bc7a6 fix(recall): Embedder http client 8s 超时 + decay 分批 AC-1 日志
- Embedder http.Client{} 无超时 → 远端 bge 半开 TCP 时 recall 永久挂起
  (gateway 10s 断 → 织忆异常误报)。加 8s 超时快速失败降级。
- decay 每 tick 限量 2000 条(最久未访问优先) + scanned/forgotten 日志
  (AC-1 验收证据)
2026-09-06 01:08:42 +08:00
xiaowei 4376f1f2ce fix(forgetting): P1 防风暴 - 限长/分桶/抽样下推/decay分批
febc2c9 全表扫描 O(n²) 风暴的根治防护(生产基线 506f76b+ 之上,不含 febc2c9 扫描代码):

1. mergeSimilar 按 category 分桶 + 单桶 maxMergePerBucket=500 截断
   - 原双层循环全量 O(n²),全表时触发 620% CPU
   - 分桶后 O(Σ桶²) << O(n²),语义不变(原 catI!=catJ continue 等价分桶)
2. scanConflicts 显式 created_at 倒序取最近 500 条
   - 原注释'最近100条'实际全量 O(n·50)
3. checkTimestampSanity 先截断 maxSanitySample=1000 再均匀抽样
   - 原全量拉取仅为 5% 抽样
4. decay 每 tick 限量 maxDecayBatch=2000,按最久未访问优先
5. 存储层输出契约统一 RFC3339 string + 补 category/created_at
   - lancedb_ipc: last_recalled_at 此前直接放 time.Time → server.go .(string)
     断言恒失败 → lastAccessed 永远默认30天前 → 遗忘判定失真(本 bug + 数据
     年龄未到 = 遗忘从不触发的双根因之一)
   - sqlite: 补 category/created_at + LIMIT 100→200(对齐 lancedb 契约)
   - 新增 memoryTimeVal/fmtTimeRFC3339 helper 兼容多类型

测试: go build ./... 全绿;gofmt 仅历史文件遗留(未全文件重排,保持最小 diff)
2026-09-06 00:56:06 +08:00
小唯 4c62074a61 fix(consolidate): 按目标分组批量LLM决策,消除O(n²)调用风暴
原实现每对高相似记忆调一次LLM → limit=100产生4950对 → 223s+未完成
→ 每天processed=0(非namespace过滤bug)。改为: 外层目标i,内层收集
全部高相似候选,每目标一次LLM(UpdatePrompt原生支持多候选)。

验证: limit=20 → 4.3s返回 processed=1 updated=1; limit=100 2min(受
llama单slot排队限制)对每日低频可用。
2026-09-06 00:32:27 +08:00
小唯 0881b9c05f fix(softdelete): 单独应用 SoftDelete 持久化修复(506f76b+SoftDelete only, 不含 lancedb_scan 风暴代码)
febc2c9 提取仅 SoftDelete 部分: updateField 提升包级 + SoftDelete 调
lancedb_update 持久化 is_deleted=true。跳过 GetCandidatesForForgetting 全表
扫描改动(有 620% CPU 风暴 bug, 待修复后另部署)。

验证: DELETE scratch2-1788616361067 → [ipc]SoftDelete persisted → 查询0条
→ 重启后仍0条(持久化成功)。
2026-09-06 00:23:23 +08:00
xiaowei 506f76bd00 fix(hermes-plugin): memory_feedback 闭环 — prefetch/memory_search 输出带 memory_id,system prompt 引导标记有用/无用 2026-09-05 21:44:08 +08:00
xiaowei 8356480541 fix(consolidate): eps 1.0->0.4 修复 DBSCAN 聚类失效 (clusters=1->34)
根因: bge-m3 向量已归一化(norm=1.0, 距离 p50=0.42-0.75), 旧 eps=1.0 按未归一化数据(p50=1.029)调试,
在归一化空间过大 -> 全部连成1簇 -> consolidate 空转多日 (clusters=1 error 每15min刷)

实测: eps=0.4 -> clusters=34 noise=1030, 能发现重复状态噪音簇(1045条主profile状态同步/961条CBM状态)
2026-09-05 18:13:53 +08:00
xiaowei 28a3d4f6b8 fix(hermes-plugin): 在正本基础上加 conflicts 解析(保留 prefetch/social 功能,勿用部署副本整体覆盖)
前一版 6fa2d9b 误用旧部署副本覆盖正本(41469B→35801B),丢了 _is_social_close/_prefetch_cache/prefetch()。已恢复正本(checkout HEAD~1)后重新应用:
- ZhiYiClient.__init__ 加 _last_conflicts
- commit() 成功时捕获 conflicts
- _tool_memory_write 检出冲突返回 warning(不静默)
2026-09-04 01:35:31 +08:00
xiaowei 6fa2d9b892 fix(hermes-plugin): commit 解析 conflicts 字段返回 warning(同步部署副本 d520a9091)
zhiyid DetectContradiction 检出矛盾后 conflicts 只放响应,插件 commit() 只取 id 忽略
→ 冲突记忆静默进 episodes→蒸馏→污染长期记忆
现在:_last_conflicts 记录 + _tool_memory_write 返回 conflicts/warning 给 agent 感知
2026-09-04 01:33:41 +08:00
xiaowei 63f123417b fix(distill): commit 检出冲突时不进自动蒸馏(conflict guard)
问题:commit 的 DetectContradiction 检出矛盾后只返回 conflicts 字段,
内容仍进 episodes→自动蒸馏→污染 distilled/memories(TencentDB 误判案例根因链一环)

修复:conflicts>0 时跳过 AutoDistillTrigger,返回 distill_skipped=conflict;
处理路径:①写错→feedback not_useful;②旧记忆错→feedback 降权;
③确认为修正→resolve_conflict=true 重 commit(待客户端支持)

验证:commit 矛盾内容 → conflicts 返回 + distill_skipped=conflict 
2026-09-04 01:29:11 +08:00
xiaowei ae73982743 fix(distill): max_tokens 800→1200 — Agnes推理token预算不足
Agnes 2.0-flash是推理模型,推理token占大量预算。
800仍不够→JSON截断(parse error: unexpected end of JSON input)。
1200确保推理+正文都够用。
2026-08-20 01:13:06 +08:00
xiaowei ea4b5a4dfe fix(distill): max_tokens 600→800 — Agnes推理模型JSON不再截断
engine.go: max_tokens 600→800
consolidate.go: max_tokens 300→800
根因: Agnes 2.0-flash是推理模型,max_tokens=600里大量是推理token,
正文只剩~300→JSON截断→parse error→蒸馏退化。
800确保推理+正文都够用。
2026-08-20 00:10:51 +08:00
小唯 38701748d1 feat(distill): P4 AAAK压缩索引 + P5 Markdown导出层
P4: 借鉴 mempalace AAAK dialect — 每条事实生成紧凑索引(实体|关键词|权重|类型)
P5: 借鉴 EverOS md真相层 — /api/v1/memories/export 导出人可读 Markdown
2026-08-12 01:37:27 +08:00
小唯 82c3d25423 feat(distill): P2 离线整合(UPDATE_PROMPT) + P3 双缓冲(token积累) + JSON健壮剥离修复
- P2: consolidate.go 新增 ConsolidateMemory + TextSimilarity,LLM三选一(update/delete/ignore)合并相似记忆
- P2: server.go 新增 POST /api/v1/consolidate/memory 手动触发端点
- P3: engine.go Enqueue 按 token 积累触发 flush(阈值2000),batchTimeout兜底
- fix: LLM JSON 剥离增强(找首个{和最后}截取),修复模型返回markdown/注释导致的parse error
2026-08-11 21:38:10 +08:00
小唯 0734ffaa5a feat(distill): LightMem式逐条事实提取 prompt(P1)— 从整段摘要升级为逐条独立事实,保留全部实体细节+时间区分+推断隐含信息 2026-08-11 17:51:08 +08:00
小唯 11162e2f60 fix: consolidation 风暴 — distill cooldown 60s→15min, cluster_only 跳过 PageRank
- triggers.go: TriggerDistill cooldown time.Minute → 15 * time.Minute
- consolidation_pipe.go: runGraphMaintenance 仅 full 模式执行(cluster_only 高频快速聚类跳过重负载 PageRank)
- 修复 zhiyid CPU 80-90% 风暴、recall API 120s+ 超时

根因:t_distill 每 60s 触发全量 DBSCAN + PageRank(10356 nodes),数据量大时单次 30-60s CPU 堆积
2026-08-10 01:21:57 +08:00
xiaowei 98e541b985 fix: distill LLM 模型切换 gemma-4-31b-it + JSON 解析增强
根因链:
1. gpt-oss-120b 是 reasoning 模型,content=null 答案全在 reasoning 字段,
   代码只读 content/reasoning_content(OpenAI 用 reasoning 字段名)→ parse 失败
   → 永远降级 keyword 提取 (facts=1 entities=0)
2. skill 记载的 m3/m2.7/mistral-large 均已 EOL 或渠道失效 (2026-07-27 后)
3. gemma-4-31b-it 对 '0.X' 占位符输出 0.0 → prompt 改为明确 0-1 浮点说明

修复:
- engine.go: 支持 reasoning 字段 + 剥离 markdown code fence + prompt 评分说明明确化
- zhiyid.service: LLM_MODEL=google/gemma-4-31b-it

验证: LLM entities=2, overall=1.000, facts=3 entities=2, recall 命中 0.765
2026-08-02 23:59:29 +08:00
xiaowei 21bc777430 fix: episodes 持久化到 LanceDB(重启不再清零)
根因: RustLanceDBClient.InsertEpisode 只写进程内存 _local.episodes,
从未持久化;Stats 的 total_episodes 用内存值覆盖 Rust 真实计数。

修复:
- InsertEpisode 增加 IPC 写入 LanceDB episodes 表(24 字段完整 schema)
- Stats 优先用 Rust sidecar 返回的 episodes 计数,缺失才回退内存
- 持久化失败只记日志不阻断请求(保持'总是写入'语义)

验证: 提交测试 episode → stats episodes=1 → 重启 zhiyid → 仍为 1
历史 45 条内存 episodes 已随重启丢失(原始日志,蒸馏结果在 memories 5063 条保留)
2026-08-02 23:41:37 +08:00
小唯 6f9361f4e9 docs: 更新 README — 4个项目关系图 + TencentDB + Soulful 2026-07-20 15:58:54 +08:00
小唯 4e17b8cb98 docs: 说明与 xiaowei-system 的关系和安装顺序
- 明确织忆是底层基础设施,xiaowei-system 是上层应用
- 安装顺序:先织忆,再小唯系统
- 加 API 调用示例
2026-07-20 15:50:07 +08:00
小唯 c4d17df71c fix: Phase D/G/H 编译修复
- governance.go: 加 PendingCount() 方法给 ConflictsPending metrics
- distill/: 删 consolidation.go(死代码,231行无引用)
- scripts/: backup.sh 加7天保留策略 + restore.sh 恢复脚本
2026-07-10 05:10:12 +08:00
小唯 d524fd741b docs: 分身速通卡(rag-skill集成+100%自动化管道说明) 2026-07-08 15:20:47 +08:00
小唯 707903dee7 docs: 织忆v3.9+rag-skill 项目复盘报告(全自动化管道产出) 2026-07-08 12:58:14 +08:00
小唯 1970fb4f06 feat: 织忆+rag-skill深度检索模式 + 07-Wiki全目录索引
Phase 3: Hermes 插件深度检索
- prefetch() 新增 depth='deep' 参数
- depth=deep: 织忆语义搜索后,异步触发本地文件渐进检索
- 结果标记 [rag-skill File — local Wiki evidence]
- 缓存 TTL 60s,支持双轮(第一轮触发,第二轮拿缓存)
- depth='fast' 默认行为完全不变

Phase 4: 07-Wiki 目录索引补全
- docs/07-Wiki-index/: 织忆同步(1039files)、织忆图谱(299files)、经证同步(29files)
- docs/memory-index/: 记忆顶层 + 织忆进度快照
2026-07-08 12:42:17 +08:00
小唯 25a1bb52dc docs: 织忆系统功能用法说明(v3.9全功能速查) 2026-07-08 12:26:49 +08:00
小唯 25151bfda2 fix: three-way-check.sh — add X-API-Key to zhiyid endpoint check, replace *** placeholder 2026-07-08 12:26:28 +08:00
小唯 8ca3ca0497 feat: 织忆系统全面推 Gitea v3.9
新增:
- cli-anything/ — 命令行伴侣
- docs/ — v3.8设计文档、v3.9 rag-skill补充设计、实施计划、进度快照、data_structure.md索引
- skills/ — zhiyi技能(SKILL.md+scripts+references)、rag-progressive-search渐进检索技能
- scripts/ — 更新wiki_curator.py(中文版)、新增three-way-check.sh、verify-gitea-deploy.sh

变更:
- scripts/wiki_curator.py — 更新为中文说明版
- README.md — 已完成(ca37de9)

功能覆盖:
- P0 Recall降级策略 / P1 自动注入 / P2 信任评分
- P3 CREATIVE.md / P4 Ground Truth / P5 Wiki策展
- H1 BM25融合 / H2 LLM策展 / H3自动信任 / H4 diversity / H5三模式 / H6多级存储
- rag-skill渐进式检索集成(分层索引+渐进检索+先学再做)
2026-07-08 12:24:39 +08:00
小唯 ca37de93b6 docs: 重写 README.md — 完整项目说明(架构图/特性清单/API速查表/目录结构) 2026-07-08 12:23:56 +08:00
小唯 51aa9de939 fix: robust auto-start after reboot
- Moved bge_embed_server.py to ~/.hermes/scripts/ (persistent)
- Moved Rust sidecar binary to ~/bin/zhiyi-consolidate (persistent)
- zhiyid.service: After=zhiyi-consolidate bge-embed (start ordering)
- All services: enabled + Linger=yes → auto-start on boot
- ExecStartPre fallback: re-copy from Gitea clone if file missing
2026-07-02 01:05:24 +08:00
小唯 c86f5bc304 fix: NewAPI key strip sk- prefix + LLM wiki graceful fallback 2026-07-02 01:00:23 +08:00
小唯 57ac628b3f fix: H1-H6 gaps all resolved
H1: BM25 keyword scoring in recall pipeline (0.7 vector + 0.3 keyword)
H2: LLM wiki curation mode (--llm flag, graceful heuristic fallback)
H3: Auto trust score update after each recall call
H4: Default diversity=0.3 (was 0 = no diversity)
H5: Three search modes: hybrid(semantic+BM25) / keyword / semantic
H6: Multi-tier fallback already covered by P0 + SQLiteClient

All verified: hybrid(0.962), keyword(1.000), semantic(0.962)
2026-07-02 00:43:46 +08:00
小唯 db3d3d8e85 docs: P3-P5 implementation plans + skill update 2026-07-02 00:30:43 +08:00
小唯 7fabc58bf3 feat: P3 CREATIVE.md isolation + P4 Ground Truth prompt + P5 Wiki curator
P3: Created ~/.hermes/CREATIVE.md for 织忆 working memory.
Updated plugin system_prompt_block() to load CREATIVE.md as [织忆 工作记忆].

P4: Added Ground Truth hierarchy (4 levels), Context injection convention,
and Memory feedback rule to SOUL.md. Injected [织忆] memory now
explicitly takes priority level 2.

P5: Created wiki_curator.py — scans .md files, extracts concepts/entities/
relations via heuristic, writes to 织忆 via /commit + /graph/edge APIs.
Includes dry-run, force, state tracking, skip rules.
2026-07-02 00:29:47 +08:00
小唯 f4313a40ef docs: add implementation plans for P0/P1/P2 features 2026-07-02 00:23:04 +08:00
小唯 5e24646600 feat: P1 auto-injection hook with social close detection
- queue_prefetch now caches next-turn recall results asynchronously
- Social closer detection skips trivial messages (ok, thanks, emoji)
- prefetch uses cached queue results when available (TTL 30s)
- Output header changed to [织忆 Memory] for source clarity
2026-07-02 00:22:43 +08:00
小唯 72cbf73583 feat: P0 recall fallback + P2 trust scoring for graph edges
P0: When bge-embed/IPC recall fails, fall back to graph.db keyword search (FallbackTextSearch) instead of 500 error. Response includes X-Fallback: graph header.

P2: Add trust_score, retrieval_count, helpful_count columns to graph_edges table. New POST /api/v1/graph/edge/feedback endpoint. UpdateEdgeTrustScores batch calculation.
2026-07-02 00:22:28 +08:00
小唯 fa0eb004a8 docs: add Memory-OS 7-layer comparison with source code analysis (2026-07-01) 2026-07-01 23:53:34 +08:00