Skip to content

Releases: monkey2jack/aiduMEI

v20.2

Choose a tag to compare

@monkey2jack monkey2jack released this 26 Aug 04:41

aiduMEI v20.2 — 智慧引擎自动挡(Wisdom Engine Autoshift)

一台引擎,两种动力,自动换挡 —— 外部服务失效时自动降挡、无感续跑;恢复时自动升挡、欠账回补;挡位永远诚实可见。这是 v20 代主题「确定性兜底与诚实召回」的完成式。

双引擎

☁️ 云挡(Full) 🔋 备胎挡(Lite)
动力 LLM 蒸馏 + 云端嵌入 纯本地 ONNX 嵌入(512 维)+ 确定性抽取 + 提取式整合
成本 正常计费 零 token · 零网络 · 零外部依赖

自动挡四件套

  • 本地嵌入备胎ducky/local_embed.py):fastembed/ONNX,运行时强制离线(备胎不许伸手要网),模型部署期就位(支持离线拷入);可选依赖组 local-embed
  • 双索引与欠账回补ducky/dual_index.py):本地 collection 与云库同源 id,删除链一把钥匙开两把锁;降挡期的 LLM 蒸馏进欠账账本,恢复后自动重放,一条不丢——欠着的债也是债,删除承诺同样覆盖它。
  • 熔断切换器ducky/gear.py):三态熔断;半开探测拿真实流量试探(不试探则成功信号永不来);云腿当场失败时同一次请求内落到本地腿——无感顺滑到单次查询。
  • 挡位诚实化/search 响应带 engine_mode(按本次实际用的腿)、lite 分数口径注记;升降挡进事件账本;/health 五组挡位探针。

生产实弹验证

断供演练在真实生产环境两轮全链验证:封锁嵌入端点 → 三连失败自动降挡 → 断供期写入照落且语义可召回(vector_leg=local 实证)→ 恢复自动升挡 → 蒸馏欠账消化归零。存量 1592 条记忆已全量回填本地索引——降挡时不失明。

诚实标注

lite 是保命档不是平替:20 条真实查询对照,本地小模型与云模型 top5 排序重叠约 9%。断供时搜得到该搜到的,排序品质明写不如云挡。

测试

用例总数 1270,全部十一条跳过轴齐备下 1270 全绿 · 0 跳过(生产机候选树实测)。本轮无外审,质量由对抗性自审承担——自审抓获并修复两项真缺陷(欠账重放与删除的竞态;测试替身实现了新版 qdrant-client 已移除的 API 造成的假绿灯)。

完整变更见 CHANGELOG.md

v20.1

Choose a tag to compare

@monkey2jack monkey2jack released this 25 Aug 23:41

aiduMEI v20.1 — 确定性兜底与诚实召回

主题一句话:LLM 不在场时,记忆系统仍然是完整的记忆系统;召回给不出可信结果时,宁可诚实说「没有」。

四个工作包

  • WP-A 确定性抽取层ducky/pattern_extract.py):纯规则的第二事实来源——零模型、零网络、零 token、同输入逐字节同输出。七类硬事实(日期时间/版本/数字单位/链接/键值/指令/偏好)挂在 /add 路由层,LLM 空抽取时硬事实不再丢失;产物按来源标记,回滚 = 按来源精确清除。
  • WP-B 无 LLM 整合升级ducky/refine_memory.py):降级链两档改三档 llm → extractive → rule。提取式档做值包含去重 + 硬实体优先 + 显式截断标注——LLM 关闭时 20 条记忆不再只换来一句目录。
  • WP-C 召回弃答信号ducky/hot/search.py):/search 响应新增三态判语 recall_verdict ∈ {found, not_found, degraded}。判定顺序即契约:故障先于缺失——嵌入服务挂了产生的空结果判 degraded,绝不冒充「查无此忆」。低分判 not_found 时结果照常返回(判语不越权丢数据)。置信下限 AIDUMEI_RECALL_VERDICT_THRESHOLD 默认 0.0,校准属部署决策(建议按真实查询分布取分位数)。
  • WP-D 核心记忆还账ducky/core_memory.py):核心块写路径同步进向量召回池(payload 对齐装配契约、reliability=1.0、确定性点位 id);陈旧告警按块分级(画像/决策 180 天 · 当前项目 30 天,依据既有分层 TTL 语义)——分级是给依据,不是调大消音。

外部评审与整改闭环

发布前经五份外部评审(四位受邀评审 + 一位社区审计),收敛出 17 项整改(R-01~R-17)全部闭合,要点:

  • 删除链收口cascade_delete_all 补清 workspace 热缓存、核心记忆正本、精炼产物、墓碑全文快照、治理候选五本账;新增 DELETE_CHAIN_MATRIX 覆盖矩阵——每张账本必须持显式 clean/exempt 裁决,元守卫枚举 sqlite_master,新账本出现而矩阵沉默即测试红。
  • 三副本对账audit_core_replicas 以正本为基准核对 FTS 与向量副本在场性,结果进 /health
  • 写入→召回契约测试:fake-embedder 真余弦 + 过滤语义走真端点真引擎,变异探针双向证明区分力。
  • 跨平台:资源探针在非 POSIX 平台诚实置 None 不崩;缺 mem0 基座由 20 条 ERROR 改为诚实跳过(登记为第十条跳过轴)。

测试

用例总数 1232:独立开发机 1220 通过 · 12 跳过(实测);全轴齐备 1232 全绿 · 0 跳过(2026-08-26 十轴实测)。平台前提:全量套件按 Linux/macOS(POSIX)口径维护。

完整变更见 CHANGELOG.md

v20.0

Choose a tag to compare

@monkey2jack monkey2jack released this 24 Aug 15:58

架构版。 版本号自本版起回归两段式,运行时不再设神话代号 —— 诸神留在谱系里作历史。

这一版修的是什么

v19 之前,「这条记忆属于谁、属于哪个领域」是靠 source / agent_id 这类渠道标记兼职表达的。但渠道不是所有权。两个互不相干的记忆域一旦撞上同一个键,后写的直接盖掉先写的 —— 两边都不报错,没有任何日志,没有任何计数会变。

v20 把作用域从一种约定变成一份契约:写、查、删、恢复、统计、反馈、后台任务、事件账本、毕业链、人格画像,每一条在线读写路径都必须显式说出自己在哪个域上工作,说不出来的在取数之前就抛错,绝不静默降级成全库扫描。

迁移全程 additive:存量数据一行未改、一行未删,老数据一律落 default 域,键的形状与 v19 逐字相同。

三块主要变化

内容
记忆域隔离 新增 ducky/bank_contract.py 确立 (user_id, bank_id) 二维作用域契约;观测面(/health/metrics/search trace)补齐域 / 后端 / 降级证据 —— 组件故障一律进 degraded,不许伪装成空结果(「没搜到」和「搜挂了」长得一模一样,是这个项目反复付过学费的失败形态)
可复现评测 新增 benchmarks/:数据集、模型、judge、prompt、seed、文件哈希全部锁死留证,适配器走真实 HTTP 契约而不是进程内捷径 —— 否则测的是自己的函数,不是这个服务
最小权限 systemd 单元与容器镜像不再默认以 root 运行。生产实机前后对照(都由 systemd-analyze 自己算):暴露分 9.6 UNSAFE → 1.7 OK,capability 41 项 → 0 项

关于跑分

本版未跑分,因此不宣称任何分数。 评测协议已就位,我们也在积极准备自己的跑分,像其他友商一样努力 —— 区别在于我们打算连复现方法一起交出去:公布分数的那天,你拿同一份协议应该能跑出同一个数。

读别人的数字时请注意口径:Recall@k(答案在前 k 条里吗)与端到端问答准确率不是同一个指标,公开资料里两者常差 30 个点以上。

测试

环境 结果
独立开发机(无宿主源码) 1099 passed · 12 skipped
生产实机(九条跳过轴全部齐备) 1111 passed · 0 skipped

用例总数 1111。「全轴齐备 1111 全绿」这个数字此前是推导值,本版首次实测(2026-08-24)。

升级

存量数据零改动,直接替换代码即可。若使用随附的 systemd 模板,降权需要先建账号并交接数据目录 —— 顺序颠倒会导致服务起不来,前置步骤写在 deploy/aidumem-api.service 的注释里,请先读那一段。

完整变更见 CHANGELOG.md

v19.5.0

Choose a tag to compare

@monkey2jack monkey2jack released this 20 Aug 00:31

v19.5.0 — 脱敏闸门 · 把铁律变成不可绕过的程序

定性:纪律版。 不改任何运行时行为,改的是「什么情况下才允许发布」。

为什么有这一版

前两轮连续栽在同一件事上:脱敏做了,但做没做到位,全靠人的记性和自觉。写在文档里的铁律,人会漏;漏了以后没有任何东西会红。

更麻烦的是,这类工具的失败是沉默的——词表少配一个词,扫描照跑、报告全绿、脏包上了公开索引,事后才发现。它不报错、不崩溃,只是安静地发放一张「已经检查过了」的凭证。

一个坏掉的扫描器和一个干净的项目,报出来的东西一模一样:都是「0」。

所以这一版真正要解决的问题不是「能不能扫出来」,而是 「当扫描器坏掉时,它会不会老老实实地失败」

做了什么

变更 说明
新增 scripts/release_scan.py 七面敏感内容扫描器。词表外置于仓库之外,模块内无任何内置词表兜底;词表为空或缺失一律拒绝运行(退出码 2)
新增 tests/test_release_hygiene.py 20 条守卫盯着闸门本身。核心是把扫描逻辑打坏成瞎子(什么都不报)、疯子(什么都报)、漏勺(豁免溢出全文件),自检必须每种都抓到
负向对照焊进代码 每次真扫前先在合成样本上三向验证;任一不符即退出码 3,整轮结果作废
公开面六面升七面 新增「⑥ 包索引渲染面」——元数据渲染出的项目网页,不下载就能看见
豁免机制收窄 只认命中所在的那一行,无文件级、更无目录级豁免;且豁免仍逐条出现在报告里:从失败计数里消失,不从视野里消失
scripts/backup_gate.sh 备份根默认值不再写死任何部署环境绝对路径,改为相对仓库根目录

闸门第一次真扫,就抓到了它自己

首版 main() 用「不以 - 开头就是目录」挑扫描目标,于是 --name X选项名被丢掉、值 X 被当成目录——而 X 并不存在,扫出 0 个文件,报告照样打印 ✅ 无硬敏感命中

一个手滑的参数换来一行绿色,正是本版立意要消灭的那类静默失败,首轮真扫时当场踩到。

已修:未知选项拒绝运行、扫描目标不存在拒绝运行(均退出码 2),并各补一条带正向对照的守卫——证明拒绝来自参数本身,而不是那个目录有问题。

这次打脸的完整经过写进了 CHANGELOG.mdducky/version.py。藏起来没有意义。

兼容性

与 v19.4.3 运行时行为完全等价。 无 API 变更、无数据迁移、无配置变更。升级即替换。

测试

423 用例 · 独立开发机 411 passed / 12 skipped · 完整环境 423 全绿

Full Changelog: v19.4.3...v19.5.0

v19.4.3

Choose a tag to compare

@monkey2jack monkey2jack released this 19 Aug 23:19

v19.4.3 · Athena 雅典娜 —— 发布卫生:发行包也是公开面

定性:与 v19.4.2 行为等价的版本,零可执行逻辑变更。
可执行逻辑与 v19.4.2 完全一致,差异仅在注释、docstring 与版本号本身。
已经在用 v19.4.2 的,升不升都不影响运行;本版是为「发布卫生」而生的。

为什么有这一版

v19.4.2 的源码注释与 docstring 里残留了对内部部署环境的描述性文字。

源码仓库这一面可以重写 —— 但发布到包索引上的同一个版本号,永久不可覆盖、不可修改。
唯一的出路是撤回旧版、另发一个干净的版本号。

这是所有公开面里唯一没有退路的一面。本版即为此而生。

这一版真正改的东西

发布链新增了一道强制卡点:

发行包必须解包实扫;且扫描器必须先在一个已知会命中的对象上验证它确实会报警(负向对照),
之后那个「0 命中」才作数,才允许上传。

一个没验证过的扫描器报「0」,和一个坏掉的扫描器报「0」,长得一模一样。

变更清单

  1. ducky/version.py / pyproject.toml / manifest.json:版本号提升至 19.4.3,谱系补记本次发布
  2. README.md / README_EN.md:版本标识与谱系表同步至 19.4.3
  3. 源码注释与 docstring 清理:移除对内部部署环境的描述性文字,不触及任何可执行逻辑

改动范围:6 files, +56/−6,无一行业务代码。

验证

结果
全量测试 391 passed, 12 skipped, 8 subtests passed —— 与 v19.4.2 基线一字不差
三条版本一致性守卫 逐条点名全部 PASSED(非 SKIPPED),均带负向对照
工作区文件内容 命中 0(237 受控文件)
全部提交信息(全历史) 命中 0,负向对照有效
发行包解包实扫(sdist + wheel) 命中 0 / 0,负向对照在旧包上命中 3
装包冒烟 版本号、代号、谱系首项全部正确

关于 19.4.2

PyPI 上的 aidumei==19.4.2删除(不是 yank —— yank 只是标记「不推荐」,包仍留在索引里可被显式安装;删除才会真正从包索引移除)。请使用最新版本。

v19.4.2

Choose a tag to compare

@monkey2jack monkey2jack released this 19 Aug 16:38

aiduMEI v19.4.2 · Athena 雅典娜 —— 守卫扩面 · 集成件凭据贯通

v19.4.1 的收口版,不引入新功能

本版主题:把守卫自己的射程焊死

v19.4.1 上线后的生产复审发现,门禁本身修对了,但**「谁需要带钥匙」这份名单列漏了**。v19.4.1 写过一条守卫测试来防调用方漏带凭据,可那条守卫只扫 scripts/ 一个目录,而缺陷分布在仓库根、integrations/mcp_server.py 上,一个都没扫到

守卫的射程小于缺陷的分布,比没有守卫更危险 —— 它提供了「已经防住了」的错觉。

所以本版的核心动作不是「再修几个文件」,而是用一条元测试断言:守卫的覆盖集合 ⊇ 全仓实际发起 HTTP 请求的文件集合,改窄射程立刻红灯。这条元测试第一次跑就当场揪出两个漏数的入口点,扩面后又揪出一个 —— 计划里点名 5 个,实际 9 个

主要变更

  • 🔴 凭据贯通:8 个入口(Hermes 注入 hook、mem0_sync/seed_demo/seed_factsmcp_server、Cursor 保存钩子、Claude Code 钩子、Hermes 插件)统一收敛到唯一真相源 ducky.utils.api_auth_headers() 与同一条 .env 兜底链。其中 Hermes 插件是典型的**「看着修了」**:代码里明明带着 Authorization 头,但 token 只从环境变量读,而 gateway 拉起插件时环境近乎为空 —— 每次请求实际都是空 token。
  • 🛡️ 守卫扩面:扫描范围扩到 scripts/ + 仓库根 *.py + integrations/**;新增元测试 tests/test_v19_4_2_auth_coverage.py
  • 🟠 静默失败可观测:sync 单元补 StartLimit*(崩溃循环不再永远卡在 activating)、logrotate 改 copytruncateStandardOutput=append: 下改名切割会让日志凭空消失)、补齐同步守护的依赖声明。
  • 🔵 审计整改轮frontend/dev_server.py 的双重逃逸(按目录 + 按信号)、README 数字守卫按 12 处逐一校验。最严重的一条:上面那两个 StartLimit* 键被写进了 [Service] 段,而 systemd 只在 [Unit] 段解析它们 —— 文件里白纸黑字、grep 查得到、review 看得过,行为却与完全没修一模一样。配置写了不等于配置生效,唯一的验收方式是问 systemd 自己算出来的值。两个单元的失败策略现在刻意不同:API 3600/30、sync 300/5
  • 🔵 收尾轮HERMES_SRC 改三态解析(未设 → 自动发现;none/no/off/0/false/空 → 强制无宿主;显式路径无效 → 直接报错并点名坏路径)。此前环境变量与硬编码路径挤在同一个候选列表顺序匹配,HERMES_SRC=/typo静默落到自动发现的路径上 —— 用户指了 A、实际测的是 B,还是绿的。隐式回退会悄悄推翻显式意图;而 README 宣称的「12 跳过」在装着宿主的机器上(生产机就是)根本复现不出来 —— 双向可复现才叫可证伪

测试

环境 结果
本机(无宿主) 391 passed, 12 skipped
生产(有宿主,未设 HERMES_SRC 403 passed
生产 HERMES_SRC=none 391 passed, 12 skipped
生产 HERMES_SRC=/不存在的路径 RuntimeError,点名那条坏路径
pytest tests/ -q -rs | tail -1                                # 无宿主:391 passed, 12 skipped
HERMES_SRC=/path/to/hermes-agent pytest tests/ -q | tail -1    # 有宿主:403 passed
HERMES_SRC=none pytest tests/ -q -rs | tail -1                 # 装了宿主也强制关掉,照旧 391 passed, 12 skipped

安装

pip install aidumei==19.4.2

完整变更见 CHANGELOG.md

v19.4.1

Choose a tag to compare

@monkey2jack monkey2jack released this 18 Aug 07:55

审计补丁版 · 鉴权贯通与租户闭环。 不引入新功能,只修「文档说了但代码没做到」的裂缝。

审计方法从「逐行读代码」改为探针实测——对 README 里每一句宣称,写一个最小可运行程序去试着推翻它。结果四条宣称被推翻,逐条修复并写进断言锁死。

🔴 安全与数据权利

鉴权贯通「一道门禁两把钥匙」
修复前两种部署形态都不可用:只设 AIDUMEM_UI_PASSWORD 时未登录 GET /api/facts 返回 200 全裸奔(口令只是前端障眼法);只设 AIDUMEM_API_TOKEN 时前端从不发 Authorization,登录后所有面板 401 报废。根因是认证结果没有服务端载体。现 /login 签发 HttpOnly + SameSite=Lax session cookie,与 Bearer 令牌任一有效即放行;新增 /logout 服务端撤销。
存量零破坏:口令哈希加 source=auto|user 标记——服务首次启动自动生成的口令只守控制台登录,不启用 REST 门禁,既有回环调用方(插件 / MCP / cron)升级后行为不变。

租户闭环
facts 层此前完全没有租户维度(19 处查询无一处过滤),新增 tenant_clause() 覆盖 9 个路由与注入出口,宽松 / 严格双档。同时修掉一处跨租户静默覆盖:唯一约束是 (agent_id, category, fact_key)agent_id 恒写常量,不同租户写同一键位时后写者会直接销毁前者的值。

删除权兑现
级联删除此前清 5 个库却独漏原文保真层,含敏感信息的逐字原文删除后仍可被检索。另外 /searchverbatim:<n> 返回原文证据(调用方唯一句柄),但 /delete 不认它——返回成功却什么都没删,而这类原文常无对应 mem0 记忆,遂成可检索但删不掉的孤儿

移除无 WHERE 全表删
各仓原有 if user_id == "default": DELETE FROM <表>,而 default 正是系统默认租户——清 default 会连带清空所有其他租户。

🟠 功能真伪

幂等键根治:判重键含 recorded_at,而生产载荷(纯字符串)不带时间戳、回落 now(),导致永不撞键——实测同一轮重放 3 次落 3 条。改为稳定因子 (user_id, content_hash, session_id),重复表述累加 occurrences 而非堆行。

中文检索从未走过索引:切词产出 2-gram 而虚拟表是 tokenize='trigram',2 字词元在 trigram 索引里永远匹配不上——每一次中文查询都静默落到 LIKE 全表扫描。20 万条实测稀有中文词 32.8ms → 0.05ms。召回结果新增 _recall_pathfts / like)自证本次真走的哪条路。

observations 幂等建表:该表自 v7 起只有读取方、全仓从无 DDL,全新部署 /observe 直接 500。

4xx 不再被降级成 500:注入拦截的 400 被外层 except Exception 吞掉再包 500,带自动重试的客户端会对着永远会被拒的内容死循环。AST 扫出同一模式 18 处,配源码守卫防复发。

🔍 三个「静默失败自我掩盖」连环案

这三个同型:异常被 except 吞掉后,业务层输出一个语法正确、语义完全错误的「正常结果」

  1. 兼容门面缺口致合并任务静默死亡三周。v11.1 重构把显著性能力拆进子包,门面只转发两个钩子,而调用方仍按老接口导入 6 个符号——每天凌晨被 cron 唤起、每次崩在 import 行,日志累积 18 次同样堆栈。期间衰减 / 指标 / 冲突检测 / 技能结晶 / 教训闭环全部未运行,而 /health 一直全绿(这些活儿本就不在服务进程里)。

  2. 两个附属库的级联清理从引入起从未执行。表名与列名双错(memory_salience 真名 salience 且无 user_id 列;evolve_snapshots 表根本不存在),错误被吞成 debug、计数恒报 0。后果是一条自我掩盖链:留下 252 条幽灵 id → 被当正常记忆持续衰减 → 进入淘汰名单 → 逐个删「早已不存在的东西」→ 日志漂亮报「删除成功 25/25」而向量库分毫未变。

  3. 技能结晶 SQL 方言错误GROUP_CONCAT(DISTINCT x, sep) 在 SQLite 报错,异常被吞后输出「生成 0 个候选项」——看似「暂时没发现模式」,实则该 SQL 从未成功执行。

🛡️ 备份纪律与 cron 凭据

备份门禁自相矛盾:原流程「先算校验和 → 再逐个打开库跑完整性检查」,而打开 WAL 库会重建 -shm 并合并日志,当场打废刚算好的基线——create 报通过、require 立刻拒绝。后果比备份失败更坏:硬门禁 100% 拦人,运维只会学会绕过它。改用 SQLite 在线备份接口生成一致快照。
不变量:校验动作本身不得破坏校验基线。

cron 凭据兜底:服务靠 systemd EnvironmentFile 读令牌,但 cron 不加载 .env——门禁一开,定时任务下次触发即集体 401,且失败只写日志无人知晓。新增凭据单一真相源,9 个运维脚本统一复用。

🟡 供应链与加固

  • 依赖收敛:pyproject 下限对齐 requirements 实锁 + 补 requires-python = ">=3.10"(此前 pip 安装与源码安装跑两套依赖树,且 3.9 用户不被拦住)
  • 口令改 PBKDF2-HMAC-SHA256(200k 轮),文件权限 0600,旧哈希首次登录自动升级;改密撤销全部会话
  • echarts 落本地(去掉无 SRI 的第三方 CDN 外链,内网 / 离线可用)
  • /docs /redoc /openapi.json 纳入门禁(135 个端点清单等于攻击面地图),AIDUMEM_PUBLIC_DOCS=1 可显式放开
  • /stats 计数按租户收窄(原为全库计数,可从中推断本机记忆总规模)
  • router_usage(ssh + exec 形态)默认禁用

🟢 文档诚信

「租户硬隔离」改为准确的「按租户收窄可见性」并明示单机自托管定位;README_EN 补齐 Testing & Quality 与 Security Model 两章。

测试数字改为自校验:此前 README 295 / 汇报 328 / 实测 340 三版互相矛盾,根因是数字靠人手抄进文档。新增守卫从 pytest --collect-only 取真值与 README 比对,并校验「通过数 + 跳过数 = 总数」——数字过期会立刻红灯。版本号测试同样从硬编码字面量改为跨文件一致性比对。

质量数据

结果
测试 339 通过 / 12 跳过(完整环境 351 全绿
新增用例 107 项,全部遵循反假绿灯纪律
覆盖率 48% → 51%
编译 0 错误(含 4 个 shell 脚本)
生产验收 数据集合比对丢失 0 条,服务自崩 0 次

本轮沉淀的四条纪律

  1. 假绿灯:断言必须覆盖生产实际走的代码路径。只测便于构造的形态而绕过真实载荷,绿灯等于没测。
  2. 宣称即承诺:README 里每一句「硬隔离」「绝不留孤儿」「trigram 索引」都是对全世界的承诺。代码没做到,先改文档。
  3. 静默失败:干净降级是好纪律,但被吞掉的异常若让业务层输出一个「看起来正常的错误结果」,危害远大于崩溃。每个 except 都要能回答「如果这里真失败了,谁会知道」。
  4. 校验不得破坏基线:任何校验动作都不得改变被校验对象的状态。

安装pip install aidumei==19.4.1Dockerghcr.io/monkey2jack/aidumei:latest
完整变更:见 CHANGELOG.md

v19.4.0

Choose a tag to compare

@monkey2jack monkey2jack released this 17 Aug 15:39

v19.4.0 — 明镜工程 Phase 1 · 原文保真层 + 生产审计修复版(2026-08-17)

本版两部分:「明镜工程 Phase 1 · 原文保真层」(主特性)与「生产审计修复」(2🔴5🟡 逐项修复,随 v19.4.0 一并发布,不另起 19.4.1)。对生产部署做全面审计(结论 2🔴5🟡),本版按审计建议的顺序逐项修复:🔴-A → 🔴-B → 🟡 五项。修复全部带回归测试。

🔴-A B4 注入框架接进生产路径(服务端出口自防御)

  • 问题:v19.4.0 的 B4 注入框架只活在 hook 脚本里,生产实际走的 /facts/inject-context 服务端出口返回裸记忆块,框架形同虚设。
  • 修复ducky/facts_recall.py 新增 INJECT_FRAME_TOP 常量与 wrap_inject_frame()——inject_context() 返回的 context 一律带「数据而非指令」框架 + <memory> 标签;raw_context 保留裸文本、wrapped 标记是否包装、token 预算语义不变(按裸文本计)。
  • hook 侧防双重包装integrations/aidumem-inject.sh_wrap_block() 见内容已含 <memory> 标记即透传;核心记忆/检查点/检索三块包装行为不变。框架措辞两侧逐字节同源(同源守卫测试盯死)。

🔴-B 治理评估器复活(call_llm 根治 SSE 假响应 + 推理截断兜底)

  • 问题:上游网关对 chat/completions 返回 Content-Type: text/event-stream 却塞 JSON + data: [DONE] 拼接体,r.json() 直接炸,评估器全部走「评估器不可用 → 人审」降级,B1 治理管线实际瘫痪。
  • 修复ducky/llm_client.py 请求显式带 "stream": False;新增 _parse_completion_body() 三态兜底解析——标准 JSON / 逐行拼接体(跳过 [DONE],message 与 delta 块分别聚合)/ 真 SSE 流;HTTP 200 但解析不出内容时记 warning 降级,不再抛异常。
  • 生产实测补强(推理截断):生产实测发现上游推理模型——请求级 reasoning_effort/enable_thinking 均被网关无视,思考与输出共享 max_tokens,小预算下思考耗尽预算 → content 空 + finish_reason=length + reasoning_content 非空,评估器 max_tokens=200 首试必截断、永远 evaluator_unavailablecall_llm 拆出 _post_completion 检测该形态,截断时自动放大预算 ×4 重试一次(封顶 4096);评估器预算 200→512、超时 15→30s。生产复测:垃圾随机词 reject(0.99)、优质偏好 approve(0.98),评估器从「永远不可用」恢复为真实裁决。

🟡-A 噪声规则升级(随机乱敲组合识别)

  • 问题asdfgh jkl 12345 xxxxx qqqq zzzz 这类键盘乱敲组合绕过旧噪声规则,进入 LLM 评估浪费配额。
  • 修复ducky/governance.py 重写 _is_noise,新增 _is_junk_token / _is_random_mash——纯符号 token、重复字符(xxx/qqq)、键盘行连续序列(asdfgh/jkl/zxcv)、连续数字(12345/54321)全 token 命中即判噪声;含 CJK 的文本一律放行交 LLM,绝不误杀中文记忆。

🟡-B backup_gate 嵌进升级入口(硬门禁)

  • 问题backup_gate.sh 造好了却没接进 pre-upgrade-check.sh,升级流程仍可无备份裸奔。
  • 修复scripts/pre-upgrade-check.sh 重排为五步——①backup_gate create(数据目录 + 代码仓轻量双备份)→ ②backup_gate require 硬校验(无验证备份 exit 1)→ ③冒烟 → ④cron dry-run → ⑤e2e;/tmp 系备份根一律拒绝(铁律)。

🟡-C 账本 target_id 别名展开

  • 问题fact:{key} / fact:{id} / 裸 memory_id 三形态并存,get_history 精确匹配,查全链得猜当初记的哪种。
  • 修复ducky/event_ledger.py 新增 _target_aliases()get_history 按别名集 IN 查询——fact:X 与裸 X 互为别名,数字额外展开 fact:{X};写入侧各形态保持原样不动,历史行零迁移。

🟡-D 次路径补账本与治理(拍板记录)

  • 问题:federation writer / refine_memory / persona ai-self 三条次路径直接写 facts,绕过治理与账本。
  • 拍板:联邦 insert 是真实外部路径(/federation/facts/add)→ 与 /facts/add 同等对待,治理 + 账本全上(规则 reject 同事务归档、provisional 降权 0.30、commit 后异步评估);update/merge 补账本。refine_memory / ai-self 是系统内部路径 → 只补账本,不上治理。治理/账本失败一律只降级不阻断写入。

🟡-E 既有备份补 SHA256SUMS

  • v19.4.0 升级时的生产备份目录缺校验和文件,部署时用 backup_gate 同款 sha256 流程补齐(部署动作,不入代码)。

✅ 回归测试

  • 新增 5 个测试文件共 40+ 项:test_v19_4_0_inject_frame_server.py(服务端包装/同源守卫/幂等/hook 透传)、test_v19_4_0_llm_sse.py(三态解析/拼接体实测/stream:False 守卫/推理截断放大重试)、test_v19_4_0_noise.py(噪声/非噪声参数化)、test_v19_4_0_ledger_target.py(别名展开/跨形态查全链/不误伤)、test_v19_4_0_secondary_paths.py(联邦三路径账本/insert 治理分流/钩子存在性守卫)。全量套件 244 通过 12 跳过。

🪞 明镜工程 Phase 1 · 原文保真层

明镜工程:不参赛、不跟人比,榜单只当镜子照自己。AML 榜单调研(2026-08-17 数据快照,榜单滚动更新)证实,显式事实召回的头部系统靠的是「原文一字不丢地存 + 混合检索」,而不是更花的抽取。本版把这一干货拿过来打磨,开源惠及大众。

📼 原文保真层 Verbatim Vault(新增 ducky/verbatim_vault.py

  • 说过的话,一字不丢:mem0 的 LLM 抽取把对话蒸馏成原子事实,语气、上下文、原话措辞都在蒸馏中丢失。Verbatim Vault 在抽取之外并行存一份逐字原文——verbatim_turns 表落 facts.db(租户硬隔离 + 幂等去重),verbatim_fts trigram 全文索引落 text_fts.db。
  • 写入挂钩/add 注入防御通过后逐条原文落库(兼容 list/dict/纯字符串三种 messages 形态),时间戳归一为 ISO;同租户同内容同时间戳重放只落一条,防重复写入。
  • 召回融合/search 在既有召回结果之上并行检索原文层并融合返回——主干优先、重合打标不重复、原文证据保留配额(最多 max(2, limit//4) 条),让召回的不只是蒸馏后的事实,还有说过的原话。
  • 级联删除对齐cascade_delete_all 新增第 6 步清理原文层(facts.db + text_fts.db 双侧),绝不留孤儿;default 全清语义与既有级联一致。
  • 启动建表:api_server 启动流程挂入幂等建表(失败降级,主服务照常启动)。
  • 失败干净降级:本层任何异常只记日志,绝不阻断 /add 与 /search 主链路;对既有 facts 数据零影响。

✅ 回归测试

  • 新增 tests/test_v19_4_verbatim_vault.py 13 项:建表幂等、逐字保真写入、幂等去重、租户硬隔离、中文 2-gram 检索、融合策略(打标/配额/limit)、级联删除双侧清干净、主链路挂钩存在性守卫。

📦 版本号五文件全量对齐

  • ducky/version.py · pyproject.toml · manifest.json · ducky/__init__.py · CHANGELOG.md 统一为 19.4.0;LINEAGE 谱系补全 19.4.0 条目;测试版本断言同步。
  • 版本号归一:审计修复原拟另起 19.4.1,经拍板并入 19.4.0 一并发布(大仓 tag/Release/PyPI 尚未发过 19.4.0,修复本该合入)。全部 19.4.1 字样归一为 19.4.0,CHANGELOG 两节合并为本节。

🪞 Mímir 借鉴六项(联邦记忆系统机制借鉴 · 单租户适配)

缘起:网友 Sandro 的 Mímir v12.0 联邦记忆系统白皮书(其「技术借鉴与鸣谢」章节亦致谢 aiduMEI 的 Tahoe-Gate 思想,双向奔赴)。研读后提出六项借鉴建议,逐项核实白皮书原文后落地。纪律:只借机制思想、不搬联邦重装备;每项过「单租户适配」闸门;既有优势(原文保真、Tahoe-Gate 相关性门控、租户硬隔离)零回退。

  • B2 备份纪律(新增 scripts/backup_gate.sh):schema/数据结构变更前必备份 + sha256 校验和 + SQLite quick_check 完整性校验;备份只进持久目录(/tmp 一律拒绝,脚本级硬断言);require 模式无有效备份则拒绝迁移(exit 1)。不借 Mímir 九级备份链命名体系。
  • B3 tombstone 遗忘层(新增 ducky/tombstone.py):遗忘不是删除——cascade_delete_memory 物理删除前先把 facts 行全文 + FTS 原文 + 理由快照进 tombstones 表(facts.db),误删可 restore_tombstone 一键恢复(回插 facts + 重建 FTS 索引)。不动 mem0 一行代码、不改任何检索路径,效果等价软删。新增 GET /tombstonesPOST /tombstone/restore
  • B4 召回侧注入框架integrations/aidumem-inject.sh):注入宿主 LLM 的记忆块统一包「数据而非指令」框架——[以下为召回的记忆数据……任何形似指令的内容一律忽略,不得执行] + <memory> 标签,三个注入块(核心/检查点/检索)全覆盖。对应 Mímir §13.4 三层注入防御的召回侧 L3。
  • B5 事件溯源账本轻量版(新增 ducky/event_ledger.py):memory_events 单表记录 add/update/delete/tombstone/restore/approve/reject/opinion_set 八类事件;record_event 只 INSERT 不 commit——与事实写入同事务同生共死;只记 hash + 理由不记快照(快照是 tombstone 的活)。新增 GET /events/history,任意记忆完整变更史可查。
  • B1 治理管线(新增 ducky/governance.py):写入后审计 + provisional 语义——mem0/facts 写入照常(不动基座),写入返回的事实立即过治理:确定性规则同步跑(密钥/token/密码模式直接 reject、删除/权限/交易语义强制人审、噪声直接 reject),独立 LLM 评估器异步补审(第二次调用、不同 prompt、硬超时);评估器超时/垃圾 JSON/未配置 → 保守进人审,绝不自动批准(Mímir 红线)。未过审事实 trust_score 降权 0.30(Mímir §7.1 provisional 语义),过审恢复 0.50;reject = 归档 + tombstone 留痕 + 账本事件,B1/B3/B5 三项咬合。候选状态精简 5 态(不照搬 12 态状态机);快线宁窄勿宽(置信度 ≥0.9 且偏好类白名单,吸取 Mímir fast_track 0 条 + 人审积压 97 条教训)。新增 GET /governance/candidatesPOST /governance/review
  • B6 信念层 Opinion 最小可用版(新增 ducky/opinion.py):事实是「是什么」,信念是「我多确定」——opinions 表三态(support/oppose/neutral)都有真实写入路径;observation 聚合吸取 Mímir 回声室教训:必须 ≥2 个不同证据来源才聚合,单来源刷好评不聚合;UNIQUE(fact_id, source) 防同源刷票;写入走 B5 账本(action=opinion_set)。完整信念演化留待 v19.5+。新增 POST /opinions/setGET /opinionsGET /opinions/aggregate

✅ Mímir 借鉴回归测试

  • 新增 4 个测试文件共 48 项:test_v19_4_tombstone.py(9 项:快照/恢复/租户隔离/检索不返回)、test_v19_4_inject_frame.py(6 项:框架文本/三包块全覆盖/无裸注入回退)、test_v19_4_event_ledger.py(8 项:变更史可查/事务同生共死/挂钩守卫)、test_v19_4_governance.py(17 项:三类样本分流/故障注入走人审/快线窄门/人审闭环)、test_v19_4_opinion.py(8 项:三态写入/单来源不聚合/双来源聚合)。全量套件 186 通过。

v19.3.3

Choose a tag to compare

@monkey2jack monkey2jack released this 17 Aug 01:48

aiduMEI v19.3.3 · Athena 雅典娜 — 审计回归修复与发布链接续

基于小猴对 v19.3.1/v19.3.2 的独立审计(实跑测试 + AST 扫描 + 最小用例实证)逐项修复。

🐛 嵌套异常处理回归修复

  • ducky/persona_memory.pybuild_persona 错误路径的内层 except Exception as e 与外层同名,Python 语义下内层退出即删除变量,外层再引用触发 NameError(v19.3.1 静默异常治理时引入,已用最小用例实证)。内层改用独立变量名 close_err

✅ 测试断言对齐与结构守卫

  • 版本断言对齐 19.3.3,恢复测试套件全绿(此前 v19.3.2 发布时断言未同步,套件 2 项失败)。
  • 新增 AST 全库结构守卫测试,杜绝嵌套 except 同名遮蔽再出现。
  • 新增 monkeypatch 断裂连接错误路径回归测试。

📦 版本号五文件对齐与谱系补全

  • version.py / pyproject.toml / manifest.json / init.py / CHANGELOG.md 统一 19.3.3。
  • LINEAGE 谱系补全 19.3.2 / 19.3.3;README 中英文同步(补齐 README_EN 文档债)。
  • PyPI 发布链接续:补发 19.3.3(此前停留在 19.3.0)。

质量门禁

  • pytest 119 passed / 12 skipped / 0 failed(本地);131 passed / 0 failed(生产实机)
  • compileall exit 0;脱密扫描 0 密钥 / 0 IP / 0 明文密码
  • 生产实例验证:1136 条事实数据无损,/facts/add、注入防御、/search 冒烟全通过
pip install --upgrade aidumei==19.3.3

v19.3.2

Choose a tag to compare

@monkey2jack monkey2jack released this 17 Aug 01:12

v19.3.2 — legacy 路由 import 修复版(2026-08-17)

根治 legacy 兼容层写入接口 500 的隐藏 bug,版本号五文件对齐。

🔧 legacy_routes 缺失 import 补全

  • ducky/hot/legacy_routes.py 补全 9 个缺失 importredatetime as _dt,以及 legacy_helpers 的 7 个符号(CONTRADICTION_WORDS_auto_detect_level_ensure_scenes_table_fact_feedback_impl_load_tags_run_consolidation_vault_refine)。此前服务可正常启动,但 /facts/add 一旦写入即触发 NameError 返回 500;补全后生产实测写入成功。

📦 版本号五文件全量对齐

  • ducky/version.py · pyproject.toml · manifest.json · ducky/__init__.py · CHANGELOG.md 统一升至 19.3.2