@shgroup/dsh-serenity-hooks 1.103.0 → 1.105.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.
Files changed (33) hide show
  1. package/README.md +1 -2
  2. package/dsh.plugin.json +2 -3
  3. package/lib/{ccc-CyYJL4F2.js → ccc-B-h_A7uc.js} +17 -36
  4. package/lib/{ccc-roots-WfktvbN8.js → ccc-roots-BPicjCsj.js} +19 -11
  5. package/lib/{channels-CuCsUfcY.js → channels-bAiZlY07.js} +2 -2
  6. package/lib/client.js +1 -6
  7. package/lib/cro/guide.d.ts +1 -1
  8. package/lib/guard/seam.d.ts +2 -1
  9. package/lib/host/access.d.ts +37 -39
  10. package/lib/host/contract.d.ts +3 -2
  11. package/lib/index.js +64 -375
  12. package/lib/invariant.js +0 -1
  13. package/lib/kernel/ccc-roots.d.ts +4 -3
  14. package/lib/kernel/ccc.d.ts +12 -30
  15. package/lib/kernel/invariant.d.ts +1 -1
  16. package/lib/{message-source-BAxZk9Dn.js → message-source-DoVtXnoe.js} +3 -3
  17. package/lib/{profile-zxakCNXy.js → profile-Dpg3wYO5.js} +1 -1
  18. package/lib/{route-DxIKWeN9.js → route-CmEoKp9w.js} +2 -2
  19. package/lib/seams/context.d.ts +5 -2
  20. package/lib/{service-DDmHSglV.js → service-Cndtf7q4.js} +6 -6
  21. package/lib/{session-DWmIqApm.js → session-CYqyod3z.js} +73 -140
  22. package/lib/surface/status.d.ts +1 -2
  23. package/lib/tools/localstore/service.d.ts +1 -1
  24. package/lib/tools/msm/service.d.ts +2 -2
  25. package/lib/tools/trajectory-constraint-admin.d.ts +1 -1
  26. package/lib/trajectory/carrier.d.ts +5 -4
  27. package/lib/trajectory/model-runtime.d.ts +5 -3
  28. package/lib/trajectory/model-string.d.ts +26 -0
  29. package/lib/trajectory/policy/profile.d.ts +1 -1
  30. package/package.json +2 -2
  31. package/lib/tools/cheap-worker.d.ts +0 -21
  32. package/lib/trajectory/delegate/core.d.ts +0 -55
  33. package/lib/trajectory/delegate/preset.d.ts +0 -42
package/lib/index.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { i as __toESM, n as __exportAll } from "./rolldown-runtime-B4iAMlE-.js";
2
- import { c as hostInjected, d as hostSessions, f as hostSettings, h as hostWebServer, i as cccRootForExec, l as hostLlm, m as hostWeb, n as agentCwdFor, o as listCccs, p as hostSubagents, r as cccRootForCwd, s as hostAgents, t as NO_CCC_FROM_AGENT_CWD, u as hostService } from "./ccc-roots-WfktvbN8.js";
3
- import { _ as resolveInside, a as findSerenityRoot$1, c as matchBlacklist, d as readCccName$1, f as readCheapWorkerConfig, h as readSafeModeHiddenTools, i as findGitRoot, l as pathInside, m as readExclusiveTools, n as SAFE_MODE_MARKER, o as isSafeModeOn, r as classifyPath, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS, u as readBlacklist } from "./ccc-CyYJL4F2.js";
4
- import { A as namingTitleFor, B as summarize, C as createSession, E as getActiveSessionInfo, F as resolveSessionByTitle, G as readTrajectoryFile, H as useSession, I as sessionEvents, J as localHuman, K as isoLocal, L as sessionsRoot, M as parseTrajectoryCode, O as listActiveTrajectories, P as readTrajectoryUid, R as setActiveSessionInfo, S as clearActiveSessionInfo, T as findSession, U as TRAJECTORY_FILENAME, V as trajectoryDescOf, W as TRAJECTORY_LEGACY_FILENAMES, Y as localIdStamp, b as UID_FILENAME, c as replacesDefaultIdentity, i as listTrajectoryConstraints, j as parseSessionContextFromEvents, k as listSessions, l as trajectoryCodeForSession, n as findDirNameByCode, o as readTrajectoryConstraintAt, q as localFileStamp, r as isTrajectoryConstrained, s as readTrajectoryConstraintByCode, t as TRAJECTORY_CONSTRAINT_FILENAME, u as trajectoryConstraintForSession, v as COGNITIVE_TRAJECTORY_ACTIONS, w as extractSessionMdPathFromText, x as archiveSession, z as showSession } from "./profile-zxakCNXy.js";
5
- import { n as checkLocalstoreGitCompliance, o as readStore, s as runLocalStore, t as LOCALSTORE_SCOPES } from "./service-DDmHSglV.js";
6
- import { _ as resolveConstraintSystemPrompt, a as listBoundSessionIds, d as constraintCognitiveTrajectory, f as constraintSystemPromptSource, g as profileWriteWhitelist, h as profileToolWhitelist, i as carrierState, l as TRAJECTORY_CONSTRAINT_HINT, n as PLUGIN_SOURCE, o as readLastBound, r as appendBound, s as resolveSessionCognitiveTrajectoryLabel, t as ACC_MESSAGE_KIND, v as ACC_VERSION, y as findPackageRoot } from "./message-source-BAxZk9Dn.js";
7
- import { A as buildResourceIndex, C as verifyPassword, D as recordToolUsage, E as verifyTotpCode, F as hasTrajectoryPrompt, M as isSafeSkillName, N as truncateContent, O as REFERENCE_DIR, P as TRAJECTORY_PROMPT_FILENAME, S as toWire, T as MECHANISM_PORTS, _ as registerEntrySkillSectionGlobal, a as trajectoryConstraintFor, b as projectKnownWorkspaces, c as trajectoryWorkspaceMdPath, d as CHEAP_WORKER_GUIDE, f as providerAvailabilityError, g as registerEntrySkillSection, h as registerCognitiveTrajectorySkillSection, i as getTrajectoryAgent, j as buildResourceNameSuffix, k as SKILL_ONTOLOGY_FILE, l as unregisterTrajectorySession, m as splitModel, n as deliverToTrajectory, o as trajectoryConstraintMsmGate, p as requireWhitelistedModel, r as ensureWorkspacePromptSection, s as trajectoryConstraintParticipates, t as createTrajectoryAgent, u as workspaceCognitiveTrajectoryLine, v as applyWirePatch, w as FACE_PORTS, x as readAdvancedSettings, y as migrateLegacyLocalstore } from "./session-DWmIqApm.js";
2
+ import { c as hostAgents, d as hostSessions, f as hostSettings, i as cccRootForExec, l as hostInjected, m as hostWebServer, n as agentCwdFor, o as listCccs, p as hostWeb, r as cccRootForCwd, t as NO_CCC_FROM_AGENT_CWD, u as hostService } from "./ccc-roots-BPicjCsj.js";
3
+ import { a as findSerenityRoot$1, c as matchBlacklist, d as readCccName$1, g as resolveInside, i as findGitRoot, l as pathInside, m as readSafeModeHiddenTools, n as SAFE_MODE_MARKER, o as isSafeModeOn, p as readExclusiveTools, r as classifyPath, s as loadSerenityConfig, t as DEFAULT_SERENITY_CONFIG_PATHS, u as readBlacklist } from "./ccc-B-h_A7uc.js";
4
+ import { A as namingTitleFor, B as summarize, C as createSession, E as getActiveSessionInfo, F as resolveSessionByTitle, G as readTrajectoryFile, H as useSession, I as sessionEvents, J as localHuman, K as isoLocal, L as sessionsRoot, M as parseTrajectoryCode, O as listActiveTrajectories, P as readTrajectoryUid, R as setActiveSessionInfo, S as clearActiveSessionInfo, T as findSession, U as TRAJECTORY_FILENAME, V as trajectoryDescOf, W as TRAJECTORY_LEGACY_FILENAMES, Y as localIdStamp, b as UID_FILENAME, c as replacesDefaultIdentity, i as listTrajectoryConstraints, j as parseSessionContextFromEvents, k as listSessions, l as trajectoryCodeForSession, n as findDirNameByCode, o as readTrajectoryConstraintAt, q as localFileStamp, r as isTrajectoryConstrained, s as readTrajectoryConstraintByCode, t as TRAJECTORY_CONSTRAINT_FILENAME, u as trajectoryConstraintForSession, v as COGNITIVE_TRAJECTORY_ACTIONS, w as extractSessionMdPathFromText, x as archiveSession, z as showSession } from "./profile-Dpg3wYO5.js";
5
+ import { n as checkLocalstoreGitCompliance, o as readStore, s as runLocalStore, t as LOCALSTORE_SCOPES } from "./service-Cndtf7q4.js";
6
+ import { _ as resolveConstraintSystemPrompt, a as listBoundSessionIds, d as constraintCognitiveTrajectory, f as constraintSystemPromptSource, g as profileWriteWhitelist, h as profileToolWhitelist, i as carrierState, l as TRAJECTORY_CONSTRAINT_HINT, n as PLUGIN_SOURCE, o as readLastBound, r as appendBound, s as resolveSessionCognitiveTrajectoryLabel, t as ACC_MESSAGE_KIND, v as ACC_VERSION, y as findPackageRoot } from "./message-source-DoVtXnoe.js";
7
+ import { A as truncateContent, C as verifyTotpCode, D as buildResourceIndex, E as SKILL_ONTOLOGY_FILE, M as hasTrajectoryPrompt, O as buildResourceNameSuffix, S as MECHANISM_PORTS, T as REFERENCE_DIR, _ as projectKnownWorkspaces, a as trajectoryConstraintFor, b as verifyPassword, c as trajectoryWorkspaceMdPath, d as splitModel, f as registerCognitiveTrajectorySkillSection, g as migrateLegacyLocalstore, h as applyWirePatch, i as getTrajectoryAgent, j as TRAJECTORY_PROMPT_FILENAME, k as isSafeSkillName, l as unregisterTrajectorySession, m as registerEntrySkillSectionGlobal, n as deliverToTrajectory, o as trajectoryConstraintMsmGate, p as registerEntrySkillSection, r as ensureWorkspacePromptSection, s as trajectoryConstraintParticipates, t as createTrajectoryAgent, u as workspaceCognitiveTrajectoryLine, v as readAdvancedSettings, w as recordToolUsage, x as FACE_PORTS, y as toWire } from "./session-CYqyod3z.js";
8
8
  import { i as sessionsRootDir, n as findSessionLog, r as hasSessionLogById } from "./cleanup-CPl1SSaK.js";
9
- import { i as runImBridge, n as isImWiredTrajectory, o as readSimpleSettings, r as registerImChannel, s as registerSettingsSection, t as imChannelIds } from "./channels-CuCsUfcY.js";
10
- import { a as readFeishuCredential, c as readWeixinSettings, d as weixinInboundDir, f as weixinSessionIdForTrajectory, i as matchWeixinRoute, n as extractWeixinText, r as hasVoiceItem, s as readWeixinCredential, t as extractWeixinMedia, u as sanitizeFileName$1 } from "./route-DxIKWeN9.js";
9
+ import { i as runImBridge, n as isImWiredTrajectory, o as readSimpleSettings, r as registerImChannel, s as registerSettingsSection, t as imChannelIds } from "./channels-bAiZlY07.js";
10
+ import { a as readFeishuCredential, c as readWeixinSettings, d as weixinInboundDir, f as weixinSessionIdForTrajectory, i as matchWeixinRoute, n as extractWeixinText, r as hasVoiceItem, s as readWeixinCredential, t as extractWeixinMedia, u as sanitizeFileName$1 } from "./route-CmEoKp9w.js";
11
11
  import { REGISTERED_TOOLS } from "./invariant.js";
12
12
  import { c as sendTextMessage, i as getUpdates, l as sendTyping, n as downloadMedia, o as markdownToPlainText, r as getConfig, s as sendFileMessage, t as TypingStatus, u as sniffImageExt } from "./ilink-CsZ-f64q.js";
13
13
  import { a as registerImAccountImpl, i as normalizeAccountChannel, n as getImAccountImpl, r as imAccountChannels } from "./accounts-BHQbakUh.js";
@@ -423,7 +423,7 @@ function runCcFs(root, args) {
423
423
  * 进程内注册(取代 v0.1 的 bash spawn runner):zod/schemastery 参数校验、
424
424
  * 规范 JSON 输出、纯 render 投影。逻辑在 tools/fs/service.ts(可单测)。
425
425
  */
426
- function renderText$11(value) {
426
+ function renderText$10(value) {
427
427
  return [{
428
428
  type: "text",
429
429
  text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
@@ -495,7 +495,7 @@ const ccFsTool = defineTool({
495
495
  },
496
496
  output: {
497
497
  schema: { type: "json" },
498
- render: (args, value) => renderText$11(value)
498
+ render: (args, value) => renderText$10(value)
499
499
  },
500
500
  async execute(args, exec) {
501
501
  const root = cccRootForExec(exec);
@@ -571,7 +571,7 @@ async function runKit(root, args, hostCtx) {
571
571
  /**
572
572
  * tools/kit/index.ts — dashboard 真实 DSH 工具定义(defineTool)(v1.30:acc_kit → dashboard)
573
573
  */
574
- function renderText$10(value) {
574
+ function renderText$9(value) {
575
575
  return [{
576
576
  type: "text",
577
577
  text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
@@ -599,7 +599,7 @@ function createKitTool(ctx) {
599
599
  },
600
600
  output: {
601
601
  schema: { type: "json" },
602
- render: (args, value) => renderText$10(value)
602
+ render: (args, value) => renderText$9(value)
603
603
  },
604
604
  async execute(args, exec) {
605
605
  return await runKit(cccRootForExec(exec), args, ctx);
@@ -915,7 +915,7 @@ function runGit(root, args) {
915
915
  /**
916
916
  * tools/git/index.ts — container_git 真实 DSH 工具定义(defineTool)(v1.30:cc_git → container_git)
917
917
  */
918
- function renderText$9(value) {
918
+ function renderText$8(value) {
919
919
  return [{
920
920
  type: "text",
921
921
  text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
@@ -963,7 +963,7 @@ const gitTool = defineTool({
963
963
  },
964
964
  output: {
965
965
  schema: { type: "json" },
966
- render: (args, value) => renderText$9(value)
966
+ render: (args, value) => renderText$8(value)
967
967
  },
968
968
  async execute(args, exec) {
969
969
  const root = cccRootForExec(exec);
@@ -1148,7 +1148,6 @@ Directory of ACC capabilities — each area lists where to go for details (guide
1148
1148
  与 praxis ontology 的分工 = 那个是**方法文本**、这个是**能跑的那个**)
1149
1149
  ③ 工具与执行 → container_fs(容器文件系统 15 子命令)/ container_git(git)/ dashboard(health 含注册表检查/time/wait)
1150
1150
  acc_msm 已并入 msm(执行+发现)与 container_admin(管理)——msm("<name>", ["<args>"]);inspect=true 查用法
1151
- cheap-worker(杂工 agent 编排——guide 子命令:cheap-worker guide)
1152
1151
  专属工具(**默认对所有 CCC 隐藏**,只有在自己 exclusiveTools 里点名的 CCC 可见)→ acc-diag(运行态诊断)
1153
1152
  ④ 轨迹约束与对外面 → container_admin config(轨迹约束四动作 guide/validate/apply/list——**原 role 域已并入 config**,旧名作过渡别名仍可用;说明类配置走**两层菜单** config docs 目录 / config docs <章节> 详情)
1154
1153
  外部程序化接入用官方 dsh --profile acp
@@ -1156,7 +1155,7 @@ Directory of ACC capabilities — each area lists where to go for details (guide
1156
1155
  ⑤ 自主与接入 → cognitive_trajectory send-now(跨轨迹的**即时**递送,**不排队**:live 目标在跑就当场注入当前轮、空闲则立即起轮;非 live 冷载入——等效于直接 wake;**有同步回执**)
1157
1156
  cognitive_trajectory send-later(跨轨迹的"未来时刻 + 一条 message";fire-and-forget,无回执无回收)
1158
1157
  weixin 微信桥(配置/扫码/路由/消息 hook——CCC 侧 weixin-doctor MSM:msm("weixin-doctor", ["guide"]))
1159
- ⑥ CCC 配置总览 → container_admin config docs config(按章详情——9 段全表)
1158
+ ⑥ CCC 配置总览 → container_admin config docs config(按章详情——8 段全表)
1160
1159
  或 container_admin msm ccc-config(同一份正文的旧入口,保留)
1161
1160
  ⑦ 注册表与安全 → mech-registry.json 由 container_admin msm register/deregister 管理(写保护——不可直接编辑)
1162
1161
  dashboard health 输出 registry 完整性检查;损坏恢复指引见 health registry.issues
@@ -1230,29 +1229,7 @@ const CCC_CONFIG_REFERENCE = `═══ CCC Configuration Reference ═══
1230
1229
  CCC-level features are configured in .opencode/serenity.json.
1231
1230
  Below are all available configuration sections.
1232
1231
 
1233
- ── 1. cheap-worker.models ──
1234
- cheap-worker(杂工)工具可用模型白名单(provider/model 列表);未配置时 cheap-worker 报错要求配置。
1235
- 缺省模型 = models[0](可用 cheap-worker.defaultModel 指定,必须 ∈ models)。
1236
- **CCC 应把该白名单指向低成本模型**——cheap-worker 是批量执行通道。
1237
- 🔴 模型**不可由调用方指定**(工具无 model 参数)⇒ 本白名单是模型选择的唯一来源。
1238
-
1239
- Behaviour(2026-10-14:background 模式已删除,只剩前台委派):
1240
- cheap-worker(task, [label]):一次前台委派(宿主委派服务 ctx.subagents.start("spawn") +
1241
- agentOptions 注入模型)——不循环、不校验完成码、不写进度文件;返回子 agent 最终文本。
1242
- cheap-worker(jobs=[{task,label?},...]):并行扇出,上限 10(硬编码),结果保持传入顺序。
1243
- ⇒ **无 background 模式、无进度文件、无续跑**(owner 2026-10-14 令「删除后台运行能力」)。
1244
-
1245
- Old key(兼容):
1246
- 读不到 "cheap-worker" 时**回落到旧键 "handyman"**(同形状:models / defaultModel)。
1247
- 旧键里的 "maxRounds"/"maxParallel" 已随 background 退场,留着无害但不再生效。
1248
-
1249
- Config:
1250
- { "cheap-worker": { "models": ["provider/model-name"] } }
1251
-
1252
- Example:
1253
- { "cheap-worker": { "models": ["minimax-cn-coding-plan/MiniMax-M3"], "defaultModel": "minimax-cn-coding-plan/MiniMax-M3" } }
1254
-
1255
- ── 2. sessionKeeper.threshold / sessionKeeper.sessionMdMaxKB ──
1232
+ ── 1. sessionKeeper.threshold / sessionKeeper.sessionMdMaxKB ──
1256
1233
  cognitive-trajectory-assistant(COGNITIVE-TRAJECTORY-ASSISTANT · CHECKPOINT)提醒机制的积分阈值(非 headless 主 agent)。
1257
1234
  按工具调用加权 + 耗时计分;达到阈值注入提醒,要求模型回复 ACK 码。
1258
1235
 
@@ -1272,20 +1249,20 @@ cognitive-trajectory-assistant(COGNITIVE-TRAJECTORY-ASSISTANT · CHECKPOINT)
1272
1249
  超限后每次工具调用都提醒;连续 3 次未重写 → 升级强制语气;
1273
1250
  文件回到限内 → 自动停止(自愈)。轨迹提醒**不机械阻断工作**(与 rebuild 提醒同族)。
1274
1251
 
1275
- ── 3. localstore.gitTrack ──
1252
+ ── 2. localstore.gitTrack ──
1276
1253
  localstore.json 的 git 策略:allow 可提交 / deny 禁提交(默认 deny)。
1277
1254
  deny 时写入自动确保 .gitignore 含该文件(物理保证),container_git commit 会检查拒绝。
1278
1255
 
1279
1256
  Config:
1280
1257
  { "localstore": { "gitTrack": "allow" } }
1281
1258
 
1282
- ── 4. hooks.autoRestoreSession ──
1259
+ ── 3. hooks.autoRestoreSession ──
1283
1260
  会话自动恢复(默认 true;受 events 门控——仅根会话 + 已有对话历史才恢复)。
1284
1261
 
1285
1262
  Config:
1286
1263
  { "hooks": { "autoRestoreSession": false } }
1287
1264
 
1288
- ── 5. safeMode(黑名单 + 开启期间隐藏的工具)──
1265
+ ── 4. safeMode(黑名单 + 开启期间隐藏的工具)──
1289
1266
  safe-mode 由 WebUI 开关控制(写 .serenity-safe-on 标记);黑名单路径受 guards seam 拦截。
1290
1267
 
1291
1268
  ▸ blacklist:写路径黑名单(同下 Config)。
@@ -1301,7 +1278,7 @@ safe-mode 由 WebUI 开关控制(写 .serenity-safe-on 标记);黑名单
1301
1278
  Config:
1302
1279
  { "safeMode": { "blacklist": [".secrets/"], "hiddenTools": ["workflow", "job_kill"] } }
1303
1280
 
1304
- ── 6. 轨迹约束.roles(F4 认知子集角色)──
1281
+ ── 5. 轨迹约束.roles(F4 认知子集角色)──
1305
1282
  轨迹约束角色 = 全知全能 cognitive trajectory 的任意子集(CCC 定义)。每角色独立模型 + 双白名单
1306
1283
  (MSM 白名单 msms[] 与非 MSM 工具白名单 tools[],白名单外全隐藏;skill 加载恒可用)。
1307
1284
  cognitive trajectory 纪律子集(session/keeper/rebuild 参与项)默认全关 = 完全独立。
@@ -1317,7 +1294,7 @@ validate 校验 / apply 生效 / list 查看:container_admin config <guide|val
1317
1294
  "systemPromptFile": ".opencode/skiff/qa.md"
1318
1295
  } } } }
1319
1296
 
1320
- ── 7. cognitive_trajectory(轨迹 + 唤醒注册表,D58)──
1297
+ ── 6. cognitive_trajectory(轨迹 + 唤醒注册表,D58)──
1321
1298
  CCC 的一条 cognitive trajectory = 持久身体(SESSION.md)+ 时间轴(AGENT_SESSIONS/ 目录 + 唤醒注册表)。
1322
1299
  一个 CCC 内可多条并行;条目全部由人类/agent 显式登记。
1323
1300
  ⚠️ ACC 不再提供**周期自唤醒**(原 autopilot,2026-09-15 整段退场:机制/时钟/container_admin autopilot
@@ -1352,7 +1329,7 @@ CCC 的一条 cognitive trajectory = 持久身体(SESSION.md)+ 时间轴(A
1352
1329
  "avoidWakeHours": { "start": 8, "end": 18 }
1353
1330
  } } }
1354
1331
 
1355
- ── 8. weixin(微信桥 F4c-3,含消息记录 hook)──
1332
+ ── 7. weixin(微信桥 F4c-3,含消息记录 hook)──
1356
1333
  CCC 级微信个人号接入(iLink 协议):dsh 一进程多 CCC,每 CCC 独立对接微信桥。
1357
1334
  账号/路由/开关在此文件;**bot_token 凭据在 CCC localstore credential scope**
1358
1335
  (扫码绑定后自动写入,永不进 git 明文面)。
@@ -1431,7 +1408,7 @@ CCC 级微信个人号接入(iLink 协议):dsh 一进程多 CCC,每 CCC
1431
1408
  微信桥消息处理/回复不受 hook 影响;脚本须在 CCC 根内(路径逃逸拒绝)。
1432
1409
  媒体 relPath 指向 _tmp/weixin-inbound/(临时目录)——需持久保存媒体文件请自行 copy。
1433
1410
 
1434
- ── 9. exclusiveTools(专属工具声明,v1.33)──
1411
+ ── 8. exclusiveTools(专属工具声明,v1.33)──
1435
1412
  **ACC 注册但默认对所有 CCC 隐藏**的工具,只有在自己这里**点名**的 CCC 可见。
1436
1413
  这是通用机制(任何工具名皆可),判据由 CCC 声明——ACC 代码里不出现任何具体 CCC 的名字。
1437
1414
  当前专属工具:acc-diag(运行态诊断——live 会话 / agent 定位 / 唤醒注册表 / 唤起条件链)。
@@ -1957,7 +1934,7 @@ async function runMsmAsync(root, args) {
1957
1934
  function agentSessionId$1(exec) {
1958
1935
  return exec.agent?.session?.id ?? "";
1959
1936
  }
1960
- function renderText$8(value) {
1937
+ function renderText$7(value) {
1961
1938
  return [{
1962
1939
  type: "text",
1963
1940
  text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
@@ -2055,7 +2032,7 @@ const msmTool = defineTool({
2055
2032
  },
2056
2033
  output: {
2057
2034
  schema: { type: "json" },
2058
- render: (args, value) => renderText$8(value)
2035
+ render: (args, value) => renderText$7(value)
2059
2036
  },
2060
2037
  async execute(args, exec) {
2061
2038
  const root = cccRootForExec(exec);
@@ -2579,7 +2556,7 @@ const PRAXIS_INDEX = `praxis — 可实践理论注入(认知框架,按需
2579
2556
  praxis ontology(本体论工程方法群——触发/编码/四组判据 M·L·D·V/OEPE 循环/公理/反模式)
2580
2557
  无参返回本目录;详情以对应框架原文为准(单一真相源)。
2581
2558
  `;
2582
- function renderText$7(value) {
2559
+ function renderText$6(value) {
2583
2560
  return [{
2584
2561
  type: "text",
2585
2562
  text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
@@ -2600,7 +2577,7 @@ const praxisTool = defineTool({
2600
2577
  } },
2601
2578
  output: {
2602
2579
  schema: { type: "string" },
2603
- render: (_args, value) => renderText$7(value)
2580
+ render: (_args, value) => renderText$6(value)
2604
2581
  },
2605
2582
  async execute(args) {
2606
2583
  if (args.section === "eap") return eapPaper();
@@ -6193,7 +6170,7 @@ const LEVELS_BY_COMMAND = {
6193
6170
  "full"
6194
6171
  ]
6195
6172
  };
6196
- function renderText$6(value) {
6173
+ function renderText$5(value) {
6197
6174
  return [{
6198
6175
  type: "text",
6199
6176
  text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
@@ -6258,7 +6235,7 @@ function createOntologyTool() {
6258
6235
  },
6259
6236
  output: {
6260
6237
  schema: { type: "string" },
6261
- render: (_args, value) => renderText$6(value)
6238
+ render: (_args, value) => renderText$5(value)
6262
6239
  },
6263
6240
  async execute(args, exec) {
6264
6241
  const root = cccRootForExec(exec);
@@ -6683,7 +6660,7 @@ serenity-skill-creator review <skill> ← C 档:文字与 ttl 逐条的合
6683
6660
  **判据**:改完**必须重跑** \`check\` —— 本仓的教训是"检查没跑"和"检查通过"在输出上必须分得开;
6684
6661
  \`review\` 出的是**问题清单**(半机械、要人回答),**不是**通过/不通过。
6685
6662
  `;
6686
- function renderText$5(value) {
6663
+ function renderText$4(value) {
6687
6664
  return [{
6688
6665
  type: "text",
6689
6666
  text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
@@ -6811,7 +6788,7 @@ function createSkillCreatorTool() {
6811
6788
  },
6812
6789
  output: {
6813
6790
  schema: { type: "string" },
6814
- render: (_args, value) => renderText$5(value)
6791
+ render: (_args, value) => renderText$4(value)
6815
6792
  },
6816
6793
  async execute(args, exec) {
6817
6794
  const root = cccRootForExec(exec);
@@ -6911,293 +6888,6 @@ function createSkillCreatorTool() {
6911
6888
  });
6912
6889
  }
6913
6890
  //#endregion
6914
- //#region src/tools/cheap-worker.ts
6915
- /**
6916
- * cheap-worker.ts — cheap-worker(杂工)真实 DSH 工具
6917
- *
6918
- * v1.24.0:loop(牛马)→ handyman(杂工);2026-10-14:handyman → cheap-worker。
6919
- * 🆕 2026-10-14(owner 令「删除后台运行能力」):**background 模式整条退场** ——
6920
- * 轮次循环 / stop-token 完成码 / 进度文件 / 重启计数 / maxRounds/maxParallel 全部删除。
6921
- * 现存只有**前台委派**一种形态:宿主起子 agent、等它跑完、取回最终文本。
6922
- *
6923
- * 机制:走宿主**委派正门** `ctx.subagents.start('spawn', …)`(深度上限、子 agent 所有权、
6924
- * `subagent/start|end` 事件、`dispose()` 收尾全部沿用宿主实现),模型经 `agentOptions` 注入。
6925
- * 前置:`exec.agent` 必须存在(前台委派要有发起方)。
6926
- *
6927
- * 🔴 **模型不可由调用方指定**(owner 令):**没有 `model` 参数**,一律读 CCC 配置
6928
- * `cheap-worker.models` / `cheap-worker.defaultModel`(单一真相源)。
6929
- *
6930
- * 递归防护:子 agent 的工具面 deny `cheap-worker` 本身(编排归主 agent,防无限嵌套)。
6931
- */
6932
- function renderText$4(value) {
6933
- return [{
6934
- type: "text",
6935
- text: typeof value === "string" ? value : JSON.stringify(value, null, 2)
6936
- }];
6937
- }
6938
- /**
6939
- * 🔴 **前台并行上限 = 10**(owner 2026-09-29 具名令:「这个版本顺手帮我把 handyman 并行度从 5 调整成 10」;
6940
- * 原值 5 出自 owner 2026-09-27 的具名令「最大 5;就当是支持自定模型的 subagent 用了,急需」)。
6941
- *
6942
- * 为什么是**硬编码**而不是又一个配置键:owner 两次都是**直接给数**(同 `REBUILD-TODO` 那次的裁决口径
6943
- * —— 设定项能不加就不加,见 S142 的「可砍设定项」)。若将来还要调,仍按具名令改这个常量。
6944
- *
6945
- * 为什么是 10 而不是更高:**前台委派会占住主 agent 的这一轮**(调用方在等结果),
6946
- * 并发越高越容易把宿主的并发面与用量推上去。
6947
- */
6948
- const FOREGROUND_MAX_PARALLEL = 10;
6949
- /** foreground 的 jobs 解析(label 可选 —— 前台 label 只是显示名,不命名任何文件) */
6950
- function parseForegroundJobs(raw) {
6951
- if (!Array.isArray(raw) || raw.length === 0) return null;
6952
- const jobs = [];
6953
- for (const item of raw) {
6954
- if (typeof item !== "object" || item === null) return null;
6955
- const rec = item;
6956
- if (typeof rec.task !== "string" || rec.task.trim() === "") return null;
6957
- jobs.push({
6958
- task: rec.task,
6959
- ...typeof rec.label === "string" && rec.label !== "" ? { label: rec.label } : {}
6960
- });
6961
- }
6962
- return jobs;
6963
- }
6964
- /**
6965
- * 选出一个可用的"启动子 agent"函数(**先新后旧**)。
6966
- *
6967
- * 🔴 **为什么需要这一层**(v1.59.3 适配,2026-10-17):
6968
- * 宿主 `0.2.1-rc.1` **移除了** `SubagentRuntime.start(name, request)`,改由
6969
- * `startActivation(spec)` 承担;而 `0.1.7-rc.*` / `0.2.0-rc.*` **只有** `start`。
6970
- * 本仓仍声明支持双档(`VERIFIED_HOST_BANDS`)⇒ **不能只留一边**。
6971
- *
6972
- * 形状差异(逐字取自两端 `.d.ts`):
6973
- * · 旧:`start('spawn', {label?, prompt, parent, signal, agentOptions, toolFilter})`
6974
- * · 新:`startActivation({provider:'spawn', label, request:{prompt, parent, agentOptions}, signal, delivery})`
6975
- * —— 注意 `label` 在新 spec 里是**必填**(`readonly label: string`),故这里补默认值。
6976
- *
6977
- * @returns 一个统一签名的启动器;两者都不存在 ⇒ `undefined`(由调用方报**可诊断**的错)
6978
- */
6979
- function resolveSubagentStarter(subagents) {
6980
- if (typeof subagents.startActivation === "function") {
6981
- const fn = subagents.startActivation;
6982
- return (req) => fn.call(subagents, {
6983
- provider: "spawn",
6984
- label: req.label,
6985
- request: {
6986
- prompt: req.prompt,
6987
- parent: req.parent,
6988
- agentOptions: req.agentOptions,
6989
- ...req.cwd === void 0 ? {} : { cwd: req.cwd }
6990
- },
6991
- signal: req.signal,
6992
- delivery: "caller"
6993
- });
6994
- }
6995
- if (typeof subagents.start === "function") {
6996
- const fn = subagents.start;
6997
- return (req) => fn("spawn", {
6998
- label: req.label,
6999
- prompt: req.prompt,
7000
- parent: req.parent,
7001
- signal: req.signal,
7002
- agentOptions: req.agentOptions,
7003
- toolFilter: { deny: ["cheap-worker"] },
7004
- ...req.cwd === void 0 ? {} : { cwd: req.cwd }
7005
- });
7006
- }
7007
- }
7008
- /** 拼接 SubagentResult.output(ContentBlock[])中的文本块 */
7009
- function subagentOutputText(output) {
7010
- if (!Array.isArray(output)) return "";
7011
- return output.filter((b) => typeof b === "object" && b !== null).filter((b) => b.type === "text" && typeof b.text === "string").map((b) => b.text).join("");
7012
- }
7013
- /**
7014
- * 任务首行 → 子会话 label(截断)。
7015
- *
7016
- * 🔴 为什么必须有一个:新宿主 `SubagentActivationSpec.label` 是**必填**(`readonly label: string`),
7017
- * 而我们对外把 `label` 当可选参数 ⇒ 缺省时必须自己造一个,否则 spec 不合法。
7018
- * 取任务首行而不是空串:子会话在列表里要能被人认出来(空串等于没有标识)。
7019
- */
7020
- function firstLineLabel(task) {
7021
- const line = task.split(/\r?\n/)[0]?.trim() ?? "";
7022
- const clipped = line.length > 60 ? `${line.slice(0, 60)}…` : line;
7023
- return clipped === "" ? "task" : clipped;
7024
- }
7025
- /**
7026
- * providerPreflight — 在**创建任何 worker 之前**判定「本机有没有该 provider 的 adapter」。
7027
- *
7028
- * 返回**可执行**的错误文本;`null` = 可用,**或无法取证**(服务缺失 / 形状不符 / 读取抛错
7029
- * ⇒ 一律**不阻断**,保持旧行为 —— 增强不得变成新的失败源)。
7030
- *
7031
- * 为什么必须放在"创建之前":宿主对未知 provider 抛 `no adapter registered for provider "…"`
7032
- * (`dsh-llm`,code `NO_ADAPTER`)。若照常创建:只拿回 `stopReason:"error"` + **空
7033
- * `diagnostic`**(实测)⇒ 调用方(LLM)无法自我修正配置。
7034
- */
7035
- function providerPreflight(ctx, model) {
7036
- const llm = hostLlm(ctx);
7037
- if (typeof llm?.listProviders !== "function") return null;
7038
- let registered;
7039
- try {
7040
- const raw = llm.listProviders();
7041
- if (!Array.isArray(raw)) return null;
7042
- registered = raw.filter((r) => typeof r === "object" && r !== null && typeof r.id === "string");
7043
- } catch {
7044
- return null;
7045
- }
7046
- let declared = [];
7047
- try {
7048
- const raw = llm.listConfigurableProviders?.();
7049
- if (Array.isArray(raw)) declared = raw.filter((d) => typeof d === "object" && d !== null && typeof d.provider === "string");
7050
- } catch {}
7051
- return providerAvailabilityError([model], {
7052
- registered,
7053
- declared,
7054
- configPath: ".opencode/serenity.json"
7055
- });
7056
- }
7057
- /**
7058
- * 单次前台串行委派。
7059
- *
7060
- * - 走宿主**委派正门** `ctx.subagents.start('spawn', …)`——深度上限、子 agent 所有权、
7061
- * `subagent/start|end` 生命周期事件、`dispose()` 收尾全部沿用宿主实现(不重写 agent 创建);
7062
- * - 模型经 `agentOptions` 注入(spawn 后端能力位 `agentOptions: true`),因此**不依赖**
7063
- * 宿主未放开的 `subagent-model-selection` 设置;
7064
- * - 不循环、不写文件、不做完成码校验——"一次调用一次结果"。
7065
- *
7066
- * 前置条件:`opts.parent` 必须是发起 agent(由调用方 `execute` 在解析 CCC 之前校验;
7067
- * 本函数不再重复检查——单一真相源)。
7068
- */
7069
- async function runForegroundJob(ctx, opts) {
7070
- const { task, label, model, models, parent, signal } = opts;
7071
- requireWhitelistedModel(model, models);
7072
- const subagents = hostSubagents(ctx);
7073
- const starter = subagents === void 0 ? void 0 : resolveSubagentStarter(subagents);
7074
- if (starter === void 0) throw new Error("cheap-worker: host subagents service unavailable — neither ctx.subagents.startActivation (0.2.1-rc.1+) nor ctx.subagents.start (0.1.7-rc.* / 0.2.0-rc.*) yielded a starter function. Check `dashboard health` (host-contract section, service \"subagents\").");
7075
- const preflight = providerPreflight(ctx, model);
7076
- if (preflight !== null) return {
7077
- mode: "foreground",
7078
- done: false,
7079
- model,
7080
- stopReason: "error",
7081
- output: "",
7082
- diagnostic: preflight
7083
- };
7084
- const { provider, model: modelName } = splitModel(model);
7085
- const run = await starter({
7086
- label: label ?? firstLineLabel(task),
7087
- prompt: [{
7088
- type: "text",
7089
- text: task
7090
- }],
7091
- parent,
7092
- signal: signal ?? new AbortController().signal,
7093
- agentOptions: {
7094
- ...provider === void 0 ? {} : { provider },
7095
- model: modelName
7096
- }
7097
- });
7098
- try {
7099
- const result = run.result === void 0 ? {} : await run.result;
7100
- const stopReason = typeof result.stopReason === "string" ? result.stopReason : "error";
7101
- return {
7102
- mode: "foreground",
7103
- done: stopReason === "completed",
7104
- model,
7105
- stopReason,
7106
- output: subagentOutputText(result.output),
7107
- ...typeof (run.childId ?? run.id) === "string" ? { childId: run.childId ?? run.id } : {},
7108
- ...typeof result.diagnostic === "string" && result.diagnostic !== "" ? { diagnostic: result.diagnostic } : {}
7109
- };
7110
- } finally {
7111
- if (run.dispose) await run.dispose().catch(() => {});
7112
- }
7113
- }
7114
- /** 创建 cheap-worker 工具(闭包捕获插件 ctx → 可访问 ctx.subagents) */
7115
- function createCheapWorkerTool(ctx) {
7116
- return defineTool({
7117
- name: "cheap-worker",
7118
- description: "The cheap-worker (杂工): delegate work to a worker agent on the CCC-configured model, and return its final text. One serial child per task; `jobs` fans out in parallel.\nUsage: cheap-worker(task, [label]) for a single delegation; cheap-worker(jobs=[{task,label?},...]) for parallel fan-out (cap 10, results keep your order).\nThe child does NOT share this conversation — the task must be self-contained.\nNo loop, no completion-code validation, no progress file, no unattended/background run.\nModel: NOT selectable per call — it is read from .opencode/serenity.json \"cheap-worker.models\" (missing config = error); \"cheap-worker.defaultModel\" names the one used, falling back to models[0].\nProvider check: the whitelist lives in the CCC (it travels with the repo) while provider adapters are registered per machine by the host — so before spawning, the provider of the resolved model is verified against the adapters present on THIS machine. If it is missing you get the available providers plus the exact fix in `diagnostic`, and no child is created.\nRecursion: a worker's tool set excludes cheap-worker itself (orchestration belongs to the main agent).\nGuide: cheap-worker(guide=true) prints the scale-up usage guide.",
7119
- parameters: {
7120
- task: {
7121
- type: "string",
7122
- description: "The task goal to complete (must be self-contained — the child does not share this conversation)"
7123
- },
7124
- label: {
7125
- type: "string",
7126
- description: "Optional child display name"
7127
- },
7128
- jobs: {
7129
- type: "array",
7130
- description: "Multi-job orchestration (workflow capability): [{task, label?}, ...] — runs jobs in parallel, cap 10 (fixed). Results keep the order you passed them in.",
7131
- items: {
7132
- type: "object",
7133
- properties: {
7134
- task: { type: "string" },
7135
- label: { type: "string" }
7136
- },
7137
- additionalProperties: false
7138
- }
7139
- },
7140
- guide: {
7141
- type: "boolean",
7142
- description: "Print the scale-up usage guide (creates no agent; includes eap design requirements / whitelist rules / jobs parallel strategy / prompt conventions)"
7143
- }
7144
- },
7145
- output: {
7146
- schema: { type: "json" },
7147
- render: (_args, value) => renderText$4(value)
7148
- },
7149
- async execute(args, exec) {
7150
- if (args.guide) return { guide: CHEAP_WORKER_GUIDE };
7151
- if (!exec.agent) throw new Error("cheap-worker: requires a calling agent (exec.agent was undefined)");
7152
- const root = cccRootForExec(exec);
7153
- if (!root) throw new Error(NO_CCC_FROM_AGENT_CWD);
7154
- const hc = readCheapWorkerConfig(root, DEFAULT_SERENITY_CONFIG_PATHS);
7155
- if (hc === null) throw new Error("cheap-worker requires a model whitelist: configure .opencode/serenity.json \"cheap-worker.models\" (e.g. {\"cheap-worker\": {\"models\": [\"minimax-cn-coding-plan/MiniMax-M3\"], \"defaultModel\": \"minimax-cn-coding-plan/MiniMax-M3\"}})");
7156
- if (args.jobs !== void 0) {
7157
- const jobs = parseForegroundJobs(args.jobs);
7158
- if (jobs === null) throw new Error("cheap-worker: jobs must be [{task, label?}, ...] (every job requires a non-empty task)");
7159
- if (jobs.length > FOREGROUND_MAX_PARALLEL) throw new Error(`cheap-worker: ${jobs.length} jobs exceed the parallel cap ${FOREGROUND_MAX_PARALLEL} (split into batches)`);
7160
- const results = await Promise.all(jobs.map((job) => runForegroundJob(ctx, {
7161
- task: job.task,
7162
- ...job.label === void 0 ? {} : { label: job.label },
7163
- model: hc.defaultModel,
7164
- models: hc.models,
7165
- parent: exec.agent,
7166
- signal: exec.signal
7167
- })));
7168
- const done = results.every((r) => r.done);
7169
- return {
7170
- mode: "foreground",
7171
- done,
7172
- jobs: results,
7173
- usage: {
7174
- how: `foreground parallel mode starts ${results.length} child agents at once through the host delegation service (ctx.subagents.startActivation on 0.2.1-rc.*+, falling back to ctx.subagents.start "spawn" on older hosts), awaits all of them, and returns each child's final text. No loop, no completion-code validation, no progress file. Cap = ${FOREGROUND_MAX_PARALLEL}.`,
7175
- model: "NOT selectable per call — resolved from the CCC config cheap-worker.models (cheap-worker.defaultModel, else models[0])",
7176
- next: done ? "All children completed; use each job's output directly (results are in the same order as the jobs you passed)" : "Some children did not complete — inspect each job's diagnostic/output (results keep the order you passed)"
7177
- }
7178
- };
7179
- }
7180
- if (typeof args.task !== "string" || args.task.trim() === "") throw new Error("cheap-worker: task is required (and must be self-contained — the child does not share this conversation)");
7181
- const res = await runForegroundJob(ctx, {
7182
- task: args.task,
7183
- ...typeof args.label === "string" && args.label !== "" ? { label: args.label } : {},
7184
- model: hc.defaultModel,
7185
- models: hc.models,
7186
- parent: exec.agent,
7187
- signal: exec.signal
7188
- });
7189
- return {
7190
- ...res,
7191
- usage: {
7192
- how: "foreground mode starts ONE serial child agent through the host delegation service (ctx.subagents.startActivation on 0.2.1-rc.*+, falling back to ctx.subagents.start \"spawn\" on older hosts) with the CCC-configured model; it awaits the run and returns the child's final text. No loop, no completion-code validation, no progress file.",
7193
- model: "NOT selectable per call — resolved from the CCC config cheap-worker.models (cheap-worker.defaultModel, else models[0])",
7194
- next: res.done ? "Child completed; use its output directly" : `Child did not complete (stopReason=${res.stopReason}); inspect diagnostic/output and decide whether to retry`
7195
- }
7196
- };
7197
- }
7198
- });
7199
- }
7200
- //#endregion
7201
6891
  //#region src/wake/registry.ts
7202
6892
  /**
7203
6893
  * wake/registry.ts — 认知轨迹唤醒注册表(D58,S142 2026-09-13)
@@ -10850,7 +10540,7 @@ function renderCroSampleSnapshot() {
10850
10540
  /**
10851
10541
  * CRO 编写指南正文(ACC 内置手册;由工具的 guide 动作输出)。
10852
10542
  *
10853
- * 结构照既有 guide 惯例(`MSM_GUIDE` / `cheap-worker(guide=true)`):
10543
+ * 结构照既有 guide 惯例(`MSM_GUIDE` / `container_admin config guide`):
10854
10544
  * 用途 → 位置 → 我给什么 → 你给我什么 → 骨架 → 常见模式 → 坑 → **自测**。
10855
10545
  */
10856
10546
  const CRO_GUIDE = `CRO(Continuous Re-Occurrence · 持续再发生)编写指南
@@ -11858,7 +11548,7 @@ function renderText$2(value) {
11858
11548
  }
11859
11549
  const localstoreTool = defineTool({
11860
11550
  name: "localstore",
11861
- description: "ACC standard local credential/config storage: one tool manages two namespaces — credential (credentials) and config (local preferences). Stored in localstore.json at the CCC root (JSON format, directly readable by MSMs). Git policy: .opencode/serenity.json localstore.gitTrack (allow commits / deny commits, default deny; .dsh fallback) — when deny, writes ensure .gitignore contains this file (physical guarantee), container_git commit checks and refuses. Subcommands: list (list keys, credentials never return values) / get <name> (read value) / set <name> <value> (write) / unset <name> (delete) / show <name> (metadata, credentials never print values) / doc (output the storage spec — path/format/key conventions/git policy; agents may operate the file directly with read/write per the spec). Default scope=credential; config requires --scope config (path is section.key, e.g. cheap-worker.models).",
11551
+ description: "ACC standard local credential/config storage: one tool manages two namespaces — credential (credentials) and config (local preferences). Stored in localstore.json at the CCC root (JSON format, directly readable by MSMs). Git policy: .opencode/serenity.json localstore.gitTrack (allow commits / deny commits, default deny; .dsh fallback) — when deny, writes ensure .gitignore contains this file (physical guarantee), container_git commit checks and refuses. Subcommands: list (list keys, credentials never return values) / get <name> (read value) / set <name> <value> (write) / unset <name> (delete) / show <name> (metadata, credentials never print values) / doc (output the storage spec — path/format/key conventions/git policy; agents may operate the file directly with read/write per the spec). Default scope=credential; config requires --scope config (path is section.key, e.g. my-feature.someKey).",
11862
11552
  parameters: {
11863
11553
  action: {
11864
11554
  type: "string",
@@ -11920,7 +11610,7 @@ becomes a 轨迹约束; delete it and it goes back to being an ordinary trajecto
11920
11610
 
11921
11611
  ── ${TRAJECTORY_CONSTRAINT_FILENAME} schema(限制面部分)──
11922
11612
  {
11923
- "model": "provider/model", // optional; **不写 = 用会话当前模型**(不回退 cheap-worker;每轮生效)
11613
+ "model": "provider/model", // optional; **不写 = 用会话当前模型**(不会回退到任何别处;每轮生效)
11924
11614
  "tools": ["read","grep","msm",...], // optional; **不写 = 不收窄**。显式 [] = 全隐藏(除 skill)
11925
11615
  "msms": ["msm-a","msm-b"], // optional; **不写 = 不收窄**。register/deregister 恒拒
11926
11616
  "writes": ["AGENT_SESSIONS/<我的目录>/"], // optional; **不写 = 不收窄**。显式 [] = 一个写都落不下
@@ -11980,7 +11670,7 @@ becomes a 轨迹约束; delete it and it goes back to being an ordinary trajecto
11980
11670
  Skill loading is always available to 轨迹约束 sessions (skills are not whitelisted — they are read-only knowledge).
11981
11671
 
11982
11672
  写完之后怎么验 → container_admin config docs trajectory-self 的「写完之后怎么验」段(同一套判据,不复制)。`;
11983
- /** 校验当前 CCC 的 轨迹约束面:msms 均已注册 / model ∈ cheap-worker.models / 提示词非空 */
11673
+ /** 校验当前 CCC 的 轨迹约束面:msms 均已注册 / 提示词非空 */
11984
11674
  function validateTrajectoryConstraint(root) {
11985
11675
  const profiles = listTrajectoryConstraints(root);
11986
11676
  const issues = [];
@@ -11991,8 +11681,6 @@ function validateTrajectoryConstraint(root) {
11991
11681
  note: `no 轨迹约束 trajectories in this CCC (no trajectory has ${TRAJECTORY_CONSTRAINT_FILENAME} — zero impact)`
11992
11682
  };
11993
11683
  const registered = new Set(loadMsmEntries(root).map((e) => e.name));
11994
- const hc = readCheapWorkerConfig(root);
11995
- const allowedModels = hc ? new Set(hc.models) : null;
11996
11684
  for (const p of profiles) {
11997
11685
  if (!(hasTrajectoryPrompt(root, p.dirName) || (() => {
11998
11686
  try {
@@ -12008,7 +11696,6 @@ function validateTrajectoryConstraint(root) {
12008
11696
  } catch (err) {
12009
11697
  issues.push(`trajectory "${p.code}": writes "${w}" is outside the CCC root (${String(err?.message ?? err)}) — a write prefix outside the container can never match; use a path relative to the CCC root`);
12010
11698
  }
12011
- if (p.model && allowedModels && !allowedModels.has(p.model)) issues.push(`trajectory "${p.code}": model "${p.model}" not in cheap-worker.models (${[...allowedModels].join(", ") || "(none)"})`);
12012
11699
  }
12013
11700
  return {
12014
11701
  ok: issues.length === 0,
@@ -12169,7 +11856,7 @@ const TRAJECTORY_SELF_GUIDE = [
12169
11856
 
12170
11857
  | 字段 | 不写它 | 生效时机 |
12171
11858
  |---|---|---|
12172
- | \`model\` | 用会话当前的模型(**不会**回退到 cheap-worker) | **每轮**(改文件下一轮即生效) |
11859
+ | \`model\` | 用会话当前的模型(**不会**回退到任何别处) | **每轮**(改文件下一轮即生效) |
12173
11860
  | \`tools\` | **不收窄**工具面 | 每轮 |
12174
11861
  | \`msms\` | **不收窄** MSM 面 | 每轮 |
12175
11862
  | \`writes\` | **不收窄**写路径(写权限 = 路径守卫那几条) | 每轮 |
@@ -14084,7 +13771,7 @@ function registerKeeper(ctx, opts = {}) {
14084
13771
  *
14085
13772
  * `model` 的**唯一消费点**曾是 `createTrajectoryAgent` 建 agent 时,而它的**唯一调用方**是
14086
13773
  * IM 入站路由 ⇒ 对**已经存在的会话**(web 会话、`send-now` 冷启的载体……)**完全不生效**。
14087
- * 而 `container_admin config list` 把它印成 `'(cheap-worker default)'`,看上去像个统一设定。
13774
+ * 而 `container_admin config list` 把它印成一个统一默认值,看上去像"已经生效了"。
14088
13775
  * ⇒ **同一个字段在 A 入口生效、在 B 入口不生效** —— 正是 owner 要禁的形态。
14089
13776
  *
14090
13777
  * ## 修法:接宿主**自带**的原语,不复刻语义
@@ -14107,8 +13794,10 @@ function registerKeeper(ctx, opts = {}) {
14107
13794
  *
14108
13795
  * ## 三条硬边界(少一条就会重演 S196 的坑)
14109
13796
  *
14110
- * 1. **未写 `model` ⇒ 不装这条缝**(`undefined` 原样返回)。⛔ **绝不回退 `cheap-worker.defaultModel`**
14111
- * —— 那个回退把"我想声明自述"变成"我被降级到杂工模型",而用户完全不会预期到。
13797
+ * 1. **未写 `model` ⇒ 不装这条缝**(`undefined` 原样返回)。⛔ **绝不回退到某个全局默认模型**
13798
+ * —— 那种回退把"我想声明自述"变成"我被悄悄换了模型",而用户完全不会预期到。
13799
+ * (历史形态:曾回退 `cheap-worker.defaultModel`;该配置段已随工具于 2026-10-28 删除,
13800
+ * 但判据不变:**没写 = 不动**。)
14112
13801
  * 2. **切换会留下宿主的 `[model changed: …]` 提示**。这是**特性不是噪声**:
14113
13802
  * 否则模型不知道自己换了,它会照旧解释上方那些由**另一个模型**生成的回合。
14114
13803
  * 3. **模型名非法 ⇒ 不切 + 响亮告警**,绝不静默停在旧模型上("改了没生效"是最难查的一类)。
@@ -14301,7 +13990,8 @@ function accIdentityText(root, configPaths = DEFAULT_SERENITY_CONFIG_PATHS, entr
14301
13990
  }
14302
13991
  /**
14303
13992
  * ACC 注入消息(S134 去重):**只含简短身份锚点**([ACC] 已激活 + CCC 根 + 约束 + Phase 2)。
14304
- * ⚠️ 原文案含「+ cheap-worker 模型」,该注入已于 2026-09-16 删除(§0e-G)⇒ 此处同步订正(散文级残留)。
13993
+ * ⚠️ 原文案含「+ cheap-worker 模型」;该注入已于 2026-09-16 删除(§0e-G),
13994
+ * 且 cheap-worker 本身已于 2026-10-28 整条下线 ⇒ 此处订正(散文级残留已无对应实现)。
14305
13995
  * 完整身份(ACC 5 块 + CCE + Constraints + EAP + SKILL 全文 + Session 块)由**系统提示词层**
14306
13996
  * (systemPrompt.section,每轮 prompt 装配自动注入,含 subagent)承担——对话消息流/压缩重注入
14307
13997
  * 不再重复注入同一内容(token 双倍浪费,见 S134 注入方案梳理)。
@@ -14383,7 +14073,9 @@ function agentScope(agent) {
14383
14073
  * 只有"conversation 根会话"才自动恢复最近激活的宁静号会话——
14384
14074
  * - subagent:session header `origin === 'subagent'`(DSH 路由语义,agent-lookup.ts)
14385
14075
  * - 派生会话:`parentSession` 存在(任何子会话)
14386
- * - cheap-worker 杂工:sessionId 固定 `cheap-worker-` 前缀(tools/cheap-worker.ts 生成)
14076
+ * - 历史 `cheap-worker-` 前缀会话(**兼容保留**:生成者 `tools/cheap-worker.ts` 已于
14077
+ * 2026-10-28 整条下线 ⇒ **不会再产生新会话**,但**旧持久化会话仍可能被 resume**,
14078
+ * 那时它依旧不该把主会话激活注入子上下文)
14387
14079
  * 三者都不恢复(避免把主会话激活注入子上下文,违背 v1.16.2 scope 隔离)。
14388
14080
  */
14389
14081
  function shouldAutoRestore(agent, root) {
@@ -14616,7 +14308,7 @@ function loadOpencodeSkill(skillDir) {
14616
14308
  /**
14617
14309
  * surface/status.ts — 状态与安全模式操作(纯逻辑,零 DSH 依赖,可独立单测)
14618
14310
  *
14619
- * WebUI 停靠栏的数据源:ACC 版本 / CCC 根 / safe-mode 状态 / 黑名单 / keeper 阈值 / cheap-worker 模型。
14311
+ * WebUI 停靠栏的数据源:ACC 版本 / CCC 根 / safe-mode 状态 / 黑名单 / keeper 阈值。
14620
14312
  * setSafeMode 直接读写 .serenity-safe-on 标记(守卫实时读取,写即生效)。
14621
14313
  */
14622
14314
  /** 宿主包名 —— 从运行入口反推包根时的**身份核对**用(见 {@link dshVersionFromEntry}) */
@@ -14701,7 +14393,6 @@ function getStatus(cwd, configPaths = DEFAULT_SERENITY_CONFIG_PATHS) {
14701
14393
  safeModeOn: false,
14702
14394
  blacklist: [],
14703
14395
  threshold: null,
14704
- cheapWorkerModel: null,
14705
14396
  trajectories: [],
14706
14397
  skills: [],
14707
14398
  restrict
@@ -14713,7 +14404,6 @@ function getStatus(cwd, configPaths = DEFAULT_SERENITY_CONFIG_PATHS) {
14713
14404
  safeModeOn: isSafeModeOn(root),
14714
14405
  blacklist: readBlacklist(root, configPaths),
14715
14406
  threshold: cfg.sessionKeeper?.threshold ?? null,
14716
- cheapWorkerModel: readCheapWorkerConfig(root, configPaths)?.defaultModel ?? null,
14717
14407
  trajectories: listActiveTrajectories(root),
14718
14408
  skills: listSkillSummaries(root),
14719
14409
  restrict
@@ -15102,11 +14792,11 @@ function registerStatusApi(ctx, opts = {}) {
15102
14792
  sendJson$2(res, 400, { error: chk.error });
15103
14793
  return;
15104
14794
  }
15105
- const { readWeixinSettings } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14795
+ const { readWeixinSettings } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15106
14796
  const { weixinBridgeStatus } = await Promise.resolve().then(() => bridge_exports);
15107
14797
  const settings = readWeixinSettings(chk.root);
15108
14798
  const bridge = weixinBridgeStatus().find((b) => b.ccc === chk.root);
15109
- const { imCredentialBound } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14799
+ const { imCredentialBound } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15110
14800
  const { normalizeAccountChannel } = await import("./accounts-BHQbakUh.js").then((n) => n.t);
15111
14801
  const accounts = (settings.accounts ?? []).map((a) => {
15112
14802
  const channel = normalizeAccountChannel(a.channel);
@@ -15143,7 +14833,7 @@ function registerStatusApi(ctx, opts = {}) {
15143
14833
  const { fetchQRCode } = await import("./ilink-CsZ-f64q.js").then((n) => n.a);
15144
14834
  const { randomUUID } = await import("node:crypto");
15145
14835
  for (const [key, v] of weixinLogins) if (Date.now() - v.startedAt > WEIXIN_LOGIN_TTL_MS) weixinLogins.delete(key);
15146
- const { readWeixinSettings } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14836
+ const { readWeixinSettings } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15147
14837
  const qr = await fetchQRCode({ botType: readWeixinSettings(root).botType ?? void 0 });
15148
14838
  const loginKey = randomUUID();
15149
14839
  weixinLogins.set(loginKey, {
@@ -15164,7 +14854,7 @@ function registerStatusApi(ctx, opts = {}) {
15164
14854
  sendJson$2(res, 400, { error: "missing accountId" });
15165
14855
  return;
15166
14856
  }
15167
- const { removeWeixinAccount } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14857
+ const { removeWeixinAccount } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15168
14858
  const { syncCccBridge } = await Promise.resolve().then(() => bridge_exports);
15169
14859
  removeWeixinAccount(root, body.accountId);
15170
14860
  syncCccBridge(ctx, root);
@@ -15190,8 +14880,8 @@ function registerStatusApi(ctx, opts = {}) {
15190
14880
  trajectory: code
15191
14881
  });
15192
14882
  }
15193
- const { saveWeixinRoutes } = await import("./route-DxIKWeN9.js").then((n) => n.l);
15194
- const { findDirNameByCode } = await import("./profile-zxakCNXy.js").then((n) => n.a);
14883
+ const { saveWeixinRoutes } = await import("./route-CmEoKp9w.js").then((n) => n.l);
14884
+ const { findDirNameByCode } = await import("./profile-Dpg3wYO5.js").then((n) => n.a);
15195
14885
  for (const r of routes) if (findDirNameByCode(root, r.trajectory) === null) {
15196
14886
  sendJson$2(res, 400, { error: `unknown trajectory: ${r.trajectory} (no such trajectory code in ${root})` });
15197
14887
  return;
@@ -15202,7 +14892,7 @@ function registerStatusApi(ctx, opts = {}) {
15202
14892
  }
15203
14893
  if (body.action === "set-enabled") {
15204
14894
  const enabled = body.enabled === true;
15205
- const { readWeixinSettings, setWeixinEnabled } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14895
+ const { readWeixinSettings, setWeixinEnabled } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15206
14896
  const { syncCccBridge } = await Promise.resolve().then(() => bridge_exports);
15207
14897
  const settings = readWeixinSettings(root);
15208
14898
  if (enabled && (settings.accounts ?? []).length === 0) {
@@ -15225,7 +14915,7 @@ function registerStatusApi(ctx, opts = {}) {
15225
14915
  sendJson$2(res, 400, { error: "appId 与 appSecret 都必须填(只填一个等于没绑)" });
15226
14916
  return;
15227
14917
  }
15228
- const { readWeixinSettings, upsertWeixinAccount, writeFeishuCredential, nextFeishuAccountId } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14918
+ const { readWeixinSettings, upsertWeixinAccount, writeFeishuCredential, nextFeishuAccountId } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15229
14919
  const { syncCccBridge } = await Promise.resolve().then(() => bridge_exports);
15230
14920
  const before = readWeixinSettings(root);
15231
14921
  const accountId = (body.accountId ?? "").trim() !== "" ? body.accountId.trim() : nextFeishuAccountId(before);
@@ -15275,7 +14965,7 @@ function registerStatusApi(ctx, opts = {}) {
15275
14965
  return;
15276
14966
  }
15277
14967
  const { pollQRStatus } = await import("./ilink-CsZ-f64q.js").then((n) => n.a);
15278
- const { readWeixinSettings } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14968
+ const { readWeixinSettings } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15279
14969
  const settings = readWeixinSettings(login.root);
15280
14970
  const status = await pollQRStatus({
15281
14971
  baseUrl: void 0,
@@ -15290,7 +14980,7 @@ function registerStatusApi(ctx, opts = {}) {
15290
14980
  });
15291
14981
  return;
15292
14982
  }
15293
- const { upsertWeixinAccount, writeWeixinCredential, nextWeixinAccountId } = await import("./route-DxIKWeN9.js").then((n) => n.l);
14983
+ const { upsertWeixinAccount, writeWeixinCredential, nextWeixinAccountId } = await import("./route-CmEoKp9w.js").then((n) => n.l);
15294
14984
  const { syncCccBridge } = await Promise.resolve().then(() => bridge_exports);
15295
14985
  const accountId = nextWeixinAccountId(settings);
15296
14986
  upsertWeixinAccount(login.root, {
@@ -15732,7 +15422,7 @@ const HOST_SERVICES = [
15732
15422
  name: "get",
15733
15423
  kind: "function"
15734
15424
  }],
15735
- impact: "轨迹约束/cheap-worker 无法创建或复用 agent",
15425
+ impact: "轨迹约束无法创建或复用 agent",
15736
15426
  required: true
15737
15427
  },
15738
15428
  {
@@ -15814,7 +15504,7 @@ const HOST_SERVICES = [
15814
15504
  name: "agentLoop",
15815
15505
  access: "injected",
15816
15506
  members: [],
15817
- impact: "cheap-worker worker agent 无法装配 preset",
15507
+ impact: "子 agent 无法装配 preset(轨迹载体创建会退到全局工具层)",
15818
15508
  required: false
15819
15509
  },
15820
15510
  {
@@ -15830,7 +15520,7 @@ const HOST_SERVICES = [
15830
15520
  kind: "function",
15831
15521
  anyOf: "spawn-starter"
15832
15522
  }],
15833
- impact: "cheap-worker 委派不可用(前台委派的正门,响亮报错)",
15523
+ impact: "子 agent 委派不可用(cheap-worker 已下线 ⇒ 现无消费者,仅备将来)",
15834
15524
  required: false
15835
15525
  },
15836
15526
  {
@@ -20249,7 +19939,7 @@ const MEDIA_MAX_BYTES = 20971520;
20249
19939
  */
20250
19940
  async function resolveCccRootByAlias(ctx, alias) {
20251
19941
  try {
20252
- const { listCccs } = await import("./ccc-roots-WfktvbN8.js").then((n) => n.a);
19942
+ const { listCccs } = await import("./ccc-roots-BPicjCsj.js").then((n) => n.a);
20253
19943
  const entries = await listCccs(ctx);
20254
19944
  const byName = entries.find((e) => e.name === alias);
20255
19945
  if (byName) return byName.root;
@@ -20317,7 +20007,7 @@ async function resolveInboundTarget(ctx, input) {
20317
20007
  });
20318
20008
  return null;
20319
20009
  }
20320
- const { findDirNameByCode } = await import("./profile-zxakCNXy.js").then((n) => n.a);
20010
+ const { findDirNameByCode } = await import("./profile-Dpg3wYO5.js").then((n) => n.a);
20321
20011
  if (findDirNameByCode(root, target.role) === null) {
20322
20012
  const detail = `目标 CCC "${target.ccc}" 内没有编码为 "${target.role}" 的认知轨迹`;
20323
20013
  console.error(`[serenity-hooks] ✗ human-channel: ${detail}(account=${input.account} user=${input.user})—— 该消息**未投递**,请改订阅表里的目标编码`);
@@ -21279,7 +20969,7 @@ function syncHumanChannel(ctx) {
21279
20969
  (async () => {
21280
20970
  try {
21281
20971
  stopMachineLoops();
21282
- const { listCccs } = await import("./ccc-roots-WfktvbN8.js").then((n) => n.a);
20972
+ const { listCccs } = await import("./ccc-roots-BPicjCsj.js").then((n) => n.a);
21283
20973
  for (const entry of await listCccs(ctx)) syncCccBridge(ctx, entry.root);
21284
20974
  } catch {}
21285
20975
  })();
@@ -21572,7 +21262,7 @@ function matchCcc(input, candidates) {
21572
21262
  }
21573
21263
  /** 组装候选列表(`ccc-roots.listCccs` 投影 + `.serenity` 名;动态 import 保持本模块静态依赖轻量) */
21574
21264
  async function collectCandidates(ctx) {
21575
- const { listCccs } = await import("./ccc-roots-WfktvbN8.js").then((n) => n.a);
21265
+ const { listCccs } = await import("./ccc-roots-BPicjCsj.js").then((n) => n.a);
21576
21266
  const entries = await listCccs(ctx, { defaultRoot: process.cwd() });
21577
21267
  const seen = /* @__PURE__ */ new Set();
21578
21268
  const out = [];
@@ -24713,7 +24403,6 @@ function apply(ctx, config) {
24713
24403
  ctx.tools.register(praxisTool);
24714
24404
  ctx.tools.register(createOntologyTool());
24715
24405
  ctx.tools.register(createSkillCreatorTool());
24716
- ctx.tools.register(createCheapWorkerTool(ctx));
24717
24406
  ctx.tools.register(localstoreTool);
24718
24407
  ctx.tools.register(createContainerAdminTool(ctx));
24719
24408
  ctx.tools.register(createImBridgeTool());