@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
package/dist/http/resume-legs.js
CHANGED
|
@@ -4,10 +4,8 @@ import { uuidv7, resumeWithVerification, CheckpointError, defaultTaskRegistry, t
|
|
|
4
4
|
import { decideParkedAgent, denyWorkflowParkForked, denyWorkflowParksUnreadable, findParkOrigin, heldWorkflowParkDecisions, planWorkflowParkedDecide } from "../parked-decide.js";
|
|
5
5
|
import { parkDecisionFingerprint } from "../orchestration/workflow-park-decision.js";
|
|
6
6
|
import { headReadOf } from "../session-incarnation.js";
|
|
7
|
+
import { createSessionWorkspaceRecorder, legSessionWitnessOf, sessionWorkspaceStoreOf } from "../session-workspace.js";
|
|
7
8
|
const DELIVERY_NOT_RECORDED = "workflow park decide: this delivery no longer holds the host session (its claim was released) — the decision was not recorded and this delivery was not started";
|
|
8
|
-
const headUnavailable = async (sessionId) => {
|
|
9
|
-
throw new Error(`parked decide cannot verify which occupant session ${sessionId} belongs to: this deployment's session store has no head read (headOf; every built-in store has one) — refusing rather than resuming unverified`);
|
|
10
|
-
};
|
|
11
9
|
import { HttpError, decodeCheckpointScope, CHECKPOINT_PUBLIC_SCOPE } from "../security.js";
|
|
12
10
|
import { graftParkToolCallId, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort } from "../runs.js";
|
|
13
11
|
import { failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane } from "../terminal.js";
|
|
@@ -38,7 +36,10 @@ import { errorText } from "../observability/err-text.js";
|
|
|
38
36
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
39
37
|
import { verifyRoundsFromBody } from "./verify-rounds.js";
|
|
40
38
|
import { planReviewDecisionExitsPlan, storedBodyPermissionMode } from "../task-settings.js";
|
|
41
|
-
import { acceptedResumingReceipt, acceptedTaskIdOf
|
|
39
|
+
import { acceptedResumingReceipt, acceptedTaskIdOf } from "./route-ctx.js";
|
|
40
|
+
import { heldFor } from "../peer-seat.js";
|
|
41
|
+
import { NO_SETTLEMENT_EVIDENCE, buildSettlementEvidence, decisionCommittedOf } from "../gate-settlement.js";
|
|
42
|
+
import { durableRowIdentity } from "../checkpoint-identity.js";
|
|
42
43
|
import { mintAndDriveDurableRun } from "./durable-run-leg.js";
|
|
43
44
|
import { createSessionsLocal } from "./routes/sessions.js";
|
|
44
45
|
import { createSessionSyncLocal } from "./routes/session-sync.js";
|
|
@@ -46,7 +47,7 @@ import { createImagesLocal } from "./routes/images.js";
|
|
|
46
47
|
import { createCapabilitiesLocal } from "./routes/capabilities.js";
|
|
47
48
|
import { gatedPrincipal, explicitOperatorOk, runIdentityOf } from "./principal-gate.js";
|
|
48
49
|
import { buildActiveRunConflict, resumeEntryForGate } from "./active-run-conflict.js";
|
|
49
|
-
import {
|
|
50
|
+
import { commitExecutionContext, isRootSessionGoneError, resolveExecutionContext, rootSessionAbsentAnswer, stampSpecRoot } from "./execution-context.js";
|
|
50
51
|
import { commitSessionInheritEnv } from "./session-inherit-env.js";
|
|
51
52
|
import { ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind, isEngineQuestionRow } from "../approval-content-kind.js";
|
|
52
53
|
import { deploymentListAsks } from "../approval.js";
|
|
@@ -75,6 +76,8 @@ const WORKER_SWAP_REDEEMABLE = {
|
|
|
75
76
|
ledger_event_unknown: true,
|
|
76
77
|
real_approval_damaged: false,
|
|
77
78
|
real_approval_forged: false,
|
|
79
|
+
tool_identity_missing: true,
|
|
80
|
+
bound_input_hash_missing: false,
|
|
78
81
|
requirements_damaged: false,
|
|
79
82
|
read_face_damaged: false,
|
|
80
83
|
read_face_forged: false,
|
|
@@ -96,6 +99,7 @@ const WORKER_SWAP_REDEEMABLE = {
|
|
|
96
99
|
unknown_model_ref: true,
|
|
97
100
|
not_a_model_ref: true,
|
|
98
101
|
unknown_role_word: true,
|
|
102
|
+
no_model_for_role: true,
|
|
99
103
|
};
|
|
100
104
|
function checkpointRowRedeemableElsewhere(reason) {
|
|
101
105
|
return reason !== undefined && WORKER_SWAP_REDEEMABLE[reason] === true;
|
|
@@ -125,9 +129,9 @@ const CHECKPOINT_ERROR_DISPOSITION = {
|
|
|
125
129
|
"checkpoint.gate_mismatch": "terminal",
|
|
126
130
|
"checkpoint.reopen_failed": "terminal",
|
|
127
131
|
"checkpoint.cwd_conflicts_restore": "terminal",
|
|
132
|
+
"steering.duplicate_input_id": "retriable",
|
|
128
133
|
"checkpoint.already_exists": "terminal",
|
|
129
134
|
"checkpoint.execution_outcome_conflict": "terminal",
|
|
130
|
-
"steering.duplicate_input_id": "terminal",
|
|
131
135
|
"steering.invalid_content": "terminal",
|
|
132
136
|
"steering.queue_full": "terminal",
|
|
133
137
|
};
|
|
@@ -159,6 +163,10 @@ const CHECKPOINT_ERROR_FIELD_ROLE = {
|
|
|
159
163
|
hostDecision: "outcome_cell",
|
|
160
164
|
approver: "outcome_cell",
|
|
161
165
|
feedback: "outcome_cell",
|
|
166
|
+
outcome: "outcome_cell",
|
|
167
|
+
updatedInput: "outcome_cell",
|
|
168
|
+
decision: "outcome_cell",
|
|
169
|
+
reason: "outcome_cell",
|
|
162
170
|
taskConfig: "config",
|
|
163
171
|
deps: "config",
|
|
164
172
|
inheritedGate: "config",
|
|
@@ -365,9 +373,7 @@ export function createResumeLegs(ctx) {
|
|
|
365
373
|
}
|
|
366
374
|
: undefined;
|
|
367
375
|
const noteLateSettleIfAccepted = (out) => {
|
|
368
|
-
if (lateSettleSink === undefined || lateSettleAnchor === undefined || out
|
|
369
|
-
return;
|
|
370
|
-
if (out.body?.errorCode === "cancelled" && out.decisionCommitted !== true)
|
|
376
|
+
if (lateSettleSink === undefined || lateSettleAnchor === undefined || !decisionCommittedOf(out))
|
|
371
377
|
return;
|
|
372
378
|
try {
|
|
373
379
|
lateSettleSink.recordLateSettle({ ...lateSettleAnchor, outcome: decision === "approve" ? "allowed" : "denied", decidedBy: hostDecision.decidedBy, ...(hostDecision.approver !== undefined ? { approver: hostDecision.approver } : {}), settledAtMs: Date.now() });
|
|
@@ -383,6 +389,7 @@ export function createResumeLegs(ctx) {
|
|
|
383
389
|
if (parkedForkLeaseDenial)
|
|
384
390
|
return parkedForkLeaseDenial;
|
|
385
391
|
const ownerLeaseAdmittedHere = req !== undefined;
|
|
392
|
+
const captureSelectedGate = () => durableRowIdentity("decision-receipt", cp.checkpointId, token);
|
|
386
393
|
if (req !== undefined) {
|
|
387
394
|
const parkedAgentStore = deps.backgroundAgentStore;
|
|
388
395
|
const parkedSurface = deps.parkedReviveSurface;
|
|
@@ -407,12 +414,32 @@ export function createResumeLegs(ctx) {
|
|
|
407
414
|
checkpointStore: cs,
|
|
408
415
|
registry: defaultTaskRegistry,
|
|
409
416
|
reviveSurface: parkedSurface,
|
|
410
|
-
headOf: headReadOf(deps.sessionStorage) ?? headUnavailable,
|
|
411
417
|
...(deps.parkedKnownAgentTypes ? { knownAgentTypes: deps.parkedKnownAgentTypes } : {}),
|
|
412
418
|
...(deps.parkedReviveInheritedGate ? { rebuildInheritedGate: deps.parkedReviveInheritedGate } : {}),
|
|
413
419
|
...(deps.toolApproval ? { approverSeatFor: windowZeroSeatOf(deps.toolApproval) } : {}),
|
|
420
|
+
execution: {
|
|
421
|
+
resolve: async (root) => {
|
|
422
|
+
let ctx;
|
|
423
|
+
try {
|
|
424
|
+
ctx = await resolveExecutionContext(deps, { kind: "continuation", root, principal: decodeCheckpointScope(cp.scope) });
|
|
425
|
+
}
|
|
426
|
+
catch (e) {
|
|
427
|
+
if (isRootSessionGoneError(e))
|
|
428
|
+
return { ok: false, gone: true };
|
|
429
|
+
if (e instanceof HttpError)
|
|
430
|
+
return { ok: false, gone: false, answer: resumeRefusalWithCard(resumeBlockedByPolicyAnswer(httpErrorRefusal(e)), true) };
|
|
431
|
+
throw e;
|
|
432
|
+
}
|
|
433
|
+
const occupant = ctx.occupant;
|
|
434
|
+
if (occupant === undefined) {
|
|
435
|
+
throw new Error(`parked decide: root session ${root} resolved without an occupant reading — the parked revive leg is wired to a session store without an execution placement seat (sessionStorage.executionPlacement), which createHttpServer should have refused at startup; refusing rather than resuming with nobody judging the root session's occupant after the claim`);
|
|
436
|
+
}
|
|
437
|
+
return { ok: true, ctx: { ...ctx, occupant } };
|
|
438
|
+
},
|
|
439
|
+
commitDeps: deps,
|
|
440
|
+
},
|
|
414
441
|
...(deps.logger ? { warn: parkWarn } : {}),
|
|
415
|
-
}, parkedReq, { handle: origin.handle, row: origin.row }));
|
|
442
|
+
}, { ...parkedReq, selectedGate: captureSelectedGate() }, { handle: origin.handle, row: origin.row }));
|
|
416
443
|
void ctxPromise.catch(() => { });
|
|
417
444
|
noteLateSettleIfAccepted(parked);
|
|
418
445
|
return parked;
|
|
@@ -440,7 +467,7 @@ export function createResumeLegs(ctx) {
|
|
|
440
467
|
if (held === null || held.fingerprint !== fingerprint)
|
|
441
468
|
return undefined;
|
|
442
469
|
const run = await runStore.getRun(held.deliveredTaskId);
|
|
443
|
-
return run != null && !isTerminalRunStatus(run.status) ? acceptedResumingReceipt(held.deliveredTaskId, held.hostSessionId) : undefined;
|
|
470
|
+
return run != null && !isTerminalRunStatus(run.status) ? acceptedResumingReceipt(held.deliveredTaskId, held.hostSessionId, NO_SETTLEMENT_EVIDENCE) : undefined;
|
|
444
471
|
};
|
|
445
472
|
const replay = await liveReceiptOf(await decisions.get(token));
|
|
446
473
|
if (replay !== undefined)
|
|
@@ -486,44 +513,52 @@ export function createResumeLegs(ctx) {
|
|
|
486
513
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
487
514
|
if (!resolved.ok)
|
|
488
515
|
return resolved.answer;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
516
|
+
try {
|
|
517
|
+
const { spec, engineNotices } = resolved;
|
|
518
|
+
const pendingTool = cp.pendingAction.toolName;
|
|
519
|
+
if (decision === "approve" && pendingTool === ASK_USER_QUESTION_TOOL_NAME && !answer) {
|
|
520
|
+
return { status: 400, body: refusalBody({ errorCode: "request.field_conflict", message: "pending action is AskUserQuestion — approve must carry body.answer ({ answers: [{ header, selected: string[], note? }] })", facts: { ...fieldConflictFacts("ask_answer", ["decision", "answer"]) } }) };
|
|
521
|
+
}
|
|
522
|
+
if (answer && (decision !== "approve" || pendingTool !== ASK_USER_QUESTION_TOOL_NAME)) {
|
|
523
|
+
return { status: 400, body: refusalBody({ errorCode: "request.field_conflict", message: `body.answer is only valid when approving a pending AskUserQuestion (decision: "${decision}", pending: "${pendingTool ?? "unknown"}")`, facts: { ...fieldConflictFacts("ask_answer", ["answer", "decision"]) } }) };
|
|
524
|
+
}
|
|
525
|
+
const { objective: resumeObjective, sessionId: _sessionId, ...taskConfig } = spec;
|
|
526
|
+
const pa = cp.pendingAction;
|
|
527
|
+
const persistedCallId = pa.kind === "tool_approval" ? pa.toolCallId : "";
|
|
528
|
+
const persistedHash = pa.kind === "tool_approval" ? (pa.boundInputHash ?? "") : "";
|
|
529
|
+
const outcome = {
|
|
530
|
+
gate: "policy_ask",
|
|
531
|
+
boundCallId: binding?.boundCallId ?? persistedCallId,
|
|
532
|
+
boundInputHash: binding?.boundInputHash ?? persistedHash,
|
|
533
|
+
decision: decision === "approve" ? "allow" : "deny",
|
|
534
|
+
...(decision === "approve" && !isEngineQuestionRow(pa) && binding?.updatedInput !== undefined ? { updatedInput: binding.updatedInput } : {}),
|
|
535
|
+
...(reason ? { reason } : {}),
|
|
536
|
+
...(binding?.feedback !== undefined ? { feedback: binding.feedback } : {}),
|
|
537
|
+
...(answer !== undefined ? { answer } : {}),
|
|
538
|
+
hostDecision,
|
|
539
|
+
};
|
|
540
|
+
const verifyRounds = verifyRoundsFromBody(ctx.body);
|
|
541
|
+
const driven = await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: runnerFor(spec), token, sessionId: cp.sessionId, principal: auth.principal, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome, commitment: { kind: "gate_resolved", ...captureSelectedGate() }, verifyRounds, resumeCtx: { sessionId, ctx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(boundGrant ? { onResumeCommitted: boundGrant } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}), ...(ownerLeaseAdmittedHere ? { ownerLeaseAdmitted: true } : {}) });
|
|
542
|
+
noteLateSettleIfAccepted(driven);
|
|
543
|
+
return driven;
|
|
493
544
|
}
|
|
494
|
-
|
|
495
|
-
|
|
545
|
+
finally {
|
|
546
|
+
resolved.peerLease.release();
|
|
496
547
|
}
|
|
497
|
-
const { objective: resumeObjective, sessionId: _sessionId, ...taskConfig } = spec;
|
|
498
|
-
const pa = cp.pendingAction;
|
|
499
|
-
const persistedCallId = pa.kind === "tool_approval" ? pa.toolCallId : "";
|
|
500
|
-
const persistedHash = pa.kind === "tool_approval" ? (pa.boundInputHash ?? "") : "";
|
|
501
|
-
const outcome = {
|
|
502
|
-
gate: "policy_ask",
|
|
503
|
-
boundCallId: binding?.boundCallId ?? persistedCallId,
|
|
504
|
-
boundInputHash: binding?.boundInputHash ?? persistedHash,
|
|
505
|
-
decision: decision === "approve" ? "allow" : "deny",
|
|
506
|
-
...(decision === "approve" && !isEngineQuestionRow(pa) && binding?.updatedInput !== undefined ? { updatedInput: binding.updatedInput } : {}),
|
|
507
|
-
...(reason ? { reason } : {}),
|
|
508
|
-
...(binding?.feedback !== undefined ? { feedback: binding.feedback } : {}),
|
|
509
|
-
...(answer !== undefined ? { answer } : {}),
|
|
510
|
-
hostDecision,
|
|
511
|
-
};
|
|
512
|
-
const verifyRounds = verifyRoundsFromBody(ctx.body);
|
|
513
|
-
const driven = await driveResumeIntoRunLog({ runner: runnerFor(spec), token, sessionId: cp.sessionId, principal: auth.principal, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome, verifyRounds, resumeCtx: { sessionId, ctx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(boundGrant ? { onResumeCommitted: boundGrant } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}), ...(ownerLeaseAdmittedHere ? { ownerLeaseAdmitted: true } : {}) });
|
|
514
|
-
noteLateSettleIfAccepted(driven);
|
|
515
|
-
return driven;
|
|
516
548
|
}
|
|
517
|
-
const ONE_SHOT_SUBMIT_KEYS = ["resumeAt", "restoreFiles", "acceptPartialRestore", "rewindFilesTo", "
|
|
549
|
+
const ONE_SHOT_SUBMIT_KEYS = ["resumeAt", "restoreFiles", "acceptPartialRestore", "rewindFilesTo", "userAttachments", "images"];
|
|
518
550
|
const ONE_SHOT_SUBMIT_STRIP = Object.fromEntries(ONE_SHOT_SUBMIT_KEYS.map((k) => [k, undefined]));
|
|
519
|
-
const resolveResumeSpec = async (ctx, req, auth) => {
|
|
551
|
+
const resolveResumeSpec = async (ctx, req, auth, lease) => {
|
|
520
552
|
const engineNotices = [];
|
|
521
|
-
const
|
|
553
|
+
const execution = await resolveExecutionContext(deps, { kind: "continuation", root: auth.sessionId, principal: auth.principal });
|
|
554
|
+
const spec = stampSpecRoot(await deps.resolveSpec({ ...ctx.body, ...ONE_SHOT_SUBMIT_STRIP }, req, auth, {
|
|
522
555
|
leg: "resume",
|
|
523
556
|
onNotice: (n) => engineNotices.push(n),
|
|
524
557
|
...(ctx.unattendedLeg === true ? { unattendedLeg: true } : {}),
|
|
525
|
-
|
|
526
|
-
|
|
558
|
+
lease,
|
|
559
|
+
execution,
|
|
560
|
+
}), execution);
|
|
561
|
+
return { spec, engineNotices, execution };
|
|
527
562
|
};
|
|
528
563
|
const refuseStoredBodyReplay = (sessionId, refusal) => {
|
|
529
564
|
deps.logger?.warn?.("resume_refused_stored_body", { sessionId, ...storedBodyReplayLogFields(refusal) });
|
|
@@ -533,11 +568,13 @@ export function createResumeLegs(ctx) {
|
|
|
533
568
|
const replay = storedBodyReplayRefusal(ctx, deps.config);
|
|
534
569
|
if (replay !== undefined)
|
|
535
570
|
return { ok: false, answer: refuseStoredBodyReplay(auth.sessionId, replay) };
|
|
571
|
+
const lease = deps.peerDesk.lease("resume");
|
|
536
572
|
try {
|
|
537
|
-
const { spec, engineNotices } = await resolveResumeSpec(ctx, req, auth);
|
|
538
|
-
return { ok: true, spec, engineNotices };
|
|
573
|
+
const { spec, engineNotices, execution } = await resolveResumeSpec(ctx, req, auth, lease);
|
|
574
|
+
return { ok: true, spec, engineNotices, execution, peerLease: lease };
|
|
539
575
|
}
|
|
540
576
|
catch (e) {
|
|
577
|
+
lease.release();
|
|
541
578
|
if (e instanceof HttpError) {
|
|
542
579
|
return { ok: false, answer: resumeRefusalWithCard(resumeBlockedByPolicyAnswer(httpErrorRefusal(e)), true) };
|
|
543
580
|
}
|
|
@@ -546,11 +583,11 @@ export function createResumeLegs(ctx) {
|
|
|
546
583
|
};
|
|
547
584
|
async function driveResumeIntoRunLog(args) {
|
|
548
585
|
if (args.acceptEarly !== true)
|
|
549
|
-
return await driveResumeLeg(args);
|
|
586
|
+
return await heldFor(args.peerLease, () => driveResumeLeg(args));
|
|
550
587
|
let settleAccepted;
|
|
551
588
|
let wasAccepted = false;
|
|
552
589
|
const accepted = new Promise((resolve) => { settleAccepted = resolve; });
|
|
553
|
-
const leg = driveResumeLeg(args, (receipt) => { wasAccepted = true; settleAccepted?.(receipt); });
|
|
590
|
+
const leg = heldFor(args.peerLease, () => driveResumeLeg(args, (receipt) => { wasAccepted = true; settleAccepted?.(receipt); }));
|
|
554
591
|
void leg.then((out) => {
|
|
555
592
|
if (wasAccepted && out.status >= 400) {
|
|
556
593
|
deps.logger?.warn?.("resume_leg_failed_after_accept", { sessionId: args.sessionId, status: out.status, body: out.body });
|
|
@@ -566,7 +603,7 @@ export function createResumeLegs(ctx) {
|
|
|
566
603
|
}
|
|
567
604
|
async function driveResumeLeg(args, onAccepted) {
|
|
568
605
|
const resumeLegStartedAt = Date.now();
|
|
569
|
-
const { runner: legRunner, token, sessionId, principal, fleetScope, taskConfig, resumeObjective, outcome, verifyRounds, resumeCtx } = args;
|
|
606
|
+
const { runner: legRunner, token, sessionId, principal, fleetScope, taskConfig, resumeObjective, outcome, verifyRounds, resumeCtx, execution } = args;
|
|
570
607
|
const reparkStatus = outcome.gate === "plan_review" ? "needs_review" : "suspended";
|
|
571
608
|
const commitResumeCtx = () => Promise.resolve().then(() => deps.checkpointStore.putCtx(resumeCtx.sessionId, sealCheckpointCtx({ ...resumeCtx.ctx, writerVersion: serviceVersion() }, deps.checkpointCtxSealing, resumeCtx.sessionId))).catch((e) => {
|
|
572
609
|
deps.metrics?.inc("resume_ctx_not_persisted_total");
|
|
@@ -610,12 +647,14 @@ export function createResumeLegs(ctx) {
|
|
|
610
647
|
if (created.existing) {
|
|
611
648
|
throw new Error(`wake fresh run: createRun observed an existing row for the freshly minted taskId ${freshId} (no idempotency key was sent) — refusing to treat it as a busy session`);
|
|
612
649
|
}
|
|
650
|
+
if (created.sessionAbsent)
|
|
651
|
+
return rootSessionAbsentAnswer();
|
|
613
652
|
if (!created.ok) {
|
|
614
653
|
return { status: 409, body: await buildActiveRunConflict({ runStore: deps.runStore, checkpointStore: deps.checkpointStore, governance: deps.config, runStaleSec: deps.config.runStaleSec, turnActivity: readTurnActivityMs }, sessionId, created.activeTaskId) };
|
|
615
654
|
}
|
|
616
|
-
const placementReject = await
|
|
655
|
+
const placementReject = await commitExecutionContext(deps, { kind: "run", runStore: deps.runStore, taskId: freshId }, execution);
|
|
617
656
|
if (placementReject)
|
|
618
|
-
return
|
|
657
|
+
return placementReject;
|
|
619
658
|
taskId = freshId;
|
|
620
659
|
freshRunClaimed = true;
|
|
621
660
|
}
|
|
@@ -626,11 +665,12 @@ export function createResumeLegs(ctx) {
|
|
|
626
665
|
if (deps.toolApproval && taskId) {
|
|
627
666
|
const toolApproval = deps.toolApproval;
|
|
628
667
|
resumeTaskConfig.onAsk = approvalLeg.unattended
|
|
629
|
-
? toolApproval.boundUnattendedAsk({ owner: principal ?? null, taskId, sessionId }, approvalLeg.unattended)
|
|
668
|
+
? toolApproval.boundUnattendedAsk({ owner: principal ?? null, taskId, sessionId, executionLane: execution.lane }, approvalLeg.unattended)
|
|
630
669
|
: toolApproval.boundAsk({
|
|
631
670
|
owner: principal ?? null,
|
|
632
671
|
taskId,
|
|
633
672
|
sessionId,
|
|
673
|
+
executionLane: execution.lane,
|
|
634
674
|
...(approvalLeg.active ? { legKey, ...(legDeadlineMonotonic !== undefined ? { legDeadlineMonotonic } : {}) } : {}),
|
|
635
675
|
});
|
|
636
676
|
}
|
|
@@ -696,6 +736,11 @@ export function createResumeLegs(ctx) {
|
|
|
696
736
|
claimedRow = freshRunClaimed ? true : await deps.runStore.markResuming(taskId, deps.instanceId ?? "default");
|
|
697
737
|
if (!claimedRow)
|
|
698
738
|
return notResumableAnswer();
|
|
739
|
+
if (!freshRunClaimed) {
|
|
740
|
+
const placementReject = await commitExecutionContext(deps, { kind: "run", runStore: deps.runStore, taskId }, execution);
|
|
741
|
+
if (placementReject)
|
|
742
|
+
return placementReject;
|
|
743
|
+
}
|
|
699
744
|
markChildrenStoppedByUserOnAbort(cancelCtrl.signal, taskId, principal);
|
|
700
745
|
fleetPub?.onStart();
|
|
701
746
|
const rs = deps.runStore;
|
|
@@ -889,6 +934,7 @@ export function createResumeLegs(ctx) {
|
|
|
889
934
|
const driveResume = async () => {
|
|
890
935
|
resumeLegLive = true;
|
|
891
936
|
const tailContentMode = resumeTaskConfig.forwardSubagentEvents === true ? "on" : "progress_only";
|
|
937
|
+
const resumeWorkspace = createSessionWorkspaceRecorder(sessionWorkspaceStoreOf(deps.sessionStorage), legSessionWitnessOf(resumeTaskConfig));
|
|
892
938
|
const stream = await legRunner.resumeStream(token, outcome, { ...resumeTaskConfig, signal: cancelCtrl.signal, preemptSignal: preemptCtrl.signal }, {
|
|
893
939
|
...launchInternals,
|
|
894
940
|
onForwardEvent: (e) => {
|
|
@@ -951,12 +997,14 @@ export function createResumeLegs(ctx) {
|
|
|
951
997
|
if (taskId)
|
|
952
998
|
steerableRuns.set(taskId, stream);
|
|
953
999
|
if (!taskId || !rs) {
|
|
1000
|
+
for await (const ev of stream)
|
|
1001
|
+
await resumeWorkspace.observe(ev);
|
|
954
1002
|
const rNoRow = await stream.result();
|
|
955
1003
|
if (await reopenedAfterLeg(rNoRow, cancelCtrl.cause() !== undefined))
|
|
956
1004
|
reopenConfirmedPark = true;
|
|
957
1005
|
return sealResultForExit(rNoRow);
|
|
958
1006
|
}
|
|
959
|
-
onAccepted?.(acceptedResumingReceipt(taskId, sessionId));
|
|
1007
|
+
onAccepted?.(acceptedResumingReceipt(taskId, sessionId, buildSettlementEvidence({ at: "engine_accepted", commitment: args.commitment })));
|
|
960
1008
|
let causeAtDone;
|
|
961
1009
|
for await (const ev of stream) {
|
|
962
1010
|
if (ev.type === "done")
|
|
@@ -964,6 +1012,7 @@ export function createResumeLegs(ctx) {
|
|
|
964
1012
|
recordTurnActivity(taskId);
|
|
965
1013
|
fleetPub?.onEvent(ev);
|
|
966
1014
|
await deps.userInputLedger?.observeLegEvent(stream, ev);
|
|
1015
|
+
await resumeWorkspace.observe(ev);
|
|
967
1016
|
await appendPromptManifest(append, deps.promptManifests, taskId);
|
|
968
1017
|
switch (ev.type) {
|
|
969
1018
|
case "text_delta":
|
|
@@ -1119,6 +1168,7 @@ export function createResumeLegs(ctx) {
|
|
|
1119
1168
|
owner: principal ?? null,
|
|
1120
1169
|
abortSignal: cancelCtrl.signal,
|
|
1121
1170
|
sessionId,
|
|
1171
|
+
executionLane: execution.lane,
|
|
1122
1172
|
emitCard: createApprovalCardEmitter({ appendDurable: (f) => approvalEmit(f) }),
|
|
1123
1173
|
emitRevoke: (f) => approvalEmit(f),
|
|
1124
1174
|
legKey,
|
|
@@ -1221,13 +1271,13 @@ export function createResumeLegs(ctx) {
|
|
|
1221
1271
|
settleFleet(checkpointReopened ? reparkStatus : resumePlane.status, fleetRunResiduals(sealed));
|
|
1222
1272
|
return {
|
|
1223
1273
|
status: 200,
|
|
1224
|
-
decisionCommitted: true,
|
|
1225
1274
|
body: {
|
|
1226
1275
|
taskId, sessionId, status: resumePlane.status,
|
|
1227
1276
|
bindingEnforced: true,
|
|
1228
1277
|
...(resumePlane.errorCode ? { errorCode: resumePlane.errorCode } : {}),
|
|
1229
1278
|
...(resumePlane.errorMessage ? { errorMessage: redactErrorMessage(resumePlane.errorMessage) ?? "" } : {}),
|
|
1230
1279
|
...(checkpointReopened ? { retriable: true } : {}),
|
|
1280
|
+
...buildSettlementEvidence({ at: "engine_terminal", commitment: args.commitment }),
|
|
1231
1281
|
},
|
|
1232
1282
|
};
|
|
1233
1283
|
}
|
|
@@ -1302,10 +1352,16 @@ export function createResumeLegs(ctx) {
|
|
|
1302
1352
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
1303
1353
|
if (!resolved.ok)
|
|
1304
1354
|
return resolved.answer;
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1355
|
+
try {
|
|
1356
|
+
const { spec, engineNotices } = resolved;
|
|
1357
|
+
const { objective: resumeObjective, sessionId: _sessionId, ...taskConfig } = spec;
|
|
1358
|
+
const verifyRounds = verifyRoundsFromBody(ctx.body);
|
|
1359
|
+
const selectedGate = durableRowIdentity("decision-receipt", cp.checkpointId, token);
|
|
1360
|
+
return await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: runnerFor(spec), token, sessionId: cp.sessionId, principal: auth.principal, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome: { gate: "resource_limit", decision: "continue" }, commitment: { kind: "gate_resolved", ...selectedGate }, verifyRounds, resumeCtx: { sessionId, ctx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}) });
|
|
1361
|
+
}
|
|
1362
|
+
finally {
|
|
1363
|
+
resolved.peerLease.release();
|
|
1364
|
+
}
|
|
1309
1365
|
}
|
|
1310
1366
|
async function startFreshHostTurn(sessionId, objective, principal, req, workflowDecision, runId) {
|
|
1311
1367
|
const cs = deps.checkpointStore;
|
|
@@ -1338,23 +1394,28 @@ export function createResumeLegs(ctx) {
|
|
|
1338
1394
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
1339
1395
|
if (!resolved.ok)
|
|
1340
1396
|
return resolved.answer;
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1397
|
+
try {
|
|
1398
|
+
const { spec, engineNotices } = resolved;
|
|
1399
|
+
const hostSpec = { ...spec, objective };
|
|
1400
|
+
const out = await mintAndDriveDurableRun(routeCtxBase, deps.runStore, {
|
|
1401
|
+
prepared: { spec: hostSpec, runner: runnerFor(hostSpec), auth, body: ctx.body, acceptance: createRunAcceptance({}, { objective }), peerLease: resolved.peerLease, execution: resolved.execution, ...(engineNotices.length > 0 ? { engineNotices } : {}) },
|
|
1402
|
+
fleetScope: resumeFleetScope(req, auth),
|
|
1403
|
+
elicitOwner: principal ?? null,
|
|
1404
|
+
source: "workflow_parked_decide",
|
|
1405
|
+
identity: runIdentityOf(req, deps.config, principal ?? null),
|
|
1406
|
+
workflowDecision,
|
|
1407
|
+
});
|
|
1408
|
+
if (out.existing) {
|
|
1409
|
+
throw new Error(`decide host turn: createRun observed an existing row ${out.existing.taskId} for a freshly minted taskId (no idempotency key was sent)`);
|
|
1410
|
+
}
|
|
1411
|
+
if (out.status !== 202)
|
|
1412
|
+
return { status: out.status, body: out.body };
|
|
1413
|
+
const minted = out.body;
|
|
1414
|
+
return acceptedResumingReceipt(minted.taskId, minted.sessionId, NO_SETTLEMENT_EVIDENCE);
|
|
1415
|
+
}
|
|
1416
|
+
finally {
|
|
1417
|
+
resolved.peerLease.release();
|
|
1353
1418
|
}
|
|
1354
|
-
if (out.status !== 202)
|
|
1355
|
-
return { status: out.status, body: out.body };
|
|
1356
|
-
const minted = out.body;
|
|
1357
|
-
return acceptedResumingReceipt(minted.taskId, minted.sessionId);
|
|
1358
1419
|
}
|
|
1359
1420
|
async function resumeWake(sessionId, message, caller, req, acceptEarly, workflowDecision, ownerLeaseAdmittedFor) {
|
|
1360
1421
|
const cs = deps.checkpointStore;
|
|
@@ -1418,26 +1479,34 @@ export function createResumeLegs(ctx) {
|
|
|
1418
1479
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
1419
1480
|
if (!resolved.ok)
|
|
1420
1481
|
return resolved.answer;
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1482
|
+
try {
|
|
1483
|
+
const { spec, engineNotices } = resolved;
|
|
1484
|
+
const { objective: resumeObjective, sessionId: _sessionId, ...taskConfig } = spec;
|
|
1485
|
+
return await driveResumeIntoRunLog({
|
|
1486
|
+
peerLease: resolved.peerLease,
|
|
1487
|
+
execution: resolved.execution,
|
|
1488
|
+
runner: runnerFor(spec),
|
|
1489
|
+
token,
|
|
1490
|
+
sessionId: cp.sessionId,
|
|
1491
|
+
principal: auth.principal,
|
|
1492
|
+
fleetScope: resumeFleetScope(req, auth),
|
|
1493
|
+
taskConfig,
|
|
1494
|
+
resumeObjective,
|
|
1495
|
+
outcome: { gate: "wake", ...(message !== undefined ? { message: { text: message, trusted } } : {}) },
|
|
1496
|
+
commitment: { kind: "delivered" },
|
|
1497
|
+
verifyRounds: undefined,
|
|
1498
|
+
resumeCtx: { sessionId, ctx },
|
|
1499
|
+
mintFreshRun: { source: "wake", identity: runIdentityOf(req, deps.config, auth.principal ?? null) },
|
|
1500
|
+
...(workflowDecision !== undefined ? { workflowDecision } : {}),
|
|
1501
|
+
...(engineNotices.length > 0 ? { engineNotices } : {}),
|
|
1502
|
+
...(acceptEarly === true ? { acceptEarly: true } : {}),
|
|
1503
|
+
...(req !== undefined ? { callerInitiated: true } : {}),
|
|
1504
|
+
...(ownerLeaseAdmittedFor !== undefined && auth.principal === ownerLeaseAdmittedFor ? { ownerLeaseAdmitted: true } : {}),
|
|
1505
|
+
});
|
|
1506
|
+
}
|
|
1507
|
+
finally {
|
|
1508
|
+
resolved.peerLease.release();
|
|
1509
|
+
}
|
|
1441
1510
|
}
|
|
1442
1511
|
async function preparePlanReview(sessionId, log, decider, sighting) {
|
|
1443
1512
|
const cs = deps.checkpointStore;
|
|
@@ -1530,18 +1599,24 @@ export function createResumeLegs(ctx) {
|
|
|
1530
1599
|
const resolved = await resolveResumeSpecOrBlocked(rebuildCtx, req, auth);
|
|
1531
1600
|
if (!resolved.ok)
|
|
1532
1601
|
return resolved.answer;
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1602
|
+
try {
|
|
1603
|
+
const { spec, engineNotices } = resolved;
|
|
1604
|
+
const { objective: resumeObjective, sessionId: _sessionId, ...taskConfig } = spec;
|
|
1605
|
+
const verifyRounds = verifyRoundsFromBody(ctx.body);
|
|
1606
|
+
const outcome = {
|
|
1607
|
+
gate: "plan_review",
|
|
1608
|
+
decision,
|
|
1609
|
+
...(editedPlan !== undefined ? { editedPlan } : {}),
|
|
1610
|
+
...(reason ? { reason } : {}),
|
|
1611
|
+
hostDecision,
|
|
1612
|
+
};
|
|
1613
|
+
const selectedGate = durableRowIdentity("decision-receipt", cp.checkpointId, token);
|
|
1614
|
+
const out = await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: runnerFor(spec), token, sessionId: cp.sessionId, principal: auth.principal, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome, commitment: { kind: "gate_resolved", ...selectedGate }, verifyRounds, resumeCtx: { sessionId, ctx: rebuildCtx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}) });
|
|
1615
|
+
return out;
|
|
1616
|
+
}
|
|
1617
|
+
finally {
|
|
1618
|
+
resolved.peerLease.release();
|
|
1619
|
+
}
|
|
1545
1620
|
}
|
|
1546
1621
|
const routeCtxBase = {
|
|
1547
1622
|
deps,
|