LifeOS Cortex 本地记忆 CLI 一次讲透:8 个子命令、隐私边界与证据校验全景
【免费下载链接】LifeOS⛰️ LifeOS — The universal AI Harness designed to move you from Current to Ideal state in both life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS
LifeOS Cortex 是跑在 LifeOS 文件型记忆系统之上的本地 Bun CLI:它是一个可验证检索与受控写入的命令行工具,不是 MCP 服务、不是常驻进程、也不是第二套记忆运行时。它被调用才启动,不联网、不建向量索引。本文一次讲清这个本地记忆 CLI 的 8 个子命令怎么调、五字段信封与退出码怎么判读、<private>标签如何 fail-closed 拦住隐私内容,以及两条证据链如何度量检索质量与运营健康。读完你可以直接跑命令、看懂结果,并精确知道系统明确不提供哪些能力。
📍 定位:它是一张契约,不是一个平台
Cortex v1 的全部边界可以压缩成一句话:有文件,有契约,没有进程,没有网络,没有第二套存储。
| 维度 | Cortex v1 是什么 | 它不是什么 |
|---|---|---|
| 进程形态 | 本地 CLI,调用即启动 | 守护进程、常驻 sidecar、MCP 或 HTTP 服务 |
| 存储地位 | 既有 Markdown / JSONL 文件型记忆之上的读取与写入入口 | Chroma、CMEM、SQLite FTS、向量索引或嵌入 |
| 数据范围 | 本机文件,规范根下的记录 | 跨设备/云同步、远程变更、外部遥测 |
它解决的问题很朴素:文件型记忆没有统一的"验证过的读 + 受控的写"入口,Cortex 用一条 CLI 契约补上这个缺口——读默认,写逐次授权。随系统发布的进程内适配器工厂位于 CortexAdapter.ts,为claude、hermes、codex、subagent四种受识别身份各建一个被Object.freeze冻结的适配器:status/search/timeline/get/export永远只读;remember/propose虽挂在接口上,但写权限逐次授予而非绑定身份——只有当次调用显式传入{allowWrite:true}时才追加--allow-write,选项里混入任何其它键都会被权限判定判死并整体拒绝。
🚀 上手:三步跑通 status,再绕开那个符号链接坑
调用格式全系统只有一种:
bun LIFEOS/TOOLS/Cortex.ts <command> [arguments] [options]根目录按四级优先级解析:运行时注入的memoryRoot→--memory-root→ 环境变量CORTEX_MEMORY_ROOT→ 默认~/.claude/LIFEOS/MEMORY。把规范根想成"户口登记地址":门口贴多少块门牌(别名)都可以,系统认的是登记地址本身。pinCanonicalRoot对根做一次realpath、确认是目录,再把真实目录"钉住"当信任边界,status会报告这条被钉住的路径——默认的LIFEOS/MEMORY符号链接借此指向私有数据仓库~/.config/LIFEOS/USER/MEMORY而无需手动解析。
第一个坑就藏在这里:顶层别名放行,钉住根之下的一切符号链接拒收。类比贴封条——进门验完真实地址就封上,之后任何再"改地址"的入口都不碰。实现上每次遍历都lstat判符号链接、校验realpath不越界,下列情况一律integrity_error、退出码 4:根下目录/文件符号链接、realpath 逃逸、重复记录 ID、格式错误 JSONL、不可能的时间戳(updated早于created、valid_from >= valid_until、非法日历日期)、非常规模块(如 socket)。此外还有语料级上限,在读取内容前就检查:文件 ≤ 10,000、单文件 ≤ 8 MiB、总量 ≤ 128 MiB、记录 ≤ 50,000,超限同样integrity_error。这就是"不确定就拒收"的 fail-closed 气质。
跑一条验证命令(退出码 0):
bun LIFEOS/TOOLS/Cortex.ts statusstatus不接受位置参数,返回规范根、记录数、mode:"local-read-only"与indexes:[]。注意它报告的是契约与语料"形状",不是运营健康——后者在证据一节单独讲。
🧭 判读:退出码 + 信封,两条证据都对才算成
能解析出 JSON 不等于这次调用成功,进程退出码和响应信封必须互相印证。
每条命令向 stdout 恰好写一个 JSON 对象,顶层字段有且仅有五个:
{"schema":"lifeos-cortex/v1","ok":true,"command":"status","data":{},"error":null}失败时结构不变:ok:false、data:null,error装{code,message},多一个顶层字段都不允许。发布版 lifeos-cortex-v1.schema.json 用oneOf互斥约束 success 与 failure 两形态,两者都声明additionalProperties:false。源码侧validateCortexEnvelope在每次ok()/fail()构造结果后先自检再返回——信封自校验是库内建的,不指望调用方守规矩。
退出码速查表:
| 退出码 | 语义 | 典型错误码 |
|---|---|---|
| 0 | 成功 | — |
| 1 | 未预期的内部失败 | internal_error |
| 3 | 显式 ID 或扩展根未找到 | not_found |
| 4 | 非法命令、选项、payload、过滤器、边界值或规范完整性问题 | invalid_input、integrity_error |
| 5 | 缺写授权,或既有治理拒绝变更 | write_refused、governance_refused |
选项解析同样是严格表:未知选项、重复选项、缺值、命令不适用该选项,一律拒绝而不是忽略,落到退出码 4 的invalid_input。
🗂 命令三组:日常只读、一致性验证、唯一的写闸门
8 个子命令按使用场景分成三组读,比逐个平铺清晰得多。所有命令都接受--memory-root <dir>和可选的--adapter claude|hermes|codex|subagent。
第一组:日常只读(status / search / timeline / get / export)
场景是日常查询取证。search基于本地 BM25(一种按词频与逆文档频率给文档打分的经典检索算法),词元按[a-z0-9]+切分:idf 取log(1 + (n-df+0.5)/(df+0.5)),tf 饱和系数 2.5,长度归一化b = 0.25 + 0.75·len/avgdl,同分按 ID 字典序定先后。--type、--source、--session是精确匹配;--from/--to对created做闭区间过滤;--recency须为有限非负数,按updated加权(score + recency·Date.parse(updated)/1e13),但不替代词法相关性。
bun LIFEOS/TOOLS/Cortex.ts search "retrieval eval" \ --type memory --from 2026-01-01 --page 1 --page-size 10 \ --expand some-id --max-nodes 10 --max-tokens 2000检索只回卡片,从不回正文:先给目录,要正文再点名。卡片仅含id、type、created、updated、provenance(source、可空session、相对path)、数值score、est_tokens(净化正文长度除以 4 向上取整)。列表响应给精确过滤后的total、从 1 计的page、page_size、items;默认第 1 页每页 10 条,页大小上限 100。可选的--expand从显式 ID 出发沿规范related做广度优先,预算默认 10 节点/2,000 token,上限 100/50,000,不构建也不查询任何持久化图数据库。
timeline用--anchor指定活跃记录 ID 或合法日期,--before/--after默认各 5、可为 0、上限 100;结果按created排序、同刻按 ID 排;ID 锚点在仍落在过滤器内时包含中心记录。get/export只回显式选中且当前生效的 ID 的完整净化记录:任一 ID 缺失、过期或未生效,整条命令退出码 3(all-or-nothing);单次最多 100 个 ID。export名字像写操作,实际只把记录序列化为lifeos-cortex-export/v1打印到 stdout,不创建任何文件——是披露,不是写。
第二组:一致性验证(rebuild)
场景是证明"记录视图可被确定性重建":
bun LIFEOS/TOOLS/Cortex.ts rebuild --from-canonicalflag 必填。它规范化记录,对规范视图与重建视图各算 SHA-256,在lifeos-cortex-canonical-rebuild/v1里报告equivalent、记录数与indexes:[],不创建任何索引。摘要相等只证明记录视图可确定性重建,不证明源文件被逐字节重写。
支撑这点的规范源规则值得记住:Markdown 与 JSONL 是规范地位,派生索引可丢弃、不能成为事实源;默认语料是KNOWLEDGE/树(排除下划线和点号前缀),根级*_MEMORY.md一并纳入,MEMORY/KNOWLEDGE/布局供隔离测试。缺失 Markdown ID 的记录获得稳定路径派生 ID(path:+ 路径 SHA-256 前 16 位);provenance 用相对规范根的路径,换别名不改摘要;规范读会再次净化,防止旧的已标记内容绕过当前边界。索引策略方面,CORTEX_INDEX_POLICY.json 是lifeos-cortex-index-policy/v1、policy:"no-index-v1"的肯定性标记:有标记无清单时,BM25 直读规范文件、rebuild什么都不建、健康检查直接报健康的no-index-v1,不为证明"没建索引"去遍历哈希整个语料;标记与清单双缺则状态歧义,仅告警index-evidence-missing;标记格式错误才是 critical。
第三组:受控写入(remember / propose)
场景只有一个:你真的要把一条新记录落进受治理的持久化路径。
bun LIFEOS/TOOLS/Cortex.ts remember '<typed-item-json>' \ --adapter claude --allow-write授权是双重绑定。其一,身份与权限分离:显式--adapter和--allow-write必须同时出现,只报身份不送任何写权限;其二,命令与条目判别器绑定:remember只收type:"memory"、"idea"、"knowledge",propose只收type:"proposal",不匹配在调用MemorySystem.add()之前就被拒。每条命令恰好收一个 JSON payload(≤ 262,144 字节)并委托给MemorySystem.add();既有的变更分层、目标钉住、提案审批、审计日志、快照、源所有权与收缩守卫仍握有最终决定权。治理拒绝是退出码 5,不存在部分成功。
资源边界一览(拒绝上限,不是目标值):
- 检索查询:2,048 字符且 64 个词法词元
- 列表页大小:100;timeline
before/after:各 0–100 - 图扩展:100 节点、50,000 估算 token
get/export显式 ID:100;CLI 写 payload:262,144 字节- 条目自由文本字段:65,536 字符;元数据字符串:1,024 字符
- 提案目标路径:4,096 字符;热记忆集合:48 条、每条 256 字符;
related链接:64
类型化持久化同时拒绝:未知字段、非法枚举或字段类型、非有限/越界 confidence、控制字符、frontmatter/注释注入、含糊的 session 元数据、超尺寸数组,以及隐私剥离后变空的必填文本。代表性 1,500 条记录的契约检索在测试中限定 1.5 秒内。
🔐 可信: 标签与"拿不准就拒绝"防线
Cortex 的整套信任设计可浓缩成一句大白话:拿不准就拒绝。
隐私 span 用类 HTML 标签书写:public <private>never persist or export this</private> public。匹配不区分大小写,容忍无害空白与属性;嵌套 span 整体移除(按深度计数而非单条正则);孤儿闭合标签当控制标记删掉、保留两侧公开文本;未闭合的开头标签 fail closed,从该位置起抑制整串剩余。更狠的是:任何"归一化后像 private 开头标签但格式不良"的构造——NUL/控制字符插入、全角 Unicode、丢失的右尖括号——都按不可信开头处理并 fail closed,而不是尝试宽松 HTML 恢复。
这条边界的应用时机在持久化之前:reviewer 推断前、reviewer 调试/错误序列化前、类型化条目路由、规范词法排序、图扩展、get、export与rebuild之前。类型化条目的净化是递归的,覆盖 content 及承载持久化语义的元数据(标题、名称、rationale、session provenance、entries、related slugs),剥离后变空的必填字段直接拒绝。
源中立的CaptureEnvelope(见 CaptureEnvelope.ts)携带source、channel、timestamps.captured_at(可选source_at)、可选valid_from/valid_until、可选session_id与content。真正的摄取助手是ingestCaptureEnvelope(input, consumer):先剥离私有内容,再把净化后的 envelope 交给 consumer。fixture 覆盖 Claude、Hermes、Codex、子代理与一个消息通道——这只能证明"能表示",只有显式调用该助手的调用点受保护,不构成"所有既有来源已自动迁移"的声明,也不存在通用适配器守护进程。
还要认清一条硬限制:原生 harness 转录在其文档所述的 30 天保留期内可能仍留着<private>内容,这超出 Cortex 控制。它不碰转录字节,只剥离受控副本;私有标签是持久化与处理边界,不是对转录、终端回显、上游日志或标签到达前已发送内容的清洗承诺。
有效期窗口同样 fail-closed:valid_from含边界、valid_until不含;缺失即开放;非法边界(Date.parse得 NaN)直接判无效。search、timeline、get、export默认排除查询时刻不生效的记录;--from/--to是另一维度,约束的是created,不覆盖也不替代有效期判定。
📊 证据:两条链,分别量检索质量与运营健康
这套体系不回答"我健康吗",只回答"证据在哪"——缺失的证据永远拿不到绿灯。
链一:检索基准(标签自写,生产排序器)
标签文件LIFEOS/MEMORY/BENCHMARKS/cortex-retrieval-v1.jsonl存放在私有 MEMORY 树,由操作者在自己的语料上、首次基准运行前自行编写,不随系统发布。每行给 query、期望 ID、可选期望时序与可选已知假阳性 ID,并必须携带lifeos-cortex-benchmark-label-provenance/v1溯源,证明期望 ID 来自真实live-cortex-cli执行与人工语料核验。
bun LIFEOS/TOOLS/CortexBenchmark.ts \ --labels LIFEOS/MEMORY/BENCHMARKS/cortex-retrieval-v1.jsonl \ --memory-root LIFEOS/MEMORY \ --output LIFEOS/MEMORY/BENCHMARKS/cortex-benchmark-v1-YYYYMMDD.jsonCortexBenchmark.ts 的关键方法论:它导入生产代码(activeCortexRecords、rankBM25、toCortexCard与规范摘要函数),不携带基准专用排序器。每条带标签查询跑 25 次;每个查询/样本只做一次生产排序,并把同一份排序结果在两种披露测量间共享:bm25-baseline序列化完整 top-5 记录;progressive序列化 top-5 卡片、仅抓取被选中的第一条完整记录。排序质量被刻意保持相同,真正被比较的是披露与注入成本,不是两个检索算法。
每个配置报告:Recall@5、MRR、时序成对排序准确率、假阳性召回、注入 token、p95 延迟、延迟样本数、语料盘上字节数、实测磁盘增长、后代进程数、峰值 RSS、执行路径名,外加语料分词次数与排序运行次数,防止卡片优先的比较掩盖重复检索工作。报告 schema 为lifeos-cortex-benchmark/v1:stdout 恒收报告;持久化靠--output显式开启,必须落在解析后的MEMORY/BENCHMARKS/下、文件名版本化cortex-benchmark-vN-*.json,且不覆盖已有报告。报告记录语料/标签摘要、精确命令、时间戳、生产排序器与有效期路径、披露路径、top K 与样本数——它是对操作者自己语料的可复现时点测量,不是普适性的延迟或质量声明。
向量采纳门槛同步给出:当前vector_config为null。采纳向量或混合索引的前提是:一份带标签报告证明检索质量相对渐进式 BM25 有提升,且索引可规范重建、保持在单独文档化的磁盘与进程边界内。只省 token 不构成证据。
链二:运营健康(阈值表说了算)
status报契约形状,运营健康来自另一工具:bun LIFEOS/TOOLS/MemoryHealthCheck.ts --json。报告含overall、实测证据、生效阈值、findings,以及按 ok/warn/critical 派生的健康退出码 0/1/2(评估器见 CortexHealth.ts)。
| 证据 | 默认阈值 | 越界结果 |
|---|---|---|
| Reviewer 成功新鲜度 | 7 天 | 陈旧 WARN |
| 进行中 reviewer 终行宽限 | 10 分钟 | 超时 CRITICAL |
| 检索证据新鲜度 | 24 小时 | 缺失/陈旧 WARN |
| 待审提案积压 | 大于 10 | WARN |
| 可观测性字节数 | 大于 256 MiB | WARN |
| 最老可观测性日志年龄 | 大于 30 天 | WARN |
| 已采用索引新鲜度 | 大于 7 天 | WARN |
判定规则几条最要紧:最新reviewer 证据压过历史成功,最新一次失败、解析失败、超时、schema 不完整或无效均为 CRITICAL;新运行目录超过 10 分钟宽限仍无终行判超时;格式错误的 JSONL 被暴露而非静默跳回上次成功;非法或未来时间戳不能证明新鲜度;提案证据只数状态恰为pending的行;可观测性证据递归测量MEMORY/OBSERVABILITY/下全部.jsonl与.log,报字节数、文件数与最老 mtime;检索证据取最新一行有效的memory-retrievals.jsonl。对未来索引,lifeos-cortex-index/v1清单必须给出规范 SHA-256、索引路径与 SHA-256、indexed_at;清单非法、路径违规、索引字节缺失、规范不匹配或索引字节不匹配均为 CRITICAL。已验证的缺失清单是健康的no-index-v1词法基线,不是把没测过的索引状态喊成健康的借口。
阈值覆盖只接受有限正数值;非法值产生 critical 的cortex-threshold-invalidfinding,而不是让比较失效。运营覆盖变量:CORTEX_RETRIEVAL_STALE_MS、CORTEX_PROPOSAL_BACKLOG、CORTEX_OBSERVABILITY_MAX_BYTES、CORTEX_OBSERVABILITY_MAX_AGE_MS;测试/自动化路径另有CORTEX_HEALTH_ROOT、CORTEX_HEALTH_NOW、CORTEX_INDEX_MANIFEST、CORTEX_HEALTH_NO_WRITE、CORTEX_HEALTH_REPORT_PATH。每次运行给出overall判定与 critical/warn/ok 逐项计数,记录的是当前证据,不是永久健康保证。
🚧 边界:明确不提供什么,以及继续读哪里
契约的另一半是负清单。已实现的这版升级不提供以下任何一项:
- MCP 服务器或网络 API
- 跨设备或云端同步
- CMEM / CMEM Cloud / Chroma / SQLite FTS / 嵌入 / 向量索引
- 外部 Cortex 遥测
- Cortex 守护进程或常驻 sidecar
- 所有 hook/通道/采集表面的自动采纳
- 对原生 harness 转录的清洗
- 从搜索结果自动注入完整记录
适用前提:以上均以当前仓库LIFEOS/TOOLS/实现为准;运行需要 Bun 运行时与已部署的规范根(~/.claude/LIFEOS/MEMORY或CORTEX_MEMORY_ROOT指定);私有 MEMORY 树里的基准标签、检索日志、索引清单都是操作者本地资产,不随开源仓库分发。
延伸阅读(仓库相对路径):
- 实现入口:Cortex.ts
- 进程内适配器工厂:CortexAdapter.ts
- 隐私 span 与有效期:CaptureEnvelope.ts
- 基准方法与报告 schema:CortexBenchmark.ts
- 证据收集与 fail-closed 评估:CortexHealth.ts
- 响应 Schema:lifeos-cortex-v1.schema.json
- 索引策略标记:CORTEX_INDEX_POLICY.json
- 记忆架构与写者清单:MemorySystem.md、CortexContract.md
- 本地可观测性管线:ObservabilitySystem.md
【免费下载链接】LifeOS⛰️ LifeOS — The universal AI Harness designed to move you from Current to Ideal state in both life and work.项目地址: https://gitcode.com/GitHub_Trending/pe/LifeOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考