@sema-agent/server 7.141.0 → 7.142.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/MIGRATION.md +215 -0
- package/USAGE.md +67 -12
- package/dist/approval-ask-audit-store.d.ts +54 -38
- package/dist/approval-ask-audit-store.js +58 -39
- package/dist/approval-card.d.ts +8 -8
- package/dist/approval-crash-convergence.d.ts +17 -7
- package/dist/approval-crash-convergence.js +94 -22
- package/dist/approval-deny-reasons.d.ts +34 -30
- package/dist/approval-deny-reasons.js +21 -6
- package/dist/approval-policy-settlement.d.ts +1 -1
- package/dist/approval-reconciler.d.ts +33 -1
- package/dist/approval-reconciler.js +43 -40
- package/dist/auth-bridge.d.ts +9 -6
- package/dist/auth-bridge.js +9 -3
- package/dist/boot/adoption.js +2 -1
- package/dist/boot/budget-tracing.d.ts +16 -0
- package/dist/boot/budget-tracing.js +10 -6
- package/dist/boot/device-lane.d.ts +1 -1
- package/dist/boot/execution-env.d.ts +24 -4
- package/dist/boot/execution-env.js +26 -23
- package/dist/boot/execution-lane.js +2 -1
- package/dist/boot/exit-boundary.js +5 -4
- package/dist/boot/memory-consolidation.js +2 -1
- package/dist/boot/parked-revive-gate.js +2 -1
- package/dist/boot/permission-rules-audit.d.ts +0 -28
- package/dist/boot/permission-rules-audit.js +2 -1
- package/dist/boot/read-deny-anchor-audit.js +2 -1
- package/dist/boot/reapers.js +4 -3
- package/dist/boot/resolve-spec.js +11 -2
- package/dist/boot/retention-lane.js +5 -3
- package/dist/boot/runner-deps.js +16 -13
- package/dist/boot/runtime-caps.js +3 -2
- package/dist/boot/session-faces.js +4 -3
- package/dist/boot/shutdown.js +3 -2
- package/dist/boot/stage-04-stores.js +3 -2
- package/dist/boot/stage-05-execution-env.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.js +8 -6
- package/dist/boot/stage-06-runners.d.ts +1 -1
- package/dist/boot/stage-06-runners.js +2 -1
- package/dist/boot/stage-07-capability-layer.d.ts +1 -1
- package/dist/boot/stage-07-capability-layer.js +2 -1
- package/dist/boot/stage-08-reapers.d.ts +1 -1
- package/dist/boot/stage-08-reapers.js +3 -2
- package/dist/boot/stage-09-leader.d.ts +1 -1
- package/dist/boot/stage-10-http-server.d.ts +1 -1
- package/dist/boot/stage-10-http-server.js +5 -4
- package/dist/boot/stores.js +3 -2
- package/dist/boot/web-admin.js +17 -17
- package/dist/boot/webfetch-summarize-lane.js +2 -1
- package/dist/boot/workflow-orchestration.js +3 -2
- package/dist/capabilities/builtin-tools.d.ts +2 -1
- package/dist/capabilities/builtin-tools.js +2 -4
- package/dist/capabilities/composite-members.d.ts +2 -1
- package/dist/capabilities/composite-members.js +2 -1
- package/dist/capability-facts.d.ts +24 -0
- package/dist/capability-facts.js +23 -0
- package/dist/config-catalog.js +1 -0
- package/dist/config-types.d.ts +15 -4
- package/dist/config.d.ts +6 -0
- package/dist/config.js +17 -3
- package/dist/execution-lane-caps.d.ts +2 -1
- package/dist/fleet/fleet-bus.d.ts +6 -3
- package/dist/hooks/hook-runner.d.ts +6 -0
- package/dist/hooks/hook-runner.js +30 -1
- package/dist/http/dispatch.js +4 -2
- package/dist/http/execution-context.d.ts +2 -2
- package/dist/http/idempotency.d.ts +1 -1
- package/dist/http/principal-gate.d.ts +3 -1
- package/dist/http/principal-gate.js +17 -8
- package/dist/http/resume-legs.js +5 -9
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/attachments.js +18 -0
- package/dist/http/routes/capabilities.js +5 -2
- package/dist/http/routes/memory-policy.js +26 -6
- package/dist/http/routes/runs.js +3 -3
- package/dist/http/routes/session-memory-sync.d.ts +63 -0
- package/dist/http/routes/session-memory-sync.js +157 -0
- package/dist/http/routes/sessions-list.d.ts +2 -1
- package/dist/http/routes/tasks.js +7 -5
- package/dist/http/run-read-face.d.ts +7 -0
- package/dist/http/run-read-face.js +9 -3
- package/dist/http/send.d.ts +5 -0
- package/dist/http/send.js +9 -2
- package/dist/http/server.d.ts +14 -8
- package/dist/http/server.js +2 -4
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +2 -2
- package/dist/http/sync-submit-body.d.ts +21 -4
- package/dist/http/sync-submit-body.js +13 -0
- package/dist/identity-source.d.ts +21 -2
- package/dist/identity-source.js +6 -0
- package/dist/memory-incident-sink.d.ts +19 -6
- package/dist/memory-incident-sink.js +8 -4
- package/dist/memory-sync-client.d.ts +21 -21
- package/dist/memory-sync-client.js +50 -42
- package/dist/memory-sync-identity.d.ts +24 -0
- package/dist/memory-sync-identity.js +57 -0
- package/dist/memory-sync.d.ts +7 -1
- package/dist/memory-sync.js +6 -3
- package/dist/observability/fail-open.d.ts +27 -10
- package/dist/observability/fail-open.js +20 -7
- package/dist/observability/run-terminal.d.ts +92 -34
- package/dist/observability/run-terminal.js +167 -162
- package/dist/plugins/approval-ask-store-file.d.ts +14 -4
- package/dist/plugins/approval-ask-store-file.js +48 -7
- package/dist/plugins/approval-ask-store-memory.d.ts +2 -1
- package/dist/plugins/approval-ask-store-memory.js +9 -8
- package/dist/plugins/approval-ask-store-sql.d.ts +42 -10
- package/dist/plugins/approval-ask-store-sql.js +49 -19
- package/dist/plugins/file-run-store.d.ts +6 -1
- package/dist/plugins/file-run-store.js +11 -1
- package/dist/plugins/local-session-store.d.ts +36 -7
- package/dist/plugins/local-session-store.js +76 -32
- package/dist/plugins/local-task-attachment-store.d.ts +12 -2
- package/dist/plugins/local-task-attachment-store.js +67 -43
- package/dist/plugins/memory-key-guards.d.ts +3 -3
- package/dist/plugins/memory-run-store.d.ts +6 -1
- package/dist/plugins/memory-run-store.js +11 -1
- package/dist/plugins/one-time-migrations.d.ts +27 -1
- package/dist/plugins/one-time-migrations.js +57 -3
- package/dist/plugins/remote-env-e2b.d.ts +23 -4
- package/dist/plugins/remote-env-e2b.js +111 -28
- package/dist/plugins/remote-env-k8s.d.ts +31 -5
- package/dist/plugins/remote-env-k8s.js +86 -19
- package/dist/plugins/remote-env-local-docker.d.ts +15 -3
- package/dist/plugins/remote-env-local-docker.js +40 -12
- package/dist/plugins/run-store-sql.d.ts +9 -1
- package/dist/plugins/run-store-sql.js +9 -1
- package/dist/plugins/store-backend.d.ts +10 -7
- package/dist/plugins/store-backend.js +1 -0
- package/dist/plugins/store-contracts.d.ts +26 -1
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/task-attachment-store.d.ts +112 -14
- package/dist/plugins/task-attachment-store.js +221 -28
- package/dist/plugins/workspace-fill.d.ts +60 -0
- package/dist/plugins/workspace-fill.js +106 -0
- package/dist/project-bundle.d.ts +38 -0
- package/dist/project-bundle.js +609 -0
- package/dist/run-local.js +2 -8
- package/dist/runs.js +1 -2
- package/dist/sandbox-egress-policy.d.ts +4 -1
- package/dist/sandbox-egress-policy.js +3 -1
- package/dist/sandbox-git-plane.d.ts +31 -12
- package/dist/sandbox-git-plane.js +24 -4
- package/dist/security.d.ts +9 -0
- package/dist/security.js +8 -0
- package/dist/session-error-wire.d.ts +24 -0
- package/dist/session-error-wire.js +7 -0
- package/dist/task-settings.d.ts +10 -2
- package/dist/task-settings.js +15 -2
- package/dist/terminal.d.ts +39 -19
- package/dist/terminal.js +65 -22
- package/dist/tool-approval.d.ts +4 -3
- package/dist/tool-approval.js +12 -14
- package/dist/trace/core-keyset-guard.d.ts +123 -6
- package/dist/trace/engine-notice-wire.d.ts +8 -2
- package/dist/trace/engine-notice-wire.js +4 -2
- package/dist/trace/exit-seat.d.ts +2 -1
- package/dist/trace/ledger-sink.d.ts +8 -4
- package/dist/trace/ledger-sink.js +2 -2
- package/dist/trace/project.d.ts +18 -1
- package/dist/trace/project.js +16 -0
- package/dist/trace/self-minted-wire.d.ts +251 -2
- package/dist/trace/self-minted-wire.js +82 -0
- package/dist/trace/wire-projection-faces.d.ts +1 -1
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/web-admin-client/apply-effective.js +21 -1
- package/dist/web-admin-client/effective-keys.js +2 -0
- package/dist/web-admin-client/types.d.ts +4 -0
- package/package.json +1 -1
- package/wire-changes/server@7.142.0.json +639 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promises as fsp } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { TaskAttachmentRecordSchema } from "./task-attachment-store.js";
|
|
3
|
+
import { bindRowsInProcess, TaskAttachmentRecordSchema } from "./task-attachment-store.js";
|
|
4
4
|
import { createZodColumnReader, decodeJsonColumn } from "./sql-json-column.js";
|
|
5
5
|
const ID_RE = /^[0-9a-f-]{16,64}$/i;
|
|
6
6
|
const readAttachmentMeta = createZodColumnReader(TaskAttachmentRecordSchema);
|
|
@@ -8,6 +8,7 @@ export class LocalTaskAttachmentStore {
|
|
|
8
8
|
dir;
|
|
9
9
|
metas;
|
|
10
10
|
hydration;
|
|
11
|
+
mutationTail = Promise.resolve();
|
|
11
12
|
constructor(rootDir) {
|
|
12
13
|
this.dir = join(rootDir, "attachments");
|
|
13
14
|
}
|
|
@@ -37,17 +38,24 @@ export class LocalTaskAttachmentStore {
|
|
|
37
38
|
})();
|
|
38
39
|
return this.hydration;
|
|
39
40
|
}
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
41
|
+
serialized(op) {
|
|
42
|
+
const run = this.mutationTail.then(op);
|
|
43
|
+
this.mutationTail = run.then(() => undefined, () => undefined);
|
|
44
|
+
return run;
|
|
45
|
+
}
|
|
46
|
+
put(rec) {
|
|
47
|
+
return this.serialized(async () => {
|
|
48
|
+
const metas = await this.hydrate();
|
|
49
|
+
await fsp.mkdir(this.dir, { recursive: true });
|
|
50
|
+
const { content, ...meta } = rec;
|
|
51
|
+
const binTmp = join(this.dir, `${rec.id}.bin.tmp`);
|
|
52
|
+
const metaTmp = join(this.dir, `${rec.id}.json.tmp`);
|
|
53
|
+
await fsp.writeFile(binTmp, Buffer.from(content));
|
|
54
|
+
await fsp.rename(binTmp, join(this.dir, `${rec.id}.bin`));
|
|
55
|
+
await fsp.writeFile(metaTmp, JSON.stringify(meta));
|
|
56
|
+
await fsp.rename(metaTmp, join(this.dir, `${rec.id}.json`));
|
|
57
|
+
metas.set(rec.id, { ...meta });
|
|
58
|
+
});
|
|
51
59
|
}
|
|
52
60
|
async get(owner, id) {
|
|
53
61
|
const m = (await this.hydrate()).get(id);
|
|
@@ -69,19 +77,29 @@ export class LocalTaskAttachmentStore {
|
|
|
69
77
|
await fsp.writeFile(tmp, JSON.stringify(m));
|
|
70
78
|
await fsp.rename(tmp, join(this.dir, `${m.id}.json`));
|
|
71
79
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
80
|
+
bind(owner, ids, sessionId, boundAtMs) {
|
|
81
|
+
return this.serialized(async () => {
|
|
82
|
+
const metas = await this.hydrate();
|
|
83
|
+
const draft = new Map(metas);
|
|
84
|
+
for (const id of new Set(ids)) {
|
|
85
|
+
const row = metas.get(id);
|
|
86
|
+
if (row !== undefined)
|
|
87
|
+
draft.set(id, { ...row });
|
|
88
|
+
}
|
|
89
|
+
const { outcome, claimed } = bindRowsInProcess(draft, owner, ids, sessionId, boundAtMs);
|
|
90
|
+
const landed = [];
|
|
91
|
+
try {
|
|
92
|
+
for (const m of claimed) {
|
|
93
|
+
await this.persistMeta(m);
|
|
94
|
+
landed.push(m);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
for (const m of landed)
|
|
99
|
+
metas.set(m.id, m);
|
|
100
|
+
}
|
|
101
|
+
return outcome;
|
|
102
|
+
});
|
|
85
103
|
}
|
|
86
104
|
async listBySession(sessionId) {
|
|
87
105
|
const metas = await this.hydrate();
|
|
@@ -95,26 +113,32 @@ export class LocalTaskAttachmentStore {
|
|
|
95
113
|
await fsp.rm(join(this.dir, `${id}.bin`), { force: true });
|
|
96
114
|
this.metas?.delete(id);
|
|
97
115
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
116
|
+
delete(owner, id) {
|
|
117
|
+
return this.serialized(async () => {
|
|
118
|
+
const m = (await this.hydrate()).get(id);
|
|
119
|
+
if (!m || m.owner !== owner)
|
|
120
|
+
return false;
|
|
121
|
+
await this.removeRow(id);
|
|
122
|
+
return true;
|
|
123
|
+
});
|
|
104
124
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
125
|
+
deleteBySession(sessionId) {
|
|
126
|
+
return this.serialized(async () => {
|
|
127
|
+
const metas = await this.hydrate();
|
|
128
|
+
const hit = [...metas.values()].filter((m) => m.sessionId === sessionId);
|
|
129
|
+
for (const m of hit)
|
|
130
|
+
await this.removeRow(m.id);
|
|
131
|
+
return hit.length;
|
|
132
|
+
});
|
|
111
133
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
134
|
+
reapUnbound(olderThanMs) {
|
|
135
|
+
return this.serialized(async () => {
|
|
136
|
+
const metas = await this.hydrate();
|
|
137
|
+
const hit = [...metas.values()].filter((m) => m.sessionId === undefined && m.createdAtMs < olderThanMs);
|
|
138
|
+
for (const m of hit)
|
|
139
|
+
await this.removeRow(m.id);
|
|
140
|
+
return hit.length;
|
|
141
|
+
});
|
|
118
142
|
}
|
|
119
143
|
}
|
|
120
144
|
//# sourceMappingURL=local-task-attachment-store.js.map
|
|
@@ -15,9 +15,9 @@ export declare const MEMORY_SLUG_COLUMN_CHARS = 512;
|
|
|
15
15
|
* sync_cursor/push_queue/history)。`formatUserScope`/`formatProjScope` 的段编码(百分号转义)会
|
|
16
16
|
* **膨胀**——非 ASCII principal 编码后可超列宽,故产出处与写口两道都要判。 */
|
|
17
17
|
export declare const MEMORY_SCOPE_COLUMN_CHARS = 190;
|
|
18
|
-
/** memory-sync 店 `sync_cursor.peer` 列宽(两方言 VARCHAR(190) 同宽)—— 中心侧请求的 `peer`
|
|
19
|
-
* (`memory-sync.ts` `
|
|
20
|
-
*
|
|
18
|
+
/** memory-sync 店 `sync_cursor.peer` 列宽(两方言 VARCHAR(190) 同宽)—— 中心侧请求的 `peer` 落这一列。唯一读者 = 同步身份的铸点
|
|
19
|
+
* (`memory-sync-identity.ts` `readMemorySyncIdentity`:规范化之后超宽 = `too-long`)—— 它的四个座位(客户端 `MEMORY_SYNC_URL` 拒启、中心声明
|
|
20
|
+
* `MEMORY_SYNC_SERVE_IDENTITY` 拒启、会话触发的 `target` 400、中心入站的 `peer` 400)由此同宽:身份就是请求的 `peer`,装不进这一列的身份每一轮都会被中心拒。 */
|
|
21
21
|
export declare const MEMORY_SYNC_PEER_COLUMN_CHARS = 190;
|
|
22
22
|
export declare function assertSlugWidth(slug: string): void;
|
|
23
23
|
export declare function assertMemoryScopeWidth(scope: string): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type UsageRow } from "../usage-analytics.js";
|
|
2
2
|
import type { TaskStatus } from "@sema-agent/core";
|
|
3
|
-
import { type FenceLanded, type FencedRun, type InProcessClaimFence, type CreateRunOutcome, type NewRunMeta, type RunIdemBinding, type RunListQuery, type RunRecord, type SessionSummary, type RunEvent, type PersistedTaskResult, type LatestRunRef } from "./store-contracts.js";
|
|
3
|
+
import { type FenceLanded, type FencedRun, type InProcessClaimFence, type CreateRunOutcome, type NewRunMeta, type RunIdemBinding, type RunListQuery, type RunRecord, type SessionSummary, type RunEvent, type PersistedTaskResult, type LatestRunRef, type SettledLegMemoryObservation } from "./store-contracts.js";
|
|
4
4
|
import type { LedgerEventType } from "../trace/ledger-events.js";
|
|
5
5
|
import { type SpaceCommitClaim, type SpaceCommitReading, type SpaceCommitState } from "../workspace-space-commit.js";
|
|
6
6
|
/**
|
|
@@ -92,6 +92,11 @@ export declare class MemoryRunStore implements InProcessClaimFence {
|
|
|
92
92
|
* `createdAt DESC, taskId DESC`,与本店 {@link MemoryRunStore.listSessions} 挑 `rn=1` 那一行的比较器逐字同一份)。
|
|
93
93
|
*/
|
|
94
94
|
latestRunForSession(sessionId: string): Promise<LatestRunRef | undefined>;
|
|
95
|
+
/**
|
|
96
|
+
* [ref] —— 这个会话**最近一条已结腿**与它的记忆观测(规则属主 = `store-contracts.ts` 的 {@link SettledLegMemoryObservation};
|
|
97
|
+
* {@link SqlRunStore.latestMemoryObservationForSession} 的孪生:同一只已结谓词(`isTerminalRunStatus`)、同一个排序口径 —— 与本店 {@link MemoryRunStore.latestRunForSession} 的比较器逐字同一份)。
|
|
98
|
+
*/
|
|
99
|
+
latestMemoryObservationForSession(sessionId: string): Promise<SettledLegMemoryObservation | undefined>;
|
|
95
100
|
/** DISTINCT sessions newest-first by last activity (the CC /resume picker): latest run's preview/status + first/last/count. */
|
|
96
101
|
listSessions(opts: {
|
|
97
102
|
owner?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { redactErrorMessage, redactLedgerEventData, sealRunRowResult } from "../observability/run-terminal.js";
|
|
2
2
|
import { outwardPlane } from "../terminal.js";
|
|
3
3
|
import { projectUsageStats, USAGE_SCAN_LIMIT } from "../usage-analytics.js";
|
|
4
|
-
import { RUN_HOLDER_DEATH_CODES, RUN_STALLED_ERROR } from "./store-contracts.js";
|
|
4
|
+
import { RUN_HOLDER_DEATH_CODES, RUN_STALLED_ERROR, isTerminalRunStatus, settledLegObservationOf } from "./store-contracts.js";
|
|
5
5
|
import { notifyRunTerminal } from "../observability/run-terminal.js";
|
|
6
6
|
import { createInProcessSpaceCommitTable, fenceSpaceCommitAtTerminal } from "../workspace-space-commit.js";
|
|
7
7
|
const ownerEq = (a, b) => (a ?? null) === (b ?? null);
|
|
@@ -273,6 +273,16 @@ export class MemoryRunStore {
|
|
|
273
273
|
}
|
|
274
274
|
return latest === undefined ? undefined : { taskId: latest.taskId, owner: latest.owner, createdAt: latest.createdAt.toISOString() };
|
|
275
275
|
}
|
|
276
|
+
async latestMemoryObservationForSession(sessionId) {
|
|
277
|
+
let latest;
|
|
278
|
+
for (const r of this.runs.values()) {
|
|
279
|
+
if (r.sessionId !== sessionId || !isTerminalRunStatus(r.status))
|
|
280
|
+
continue;
|
|
281
|
+
if (latest === undefined || r.createdAt.getTime() > latest.createdAt.getTime() || (r.createdAt.getTime() === latest.createdAt.getTime() && r.taskId > latest.taskId))
|
|
282
|
+
latest = r;
|
|
283
|
+
}
|
|
284
|
+
return latest === undefined ? undefined : settledLegObservationOf(latest.taskId, latest.result);
|
|
285
|
+
}
|
|
276
286
|
async listSessions(opts) {
|
|
277
287
|
const bySession = new Map();
|
|
278
288
|
for (const r of this.runs.values()) {
|
|
@@ -328,6 +328,16 @@
|
|
|
328
328
|
* **回滚**:边档对象形一格是严格形,上一版不认 `createdAt` / `forkedFrom` 两键 ⇒ 读本版写过的边档严格拒启 —— 回滚的唯一支持形 = 恢复升级前的数据根备份(MIGRATION 写了:升级前备份、先停光旧副本)。
|
|
329
329
|
* 读数:`localArchiveRowFactsBackfilled` / `localArchivesAnonymized` / `localArchivesKeptStamped`(点名数组 `{ sessionId, reason }`)/ `localArchivesUnreadable`(点名数组 `{ sessionId }`)/
|
|
330
330
|
* `localArchiveSnapshotsRecovered`;只 local(SQL 恒零 / 空)。
|
|
331
|
+
* · **M34 问账行成因两列**(7.142.0)—— ≤7.141.x 的 `approval_ask` 只有一列 `denied_reason`,按行的 state 承载两种意思(PARKING / PARKED 行上是转 park 的触发成因,VOID / DENIED 行上是
|
|
332
|
+
* 终态成因),对账器把 PARKING 行收成 DENIED / VOID 时终态成因**覆盖**了触发成因。本版一列一义:`ending_cause`(终态成因)+ `park_trigger`(触发成因,只由 expire claim 写一次)。
|
|
333
|
+
* **SQL 两方言**({@link splitApprovalAskCauseColumns},锁内,M18 之后):① `denied_reason` 在 ⇒ 改名成 `ending_cause`(MySQL 协议 `CHANGE COLUMN`、PG `RENAME COLUMN`;后置条件 `execUntil`)——
|
|
334
|
+
* 改名让滚动窗里的旧副本对这张表的每一条读写**响亮失败**(它们的列清单点名 `denied_reason`),而不是把触发词写进终态列;② `park_trigger` 不在 ⇒ 加列;
|
|
335
|
+
* ③ PARKING / PARKED 行上那一格搬进 `park_trigger`(`park_trigger IS NULL` 才搬),再把这两态上的 `ending_cause` 置空(两句各自幂等;第二跑起零命中)。
|
|
336
|
+
* 中断 ⇒ 下一次起服从首个未满足的后置条件续(钉:真库在改名之后续跑收敛)。终态行上被覆盖掉的触发词没有出处可补 —— 如实缺席。
|
|
337
|
+
* **local 车道**(File 问账日志):信封号 1 → 2;窗内读侧半场按意义译 v1 记录(`approval-ask-store-file.ts` 的 `translateJournalV1Record`),
|
|
338
|
+
* 起服迁移的 local 腿(`FileApprovalAskStore.upgradeJournalEnvelope`)一次压实把整本重写成 v2。
|
|
339
|
+
* **回滚**:7.141.x 对改名后的表每一条读写都响亮失败、对 v2 日志拒启 —— 回滚的唯一支持形 = 恢复升级前的备份,或手工把列改回(MIGRATION 写了语句)。
|
|
340
|
+
* 读数:`askCauseColumnsChanged`(0–2 处表形改动)/ `askParkTriggersMoved`(SQL;local 恒 0)/ `askJournalRecordsUpgraded`(local;SQL 恒 0)。
|
|
331
341
|
*
|
|
332
342
|
* ## 收据账(一次起服一只,每一条迁移同一只)
|
|
333
343
|
* 每一步把它**已提交**的改写 / 删除与点名读数当场记进同一只收据账({@link MigrationReceipts}):计数随每次提交累加、行随每次提交追加、形读数在那一步落定时写。走完 ⇒
|
|
@@ -446,6 +456,12 @@ export interface OneTimeMigrationReport {
|
|
|
446
456
|
readonly localArchivesUnreadable: readonly LocalArchiveUnreadable[];
|
|
447
457
|
/** M33:本次起服消化掉的快照记录数(上一次被打断的改写留下的;补回 / 丢弃)。local 独有;SQL 恒 0。 */
|
|
448
458
|
readonly localArchiveSnapshotsRecovered: number;
|
|
459
|
+
/** M34:本次对 `approval_ask` 成因列做的表形改动数(改名 `denied_reason → ending_cause`、加 `park_trigger`;0–2)。非零 = 这次真改了表形。SQL 独有;local 恒 0。 */
|
|
460
|
+
readonly askCauseColumnsChanged: number;
|
|
461
|
+
/** M34:本次把那一格从 `ending_cause` 搬进 `park_trigger` 的 PARKING / PARKED 行数。非零 = 真写了存量行。SQL 独有;local 恒 0。 */
|
|
462
|
+
readonly askParkTriggersMoved: number;
|
|
463
|
+
/** M34 local 腿:问账日志里信封号 1 的记录数(窗内读侧已按意义译读;本次一次压实把整本重写成 v2)。非零 = 真重写了日志。local 独有;SQL 恒 0。 */
|
|
464
|
+
readonly askJournalRecordsUpgraded: number;
|
|
449
465
|
}
|
|
450
466
|
/** 退役的两只命令桶(引擎 7.51.0 起不是桶;只给 M17 点名认)。 */
|
|
451
467
|
export type RetiredSessionRuleBucket = "commandAllow" | "commandDeny";
|
|
@@ -585,7 +601,7 @@ export declare function migrationWindowOpen(window: Pick<OneTimeMigrationWindow,
|
|
|
585
601
|
*/
|
|
586
602
|
export declare function migrationWindowEnd(id: string): string;
|
|
587
603
|
/** local 车道上 SQL 独有的几条(M8 / M9 / M11 / M17 / M18 / M21 / M23 / M24 / M26 / M27 / M29)的读数(M6 与 M32 的回填两车道都有、M33 只在 local,local 腿的读数由 `LocalBackend.runOneTimeMigrations` 现算):那几张表 / 列在文件底座上从来不存在 ⇒ 如实答 absent / 0。 */
|
|
588
|
-
export declare const NO_SQL_MIGRATIONS: Omit<OneTimeMigrationReport, "holderDeathCodeRowsBackfilled" | "executionPlacementsBackfilled" | "askExecutionLanesBackfilled" | "executionPlacementSessionsUnreadable" | "localArchiveRowFactsBackfilled" | "localArchivesAnonymized" | "localArchivesKeptStamped" | "localArchivesUnreadable" | "localArchiveSnapshotsRecovered">;
|
|
604
|
+
export declare const NO_SQL_MIGRATIONS: Omit<OneTimeMigrationReport, "holderDeathCodeRowsBackfilled" | "executionPlacementsBackfilled" | "askExecutionLanesBackfilled" | "executionPlacementSessionsUnreadable" | "localArchiveRowFactsBackfilled" | "localArchivesAnonymized" | "localArchivesKeptStamped" | "localArchivesUnreadable" | "localArchiveSnapshotsRecovered" | "askJournalRecordsUpgraded">;
|
|
589
605
|
/** 启动期的日志口(logger 的子集)。两级各有其用,见 {@link logOneTimeMigrations}。 */
|
|
590
606
|
export interface MigrationLogSink {
|
|
591
607
|
warn(msg: string, meta?: Record<string, unknown>): void;
|
|
@@ -619,6 +635,16 @@ export interface MigrationDb {
|
|
|
619
635
|
* `createStoreBackend()` → `ensureSchema()` → `runOneTimeMigrations()` 的嵌入方与本服务的起服序列一样,有这一问、零动作。
|
|
620
636
|
*/
|
|
621
637
|
export declare function runSqlOneTimeMigrations(dialect: SqlDialect, pool: MysqlPool | PgPool, input: ExecutionPlacementSwitchInput): Promise<OneTimeMigrationReport>;
|
|
638
|
+
/**
|
|
639
|
+
* M34 —— 问账行成因两列(判据与形见头注 M34 段)。三步,每一步先读形再判,DDL 按后置条件收敛({@link execUntil}),中断 ⇒ 下一次起服从首个未满足的后置条件续:
|
|
640
|
+
* ① `denied_reason` 在 ⇒ 改名成 `ending_cause`(后置条件:旧名不在 ∧ 新名在)—— 改名让滚动窗里的旧副本对这张表的每一条读写响亮失败;
|
|
641
|
+
* ② `park_trigger` 不在 ⇒ 加列(列定义 = 建表 DDL 内联的同一份);
|
|
642
|
+
* ③ PARKING / PARKED 行:`ending_cause` 里的词搬进 `park_trigger`(只搬 `park_trigger IS NULL` 的行),再把这两态上的 `ending_cause` 置空。两句而不是一句
|
|
643
|
+
* `SET park_trigger = ending_cause, ending_cause = NULL`:一句的结果取决于赋值的求值次序(MySQL 协议方言按左到右读已改的值,PG 读原行),两句不依赖它;两句各自幂等,
|
|
644
|
+
* 中间被打断 ⇒ 下一次起服第一句零命中、第二句收尾(这期间读口照旧:终态成因读口在这两态上不作数)。本版写者不会在这两态上写终态成因 ⇒ 第二跑起两句都零命中。
|
|
645
|
+
* 表不在(中央 DDL 之前被调到)⇒ 零动作。读数:①② 各记 `askCauseColumnsChanged` +1;③ 第一句的受影响行数记 `askParkTriggersMoved`。
|
|
646
|
+
*/
|
|
647
|
+
export declare function splitApprovalAskCauseColumns(db: MigrationDb, dialect: SqlDialect, receipts: MigrationReceipts): Promise<void>;
|
|
622
648
|
/** M32 的起服拒码(确定的拒启表态:再等也等不来另一个答案;不是线上 wire 码,与 `config.schema_mismatch` 同一族)。 */
|
|
623
649
|
export declare const EXECUTION_PLACEMENT_SWITCH_REFUSED_CODE = "config.execution_placement_switch_refused";
|
|
624
650
|
/** 拒因闭集:`fence` = 切换开始之后退役绑定表里又出现了行(旧版副本 / 手工写下的);`backfill_ambiguous` = 车道表不止一项而还有要回填的存量。 */
|
|
@@ -17,7 +17,7 @@ import { redactSecrets } from "../trace/redact.js";
|
|
|
17
17
|
import { CLAIM_OWNERLESS_PLACED_SQL, claimOwnerlessParams, isOrphanSessionOwner, judgeDelegatedOwner } from "../delegated-session-owner.js";
|
|
18
18
|
import { MAILBOX_KEYED_TABLES, mailboxKeyDeleteSql, storedMailboxKeyless } from "./mailbox-store-sql.js";
|
|
19
19
|
import { SESSION_META_PLACEMENT_COLUMNS, backfillWriterStatement, countOrphanBindingsStatement, migrateDeviceBindingsStatement } from "./execution-placement-sql.js";
|
|
20
|
-
import { APPROVAL_ASK_EXECUTION_LANE_COLUMN, APPROVAL_ASK_TABLE } from "./approval-ask-store-sql.js";
|
|
20
|
+
import { APPROVAL_ASK_ENDING_CAUSE_COLUMN, APPROVAL_ASK_EXECUTION_LANE_COLUMN, APPROVAL_ASK_PARK_TRIGGER_COLUMN, APPROVAL_ASK_TABLE } from "./approval-ask-store-sql.js";
|
|
21
21
|
import { isUnusableArchive } from "../execution-placement.js";
|
|
22
22
|
const RETIRED_SESSION_RULE_BUCKETS = ["commandAllow", "commandDeny"];
|
|
23
23
|
export function buildMigrationReceipts() {
|
|
@@ -60,6 +60,9 @@ export function buildMigrationReceipts() {
|
|
|
60
60
|
localArchivesKeptStamped: [],
|
|
61
61
|
localArchivesUnreadable: [],
|
|
62
62
|
localArchiveSnapshotsRecovered: 0,
|
|
63
|
+
askCauseColumnsChanged: 0,
|
|
64
|
+
askParkTriggersMoved: 0,
|
|
65
|
+
askJournalRecordsUpgraded: 0,
|
|
63
66
|
};
|
|
64
67
|
}
|
|
65
68
|
function completedReport(r) {
|
|
@@ -110,7 +113,10 @@ function changedAnything(r) {
|
|
|
110
113
|
r.localArchivesAnonymized > 0 ||
|
|
111
114
|
r.localArchivesKeptStamped.length > 0 ||
|
|
112
115
|
r.localArchivesUnreadable.length > 0 ||
|
|
113
|
-
r.localArchiveSnapshotsRecovered > 0
|
|
116
|
+
r.localArchiveSnapshotsRecovered > 0 ||
|
|
117
|
+
r.askCauseColumnsChanged > 0 ||
|
|
118
|
+
r.askParkTriggersMoved > 0 ||
|
|
119
|
+
r.askJournalRecordsUpgraded > 0);
|
|
114
120
|
}
|
|
115
121
|
function readingsSnapshot(r) {
|
|
116
122
|
return {
|
|
@@ -561,6 +567,22 @@ export const ONE_TIME_MIGRATIONS = [
|
|
|
561
567
|
"读 / 续跑 / 拉取照常 —— 出路 = 删掉会话后重推,或升级时先过一次带本条的版本并在窗内起服;③ 行上没有建档时刻的格(同一类数据根)⇒ 列表 / 会话视图 / 交出的元数据读纪元(F 类 tag 计数)",
|
|
562
568
|
reportKeys: ["localArchiveRowFactsBackfilled", "localArchivesAnonymized", "localArchivesKeptStamped", "localArchivesUnreadable", "localArchiveSnapshotsRecovered"],
|
|
563
569
|
},
|
|
570
|
+
{
|
|
571
|
+
id: "M34",
|
|
572
|
+
introducedIn: "7.142.0",
|
|
573
|
+
releasedOn: "2026-10-30",
|
|
574
|
+
removableAfter: "2026-11-29",
|
|
575
|
+
removal: "删 migrateStepsOn 的 M34 步(`splitApprovalAskCauseColumns`、`RETIRED_ASK_CAUSE_COLUMN`、`renameAskCauseColumnSql`)与本文件的 `askCauseColumnsChanged` / `askParkTriggersMoved` / `askJournalRecordsUpgraded`" +
|
|
576
|
+
"(报告 / 收据 / `changedAnything` / `readingFields` / `NO_SQL_MIGRATIONS` 与读数行 note 里的 M34 句、头注 M34 段);`approval-ask-store-file.ts` 的 v1 读侧半场 " +
|
|
577
|
+
"(`translateJournalV1Record`、`JOURNAL_V1_ENVELOPE`、`V1_ENDING_STATES` / `V1_TRIGGER_STATES`、`replayRecord` 里认 v1 的那两行与 `journalV1Records`)与 local 腿 `upgradeJournalEnvelope`、" +
|
|
578
|
+
"`store-backend.ts` 的 `LocalBackend.runOneTimeMigrations` 里报 `askJournalRecordsUpgraded` 的那一行;`test/approval-ask-store-db-integration.test.ts` 的 M34 组与 " +
|
|
579
|
+
"`test/approval-ask-cause-columns.test.ts` 里标题含 ⑤ 与 local 腿读数的格。**不随本条删**:两列与它们的列定义(`APPROVAL_ASK_ENDING_CAUSE_COLUMN` / `APPROVAL_ASK_PARK_TRIGGER_COLUMN`)、" +
|
|
580
|
+
"两只读口(`askRowEndingCause` / `askRowParkTrigger`)、信封号 2 与「认不出的信封号 ⇒ 拒启」那一臂(常设的数据形)",
|
|
581
|
+
afterRemoval: "两只常设臂接住:① SQL —— 删码同版把 `approval_ask.denied_reason` 加进退役 schema 判据(`schema-consistency.ts` 的跳版库探针,先于建表)⇒ 跳过了带本条的版本直接升的库响亮拒启," +
|
|
582
|
+
"出路 = 先在带本条的版本起服一次让迁移走完,再升(列册对账见幽灵列 / 缺列同样拒启,但它的拒句给的是加列,不是这一出路 —— 所以退役判据要在删码同版加上);" +
|
|
583
|
+
"② local —— 信封号 1 的日志记录走 File 问账店「认不出的信封号」拒启(`unknown envelope version`,点名文件与出路:用写下它的那一版起服一次,或移开文件)",
|
|
584
|
+
reportKeys: ["askCauseColumnsChanged", "askParkTriggersMoved", "askJournalRecordsUpgraded"],
|
|
585
|
+
},
|
|
564
586
|
];
|
|
565
587
|
export function migrationWindowOpen(window, today) {
|
|
566
588
|
return window.removableAfter === null || today <= window.removableAfter;
|
|
@@ -606,6 +628,8 @@ export const NO_SQL_MIGRATIONS = {
|
|
|
606
628
|
deviceBindingsMoved: 0,
|
|
607
629
|
deviceBindingsOrphaned: 0,
|
|
608
630
|
deviceBindingTablesDropped: 0,
|
|
631
|
+
askCauseColumnsChanged: 0,
|
|
632
|
+
askParkTriggersMoved: 0,
|
|
609
633
|
};
|
|
610
634
|
function mysqlDb(conn) {
|
|
611
635
|
return {
|
|
@@ -701,6 +725,7 @@ async function migrateStepsOn(db, dialect, receipts, input) {
|
|
|
701
725
|
: "UPDATE task_run SET error_code = $1 WHERE status = 'failed' AND error_code IS NULL AND (error = $2 OR error LIKE $3)", [RUN_HOLDER_DEATH_CODES.orphaned, RUN_ORPHANED_ERROR, `${RUN_ORPHANED_ERROR} (%`]);
|
|
702
726
|
await migrateShadowedRuleKey(db, dialect, receipts);
|
|
703
727
|
await migrateRetiredCardWords(db, dialect, receipts);
|
|
728
|
+
await splitApprovalAskCauseColumns(db, dialect, receipts);
|
|
704
729
|
await reshapeWorkflowParkIndex(db, dialect, receipts);
|
|
705
730
|
await migrateSessionRuleGrammar(db, dialect, receipts);
|
|
706
731
|
await repairParkedRows(db, dialect, receipts);
|
|
@@ -715,6 +740,28 @@ async function migrateStepsOn(db, dialect, receipts, input) {
|
|
|
715
740
|
await dropRejectedMailboxKeys(db, dialect, receipts);
|
|
716
741
|
await switchExecutionPlacement(db, dialect, receipts, input);
|
|
717
742
|
}
|
|
743
|
+
const RETIRED_ASK_CAUSE_COLUMN = "denied_reason";
|
|
744
|
+
function renameAskCauseColumnSql(dialect) {
|
|
745
|
+
return dialect === "mysql"
|
|
746
|
+
? `ALTER TABLE ${APPROVAL_ASK_TABLE} CHANGE COLUMN ${RETIRED_ASK_CAUSE_COLUMN} ${APPROVAL_ASK_ENDING_CAUSE_COLUMN.mysql}`
|
|
747
|
+
: `ALTER TABLE ${APPROVAL_ASK_TABLE} RENAME COLUMN ${RETIRED_ASK_CAUSE_COLUMN} TO ${APPROVAL_ASK_ENDING_CAUSE_COLUMN.name}`;
|
|
748
|
+
}
|
|
749
|
+
export async function splitApprovalAskCauseColumns(db, dialect, receipts) {
|
|
750
|
+
if (!(await tableExists(db, dialect, APPROVAL_ASK_TABLE)))
|
|
751
|
+
return;
|
|
752
|
+
const has = (column) => columnExists(db, dialect, APPROVAL_ASK_TABLE, column);
|
|
753
|
+
if (await has(RETIRED_ASK_CAUSE_COLUMN)) {
|
|
754
|
+
await execUntil(db, renameAskCauseColumnSql(dialect), async () => !(await has(RETIRED_ASK_CAUSE_COLUMN)) && (await has(APPROVAL_ASK_ENDING_CAUSE_COLUMN.name)));
|
|
755
|
+
receipts.askCauseColumnsChanged += 1;
|
|
756
|
+
}
|
|
757
|
+
if (!(await has(APPROVAL_ASK_PARK_TRIGGER_COLUMN.name))) {
|
|
758
|
+
await execUntil(db, `ALTER TABLE ${APPROVAL_ASK_TABLE} ADD COLUMN ${APPROVAL_ASK_PARK_TRIGGER_COLUMN[dialect]}`, () => has(APPROVAL_ASK_PARK_TRIGGER_COLUMN.name));
|
|
759
|
+
receipts.askCauseColumnsChanged += 1;
|
|
760
|
+
}
|
|
761
|
+
receipts.askParkTriggersMoved += await db.exec(`UPDATE ${APPROVAL_ASK_TABLE} SET ${APPROVAL_ASK_PARK_TRIGGER_COLUMN.name} = ${APPROVAL_ASK_ENDING_CAUSE_COLUMN.name} ` +
|
|
762
|
+
`WHERE state IN ('PARKING', 'PARKED') AND ${APPROVAL_ASK_PARK_TRIGGER_COLUMN.name} IS NULL AND ${APPROVAL_ASK_ENDING_CAUSE_COLUMN.name} IS NOT NULL`);
|
|
763
|
+
await db.exec(`UPDATE ${APPROVAL_ASK_TABLE} SET ${APPROVAL_ASK_ENDING_CAUSE_COLUMN.name} = NULL WHERE state IN ('PARKING', 'PARKED') AND ${APPROVAL_ASK_ENDING_CAUSE_COLUMN.name} IS NOT NULL`);
|
|
764
|
+
}
|
|
718
765
|
const RETIRED_DEVICE_BINDING_TABLE = "device_session";
|
|
719
766
|
const PARKED_DEVICE_BINDING_TABLE = "device_session_retired";
|
|
720
767
|
const BINDING_COLUMNS = "root_session_id, device_id, owner_tenant, owner_subject, bound_at, rev";
|
|
@@ -1637,6 +1684,9 @@ function readingFields(r) {
|
|
|
1637
1684
|
localArchivesKeptStamped: r.localArchivesKeptStamped.length,
|
|
1638
1685
|
localArchivesUnreadable: r.localArchivesUnreadable.length,
|
|
1639
1686
|
localArchiveSnapshotsRecovered: r.localArchiveSnapshotsRecovered,
|
|
1687
|
+
askCauseColumnsChanged: r.askCauseColumnsChanged,
|
|
1688
|
+
askParkTriggersMoved: r.askParkTriggersMoved,
|
|
1689
|
+
askJournalRecordsUpgraded: r.askJournalRecordsUpgraded,
|
|
1640
1690
|
};
|
|
1641
1691
|
}
|
|
1642
1692
|
export function logOneTimeMigrations(log, backend, report) {
|
|
@@ -1690,7 +1740,11 @@ export function logOneTimeMigrations(log, backend, report) {
|
|
|
1690
1740
|
"that still carried an importer's owner stamp were rewritten as anonymous with every entry kept as it was (a snapshot of the log is written before each rewrite " +
|
|
1691
1741
|
"and removed after it; an interrupted rewrite is finished from the snapshot on the next boot); an archive whose log the import check refuses, whose re-import would " +
|
|
1692
1742
|
"change its content, or whose read skipped unreadable records is left byte for byte as it was and named by a local_archive_kept_stamped line, and a session whose " +
|
|
1693
|
-
"archive header cannot be read is named by a local_archive_unreadable line
|
|
1743
|
+
"archive header cannot be read is named by a local_archive_unreadable line; " +
|
|
1744
|
+
"M34: the approval ask table's single cause column denied_reason — the reason a row was moved to the delivery surface while it is PARKING or PARKED, " +
|
|
1745
|
+
"the reason it ended without a human answer while it is VOID or DENIED, overwritten by the second when a parked row was closed — renamed ending_cause, " +
|
|
1746
|
+
"a column park_trigger added, and the word on PARKING and PARKED rows moved into park_trigger; on the local backend the approval ask journal is rewritten " +
|
|
1747
|
+
"once with record envelope 2, its envelope-1 records read with the same meaning). Each step " +
|
|
1694
1748
|
"runs on every boot until its window closes (the release that introduced it + 30 days; the per-step date is in " +
|
|
1695
1749
|
"removableAfter, null while that release is not published yet) and is deleted in the first minor after that — start a " +
|
|
1696
1750
|
"version that still carries a step at least once before upgrading past its deletion.",
|
|
@@ -24,6 +24,7 @@ import { FileError, ExecutionError, RemoteExecutionError, type ExecutionEnv, typ
|
|
|
24
24
|
import { type SandboxReadFloorKnob } from "../execution-lane-caps.js";
|
|
25
25
|
import { type SandboxReadFloor } from "./sandbox-read-floor.js";
|
|
26
26
|
import { type LaneHomeConfig } from "../lane-home-probe.js";
|
|
27
|
+
import type { WorkspaceFill, WorkspaceFillOf } from "./workspace-fill.js";
|
|
27
28
|
/** Options accepted by `ExecutionEnv.exec` (core does not re-export the type; derive it from the seam). */
|
|
28
29
|
type ExecOpts = Parameters<ExecutionEnv["exec"]>[1];
|
|
29
30
|
/** Minimal optional observability hooks (kept structural so the adapter stays standalone-testable). */
|
|
@@ -75,6 +76,8 @@ export interface RemoteContainerEnvConfig extends RemoteEnvObservers, LaneHomeCo
|
|
|
75
76
|
dataTimeoutMs?: number;
|
|
76
77
|
/** `SANDBOX_READ_FLOOR`(keep | off;缺席 ⇒ keep):本沙箱守不守读拒表的字节地板 = 读地板模块服务本车道 ∧ 本键不是 off(`sandbox-read-floor.ts`)。 */
|
|
77
78
|
sandboxReadFloor?: SandboxReadFloorKnob;
|
|
79
|
+
/** 恢复点的填充座(`workspace-fill.ts`;工厂按 run 装配):沙箱新建 / 恢复之后、交给本环境之前,经本适配器已连上的通道往工作区里放内容。缺席 ⇒ 不放。 */
|
|
80
|
+
workspaceFill?: WorkspaceFill;
|
|
78
81
|
}
|
|
79
82
|
/** Minimal slice of the E2B `Sandbox` static API the adapter uses — injectable so tests pass a fake. */
|
|
80
83
|
export interface SandboxApi {
|
|
@@ -124,9 +127,12 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
|
|
|
124
127
|
private destroyed;
|
|
125
128
|
/** 家目录的座(主张在场 ⇒ 每只沙箱对证 · 否则建沙箱那一拍实测 · 实测缺席 ⇒ 缺席 + 一行 warn)。 */
|
|
126
129
|
private readonly homeSeat;
|
|
127
|
-
/**
|
|
128
|
-
|
|
129
|
-
|
|
130
|
+
/** 这只环境的拒 —— 记一次、此后每次连接 / 恢复原样回它(同一模板同一个答案:不再建沙箱、不再问)。两个写者:家目录(沙箱答了而与主张不一致,或答的不是绝对路径)
|
|
131
|
+
* 与恢复点的填充(换一台沙箱也是同一个答的拒:种子不是项目包、摘要不符、镜像没有 `tar`、镜像预置撞名 —— `FillOutcome.standing`)。 */
|
|
132
|
+
private connectRefusal?;
|
|
133
|
+
/** In-flight connect/resume, memoized so concurrent lazy first-use OR resume provisions exactly one VM (no double-bill). `target` = the snapshot a resume
|
|
134
|
+
* restores (`undefined` = a fresh sandbox): {@link resumeVM} shares only a resume of the SAME snapshot — a connect for anything else is not the
|
|
135
|
+
* workspace it is asked to restore (it waits that one out, then releases the sandbox it left). */
|
|
130
136
|
private connecting?;
|
|
131
137
|
/** Count of exec/execStream calls in flight — `suspendVM` refuses while > 0 (council #4: never snapshot a running command). */
|
|
132
138
|
private activeCommands;
|
|
@@ -150,6 +156,8 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
|
|
|
150
156
|
/** 地板模块的三件原语。引导命令经 {@link startIn}(起动形 `bootstrap`:只在附着中合法);放置 = root 建目录 → `files.write`(root)写暂存件 →
|
|
151
157
|
* root `chmod 0755 && mv -f`;中继 = 以模块给的身份起一只长连后台命令(stdin 开着:`sendStdin` 写答,stdout 回调读问)。 */
|
|
152
158
|
private floorTransport;
|
|
159
|
+
/** 收据句柄。还没连上(懒环境:续跑腿的引擎在 `resumeVM` **之前**先取它比车道)⇒ 未连接形 `{ sandboxId: "(unconnected)", provider, mountPath }`(与 k8s 车道同形),
|
|
160
|
+
* 不抛 —— 抛了,续跑腿在恢复之前就失败。 */
|
|
153
161
|
workspaceHandle(): WorkspaceHandle;
|
|
154
162
|
/**
|
|
155
163
|
* Public host for a port inside the sandbox (E2B reverse proxy → `<port>-<id>.e2b.app`). The LSP sidecar
|
|
@@ -197,6 +205,11 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
|
|
|
197
205
|
ok: false;
|
|
198
206
|
error: RemoteExecutionError;
|
|
199
207
|
}>;
|
|
208
|
+
/** The one walk of a resume ({@link resumeVM} memoizes it). */
|
|
209
|
+
private resumeWalk;
|
|
210
|
+
/** Kill the fresh sandbox this env holds (minted before a restore point that restores another): no second billable VM, no answer from the wrong workspace.
|
|
211
|
+
* The connect memo is the calling resume's own ({@link resumeVM}) — left as it is. */
|
|
212
|
+
private releaseMinted;
|
|
200
213
|
private doResumeVM;
|
|
201
214
|
/** Cross-replica re-attach to a still-running VM = v2 ([ref] council #15: v1.5 always snapshots→resumeVM). */
|
|
202
215
|
reconnect(_sessionToken: SessionToken): Promise<{
|
|
@@ -227,6 +240,10 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
|
|
|
227
240
|
* 上界 = 控制面 RPC 的墙钟(`rpcTimeoutMs`:问一个环境变量,不是跑用户命令)。
|
|
228
241
|
*/
|
|
229
242
|
private homeVerdict;
|
|
243
|
+
/** 恢复点的填充:有座 ⇒ 经这只沙箱的通道({@link fillChannel})放(`origin` = 新建的沙箱 / 恢复出来的沙箱);没有 ⇒ 什么都不放。 */
|
|
244
|
+
private fillAt;
|
|
245
|
+
/** 恢复点手里的通道:固定命令经唯一起动接缝(起动形 `adapter`,与引擎命令同一执行用户)、写 = `files.write`(与文件面同一个缺省用户);两件都受数据墙钟。 */
|
|
246
|
+
private fillChannel;
|
|
230
247
|
/** BL-31 — (re)start the periodic sandbox-lifetime extension. `setTimeout(timeoutMs)` resets the auto-kill window
|
|
231
248
|
* from now; we re-arm at ~80% of the (clamped, ≤1h) window so a long-held sandbox never expires mid-run. A no-op
|
|
232
249
|
* when paused/destroyed; `unref`'d so it never keeps the process alive; cleared on destroy. */
|
|
@@ -380,6 +397,8 @@ export declare class RemoteContainerExecutionEnv implements RemoteExecutionEnv,
|
|
|
380
397
|
* so a task that never touches the hand (e.g. a leader that only plans) pays zero VM cost. The Runner owns the
|
|
381
398
|
* lifetime and calls `destroy()` on task end (via `hasDestroy`); a never-used env's destroy is a no-op.
|
|
382
399
|
*/
|
|
383
|
-
export declare function e2bExecutionEnvFactory(config: RemoteContainerEnvConfig,
|
|
400
|
+
export declare function e2bExecutionEnvFactory(config: Omit<RemoteContainerEnvConfig, "workspaceFill"> & {
|
|
401
|
+
readonly workspaceFillOf?: WorkspaceFillOf;
|
|
402
|
+
}, deps?: RemoteContainerEnvDeps): ExecutionEnvFactory;
|
|
384
403
|
export {};
|
|
385
404
|
//# sourceMappingURL=remote-env-e2b.d.ts.map
|