oh-my-openagent memory-v2 F1 终审合规审计:以提交 Blob 与中止边界双重验证记忆系统

📅 发布时间:2026/9/19 23:18:23
oh-my-openagent memory-v2 F1 终审合规审计:以提交 Blob 与中止边界双重验证记忆系统
oh-my-openagent memory-v2 F1 终审合规审计以提交 Blob 与中止边界双重验证记忆系统【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent本文为 oh-my-openagent 仓库中memory-v2特性计划的 F1 轮次“第四次也是最后一次”合规审计F1-final2提供完整解读。审计只复核了尚未两连过的两行要求MH-4soul 编辑公告规则的单载体设计与 MN-91500ms 关停截止线后的排空中止边界并给出了判定依据已提交 blob 检查、逐操作边界的 AbortSignal 重检点清单、四个内部钩子翻转信号的边界测试以及 15 个测试全部通过的运行时结果。读完本文你可以掌握该项目“合规证据”的验证方法git show HEAD:path提交 blob 检查而非工作树检查、soul 公告规则“单一载体”的跨表面设计以及记忆排空管线在关停路径上每个 I/O 边界如何携带并复检中止信号使任何被中断的排空都保持可重试而不产生半写入状态。审计基线与方法审计文档位于 .omo/evidence/omo-senpi-adapter/memory-v2/F1-final2/compliance.md结果判定为PASS。其审计依据在文档开头完整列出绑定检查单本地文件/tmp/memv2/musthave.md计划必须满足项清单非仓库内文件前序审计F1 初审、F1 复跑 与 F1-final 审计——同一轮次目录下存在 F1、F1-rerun、F1-final、F1-final2 多个审计版本体现了“整改一次、复审一次”的证据链管理只审计未过两遍的行本次仅复核 MH-4 与 MN-9其余行已两连通过不再重复审计证据提交前的源码 HEAD37bd4946844d383de29928231d73a690c98dc254最终整改提交37bd49468提交信息为fix(memory): close the remaining abort-boundary gaps and finalize the soul single-carrier与本文两行要求一一对应审计方法对 HEAD 做committed-blob 检查git show HEAD:path即检查提交对象而非工作树、按当前行号复核以及只运行三个被明确授权的聚焦测试文件源码在本审计中未被修改一个边界纪律细节此前已暂存的packages/omo-senpi/plugin/extensions/facts-persona.md保持未触碰并被排除在本次证据提交之外——审计只固化与结论相关的变更。之所以强调 committed-blob 而非工作树检查文档说得非常直接这证明“重复标题与独立指令不存在于已提交的 blob中而不仅仅是不存在于工作树中”。工作树内容随时可被再次修改只有提交对象才是可引用的证据。MH-4soul 编辑公告规则的“单一载体”要求MH-4 要求记忆系统各提示表面nudge 行、REMINDER v2、memory-discipline skill协同提供记忆纪律但同一条规则不得跨表面重复——尤其 soulsystem/目录下的自我模型文件编辑公告规则必须且只能有一个操作性载体避免多个表面各自表述、逐渐漂移出矛盾版本。已提交 blob 验证审计对 HEAD 执行git show HEAD:packages/memory-core/src/seeds/memory-discipline.ts确认其中存在唯一的## Soul rules标题并且其唯一的公告规则引用是一条中性指针## Soul rules Files under system/ are your self-model, projected into every prompt. Edit them only for durable identity changes and keep them minimal. The persona is the single carrier of the announcement rule for those edits; this skill deliberately does not restate it.上引文为审计记录中该 blob 的原文当前工作树同段表述略有后续润色语义不变。blob 级检查计数为soul_headers1 independent_commands0即前一轮审计发现的两处违规——重复的## Soul rules标题、以及 skill 内独立出现的Never edit them silently禁令——在提交对象中均已消失。源码侧印证skill 与 persona 的分工当前仓库中 memory-discipline.ts 印证了审计结论的结构。该文件把skills/memory-discipline/SKILL.md播种到新鲜仓库内容是散文加一个机器消费值frontmatter 的 description 触发短语。它教给 agent 的核心是知识的归属路由你学到的东西放在哪里关于项目或工作的持久事实、决定、纠正记忆笔记notes/、reference/必须常驻上下文时用system/块可重复执行的流程技能skills/name/SKILL.mddescription 说明何时使用关于某个具体人的事实该人的 people 记录主用户在system/human.md其他人在people/slug/card.mdobservations.md用户明确说不要做的事system/boundaries.md用其原话绝不写你推断的规则用户、reviewer 或测试暴露的你的行为问题reference/self/observations.md引用来源reflection 将其提升到system/self-aware.md瞬时状态、推测、或以上已覆盖的内容无处可放。“不保存”也是有效结论但要刻意做出该决定其中“一个事实一个家”One home per fact原则要求同一知识看似适合两个位置时选更具体的那个另一处只引用、不复制——这正是“不跨表面重复规则”这一设计哲学在具体记忆条目上的应用。真正的公告规则载体在 default-memory.ts。persona 块system/persona.md的种子正文描述$MEMORY_DIR版本控制文件系统契约后以唯一一句收尾If you change this file, tell the user. It is your soul and they should know.见 default-memory.ts#L48审计时行号为 45-47后续提交有轻微行号漂移。该文件的注释明确写着设计意图“soul 编辑公告句只在这里陈述没有其他表面复述它。”The soul-edit announcement sentence is stated here only; no other surface repeats it.于是形成清晰分工personadefault-memory.ts公告规则的唯一操作性载体memory-discipline skillmemory-discipline.ts只放一条中性指针把读者引向 persona明确“本 skill 刻意不复述该规则”其他表面nudge、REMINDER不含独立公告指令independent_commands0验证了这一点。这种“单一载体 指针”模式的价值在于规则未来若需修改只改一处且任何表面间的措辞漂移都会立刻暴露为指针与载体的不一致而不是变成两个互相矛盾的“规则”。MN-91500ms 关停截止线后的中止边界要求MN-9 要求超过 1500ms 排空截止线后不再启动任何新的特性工作并且每一个排空步骤都要携带 AbortSignal 并在每个操作边界重检。这里的背景是会话关停时有一条排空drain窗口用于把未落盘的记忆数据facts 队列条目、skills 用量账本刷写到磁盘若排空超时或身份identity被释放任何尚未完成的写入都必须干净中止且不能留下半完成状态破坏重试性。FactsQueue入队路径的五个检查点核心实现在 queue.ts 的FactsQueue.enqueuequeue.ts#L63-L106。信号在以下边界逐一重检检查点位置语义入口检查enqueue开头、locked()之前已中止则直接返回no-new-entries不进锁发布前重检publish调用前构建出条目后、落盘前再确认信号写-改名之间publish内部临时writeFile与持久rename之间临时文件已写、正式文件未出现时中止则rm临时文件队列里不出现新条目发布后、推进前enqueue返回前条目已持久化但水位未推进时中止保持可重试游标推进advanceEnqueued读取游标之后、writeCursor之前见 queue.ts#L276-L285关键设计在publishqueue.ts#L208-L214先writeFile到.tmp若此时signal.aborted为真则删除临时文件返回否则rename为正式条目。文件头注释还说明了持久化布局本身的可恢复性发布是“.tmp rename在身份级facts-queue锁下执行入队水位是单调的晚完成的老批次永远无法重发布与较新保留条目重叠的范围”。为什么“发布后、游标推进前”要单独重检因为入队水位是单调的且永不在markConsumed回退如果发布已落地但中止发生在水位推进之前队列条目依然保留pending后续启动会把它视为未消费并重试——这正是“可重试性优先于进度”的边界设计。Skills 账本flush 的两级检查skills 用量账本的排空在 skills-usage-tracker.ts审计文档引用的 skills-usage.ts 现为兼容导出面仅重导出 ledger/tracker/wiring 三类符号flushskills-usage-tracker.ts#L57-L70入口检查signal?.aborted然后把信号传入flushBatchflushBatch在创建锁记录之前检查一次在withLock之前再检查一次并在锁内mkdir前与writeLedgerAtomic前各检查一次。锁内检查是必要的即使拿锁瞬间信号未中止锁持有期间的 I/O 也可能跨过关停边界任何一次原子账本写入之前都必须重新确认“还允许写”。Facts 启动器从入口到子进程 spawn 前FactsExtractorRunner 的launchPendingfacts-runner.ts#L67-L77入口即检查信号已中止返回skippedlaunchPendingOncefacts-runner.ts#L108-L122则在入口、模型注册表解析前后、listPending之后、保留运行目录reserveFactsRunDir之前、以及runFactsChildspawn 之前逐点重检。检查点密集到“创建批次 ID、声明队列占用”这类轻量操作之后也不放过——因为任何一步之后发生的中止都不允许留下已声明但未消费的批次或半创建的运行目录。排空接线信号如何流进每一步关停调用点通过 wiring.ts 中的flushSkillsUsageTrackers把信号传给 tracker flush循环内每个 tracker 前都重检一次见 wiring.ts#L76-L85facts-wiring.ts 的fire与enqueueSettledfacts-wiring.ts#L59-L97在调用extractor.launchPending/queue.enqueue前以外层边界检查拦截已中止的调用并把信号继续传入FactsQueue.enqueue与launchPending。整条链是关停 → 排空步骤skills flush / 最终 delta 入队 / facts 启动→ 各步骤入口与内部边界逐点重检——没有任何一步依赖“入口时没中止就不会中止”的假设。边界测试证据审计没有满足于“入口已中止则什么都不做”的浅层断言而是选择在内部钩子上翻转信号——这直接对应“每个操作边界都重检”的要求因为入口中止的测试无法证明内部边界存在检查点。四个测试及各自的中止注入点queue.test.ts#L195-L215从注入的now()时钟钩子触发中止enqueue在计算时间戳时调用now()中止恰好落在锚点计算与发布之间。断言入队报告无发布、listPending()保持空、入队游标保持 null。queue.test.ts#L217-L243通过替换FactsQueue.prototype[publish]在发布落地后立即中止。断言持久条目保持 pending 而入队水位保持 null——批次保持可重试正对应上文的“发布后、推进前”边界。facts-runner-abort.test.ts#L25-L44从注入的createBatchId钩子中止。断言启动被跳过status: skipped、队列条目保留、运行目录facts/runs根本未被创建因此子进程不可能 spawn。skills-usage-wiring.test.ts#L101-L125存在待写入增量但排空信号已中止时 flush断言账本文件从未被写入Object.keys(ledger)为空。审计只运行了三个被授权的文件命令与运行时结果原样记录在文档中bun test packages/memory-core/src/facts/queue.test.ts \ packages/omo-senpi/src/components/memory/facts-runner-abort.test.ts \ packages/omo-senpi/src/components/memory/skills-usage-wiring.test.ts15 pass 0 fail 41 expect() calls Ran 15 tests across 3 files. [1370.00ms]值得注意的是这个运行时长约 1.4 秒本身与“1500ms 截止线”要求同处一个数量级排空窗口内必须完成的工作被压缩在亚秒级的验证成本内边界测试不需要等待真实关停路径。审计结论与可复用的验证方法F1: PASS。两行要求MH-4、MN-9均判定 DELIVERED无失败行。从这份终审审计中可以提炼出三条对“合规证据”本身有约束力的方法证据锚定提交对象用git show HEAD:path检查 committed blob 而非工作树配合soul_headers1/independent_commands0这类可复算的计数让“某违规已消除”成为可独立复核的命题中止边界测试要翻转内部钩子只在入口中止的测试对“每边界重检”是零信息量的把信号翻转注入点放在now()、publish、createBatchId等内部缝上才能真正证明边界检查点存在且行为正确发布可落地但水位不推进、临时文件可清理、运行目录不创建;最小授权面只运行计划明确授权的测试文件、不动暂存的无关文件、不修改源码使证据提交的 diff 与审计结论严格对应。这套方法与仓库的记忆系统实现memory-core 包与 omo-senpi 记忆组件共同构成了一个可引用的闭环规则设计单载体公告、单一归属路由、实现逐边界重检的排空管线与证据blob 检查 内部钩子测试三者一一对应。【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考