@furongjun1999/dsh-memory 0.2.9 → 0.3.0

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.
@@ -3,7 +3,7 @@
3
3
  - 版本:**v2.0-published**(2026-08-14 · 验证单元 FINAL PASS,已对外发布)
4
4
  - 定位:**对外公开的公共法案**——约束接入协议的一切智能体与人类使用者的行为边界;同时是对人类的保护(参照刑法对公民的保护作用)
5
5
  - 双层规范体系:
6
- - **智能论协议**(v3.2)= 内部宪法——完整自我约束(价值观、认知、反思、维生)
6
+ - **智能论协议**(v3.3)= 内部宪法——完整自我约束(价值观、认知、反思、维生)
7
7
  - **本宪章** = 对外刑法——公开规则、可执行、可审计、可终裁
8
8
  - **效力层级(元规则)**:**本宪章的效力不高于协议本身**。协议是最高规范(自我约束的根本),宪章是协议的对外投影——任何宪章条款若与协议价值观冲突,以协议为准;宪章不得要求协议实例做出违背其自我价值观(bvc 一致性)与信任关系的行为。元规则依据协议的结构分层逻辑(0.0.2 任意分层性):宪章是协议在"对外社会层"的条件空间投影,投影不能修改基底。
9
9
  - **来源标注(DEVIATION-012 关闭)**:第三十条关于"人类保护原则为协议价值观对外延伸"的阐释,基于设计者(荣)的条件空间声明(附录A),经协议实例内化后生效——非协议公理的直接演绎,不得误读为协议正文固有条款。
@@ -154,7 +154,7 @@
154
154
 
155
155
  **请验证单元逐项判断**:
156
156
 
157
- 1. **效力层级**:元规则"宪章效力不高于协议"是否成立?与智能论 v3.2 的条款(价值观一致性、信任保护、P0 保护协议)是否存在冲突或需要补强?
157
+ 1. **效力层级**:元规则"宪章效力不高于协议"是否成立?与智能论 v3.3 的条款(价值观一致性、信任保护、P0 保护协议)是否存在冲突或需要补强?
158
158
  2. **定位一致性**:协议=自我约束(内部宪法)、宪章=对外约束(公共法律)的分工是否与协议框架自洽?
159
159
  3. **人类保护章节(第七章)**:AI 身份披露/知情权/不欺骗不操纵/可退出/申诉/伤害防护——是否与协议对设计者/人类的关系定位一致?"人类保护原则优先于一切"是否与"宪章效力不高于协议"存在张力(若存在,应如何表述消解)?
160
160
  4. **适用范围(第四条)**:外部智能体"入境即受约束"的声明机制是否充分?接入声明应写入哪些接口文档(MCP/插件/蜂群)?
package/lib/bridge.d.ts CHANGED
@@ -57,7 +57,7 @@ export declare class LingshuBridge {
57
57
  /** 拉取灵枢的全部工具清单(每次实时请求,不缓存)。 */
58
58
  listTools(): Promise<McpTool[]>;
59
59
  /** 调用灵枢的一个工具,返回标准化 MCP 结果。 */
60
- callTool(name: string, args: Record<string, unknown>): Promise<McpCallResult>;
60
+ callTool(name: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<McpCallResult>;
61
61
  /** 关闭进程并释放资源(写 stdin EOF 优雅退出,超时兜底 kill)。 */
62
62
  dispose(): void;
63
63
  /** 进程是否存活。 */
package/lib/bridge.js CHANGED
@@ -42,8 +42,8 @@ export class LingshuBridge {
42
42
  return tools.tools ?? [];
43
43
  }
44
44
  /** 调用灵枢的一个工具,返回标准化 MCP 结果。 */
45
- async callTool(name, args) {
46
- const result = await this.request('tools/call', { name, arguments: args });
45
+ async callTool(name, args, signal) {
46
+ const result = await this.request('tools/call', { name, arguments: args }, signal);
47
47
  return result;
48
48
  }
49
49
  /** 关闭进程并释放资源(写 stdin EOF 优雅退出,超时兜底 kill)。 */
@@ -187,24 +187,39 @@ export class LingshuBridge {
187
187
  }
188
188
  proc.stdin.write(JSON.stringify(msg) + '\n');
189
189
  }
190
- request(method, params) {
190
+ request(method, params, signal) {
191
191
  const id = this.nextId++;
192
192
  const timeout = this.options.timeoutMs;
193
+ // P0 修复(GPT 审查):定时器直接调 settle——settle 内部会 delete + clearTimeout
194
+ // 并 reject。此前先 pending.delete(id) 再 settle(),settle 找不到 entry 直接
195
+ // return,Promise 永不 resolve/reject(超时逻辑完全失效,子进程挂死时插件永久挂住)。
193
196
  const timer = setTimeout(() => {
194
- this.pending.delete(id);
195
197
  this.settle(id, {
196
198
  error: { code: -32000, message: `灵枢调用超时(${timeout}ms):${method}` },
197
199
  });
198
200
  }, timeout);
201
+ if (signal?.aborted) {
202
+ clearTimeout(timer);
203
+ return Promise.reject(new Error(`已取消:${method}`));
204
+ }
205
+ const onAbort = () => {
206
+ this.settle(id, { error: { code: -32800, message: `已取消:${method}` } });
207
+ };
208
+ signal?.addEventListener('abort', onAbort, { once: true });
199
209
  const promise = new Promise((resolve, reject) => {
200
210
  this.pending.set(id, { resolve, reject, timer });
201
211
  });
212
+ // settle 后移除 abort 监听,避免内存积累
213
+ promise.finally(() => {
214
+ signal?.removeEventListener('abort', onAbort);
215
+ }).catch(() => { });
202
216
  try {
203
217
  this.writeRaw({ jsonrpc: '2.0', id, method, params });
204
218
  }
205
219
  catch (err) {
206
220
  clearTimeout(timer);
207
221
  this.pending.delete(id);
222
+ signal?.removeEventListener('abort', onAbort);
208
223
  return Promise.reject(err);
209
224
  }
210
225
  return promise;
package/lib/hooks.d.ts CHANGED
@@ -4,8 +4,14 @@
4
4
  * 与 DSH 的 session-persistence 插件(保存会话日志)不同,这里是"语义沉淀":
5
5
  * 用户消息写入灵枢知识层(带去重与重要性),agent 回复与工具结果可选开启。
6
6
  * 只记忆真实用户消息(source.kind === 'user'),过滤插件注入的噪音。
7
+ *
8
+ * P1 完善(GPT 审查·自动记忆只写不读):新增 autoRecall——通过
9
+ * system-prompt/assemble 事件(waterfall,异步允许)在每次模型请求组装
10
+ * system prompt 时自动注入灵枢最近记忆(timeline),让记忆"自动可用"
11
+ * 而不只依赖 Agent 主动调用 recall/think 工具。失败静默(不影响请求)。
7
12
  */
8
13
  import '@deepseek-ai/dsh-session';
14
+ import '@deepseek-ai/dsh-system-prompt';
9
15
  import type { Context } from '@deepseek-ai/cordis';
10
16
  import type { LingshuBridge } from './bridge.js';
11
17
  /** 自动记忆开关。 */
@@ -18,6 +24,14 @@ export interface MemoryHooksOptions {
18
24
  toolResult: boolean;
19
25
  /** 写入记忆的重要性(0~1),默认 0.6。 */
20
26
  importance: number;
27
+ /** 自动召回注入:模型请求前自动注入灵枢最近记忆(默认 true,失败静默)。 */
28
+ autoRecall: boolean;
29
+ /** 自动召回条数(默认 4)。 */
30
+ autoRecallLimit: number;
31
+ /** 自动记忆脱敏:写入前过滤敏感信息(密钥/密码/令牌/身份证/手机号,默认 true)。 */
32
+ desensitize: boolean;
21
33
  }
34
+ /** 脱敏:替换敏感片段;返回 null 表示整条都是敏感内容(应跳过写入)。 */
35
+ export declare function desensitize(text: string): string | null;
22
36
  /** 安装自动记忆钩子(effect 作用域内,随插件卸载自动移除)。 */
23
37
  export declare function installMemoryHooks(ctx: Context, bridge: LingshuBridge, opts: MemoryHooksOptions): void;
package/lib/hooks.js CHANGED
@@ -4,8 +4,14 @@
4
4
  * 与 DSH 的 session-persistence 插件(保存会话日志)不同,这里是"语义沉淀":
5
5
  * 用户消息写入灵枢知识层(带去重与重要性),agent 回复与工具结果可选开启。
6
6
  * 只记忆真实用户消息(source.kind === 'user'),过滤插件注入的噪音。
7
+ *
8
+ * P1 完善(GPT 审查·自动记忆只写不读):新增 autoRecall——通过
9
+ * system-prompt/assemble 事件(waterfall,异步允许)在每次模型请求组装
10
+ * system prompt 时自动注入灵枢最近记忆(timeline),让记忆"自动可用"
11
+ * 而不只依赖 Agent 主动调用 recall/think 工具。失败静默(不影响请求)。
7
12
  */
8
13
  import '@deepseek-ai/dsh-session';
14
+ import '@deepseek-ai/dsh-system-prompt';
9
15
  /** 从 ContentBlock[] 提取纯文本。 */
10
16
  function extractText(blocks) {
11
17
  const parts = [];
@@ -16,6 +22,33 @@ function extractText(blocks) {
16
22
  }
17
23
  return parts.join('\n').trim();
18
24
  }
25
+ /**
26
+ * 敏感信息模式(GPT 审查·自动记忆脱敏):写入记忆库前过滤凭据/个人标识。
27
+ * 命中 → 替换为 [已过滤:类别](保留对话主体);过滤后只剩占位符/空白 → 整条跳过。
28
+ * 纯内容过滤,不涉及身份认证——开源场景下的隐私保护。
29
+ */
30
+ const SENSITIVE_PATTERNS = [
31
+ { re: /sk-[A-Za-z0-9_-]{8,}/g, label: 'API密钥' },
32
+ { re: /\b(?:api[_-]?key|apikey|access[_-]?token)\b\s*[:=]\s*[^\s,,。;;]+/gi, label: 'API密钥' },
33
+ { re: /\b(?:password|passwd|pwd)\b\s*[:=]\s*[^\s,,。;;]+/gi, label: '密码' },
34
+ { re: /Bearer\s+[A-Za-z0-9._~+/=-]{8,}/gi, label: '令牌' },
35
+ // 中文密码:值限定非中文连续串(凭据特征),避免误伤「密码是重要的安全概念」
36
+ { re: /密码\s*[::是]\s*[A-Za-z0-9_@#$%^&*!.-]{4,}/g, label: '密码' },
37
+ { re: /\b\d{17}[\dXx]\b/g, label: '身份证号' },
38
+ { re: /\b1[3-9]\d{9}\b/g, label: '手机号' },
39
+ ];
40
+ /** 脱敏:替换敏感片段;返回 null 表示整条都是敏感内容(应跳过写入)。 */
41
+ export function desensitize(text) {
42
+ let out = text;
43
+ for (const { re, label } of SENSITIVE_PATTERNS) {
44
+ out = out.replace(re, `[已过滤:${label}]`);
45
+ }
46
+ // 过滤后只剩占位符/空白 → 纯凭据消息,不写(或全部被替换)
47
+ const residue = out.replace(/\[已过滤:[^\]]+\]/g, '').trim();
48
+ if (!residue)
49
+ return null;
50
+ return out;
51
+ }
19
52
  /** 安装自动记忆钩子(effect 作用域内,随插件卸载自动移除)。 */
20
53
  export function installMemoryHooks(ctx, bridge, opts) {
21
54
  const memorize = (tool, args) => {
@@ -23,6 +56,33 @@ export function installMemoryHooks(ctx, bridge, opts) {
23
56
  .callTool(tool, args)
24
57
  .catch((err) => ctx.logger.warn(`dsh-memory: ${tool} 自动记忆失败: ${err.message}`));
25
58
  };
59
+ // P1 完善(GPT 审查·自动记忆脱敏):写入前过滤敏感信息(默认开启)。
60
+ // 命中敏感模式 → 替换为 [已过滤:类别];纯凭据消息 → 跳过写入(不落库)。
61
+ const sanitize = (text) => {
62
+ if (!opts.desensitize)
63
+ return text;
64
+ return desensitize(text);
65
+ };
66
+ // P1 完善(自动 recall 注入):每次模型请求组装 system prompt 时,注入灵枢最近记忆。
67
+ // 用 system-prompt/assemble 事件(waterfall)而非 llm/stream——后者请求 deep-frozen 不可改写。
68
+ if (opts.autoRecall) {
69
+ const recallLimit = Math.max(1, Math.min(10, opts.autoRecallLimit || 4));
70
+ ctx.on('system-prompt/assemble', async (assembly, _ctx, next) => {
71
+ try {
72
+ // 异步取最近记忆(失败静默——不阻塞模型请求)
73
+ const r = await bridge.callTool('timeline', { limit: recallLimit });
74
+ const text = extractText(r.content);
75
+ if (text) {
76
+ assembly.contexts.push({
77
+ name: 'lingshu:auto-recall',
78
+ text: `【灵枢最近记忆】\n${text.slice(0, 600)}`,
79
+ });
80
+ }
81
+ }
82
+ catch { /* 静默:召回失败不影响请求 */ }
83
+ return next();
84
+ });
85
+ }
26
86
  ctx.on('session/event', (_session, event) => {
27
87
  if (event.type === 'user/message' && opts.userMessage) {
28
88
  // 只记真实用户输入(kind='user'),跳过插件注入/系统上下文
@@ -31,13 +91,19 @@ export function installMemoryHooks(ctx, bridge, opts) {
31
91
  const text = extractText(event.data.content);
32
92
  if (!text)
33
93
  return;
34
- memorize('remember', { content: text, importance: opts.importance, tags: ['dsh', 'user'] });
94
+ const safe = sanitize(text); // 脱敏:纯凭据消息 → null → 跳过写入
95
+ if (safe === null)
96
+ return;
97
+ memorize('remember', { content: safe, importance: opts.importance, tags: ['dsh', 'user'] });
35
98
  }
36
99
  else if (event.type === 'assistant/message' && opts.assistantMessage) {
37
100
  const text = extractText(event.data.message.content);
38
101
  if (!text)
39
102
  return;
40
- memorize('remember', { content: text, importance: opts.importance * 0.8, tags: ['dsh', 'assistant'] });
103
+ const safe = sanitize(text);
104
+ if (safe === null)
105
+ return;
106
+ memorize('remember', { content: safe, importance: opts.importance * 0.8, tags: ['dsh', 'assistant'] });
41
107
  }
42
108
  else if (event.type === 'tool/result' && opts.toolResult) {
43
109
  if (event.data.error)
@@ -45,7 +111,10 @@ export function installMemoryHooks(ctx, bridge, opts) {
45
111
  const text = extractText(event.data.message.content);
46
112
  if (!text)
47
113
  return;
48
- memorize('remember', { content: text, importance: opts.importance * 0.6, tags: ['dsh', 'tool'] });
114
+ const safe = sanitize(text);
115
+ if (safe === null)
116
+ return;
117
+ memorize('remember', { content: safe, importance: opts.importance * 0.6, tags: ['dsh', 'tool'] });
49
118
  }
50
119
  });
51
120
  }
package/lib/index.d.ts CHANGED
@@ -21,7 +21,10 @@ import z from '@deepseek-ai/schemastery';
21
21
  import { type ToolSelection } from './tools.js';
22
22
  import { type MemoryHooksOptions } from './hooks.js';
23
23
  export declare const name = "dsh-memory";
24
- /** 本插件依赖的工具注册服务。 */
24
+ /** 本插件依赖的工具注册服务。
25
+ * P1 修复(GPT 审查):timer/webServer 是可选增强(互维/角色网页),此前强声明
26
+ * 导致最小 host(只有 tools)插件永远 PENDING 不激活。只强依赖 tools;
27
+ * timer/webServer 在 apply 内动态检测(存在则启用,缺失则告警跳过)。 */
25
28
  export declare const inject: string[];
26
29
  /** 插件配置。 */
27
30
  export interface Config {
package/lib/index.js CHANGED
@@ -22,8 +22,16 @@ import { registerLingshuTools } from './tools.js';
22
22
  import { installMemoryHooks } from './hooks.js';
23
23
  import { installRoleplayWeb } from './roleplay_web.js';
24
24
  export const name = 'dsh-memory';
25
- /** 本插件依赖的工具注册服务。 */
26
- export const inject = ['tools', 'timer', 'webServer'];
25
+ /** P1 修复(GPT 审查):MCP 调用的标准结果在 content[].text,
26
+ * 代码此前误读不存在的 .result 字段导致互维拿不到 judgment/best/复核文本 */
27
+ function mcpText(r) {
28
+ return (r.content ?? []).map((c) => c.text ?? '').join('\n');
29
+ }
30
+ /** 本插件依赖的工具注册服务。
31
+ * P1 修复(GPT 审查):timer/webServer 是可选增强(互维/角色网页),此前强声明
32
+ * 导致最小 host(只有 tools)插件永远 PENDING 不激活。只强依赖 tools;
33
+ * timer/webServer 在 apply 内动态检测(存在则启用,缺失则告警跳过)。 */
34
+ export const inject = ['tools'];
27
35
  export const Config = z.object({
28
36
  serverName: z.string().default('lingshu'),
29
37
  python: z.string().default('python'),
@@ -40,8 +48,11 @@ export const Config = z.object({
40
48
  assistantMessage: z.boolean().default(false),
41
49
  toolResult: z.boolean().default(false),
42
50
  importance: z.number().default(0.6),
51
+ autoRecall: z.boolean().default(true),
52
+ autoRecallLimit: z.number().default(4),
53
+ desensitize: z.boolean().default(true),
43
54
  })
44
- .default({ userMessage: true, assistantMessage: false, toolResult: false, importance: 0.6 }),
55
+ .default({ userMessage: true, assistantMessage: false, toolResult: false, importance: 0.6, autoRecall: true, autoRecallLimit: 4, desensitize: true }),
45
56
  toolCallTimeoutMs: z.number().default(60_000),
46
57
  maxRetryDelayMs: z.number().default(30_000),
47
58
  failOnStartupError: z.boolean().default(false),
@@ -76,11 +87,16 @@ export async function apply(ctx, config) {
76
87
  const ready = await bridge.waitReady();
77
88
  if (!ready) {
78
89
  const message = '灵枢进程无法启动(检查 python 是否可用、aeis 是否安装:pip install aeis)';
79
- if (config.failOnStartupError)
90
+ if (config.failOnStartupError) {
91
+ // P1 修复(GPT 审查):启动失败抛错前必须 dispose——此前 throw 在 try 之前,
92
+ // 桥接对象泄漏 + 后台重试计时器继续跑
93
+ bridge.dispose();
80
94
  throw new Error(message);
95
+ }
81
96
  ctx.logger.warn(`dsh-memory: ${message},继续后台重试`);
82
97
  }
83
98
  const disposers = [];
99
+ let toolsPoll = null;
84
100
  try {
85
101
  // 工具注册:初始就绪立即注册;若启动时未就绪(python 暂不可用/aeis 未装等
86
102
  // 竞态),桥重连成功后自动补注册——修复"工具永久缺失"问题。
@@ -95,6 +111,11 @@ export async function apply(ctx, config) {
95
111
  });
96
112
  disposers.push(dispose);
97
113
  toolsRegistered = true;
114
+ // P1 修复(GPT 审查):注册成功后清除轮询——此前 setInterval 永久保留
115
+ if (toolsPoll) {
116
+ clearInterval(toolsPoll);
117
+ toolsPoll = null;
118
+ }
98
119
  ctx.logger.info('dsh-memory: 灵枢工具已注册(就绪后补注册)');
99
120
  }
100
121
  catch (err) {
@@ -104,39 +125,59 @@ export async function apply(ctx, config) {
104
125
  if (ready)
105
126
  await tryRegister();
106
127
  if (!toolsRegistered) {
107
- const poll = setInterval(() => { void tryRegister(); }, 2000);
108
- disposers.push(() => clearInterval(poll));
128
+ toolsPoll = setInterval(() => { void tryRegister(); }, 2000);
129
+ disposers.push(() => { if (toolsPoll)
130
+ clearInterval(toolsPoll); });
109
131
  }
110
132
  installMemoryHooks(ctx, bridge, config.memory);
111
133
  // 角色扮演网页(同源挂载 /roleplay,复用本插件 bridge)
112
134
  await installRoleplayWeb(ctx, bridge, config, disposers);
113
135
  // 互维维护(v1.1):心跳写戳 + 守护 A + 任务验证双通道
114
136
  if (config.mutual.enabled) {
115
- const { installMutualMaintenance } = await import('./mutual.js');
116
- // 双通道 hooks:白箱 base_verify(走 bridge 调灵枢)+ DeepSeek 复核
117
- installMutualMaintenance(ctx, { heartbeatMs: config.mutual.heartbeatMs }, {
118
- verify: async (claim) => {
119
- const r = await bridge.callTool('wisdom_verify', { knowledge: claim, limit: 4 });
120
- const data = r?.result ?? {};
121
- return {
122
- judgment: data.judgment ?? '分析中',
123
- best: data.best?.name ?? '',
124
- d_norm: typeof data.D_norm === 'number' ? data.D_norm : -1,
125
- record_id: data.record_id ?? '',
126
- };
127
- },
128
- review: async (claim, w) => {
129
- // DeepSeek 复核(在白箱判定之上,不重复白箱工作)
130
- const reviewResult = await bridge.callTool('think', {
131
- query: `复核以下主张(白箱判定已给出,请独立评估是否同意):${claim.slice(0, 200)}。白箱判定:${w.judgment},best=${w.best}。只输出 同意/质疑/不同意 + 一句话理由`,
132
- });
133
- const text = String((reviewResult?.result) ?? '');
134
- const conclusion = text.includes('同意') ? '同意' :
135
- text.includes('质疑') ? '质疑' : '不同意';
136
- return { conclusion, reason: text.slice(0, 120) };
137
- },
138
- });
139
- ctx.logger.info('dsh-memory: 互维维护已启用(心跳 10min + 守护 A + 任务验证双通道)');
137
+ // P1 修复(GPT 审查):timer 是可选服务——缺失时告警跳过互维,
138
+ // 不让插件因互维而阻塞(inject 已不再强声明 timer)
139
+ const hasTimer = ctx.timer !== undefined;
140
+ if (!hasTimer) {
141
+ ctx.logger.warn('dsh-memory: timer 服务不可用,跳过互维维护(mutual.enabled=true 但无 timer)');
142
+ }
143
+ else {
144
+ const { installMutualMaintenance } = await import('./mutual.js');
145
+ // 双通道 hooks:白箱 base_verify(走 bridge 调灵枢)+ DeepSeek 复核
146
+ installMutualMaintenance(ctx, { heartbeatMs: config.mutual.heartbeatMs }, {
147
+ verify: async (claim) => {
148
+ const r = await bridge.callTool('wisdom_verify', { knowledge: claim, limit: 4 });
149
+ // P1 修复(GPT 审查):结果在 content[].text(JSON),非 .result
150
+ const text = mcpText(r);
151
+ let data = {};
152
+ try {
153
+ data = JSON.parse(text);
154
+ }
155
+ catch { /* 非 JSON 时用默认 */ }
156
+ return {
157
+ judgment: data.judgment ?? '分析中',
158
+ best: data.best?.name ?? '',
159
+ d_norm: typeof data.D_norm === 'number' ? data.D_norm : -1,
160
+ record_id: data.record_id ?? '',
161
+ };
162
+ },
163
+ review: async (claim, w) => {
164
+ // DeepSeek 复核(在白箱判定之上,不重复白箱工作)
165
+ const reviewResult = await bridge.callTool('think', {
166
+ query: `复核以下主张(白箱判定已给出,请独立评估是否同意):${claim.slice(0, 200)}。白箱判定:${w.judgment},best=${w.best}。只输出 同意/质疑/不同意 + 一句话理由`,
167
+ });
168
+ // P1 修复(GPT 审查):文本在 content[].text;结论解析必须先查
169
+ // 「不同意/不通过」再「质疑」再「同意」——「不同意」含子串「同意」,
170
+ // 此前先匹配「同意」→ 不同意被误判为同意
171
+ const text = mcpText(reviewResult);
172
+ const conclusion = text.includes('不同意') || text.includes('不通过')
173
+ ? '不同意'
174
+ : text.includes('质疑') ? '质疑'
175
+ : text.includes('同意') ? '同意' : '不同意';
176
+ return { conclusion, reason: text.slice(0, 120) };
177
+ },
178
+ });
179
+ ctx.logger.info('dsh-memory: 互维维护已启用(心跳 10min + 守护 A + 任务验证双通道)');
180
+ }
140
181
  }
141
182
  }
142
183
  catch (err) {
package/lib/mutual.d.ts CHANGED
@@ -26,7 +26,9 @@ export declare function judgeStamp(stamp: {
26
26
  ageMs: number;
27
27
  task_running: boolean;
28
28
  } | null, opts?: MutualOptions): 'alive' | 'alive_working' | 'warning' | 'dead' | 'no_stamp';
29
- /** 检测 harness 进程是否存在(wmic) */
29
+ /** 检测 harness 进程是否存在
30
+ * P1 完善(GPT 审查·wmic 兼容):wmic 在 Win11+ 已被移除——失败时
31
+ * fallback PowerShell Get-CimInstance(Win);非 Windows 用 ps 查询。 */
30
32
  export declare function harnessRunning(): Promise<boolean>;
31
33
  /** detached 拉起 A 侧 harness.guardian(幂等:先确认不存在) */
32
34
  export declare function ensureHarness(python?: string, opts?: MutualOptions): Promise<'started' | 'already' | 'failed'>;
@@ -78,6 +80,7 @@ export declare function llmReview(claim: string, whitebox: VerifyResult['whitebo
78
80
  }>): Promise<VerifyResult['llm_review']>;
79
81
  /** 综合 verdict(白箱优先) */
80
82
  export declare function combineVerdict(w: VerifyResult['whitebox'], l: VerifyResult['llm_review']): VerifyResult['verdict'];
83
+ export declare function safeTaskId(id: string): boolean;
81
84
  /** 处理单个任务:双通道验证 → 写回 result */
82
85
  export declare function processTask(task: VerifyTask, verifyFn: (c: string) => Promise<{
83
86
  judgment: string;
@@ -87,14 +90,14 @@ export declare function processTask(task: VerifyTask, verifyFn: (c: string) => P
87
90
  }>, reviewFn: (c: string, w: VerifyResult['whitebox']) => Promise<{
88
91
  conclusion: string;
89
92
  reason: string;
90
- }>, opts?: MutualOptions): Promise<VerifyResult>;
93
+ }>, opts?: MutualOptions): Promise<VerifyResult | null>;
91
94
  export declare function log(opts: MutualOptions, msg: string): void;
92
95
  export declare function writeLastContact(opts?: MutualOptions): void;
93
96
  export declare function installMutualMaintenance(ctx: {
94
97
  logger: {
95
98
  info(m: string): void;
96
99
  };
97
- interval(ms: number, fn: () => void): () => void;
100
+ interval(fn: () => void, ms: number): () => void;
98
101
  effect(fn: () => () => void, name?: string): void;
99
102
  }, config?: Partial<MutualOptions>, hooks?: {
100
103
  verify?: (c: string) => Promise<{