DeepSeek Harness Plugin

Icstick/dsh-adaptive-context

Stars ★ 4 Category Memory Added 2026-09-03

Governed long-term memory for DeepSeek Harness: append-only evidence ledger with write guards, 7-tier authority claims, supersede chains, and budgeted pre-step injection with per-domain quotas.

Install

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:Icstick/dsh-adaptive-context

Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

This plugin publishes its README in Chinese only.

DeepSeek Harness (dsh) 的 AdaptiveContextPlane (ACP) 插件——带治理的长期记忆系统。

设计铁律

证据即真相;视图可重建。 置信度不是权威;检索不等于披露。 学到东西不等于可以改变行为;记忆不负责替你把活干完。

为什么需要它

用过 agent 的人大概都经历过这几件事:

  • 忘了说过什么。上周明明告诉它"配置和代码分开放",这周它又混在一起,你只好再说一遍。
  • 不敢让它记。有些"记忆"系统什么都往提示词里塞,一句话可能来自某个不可靠的网页,却被当成你的偏好,从此每个会话都被它影响。
  • 改不回来。发现它记错了,但不知道错在哪、谁记的、怎么改。只能手动翻文件,或者干脆把记忆清空重来。

ACP 想解决的问题很简单:让记忆像账本一样清楚。每一条都有来源、有权威、有生效时间;写入要过闸门,注入有预算,行为变化要经审批。你可以随时查它记了什么、为什么这么记、改没改过。

一个简单的例子

假设你叫小林,最近在用 dsh 写一个自动化脚本项目。

第一天。你对 agent 说:"记得我喜欢把配置和代码分开。"这句话被 ACP 记成一条用户事实证据——来源是你,权威是明确声明,领域是用户事实。之后你换了台机器、开了新会话,agent 自动把这条证据带进上下文,你不用重新交代。

第二周。你发现 agent 生成的代码一直用 2 空格缩进,皱眉说:"都说了,用 4 空格。"这句话以"用户纠正"的身份写入,同时把之前那条相反的旧证据标记为已取代。从这一秒起,注入的只会是新偏好。旧的那条还躺在账本里——它记录了你改主意的完整过程,但不再生效。

一个月后。你想换一台服务器,打开导出功能,一条 JSONL 把全部证据带走;新环境导入,一条不少。想查账?审计记录里谁记的、什么时候、为什么,全都有。

核心能力

能力 说明
证据账本 只追加、不修改的 SQLite 账本;同一事件重放只会落一条;每条证据声明权威(7 级)与领域(6 类),资格矩阵决定谁有资格进入哪个领域
治理 写入闸门(写入时拦截密钥、隐私、提示注入)+ 读取闸门(作用域/状态/资格过滤)+ 用户权利(查看/导出/纠正/释放/脱敏/删除/回滚)
上下文编排 每轮对话的 pre-step 注入;文本相关 + 语义相关双通道排序(MemOS 等记忆源提供语义分);自动排除本轮的自我回声、内容级去重;按区块配额控制注入量
用户模型 用户事实/偏好/工作/表达风格/经验/外部事实六个领域,全部显式建模——不做偷偷摸摸的推断画像
后台沉淀 每轮结束后台运行:证据积压到一定量才触发(不拖慢对话);LLM 提炼观察结论——失败不推水位、下轮重试同批(P0-1,避免"失败批被永久标记已消化"),仅 LLM 完全不可用时走规则兜底;同键冲突标记取代并保留演化链
时间真相 证据带生效起止时间;可以查"上个月的视图";被取代的证据在旧时点依然可见——完整旅程,不是覆盖
表达风格晋升 风格候选要么过人工审批门,要么满足策略护栏才自动生效(最低门槛不可调低);五态状态机 + 物化视图,随时可回滚
多源路由 多个记忆源并行召回,各自超时、互不拖累;LLM 任务可按用途配不同模型,主路挂了自动走备路
审计与导出 所有关键操作留痕(谁/何时/为什么/附带数据);JSONL 全量导出导入(证据/观察/候选/审计);视图可一键重建并校验
用户画像(Profile,2026-09-22) user_model 段的候选不再来自原始消息流,改由 Profile 物化视图供——由蒸馏出的 observation 构建,分 stableFacts / preferences 两组,每条可回链到证据与会话。按「支撑证据数 / 跨日复现 / 人工批准」加权排序(只动排序信号,不碰 authority)
回链可核验性(2026-09-25) 读侧把「外机导入、回链按设计清空」与「本机产出却没有回链」分开:前者是不可核验(外机)的结构事实(只计数不告警),后者才是真异常(告警 + 人工队列)。判据靠 id 与自身字段的自洽性(不写任何存量数据),实现 src/backlink.mjs
离线巩固(Dreaming,2026-09-22) 慢环:离线把证据与观察整理成稳定的候选结论。第一增量是三件零 LLM 的确定性事——归并(同域内同主体或二元组 Jaccard ≥ 阈值)、复现计数(跨会话/跨自然日)、遗忘(只出冷存清单,不删)。候选池与 observation 物理分离,晋升必须过人工门

工作原理

DSH 会话事件
  │  session/event(agent / inbox / spliced)
  ├─→ 事件归一 → 写入闸门 → 证据表(只追加,幂等)
  │
  │  agent/pre-step(每轮,3 秒预算)
  │    ├─ 账本候选(读取闸门过滤 + 资格矩阵)
  │    ├─ 记忆源候选(并行召回,故障不阻断)
  │    └─ 编排:排序 → 去回声 → 内容去重 → 预算打包 → 注入
  │
  └─ turn/end → 沉淀队列(不阻塞下一轮)
        ├─ 积压达标 → LLM 提炼观察(失败规则兜底)
        ├─ 同键冲突 → 标记取代 + 演化链
        └─ 风格候选 → 策略评估 → 护栏内自动晋升 或 人工审批门
              └─ 候选状态机 → 物化视图(pre-step 注入时读取)

注入的召回消息以 source.kind: plugin:dsh-adaptive-context 标记生产者,并保留 form: recall 供会话审计。

DSH 兼容声明与验收范围

package.json 的 dsh.compatibility 显式声明 DSH 0.2.0-rc.1;Node.js 范围沿用 engines.node: ^22.19.0 || >=24.0.0(运行依赖 Node.js 内置 node:sqlite)。 Web 配置界面还依赖宿主提供的 React、UI slots/settings 服务与对应客户端模块; 各 @deepseek-ai/* 子包的 peer 范围是依赖约束,不替代 DSH 主版本兼容证据。

DSH 完整版本 声明 依据与限制
0.2.0-rc.1 compatible 2026-10-13 作者报告“0.2.0-rc1可以,后续不清楚”;属于作者可用性声明,未提供测试 Commit、系统和完整操作日志
0.2.0-rc.2 unknown 尚无本仓对应的完整版本验收记录
0.2.1-alpha.1 unknown 尚无本仓对应的完整版本验收记录
0.2.1-alpha.2 unknown 尚无本仓对应的完整版本验收记录

其他版本未声明兼容;精确范围 0.2.0-rc.1 不自动覆盖后续 rc、alpha 或稳定版。 profiles: ["web"] 表示客户端目标,不表示其他 Profile 不可运行,也不表示已完成 Web Profile 验收。 当前 dshOperations 的 install/start/uninstall/rollback 都保持 unknown。 作者报告、源码/单元测试、一次性 Profile 操作验收和独立安全审查分别记录; 单元测试通过不能把操作矩阵改为 passed。

兼容来源与一次性 Profile 验收清单 记录证据边界、验证步骤和回滚要求。 此声明不会消除文件、网络或环境变量访问信号,也不保证商城自动批准。

权限、外部服务与失败边界

ACP 使用 DSH 进程权限 运行,没有独立文件或网络沙箱。配置路径与服务地址由用户指定, 代码没有把它们限制在插件目录内;结合会话内容、持久账本、规则写入与可选外部调用, 按保守口径应视为高权限插件。

能力 用途、默认行为与边界
会话与持久记忆 监听宿主会话事件,把通过治理闸门的真人输入、工具输出及溯源信息存入账本,并在后续步骤按作用域与预算注入。跨会话记忆包含用户内容,应按敏感数据管理;治理过滤不能保证识别所有秘密
文件 / SQLite 读写 ledgerDir/acp-ledger.db 及 SQLite WAL/SHM 文件;打开时自动建表/迁移。默认账本在 resolveDshHome()/acp,其中 home 按非空 DSH_HOME → 用户主目录的 .dsh 回退。建议显式配置独立绝对路径
表达视图 viewsDir 默认为 ledgerDir/views;读取/校验 expression.json,重建时经临时文件和 rename 替换。写失败会尝试清理临时文件
规则视图 rulesDir 默认为 resolveDshHome()/rules,跨 Profile 共享。重建会替换同名域文件;域集非空时可删除带 kind: acp-rules 标记的陈旧 .md,空域集跳过清理。请使用独立目录,避免与手写规则混用
MemOS 网络 recallProviders 默认 [],不自动探测 MemOS。显式启用 memos 后,向用户配置的 baseUrl + /api/v1/memory/search 发送 POST:查询文本(最多 512 字符)、agent 命名空间、topK。适配器不上传整份账本;查询本身仍可能包含私人内容。未指定地址时适配器使用 http://127.0.0.1:18801,配置远端地址会把查询送出本机
模型服务 配置 consolidationProvider/consolidationModel 或 llmTasks 后,经宿主 llm.stream 将选中的证据文本与提炼提示交给该模型;实际 endpoint、认证、数据保留与计费由宿主提供方和外部服务决定。未配置模型时走本地规则兜底
环境变量 / 凭据 当前运行源码用 process.env 读取 DSH_HOME 定位目录;未发现运行源码直接读取 API key 或系统钥匙串。模型认证委托宿主,本插件会调用宿主已授权的服务;自定义 provider 的能力需另行审查。读取环境变量会触发商城的保守凭据信号,不能据此宣称完全无凭据影响
命令与生命周期 当前 src 运行链没有启动 Shell/子进程;manifest 无 preinstall/install/postinstall/prepare 脚本。离线运维脚本由用户显式运行,不是安装钩子,导入/放行/隔离等写操作须单独审阅

外部依赖:宿主需提供 manifest 中声明的 Cordis、Schemastery、LLM、session、tools 和 UI 服务。 MemOS 仅在显式配置时需要,不是默认启动依赖;自定义 recall provider 可以有自己的网络、 文件和认证行为,本表仅描述内置实现。开发测试和客户端构建工具见 devDependencies/scripts。

失败边界:

  • MemOS 召回默认最多 3 秒,HTTP 错误、超时或不合法结果会记录降级并返回空结果; 全部 provider 失败时注入回落到无 provider 分支,既有本地账本继续可用。
  • 模型路由有超时和可选 fallback;提炼批次失败不推进处理水位,保留下轮重试。 没有可用模型服务时采用规则兜底;外部调用可能产生费用。
  • 表达视图缺失、损坏或 checksum 不符时不注入该视图,回落账本; 数据目录不可写、SQLite 打开/迁移失败会导致启动失败,不能把它解释为空记忆。
  • 卸载/停用的 dispose 对在途沉淀最多等待 5 秒,然后关闭账本; 不删除账本、表达视图或规则视图。规则视图可能仍被其他组件读取,需检查宿主规则装载范围。

Agent 安装指南(面向自动化装配)

给需要在本机 dsh 装配本插件的 agent/脚本读;人工安装见下一节。 三条装配注意事项:① 建议显式配置独立数据目录;② pnpm install 前先停 dsh(Windows native DLL 锁);③ 同 id 的 patch 条目是整体覆盖,不要重复插。

1. 定位 profile:<DSH_HOME>/profiles/<profile>/(例 C:\Users\<you>\.dsh\profiles\web)。 先读该目录 package.json:若没有 dsh.profile.bundles 键,说明 profile 未初始化, 先 dsh plugin --profile <profile> list(或人工建 package.json)再继续。

2. 添加依赖(二选一):

# A. GitHub 源(远端安装推荐):CLI 自动把声明 dsh.bundle 的包加入 dsh.profile.bundles
dsh plugin --profile <profile> add github:Icstick/dsh-adaptive-context
# B. 本地开发:profile package.json dependencies 加 "dsh-adaptive-context": "link:<绝对路径>",
#    并在同文件 dsh.profile.bundles 数组追加 "dsh-adaptive-context"

⚠️ dsh plugin add 只装依赖并 reconcile bundles,不会写配置条目——第 3 步必须做。

3. 写配置:编辑 profile 根 cordis.patch.yml(无则新建):

- id: adaptive-context
  name: dsh-adaptive-context
  config:
    ledgerDir: C:\path\to\acp-data   # 建议:独立账本目录绝对路径;省略时按 DSH_HOME → ~/.dsh 回退
    # 可选:consolidationProvider/Model——配了才有 LLM 沉淀,不配走规则兜底

4. 安装并重启:停 dsh → profile 目录 pnpm install → 重启 dsh。

5. 验证:

  • 数据:<ledgerDir> 下出现 acp-ledger.db 与 views/
  • 生效:新会话 pre-step 注入出现 [acp:...] 前缀条目(如 [acp:user_input | id=ev_...])

故障速查:不注入/不沉淀 → 检查 ledgerDir 显式且可写;boot 报 duplicate loader entry → patch 里同 id 插了两遍;Web 设置无配置卡片 → 源码形态需先跑 node scripts/build-client.mjs 生成 client bundle。

安装

GitHub 一键安装:dsh plugin --profile <name> add github:Icstick/dsh-adaptive-context (bundle patch 会自动挂载 adaptive-context 条目)。装完后仍需在 profile 的 cordis.patch.yml 给该条目补 config.ledgerDir(建议使用独立目录)并重启; 完整三步与字段说明见下。

在 dsh 的 profile 目录(比如 ~/.dsh/profiles/web/)做三步:

1. package.json 加依赖(link 指向本仓库):

{
  "dependencies": {
    "dsh-adaptive-context": "link:D:/path/to/dsh-adaptive-context"
  },
  "dsh": {
    "profile": {
      "bundles": ["dsh-adaptive-context"]
    }
  }
}

2. cordis.patch.yml(profile 根目录)挂载并配置:

- id: adaptive-context
  name: dsh-adaptive-context
  config:
    ledgerDir: C:\path\to\acp-data    # 建议显式指定独立目录;省略时按 DSH_HOME → ~/.dsh 回退
    consolidationProvider: your-provider # 可选:开了才有 LLM 提炼
    consolidationModel: your-model

3. 安装并重启:

cd <profile 目录>
pnpm install
# 重启 dsh

注意:cordis.patch.yml 里同一个 id 的多个条目,后者整体覆盖前者(不是合并)——adaptive-context 只写一块。

设置页配置卡片(v0.1.1+)

  • 位置:DSH Web 设置 → 插件 → 插件配置(adaptive-context 卡片)
  • 机制:host 侧注册 settings namespace(adaptive-context),client bundle(lib/client.js, 由 node scripts/build-client.mjs 生成)注册设置卡片;保存写入 settings.yaml
  • 生效语义:保存后重启生效(apply 时 settings 值覆盖 cordis Config,未配置字段回退 Config/默认值)
  • 字段:ledgerDir / hotTokens / observationInjection / observationAuthorities / recallLimit / crossSessionPolicy / subagentDowngrade / consolidationProvider / consolidationModel / autoPromote / debug (memosEnabled / memosBaseUrl 已于 2026-10-01 退场,见下方配置表注) (targetDomain 已弃用:卡片保留仅兼容展示,不再影响注入)
  • client 依赖:react(DSH 预加载)+ @deepseek-ai/dsh-client-ui-slots + @deepseek-ai/dsh-client-ui-settings(client module table 提供,无需安装到项目依赖)

配置(全部字段)

字段 类型 默认 说明
ledgerDir string resolveDshHome()/acp 数据目录(acp-ledger.db 所在)。建议显式指定独立绝对路径;否则按非空 DSH_HOME → ~/.dsh 回退
hotTokens number 900 热路径注入预算(tokens/轮)。2026-09-02 P0-5:默认对齐 MVP 总预算 900(此前文档写 300 且 composer 从不读取,实际配额合计一直是 900)
observationInjection boolean false observation 蒸馏轨注入开关(2026-09-02 决策:默认冻结;接线已就位,打开即用)。生产实例经 profile patch 开启并配权威白名单与配额
observationAuthorities array ["user_explicit","user_correction"] T2(2026-09-07):observation 注入权威闸门——只放行高权威蒸馏轨;single_observation 等低权威不进常规注入(留账本供 acp_query)。语义:开闸≠全量开
sectionQuota object MVP_SECTION_QUOTA(user_model 180 / work_state 250 / memory 290 / expression 120 / rules 60,合计 900) section 配额覆盖(S1 P2):如 { user_model: 800 };总预算仍由 hotTokens 控制(注:provenance 配额已于 2026-09-02 删除——sectionOf 从不产出,是死配额;T4 2026-09-07 新增 rules 段 60,memory 350→290 让渡,总额仍 900 不回退)
recallLimit number 20 每个记忆源的召回候选上限
targetDomain enum work DEPRECATED(2026-09-07):读侧资格矩阵已按候选自身 claimDomain 自然分组,本键不再影响注入;保留键位仅为兼容存量配置/设置页
debug boolean false 调试日志
recallProviders array [](无 provider) 记忆源注册表:[{id, enabled, timeoutMs, weight, baseUrl?}]。2026-10-01 行为变更:缺省 = 无 provider(缺省与显式 [] 完全等价)。M2 的兼容垫「缺省自动造默认 memos 项指向 127.0.0.1:18801」已拆除——memos 已在本机/云端摘除。要启用 memos 仍可显式配置:recallProviders: [{id: 'memos', baseUrl: 'http://host:18801'}](适配器保留在 src/providers/memos.mjs);memosBaseUrl / memosEnabled 两个平铺键随之退场(存量配置里的这两个键被忽略,不再产生任何 provider)
llmTasks object consolidation 由 consolidationProvider/Model 推出 LLM 任务路由:{任务名: {provider, model, fallback?: [{provider, model}], timeoutMs, maxTokens}}
consolidationMinEvidence number 10 节流:未消化的证据攒到这么多就触发沉淀
consolidationMinTurns number 5 节流:距上次沉淀超过这么多轮就触发
consolidationProvider string — 提炼用的模型服务商(不配就走规则兜底)
consolidationModel string — 提炼用的模型
consolidationMaxTokens number 1024 提炼输出上限。生产实例踩坑(2026-09-02/03):默认 1024 太小——模型按每条证据逐条输出完整 observation(每条可达数百 token),40 条/批必然截断 → 判失败 → 水位永不推进(连续 24 败)。修复组合:prompt 引导合并输出 + 批次收敛 + 配额放大(见下)
consolidationMaxBatch number 40 单批证据上限(P0-6)。生产建议 8:配合 maxTokens 12288(约 2 倍输出余量);prompt 已引导"合并相似证据、禁止逐条机械输出"(P0-7)
consolidationTimeoutMs number 30000 提炼调用超时
autoPromote boolean false 风格候选策略达标后自动晋升(默认关,走人工审批门)
viewsDir string ledgerDir/views 物化视图目录
rulesDir string ~/.dsh/rules 规则视图目录(T4 M4.1:反馈通道规则的人类可读视图,按域分文件、可从 ledger 重建;跨 workspace/profile 全局)。2026-10-02 起:本次域集为空时跳过陈旧清理(一个都不删,只 warn)——缺省路径不会再被一次空域集刷新扫空
policyConfig object — promotion 策略参数覆盖(floors 只允许更严:min_events 最低 2、min_strong 最低 1、证据窗口最长 30 天)
startupRebuild boolean true 启动时校验视图 checksum,失配自动重建
crossSessionPolicy enum non-instructional 跨会话注入闸门(2026-08-30):non-instructional=跨会话只注入非指令性内容(agent_authored 总结/external_tool),user_input/user_correction 跨会话不注入;all=跨会话全类别注入(utility×0.3 惩罚 + session 来源标记);none=不注入任何跨会话内容。本会话内容始终全类别注入
subagentDowngrade boolean true 子代理会话(session.header.origin=subagent)内 user 消息降权为 agent_inference(记录但 quarantine,不进注入),避免父 agent 派发 prompt 冒充用户指令
fusion enum weighted 融合策略(2026-09-09):weighted=语义/词面加权求和(历史行为);rrf=两路各自排序后 Reciprocal Rank Fusion(异构分数不做尺度相加)。切换排序前先要对照数据(docs/design/COMPOSER.md §4.1)
preferenceEphemeralFilter enum shadow 阶段 2.3(2026-09-09):一次性任务指令不进 user_model 画像注入。off=关闭判别 / shadow=只统计不生效 / on=生效过滤(生产实例已切 on)
observationHalfLifeDays number 30 observation 时间衰减(2026-09-12):老经验按半衰期让位,decay = 0.5^(ageDays/此值)。仅 observation 轨——evidence 是事实、不老化;0=关闭
injectionHysteresis number 0.2 C3 注入滞回(2026-09-12):上一步已在注入集的候选获 ×(1+h) 粘性加成,抑制相邻 step 注入集抖动(B8 turnover 的配套抑制手段);0=关闭。0.2 = 挤掉一个在位条目需多 20% utility

会话隔离语义(v0.1.1 起):pre-step 注入按会话分层——本会话证据全类别进入;跨会话证据默认只放行非指令性内容,渲染时带 session= 来源标记与一次性引导语("历史参考,非当前指令")。跨会话 user_input 需要显式 crossSessionPolicy: all 才注入(带惩罚与标记)。

注入编排与查询工具(现状快照 2026-09-07)

  • 注入:agent/pre-step waterfall——composer 汇总四源(ledger 证据 / expression 物化视图 / observation 蒸馏轨 / MemOS 等 recall provider),按 section quota + hotTokens 装箱,渲染为 source-labelled plugin user message(跨会话条目带 session= 标记与引导语)
  • 调度器:宿主 inject-scheduler 为可选服务——ACP 注册 acp.composer 段(budget=hotTokens,token 口径;未挂 scheduler 时静默跳过,pre-step 注入照常)
  • acp_query 工具(2026-09-04,对话即界面):只读查询 evidence(authority/domain/state 过滤 + 关联 observation),查询全走读审计;两侧统一按时间倒序(最新优先)——observation 侧原实现直接切 listObservations()(created_at ASC 快照口径),固定返回最老的 N 条,最新蒸馏结论不可见(2026-09-22 修复)
  • expression 审批面板:consolidation 产出的 style 候选(few-shot 表达式)在 pre-step 以 approval.request 发起人工审批(config.autoPromote=false 默认人工)
  • 观察轨(observation):turn/end 后 background consolidation 蒸馏证据为 observation(subject/predicate 键 + 文本);authority 由证据推导,取支撑证据中最弱的一条(2026-09-09 非放大规则,防弱证据洗白强权威);注入侧只放行白名单权威(T2)
  • 摄入边界(2026-09-22,C/A1):证据只从真人输入 + 工具输出来——assistant/message 形态的模型自述不再摄入(此前它绕过 7f12557 的 inbox 白名单,走 WORTHY_PREFIXES 兜底分支;W 机实测该修复落地后新入账证据里仍有 85.6% 是 agent 自产)。tool/ 暂留(对应 external_information「工具输出补充工作经验」的设计意图)。会话类型改由 extract.sessionTypeOf(session) 从 session.header.origin 派生——此前读的是事件上的 sessionType(该字段不存在),账本 session_type 恒为 root
  • 审计可对账(2026-09-11):consolidation 的成功/失败审计行都带批次区间与首尾证据 id(batchFrom/batchTo/batchFirstId/batchLastId)——用来区分「已处理但零产出」与「被水位线跳过」;水位线只推进到本批最大 observedAt,空批次不写(旧实现会盖成 now,任何早于 now 的回填/时钟偏移证据都会被静默跳过)

API(ctx.acp)

方法 说明
append(input) 写入证据(过写入闸门 + 资格矩阵;内容重复则返回已存在的 id)。摄入闸门(2026-09-22,B1):需显式声明 input.ingest——'session-event'(session/event 摄入路径)/ 'user-correction'(correct 快路径)过闸门后按写入闸门结论落 state;未声明与其它来源一律落 quarantined(公开服务面 fail-closed,账本 append-only 删不掉;已隔离行不注入,release(id) 可放行)。ingest 不是 evidence 列,落库前剔除
get(id) / inspect(id) 读单条(inspect 附带治理裁决细节)
setState(id, state, opts) 状态迁移(正常/隔离/已取代/已脱敏)
recall({query, scopeId, targetDomain, validAt, allowSuperseded, maxTokens}) 召回(编排的最小入口;validAt 支持历史视图)。targetDomain 参数 DEPRECATED(2026-09-07):资格按候选自身 claimDomain 裁决
history(id) 证据的演化链(谁取代了谁)
stats() 账本统计
export(scopeId, {format, streams}) 导出(json / jsonl;证据/观察/候选/审计四类流)
import(jsonlText) 导入(证据按内容哈希幂等,重复不落)
correct(input) 用户纠正:写入纠正证据 + 立即取代旧证据
release(id) / rollback(id) / redact(id) / delete(id) 用户权利操作(释放隔离/回滚/脱敏/删除)
queryObservations({scopeId, state, claimDomain, authorities, limit, order}) 查蒸馏 Observation 轨(T2 权威闸门:authorities IN 过滤;跨插件取高权威画像的公开入口,如 maid PIN 钉扎)
audit({op, scopeId, actor, limit}) 查审计
startupVerify() 启动校验物化视图与 candidate 重放一致;失配且 startupRebuild=true(缺省)→ 自动重建 + audit。返回 {ok, checksum, rebuilt, reason?}
rebuild(viewName) 手动重建物化视图(视图随时可以重建)
exportActive(scopeId) 只导出生效中的证据(便捷方法)

反馈通道:纠正 → 规则(T4,0.3.0)

  • 草拟:user_correction/user_explicit 证据过闸门(G1 显式前缀 记住:/更正:/规则:;G2 同义纠正前 24 字符重复 ≥2)→ LLM 草拟(复用 consolidation 路由,可缺失→G1 去前缀兜底)→ rule 表 draft 行 + audit rule_drafted;幂等(已入 rules 的证据不重复草拟),日限 4 run
  • 审批与治理:/acp rule list | accept <n> | reject <n> | rebuild | pin <n> | unpin <n>(人工/headless 通道,never 策略可用;accept → active + rulesDir 视图重建 + audit;rebuild = 规则经脚本/外部写入后手动刷新视图;pin/unpin = 常驻标记(gates: always → 注入 pinBoost 加成,见下));style 候选审批在 never 策略下不自动发起(防静默 dismiss,isNeverApprovalPolicy)
  • 注入(2026-09-12 容量治理,B14):全量 active 规则进候选,按 composer utility(词面相关度主导 + explicitRef 加成 + gates:['always'] 的 pinBoost 常驻加成)竞争 rules 段容量;短标签 [rule] 渲染(每条固定开销按 4 token 记账,此前按 20 计 → 段内实装条数从 1 提升到 3-4 条);段配额由 sectionQuota.rules 决定(默认 60,生产 140)
  • 可注入性:单条成本 ≈ 4 token(短标签)+ 正文 1.0 token/CJK 字;超过 40 字(默认段配额下的安全线)的规则可能被整条丢弃——/acp rule list 会标 ⚠超40字安全线,草拟期即可发现
  • 修订:规则修订 = 新行 supersedes 旧行(lineage 回溯);不满足闸门的纠正维持 evidence 层按需召回
  • 失效观测(B11,2026-09-12):新纠正与某条 active 规则 bigram 重叠 ≥0.6 → 判定"规则疑似未生效"——不再重复草拟(避免同义规则堆积),落 audit rule_ineffective_suspect(含 evidenceId / overlap / ruleTitle)并写日志;短文本(<10 字)不判定(防假阳性)。用途:规则太长注不进、被容量裁掉、或模型未遵守,都能从审计里看出来

离线巩固:Dreaming(2026-09-22)

在线快环已通(pre-step 注入 + turn/end 蒸馏),Dreaming 是慢环:离线把证据与观察整理成「可注入的稳定结论」, 且必须经过一道门才允许晋升。设计全文见 docs/design/DREAMING.md。

第一增量只做三件零 LLM 的确定性事(src/dream.mjs):

件 判据
① 归并 同 claimDomain 内——同 subject 或 CJK 二元组 Jaccard ≥ 0.55 → 同簇
② 复现计数 簇成员跨 ≥2 个不同会话 或 ≥2 个自然日 → 升 consensus,否则留 candidate
③ 遗忘 superseded observation / quarantined evidence 超 90 天 → 出冷存清单(只标记,不删)
node scripts/dream.mjs --dir <ledgerDir>            # 预演(默认 dry-run,一行不写)
node scripts/dream.mjs --dir <ledgerDir> --apply    # 落库:只写候选池与跑批台账,绝不写 observation
node scripts/dream-review.mjs --dir <ledgerDir> --list [--domain work]
node scripts/dream-review.mjs --dir <ledgerDir> --approve <id>…    # 人工审
node scripts/dream-export.mjs --dir <ledgerDir> --state approved   # 预览可导出条目

三条纪律:① 物理分离——候选池(candidate_memory)与 observation 是两张表,候选绝不直接变成 observation; ② 不覆盖人的决定——库里已 approved/rejected 的候选,重跑只更新统计字段;③ 只标记不删除。

与 weaver 的通道(分域白名单)

只有 work / external_fact 两域可导出到 weaver,且必须人工审;画像三域(user_preference / user_fact / style)永不出 ACP。 导出产物是 wv import 兼容的 JSONL(title 是正文截取不是生成,body 附溯源脚注),由人跑最后一步。 理由与量级测算见 DREAMING.md §10;云端 staging 方案见 §11。

用户画像:Profile(2026-09-22)

在此之前,user_model 段的候选源是 evidence 直供——真人短消息(「继续」「重启好了」)把配额塞到 121%, 而 CONTRACTS.md §4 定义的 Profile(五数组、可追溯到 session event)一行实现都没有。

现在 src/profile.mjs 把它实现了:由 observation(蒸馏过的结论)构建,

stableFacts  ← claimDomain user_fact
preferences  ← claimDomain user_preference
recentState / interactionPatterns / inferredTraits   ← MVP 恒空(CONTRACTS §4:v0.1 启用)
  • 不落盘、每步现算:源只有几十条,派生成本≈0,而落盘视图会引入「缓存陈旧」整类故障
  • 可追溯:每条 ref 带 observationId + evidenceIds → Observation → Evidence → session event
  • 加权:weight = clamp(0.6 + min(ev-1,4)×0.08 + min(days-1,3)×0.08 + approved×0.12, 0, 0.95), 落在 confidence 上(排序信号)——authority 是写入时确定性声明的安全核心,加权绝不碰它

work / style / experience / external_fact 不进画像(分别归 work_state / expression / memory 段)。

回链可核验性:本机缺回链 ≠ 外机不可核验(2026-09-25)

问题。跨机同步上线(2026-09-22)后,W 机 1070 条 active observation 里有 918 条 evidence_ids = []。此前所有读侧判据都把它们读成同一句话:「这条结论没有支撑证据」—— 也就是「本机数据有问题」。

实测结论。那个读法是错的。两类必须分开:

档 含义 判据 怎么处置
verifiable 有回链(给了解析器且全部在本机可解析) — 正常
unverifiable_foreign 外机导入:回链按设计清空,源侧 id 在本机不可解析 id 由源机按原证据集派生,与本机空集不自洽 不是缺陷。只计数、打 foreign-unverifiable tag,不拦、不告警
missing_backlink 本机产出却没有回链 id 与空证据集自洽(= store 写入路径的形状) 真异常,告警 + 进人工队列
unknown 信息不足(id 不是派生形状) — 不指控任何一方

为什么清空是设计:scripts/ledger-import.mjs:82-85 导入时刻意清空 evidenceIds / supersedes——evidence 不跨机,跨机引用必然悬空,「留着比清掉更误导」。这一侧不改; 本方案也不写任何存量数据(零数据风险是它的全部卖点)。

怎么在不写数据的前提下把两类分开:observation 的 id 是按自身字段派生的 (obs_ + sha256(scope|subject|predicate|domain|text|JSON(evidenceIds)) 前 24 位)。 本机写出的行,id 必然与它当前的 (..., evidenceIds) 自洽;跨机导入行走 export-import.mjs 的显式 id 原样 INSERT,那个 id 是源机按原证据集算的、而回链已被清空 → 不自洽。W 机实测:152 条自洽(= 本机行,全部有回链)+ 918 条不自洽(= 导入行,全部无回链),0 例外。 判据只有一份实现:src/backlink.mjs(observationIdOf 搬到这里,store 反过来 import 它,防两处漂移)。

落地:

  • 放行闸门(src/release-gate.mjs)加第八类 backlink——此前该文件里 grep evidenceIds 0 命中,七类三档完全没有回链这一维。语义:本机缺回链 → hard_quarantine; 外机不可核验 → pass(拦下它等于把跨机同步整个否掉,那是换一个错误)。 新签名 gateVerdict(row, cfg, { resolvableEvidence })。
  • Dreaming 导出:无证据回链 一分为二(不可核验(外机导入…) / 无证据回链(本机产出…真异常))。判据不放宽——两类都仍然进不了 staging: 放行会让 572 个簇从「已知缺证据」变成「看起来有证据」(源侧 1393 个 evidence id 在本机 100% 不可解析)。
  • 写入侧护栏:parseObservations 遇到 evidenceIds: [] 逐条回 warnings; upsertObservation 结果带 backlink(missing_backlink 时 alert: true);consolidation 落 [acp] acp:degraded observation_without_backlink ... 日志;prompt 由「劝阻」改为要求 ≥1 条回链。 写入仍不拒绝(账本 append-only、fail-open)——护栏是留痕,不是拦死。
  • 只读体检:ledger-audit.mjs 新增 [回链] 一节,只有 missing_backlink 进告警。
  • 打分一律不动:backlinkTier 只标注在候选上。空回链的候选本来就有 evidenceSupportScore → confidence(0.6) 的兜底(composer.mjs:146),不存在「被压到 0」; 实测画像权重 min 0.6 / avg 0.604 / max 0.8。

数据位置与备份

  • 账本数据在 ledgerDir 下(表达视图和规则视图可单独配置目录):acp-ledger.db(SQLite,WAL 模式),八张表:证据 / 观察 / 候选 / 候选事件 / 规则(v6)/ 审计 / 候选记忆(v7) / 巩固跑批台账(v7)
  • 账本 schema 版本在 acp_meta.schema_version;升级是自动的(打开时建表并写版本号),无需手工迁移脚本
  • 物化视图在 ledgerDir/views/ 下,可随时重建(带校验和)
  • 规则视图(反馈通道,T4)在 rulesDir(缺省 ~/.dsh/rules)下:<domain>.md 人类可读,启动时从 ledger active 规则全量重建(Evidence is truth; views are rebuildable);规则经外部脚本写入后视图不会自动刷新,用 /acp rule rebuild 手动重建
  • 陈旧清理的空域集守卫(2026-10-02 事故):重建时会把「目录里带 kind: acp-rules 头、却不在本次域集内」的 .md 当陈旧域删掉(清理只检查带标记的文件;同名域视图写入仍会替换目标文件,建议独立目录);但域集为空时整条清理跳过,一个都不删,只在日志打一条 warn(写明目标目录与保留的 md 数)。缘由:当天一次域集为空的装配(apply() 里 eager 重建,未传 rulesDir → 回落 ~/.dsh/rules,且那一刻账本一条 active 规则都没读到)把该目录下的 security.md / workflow.md 当真陈旧域删了。取舍:宁可留下一个失效域的视图(可从账本重建、可手删,下一次带非空域集的刷新会正常把它收走),也不冒删光真规则的风险
  • 备份/迁移:导出(JSONL)→ 新环境导入,按内容哈希幂等合并
  • 数据是你的:卸载插件不会删数据;装回来即恢复

卸载

  1. 停止该 Profile 的 DSH 进程,备份 Profile 配置/锁文件和账本、表达视图、规则视图。
  2. 从 profile 的 package.json dependencies 里移除 dsh-adaptive-context,并从 dsh.profile.bundles 移除包名。
  3. 移除 profile cordis.patch.yml 中手工添加的 adaptive-context 配置,避免保留失效入口。
  4. 在该 Profile 目录执行 pnpm install 后重启,确认插件不再装配。

卸载保留 ledgerDir、viewsDir 和 rulesDir 中的数据;规则视图可能仍被宿主其他组件读取, 需检查规则装载范围。要彻底清除时,先备份并确认这些目录是 ACP 独占目录,再自行清理。 回滚需恢复原 Profile 配置/锁文件及必要的数据快照,步骤见 一次性 Profile 验收清单。

故障排查

症状 原因 / 处理
注入不生效 确认 cordis.patch.yml 里 ledgerDir 显式配置(DSH_HOME 不可靠,缺省可能落到当前目录)
沉淀不出观察 没配 consolidationProvider/Model → 走规则兜底(仍会产出,只是精度低);或证据积压没到节流线(10 条或 5 轮)
审批面板看不到晋升请求 审批请求由下一轮的 pre-step 发起(后台任务没有 agent 引用);确认会话有面板渲染
启动报 llm purpose 错误 内部用 purpose:'compaction'(dsh-llm 枚举只有 compaction/session-title)——别在 llmTasks 里覆盖这个语义
日志啥都看不到 开 debug: true;关键操作日志前缀是 [acp],可以 grep

开发

node test/<file>.test.mjs   # 单文件直跑(沙箱环境 node --test 递归受限)

设计长文见 docs/design/(架构 / 契约 / 编排 / 治理 / 沉淀 / 表达 / 多源等;2026-09-08 自 acp-docs 并入,原仓库已归档);开发史文档见 docs/history/。 仓库级开发计划与问题登记(backlog):docs/DEVELOPMENT-PLAN.md。

License 与致谢

MIT License。参考项目致谢见 ACKNOWLEDGMENTS.md(MemOS / Hindsight / personagent / DeepSeek Harness)。

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.