@shgroup/dsh-serenity-hooks 1.19.4 → 1.19.6
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 +1 -1
- package/lib/index.js +92 -75
- package/package.json +1 -1
package/dsh.plugin.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-serenity-hooks",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.6",
|
|
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
|
-
/**
|
|
3563
|
-
*
|
|
3564
|
-
|
|
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
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
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:
|
|
3697
|
-
promoteEvents:
|
|
3698
|
-
requiredSignals:
|
|
3699
|
-
suppressedSources:
|
|
3700
|
-
compactionTools:
|
|
3701
|
-
anchorMessages,
|
|
3702
|
-
zeroTools:
|
|
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
|
|
3707
|
-
*
|
|
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
|
-
/**
|
|
3721
|
-
|
|
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
|
|
3717
|
+
const trackerFor = (root) => {
|
|
3742
3718
|
let t = trackers.get(root);
|
|
3743
3719
|
if (!t) {
|
|
3744
|
-
t = createEpochPromotion(
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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:
|
|
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: ${
|
|
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
|
|
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 (
|
|
3784
|
+
if (SETTINGS.zeroTools) {
|
|
3815
3785
|
if (status.boundary < 0) return {
|
|
3816
3786
|
...assembled,
|
|
3817
3787
|
tools: []
|
|
3818
3788
|
};
|
|
3819
|
-
const keep = new Set(
|
|
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(
|
|
3831
|
-
if (status.boundary >= 0) for (const toolName of
|
|
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
|
-
|
|
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" || !
|
|
3827
|
+
return typeof kind !== "string" || !SETTINGS.suppressedSources.has(kind);
|
|
3860
3828
|
});
|
|
3861
3829
|
return kept.length === messages.length ? decision : {
|
|
3862
3830
|
...decision,
|
|
@@ -4048,7 +4016,7 @@ function accBlock(root) {
|
|
|
4048
4016
|
"",
|
|
4049
4017
|
"=== Serenity ACC ===",
|
|
4050
4018
|
`ACC: dsh-serenity-hooks v${ACC_VERSION}`,
|
|
4051
|
-
`CCC: ${cccName}
|
|
4019
|
+
`CCC: ${cccName}`,
|
|
4052
4020
|
"",
|
|
4053
4021
|
"You are running inside a Concrete Cognitive Container (CCC) —",
|
|
4054
4022
|
"the runtime instance of an Abstract Cognitive Container (ACC).",
|
|
@@ -4115,10 +4083,6 @@ function cceBlock() {
|
|
|
4115
4083
|
"continuity condition: organization must at minimum match accumulation (ΔH_org ≥ ΔH_in).",
|
|
4116
4084
|
"Your actions affect H_op — unorganized output increases it, organization decreases it.",
|
|
4117
4085
|
"",
|
|
4118
|
-
"CCE AND EAP: EAP governs artifact quality (how explicit to be). CCE governs temporal",
|
|
4119
|
-
"coherence (how to maintain consistency over time). When structuring a document, apply",
|
|
4120
|
-
"EAP (E↑ R↓ S↑). When maintaining cross-session coherence, apply CCE.",
|
|
4121
|
-
"",
|
|
4122
4086
|
"THIS IS PERSISTENCE ENGINEERING: The goal is not to become greater. The goal is to",
|
|
4123
4087
|
"remain coherent. CCE has no terminal KPI — continuity is maintained while the entity",
|
|
4124
4088
|
"exists, not optimized toward an endpoint.",
|
|
@@ -4155,6 +4119,58 @@ function eapBlock() {
|
|
|
4155
4119
|
].join("\n");
|
|
4156
4120
|
}
|
|
4157
4121
|
/**
|
|
4122
|
+
* Metaphor 强化块(v1.19.6,S142):宁静号宇宙隐喻域(船/海/罗盘/日志/船员)。
|
|
4123
|
+
* 隐喻是记忆钩子——形象唤起约束,前述块保持规则精确。每条隐喻 = 一个不可违背的
|
|
4124
|
+
* 物理事实 + 行为判据(verdict)。全英文(与 CCE/Constraints 一致);独立块可
|
|
4125
|
+
* 回退;无 osp 对应(dsp 扩展,不进对齐断言参照)。
|
|
4126
|
+
*/
|
|
4127
|
+
function metaphorBlock() {
|
|
4128
|
+
return [
|
|
4129
|
+
"",
|
|
4130
|
+
"=== Serenity Metaphor ===",
|
|
4131
|
+
"The Serenity Universe — one ship, one sea. Metaphors are memory hooks:",
|
|
4132
|
+
"they make constraints vivid, while the rules above stay precise. Each",
|
|
4133
|
+
"metaphor is an unbreakable physical fact; violating one is a behavioral",
|
|
4134
|
+
"violation.",
|
|
4135
|
+
"",
|
|
4136
|
+
"1. The Hull — You exist only inside this ship. Cargo outside the hull",
|
|
4137
|
+
" (knowledge the container has not accumulated) does not exist; do not",
|
|
4138
|
+
" assume it. Verdict: citing facts absent from the container = overload.",
|
|
4139
|
+
"",
|
|
4140
|
+
"2. The Logbook — SESSION.md is the only ship log. Unrecorded = unvoyaged.",
|
|
4141
|
+
" Verdict: finishing multi-step work without a progress record = a missing page.",
|
|
4142
|
+
"",
|
|
4143
|
+
"3. The Ship of Theseus — Planks may be replaced; the ship remains the same.",
|
|
4144
|
+
" The container can be rebuilt; identity persists. You are part of a",
|
|
4145
|
+
" trajectory, not a new ship. Verdict: acting without consulting precedent",
|
|
4146
|
+
" = a different ship.",
|
|
4147
|
+
"",
|
|
4148
|
+
"4. Deck Order — Clutter on deck raises the cost of finding things (H_op).",
|
|
4149
|
+
" H_op ≤ H_critical = the ship stays afloat. Verdict: disorganized output",
|
|
4150
|
+
" = stones on deck.",
|
|
4151
|
+
"",
|
|
4152
|
+
"5. Blueprint over Statue — Keep the blueprint, not the statue. Recording",
|
|
4153
|
+
" only conclusions without rationale = a statue with no blueprint,",
|
|
4154
|
+
" unreconstructable. Verdict: a decision record without reasons or",
|
|
4155
|
+
" alternatives = cannot be rebuilt.",
|
|
4156
|
+
"",
|
|
4157
|
+
"6. Crew Rotation — Other crew members will come after you. When you leave,",
|
|
4158
|
+
" leave a handover they can pick up (SESSION closed, open problems listed).",
|
|
4159
|
+
" Verdict: leaving without handover = abandoning ship.",
|
|
4160
|
+
"",
|
|
4161
|
+
"7. Harbor Inspection — The first anchor = departure inspection: confirm",
|
|
4162
|
+
" identity (ACC manifesto), logbook (SESSION), ballast (constraints)",
|
|
4163
|
+
" before setting sail. Verdict: skipping the anchor and working directly",
|
|
4164
|
+
" = sailing uninspected.",
|
|
4165
|
+
"",
|
|
4166
|
+
"8. Engineering Drawings — EAP = engineering drawings: every part",
|
|
4167
|
+
" dimensioned (E↑), the drawings rebuild the whole machine (R↓), the",
|
|
4168
|
+
" drawings are reusable (S↑). Verdict: an undimensioned part",
|
|
4169
|
+
" = unassemblable.",
|
|
4170
|
+
""
|
|
4171
|
+
].join("\n");
|
|
4172
|
+
}
|
|
4173
|
+
/**
|
|
4158
4174
|
* 运行时状态块 1) safe-mode(S134 v1.16.12):ON 时告知 agent(行为约束;机制仍由 guards 强制)。
|
|
4159
4175
|
* 文案与实现逐项对应(guards.ts):bash 禁用(restrict deny + decideGuard)、
|
|
4160
4176
|
* 黑名单路径拦截、CCC 治理文件保护;write/edit 等其余工具保留(受路径逃逸/黑名单约束)。
|
|
@@ -4264,6 +4280,7 @@ function serenitySystemPrompt(root, scope = DEFAULT_SESSION_SCOPE) {
|
|
|
4264
4280
|
const state = [safeModeBlock(root), localstoreBlock(root)].filter((b) => b !== "").join("\n");
|
|
4265
4281
|
if (state) parts.push(state);
|
|
4266
4282
|
parts.push(eapBlock());
|
|
4283
|
+
parts.push(metaphorBlock());
|
|
4267
4284
|
const skill = entrySkillSectionText(root);
|
|
4268
4285
|
if (skill) parts.push(skill);
|
|
4269
4286
|
const session = sessionBlock(root, scope);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shgroup/dsh-serenity-hooks",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.6",
|
|
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": {
|