memory-pointer-system
Skill91 starsChanged 18 days agoMITView on GitHub
Use when 维护记忆指针/跑 mem_guard 体检/写指针/改记忆条目/记忆分层审计。改记忆前必挂。
- Reads credentials
In this repository2 other files it gives its agents.
- memory-governanceSkill
- pulse-pathSkill
The file
Files
记忆指针系统(Pointer Dictionary + Guard)
pulse-path 是方法论层(链表五律),本技能是实现层:指针怎么写、怎么体检、怎么同步。
设计定案
- 指针格式只给机器用:人不需要阅读,格式完全面向机器(简洁、规范、可解析),迁就人类阅读的格式设计被否
- 全量指针化:所有记忆都是指针,无例外、无触发——不存在"大项目才启用",根治"忘挂链"问题
- 指针 + 摘要安全网(关键):防模型忽略指针导致记忆断片——每行指针自带最小语义,模型不解析指针也能兜住基本上下文;断链只影响"细节"不影响"记忆存在"
- key 用英文,用户需要时解释一遍
- 迁移分批试点,试点验证通过才全量
指针语言 v0.1
key = scheme://target | 摘要key:英文小写下划线,全库唯一,稳定标识scheme(11 类):skill/doc/viking/fact/script/cron/cfg/rule/env/mem/store(store://= 外部记忆服务里的对象,只对接不 vendor,见docs/store-interop.md)target:可验证路径或标识| 摘要:安全网,≤40 字(上限在mem_rules.json的summary.max_len;超长=体检报 🔴「摘要过长: N 字 > 40」)- 验证态:
✓存在 /✗断链 /?未检——mem_guard 维护,不手写
解析正则:^([a-z_][a-z0-9_]*) = ([a-z]+)://(\S+?) \| (.+)$
三级条目(按"模型忽略指针的代价"分级)
| 级 | 类型 | 摘要策略 | 例 |
| S 级 | 红线/铁律 | 摘要=完整语义,指针可省 | respect = rule://respect-people | 尊重人底线… |
| A 级 | 高频配置 | 摘要=关键值 | net_proxy = cfg://proxy | 代理 host:port |
| B 级 | 低频大内容 | 摘要=一句话定位 | nav = skill://project-navigator | 项目导航技能… |
mem_guard 保卫系统
位置:scripts/mem_guard.py(本仓库内,可被定时任务直跑)
- 定时体检(如每天一次;脚本型无 LLM 开销)
- 分级:
- 🔴 人工决策级(涉及决策/逻辑链/需理解省略语义的复杂问题)→ 上报通知渠道
- 🟡 自动修复级(明显/单一:大小写、路径分隔符、唯一近似匹配)→ 自动修 + 记报告,不投递
- 🟢 正常 → 静默(零输出 = 定时任务不投递;非空 stdout 才投递)
- 验证分派:
skill://→查 skills/ 目录、doc://→查路径存在、script://→查 scripts/、cfg:///env://→查 .env 对应 key(大写)、cron://→查$HERMES_HOME/cron/jobs.json的 job id/名(库文件不存在报 ?)、mem://→查同文件内该 key 是否存在(跨指针引用完整性)、rule://→全量版再验(试点期报 ?)、viking/fact→全量版再验(试点期报 ?)、store://→跑规则表store.command拿退出码(0=命中 / 64=断链 / 65=服务不可用记 ?;command 空=未配置,全部记 ? 不报断链) - 报告落盘:
$HERMES_HOME/reports/mem_guard-report.md(始终记录,可回溯) - 水位检查:
check_watermark遍历mem_rules.json的watermark.files,任一 ≥watermark.threshold就报 🔴 并生成条目整理清单(按§分段取首行,预览 15 条 + 总数)——调阈值/增监控文件纯声明式改规则表,引擎零改动 - 退出码恒 0:早期"red 级问题就
exit 1"导致定时任务误标 script failed/error(预警在 stdout 但被 failed 掩盖)。问题经 stdout 传递;last_status=error从此不是"有预警"的标志,排查时别当设计解释
实测价值
mem_guard 抓到过自己手写的断链:cfg://X 在 .env 里不存在(实际 key 是另一个名字)——"看起来对、实际断"的链正是人眼发现不了的。改完指针必跑 python scripts/mem_guard.py --check --verbose 验证。
多副本同步渠道
知识技能常有三份拷贝,必须定一个权威源并自动化同步,否则必然断联:
权威库(远端仓库)
↔ 本地 clone(人工核对用)
↔ 安装/使用副本(agent 实际加载的那份 = 真正被读取的源)- 同步脚本职责:
push(使用版 → clone → commit → push 远端,默认)/pull(远端 → clone → 使用版)/--local-only(只同步本地不推送,核验用)/--quiet(无变化时完全静默:零输出 + 退出码 0,供定时任务用) - 每日定时自动同步(脚本型,内部 runpy 调同步脚本):无变化静默不打扰,有变化自动 commit+push 并投递摘要——根治"改完忘推"断联复发
- 改完技能必跑同步,禁只改不推:曾断联 9 天(仓库停更、使用版演化无人推回)
- ⚠️ 同步范围要显式列清单:同步脚本通常只覆盖技能目录内的白名单文件(如
MPS_FILES)。运行目录下的运维脚本(同步脚本自身、wrapper)不在清单内,随本地环境走即可
同步坑(实测)
git pull --rebase必须先 commit:工作区有未提交变更会直接拒绝(cannot pull with rebase: You have unstaged changes)--local-only遗留变更识别:不能只比两版文件 diff(已一致),要用git status --porcelain查未提交变更- Windows
core.autocrlf=true会把仓库文件变 CRLF(脚本出现 CRLF vs LF 全文件假 diff)——.gitattributes写*.md text eol=lf+*.py text eol=lf根治 - git-bash 调 python 脚本:路径用原生绝对形式(
python "<盘符>:/…/script.py");MSYS 的~/不展开、/<盘符>/…风格路径不会被自动转换,两者都会报 can't open file。给脚本传环境变量同理——用原生绝对路径
批量指针化迁移(叙述条目 → 指针)
分批把内置记忆从叙述式转成指针时,流程与关键判据:
核心判据:内容层「覆盖度」验证,不是「存在性」验证
转指针前必须确认 L2 目标真的装得下被转条目的全部语义,不能只看 target 存在。三类常见坑:
- 技能是方法论 ≠ 技能含运维细节:
pulse-path技能只讲链表五律(方法论层),仓库地址/多副本/同步脚本细节在语义库里。→ 指针应指向信息最全的那个落点(语义库实体),不是同名的技能。判定:先读技能,看被转条目的关键值(路径/地址/ID/脚本名)是否都在技能正文里。 - 技能范围窄 → 先补 L2 再转:某技能是选型方法论,微调部署细节不在技能内 → 先往语义库落一条完整部署细节,再转指针指向技能 + 摘要注明"详见语义库"。
- 关键标识塞不进 ≤40 字摘要 → 保留最高价值那个:一条记忆带 2 个 ID,技能里都没有 → 摘要只留运维价值最高的那个,另一个靠语义库检索兜底。
- doc:// 档案可能缺「后来发现的动态坑」→ 先补语义库再转:硬件档案生成较早,不含之后发现的功耗墙/误判/休眠设置等动态坑 → 直接 doc:// 指向档案会丢这些关键坑 → 先落一条补充实体,指针 doc:// 指向档案 + 摘要注明"XX 等坑见语义库"。
- viking:// target 用「语义检索词」而不是猜测的 URI 路径:猜目录前缀(
viking://user/default/memories/events/2026/08/20/)不精准、易断链 → 统一写成语义词(viking://某平台/viking://某组织),模型看到后viking_search语义检索即命中;已有明确实体 URI 的才写完整 URI。
铁律:内容层未落盘的条目禁止直接转指针(指针=删内容,先保证完整内容已在技能/语义库/文档)。
落盘实现:前缀匹配整行替换(比整串替换稳)
长中文条目整串 replace 易因引号/转义失配。用 python 逐行扫,按行首唯一前缀匹配整行替换:
repls = [("项目甲(", "pa = skill://project-a-navigator | ..."), ("记忆治理:", "ov = skill://..."), ...]
for i, ln in enumerate(lines):
for prefix, new in repls:
if ln.startswith(prefix):
lines[i] = new; break⚠️ patch 工具/整串 replace 对中文引号失配:文档里 "方案先交审" 实际是 ASCII 直引号 ",写中文引号当 old_string 会 NOT FOUND 连败。两个可靠备选:(a) 找段落锚点(如 ## 七、交接待办清单)后用 split/前缀匹配重写;(b) 整块按索引截断替换(head = lines[:start] + 新 tail)。判据:整串 replace 失败时,先 repr(txt[idx:idx+...]) 看真实字符,别盲改引号重试。
改完必跑 python mem_guard.py --check --verbose 验证(0 断链 / 0 超长摘要 / key 冲突)。
摘要瘦身/转指针前的「L2 覆盖校验」
压缩指针摘要(或把长叙述转指针)之前,必须先证"要删的关键标识已在 L2"——摘要=安全网,删掉的内容没落盘=断片。别靠人眼比对,跑脚本:
python scripts/check_l2_coverage.py [指针文件.md]它抽每条超长摘要里的特征 token(12 位 cron ID / *.py 脚本名 / 绝对路径 / 数字),逐个 grep 指针的 L2 target(skill 目录、doc 文件/目录),输出 missing_at_L2=[...]——这些 token 必须留在新摘要里。
实战判据(一轮:11 条超长摘要 + 4 条转换,水位降 14 点、0 断链 0 超长):
missing_at_L2里的 token 分三类:①真丢(必须保留)②陈旧(该删就删:已删除的 cron ID 从摘要里去掉才是修复)③在另一个 L2(提示在 A 技能,而指针 target 是 B 技能)——可接受但要知会用户- viking:// target 是语义检索词不是路径,脚本会报"无法解析"——这类改用真实
viking_search命中验证(命中新内容才算通) - 内容分散在多处时禁止转指针:某口径 SSOT 的新条目散在报告 + 策划书两处 → 单指针必丢内容,正确动作是"先把口径集中落盘一处,再转指针"(宁可先不转)
- 转完跑
mem_guard.py --check --verbose,看正常 N变化 + 0 断链;数值化汇报(水位、指针数)便于用户拍板下一档
多会话接力:交接档案
大迁移跨会话时,前一会话落盘交接档案 md(任务背景/指针语言规范/试点经验/分类迁移表/待办清单),新会话读档案接手。档案里"当前状态"需在每批完成后回写,保持事实基线。
大规模整脉收编
项目整脉("提到即激活")收编流程:子代理做盘点 + 逐条 L2 覆盖验证 + 产出编辑方案(每条给 old_text/处置类/新内容全文/L2 落点证据),主会话执行 memory 写入(L1 是敏感步,主会话持有已验证的批量写入流程)。执行前先备份 MEMORY.md/USER.md 到 scratch(带时间戳,可回滚)。
叙述不指针化的三类正当理由(用户问"为什么不做成指针"时的判据):① S 级红线/纪律——摘要 ≤40 字装不下完整语义(口径/答辩约束),放 L1 是防御防忘查;② 已精简短坑位——每条几十字,指针化省 ~30-50 字却多一个解析点+断链点,不划算;③ 就地状态——无 L2 落点,铁律"内容未落盘禁转指针",硬转要先建语义库载体反而绕路。判断标准是净收益:省字符 vs 解析开销+断链风险+语义密度损失。
脉络规划设计原则 = 渐进披露
内置记忆是全局路由表,不是项目仓库:项目只留 1 条头指针(skill:// 指导航技能),平时非项目会话不注入任何项目内容;"提到项目"才激活头指针 → 导航技能 → AGENTS.md/语义库整脉。业界同构 = Progressive Disclosure(渐进披露:上下文是预算不是仓库) + tier model(Instructions 总注入 / Curated core 小+预算 / Episodic 永不注入按需检索 / Prospective 触发才激活)+ 学术版 BudgetMem(查询感知预算分层路由,对单机过度工程)。
项目整脉收编落地清单:①项目内容先落 L2(语义库实体 / AGENTS.md 硬约束 / 文档)②导航技能升级为完整路由表(登记该项目全部实体+文档)③L1 删该项目全部指针与安全网摘要,只留头指针——只要硬约束在 AGENTS.md,项目会话激活链走到即拿到,平时非项目会话零注入 ④死点测试(冷启动只给头指针,问项目关键事实能否激活取到)通过才收编。安全网摘要不是收编豁免理由:它防的是"忘查",激活链走到 AGENTS.md 即兜住,非项目会话就该零注入。
按"全局 vs 项目"维度优先:凡属某项目的条目一律走头指针收编,留 L1 的只应是跨项目通用内容(红线/工具坑/系统状态)。
冷启动验证法(指针会被模型正确解析吗)
delegate 子代理模拟全新会话(只注入指针条目,无历史上下文),问"摘要里没有答案"的问题:
- 看子代理是否主动读技能 / 搜索 target 而不是只靠摘要答
- 实测:子代理主动解析两个 skill 指针且两级深入(继续读 references/templates)✅——证明"摘要给定位、指针驱动深挖"成立
坑位
- 引用体检结论会随工具版本失效,复跑用当前版:幽灵扫描 v1 把某脚本判为真幽灵,v2(修正则 + 全盘搜索)后归零——前者是
download.pytorch.orgURL 误报、后者在归档区真实存在。凡引用过往扫描/体检结论前,先用当前脚本复跑,别沿用旧报告的"真幽灵 N 个"。完整基准拓扑 + 修正则 + 判定流程见references/ghost-scan-v2.md - 验证报告/实体里的断言数会滞后于实际:曾出现验收报告与实体记"22/22 通过",但测试套件重建为 25 断言后未同步。教训:引用断言数前先
grep -c "check("当前文件核对,别照抄旧数字;改完测试套件要同步改验收报告 + 实体 - 摘要 ≤40 字是硬规范:试点期 3 条全超长(73-84 字)被体检拦下——写指针时先数摘要,别把细节塞摘要里
- 指针 target 写完后必须验证存在性,别凭记忆写
- 旧格式与新格式共存期(试点阶段):mem_guard 对非指针格式行跳过不报,不误伤
- ⚠️ 无版本控制的运行目录里核心脚本会丢:测试文件曾多次消失(会话内误删/清理)→ 把核心脚本纳入多副本同步清单,运行目录缺失时自动从技能副本补齐(
ensure_run_scripts()式保护)。⚠️ 但只防丢、不自动传播修改:改的是运行版但没同步技能副本 → 更新进不了仓库;改完运行版必须手动复制到技能副本再同步 - 先查已有引擎,再想新脚本:给定时任务加新功能/新检查前,先看有没有现成脚本已覆盖该职责。曾拟新建水位巡检脚本,实际 mem_guard 的
check_watermark早已实现且是超集——正确做法是扩展/复用现有引擎(改规则表 + 引擎小扩展),不新起脚本避免职责重复与维护分裂 git pull --rebase被未提交改动挡住时,若该文件是同步脚本每次会重写的镜像文件,可安全git checkout -- <file>丢弃:判据:确认该文件在脚本MIRROR_DIRS/COVER_FILES里会被覆盖,再丢弃;否则先 stash/commit- 语义库实体更新必须走其 CLI,不能直接改源 md:文件即源但语义检索走异步向量库——用编辑器/patch 直接改
entities/.../*.md后,检索仍返回旧内容(向量没重建,冷启动照样取到过期数据)。正确姿势:
输出ov write "viking://user/default/memories/entities/<分类>/<名>.md" \ --from-file "<本地改好的路径>" --wait --timeout 120vector_status: complete才算真生效(semantic_status: skipped正常)。改完必须检索命中新内容验证(光看文件改了不算数) - 正文引用/实体里的动态坑要单独补一份:档案类文档是快照,之后发现的坑不会自动进去(见上文 L2 覆盖校验第 4 条)
记忆分层审计法(量化"丢失了多少记忆")
用户问"X 项目丢失了多少记忆"时,不要只查工具健康——做跨载体的分层审计,给出量化结论。记忆不在一处,分层盘:
| 载体 | 位置 | 判断"完整性"的指标 |
| ① 会话历史(底层·无限兜底) | $HERMES_HOME/state.db(sessions/messages 表) | 总消息数 + 每会话 compression_fallback_streak/compression_ineffective_count 是否全 0(0=无压缩失败=原始记录没丢);有 state-backup-YYYYMMDD.db 时与当前库比对行数作基线 |
| ② fact_store(结构化事实) | $HERMES_HOME/memory_store.db(facts 表) | 相关 fact 的时间跨度——最新 fact 停在哪天,之后的关键决策有没有进 |
| ③ 语义库事件 | ~/.openviking/data/viking/.../memories/events/ | 事件文件的日期目录——停在哪天=自动抽取断在哪天 |
| ④ 语义库实体 | 同上的 entities/ | 实体是否覆盖最近的关键决策(新决策有没有建实体) |
| ⑤ 项目文档 | 项目文档区 | 文件数 vs 索引清单 |
| ⑥ 内置 memory(L1) | 系统提示注入 | 水位 + 关键指针条目是否在 |
典型结论形态:会话历史一条没丢(compression 全 0)≠ 记忆没丢——丢的常是"结构化提炼层"(fact_store / 事件停止更新),即决策只在底层可回溯、冷启动查不到。根因通常是"自动抽取没被触发"(回调几乎没跑),不是崩溃丢数据。⚠️ processed 是累计计数——判断"在不在转"看是否仍在增长 + 每日事件文件数,禁把历史旧值当现状。
查自动抽取是否在跑:ov observer queue 看 SessionCommit / Semantic 的 processed 计数。0 或个位数=自动抽取管线没转,改手动补沉淀或修触发。
诊断记忆轮子是否真在跑(不只看"已启用"):config 里 enabled 不等于 engine 启动。查实现层:看插件 data 目录是否存在(不存在=从未初始化);若硬编码容器主机名 + 本机不存在的模型,=抄自容器环境本地跑不了。别假设轮子装了就会转。
支持文件
scripts/mem_guard.py:体检引擎 v2(声明式规则表 + 四段管道:parse/verify/act/report;--help看环境变量)scripts/mem_rules.json:声明式规则表(加新 scheme=加 3 行 JSON,引擎零改动;summary.max_len/severity管摘要长度上限与报告等级)scripts/test_mem_guard.py:单元测试套件(自包含沙箱,不依赖本机路径)scripts/auditor.py:内容级审计(类目遵守/跨载体重复/指针存在性/ticket→入库链路)scripts/consolidator.py:睡眠期巩固检测(水位/降级候选/重复/过期/类目建议)scripts/curator.py:记忆管理员(唯一写口;默认 dry-run,--commit才落库)scripts/memory_request.py:会话侧发起入口(只产 ticket 不直接写)scripts/check_l2_coverage.py:摘要瘦身前的 L2 覆盖校验scripts/scan_ghost_script_refs.py:幽灵引用扫描 v2(修正则 + 全盘二次确认)scripts/scan_archived_deps.py:归档依赖扫描——哪些已归档/已删技能仍被活文件引用(path:line列出,检测脚本恒 exit 0)scripts/pp_index.py:本地检索——stdlib sqlite3 + FTS5 给指针目标建倒排(--build/--search/--stats,trigram 分词中文可搜、增量重建、--selftest离线自测)scripts/stress_pointer_test.py:弱模型下限压测——塞满上下文、指针藏中段、按 target 关键词判分(--plan不联网先看载荷)scripts/project_registry.py:项目注册——往规则表登记项目 + 往记忆文件插一条头指针(默认 dry-run,--commit先备份再写、写后读回校验)references/ghost-scan-v2.md:幽灵扫描基准拓扑 + 修正则 + 判定流程references/governance-engines.md:治理引擎(整理员/审计员)全景与职责边界
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

