@shgroup/dsh-serenity-hooks 1.87.0 → 1.87.1

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/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-serenity-hooks",
3
- "version": "1.87.0",
3
+ "version": "1.87.1",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):给 DSH 装一个「AI 工作区」——14 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档,deepseek-ai/deepseek-harness)。",
6
6
  "engines": {
package/lib/index.js CHANGED
@@ -11872,6 +11872,8 @@ async function runImBridge(root, req) {
11872
11872
  }
11873
11873
  //#endregion
11874
11874
  //#region src/seams/tool-visibility.ts
11875
+ /** ACC 自己注册的工具名集合(退化档只发这些 —— 它们一定在册) */
11876
+ const REGISTERED_TOOLS_SET = new Set(REGISTERED_TOOLS);
11875
11877
  /** 收集器:把各来源的 deny 合并成一个判决(**纯函数、无副作用**) */
11876
11878
  function collectVisibilityDecision(sources) {
11877
11879
  const deny = /* @__PURE__ */ new Set();
@@ -11903,10 +11905,12 @@ const applied = /* @__PURE__ */ new Map();
11903
11905
  * (旧集合是新集合的子集时叠不叠都看不出来,但**不是子集时**会残留 —— 必须撤。)
11904
11906
  * ③ 🔴 **未注册的名字不许炸掉整次发射**:宿主契约"unknown names … fail"。
11905
11907
  * 合并后集合里只要有一个不在册的名字,整次 restrict 就失败 ⇒ 六个机制**全都不生效**。
11906
- * ⇒ 发射前**先逐个探活**(`tools.get(name)`),把不在册的名字剔掉并**如实记账**
11907
- * (剔除的名字进 `dropped`,由调用方决定要不要告警)。
11908
+ * ⇒ 策略 = **直接发 → 全量被拒才退到「只发 ACC 自己注册的那些」一档**,退档时
11909
+ * 把被放弃的名字如实记账(进 `dropped`,由调用方决定要不要告警)。
11910
+ * ⚠️ **不做 `tools.get` 预探活** —— 那个视图查不出 agent-plane 贡献的工具
11911
+ * (`bash` / `schedule_*`),会把**在册的名字误判成未注册**(见下方发射段的实测记录)。
11908
11912
  * ⚠️ 这比旧行为**更保守**:旧行为是"某条 restrict 失败 ⇒ 那一格静默不生效",
11909
- * 新行为是"剔掉那个名字、其余照常生效" —— **等价或更好**,且总有日志。
11913
+ * 新行为是"全量失败 ⇒ 至少 ACC 那一格照常生效" —— **等价或更好**,且总有日志。
11910
11914
  *
11911
11915
  * @returns `'unchanged'` / `'applied'` / `'failed'`(`failed` 时 `deny` 保持原样)
11912
11916
  */
@@ -11925,20 +11929,7 @@ function applyVisibilityDecision(agent, sessionId, decision) {
11925
11929
  }
11926
11930
  const tools = agent.ctx.tools;
11927
11931
  const dropped = [];
11928
- let names = decision.deny;
11929
- if (typeof tools.get === "function") {
11930
- names = [];
11931
- for (const n of decision.deny) {
11932
- let present = false;
11933
- try {
11934
- present = tools.get(n) !== void 0;
11935
- } catch {
11936
- present = false;
11937
- }
11938
- if (present) names.push(n);
11939
- else dropped.push(n);
11940
- }
11941
- }
11932
+ const names = decision.deny;
11942
11933
  if (names.length === 0) {
11943
11934
  applied.set(sessionId, {
11944
11935
  signature,
@@ -11961,12 +11952,32 @@ function applyVisibilityDecision(agent, sessionId, decision) {
11961
11952
  status: "applied",
11962
11953
  dropped
11963
11954
  };
11964
- } catch (e) {
11965
- return {
11955
+ } catch (firstError) {
11956
+ const accOnly = names.filter((n) => REGISTERED_TOOLS_SET.has(n));
11957
+ if (accOnly.length === 0 || accOnly.length === names.length) return {
11966
11958
  status: "failed",
11967
11959
  dropped,
11968
- error: e.message
11960
+ error: firstError.message
11969
11961
  };
11962
+ const abandoned = names.filter((n) => !REGISTERED_TOOLS_SET.has(n));
11963
+ try {
11964
+ const dispose = tools.restrict({ deny: accOnly });
11965
+ applied.set(sessionId, {
11966
+ signature,
11967
+ deny: accOnly,
11968
+ dispose
11969
+ });
11970
+ return {
11971
+ status: "applied",
11972
+ dropped: abandoned
11973
+ };
11974
+ } catch (secondError) {
11975
+ return {
11976
+ status: "failed",
11977
+ dropped,
11978
+ error: secondError.message
11979
+ };
11980
+ }
11970
11981
  }
11971
11982
  }
11972
11983
  /** 会话销毁清理(防 per-会话 Map 无界增长;lifecycle 调用) */
@@ -12262,8 +12273,9 @@ const IM_BRIDGE_TOOL_NAME = "im-bridge";
12262
12273
  * 宁静号的唤醒/巡航走 `cognitive_trajectory send-later` → `AGENT_SESSIONS/wake-registry.json`
12263
12274
  * → 中心调度器 5min tick(D58)。宿主这套定时器是**另一个**真相源 ⇒ 两处记账、
12264
12275
  * CRO 判据失真、且模型可能顺手排一个"不在任何账本里"的唤醒。
12265
- * ⚠️ 本清单**合并发射时不需要探活**(`applyVisibilityDecision` 统一个剔掉未注册名),
12266
- * 所以宿主没装该包时不会炸掉整次发射 —— 这是方案 C 顺带修掉的一个旧坑。
12276
+ * ⚠️ 本清单**合并发射时不做探活**。⚠️ 现状缺口(v1.87.1 如实登记):宿主**没装**
12277
+ * `dsh-tool-schedule` 时,这 4 个名字会把整次 restrict 拒掉,而退档只保留 ACC 自己的名字
12278
+ * ⇒ 这一格的屏蔽**不生效**(旧实现同样不生效,**未回归**;但"顺带修好了"这句是假的,已删)。
12267
12279
  */
12268
12280
  const HOST_SCHEDULE_TOOL_NAMES = [
12269
12281
  "schedule_create",
@@ -51,10 +51,12 @@ export declare function getToolVisibilityDiagnostics(): {
51
51
  * (旧集合是新集合的子集时叠不叠都看不出来,但**不是子集时**会残留 —— 必须撤。)
52
52
  * ③ 🔴 **未注册的名字不许炸掉整次发射**:宿主契约"unknown names … fail"。
53
53
  * 合并后集合里只要有一个不在册的名字,整次 restrict 就失败 ⇒ 六个机制**全都不生效**。
54
- * ⇒ 发射前**先逐个探活**(`tools.get(name)`),把不在册的名字剔掉并**如实记账**
55
- * (剔除的名字进 `dropped`,由调用方决定要不要告警)。
54
+ * ⇒ 策略 = **直接发 → 全量被拒才退到「只发 ACC 自己注册的那些」一档**,退档时
55
+ * 把被放弃的名字如实记账(进 `dropped`,由调用方决定要不要告警)。
56
+ * ⚠️ **不做 `tools.get` 预探活** —— 那个视图查不出 agent-plane 贡献的工具
57
+ * (`bash` / `schedule_*`),会把**在册的名字误判成未注册**(见下方发射段的实测记录)。
56
58
  * ⚠️ 这比旧行为**更保守**:旧行为是"某条 restrict 失败 ⇒ 那一格静默不生效",
57
- * 新行为是"剔掉那个名字、其余照常生效" —— **等价或更好**,且总有日志。
59
+ * 新行为是"全量失败 ⇒ 至少 ACC 那一格照常生效" —— **等价或更好**,且总有日志。
58
60
  *
59
61
  * @returns `'unchanged'` / `'applied'` / `'failed'`(`failed` 时 `deny` 保持原样)
60
62
  */
@@ -64,7 +66,6 @@ export declare function applyVisibilityDecision(agent: {
64
66
  restrict(f: {
65
67
  deny: string[];
66
68
  }): () => void;
67
- get?(n: string): unknown;
68
69
  };
69
70
  };
70
71
  }, sessionId: string, decision: VisibilityDecision): {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.87.0",
3
+ "version": "1.87.1",
4
4
  "description": "宁静号 ACC harness(Native Cordis 插件)——给 DeepSeek Harness 装一个「AI 工作区」:14 个工具(container_fs/cognitive_trajectory/dashboard/container_git/msm/praxis/ontology/serenity-skill-creator/cheap-worker/localstore/container_admin;另三个 im-bridge/acc-diag/diagram 按配置条件出现)+ 机械约束(安全模式/工作区围墙/密钥守卫/对外输出守卫)+ 认知轨迹日志与原地重建 + 网页登录入口/IM 桥/认知轨迹唤醒注册表。轨迹声明 = 轨迹目录下的 trajectory.json(约束面 + 旧标识 uid + CRO 机器绑定 cro.host;旧名 trajectory-constraint.json / skiff.json 仍在读取族里);轨迹提示词 = 轨迹目录下的 PROMPT.md(一条轨迹「是谁、按什么章程工作」,所有轨迹通用,追加在容器层与质量层之后,不替换它们)。适配 DSH 0.1.7-rc.1 / 0.2.0-rc.1 / 0.2.1-rc.1(三档)。",
5
5
  "license": "MIT",
6
6
  "repository": {