@sema-agent/server 7.137.0 → 7.139.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 +600 -142
- package/README.md +7 -3
- package/README.zh-CN.md +6 -3
- package/USAGE.md +132 -41
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/lib/lanes.json +3 -2
- package/dist/adoption/wire.d.ts +3 -3
- package/dist/approval-card.d.ts +23 -16
- package/dist/approval-card.js +1 -0
- package/dist/audit.js +1 -0
- package/dist/background-agent-name.d.ts +5 -0
- package/dist/background-agent-name.js +5 -0
- package/dist/bench/s1/arms.d.ts +1 -1
- package/dist/bench/s1/arms.js +1 -3
- package/dist/bench/s1/run-firm.js +2 -2
- package/dist/boot/budget-tracing.d.ts +1 -12
- package/dist/boot/deployment-mods.d.ts +46 -16
- package/dist/boot/deployment-mods.js +82 -6
- package/dist/boot/device-lane.d.ts +8 -3
- package/dist/boot/device-lane.js +7 -2
- package/dist/boot/execution-env.d.ts +4 -2
- package/dist/boot/execution-env.js +16 -24
- package/dist/boot/execution-lane.d.ts +1 -1
- package/dist/boot/governance-seams.d.ts +12 -18
- package/dist/boot/governance-seams.js +10 -24
- package/dist/boot/leader.d.ts +3 -0
- package/dist/boot/leader.js +1 -0
- package/dist/boot/memory-consolidation.js +2 -2
- package/dist/boot/org-delivery.js +15 -2
- package/dist/boot/resolve-spec.d.ts +4 -1
- package/dist/boot/resolve-spec.js +29 -19
- package/dist/boot/retention-lane.d.ts +14 -8
- package/dist/boot/retention-lane.js +2 -8
- package/dist/boot/runner-deps.d.ts +10 -4
- package/dist/boot/runner-deps.js +2 -0
- package/dist/boot/session-faces.d.ts +0 -3
- package/dist/boot/session-faces.js +15 -8
- package/dist/boot/stage-02-web-admin-pull.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -12
- package/dist/boot/stage-05-execution-env.d.ts +3 -12
- package/dist/boot/stage-05-execution-env.js +8 -5
- package/dist/boot/stage-06-runners.d.ts +3 -12
- package/dist/boot/stage-06-runners.js +5 -3
- package/dist/boot/stage-07-capability-layer.d.ts +3 -12
- package/dist/boot/stage-07-capability-layer.js +2 -2
- package/dist/boot/stage-08-reapers.d.ts +3 -12
- package/dist/boot/stage-09-leader.d.ts +3 -12
- package/dist/boot/stage-09-leader.js +2 -3
- package/dist/boot/stage-10-http-server.d.ts +3 -12
- package/dist/boot/stage-10-http-server.js +5 -3
- package/dist/boot/stores.js +4 -4
- package/dist/boot/web-admin.d.ts +5 -2
- package/dist/boot/web-admin.js +5 -5
- package/dist/brain.js +5 -5
- package/dist/budget.d.ts +17 -15
- package/dist/budget.js +2 -2
- package/dist/capabilities/mcp-probe.d.ts +36 -11
- package/dist/capabilities/mcp-probe.js +44 -5
- package/dist/capabilities/scenarios.d.ts +1 -1
- package/dist/capability-facts.d.ts +21 -7
- package/dist/capability-facts.js +13 -3
- package/dist/checkpoint-identity.d.ts +13 -6
- package/dist/config-catalog.js +14 -8
- package/dist/config-invariants.d.ts +23 -3
- package/dist/config-invariants.js +42 -0
- package/dist/config-provider.d.ts +19 -24
- package/dist/config-provider.js +27 -12
- package/dist/config-types.d.ts +25 -12
- package/dist/config.d.ts +33 -0
- package/dist/config.js +52 -20
- package/dist/delegated-session-owner.d.ts +2 -2
- package/dist/deployment-shape.d.ts +7 -7
- package/dist/device-enrollment.d.ts +41 -2
- package/dist/device-enrollment.js +27 -12
- package/dist/device-store.d.ts +58 -85
- package/dist/device-store.js +19 -49
- package/dist/device-ws-hub.js +2 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -4
- package/dist/exec-cut.d.ts +60 -0
- package/dist/exec-cut.js +36 -0
- package/dist/execution-lane-caps.d.ts +19 -0
- package/dist/execution-lane-caps.js +10 -0
- package/dist/execution-placement.d.ts +259 -0
- package/dist/execution-placement.js +199 -0
- package/dist/field-conflict.d.ts +3 -2
- package/dist/field-conflict.js +1 -0
- package/dist/gate-settlement.d.ts +71 -0
- package/dist/gate-settlement.js +40 -0
- package/dist/hooks/classic-stations.d.ts +1 -0
- package/dist/hooks/classic-stations.js +1 -0
- package/dist/hooks/command-spawn.d.ts +2 -2
- package/dist/hooks/hook-runner.js +14 -14
- package/dist/hosted-posture.d.ts +2 -2
- package/dist/http/admission.js +10 -19
- package/dist/http/checkpoint-ctx.d.ts +21 -12
- package/dist/http/checkpoint-ctx.js +4 -2
- package/dist/http/claimed-run.d.ts +1 -1
- package/dist/http/dispatch.d.ts +4 -0
- package/dist/http/dispatch.js +3 -0
- package/dist/http/durable-run-leg.js +12 -6
- package/dist/http/execution-context.d.ts +218 -0
- package/dist/http/execution-context.js +330 -0
- package/dist/http/memory-compliance-failure-reply.js +3 -0
- package/dist/http/resume-legs.d.ts +5 -11
- package/dist/http/resume-legs.js +179 -104
- package/dist/http/route-ctx.d.ts +44 -59
- package/dist/http/route-ctx.js +2 -5
- package/dist/http/routes/a2a-serve.js +10 -4
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +5 -1
- package/dist/http/routes/approvals-assistant.js +6 -6
- package/dist/http/routes/background.d.ts +29 -1
- package/dist/http/routes/background.js +29 -2
- package/dist/http/routes/capabilities.js +12 -10
- package/dist/http/routes/devices.d.ts +13 -19
- package/dist/http/routes/devices.js +21 -26
- package/dist/http/routes/mcp-reconnect.d.ts +3 -2
- package/dist/http/routes/mcp-reconnect.js +7 -5
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/rules.js +3 -3
- package/dist/http/routes/runs.js +11 -7
- package/dist/http/routes/session-sync.js +110 -15
- package/dist/http/routes/sessions.d.ts +6 -0
- package/dist/http/routes/sessions.js +119 -13
- package/dist/http/routes/side-query.d.ts +12 -4
- package/dist/http/routes/side-query.js +6 -8
- package/dist/http/routes/tasks.js +800 -782
- package/dist/http/server.d.ts +61 -39
- package/dist/http/server.js +11 -0
- package/dist/http/session-inherit-env.d.ts +3 -4
- package/dist/http/session-inherit-env.js +1 -1
- package/dist/http/wire-types.d.ts +22 -18
- package/dist/identity-source.d.ts +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/leader/wire.d.ts +7 -0
- package/dist/leader/wire.js +5 -4
- package/dist/mcp-assertion-header.d.ts +51 -40
- package/dist/mcp-assertion-header.js +10 -11
- package/dist/mcp-authorization-face.d.ts +27 -0
- package/dist/mcp-authorization-face.js +15 -0
- package/dist/memory-operator-faces.d.ts +13 -4
- package/dist/memory-operator-faces.js +1 -17
- package/dist/memory-sync-client.d.ts +53 -14
- package/dist/memory-sync-client.js +187 -92
- package/dist/memory-sync.d.ts +1 -1
- package/dist/memory-sync.js +3 -2
- package/dist/model-route-gap.d.ts +6 -22
- package/dist/model-route-gap.js +7 -5
- package/dist/mods-declaration.d.ts +110 -0
- package/dist/mods-declaration.js +109 -0
- package/dist/observability/cost-taxonomy.d.ts +2 -2
- package/dist/observability/err-text.d.ts +5 -0
- package/dist/observability/err-text.js +9 -0
- package/dist/observability/fail-open.d.ts +17 -1
- package/dist/observability/fail-open.js +17 -1
- package/dist/observability/run-terminal.js +0 -1
- package/dist/observability/secret-env-scrub.d.ts +1 -1
- package/dist/observability/secret-env-scrub.js +1 -1
- package/dist/orchestration/workflow-notify-journal.js +4 -4
- package/dist/org-memory-admission.d.ts +4 -3
- package/dist/org-memory-admission.js +6 -6
- package/dist/parked-decide.d.ts +49 -11
- package/dist/parked-decide.js +25 -26
- package/dist/parked-revive-surface.d.ts +12 -15
- package/dist/parked-revive-surface.js +3 -6
- package/dist/peer-seat.d.ts +156 -0
- package/dist/peer-seat.js +273 -0
- package/dist/permission-rule-vocab.d.ts +7 -7
- package/dist/permission-rule-vocab.js +3 -3
- package/dist/plain-string-record.d.ts +38 -0
- package/dist/plain-string-record.js +38 -0
- package/dist/plugins/approval-ask-store-file.d.ts +7 -0
- package/dist/plugins/approval-ask-store-file.js +11 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -0
- package/dist/plugins/approval-ask-store-memory.js +12 -0
- package/dist/plugins/approval-ask-store-sql.d.ts +22 -5
- package/dist/plugins/approval-ask-store-sql.js +30 -12
- package/dist/plugins/background-agent-store-sql.js +6 -3
- package/dist/plugins/caching-session-store.d.ts +11 -2
- package/dist/plugins/caching-session-store.js +15 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +21 -25
- package/dist/plugins/checkpoint-store-sql.js +13 -15
- package/dist/plugins/device-store-sql.d.ts +25 -51
- package/dist/plugins/device-store-sql.js +49 -103
- package/dist/plugins/execution-placement-sql.d.ts +151 -0
- package/dist/plugins/execution-placement-sql.js +223 -0
- package/dist/plugins/file-history-store-sql.d.ts +7 -6
- package/dist/plugins/file-history-store-sql.js +8 -7
- package/dist/plugins/file-run-store.d.ts +6 -1
- package/dist/plugins/file-run-store.js +4 -0
- package/dist/plugins/fork-routing-session-store.d.ts +6 -0
- package/dist/plugins/fork-routing-session-store.js +16 -0
- package/dist/plugins/k8s-pod-reaper.d.ts +2 -8
- package/dist/plugins/k8s-pod-reaper.js +3 -3
- package/dist/plugins/local-checkpoint-store.d.ts +1 -11
- package/dist/plugins/local-checkpoint-store.js +0 -1
- package/dist/plugins/local-session-store.d.ts +183 -45
- package/dist/plugins/local-session-store.js +412 -105
- package/dist/plugins/mailbox-store-sql.d.ts +11 -3
- package/dist/plugins/mailbox-store-sql.js +103 -15
- package/dist/plugins/memory-key-guards.d.ts +4 -0
- package/dist/plugins/memory-key-guards.js +1 -0
- package/dist/plugins/memory-run-store.d.ts +1 -1
- package/dist/plugins/memory-sync-store-pg.d.ts +16 -5
- package/dist/plugins/memory-sync-store-tidb.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +117 -6
- package/dist/plugins/one-time-migrations.js +383 -14
- package/dist/plugins/outcome-ledger-sql.d.ts +2 -2
- package/dist/plugins/permission-rule-store-sql.d.ts +13 -15
- package/dist/plugins/permission-rule-store-sql.js +34 -29
- package/dist/plugins/pg-pool.d.ts +7 -3
- package/dist/plugins/pg-session-storage.d.ts +41 -22
- package/dist/plugins/pg-session-storage.js +136 -55
- package/dist/plugins/remote-env-adb.d.ts +22 -4
- package/dist/plugins/remote-env-adb.js +70 -62
- package/dist/plugins/remote-env-device.d.ts +32 -12
- package/dist/plugins/remote-env-device.js +18 -17
- package/dist/plugins/remote-env-e2b.d.ts +19 -3
- package/dist/plugins/remote-env-e2b.js +41 -42
- package/dist/plugins/remote-env-file-error.d.ts +2 -0
- package/dist/plugins/remote-env-file-error.js +1 -1
- package/dist/plugins/remote-env-host.d.ts +23 -8
- package/dist/plugins/remote-env-host.js +66 -70
- package/dist/plugins/remote-env-k8s.d.ts +13 -16
- package/dist/plugins/remote-env-k8s.js +61 -54
- package/dist/plugins/remote-env-local-docker.d.ts +30 -5
- package/dist/plugins/remote-env-local-docker.js +46 -59
- package/dist/plugins/remote-env-ssh.d.ts +18 -4
- package/dist/plugins/remote-env-ssh.js +72 -56
- package/dist/plugins/remote-shell.d.ts +100 -3
- package/dist/plugins/remote-shell.js +166 -2
- package/dist/plugins/retention-store-sql.d.ts +23 -8
- package/dist/plugins/retention-store-sql.js +13 -1
- package/dist/plugins/run-store-sql.d.ts +13 -3
- package/dist/plugins/run-store-sql.js +5 -0
- package/dist/plugins/schema-consistency.d.ts +15 -5
- package/dist/plugins/schema-consistency.js +14 -8
- package/dist/plugins/schema-drift-sentence.d.ts +27 -0
- package/dist/plugins/schema-drift-sentence.js +38 -0
- package/dist/plugins/session-fork.d.ts +63 -12
- package/dist/plugins/session-fork.js +38 -21
- package/dist/plugins/session-ownership.d.ts +7 -0
- package/dist/plugins/session-ownership.js +5 -0
- package/dist/plugins/session-row-sql.d.ts +22 -0
- package/dist/plugins/session-row-sql.js +81 -0
- package/dist/plugins/session-store.d.ts +1 -1
- package/dist/plugins/session-workspace-cell.d.ts +17 -0
- package/dist/plugins/session-workspace-cell.js +38 -0
- package/dist/plugins/store-backend.d.ts +1 -1
- package/dist/plugins/store-backend.js +26 -14
- package/dist/plugins/store-contracts.d.ts +25 -5
- package/dist/plugins/tidb-pool.d.ts +12 -7
- package/dist/plugins/tidb-pool.js +15 -3
- package/dist/plugins/tidb-session-store.d.ts +74 -28
- package/dist/plugins/tidb-session-store.js +132 -53
- package/dist/plugins/tool-result-store-sql.d.ts +16 -8
- package/dist/plugins/tool-result-store-sql.js +26 -17
- package/dist/plugins/worktree-isolation.d.ts +3 -2
- package/dist/plugins/worktree-isolation.js +1 -7
- package/dist/project-identity.d.ts +1 -14
- package/dist/project-identity.js +0 -4
- package/dist/project-memory.d.ts +9 -15
- package/dist/project-memory.js +5 -4
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +6 -7
- package/dist/request-value-closure.js +1 -3
- package/dist/rules-consent.js +6 -4
- package/dist/run-local.d.ts +6 -0
- package/dist/run-local.js +36 -26
- package/dist/runs.d.ts +9 -2
- package/dist/runs.js +9 -2
- package/dist/sandbox-git-plane.d.ts +2 -2
- package/dist/security.d.ts +38 -12
- package/dist/security.js +8 -2
- package/dist/server-secret-env.d.ts +15 -8
- package/dist/server-secret-env.js +4 -2
- package/dist/session-children-retire.d.ts +27 -9
- package/dist/session-children-retire.js +9 -5
- package/dist/session-incarnation.d.ts +19 -10
- package/dist/session-incarnation.js +5 -3
- package/dist/session-row.d.ts +114 -5
- package/dist/session-row.js +55 -5
- package/dist/session-titler.d.ts +2 -2
- package/dist/session-workspace.d.ts +130 -0
- package/dist/session-workspace.js +83 -0
- package/dist/spec-fields.d.ts +1 -1
- package/dist/standing-answer-grant.d.ts +2 -13
- package/dist/standing-answer-grant.js +0 -7
- package/dist/task-a2a.d.ts +44 -14
- package/dist/task-a2a.js +46 -20
- package/dist/task-cwd.d.ts +6 -1
- package/dist/task-mcp.d.ts +33 -20
- package/dist/task-mcp.js +46 -22
- package/dist/tool-approval.d.ts +38 -8
- package/dist/tool-approval.js +57 -13
- package/dist/trace/core-keyset-guard.d.ts +33 -18
- package/dist/trace/engine-notice-wire.d.ts +1 -1
- package/dist/trace/engine-notice-wire.js +2 -0
- package/dist/trace/exit-seat.d.ts +20 -1
- package/dist/trace/exit-seat.js +3 -0
- package/dist/trace/extension-call-face.d.ts +33 -0
- package/dist/trace/extension-call-face.js +39 -0
- package/dist/trace/project.d.ts +26 -7
- package/dist/trace/project.js +30 -3
- package/dist/trace/redact.js +42 -13
- package/dist/trace/self-minted-wire.d.ts +240 -12
- package/dist/trace/self-minted-wire.js +100 -4
- package/dist/trace/wire-projection-faces.d.ts +6 -6
- package/dist/trace/wire-projection-faces.js +6 -5
- package/dist/url-refusal.d.ts +1 -1
- package/dist/user-authored-text.d.ts +2 -2
- package/dist/user-authored-text.js +16 -1
- package/dist/web-admin-client/apply-effective.d.ts +17 -3
- package/dist/web-admin-client/apply-effective.js +20 -10
- package/dist/web-admin-client/center-request.d.ts +3 -2
- package/dist/web-admin-client/center-request.js +2 -3
- package/dist/web-admin-client/skills-mcp.d.ts +8 -4
- package/dist/web-admin-client/skills-mcp.js +32 -18
- package/dist/web-admin-client/types.d.ts +11 -0
- package/package.json +3 -3
- package/wire-changes/server@7.138.0.json +446 -0
- package/wire-changes/server@7.139.0.json +348 -0
- package/dist/http/device-placement.d.ts +0 -175
- package/dist/http/device-placement.js +0 -145
- package/dist/http/mcp-remote-text.d.ts +0 -5
- package/dist/http/mcp-remote-text.js +0 -7
|
@@ -32,20 +32,13 @@ export const MAX_HOOK_CONTEXT_TOTAL_CHARS = 10_000;
|
|
|
32
32
|
const MIN_HOOK_CONTEXT_PARTIAL_CHARS = 256;
|
|
33
33
|
const MAX_TOOL_RESPONSE_CHARS = 32_768;
|
|
34
34
|
const MAX_TOOL_INPUT_CHARS = 262_144;
|
|
35
|
-
const HOOK_ENV_ALLOWLIST = [
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
function hookBaseEnv(spawning) {
|
|
40
|
-
return spawning
|
|
41
|
-
? hostSubprocessEnv({ site: "server.hooks.spawn-env", policy: [...HOOK_ENV_ALLOWLIST], allow: [] })
|
|
42
|
-
: composeHostSubprocessEnv({ policy: [...HOOK_ENV_ALLOWLIST], allow: [] });
|
|
43
|
-
}
|
|
44
|
-
function hookEnvOverBase(layer, spawning) {
|
|
45
|
-
return { ...hookBaseEnv(spawning), ...layer };
|
|
35
|
+
const HOOK_ENV_ALLOWLIST = ["PATH", "HOME", "SHELL", "USER", "LOGNAME", "TERM", "TZ", "LANG", "LC_ALL", "LC_CTYPE", "LC_MESSAGES", "TMPDIR"];
|
|
36
|
+
function hookChildEnv(layer, spawning) {
|
|
37
|
+
const o = { policy: [...HOOK_ENV_ALLOWLIST], allow: [], grants: [layer] };
|
|
38
|
+
return spawning ? hostSubprocessEnv({ site: "server.hooks.spawn-env", ...o }) : composeHostSubprocessEnv(o);
|
|
46
39
|
}
|
|
47
40
|
function hookEnv(ctx) {
|
|
48
|
-
return
|
|
41
|
+
return hookChildEnv(composeHookEnvLayer(ctx.shellEnv, ctx.cwd, undefined), false);
|
|
49
42
|
}
|
|
50
43
|
export const SETTINGS_HOOK_STATIONS = {
|
|
51
44
|
PreToolUse: ["classic.PreToolUse"],
|
|
@@ -754,7 +747,7 @@ function buildHookContextField(parts) {
|
|
|
754
747
|
return text === undefined ? {} : { additionalContext: text };
|
|
755
748
|
}
|
|
756
749
|
function spawnPlannedCommand(plan, ctx, stdio) {
|
|
757
|
-
const env =
|
|
750
|
+
const env = hookChildEnv(plan.env, true);
|
|
758
751
|
if (plan.kind === "exec")
|
|
759
752
|
return spawn(plan.file, [...plan.args], { cwd: ctx.cwd, env, stdio, detached: true });
|
|
760
753
|
const sh = hostShell();
|
|
@@ -1006,7 +999,14 @@ async function runLlmHook(entry, payload, ctx, extra) {
|
|
|
1006
999
|
const MAX_BLANKED_REFERENCES_LOGGED = 16;
|
|
1007
1000
|
async function runHttpHook(entry, payload, ctx, event) {
|
|
1008
1001
|
const timeoutMs = Math.min(entry.timeout ?? DEFAULT_HOOK_TIMEOUT_SECONDS, MAX_HOOK_TIMEOUT_SECONDS) * 1000;
|
|
1009
|
-
|
|
1002
|
+
let hookChildVars;
|
|
1003
|
+
try {
|
|
1004
|
+
hookChildVars = hookEnv(ctx);
|
|
1005
|
+
}
|
|
1006
|
+
catch (e) {
|
|
1007
|
+
return { code: null, stdout: "", stderr: "", timedOut: false, spawnError: String(e) };
|
|
1008
|
+
}
|
|
1009
|
+
const interpolated = interpolateHookEnvVars(entry.headers ?? {}, entry.allowedEnvVars ?? [], hookChildVars);
|
|
1010
1010
|
if (interpolated.blanked.length > 0) {
|
|
1011
1011
|
ctx.logger.warn("hook_http_header_env_blanked", {
|
|
1012
1012
|
event,
|
package/dist/hosted-posture.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* `multiTenant` 的反面 ⇒ 采纳,否则忽略(**不看车道**,任何 `REMOTE_EXEC` 都一样);
|
|
18
18
|
* · `additionalDirectories` / `additionalReadDirectories` —— 表行 `callerOwnsWorkerDisk`(手在本 worker 盘上 ∧ 单主 = 今天只有 host);
|
|
19
19
|
* · `settings.env` / `cwd` —— 表行 `callerCwd`(读能力表 `callerCwd` 位:host 单主才开,**device 不读租户**:那条路径落在
|
|
20
|
-
*
|
|
20
|
+
* **发起者自己的设备**上,归属由根会话行执行格上的设备绑定验过 ⇒ 跨租户面结构性不存在)。
|
|
21
21
|
*
|
|
22
22
|
* ⇒ 先把这个判定位铸成**一处**,再让各条腿都读它(clay 裁定③,2026-09-22):**不许各自加特判**——
|
|
23
23
|
* 每加一条特判,「这台机器算不算托管」在本仓就多一个可以自己漂的答案。
|
|
@@ -106,7 +106,7 @@ export declare const HOST_POSTURE_REFUSED_CODE = "request.host_posture_refused";
|
|
|
106
106
|
* [ref] 前还有腿③(`approverPosture`,忽略 + 留声),随那个请求键一起退役。射程只铸在这一处,同族声明读同一只。
|
|
107
107
|
*
|
|
108
108
|
* 🔴 **device 车道不适用(clay 裁定③ 2026-09-22)**:device 车道上 host 闸防的那个跨租户宿主穿越**结构性不存在**
|
|
109
|
-
* (
|
|
109
|
+
* (路径落在**发起者自己的设备**上,归属由根会话行执行格上的设备绑定 + 准入链的 owner 谓词验过),叠加 clay [ref]
|
|
110
110
|
* 「device 零额外审批」⇒ 在那条车道上拿租户声明当判据就是**用错轴**。与 `settings.env` / `cwd` 两键在那条车道上的既有臂同源同形。
|
|
111
111
|
* [ref] 起射程判据 = 部署形表行 `taskHostPostureDeclarations`(device 车道 ∨ 单主;轴列 lane + principal);下面是它读的键集(托管证据 + 车道)。
|
|
112
112
|
*/
|
package/dist/http/admission.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { APPROVAL_REACH,
|
|
1
|
+
import { APPROVAL_REACH, IMAGE_ADMISSION, isApprovalReach, isPermissionMode, isThinkingLevel, expandTiers } from "@sema-agent/core";
|
|
2
2
|
import { isAtMentionable, matchCatalogModel, refusedCatalogEntry, selectableCatalog } from "../model-select.js";
|
|
3
3
|
import { echoModelRef, modelUnavailableMessage } from "../model-entry-refusal.js";
|
|
4
4
|
import { HttpError, sessionIdShapeIssue } from "../security.js";
|
|
@@ -20,7 +20,7 @@ import { echoCallerText, quotedCallerText } from "../caller-text-echo.js";
|
|
|
20
20
|
import { MAX_ADDITIONAL_DIRS } from "../task-cwd.js";
|
|
21
21
|
import { verifyRoundsFromBody } from "./verify-rounds.js";
|
|
22
22
|
import { skillCarriesRetiredManifest } from "./retired-skill-manifest.js";
|
|
23
|
-
import {
|
|
23
|
+
import { resolveExecutionContext, stampSpecRoot } from "./execution-context.js";
|
|
24
24
|
import { callerTrust, requestTrustRefusal } from "./caller-trust.js";
|
|
25
25
|
import { createRunAcceptance } from "../run-acceptance.js";
|
|
26
26
|
import { sendError, sendHttpError } from "./send.js";
|
|
@@ -88,7 +88,7 @@ function userSkillShapeIssue(item, index) {
|
|
|
88
88
|
}
|
|
89
89
|
export const SKILL_MANIFEST_RETIRED = "skill.manifest was retired in core 7.41.0 — a skill's tools are its allowedTools / disallowedTools now (an allow-rule and a deny-rule source for the run the skill is activated in, never a fence); move manifest.allowTools to allowedTools. To fence tools use deny rules (settings.permissions.deny) or a delegated agent's allowTools; to fence write paths use the session rules' allowDirs";
|
|
90
90
|
const MAX_IMAGES_PER_REQUEST = 20;
|
|
91
|
-
const MAX_IMAGE_BASE64_BYTES =
|
|
91
|
+
const MAX_IMAGE_BASE64_BYTES = IMAGE_ADMISSION.hard.imageBase64Chars;
|
|
92
92
|
function mentionableNames(config, catalog) {
|
|
93
93
|
return Object.keys(catalog).filter((n) => n !== "default" && isAtMentionable(n, catalog, config.atMention, config.modelRefusals));
|
|
94
94
|
}
|
|
@@ -433,10 +433,6 @@ export function createAdmission(ctx) {
|
|
|
433
433
|
return null;
|
|
434
434
|
}
|
|
435
435
|
}
|
|
436
|
-
if (body.rewindFiles !== undefined && typeof body.rewindFiles !== "boolean") {
|
|
437
|
-
sendError(res, 400, "request.field_invalid", "rewindFiles must be a boolean");
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
440
436
|
if (body.restoreFiles !== undefined && typeof body.restoreFiles !== "boolean") {
|
|
441
437
|
sendError(res, 400, "request.field_invalid", "restoreFiles must be a boolean");
|
|
442
438
|
return null;
|
|
@@ -743,26 +739,21 @@ export function createAdmission(ctx) {
|
|
|
743
739
|
}
|
|
744
740
|
}
|
|
745
741
|
const { body: admitted, entry: entryMode } = stampEntryPermissionMode(body, autonomyModeFloor(deps.config.autonomy));
|
|
742
|
+
const lease = deps.peerDesk.lease("fresh");
|
|
746
743
|
try {
|
|
747
|
-
const auth =
|
|
744
|
+
const auth = await deps.authorize({ req, body: admitted });
|
|
745
|
+
const execution = await resolveExecutionContext(deps, { kind: "fresh", root: auth.sessionId, principal: auth.principal, judged: auth.head, req, deviceId: admitted.deviceId });
|
|
748
746
|
const engineNotices = [];
|
|
749
|
-
const spec = await deps.resolveSpec(admitted, req, auth, { leg: "fresh", ...(legFacts?.liveStream === true ? { liveStream: true } : {}), onNotice: (n) => engineNotices.push(n) });
|
|
750
|
-
const bindingIntent = await resolveDevicePlacementIntent({
|
|
751
|
-
config: deps.config,
|
|
752
|
-
req,
|
|
753
|
-
rootSessionId: spec.sessionId,
|
|
754
|
-
deviceId: admitted.deviceId,
|
|
755
|
-
store: deps.deviceStore,
|
|
756
|
-
enrollment: deps.deviceEnrollment,
|
|
757
|
-
});
|
|
747
|
+
const spec = stampSpecRoot(await deps.resolveSpec(admitted, req, auth, { leg: "fresh", ...(legFacts?.liveStream === true ? { liveStream: true } : {}), onNotice: (n) => engineNotices.push(n), lease, execution }), execution);
|
|
758
748
|
const model = modelIdOf(spec.model);
|
|
759
|
-
const acceptance = createRunAcceptance({ sessionTitler: deps.sessionTitler }, {
|
|
749
|
+
const acceptance = createRunAcceptance({ sessionTitler: deps.sessionTitler }, { sessionId: spec.sessionId, objective: spec.objective, ...(model !== undefined ? { model } : {}) });
|
|
760
750
|
const clampNotice = buildEntryModeClampNotice(entryMode, spec.sessionId);
|
|
761
751
|
const pendingNotices = clampNotice !== undefined ? [clampNotice, ...engineNotices] : engineNotices;
|
|
762
752
|
const warnings = allowSelectorWarningsOf(admitted, spec.tools ?? []);
|
|
763
|
-
return { spec, runner: runnerFor(spec), auth, verify, cascade, jobId: admitted.jobId, body: admitted, acceptance,
|
|
753
|
+
return { spec, runner: runnerFor(spec), auth, verify, cascade, jobId: admitted.jobId, body: admitted, acceptance, peerLease: lease, execution, ...(pendingNotices.length > 0 ? { engineNotices: pendingNotices } : {}), ...(warnings.length > 0 ? { warnings } : {}) };
|
|
764
754
|
}
|
|
765
755
|
catch (err) {
|
|
756
|
+
lease.release();
|
|
766
757
|
if (err instanceof HttpError) {
|
|
767
758
|
if (onTypedFailure) {
|
|
768
759
|
onTypedFailure(err);
|
|
@@ -32,10 +32,15 @@
|
|
|
32
32
|
* 与 7.121.x 的 `AUTONOMY=plan` 同一个结局,且没有入口地板 ⇒ 不拒)。删除条件登记在 `plugins/one-time-migrations.ts` 的 M12 行。
|
|
33
33
|
*
|
|
34
34
|
* ## 第四问(7.137.0):体里的退役请求键
|
|
35
|
-
* 请求键退役之后(
|
|
36
|
-
* (
|
|
37
|
-
*
|
|
38
|
-
*
|
|
35
|
+
* 请求键退役之后({@link RETIRED_REQUEST_KEYS}:今天两只 —— `promptProfile` 换成布尔 `promptLean`,`rewindFiles` 是退役的旧文件还原拼法),新提交带它在键闭集门 400。存体里的旧键怎么办,闭集里每个键有
|
|
36
|
+
* **一个处置格**,住在哪张表就是哪个处置:**拒**表({@link REPLAY_REFUSED_RETIRED_KEYS},今天 `promptProfile`)是塑形过任务本身的键,**惰性**表({@link INERT_RETIRED_KEYS},今天 `rewindFiles`)是一次性键。
|
|
37
|
+
* · 拒表的键:存体里的旧键由一次性迁移在起服时原地改写
|
|
38
|
+
* (M30,`stored-request-prompt-profile-m30.ts`,行改写经本模块的 {@link rewriteStoredBodyKeys})。改写不到的残留行(窗内从没起过服的部署;起服扫描之后滚动升级里
|
|
39
|
+
* 旧副本才写下的行)体里仍带旧键 ⇒ 拒({@link retiredRequestKeyRefusal},码同前两只读法拒:`checkpoint.unsupported_version`)。**没有**续跑时按旧键读的第二种读法,
|
|
40
|
+
* 也**没有**「旧键无人读、静默续跑」的臂:旧键还在 = 这份体没被改写过,它当年要的形本版读不出来。
|
|
41
|
+
* · 惰性表的键:一次性键 —— 只在提交的那一拍起作用(文件还原的一次性动作),续跑重建里没有任何一条腿读它,存体里留着它不要求任何事、不改变重放要做的事 ⇒ 不拒、不改写、续跑照常。
|
|
42
|
+
* 这不是上面那条「旧键无人读、静默续跑」的臂:那一臂的前提是读不出旧键会让续跑做一件提交时没要的事,惰性格的判据恰是「没有这个键,重放做的事一字不差」。
|
|
43
|
+
* 加一个退役键必须选格 —— 进拒表 ⇒ {@link retiredRequestKeyRefusal} 的 switch 与 `stored-body-replay.ts` 的迁移 id 表编译红,直到给它一句拒句和改写它的迁移;进惰性表 ⇒ 改动里要写明它为什么是一次性的。
|
|
39
44
|
*
|
|
40
45
|
* ## 一只判据、五个问点(`http/stored-body-replay.ts` 的 `storedBodyReplayRefusal` / 本模块的 {@link storedBodyReplayAnswer})
|
|
41
46
|
* 「这条停驻行的持久化体在本版上能否重放」只有**一个**读法:上面四问合在 `stored-body-replay.ts` 的 `storedBodyReplayRefusal` 一处(前两问的判据在本模块、第三问读请求设置
|
|
@@ -117,13 +122,17 @@ export declare function permissionModeReadingStated(ctx: CheckpointCtx): boolean
|
|
|
117
122
|
*/
|
|
118
123
|
export declare function permissionModeReadingRefusal(): ResumeRefusalAnswer;
|
|
119
124
|
/**
|
|
120
|
-
* 第四问:**退役的请求键**闭集(新提交在键闭集门 400;存体里还带着它 =
|
|
121
|
-
* {@link retiredRequestKeyRefusal}
|
|
125
|
+
* 第四问:**退役的请求键**闭集 = 两张处置表之并(新提交在键闭集门 400;存体里还带着它 = 这份体是更早的写者写下的)。键住在哪张表就是它的处置格,规则全文见头注第四问。
|
|
126
|
+
* 拒表:存体仍带它 ⇒ 续跑重放拒({@link retiredRequestKeyRefusal});加一个 ⇒ 加一行,那只函数的 switch 编译红直到给它一句拒句。今天一只:`promptProfile`(7.137.0 起换成布尔 `promptLean`;存体由 M30 起服改写)。
|
|
122
127
|
*/
|
|
123
|
-
export declare const
|
|
128
|
+
export declare const REPLAY_REFUSED_RETIRED_KEYS: readonly ["promptProfile"];
|
|
129
|
+
export type ReplayRefusedRetiredKey = (typeof REPLAY_REFUSED_RETIRED_KEYS)[number];
|
|
130
|
+
/** 惰性表:**一次性键**(只在提交那一拍起作用,续跑重建里没有任何一条腿读它)—— 存体里带着它不改变重放要做的事 ⇒ 不拒、不改写。今天一只:`rewindFiles`(旧的文件还原拼法;现役拼法 `restoreFiles` / `rewindFilesTo` 同为一次性动作,续跑重建整族剥掉)。 */
|
|
131
|
+
export declare const INERT_RETIRED_KEYS: readonly ["rewindFiles"];
|
|
132
|
+
export declare const RETIRED_REQUEST_KEYS: readonly ["promptProfile", "rewindFiles"];
|
|
124
133
|
export type RetiredRequestKey = (typeof RETIRED_REQUEST_KEYS)[number];
|
|
125
|
-
/**
|
|
126
|
-
export declare function retiredRequestKeyOf(body: unknown):
|
|
134
|
+
/** 存体顶层带的第一只**需要拒**的退役请求键(拒表序);惰性键不算,没有 ⇒ `undefined`。只看自有键(原型上的同名不算)。 */
|
|
135
|
+
export declare function retiredRequestKeyOf(body: unknown): ReplayRefusedRetiredKey | undefined;
|
|
127
136
|
/**
|
|
128
137
|
* 第四问的拒答复 —— 码与落点同另两只读法拒(`checkpoint.unsupported_version`,409;卡仍 pending 时的 `retriable:true` 由 {@link resumeRefusalWithCard} 追加,本铸点不带)。
|
|
129
138
|
* 句子说键、它换成了什么、为什么不续跑,与两条出路(运维在一次性迁移的窗内重启本服务 ⇒ 起服改写存体、同一请求可再发;否则作为新任务重提,仍停驻的先取消)。不回显值。
|
|
@@ -132,7 +141,7 @@ export declare function retiredRequestKeyOf(body: unknown): RetiredRequestKey |
|
|
|
132
141
|
* 句子写绝对日期(过了这一天读句子的人一眼看出出路已关,不靠「本版发布日」这种随版漂的说法)。
|
|
133
142
|
* 删法见登记表 M30 的 `removal`(唯一来源)。
|
|
134
143
|
*/
|
|
135
|
-
export declare function retiredRequestKeyRefusal(key:
|
|
144
|
+
export declare function retiredRequestKeyRefusal(key: ReplayRefusedRetiredKey, rewriteWindowEnd: string): ResumeRefusalAnswer;
|
|
136
145
|
/**
|
|
137
146
|
* 本行能否被按当前读法重放:体里 `allow` 在生效而行上的记号不是当前这一个词 ⇒ **不能**(`true` = 拒)。
|
|
138
147
|
* 记号缺席、是旧词(`"statement"`)或认不得(手改 / 将来的写者)⇒ 同样拒:只有当前这个词是「按当前读法写下」的证据。
|
|
@@ -166,7 +175,7 @@ export type StoredBodyReplayRefusal = {
|
|
|
166
175
|
readonly writerVersion?: string;
|
|
167
176
|
} | {
|
|
168
177
|
readonly kind: "retired_request_key";
|
|
169
|
-
readonly key:
|
|
178
|
+
readonly key: ReplayRefusedRetiredKey;
|
|
170
179
|
/** 改写这只退役键的一次性迁移窗的最后一天(UTC 日历日 YYYY-MM-DD)—— 登记表那一行的 `removableAfter`,由判据(`stored-body-replay.ts`)读来:本模块的闭包只许 node 内建 / 引擎包根,读不了登记表,日期只能由调用方交。 */
|
|
171
180
|
readonly rewriteWindowEnd: string;
|
|
172
181
|
readonly writerVersion?: string;
|
|
@@ -230,7 +239,7 @@ export declare function storedBodyReplayLogFields(refusal: StoredBodyReplayRefus
|
|
|
230
239
|
layer?: InertToolListEntry["layer"];
|
|
231
240
|
storedMode?: PermissionMode | null;
|
|
232
241
|
floor?: PermissionMode;
|
|
233
|
-
key?:
|
|
242
|
+
key?: ReplayRefusedRetiredKey;
|
|
234
243
|
note: string;
|
|
235
244
|
};
|
|
236
245
|
/**
|
|
@@ -39,11 +39,13 @@ export function permissionModeReadingRefusal() {
|
|
|
39
39
|
}),
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
export const
|
|
42
|
+
export const REPLAY_REFUSED_RETIRED_KEYS = ["promptProfile"];
|
|
43
|
+
export const INERT_RETIRED_KEYS = ["rewindFiles"];
|
|
44
|
+
export const RETIRED_REQUEST_KEYS = [...REPLAY_REFUSED_RETIRED_KEYS, ...INERT_RETIRED_KEYS];
|
|
43
45
|
export function retiredRequestKeyOf(body) {
|
|
44
46
|
if (body === null || typeof body !== "object" || Array.isArray(body))
|
|
45
47
|
return undefined;
|
|
46
|
-
return
|
|
48
|
+
return REPLAY_REFUSED_RETIRED_KEYS.find((key) => Object.hasOwn(body, key));
|
|
47
49
|
}
|
|
48
50
|
export function retiredRequestKeyRefusal(key, rewriteWindowEnd) {
|
|
49
51
|
switch (key) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 一条提交腿**刚认领**的 run 在起跑之前就收场 —— 撤掉本请求建的东西的**唯一**写法。三个调用点:device 落点拒
|
|
3
|
-
* (`
|
|
3
|
+
* (`execution-context.ts` `commitExecutionContext`)、续跑输入写不进(`submit-ctx.ts` `persistSubmitCtx`)与 workflow 决定行没落成
|
|
4
4
|
* (`durable-run-leg.ts` 的 fresh 投递腿;此刻认领可能已被收割归了别人 —— 两步都按这一跑自己的 taskId,碰不到别人的认领)。
|
|
5
5
|
*
|
|
6
6
|
* 撤两步,**各自独立**(一步失败不拦另一步,残余最小):
|
package/dist/http/dispatch.d.ts
CHANGED
|
@@ -18,6 +18,10 @@ import type { IncomingMessage, ServerResponse } from "node:http";
|
|
|
18
18
|
import type { ServiceConfig } from "../config-types.js";
|
|
19
19
|
import type { RouteCtxBase, RunRegistry } from "./route-ctx.js";
|
|
20
20
|
import type { FlatServiceDeps } from "./server.js";
|
|
21
|
+
/** `/health` 的 `mods` 段(运维声明的 mod 包装上了几只;present-iff 装上了)—— 段的键集属主,自铸 wire 值登记表 `healthModsKey` 绑它。 */
|
|
22
|
+
export interface HealthDeploymentModsSection {
|
|
23
|
+
readonly deploymentPackages: number;
|
|
24
|
+
}
|
|
21
25
|
/**
|
|
22
26
|
* 🔴 [ref](test T-72 [ref];主会话裁 ①,分诊 [ref])—— 全局服务凭据门**之前**那几族只读路
|
|
23
27
|
* (`route-table.ts` 里 `position: "read-credential"` 的行)的**唯一**鉴权谓词:「服务凭据 ∨ 已验 principal」。
|
package/dist/http/dispatch.js
CHANGED
|
@@ -9,6 +9,7 @@ import { sendJson, sendError, isSseResponse, endSseWithError } from "./send.js";
|
|
|
9
9
|
import { admissionRefusalOf, readinessOf, healthReadinessKeys, sendReadyz, sendBillableRefusal, billableRefusalOf, billableRefusalFrame } from "./readiness.js";
|
|
10
10
|
import { ENGINE_SIGNAL_KEY, buildEngineSignal, fleetMembershipKeys, healthConfigLedgerKeys, healthDrainingKeys, mintEngineSignal, restartActionable } from "../fleet/engine-signal.js";
|
|
11
11
|
import { buildHealthSelfReport } from "./health-self-report.js";
|
|
12
|
+
import { deploymentModPackages as deploymentModPackagesFact } from "../capability-facts.js";
|
|
12
13
|
import { actsForDeployment, admitRunIdentity, authorized, systemFor, gatedPrincipal, sendPrincipalRefusal, sendUnauthorized, traceTokenPresented, verifiedIdentitySource, hasServiceAuth, devOpenDeployment } from "./principal-gate.js";
|
|
13
14
|
const PROCESS_STARTED_AT_MS = Date.now() - Math.round(process.uptime() * 1000);
|
|
14
15
|
export function readCredentialOk(req, config) {
|
|
@@ -127,6 +128,7 @@ export function createDispatch(ctx) {
|
|
|
127
128
|
if (req.method === "GET" && url === "/health") {
|
|
128
129
|
const signal = mintEngineSignal(deps);
|
|
129
130
|
const engineSignal = buildEngineSignal(signal);
|
|
131
|
+
const declaredMods = deploymentModPackagesFact(deps);
|
|
130
132
|
const configHash = createHash("sha256")
|
|
131
133
|
.update(JSON.stringify({ model: deps.config.model.id, sessionBackend: deps.config.sessionBackend, dbBackend: deps.config.dbBackend, dataRoot: deps.config.localDataRoot, configProvider: deps.config.configProvider, remoteExec: deps.config.remoteExec?.provider, port: deps.config.port }))
|
|
132
134
|
.digest("hex")
|
|
@@ -149,6 +151,7 @@ export function createDispatch(ctx) {
|
|
|
149
151
|
startedAt: PROCESS_STARTED_AT_MS,
|
|
150
152
|
port: req.socket.localPort,
|
|
151
153
|
...(deps.config.directDoorActive ? { directDoorActive: true } : {}),
|
|
154
|
+
...(declaredMods.available ? { mods: { deploymentPackages: declaredMods.count } } : {}),
|
|
152
155
|
...buildHealthSelfReport(deps),
|
|
153
156
|
...(signal.restart ? { ...(restartActionable(signal) ? { restartRequired: true } : {}), restart: signal.restart } : {}),
|
|
154
157
|
...(() => {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { uuidv7 } from "@sema-agent/core";
|
|
2
2
|
import { heldWorkflowParkDecisions } from "../parked-decide.js";
|
|
3
3
|
import { HEARTBEAT_MS, runInBackground } from "../runs.js";
|
|
4
|
+
import { heldFor } from "../peer-seat.js";
|
|
4
5
|
import { fleetRunPublisher, fleetRunLabels } from "../fleet/fleet-bus.js";
|
|
5
6
|
import { cascadeConfig, runMeta } from "./run-meta.js";
|
|
6
7
|
import { declaredApprovalFrameFamilies, resolveStreamApprovalGate } from "../tool-approval.js";
|
|
7
8
|
import { buildActiveRunConflict } from "./active-run-conflict.js";
|
|
8
|
-
import {
|
|
9
|
+
import { commitExecutionContext } from "./execution-context.js";
|
|
10
|
+
import { rootSessionAbsentAnswer } from "./execution-context.js";
|
|
9
11
|
import { commitSessionInheritEnv } from "./session-inherit-env.js";
|
|
10
12
|
import { clearTurnActivity, readTurnActivityMs } from "../turn-activity.js";
|
|
11
13
|
import { recordResourceWindow } from "../resource-window.js";
|
|
@@ -13,10 +15,11 @@ import { persistSubmitCtx } from "./submit-ctx.js";
|
|
|
13
15
|
import { releaseClaimedRun } from "./claimed-run.js";
|
|
14
16
|
import { serviceVersion } from "../service-version.js";
|
|
15
17
|
import { headReadOf } from "../session-incarnation.js";
|
|
18
|
+
import { createSessionWorkspaceRecorder, legSessionWitnessOf, sessionWorkspaceStoreOf } from "../session-workspace.js";
|
|
16
19
|
export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
17
20
|
const { deps } = ctx;
|
|
18
21
|
const { inflightRuns, preemptableRuns, steerableRuns } = ctx.registry;
|
|
19
|
-
const sessionId = args.prepared.spec.sessionId
|
|
22
|
+
const sessionId = args.prepared.spec.sessionId;
|
|
20
23
|
const taskId = args.clientTaskId ?? uuidv7();
|
|
21
24
|
const trustedInternals = await heldWorkflowParkDecisions(deps, sessionId, args.workflowDecision?.carried);
|
|
22
25
|
const created = await runStore.createRun(taskId, sessionId, args.prepared.auth?.principal ?? null, deps.instanceId ?? "default", { ...runMeta(args.prepared, args.source), identity: args.identity, idem: args.idem ?? null });
|
|
@@ -26,6 +29,8 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
|
26
29
|
recordResourceWindow(taskId, args.prepared.spec.resourceSuspend);
|
|
27
30
|
if (created.existing)
|
|
28
31
|
return { existing: created.existing };
|
|
32
|
+
if (created.sessionAbsent)
|
|
33
|
+
return rootSessionAbsentAnswer();
|
|
29
34
|
if (!created.ok) {
|
|
30
35
|
return { status: 409, body: await buildActiveRunConflict({ runStore, checkpointStore: deps.checkpointStore, governance: deps.config, runStaleSec: deps.config.runStaleSec, turnActivity: readTurnActivityMs }, sessionId, created.activeTaskId) };
|
|
31
36
|
}
|
|
@@ -35,9 +40,9 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
|
35
40
|
}, HEARTBEAT_MS);
|
|
36
41
|
preLaunchHeartbeat.unref?.();
|
|
37
42
|
try {
|
|
38
|
-
const placementReject = await
|
|
43
|
+
const placementReject = await commitExecutionContext(deps, { kind: "run", runStore, taskId }, args.prepared.execution);
|
|
39
44
|
if (placementReject)
|
|
40
|
-
return
|
|
45
|
+
return placementReject;
|
|
41
46
|
if (deps.checkpointStore) {
|
|
42
47
|
const ctxRefusal = await persistSubmitCtx(deps.checkpointStore, deps, { runStore, taskId }, sessionId, { body: args.prepared.body, memoryScope: args.prepared.auth?.memoryScope, writerVersion: serviceVersion() });
|
|
43
48
|
if (ctxRefusal)
|
|
@@ -78,7 +83,7 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
|
78
83
|
sessionId,
|
|
79
84
|
...fleetRunLabels(args.prepared.spec.objective),
|
|
80
85
|
});
|
|
81
|
-
void runInBackground(args.prepared.runner,
|
|
86
|
+
void heldFor(args.prepared.peerLease, () => runInBackground(args.prepared.runner, args.prepared.spec, runStore, taskId, deps.metrics, args.prepared.auth?.principal, args.prepared.verify, args.prepared.cascade ? cascadeConfig(deps.config.cascadeLadder, args.prepared.spec.limits?.maxCostUsd) : undefined, deps.instrumentDegenerate, deps.planCacheProbe, deps.config.traceThinking, inflightRuns, preemptableRuns, steerableRuns, deps.modelUsage, deps.elicitation, args.elicitOwner, captureTurnAnchor, fleetPub, captureUserMessageAnchor, deps.question, deps.workflowCompletionInbox, deps.subagentSteerRegistry, (m, x) => deps.logger?.info?.(m, x), deps.sendUserFile, deps.promptManifests, deps.toolApproval
|
|
82
87
|
? {
|
|
83
88
|
coordinator: deps.toolApproval,
|
|
84
89
|
streamApprovalOn: resolveStreamApprovalGate({
|
|
@@ -90,8 +95,9 @@ export async function mintAndDriveDurableRun(ctx, runStore, args) {
|
|
|
90
95
|
windowMs: deps.config.streamApproval?.windowMs,
|
|
91
96
|
windowMarginMs: deps.config.streamAskWindowMarginMs,
|
|
92
97
|
declaredFamilies: declaredApprovalFrameFamilies(args.prepared.body.settings),
|
|
98
|
+
executionLane: args.prepared.execution.lane,
|
|
93
99
|
}
|
|
94
|
-
: undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance);
|
|
100
|
+
: undefined, deps.checkpointStore, args.prepared.engineNotices, trustedInternals, deps.userInputLedger, args.prepared.acceptance, createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), legSessionWitnessOf(args.prepared.spec))));
|
|
95
101
|
return { status: 202, body: { taskId, sessionId, status: "running", ...(args.prepared.warnings !== undefined ? { warnings: args.prepared.warnings } : {}) } };
|
|
96
102
|
}
|
|
97
103
|
//# sourceMappingURL=durable-run-leg.js.map
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **执行上下文** —— 每条执行起点从这一只解析器取同一型上下文:根会话是谁、这一位住客在根会话行上的执行放置是什么、这条执行走哪条车道、
|
|
3
|
+
* 主体能不能用这条车道;认领之后的初始放置只有一只写口 {@link commitExecutionContext}。
|
|
4
|
+
*
|
|
5
|
+
* ## 规则(一句)
|
|
6
|
+
* 根只有一个来源 = authorizer(`ServiceCoreDeps.authorize` 必填席,唯一铸点即登记点),根进 spec 只有一个写者 = {@link stampSpecRoot};
|
|
7
|
+
* 执行放置**读只有一只** —— 会话店执行席 `seat.read(root)` 一次行读(住客 + 格),解析器读它、提交腿的门交来的 `judged` 比它、设备准入链判的也是这一读;
|
|
8
|
+
* **写只有一只** —— 认领之后的 {@link commitExecutionContext}(按解析器那一读的住客定址,0 行按住客复读分类,永不对现住客重试)。
|
|
9
|
+
*
|
|
10
|
+
* ## 解析步序(设计 §3.2 表 ①–④;⑤ 取 rig 不在本版)
|
|
11
|
+
* ① 读:会话店不带执行席 ⇒ absent、`occupant` 缺(只一元车道表的部署可能);否则一次行读 —— 行不在 ⇒ 404 `resume.session_not_found`;`judged`(门判过的那一读)
|
|
12
|
+
* 在场而与行头不是同一位住客(化身 ∧ 属主,写口同一只判官 `sameOccupant`)⇒ 同 404(他人在门与解析之间删掉并同 id 重登记,或同一化身的属主变了 ——
|
|
13
|
+
* local M10 认领 / identical 重戳 / SQL 导入提交点改属主 —— 判到新住客的车道就是错的);local 格是 `forking`
|
|
14
|
+
* ⇒ 409 `conflict.fork_in_progress`;读故障抛(不吞成 absent)。解析器不建行、不铸根。
|
|
15
|
+
* ② 定车道:`mirror` ⇒ 409 `conflict.session_mirror`(体带 `forkPath`);`writer(L)` 而 L 不在本部署的车道表 ⇒ 409 `execution_lane.not_served{boundLane}`;absent ⇒ 表首。
|
|
16
|
+
* ③ 授权:主体的执行车道裁定(`gateExecutionLane`,判据与码同 `runtime-caps-resolver.ts`);服务形不判。
|
|
17
|
+
* ④ 只 fresh:设备准入链(体 `deviceId` 只在 device 车道收;准入链三步 + 首绑目标三读,全读;判的是步 ① 那一读)。
|
|
18
|
+
*
|
|
19
|
+
* 入口三形(判别联合,{@link ExecutionEntry}):`fresh`(提交腿:根 = authorizer 交出的 `auth.sessionId`,`judged` = authorizer 判过的头)·
|
|
20
|
+
* `continuation`(续跑家族与停驻赎回:根 = checkpoint / 停驻行的根;不带 `judged` —— 步 ① 那一读就是这条执行对根的唯一一读,认领之后由写口按它判)·
|
|
21
|
+
* `service`(服务 run:没有会话根)。
|
|
22
|
+
* `fresh` / `continuation` 两形型上恒带 `root: string`,`service` 形没有 `root` 键 —— 「按一只缺席的根去读行」在型上不可表达。
|
|
23
|
+
*
|
|
24
|
+
* ## 提交({@link commitExecutionContext};设计 §3.2「提交」)
|
|
25
|
+
* 只在认领之后(四个 `createRun` 点、续跑家族 `markResuming` 之后、停驻赎回 `claimParkedAgent` 之后)调,是认领之后改执行放置的唯一写口:
|
|
26
|
+
* · 有设备意图(fresh ∧ device 车道)⇒ 首绑(设备店一只事务,按住客定址)或已绑臂的再断言(按住客再读 + 准入链再断言设备);
|
|
27
|
+
* · absent ⇒ place(非 device 车道);命中 = 成立;0 行按住客复读分类:同值 = 成立 · 异车道 ⇒ `execution_lane.tree_bound` · mirror ⇒ `conflict.session_mirror` ·
|
|
28
|
+
* gone(行不在或住客不是解析器那一位)⇒ 「会话不在」(提交腿 404 `resume.session_not_found`;停驻赎回答它自己的 `decide.not_parked`)—— **不对现住客重试**;
|
|
29
|
+
* · writer ⇒ 按住客再读断言仍是 writer(L);
|
|
30
|
+
* · 拒 ⇒ 先释放本次认领(run:终结 + 放认领 + 放幂等键;停驻:回滚认领)再交回拒答;店故障 ⇒ 释放后原样上抛(响亮,不当答案)。
|
|
31
|
+
* claim 之后每一次店往返都带 {@link placementWriteDeadlineMs} 硬时限。
|
|
32
|
+
*
|
|
33
|
+
* ## 便利度不变(clay [ref] 硬约束)
|
|
34
|
+
* 本文件**不产生任何审批**:只做「这条会话放在哪条车道 / 哪台设备上」的读、判与认领之后的一次写。device 车道上 `permissionMode: "bypassPermissions"` 的 run
|
|
35
|
+
* 与 host 车道同构造同读数(判据钉在 device-first-bind 测试的「零额外审批」格)。
|
|
36
|
+
*/
|
|
37
|
+
import type { IncomingMessage } from "node:http";
|
|
38
|
+
import type { SessionHead, TaskSpec } from "@sema-agent/core";
|
|
39
|
+
import { type DeviceOwner, type DeviceStore } from "../device-store.js";
|
|
40
|
+
import { type DeviceEnrollment, type DeviceRejection } from "../device-enrollment.js";
|
|
41
|
+
import type { ServiceConfig } from "../config.js";
|
|
42
|
+
import type { RunStore } from "../plugins/store-backend.js";
|
|
43
|
+
import { type ExecutionPlacementSeat } from "../execution-placement.js";
|
|
44
|
+
import { type ExecutionLane } from "../execution-lane-caps.js";
|
|
45
|
+
import type { ExecutionRuling } from "../web-admin-client/facade.js";
|
|
46
|
+
import type { Logger } from "../observability/logger.js";
|
|
47
|
+
import type { SessionFace } from "../session-incarnation.js";
|
|
48
|
+
import { type RefusalBody } from "./refusal-body.js";
|
|
49
|
+
/** 门判过的那一读(authorizer 的头;只 `fresh` 入口带):解析器拿它的住客(化身 ∧ 属主)与行头比 —— 判官 = 写口同一只 `sameOccupant`。 */
|
|
50
|
+
export type JudgedOccupant = Pick<SessionHead, "owner" | "incarnation">;
|
|
51
|
+
/** 执行起点交给解析器的入口。 */
|
|
52
|
+
export type ExecutionEntry = {
|
|
53
|
+
readonly kind: "fresh";
|
|
54
|
+
readonly root: string;
|
|
55
|
+
/** 主体(授权步 ③ 按它问执行车道裁定)。 */
|
|
56
|
+
readonly principal: string | undefined;
|
|
57
|
+
/** authorizer 判过的头(属主门那一读;现铸臂是登记后那一读)。缺 = 店没有 `headOf`(只一元表无席形可达)。 */
|
|
58
|
+
readonly judged: JudgedOccupant | undefined;
|
|
59
|
+
/** 设备准入(步 ④)的两样输入:调用方的请求(判调用方域)与体里的 `deviceId`(原值,形在步 ④ 判)。 */
|
|
60
|
+
readonly req: IncomingMessage | undefined;
|
|
61
|
+
readonly deviceId: unknown;
|
|
62
|
+
} | {
|
|
63
|
+
readonly kind: "continuation";
|
|
64
|
+
readonly root: string;
|
|
65
|
+
readonly principal: string | undefined;
|
|
66
|
+
} | {
|
|
67
|
+
readonly kind: "service";
|
|
68
|
+
};
|
|
69
|
+
/** 解析器的产出:有会话根的两形与没有根的服务形。 */
|
|
70
|
+
export type ExecutionContext = {
|
|
71
|
+
readonly kind: "fresh" | "continuation";
|
|
72
|
+
readonly root: string;
|
|
73
|
+
/** 步 ① 那一读的住客;会话店不带执行席 ⇒ 缺(提交无事可做)。 */
|
|
74
|
+
readonly occupant: SessionFace | undefined;
|
|
75
|
+
readonly placement: "absent" | "writer";
|
|
76
|
+
readonly lane: ExecutionLane;
|
|
77
|
+
/** 只 fresh ∧ device 车道:准入链判完的设备意图(认领之后由 {@link commitExecutionContext} 写或再断言)。 */
|
|
78
|
+
readonly device?: DevicePlacementIntent;
|
|
79
|
+
} | {
|
|
80
|
+
readonly kind: "service";
|
|
81
|
+
readonly lane: ExecutionLane;
|
|
82
|
+
readonly placement: "absent";
|
|
83
|
+
};
|
|
84
|
+
/** 带根的上下文 —— 认领之后的提交、审批席的出处车道读这一形(服务 run 不认领)。 */
|
|
85
|
+
export type RootedExecutionContext = Extract<ExecutionContext, {
|
|
86
|
+
readonly root: string;
|
|
87
|
+
}>;
|
|
88
|
+
/** 装配器(`resolveSpec`)收的那一半:根与入口形(它不判放置、不选车道)。 */
|
|
89
|
+
export type ExecutionRoot = Pick<RootedExecutionContext, "kind" | "root">;
|
|
90
|
+
/** 解析器读的部署件(全部取自同一只 `ServiceDeps`)。 */
|
|
91
|
+
export interface ExecutionContextDeps {
|
|
92
|
+
readonly config: ServiceConfig;
|
|
93
|
+
/** 会话店:执行席 `executionPlacement` 是放置的唯一载体与唯一读。 */
|
|
94
|
+
readonly sessionStorage?: {
|
|
95
|
+
readonly executionPlacement?: ExecutionPlacementSeat;
|
|
96
|
+
} | undefined;
|
|
97
|
+
/** 主体的执行车道裁定(caps client;缺 = 无中心 ⇒ 不判,与已发同)。 */
|
|
98
|
+
readonly executionRuling?: ((principal: string | undefined) => Promise<ExecutionRuling | undefined>) | undefined;
|
|
99
|
+
readonly logger?: Logger | undefined;
|
|
100
|
+
readonly deviceStore?: DeviceStore | undefined;
|
|
101
|
+
readonly deviceEnrollment?: DeviceEnrollment | undefined;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* **唯一的解析器**(设计 §3.2 步 ①–④)。同一入口、同一行、同一裁定恒得同一上下文;判别是穷举的(新入口形 = 编译错)。
|
|
105
|
+
* 拒一律抛 typed `HttpError`(提交腿原样答;续跑家族照它自己的折叠律答,`http/resume-legs.ts`)。
|
|
106
|
+
*/
|
|
107
|
+
export declare function resolveExecutionContext(deps: ExecutionContextDeps, entry: Extract<ExecutionEntry, {
|
|
108
|
+
readonly root: string;
|
|
109
|
+
}>): Promise<RootedExecutionContext>;
|
|
110
|
+
export declare function resolveExecutionContext(deps: ExecutionContextDeps, entry: ExecutionEntry): Promise<ExecutionContext>;
|
|
111
|
+
/** 拒体里「继续在本处执行」的下一步路径(fork 口)—— 镜像拒体的 `forkPath` 唯一铸法(执行面与会话行写口 `PATCH /v1/sessions/:id` 同读)。 */
|
|
112
|
+
export declare function forkPathOf(root: string): string;
|
|
113
|
+
/** 解析器的拒是不是「会话不在」(停驻赎回腿把它答成自己既有的 `decide.not_parked`;判据只在这里认那只答复的码)。 */
|
|
114
|
+
export declare function isRootSessionGoneError(err: unknown): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* 调用方 device 域的**唯一铸造点**。`undefined` = 判不出域(无 principal,或凭据不带 tenant claim)—— 消费点必须响亮拒,禁静默空视图。
|
|
117
|
+
*
|
|
118
|
+
* 🔴 位置即契约:`{owner_tenant, owner_subject}` 是 O11 的 device-lane-local 复合身份(全局 principal 一个字节不动)。subject = `gatedPrincipal`(verified 链),
|
|
119
|
+
* tenant = `ssoVerifiedScope`(registry auth-bridge JWT 的 `scope` claim)—— **两者都是签名真源,不是自报头**。管理面三读三写与首绑写协议全部从这一只函数取域;
|
|
120
|
+
* 派生第二份就是把 O11 的判据本体复制成一份会漂的孪生。
|
|
121
|
+
*/
|
|
122
|
+
export declare function deviceOwnerDomainOf(req: IncomingMessage, config: ServiceConfig): DeviceOwner | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* **已校验、未写库**的设备放置意图(device 车道的 fresh 上下文才带)。解析那一刻还不知道哪个并发请求会赢下会话的认领,所以它不写 ——
|
|
125
|
+
* 只把「如果我赢了,该写什么 / 该断言什么」算好交给 {@link commitExecutionContext}。
|
|
126
|
+
*/
|
|
127
|
+
export interface DevicePlacementIntent {
|
|
128
|
+
/** 绑定键 = **根**会话(后代无条件继承)。 */
|
|
129
|
+
readonly rootSessionId: string;
|
|
130
|
+
/** 步 ① 那一读的住客:首绑写按住客谓词;已绑臂的再断言先比住客。 */
|
|
131
|
+
readonly occupant: SessionFace;
|
|
132
|
+
/** 验证过的复合身份(恒取 verified 链,不取自可伪造头)。 */
|
|
133
|
+
readonly owner: DeviceOwner;
|
|
134
|
+
/**
|
|
135
|
+
* **准入链批准的那台设备** —— 提交的断言对象。身份留在意图里,已绑臂才有东西可断言(一条写了 `deviceId: A` 的提交在「准入过后、认领之前」被换绑到 B
|
|
136
|
+
* 时不许静默在 B 上跑完 —— 执行环境工厂读的是**当下**的绑定)。
|
|
137
|
+
*/
|
|
138
|
+
readonly admittedDeviceId: string;
|
|
139
|
+
/** `true` = 解析那一读里还没有设备绑定 ⇒ 提交做那一次首绑(写);`false` = 已绑 ⇒ 提交不写,只再断言。 */
|
|
140
|
+
readonly firstBind: boolean;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 装配器的产物型:根不归装配器写。`{ sessionId?: never }` 让任何型上带 `string` 的 `sessionId`(字面量、变量、展开、`TaskSpec` 型值)都不可赋;
|
|
144
|
+
* 擦型(`any` / `as unknown as`)与 JS 嵌入方不归型管,由 {@link stampSpecRoot} 的运行时判兜。
|
|
145
|
+
*/
|
|
146
|
+
export type ResolvedTaskSpec = Omit<TaskSpec, "sessionId"> & {
|
|
147
|
+
sessionId?: never;
|
|
148
|
+
};
|
|
149
|
+
/** 盖过根的 spec:执行点、认领、续跑输入读的都是这一形(`sessionId` 恒在)。 */
|
|
150
|
+
export type RootedTaskSpec = TaskSpec & {
|
|
151
|
+
readonly sessionId: string;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* **根进 spec 的唯一写者。** 装配器交回的 spec 上 `sessionId` 缺席(或为 `undefined`)⇒ 盖上这条上下文的根;
|
|
155
|
+
* 在场且等于根 ⇒ 同值,照盖;在场而**不等** ⇒ 400 `request.precondition_unmet`(嵌入方的装配器另点了一只会话 —— 它在型上不能这么写,
|
|
156
|
+
* 走到这里只能是擦型或 JS 形;拒在建任何行之前)。续跑家族照它自己的折叠律把这只拒答成 409 `resume_blocked_by_policy`(`blockedBy` = 这只码,
|
|
157
|
+
* `http/resume-legs.ts` 的 `resolveResumeSpecOrBlocked`:装配期的每一只 `HttpError` 在续跑腿上都这么折),同样什么都没续。
|
|
158
|
+
*/
|
|
159
|
+
export declare function stampSpecRoot(spec: ResolvedTaskSpec, ctx: ExecutionRoot): RootedTaskSpec;
|
|
160
|
+
/**
|
|
161
|
+
* run 店建行时根会话行已经不在(`CreateRunOutcome.sessionAbsent`:受理之后、认领之前会话被删)的**唯一**答复 ——
|
|
162
|
+
* 四个建行点(同步 / 流式 / durable / wake)、解析期的「行不在 / 住客换了」与提交期的 `gone` 同答 404 `resume.session_not_found`,什么都没建、什么都没跑。
|
|
163
|
+
*/
|
|
164
|
+
export declare function rootSessionAbsentAnswer(): {
|
|
165
|
+
status: 404;
|
|
166
|
+
body: RefusalBody;
|
|
167
|
+
};
|
|
168
|
+
/** 提交点的拒答(各建行点用自己协议的发送姿势,状态与体只有这一份)。 */
|
|
169
|
+
export interface ExecutionRefusal {
|
|
170
|
+
readonly status: number;
|
|
171
|
+
readonly body: RefusalBody;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* 本次认领 —— 提交拒时要释放的东西。`run` = 四个建行点与续跑家族认领的 run 行(释放 = 终结 + 放认领 + 放幂等键,唯一写法 `releaseClaimedRun`);
|
|
175
|
+
* `parked` = 停驻赎回的认领(释放 = 回滚认领;「会话不在」答那条腿既有的 `decide.not_parked`,不是提交腿的 404)。
|
|
176
|
+
*/
|
|
177
|
+
export type ExecutionClaim = {
|
|
178
|
+
readonly kind: "run";
|
|
179
|
+
readonly runStore: RunStore;
|
|
180
|
+
readonly taskId: string;
|
|
181
|
+
} | {
|
|
182
|
+
readonly kind: "parked";
|
|
183
|
+
readonly taskId: string;
|
|
184
|
+
readonly rollback: (why: string) => Promise<unknown>;
|
|
185
|
+
readonly goneAnswer: ExecutionRefusal;
|
|
186
|
+
};
|
|
187
|
+
/** {@link commitExecutionContext} 的依赖 —— 逐字取自 `ServiceDeps` 的同名键(同一只 deps 对象喂进来)。 */
|
|
188
|
+
export interface ExecutionCommitDeps {
|
|
189
|
+
readonly sessionStorage?: {
|
|
190
|
+
readonly executionPlacement?: ExecutionPlacementSeat;
|
|
191
|
+
} | undefined;
|
|
192
|
+
readonly deviceEnrollment?: DeviceEnrollment | undefined;
|
|
193
|
+
readonly config?: {
|
|
194
|
+
readonly runStaleSec?: number;
|
|
195
|
+
} | undefined;
|
|
196
|
+
readonly logger?: {
|
|
197
|
+
warn(msg: string, fields?: Record<string, unknown>): void;
|
|
198
|
+
} | undefined;
|
|
199
|
+
readonly metrics?: {
|
|
200
|
+
inc(name: string, labels?: Record<string, string>): void;
|
|
201
|
+
} | undefined;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* claim 之后那一次写 / 再读的**硬时限**:从 `runStaleSec` 派生(不新铸旋钮)—— 它只回答「这次店往返会不会挂到 stale 回收把认领收走」。
|
|
205
|
+
* 取四分之一并夹在 `[1s, 15s]`。
|
|
206
|
+
*/
|
|
207
|
+
export declare function placementWriteDeadlineMs(runStaleSec: number | undefined): number;
|
|
208
|
+
/** 拒绝的**唯一** wire 体铸点(各消费点各自用自己协议的发送姿势,但体的键集只有这一份)。 */
|
|
209
|
+
export declare function devicePlacementErrorBody(rej: DeviceRejection): RefusalBody;
|
|
210
|
+
/**
|
|
211
|
+
* **认领之后的唯一写口**(四个 `createRun` 点、续跑家族 `markResuming` 之后、停驻赎回 `claimParkedAgent` 之后)。返回 `null` = 放行;
|
|
212
|
+
* 否则本次认领已释放,调用方交回拒答。店故障 / 超时 ⇒ 释放后原样上抛(响亮,不当答案);设备意图那一支的注册簿故障答 {@link registryUnavailable}(设备闭集,同准入阶段)。
|
|
213
|
+
*
|
|
214
|
+
* 不变量(一句):**离开本函数的那一刻,这条会话(解析器那一位住客)的格就是这条执行的车道(device 车道:准入批准的那台设备);否则本次认领已释放、调用方拿到拒答。**
|
|
215
|
+
* 它不说「此后不变」:认领持有期间根行住客与放置不被换绑 / 导入改动,那是各写者写事务内锁根行后读认领的保证(规则句),不在本函数重复判。
|
|
216
|
+
*/
|
|
217
|
+
export declare function commitExecutionContext(deps: ExecutionCommitDeps, claim: ExecutionClaim, ctx: RootedExecutionContext): Promise<ExecutionRefusal | null>;
|
|
218
|
+
//# sourceMappingURL=execution-context.d.ts.map
|