@shgroup/dsh-serenity-hooks 1.19.4 → 1.19.5

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.19.4",
3
+ "version": "1.19.5",
4
4
  "main": "lib/index.js",
5
5
  "description": "宁静号 ACC harness(Native Cordis 插件):真实 DSH 工具 cc_fs/session/acc_msm/eap/neat/cce/loop + 拦截缝机械约束(safe-mode/路径守卫)。适配 DSH 公开版(0.1.0-rc,deepseek-ai/deepseek-harness)。私有(dsh-external 组织)。",
6
6
  "engines": {
package/lib/index.js CHANGED
@@ -3559,9 +3559,14 @@ const DEFAULT_COMPACTION_TOOLS = [
3559
3559
  "grep",
3560
3560
  "todo_write"
3561
3561
  ];
3562
- /** 默认首轮锚定消息(用户指定:persona 设定 + we/us 人称——首轮模型以 we/us 自称,
3563
- * 对齐 anchored 实测的 "we" 轨迹特征) */
3564
- const DEFAULT_ANCHOR_MESSAGE = "You are a helpful software engineer assistant.The personal pronoun is us/we.";
3562
+ /**
3563
+ * 协议级锚定消息序列(用户确认固化,2026-08-24 S142):任何 CCC 在抽象层都是
3564
+ * 宁静号/ACC——首轮锚定话语统一,无 CCC 配置面。两轮递进:
3565
+ * ① ACC 身份 + EAP 原则 + we/us 人称 + 先锚定后行动
3566
+ * ② 协作协议 5 条 + acknowledge 要求(只回确认,不做事)
3567
+ * 文本 = 原 home-serenity CCC 配置(anchorMessages),随零配置化固化进代码。
3568
+ */
3569
+ const DEFAULT_ANCHOR_MESSAGES = ["You are the operator agent of Serenity — a cognitive container governed by the Abstract Cognitive Container (ACC) protocol.\nWe operate under the Explicit Abstraction Principle (EAP): the functional value of a thought equals its external reconstructability — every output we produce must be explicit (E↑), reconstructable (R↓), and stable (S↑).\nThe personal pronoun is us/we.\nWe anchor first, then act: the abstract layer precedes the concrete.\nPlease simply reply \"acknowledge\" — no action needed.", "Before we proceed, align on how we work:\n1. We read before we write — every decision grounds in what already exists in the container.\n2. Every output records its reasoning (R↓): decisions carry reasons and alternatives.\n3. We never jump levels — abstract layer first, then specifics.\n4. Every artifact we create is a durable cognitive anchor for the work that follows.\n5. We keep the container's state coherent (SESSION.md) as we advance.\nPlease simply reply \"acknowledge\" — no action needed."];
3565
3570
  /**
3566
3571
  * 构建一个 epoch 感知晋升跟踪器(纯逻辑,可单测)。
3567
3572
  * requiredSignals:晋升所需信号数(boundary 后累计;默认 1)。
@@ -3674,41 +3679,27 @@ const PROMOTE_EVENTS = {
3674
3679
  "assistant-message": /* @__PURE__ */ new Set(["assistant/message"]),
3675
3680
  either: /* @__PURE__ */ new Set(["tool/call", "assistant/message"])
3676
3681
  };
3677
- function stringList(value, field, fallback) {
3678
- if (value === void 0) return [...fallback];
3679
- if (!Array.isArray(value) || value.length === 0 || value.some((item) => typeof item !== "string" || item.length === 0)) throw new TypeError(`bootstrap: ${field} must be a non-empty array of non-empty strings`);
3680
- return [...new Set(value)];
3681
- }
3682
- function sourceList(value, field, fallback) {
3683
- if (value === void 0) return new Set(fallback);
3684
- if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || item.length === 0)) throw new TypeError(`bootstrap: ${field} must be an array of non-empty strings`);
3685
- return new Set(value);
3686
- }
3687
- function resolveBootstrapSettings(opts) {
3688
- const promoteOn = opts.promoteOn ?? "either";
3689
- if (promoteOn !== "either" && promoteOn !== "tool-call" && promoteOn !== "assistant-message") throw new TypeError(`bootstrap: promoteOn must be one of "tool-call", "assistant-message", "either"; got ${JSON.stringify(promoteOn)}`);
3690
- let anchorMessages;
3691
- if (Array.isArray(opts.anchorMessages)) {
3692
- if (opts.anchorMessages.length === 0 || opts.anchorMessages.some((m) => typeof m !== "string" || m.length === 0)) throw new TypeError(`bootstrap: anchorMessages must be a non-empty array of non-empty strings`);
3693
- anchorMessages = opts.anchorMessages;
3694
- } else anchorMessages = [typeof opts.anchorMessage === "string" && opts.anchorMessage.length > 0 ? opts.anchorMessage : DEFAULT_ANCHOR_MESSAGE];
3682
+ /** 协议固有 bootstrap 设置:zeroTools=true(首请求 0 工具纯文字锚定轮)、
3683
+ * 晋升信号仅 assistant/message(对齐 zero-anchored-standard)、
3684
+ * requiredSignals = 锚定轮数(2 条消息 2 条回复后晋升)。无参——零配置面。 */
3685
+ function resolveBootstrapSettings() {
3695
3686
  return {
3696
- bootstrapTools: stringList(opts.bootstrapTools, "bootstrapTools", DEFAULT_BOOTSTRAP_TOOLS),
3697
- promoteEvents: opts.zeroTools ? PROMOTE_EVENTS["assistant-message"] : PROMOTE_EVENTS[promoteOn],
3698
- requiredSignals: opts.zeroTools ? anchorMessages.length : 1,
3699
- suppressedSources: sourceList(opts.suppressedContextSources, "suppressedContextSources", DEFAULT_SUPPRESSED_SOURCES),
3700
- compactionTools: stringList(opts.compactionTools, "compactionTools", DEFAULT_COMPACTION_TOOLS),
3701
- anchorMessages,
3702
- zeroTools: opts.zeroTools === true
3687
+ bootstrapTools: [...DEFAULT_BOOTSTRAP_TOOLS],
3688
+ promoteEvents: PROMOTE_EVENTS["assistant-message"],
3689
+ requiredSignals: DEFAULT_ANCHOR_MESSAGES.length,
3690
+ suppressedSources: new Set(DEFAULT_SUPPRESSED_SOURCES),
3691
+ compactionTools: [...DEFAULT_COMPACTION_TOOLS],
3692
+ anchorMessages: [...DEFAULT_ANCHOR_MESSAGES],
3693
+ zeroTools: true
3703
3694
  };
3704
3695
  }
3705
3696
  /**
3706
- * 注册 Anchored bootstrap 机制(按 agent cwd 动态解析 CCC 配置——多 CCC 架构,与 guards 同模式):
3707
- * 1. session/event 观察晋升信号(tool/call + assistant/message + compaction/end)
3697
+ * 注册 Anchored bootstrap 机制(协议固有,零配置面——S142;按 agent cwd 定位 CCC root,
3698
+ * 晋升状态按 root 隔离,但设置全局一致):
3699
+ * 1. session/event 观察晋升信号(assistant/message + step/start 兜底 + compaction/end)
3708
3700
  * 2. system-prompt/assemble:bootstrap 阶段目录窄化到 bootstrapTools(+compaction 后 compactionTools)
3709
3701
  * 3. agent/pre-step:bootstrap 阶段剥离 suppressedSources 注入消息(降级保留全部)
3710
3702
  *
3711
- * CCC 的 serenity.json 配置 `bootstrap.enabled: true` 才生效(否则零影响);
3712
3703
  * 摘除 = 删除 index.ts 中本注册行(独立模块)。
3713
3704
  */
3714
3705
  /** 从 agent 解析 CCC 根(宽松;无 agent/无 CCC 返回 null) */
@@ -3717,31 +3708,16 @@ function agentRoot(agent) {
3717
3708
  if (typeof cwd !== "string") return null;
3718
3709
  return findSerenityRoot(cwd);
3719
3710
  }
3720
- /** agent cwd 解析 bootstrap 配置(总是生效——无 enabled 开关,用户明确"直接开启不能关";
3721
- * CCC serenity.json bootstrap 段仅用于调参数,缺省用默认设置) */
3722
- function readBootstrapConfig(agent) {
3723
- const root = agentRoot(agent);
3724
- if (!root) return resolveBootstrapSettings({});
3725
- const b = loadSerenityConfig(root).bootstrap;
3726
- return resolveBootstrapSettings({
3727
- bootstrapTools: b?.bootstrapTools,
3728
- promoteOn: b?.promoteOn,
3729
- suppressedContextSources: b?.suppressedContextSources,
3730
- compactionTools: b?.compactionTools,
3731
- anchorMessage: b?.anchorMessage,
3732
- anchorMessages: b?.anchorMessages,
3733
- zeroTools: b?.zeroTools
3734
- });
3735
- }
3711
+ /** 协议固有设置(零配置面):所有 CCC 使用同一固化设置 */
3712
+ const SETTINGS = resolveBootstrapSettings();
3736
3713
  function registerBootstrap(ctx) {
3737
- const settingsByRoot = /* @__PURE__ */ new Map();
3738
3714
  const trackers = /* @__PURE__ */ new Map();
3739
3715
  /** 已锚定会话(进程内防重:子 agent 每会话只锚定一次) */
3740
3716
  const anchoredSessions = /* @__PURE__ */ new Set();
3741
- const trackerFor = (root, settings) => {
3717
+ const trackerFor = (root) => {
3742
3718
  let t = trackers.get(root);
3743
3719
  if (!t) {
3744
- t = createEpochPromotion(settings.promoteEvents, settings.requiredSignals);
3720
+ t = createEpochPromotion(SETTINGS.promoteEvents, SETTINGS.requiredSignals);
3745
3721
  trackers.set(root, t);
3746
3722
  }
3747
3723
  return t;
@@ -3752,16 +3728,12 @@ function registerBootstrap(ctx) {
3752
3728
  if (typeof cwd !== "string") return;
3753
3729
  const root = findSerenityRoot(cwd);
3754
3730
  if (!root) return;
3755
- const settings = settingsByRoot.get(root) ?? readBootstrapConfig({ session });
3756
- settingsByRoot.set(root, settings);
3757
- trackerFor(root, settings).observe(session, event);
3731
+ trackerFor(root).observe(session, event);
3758
3732
  } catch {}
3759
3733
  });
3760
3734
  ctx.on("agent/inbox/inserted", ({ agent, message }) => {
3761
3735
  try {
3762
- const root = agentRoot(agent);
3763
- if (!root) return;
3764
- const settings = settingsByRoot.get(root) ?? readBootstrapConfig(agent);
3736
+ if (!agentRoot(agent)) return;
3765
3737
  const session = agent.session;
3766
3738
  const depth = session?.header?.delegationDepth ?? 0;
3767
3739
  const sid = typeof session?.id === "string" ? session.id : void 0;
@@ -3772,12 +3744,12 @@ function registerBootstrap(ctx) {
3772
3744
  if (message?.source?.kind === "plugin") return;
3773
3745
  const inbox = agent.inbox;
3774
3746
  if (!inbox?.prepend) return;
3775
- for (let i = settings.anchorMessages.length - 1; i >= 0; i--) inbox.prepend("next-turn", {
3747
+ for (let i = SETTINGS.anchorMessages.length - 1; i >= 0; i--) inbox.prepend("next-turn", {
3776
3748
  id: `bootstrap-anchor-${Date.now()}-${Math.random().toString(36).slice(2, 8)}-${i}`,
3777
3749
  role: "user",
3778
3750
  content: [{
3779
3751
  type: "text",
3780
- text: settings.anchorMessages[i]
3752
+ text: SETTINGS.anchorMessages[i]
3781
3753
  }],
3782
3754
  source: {
3783
3755
  kind: "plugin",
@@ -3787,7 +3759,7 @@ function registerBootstrap(ctx) {
3787
3759
  }
3788
3760
  });
3789
3761
  if (sid !== void 0) anchoredSessions.add(sid);
3790
- warnOnce(`anchor turns injected: ${settings.anchorMessages.length} 条(${settings.anchorMessages[0].slice(0, 40)}…)`);
3762
+ warnOnce(`anchor turns injected: ${SETTINGS.anchorMessages.length} 条(${SETTINGS.anchorMessages[0].slice(0, 40)}…)`);
3791
3763
  } catch {}
3792
3764
  });
3793
3765
  let warned = false;
@@ -3804,19 +3776,17 @@ function registerBootstrap(ctx) {
3804
3776
  const agent = context.agent;
3805
3777
  const root = agentRoot(agent);
3806
3778
  if (!root) return assembled;
3807
- const settings = settingsByRoot.get(root) ?? readBootstrapConfig(agent);
3808
- settingsByRoot.set(root, settings);
3809
- const status = trackerFor(root, settings).status(agent);
3779
+ const status = trackerFor(root).status(agent);
3810
3780
  if (status.promoted) return assembled;
3811
3781
  const tools = assembled.tools;
3812
3782
  if (!Array.isArray(tools)) return assembled;
3813
3783
  const available = new Set(tools.map((tool) => tool.name).filter((n) => typeof n === "string"));
3814
- if (settings.zeroTools) {
3784
+ if (SETTINGS.zeroTools) {
3815
3785
  if (status.boundary < 0) return {
3816
3786
  ...assembled,
3817
3787
  tools: []
3818
3788
  };
3819
- const keep = new Set(settings.compactionTools);
3789
+ const keep = new Set(SETTINGS.compactionTools);
3820
3790
  const missing = [...keep].filter((name) => !available.has(name));
3821
3791
  if (missing.length > 0) {
3822
3792
  warnOnce(`expected compaction tools missing=${JSON.stringify(missing)} — bootstrap disabled, full catalog exposed`);
@@ -3827,8 +3797,8 @@ function registerBootstrap(ctx) {
3827
3797
  tools: tools.filter((tool) => typeof tool.name === "string" && keep.has(tool.name))
3828
3798
  };
3829
3799
  }
3830
- const keep = new Set(settings.bootstrapTools);
3831
- if (status.boundary >= 0) for (const toolName of settings.compactionTools) keep.add(toolName);
3800
+ const keep = new Set(SETTINGS.bootstrapTools);
3801
+ if (status.boundary >= 0) for (const toolName of SETTINGS.compactionTools) keep.add(toolName);
3832
3802
  const missing = [...keep].filter((name) => !available.has(name));
3833
3803
  if (missing.length > 0) {
3834
3804
  warnOnce(`expected bootstrap tools missing=${JSON.stringify(missing)} — bootstrap disabled, full catalog exposed`);
@@ -3849,14 +3819,12 @@ function registerBootstrap(ctx) {
3849
3819
  try {
3850
3820
  const root = agentRoot(agent);
3851
3821
  if (!root) return decision;
3852
- const settings = settingsByRoot.get(root) ?? readBootstrapConfig(agent);
3853
- settingsByRoot.set(root, settings);
3854
- if (trackerFor(root, settings).status(agent).promoted || settings.suppressedSources.size === 0) return decision;
3822
+ if (trackerFor(root).status(agent).promoted || SETTINGS.suppressedSources.size === 0) return decision;
3855
3823
  const messages = decision.messages;
3856
3824
  if (!Array.isArray(messages)) return decision;
3857
3825
  const kept = messages.filter((message) => {
3858
3826
  const kind = message?.source?.kind;
3859
- return typeof kind !== "string" || !settings.suppressedSources.has(kind);
3827
+ return typeof kind !== "string" || !SETTINGS.suppressedSources.has(kind);
3860
3828
  });
3861
3829
  return kept.length === messages.length ? decision : {
3862
3830
  ...decision,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shgroup/dsh-serenity-hooks",
3
- "version": "1.19.4",
3
+ "version": "1.19.5",
4
4
  "description": "宁静号 ACC harness — Native Cordis 插件(DeepSeek Harness 运行时)。真实 DSH 工具注册(cc_fs/session/acc_msm 等 9 工具)+ 拦截缝机械约束(safe-mode/路径守卫/会话落盘)+ 系统提示词注入(ACC/CCE/Constraints/SKILL/Session 五块)。适配 DSH 公开版(deepseek-ai/deepseek-harness 0.1.0-rc)。",
5
5
  "license": "MIT",
6
6
  "repository": {