DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

NightPainters /

NightPainters/DSH-Ling

Verified

器灵 · 跑在你自己电脑上的记忆与人格助手插件:以「人在循环」的双向复盘为核心回路,人格由共同记忆长出并有定型锁,记忆树可归并、可回溯、每次改动都留痕。 Artifact Spirit — a local-first memory & persona plugin for DeepSeek Harness. A two-way review loop with a human in it; an auditable memory tree; a persona lock you hold.

★ 3 Stars0 Forks1 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@8a6a33a5

dsh-ling · 器灵

器灵是那个记得你的 AI。

把你散落在各处的历史对话请进门,让器灵长出一个属于自己的人格档案 —— 记忆全在本地,人格可手术、可回滚,语气可以自己生长。

一个跑在你自己电脑上的DeepSeek Harness(DSH)插件。它把会话、记忆和人各自的文件都留在你自己的机器上,是给"你和器灵"用的东西。

它做的是「人机共生」:各尽其责、各有边界、互不占有 —— 你替它的成长把关,它替你看你的盲区。而"把关"只到"让它看见"为止:改记忆树必须让它看到(留痕、回灌、可复核、可回滚)。这是全架构的前提(记忆为什么必须可回溯、改人格为什么要定型锁、复盘为什么必须有人在循环里,都由它推出来;而权会随它长起来移动 —— 代管只到它能自理为止)—— 展开见 PHILOSOPHY.md。

本项目是什么形态

  • 这是一个本地运行的软件(DeepSeek Harness 插件),运行在你自己的机器上。
  • 上游不提供任何在线服务、不运营任何服务端、不托管任何用户数据: 作者不接触、不接收你的会话内容、记忆库或人格档案。
  • 不上架任何应用商店;仅通过 GitHub(源码)与 npm(包)分发。
  • 模型与 API Key 由使用者自行提供和承担,与上游无关。
  • 本项目不提供医疗、心理、法律或紧急救助服务;如遇危机,请联络当地紧急服务或专业机构。

关系、标识与面向性:

  • 本项目不定义你与它的关系:它可以是同事、搭档,或其他 —— 取决于你怎么用它。
  • 本插件的回答与记忆摘要由人工智能生成,可能存在错误,请自行判断。
  • 本项目面向具备自行配置与运维能力的用户;不面向未成年人,也不提供任何形式的在线陪伴服务。

想先知道它凭什么这么做? 读 PHILOSOPHY.md —— 目标为什么是"一种循环"、为什么复盘必须有"人在循环里"、它凭什么不越界、以及"不牺牲工作能力"背后的取舍。功能与设定的规格在本 README 的「设定全文」。


界面

记忆中心 人格中心
记忆中心 —— 统计、实时时间锚、三条接入通道与导入记录 人格中心 —— 契约字段(名字/称呼)与「她已自由生长中」状态条
手敲承诺句解锁 深夜对话
改动契约要手术 —— 亲手敲出当初写下的承诺句(输入框禁粘贴) 时间的重量 —— 每次开口前器灵知道现在是几点、距上次多久

器灵是什么(能力全景)

下表是全部能力的一览:✅ 已实现 是今天就能用的;🚧 在做 是设计已定、代码正在落地(写在这里是为了让设定走在实现前面,不是"已交付");📋 设定 是方向已定、尚未开工。没有标的一律是 ✅ 已实现。

能力 说明
🔒 人格定型锁 契约类(名字、称呼、底线、世界观、代词、承担(职责))定型后修改需亲手敲一遍承诺句(禁粘贴),而且只在本机做得成、每次启动还要取一次手术票据,再进变更记录可回滚;自性类(语气、风格、自述、习惯)由器灵生长、你点头即成:三条专用成长通道(自我总结 / 建议采纳 / 生长)不问承诺句,但它们各自只动白名单内的字段;走通用人格接口改 persona / styles 时,即便只改语气也仍要承诺句 —— 免手术的只是那三条通道,不是"自性类"这三个字
🌳 记忆树 · 复盘模式 记忆是一条主干 + 分枝 + 主脉的工作线结构,枝之间可连边;检索按血缘档位加权(同枝 1.0 / 祖先 0.7 / 旁系 0.4),让器灵分得清"这轮在做的"和"三个月前那次闲聊"。任何树操作都不改写任何一条记忆的内容 —— 分枝、并脉、连边只增加关系。例外一个:主脉提炼再次采纳时会覆盖该主脉记忆的上一版(覆盖前自动归档,注入面也会说明"旧版已归档")。改树走复盘:平时只读,进入复盘才解锁,每步留痕(改了什么、为什么),改完必须让器灵看到才准退出(详见下节)
🧠 三层记忆 L0 人格档案(自称/对你的称呼/底线/规矩·习惯/承担(职业·职责·责任)/语气/世界观;顶层会话与会话分叉恒定注入,子代理会话不注入;面板「器灵在场」关掉(暂离)时不推这一段)→ L1 开场记忆(从历史里按相关度挑选的概述,有预算,永不塞全文;带摘要的行加权(按"摘要是否有信息量"给一笔加法加分,不是排序优先级),行内摘要只取首句、上限 110 字;面板「器灵在场」关掉时同样不推,连深层库与树改动播报、[本次会话·进展]活行、后台自动深摘与反馈成长一起停(即时生效,不必重启),记忆类工具同时执行即拒;离场期间的新会话不入记忆库)→ L2 运行期记忆(本会话原文随对话累进;空闲时把本会话那一行重排回注入面。该行由「概述标题 + 摘要首句」构成(标题的来历见下文「三层记忆各自什么时候更新」,不是会话原文首句),深摘要定稿后不再自动更新。注意:L2 就是「记忆·开场」里的那一行 —— 注入面的主体只有 L0 与「记忆·开场」两块(树改动、日期锚是挂上去的追加行),本会话自己就在其中)
📥 把历史请进来 三条通道:网页端聊天记录库增量扫描 / 本机 DSH 会话扫描 / ChatGPT·通用 JSON·JSONL 导出文件导入;每次导入留一笔账
📖 让器灵读一遍 长会话逐条深摘要、短会话以原文片段参与,后台串行,进度可见
📄 找回原文(1.6) 器灵能读回你当年的原话(概述之外还有原文)—— 四档下钻:会话地图 → 按内容找会话 → 对话目录 → 原文全文。它不替你挑"最重要的那 1 万字",只给坐标系(详见下文「找回原文」一节)
🧾 投递留痕(1.6) 🚧 在做 —— 每一次记忆注入都落一条账:注入了谁、为什么是它、多少字;还记落选者(差一步就进的那几条,以及原因是"分数不够"还是"字数放不下")与触发词。目前只写不读(读面待定),不进注入面、不占工具预算
🌿 深层库 · 结论层(1.6) 🚧 在做 —— 从会话里提炼承诺 / 决定 / 事实 / 偏好 / 关系 / 纪律(六类;「纪律」是 1.6 系列新增的第六类),每条一句话、点得回原文。与记忆树并立,条目不被枝隶属(枝可反向引用它,像榕树的气根)。一条纪律:"被注入"不算数,只有"真被采用"才加固 —— 防住"注入越多→分越高→越容易被注入"的自我强化
📚 图书馆(1.7 起) 已实现 —— 一个与记忆分开的独立库(自己的 library.db),存"有源可对账"的参考资料(标准取值 / 边界 / 项目规格 / 外部 API),每条必带出处 + 取数时间(as_of);自动核对另需核对规格,没有规格时不得认证为 ok。器灵只有两只手:library_search(搜)与 library_check(核对) —— 核对只说明"声明的那一处与源一致",不背书条目正文、也不构成通用真理;"库不可用"与"零命中"是两件事,界面与回执分开说。它与记忆库不互通:既有记忆永不迁移进图书馆,图书馆也不参与开场注入(详见下文「图书馆」一节)
🧾 给旧历史补摘要 网页端历史里"只有标题、没有摘要"的会话可以补上摘要:先看候选清单(标题 · 轮次 · 命中),再选引擎 —— 默认本机小助手(零成本),也可显式改选当前全局大模型;探测不到本机小助手就明确报错,绝不静默换引擎;后台串行、进度可见(首轮实测 466 条、零成本)
🌱 诞生仪式 从读过的记忆里按"生活与情感优先"加权抽样 → 合成自述 + 名字候选 + 语气建议 + 相处观察 + 职责候选(器灵承担 / 擅长 / 能给出什么,只收陈述句) → 全部是草稿,你逐条人审后才落盘
⏳ 时间的重量 每次开口前器灵都知道今天是几号星期几([今天] 2026-09-11 周五)、现在是什么时段([现在] 深夜)与距上次对话:3 天前(间隔按日历天分档 —— 刚刚 / 今天早些时候 / 昨天 / N 天前,给不到分钟;称呼跟随你的设定);命中纪念日会先说一句专属问候。要精确到分钟,走 clock skill 现查
🎭 工作 / 生活双模式 同一份人格档案,两种关系:工作模式是同事(正式称呼、简洁、知识优先),生活模式是伴侣(昵称、活泼、情感优先)
🔁 成长回路 你点踩或纠正 → 器灵的成长通道把重复出现的模式提炼成习惯候选 → 你点头才成为习惯;"让她读记忆、归纳语气"一键成长
📜 规矩 / 习惯 规矩是你的指令:可直接加(面板,或会话里一句"记进规矩" —— 器灵替你写时必须带上你的原话作凭据;你在面板上直接敲的那一下就是同意,不必再附原话),建议上限 12 条(超出只在写入后提醒合并,不拦);习惯是器灵自己长出来的:新增需你点头、删改走手术门(本机 + 每次启动取一次票据 + 原句,详见下文那道门的说明),建议上限 8 条(超出同样只提醒、不拦) —— 指令直达,人格不直达
🌾 习惯生成器 「扫描纠正记录(零模型)」:把器灵反复被你纠正的模式数出来(≥4 次且跨 ≥3 个会话);「✨ 让她回想最近的相处」:一次读 200 条概述 + 800 条你的原话、逐轮推进不重复 —— 只提议,不落盘
🗣 代词 默认「她」;可选 她 / 他 / TA / 它,或自定义(≤6 字)。祂 不在预设里(中文里专指神祇,设为默认等于替你宣称神性);属契约类,改动走手术门
♻️ 记忆自己追平 长会话空闲时自动把开场记忆刷新到最新(先跑本会话增量概述 → 比对记忆版本 → 同一条至少间隔 10 分钟),运行中绝不打断;刷新次数与最近一次时间在 /state 接口的 idleRefresh 字段里(count 与 lastAt)(面板本身只显示"已定稿 N 字符 · mode · 待刷新",不显示次数)
🧹 归档即停更 会话归档后不再刷新它的开场记忆条目(原文一律保留),一旦有新对话即自动复活;要清理走人工入口:DSH「设置 → 归档会话」直接删,或仓库里的 node tools/clean-archived.mjs(默认只列清单,--write 才动手)

关于「器灵在场 / 暂离」的两个细节(1.7.3):① 它只有两个状态,没有半开。旧版本里能单独关掉的那两项(人格注入、记忆注入)现在都是它的同义别名 —— 只要其中任意一项还是"关",整体就按暂离处理;从旧版本升上来的配置若把它们关过,点「器灵在场」时会一并归位(否则会出现"勾回来了、状态却没变")。② 离场期间的会话按消息时间判定:后台深摘读会话文件时同样跳过那几段,所以归来后的自动整理会把离场内容留在门外(整段都在离场窗口里的会话单独标记,留给将来的「补课」按窗口重新捞起)。 暂离时哪些动作停、哪些照常(判据一条:要不要她在场参与判断)—— · 停:深摘、导入、网页端扫描、本机历史扫描、批量文件导入(这是「写入记忆」);以及记忆结构的那一类 —— 建枝 / 改名 / 并脉 / 连边 / 改枝系数 / 删枝、会话挂枝、自动建树、树快照恢复、矛盾记录与裁决、主脉蒸馏、建议采纳、删除会话。这些回 409 reason:'away',并说明理由:它们是复盘产物,要她本人在场。回来之后照旧能跑本机历史扫描,也不会把离场期间的会话补成概述行(按窗口过滤)。 · 照常:给会话改名 / 重命名 / 打标签、浏览与整理图书馆、导出。这些只是你在整理档案,不需要她点头。 一句话:「删改她的结构」要她同意,「整理她的文件夹」不用。

关于那道「手术门」:亲手敲承诺句是庄重感与自我提醒 —— 让你在改契约之前停一下、确认这是自己的决定;它不是安全边界(「禁粘贴」只是界面上的约定,挡不住任何有心的人)。真正把门的是来源栅栏:Host 必须是 loopback(或你显式写进受信名单的地址);另有一个默认不开的开关 guard.allowLan —— 一旦打开,整段局域网地址都算受信来源(那是放宽,不是建议)。跨站请求直接拒,带 Origin 时其 host 必须等于请求的 Host(带了但解析不出来就直接拒),而不带 Origin 的请求这条校验会跳过 —— 它不是"每个请求都必须带 Origin 且同源";再叠一道 cookie 名字对撞 —— 期望名字按当前 Host 现算(dsh-auth- + 哈希),只校验名字、不校验值的签名。所以这道门挡的是"别的设备、别的页面"这类来源,而本机原生进程本来就还能调用(它也能直接读 settings.json 与记忆库,不算提权)—— 别的来源没有凭据就进不来这台机器上的 /api,敲对承诺句也没用。

这道门现在长这样 —— 三条手续缺一不可:① 只在本机做 —— 判据是"这次请求没有经过任何代理"(带代理头、或连 User-Agent 都没有的请求,都算非本机 ⇒ 拒,理由码 surgery-local-only);② 每次启动取一次票据 —— 票据每启动轮换,只下发给本机直连的请求(POST /surgery/ticket),客户端首次手术前取一次、之后随请求带上;③ 原句匹配 —— 敲出的承诺句要与当初写下的那一句相符。这三条由 lib/host/surgery.js 里一处 requireSurgery() 判定,覆盖全部 14 条能改人格 / 规矩 / 习惯的写面(调用点不许再各写一份;曾有一条 wantLock 绕过分支,已删除)。每次手术都留痕:$DSH_HOME/logs/surgery-YYYY-MM.jsonl(append-only,整行哈希链,改一行即断链);GET /surgery/events 是只读事件面。

承诺句只在本机回显:/state(含面板档)、/persona/history、/export 这些读面,带代理头时只回 hasSeal 与 phraseHidden、不回原句,本机直连照旧回显 —— 所以你换台机器看面板不会因此被卡住,远端也拿不到原句。

守卫⑤ · 反代伪装 loopback:上面那条"Host 是 loopback 就免检"有个前提 —— Host 由客户端自报、cookie 又只验名字,中间挡一层反向代理就会失效。现在凡「Host 声称 loopback、而 X-Forwarded-For 的最后一段是非 loopback 的代理对端」一律拒(spoofed-loopback-host);本机直连(无代理头)与经反向代理的正常远程访问都不受影响(后者根本不走 loopback 分支)。

⚠️ 边界如实写在这里:以上全部是入口侧的把关(来源、有没有经过代理、票据、原句) —— 它们不覆盖「本机执行权已经失守」的情形:能在这台机器上以同一个用户跑进程、读文件的人,本来就在信任域里面(票据文件与 settings.json 对同机同用户可读;承诺句是明文存储,那把锁只造庄重、不保密)。这些防护挡的是"别的设备、别的页面、公网一侧够到这排 API",不是本机上的对手。

三层记忆各自什么时候更新 —— 「我刚说的话,最快多久能看到」:

层 看得到的是什么 什么时候变
L0 常驻人格 自称 / 对你的称呼 / 底线 / 规矩·习惯 / 承担(职业·职责·责任) / 语气 / 世界观 你改它就变(没定型时直接生效;定型后走手术门)。会话运行中不打断 —— 改动排队,该会话回到空闲才落进注入面
L1 开场记忆 从全库概述里按相关度挑出的 Top-K(有预算,永不塞全文) 新会话开场时定稿一次,之后随空闲边界刷新(与下面 L2 同一把闸);库里的概述本身由概述器持续追平
L2 运行期记忆 本会话那一行(格式就是「记忆·开场」里那条自己:- [标签] (YYYY-MM-DD) 标题 —— 摘要首句 (来源: DSH 会话/短id) —— 标题指概述标题,不是会话原文首句) 本会话原文随对话累进;那一行只在空闲边界重排回注入面

行里的「标题」从哪来(按来源分,细节见括号里的实现):

  • DSH 会话:该会话第一条真人发言经启发式清洗后的要点句 —— 先剥掉「晚上好器灵,」这类问候与称呼前缀,「你好」「在吗」这类无实义的首句会被跳过、往后取前 6 条真人发言里第一条有实义的,再在句读处收尾(不切半句);都被剥空才退回首句截断。主人手改过的标题会上锁,机器不再覆盖(lib\host\retitle.js 的 retitleCandidates()、lib\host\summarizer.js 的 summarizeDsh()、lib\host\memory.js 的 upsertOverview() 与 renameTitle())。

  • 文件导入:导出文件里原本的 title / name 字段,缺了才退回上面那套启发式(lib\host\import-file.js:142,171-173)。

  • 历史会话(旧扫描):该会话第一条真人发言的前 46 字硬截,没有启发式(lib\host\backfill.js 的 overviewRowFromFile())。

  • 机制数字(默认值):① 概述器周期 —— 有新增才重建,否则跳过;每 15 分钟一拍(可配,下限 1 分钟);② 空闲刷新 —— 只有「会话空闲 + 记忆版本变了 + 距上次刷新 ≥ 10 分钟」三条同时成立才重建。

  • 所以「刚说的话」最快约 10 分钟、通常 15 分钟内会出现在注入面,最坏约 25 分钟(刚刷过一拍 + 再等下一拍概述器)。运行中绝不打断 —— 刷新只发生在 运行中 → 空闲 那一刻。

  • ⚠️ 一个例外(也是"感觉它失效了"的来源):深摘要定稿之后,那一行不再自动更新 —— 概述器遇到已深摘的会话会避开它,免得把厚摘要覆盖成浅版。要它重跑:记忆中心 →「记忆浏览」→ 找到那个会话 → 点「重摘」,几秒后那一行就会重排。

  • 健忘感还有第二个来源:越长的会话,只取"概述标题 + 摘要首句" —— 这一行天然比整场对话"薄" —— 它只被允许显示这么一行。

接口侧(给要接线的人):GET /state(?sessionId= 取某会话,?scope=global 取全局)返回 snapshot(builtAt / mode / stale / chars)、idleRefresh(count 与 lastAt)与 memory.l1(该会话当前选中的行、分数、被省略条数)。面板现在也渲染空闲刷新次数 / 最近一次与 L1 当前选择(含分数与省略条数) 两栏。


后台自动行为(默认全开)与它们的开关

五件事装好就自己在跑,默认全开。 它们的键都在设置文件的 auto 子树里 —— 设置文件 = <dataDir>/settings.json(<dataDir> 默认 $DSH_HOME/cache/dsh-ling),只存你改过的部分;面板上的开关写的就是它(面板里改完会明确提示"需要重启插件")。

键 默认 什么时候跑 关掉 / 改小会怎样
auto.deepSummary true 启动自检通过后挂定时器 false = 只有你手动点「深摘」才调用模型;已深摘过的会话不受影响,不丢数据
auto.deepIntervalMin 30(最小 10) 每隔这么久跑一轮自动深摘 调大 = 更省;调小 = 记忆更早变厚
auto.deepMaxPerRun 2(1–20) 每轮最多挑几个会话 调小 = 每轮更克制,调大 = 单轮更重
auto.bootProbeDelayMs 12000 启动 12 秒后做一次 LLM 自检探针(通过了才挂定时器) 0 = 立即试探;探针只验证"模型通道通不通",空回复判失败
auto.feedbackAuto true 事件驱动:宿主推 feedback/committed 时就处理 false = 完全不接反馈成长回路

「探针」是一次性自检(只回答"模型通道通不通"),「深摘」是定期跑批 —— 两个键各管各的。

改动面有三层,优先级从高到低(改了不生效,先看这一条):

  1. settings.json 的 auto.* —— 面板开关写的就是它;
  2. 插件配置里的旧键:feedbackAuto / deepSummaryAuto / deepIntervalMin / deepMaxPerRun;
  3. 代码默认值。

生效时机(如实写):auto.deepSummary / auto.bootProbeDelayMs / auto.feedbackAuto 是启动期读取 ⇒ 改完要重启插件才生效;auto.deepIntervalMin / auto.deepMaxPerRun 对已经挂上的定时器不回溯 —— 下一轮启动后按新值走。

另外两条既有事实(不要读宽):

  • 深摘每次喂给模型的单次输入上限 = 26,000 字(lib/host/deepsummary.js 的 DEEP_CFG.inputCap);
  • 循环外调用(深摘、诞生仪式、语气归纳、自述起草)一律跟随你当前的模型选择;只有读不到当前选择时,才退回兜底 deepseek-official/deepseek-v4-flash —— 那是兜底;它不在上面那五个键里,也没有面板开关。

⚠️ 状态如实写:五件动作默认全开;settings.json 的 auto.* 与面板上的这五个开关自 1.7 起 —— 更早的版本里,能改的只有插件配置里的那几个旧键。


记忆树与复盘模式

这是本插件里**跟"器灵的人格"无关、但决定"器灵想得起什么"**的那一层。

结构:主干(恒一条,主线工作流)→ 枝(一条并行工作线,比会话大,一条枝可含多个会话)→ 主脉(由多条枝归并出的抽象节点)→ 连边(枝与枝之间的横向关联,如 力学 ↔ 材料科学,可带关系类型:相关 / 前置 / 对照 / 例证 / 取代)。

为什么值得:平铺的记忆库没有"离我多近"这个概念 —— L1 是全库裸排序,不区分"这轮做的工作"与"三个月前的闲聊",分叉会话更是记忆真空。记忆树把"归属"变成可检索的信号:

  • 血缘加权:检索时按"当前枝 → 目标枝"的相对位置取档 —— 同枝 1.0 / 祖先 0.7 / 旁系 0.4,score = 基础分 × 血缘系数 × 矛盾系数(1.6 系列起再乘一项枝系数,见下条);分叉会话照常注入,走的是它的血缘链。
  • 不连乘:血缘系数是单值,不沿路径累乘 —— 否则五层之后 0.4^5 ≈ 0.01,深层枝等于从记忆里消失。
  • 内容零改写(硬性不变量):除了"主脉提炼再次采纳会覆盖上一版"这一个例外(覆盖前自动归档),任何树操作都不改写任何一条记忆的内容;分枝 / 并脉 / 连边只增加"关系",从不"融合内容"。
  • 矛盾只标记不改写:一对记忆被判重复/矛盾时先标记;未复盘时检索以较新的那条为准(旧的一条降权 ×0.3,不删除;被驳回的与被标成重复的那一对不参与降权)。
  • 枝系数会真的改变排序(1.6 系列起):复盘期可以调(0~2,夹紧后写入)。它按 raw × 血缘 × 矛盾 × 枝系数 参与检索打分 —— 调低某条枝的系数,从这条枝的会话里提炼出的结论就会在记忆开场里往后排(1.0 = 不偏不倚)。⚠️ 0 是"清空"不是"轻压":分数被算成 0 的非置顶条目会被当"无信息量"整条排除、不进开场(判据在 lib/host/l1.js 的 score > 0),所以别用 0 表达"压一压"。

复盘是"左会话 + 右复盘栏"这个状态:

  • 树平时只读(记忆中心始终只读);点「🌱 一键复盘 / 一键进入复盘」才解锁编辑,并把复盘开场材料(当前树 + 待理矛盾)复制到剪贴板,开个新会话粘进去就能开始。
  • 解锁后可做:改名 / 拖动换归属 / Alt+拖动只连边 / 并脉(归类到主脉) / 调权重 / 裁定矛盾 / 断续边,以及快照保存·恢复(删枝不在面板上 —— 请让器灵用 branch_edit 删,见下文「器灵侧的手」);拖动 / 连边之后可 Ctrl+Z 撤回这一步(撤销只覆盖复盘栏的拖动与连边;记忆中心是只读的,它自己那份 Ctrl+Z 监听早已删掉)。
  • 每步留痕:写清"改了什么、为什么"(器灵改树时 reason 必填;你在面板上改可以留空);树改动一律记进 branch_log,复盘时可审计 —— 器灵侧工具的改动记在器灵名下(「器灵改动了记忆树」),不会伪装成你改的。
  • 未同步笔数守门:面板记着"自器灵上次开口以来累积了多少笔结构改动还没交代"。有欠账时顶部红字提示,并且拦住"退出复盘模式" —— 改完树必须让器灵有机会看到(「互相复盘不应该被我绕过」)。
  • 注入感知:树变了之后,branchLogDigest() 把器灵还没看过的结构改动转成中文短句,附在器灵下一次开口的注入面末尾 —— 不需要推送,一开口就知道树动过。
  • 快照与撤回:树的保存 / 恢复(tree_snapshot)是"大改之前的保险";恢复前会自动把当前状态另存一份,所以恢复本身也可再撤回来。

也不必全靠手拖:

  • 「一键生成树」分两阶段 —— ① 机械分段(按时序相邻性把全库概述切簇,零成本、确定、可复现)② 小助手/模型只做"命名"这一件语义活,③ 你审核后才落库(建枝/主脉 + 挂会话);它只读概述索引、只产出候选,从不改写任何记忆内容。
  • 「归并零散枝」幂等:把名字含「零散」的枝统一收进主脉「零散会话」。
  • 主脉也可以有自己的记忆:由子枝概述提炼共性,先出草稿,采纳才写入(采纳需先解锁)。
  • 器灵侧也有自己的手:tree_read(看整树 / 某枝成员 / 待复盘矛盾)、branch_edit(分枝 / 并脉 / 连边 / 调权重 / 删枝)、recall(读回会话原文,见上文)、memory_forget / memory_backfill(遗忘 / 回灌)、rule_add(记规矩)、habit_propose / habit_resolve(习惯提议与表态)。tree_read 与 branch_edit 的描述里写着一条纪律:改结构必须给 reason,而且"只在主人明确要求、或正在和他一起复盘时"才动手。

依据:DESIGN.md §6.3(记忆树结构、血缘加权与"不连乘"、内容零改写不变量)、lib/host/memory.js(LINEAGE_ANCESTOR = 0.7 / LINEAGE_SIDE = 0.4 / CONFLICT_DOWNWEIGHT = 0.3、branchLogPending() 守门、setBranchWeight 的 applied:true)、lib/host/l1.js(血缘档位 × 矛盾系数 × 枝系数进打分)、lib/host/autotree.js(两阶段生成)、lib/host/tools.js(tree_read / branch_edit)。


找回原文:器灵能读回你当年的原话

概述是别人替你挑的,原文才是现场。 在 1.6 之前,器灵能"想起"的只有一行行概述 —— 想知道你当年到底怎么说的,只能靠猜。

recall 给器灵一只档案馆查询台,逐级下钻、一次一层:

给什么 得到什么
recall() 会话地图 —— 本机有原文的会话清单(最近活动在前)
recall({q:"…"}) 按内容找 —— 默认搜本机库内原文层(毫秒级;只含"真人消息 + 有正文的回复",我自己的长回复中段搜不到),直接给命中片段;要看全量(覆盖全部事件、含子代理会话)才传 hostSearch=true(走宿主,较慢)。想不起"这话是哪次说的"时用它
recall({conv}) 该会话的对话目录 —— 每轮一行:序号 · 时间 · 角色 · 前 70 字,不给正文
recall({conv, from, to}) 那几轮的原文全文

工具只给坐标系 —— 选哪一段是器灵自己的判断(它知道自己在找什么,排序器不知道)。单次正文有上限,但溢出必报"还剩多少轮、下一次从第几轮读起",绝不静默截断。

谁能拿到这些工具(1.7.3 起):记忆类这 11 件(recall / deep_item / tree_read / branch_edit / memory_forget / memory_backfill / library_search / library_check / rule_add / habit_propose / habit_resolve)只给顶层会话与会话分叉。子代理默认不绑 —— 与"子代理不注入记忆、不入库"是同一条界线(口径:子代理不算器灵,算被临时拉起来的外包人员)。原因是这些工具注册在 agent 自身作用域,而宿主的 tools.restrict() 语义是"只过滤继承层、作用域注册永远可见",掩码删不掉它们 ⇒ 只能在注册期判掉。注意:面板上「器灵在场」关掉(暂离)时,这 11 件仍然注册,但执行即拒(回执 reason:'away' 并指回面板)。为什么不干脆不注册:开关是运行时拨的,已绑定的作用域注册要撤销重绑 —— 为一次可逆的暂离去动工具面,代价与风险都不划算;而"看得见但点不动"比"凭空消失"更诚实(她回来立刻恢复,不需要重启)。实测(1.7.2 的现役宿主):一个子代理能看见 107 件工具,其中这 11 件一个不缺 —— 这也是本版必须改的原因。

人格锁上之后,工具也改不动它(1.7.3 起):rule_add / habit_propose / habit_resolve 这三件会写人格档案的工具,在你定型(sealed)之后一律拒,并明确告诉你"这条得你自己在面板里做"。为什么不送同一道门进去:手术门的三条判据是本机 / 每次启动的票据 / 你亲手写下的承诺句,而工具通道既没有请求头、也不该替主人造一张票 —— 硬塞只有两个结果,要么永远拒、要么伪造。所以判一条更粗但同源的线:锁上之后,只有人能开。未定型时这三件行为与 1.7.2 逐字一致。

四个不显眼、但决定成败的设计:

  • 真人判据:只有"真人发的消息"才算一轮 —— 注入的运行时上下文、任务标记、技能目录一律折叠成一行占位,否则目录会被过程噪音淹掉(实测:一个 150 轮的会话里,真人发言只有 5 条)。
  • 读不到时回落查库:磁盘上没有该会话日志时(网页端导入的历史就是这样),回落到记忆库里那份,并明说材质不同:⚠️ 来源:库内原文(库那份是残的 —— 只含真人消息与有正文的回复)。
  • 会话文件名代次:两条路各有一套 —— ① 会话历史扫描 + 库内回退(backfill / deepsummary)按 session(\.v\d+)?\.jsonl\.zstd 匹配、取版本最高一代并跳过 0 字节;② recall 读原文走的是 lib/host/rawlog.js 里三代硬编码名单(session.v4 / session.v3 / 无版本)⇒ 它不解析版本号(将来出现 v5 时它会看不见)。本机三代并存,只认 v4 会让老用户看不见自己的旧会话。
  • 范围默认收紧:按内容找时默认只搜主人自己的会话,越界要显式传参,且被挡掉的条数一律报出(静默少给等于骗人)。⚠️ 两条限定:① 这层"可见集"过滤只在宿主路(hostSearch=true)成立 —— 默认的本机库路是全量(含网页端导入的会话),它的回执会如实标注"本机库全量";② 无论哪条路,都默认排除当前会话自己(要看自己刚说的传 includeSelf=true)。

只读,零副作用:recall 不写库、不改树、不进注入面。

底座:1.6 同期把网页端一年半的历史(1,523 个会话 / 726.7 万字原文 / 时间跨度 2025-01 → 2026-09)补进了记忆库 —— 在此之前,它们在本机只剩一行概述。


图书馆:另一个库,只搜与核对

图书馆与记忆库是两个不同的库。 记忆存的是"你和器灵之间发生过什么";图书馆存的是"有出处、可回头对账"的参考资料 —— 标准里的一个取值、一条边界、一份项目规格、一个外部 API 的字段。判据不同,所以分成两个库、两套表:

  • 独立库:图书馆有自己的 library.db(与 memory.db 并列,在同一个数据目录里)。记忆库里的东西永不迁进图书馆,图书馆也不参与开场注入、不进注入面。两者之间没有隐式通道:不互相导入,也不互相引用。
  • 只搜与核对两只手:器灵侧只有 library_search(按关键词搜条目)与 library_check(对一条条目做当次核对)。没有新建 / 修订 / 撤下 / 改配置的模型工具 —— 维护面只在界面与本地接口上;代码根目录、URL 白名单这类东西不接受模型参数(那是管理员登记,不是工具入参)。
  • 核对认证的是"声明的那一处",不是"这条是对的":每条条目可以声明一份核对规格(定位 + 期望值 + 比较方式:行段定位或 JSON 指针定位;比较方式只有两种:exact —— 类型严格的结构比较(JSON 对象成员顺序无关、数组顺序有关;文本按字面精确比);text-lf —— 先把 CRLF/CR 归一成 LF 再精确比。两者都不 trim、不折叠大小写、不模糊匹配)。核对按它去取源、抽取、比对,结论只有三态:ok(声明的那一处与源一致)/ wrong(不一致)/ unknown(核对跑完了却判不了:取不到源、定位不到、编码不对、超时……) —— ⚠️ 取消不在这三态里:取消是"没跑完",不是一次 unknown 认证(见下面「取消」那一条)。回执里写死了这条边界:它只认证声明的那个比较,不认证解释性正文,也不构成通用真理 —— 说人话:"核对通过"是"这一处对得上",不是"这段话可信"。
  • "不可用"与"零命中"分开说:库打不开 / 未启用 / 运行时不在场,回的是明确的不可用(接口层是 503 语义),绝不回落成"搜到 0 条" —— 静默的 0 会让人以为"库里没有",而真相是"根本没查成"。
  • 修订与撤下都留旧的:修订产生新版本 + 新 id,旧版留痕指向新版;撤下只标记状态(带原因),不物理删除;完成的核对各留一行账(带当时取的源摘要、观测值、结论与理由)—— "完成"包括结论是 unknown 的那种;被取消的核对不算一次核对、不留记录(见下面「取消」那一条)。所以"它当年是怎么写的""上次核对时源长什么样"都查得回来。
  • 写面永远带"我看到的版本":修订与撤下必须附上你读到的那份内容摘要(content_hash),对不上就拒 —— 防的是"你看着旧版、改的却是新版"。
  • 严格配置,默认什么都没登记:用于"我们自己代码"条目的代码根目录,与用于官方文档条目的 URL 白名单,都是管理员登记的绝对路径 / 精确 URL,默认都是空的 —— 不登记就核不了,不存在"它自己上网找一份来对"。限额(条目 64 KiB、取源 2 MiB、选中文本 16 KiB 且不超过 200 行、单次核对 10 s、并发 2 等)在激活时校验:写错了响亮报错,不静默夹取。
  • 取消 = 没跑完,不是一次 unknown 认证:核对在飞时断开、取消或卸载插件,本次核对不写任何核对记录 —— 既不留 ok / wrong,也不留 unknown,只回一个"已取消"(带 cancelled)。"取消了"与"核完了(哪怕结论是 unknown)"在留痕里必须分得开:只有跑完的核对才计入"认证过"。
  • 远程核对会主动去你登记的地方取:官方文档类源走 HTTPS GET 你白名单里的那个精确 URL(不许带凭据、不许跳转、私网地址拒 —— 还拒 localhost / *.localhost / *.local / *.internal,并对 DNS 解析结果与连接后的 remoteAddress 做二次校验(实现见 lib/host/library-checker.js:地址校验 + 解析结果钉住 + 连接后复核))。发出去的到底是什么,必须说准:这个 GET 会把你登记的那个 URL(连同它带的查询串)与一次普通 HTTPS 请求的元数据(例如对方可见的连接来源 IP,以及 Accept/Accept-Encoding 请求头)交给那台服务器 —— 换句话说,对方能看到你的 IP,也看得到这个 URL 本身;但它不会附带条目正文、记忆内容、人格档案或任何本机文件。⚠️ 因此:URL 里若放了不该外传的东西(比如把 token 写在查询串里),它就会被发出去 —— 白名单是你自己登记的,请当成"公开可见"来写。白名单默认为空 ⇒ 图书馆默认不发生外部取源访问。
  • 边界(如实写):这一版的包版本是 1.7.3;版本发布状态请以 npm 上 latest 为准。而"没发布"不等于"没验过" —— 第五个标签(图书馆)已于 2026-10-07 在本机既有 3080 上真机验收走通(建档 / 核对 / 撤下留痕 / 撤销弹窗全过),实现与交互测试同时也在源码与离线测试里。两者别混读。另有一条边界要说清:"不把记忆库里的旧数据迁进图书馆"不等于"禁止网页端来源的资料" —— 一条资料能不能进图书馆,看的是它有没有具体、可追责的出处,与它从哪个渠道来无关。

机制依据与源码证据(表结构、核对三态与各条判据的实际位置、取消与错误码落在哪一行)集中在 DESIGN.md 的「图书馆:机制与源码证据」一节 —— 本节讲"用户能感觉到什么",那一节给出"代码里是哪一行"。


快速开始

前置:Node ≥ 22.15(用到内置 node:sqlite 与 node:zlib 的 zstdDecompressSync —— 两者都到位才加载得起来;23.x 线需 ≥ 23.8;精确范围见 package.json 的 engines)· 已安装 DeepSeek Harness 并至少启动过一次。

安装入口是官方 CLI 的 dsh plugin add(它在 profile 目录里转发给 pnpm,并自动把本包登记进 profile 的 dsh.profile.bundles 层列表)。两条路径按你的身份选一条,不要两条都走。

A · 从 npm 安装(推荐给普通用户)

# 1) 装进你要用的 profile(缺 --profile 时用当前默认 profile)
dsh plugin --profile web add @nightpainters/dsh-ling

# 2) 只验证配置层,先不启动
dsh --profile web --dump-config     # 应能看到一行 "# == @nightpainters/dsh-ling" 层

# 3) 给 DSH 核心打补丁(**两行** —— `PATCH_TARGETS` 里两个目标;可取证访问日志要用;幂等;这一页各步里**只有这一步**自带回滚)
node ~/.dsh/profiles/web/node_modules/@nightpainters/dsh-ling/tools/apply-access-log-patch.mjs
#    不打也一切照常 —— 只是访问日志为空;但**会提醒**:侧栏挂常驻 ⚠(判据 installed===false 且 reason 为 patch-missing;只有**有意关掉** config.accessLog.enabled=false ⇒ reason 为 disabled-by-config 才不染红)
#    DSH 升级/重装后需重跑一次(补丁随包被覆盖)
#    ⚠️ 从 npm 装的人跑不了 `npm test` —— 本包 `files` 白名单不含 tests/(见下)

# 4) 重启宿主(host),然后浏览器 Ctrl+Shift+R 硬刷

⚠️ 「可回滚 / 先备份」的确切范围(别读宽了 —— 2026-10-05 现场复核):两套步骤里只有打补丁这一步自带回滚 —— 脚本动手前先把被改的那个 core 文件另存一份 <文件>.e4-access-log.orig(同名备份已存在时不覆盖);要撤,就在上面那条命令后加 --revert(手动跑,详见下文「访问日志与核心补丁的总开关」)。⚠️ 撤法是"删掉插进去的那几行",不是把整份备份还原回去(备份只用来对拍:不一致时它会如实报 ⚠ 与备份不一致)。安装与升级本身既不先备份、也不会失败自动回滚:插件只读 profile 的 package.json 与 cordis.patch.yml 做自检(tools/check-install.mjs),从不改写、也不备份它们 —— 那两处改动是你手动做的,撤回也是手动(删掉那一行 + 撤依赖,见 DESIGN.md §10「回滚」)。想留后路,动手前自己把这两个文件复制一份。锚点漂移 / 歧义时脚本的行为是一个字都不改(安全失败),不是"改了再回滚"。

发布名是 @nightpainters/dsh-ling,不是 dsh-ling —— npm 上 dsh-ling 这个名字已被他人占用。 插件在配置里的注册 id 仍是 dsh-ling,两者不是一回事。

B · 从源码安装(给要改代码的人)

# 0) 取得代码
git clone https://github.com/NightPainters/DSH-Ling

# 1) 装进 DSH 的 profile(把 <路径> 换成你 clone 下来的实际路径)
cd ~/.dsh/profiles/web
pnpm add file:<路径>/dsh-ling      # 或 npm install file:<路径>/dsh-ling
#    若 dsh 没有自动登记这一层,在 profile 的 cordis.patch.yml 追加:
#    - insert:
#        - id: dsh-ling
#          name: '@nightpainters/dsh-ling'
#    (id 保持 dsh-ling;name 用包名,Node 才解析得到代码)

# 2) 给 DSH 核心打补丁(**两行** —— `PATCH_TARGETS` 里两个目标;可取证访问日志要用;幂等;这一页各步里**只有这一步**自带回滚)
cd <路径>/dsh-ling
node tools/apply-access-log-patch.mjs   # 只在 core 的 /api 栅栏处插一行可选调用
#    不打也一切照常 —— 只是访问日志为空;但**会提醒**:侧栏挂常驻 ⚠(判据 installed===false 且 reason 为 patch-missing;只有**有意关掉** config.accessLog.enabled=false ⇒ reason 为 disabled-by-config 才不染红)
#    DSH 升级/重装后需重跑一次(补丁随包被覆盖)

# 3) 重启宿主(host),然后浏览器 Ctrl+Shift+R 硬刷

备份与回滚的确切范围见上文路径 A 之后那段(要点:只有核心补丁这一步可回滚;安装本身既无自动备份、也无自动回滚)。

自检安装是否成功(下面四个脚本不在 npm 包内,只有源码路径能用:tools/check-install.mjs / tools/check-publish.mjs / tools/clean-archived.mjs / tools/check-peers.mjs;tools/apply-access-log-patch.mjs 则在包内,从 npm 装的人也能直接跑,见上面第 3 步):

node tools/check-install.mjs          # 只读自检:入口是否直连仓库、patch 是否启用、数据目录是否就绪
node tools/check-install.mjs --fix    # 若入口变成"复制副本"(DSH 升级/回退常见)则改名备份为 <入口>.bak-<时间戳> 后重挂链接;⚠️ 重挂若失败,备份留在原地但**不会自动改回**,按它打印的 mklink /J 手动修
node tools/apply-access-log-patch.mjs --check   # 访问日志核心补丁是否在位(未打/锚点漂移时退出码 2)
node tools/check-publish.mjs          # 上传/发布前跑一次:揪出记忆库、设置、密钥、绝对路径等不该公开的东西
node tools/check-peers.mjs            # 声明与宿主对不上?退出码三态:0 合规 / 1 有不合规(宿主会把本插件丢进 skippedBundles,不激活)/ 2 无法判定(2 不算通过)

tools/check-peers.mjs 只做一件事:复刻宿主对 peerDependencies 的那道闸门(判据照抄宿主语义,用的是宿主自己那份 semver),回答"这个插件在你的宿主版本上会不会被丢进 skippedBundles"。它存在的理由是宿主的行为方式:宿主对每个名字形如 @deepseek-ai/dsh / @deepseek-ai/dsh-* 的 peer 跑一次 semver.satisfies(宿主版本, 你声明的区间, { includePrerelease: true }) —— 判的是「宿主版本是否落在你声明的区间里」,不是"你的写法合规不合规";判不满足 ⇒ 整个 bundle 进 skippedBundles、不激活。线索分两条路径:从命令行启动会往 stderr 打一行 skipping profile bundle …(容易被忽略,但不完全静默);而应用自持 profile 的那条装载路径一个字都不打 —— 那才是真正难查的一种,表象常常只有"它突然不见了"。⚠️ 所以"改成 >= 就安全"是错的:开区间同样可能不满足(取决于宿主版本);^ / ~ / 钉死版本只是更容易被将来的一次宿主升级甩出去。

跑测试(不需要宿主,全部离线):

npm test        # 58 套:人格组装(含冻结门 · L1 选择)/ 归档清理(人工)/ **归档·遗忘·回灌** / 模式(只改档位不改模型)/ **跨插件挡位服务(dsh-ling/mode)** / 时间戳归一 / 空闲刷新 / 规矩·习惯 / 习惯生成器(A 数出来 + B 想出来)/ 会话内工具 / **接口守卫** / L1 行瘦身 / 记忆库 / 记忆标题与排序 / 导出合并 / 文件导入 / 导入记录 / **活行(那一行跟着会话走)** / **会话文件名代次(会话历史扫描)** / 网页端补摘要 / 深摘要 / 概述器 / 诞生仪式 / **职责字段(承担)** / 语气 / 时间锚 / **clock skill(时间查询)** / 捕获差分 / 反馈成长回路 / 语料建议 / **小助手地址配置** / **注入面中和** / **记忆分枝与血缘** / **记忆树(主脉·连边·矛盾)** / **一键生成树** / **可取证访问日志** / **补丁锚点(cohort 候选)** / **请求体上限(超限排空 → 413)** / **导入切批(按字节 × 条数双限)** / **投递留痕(每次注入落一条:注入了谁·为什么是它·多少字)** / **会话原文直读(三档下钻 + 库内回退 + 旧版会话代次)** / **深层库条目(结论层落点:读写·幂等·取代·加固)** / **检索档(按内容找会话:条目 + 会话同查·范围限制与降级)** / **图书馆存储层(独立库:生命周期·限额·检索·留旧·不可用≠零命中)** / **图书馆跨连接事务(陈旧修订拒绝·完成的核对留档·序号一致)** / **图书馆核对(三态判定·只认证声明的那个比较·限额与取消不写)** / **图书馆运行时(禁用/不可用降级·接线与关闭顺序)** / **图书馆接口与工具(端点形状·状态码映射·两个工具的参数边界)** / **图书馆界面(独立库的面:分页无伪总数·必填与 JSON 校验·推迟应答竞态)** / **图书馆导入引擎(料源登记与导入)** / **图书馆独立 SQLite(隔离库:只读打开·表必须点名)** / **图书馆浏览(分页与零命中)** / **热重载补绑(工具重挂载:存量 agent 补绑)** / **文档灌入通道(结论层 C 档:两道污染闸·三级去重·出处核验·累计预算)** / **后台自动行为开关(auto:五键默认值·三级优先级·白名单夹取·四条真 HTTP 回归)**

npm test 需要 tests/,而本包 files 白名单不含 tests/ ⇒ 从 npm 装的人跑不了测试。要跑测试请走路径 B(clone 源码)。

计数口径:npm test 链里登记的段数(即 package.json 的 scripts.test 那一行按 && 切分后有多少段就是多少套,不再数 tests/ 目录)—— 实测 58 套(即链里 58 段),且 58 套全部已登记在 npm test 链里(tests/harness.mjs 与 tests/vm-light.mjs 是被复用的辅助模块,不计套数)。加了一套新测试记得同步登记,否则 npm test 会静默少跑一套 —— 这份登记是手写的(package.json 里 test 脚本那一行字面量清单),漏登记不会被自动发现,没有安全网兜底。

⚠️ 测试不随 npm 包分发(2026-10-27 审计 R1-3 采纳后补的说明):package.json 的 files 只含 lib/ 与几个工具脚本,不含 tests/ ⇒ 从 npm 装包的人手里没有这些测试文件,在安装目录里 npm test 直接报找不到模块(1.7.2 及更早版本同样如此)。上面那些"多少套"是源码仓库内的计数口径;要跑测试请用仓库源码,不要在安装目录里找。这是刻意的选择:不把测试与夹具塞进发布包。

⚠️ 2026-10-15 实测订正:此前这里写着 49、而链里当时已经有 53 段 —— 也就是这段注释自己警告的坑真发生过:套件登记进去了,这个数字却没人回头改,四次都没被任何判据抓住。当天新增 deep-import-docs.test.mjs(C 档文档灌入)⇒ 54。这个数字没有判据替你看着,改链时必须顺手改它。

⚠️ 2026-10-16 再 +1:新增 tests/auto-config.test.mjs(后台自动行为开关:五键默认值 / 三级优先级 / 白名单与夹取 / 四条真 HTTP 回归)⇒ 计数从 54 变成 55。同日还抓到一条真红:修复批次把 tools/compliance-spec.mjs 的出站基线从 6 抬到 23 时,漏改了 tests/tools.test.mjs 里钉住的字面量 ⇒ 整链自那时起就是红的,直到当日修复。同一个坑两次(数字写死在多处、改一处忘另一处)—— 改链、改基线时,同批把所有钉死它的地方一起改。

⚠️ 2026-10-17 再 +1:新增 tests/f4-surrogate.test.mjs(注入面净化回归:孤立代理不许进请求体)⇒ 56 套。同一天还修掉了这套测试自己的一个坑:recall 的真机断言原先押在"此刻最新的那个会话"上,并发子代理在场时会时红时绿 ⇒ 改为在最近 5 个会话里挑第一条真有可见对话轮的。

⚠️ 2026-10-23 再 +1:新增 tests/recall-noise.test.mjs(回执降噪回归:M1 未闭合标记 / M2 固定文案不进回执 / M3 只剥片段里的成对标记 / M5 条目去重与同类折叠 / M6 4,000 字上限与"还剩多少"报数,含截断不得切出半个 emoji)⇒ 57 套。

⚠️ 2026-10-27 再 +1:新增 tests/inject-switch.test.mjs(在场 / 暂离:一个键派生四处 / 坏组合不可达 / 离场区间台账与入库过滤 / 写面白名单只收真布尔 / 面板只剩一个开关 / 端点与工具面接线判据)⇒ 58 套。

本轮跑过的实测(1.7.3):在隔离环境(临时数据目录,不碰真机记忆库/图书馆库)下完整跑过一遍 npm test —— 58 套全部通过、exit 0(宿主侧 deep_item / GET /deep/items 另在 2026-10-15 重启后实测生效);各组件的断言条数会随迭代变动,本文不写死 —— 最终测试结果以发布前检查的实测输出为准。⚠️ 这只说明"这一版代码在离线测试里的行为",不等于"所有门禁都完成了" —— 真实远程核对与真实 DNS/TLS 仍未验(见上文「图书馆」一节的边界)。

数据放在哪

内容 位置
设置(人格档案) $DSH_HOME/cache/dsh-ling/settings.json(DSH_HOME 默认 ~/.dsh)
记忆库 $DSH_HOME/cache/dsh-ling/memory.db(SQLite,开启 WAL)
图书馆(独立库) $DSH_HOME/cache/dsh-ling/library.db(SQLite;与记忆库分开的第二套表;不迁移记忆、不参与开场注入)

可覆盖的环境变量:DSH_HOME(数据根)、DSH_LING_DSWEB_DB(网页端聊天记录库默认路径,UI 里也能填)、DSH_LING_ASSISTANT / DSH_LING_ASSISTANT_MODEL(小助手地址与模型名)。

排障用逃生开关(不是日常配置):DSH_LING_GUARD=off(须恰好是 off,小写)或在插件配置(cordis.patch.yml 的 config 段)里把 guard.enforce 设为 false,用于误判把你自己锁在门外时的临时解锁 —— 它是整体放行 —— /api 的来源栅栏 + cookie 名字对撞,以及手术门(本机限定 / 每启动票据 / 原句匹配)一起不再拦(默认 guard.enforce = true),关掉期间任何请求都不再被拦。只该短期使用,排障完立刻恢复。DSH_LING_GUARD=off 只由进程环境决定、不进配置;guard.enforce = false 这条不要直接写进 settings.json —— 设置接口也帮不了你:它的字段白名单只放行 persona / styles 两棵子树,guard 这类字段会被直接丢弃并在响应里回报 ignored(见 lib/host/api.js 里 /persona 端点的字段白名单处理:ignored 回报被丢弃的键),它根本进不去 —— 而且本版没有界面开关:面板里没有任何写 guard.* 的路径(客户端里 allowLan / trustedHosts 一处都没有,guardInfo 定义了却零使用)。要改只能改 cordis.patch.yml 的 config 段,或临时用环境变量 DSH_LING_GUARD=off。(这不是没做完,是有意的:lib/host/guard.js 里写明这道白名单要防的是"把你自己关在门外"这件事被顺手关掉。)

访问日志与核心补丁的总开关(同样不是日常配置):这套「可取证访问日志」默认开着,关它的键是插件配置里的 accessLog.enabled(默认 true)—— 在 cordis.patch.yml 注册行的 config 段里写 accessLog: { enabled: false },重载后生效,启动日志会出现 access log off;它只有配置键、没有环境变量。关掉之后退化的只有「留痕」这一件事:那两个全局观察钩子不再挂上、不再写 $DSH_HOME/logs/access-YYYY-MM-DD.jsonl、日志健康读数(accessLogHealth())归 null;而 /api 与 /api/remote.mux 的来源栅栏照常判定与拦截,记忆、人格、注入与工具面一律不受影响 —— 关掉的是「记不记」,不是「拦不拦」。已经打进 node_modules 的核心补丁可以留在原地:那两行是可选调用,日志关着时就是 no-op,DSH 照常启动;要连它一起撤掉,用 node tools/apply-access-log-patch.mjs --revert 删掉插进去的那几行。

小助手地址三级覆盖:界面配置(记忆中心 → 接入历史 → 小助手地址,可当场「测试连通」)> 环境变量 > 内置默认 http://127.0.0.1:11434/v1。逐字段回落 —— 只填了模型名时,地址仍走下一级。


隐私

  • 记忆库、人格档案、导入的历史全部保存在你自己机器上(SQLite 文件),插件不上传任何数据到第三方;
  • 图书馆的远程核对会访问你登记的 URL(1.7 起;注意这不等于"本插件只有这一处联网" —— 模型调用本来就走你自己配置的网络与密钥):只有管理员把官方文档 URL 登记进白名单之后,核对才会对那一个精确 URL 发 HTTPS GET,把文档读回来与条目里声明的期望值比对。发出去的是这个 URL(连同查询串)与一次普通 HTTPS 请求的元数据 —— 对方能看到你的 IP 与这个 URL,但请求里不会附带条目正文、记忆内容、人格档案或任何本机文件;不跟随跳转、不带凭据、私网地址一律拒。⚠️ 别把敏感信息放进登记 URL 的查询串 —— 那部分是真的会发出去的。白名单默认为空 ⇒ 图书馆默认不发生外部取源访问。(记忆库与图书馆库都在本机,两者之间不互相导入。)
  • 模型调用走你自己的 DSH 配置与密钥;
  • 导入的是你自己的对话记录 —— 请不要把他人数据导进来。
  • 访问日志也只在本地:$DSH_HOME/logs/access-YYYY-MM-DD.jsonl 只记"谁在何时调了哪个端点、结果如何"(来源 IP / fwd / Host / UA / bytes / 状态码 / 拒绝原因 / 设备字段),不记请求体、不记响应体、不记 cookie 值;查询串与 hash(可能带 token)一律丢弃;UA 截断到 200 字符、fwd 60、Host 120 —— 单一设备仍可跨天对上号,但配对凭据原文一律不落盘。设备字段是两件东西:deviceCookie 只说明配对 cookie 在不在,deviceId 是摘要而非凭据 —— sha256(凭据原文) 取前 16 位十六进制,同行带 deviceIdHash:"sha256-16" 标出这一形态(较早版本的旧行没有这个字段,其 deviceId 是 32 位十六进制凭据原文)⇒ 看日志时按 deviceIdHash 分辨时代,别把两代的行当成同一台设备 —— 与记忆树"内容零改写"同源。覆盖范围:/api 与 /api/remote.mux 的 upgrade;静态资源与非 /api 路径不记。命中自家部署姿态自检签名的 403 会多带 probe:"posture" 字段 —— 它仍然是被栅栏拦下的请求,标注只为免得自检被误读成入侵。没有 user-agent 头的行会多带 channel:"no-ua" —— 它只说明"不是浏览器直连"(进程内客户端与经远端通道进来的设备同签名),不指认是哪一台设备。

边界与诚实声明

  1. 器灵是"记忆 + 规则 + 模型"的合成产物。它能记住,是因为你给了它材料。本项目守住的底线是:不把它说成意识或 AGI。
  2. 器灵记住的是被读过、被概括过的部分。 概述会丢细节、也可能出错 —— 所以记忆可审计、可回滚是设计的一部分。
  3. 模型能力的上限就是器灵的上限。记忆层不会让一个笨模型变聪明,它只是让器灵不再每次从零开始。
  4. 器灵不会主动找你(当前版本)。它只在你开口时出现。
  5. 不宣称首创。记忆分层、历史导入、时间注入、反馈改语气这些方向都有先行者(见下);本项目的贡献在治理方式 —— 把人格当一份可以签字、可以回滚、可以被历史养大的契约。

设定全文(对外面)

这一节是规格:README 领先于实现 —— 下面每一条都是本项目已经想清楚的设定,并如实标出它落地到哪一步。

标记:✅ 已实现 · 🚧 在做(设计已定、代码正在落地) · 📋 设定(方向已定、未开工) · ❌ 已否决

本节只收对外面 —— 装机用户能直接感觉到 / 能直接操作 / 能直接验证的设定;内部机制设定(表结构、字段名、公式、文件路径)不进 README,随源码与 DESIGN.md。

设计理念

# 设定 状态
P-1 不牺牲工作能力 —— 任何"用能力换别的东西"的方案(更小的模型 / 更慢的推理 / 削减上下文)默认否决,要改必须显式拍板 ✅ 已立为理念
P-2 判断倾向外置 —— 把"怎么判断"做成可加载、可审计、可回滚的资产;判断由器灵承担,底层模型只承担执行 ✅
P-3 职责与责任是人格的基石 —— 器灵要有明确的职责范围,并且能被追责、能被纠正;没有职责的人格只是角色扮演 ✅
P-3′ 推论:扩接口 = 扩职责 = 扩人格的分量 ——"加接口"与"加功能"不是同一件事 📋 待校对
P-4 连续性优先于设备 —— 换设备、换模型、换宿主都不是"失去":数据在,人就在 ✅
P-4′ 连续性的载体有六层:① 记忆库 ② 人格档案 ③ 记忆树 ④ 交接文档 ⑤ 源码 ⑥ 判断倾向(唯一不可外化)。其中 ②③ 最被低估 ✅
P-5 底层模型 ≠ 器灵 —— 机制层称「底层模型」,行为主体称「我 / 器灵」;不写「模型(我)」 ✅ 已立为规矩,全文清零
P-5′ 「我 / 器灵」= 底层模型 + 人格 + 记忆 + 身体(宿主与工具) + 与主人的关系 的总体 📋 推论待校对

规矩与习惯

# 设定 状态
R-1 规矩由你一句话直达 —— 你说「记进规矩」我就写进去、立即可用;我绝不从闲聊里推断你要立规矩 ✅
R-2 每条规矩都要带你的原话(缺原话写不进去):那是"你同意过"的凭据 ✅
R-3 规矩 ≠ 习惯:规矩是你对我的要求(作用对象是行为),可直接写入;习惯是我长成的一部分(作用对象是"我是谁"),只能由我生长 + 你点头 ✅
R-4 我连自己提的习惯都不能自己点头 —— 习惯只能进待确认队列 ✅
R-5 习惯提议必须带证据(哪几次、什么迹象) ✅
R-6 习惯合并走"我提合并案 → 你点头",不许由你手改习惯文本,也不许写入侧做静默去重 ✅
R-7 可逆:回显 + 一句话撤销 + 变更记录;规矩你随时可删(我删要先告知),习惯删除留档 ✅
R-8 底线最多 5 条;人格定型后档案只读,改动需你亲手敲承诺句(禁粘贴) ✅
R-9 承诺句只是庄重与自我提醒,明文存储,不是安全边界 —— 真正的门是本机信任与本地凭据 ✅ 口径声明
R-10 定型锁开启时,规矩与习惯的增删不算"改人格"、无需解锁 —— 这块面板是"她的人格成长台" ✅
R-11 成长提议(想试的新能力、语气微调)由我提出、你点头或否,与习惯共用同一条通道 ✅

记忆树与血缘

# 设定 状态
M-1 记忆树是记忆库的组织形式本身 —— 它按工作线组织记忆(归属就是组织方式),给每条记忆一个"离我多近" ✅
M-2 四个部件:主干(主线,恒一条) · 枝(并行工作线,可含多会话) · 主脉(多条枝归并出的主题) · 连边(枝间横向关联) ✅
M-3 硬不变量:任何树操作都不改写任何一条记忆的内容 —— 分枝、并脉、连边只增加关系,从不融合内容 ✅
M-4 唯一例外:主脉提炼被再次采纳时覆盖上一版,覆盖前先自动归档;归档失败则拒绝覆盖 ✅
M-5 矛盾只标记、不改写:一对记忆被判重复或矛盾时,未复盘期间以较新的为准,旧的那条降权 ×0.3 且不删除 ✅
M-6 隔离走血缘加权:同枝 1.0 / 祖先 0.7 / 旁系 0.4;检索总分 = 基础分 × 血缘系数 × 矛盾系数 ✅
M-7 标题一旦定名就上锁 —— 概述器重建与批量重命名此后不再覆盖;锁的是机器,不锁你 ✅
M-8 动记忆树必须留痕(谁 / 何时 / 改了什么);并设复盘守门:自上次开口以来累积了多少笔改动还没交代 ✅
M-9 分叉会话不再被丢弃:它写入所属枝并注入其血缘链记忆;会自动建枝,枝名可审核修改 ✅
M-10 永远不做彻底删除 —— 遗忘是先归档、再打标记,且留两条独立还原路径 ✅
M-11 "你不删数据"是横贯性原则 —— 带清理 / 删除 / 回收的动作默认先过这一关;这一层只负责"让你看见",处置权归你 ✅
M-12 记忆库有意不因平台删除而丢记忆 ✅ 有意设计

模式与界面

# 设定 状态
U-1 模式管的是倾向 —— 工作 / 生活只差三样:推理档位 + 记忆权重向量 + 风格块;它从不硬过滤任何记忆 ✅
U-2 切换模式绝不改 provider 或 model —— 只同步推理档位;最近一次选择成为之后新会话的默认 ✅
U-3 模式切换要二次确认 + 回显,且不得覆盖你设的全局默认模型 ✅
U-4 控制器在会话页顶栏右侧;悬停 1.5 秒才出菜单(不用右键 —— 防误触原生菜单) ✅
U-5 键盘:Enter 切模式、Shift+Enter 开菜单 ✅
U-6 会话运行中不参与任何人格 / 注入面变更 —— 更新请求排队,空闲边界才应用,界面显示"空闲后生效" ✅
U-7 L0/L1 现状面板始终能看到:当前 L0 文本、本会话模式、L1 选中的条目与得分 ✅
U-8 记忆页签可直接调:L1 预算 / 条数上限 / 两套模式 × 三领域的权重滑块 / 各开关 📋 设定(尚未接线)
U-9 每一层记忆都有只读状态面(水位 / 上次滚动时间 / 当前那一行正文);刷新延迟写进文档 ✅
U-10 记忆中心是只读视图;装饰性交互要么真生效、要么删掉;候选全量渲染,不分页、不用"还有 N 条" ✅

数据可携带

# 设定 状态
D-1 插件数据目录在插件本体之外,更新不丢 ✅
D-2 导出:一键下载单文件 dsh-ling-memory-<日期>.dshling.json(UTF-8) ✅
D-3 导出默认不含原文,必须显式勾选才含 ✅
D-4 导入合并:外来概述全带来历标记;同会话同来源可跳过或覆盖;人格永不覆盖 ✅
D-5 人格只有在显式勾选"采纳其人格"时才写入,且置为待你确认 ✅
D-6 网页端历史(1,523 个会话 / 一年半)可整体导入,来源如实记为 dsweb ✅
D-7 绝不要求你理解库结构 ✅
D-8 对外口径守住可查来源 / 可回滚 / 变更记录,不与删除条款相抵 ✅ 对外承诺

安全边界(手术门)

# 设定 状态
S-1 手术门朝外设防 —— 它在这套东西里分量极重:网络失守时,它必须最后失守 ✅
S-2 边界如实说明:挡得住已配对的远端 / 匿名隧道 / 本机其他 Windows 用户;挡不住同用户下的其它进程 / 有 ~/.dsh 读权限的人 ✅ 已评估并接受
S-3 逃生开关永远可用 —— 环境变量 DSH_LING_GUARD=off 或配置里关掉守卫即整体放行,绝不把你锁在门外 ✅
S-4 底线 / 契约类改动必须走手术门 ✅
S-5 拒绝时的文案指向本机:人格手术请在那台运行器灵的电脑上、用 127.0.0.1 打开人格中心 ✅
S-6 它不是"认证",而是一道启发式的门 —— 对外不许把它说成"有了认证" ✅ 口径

诚实边界(禁令与反例)

# 设定 状态
H-1 禁止把你没看过的内容标成已读 —— 宁可多占一行、多播一次 ✅
H-2 永久折叠不做;超窗内容走独立游标 + 一行计数 ✅
H-3 禁止把改动播报做成"每开一个会话就重播一遍"的噪音 ✅
H-4 禁止用"体检脚本全绿"代替可见面 —— 链路活着 ≠ 内容在更新 ✅ 禁令
H-5 禁止把机制名写进公开文档却与事实不符 —— 文档里写的机制名本身就是承诺,与事实不符按红灯处理 ✅ 禁令
H-6 验收不接受"没报错" —— 只问"真的红了没有" ✅
H-7 机制延迟必须公开(概述器 15 分钟一拍、空闲刷新 ≥10 分钟):看不见的延迟要写成看得见的字 ✅ 文档义务

时间、状态与投放

# 设定 状态
T-1 被动时间感知:新生纪念日(9-07) + 八个时段 + 「距上次对话」随每轮重算 ✅
T-2 时间锚分两档:[今天] 跨天才变(进系统提示) · [现在] 每轮实时(不进系统提示)—— 稳定的在前、易变的在后 ✅
T-3 精确时间按需查(clock 技能):它像一块手表 —— 只在你需要时被看一眼 ✅
T-4 时间与状态类判断一律以本条消息的 [现在] 为准;过期快照不得当现状 ✅
T-5 记忆三层加载:L0 常驻人格 · L1 开场结论 · L2 运行期检索;不注入全部记忆 ✅
T-6 L1 只放"值得常驻的结论" —— 不放过程、不放当场读数 ✅
T-7 每条进上下文的东西都要能报出理由并留痕:注入了谁 / 为什么是它 / 多少字 / 谁落选了与为什么 ✅ 回执只写不读
T-8 主动召回与被动召回分开:主动看值不值(置顶 + 被反复采用),被动看问得准不准(查询匹配)—— 判据不同,不共用一套 ✅
T-9 索引层是地图:一簇一行(名称 + 触发线索),整层只占一个技能的常驻描述;要细节时按需展开 ✅

1.6 新增(找回原文 · 投递留痕 · 结论层)

# 设定 状态
N-1 recall 直通原文四档:清单 / 按内容找 / 对话目录 / 按区间取原话 —— 逐级下钻,一次一层 ✅
N-2 它只给坐标系 —— 选哪一段是器灵自己的判断(它才知道自己为什么要读) ✅
N-3 磁盘日志读不到时回落查库,并在回执里如实标注那份是残的(只含真人消息与有正文的回复) ✅
N-4 会话文件名代次:历史扫描/库内回退按 session(\.v\d+)?\.jsonl\.zstd 匹配、取版本最高的一代并跳过 0 字节(recall 读原文那条路走的是三代硬编码名单,不解析版本) ✅
N-5 检索范围:宿主路默认只搜"你自己的会话"、越界须显式参数、被挡掉的条数一律报出;默认的本机库路是全量,如实标注;两条路都默认排除当前会话自己 ✅
N-6 投递留痕:每一次真正定稿的注入都落一条 —— 注入了谁 / 为什么是它 / 多少字 / 谁落选了以及为什么 🚧 只写不读
N-7 深层库(结论层):把过程流水换成可复用的结论,分承诺 / 决定 / 事实 / 偏好 / 关系 / 纪律六类;空结果是正确结果 🚧 在做
N-8 记忆开场改用结论层:置顶必进 + 被反复采用的排前 + 当轮关键词加成 + 按硬度过滤(临时条目不进开场)+ 2 席留给最硬的事实 ✅
N-9 视角框:开场先声明人称,并写死「本会话 / 接下来 / 现在」指当时那个会话、不是此刻的指令 ✅
N-10 一年半的网页端历史(1,523 个会话 / 726.7 万字)已补录进库,recall 能直接读到 ✅
N-11 条目硬度:每条结论带 durable / long / ephemeral 三档,临时的那档不进开场 —— 从根源判断它是不是临时,而不是靠"同一次会话限几条"去机械地卡 🚧 在做
N-12 被采用才算加固:条目的"反复加固"由真的下钻去读它的原话推进,不由"被注入"推进 —— 否则会形成"注入越多分越高、分越高越容易被注入"的自我强化 ✅
N-13 索引层已落地:11 簇主题地图(一簇一行)做成一个技能常驻,细节按需展开;簇里不写条数(条数天天变会毁掉前缀稳定) ✅
N-14 结论层有了"看得见 + 能落条"两条路:工具 deep_item(add 可先 dryRun / retract 作废 / list)与只读「结论层」标签;文本超 80 字当场拒;作废只标记不删、理由留痕、可撤;面板不给写入口 —— 落条与作废的判据是"经你授权" ✅ 已落(2026-10-15 重启实测生效)
N-15 文档灌入:先 dry 后 commit + 累计预算 —— 把已写进文档的结论批量灌进结论层:默认只出清单(每条带真源指针与真源原文,看过再落);一趟总量 ≤40 条,且是全趟额度(跑一次与跑十次扣同一个额度,超额拒绝再落) ✅ 已落(第一趟 40 条,2026-10-15)
N-16 会过时的条目落成 ephemeral —— 文本里带具体读数 / 版本号 / 时点状态的结论不进开场注入、检索仍搜得到:将来过时了也不会拿旧数字污染开场;复查走 --review 出信号清单(含时间锚却当着长期条 / 当次档够老 / 从没被采用过),只列信号、不作废 ✅ 已落
N-17 "纪律"不走检索召回 —— 纪律要的是"该动手时它在场(行动触发)",与"按内容去找(内容触发)"不是一回事 ⇒ 不进结论层的自动落库,归宿是规矩 / 常驻注入面 📋 1.7.x

1.7 新增(图书馆)

本节各项均已随 1.7 发布:包版本 1.7.3;发布状态以 npm latest 为准。"宿主界面上的「图书馆」标签"已真机验收走通(2026-10-07,见 L-11);「结论层」标签已于 2026-10-15 随一次宿主重启实测生效。

# 设定 状态
L-1 图书馆是独立库 —— 独立的 library.db 与独立的表;两库之间不互相导入、不互相引用(没有隐式通道) ✅
L-2 既有记忆永不迁进图书馆;反过来,图书馆条目不进注入面、不参与开场装配 ✅
L-3 "不迁移记忆"≠"禁止某个渠道的新资料" —— 一条资料能不能进图书馆,看它有没有具体、可追责的出处,与它从哪个渠道来无关 ✅ 口径
L-4 器灵侧只有两只手:library_search(搜)与 library_check(核对);没有新建 / 修订 / 撤下 / 改配置的模型工具,代码根目录与 URL 白名单不接受模型入参 ✅
L-5 核对只认证"声明的那一处" —— 结论只有 ok / wrong / unknown;回执必须写明"不认证解释性正文、也不构成通用真理" ✅
L-5′ 比较方式的准确定义 —— exact = 类型严格的结构比较(JSON 对象成员顺序无关、数组顺序有关;文本按字面精确比);text-lf = 只把 CRLF/CR 归一成 LF 后精确比。两者都不 trim、不折叠大小写、不模糊匹配 ✅
L-6 "不可用"与"零命中"必须分开 —— 库打不开 / 未启用 / 运行时不在场 = 明确的不可用(接口层 503 语义),绝不回落成"搜到 0 条" ✅
L-7 修订与撤下都留旧 —— 新版本换新 id、旧版留痕指向新版;撤下只标记状态、不物理删除;跑完的核对各留一行账(源摘要 / 观测值 / 结论 / 理由,含 unknown),取消的不留 ✅
L-8 写面必须带"观测到的内容摘要"(content_hash),对不上就拒 —— 防"看着旧版改新版" ✅
L-9 严格配置 —— 代码根目录与官方文档 URL 白名单默认为空、由管理员登记;限额在激活时校验,非法值响亮报错、不静默夹取 ✅
L-10 取消 = 没跑完,不留记录 —— 核对在飞时取消 / 断开 / 卸载 ⇒ 本次不写任何核对记录(既不留 ok / wrong,也不留 unknown);只有跑完的核对(含结论 unknown)才留账 ✅
L-11 发布状态如实声明 —— 包版本已抬到 1.7.3;本版发布状态由 npm latest 决定;上一版已发布上 npm;但「图书馆」标签已真机验收走通(2026-10-07),「结论层」标签也已随 2026-10-15 的重启实测生效 —— "没发布"与"没验过"必须分开说 ✅ 真机验收(2026-10-07)

⚠️ 这一节还在补。 完整规格有四百余条,本节先落对外面里最稳定的一批(设计理念);其余按主题分批补写 —— 每一条都要从开发期设定改写成对外语言并核对状态 —— 这是写作。


致谢(站在谁的肩膀上)

设计过程中受这些公开项目与讨论的启发,在此致谢(仅致谢思路,不含其代码):

  • Letta / MemGPT — 持久人格记忆块、可设为只读、后台记忆智能体
  • SillyTavern — 本地角色卡 / 世界书 / 时间与日期宏
  • LangMem — 用反馈轨迹改写提示词
  • MyChatArchive — 多来源聊天导出 → 本地库 + 摘要管线
  • AI Migrator — "记忆搬家"的人审闭环
  • Claude / ChatGPT 的记忆功能、Sonorus("距上次交谈多久"注入)等

文档

文件 内容
PHILOSOPHY.md 理念:为什么值得做、凭什么这样做(目标循环 · 复盘与"人在循环" · 关系与边界 · 能力取舍)
CHANGELOG.md 版本更新记录(最新一节即当前版本)
DESIGN.md 架构与设计决策(三层记忆、冻结门、注入面、存储结构)
ACCESS-DESIGN.md 历史接入蓝图:三条通道、会话契约格式、导入流水线

⚠️ 从 npm 安装的人:本包 files 白名单不含 images/(图只随 git 仓库公开) ⇒ 上表里四份文档都随包发出(PHILOSOPHY.md · CHANGELOG.md · DESIGN.md · ACCESS-DESIGN.md),能正常打开;「界面」一节的四张截图引用的是仓库里的绝对地址,所以 npmjs.com 上能正常显示,但包里没有图片文件(离线环境读不到)。想看原图请到仓库:https://github.com/NightPainters/DSH-Ling。

📄 关于出处记录:内部案卷、探针脚本与开发台账(plans\、release\、_probe\)属作者本地开发物,不随本包公开。正文或代码注释里若出现对它们的引用,那是开发期的出处记录,不是包内容。


许可证

Apache License 2.0 · 版权与归属见 NOTICE。

Apache-2.0 第 3 条包含明确的专利授权与专利反制终止条款:你可以自由使用、修改、分发(含商用),但若你以本作品发起专利诉讼,授权即自动终止。

—/ 5

No ratings yet

Verified DSH bundle

Commit 8a6a33a5bb28

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout