@bolloon/bolloon-agent 0.6.1 → 0.6.3

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 (78) hide show
  1. package/README.md +128 -111
  2. package/dist/agents/gateway-group.js +231 -6
  3. package/dist/agents/group-autopilot.js +256 -0
  4. package/dist/agents/pi-sdk-tools.js +302 -0
  5. package/dist/agents/pi-sdk.js +89 -140
  6. package/dist/agents/task-group.js +21 -4
  7. package/dist/cli/log-gate.js +68 -4
  8. package/dist/cli/mention-data.js +1 -1
  9. package/dist/cli/model-selector.js +84 -104
  10. package/dist/cli/setup-wizard.js +2 -10
  11. package/dist/cli/tui-select.js +99 -10
  12. package/dist/cli-entry.js +1 -9
  13. package/dist/electron-build/agents/gateway-group.js +814 -0
  14. package/dist/electron-build/agents/gateway-group.js.map +1 -0
  15. package/dist/electron-build/agents/group-autopilot.js +302 -0
  16. package/dist/electron-build/agents/group-autopilot.js.map +1 -0
  17. package/dist/electron-build/agents/pi-sdk-tools.js +302 -0
  18. package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
  19. package/dist/electron-build/agents/pi-sdk.js +88 -139
  20. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  21. package/dist/electron-build/agents/task-group.js +601 -0
  22. package/dist/electron-build/agents/task-group.js.map +1 -0
  23. package/dist/electron-build/agents/task-public-text.js +97 -0
  24. package/dist/electron-build/agents/task-public-text.js.map +1 -0
  25. package/dist/electron-build/efficode/compress.js +86 -0
  26. package/dist/electron-build/efficode/compress.js.map +1 -0
  27. package/dist/electron-build/efficode/crc32.js +44 -0
  28. package/dist/electron-build/efficode/crc32.js.map +1 -0
  29. package/dist/electron-build/efficode/did.js +74 -0
  30. package/dist/electron-build/efficode/did.js.map +1 -0
  31. package/dist/electron-build/efficode/lz77.js +175 -0
  32. package/dist/electron-build/efficode/lz77.js.map +1 -0
  33. package/dist/electron-build/efficode/negotiate.js +233 -0
  34. package/dist/electron-build/efficode/negotiate.js.map +1 -0
  35. package/dist/electron-build/efficode/ops.js +96 -0
  36. package/dist/electron-build/efficode/ops.js.map +1 -0
  37. package/dist/electron-build/efficode/packet.js +279 -0
  38. package/dist/electron-build/efficode/packet.js.map +1 -0
  39. package/dist/electron-build/efficode/types.js +50 -0
  40. package/dist/electron-build/efficode/types.js.map +1 -0
  41. package/dist/electron-build/kernel/code-write-gate.js +55 -0
  42. package/dist/electron-build/kernel/code-write-gate.js.map +1 -0
  43. package/dist/electron-build/kernel/run-lifecycle.js +23 -0
  44. package/dist/electron-build/kernel/run-lifecycle.js.map +1 -1
  45. package/dist/electron-build/kernel/run-resume.js +62 -0
  46. package/dist/electron-build/kernel/run-resume.js.map +1 -0
  47. package/dist/electron-build/kernel/session-lifecycle.js +223 -0
  48. package/dist/electron-build/kernel/session-lifecycle.js.map +1 -0
  49. package/dist/electron-build/kernel/turn-selfcheck.js +65 -0
  50. package/dist/electron-build/kernel/turn-selfcheck.js.map +1 -0
  51. package/dist/electron-build/llm/config-store.js +2 -2
  52. package/dist/electron-build/llm/config-store.js.map +1 -1
  53. package/dist/electron-build/llm/model-selection.js +16 -2
  54. package/dist/electron-build/llm/model-selection.js.map +1 -1
  55. package/dist/electron-build/llm/pi-ai.js +2 -2
  56. package/dist/electron-build/llm/pi-ai.js.map +1 -1
  57. package/dist/electron-build/orbitdb/cid-database.js +98 -19
  58. package/dist/electron-build/orbitdb/cid-database.js.map +1 -1
  59. package/dist/electron-build/orbitdb/group-access.js +399 -0
  60. package/dist/electron-build/orbitdb/group-access.js.map +1 -0
  61. package/dist/index.js +143 -10
  62. package/dist/ios/bolloon-web.json +3 -3
  63. package/dist/ios/sw.js +1 -1
  64. package/dist/kernel/code-write-gate.js +47 -0
  65. package/dist/kernel/gate-scan.js +5 -1
  66. package/dist/kernel/plan-harness.js +3 -2
  67. package/dist/kernel/roster.js +6 -6
  68. package/dist/kernel/run-lifecycle.js +21 -0
  69. package/dist/kernel/run-resume.js +58 -0
  70. package/dist/kernel/session-lifecycle.js +210 -0
  71. package/dist/kernel/turn-selfcheck.js +60 -0
  72. package/dist/llm/config-store.js +2 -2
  73. package/dist/llm/model-selection.js +16 -2
  74. package/dist/llm/pi-ai.js +2 -2
  75. package/dist/orbitdb/cid-database.js +95 -19
  76. package/dist/web/bolloon-web.json +3 -3
  77. package/dist/web/sw.js +1 -1
  78. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-access.js","sourceRoot":"","sources":["../../../src/orbitdb/group-access.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import * as readline from 'readline';
28
28
  import { printBanner, termHeight, truncate, renderDialog, renderUserMessage, renderAgentMessage, renderMessageBox, renderToolCallListItem, termWidth, ROBOT_HEAD, BOLLOON_BANNER, BOLLOON_BANNER_SMALL, dispWidth } from './cli/loading-tui.js';
29
29
  import { startInk, stopInk, suspendInk, resumeInk, inkAppendLine as appendLine, inkSetStatus, inkSetThinking, inkSetTransient, bootPanelMaxLines } from './cli/ink-app.js';
30
30
  // 2026-09-26: 启动期日志闸门 (默认静默加载日志 + 写文件 + verbose 全量回流 + 信号行不吞)
31
- import { installStartupLogGate, isStartupVerbose, startupLogPath, VERBOSE_ENV, carriesHumanSignal, logStartupLine } from './cli/log-gate.js';
31
+ import { installStartupLogGate, isStartupVerbose, startupLogPath, VERBOSE_ENV, carriesHumanSignal, isInternalChatter, logStartupLine } from './cli/log-gate.js';
32
32
  // 2026-09-27: 回复流卫生 — 内部运行日志 (循环推进/运行登记/收尾计数…) 不进对话回复流, 改落日志文件
33
33
  import { isInternalRunLog, appendInternalRunLog } from './cli/reply-hygiene.js';
34
34
  // 2026-09-27: 启动**前言 / 就绪度报告**闸门 (默认不上屏 → 面板一行 + 显式查询命令; 失败折成面板提示)
@@ -49,7 +49,7 @@ export function parseGroupSub(input) {
49
49
  // 与 `/channel <序号>` 同一个习惯 ✓ (列表里就带序号)
50
50
  if (/^\d+$/.test(head))
51
51
  return { sub: 'use', arg: head };
52
- const known = ['list', 'new', 'join', 'leave', 'use', 'send', 'log', 'members', 'help'];
52
+ const known = ['list', 'new', 'join', 'leave', 'use', 'send', 'log', 'members', 'invite', 'kick', 'link', 'privacy', 'status', 'help'];
53
53
  return { sub: known.includes(sub) ? sub : 'help', arg: known.includes(sub) ? arg : rest };
54
54
  }
55
55
  export const CLI_KNOWN_COMMAND_HEADS = new Set([
@@ -153,6 +153,12 @@ const SHOW_CURSOR = '\x1b[?25h';
153
153
  * Ink 在跑 ⇒ **一律走它自己的消息流**; 没跑(boot 期)⇒ 才直写 ✓。
154
154
  */
155
155
  function writeOut(line) {
156
+ // 2026-10-02 (leo: 「cli 的 UI 需要有渲染过滤」): 内部诊断行**不进对话流** (仍一字不漏落日志文件;
157
+ // `BOLLOON_VERBOSE=1` 下闸门不装 ⇒ 照原样上屏)。判据与启动期门同一套: 按行首模块标签锚定。
158
+ if (isInternalChatter(String(line))) {
159
+ bootLogOnly(line);
160
+ return;
161
+ }
156
162
  // 2026-10-01 (用户: 「时间好像是面板后面启动的」+「继续,还没去掉」):
157
163
  // **关键**: 启动那几步**不是 await 的** ✗(fire-and-forget)⇒ 它们常在 `startupPanelReady = true`
158
164
  // **之后**才打印 ✓ ⇒ 用"面板好了没"当判据必然漏 ✗(我上一版就栽在这 ✓)。
@@ -179,6 +185,11 @@ function writeOut(line) {
179
185
  * Ink 没起 ⇒ 先缓冲, `flushBootBuffer()` 在 Ink 起来后灌进对话流 ✓; Ink 已在跑 ⇒ 直接进 ✓。
180
186
  */
181
187
  function writeOutWarn(line) {
188
+ // 2026-10-02: 警告路同样过渲染过滤 —— 内部诊断行(带 ⚠ 也算)只落盘, 不占屏
189
+ if (isInternalChatter(String(line))) {
190
+ bootLogOnly(line);
191
+ return;
192
+ }
182
193
  if (startupPanelReady) {
183
194
  try {
184
195
  appendLine(line);
@@ -387,7 +398,7 @@ async function bootstrapIdentity() {
387
398
  writeOut(` ${reused ? GRAY + '复用 ' : ''}${GRAY}DID:${RESET} ${did}`);
388
399
  writeOut(` ${GRAY}名称:${RESET} ${name}`);
389
400
  s.step(1, 5, reused ? '复用 DIAP 身份' : '生成 DIAP 身份', 'ok');
390
- return { keypair: kp, did, name };
401
+ return { keypair: kp, did, name, created: !reused };
391
402
  }
392
403
  function publishDID(name, kp) {
393
404
  // 2026-06-17: 去掉 IPNS 重试机制 — 老逻辑 60s × 10 次 = 10 分钟阻塞,
@@ -3867,6 +3878,11 @@ async function processInputInner(input, comm) {
3867
3878
  dim(' /group send <文本> 往当前群发一条');
3868
3879
  dim(' /group log [N] 看当前群最近 N 条 (默认 10)');
3869
3880
  dim(' /group members 列当前群成员');
3881
+ dim(' /group invite <orbitdbId> 邀请进白名单 (门控群; 重建群地址)');
3882
+ dim(' /group kick <orbitdbId> 踢出白名单 (门控群; 重建群地址)');
3883
+ dim(' /group link 分享当前群链接');
3884
+ dim(' /group privacy on|off 隐私群标记 (默认建群即隐私)');
3885
+ dim(' /group status 群状态: 成员/消息/白名单/门控/隐私');
3870
3886
  return;
3871
3887
  }
3872
3888
  if (sub === 'list') {
@@ -3972,6 +3988,116 @@ async function processInputInner(input, comm) {
3972
3988
  dim(ms.length ? ms.join('\n') : '(暂无成员记录)');
3973
3989
  return;
3974
3990
  }
3991
+ // ── 2026-10-05 (leo): 群运营能力 —— 邀请/踢出/链接/隐私/状态
3992
+ if (sub === 'invite') {
3993
+ const gid = await ensureCurrentGroup(gg);
3994
+ if (!gid)
3995
+ return;
3996
+ const g = await gg.groupInfo(gid);
3997
+ if (!g) {
3998
+ dim('群不存在');
3999
+ return;
4000
+ }
4001
+ if (!g.gated) {
4002
+ appendLine(`${C_DIM}「${g.name}」是开放群 (write:[*]) —— 邀请 = 把链接发给对方自行加入:${RESET}\n${C_ACCENT}${g.link}${RESET}`);
4003
+ return;
4004
+ }
4005
+ if (!arg) {
4006
+ dim('用法: /group invite <orbitdbId> (门控群: 把对方加进白名单, 会重建群地址)');
4007
+ return;
4008
+ }
4009
+ const ref = {
4010
+ did: arg.startsWith('did:') ? arg : `did:key:z${arg.slice(0, 40)}`,
4011
+ publicKeyHex: '',
4012
+ orbitdbId: arg.startsWith('did:') ? (await gg.groupMembers(gid).catch(() => [])).find((m) => m === arg) || arg : arg,
4013
+ };
4014
+ const r = await gg.inviteMember(gid, ref);
4015
+ if (!r.ok) {
4016
+ appendLine(`${C_WARN}邀请失败: ${r.error}${RESET}`);
4017
+ return;
4018
+ }
4019
+ appendLine(renderMessageBox({
4020
+ title: `✅ 已邀请进白名单: ${r.group?.name}`,
4021
+ body: `新地址: ${r.group?.link}\n\n⚠ 重建代价 (IPFS 白名单不能就地改):\n${(r.costs || []).slice(0, 3).map((c) => `· ${c}`).join('\n')}\n\n把新链接发给对方, 用 /group join <链接> 加入 (老链接作废)`,
4022
+ color: C_ACCENT, maxLines: 12,
4023
+ }));
4024
+ currentGroupId = r.group?.id || currentGroupId;
4025
+ return;
4026
+ }
4027
+ if (sub === 'kick') {
4028
+ const gid = await ensureCurrentGroup(gg);
4029
+ if (!gid)
4030
+ return;
4031
+ const g = await gg.groupInfo(gid);
4032
+ if (!g) {
4033
+ dim('群不存在');
4034
+ return;
4035
+ }
4036
+ if (!g.gated) {
4037
+ dim('「' + g.name + '」是开放群 (write:[*]), 没有踢人语义 (人人可写)');
4038
+ return;
4039
+ }
4040
+ if (!arg) {
4041
+ dim('用法: /group kick <orbitdbId> (从白名单移除; 重建群地址)');
4042
+ return;
4043
+ }
4044
+ const r = await gg.kickMember(gid, arg);
4045
+ if (!r.ok) {
4046
+ appendLine(`${C_WARN}踢出失败: ${r.error}${RESET}`);
4047
+ return;
4048
+ }
4049
+ appendLine(renderMessageBox({
4050
+ title: `✅ 已移出白名单: ${r.group?.name}`,
4051
+ body: `新地址: ${r.group?.link}\n\n⚠ 重建代价:\n${(r.costs || []).slice(0, 3).map((c) => `· ${c}`).join('\n')}\n\n被踢者老链接作废; 其他成员要用新链接重新加入`,
4052
+ color: C_ACCENT, maxLines: 12,
4053
+ }));
4054
+ currentGroupId = r.group?.id || currentGroupId;
4055
+ return;
4056
+ }
4057
+ if (sub === 'link') {
4058
+ const gid = await ensureCurrentGroup(gg);
4059
+ if (!gid)
4060
+ return;
4061
+ const g = await gg.groupInfo(gid);
4062
+ if (!g) {
4063
+ dim('群不存在');
4064
+ return;
4065
+ }
4066
+ appendLine(renderMessageBox({ title: `群链接: ${g.name}`, body: `${g.link}\n\n复制发给同伴, 用 /group join <链接> 加入`, color: C_ACCENT, maxLines: 8 }));
4067
+ return;
4068
+ }
4069
+ if (sub === 'privacy') {
4070
+ const gid = await ensureCurrentGroup(gg);
4071
+ if (!gid)
4072
+ return;
4073
+ const on = arg === 'on' || arg === 'true' || arg === '1';
4074
+ const off = arg === 'off' || arg === 'false' || arg === '0';
4075
+ if (!on && !off) {
4076
+ dim('用法: /group privacy on|off (隐私群标记, 只影响本机展示/默认 ACL 说明)');
4077
+ return;
4078
+ }
4079
+ const r = await gg.setGroupPrivacy(gid, on);
4080
+ appendLine(r.ok ? `${C_ACCENT}✓ 隐私群 ${on ? '开启' : '关闭'}: ${r.group?.name}${RESET}${C_DIM} (白名单/ACL 由建群时决定, 本标记只做展示)${RESET}` : `${C_WARN}设置失败: ${r.error}${RESET}`);
4081
+ return;
4082
+ }
4083
+ if (sub === 'status') {
4084
+ const gid = await ensureCurrentGroup(gg);
4085
+ if (!gid)
4086
+ return;
4087
+ const s = await gg.groupStatus(gid);
4088
+ if (!s.ok || !s.status) {
4089
+ appendLine(`${C_WARN}${s.error}${RESET}`);
4090
+ return;
4091
+ }
4092
+ const st = s.status;
4093
+ const wl = st.writeList.slice(0, 12).join('\n ');
4094
+ appendLine(renderMessageBox({
4095
+ title: `群状态: ${st.group.name}`,
4096
+ body: `隐私: ${st.privacy ? '🔒 是' : '公开'} · 门控: ${st.gated ? '是' : '否'} · 成员: ${st.memberCount} · 消息: ${st.messageCount}\n最后同步: ${st.lastSyncAt || '-'}\n群主: ${st.ownerDid ? String(st.ownerDid).slice(0, 32) + '…' : '-'}\n\n写白名单 (${st.writeList.length}):\n ${wl || '(无)'}`,
4097
+ color: C_ACCENT, maxLines: 20,
4098
+ }));
4099
+ return;
4100
+ }
3975
4101
  dim('用法: /group help');
3976
4102
  }
3977
4103
  catch (e) {
@@ -4166,12 +4292,16 @@ async function processInputInner(input, comm) {
4166
4292
  if (plain && !onlyMarker)
4167
4293
  appendLine(renderMessageBox({ title: '💡 反思', body, color: C_WARN }));
4168
4294
  }
4169
- else if (!content.includes('🔄 循环') && !content.includes('📋 参数')
4170
- && !content.includes('🔍 任务复杂度') && !content.includes('⚙️ 动态配置')
4171
- && !content.includes('⏹️ pivot loop')
4172
- // 2026-08-12 (Task4): 循环过渡噪音 — "工具执行完成继续循环"/"继续总结" 是内部推进过程,
4173
- // 不是给用户看的内容, 一律静默丢弃 (用户抱怨"每次显示触发下一轮循环"的真凶).
4174
- && !content.includes('继续循环') && !content.includes('继续总结')) {
4295
+ else if (isInternalChatter(content)) {
4296
+ // 2026-10-02 (leo: 「✅ 最终回复 (质量 …) · 🔄 循环 N/10 这类也去掉」):
4297
+ // 老写法是一串 `content.includes(...)` 黑名单 —— 猜不完 (真机漏过), 且与 console 行各有一套判据。
4298
+ // 现在与 console 行**共用同一个判据** (`isInternalChatter`); 同样"搬走不是删掉":
4299
+ // 落盘 (`appendInternalRunLog`) + `--verbose` 原样上屏。
4300
+ appendInternalRunLog(content, e.tool);
4301
+ if (isStartupVerbose())
4302
+ appendLine(`${C_DIM}${content}${RESET}`);
4303
+ }
4304
+ else {
4175
4305
  appendLine(`${C_DIM}${content}${RESET}`);
4176
4306
  }
4177
4307
  }
@@ -6120,7 +6250,7 @@ async function main() {
6120
6250
  s.warn('未设置任何 LLM API Key,功能受限');
6121
6251
  }
6122
6252
  }
6123
- const { keypair, did, name } = await bootstrapIdentity();
6253
+ const { keypair, did, name, created } = await bootstrapIdentity();
6124
6254
  agentIdentity = { did, name, publicKey: Buffer.from(keypair.publicKey).toString('hex') };
6125
6255
  // 2026-08-07: CLI 模式后台自动安装/启动本地 Kubo (web 模式 server.ts 已有, CLI 缺 → IPNS 发布后无法解析的根因)
6126
6256
  // fire-and-forget, 不阻塞启动; Kubo 就绪后才发布 DID (避免 registerAgent 在 Kubo 未启动时 30s 超时)
@@ -6146,6 +6276,9 @@ async function main() {
6146
6276
  catch (e) {
6147
6277
  bootNotice('warn', `Kubo 自动安装失败 (非致命): ${String(e?.message || e).slice(0, 120)}`);
6148
6278
  }
6279
+ // DID 已存在时不重复发布;只有首次创建或显式要求刷新才发布。
6280
+ if (!created && process.env.BOLLOON_REFRESH_DID !== '1')
6281
+ return;
6149
6282
  publishDID(name, keypair).then(({ cid, ipnsName }) => {
6150
6283
  if (cid)
6151
6284
  agentIdentity.cid = cid;
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "schema": "bolloon-mobile-web/1",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "channel": "stable",
5
5
  "build": "stable",
6
- "commit": "6e2afcdd8723004df91715d48cf7bf7d291ab7af",
7
- "builtAt": "2026-10-04T08:00:57.589Z",
6
+ "commit": "eb3ebe6fed23cb70e901ac8da92e6420bc0673ad",
7
+ "builtAt": "2026-10-05T06:19:40.124Z",
8
8
  "layer": "web",
9
9
  "note": "web 资源层构建戳 (手机端 OTA 的身份第 ③ 级回退; 装机后以 OTA state.json 为准)"
10
10
  }
package/dist/ios/sw.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * 现在: 代码类资源 (html/js/css/json) 一律 **network-first** (拿不到网才回退缓存),
7
7
  * 缓存名带版本号, activate 时清掉所有旧缓存; 图标等静态资源仍 cache-first。
8
8
  */
9
- const CACHE = 'bolloon-mobile-v0.6.1';
9
+ const CACHE = 'bolloon-mobile-v0.6.3';
10
10
  const SHELL = [
11
11
  './mobile.html',
12
12
  './mobile.css',
@@ -0,0 +1,47 @@
1
+ /**
2
+ * 代码写改的"类型门" (2026-10-01, 回应「tsc 抓错这个功能 bolloon 有吗」)。
3
+ *
4
+ * 查到的事实: bolloon **早就**有类型检查, 而且有三层 —— pre-commit 的 `tsc-check`(lefthook) ·
5
+ * `build:main = tsc && …` · 以及**给智能体的工具** `tsc_check`(pi-sdk-tools.ts:1450, 60s timeout)。
6
+ * 但**循环里没有"编辑后自动检查"** ✗ ⇒ `tsc_check` 是个"模型想得起来才会调"的工具 ✓
7
+ * ⇒ 和 #4(写操作读回)同一个病: **规矩写了, 没人执行** ✓。
8
+ * 这条把它变成机制: 本回合**改过 .ts/.tsx** ⇒ 回合收尾**自动**跑一次类型检查(一轮只跑一次, 不管改了 1 个还是 8 个文件 ✓),
9
+ * 结果以一行状态进对话流 —— "类型过没过"不再依赖模型自觉 ✓。
10
+ * 纪律: 每个回合最多一次(tsc 是秒级开销, 但也不该每改一个文件就跑) · 只对 TS 源码生效 · 失败绝不影响回合结果 ✓。
11
+ */
12
+ /** 写/改类工具里, 会"产出源码"的那些 */
13
+ export const CODE_WRITE_TOOLS = new Set(['write_file', 'edit_file', 'patch', 'move_file', 'copy_file']);
14
+ export function isTypeScriptFile(p) {
15
+ return /\.(ts|tsx|mts|cts)$/i.test(String(p || '').trim());
16
+ }
17
+ /**
18
+ * 这次写操作是否**产生了/改动了 TS 源码** ⇒ 返回那个路径(否则 null)。
19
+ * 只看路径, 不看内容(便宜且够用 ✓)。
20
+ */
21
+ export function codeWriteTarget(toolName, args) {
22
+ if (!CODE_WRITE_TOOLS.has(String(toolName)))
23
+ return null;
24
+ const rel = String(args?.path ?? args?.to ?? args?.file ?? '').trim();
25
+ if (!rel)
26
+ return null;
27
+ return isTypeScriptFile(rel) ? rel : null;
28
+ }
29
+ /**
30
+ * 回合收尾要不要跑类型检查: 改过 TS 且本回合还没跑过 ⇒ 跑。
31
+ * 抽成纯函数是为了**可测**: "一轮只跑一次"这条最容易写错(写成每个文件跑一次就把时间烧光 ✓)。
32
+ */
33
+ export function decideTypecheck(touched, ranThisTurn) {
34
+ return !ranThisTurn && touched.length > 0;
35
+ }
36
+ /** 类型检查结果 ⇒ **一行**状态 (给对话流看; 错误多时只给前几条 + 总数) */
37
+ export function formatTypecheckResult(ok, output, maxLines = 6) {
38
+ const body = String(output || '').split('\n').map((l) => l.trim()).filter(Boolean);
39
+ if (ok)
40
+ return '✅ 类型检查通过 (tsc --noEmit, 本回合改过 TS 后自动跑)';
41
+ const errs = body.filter((l) => /error TS\d+/.test(l));
42
+ const head = (errs.length ? errs : body).slice(0, maxLines);
43
+ const more = (errs.length || body.length) - head.length;
44
+ return `❌ 类型检查没过: ${errs.length || '?'} 个错误\n` + head.map((l) => ` ${l.slice(0, 160)}`).join('\n')
45
+ + (more > 0 ? `\n …还有 ${more} 条` : '')
46
+ + '\n ⇒ **先修类型再继续**(别在同一轮里叠加更多改动)';
47
+ }
@@ -477,7 +477,11 @@ export function scanRunIdSeed(files, opts) {
477
477
  }
478
478
  const helper = extractSeedHelper(code);
479
479
  // 批次5: 播种读取读的是**本体** (actor.state.activeRun) —— 语义不变 (仍是"恰好一处, 且在播种体内")
480
- const seedInHelper = (helper.match(/runId: this\.actor!\.state\.activeRun\b/g) || []).length;
480
+ // 2026-10-02 (K10 余项): 播种读取的形状从「对象字面量字段」变成「`composeRunSeed` 的实参」——
481
+ // 合并顺序 (runId 打底 · extra 覆盖) 已归内核 (`kernel/session-lifecycle.ts`), K2 的不变量**一字未松**:
482
+ // 两种形状**相加仍必须恰好 1 处**, 且仍只在 `seedRunContext` 体内 (循环内新增读取由上面的"总访问数 == 冻结值"覆盖)。
483
+ const seedInHelper = (helper.match(/composeRunSeed\(\s*this\.actor!\.state\.activeRun\b/g) || []).length
484
+ + (helper.match(/runId: this\.actor!\.state\.activeRun\b/g) || []).length;
481
485
  const seedAnywhere = (code.match(/runId: this\.currentRunId\b/g) || []).length;
482
486
  if (seedInHelper !== opts.seedReads) {
483
487
  out.push({ rule: 'runid-seed-count', file: 'agents/pi-sdk.ts', line: 1, what: `seedRunContext 体内播种读取 ${seedInHelper} 处 ≠ 冻结 ${opts.seedReads}` });
@@ -43,7 +43,8 @@ export const HARNESS_SURFACES = [
43
43
  * 在 pi-sdk 插入 ~35 行后, 台账里的 4144 实际已变 4176)。说清"是哪一处"用函数名/类名/调用形态。
44
44
  */
45
45
  export const HARNESS_EXEC_SITES = [
46
- { file: 'src/agents/pi-sdk.ts', count: 5, kinds: ['main', 'skill', 'bypass', 'homonym', 'registry'], why: '**主执行点 1 = pivot 的 `guardedExecute` 端口内那次 `await tool.execute(args)`** (2026-10-02 K4-B: 老 `runReActLoop` 的执行点随 loop 删除, 端口成为唯一主执行点; 它先过 `beforeToolCall` 再执行、执行后过 `afterToolCall`) · skill 2 (`getSkillRegistry()` 暴露的 `skillRegistry.execute` + 内置 `sk.execute`; **2026-10-02 量到: 这两条在生产代码里零调用者** —— 但 `PiAgentSession.executeSkill`/`getSkillRegistry` 是**已发布 npm 包的公开方法** ⇒ 属"不擅动公开契约", 删/收口都要等用户口径) · 内置 tscTool 直调 1 (bypass, 已在 `runTurnEndTypecheck` 内先问门) · `loop.execute` 1 (homonym)' },
46
+ { file: 'src/kernel/turn-selfcheck.ts', count: 1, kinds: ['bypass'], why: '收尾自检的**执行点** (2026-10-02 从 pi-sdk 的方法体搬进内核): 系统自检也要**先问门** ⇒ 被拒/门抛错零执行, 且拒绝可见。它属 bypass 类 (不是模型发起的调用), 但已按"走门"收敛。' },
47
+ { file: 'src/agents/pi-sdk.ts', count: 4, kinds: ['main', 'skill', 'homonym', 'registry'], why: '**主执行点 1 = pivot 的 `guardedExecute` 端口内那次 `await tool.execute(args)`** (2026-10-02 K4-B: 老 `runReActLoop` 的执行点随 loop 删除, 端口成为唯一主执行点; 它先过 `beforeToolCall` 再执行、执行后过 `afterToolCall`) · skill 2 (`getSkillRegistry()` 暴露的 `skillRegistry.execute` + 内置 `sk.execute`; **2026-10-02 量到: 这两条在生产代码里零调用者** —— 但 `PiAgentSession.executeSkill`/`getSkillRegistry` 是**已发布 npm 包的公开方法** ⇒ 属"不擅动公开契约", 删/收口都要等用户口径) · 内置 tscTool 直调 1 (bypass, 已在 `runTurnEndTypecheck` 内先问门) · `loop.execute` 1 (homonym)' },
47
48
  { file: 'src/agents/workflow-pivot-loop.ts', count: 2, kinds: ['bypass', 'homonym'], why: '**pivot loop 直接执行工具** 1 (bypass —— 2026-10-02 已收敛: 走注入的 `guardedExecute` 门端口) · `loop.execute` 1 (homonym)' },
48
49
  { file: 'src/agents/tool-registry.ts', count: 1, kinds: ['registry'], why: '注册表统一执行口 (唯一咽喉候选)' },
49
50
  { file: 'src/agents/pi-sdk-tools.ts', count: 1, kinds: ['mcp'], why: 'MCP `executeTool` 1' },
@@ -58,7 +59,7 @@ export const HARNESS_EXEC_SITES = [
58
59
  ];
59
60
  export const K7_BYPASS_CANDIDATES = [
60
61
  { target: 'src/agents/workflow-pivot-loop.ts', symbol: 'guardedExecute', replacesWith: '走 Harness 门链 (与 pi-sdk 主执行点同一条咽喉)', why: 'pivot loop 是第二条工具执行路径 ⇒ 未经 deny/policy 就能执行工具 (架构缺陷定义的那一类)', status: 'converged', evidence: '2026-10-02: `PivotLoopConfig.guardedExecute` 端口 (`044cde2`) + pi-sdk 在 `promptWithPivotLoop` 注入同一 `piHarness().beforeToolCall` (`69397f6`); 用例: 未注入行为不变 / 注入后 `tool.execute` 计数 0 / 端口抛错不执行 / 机械接线断言' },
61
- { target: 'src/agents/pi-sdk.ts', symbol: 'tscTool.execute', status: 'converged', replacesWith: '经门链执行, 或在台账里登记为"内部诊断白名单"并写明理由', why: '内置诊断工具直调: 要么走门, 要么**显式登记**为白名单 —— 不许处于"没人知道它绕过"的状态。**2026-10-02 选"走门"并已接线**: 回合末尾 TS 自检先问 `beforeToolCall({tool: tsc_check, args: {}, ctx: harnessCtx(), permissionMode})`, 被拒或抛错 ⇒ **不执行**且**可见**报出 (拒绝不静默); 机械断言: 判定在 `tscTool.execute` 之前 + `if (!tscAllowed)` 分支存在 + 拒绝文案存在。**端到端未单独取证** (该路径由"本回合改过 TS"的收尾自检触发, 需要真 LLM 回合) ⇒ **2026-10-02 端到端取证完成** (`src/test/k7-tsc-tool-e2e.test.ts`, 真 LLM 回合 + 真门实例): ① 允许路 —— 门被问过 `tsc_check` 且恰执行一次 (门被问到 `read_file, edit_file, tsc_check`), 结论 `🔎 类型检查` 进对话流; ② 拒绝路 —— 门拒绝 ⇒ `tsc_check` **零执行** + 拒绝文案 (带门给出的理由) 进对话流。**两条变异都真做且判红**: 变异①把问门时的工具名改掉 ⇒ 允许路判红 (`expected [...] to include 「tsc_check」`); 变异②把拒绝分支改成 fail-open (`if (false && !tscAllowed)`) ⇒ 拒绝路判红 (`被门拒绝 ⇒ 一次都不许执行: expected 1 to be +0`)。**如实记边界**: 拒绝路里"拒绝"这个判定是测试注入的 (沿用仓里端口注入法), 产品侧被证的是"**先问门、被拒后不执行**"这一半; "门自己判出来的拒绝"由 pre-tool-validator/react-harness 既有用例覆盖。**踩坑两条**: (a) 少了 `initMinimax()` 装配 ⇒ session 走未初始化模型兜底路 (回显、不调工具), 门一次都不会被问 ⇒ 假红; (b) 少了 `resetAgentSession()` ⇒ `createAgentSession` 复用上一条用例的 session (带着"我改过这个文件了"的记忆) ⇒ 第二条用例的模型回"需求已完整满足"不调工具 ⇒ 前提假红。两条都写进用例头。',
62
+ { target: 'src/kernel/turn-selfcheck.ts', symbol: 'tool.execute({})', status: 'converged', replacesWith: '经门链执行, 或在台账里登记为"内部诊断白名单"并写明理由', why: '内置诊断工具直调: 要么走门, 要么**显式登记**为白名单 —— 不许处于"没人知道它绕过"的状态。**2026-10-02 选"走门"并已接线**: 回合末尾 TS 自检先问 `beforeToolCall({tool: tsc_check, args: {}, ctx: harnessCtx(), permissionMode})`, 被拒或抛错 ⇒ **不执行**且**可见**报出 (拒绝不静默); 机械断言: 判定在 `tscTool.execute` 之前 + `if (!tscAllowed)` 分支存在 + 拒绝文案存在。**端到端未单独取证** (该路径由"本回合改过 TS"的收尾自检触发, 需要真 LLM 回合) ⇒ **2026-10-02 端到端取证完成** (`src/test/k7-tsc-tool-e2e.test.ts`, 真 LLM 回合 + 真门实例): ① 允许路 —— 门被问过 `tsc_check` 且恰执行一次 (门被问到 `read_file, edit_file, tsc_check`), 结论 `🔎 类型检查` 进对话流; ② 拒绝路 —— 门拒绝 ⇒ `tsc_check` **零执行** + 拒绝文案 (带门给出的理由) 进对话流。**两条变异都真做且判红**: 变异①把问门时的工具名改掉 ⇒ 允许路判红 (`expected [...] to include 「tsc_check」`); 变异②把拒绝分支改成 fail-open (`if (false && !tscAllowed)`) ⇒ 拒绝路判红 (`被门拒绝 ⇒ 一次都不许执行: expected 1 to be +0`)。**如实记边界**: 拒绝路里"拒绝"这个判定是测试注入的 (沿用仓里端口注入法), 产品侧被证的是"**先问门、被拒后不执行**"这一半; "门自己判出来的拒绝"由 pre-tool-validator/react-harness 既有用例覆盖。**踩坑两条**: (a) 少了 `initMinimax()` 装配 ⇒ session 走未初始化模型兜底路 (回显、不调工具), 门一次都不会被问 ⇒ 假红; (b) 少了 `resetAgentSession()` ⇒ `createAgentSession` 复用上一条用例的 session (带着"我改过这个文件了"的记忆) ⇒ 第二条用例的模型回"需求已完整满足"不调工具 ⇒ 前提假红。两条都写进用例头。',
62
63
  evidence: '2026-10-02 端到端: `src/test/k7-tsc-tool-e2e.test.ts` (真 LLM 回合 + 真门实例包裹) —— 允许路: 门被问过 `tsc_check` 且恰执行一次, `🔎 类型检查` 进对话流; 拒绝路 (判定注入): `tsc_check` 零执行 + 拒绝文案带理由进对话流。变异①(问门工具名改掉)⇒允许路判红; 变异②(拒绝分支改 fail-open)⇒拒绝路判红。**2026-10-02 K4-B 侦查补正**: 上面两条用的是**默认配置** (老 `runReActLoop`), 而**生产里 web 走 pivot 路径** (`usePivotLoop: true` + 流式入口原先"提前 return") ⇒ 那条自检在生产**一次都没跑过** (早先证据只覆盖非生产形状)。已修: 抽成 `runTurnEndTypecheck()`, **三条路径全挂** (pivot prompt / 老 loop / 流式 pivot); 用例补第三条"生产形状" (注入 touched 状态 ⇒ 判**接线**), **变异 (撤掉流式路径那行) ⇒ 判红** (`expected [] to include tsc_check`)。' },
63
64
  { target: 'src/agents/pi-sdk.ts', symbol: 'getSkillRegistry', replacesWith: '返回**受门包装** (`GuardedSkillRegistry`): `execute` / `get().execute` / `list()[].execute` 三条都经 `executeSkill` ⇒ Harness', status: 'converged', evidence: '2026-10-02 按 leo 口径 **(b)** 落地 (原选 a 为纸面约定, leo 裁定走 b): ① 包装堵住**三条**隐藏路径 —— 只堵 `execute` 不够, `get()`/`list()` 返回的 `Skill` 自带裸 `execute`; ② 真跑 `k7-session-skill-gate.test.ts` ⑥: allow 时三条各恰一次 (计数 3), `denyTool` 后**三条全零执行** (计数仍 3); ③ 真变异两条 (`list` 裸透传 / `get` 裸透传) 均判红 (`expected FACADE_EXECUTED to match /^拒绝: /`), 还原回绿; ④ 机械断言: 方法体内无 `return this.skillRegistry;`、`list` 过 `guarded` 映射、**零** `this.skillRegistry.execute(` 直连。⚠️ 行为变更 (可能属破坏性, leo 已知并裁定): 旧 `.execute()` 被拒时**不再执行**, 改为返回 `拒绝: [...]`; 方法名/签名不变 ⇒ 源码级兼容。**管不到的一条 (如实记)**: 调用方自己 `register` 时传进来的那个对象仍有裸 `execute` —— 那是调用方的对象, 不属本出口能管的面', why: '**未过门的原始出口**: 拿到裸 registry 就有三条绕过 Harness 的路径 (`execute` / `get().execute` / `list()[].execute`) —— 公开兼容面不许无声删, 但也**不许不登记** (leo 的最终要求: 任何 skill 执行入口只能经 Harness)' },
64
65
  { target: 'src/bollharness-integration/skill-adapter.ts', symbol: 'registry.execute', replacesWith: '收敛成唯一 skill 执行入口 (且该入口经门)', status: 'converged', evidence: '2026-10-02 两条路都真跑取证+变异验证: ① adapter 路 `k7-skill-denylist-e2e.test.ts` (真 session→真 Harness→integration→adapter) ② 公开出口路 `k7-session-skill-gate.test.ts` (`executeSkill` 探针 skill 计数: 允许恰 1 次执行返回标记 · deny **零执行** · 重试仍拒 · 放开又能执行); 两处变异(拆保护/门永远放行)均判红 ⇒ 用例承重', why: 'skill 有两条执行路径 ⇒ 必然一条有门一条没有 ("同一个能力只许有一套实现" 的同型教训). **2026-10-02 实测**: 活路径 = `SkillAdapter.executeSkill` (`bollharness-integration/integration.ts` ← `index.ts` 的 harness 入口); `PiAgentSession.executeSkill` **生产零调用者** (但属公开契约 ⇒ 删除待用户口径). 活路径已接线: 端口 (`setGuardedExecute`, **判定**契约) + integration 透传 (`setSkillGuard`) + `index.ts` 活路径注入 (门建不起来 ⇒ deny-all); **真跑已通 (allow 路)**: `node dist/index.js --harness-skill arch get_gate` 真执行并返回真实 skill 输出 —— **注意读的地方**: 响应经"启动期日志闸门"写进 `~/.bolloon/logs/startup.log` (`[boot] 🎯 Skill <name> 执行结果:`), **stdout 里看不到** (我上一轮据此误判"没走到分发器", 是假阴性); 且无 `[K7] skill 门未能建立` 警告 ⇒ 门确实建起来了。**deny 路已取得 ★真跑**: `k7-skill-denylist-e2e.test.ts` 走**真链** (真 session → 真 Harness 的 deny-list checker → integration → adapter → registry): allow 基线不被拒 · 把 `skill:arch` 放进拒绝列表 ⇒ 结果 `拒绝: [deny-list]` 且拿不到 skill 真实输出 · 重试仍被拒 · 放开名单 ⇒ 又能执行; **变异** (拆掉 adapter 的门分支) ⇒ 该用例判红, 还原 ⇒ 回绿且无 diff ⇒ **用例承重**。**状态仍 open**: 本条目含两条路径, 公开兼容面 (`PiAgentSession.executeSkill`) 未收敛 (leo 第 4 步: 降为兼容转发 ⇒ 唯一 SkillExecutionPort)' },
@@ -100,7 +100,7 @@ export const KERNEL_ALLOWED_IMPORT_PREFIXES = ['kernel/'];
100
100
  * 判据是**双向相等**: 盘上多一个未登记文件 ⇒ 红; 名册有而盘上没有 ⇒ 红。
101
101
  * (先例: SEAM_ROSTER 的「名册外无人越界」)
102
102
  */
103
- export const KERNEL_FILES = ['kernel/channel-actor.ts', 'kernel/control.ts', 'kernel/run-lifecycle.ts', 'kernel/transport.ts', 'kernel/gate-scan.ts', 'kernel/model-runtime.ts', 'kernel/plan-harness.ts', 'kernel/plan-modelruntime.ts', 'kernel/plan-constraint.ts', 'kernel/plan-channel-actor.ts', 'kernel/plan-deletion.ts', 'kernel/plan-runcontext.ts', 'kernel/plan-communication.ts', 'kernel/plan.ts', 'kernel/roster.ts'];
103
+ export const KERNEL_FILES = ['kernel/channel-actor.ts', 'kernel/control.ts', 'kernel/run-lifecycle.ts', 'kernel/transport.ts', 'kernel/session-lifecycle.ts', 'kernel/code-write-gate.ts', 'kernel/turn-selfcheck.ts', 'kernel/run-resume.ts', 'kernel/gate-scan.ts', 'kernel/model-runtime.ts', 'kernel/plan-harness.ts', 'kernel/plan-modelruntime.ts', 'kernel/plan-constraint.ts', 'kernel/plan-channel-actor.ts', 'kernel/plan-deletion.ts', 'kernel/plan-runcontext.ts', 'kernel/plan-communication.ts', 'kernel/plan.ts', 'kernel/roster.ts'];
104
104
  /** Goal 事实的写入口 (goal-store.ts 的导出中带副作用的那些) */
105
105
  export const GOAL_WRITES = [
106
106
  'createGoal',
@@ -209,7 +209,7 @@ export const STAGE_STATUS = {
209
209
  K7: 'done', // 2026-10-02 收尾: 旁路 **3 → 0** (pivot ✅ · skill ✅ 两路端到端 · tscTool ✅ 端到端取证含两条变异 · getSkillRegistry ✅ 受门包装) — 提交 5483e3a / 1af7e46
210
210
  K8: 'partial', // 台账+门已落 · 直连 12 → **0** · 各通道状态 37/33 · didFixQueue 经邮箱 · **正刀已落地** (每条消息都进邮箱, 删掉重复的第二条路径, 提交 2fc197e, 真跑: 一条不丢/严格串行/FIFO) ⇒ 剩 `abortController` 语义定夺 (目标是 ExecutionRequest.signal), 显式留下不随队列顺手合并
211
211
  K9: 'done', // 2026-10-02: **转 done (口径已重述并逐条取证)** —— 设计页那条"与 Pi 完全相同的五套验收"里, 4 套全过; 第 5 套("Durable Run/checkpoint 经适配器")经核实**按字面不可造**(startRun/recordStep 的真调用者只有 真钱 M1 任务 / x402 付费 / 回退路径, 与"适配器只在 LLM 可用时生效"互斥) ⇒ 重述为两半并各自取证: ① durable 写入经内核端口 = K10 ① (门 8/8 + 4/4, 两处变异判红); ② 适配器驱动真跑 = CLI + Web 真跑(会话落库)。 要合成一条"经适配器 + durable"的验收需先补**不含真钱**的 durable-run 路径 ⇒ 已登记为产品/验收设计待办, **不阻塞 K9 收口** (不假装跑过)。原始逐条记录见本条尾部。 // 2026-10-02: **不能算 done** —— 设计页的 K9 要求"最小 Native Adapter 必须通过与 Pi **完全相同**的五套验收"; 已过: model call (真端点 200+回复) · tool call 经 Harness 门恰一次/拒绝零执行 · CLI 非流式真跑 · 名字净化/回程还原 · 超时/退避/abort/4xx 不重试。**未过 → 2026-10-02 口径重述 (有证据)**: "Durable Run / checkpoint 经适配器"这条**按字面不可造** —— 核实三处: ① `startRun` 的真调用者只有 **`agents/task/task-runner.ts:358`(M1 任务, **走真钱/预算**) · `x402/goal-run-bridge.ts`(付费信息场景) · pi-sdk 回退路径(本机不可达)**; ② `recordStep`(每步写 checkpoint) 的调用者也全在这三条路径上; ③ checkpoint 字段实际由 `recordStep`(每步)/`prepareResume`(resume) 写, `saveCheckpoint` 本身**无人调**。 ⇒ 可选路径里**没有一条既不含真钱又能经适配器**(适配器只在 LLM 可用时生效, 而"回退路径"按定义要求 LLM 不可用 ⇒ 互斥)。**诚实处置**: 该条拆成两半分别验 —— ① "durable 写入经内核端口" = K10 ① (门 8/8 + 4/4 + 两处变异); ② "适配器驱动真跑" = CLI(`三面通过`)+Web(会话落库) 真跑。要合成一条"经适配器 + durable"的验收, 得先补一条**不含真钱**的 durable-run 路径 ⇒ 属产品/验收设计, 需拍板。 (适配器层的并发/取消/流式回调已由 ⑧⑨⑩ 覆盖: 3 条并发各自拿到自己的回复 · abort 中途打断且适配器之后仍可用 · 真 loop 的 onStream 收到 token/reply-preview)。以下是已落地部分: **第二个 (非 Pi) 推理适配器** `src/llm/native-adapter.ts` (fetch 直连 OpenAI 兼容端点, 源码不 import 任何 Pi 模块) + 唯一选择点 `BOLLOON_NATIVE_ADAPTER=1`; 门 `k9-native-adapter.test.ts` **8/8** (机械: 不许是 Pi 的壳 · 行为: 回复/tokens · native tool_calls 原样 · 429 退避重试 · abort 透传 · 4xx 不重试 · **出程名字净化+回程还原** · **过同一套门**: 适配器的 tool_call 经受门端口恰执行一次, 拒绝⇒零执行); **真跑**: 非流式 `prompt` 走该适配器打真端点 ⇒ 回 `适配器切换成功` (HTTP 200)。**顺带修掉一处隐式 Pi 依赖**: pivot 入口的 `!minimaxAvailable ⇒ fallback` 改成问**当前适配器**。**如实范围**: 适配器只实现接口所需的 chat 契约 + 超时/退避/abort/名字净化; Pi 侧的 KV 前缀/轻量分流等属 Pi 自身特性, 不在接口面内
212
- K10: 'done', // 2026-10-02: **八步全落地** —— ① 4/4 (门 8/8 + 4/4, 两处变异) · ② 轻版落地 (内核运行时进生产路径, 门 6/6 + 变异 + 真跑) · ③ 实质完成 · ④ 全接线 (门 26/26 + 变异) · ⑤⑥ 早完成 (K7/K4-B) · ⑦ 已查清处置 (接上死机制, 其余登记保留) · ⑧ 按判据给出结论 (不宣称替换成功 · 不物理删)。**余项(不阻塞)**: 6 处辅助调用仍拿现成 handle; `checkMinimax` 仍 Pi 专有; 12.3% 运行/通道接线待薄化。 // 2026-10-02 起手 (先量后删): pi-sdk.ts **3353 行**; 8 步现状 —— **⑤ 旧工具 gate ✅ (K7 已做)** · **⑥ 旧 loop ✅ (K4-B 删 runReActLoop 1123 行)** · **① Pi 的 Goal/Run 写入 = 已接线 4/4** (端口 `kernel/run-lifecycle.ts` 落地 + 回退路径三处 `start-run/record-step/finish-run` 改经端口 + `assertLifecycleOk` 响失; 门 `k10-run-lifecycle-port.test.ts` 8/8 + 变异判红; **真跑待补**: 该分支需 `getMinimax()` 真抛, 本机模型总能构造 ⇒ 不可达; 第 4 处 = `safeSetRunStatus` 的状态迁移**已改经控制面** (`submitRunControl(kind:"set-run-status")` + `runControlPorts()` 注入; 口径保真: 被拒⇒false 且不记降级 · 未注入/抛错⇒false 并记降级), 门 `k10-run-control-wiring.test.ts` **4/4**(真调私有方法体三态 + 反回归) + **变异判红**(绕过控制面 ⇒ 4 条全红)): 写点 4 处 (1244 `startRun` / 1254 `recordStep` / 1255 `finishRun` = 回退路径落 run 事实; 1999 在 `setGoalId` 里 = Pi 的 Goal 写入), 内核**已有控制面** `kernel/control.ts` (`RunControlRequest{kind,origin,runId,goalId,payload}` → `RunControlPorts{recordRecovery,setRunStatus,setContinuation}`), 但它是**命令式控制面** (供 web/cli/supervisor 发 pause/resume/abort/recover), **不是 run 生命周期写口** ⇒ ① 的正确下一刀 = **照 control.ts 的形状新增 run-lifecycle 端口** (`startRun/recordStep/finishRun/saveCheckpoint`, 同样端口注入 + 未注入即拒), 再把 4 处改经它 (禁直接调 run-store); 不许把生命周期写入硬塞进控制面的 `kind` 里 (语义不同: 一个是"谁命令我停", 一个是"我这一轮的事实") · **② 模型配置解析 = 轻版落地** (回合的模型**先向内核运行时取租约** —— `ModelRuntime.acquire(snapshot)` 只读入手, 超时/取消/退避/熔断/回退/记账/连接池/能力检查由 K6 运行时负责; **传输仍是 Pi 客户端** (端口 `openPiConnection` 注入) ⇒ 行为不变; 取不到就**如实记**"内核租约不可用 ⇒ 回落 Pi 直连"(不假装); 新增只读投影 `snapshotFromSelection`(缺 provider/model ⇒ null, 不许编); 门 `k10-model-runtime-wiring.test.ts` **5/5** + 变异判红; **真跑**: `推理适配器 = kernel-model-runtime (只读 acquire 租约)` + 回复 `内核租约` ✓ ⇒ K6 那个"造了没人用"的运行时**进生产路径了**。**② 余下 (预留升级)**: 6 处辅助调用的 `getMinimax()` 仍拿现成 handle; `checkMinimax` 仍是 Pi 专有探针 —— 两条都属"下一刀", 已点名) (10 处: 6 处 `getMinimax()` 供辅助功能自取自用 [judgment hint 2625 · suggestRename 2915/2946 · summarizeDocument 2970 · improveDocument 3003 · 自动压缩注入 1392] + `checkMinimax` 1127 + 适配器回落 1735 + 注释 2; 内核已有 `class ModelRuntime`(517 行, `acquire(snapshot): ModelLease` 只读) 与能力 9/9 ⇒ **缺的不是运行时, 是取舍**: ① snapshot 由谁传给 Pi (Run 级 vs 会话级) ② 辅助调用拿 lease 还是拿现 handle ③ `checkMinimax` 这种 Pi 专有探针是否保留 —— 三条都影响公开行为, 须拍板后再动, 不许硬编) · **③ Channel 状态 = 已量清, 实质完成** (Pi **无自有**通道状态字段: `this.channelId/currentSessionId/sessionKey/channelName` 赋值与读点均 **0**; 剩余 8 处 `actor.state.channelId` 读的正是 K5 actor —— 归属已在内核) · **⑦ 已查清处置**: 查 6 个导出时挖出 **`verifyWriteOutcome` 是"写后读回"纪律的唯一实现却 0 调用点, 且函数体用 `require('node:fs')`(ESM 产物里必炸、被自己 catch 吞成 `[未核对] … require is not defined` ⇒ 它一次都没成功过)** ⇒ 按"无替代路径不许删"**改为接上**: 拆成 `src/agents/write-verify.ts`(静态 import) + `withWriteVerified` 接进 `write_file`/`edit_file` 成功返回; 门 `k10-write-verify-wiring.test.ts` **10/10**(含两条端到端真跑) + **变异判红**(拆接线 ⇒ 2 条红); 其余 4 导出各有测试与用途 ⇒ **登记保留**, 不删 · · **④ 通信入口 = 首刀落地** (新增内核端口 `kernel/transport.ts`: `send/broadcast/peers` 三动作, 端口注入 + 未注入即拒 + `{ok:false}` 归一化 + 审计, 与 control/run-lifecycle 同一套写法; pi-sdk 的 `sendMessage`/`broadcast` 改经端口 + **失败一律抛**(发送有副作用: 静默丢消息比抛错更糟); 门 `k10-transport-port.test.ts` **8/8**(含真调方法体两条) + **变异判红**(绕过端口 ⇒ 3 条红, 直连真传输那次的失效形态正是 `Node not initialized`); **④ 后半已落地 = ④ 全接线**: 加**同步**读入口 `transportPeersSync(ports)` + `peersSync` 端口 (不硬塞进 async 的 `submitTransport` —— 分开是因为**签名**不是语义: 上层有同步调用点, sync 签名不能凭空变 async); `getPeers()`/`listPeers()` 改经端口: `listPeers` 在端口未注入时**明说"读不到"**(不假装"没有对端"), `getPeers()` 未注入时回落直读并 `console.warn` 留痕; 门扩到 **11/11**(同步入口两种注入态 + 真调方法体三态) + **变异判红**(同步读绕过端口 ⇒ `listPeers` 谎报"无对端", 门抓到)) · **⑦ 兼容层 6 个导出面** · **⑧ 是否删 Pi Adapter 本身 = 已按判据给出结论 (不物理删)**。量占比 (**行数口径**, 方法: 按方法块归类, 脚本在 `docs/wiki/log.md`): `pi-sdk.ts` **3497 行** ⇒ 传输/供应商 **14.4%** · turn-glue **14.0%** · 运行/通道/通信接线 **12.3%** · 文档辅助 **9.2%** · 其余 50.1% 通用编排/装配。**职责口径**: K0–K10 已把「循环 (K4-B) · 工具门 (K7) · Run 事实 (①) · 通道状态 (③) · 通信 (④) · 模型选择 (②)」**全部搬出 Pi** ⇒ 岗位职责只剩"传输适配 + 供应商/Harness 特性 + 文档辅助 + 端口接线"。**结论**: 按判据「迁移后 Pi 职责仍超原职责 30% ⇒ 不许宣称替换成功」—— 行数口径下 Pi 仍是本仓最大单体 ⇒ **不宣称替换成功** (诚实口径); **不物理删** (五个删除条件不满足: 传输在 Pi 有专有实现、无替代路径; 且属公开契约)。**下一刀候选** (已点名): 继续薄化那 12.3% 的运行/通道**接线**与 turn-glue 里的生命周期部分。
212
+ K10: 'done', // 2026-10-02: **八步全落地** —— ① 4/4 (门 8/8 + 4/4, 两处变异) · ② 轻版落地 (内核运行时进生产路径, 门 6/6 + 变异 + 真跑) · ③ 实质完成 · ④ 全接线 (门 26/26 + 变异) · ⑤⑥ 早完成 (K7/K4-B) · ⑦ 已查清处置 (接上死机制, 其余登记保留) · ⑧ 按判据给出结论 (不宣称替换成功 · 不物理删)。**余项(不阻塞)**: 6 处辅助调用仍拿现成 handle; `checkMinimax` 仍 Pi 专有。**12.3% 运行/通道接线的第一刀已落 (2026-10-02)**: 新增内核模块 `kernel/session-lifecycle.ts` (278 行) —— 把四处**规则**搬进内核: ① `save-session` 的消息→持久形态映射 + key 校验 (原在 `saveCurrentSession` 方法体里) ② `peek-history` / `hydrate` 的**读回过滤/水合规则** (原为 `_filterToMessage` —— 全仓唯一副本, **已删**) ③ `seed-run` 的运行种子合并顺序 (`composeRunSeed`: 活跃运行打底 · extra 覆盖, 与同步调用点共用同一条) · I/O (actor 快照 / SessionStore / 上下文工厂) 全部端口注入。**门** `k10-session-lifecycle-port.test.ts` **16/16** (纯规则四条"必须保留/必须剔" + 端口语义 + 审计 + 源级反回归) + **变异判红** (把过滤副本塞回 pi-sdk ⇒ 反回归精确判红)。**扣减**: pi-sdk **3497 → 3479 行 (-18)**; K3 显式抬档 +278 (真实值 3583)。 **第二刀 (2026-10-02)**: ① `src/agents/code-write-gate.ts` (**49 行纯规则** —— 哪个写操作产出 TS · 收尾要不要跑 tsc · 结果怎么压成一行) **整条搬进内核** (`kernel/code-write-gate.ts`) ⇒ agent 侧**少一个模块** (减法); ② 两条恢复规则搬进 `kernel/run-lifecycle.ts`: `decideResumeReinstall` (一致**不**重装 · 漂了/核对不了才装 · **无结论不装**) 与 `pickRunIdForResume` (显式 lastRunId 优先 · 回落活跃运行); 两条都补了门断言 + **变异判红** (把重装判据改成恒 false ⇒ 门红)。K3 抬档 **3660** (真实值)。 **第三刀 (2026-10-02)**: `runTurnEndTypecheck` 的**编排与政策**整条搬进内核 (`kernel/turn-selfcheck.ts`) —— 该不该跑 (纯规则在 `code-write-gate.ts`) · **系统自检也过门** · **被拒/门抛错 ⇒ 零执行且可见** (fail-closed) · 执行抛错 ⇒ 一行"没能跑起来"且**从不抛**; pi-sdk 的方法体 **40 → 26 行**, 只剩三个端口实现 (取工具 / 问门 / 上报)。门 `k10-turn-selfcheck.test.ts` **10/10** (含"被拒零执行"与"门抛错"两条政策) + **变异判红**; K7 端到端 (真模型) 仍绿 ⇒ 换主人后行为不变。K3 抬档 **3752** (真实值)。 **第四刀 (2026-10-02)**: `resumeRun` 的**编排与政策**整条搬进内核 (`kernel/run-resume.ts`) —— 漂移上报口径 (漂了 warn · 一致 info) · **核对失败不阻塞恢复** · 「只在漂了/核对不了时装运行时」· **装配失败也不阻塞** (留在返回值里) · 准备失败早返回 (不驱动不落态) · 恢复态**单次语义** (驱动抛错也一定清) · 驱动同一 runId; pi-sdk 方法体 **40 → 29 行**, 只剩七个端口实现 (核对/准备/装配/落态/驱动/清态/日志, 日志前缀 `[pi-sdk]` 保留 ⇒ 对外无可感知变化)。门 `k10-run-resume.test.ts` **10/10** + **变异判红** (改成"一致也重装" ⇒ 「一致就不该重装」判红); `pi-run-context-wiring` 仍绿。K3 抬档 **3852** (真实值)。 // 2026-10-02 起手 (先量后删): pi-sdk.ts **3353 行**; 8 步现状 —— **⑤ 旧工具 gate ✅ (K7 已做)** · **⑥ 旧 loop ✅ (K4-B 删 runReActLoop 1123 行)** · **① Pi 的 Goal/Run 写入 = 已接线 4/4** (端口 `kernel/run-lifecycle.ts` 落地 + 回退路径三处 `start-run/record-step/finish-run` 改经端口 + `assertLifecycleOk` 响失; 门 `k10-run-lifecycle-port.test.ts` 8/8 + 变异判红; **真跑待补**: 该分支需 `getMinimax()` 真抛, 本机模型总能构造 ⇒ 不可达; 第 4 处 = `safeSetRunStatus` 的状态迁移**已改经控制面** (`submitRunControl(kind:"set-run-status")` + `runControlPorts()` 注入; 口径保真: 被拒⇒false 且不记降级 · 未注入/抛错⇒false 并记降级), 门 `k10-run-control-wiring.test.ts` **4/4**(真调私有方法体三态 + 反回归) + **变异判红**(绕过控制面 ⇒ 4 条全红)): 写点 4 处 (1244 `startRun` / 1254 `recordStep` / 1255 `finishRun` = 回退路径落 run 事实; 1999 在 `setGoalId` 里 = Pi 的 Goal 写入), 内核**已有控制面** `kernel/control.ts` (`RunControlRequest{kind,origin,runId,goalId,payload}` → `RunControlPorts{recordRecovery,setRunStatus,setContinuation}`), 但它是**命令式控制面** (供 web/cli/supervisor 发 pause/resume/abort/recover), **不是 run 生命周期写口** ⇒ ① 的正确下一刀 = **照 control.ts 的形状新增 run-lifecycle 端口** (`startRun/recordStep/finishRun/saveCheckpoint`, 同样端口注入 + 未注入即拒), 再把 4 处改经它 (禁直接调 run-store); 不许把生命周期写入硬塞进控制面的 `kind` 里 (语义不同: 一个是"谁命令我停", 一个是"我这一轮的事实") · **② 模型配置解析 = 轻版落地** (回合的模型**先向内核运行时取租约** —— `ModelRuntime.acquire(snapshot)` 只读入手, 超时/取消/退避/熔断/回退/记账/连接池/能力检查由 K6 运行时负责; **传输仍是 Pi 客户端** (端口 `openPiConnection` 注入) ⇒ 行为不变; 取不到就**如实记**"内核租约不可用 ⇒ 回落 Pi 直连"(不假装); 新增只读投影 `snapshotFromSelection`(缺 provider/model ⇒ null, 不许编); 门 `k10-model-runtime-wiring.test.ts` **5/5** + 变异判红; **真跑**: `推理适配器 = kernel-model-runtime (只读 acquire 租约)` + 回复 `内核租约` ✓ ⇒ K6 那个"造了没人用"的运行时**进生产路径了**。**② 余下 (预留升级)**: 6 处辅助调用的 `getMinimax()` 仍拿现成 handle; `checkMinimax` 仍是 Pi 专有探针 —— 两条都属"下一刀", 已点名) (10 处: 6 处 `getMinimax()` 供辅助功能自取自用 [judgment hint 2625 · suggestRename 2915/2946 · summarizeDocument 2970 · improveDocument 3003 · 自动压缩注入 1392] + `checkMinimax` 1127 + 适配器回落 1735 + 注释 2; 内核已有 `class ModelRuntime`(517 行, `acquire(snapshot): ModelLease` 只读) 与能力 9/9 ⇒ **缺的不是运行时, 是取舍**: ① snapshot 由谁传给 Pi (Run 级 vs 会话级) ② 辅助调用拿 lease 还是拿现 handle ③ `checkMinimax` 这种 Pi 专有探针是否保留 —— 三条都影响公开行为, 须拍板后再动, 不许硬编) · **③ Channel 状态 = 已量清, 实质完成** (Pi **无自有**通道状态字段: `this.channelId/currentSessionId/sessionKey/channelName` 赋值与读点均 **0**; 剩余 8 处 `actor.state.channelId` 读的正是 K5 actor —— 归属已在内核) · **⑦ 已查清处置**: 查 6 个导出时挖出 **`verifyWriteOutcome` 是"写后读回"纪律的唯一实现却 0 调用点, 且函数体用 `require('node:fs')`(ESM 产物里必炸、被自己 catch 吞成 `[未核对] … require is not defined` ⇒ 它一次都没成功过)** ⇒ 按"无替代路径不许删"**改为接上**: 拆成 `src/agents/write-verify.ts`(静态 import) + `withWriteVerified` 接进 `write_file`/`edit_file` 成功返回; 门 `k10-write-verify-wiring.test.ts` **10/10**(含两条端到端真跑) + **变异判红**(拆接线 ⇒ 2 条红); 其余 4 导出各有测试与用途 ⇒ **登记保留**, 不删 · · **④ 通信入口 = 首刀落地** (新增内核端口 `kernel/transport.ts`: `send/broadcast/peers` 三动作, 端口注入 + 未注入即拒 + `{ok:false}` 归一化 + 审计, 与 control/run-lifecycle 同一套写法; pi-sdk 的 `sendMessage`/`broadcast` 改经端口 + **失败一律抛**(发送有副作用: 静默丢消息比抛错更糟); 门 `k10-transport-port.test.ts` **8/8**(含真调方法体两条) + **变异判红**(绕过端口 ⇒ 3 条红, 直连真传输那次的失效形态正是 `Node not initialized`); **④ 后半已落地 = ④ 全接线**: 加**同步**读入口 `transportPeersSync(ports)` + `peersSync` 端口 (不硬塞进 async 的 `submitTransport` —— 分开是因为**签名**不是语义: 上层有同步调用点, sync 签名不能凭空变 async); `getPeers()`/`listPeers()` 改经端口: `listPeers` 在端口未注入时**明说"读不到"**(不假装"没有对端"), `getPeers()` 未注入时回落直读并 `console.warn` 留痕; 门扩到 **11/11**(同步入口两种注入态 + 真调方法体三态) + **变异判红**(同步读绕过端口 ⇒ `listPeers` 谎报"无对端", 门抓到)) · **⑦ 兼容层 6 个导出面** · **⑧ 是否删 Pi Adapter 本身 = 已按判据给出结论 (不物理删)**。量占比 (**行数口径**, 方法: 按方法块归类, 脚本在 `docs/wiki/log.md`): `pi-sdk.ts` **3497 行** ⇒ 传输/供应商 **14.4%** · turn-glue **14.0%** · 运行/通道/通信接线 **12.3%** · 文档辅助 **9.2%** · 其余 50.1% 通用编排/装配。**职责口径**: K0–K10 已把「循环 (K4-B) · 工具门 (K7) · Run 事实 (①) · 通道状态 (③) · 通信 (④) · 模型选择 (②)」**全部搬出 Pi** ⇒ 岗位职责只剩"传输适配 + 供应商/Harness 特性 + 文档辅助 + 端口接线"。**结论**: 按判据「迁移后 Pi 职责仍超原职责 30% ⇒ 不许宣称替换成功」—— 行数口径下 Pi 仍是本仓最大单体 ⇒ **不宣称替换成功** (诚实口径); **不物理删** (五个删除条件不满足: 传输在 Pi 有专有实现、无替代路径; 且属公开契约)。**下一刀候选** (已点名): 继续薄化那 12.3% 的运行/通道**接线**与 turn-glue 里的生命周期部分。
213
213
  };
214
214
  /**
215
215
  * **越权欠账台账 (棘轮)** —— 判据是「实际违规多重集 == 本表逐字相等」, 不是「⊆」:
@@ -230,15 +230,15 @@ export const AUTHORITY_DEBT_FROZEN_AT = 0; // 3 → 0 (K4 用内核控制面还
230
230
  * 目的只有一个: **不许所有逻辑回流到 kernel.ts**。要加就得显式抬这个数字, 留下痕迹。
231
231
  * 数值 = 当前 kernel 目录真实行数, 不留余量。
232
232
  */
233
- export const KERNEL_LINE_BUDGET = 3305; // 2026-10-02: K10 ② 内核新增 `snapshotFromSelection` 只读投影 (+20, 显式抬档); // 2026-10-02 **显式抬档 +22** (K8 收尾: channel-actor 加 `abortActorsOfChannel` + 台账/门同步) // 2026-10-02 **显式抬档 +16** (K10 ④ 后半: transport.ts 加同步读入口 `transportPeersSync` + `peersSync` 端口) // 2026-10-02 **显式抬档 +145** (K10 ④: 新增内核模块 kernel/transport.ts —— 通信入口端口) // 2026-10-02 **显式抬档 +184** (K10 ①: 新增内核模块 kernel/run-lifecycle.ts —— 运行生命周期写口, 与 control.ts 的控制面分开; 预算 == 真实值) // 2026-10-02: +1 (K4-B: gate-scan 复位阈值注释) // 2026-10-02: +5 (K8 正刀: gate-scan 加"收口字段数 3→1"+ queue 反回归) // 2026-10-02: +54 (K8: gate-scan 加 K8 判据) // 2026-10-02: +2 (STAGE_STATUS 拆 K4-A/K4-B + K6/K7 如实修正)
233
+ export const KERNEL_LINE_BUDGET = 3852; // 2026-10-02: 收尾自检规则 `kernel/code-write-gate.ts` 从 agents 侧整条搬入 (+49, 减法: agent 侧少一个模块) // 2026-10-02: 会话生命周期端口 `kernel/session-lifecycle.ts` (278 行) + `gate-scan` 播种锚点跟形状 (+4) —— **显式抬档 +282** (K10 余项; pi-sdk 本批 -18 行); // 2026-10-02 **显式抬档 +22** (K8 收尾: channel-actor 加 `abortActorsOfChannel` + 台账/门同步) // 2026-10-02 **显式抬档 +16** (K10 ④ 后半: transport.ts 加同步读入口 `transportPeersSync` + `peersSync` 端口) // 2026-10-02 **显式抬档 +145** (K10 ④: 新增内核模块 kernel/transport.ts —— 通信入口端口) // 2026-10-02 **显式抬档 +184** (K10 ①: 新增内核模块 kernel/run-lifecycle.ts —— 运行生命周期写口, 与 control.ts 的控制面分开; 预算 == 真实值) // 2026-10-02: +1 (K4-B: gate-scan 复位阈值注释) // 2026-10-02: +5 (K8 正刀: gate-scan 加"收口字段数 3→1"+ queue 反回归) // 2026-10-02: +54 (K8: gate-scan 加 K8 判据) // 2026-10-02: +2 (STAGE_STATUS 拆 K4-A/K4-B + K6/K7 如实修正)
234
234
  /** 预算冻结值 (棘轮: 只许减; 想抬预算必须同时改上面那个数字 ⇒ 一次显式动作, diff 里看得见) */
235
- export const KERNEL_LINE_BUDGET_FROZEN_AT = 3305; // 同步至 2026-10-02 真实值 (K10 ④ 新增 transport.ts 后)
235
+ export const KERNEL_LINE_BUDGET_FROZEN_AT = 3852; // 同步至 2026-10-02 真实值 (K10 ④ 新增 transport.ts 后)
236
236
  /**
237
237
  * K3b —— **台账数据**单独一档预算 (`src/kernel/plan.ts`)。
238
238
  *
239
239
  * 为什么分开: K3 要防的是「逻辑回流到内核代码」; 台账是**数据** (owner 名册 / 入口图 / 删除候选),
240
240
  * 把它算进代码预算会逼着人抬代码上限, 棘轮的信号就废了。两档各自冻结, 都只许减。
241
241
  */
242
- export const KERNEL_PLAN_LINE_BUDGET = 1442; // 2026-10-02 **显式抬档 +3** (K8 收尾: plan-communication 把 abortController 条目改成删除说明) // 2026-10-02: **收紧** -2 (queue 字段条目删除: 8 字段 → 7) // 2026-10-02: +14 (K8 前置自纠: 把错的"check-then-set 非原子"换成已核实的"handoff 丢消息") // 2026-10-02: K7 tscTool 端到端取证 (evidence 字段 + 变异/踩坑记录) ⇒ 显式抬档 +1 // 2026-10-02: K8 通道状态台账+门落地 ⇒ 显式抬档 (棘轮只许减, 抬档要一次显式动作) // 真实值 (删 ENTRY_GRAPH 一行后); 变异用例要求预算 == 真实值 // 2026-10-02: +91 (K8 台账 plan-communication.ts 落地) // 2026-10-02: +12 (K7 第二步 b: 旁路 status/symbol/evidence 字段 + 卫生规则注释 + 防漂用例)
242
+ export const KERNEL_PLAN_LINE_BUDGET = 1443; // 2026-10-02: Harness 台账登记「收尾自检执行点」搬进 kernel/turn-selfcheck.ts (+1) // 2026-10-02 **显式抬档 +3** (K8 收尾: plan-communication 把 abortController 条目改成删除说明) // 2026-10-02: **收紧** -2 (queue 字段条目删除: 8 字段 → 7) // 2026-10-02: +14 (K8 前置自纠: 把错的"check-then-set 非原子"换成已核实的"handoff 丢消息") // 2026-10-02: K7 tscTool 端到端取证 (evidence 字段 + 变异/踩坑记录) ⇒ 显式抬档 +1 // 2026-10-02: K8 通道状态台账+门落地 ⇒ 显式抬档 (棘轮只许减, 抬档要一次显式动作) // 真实值 (删 ENTRY_GRAPH 一行后); 变异用例要求预算 == 真实值 // 2026-10-02: +91 (K8 台账 plan-communication.ts 落地) // 2026-10-02: +12 (K7 第二步 b: 旁路 status/symbol/evidence 字段 + 卫生规则注释 + 防漂用例)
243
243
  /** 台账预算冻结值 (棘轮: 只许减) */
244
- export const KERNEL_PLAN_LINE_BUDGET_FROZEN_AT = 1442; // 同步至 2026-10-02 真实值
244
+ export const KERNEL_PLAN_LINE_BUDGET_FROZEN_AT = 1443; // 同步至 2026-10-02 真实值
@@ -25,6 +25,27 @@ export const RUN_LIFECYCLE_NEEDS_RUN_ID = {
25
25
  'finish-run': true,
26
26
  'save-checkpoint': true,
27
27
  };
28
+ /** 写原语 (由调用方注入; 内核只认形状) —— 对应 run-store 的 startRun/recordStep/finishRun/saveCheckpoint */
29
+ // ── K10 余项: 恢复相关的**纯规则** (从 pi-sdk 方法体里搬出来, 可单独判) ──────────
30
+ /**
31
+ * 恢复一次运行前, **要不要按 Run 快照重装运行时**。
32
+ * 规则: 一致 (`drifted=false` 且 `verified=true`) ⇒ **不重装** (运行时本来就是对的, 重装是白跑一趟);
33
+ * 漂了 (`drifted`) 或**核对不了** (`verified!==true`) ⇒ 装 (带着漂移继续跑会把漂移固化成历史)。
34
+ * 没有核对结论 (`undefined`) ⇒ 不装 (核对失败不阻塞恢复, 与迁移前一致)。
35
+ */
36
+ export function decideResumeReinstall(drift) {
37
+ if (!drift)
38
+ return false;
39
+ return drift.drifted === true || drift.verified !== true;
40
+ }
41
+ /**
42
+ * "上一次运行"的取值规则: **显式记录的 lastRunId 优先**, 没有才回落当前活跃运行。
43
+ * 为什么是规则: Supervisor / 控制面要在运行结束后问"刚才跑的是哪条 run",
44
+ * 而重启一轮时活跃运行已经被清空 —— 二者优先级搞反会让上层拿旧 run 做决策。
45
+ */
46
+ export function pickRunIdForResume(lastRunId, activeRunId) {
47
+ return String(lastRunId || activeRunId || '');
48
+ }
28
49
  /**
29
50
  * 端口**不抛异常但明确拒绝** (`{ ok: false, reason }`) 的归一化 —— 与 `control.ts` 同口径。
30
51
  * 为什么必须有: store 类原语用返回值表达拒绝 (例如状态迁移不合法), 只看"有没有抛"会把**被拒当成成功**。
@@ -0,0 +1,58 @@
1
+ /**
2
+ * run-resume.ts — K10 余项: **从 checkpoint 恢复一次运行的编排与政策** (从 pi-sdk 的方法体搬进内核)
3
+ *
4
+ * 搬走的是**序列与政策** (不是 I/O):
5
+ * ① 恢复前**反查模型配置**: Run 记录里的 `modelConfig` 快照不能只写不核 —— "快照记 A, 现在盘上生效 B"
6
+ * 这种漂移若被静默继续, 长任务的历史执行链就说不清了;
7
+ * ② 漂移的**上报口径**: 漂了 ⇒ warn (说清哪几个字段) · 一致 ⇒ info 一句明确结论 · **核对失败不阻塞恢复**;
8
+ * ③ **按 Run 快照装配运行时的判据** (`decideResumeReinstall`, 见 `run-lifecycle.ts`):
9
+ * 只在"漂了"或"核对不了"时装 —— 一致时运行时本来就是对的, 重装是白跑一趟; **装配失败也不阻塞恢复**;
10
+ * ④ 准备失败 ⇒ 直接把 `plan` 交回 (不驱动);恢复态的**单次语义**: 驱动前后由端口负责设置/清除 (finally 保证清)。
11
+ *
12
+ * I/O 全部端口注入 (核对 / 准备 / 装配 / 落态 / 驱动 / 清态 / 日志)。本模块不 import 任何 agent 侧模块。
13
+ */
14
+ import { decideResumeReinstall } from './run-lifecycle.js';
15
+ /**
16
+ * 恢复一次运行 —— **唯一入口**。语义与迁移前逐条一致 (见文件头 ①②③④); **本函数只在驱动阶段可能抛**
17
+ * (与迁移前一致: `prompt` 抛错会冒出去, 但恢复态**一定**被清), 其余每一步失败都**不阻塞恢复**。
18
+ */
19
+ export async function resumeRunViaKernel(runId, ports) {
20
+ let modelDrift;
21
+ let modelApplied;
22
+ try {
23
+ modelDrift = (await ports.detectDrift(runId)) || undefined;
24
+ if (modelDrift?.drifted) {
25
+ ports.log?.('warn', `恢复时模型配置已偏离 Run 快照: ${String(modelDrift.message ?? '')}`);
26
+ }
27
+ else if (modelDrift) {
28
+ ports.log?.('info', `恢复前核对: ${String(modelDrift.message ?? '')}`);
29
+ }
30
+ }
31
+ catch {
32
+ /* 核对本身失败不阻塞恢复 (与迁移前一致) */
33
+ }
34
+ const prep = await ports.prepareResume(runId);
35
+ if (!prep?.ok || !prep.plan) {
36
+ return { ok: false, reason: prep?.reason, ...(modelDrift ? { modelDrift } : {}) };
37
+ }
38
+ if (modelDrift && decideResumeReinstall(modelDrift)) {
39
+ try {
40
+ modelApplied = await ports.applySnapshot(modelDrift.snapshot);
41
+ ports.log?.('info', `已按 Run 快照装配运行时: ${String(modelApplied?.provider ?? '')}/${String(modelApplied?.model ?? '')}` +
42
+ ` (configHash ${String(modelApplied?.configHash ?? '').slice(0, 12)})`);
43
+ }
44
+ catch (e) {
45
+ // 装配失败不阻塞恢复 (如实说; 调用方可以从返回值里看出没装成)
46
+ ports.log?.('warn', `按 Run 快照装配运行时失败, 保持当前运行时: ${String(e?.message || e).slice(0, 160)}`);
47
+ modelApplied = undefined;
48
+ }
49
+ }
50
+ ports.applyPlan(prep.plan);
51
+ try {
52
+ const reply = await ports.continueRun(prep.plan);
53
+ return { ok: true, reply, ...(modelDrift ? { modelDrift } : {}), ...(modelApplied ? { modelApplied } : {}) };
54
+ }
55
+ finally {
56
+ ports.clearPlan();
57
+ }
58
+ }