@sema-agent/server 7.43.0 → 7.44.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/USAGE.md +18 -0
- package/dist/adoption/plan.js +31 -192
- package/dist/adoption/quiesce.js +3 -86
- package/dist/adoption/runner.js +3 -140
- package/dist/adoption/sql.js +0 -74
- package/dist/adoption/wire.js +0 -80
- package/dist/approval-ask-machine.js +0 -75
- package/dist/approval-card.js +0 -323
- package/dist/approval-deny-reasons.js +0 -42
- package/dist/approval-hmac.js +0 -35
- package/dist/approval-reconciler.js +8 -166
- package/dist/approval.js +4 -67
- package/dist/audit.js +1 -44
- package/dist/auth-bridge.js +4 -47
- package/dist/auth-keys.js +0 -23
- package/dist/bake-runner/main.js +4 -65
- package/dist/bake-runner/protocol.js +3 -58
- package/dist/bake-runner/runner.js +5 -91
- package/dist/bench/l8/artifact.js +2 -61
- package/dist/bench/l8/escape.js +0 -25
- package/dist/bench/l8/index.js +0 -14
- package/dist/bench/l8/probes.js +0 -60
- package/dist/bench/l8/run-probes.js +2 -45
- package/dist/bench/s1/arms.js +14 -189
- package/dist/bench/s1/live-deps.js +11 -253
- package/dist/bench/s1/oracle.js +1 -36
- package/dist/bench/s1/repair-oracle-adapter.js +0 -30
- package/dist/bench/s1/reviewer.js +0 -34
- package/dist/bench/s1/row.js +0 -62
- package/dist/bench/s1/run-firm.js +4 -70
- package/dist/bench/s1/runner-ctx.js +0 -40
- package/dist/bench/s1/tasks.js +0 -115
- package/dist/boot/adoption.js +0 -20
- package/dist/boot/budget-tracing.js +3 -55
- package/dist/boot/config-center.js +43 -551
- package/dist/boot/coordinators.js +1 -69
- package/dist/boot/crash-last.js +0 -18
- package/dist/boot/deferred-sandbox-path-env.js +3 -119
- package/dist/boot/execution-env.js +5 -171
- package/dist/boot/governance-seams.js +0 -92
- package/dist/boot/leader.js +0 -69
- package/dist/boot/limit-sync.js +0 -2
- package/dist/boot/memory-boundary.js +3 -91
- package/dist/boot/org-memory.js +1 -25
- package/dist/boot/parked-revive-gate.js +0 -150
- package/dist/boot/permission-rules-audit.js +1 -56
- package/dist/boot/reapers.js +15 -273
- package/dist/boot/resolve-spec.js +9 -768
- package/dist/boot/retention-lane.js +4 -87
- package/dist/boot/runner-deps.js +3 -297
- package/dist/boot/runtime-caps.js +0 -40
- package/dist/boot/session-faces.js +2 -133
- package/dist/boot/shutdown.js +9 -83
- package/dist/boot/side-query-lane.js +2 -137
- package/dist/boot/stores.js +15 -215
- package/dist/boot/task-list-lane.js +0 -18
- package/dist/boot/webfetch-summarize-lane.js +0 -47
- package/dist/boot/workflow-orchestration.js +3 -99
- package/dist/boot-reclaim.js +0 -20
- package/dist/bounded-session-map.js +0 -19
- package/dist/brain.js +2 -139
- package/dist/budget.js +9 -244
- package/dist/capabilities/builtin-tools.js +0 -3
- package/dist/capabilities/center-plugins.js +6 -51
- package/dist/capabilities/center-prompts.js +6 -71
- package/dist/capabilities/code-review-council.js +7 -40
- package/dist/capabilities/collab-workflows.js +1 -44
- package/dist/capabilities/hands-lane.js +0 -65
- package/dist/capabilities/memory-notice.js +0 -70
- package/dist/capabilities/prompt.js +0 -14
- package/dist/capabilities/prompts/code-review.js +0 -14
- package/dist/capabilities/prompts/identity.js +0 -6
- package/dist/capabilities/prompts/team.js +0 -4
- package/dist/capabilities/repo-tools.js +0 -34
- package/dist/capabilities/sandbox-file-send.js +3 -92
- package/dist/capabilities/scenarios.d.ts +0 -1
- package/dist/capabilities/scenarios.js +18 -279
- package/dist/capabilities/select-environment-tool.js +0 -32
- package/dist/capabilities/send-user-file-tool.js +2 -66
- package/dist/capabilities/skills.d.ts +1 -2
- package/dist/capabilities/skills.js +3 -21
- package/dist/capabilities/team.d.ts +3 -11
- package/dist/capabilities/team.js +3 -51
- package/dist/capabilities/tool-defer.js +0 -3
- package/dist/config-center/apply-effective.js +15 -330
- package/dist/config-center/apply-ledger.js +5 -38
- package/dist/config-center/facade.js +0 -41
- package/dist/config-center/hot-keys-registry.js +0 -20
- package/dist/config-center/http-client.js +2 -125
- package/dist/config-center/mcp-revocation.js +2 -34
- package/dist/config-center/read-face.js +0 -59
- package/dist/config-center/restart-signal.js +1 -85
- package/dist/config-center/skills-mcp.d.ts +1 -1
- package/dist/config-center/skills-mcp.js +9 -76
- package/dist/config-center/stage-limits.js +8 -35
- package/dist/config-invariants.js +0 -16
- package/dist/config-lkg.js +0 -42
- package/dist/config-provider.js +3 -186
- package/dist/config-types.js +0 -5
- package/dist/config.js +107 -1145
- package/dist/degenerate-instrument.js +3 -67
- package/dist/deployment-governance.js +0 -124
- package/dist/digest-form.js +0 -12
- package/dist/elicitation.js +3 -86
- package/dist/env-facts.js +7 -75
- package/dist/fleet/fleet-bus.js +34 -507
- package/dist/fleet/fleet-reconciler.js +9 -149
- package/dist/fleet/fleet-terminal-window.js +10 -178
- package/dist/fleet/subagent-tail-bus.js +3 -72
- package/dist/fleet-client.js +10 -70
- package/dist/fleet-lease.js +5 -79
- package/dist/git-api-kind.js +0 -3
- package/dist/governance-ask-marks.js +2 -78
- package/dist/hooks/branch-transcript.js +0 -74
- package/dist/hooks/cc-agent-hook-prompt.js +0 -29
- package/dist/hooks/cc-stop-prompt.js +1 -46
- package/dist/hooks/hook-llm.js +1 -53
- package/dist/hooks/hook-runner.js +20 -414
- package/dist/http/active-run-conflict.js +4 -129
- package/dist/http/cursor-fingerprint.d.ts +5 -0
- package/dist/http/cursor-fingerprint.js +5 -0
- package/dist/http/idempotency.js +0 -37
- package/dist/http/principal-gate.js +3 -40
- package/dist/http/route-ctx.js +0 -9
- package/dist/http/routes/a2a-serve.js +7 -319
- package/dist/http/routes/admin-config-refresh.js +0 -4
- package/dist/http/routes/admin-drain.js +0 -10
- package/dist/http/routes/adoption.js +1 -29
- package/dist/http/routes/agents-roster.js +1 -47
- package/dist/http/routes/approvals-assistant.js +32 -395
- package/dist/http/routes/attachments.js +4 -22
- package/dist/http/routes/capabilities.js +3 -420
- package/dist/http/routes/diagnostics.js +1 -81
- package/dist/http/routes/fleet.js +9 -185
- package/dist/http/routes/images.js +14 -239
- package/dist/http/routes/leader.js +0 -13
- package/dist/http/routes/memory-bundle.js +1 -61
- package/dist/http/routes/memory-policy.js +9 -99
- package/dist/http/routes/notify-wake.js +3 -37
- package/dist/http/routes/observability.js +2 -19
- package/dist/http/routes/retention-ops.js +2 -34
- package/dist/http/routes/rules.js +1 -93
- package/dist/http/routes/runs.js +64 -873
- package/dist/http/routes/session-sync.js +19 -258
- package/dist/http/routes/sessions-list.js +17 -43
- package/dist/http/routes/sessions.js +34 -226
- package/dist/http/routes/shared-memory.js +5 -36
- package/dist/http/routes/side-query.js +1 -87
- package/dist/http/routes/tasks.js +52 -722
- package/dist/http/routes/trace-usage.js +32 -195
- package/dist/http/routes/workflows.js +19 -195
- package/dist/http/run-meta.js +0 -6
- package/dist/http/send.js +0 -32
- package/dist/http/server.js +92 -1597
- package/dist/http/sse-lifecycle.js +2 -13
- package/dist/http/sse-log.js +3 -48
- package/dist/http/tar.js +5 -21
- package/dist/http/verify-rounds.js +0 -5
- package/dist/http/wire-gate.js +0 -9
- package/dist/http/workspace-content.js +0 -10
- package/dist/images/bake-validate.js +1 -70
- package/dist/images/manifest.js +1 -6
- package/dist/index.js +0 -21
- package/dist/key-resolver.js +2 -17
- package/dist/leader/diffout.js +1 -20
- package/dist/leader/diffup.js +0 -47
- package/dist/leader/endpoint.js +2 -57
- package/dist/leader/fanout.js +3 -45
- package/dist/leader/grader-env-factory.js +3 -72
- package/dist/leader/leader.js +5 -156
- package/dist/leader/merge.js +8 -115
- package/dist/leader/planner.js +3 -54
- package/dist/leader/repair-oracle.js +1 -60
- package/dist/leader/repair-wire.js +2 -79
- package/dist/leader/wire.js +8 -307
- package/dist/lsp/e2b-bridge.js +4 -64
- package/dist/lsp/e2b-manager.js +6 -94
- package/dist/lsp/lsp-frames.js +0 -12
- package/dist/lsp/manager.js +4 -96
- package/dist/lsp/ws-transport.js +5 -55
- package/dist/lsp-evict.js +1 -15
- package/dist/main.js +57 -765
- package/dist/memory-bundle-engine.js +0 -55
- package/dist/memory-export.js +0 -4
- package/dist/memory-posture.js +1 -15
- package/dist/memory-scope.js +11 -148
- package/dist/memory-sync-client.js +2 -44
- package/dist/memory-sync.js +1 -80
- package/dist/model-select.js +3 -80
- package/dist/observability/cost-quota.js +1 -17
- package/dist/observability/cost-taxonomy.js +0 -34
- package/dist/observability/fail-open.js +7 -86
- package/dist/observability/logger.js +0 -6
- package/dist/observability/metrics.js +0 -94
- package/dist/observability/otel-exporter.js +3 -13
- package/dist/observability/principal-context.js +0 -9
- package/dist/observability/prompt-manifest.js +1 -37
- package/dist/observability/rate-limit.js +0 -4
- package/dist/observability/secret-env-scrub.js +2 -56
- package/dist/observability/tool-trace.js +1 -70
- package/dist/orchestration/hardened-vm-runner.js +4 -118
- package/dist/orchestration/hardened-vm-worker-runner.js +1 -26
- package/dist/orchestration/hardened-vm-worker.js +0 -27
- package/dist/orchestration/subagent-steer.js +1 -45
- package/dist/orchestration/workflow-agent-steer.js +1 -80
- package/dist/orchestration/workflow-completion-inbox.js +32 -285
- package/dist/orchestration/workflow-notify-journal.js +16 -259
- package/dist/org-memory-admission.js +3 -47
- package/dist/parent-watch.js +2 -48
- package/dist/parked-decide.js +1 -109
- package/dist/per-task-image.js +0 -57
- package/dist/plan-cache-probe.js +3 -27
- package/dist/plugins/adoption-log-sql.js +2 -119
- package/dist/plugins/approval-ask-store-memory.js +3 -38
- package/dist/plugins/approval-ask-store-sql.js +6 -188
- package/dist/plugins/approval-exemption-store.js +2 -28
- package/dist/plugins/background-agent-store-sql.js +4 -105
- package/dist/plugins/background-shell-support.js +14 -122
- package/dist/plugins/blob-backend.js +6 -169
- package/dist/plugins/breaker-state-sql.js +8 -46
- package/dist/plugins/caching-session-store.js +4 -106
- package/dist/plugins/checkpoint-store-sql.js +18 -505
- package/dist/plugins/e2b-orphan-reclaim.js +0 -45
- package/dist/plugins/file-outcome-sink.js +0 -9
- package/dist/plugins/file-resume-anchor-store.js +4 -43
- package/dist/plugins/file-run-store.js +26 -364
- package/dist/plugins/file-snapshot-store-sql.js +10 -181
- package/dist/plugins/fork-routing-session-store.js +8 -111
- package/dist/plugins/host-platform.js +2 -91
- package/dist/plugins/image-bake-store-sql.js +7 -250
- package/dist/plugins/image-index-sql.js +4 -123
- package/dist/plugins/k8s-bg-scripts.js +4 -88
- package/dist/plugins/k8s-exec-protocol.js +0 -41
- package/dist/plugins/leader-run-store-sql.js +0 -101
- package/dist/plugins/local-checkpoint-store.js +8 -128
- package/dist/plugins/local-session-store.js +34 -296
- package/dist/plugins/local-task-attachment-store.js +2 -16
- package/dist/plugins/mailbox-store-sql.js +8 -65
- package/dist/plugins/memory-embedder-fingerprint.js +5 -166
- package/dist/plugins/memory-embedder.js +4 -70
- package/dist/plugins/memory-engine-pg.js +6 -170
- package/dist/plugins/memory-engine-tidb.js +7 -155
- package/dist/plugins/memory-engine-vector-util.js +0 -10
- package/dist/plugins/memory-key-guards.js +0 -34
- package/dist/plugins/memory-origin-law.js +0 -187
- package/dist/plugins/memory-resume-anchor-store.js +0 -17
- package/dist/plugins/memory-run-store.js +12 -89
- package/dist/plugins/memory-session-policy-store.js +0 -17
- package/dist/plugins/memory-sync-store-pg.js +4 -49
- package/dist/plugins/memory-sync-store-tidb.js +3 -35
- package/dist/plugins/outcome-ledger-sql.js +3 -97
- package/dist/plugins/permission-rule-store-file.js +5 -133
- package/dist/plugins/permission-rule-store-sql.d.ts +3 -0
- package/dist/plugins/permission-rule-store-sql.js +50 -307
- package/dist/plugins/pg-cost-quota.js +0 -7
- package/dist/plugins/pg-pool.js +0 -92
- package/dist/plugins/pg-rate-limiter.js +2 -13
- package/dist/plugins/pg-safe-json.js +4 -40
- package/dist/plugins/pg-session-storage.js +25 -189
- package/dist/plugins/posix-shell-fs.js +1 -31
- package/dist/plugins/remote-env-adb.js +12 -101
- package/dist/plugins/remote-env-e2b.js +40 -371
- package/dist/plugins/remote-env-file-error.js +0 -37
- package/dist/plugins/remote-env-host.js +63 -483
- package/dist/plugins/remote-env-k8s.js +32 -326
- package/dist/plugins/remote-env-local-docker.js +24 -157
- package/dist/plugins/remote-env-ssh.js +20 -128
- package/dist/plugins/remote-scratchpad.js +2 -32
- package/dist/plugins/remote-shell.js +1 -32
- package/dist/plugins/resume-anchor-store-sql.js +0 -11
- package/dist/plugins/retention-lane-store-sql.js +0 -108
- package/dist/plugins/retention-store-sql.js +4 -383
- package/dist/plugins/roster-store-sql.js +0 -55
- package/dist/plugins/run-store-sql.js +14 -251
- package/dist/plugins/s3-presign.js +2 -49
- package/dist/plugins/scheduler-support.js +3 -80
- package/dist/plugins/send-file-ledger.js +4 -53
- package/dist/plugins/send-user-file.js +4 -94
- package/dist/plugins/session-placement.js +1 -89
- package/dist/plugins/session-policy-store-sql.js +3 -81
- package/dist/plugins/session-store.js +0 -57
- package/dist/plugins/shared-memory-store-sql.js +4 -167
- package/dist/plugins/sql-driver.js +0 -17
- package/dist/plugins/sql-errors.js +0 -7
- package/dist/plugins/sql-escape.js +0 -8
- package/dist/plugins/sql-row-helpers.js +0 -25
- package/dist/plugins/store-backend.js +42 -222
- package/dist/plugins/store-contracts.js +2 -46
- package/dist/plugins/task-attachment-store.js +3 -49
- package/dist/plugins/task-list-store-sql.js +0 -79
- package/dist/plugins/tidb-cost-quota.js +1 -4
- package/dist/plugins/tidb-pool.js +1 -207
- package/dist/plugins/tidb-rate-limiter.js +3 -9
- package/dist/plugins/tidb-session-storage.js +4 -70
- package/dist/plugins/tidb-session-store.js +19 -341
- package/dist/plugins/tool-result-store-sql.js +4 -179
- package/dist/plugins/usage-window-store-sql.js +0 -8
- package/dist/plugins/web-search.js +10 -132
- package/dist/plugins/workflow-journal-store-sql.js +2 -58
- package/dist/plugins/workflow-run-store-sql.js +6 -91
- package/dist/plugins/worktree-isolation.js +6 -126
- package/dist/plugins/write-behind-counter.js +16 -75
- package/dist/principal-jwt.js +5 -60
- package/dist/project-memory.js +15 -146
- package/dist/prompts-domain-validate.js +1 -51
- package/dist/question.js +2 -111
- package/dist/resource-suspend.js +0 -18
- package/dist/router/route-orchestration.js +0 -77
- package/dist/rules-consent.d.ts +44 -5
- package/dist/rules-consent.js +75 -215
- package/dist/run-local.js +14 -381
- package/dist/runs.js +29 -617
- package/dist/runtime-caps-resolver.js +6 -132
- package/dist/runtime-governance.js +1 -232
- package/dist/sandbox-pkg-source.js +0 -37
- package/dist/sealed-key.js +3 -68
- package/dist/security.js +6 -291
- package/dist/session-leaf-bus.js +0 -32
- package/dist/session-sync-content.js +1 -69
- package/dist/session-sync-kernel.js +3 -60
- package/dist/session-sync.js +3 -66
- package/dist/session-titler.js +7 -41
- package/dist/session-watch.js +9 -73
- package/dist/shared-memory-scope-authorizer.js +0 -18
- package/dist/sighup-idle.js +1 -12
- package/dist/spec-fields.js +4 -143
- package/dist/store-live-probe.js +3 -49
- package/dist/task-a2a.js +1 -126
- package/dist/task-cwd.js +1 -103
- package/dist/task-mcp.js +1 -89
- package/dist/task-settings.js +10 -300
- package/dist/task-workflow.js +8 -75
- package/dist/tool-approval.d.ts +28 -1
- package/dist/tool-approval.js +70 -1430
- package/dist/trace/artifacts.js +5 -20
- package/dist/trace/engine-notice-wire.js +6 -138
- package/dist/trace/ledger-sink.js +7 -96
- package/dist/trace/project.js +4 -448
- package/dist/trace/redact.js +9 -77
- package/dist/turn-activity.js +1 -27
- package/dist/usage-analytics.js +4 -34
- package/dist/wall-clock-jump-guard.js +1 -68
- package/package.json +3 -3
- package/dist/capabilities/scenario-alias.d.ts +0 -27
- package/dist/capabilities/scenario-alias.js +0 -61
|
@@ -1,43 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* #242([3738] / design/242 v1)— E2B 孤儿沙盒回收。
|
|
3
|
-
*
|
|
4
|
-
* 病:server 进程崩溃(SIGKILL/OOM)后 core Runner 的 `destroy()` 不跑,E2B 沙盒按自己的
|
|
5
|
-
* timeout 窗继续存活计费;崩溃循环下泄漏累积。create 侧的归属打标早已在
|
|
6
|
-
* (`remote-env-e2b.ts` factory:metadata 带 sessionId/taskId,本批补 `semaManaged:"1"`);
|
|
7
|
-
* 本模块是缺的另一半——回收腿。
|
|
8
|
-
*
|
|
9
|
-
* 判据(全部保守方向,**拿不准恒不杀**——回收是清理型能力,缺席判据=不动作,方向纪律见
|
|
10
|
-
* memory `capability-probe-fail-direction`;误杀的代价是杀死一个活任务的手,漏杀的代价只是钱):
|
|
11
|
-
* a. `metadata.semaManaged !== "1"` → 非我方铸造,provider 侧 query 过滤已排除;防御性重验。
|
|
12
|
-
* b. `metadata.taskId` 缺席 → 病态形(factory 恒打标),不杀 + failOpen 留痕。
|
|
13
|
-
* c. run 行在场:
|
|
14
|
-
* LIVE 词(running/suspended/needs_review)→ 活,跳过;
|
|
15
|
-
* TERMINAL 词 → 孤儿,kill;
|
|
16
|
-
* 两表皆不中的词 → 词表纪律(#157):不杀 + failOpen(新词先安全后收编)。
|
|
17
|
-
* d. 行不存在:
|
|
18
|
-
* startedAt 距今 < GRACE → create→行落库窗口,跳过(防误杀新沙盒);
|
|
19
|
-
* ≥ GRACE → 真孤儿,kill(单库 fleet 方向下行跨副本可见)。
|
|
20
|
-
* e. `getRun` 抛错 → 不杀 + failOpen(不知道 ≠ 孤儿)。
|
|
21
|
-
*
|
|
22
|
-
* v1 边界(design/242 §设计②,发车说明同步):跨部署**异库**共用一把 E2B key 的形不支持——
|
|
23
|
-
* 别家沙盒的 taskId 在本库查不到行,超 GRACE 会被误杀;前置=每部署独立 E2B key(本就是推荐姿势)。
|
|
24
|
-
* metadata 无跨重启稳定的部署标识可用(instanceId 每 boot 变,恰是要回收上一世代)是结构原因。
|
|
25
|
-
*
|
|
26
|
-
* kill 逐只 try/catch(一只失败不挡其余);list 整体失败由调用方(reaper throttled catch)兜底。
|
|
27
|
-
*/
|
|
28
1
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
29
|
-
/** create→run 行落库窗口的误杀护栏。非行为表态面,常量不设旋钮(理由:它只需要「远大于一次
|
|
30
|
-
* create+首写延迟、远小于沙盒 timeout 窗」,10min 对两端都有量级余量;错设它的运维事故面比
|
|
31
|
-
* 它保护的窗口更大)。 */
|
|
32
2
|
export const E2B_ORPHAN_GRACE_MS = 10 * 60 * 1000;
|
|
33
|
-
/** factory 打进 metadata 的归属标(create 半场,remote-env-e2b.ts);值恒 "1"。 */
|
|
34
3
|
export const SEMA_MANAGED_METADATA_KEY = "semaManaged";
|
|
35
|
-
// 构造侧 satisfies 锚类型真源;容器声明 ReadonlySet<string> 让消费侧(窄读口的 status: string)直判。
|
|
36
4
|
const LIVE_STATUSES = new Set(["running", "suspended", "needs_review"]);
|
|
37
5
|
const TERMINAL_STATUSES = new Set(["completed", "blocked", "failed"]);
|
|
38
6
|
const _statusesCovered = true;
|
|
39
7
|
void _statusesCovered;
|
|
40
|
-
/** 一轮回收(boot 一次 + reaper interval 周期共用)。list 抛错穿透给调用方(reaper catch 族)。 */
|
|
41
8
|
export async function reclaimOrphanE2bSandboxes(deps) {
|
|
42
9
|
const now = deps.now ?? Date.now;
|
|
43
10
|
const graceMs = deps.graceMs ?? E2B_ORPHAN_GRACE_MS;
|
|
@@ -45,14 +12,12 @@ export async function reclaimOrphanE2bSandboxes(deps) {
|
|
|
45
12
|
const sandboxes = await deps.provider.listManaged();
|
|
46
13
|
for (const sbx of sandboxes) {
|
|
47
14
|
summary.scanned++;
|
|
48
|
-
// a. 防御性重验(provider 装配侧已 query 过滤;fake/将来的宽 provider 不许绕过归属判别)。
|
|
49
15
|
if (sbx.metadata[SEMA_MANAGED_METADATA_KEY] !== "1") {
|
|
50
16
|
summary.skippedUnknown++;
|
|
51
17
|
recordFailOpen("server.e2b.orphan-skip-unknown");
|
|
52
18
|
continue;
|
|
53
19
|
}
|
|
54
20
|
const taskId = sbx.metadata.taskId;
|
|
55
|
-
// b. 病态形:factory 恒打 taskId(ctx.taskId 缺席时连 sessionId 都在而 taskId 不在)——不杀,留痕。
|
|
56
21
|
if (!taskId) {
|
|
57
22
|
summary.skippedUnknown++;
|
|
58
23
|
recordFailOpen("server.e2b.orphan-skip-unknown");
|
|
@@ -62,7 +27,6 @@ export async function reclaimOrphanE2bSandboxes(deps) {
|
|
|
62
27
|
try {
|
|
63
28
|
const run = await deps.runs.getRun(taskId);
|
|
64
29
|
if (run === undefined) {
|
|
65
|
-
// d. 无行:GRACE 内=create→落库窗口;超窗=真孤儿。
|
|
66
30
|
verdict = now() - sbx.startedAt.getTime() < graceMs ? "grace" : "kill";
|
|
67
31
|
}
|
|
68
32
|
else if (LIVE_STATUSES.has(run.status)) {
|
|
@@ -72,12 +36,10 @@ export async function reclaimOrphanE2bSandboxes(deps) {
|
|
|
72
36
|
verdict = "kill";
|
|
73
37
|
}
|
|
74
38
|
else {
|
|
75
|
-
// c. 词表外的新词:不杀 + failOpen(先安全后收编;收编=上面两表加词,遗漏在 census 计数可见)。
|
|
76
39
|
verdict = "unknown";
|
|
77
40
|
}
|
|
78
41
|
}
|
|
79
42
|
catch {
|
|
80
|
-
// e. store 读错:不知道 ≠ 孤儿。
|
|
81
43
|
verdict = "unknown";
|
|
82
44
|
}
|
|
83
45
|
if (verdict === "live")
|
|
@@ -105,19 +67,12 @@ export async function reclaimOrphanE2bSandboxes(deps) {
|
|
|
105
67
|
}
|
|
106
68
|
return summary;
|
|
107
69
|
}
|
|
108
|
-
/** provider RPC 墙钟上限。🔴 codex 对抗复审 R2(验真后修):无超时的 list/kill 一次 provider 挂起会让
|
|
109
|
-
* 调用方的重入旗永挂(finally 等的 promise 永不结算)⇒ 回收腿从此静默死掉。SDK 原生收
|
|
110
|
-
* `requestTimeoutMs`(SandboxApiOpts),用它而非外包 race——超时语义留在 SDK 的连接层。 */
|
|
111
70
|
const PROVIDER_RPC_TIMEOUT_MS = 30_000;
|
|
112
|
-
/** 真实 provider(E2B SDK 包装)。SDK 静态面动态 import——回收腿只在 e2b 部署形挂载,
|
|
113
|
-
* 非 e2b 形零加载(与 execution-env 的按需装配同姿势)。 */
|
|
114
71
|
export function createE2bOrphanSandboxProvider(cfg) {
|
|
115
72
|
return {
|
|
116
73
|
async listManaged() {
|
|
117
74
|
const { Sandbox } = await import("e2b");
|
|
118
75
|
const out = [];
|
|
119
|
-
// 服务端 metadata 过滤(SandboxListOpts.query.metadata,AND 语义);state 默认含 running+paused
|
|
120
|
-
// ——paused 也计费存储位且同样是孤儿人群,刻意不收窄。
|
|
121
76
|
const paginator = Sandbox.list({ apiKey: cfg.apiKey, requestTimeoutMs: PROVIDER_RPC_TIMEOUT_MS, query: { metadata: { [SEMA_MANAGED_METADATA_KEY]: "1" } } });
|
|
122
77
|
while (paginator.hasNext) {
|
|
123
78
|
const items = await paginator.nextItems();
|
|
@@ -1,18 +1,9 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* design/73 §1 consumption, LOCAL lane — the File twin of the TiDB/Pg outcome ledgers for the single-user /
|
|
3
|
-
* no-DB posture: append each core `TaskOutcome` fact VERBATIM to an owner-only JSONL ledger. Read-only v1
|
|
4
|
-
* (dashboard/backtest dataset — mirrors the SQL ledgers' read-only red line); no query surface here, the
|
|
5
|
-
* file IS the dataset. Non-load-bearing observability → no fsync (a crash may lose the tail fact; the run
|
|
6
|
-
* itself is unaffected — same posture as metrics).
|
|
7
|
-
*/
|
|
8
1
|
import { mkdirSync, appendFileSync } from "node:fs";
|
|
9
2
|
import { join } from "node:path";
|
|
10
3
|
export class FileOutcomeSink {
|
|
11
4
|
path;
|
|
12
5
|
constructor(root) {
|
|
13
6
|
const dir = join(root, "outcomes");
|
|
14
|
-
// 0o700 dir + 0o600 file: outcome facts carry model/taskSignature/oracle detail — operator-only, parity
|
|
15
|
-
// with the other File ledgers' posture.
|
|
16
7
|
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
17
8
|
this.path = join(dir, "outcomes.jsonl");
|
|
18
9
|
}
|
|
@@ -1,47 +1,23 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* File-backed resume-at anchor map (E18) — the DURABLE local twin of {@link MemoryResumeAnchorStore}, persisting the
|
|
3
|
-
* service-owned eventId→entryId translation across a process restart (P0.5 variant-1, clay 2026-06-26; the file-backed
|
|
4
|
-
* follow-on the Memory twin's header promised). Behaviour is byte-identical to the Memory store (put/resolve/
|
|
5
|
-
* deleteBySession + the §0.5/2c `listBySession` add); the only difference is durability.
|
|
6
|
-
*
|
|
7
|
-
* Persistence: one append-only JSONL log per session at `<root>/resume-anchors/<sanitizePathComponent(sessionId)>.jsonl`,
|
|
8
|
-
* each line `{eventId, entryId, owner, ts}`. `put` APPENDS (fsync:true — an anchor is a durable rewind boundary; a lost
|
|
9
|
-
* anchor silently breaks the next rewind), and the in-memory index is upserted last-wins so a re-stamped eventId
|
|
10
|
-
* overwrites (parity with the SQL ON DUPLICATE/CONFLICT). On construction the index is HYDRATED by replaying every
|
|
11
|
-
* session log via core's `readJsonlRecords` (torn-tail-safe: a crash mid-append drops only the partial last line, and a
|
|
12
|
-
* later `put` re-records it). `resolve`/`listBySession` read the in-memory index (O(1)/O(per-session)); `deleteBySession`
|
|
13
|
-
* unlinks the file + drops the index entry. owner null-safe guard (`(a??null)===(b??null)`) = the SQL `owner <=> ?`
|
|
14
|
-
* defense-in-depth twin. Single-process (the FileStorageBackend boot lock guarantees one writer per data dir), so there
|
|
15
|
-
* is no per-op lock — the in-process model is the premise (core fs-atomic BootLock).
|
|
16
|
-
*/
|
|
17
1
|
import { join } from "node:path";
|
|
18
2
|
import { existsSync, readdirSync, rmSync } from "node:fs";
|
|
19
3
|
import { AppendLog, ensureDir, readJsonlRecords, sanitizePathComponent } from "@sema-agent/core";
|
|
20
|
-
/** Null-safe owner equality — the JS twin of the SQL `owner <=> ?` guard (a legacy null-owner anchor matches owner=null). */
|
|
21
4
|
const ownerEq = (a, b) => (a ?? null) === (b ?? null);
|
|
22
5
|
export class FileResumeAnchorStore {
|
|
23
6
|
dir;
|
|
24
|
-
/** sessionId → (eventId → {entryId, owner}) — the same in-memory shape MemoryResumeAnchorStore holds, hydrated on ctor. */
|
|
25
7
|
bySession = new Map();
|
|
26
|
-
/** sessionId → the open append log (one O_APPEND fd per session, lazily opened on first put, held for lifetime). */
|
|
27
8
|
logs = new Map();
|
|
28
9
|
constructor(root) {
|
|
29
10
|
this.dir = join(root, "resume-anchors");
|
|
30
11
|
ensureDir(this.dir);
|
|
31
12
|
this.hydrate();
|
|
32
13
|
}
|
|
33
|
-
/** `<dir>/<sanitizePathComponent(sessionId)>.jsonl` — the per-session log path (sessionId is uuidv7, already safe). */
|
|
34
14
|
pathFor(sessionId) {
|
|
35
15
|
return join(this.dir, `${sanitizePathComponent(sessionId)}.jsonl`);
|
|
36
16
|
}
|
|
37
|
-
/** Replay every session log into the in-memory index on boot (torn-tail-safe via readJsonlRecords; last-wins upsert
|
|
38
|
-
* so a re-stamped eventId reflects the latest appended record). The in-memory index is keyed by the SANITIZED
|
|
39
|
-
* sessionId throughout (put/resolve/list/delete all sanitize), and each on-disk file's base name IS
|
|
40
|
-
* `sanitizePathComponent(sessionId)` — so the index key is just the file base, with no de-sanitize needed. */
|
|
41
17
|
hydrate() {
|
|
42
18
|
let names;
|
|
43
19
|
try {
|
|
44
|
-
names = readdirSync(this.dir);
|
|
20
|
+
names = readdirSync(this.dir);
|
|
45
21
|
}
|
|
46
22
|
catch {
|
|
47
23
|
return;
|
|
@@ -49,20 +25,19 @@ export class FileResumeAnchorStore {
|
|
|
49
25
|
for (const name of names) {
|
|
50
26
|
if (!name.endsWith(".jsonl"))
|
|
51
27
|
continue;
|
|
52
|
-
const key = name.slice(0, -".jsonl".length);
|
|
28
|
+
const key = name.slice(0, -".jsonl".length);
|
|
53
29
|
const records = readJsonlRecords(join(this.dir, name));
|
|
54
30
|
if (!records.length)
|
|
55
31
|
continue;
|
|
56
32
|
const m = this.bySession.get(key) ?? new Map();
|
|
57
33
|
for (const r of records) {
|
|
58
34
|
if (!r || typeof r.eventId !== "string" || typeof r.entryId !== "string")
|
|
59
|
-
continue;
|
|
60
|
-
m.set(r.eventId, { entryId: r.entryId, owner: r.owner ?? null });
|
|
35
|
+
continue;
|
|
36
|
+
m.set(r.eventId, { entryId: r.entryId, owner: r.owner ?? null });
|
|
61
37
|
}
|
|
62
38
|
this.bySession.set(key, m);
|
|
63
39
|
}
|
|
64
40
|
}
|
|
65
|
-
/** Open (or reuse) the append log for a session. The file base is the SANITIZED id (matches hydrate's de-sanitize). */
|
|
66
41
|
logFor(sessionId) {
|
|
67
42
|
const key = sanitizePathComponent(sessionId);
|
|
68
43
|
let log = this.logs.get(key);
|
|
@@ -72,9 +47,6 @@ export class FileResumeAnchorStore {
|
|
|
72
47
|
}
|
|
73
48
|
return log;
|
|
74
49
|
}
|
|
75
|
-
/** Record/overwrite the anchor for one settled message boundary (idempotent upsert; parity with the SQL
|
|
76
|
-
* ON DUPLICATE/CONFLICT). Appends a durable record (fsync:true) THEN upserts the index — a crash after the
|
|
77
|
-
* fsync is recovered by hydrate (the record is on disk); a crash before it just loses an un-acked anchor. */
|
|
78
50
|
async put(sessionId, eventId, entryId, owner) {
|
|
79
51
|
const key = sanitizePathComponent(sessionId);
|
|
80
52
|
this.logFor(sessionId).append({ eventId, entryId, owner: owner ?? null, ts: new Date().toISOString() }, true);
|
|
@@ -85,15 +57,10 @@ export class FileResumeAnchorStore {
|
|
|
85
57
|
}
|
|
86
58
|
m.set(eventId, { entryId, owner });
|
|
87
59
|
}
|
|
88
|
-
/** Resolve a shell-supplied eventId → the persisted SessionTreeEntry.id for TaskSpec.resumeAt; undefined = unknown
|
|
89
|
-
* anchor (the route 4xx's before handing core a bad id). owner null-safe guard = the SQL `owner <=> ?` defense-in-depth. */
|
|
90
60
|
async resolve(sessionId, eventId, owner) {
|
|
91
61
|
const e = this.bySession.get(sanitizePathComponent(sessionId))?.get(eventId);
|
|
92
62
|
return e && ownerEq(e.owner, owner) ? e.entryId : undefined;
|
|
93
63
|
}
|
|
94
|
-
/** 2c session-sync: ALL anchors for a session (every eventId→entryId + its owner), UNFILTERED — a cross-backend
|
|
95
|
-
* session EXPORT bundles the whole anchor map so the importer can RE-KEY owner to the target principal (§9). The
|
|
96
|
-
* route already proved session ownership (the export gate), so no per-row owner filter here. Twin of the SQL stores. */
|
|
97
64
|
async listBySession(sessionId) {
|
|
98
65
|
const m = this.bySession.get(sanitizePathComponent(sessionId));
|
|
99
66
|
if (!m)
|
|
@@ -103,9 +70,6 @@ export class FileResumeAnchorStore {
|
|
|
103
70
|
out.push({ eventId, entryId: e.entryId, owner: e.owner });
|
|
104
71
|
return out;
|
|
105
72
|
}
|
|
106
|
-
/** E21 (§0.5 delete) — purge ALL anchors for a session, scoped by session_id ALONE (the route already proved session
|
|
107
|
-
* ownership; a per-row owner guard would orphan rows stored under a divergent per-run principal). Idempotent (count).
|
|
108
|
-
* Closes + unlinks the session log so the dir does not leak a file, and drops the in-memory index entry. */
|
|
109
73
|
async deleteBySession(sessionId) {
|
|
110
74
|
const key = sanitizePathComponent(sessionId);
|
|
111
75
|
const removed = this.bySession.get(key)?.size ?? 0;
|
|
@@ -121,19 +85,16 @@ export class FileResumeAnchorStore {
|
|
|
121
85
|
rmSync(path, { force: true });
|
|
122
86
|
}
|
|
123
87
|
catch {
|
|
124
|
-
/* best-effort — a stale file is harmless (the index entry is already gone) */
|
|
125
88
|
}
|
|
126
89
|
}
|
|
127
90
|
return removed;
|
|
128
91
|
}
|
|
129
|
-
/** Release every open append-log fd (called by LocalBackend.close so a graceful restart can re-open the data dir). */
|
|
130
92
|
dispose() {
|
|
131
93
|
for (const log of this.logs.values()) {
|
|
132
94
|
try {
|
|
133
95
|
log.close();
|
|
134
96
|
}
|
|
135
97
|
catch {
|
|
136
|
-
/* best-effort */
|
|
137
98
|
}
|
|
138
99
|
}
|
|
139
100
|
this.logs.clear();
|