@kira905/dsh-memory-toolkit 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dsh-memory-local/deploy.mjs +14 -2
- package/dsh-memory-local/lib/host-adapter.js +3 -3
- package/dsh-memory-local/src/host-adapter.js +3 -3
- package/memory-db-tools/audit-analyze.mjs +1 -1
- package/memory-db-tools/audit-struct-probe.mjs +2 -2
- package/memory-db-tools/refine-memories.mjs +1 -1
- package/memory-engine/lib/domain-tags.mjs +1 -1
- package/memory-engine/test/07-domain-tags.test.mjs +6 -6
- package/memory-engine/test/08-distill.test.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
本仓的版本按**语义化版本**:改结论/改契约升主版本,加能力升次版本,修错别字与文档订正不升。
|
|
4
4
|
英文摘要见每节末尾的 *English* 行。
|
|
5
5
|
|
|
6
|
+
## v0.1.2 — 2026-10-30
|
|
7
|
+
|
|
8
|
+
**内部标识残留清剿**(无 API / 行为契约变化):
|
|
9
|
+
|
|
10
|
+
- 注释里残留的内部笔记路径、构建机设备标记一并清掉;`dsh-memory-local` 的 `lib/` 与 `src/` 两份适配层副本
|
|
11
|
+
改成一致(`memory-engine` 184 项与适配层收敛用例复跑同绿)。
|
|
12
|
+
|
|
13
|
+
*English: residual internal note paths and build-machine device markers removed from comments; the lib/ and src/ adapter copies stay byte-identical; no behaviour change.*
|
|
14
|
+
|
|
15
|
+
## v0.1.1 — 2026-10-30
|
|
16
|
+
|
|
17
|
+
**部署面补齐 + 用语刷净**(无 API / 行为契约变化):
|
|
18
|
+
|
|
19
|
+
- `dsh-memory-local/` 部署侧支持 `.modules.yaml` profiles(主包 0.2.0-rc.x 的文件布局),新增「全新安装」分支,备份目录改为按需创建。
|
|
20
|
+
- 内部用语刷净:构建机的设备标记改为中性写法(`【设备:ROG】`),文档标签示例由设备名改为通用词(`工作记录`);对应单测断言同步更新,`memory-engine` 184 项全绿。
|
|
21
|
+
- 本版起 `npm publish` 走 `next` 标签、稳定后再挂 `latest`。
|
|
22
|
+
|
|
23
|
+
*English: deploy side now supports `.modules.yaml` profiles (host 0.2.0-rc.x) with a fresh-install branch and lazy backup-dir creation; internal build-machine wording scrubbed (no API/behaviour change).*
|
|
24
|
+
|
|
6
25
|
## v0.1.0 — 2026-10-19(首发)
|
|
7
26
|
|
|
8
27
|
**首发范围**(从自用工作流中拆出的记忆面四件,源码级只读复制 + 脱敏 + 补齐仓骨架):
|
|
@@ -137,8 +137,13 @@ console.log(`source : ${here}`)
|
|
|
137
137
|
console.log(`target : ${target}${isProduction ? ' ⚠ PRODUCTION HOME' : ' [non-default home]'}`)
|
|
138
138
|
console.log(`entity : ${entityExists ? (alreadyFork ? `already fork (sha ${entitySha.slice(0, 16)}…)` : entityPkg?.fork ? 'fork, but different sha' : `upstream ${entityPkg?.name}@${entityPkg?.version}`) : 'absent'}`)
|
|
139
139
|
console.log(`lib sha : ${srcSha}`)
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
// gate0b:profile 可加载性 —— 0.1.x 世代用 node_modules/.package-map.json,
|
|
141
|
+
// 0.2.0-rc.x 起该文件已废弃(2026-10-28 实测:已装 @deepseek-ai 包 6,273 个 .js
|
|
142
|
+
// 里 `package-map` / `packageMap` / `modules.yaml` 零引用),现世代以 pnpm 的
|
|
143
|
+
// node_modules/.modules.yaml 为准 ⇒ 二者任一存在即视为可加载。
|
|
144
|
+
const modulesYamlFile = path.join(profile, 'node_modules', '.modules.yaml')
|
|
145
|
+
if (!fs.existsSync(packageMapFile) && !fs.existsSync(modulesYamlFile)) {
|
|
146
|
+
console.error(`[deploy] 找不到 ${packageMapFile} 或 ${modulesYamlFile} —— 这不是一个可加载的 DSH profile`)
|
|
142
147
|
process.exit(EXIT.USAGE)
|
|
143
148
|
}
|
|
144
149
|
|
|
@@ -170,6 +175,12 @@ if (isUpstream) {
|
|
|
170
175
|
const existing = findMatchingSnapshot(target)
|
|
171
176
|
if (existing) { backupDir = existing; reusedSnapshot = true }
|
|
172
177
|
else backupDir = path.join(archiveRoot, `g24-s2a-memory-deploy-${stamp()}`)
|
|
178
|
+
} else if (!entityExists) {
|
|
179
|
+
// 目标 profile 里**根本没有** dsh-memory 实体 = 全新安装(2026-10-28 为小汐生活实例
|
|
180
|
+
// `--profile life` 补的分支):没有「上游原物」可归档,restore.mjs 也用不到还原源
|
|
181
|
+
// ⇒ 只建一个记录目录,DEPLOY-INFO 落这里。
|
|
182
|
+
backupDir = path.join(archiveRoot, `g24-s2a-memory-deploy-${stamp()}`)
|
|
183
|
+
console.log('[deploy] 目标 profile 无 dsh-memory 实体 = 全新安装,无需归档上游原物')
|
|
173
184
|
} else {
|
|
174
185
|
// 已在 fork 态:沿用最近一个「含上游原物」的备份目录(restore 的唯一还原源)
|
|
175
186
|
const candidates = fs.existsSync(archiveRoot)
|
|
@@ -288,6 +299,7 @@ const info = {
|
|
|
288
299
|
rollback: `node ${path.join(here, 'restore.mjs')} --target ${home}${isProduction ? ' --allow-production' : ''}`,
|
|
289
300
|
}
|
|
290
301
|
const infoFile = path.join(backupDir, `DEPLOY-INFO-${stamp()}.json`)
|
|
302
|
+
fs.mkdirSync(backupDir, { recursive: true })
|
|
291
303
|
fs.writeFileSync(infoFile, `${JSON.stringify(info, null, 2)}\n`, 'utf8')
|
|
292
304
|
console.log(`\n[deploy] complete — 记录:${infoFile}`)
|
|
293
305
|
console.log('[deploy] 未重启任何 DSH(本脚本不做重启)。隔离实例请用测试环境冒烟脚本启动:')
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
// 唯一源 = 本文件;派生副本 = `tools/sync-host-adapter.mjs` 幂等生成到各包 `lib/host-adapter.mjs`(含源 sha 头);
|
|
51
51
|
// 守门 = `tools/check-decoupling.mjs` R5 校验副本 sha == 唯一源。
|
|
52
52
|
//
|
|
53
|
-
//
|
|
53
|
+
// P0 落地 2026-09-14 | P2-提前批 2026-09-15 | +`SVC.clientModules`(生态面板 boot 解析修复)2026-09-23
|
|
54
54
|
// | 2026-09-28 档 B 切(`UNKNOWN_FAMILY_POLICY`: 'unknown' → 'open',主人单独批准)
|
|
55
55
|
// | 2026-10-10 空会话误判治本(`classifyTail` 加「整段零回合内事件 ⇒ closed」前置判定;
|
|
56
56
|
// 修「新建空会话静止 10 分钟被判卡死」;真源 `docs\交付报告-卡死自愈空会话误判治本-20261010.md`)
|
|
@@ -105,7 +105,7 @@ export const EV = Object.freeze({
|
|
|
105
105
|
FS_OBSERVED: 'fs/observed',
|
|
106
106
|
TOOLS_PRE_EXECUTE: 'tools/pre-execute',
|
|
107
107
|
// —— P2:0.1.5 新增事件族(取证口径 = 两线 `lib/types/known-event-types.js` 逐行 diff,
|
|
108
|
-
//
|
|
108
|
+
// 依据见项目内部取证笔记)。
|
|
109
109
|
// ⚠️ **只登记常量,不进任何判定表**:这些名字属"新线上可能出现的事件",
|
|
110
110
|
// 是否需要据此改判定属档 B(换尺子),本批不做。
|
|
111
111
|
DELIVERABLES_PRESENTED: 'deliverables/presented',
|
|
@@ -900,7 +900,7 @@ const CAPABILITY_LINES = Object.freeze({
|
|
|
900
900
|
* P2 能力档扩展面(**只登记"这条线上有什么"的事实**:承载体 / 失效症状 / 降级出口)。
|
|
901
901
|
* ⚠️ 本表**不含策略** —— 不写"该怎么办",只写"是什么、会怎样坏、哪个出口可用";
|
|
902
902
|
* `fallback` 给的是**出口名**(调用方自行决定用不用),不是自动行为。
|
|
903
|
-
*
|
|
903
|
+
* 取证来源:项目内部取证笔记 +
|
|
904
904
|
* 本批 2026-09-15 两线主包闭包实读(服务名扫描 / settings 导出面 / known-event-types diff)。
|
|
905
905
|
*/
|
|
906
906
|
const CAPABILITY_DETAIL = Object.freeze({
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
// 唯一源 = 本文件;派生副本 = `tools/sync-host-adapter.mjs` 幂等生成到各包 `lib/host-adapter.mjs`(含源 sha 头);
|
|
51
51
|
// 守门 = `tools/check-decoupling.mjs` R5 校验副本 sha == 唯一源。
|
|
52
52
|
//
|
|
53
|
-
//
|
|
53
|
+
// P0 落地 2026-09-14 | P2-提前批 2026-09-15 | +`SVC.clientModules`(生态面板 boot 解析修复)2026-09-23
|
|
54
54
|
// | 2026-09-28 档 B 切(`UNKNOWN_FAMILY_POLICY`: 'unknown' → 'open',主人单独批准)
|
|
55
55
|
// | 2026-10-10 空会话误判治本(`classifyTail` 加「整段零回合内事件 ⇒ closed」前置判定;
|
|
56
56
|
// 修「新建空会话静止 10 分钟被判卡死」;真源 `docs\交付报告-卡死自愈空会话误判治本-20261010.md`)
|
|
@@ -105,7 +105,7 @@ export const EV = Object.freeze({
|
|
|
105
105
|
FS_OBSERVED: 'fs/observed',
|
|
106
106
|
TOOLS_PRE_EXECUTE: 'tools/pre-execute',
|
|
107
107
|
// —— P2:0.1.5 新增事件族(取证口径 = 两线 `lib/types/known-event-types.js` 逐行 diff,
|
|
108
|
-
//
|
|
108
|
+
// 依据见项目内部取证笔记)。
|
|
109
109
|
// ⚠️ **只登记常量,不进任何判定表**:这些名字属"新线上可能出现的事件",
|
|
110
110
|
// 是否需要据此改判定属档 B(换尺子),本批不做。
|
|
111
111
|
DELIVERABLES_PRESENTED: 'deliverables/presented',
|
|
@@ -900,7 +900,7 @@ const CAPABILITY_LINES = Object.freeze({
|
|
|
900
900
|
* P2 能力档扩展面(**只登记"这条线上有什么"的事实**:承载体 / 失效症状 / 降级出口)。
|
|
901
901
|
* ⚠️ 本表**不含策略** —— 不写"该怎么办",只写"是什么、会怎样坏、哪个出口可用";
|
|
902
902
|
* `fallback` 给的是**出口名**(调用方自行决定用不用),不是自动行为。
|
|
903
|
-
*
|
|
903
|
+
* 取证来源:项目内部取证笔记 +
|
|
904
904
|
* 本批 2026-09-15 两线主包闭包实读(服务名扫描 / settings 导出面 / known-event-types diff)。
|
|
905
905
|
*/
|
|
906
906
|
const CAPABILITY_DETAIL = Object.freeze({
|
|
@@ -298,7 +298,7 @@ export function selfTest() {
|
|
|
298
298
|
const inFile = path.join(tmp, "memories.json");
|
|
299
299
|
const outDir = path.join(tmp, "out");
|
|
300
300
|
try {
|
|
301
|
-
const base = "
|
|
301
|
+
const base = "【设备:ROG】重复内容判定用长文本片段甲乙丙丁戊己庚辛壬癸子丑寅卯辰巳午未申酉戌亥";
|
|
302
302
|
const DRV = path.parse(process.cwd()).root;
|
|
303
303
|
const mems = [
|
|
304
304
|
{ id: 1, text: base, pinned: true, tags: "", created_at: 1, updated_at: 1 },
|
|
@@ -166,11 +166,11 @@ export function selfTest() {
|
|
|
166
166
|
try {
|
|
167
167
|
const mems = [
|
|
168
168
|
{ id: 1, text: "普通条目", pinned: false, tags: "", created_at: 1, updated_at: 1 },
|
|
169
|
-
{ id: 2, text: "
|
|
169
|
+
{ id: 2, text: "【设备:ROG】正常条目", pinned: true, tags: "", created_at: 1, updated_at: 1 },
|
|
170
170
|
{ id: 3, text: "【设备:某个奇怪的东西】异常设备标", pinned: false, tags: "", created_at: 1, updated_at: 1 },
|
|
171
171
|
{
|
|
172
172
|
id: 4,
|
|
173
|
-
text: "
|
|
173
|
+
text: "【设备:ROG】\n【设备:TUF】双标条目" + "x".repeat(300),
|
|
174
174
|
pinned: false,
|
|
175
175
|
tags: "",
|
|
176
176
|
created_at: 1,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* refine-memories.mjs —— 记忆库「按 payload 逐条改写」通用写入入口(先 dry-run,--apply 才写)
|
|
4
4
|
*
|
|
5
5
|
* 与既有一次性大扫除脚本的关系:
|
|
6
|
-
* · 后者是 **2026-09-15
|
|
6
|
+
* · 后者是 **2026-09-15 那次一次性梳理脚本** —— 它的 `validate()` 内置
|
|
7
7
|
* `IDS_EXPECTED = [17 个固定 id]` 覆盖度自检("载荷必须恰好是那 17 条")⇒ **新 payload 必被 fail-closed 拒**,
|
|
8
8
|
* 不可复用(2026-09-24 实测:新载荷报「载荷缺条目 / 含计划外条目」)。
|
|
9
9
|
* · 本脚本 = 同一套安全骨架(单事务 / 逐条校验 / 改前全文留档 / 可回滚),**去掉硬编码 id 清单**,
|
|
@@ -81,7 +81,7 @@ export function tokensOf(tags) {
|
|
|
81
81
|
return String(tags ?? '').split(/\s+/).map((t) => t.trim()).filter(Boolean);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
/** 该条 already 有哪些域标签(token 级精确比较,**不用 includes
|
|
84
|
+
/** 该条 already 有哪些域标签(token 级精确比较,**不用 includes**:`工作记录` 不等于 `工作`)。 */
|
|
85
85
|
export function domainTokensIn(tags) {
|
|
86
86
|
const set = new Set(tokensOf(tags));
|
|
87
87
|
return DOMAIN_TOKENS.filter((t) => set.has(t));
|
|
@@ -42,17 +42,17 @@ test('appendDomainTags:追加不覆盖原标签', () => {
|
|
|
42
42
|
assertEq(r.added, ['技术', 'dsh生态'], 'added 记录实际新增');
|
|
43
43
|
});
|
|
44
44
|
test('appendDomainTags:同输入跑两次 ⇒ 第二次零新增(写前逐标签判重)', () => {
|
|
45
|
-
const once = D.appendDomainTags('项目
|
|
45
|
+
const once = D.appendDomainTags('项目 工作记录', ['工作']);
|
|
46
46
|
const twice = D.appendDomainTags(once.tags, ['工作']);
|
|
47
|
-
assertEq(once.tags, '项目
|
|
47
|
+
assertEq(once.tags, '项目 工作记录 工作', '第一次追加');
|
|
48
48
|
assertEq(twice.added, [], '第二次零新增');
|
|
49
49
|
assertEq(twice.tags, once.tags, '第二次不改内容');
|
|
50
50
|
const tokens = D.tokensOf(twice.tags);
|
|
51
51
|
assertEq(tokens.length, new Set(tokens).size, '无重复 token');
|
|
52
52
|
});
|
|
53
|
-
test('appendDomainTags:**token
|
|
54
|
-
const r = D.appendDomainTags('
|
|
55
|
-
assertEq(r.added, ['工作'], '
|
|
53
|
+
test('appendDomainTags:**token 级**判重(`工作记录` ≠ `工作`)', () => {
|
|
54
|
+
const r = D.appendDomainTags('工作记录', ['工作']);
|
|
55
|
+
assertEq(r.added, ['工作'], '`工作记录` 不算已含 `工作`');
|
|
56
56
|
assert(r.tags.split(/\s+/).includes('工作'), '新 token 独立存在');
|
|
57
57
|
});
|
|
58
58
|
test('appendDomainTags:集合外的标签被丢弃(模型自创词不落库)', () => {
|
|
@@ -66,7 +66,7 @@ test('appendDomainTags:标签集为空 ⇒ 一个字都不动', () => {
|
|
|
66
66
|
assertEq(r.added, [], '零新增');
|
|
67
67
|
});
|
|
68
68
|
test('domainTokensIn:只认域标签 token', () => {
|
|
69
|
-
assertEq(D.domainTokensIn('技术 dsh生态
|
|
69
|
+
assertEq(D.domainTokensIn('技术 dsh生态 工作记录'), ['技术', 'dsh生态'], 'token 级识别');
|
|
70
70
|
assertEq(D.domainTokensIn(''), [], '空 tags');
|
|
71
71
|
});
|
|
72
72
|
test('tagSetHash:与顺序无关、与重复无关、不同集不同哈希', () => {
|
|
@@ -124,7 +124,7 @@ test('distilledTagOf / srcKeyInTags:标签形态可往返解析', () => {
|
|
|
124
124
|
assert(tags.includes('srcids=3,9'), '带源 id 清单(升序)');
|
|
125
125
|
assert(/\sdate=\d{8}$/.test(tags), '带日期');
|
|
126
126
|
assertEq(D.srcKeyInTags(tags), 'd0123456789abcdef', '能解析回来');
|
|
127
|
-
assertEq(D.srcKeyInTags('技术
|
|
127
|
+
assertEq(D.srcKeyInTags('技术 工作记录'), null, '普通标签解析为 null');
|
|
128
128
|
});
|
|
129
129
|
|
|
130
130
|
// ── 02 输入挑选:窗口 ∪ 台账 + 不自我指涉 + D2 从严 ─────────────────────────
|