@bolloon/bolloon-agent 0.5.4 → 0.6.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.
- package/dist/agents/agent-identity-store.js +41 -5
- package/dist/agents/background-notices.js +124 -0
- package/dist/agents/channel-identity.js +54 -0
- package/dist/agents/code-write-gate.js +47 -0
- package/dist/agents/deny-pipeline.js +11 -2
- package/dist/agents/egress-sanitize.js +69 -0
- package/dist/agents/error-classifier.js +67 -5
- package/dist/agents/experience-review.js +226 -0
- package/dist/agents/gateway-group.js +153 -18
- package/dist/agents/iteration-budget.js +64 -0
- package/dist/agents/lesson-to-skill.js +211 -0
- package/dist/agents/managed-services.js +64 -0
- package/dist/agents/parse-tool-call.js +43 -32
- package/dist/agents/pi-sdk-session-factory.js +36 -3
- package/dist/agents/pi-sdk-session-manager.js +72 -3
- package/dist/agents/pi-sdk-tools.js +201 -32
- package/dist/agents/pi-sdk.js +798 -206
- package/dist/agents/plan-store.js +36 -0
- package/dist/agents/process-runner.js +64 -2
- package/dist/agents/run-context.js +20 -0
- package/dist/agents/runner-resolver.js +2 -1
- package/dist/agents/shell-guard.js +109 -13
- package/dist/agents/skill-health.js +90 -0
- package/dist/agents/skill-ledger.js +129 -0
- package/dist/agents/tool-loop-guard.js +303 -0
- package/dist/agents/tool-path-args.js +53 -0
- package/dist/agents/tool-result-gate.js +50 -0
- package/dist/agents/tool-subset.js +109 -0
- package/dist/agents/tool-telemetry.js +97 -0
- package/dist/bootstrap/context-collector.js +37 -7
- package/dist/bootstrap/lifecycle-hooks.js +12 -3
- package/dist/bootstrap/persona-init.js +174 -0
- package/dist/bootstrap/persona-loader.js +5 -1
- package/dist/cli/ink-app.js +153 -6
- package/dist/cli/input-paste.js +218 -0
- package/dist/cli/loading-tui.js +3 -1
- package/dist/cli/log-gate.js +7 -0
- package/dist/cli/mention-data.js +30 -0
- package/dist/cli/reasoning-view.js +103 -0
- package/dist/cli/startup-notice.js +25 -0
- package/dist/cli/status-segments.js +87 -2
- package/dist/cli/trace-line.js +54 -0
- package/dist/context-compaction/auto-compact.js +37 -2
- package/dist/electron-build/agents/agent-identity-store.js +43 -5
- package/dist/electron-build/agents/agent-identity-store.js.map +1 -1
- package/dist/electron-build/agents/background-notices.js +138 -0
- package/dist/electron-build/agents/background-notices.js.map +1 -0
- package/dist/electron-build/agents/channel-identity.js +64 -0
- package/dist/electron-build/agents/channel-identity.js.map +1 -0
- package/dist/electron-build/agents/code-write-gate.js +55 -0
- package/dist/electron-build/agents/code-write-gate.js.map +1 -0
- package/dist/electron-build/agents/deny-pipeline.js +11 -2
- package/dist/electron-build/agents/deny-pipeline.js.map +1 -1
- package/dist/electron-build/agents/egress-sanitize.js +76 -0
- package/dist/electron-build/agents/egress-sanitize.js.map +1 -0
- package/dist/electron-build/agents/error-classifier.js +68 -5
- package/dist/electron-build/agents/error-classifier.js.map +1 -1
- package/dist/electron-build/agents/experience-review.js +243 -0
- package/dist/electron-build/agents/experience-review.js.map +1 -0
- package/dist/electron-build/agents/iteration-budget.js +73 -0
- package/dist/electron-build/agents/iteration-budget.js.map +1 -0
- package/dist/electron-build/agents/lesson-to-skill.js +228 -0
- package/dist/electron-build/agents/lesson-to-skill.js.map +1 -0
- package/dist/electron-build/agents/managed-services.js +69 -0
- package/dist/electron-build/agents/managed-services.js.map +1 -0
- package/dist/electron-build/agents/parse-tool-call.js +43 -32
- package/dist/electron-build/agents/parse-tool-call.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-session-factory.js +36 -3
- package/dist/electron-build/agents/pi-sdk-session-factory.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-session-manager.js +75 -3
- package/dist/electron-build/agents/pi-sdk-session-manager.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-tools.js +200 -31
- package/dist/electron-build/agents/pi-sdk-tools.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk-types.js.map +1 -1
- package/dist/electron-build/agents/pi-sdk.js +799 -206
- package/dist/electron-build/agents/pi-sdk.js.map +1 -1
- package/dist/electron-build/agents/plan-store.js +37 -0
- package/dist/electron-build/agents/plan-store.js.map +1 -1
- package/dist/electron-build/agents/process-runner.js +71 -2
- package/dist/electron-build/agents/process-runner.js.map +1 -1
- package/dist/electron-build/agents/run-context.js +24 -0
- package/dist/electron-build/agents/run-context.js.map +1 -0
- package/dist/electron-build/agents/runner-resolver.js +2 -1
- package/dist/electron-build/agents/runner-resolver.js.map +1 -1
- package/dist/electron-build/agents/shell-guard.js +110 -14
- package/dist/electron-build/agents/shell-guard.js.map +1 -1
- package/dist/electron-build/agents/skill-health.js +103 -0
- package/dist/electron-build/agents/skill-health.js.map +1 -0
- package/dist/electron-build/agents/skill-ledger.js +146 -0
- package/dist/electron-build/agents/skill-ledger.js.map +1 -0
- package/dist/electron-build/agents/tool-loop-guard.js +319 -0
- package/dist/electron-build/agents/tool-loop-guard.js.map +1 -0
- package/dist/electron-build/agents/tool-path-args.js +63 -0
- package/dist/electron-build/agents/tool-path-args.js.map +1 -0
- package/dist/electron-build/agents/tool-result-gate.js +59 -0
- package/dist/electron-build/agents/tool-result-gate.js.map +1 -0
- package/dist/electron-build/agents/tool-subset.js +116 -0
- package/dist/electron-build/agents/tool-subset.js.map +1 -0
- package/dist/electron-build/agents/tool-telemetry.js +108 -0
- package/dist/electron-build/agents/tool-telemetry.js.map +1 -0
- package/dist/electron-build/bootstrap/context-collector.js +38 -7
- package/dist/electron-build/bootstrap/context-collector.js.map +1 -1
- package/dist/electron-build/bootstrap/lifecycle-hooks.js +12 -3
- package/dist/electron-build/bootstrap/lifecycle-hooks.js.map +1 -1
- package/dist/electron-build/bootstrap/persona-init.js +216 -0
- package/dist/electron-build/bootstrap/persona-init.js.map +1 -0
- package/dist/electron-build/bootstrap/persona-loader.js +5 -1
- package/dist/electron-build/bootstrap/persona-loader.js.map +1 -1
- package/dist/electron-build/context-compaction/auto-compact.js +38 -2
- package/dist/electron-build/context-compaction/auto-compact.js.map +1 -1
- package/dist/electron-build/external-engines/delegate.js +22 -0
- package/dist/electron-build/external-engines/delegate.js.map +1 -1
- package/dist/electron-build/kernel/channel-actor.js +314 -0
- package/dist/electron-build/kernel/channel-actor.js.map +1 -0
- package/dist/electron-build/orbitdb/cid-database.js +55 -0
- package/dist/electron-build/orbitdb/cid-database.js.map +1 -1
- package/dist/electron-build/orbitdb/ipfs-node.js +36 -11
- package/dist/electron-build/orbitdb/ipfs-node.js.map +1 -1
- package/dist/electron-build/web/server-storage.js +26 -5
- package/dist/electron-build/web/server-storage.js.map +1 -1
- package/dist/external-engines/delegate.js +21 -0
- package/dist/index.js +526 -95
- package/dist/kernel/channel-actor.js +297 -0
- package/dist/kernel/control.js +95 -0
- package/dist/kernel/gate-scan.js +1036 -0
- package/dist/kernel/model-runtime.js +472 -0
- package/dist/kernel/plan-channel-actor.js +298 -0
- package/dist/kernel/plan-constraint.js +165 -0
- package/dist/kernel/plan-deletion.js +32 -0
- package/dist/kernel/plan-modelruntime.js +60 -0
- package/dist/kernel/plan-runcontext.js +163 -0
- package/dist/kernel/plan.js +153 -0
- package/dist/kernel/roster.js +242 -0
- package/dist/orbitdb/cid-database.js +55 -0
- package/dist/orbitdb/event-index.js +370 -0
- package/dist/orbitdb/event-query.js +131 -0
- package/dist/orbitdb/event-shell.js +510 -0
- package/dist/orbitdb/group-access.js +381 -0
- package/dist/orbitdb/group-shards.js +140 -0
- package/dist/orbitdb/ipfs-node.js +36 -11
- package/dist/web/bolloon-web.json +3 -3
- package/dist/web/client.js +4 -2
- package/dist/web/mobile-core.js +7762 -6289
- package/dist/web/routes-mobile-tasks.js +2 -1
- package/dist/web/routes-tasks.js +5 -1
- package/dist/web/server-storage.js +26 -5
- package/dist/web/server.js +60 -18
- package/dist/web/sw.js +1 -1
- package/dist/web/ui/message-renderer.js +473 -29
- package/dist/web/ui/step-timeline.js +13 -12
- package/package.json +2 -1
- package/scripts/build-web.ts +74 -1
- package/dist/constraint-runtime/_archive_helper.d.ts +0 -1
- package/dist/constraint-runtime/_archive_helper.js +0 -9
- package/dist/constraint-runtime/assistant/index.d.ts +0 -11
- package/dist/constraint-runtime/assistant/index.js +0 -12
- package/dist/constraint-runtime/bootstrap/index.d.ts +0 -11
- package/dist/constraint-runtime/bootstrap/index.js +0 -12
- package/dist/constraint-runtime/bridge/index.d.ts +0 -11
- package/dist/constraint-runtime/bridge/index.js +0 -12
- package/dist/constraint-runtime/buddy/index.d.ts +0 -11
- package/dist/constraint-runtime/buddy/index.js +0 -12
- package/dist/constraint-runtime/cli/index.d.ts +0 -11
- package/dist/constraint-runtime/cli/index.js +0 -12
- package/dist/constraint-runtime/components/index.d.ts +0 -11
- package/dist/constraint-runtime/components/index.js +0 -12
- package/dist/constraint-runtime/constants/index.d.ts +0 -11
- package/dist/constraint-runtime/constants/index.js +0 -12
- package/dist/constraint-runtime/coordinator/index.d.ts +0 -11
- package/dist/constraint-runtime/coordinator/index.js +0 -12
- package/dist/constraint-runtime/cost_hook.d.ts +0 -2
- package/dist/constraint-runtime/cost_hook.js +0 -4
- package/dist/constraint-runtime/entrypoints/index.d.ts +0 -11
- package/dist/constraint-runtime/entrypoints/index.js +0 -12
- package/dist/constraint-runtime/execution_registry.d.ts +0 -20
- package/dist/constraint-runtime/execution_registry.js +0 -44
- package/dist/constraint-runtime/hooks/index.d.ts +0 -11
- package/dist/constraint-runtime/hooks/index.js +0 -12
- package/dist/constraint-runtime/ink.d.ts +0 -1
- package/dist/constraint-runtime/ink.js +0 -4
- package/dist/constraint-runtime/keybindings/index.d.ts +0 -11
- package/dist/constraint-runtime/keybindings/index.js +0 -12
- package/dist/constraint-runtime/memdir/index.d.ts +0 -11
- package/dist/constraint-runtime/memdir/index.js +0 -12
- package/dist/constraint-runtime/migrations/index.d.ts +0 -11
- package/dist/constraint-runtime/migrations/index.js +0 -12
- package/dist/constraint-runtime/moreright/index.d.ts +0 -11
- package/dist/constraint-runtime/moreright/index.js +0 -12
- package/dist/constraint-runtime/native_ts/index.d.ts +0 -11
- package/dist/constraint-runtime/native_ts/index.js +0 -12
- package/dist/constraint-runtime/output_styles/index.d.ts +0 -11
- package/dist/constraint-runtime/output_styles/index.js +0 -12
- package/dist/constraint-runtime/plugins/index.d.ts +0 -11
- package/dist/constraint-runtime/plugins/index.js +0 -12
- package/dist/constraint-runtime/port_manifest.d.ts +0 -7
- package/dist/constraint-runtime/port_manifest.js +0 -11
- package/dist/constraint-runtime/query.d.ts +0 -6
- package/dist/constraint-runtime/query.js +0 -1
- package/dist/constraint-runtime/remote/index.d.ts +0 -11
- package/dist/constraint-runtime/remote/index.js +0 -12
- package/dist/constraint-runtime/schemas/index.d.ts +0 -11
- package/dist/constraint-runtime/schemas/index.js +0 -12
- package/dist/constraint-runtime/screens/index.d.ts +0 -11
- package/dist/constraint-runtime/screens/index.js +0 -12
- package/dist/constraint-runtime/server/index.d.ts +0 -11
- package/dist/constraint-runtime/server/index.js +0 -12
- package/dist/constraint-runtime/services/index.d.ts +0 -11
- package/dist/constraint-runtime/services/index.js +0 -12
- package/dist/constraint-runtime/state/index.d.ts +0 -11
- package/dist/constraint-runtime/state/index.js +0 -12
- package/dist/constraint-runtime/system_init.d.ts +0 -1
- package/dist/constraint-runtime/system_init.js +0 -20
- package/dist/constraint-runtime/types/index.d.ts +0 -11
- package/dist/constraint-runtime/types/index.js +0 -12
- package/dist/constraint-runtime/upstream_proxy/index.d.ts +0 -11
- package/dist/constraint-runtime/upstream_proxy/index.js +0 -12
- package/dist/constraint-runtime/utils/index.d.ts +0 -11
- package/dist/constraint-runtime/utils/index.js +0 -12
- package/dist/constraint-runtime/vim/index.d.ts +0 -11
- package/dist/constraint-runtime/vim/index.js +0 -12
- package/dist/constraint-runtime/voice/index.d.ts +0 -11
- package/dist/constraint-runtime/voice/index.js +0 -12
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **K2 台账: RunContext 状态外置** —— Pi 实例上的可变运行状态, 要搬进显式 RunContext。
|
|
3
|
+
*
|
|
4
|
+
* 现状 (2026-10-02 真读, 剥注释后计数): `agents/pi-sdk.ts` **4099 行**里 **8 个字段 / 185 处 `this.` 访问**, 且
|
|
5
|
+
* `runReActLoop(onStream?, signal?)` 只收 2 个参数却隐式依赖这 8 个字段 ⇒ 并发 Run 之间靠实例字段互相污染。
|
|
6
|
+
*
|
|
7
|
+
* 门的口径 (`src/test/kernel-runcontext.test.ts`):
|
|
8
|
+
* · 逐字段计数必须与冻结值**双向相等** (多一处 = 新增泄漏; 少一处 = 改了代码没改账, 要显式 rebase);
|
|
9
|
+
* · 标了 `migrated` 的字段 `this.` 访问必须为 **0** (假完成判红);
|
|
10
|
+
* · 8 个字段必须都能在 RunContext 目标清单里找到位置 (不然外置到哪里去)。
|
|
11
|
+
*/
|
|
12
|
+
export const RUN_CONTEXT_FILES = ['agents/pi-sdk.ts'];
|
|
13
|
+
export const RUN_CONTEXT_FROZEN_AT = '2026-10-02';
|
|
14
|
+
export const RUN_CONTEXT_ENTRY = 'agents/pi-sdk.ts:1923 runReActLoop(onStream?, signal?) —— 目标签名: runReActLoop(ctx: RunContext)';
|
|
15
|
+
export const RUN_CONTEXT_FIELDS = [
|
|
16
|
+
{ name: 'messageHistory', declaredAt: '(已删, 见 K5 步骤⑧)', scope: 'session', accesses: 0, into: 'history', migrated: false, payDownIn: 'K2' },
|
|
17
|
+
{ name: 'currentOnStream', declaredAt: 'agents/pi-sdk.ts:442', scope: 'run', accesses: 0, into: 'eventSink', migrated: true, payDownIn: 'K2' },
|
|
18
|
+
{ name: 'currentSignal', declaredAt: 'agents/pi-sdk.ts:443', scope: 'run', accesses: 0, into: 'abortSignal', migrated: true, payDownIn: 'K2' },
|
|
19
|
+
{ name: 'currentChannelId', declaredAt: '(已删, 见 K5 步骤⑧ 批次4)', scope: 'session', accesses: 0, into: 'channelId', migrated: false, payDownIn: 'K2' },
|
|
20
|
+
{ name: 'currentRunId', declaredAt: '(已删, 见 K5 步骤⑧ 批次5)', scope: 'run-boundary', accesses: 0, into: 'runId', migrated: false, payDownIn: 'K2' },
|
|
21
|
+
{ name: 'currentIntent', declaredAt: 'agents/pi-sdk.ts:463', scope: 'run', accesses: 0, into: 'intent', migrated: true, payDownIn: 'K2' },
|
|
22
|
+
{ name: 'currentGoalId', declaredAt: '(已删, 见 K5 步骤⑧ 批次3)', scope: 'session', accesses: 0, into: 'goalId', migrated: false, payDownIn: 'K2' },
|
|
23
|
+
{ name: 'currentAgentId', declaredAt: '(已删, 见 K5 步骤⑧ 批次2)', scope: 'session', accesses: 0, into: 'agentId', migrated: false, payDownIn: 'K2' },
|
|
24
|
+
];
|
|
25
|
+
/** RunContext 必须带的字段 (leo 的 K2 清单) */
|
|
26
|
+
export const RUN_CONTEXT_TARGET = ["requestId", "channelId", "agentId", "goalId", "runId", "intent", "modelSnapshot", "history", "abortSignal", "budget", "eventSink", "harnessContext"];
|
|
27
|
+
/** 冻结总量 (棘轮只许减) */
|
|
28
|
+
export const RUN_CONTEXT_ACCESS_TOTAL = 0; // 批次5: 8 个字段全部迁出 ⇒ Pi 侧 0 处访问
|
|
29
|
+
/** 已外置字段数 (棘轮: 只许增)。改动这里 = 明确宣告"又搬完一个字段" */
|
|
30
|
+
export const RUN_CONTEXT_MIGRATED_FROZEN = 3;
|
|
31
|
+
/**
|
|
32
|
+
* 已迁移字段的落地位置 (便于人工复核"搬去哪了"):
|
|
33
|
+
* · currentOnStream → `src/agents/run-context.ts` 的 `RunContext.eventSink`
|
|
34
|
+
* (入口 `createRunContext({ eventSink })` 快照; 清空 = 换一个空 Context; 15 处访问归零)
|
|
35
|
+
*/
|
|
36
|
+
export const RUN_CONTEXT_DONE = ['currentOnStream', 'currentSignal', 'currentIntent'];
|
|
37
|
+
/** K2 的 per-run 外置面 = scope:'run' 的字段数 (session 级的不算) */
|
|
38
|
+
export const RUN_CONTEXT_RUN_SCOPED = 3;
|
|
39
|
+
/**
|
|
40
|
+
* **K2 第 4 格改判记录: `currentGoalId` 是 session 级, 不搬进 RunContext。**
|
|
41
|
+
*
|
|
42
|
+
* 证据 (2026-10-02 真读 `pi-sdk.ts`):
|
|
43
|
+
* · 写入口① `setGoalId(goalId)` (行 1747) —— **公开 API**, CLI/Web/runner 在 run **之前**注入
|
|
44
|
+
* ("有 goalId 就在该 Goal 下执行" ⇒ 这是会话绑定, 不是本轮状态);
|
|
45
|
+
* · 写入口② run 内部 (行 2024 / 1091): 未绑定时 `findActiveGoal` 或 `createGoal` 再 `startRun({ goalId })`
|
|
46
|
+
* —— **run 会写它, 且必须活到下一个 run**;
|
|
47
|
+
* · 读出口: harness 上下文 (行 1914) · 轨迹/报告 (行 2866/2995/3006/3023) · `bindExternalWait` (1804-1806);
|
|
48
|
+
* · 行 1081/1091 · 2003/2024 有 "暂存-重绑-还原" 模式 (跨块共享)。
|
|
49
|
+
*
|
|
50
|
+
* 为什么不能"入口 copy 一份进 Context": run 内的写会落进 per-run ctx ⇒ 会话字段不被更新 ⇒
|
|
51
|
+
* 下一个 run 走"未绑定 ⇒ 重新 findActiveGoal"分支 ⇒ **行为改变** (旧行为是复用同一绑定)。
|
|
52
|
+
*
|
|
53
|
+
* 结论: 它该收进的是**会话/通道级持有者** (K5 Channel Actor 的 actor 状态), 不是 RunContext。K2 不碰它。
|
|
54
|
+
*/
|
|
55
|
+
export const RUN_CONTEXT_SESSION_SCOPED_NOTE = 'currentGoalId: 会话级绑定 (setGoalId 外部注入 + run 内可能重绑), 归 K5 actor 状态, 不进 RunContext';
|
|
56
|
+
/**
|
|
57
|
+
* **K2 第 5~8 格改判记录 (2026-10-02, 一次把剩下 4 个字段全定性)**
|
|
58
|
+
*
|
|
59
|
+
* 逐字段证据 (真读 `pi-sdk.ts` 的**写入点**, 不是看名字):
|
|
60
|
+
*
|
|
61
|
+
* | 字段 | 写入点 | 判定 |
|
|
62
|
+
* | --- | --- | --- |
|
|
63
|
+
* | `currentAgentId` (20) | **只有 1 个**: 构造函数 547 行 `= config.agentId` (createAgentSession 注入) | **session 级** —— 会话创建时定 |
|
|
64
|
+
* | `currentChannelId` (21) | 4 个, 全是 `= channelId ?? this.currentChannelId` (显式**保留**上一轮的值) / 3895 直设 | **session 级** —— 设计上就跨 Run 存活 |
|
|
65
|
+
* | `messageHistory` (53) | 3 个, 全是整体替换 (hydrate 680 / compact 3243 / 真破坏性更新 3445) | **session 级** —— 它就是"会话记忆"本身, 跨 Run 累积 |
|
|
66
|
+
* | `currentRunId` (36) | 1989 行在 resume 里 `= this.resumeRunId` **然后才调 prompt**; 2036 在 run 内; 3034/3038 清空 | **run-boundary** —— 属 Run, 但值在入口之前就设好 ⇒ 必须由入口**显式播种** |
|
|
67
|
+
*
|
|
68
|
+
* ⇒ **K2 的 per-run 外置面只有 3 个字段** (`eventSink` / `abortSignal` / `intent`), **且已 100% 完成**
|
|
69
|
+
* (`RUN_CONTEXT_RUN_SCOPED = 3` == `RUN_CONTEXT_DONE.length`)。
|
|
70
|
+
*
|
|
71
|
+
* ⇒ 剩下 5 个不属于"每轮状态": 4 个 session 级该收进**会话/通道级持有者** (K5 Channel Actor 的 actor 状态);
|
|
72
|
+
* 1 个 run-boundary 需要一个**入口播种**动作 (在 `createRunContext(...)` 里显式带上 runId) ——
|
|
73
|
+
* 播种会新增对旧实例字段的读, 所以它必须作为**独立一格**记账并说明理由, 不能混在"纯减"里。
|
|
74
|
+
*
|
|
75
|
+
* ⇒ **连带结论 (对 K2 验收标准的影响)**: leo 写的「两个并发 Run 的 history 不互相污染」**不是 K2 能靠搬字段达成的**
|
|
76
|
+
* —— `messageHistory` 是会话记忆, 共享是它的本质; 要"不互相污染"必须让**每个 channel 有自己的会话/history**
|
|
77
|
+
* (K5 Channel Actor), 或让每个 Run 在不可变基准上各写各自的分支。**这条验收标准的落点应改判到 K5。**
|
|
78
|
+
*/
|
|
79
|
+
export const RUN_CONTEXT_REMAINING_NOTE = 'remaining 4: agentId/channelId/messageHistory = session 级 (K5 actor); runId = 入口播种 (独立一格)';
|
|
80
|
+
/**
|
|
81
|
+
* **K2 收尾 (leo 2026-10-02 口径) —— 播种读取单独记账**
|
|
82
|
+
*
|
|
83
|
+
* `currentRunId` 属 **run-boundary**: 它对 Run 是真状态, 但值在**入口之前**就设好 (resume 路径
|
|
84
|
+
* `this.currentRunId = this.resumeRunId` 然后才调 prompt) ⇒ 循环内部不该再去读实例字段。
|
|
85
|
+
*
|
|
86
|
+
* 允许**一次**显式播种 (只在 `PiAgentSession.seedRunContext()` 里):
|
|
87
|
+
* createRunContext({ runId: this.currentRunId, ...extra })
|
|
88
|
+
*
|
|
89
|
+
* 记账规则 (三条, 由门强制):
|
|
90
|
+
* · `CURRENT_RUN_ID_SEED_READS = 1` —— 播种读取**恰好一处**, 且必须在 `seedRunContext` 体内;
|
|
91
|
+
* · `CURRENT_RUN_ID_SEED_SITES = 2` —— 调用播种的入口恰好两个 (`prompt` / `promptStream`), 且都在循环之外;
|
|
92
|
+
* · `currentRunId.accesses = 38 = 37(历史匹配) + 1(播种)` —— **不计进"必须下降"的纯迁移统计**, 也**不算 K2 未完成**。
|
|
93
|
+
*
|
|
94
|
+
* 性质: 只在进入一次 Run 时发生; 只把已有恢复身份播种给 RunContext; 不是循环内部重新读旧实例状态;
|
|
95
|
+
* 不得成为新的写入口。**K5 完成后**改为 `createRunContext({ runId: request.resumeRunId })`, 届时删除该字段本体。
|
|
96
|
+
*/
|
|
97
|
+
export const CURRENT_RUN_ID_SEED_READS = 1;
|
|
98
|
+
export const CURRENT_RUN_ID_SEED_SITES = 2;
|
|
99
|
+
export const CURRENT_RUN_ID_SEED_NOTE = 'run-boundary 播种 (口径=判据同款/匹配次数): 批次5 后 pi-sdk 侧 currentRunId = 0 处 (名字已不存在); 播种读取只剩 seedRunContext 内一处, 读的是本体 actor.state.activeRun';
|
|
100
|
+
/**
|
|
101
|
+
* **K2 验收标准 (leo 2026-10-02 修订 —— 把 history 并发隔离移出)**
|
|
102
|
+
* ① 三个 run 级字段 (eventSink / abortSignal / intent) 全部迁移;
|
|
103
|
+
* ② `RunContext` 接线完整 (入口建 Context · 循环从 Context 取值);
|
|
104
|
+
* ③ 循环使用**显式** Context, 不再隐式读已迁移的 run 级实例字段;
|
|
105
|
+
* ④ 已迁移字段零 `this.` 残留;
|
|
106
|
+
* ⑤ 新 Run **不继承**上一 Run 的 event / signal / intent (未给字段显式置空);
|
|
107
|
+
* ⑥ `currentRunId` 的播种读取**只有一个冻结入口** (`seedRunContext`);
|
|
108
|
+
* ⑦ **不要求** K2 解决 session history 并发隔离 (那条移给 K5)。
|
|
109
|
+
*/
|
|
110
|
+
export const K2_ACCEPTANCE = [
|
|
111
|
+
'① run 级 3 字段全迁移',
|
|
112
|
+
'② RunContext 接线完整 (入口建 · 循环从 Context 取)',
|
|
113
|
+
'③ 循环只吃显式 Context',
|
|
114
|
+
'④ 已迁移字段零 this. 残留',
|
|
115
|
+
'⑤ 新 Run 不继承上一 Run 的 event/signal/intent',
|
|
116
|
+
'⑥ currentRunId 播种只有一个冻结入口',
|
|
117
|
+
'⑦ 不含 history 并发隔离 (→ K5)',
|
|
118
|
+
];
|
|
119
|
+
/**
|
|
120
|
+
* **K5 验收标准 (leo 2026-10-02 增加 —— 承接从 K2 移出的部分)**
|
|
121
|
+
* ① 同 Channel 消息串行 (输入只能排队, 不能并发改 history);
|
|
122
|
+
* ② 不同 Channel history 不交叉 (完全隔离);
|
|
123
|
+
* ③ 同一 Channel 的多个 Run 不互相污染 (靠 Actor 串行调度 + Run 边界隔离);
|
|
124
|
+
* ④ 页面 / CLI / P2P / Supervisor 都进入同一 Actor mailbox;
|
|
125
|
+
* ⑤ Actor 崩溃后可由 Supervisor 恢复;
|
|
126
|
+
* ⑥ `messageHistory` 不再由 Pi 直接拥有。
|
|
127
|
+
*/
|
|
128
|
+
export const K5_ACCEPTANCE = [
|
|
129
|
+
'① 同 Channel 串行 (排队, 不并发改 history)',
|
|
130
|
+
'② 不同 Channel history 完全隔离',
|
|
131
|
+
'③ 同 Channel 多 Run 不互相污染',
|
|
132
|
+
'④ 页面/CLI/P2P/Supervisor 进同一 mailbox',
|
|
133
|
+
'⑤ Actor 崩溃可由 Supervisor 恢复',
|
|
134
|
+
'⑥ messageHistory 不再由 Pi 拥有',
|
|
135
|
+
];
|
|
136
|
+
/** 两个百分比**不能合并** (leo 口径: 合并会产生误导) */
|
|
137
|
+
export const K2_PROGRESS = {
|
|
138
|
+
runContextExternalized: '100%',
|
|
139
|
+
sessionActorization: '未开始',
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* **口径统一说明 (2026-10-02, 必读, 否则会误读数字)**
|
|
143
|
+
*
|
|
144
|
+
* 判据原先按**行数**计 (`if (rx.test(line)) actual += 1`), 而 K2 收尾新加的播种判据按**匹配次数**计
|
|
145
|
+
* ⇒ 同一条台账在 1916 行那种"一行含两处"的地方给出 37 / 38 两个答案。**已统一为匹配次数**。
|
|
146
|
+
*
|
|
147
|
+
* 因此逐字段冻结值被整体重算过, session 级那几个"变大"**不是新增泄漏, 是口径变化**:
|
|
148
|
+
*
|
|
149
|
+
* | 字段 | 行数口径(旧) | 匹配口径(现) |
|
|
150
|
+
* | --- | --- | --- |
|
|
151
|
+
* | messageHistory | 53 | **56** |
|
|
152
|
+
* | currentChannelId | 21 | **24** |
|
|
153
|
+
* | currentGoalId | 19 | **22** |
|
|
154
|
+
* | currentAgentId | 20 | **21** |
|
|
155
|
+
* | currentRunId | 36(+1播种) | **38** |
|
|
156
|
+
*
|
|
157
|
+
* **同口径的迁移前/后对比** (用匹配口径回算提交 `04f64fb` = K2 第一次迁移之前):
|
|
158
|
+
* 迁移前 **193** → 现在 **161** (净 **-32**)。拆解: 三个 run 级字段 **-33** (15 + 8 + 10)
|
|
159
|
+
* + run-boundary 播种 **+1** (记账例外: 不计入"必须下降"的纯迁移统计, 也不算 K2 未完成)。
|
|
160
|
+
* 三个 run 级字段: currentOnStream 15→0 · currentSignal 8→0 · currentIntent 10→0。
|
|
161
|
+
* 其余 5 个 session/run-boundary 字段在**同口径**下逐字未变 (变大纯属换口径)。
|
|
162
|
+
*/
|
|
163
|
+
export const RUN_CONTEXT_COUNT_METHOD = 'match-count (不是行数; 一行含两处记 2)';
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* K0 ②③④ —— 模块 owner 名册 · 入口调用关系图 · 旧代码删除台账 (冻结面, 数据, 零 import)
|
|
3
|
+
*
|
|
4
|
+
* 这三样是 leo 修订版 K0 的缺项 (原 K0 只交了 import 白名单 / 越权检测 / 行数棘轮)。
|
|
5
|
+
* 判据: src/test/kernel-plan.test.ts; 纯函数: src/kernel/gate-scan.ts。
|
|
6
|
+
*
|
|
7
|
+
* 生成口径 (防"好看的架构图"):
|
|
8
|
+
* · owner 名册由**真实文件清单机械生成** + 逐条处置 —— 门枚举 src/ 每个产品码文件, 必须恰好命中一条;
|
|
9
|
+
* · ENTRY_GRAPH 每行由**判据自己扫出来的**调用点填 (不手写): 门重扫一次必须逐字相等 (含 count);
|
|
10
|
+
* · 删除候选集用**集合 sha256** 冻结: 增/删/替换任一条都变哈希 ⇒ 红。
|
|
11
|
+
*/
|
|
12
|
+
/** ② 模块 owner 名册 —— 覆盖 src/ 全部产品码 (test/ 与 constraint-runtime/ 另册) */
|
|
13
|
+
export const MODULE_OWNERS = [
|
|
14
|
+
{ key: 'kernel/', module: 'kernel', owner: '内核线', disposition: 'keep', phase: 'K0', note: "K1/K2/K3 三道门 + 台账" },
|
|
15
|
+
{ key: 'agents/pi-sdk.ts', module: 'adapter', owner: '推理适配器线', disposition: 'converge', phase: 'K2/K4/K10', note: "Pi 可变状态外置 → 拆 Adapter" },
|
|
16
|
+
{ key: 'agents/workflow-pivot-loop.ts', module: 'adapter', owner: '推理适配器线', disposition: 'converge', phase: 'K4', note: "旧 loop 降为策略" },
|
|
17
|
+
{ key: 'agents/loop-review.ts', module: 'adapter', owner: '推理适配器线', disposition: 'converge', phase: 'K4', note: "并进 KernelLoop 的 reducer 段" },
|
|
18
|
+
{ key: 'agents/react-loop.ts', module: 'adapter', owner: '推理适配器线', disposition: 'converge', phase: 'K4', note: "并进 KernelLoop" },
|
|
19
|
+
{ key: 'agents/pi-sdk-tools.ts', module: 'tools', owner: 'Tool 线', disposition: 'converge', phase: 'K7', note: "经 Harness 唯一门" },
|
|
20
|
+
{ key: 'agents/pi-harness.ts', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "已是唯一门面, 继续补齐" },
|
|
21
|
+
{ key: 'agents/deny-pipeline.ts', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "" },
|
|
22
|
+
{ key: 'agents/pre-tool-validator.ts', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "" },
|
|
23
|
+
{ key: 'agents/permission-mode.ts', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "" },
|
|
24
|
+
{ key: 'agents/shell-guard.ts', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "" },
|
|
25
|
+
{ key: 'agents/goal-store.ts', module: 'state', owner: 'Goal-Run 线', disposition: 'keep', phase: 'K2', note: "唯一事实来源" },
|
|
26
|
+
{ key: 'agents/run-store.ts', module: 'state', owner: 'Goal-Run 线', disposition: 'keep', phase: 'K2', note: "唯一事实来源" },
|
|
27
|
+
{ key: 'agents/decision-store.ts', module: 'state', owner: 'Goal-Run 线', disposition: 'keep', phase: 'K2', note: "" },
|
|
28
|
+
{ key: 'agents/plan-store.ts', module: 'state', owner: 'Goal-Run 线', disposition: 'keep', phase: 'K2', note: "" },
|
|
29
|
+
{ key: 'agents/pi-sdk-session-manager.ts', module: 'channel', owner: 'Channel 线', disposition: 'converge', phase: 'K2', note: "Session 不再是全局可变状态中心" },
|
|
30
|
+
{ key: 'agents/pi-sdk-session-factory.ts', module: 'channel', owner: 'Channel 线', disposition: 'converge', phase: 'K2', note: "" },
|
|
31
|
+
{ key: 'agents/session-store.ts', module: 'channel', owner: 'Channel 线', disposition: 'keep', phase: 'K2', note: "" },
|
|
32
|
+
{ key: 'agents/', module: 'agents-misc', owner: 'Agent 装配线', disposition: 'converge', phase: 'K2/K7', note: "逐个判归宿: 状态类→state, 工具类→tools" },
|
|
33
|
+
{ key: 'llm/', module: 'llm', owner: 'Model 线', disposition: 'keep', phase: 'K6', note: "唯一写口保留, 加 ModelRuntime 只读层" },
|
|
34
|
+
{ key: 'security/', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "" },
|
|
35
|
+
{ key: 'web/', module: 'channel-web', owner: 'Channel 线', disposition: 'converge', phase: 'K3/K5', note: "入口只能投递事件" },
|
|
36
|
+
{ key: 'cli/', module: 'cli', owner: 'CLI 表面线', disposition: 'converge', phase: 'K3', note: "与 Web 共用同一 KernelLoop" },
|
|
37
|
+
{ key: 'external-engines/', module: 'delegate', owner: '子 Agent 线', disposition: 'converge', phase: 'K7', note: "子 Agent 不能结束 Goal" },
|
|
38
|
+
{ key: 'bollharness/', module: 'bollharness', owner: '外部项目镜像', disposition: 'freeze', phase: '第一批审查', note: "**不是 Bolloon 运行时**; 68 文件, 61 个 0 入边" },
|
|
39
|
+
{ key: 'bollharness-integration/', module: 'bollharness-integration', owner: 'Harness 集成线', disposition: 'freeze', phase: '第一批审查', note: "" },
|
|
40
|
+
{ key: 'bootstrap/', module: 'bootstrap', owner: '装配/上下文线', disposition: 'converge', phase: 'K2', note: "Context 归 RunContext/ChannelContext" },
|
|
41
|
+
{ key: 'context-compaction/', module: 'bootstrap', owner: '装配/上下文线', disposition: 'converge', phase: 'K2', note: "" },
|
|
42
|
+
{ key: 'cron/', module: 'channel', owner: 'Channel 线', disposition: 'converge', phase: 'K3', note: "入口只能投递事件" },
|
|
43
|
+
{ key: 'network/', module: 'communication', owner: '通信线', disposition: 'converge', phase: 'K8', note: "绝不能 transport → agent.promptStream" },
|
|
44
|
+
{ key: 'git-transport/', module: 'communication', owner: '通信线', disposition: 'converge', phase: 'K8', note: "" },
|
|
45
|
+
{ key: 'orbitdb/', module: 'communication', owner: '通信线', disposition: 'keep', phase: 'K8', note: "群/事件层已被 P0-P5 验收" },
|
|
46
|
+
{ key: 'heartbeat/', module: 'communication', owner: '通信线', disposition: 'converge', phase: 'K8', note: "" },
|
|
47
|
+
{ key: 'social/', module: 'communication', owner: '通信线', disposition: 'converge', phase: 'K8', note: "" },
|
|
48
|
+
{ key: 'pi-ecosystem-judgment/', module: 'judgment', owner: '判断力线', disposition: 'converge', phase: 'K7', note: "经 Harness 接入" },
|
|
49
|
+
{ key: 'judgeness/', module: 'judgment', owner: '判断力线', disposition: 'converge', phase: 'K7', note: "" },
|
|
50
|
+
{ key: 'pi-ecosystem-mcp/', module: 'judgment', owner: 'MCP 线', disposition: 'converge', phase: 'K7', note: "MCP 不能绕过 Harness" },
|
|
51
|
+
{ key: 'pi-ecosystem-a2ui/', module: 'judgment', owner: 'UI 桥线', disposition: 'freeze', phase: 'K7', note: "" },
|
|
52
|
+
{ key: 'pi-ecosystem-goals/', module: 'state', owner: 'Goal-Run 线', disposition: 'freeze', phase: 'K2', note: "与 goal-store 职责待收敛" },
|
|
53
|
+
{ key: 'workflows/', module: 'adapter', owner: '推理适配器线', disposition: 'converge', phase: 'K4', note: "" },
|
|
54
|
+
{ key: 'documents/', module: 'tools', owner: 'Tool 线', disposition: 'converge', phase: 'K7', note: "" },
|
|
55
|
+
{ key: 'lsp/', module: 'tools', owner: 'Tool 线', disposition: 'converge', phase: 'K7', note: "" },
|
|
56
|
+
{ key: 'hooks/', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "hooks-engine 属策略面" },
|
|
57
|
+
{ key: 'constraints/', module: 'policy', owner: 'Harness 线', disposition: 'keep', phase: 'K7', note: "" },
|
|
58
|
+
{ key: 'storage/', module: 'state', owner: 'Goal-Run 线', disposition: 'keep', phase: 'K2', note: "" },
|
|
59
|
+
{ key: 'setup/', module: 'bootstrap', owner: '装配/上下文线', disposition: 'converge', phase: 'K2', note: "" },
|
|
60
|
+
{ key: 'utils/', module: 'shared', owner: '共享原语线', disposition: 'keep', phase: '—', note: "全仓可用的纯工具" },
|
|
61
|
+
{ key: 'locales/', module: 'shared', owner: '共享原语线', disposition: 'keep', phase: '—', note: "" },
|
|
62
|
+
{ key: 'efficode/', module: 'efficode', owner: '对外协议线', disposition: 'freeze', phase: '第一批审查', note: "AI 间交流语言, 不属内核" },
|
|
63
|
+
{ key: 'electron/', module: 'electron', owner: '桌面壳', disposition: 'freeze', phase: '第一批审查', note: "" },
|
|
64
|
+
{ key: 'migration/', module: 'migration', owner: '迁移脚本', disposition: 'freeze', phase: '第一批审查', note: "一次性" },
|
|
65
|
+
{ key: 'scripts/', module: 'scripts', owner: '内嵌脚本', disposition: 'freeze', phase: '第一批审查', note: "" },
|
|
66
|
+
{ key: 'cli-entry.ts', module: 'entry', owner: '入口装配', disposition: 'converge', phase: 'K3', note: "CLI 入口: 只能投递事件" },
|
|
67
|
+
{ key: 'index.ts', module: 'entry', owner: '入口装配', disposition: 'converge', phase: 'K3', note: "CLI/Web 装配点; 8 处直调 prompt" },
|
|
68
|
+
{ key: 'electron.ts', module: 'electron', owner: '桌面壳', disposition: 'freeze', phase: '第一批审查', note: "" },
|
|
69
|
+
{ key: 'electron-preload.ts', module: 'electron', owner: '桌面壳', disposition: 'freeze', phase: '第一批审查', note: "" },
|
|
70
|
+
{ key: 'pi-ecosystem-subagents/', module: 'judgment', owner: '子智能体线', disposition: 'converge', phase: 'K7', note: "" },
|
|
71
|
+
{ key: 'pi-ecosystem/', module: 'judgment', owner: '判断力/MCP 线', disposition: 'converge', phase: 'K7', note: "" },
|
|
72
|
+
{ key: 'agents/x402/', module: 'state', owner: 'Goal-Run 线', disposition: 'keep', phase: 'K2', note: "交易/支付事实层" },
|
|
73
|
+
];
|
|
74
|
+
/** 名册外的根 (各有自己的册子, 不混进产品码覆盖判据) */
|
|
75
|
+
export const OUT_OF_SCOPE_ROOTS = ['test/', 'constraint-runtime/'];
|
|
76
|
+
export const ENTRY_GRAPH = [
|
|
77
|
+
// K5 步骤⑦: `runExecution` (一次性请求的唯一入口) 内部派发 —— 新增 prompt/promptStream 各一处
|
|
78
|
+
{ file: 'agents/pi-sdk.ts', kind: 'adapter-internal', method: 'prompt', count: 2, path: 'direct', targetPhase: 'K4', note: "适配器内部 pivot 分派 + runExecution 的非流式派发 (都不是外部入口)" },
|
|
79
|
+
{ file: 'agents/pi-sdk.ts', kind: 'adapter-internal', method: 'promptStream', count: 1, path: 'direct', targetPhase: 'K4', note: "runExecution 的流式派发 (K5 步骤⑦ 新增)" },
|
|
80
|
+
{ file: 'agents/pi-sdk.ts', kind: 'adapter-internal', method: 'promptWithPivotLoop', count: 2, path: 'direct', targetPhase: 'K4', note: "适配器内部 pivot 分派 (不是外部入口)" },
|
|
81
|
+
{ file: 'agents/runner-resolver.ts', kind: 'agent-entry', method: 'prompt', count: 1, path: 'direct', targetPhase: 'K3', note: "独立宿主: 目前直调" },
|
|
82
|
+
{ file: 'cli/interface.ts', kind: 'readline-tui', method: 'prompt', count: 3, path: 'queued', targetPhase: 'K3', note: "readline 输入提示, 非 agent 入口" },
|
|
83
|
+
{ file: 'index.ts', kind: 'agent-entry', method: 'prompt', count: 7, path: 'direct', targetPhase: 'K3', note: "CLI 装配点" },
|
|
84
|
+
{ file: 'index.ts', kind: 'agent-entry', method: 'promptStream', count: 1, path: 'direct', targetPhase: 'K3', note: "CLI 装配点" },
|
|
85
|
+
{ file: 'web/routes-tasks.ts', kind: 'agent-entry', method: 'prompt', count: 1, path: 'direct', targetPhase: 'K3', note: "任务路由: 目前直调" },
|
|
86
|
+
{ file: 'web/server.ts', kind: 'agent-entry', method: 'prompt', count: 3, path: 'direct', targetPhase: 'K3', note: "Web 主入口 (非流式 3 处仍直调)" },
|
|
87
|
+
{ file: 'web/server.ts', kind: 'agent-entry', method: 'promptStream', count: 7, path: 'direct', targetPhase: 'K3', note: "Web 主入口: 1 处已改请求式 (K5 步骤⑦), 余 10 处仍直调" },
|
|
88
|
+
];
|
|
89
|
+
/**
|
|
90
|
+
* 直调 `prompt*()` 的调用点总数 (K3 只许把它压到 0; 棘轮只许减)。
|
|
91
|
+
* ⚠️ 24 → **25** (2026-10-02, K5 步骤⑦): `runExecution` 内部新增 `prompt`/`promptStream` 派发各 1 处 (+2),
|
|
92
|
+
* web/server.ts 用户消息路径改成请求式 (-1)。**这是"形态变化"不是"旁路复活"** —— 见 ENTRY_GRAPH 的两行 adapter-internal。
|
|
93
|
+
*/
|
|
94
|
+
export const ENTRY_DIRECT_CALLS_FROZEN_AT = 25;
|
|
95
|
+
export const DELETION_LEDGER = [
|
|
96
|
+
{
|
|
97
|
+
target: 'src/constraint-runtime/src/migrations/',
|
|
98
|
+
oldEntry: '无 (0 引用; 不在 CR/src/index.ts 导出面)',
|
|
99
|
+
replacement: '无 (0 引用; 不在 CR/src/index.ts 导出面)',
|
|
100
|
+
remainingRefs: 0,
|
|
101
|
+
runtimeHits: 0,
|
|
102
|
+
acceptance: 'tsc --noEmit 0 错 · 四道 kernel 门 75/75 · 引用面核验 0 处 · pre-commit 聚焦套件',
|
|
103
|
+
rollbackCommit: '9808e8e',
|
|
104
|
+
deletedAt: '2026-10-02',
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
target: 'src/constraint-runtime/src/remote/',
|
|
108
|
+
oldEntry: '无 (0 引用; 不在 CR/src/index.ts 导出面)',
|
|
109
|
+
replacement: '无 (0 引用; 不在 CR/src/index.ts 导出面)',
|
|
110
|
+
remainingRefs: 0,
|
|
111
|
+
runtimeHits: 0,
|
|
112
|
+
acceptance: 'tsc --noEmit 0 错 · 四道 kernel 门 75/75 · 引用面核验 0 处 · pre-commit 聚焦套件',
|
|
113
|
+
rollbackCommit: '9808e8e',
|
|
114
|
+
deletedAt: '2026-10-02',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
target: 'src/constraint-runtime/src/<26 个移植存档壳>/index.ts',
|
|
118
|
+
targets: ['src/constraint-runtime/src/assistant/index.ts', 'src/constraint-runtime/src/bootstrap/index.ts', 'src/constraint-runtime/src/bridge/index.ts', 'src/constraint-runtime/src/buddy/index.ts', 'src/constraint-runtime/src/cli/index.ts', 'src/constraint-runtime/src/components/index.ts', 'src/constraint-runtime/src/constants/index.ts', 'src/constraint-runtime/src/coordinator/index.ts', 'src/constraint-runtime/src/entrypoints/index.ts', 'src/constraint-runtime/src/hooks/index.ts', 'src/constraint-runtime/src/keybindings/index.ts', 'src/constraint-runtime/src/memdir/index.ts', 'src/constraint-runtime/src/moreright/index.ts', 'src/constraint-runtime/src/native_ts/index.ts', 'src/constraint-runtime/src/output_styles/index.ts', 'src/constraint-runtime/src/plugins/index.ts', 'src/constraint-runtime/src/schemas/index.ts', 'src/constraint-runtime/src/screens/index.ts', 'src/constraint-runtime/src/server/index.ts', 'src/constraint-runtime/src/services/index.ts', 'src/constraint-runtime/src/state/index.ts', 'src/constraint-runtime/src/types/index.ts', 'src/constraint-runtime/src/upstream_proxy/index.ts', 'src/constraint-runtime/src/utils/index.ts', 'src/constraint-runtime/src/vim/index.ts', 'src/constraint-runtime/src/voice/index.ts'],
|
|
119
|
+
oldEntry: '26 个 15 行移植存档壳 (assistant/bootstrap/bridge/.../voice): 每个 import _archive_helper 并读 reference_data/subsystems/<name>.json 快照, 自述为 "Python placeholder package"',
|
|
120
|
+
replacement: '无 (包入口闭包外 + 主仓 0 引用 + 不在任何快照的 source_hint 里)',
|
|
121
|
+
remainingRefs: 0,
|
|
122
|
+
runtimeHits: 0,
|
|
123
|
+
acceptance: 'CR tsc 0 错 · 主仓 tsc 0 错 · 五道 kernel 门全绿 · 引用 CR 的两个主仓测试 20/20 · 运行期真跑 require(dist/index.js) 25 个导出完好 · 干净重建 dist 保留文件逐字节一致',
|
|
124
|
+
rollbackCommit: '3b1bc42',
|
|
125
|
+
deletedAt: '2026-10-02',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
target: 'src/constraint-runtime/src/_archive_helper.ts',
|
|
129
|
+
targets: ['src/constraint-runtime/src/_archive_helper.ts'],
|
|
130
|
+
oldEntry: 'loadArchiveMetadata(): 读 reference_data/subsystems/<name>.json —— 只被上面 26 个存档壳调用',
|
|
131
|
+
replacement: '无 (随存档壳一起消失; reference_data/subsystems/*.json 变为孤立数据, 待第③批处置)',
|
|
132
|
+
remainingRefs: 0,
|
|
133
|
+
runtimeHits: 0,
|
|
134
|
+
acceptance: '同上 (同一批)',
|
|
135
|
+
rollbackCommit: '3b1bc42',
|
|
136
|
+
deletedAt: '2026-10-02',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
target: 'src/constraint-runtime/src/<6 个根级移植残留>.ts',
|
|
140
|
+
targets: ['src/constraint-runtime/src/_archive_helper.ts', 'src/constraint-runtime/src/cost_hook.ts', 'src/constraint-runtime/src/execution_registry.ts', 'src/constraint-runtime/src/ink.ts', 'src/constraint-runtime/src/port_manifest.ts', 'src/constraint-runtime/src/query.ts', 'src/constraint-runtime/src/system_init.ts'],
|
|
141
|
+
oldEntry: 'cost_hook / execution_registry / ink / port_manifest / query / system_init —— 移植快照的根级镜像文件',
|
|
142
|
+
replacement: '无 (闭包外 + 主仓 0 引用 + 快照 0 点名)',
|
|
143
|
+
remainingRefs: 0,
|
|
144
|
+
runtimeHits: 0,
|
|
145
|
+
acceptance: '同上 (同一批)',
|
|
146
|
+
rollbackCommit: '3b1bc42',
|
|
147
|
+
deletedAt: '2026-10-02',
|
|
148
|
+
},
|
|
149
|
+
];
|
|
150
|
+
/** 第一批删除候选 = 产品码里 **0 入边引用** 且非入口形态 (机械派生, 不手写) */
|
|
151
|
+
export const DELETION_CANDIDATE_COUNT = 94;
|
|
152
|
+
export const DELETION_CANDIDATE_SHA256 = '8ec437279513ddb82e0d909338c84d003486c3905143615b2b86f76d0d070112';
|
|
153
|
+
export const DELETION_CANDIDATE_DIRS = { "agents": 5, "bollharness-integration": 1, "bollharness": 61, "cli": 1, "(根)": 1, "judgeness": 3, "llm": 1, "network": 3, "orbitdb": 2, "scripts": 1, "social": 2, "utils": 3, "web": 10 };
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bolloon Native Macro-Kernel —— K0 模块名册与越权禁令 (冻结面, **数据, 零逻辑, 零 import**)
|
|
3
|
+
*
|
|
4
|
+
* 设计页: docs/wiki/bolloon-native-macro-kernel.md
|
|
5
|
+
* 门: src/test/kernel-boundary.test.ts (K1 目录边界 / K3 行数棘轮)
|
|
6
|
+
* src/test/kernel-authority.test.ts (K2 五条越权禁令)
|
|
7
|
+
* 判据: src/test/kernel-gate-scan.ts (纯函数吃源码文本; 变异验证在测试里每次真跑)
|
|
8
|
+
*
|
|
9
|
+
* 本文件为什么零 import: 它自己就是「内核目录不许 import 业务模块」这条规则的第一个样本 ——
|
|
10
|
+
* 规则若在本文件上都成立不了, 那道门就是装饰。**别在这里加 import。**
|
|
11
|
+
*
|
|
12
|
+
* 为什么名册要机器校验而不是靠人记: 「模块不许互相越权」写成文档 = 半年后没人知道有没有被绕过;
|
|
13
|
+
* 写成这张表 + 两道门 = 绕过它当场判红。仓里先例: goal-flywheel/wiring/seams.ts + wiring-freeze 门。
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* 层划分 —— **按真实目录/文件声明**, 不是理想蓝图。
|
|
17
|
+
* 这份划分是 K0 的冻结面: 改它等于改门的判据, 必须同时说明为什么 (留 diff)。
|
|
18
|
+
*/
|
|
19
|
+
export const LAYERS = [
|
|
20
|
+
{
|
|
21
|
+
id: 'kernel',
|
|
22
|
+
paths: ['kernel/'],
|
|
23
|
+
role: '内核: 调度 / 队列 / 并发 / 取消 / 超时 / 资源隔离 / 状态提交 / 事件派发 (只机制, 不业务判断)',
|
|
24
|
+
},
|
|
25
|
+
{ id: 'llm', paths: ['llm/'], role: 'Model Runtime + 供应商/目录/发现/模型选择协议 (写口唯一)' },
|
|
26
|
+
{
|
|
27
|
+
id: 'policy',
|
|
28
|
+
paths: [
|
|
29
|
+
'security/',
|
|
30
|
+
'agents/pi-harness.ts',
|
|
31
|
+
'agents/deny-pipeline.ts',
|
|
32
|
+
'agents/pre-tool-validator.ts',
|
|
33
|
+
'agents/permission-mode.ts',
|
|
34
|
+
'agents/shell-guard.ts',
|
|
35
|
+
],
|
|
36
|
+
role: 'Policy / Harness: 拒绝与许可的唯一判定面',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'state',
|
|
40
|
+
paths: [
|
|
41
|
+
'agents/goal-store.ts',
|
|
42
|
+
'agents/run-store.ts',
|
|
43
|
+
'agents/transaction-store.ts',
|
|
44
|
+
'agents/decision-store.ts',
|
|
45
|
+
'agents/plan-store.ts',
|
|
46
|
+
],
|
|
47
|
+
role: 'Goal / Run / 证据 / 恢复: **唯一事实来源**',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'tools',
|
|
51
|
+
paths: [
|
|
52
|
+
'agents/pi-sdk-tools.ts',
|
|
53
|
+
'agents/patch-tool.ts',
|
|
54
|
+
'agents/computer-use.ts',
|
|
55
|
+
'agents/browser-cdp.ts',
|
|
56
|
+
'agents/tool-subset.ts',
|
|
57
|
+
'agents/managed-services.ts',
|
|
58
|
+
'agents/tool-path-args.ts',
|
|
59
|
+
'agents/tool-result-gate.ts',
|
|
60
|
+
'agents/tool-telemetry.ts',
|
|
61
|
+
'lsp/lsp-tools.ts',
|
|
62
|
+
],
|
|
63
|
+
role: 'Tool Runtime: 工具实现 (副作用在这里, 权限判定不在这里)',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: 'channel',
|
|
67
|
+
paths: [
|
|
68
|
+
'web/',
|
|
69
|
+
'agents/pi-sdk-session-manager.ts',
|
|
70
|
+
'agents/pi-sdk-session-factory.ts',
|
|
71
|
+
'agents/session-store.ts',
|
|
72
|
+
],
|
|
73
|
+
role: 'Channel Runtime: 通道/会话/入站出站 (将来是一个 Actor)',
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 'adapter',
|
|
77
|
+
paths: [
|
|
78
|
+
'agents/pi-sdk.ts',
|
|
79
|
+
'agents/workflow-pivot-loop.ts',
|
|
80
|
+
'agents/loop-review.ts',
|
|
81
|
+
'agents/react-loop.ts',
|
|
82
|
+
],
|
|
83
|
+
role: '推理适配器 (当前实现 = Pi; 将来可被第二个实现替换)',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: 'delegate',
|
|
87
|
+
paths: ['external-engines/', 'agents/runner-resolver.ts'],
|
|
88
|
+
role: '子 Agent / 外部引擎委派',
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
/**
|
|
92
|
+
* K1 —— kernel 目录允许 import 的前缀 (相对 src/)。
|
|
93
|
+
*
|
|
94
|
+
* 现阶段**只许 kernel 内部**: 内核需要的对外能力一律通过 contracts / ports / adapters 传入,
|
|
95
|
+
* 不许自己伸手去摸业务模块 (那正是 pi-sdk.ts 变成 4099 行单体的成因)。
|
|
96
|
+
*/
|
|
97
|
+
export const KERNEL_ALLOWED_IMPORT_PREFIXES = ['kernel/'];
|
|
98
|
+
/**
|
|
99
|
+
* 名册登记的 kernel 目录文件 (相对 src/)。
|
|
100
|
+
* 判据是**双向相等**: 盘上多一个未登记文件 ⇒ 红; 名册有而盘上没有 ⇒ 红。
|
|
101
|
+
* (先例: SEAM_ROSTER 的「名册外无人越界」)
|
|
102
|
+
*/
|
|
103
|
+
export const KERNEL_FILES = ['kernel/channel-actor.ts', 'kernel/control.ts', 'kernel/gate-scan.ts', 'kernel/model-runtime.ts', 'kernel/plan-modelruntime.ts', 'kernel/plan-constraint.ts', 'kernel/plan-channel-actor.ts', 'kernel/plan-deletion.ts', 'kernel/plan-runcontext.ts', 'kernel/plan.ts', 'kernel/roster.ts'];
|
|
104
|
+
/** Goal 事实的写入口 (goal-store.ts 的导出中带副作用的那些) */
|
|
105
|
+
export const GOAL_WRITES = [
|
|
106
|
+
'createGoal',
|
|
107
|
+
'updateGoal',
|
|
108
|
+
'attachRun',
|
|
109
|
+
'markCriterion',
|
|
110
|
+
'setUnresolved',
|
|
111
|
+
'addEvidence',
|
|
112
|
+
'setCriteria',
|
|
113
|
+
'completeGoalIfEligible',
|
|
114
|
+
'setContinuation',
|
|
115
|
+
'bumpContinuationAttempts',
|
|
116
|
+
'resetContinuationAttempts',
|
|
117
|
+
'claimGoal',
|
|
118
|
+
'heartbeatGoal',
|
|
119
|
+
'releaseGoal',
|
|
120
|
+
];
|
|
121
|
+
/** Run 事实的写入口 (run-store.ts 的导出中带副作用的那些) */
|
|
122
|
+
export const RUN_WRITES = [
|
|
123
|
+
'startRun',
|
|
124
|
+
'setRunStatus',
|
|
125
|
+
'saveCheckpoint',
|
|
126
|
+
'recordRecovery',
|
|
127
|
+
'recordHarnessEvent',
|
|
128
|
+
'recordModelSwitch',
|
|
129
|
+
'addRunEvidence',
|
|
130
|
+
'recordStep',
|
|
131
|
+
'finishRun',
|
|
132
|
+
'markRunRunning',
|
|
133
|
+
'setOnRunTerminal',
|
|
134
|
+
];
|
|
135
|
+
/** 权限的写入口 (allowTool/denyTool 在会话上是真改权限面; permission-mode 的测试重置口也算) */
|
|
136
|
+
export const PERMISSION_WRITES = [
|
|
137
|
+
'allowTool',
|
|
138
|
+
'denyTool',
|
|
139
|
+
'setPermissionMode',
|
|
140
|
+
'clearDeniedTools',
|
|
141
|
+
'_resetPermissionModeForTest',
|
|
142
|
+
];
|
|
143
|
+
export const PROHIBITIONS = [
|
|
144
|
+
{
|
|
145
|
+
id: 'model-must-not-execute-tool',
|
|
146
|
+
rule: 'Model 不能直接执行 Tool',
|
|
147
|
+
fromLayer: 'llm',
|
|
148
|
+
mode: 'import-edge',
|
|
149
|
+
targets: [
|
|
150
|
+
'agents/pi-sdk-tools',
|
|
151
|
+
'agents/patch-tool',
|
|
152
|
+
'agents/managed-services',
|
|
153
|
+
'agents/computer-use',
|
|
154
|
+
'agents/browser-cdp',
|
|
155
|
+
'lsp/lsp-tools',
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
id: 'provider-must-not-write-run',
|
|
160
|
+
rule: 'Provider 不能直接写 Run',
|
|
161
|
+
fromLayer: 'llm',
|
|
162
|
+
mode: 'write-call',
|
|
163
|
+
writeCalls: RUN_WRITES,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
id: 'tool-must-not-change-permission',
|
|
167
|
+
rule: 'Tool 不能直接改权限',
|
|
168
|
+
fromLayer: 'tools',
|
|
169
|
+
mode: 'write-call',
|
|
170
|
+
writeCalls: PERMISSION_WRITES,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
id: 'channel-must-not-write-goal',
|
|
174
|
+
rule: 'Channel 不能直接改 Goal',
|
|
175
|
+
fromLayer: 'channel',
|
|
176
|
+
mode: 'write-call',
|
|
177
|
+
writeCalls: GOAL_WRITES,
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
id: 'channel-must-not-write-run',
|
|
181
|
+
rule: 'Channel 不能直接写 Run',
|
|
182
|
+
derivedFrom: '路线 K3「入口收口」—— 所有入口统一走 submit(request) → enqueue → RunContext → execute → close',
|
|
183
|
+
fromLayer: 'channel',
|
|
184
|
+
mode: 'write-call',
|
|
185
|
+
writeCalls: RUN_WRITES,
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
id: 'child-must-not-end-goal',
|
|
189
|
+
rule: '子 Agent 不能直接结束 Goal',
|
|
190
|
+
fromLayer: 'delegate',
|
|
191
|
+
mode: 'write-call',
|
|
192
|
+
writeCalls: ['completeGoalIfEligible', 'updateGoal', 'setCriteria', 'createGoal'],
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
/**
|
|
196
|
+
* **阶段完工状态** (数据) —— 供判据核"欠账记着由某阶段还, 而那个阶段已经收工"。
|
|
197
|
+
* 只许按事实填: 说 `done` 就要有对应的完工判据支撑 (K5 有 `K5_STEP8` + `scanStep8Completion`)。
|
|
198
|
+
*/
|
|
199
|
+
export const STAGE_STATUS = {
|
|
200
|
+
K0: 'done',
|
|
201
|
+
K1: 'partial',
|
|
202
|
+
K2: 'done',
|
|
203
|
+
K3: 'done',
|
|
204
|
+
K5: 'done',
|
|
205
|
+
K4: 'partial', // 模块边界收口进行中: 越权欠账已归零, 还有 K1 遗留的领域直连欠账
|
|
206
|
+
K6: 'not-started',
|
|
207
|
+
K7: 'not-started',
|
|
208
|
+
K8: 'not-started',
|
|
209
|
+
K9: 'not-started',
|
|
210
|
+
K10: 'not-started',
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* **越权欠账台账 (棘轮)** —— 判据是「实际违规多重集 == 本表逐字相等」, 不是「⊆」:
|
|
214
|
+
* · 新增一条违规 ⇒ 门立刻红 (要登记就得改这张表, diff 里看得见)
|
|
215
|
+
* · 修掉一条却没同步删 ⇒ 门也红 (强制台账与事实同步, 不许台账烂在上面)
|
|
216
|
+
* 条数另有 `AUTHORITY_DEBT_FROZEN_AT` 冻死, **只许减不许增**。
|
|
217
|
+
*/
|
|
218
|
+
export const AUTHORITY_DEBT = [
|
|
219
|
+
// **K4 已全部还清 (3 → 0)**: 三条越权写 (setContinuation / setRunStatus ×2 / recordRecovery)
|
|
220
|
+
// 都改成"channel 提交请求 → 内核控制面执行写" (kernel/control.ts)。
|
|
221
|
+
// 这张表保持**空**是有判据盯着的事实: 任何一处新的 channel 直写都会让双向判据报 missing ⇒ 立刻红。
|
|
222
|
+
];
|
|
223
|
+
/** 欠账条数冻结值 (只许减; 要加必须同时改这里 → 在 diff 里是一次显式动作) */
|
|
224
|
+
export const AUTHORITY_DEBT_FROZEN_AT = 0; // 3 → 0 (K4 用内核控制面还清全部三条越权写)
|
|
225
|
+
/**
|
|
226
|
+
* K3 —— kernel 目录行数预算 (棘轮, 只许减不许增)。
|
|
227
|
+
*
|
|
228
|
+
* 目的只有一个: **不许所有逻辑回流到 kernel.ts**。要加就得显式抬这个数字, 留下痕迹。
|
|
229
|
+
* 数值 = 当前 kernel 目录真实行数, 不留余量。
|
|
230
|
+
*/
|
|
231
|
+
export const KERNEL_LINE_BUDGET = 2555;
|
|
232
|
+
/** 预算冻结值 (棘轮: 只许减; 想抬预算必须同时改上面那个数字 ⇒ 一次显式动作, diff 里看得见) */
|
|
233
|
+
export const KERNEL_LINE_BUDGET_FROZEN_AT = 2555;
|
|
234
|
+
/**
|
|
235
|
+
* K3b —— **台账数据**单独一档预算 (`src/kernel/plan.ts`)。
|
|
236
|
+
*
|
|
237
|
+
* 为什么分开: K3 要防的是「逻辑回流到内核代码」; 台账是**数据** (owner 名册 / 入口图 / 删除候选),
|
|
238
|
+
* 把它算进代码预算会逼着人抬代码上限, 棘轮的信号就废了。两档各自冻结, 都只许减。
|
|
239
|
+
*/
|
|
240
|
+
export const KERNEL_PLAN_LINE_BUDGET = 1054;
|
|
241
|
+
/** 台账预算冻结值 (棘轮: 只许减) */
|
|
242
|
+
export const KERNEL_PLAN_LINE_BUDGET_FROZEN_AT = 1054;
|
|
@@ -102,6 +102,61 @@ export class OrbitDBAdapter {
|
|
|
102
102
|
get ipfsPaths() {
|
|
103
103
|
return this.node?.paths ?? null;
|
|
104
104
|
}
|
|
105
|
+
// ============ P2P 观测/接入口 (2026-09-30, 为真两节点复制验证加的) ============
|
|
106
|
+
// 之前 helia/libp2p 完全藏在私有字段里 —— 于是所有多节点测试只能注入 fake CIDDatabase,
|
|
107
|
+
// 「真两节点能不能同步」从来没被验过。这三个口只读/只拨号, 不改变任何既有行为。
|
|
108
|
+
/** 本节点 peerId (未初始化时 null; 验收/诊断用) */
|
|
109
|
+
get peerId() {
|
|
110
|
+
return this.node?.peerId ?? null;
|
|
111
|
+
}
|
|
112
|
+
/** 本节点当前监听地址 (multiaddr 字符串; 未初始化时 []) */
|
|
113
|
+
listenAddrs() {
|
|
114
|
+
const l = this.node?.helia?.libp2p;
|
|
115
|
+
try {
|
|
116
|
+
return (l?.getMultiaddrs?.() ?? []).map((m) => m.toString());
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 当前与本节点**有连接**的对端 (诊断用只读口)。
|
|
124
|
+
* 用途: P0 门里 S3「不拨号必须看不见」不稳定 (关 mDNS、全静默档都仍 seen=101) ——
|
|
125
|
+
* 得先看清"是谁、通过什么连上的", 再谈判据。返回 `peerId ← 远端地址`。
|
|
126
|
+
*/
|
|
127
|
+
peerConnections() {
|
|
128
|
+
const l = this.node?.helia?.libp2p;
|
|
129
|
+
try {
|
|
130
|
+
return (l?.getConnections?.() ?? []).map((c) => {
|
|
131
|
+
const p = c.remotePeer?.toString?.() ?? String(c.remotePeer);
|
|
132
|
+
const a = c.remoteAddr?.toString?.() ?? '';
|
|
133
|
+
return `${p} ← ${a}`;
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* 某个 pubsub 主题当前的订阅者 peerId (诊断用只读口)。
|
|
142
|
+
* OrbitDB 的同步靠 pubsub: 新 peer 订阅 `address` 主题后, 已在线的 peer 会把 heads 发给它
|
|
143
|
+
* (@orbitdb/core src/sync.js:143 的 join 事件)。所以"订阅者为 0"和"日志为空"是两回事, 必须分开看。
|
|
144
|
+
*/
|
|
145
|
+
pubsubSubscribers(topic) {
|
|
146
|
+
const ps = this.node?.helia?.libp2p?.services?.pubsub;
|
|
147
|
+
try {
|
|
148
|
+
return (ps?.getSubscribers?.(topic) ?? []).map((x) => x.toString());
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** 拨号到另一个真节点 (验收/群组接入用)。失败原样抛, 不吞。 */
|
|
155
|
+
async dial(addr) {
|
|
156
|
+
await this.ensure();
|
|
157
|
+
const { multiaddr } = await import('@multiformats/multiaddr');
|
|
158
|
+
await this.node.helia.libp2p.dial(multiaddr(addr));
|
|
159
|
+
}
|
|
105
160
|
/** 懒初始化: 首次使用时启动 helia + OrbitDB + 打开 keyvalue store */
|
|
106
161
|
async ensure() {
|
|
107
162
|
if (this.db)
|