Repository navigation
Releases: Aik358/dsh-auto-memory
Release list
v3.3.17 · 自动沉淀「每日额度」落盘,跨宿主重启延续
[3.3.17] — 2026-10-23 · 自动沉淀「每日额度」落盘,跨宿主重启延续
一句话:
autoConsolidateDailyMax的计数此前只存内存、只有「日期变化」一个清零条件,宿主重启即归零 ⇒ 设成「每天 8 次」实际是「每次启动 8 次」。本版把计数按记忆日落盘,并对配置注释里从未实现过的单例承诺按实际行为改写。
已确认修复
| # | 位置 | 修复 |
|---|---|---|
| ① | lib/index.js · MemoryEngine |
新增 autoCallStatePath() / _loadAutoCallState() / _saveAutoCallState():状态落盘于 ~/.dsh/memory/auto-consolidate-state.json({date, count, lastAt}),构造期加载,累加后立即原子写(config-io 的 writeTextAtomicPreSync,tmp+rename) |
| ② | lib/index.js · consolidateTurn |
额度判定前把 _autoCallDate 对齐到 today,累加后落盘。日期口径用 memToday()(记忆日、dayBoundaryMinutes),不用 toISOString()(UTC 日,UTC+8 凌晨会差一天) |
| ③ | lib/index.js · _loadAutoCallState |
跨日 / 损坏 / 脏值 / 缺字段 ⇒ 显式归零并回写 _autoCallDate=today,不依赖「构造期内存恰好为 0」。文件读不到一律 fail-soft,绝不阻塞插件加载 |
| ④ | lib/index.js · DEFAULT_CONFIG |
autoConsolidateDailyMax 注释按实际行为改写:删掉「跨插件实例应只保留一个实例」(该机制从未实现,全仓无实例锁/PID 文件),改为如实描述「额度不跨进程共享」,并说明若要跨进程去重是独立需求 |
口径边界(如实说明)
- 冷却(
lastConsolidateAt)仍是内存态(SessionRuntimeStore,per-session)。本次不持久化,理由:每日计数已落盘,冷却即便重启失效最多也只多跑 1 次(下一次就被dailyMax挡住);而按sessionId落盘需处理「接续会话 id 会变」与「文件按会话增长」两个清理问题,收益不成比例。 - 额度不跨进程共享:同时开两个 DSH 会各算各的上限。本版不做跨进程去重(行为变更较大:第二个实例将完全不能自动沉淀),如需另开需求。
归因说明(重要)
这与 2026-09-23 修过的 A-11b 是同根同因:当时 lib/recall-stats.js 的 observe() 只置 dirty = true、全仓零调用 save(),导致重启后统计全清零;那次只修了那一个模块,autoConsolidateDailyMax 这处漏了。本次按「同族缺陷全仓普查」纪律一并处理。
测试
- 新增
tests/smoke/smoke-test-issue456-consolidate-quota.mjs:28 断言,真 import 生产MemoryEngine→ 真构造 → 真调_load/_save,断言磁盘文件内容与实例字段。 - 含 2 条负控:
_loadAutoCallState置空 ⇒ 重启延续判据必红;_saveAutoCallState置空 ⇒ 落盘判据必红(还原后复绿)——证明断言有鉴别力,不是恒真守卫。
构建与校验信息
- 构建源 SHA:
945ac0932867104cf7c3796054b1f81c856d8c69(REL 树main) - 平台:Windows 11 / Node.js v24.18.0
- 测试命令:
node tools/run-smoke.mjs(443 套件) - 执行套件数:443 | 结果:PASS 443 / FAIL 0 / TIMEOUT 0(161.7s)
- 排除项:无
- npm:
@a9i5k4/dsh-auto-memory@3.3.17,shasum0f36435ce61afcb0f8288bcada21ace2b235e6a2 - tarball 校验:registry shasum == 下载件 SHA1(node crypto 复算),24,925,975 字节
- 包内卫生:
tests/、docs/不在包内;.bak/凭据类文件 0 个 - 注意:宿主侧
lib/index.js改动需重启 dsh web 后生效。
v3.3.16 · 面板支持局域网/远程访问 + 技能查重面扩至磁盘
[3.3.16] — 2026-10-22 · 面板支持局域网/远程访问 + 技能查重面扩至磁盘
一句话:
dsh web --host <LAN-IP>部署下面板所有接口 403(守卫硬要求「来源回环 + Host=localhost」);本版把守卫扩为两档,未配置白名单时行为逐字节不变。同时把技能查重面扩到磁盘已有的SKILL.md,并折叠审批面里结构上无法晋升的观察行。
已确认修复
| # | 位置 | 修复 |
|---|---|---|
| ① | lib/index.js · isLoopbackRequest |
由「回环且 Host=localhost」单档扩为两档:①回环档(旧行为,未配置也生效)②白名单档(仅当白名单非空:私有/链路本地来源 + Host 命中白名单 + 非 sec-fetch-site: cross-site + 有 Origin 时必须同源)。公网来源、0.0.0.0、解析不出的形态一律 fail closed |
| ② | lib/index.js |
DEFAULT_CONFIG 新增 panelAllowedHosts(159→160),支持环境变量 DSH_AUTO_MEMORY_ALLOWED_HOSTS 覆盖;73 处面板守卫统一改调同一份已解析白名单(在 apply 内解析一次,避免 73 份判据漂移) |
| ③ | lib/index.js |
面板 403 响应体从只回 loopback-only 扩为带判定现场:reason / remoteAddress / host / allowlistConfigured / hint。只告知「有没有配、几条」,不回显白名单条目本身(防主机名探测) |
| ④ | lib/skill-export-host.js |
新增 listLocalSkillsPre:全量列举 ~/.dsh/skills/ 下所有可解析 SKILL.md(含用户手写、其它工具带来、孤儿导出),title 取正文 # 标题而非 ASCII name(中文技能才查得出重复) |
| ⑤ | lib/index.js · proceduresFindDuplicatePre |
查重加第二路:除 procedure store 外,还比对磁盘技能目录,标题归一化相等即命中并拒写(回传 skillDir 与来源标注)。只认精确相等、不做模糊匹配(避免误伤相似但不同的流程);磁盘列举失败不阻塞 store 那一路 |
| ⑥ | lib/index.js · memory_procedure_list |
默认折叠「observationOnly 或 缺 successCriteria」的低质量观察行(结构上无法晋升),结尾如实报出折叠条数并给 includeNoise=true 查看全量。不删、不隐藏 |
归因说明(重要)
第 ⑥ 项不是在阻止新的污染。核查确认:机械切片产生源已于 2026-09-23 结构性删除(memory-hub.js 的 crossFeed() 循环体为空,hubMechanicalProcedureFeedEnabled 开关连同设置项、getter 同轮移除;procedureCandidateFromRow 另补「无真标题即拒收」)。
本机实测 103 条中 26 条低质量行:26/26 全部为机械派生,创建时间全部早于 2026-09-23;2026-10 新建的 27 条零低质量。⇒ 折叠处理的是历史存量的观感,不是防回归。
配置键计数联动
DEFAULT_CONFIG 159 → 160,已同步 README.md / README.zh-CN.md / docs/WHITEPAPER.md / docs/FRONTEND-CO-CREATION.md / docs/HOMEPAGE-CONTENT-FOR-GM53.md 共 6 处,tools/verify-docs.mjs 全部一致。
已知限制 / 未验证
- GUI 设置页暂无
panelAllowedHosts输入框:前端字段表是手写的(108 个可写键里无此键),当前启用方式只有环境变量或直接编辑~/.dsh/dsh-auto-memory.json后重启。此前 403 提示里写「在插件设置里填」是假承诺,已改为如实描述。设置页入口留待后续版本。 - 未对齐宿主
--trusted-host:宿主未把该信任列表暴露给插件(本仓 0 处接入点),故只能自建白名单。 - 存量 26 条低质量行未物理删除(按「技能库条目删除须用户批准」的规矩,待裁定)。
- 宿主侧改动需重启 dsh web 生效(路由守卫在
apply期解析一次);前端半边刷新页面即可。
验证
- 全量回归 PASS 442 / FAIL 0 / TIMEOUT 0(161.8s)。
- 新增套件
tests/smoke/smoke-test-issue454-panel-lan.mjs:61 断言全绿,变异捕获 6/6(含「401 体不得回显白名单条目」的变异验证)。 - 新增套件
tests/smoke/smoke-test-issue453-procedure-dedupe.mjs:30 断言全绿,变异捕获 3/3。 - 回环档等价性差分:修复前(HEAD)与修复后实现抽出,在 1584 个输入组合(16 来源地址 × 11 Host × 9 header 组合)上逐例比对 ⇒ 0 处差异(36 例 true / 1548 例 false),证明「未配置白名单时行为不变」。
tools/verify-docs.mjs0 红项(工具 19 · 路由 73 · 配置键 160)。
构建与校验信息
- 构建源 SHA:
4a0d621f3e8f7dadf7d2de6649b4f6db891d065f(REL 树main) - 平台:Windows 11 / Node.js v24.18.0
- 测试命令:
node tools/run-smoke.mjs(442 套件) - 执行套件数:442 | 结果:PASS 442 / FAIL 0 / TIMEOUT 0(161.3s)
- 排除项:无
- npm:
@a9i5k4/dsh-auto-memory@3.3.16,shasum0d8ffb1f3041b42f8e7f077ec2cab9a15e264123 - tarball 校验:registry shasum == 下载件 SHA1(node crypto 复算),24,922,903 字节
- 包内卫生:
tests/、docs/不在包内;凭据类文件 0 个
v3.3.15 — 前端超时区间对齐后端 + 根治 docs 整树覆盖隐患
一句话
上一版把接续超时开放成设置项,但前端仍按 600 秒封顶——你把「刷新仪式超时」调到 900,后端会等 900 秒、前端 600 秒就放弃并报超时。本版把两端区间与默认值对齐,并给发布脚本加一道 docs 覆盖护栏。
改了什么
| # | 位置 | 修复 |
|---|---|---|
| ① | lib/client.js · waitForRefresh |
轮询区间 15–600 → 15–900、默认 90000 → 120000 毫秒,与后端 DEFAULT_CONFIG 同源 |
| ② | docs/landing/news/index.html |
dev 与 main 的措辞对齐,使 docs/ 整树覆盖不再产生线上回退 |
| ③ | tools/release.mjs |
新增 docs 覆盖护栏:复制完 docs/ 后把 REL 工作区与 origin/main 逐文件比对(两侧归一化 CRLF→LF),列出实质内容有差异的文件并告警 |
为什么护栏是「告警」而不是「阻断」
docs/ 覆盖本身是正向路径(dev 是唯一发布源,dev 领先 main 是常态)。粗暴 fail-closed 会让每次正常发版都崩。真正的风险只在于「某处改动是在 main 上做的、dev 没同步」,这只能由人判断,故只做机械比对 + 显式清单。
验证
- 串行全量回归 PASS 440 / FAIL 0 / TIMEOUT 0(746.8s)。
- 护栏以独立脚本对真实 REL 实测:准确识别出
docs/下 3 个实质内容差异文件(FRONTEND-CO-CREATION.md/HOMEPAGE-CONTENT-FOR-GM53.md/WHITEPAPER.md,即上一版 158→159 的计数改动),且未被行尾差异干扰(dev 是 CRLF、main 是 LF)。 - 真实构建时护栏已实际打印告警(非仅在测试中验证)。
docs/landing/news/index.html归一化后与origin/main逐字节一致(sha16d3c8e02c94c0689d)。- 两把基线锁按实测重钉并附归因:
iter5-skin→7d3fc06e…、settings-archive-interval→3ee26651…。 - tarball 三重校验:registry
dist.shasum= 下载件 SHA1 =9587c0a8b765498e90f9b6bf08ca3624100e248c;解包 246 文件、version=3.3.15、指纹行dsh-030-timeout-range-docs-guard、前端 900 区间与 120s 默认值均在包内、tests/与docs/不在包内、凭据 0。
仍在问题中 / 未验证
- 护栏在 dry-run 模式下会跳过(staging 目录不是 git 仓库,走 fail-soft 分支),只在真实构建时生效。这是刻意设计(dry-run 不该依赖 REL 的 git 状态),但也意味着dry-run 全绿不代表护栏跑过。
- 护栏只覆盖
docs/;skins/、locale/、.github/等其他整树拷贝项仍未加同类护栏。 - 真实 6 tok/s 本地模型仍未端到端验证(本机无该规模环境),两端的区间一致性已由代码与锁验证,但实际慢模型下的等待体验未实测。
v3.3.14 — 接续刷新仪式超时可配(本地/慢速模型诉求)
一句话
本地模型(实测 6 tok/s)在默认 90 秒内跑不完接续刷新仪式,而「单次探测超时」写死 30 秒、设置页也找不到任何可调项。本版把三层超时中的两处开放成配置项,默认值各抬高。
改了什么
| # | 位置 | 改动 |
|---|---|---|
| ① | lib/index.js |
总超时默认 90 → 120 秒(按用户要求「拉大一点点,大概 30 秒左右」);允许区间 15–600 → 15–900 |
| ② | lib/index.js |
单次 probe 上限由 Math.min(30000, …) 写死改为可配置:新增 autoContinueProbeTimeoutSeconds(默认 60 秒,允许 10–300),仍与剩余预算取 min |
| ③ | lib/client.js + .frozen |
两个设置项三面同步开放(经典档手写区 / iter5 生成区 / 冻结档),各 +2 个数字控件 |
| ④ | lib/client.js |
i18n zh/en 各 +4 键;ja 走 zh 兜底(L10N.ja 表本就不含任何 f* 字段键,与该表既有惯例一致) |
为什么这是「真配置」而不是加个按钮
原代码两处都在函数内部写死:
const timeoutMs = (sec >= 15 && sec <= 600 ? sec : 90) * 1000 // 上限 600、越界静默回 90
const probe = (fn) => continuationProbePre(fn, Math.min(30000, …)) // 30 秒写死,无从调整现在改为读配置 + 模块级常量兜底,并保留 min 关系。对未改配置的用户:默认值从 90/30 变为 120/60,只会更宽松,不会更早超时。
验证
- 串行全量回归 PASS 440 / FAIL 0 / TIMEOUT 0(
--jobs=1 --timeout=180000,761.7s,440/440 套件)。 - 新增
tests/smoke/smoke-test-v3314-continuation-timeout.mjs(22 断言,真构造 engine + 真跑hostRefreshRitual):- A 组真构造 MemoryEngine 后读
engine.config(不是读源码字符串)断言默认值 120 / 60; - B 组注入永不 resolve 的
inspect,断言按时 fail-soft 而非挂死,耗时 ≈ probe 值; - C 组同一逻辑两组配置(probe 10s vs 20s)⇒ 实测耗时显著不同,证明上限真由配置驱动;
- D 组负路径:越界值回落默认、
min关系成立、仪式关闭立即返回disabled; - E 组变异必红:M1 probe 退回写死 30000 →
fail=1;M2 默认退回 90 →fail=1。
- A 组真构造 MemoryEngine 后读
- ★过程中发现并修掉三个「假绿 / 没鉴别力」:
- 变异子进程原本用
status !== 0判红,会把「被 spawnSync 超时杀掉(status=null)」也当成红 ⇒ 收紧为status === 1; - B 组原配置对 M1 变异没有鉴别力:总超时给 15s 时,
min(写死30000, 15000)仍是 15s ⇒ 变异照样绿。已把 B 组总超时放宽到 900s,只让 probe 决定耗时,M1 才真正变红; - 新套件单跑 161.1 秒,逼近轻车道 180 秒上限 ⇒ 已登记进
HEAVY_MS重车道(timeout 240s)。
- 变异子进程原本用
- 三把基线锁按实测重钉并附归因:
r26E3F84BC89E…→D5FCCE5A…(1,109,579 字符)、iter5-skin→24d7f96f…、settings-archive-interval→461dbf8c…。 - 判据过期修正(非缺陷):
smoke-test-continuation-transaction的 C11 原断言ms <= 30000(「上限恒为 30s」时代)⇒ 改为<= 300000,判据意图不变。 - 两个靠
new Function抽源码求值的套件(autocont-host/continuation-transaction)按其自身既有注入表纪律补入两个新常量。 - tarball 三重校验:registry
dist.shasum= 下载件 SHA1 =7bbb71607778cde19d53d98d6990f90d64a7ac57;解包 246 文件、version=3.3.14、指纹行dsh-029-continuation-timeout、新键与新控件均在包内、tests/与docs/不在包内、凭据 0。
仍在问题中 / 未验证
- 未在真实 6 tok/s 本地模型上验证:本机无该规模的本地推理环境。本批以「注入永不 resolve 的 inspect + 缩小的超时值」验证超时机制与配置驱动关系,不是真实慢模型的端到端实测。
- 前端等待循环(
client.js的waitForRefresh)仍写死 90 秒、未并入本次配置;它读同一配置键但上限不同 —— 这是已知的不一致,留作后续统一。 - 顺带修复的发版问题:本次推送因 REL 树与远端 main 分叉被受保护分支钩子拒绝(
--force被拒),改为rebase origin/main后快进推送;过程中发现release.mjs会把 dev 的docs/整树覆盖进 REL,已确认本次「协作征集」文案未被回退(与 main 逐字节一致)。
v3.3.13 — 补 issue #451 的「半修」:水位三字段投影不全 + 前端从未消费
一句话
v3.3.11 声称「水位三字段已透出、面板可核对走没走代理压缩兜底」,实测发现两处都没做完。本版补齐。
缺陷形态(重启后实测发现)
① 后端:三个投影点里只有一个漏字段
handoff-state 有 3 个 waterLevel 构造点(rec 分支 / else 分支 / 全局 state 分支)。其中 else 分支(有 sessionId 但该会话尚无水位记录时走的那条)没有 meterViaProxy / estimatedTokens / realUsageTokens:
6751: } else {
6752: const wi = await this.waterWindowForSession(sessionId)
6753: water = {
6754: ratio: 0, tokens: 0, window: ..., meter: '',
6755: ...
6756: } ← 三字段不在这里
⇒ 调用方恰好走到这条分支就拿到 undefined,而另两个分支正常。典型的「半修」,故障难复现。现补齐(取值语义 = 未走兜底:false / 0 / 0)。
② 前端:这三个字段从未被消费
lib/client.js 对 meterViaProxy / estimatedTokens / realUsageTokens 的引用数为 0(对照:officialRatio 2 处、thresholdMode 3 处都有消费点)⇒ v3.3.11 的 CHANGELOG 那句「面板可核对」是空头支票。
现新增「代理压缩双数对照」行:显示「官方估算 X token / provider 实测 Y token」,i18n 三语(zh/en/ja)各 +1 键。
③ 为什么 3.3.11 的守卫没拦住
a30 套件 D6b 把计数写死为「记录 1 处 + 两条投影各 1 处 = 3」—— 而实际有 3 个构造点。正是这条过期判据让漏字段的分支保持绿色。现改为跟着实际构造点数走(waterCtorCount + 1),a30 从 82 → 83 断言。
对普通用户的影响:零
新行受 wl.meterViaProxy === true 门控 —— 未使用 billion-context 代理压缩的用户永远为 false,不渲染任何新节点,界面与 3.3.12 逐字节等价。
验证
- 串行全量回归 PASS 439 / FAIL 0 / TIMEOUT 0(
--jobs=1 --timeout=180000,618.7s,439/439 套件)。 - 新增
tests/smoke/smoke-test-v3313-water-projection.mjs(29 断言):- A 组真跑
handoff-state三分支(全局视图 / else 分支 / 带兜底状态),逐分支断言三键齐全与取值语义(含真值传播实测900000/420000); - B 组断言前端真的消费(渲染锚点 + 门控 + 两数都被读取 + 三语齐备);
- C 组负路径;D 组结构判据(三构造点全带三键);
- E 组变异必红:删掉 else 分支三字段 →
fail=1;去掉前端门控 →fail=2。
- A 组真跑
- ★D 组首次实现对变异不敏感(硬编码读真实文件,注入路径未生效 → M1 变异仍绿)。已修为读可注入路径,M1 才真正变红 —— 这条本身就是「守卫没鉴别力」的实例。
- 三把基线锁按实测重钉并附归因:
r26E372C0DA04…→F84BC89E…、iter5-skin127db190…→9caf68af…、settings-archive-intervalec132f81…→6f21c2ad…。 - tarball 三重校验:registry
dist.shasum= 下载件 SHA1 =bc4e1de03aa164ff7e70ec06b68803a5113dba42;解包实测 246 文件、version=3.3.13、指纹行dsh-028-water-proxy-pair、水卡新行与 i18n 均在包内、tests/与docs/不在包内、凭据类文件 0。
仍在问题中 / 未验证
- 真实链路仍未本机验证:本机未安装 billion-context 代理型插件,
meterViaProxy恒为false。本批以「预置state.waterLevelProxyCompat后真跑handoff-state」验证真值传播,未在真有该插件的机器上跑过。 paramSource字段仍是「后端投影、前端未消费」—— 不属于 #451 的承诺范围(同批字段里多投影的一个),本次未改,留作后续清理。- 本轮回归中
smoke-test-issue207-processes曾 1 次失败(EPERM: rename cont-seq.json.tmp,Windows 文件占用),单跑连跑 6 次全 PASS,判为并发夹具偶发;最终一轮 439/439 全绿。
v3.3.12 — 团队同步活锁 / 缺幂等键 / 响应无上限
一句话
服务端记录只增不减 + 客户端每 5 秒重取全史,最终把服务端撑到 12GB 文件 / 29GB 常驻。本版修客户端侧五处、新增 2 个配置键、附一份服务端处置手册。
根因与修复(五处)
| # | 位置 | 修复 |
|---|---|---|
| ① | lib/team-sync.js |
推送体没有幂等键(实测顶层仅 [kind,key,at,payload,member])⇒ 服务端结构上只能 append。现补 idemKey(取 outbox 已持久化的 eventId,缺失回退 kind|key),并另带一份 eventId 兼容老服务端;重试时推送体逐字节相同 |
| ② | lib/team-pull.js |
游标只认数字,而契约里是 c_0001250 这类字符串 ⇒ since 永远 0 ⇒ 每 5 秒重取全史。新增 normalizeCursorPre:字符串与数字都接受,NaN/Infinity/空串明确拒收 |
| ③ | lib/team-pull.js + lib/index.js |
游标只在内存,重启即归零。现经注入 loadCursor/saveCursor 落到 ~/.dsh/memory/team/pull-cursor.json(原子写 + 隔离开读),reset() 同样落盘;该模块仍然不 import fs |
| ④ | lib/team-pull.js |
no-applier 活锁:我方唯一生产者推 handoff 而 appliers 只有 fact,服务端回抛时旧实现判 transient ⇒ 游标永久不动。现按「是否本次 requestKinds」分流:请求内仍 transient(保 #364),请求外按 business 前进 |
| ⑤ | lib/team-auth.js |
响应体无字节上限 ⇒ 大响应先把客户端撑爆。现加 32MB 硬上限:content-length 预检(超限不读体)+ 实测兜底,返回 response-too-large |
新增
- 配置键
teamPushPath/teamPullPageLimit(DEFAULT_CONFIG156 → 158),设置页三面同步 +2 行;上行端点可覆盖,默认值不变保老服务端零影响。 docs/TEAM-SYNC-INCIDENT-PLAYBOOK.md:止血顺序、服务端三处必改、可照抄的最小实现、存量数据压缩脚本、四条验收判据、回退路径。tests/smoke/smoke-test-team-sync-livelock.mjs(71 断言 + 5 组变异必红)。
仍在问题中 / 未验证
- 服务端代码不在本仓库,也无法在本机找到(D:/E:/C: 全盘搜
team-server目录与records.jsonl均 0 命中,git log -S records.jsonl0 命中)⇒ 「29GB = 全量JSON.parse」是按其行为推断(12GB × 2.4 ≈ 29GB,与 JS 对象膨胀量级吻合),未在真实服务端上验证。 - 真实两机链路未端到端验证:本机
teamEnabled=false、未装该服务端;所有断言基于真构造 + 真调用 + 假服务端注入。 - 存量数据不会自动缩小:本版只止住增长;已有的 12GB 需按手册 §4 主动压缩或换库。
验证
- 串行全量回归 PASS 438 / FAIL 0 / TIMEOUT 0(
--jobs=1 --timeout=180000,596.5s,438/438 套件)。 - 既有团队套件全绿:
issue34346/0、issue364PASS×2、issue370PASS、team-identity-seam17/0、settings-parityPASS、iter5-skinPASS、l3-team100/0、client-loadable17/0。 - 基线锁按实测重钉并附归因:
r26E355A407E3…→72C0DA04…;iter5-skin08aa7ef7…→127db190…;settings-archive-intervalf4ce3086…→ec132f81…;l3-team键数 23→25。两条 client.js 锁均用「删掉本批 8 行后复算 == 旧锁」正面证明漂移全来自本批。 verify-docs全部一致(配置键 156→158 已同步 6 处文档);build-iter5-skin --check --strict= SYNC-OK。- tarball 三重校验:本地 pack SHA1 = registry
dist.shasum= 下载件 SHA1 =69f9f393174ce8b13033d070da20fa3961a23957;解包实测 246 文件、version=3.3.12、指纹行dsh-027-team-sync-livelock、tests/与docs/不在包内、凭据类文件 0。
建 issue 说明
注:smoke-test-external 单跑实测 66.5s,超过 runner 默认 60s 阈值;--jobs=1 会绕过双车道(run-smoke.mjs:437)故只能拿到默认阈值 ⇒ 本次统一用 --timeout=180000,该套件实测 PASS。
v3.3.11 — billion-context 代理压缩适配 + 语义侧车根治
已确认修复
- #451:装了 billion-context 代理型压缩插件时,上下文水位恒虚高十余倍(实测 2,177,730 vs 16 万),导致每轮误判硬触发(重复写骨架账本 + 无谓 arm 自动接续)。现改为四道校验全过才用 provider 真实 usage 计算水位,任一不满足逐字节走原路径。
- Python 语义侧车静默残废:进程 alive 但从不产出结果(stats.starts=1 / exits=0)。补解释器验证闸、长驻进程健康巡检、stderr 增量落盘、诊断日志轮转、dispose 清理。
新增
- 配置键
waterLevelProxyCompat(默认开)。检测到该插件时一次性询问是否开启;设置页三档皮肤同步可改;水位卡显示「代理压缩实测」。
仍未解决 / 未验证
- 上游缺陷未修:根因在
@deepseek-ai/dsh-token-meter的守卫判据(用未压缩 anchor 估算去比较压缩后真实用量),本版只是插件侧防御。已确认 npm0.2.1-rc.2与0.2.1-alpha.5两版均未修,建议上报上游。 - 真实链路未本机验证:本机未安装该插件,兜底以合成事件验证(a30 套件 82 断言 + 5 组变异必红)。有该插件的用户需实测
water level advisory行的双数输出。
验证
- 全量回归 PASS 429 / FAIL 0 / TIMEOUT 0(
--jobs=1串行,506.1s,429/429 套件) - tarball 双检:本地 pack SHA1 == registry dist.shasum ==
a49694d2cd52270e29ba931b56320ec736393e09(node 复算,逐字节同源) - 重启后实测
proxyCompaction = {"enabled":true,"detected":false,"reason":"absent"},水位ratio=0.43 / meter=official:usage⇒ 普通用户路径与 3.3.10 完全一致
v3.3.4 — 吸收社区 60 项修复(#359–#419)+ 修「启动自检误清配置错误」
3.3.4 — 吸收社区 60 项修复(#359–#419)+ 修「启动自检误清配置错误」
安装 / 升级
npm install @a9i5k4/dsh-auto-memory@3.3.4界面半边刷新页面即可;宿主半边(
lib/index.js)改动需重启 dsh web 生效。
构建源(可逐项核对)
| 项 | 值 |
|---|---|
| 构建源提交 | 832e256205290a7f9f02024701d0466c4ae2a5cc(GitHub main = tag v3.3.4) |
| npm 包 | @a9i5k4/dsh-auto-memory@3.3.4 |
| tarball shasum | dc75b632e3c11219fea54068f42aecd866dafc53 |
| 文件数 | 246 |
| 平台 / 运行时 | Windows 11 · Node 24.18.0 · npm 11 |
| 全量测试命令 | node tools/run-smoke.mjs |
| 结果 | 399 PASS / 1 FAIL / 0 TIMEOUT / 208.6s |
| 失败项 | smoke-test-a1-mutation-admission —— 既有间歇缺陷,非本版引入 |
| CI(同 sha) | 见 Actions |
本版内容
1. 吸收社区贡献(#357 承诺的落实)
合并并逐块移植 Minervaowl7 的 PR #394 / #420(共 73 个提交,处理 60 项 issue:#359–#419)。
main:「054942b5」→「394fdbe2」→「832e2562」,两个 merge commit 保留在历史上(7e379262+394fdbe2)- 并开启
main分支保护(禁止强推 / 禁止删除 / 对管理员同样生效)。原因:旧推送命令带--force,已把 PR#240 / #243 / #279 / #280 四个已合并 PR 从main世界线抹掉(页面仍显示 Merged,merge commit 已非祖先) - 60 项 issue 全部保持 open,未因合并触发自动关闭(两个 PR 的正文与 73 条 commit message 中
fix #N/closes #N计数为 0)
2. 为什么不是照搬(移植方式可机器复核)
开发树与 main 历史分叉且行尾不同(开发树 CRLF / 仓库历史 LF / .gitattributes 未声明 eol)⇒ 直接三方合并实测 790 冲突;merge.renormalize 只能降到 372 且会改变结果树。改用三分桶整文件法:
| 桶 | 条件 | 数量 |
|---|---|---|
| A | 开发树该文件 ≡ main(忽略行尾)⇒ 整文件取 PR 版(等价于一次干净三方合并的结果) |
84 |
| B | 开发树中不存在 ⇒ 新增 | 56 |
| C | 需判断 | 2 |
| 守恒 A+B+C | 142 = PR 变更路径总数 |
EOL 全程不翻转:17 个 CRLF 保持 CRLF、67 个 LF 保持 LF、53 个新增按 LF、3 个二进制逐字节。
C 桶处置:.gitattributes 保留开发树版(6 条有效规则是 PR 的 1 条的真超集);tools/check-write-contract.mjs 同名异物 ⇒ 重命名共存(PR 版 → check-write-contract-await.mjs,两套检查并存)。
3. 缺陷修复
- 启动自检会静默抹掉真实的配置错误(移植中发现,与 #376/#421 同族):
updateEmbeddingConfigPre在createOnly命中已存在文件时不写盘,却返回与「真写过」同形的对象 ⇒ 调用点engine._jsConfigurationError = ''凭空清掉真实错误。启动约 16s 后跑一次该自检 ⇒ 用户重启后面板显示「正常」,配置其实仍是坏的。现让「未写」可区分(__unchangedByCreateOnly),调用点据此才清空。 - 覆盖 #421(
lujfsd报:唤起注入模式改为 canary-explicit 后重启被重写回 shadow):PR 已引入启动自检createOnly: true,叠加上述修复后启动路径既不覆盖用户档位、也不误清错误状态。 - 诊断证据口径恢复:
semantic-emit: ok ...补回created=/emit=/policy=—— #421 报障者引用的正是这三个字段。
4. 发布物漏拷修复(发版时实测抓到)
.gitattributes此前不在任何复制清单:漏拷会让它从main被删除 ⇒ CI 行尾红、zip 字节契约与 group-digest 锚串失守tools/白名单缺两个被发布树测试引用的写入契约检查器
未吸收项(如实登记)
- #390 / #400 / #405:有修复代码,但在开发树回归中找不到对应套件(其余 57 项都有)。已在各 issue 评论中回报并建议并入相邻组;未替贡献者补测试。
- #179 / #201:两条 [Hold] 继续保持 open(迁移 / 重嵌入代价需产品决策)。已附今日重新复现的证据。
独立验证
git fetch origin && git log --oneline -3 origin/main # 看两个 merge commit
git merge-base --is-ancestor 3d55c4552fc0662ce9f5ba03a62d5f98effb50f0 origin/main \
&& echo "PR#420 在 main 上"
node tools/build-iter5-skin.mjs --check # 期望 SYNC-OK
node tests/smoke/smoke-test-issue368-write-contract-negative.mjs # PR 的写入契约套件
node tests/smoke/smoke-test-i332-write-contract.mjs # 开发树既有契约套件(两者并存)完整变更见 CHANGELOG.md。
v3.3.3 — JS 档语义开关修复 + 关系图集成补全 + 回归提速 1.79×
主要修复
- 只装 JS 档的用户,语义开关永久不可用(点开关报
Invalid semantic configuration)。根因:semantic-emit端点把「配置文件不存在」与「真损坏」当成同一种情况 —— 全新安装或刚切换引擎的用户配置本就还没建,却被判为损坏直接抛错。现在区分 ENOENT 与真损坏:缺失时按引擎身份首建,只有真损坏才报错。修复 #356 家族。 - 模型刚下好、还没重开面板的窗口期:下载完成即补建引擎配置,不再要求重开面板。
- 工作区关系图移植不完整(#354):默认档/经典档/小窗此前仍走旧固定尺寸 SVG,缺共享卡片/标题/工具栏样式 ⇒ 小窗横向溢出、点击节点无反馈。已补齐手写入口适配器与共享 CSS。
- 该端点补六处诊断留痕:此前「报保存失败但盘上零痕迹」,支持端无从归因;现在 MISSING / CORRUPT / 原子写失败 / 成功 / catch 兜底各自留痕,且损坏与缺失必须可区分。
质量
- 全量回归 354 PASS / 0 FAIL / 0 TIMEOUT;
verify-docs.mjs全部一致;生成器--check= SYNC-OK。 - 回归提速 1.79×:276.4s(1 TIMEOUT + 1 并发假红)→ 147.3s。根因实测:最长套件单跑即 67.8s 已超原 60s 阈值;12 个最重套件串行 389s 仅耗 16.5 CPU 秒(≈4% CPU)⇒ 等 IO 而非 CPU 密集。改为重/轻双车道调度。
- 新增永久套件 2 个(均真执行被测逻辑):
smoke-test-i356-js-only-embedding-config.mjs(49/0,含「损坏不得误报缺失」负路径)、smoke-test-workspace-network-integration.mjs。
站点与文档
- 宣传主页与技术报告上线 GitHub Pages:https://aik358.github.io/dsh-auto-memory/
- README 两份顶部链接由第三方代理
htmlpreview.github.io换成正式站点。
关联 issue / PR
安装 / 更新
npm install @a9i5k4/dsh-auto-memory@3.3.3或在 DSH 插件设置页点「检查更新」。宿主半边需重启 DSH 生效,界面半边刷新页面即可。
本条 Release 也是对本仓协作流程建议(#357)的落地承诺之一:此后每次 tag 均配套 Release,列明主要修复、关联 issue 与安装方式。