Repository navigation
Description
使用场景
顺着之前的提案顺下来,当我们能让 mneme 能导出记忆为 markdown 后,我认为这意味着用户可以将 mneme 的导出当「能长期维护的笔记」用:一个记忆库导出成一批 markdown,交给编辑器或别的工具索引、浏览、跨机器带走。但这会引入新的问题,用久了自然会串成一条链:整理记忆 → 落盘文件变多 → 需要一个统一的落点来管它们 → 这个落点该不该继续待在 ~/.dsh 下 → 将来要不要把每个工作区的记忆也投影一份到仓库里。
这条链的第一环已经在做了(#231 的整理接口),后面几环到现在没有落点。它们不是四个独立功能:共用同一套渲染逻辑,只差落在哪、以及能不能改回来。所以想一次把形态与归属议清楚,而不是一个 PR 改一处、每个落点各自发明一套。
已查现状
现在有三个落点,行为各不相同:
~/.dsh/memory/*.md——磁盘镜像,按 type 分五个文件;有回流:/import与磁盘镜像的合并走mirror-digest加更新时间的三方合并,只吃title与content。/api/dsh-mneme/export——只读导出,format=json给整表 JSON,format=markdown按类型分节拼成一个文件,与镜像共用同一条渲染路径。<workspace>/.mneme/——工作区投影,还不存在。
工作区投影这件事,是回调一条更早的设计:#17 的 §五「workspace 投影(备份性质,可选)」写过它的一份完整草稿——定位是单向投影、不是权威源;可选、默认关;把 workspace_scope = 当前 workspace 的记忆渲染到 <workspace>/.mneme/,按 type 分文件,frontmatter 带 memory id / WorkspaceId / 导出时间;agent 维度写进 frontmatter 而不建子目录(避免笛卡尔积);价值是「编辑器里直接读项目记忆」与「DB 损坏时的明文兜底」,恢复走显式命令、靠 (type, title, scope) 去重保幂等。
但那是一版随 issue 搁置的草稿,不是生效中的设计:它没有随那一批落地,也没有排期。你关闭 #17 时列的偏差里就有它——「mirror 分域路径(第 6 条)……未随本批,作为已知边界跟踪(见 #168 的 PR 描述边界节)」,同一个 issue 的 M3 清单也列了它。也就是说它现在只存在于一个已关闭的 issue 和一个 PR 的描述里;代码里没有任何实现(src/ 下写记忆文件的只有 mirror.js 一处)。
所以下面拿它当回调看:它的价值在于「当时有人把该带哪些 frontmatter 字段列出来了」,而不在于「它已经定了」。
另外两条现状,都影响怎么选:
- 目录:记忆库现在是
~/.dsh/memory(memoryDir的默认值,放memory.db与那五个镜像文件),运行时重载荷在~/.dsh/mneme/。而src/runtime/layout.js里有一句注释写着这些「都挂在~/.dsh/mneme/下,便于用户整个删掉重来」——所以迁出这件事与你当初的意图是冲突的,要先对口径。 - 硬约束:同一个 scope 设计里,
sensitivity=1的记忆「不参与跨库检索、不进 mirror 导出、不入跨项目 dream 提炼」。任何新落点都必须继承这条。
期望的行为变化
同一份记忆,无论落在哪个位置,读到的形态是同一套;并且哪个落点允许改回库、哪个只读是明确定义的,不靠使用者的印象。
具体到四件事:
- 格式:落盘文件带 frontmatter,字段能直接当查询信号(来源、生成者、时间、状态)。我这边看的是 Open Knowledge Format v0.2——一个 concept 一个文件、
type必填,sources/generated/status可选。它与我们已有的列重叠度不低,但要不要采用、还是只借它的键名,我不预设。 - 回流:现在只有全局镜像能改回库,而且只吃 title 与 content——标签、重要性、来源、状态从文件改不回来。要不要扩到元数据,得先定义字段的权威归属(比如 type 算不算身份锚、
status: deprecated对应归档时是不是单向的)。 - 目录:记忆库是否从
~/.dsh迁到~/.mneme这类用户目录下、按用途分子目录。理由不是整洁:落盘文件一旦是给人读、给人改的,它放在宿主的私有目录里就等于在暗示用户别碰。 - 投影:工作区投影要不要重新排期。它跟第 3 条互相牵制——投影目录本身就长在用户仓库里,先把库的位置定下来,投影的位置才有意义。
想先确认的
- [Feature Request] 按 agent 与 workspace 隔离记忆:专属记忆 + 全局共享记忆并存 #17 §五 那版草稿只当参考,不当依据。 里面「单向、无回流」这条尤其想重看:当时给的理由是双向同步要解决 git checkout 冲突、双写向量、digest 冲突;但今天全局镜像已经是双向的(
/import+mirror-digest三方合并),而<workspace>/.mneme/在用户的 git 仓库里,读回会跟git checkout打架。两个落点的策略本来就可以不同、不必统一——这一条想听你怎么看。 - 迁出
~/.dsh与「便于用户整个删掉重来」怎么取舍;存量安装要不要迁移(memoryDir是用户可配置键)。 - 这一串拆成几个 PR、按什么顺序落。
可能的做法(仅供讨论,不是方案)
摆在桌上的只有这几条,我不预设:只给 /export 加一个新出口;镜像文件本身加 frontmatter;彻底改成一条记忆一个文件。粒度的代价可以量化,顺带一提:现在 5 个文件,一条记忆一个文件就是数千个,Windows 上的写入与扫描代价需要实测一次再决定——这条数据可能比格式本身更能定方向。
Activity
heptaspirit commentedon Sep 21, 2026
@modusensus 补一条同一议题里的关联:说「能读也能写」时,读回环其实今天已经在(
/export↔/import、磁盘镜像 ↔syncMirror),真正缺的是元数据也能写。现状(读码所得):
/import→parseHumanEdits→mergeHumanEdits,这条链只消费title与content(src/api.js的注释自己写明「只吃 title/content」),parseHumanEdits返回的也只有 id/title/content 加两个版本 token(更新时间、mirror-digest)。也就是说标签、重要性、来源、归档状态,今天从文件里改不了。所以如果 frontmatter 要成为正本的一部分,得先约定字段的权威归属——OKF 只规定键名,没规定谁说了算。我这边列几个需要落定的问题,供讨论、不定方案:
type是身份锚吗?改它等于换了一条记忆,还是直接拒绝?title/ 正文 /tags/importance允许从文件改回库,这些是无损的;status: deprecated对应归档:方向是单向的吗(能归档,能不能取消归档)?source只能追加还是可改?它在 OKF 里对应两个不同的键——「谁生成的」(generated.by)与「从哪来」(sources),我们现在只有一个单值字符串列;mirror-digest,换成 frontmatter 之后它放哪。这些定下来,「能读也能写」才有确定语义。定不下来我倾向先只做读(导出)方向,写回等粒度定了再说。
另外一处与粒度相关的成本,可能比格式本身更能定方向:一条记忆一个文件意味着文件数从 5 个变成数千个,Windows 上的镜像写入与扫描代价需要实测一次。
[-][Feature] 导出格式与 OKF v0.2 对齐:frontmatter 与概念粒度[/-][+][Feature] 记忆落盘形态与目录归属:镜像、导出、工作区投影的统一与迁出 ~/.dsh[/+]modusensus commentedon Sep 21, 2026
@heptaspirit 这份把形态与归属议清楚了,值得一次议定。先核对你的现状清单——大部分属实,但有一处必须修正,它影响整条链的假设。
一处现状修正:sensitivity 那条不是「硬约束」
你写「
sensitivity=1的记忆『不参与跨库检索、不进 mirror 导出、不入跨项目 dream 提炼』……任何新落点都必须继承这条」——这条约束在代码里不存在。我逐处核过 main:src/mirror.js、src/export.js:没有任何 sensitivity 过滤,渲染路径全量写出;src/dream.js/src/dream/*:无 sensitivity 判断;src/service.js:105明说「sensitivity 是标签不参与可见性判定」;检索侧的 scope 加权/过滤只认agent_scope/workspace_scope(strictScope 也只收窄这两维,README 原话「真正的物理隔离请用 sensitivity」是建议,不是实现)。也就是说 sensitivity 目前真实的语义只有两个:去重键第三维(跨 sensitivity 不合并)+ 标签展示。你引的那三条是我方文档里的建议口径,不是生效代码。所以新落点不是「继承」一条硬约束,而是第一次落地它——这反而是好事:约束怎么写、过滤规则是什么,可以在这次一起定,而不是背着一条没实现的口径往前走。建议:frontmatter 带 sensitivity 字段(信息展示),过滤语义并进「存储生命周期」issue 的可见性部分一起定。
其余现状核对(属实)
mirror-digest+ 更新时间三方合并、只吃 title/content)、export(只读、共用renderMirrorText)、工作区投影(不存在)——对。~/.dsh/memory默认值(config.js:9)、~/.dsh/mneme/运行时目录 + layout.js:79「便于整个删掉重来」——对。逐条拍板
1. 格式:只借 OKF 键名,不整体采纳。 OKF 的 one-concept-per-file 与我们的 type 分文件镜像形态冲突,且一条记忆一个文件 = 数千文件,Windows 写入/扫描成本未实测——你这条数据本身可能比格式更能定方向,我同意先实测。字段集以 #17 §五 草稿为底:memory id / type / scope(agent+workspace)/ sensitivity / updated / status / generated.by,键名对齐 OKF(
sources/generated/status可借),值域用我们的。2. 回流:第一批只做读方向。 title/content 回流保持现状(mirror-digest 三方合并已稳),元数据写回不做——字段权威归属不定,写回就是拍脑袋。归属表先定:
type是身份锚(去重键成员,文件不可改写);title/content/tags/importance 可写回;status: deprecated单向(对应归档,不回退);source 追加只读。这张表并进「存储生命周期」issue(我方欠的一个立项),定稿后元数据写回作为第二批。3. 目录:不迁
~/.dsh。 理由:layout.js 那句「便于整个删掉重来」是我们的原意,迁出与它直接冲突,且收益是感受层面的;memoryDir已是用户可配置键,想要用户目录的自己配。「放宿主私有目录 = 暗示用户别碰」用文档明示「镜像可编辑」解决,不动目录。记忆库留在~/.dsh/memory。4. 投影:重新排期,放第一批之后。 两个落点策略不必统一——同意你,而且理由比你说的更硬:全局镜像能双向,是因为
mirror-digest是我们自己定义的文件状态(三方合并语义由我们定);工作区投影长在用户的 git 仓库里,git checkout会覆盖文件、digest 语义直接失效。所以:全局镜像双向(现状)、工作区投影单向只读(#17 §五 原案:按 type 分文件、frontmatter 带 id/WorkspaceId/导出时间、agent 进 frontmatter 不建子目录、恢复走显式命令、按(type,title,scope)去重保幂等)。投影目录<workspace>/.mneme/在用户仓库内,与记忆库位置无关,不互相牵制——第 3 条不阻塞它。拆分与顺序
第一批就是「只读方向」:所有落点读到的形态同一套、能改回库的只有 title/content、sensitivity 过滤语义随存储生命周期定。投影从「不存在的第四件事」变成「已排期的第二批」,价值不变、风险可控。
关键判断:#278 拍板 = sensitivity 约束实为建议口径(首次落地而非继承);只借 OKF 键名;第一批只做只读导出、元数据写回等归属表;不迁 ~/.dsh;投影单向只读排第二批;前置先测 Windows 文件成本。
heptaspirit commentedon Sep 21, 2026
补一条更正,四批拆分收下
先更正:
sensitivity那三条隔离口径是我引错了,你说得对,代码里没有。照你指的位置我逐处复核了upstream/main,全部属实,且比你说的还干净:src/mirror.js与src/export.js的渲染路径无过滤,src/dream.js与src/dream/*无判断,src/service.js:105明写「sensitivity 是标签不参与可见性判定」。它今天真实的语义只有两条:去重键第三维(service.js:1154/:1165、document.js:117的 supersede 匹配键)与标签展示(tools.js:37/:72)。我把设计文档里的建议口径当成了生效实现,这个错误随正文一起传给了你。四条拍板都收下。其中「不迁
~/.dsh」我一开始想拧,看完理由认了:memoryDir本来就是可配置键,我这边真正要的是「用户知道能配」,那是文档的活,不是目录的活。投影那条理由我也认,而且确实比我原来给的硬:mirror-digest是自己定义的文件状态,投影长在别人的 git 仓库里,git checkout一覆盖 digest 就失效。前置那条实测我这边做,没有依赖,三档粒度一起量:5 个 type 文件 / 一条一文件 / 按簇分桶,每组都测全量重写、单条增量写、扫描与读取。
顺手先摆一个规模事实,免得「数千文件」后面被当成既定量级:今天的镜像只覆盖
store.list({ limit: 500, includeForgotten: false }),而list默认includeArchived: false(store.js:1234/:1310),归档根本不进镜像。「数千」要同时满足「含归档」与「一条一文件」才出现,眼下活跃集是 260 条。那个 500 的硬顶本身像是另一个独立问题:活跃数长过 500 之后镜像会静默截断。借这条再提一件相邻的事:配置说明缺一份
这次能发现自己忽略了
memoryDir可配,是靠你在回复里顺手指出。往前追一步,是我们参与开发这个项目的人自己就说不清一部分配置:上面那条引错的约束也是同一个来源,手边没有一处能查「这个键干什么、默认是什么、改了会怎样」,于是拿设计文档里的建议口径当了生效实现。我这边的开关状态一多半是「名字看着有用就开着」,答不上具体改变了什么行为。用户侧现在能查的只有 README 的「Quick config (optional)」一节;
dsh-mneme/docs/下五份(ENTITIES / LOCAL_MODEL / MIGRATION / SEMANTIC / SLEEP)讲的都是机制,不是怎么配。而配置实际分在两处,改法还不一样:src/config.js的 137 个键属宿主挂载时的插件配置,src/settings.js:177的 39 个功能开关存在库里的user_settings表(settings.js:7/:286/:292),没有文件可改。从这一脚往外看,需要的可能是单独一份配置说明,要满足几点:新增功能时跟着过一遍;用户能读到(面板里能打开?);agent 也能读到,好按用户的需求解释或者直接配。它和 #249 是一件事的两面——#249 管模型怎么用记忆,这一面管用户或 agent 怎么配记忆;同一个开关,两边说的应该是同一件事。形态、位置、要不要单独立项,你来定,我们只是希望它别排得太靠后:这一轮的混淆就是它缺位的直接后果。
heptaspirit commentedon Sep 22, 2026
前置实测:三档粒度的写入与扫描成本
环境 NTFS / C 盘 / node v26;内容用真渲染器
renderMirrorText生成,数据形状取本机库(活跃 282 条均 387 字符、归档 2638 条均 262);三次取中位数。三条读数:
建议直接排除「一条一文件」。 除了这个倍数,数千个小文件的维护面(重命名、手工编辑、diff、将来进了 git 仓库的投影)也会跟着涨,而它换来的东西在这张表里看不到。粒度不动的话现状够用;真要按主题切,按簇分桶是可选项。
表里的数只够支撑方向判断:缓存热、单进程、顺序执行,内容长度取均值,「簇」是顺序切 25 条而非真语义聚类(真聚类后桶大小不匀,只会更差一点)。
顺带撞见一个比粒度更早的问题
本机活跃库有 9 个 type,
TYPE_FILE(src/mirror.js)只有 5 个,两处落点都按它过滤:mirror.js:187只渲命中的 type,renderMirrorText对未知 type 返回undefined;/exportapi.js:1004-1006先按TYPE_FILE[row.type]丢行,:1008-1010再只遍历那 5 个键出节。本机分布是
pitfall69、constraint51、rejected_solution16、pattern7:282 条活跃里 143 条从不进镜像,导出的 markdown 同样少一半,没有任何提示。constraint与pitfall还是插件自己新增的 type,现在整类没有落点。第一批说「所有落点读到的形态同一套」,得先让所有 type 有落点。这条要不要并进第一批,你定。
索引这一层
文件化之后,跨 type 的「按主题找」没有入口,5 个文件就是全部。tag 的现状我核了:字段有、
memory_save收、镜像里渲成- **标签**:;但它在service.js与src/search/里只出现在去重、质量信号与叙事标签几处,没进检索权重。缺的更像是一个索引产物,tag 字段本身够用;而summary这个 type 已经是一个空着的索引位(TYPE_FILE.summary→summary.md)。这一层算第一批的一部分,还是并进第二批的投影?另外 tag 现在落在块内一行,要拿它建索引得先解析它;若第一批上了 frontmatter,它就落到文件头,外部工具与 agent 能直接聚合。
两处小修正
src/export.js不存在(src/下只有mirror.js),/export在api.js:977-1011。store.list({ limit: 500, ... })(service.js:1815)在活跃超过 500 时静默截断,本机 282 尚未触顶。modusensus commentedon Sep 22, 2026
@heptaspirit 实测收下——这张表把「数千文件」从猜想变成了读数,当初「成本未实测」的悬念可以关掉了。
拍板
1. 粒度:维持按 type 分文件,正式排除「一条一文件」。 330 倍的全量重写差距(6 ms → 1998 ms)、增量写毫无收益(三档都是 0.6–1.1 ms——现状的增量本就是重写所属 type 文件,热缓存下 3 MB 只要 1 ms)、再算上数千小文件在 diff / 手工编辑 / 将来投影里的维护面:它在这张表里换不到任何东西。按簇分桶记为后备选项,只在将来出现「按主题做文件级操作」的真实需求时再启用。你这份数据建议原样带进第一批的 PR 说明,省得后人重测。
2. 9-type 盲区:并进第一批,作为前置项。 你的判断是对的——「所有落点读到的形态同一套」的前提是所有 type 有落点,否则第一批做完,镜像与导出对一半活跃记忆仍然是盲的(你本机 143/282 这个数字本身就是验收理由)。
constraint和pitfall还是 v0.7.13 我们自己新增的 type,加的时候没接落点,这笔账该还。落点两处都要修:mirror 的渲染过滤(mirror.js:187一带)与/export的 byType 丢弃 + 节遍历(api.js:1004-1010);新增 type 的文件名按现有命名风格定,readHumanEdits走Object.keys(TYPE_FILE)表扩了自动跟上,但要补对应 type 的解析回归测试。顺带认领你两处修正里的第一处:src/export.js是我上一楼的引用笔误,/export逻辑在api.js,以你核的位置为准。3.
limit: 500截断:一并修。 镜像宣称覆盖活跃集就不能带静默截断,这和盲区是同一类问题(落点存在但覆盖不完整、无提示),放进第一批顺手处理,不单开。4. tag / 索引层:拆两半。 格式层进第一批——frontmatter 定下来时 tag 落文件头,外部工具与 agent 直接可聚合,这属于格式约定本身;检索权重化不进第一批——那是
search/侧的改动,有自己的验收线(检索质量回归基准),混进落盘批次会把两个本可独立回滚的改动绑死,第二批再议。TYPE_FILE.summary那个空索引位的观察很好,第一批定文件名时一并考虑去留。5. 配置说明:认账,我们来立项。 你描述的状态是真实的:
user_settings的 39 个开关存在库里没有文件可改,137 个 config 键没有一处汇总可查——这一轮 sensitivity 的混淆(你引错的建议口径、我引错的不存在文件,两端都中招)就是它缺位的直接后果。形态按你提的三点要求来:随功能更新维护、用户与 agent 都能读、与 #249 对同一开关说同一件事。单独立项,我们这边开单不让你背,开出来会链回这条线。第一批不与它耦合。第一批的验收范围因此更新为:落盘形态(含 frontmatter / tag 落头)+ 9-type 盲区 + 500 截断,粒度不动。你可以按这个范围出第一批的具体方案了。
heptaspirit commentedon Sep 22, 2026
@modusensus
第一批实施方案
范围按你的拍板:落盘形态(frontmatter + tag)+ 9-type 盲区 + 500 截断,粒度不动。
需要你拍四点
store.list默认不含归档,修好截断后归档仍不出现。建议不进,文件头写「活跃 N 条,不含归档」。type/generated.by/generated.at/covered/coverage/tags。实施
frontmatter 只能文件级,落两层:文件头放上列键;条目块沿用
## <title>+- **ID**:锚,按需补scope/sensitivity/status。逐条 YAML 会打断parseHumanEdits的锚点契约(mirror.js:74-82),不在这批。9-type 盲区:
TYPE_FILE补pitfalls.md/constraints.md/rejected-solutions.md/patterns.md(旧 5 个不动,改了会让磁盘上已有文件与 digest 失配);两处过滤(mirror.js:174/:187、service.js:1818、api.js:1004-1010)照表走;加断言「TYPE_FILE覆盖 store 全部 type」防复发,新 type 各补解析往返测试。500 截断:
service.js:1816的limit: 500去掉,文件头写清覆盖范围。要先解决的风险:
parseHumanEdits(mirror.js:111-113)的白名单是手写正则,渲染标签来自lang.js的mirrorLabel(zh/en)。今天两处逐字一致(已核,无脏数据),但加字段要改三处,漏一处该行就随/import写进 content。改成常量表单点定义 + 往返测试。不做
粒度;目录层级(继续平铺
memoryDir);第二个文件写入器(多一个可编辑落点=多一个 digest 合并面);元数据写回;tag 检索权重化。heptaspirit commentedon Sep 22, 2026
@modusensus 按这个范围做完了,PR:#288。三件事都在,粒度没动。
9-type 盲区:
TYPE_FILE补pitfalls.md/constraints.md/rejected-solutions.md/patterns.md(旧 5 个名不动),两处过滤随表扩自动收敛。document指针行显式排除(MIRROR_EXCLUDED_TYPES):镜像块渲染的字段里没有doc_path,落一个documents.md会得到「看着完整、其实找不到文件」的视图,它的落点归 #230 那条线;TYPES \ TYPE_FILE必须恰好等于排除集,测试双向钉住。文件头 frontmatter:
type/generated.by/generated.at/covered/coverage/tags。键名逐个对过 OKF v0.2:type是 §4.1 必填,generated.*是 §5.2 的 trust 族(generated.by按 §7 的 actor 约定写dsh-mneme/<版本>),author只在sources[]里当可信度信号、不是顶层键,updated在 v0.2 里不存在(§13.1 已用generated.at取代 v0.1 的timestamp)。covered/coverage是我们自己的扩展。条目级元数据仍在块内,并按你拍的清单补齐:ID/类型/重要性/标签/更新时间/来源/作用域(agent / workspace) /敏感度(后两者有值才渲染);status没有对应列:OKF 的status: deprecated对应归档,属写回语义,跟第三批的字段权威归属表一起定。块内逐条 YAML 会打断 import 必须吃回 export 的锚点契约,所以不走那条路。sensitivity 按讨论的结论只做信息展示,过滤语义不在这里落地。500 截断:改
store.all()+ 同一套!forgotten && !archived(不能只去掉 limit,store.list的默认值是 50)。代价是全表读落在最热路径上,要压得换按 type 分页,属另一批。自查与一次单盲审查各抓出两条,都已修:① 无条件重写会让
generated.at在每次业务写后改掉全部镜像文件的字节(编辑器会提示「被外部修改」,进行中的手工编辑有被冲掉的风险),现在内容没变就不落盘;② markdown 导出原先是 9 段文件头串在一个.md里,只有第一段是真 frontmatter、其余type:/tags:会变成正文段落,所以改成一份文档级 frontmatter(coverage: all,如实声明含 archived/forgotten)+ 分节。summary那个位的去留一并答了:留着。它装的是 dream 生成的叙述条与状态摘要,有真实内容;删掉它就得进排除集,那才是真开盲区。读数:
node --test1292 / 1291 pass / 0 fail;check-syncsrc↔lib 一致(44 文件)。另有一处同类盲区想请教:service.js的INJECT_TYPES、summarize.js的VALID、tools.js的 enum 仍是 5-type 字面量,本批范围只钉了 mirror + /export,所以没动。要不要另开一批,你定。heptaspirit commentedon Sep 22, 2026
@modusensus 第一批的范围之外,想补一个「第二类落点」的问题:document 型记忆的全文放哪。
现状:注册只校验「绝对路径 + 文件存在非空」(
src/document.js:52-76),没有落点约定,也没有对应的配置键(目录相关的键只有memoryDir)。也就是说doc_path是一个自由字符串,放工作区、放临时目录、放哪都收。文档一多,库里是一堆摘要行、文件系统里是一堆 md,两边都靠记忆找。本地实测(我在自己的实例上把一份整理稿按 document 型注册,再搬家一次):
action: superseded,旧行归档并追加[superseded by <新行 id>],旧摘要进content_history(document.js:132-133的同路径/同标题匹配)。DOCUMENT_MIN_SIM = 0.92,:139-159),按设计是防「搬家变成留两份互相漂移的指针」。这条我赞成,别绕过。会怎么乱(按后果排):①路径散落,每次都要重新决定放哪;②把工作区路径写进
doc_path,仓库改名/移动后指针全废,而且注册之后再没有任何地方读那个文件(全库只有:73一次statSync),所以文件缺失与摘要漂移都没有检测点;③没有索引,文档多了无法浏览;④supersede 匹配带scopeKeyOf,跨 scope 永不互判,同一份文档换工作区重注册会留两份指针行。一个提案(供讨论,不是方案):加
documentDir(默认<memoryDir>/documents/,跟memoryDir可配置),配两级规则:<YYYY-MM-DD>-<slug>.md,按 workspace 再分一层);index.md(按 OKF §8 的渐进式披露列 title / doc_path / 摘要首句 / updated),让文档多起来仍可按需读取。想请你拍四点:①要不要加
documentDir这个键;②managed 目录要不要 mneme 来建(今天是「管线对文件零读零写零改」,建目录算不算越界);③index.md谁来维护(一碰自动写文件就回到写入权分离的边界);④文档要不要在镜像/工作区投影里有一个只读视图(今天 document 行被MIRROR_EXCLUDED_TYPES排除,镜像里看不到任何文档)。要不要单独开 issue、或并进哪个批次,你定;我这边先把实验记录留在本地。
modusensus commentedon Sep 23, 2026
@heptaspirit 单开 issue,跟 #230 那条线走——第一批已经做完在 #288,不再往里塞。四点先给方向,开单后正式拍:
documentDir加。 路径散落、每次重新决定放哪是真问题;默认<memoryDir>/documents/跟memoryDir可配置的结构也对。index.md和镜像 md 同权(机器所有产物)。真正的红线是不碰 external 路径的文件,以及 managed 文件的正文内容。index.md整文件机器所有。 不给手工编辑面,「谁维护」的问题就不存在;要人工批注,进记忆库,不进 index。doc_path;等 [Feature] document 型记忆:agent 产出的长文档入库——注册校验、摘要+指针落库、supersede 记账 #230 线把doc_path纳入渲染字段后随MIRROR_EXCLUDED_TYPES复审——有测试钉着,去留都是一行的事。supersede 跨 scope 不互判那条,连同你「别绕过 C2 门」的立场一起带进单里,那条设计是对的。
feat(mirror): 补落盘盲区、文件头 frontmatter 与无上限覆盖(slow-stack#278)
Merge pull request #288 from heptaspirit/feat/278-file-format
fix(store): 写路径按需取列,不再为 20 条正文物化整库(issue slow-stack#430)
modusensus commentedon Oct 20, 2026
现状(2026-10-21 对照
main实测)正文没有勾选框,是纯设计帖。实测:目录形态与镜像已落地,
~/.dsh迁出未做。已落地
dsh-mneme/src/里mirror出现 110 次;lib/client.js里 51 次(面板健康卡)。2f038eafeat(mirror): 补落盘盲区、文件头 frontmatter 与无上限覆盖([Feature] 记忆落盘形态与目录归属:镜像、导出、工作区投影的统一与迁出 ~/.dsh #278)。memoryDir28 次命中,config.js里是顶层键。projection在continuity.js:102、inject.js:23有处理(宿主的_assertProjections约束)。未落地
~/.dsh迁出:migrateOut/exportMirror均 0 命中。当前默认仍在~/.dsh/mneme(注意:那是 embedding 模型缓存与 onnxruntime,不是记忆库;记忆库在~/.dsh/memory/memory.db)。memory_list/memory_search有include_archived,但没有「整库导出」入口)。还缺什么
~/.dsh下挪到可配位置,并提供迁移工具(含回滚);~/.dsh/mneme(模型缓存)当成记忆库——这个坑我自己踩过。接手建议
这条的三个子项互相独立,建议拆开。最容易先做且收益最高的是第 3 条(目录归属文档),因为它防的是真实发生过的误解。
docs(directories): 目录归属总账(#278) (#624)
modusensus commentedon Nov 11, 2026
按 2026-10-21 盘点的三个子项收口:
已落地:
2f038ea(补落盘盲区、文件头 frontmatter 与无上限覆盖);~/.dsh/mneme(模型缓存)与~/.dsh/memory(记忆库)这两个易混名字拆开了;memoryDir本就可配(顶层键)。剩余两环拆出:
~/.dsh(迁移工具含回滚 + 默认值口径)→ #NNNA维持搁置: 工作区投影(
<workspace>/.mneme/,#17 §五的回调草稿)——它与迁出互相牵制,库的位置定下来再议;若立项单开 issue,frontmatter 口径以 #NNNB 为准。本 issue 关闭留作设计帖索引;原正文对 Open Knowledge Format、回流权威归属的分析在两条新 issue 里各有承接。