@sema-agent/server 7.147.0 → 7.148.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 +1039 -24
- package/README.md +20 -7
- package/README.zh-CN.md +14 -8
- package/USAGE.md +380 -163
- package/deploy/sema-up/README.md +16 -5
- package/deploy/sema-up/chart/templates/NOTES.txt +1 -1
- package/deploy/sema-up/chart/templates/_helpers.tpl +20 -4
- package/deploy/sema-up/chart/values.yaml +3 -2
- package/deploy/sema-up/cluster-up.sh +74 -176
- package/deploy/sema-up/kube-up.sh +29 -49
- package/deploy/sema-up/lib/chart-run.sh +23 -0
- package/deploy/sema-up/lib/dataroot.sh +3 -3
- package/deploy/sema-up/lib/health.sh +62 -13
- package/deploy/sema-up/lib/helm-values-cluster.py +18 -0
- package/deploy/sema-up/lib/helm-values-kube.py +35 -0
- package/deploy/sema-up/lib/regcred.py +8 -0
- package/deploy/sema-up/lib/remote/helm-install.sh +3 -0
- package/deploy/sema-up/lib/remote/image-import.sh +6 -0
- package/deploy/sema-up/lib/remote/machine-precheck.sh +11 -0
- package/deploy/sema-up/lib/remote/region-probe.sh +3 -0
- package/deploy/sema-up/lib/remote/stack-ready.sh +26 -0
- package/deploy/sema-up/lib/remote/vxlan-guard.sh +8 -0
- package/deploy/sema-up/lib/render-stack.py +17 -0
- package/deploy/sema-up/lib/shell-text.sh +87 -0
- package/deploy/sema-up/lib/usage-flags.txt +10 -0
- package/deploy/sema-up/lib/usage-head.txt +1 -0
- package/deploy/sema-up/lib/usage-tail.txt +13 -0
- package/deploy/sema-up/preflight.sh +10 -8
- package/deploy/sema-up/sema-up.sh +14 -39
- package/deploy/sema-up/smoke.sh +7 -6
- package/deploy/sema-up/stack/compose.dataroot.yaml +3 -0
- package/deploy/sema-up/stack/compose.yaml +13 -1
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +21 -0
- package/dist/adoption/plan.d.ts +24 -0
- package/dist/adoption/plan.js +53 -1
- package/dist/adoption/runner.d.ts +10 -1
- package/dist/adoption/runner.js +36 -16
- package/dist/adoption/wire.d.ts +3 -3
- package/dist/approval-card.d.ts +28 -30
- package/dist/approval-gate-currency.js +3 -2
- package/dist/approval-reconciler.d.ts +4 -13
- package/dist/approval-reconciler.js +2 -2
- package/dist/approval.d.ts +13 -11
- package/dist/approval.js +3 -3
- package/dist/audit.d.ts +10 -3
- package/dist/audit.js +15 -7
- package/dist/auth-bridge.d.ts +0 -14
- package/dist/auth-bridge.js +0 -7
- package/dist/auto-mode-face.d.ts +10 -7
- package/dist/auto-mode-face.js +7 -4
- package/dist/background-agent-name.d.ts +19 -1
- package/dist/background-agent-name.js +12 -2
- package/dist/background-session-reap.d.ts +1 -1
- package/dist/bake-runner/main.js +9 -6
- package/dist/bench/s1/arms.js +6 -5
- package/dist/bench/s1/live-deps.js +5 -2
- package/dist/bench/s1/run-firm.js +6 -5
- package/dist/bind-host.d.ts +25 -0
- package/dist/bind-host.js +25 -0
- package/dist/boot/adoption.d.ts +3 -0
- package/dist/boot/adoption.js +1 -0
- package/dist/boot/deployment-mods.d.ts +1 -1
- package/dist/boot/execution-env.d.ts +17 -7
- package/dist/boot/execution-env.js +37 -31
- package/dist/boot/exit-boundary.d.ts +2 -2
- package/dist/boot/exit-boundary.js +6 -5
- package/dist/boot/fatal-exit.d.ts +3 -5
- package/dist/boot/fatal-exit.js +2 -2
- package/dist/boot/leader.d.ts +15 -0
- package/dist/boot/leader.js +17 -15
- package/dist/boot/memory-consolidation.d.ts +37 -29
- package/dist/boot/memory-consolidation.js +11 -5
- package/dist/boot/org-memory.js +1 -1
- package/dist/boot/parked-revive-gate.js +2 -2
- package/dist/boot/reapers.d.ts +4 -3
- package/dist/boot/reapers.js +19 -16
- package/dist/boot/resolve-spec.d.ts +5 -3
- package/dist/boot/resolve-spec.js +55 -67
- package/dist/boot/retention-lane.d.ts +4 -4
- package/dist/boot/retention-lane.js +2 -2
- package/dist/boot/runner-deps.d.ts +28 -7
- package/dist/boot/runner-deps.js +11 -4
- package/dist/boot/runtime-caps.d.ts +2 -2
- package/dist/boot/runtime-caps.js +16 -2
- package/dist/boot/session-faces.d.ts +16 -7
- package/dist/boot/session-faces.js +114 -94
- package/dist/boot/shutdown.d.ts +5 -4
- package/dist/boot/shutdown.js +6 -4
- package/dist/boot/stage-01-config.js +9 -1
- package/dist/boot/stage-02-web-admin-pull.d.ts +1 -0
- package/dist/boot/stage-02-web-admin-pull.js +6 -1
- package/dist/boot/stage-03-store-backend.d.ts +3 -0
- package/dist/boot/stage-03-store-backend.js +4 -3
- package/dist/boot/stage-04-stores.d.ts +2 -0
- package/dist/boot/stage-04-stores.js +2 -2
- package/dist/boot/stage-05-execution-env.d.ts +7 -3
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +10 -12
- package/dist/boot/stage-06-runners.js +23 -15
- package/dist/boot/stage-07-capability-layer.d.ts +11 -8
- package/dist/boot/stage-07-capability-layer.js +5 -3
- package/dist/boot/stage-08-reapers.d.ts +11 -8
- package/dist/boot/stage-08-reapers.js +3 -3
- package/dist/boot/stage-09-leader.d.ts +12 -15
- package/dist/boot/stage-09-leader.js +12 -4
- package/dist/boot/stage-10-http-server.d.ts +12 -15
- package/dist/boot/stage-10-http-server.js +7 -4
- package/dist/boot/store-evidence.d.ts +20 -0
- package/dist/boot/store-evidence.js +13 -0
- package/dist/boot/stores.d.ts +3 -0
- package/dist/boot/stores.js +21 -10
- package/dist/boot/task-list-lane.d.ts +4 -4
- package/dist/boot/web-admin.d.ts +4 -2
- package/dist/boot/web-admin.js +55 -35
- package/dist/boot/webfetch-summarize-lane.d.ts +1 -1
- package/dist/boot-reclaim.d.ts +3 -1
- package/dist/boot-reclaim.js +1 -1
- package/dist/brain.d.ts +7 -18
- package/dist/brain.js +5 -17
- package/dist/budget.js +6 -6
- package/dist/capabilities/center-plugins.d.ts +7 -1
- package/dist/capabilities/center-plugins.js +32 -10
- package/dist/capabilities/center-wiring.js +1 -1
- package/dist/capabilities/composite-members.d.ts +2 -2
- package/dist/capabilities/composite-members.js +2 -2
- package/dist/capabilities/repo-tools.d.ts +2 -0
- package/dist/capabilities/repo-tools.js +14 -12
- package/dist/capabilities/scenarios.d.ts +6 -15
- package/dist/capabilities/scenarios.js +11 -16
- package/dist/capabilities/skills.d.ts +1 -1
- package/dist/capabilities/tool-defer.d.ts +1 -1
- package/dist/capability-facts.d.ts +38 -11
- package/dist/capability-facts.js +47 -8
- package/dist/card-void.d.ts +4 -4
- package/dist/card-void.js +1 -1
- package/dist/center-credential-renewer.d.ts +6 -2
- package/dist/center-credential-renewer.js +7 -3
- package/dist/config-catalog.d.ts +16 -1
- package/dist/config-catalog.js +62 -56
- package/dist/config-dir-trust.d.ts +37 -4
- package/dist/config-dir-trust.js +88 -44
- package/dist/config-invariants.d.ts +42 -3
- package/dist/config-invariants.js +69 -5
- package/dist/config-lkg.d.ts +23 -1
- package/dist/config-lkg.js +17 -3
- package/dist/config-provider.d.ts +9 -9
- package/dist/config-provider.js +25 -110
- package/dist/config-pull-failure.d.ts +50 -0
- package/dist/config-pull-failure.js +48 -0
- package/dist/config-types.d.ts +26 -17
- package/dist/config.d.ts +8 -16
- package/dist/config.js +113 -47
- package/dist/delegated-session-owner.d.ts +1 -1
- package/dist/deleted-session-ids.d.ts +3 -2
- package/dist/deployment-governance.d.ts +3 -3
- package/dist/deployment-shape.d.ts +30 -4
- package/dist/deployment-shape.js +7 -0
- package/dist/egress-redirect.d.ts +25 -7
- package/dist/egress-redirect.js +20 -2
- package/dist/elicitation.d.ts +6 -5
- package/dist/elicitation.js +23 -22
- package/dist/engine-identity.d.ts +28 -0
- package/dist/engine-identity.js +10 -0
- package/dist/entry-problems.d.ts +5 -7
- package/dist/entry-problems.js +1 -1
- package/dist/env-facts.js +2 -1
- package/dist/env-witness.d.ts +7 -0
- package/dist/env-witness.js +16 -0
- package/dist/execution-lane-caps.d.ts +5 -18
- package/dist/execution-lane-caps.js +0 -22
- package/dist/execution-placement.d.ts +58 -18
- package/dist/execution-placement.js +41 -2
- package/dist/field-conflict.d.ts +7 -11
- package/dist/field-conflict.js +3 -3
- package/dist/file-history-capture.d.ts +3 -3
- package/dist/file-history-disclosure.js +1 -0
- package/dist/fleet/fleet-bus.d.ts +21 -3
- package/dist/fleet/fleet-bus.js +35 -25
- package/dist/fleet/fleet-reconciler.js +2 -2
- package/dist/fleet/serving-lease.js +3 -3
- package/dist/fleet-client.js +3 -3
- package/dist/fleet-lease.d.ts +0 -1
- package/dist/fleet-lease.js +4 -5
- package/dist/history-anchor.d.ts +23 -3
- package/dist/history-anchor.js +24 -4
- package/dist/hitl-delivery.d.ts +90 -0
- package/dist/hitl-delivery.js +98 -0
- package/dist/hooks/classic-stations.d.ts +8 -11
- package/dist/hooks/classic-stations.js +0 -7
- package/dist/hooks/hook-llm.d.ts +5 -1
- package/dist/hooks/hook-llm.js +24 -15
- package/dist/hooks/hook-runner.d.ts +67 -57
- package/dist/hooks/hook-runner.js +260 -186
- package/dist/host-lsp-manager.d.ts +22 -8
- package/dist/host-lsp-manager.js +4 -1
- package/dist/http/active-run-conflict.d.ts +2 -43
- package/dist/http/active-run-conflict.js +3 -7
- package/dist/http/admission.d.ts +4 -18
- package/dist/http/admission.js +75 -78
- package/dist/http/approval-sweeps.d.ts +3 -3
- package/dist/http/approval-sweeps.js +54 -30
- package/dist/http/caller-trust.d.ts +8 -10
- package/dist/http/caller-trust.js +1 -2
- package/dist/http/claim-heartbeat.d.ts +49 -0
- package/dist/http/claim-heartbeat.js +46 -0
- package/dist/http/claimed-run.d.ts +4 -3
- package/dist/http/dispatch.d.ts +8 -1
- package/dist/http/dispatch.js +76 -30
- package/dist/http/durable-run-leg.d.ts +3 -3
- package/dist/http/durable-run-leg.js +17 -12
- package/dist/http/execution-context.d.ts +17 -43
- package/dist/http/execution-context.js +7 -5
- package/dist/http/health-reader.d.ts +36 -0
- package/dist/http/health-reader.js +21 -0
- package/dist/http/health-self-report.d.ts +9 -9
- package/dist/http/health-self-report.js +4 -4
- package/dist/http/idempotency.d.ts +9 -5
- package/dist/http/idempotency.js +4 -4
- package/dist/http/memory-compliance-failure-reply.d.ts +15 -16
- package/dist/http/memory-compliance-failure-reply.js +4 -2
- package/dist/http/memory-face-fault-reply.d.ts +67 -0
- package/dist/http/memory-face-fault-reply.js +71 -0
- package/dist/http/memory-store-refusal-reply.d.ts +1 -1
- package/dist/http/memory-store-refusal-reply.js +3 -0
- package/dist/http/owner-access.d.ts +391 -67
- package/dist/http/owner-access.js +371 -35
- package/dist/http/principal-gate.d.ts +24 -81
- package/dist/http/principal-gate.js +24 -68
- package/dist/http/refusal-body.d.ts +35 -2
- package/dist/http/refusal-body.js +34 -0
- package/dist/http/request-guards.d.ts +9 -13
- package/dist/http/request-guards.js +34 -68
- package/dist/http/resume-composition.d.ts +37 -0
- package/dist/http/resume-composition.js +18 -0
- package/dist/http/resume-ctx-read.d.ts +35 -12
- package/dist/http/resume-ctx-read.js +25 -6
- package/dist/http/resume-legs.d.ts +21 -18
- package/dist/http/resume-legs.js +189 -129
- package/dist/http/retired-skill-manifest.d.ts +1 -1
- package/dist/http/route-ctx.d.ts +25 -32
- package/dist/http/routes/a2a-serve.d.ts +43 -5
- package/dist/http/routes/a2a-serve.js +58 -37
- package/dist/http/routes/admin-config-refresh.js +2 -2
- package/dist/http/routes/admin-drain.js +2 -2
- package/dist/http/routes/admin-memory-optout.js +4 -3
- package/dist/http/routes/adoption.d.ts +3 -0
- package/dist/http/routes/adoption.js +17 -10
- package/dist/http/routes/agents-roster.js +13 -7
- package/dist/http/routes/approvals-assistant.js +70 -65
- package/dist/http/routes/attachments.js +2 -2
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/background.js +9 -17
- package/dist/http/routes/capabilities.js +15 -18
- package/dist/http/routes/config-catalog.js +2 -2
- package/dist/http/routes/devices.d.ts +3 -3
- package/dist/http/routes/devices.js +4 -4
- package/dist/http/routes/diagnostics.d.ts +27 -3
- package/dist/http/routes/diagnostics.js +27 -21
- package/dist/http/routes/engine.js +2 -2
- package/dist/http/routes/fleet.js +5 -3
- package/dist/http/routes/images.js +10 -6
- package/dist/http/routes/leader.d.ts +7 -2
- package/dist/http/routes/leader.js +12 -3
- package/dist/http/routes/mcp-reconnect.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +7 -15
- package/dist/http/routes/memory-bundle.js +4 -7
- package/dist/http/routes/memory-compliance.js +4 -4
- package/dist/http/routes/memory-consolidation.js +6 -9
- package/dist/http/routes/memory-origin.d.ts +2 -0
- package/dist/http/routes/memory-origin.js +7 -8
- package/dist/http/routes/memory-policy.js +17 -12
- package/dist/http/routes/notify-wake.js +10 -19
- package/dist/http/routes/observability.js +3 -3
- package/dist/http/routes/principal-inbox.d.ts +1 -1
- package/dist/http/routes/principal-inbox.js +2 -2
- package/dist/http/routes/projects.d.ts +1 -1
- package/dist/http/routes/projects.js +3 -2
- package/dist/http/routes/retention-ops.js +6 -9
- package/dist/http/routes/rules.js +20 -5
- package/dist/http/routes/run-memory-capture.d.ts +2 -2
- package/dist/http/routes/run-memory-capture.js +6 -12
- package/dist/http/routes/run-permission-mode.d.ts +2 -2
- package/dist/http/routes/run-permission-mode.js +10 -17
- package/dist/http/routes/runs.js +146 -231
- package/dist/http/routes/session-memory-sync.d.ts +2 -2
- package/dist/http/routes/session-memory-sync.js +7 -13
- package/dist/http/routes/session-sync.d.ts +4 -2
- package/dist/http/routes/session-sync.js +21 -20
- package/dist/http/routes/sessions-list.d.ts +3 -3
- package/dist/http/routes/sessions-list.js +9 -9
- package/dist/http/routes/sessions.js +87 -124
- package/dist/http/routes/shared-memory.js +6 -6
- package/dist/http/routes/side-query.js +2 -2
- package/dist/http/routes/tasks.js +136 -120
- package/dist/http/routes/trace-usage.d.ts +0 -12
- package/dist/http/routes/trace-usage.js +40 -46
- package/dist/http/routes/workflows.d.ts +39 -4
- package/dist/http/routes/workflows.js +42 -14
- package/dist/http/run-concurrency-cap.d.ts +20 -12
- package/dist/http/run-concurrency-cap.js +39 -26
- package/dist/http/run-read-face.d.ts +3 -5
- package/dist/http/run-read-face.js +8 -13
- package/dist/http/send.d.ts +12 -3
- package/dist/http/send.js +42 -6
- package/dist/http/server.d.ts +39 -40
- package/dist/http/server.js +36 -11
- package/dist/http/sse-log.d.ts +17 -10
- package/dist/http/sse-log.js +7 -7
- package/dist/http/stored-body-replay.d.ts +12 -0
- package/dist/http/stored-body-replay.js +2 -2
- package/dist/http/submit-ctx.d.ts +16 -8
- package/dist/http/submit-ctx.js +6 -2
- package/dist/http/submit-replay.d.ts +19 -6
- package/dist/http/submit-replay.js +18 -6
- package/dist/http/sync-submit-body.d.ts +3 -4
- package/dist/http/sync-submit-body.js +4 -5
- package/dist/http/wire-types.d.ts +4 -3
- package/dist/identity-source.d.ts +36 -5
- package/dist/identity-source.js +27 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/key-resolver.d.ts +32 -0
- package/dist/key-resolver.js +23 -9
- package/dist/leader/diffup.js +2 -1
- package/dist/leader/endpoint.d.ts +26 -5
- package/dist/leader/endpoint.js +154 -14
- package/dist/leader/fanout.d.ts +3 -0
- package/dist/leader/fanout.js +78 -63
- package/dist/leader/leader.d.ts +16 -0
- package/dist/leader/leader.js +43 -3
- package/dist/leader/merge.d.ts +9 -1
- package/dist/leader/merge.js +16 -1
- package/dist/leader/repair-wire.js +1 -1
- package/dist/leader/wire.d.ts +36 -3
- package/dist/leader/wire.js +59 -18
- package/dist/lsp-evict.d.ts +6 -4
- package/dist/lsp-evict.js +2 -3
- package/dist/memory-operator-faces.d.ts +5 -4
- package/dist/memory-operator-faces.js +1 -1
- package/dist/memory-scope.d.ts +29 -2
- package/dist/memory-scope.js +64 -15
- package/dist/memory-store-refusal.d.ts +5 -2
- package/dist/memory-sync-client.d.ts +3 -2
- package/dist/memory-sync-client.js +6 -3
- package/dist/model-compat.d.ts +17 -8
- package/dist/model-compat.js +6 -2
- package/dist/model-context-window.d.ts +18 -0
- package/dist/model-context-window.js +2 -0
- package/dist/model-entry-headers.d.ts +46 -4
- package/dist/model-entry-headers.js +2 -2
- package/dist/model-entry-refusal.d.ts +35 -16
- package/dist/model-entry-refusal.js +40 -27
- package/dist/model-plane-face.d.ts +19 -11
- package/dist/model-plane-face.js +9 -1
- package/dist/model-plane-probe.d.ts +2 -0
- package/dist/model-plane-probe.js +17 -0
- package/dist/model-provider.d.ts +3 -3
- package/dist/model-route-endpoint.d.ts +9 -5
- package/dist/model-route-endpoint.js +29 -7
- package/dist/model-select.d.ts +16 -0
- package/dist/model-select.js +4 -0
- package/dist/mountinfo.d.ts +37 -0
- package/dist/mountinfo.js +47 -0
- package/dist/namespaced-rule-name.d.ts +23 -14
- package/dist/namespaced-rule-name.js +8 -11
- package/dist/net-address.d.ts +1 -1
- package/dist/observability/corrupt-read-seat.d.ts +4 -4
- package/dist/observability/corrupt-read-seat.js +5 -3
- package/dist/observability/fail-open.d.ts +58 -38
- package/dist/observability/fail-open.js +60 -38
- package/dist/observability/logger.d.ts +22 -1
- package/dist/observability/logger.js +89 -12
- package/dist/observability/metrics.js +3 -4
- package/dist/observability/otel-exporter.js +2 -1
- package/dist/observability/principal-context.d.ts +14 -7
- package/dist/observability/principal-context.js +8 -3
- package/dist/observability/run-terminal.d.ts +7 -1
- package/dist/observability/run-terminal.js +5 -2
- package/dist/orchestration/hardened-vm-runner.d.ts +1 -0
- package/dist/orchestration/hardened-vm-runner.js +11 -5
- package/dist/orchestration/hardened-vm-worker-runner.d.ts +0 -14
- package/dist/orchestration/hardened-vm-worker-runner.js +5 -0
- package/dist/orchestration/hardened-vm-worker.js +2 -1
- package/dist/orchestration/workflow-completion-inbox.d.ts +3 -3
- package/dist/orchestration/workflow-completion-inbox.js +3 -2
- package/dist/org-delivery-gate.d.ts +5 -4
- package/dist/org-delivery-gate.js +7 -6
- package/dist/outbound-dispatcher.d.ts +1 -1
- package/dist/outbound-dispatcher.js +6 -12
- package/dist/owner-brands.d.ts +81 -0
- package/dist/owner-brands.js +42 -0
- package/dist/owner-faces.d.ts +531 -0
- package/dist/owner-faces.js +126 -0
- package/dist/parked-decide.d.ts +67 -5
- package/dist/parked-decide.js +127 -5
- package/dist/parked-revive-surface.d.ts +14 -4
- package/dist/parked-revive-surface.js +5 -4
- package/dist/peer-directory.d.ts +6 -8
- package/dist/peer-directory.js +3 -2
- package/dist/permission-rule-vocab.d.ts +53 -8
- package/dist/permission-rule-vocab.js +30 -2
- package/dist/plugins/adoption-log-sql.d.ts +0 -22
- package/dist/plugins/adoption-log-sql.js +5 -3
- package/dist/plugins/approval-ask-retired-delete-by-task-m50.d.ts +7 -0
- package/dist/plugins/approval-ask-retired-delete-by-task-m50.js +17 -0
- package/dist/plugins/approval-ask-store-file.d.ts +18 -7
- package/dist/plugins/approval-ask-store-file.js +37 -14
- package/dist/plugins/approval-ask-store-memory.d.ts +12 -4
- package/dist/plugins/approval-ask-store-memory.js +24 -10
- package/dist/plugins/approval-ask-store-sql.d.ts +39 -20
- package/dist/plugins/approval-ask-store-sql.js +41 -10
- package/dist/plugins/approval-exemption-skill-m46.d.ts +20 -0
- package/dist/plugins/approval-exemption-skill-m46.js +25 -0
- package/dist/plugins/approval-exemption-store.d.ts +6 -1
- package/dist/plugins/approval-exemption-store.js +14 -0
- package/dist/plugins/approval-nonce-store.d.ts +39 -12
- package/dist/plugins/approval-nonce-store.js +72 -23
- package/dist/plugins/blob-backend.d.ts +2 -0
- package/dist/plugins/blob-backend.js +9 -6
- package/dist/plugins/caching-session-store.d.ts +13 -1
- package/dist/plugins/caching-session-store.js +43 -4
- package/dist/plugins/checkpoint-index-columns.d.ts +32 -5
- package/dist/plugins/checkpoint-index-columns.js +36 -1
- package/dist/plugins/checkpoint-store-face.d.ts +83 -10
- package/dist/plugins/checkpoint-store-face.js +18 -1
- package/dist/plugins/device-store-sql.js +1 -0
- package/dist/plugins/ensure-index.d.ts +13 -1
- package/dist/plugins/ensure-index.js +154 -21
- package/dist/plugins/ensure-schema-lock-policy.d.ts +0 -15
- package/dist/plugins/ensure-schema-lock-policy.js +3 -2
- package/dist/plugins/file-run-store.d.ts +63 -23
- package/dist/plugins/file-run-store.js +138 -83
- package/dist/plugins/host-platform.d.ts +24 -3
- package/dist/plugins/host-platform.js +15 -1
- package/dist/plugins/image-bake-store-sql.js +2 -0
- package/dist/plugins/imported-layer-root-retirement.d.ts +2 -2
- package/dist/plugins/k8s-pod-reaper.d.ts +1 -3
- package/dist/plugins/k8s-pod-reaper.js +0 -1
- package/dist/plugins/leader-run-store-sql.d.ts +22 -0
- package/dist/plugins/leader-run-store-sql.js +34 -4
- package/dist/plugins/local-checkpoint-store.d.ts +58 -23
- package/dist/plugins/local-checkpoint-store.js +195 -76
- package/dist/plugins/local-data-dir-modes-m39.js +2 -1
- package/dist/plugins/local-docker-capacity.d.ts +93 -0
- package/dist/plugins/local-docker-capacity.js +194 -0
- package/dist/plugins/local-docker-reaper.d.ts +92 -0
- package/dist/plugins/local-docker-reaper.js +102 -0
- package/dist/plugins/local-engine-high-water.d.ts +4 -2
- package/dist/plugins/local-engine-high-water.js +4 -1
- package/dist/plugins/local-session-store.d.ts +358 -125
- package/dist/plugins/local-session-store.js +824 -251
- package/dist/plugins/local-session-window.d.ts +3 -2
- package/dist/plugins/local-session-window.js +3 -2
- package/dist/plugins/local-sidecar-quarantine.js +3 -2
- package/dist/plugins/local-task-attachment-store.d.ts +18 -1
- package/dist/plugins/local-task-attachment-store.js +22 -1
- package/dist/plugins/memory-embedder.js +9 -7
- package/dist/plugins/memory-engine-pg.d.ts +3 -2
- package/dist/plugins/memory-engine-pg.js +14 -5
- package/dist/plugins/memory-engine-sql-apply.d.ts +8 -4
- package/dist/plugins/memory-engine-sql-apply.js +6 -8
- package/dist/plugins/memory-engine-tidb.d.ts +4 -2
- package/dist/plugins/memory-engine-tidb.js +11 -2
- package/dist/plugins/memory-optout-grant-store-sql.d.ts +1 -1
- package/dist/plugins/memory-optout-grant-store-sql.js +3 -3
- package/dist/plugins/memory-run-store.d.ts +39 -27
- package/dist/plugins/memory-run-store.js +72 -70
- package/dist/plugins/one-time-migration-marker.d.ts +10 -0
- package/dist/plugins/one-time-migration-marker.js +7 -0
- package/dist/plugins/one-time-migrations.d.ts +186 -45
- package/dist/plugins/one-time-migrations.js +442 -119
- package/dist/plugins/org-delivery-quota-store.js +2 -1
- package/dist/plugins/permission-rule-store-file.d.ts +3 -3
- package/dist/plugins/permission-rule-store-sql.d.ts +4 -63
- package/dist/plugins/permission-rule-store-sql.js +6 -86
- package/dist/plugins/pg-pool.d.ts +1 -31
- package/dist/plugins/pg-pool.js +16 -7
- package/dist/plugins/remote-env-e2b.d.ts +7 -25
- package/dist/plugins/remote-env-e2b.js +34 -25
- package/dist/plugins/remote-env-host.d.ts +2 -9
- package/dist/plugins/remote-env-host.js +34 -22
- package/dist/plugins/remote-env-k8s.d.ts +40 -45
- package/dist/plugins/remote-env-k8s.js +107 -58
- package/dist/plugins/remote-env-local-docker.d.ts +148 -14
- package/dist/plugins/remote-env-local-docker.js +367 -72
- package/dist/plugins/remote-scratchpad.js +4 -0
- package/dist/plugins/retention-deployment.d.ts +49 -17
- package/dist/plugins/retention-deployment.js +39 -8
- package/dist/plugins/run-preview-m45.d.ts +11 -0
- package/dist/plugins/run-preview-m45.js +19 -0
- package/dist/plugins/run-store-sql.d.ts +56 -68
- package/dist/plugins/run-store-sql.js +127 -116
- package/dist/plugins/s3-answer.d.ts +2 -1
- package/dist/plugins/sandbox-reaper.d.ts +26 -0
- package/dist/plugins/sandbox-reaper.js +2 -0
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +54 -0
- package/dist/plugins/scenario-prefix-switch-m42.js +55 -0
- package/dist/plugins/scheduler-support.d.ts +16 -1
- package/dist/plugins/scheduler-support.js +22 -2
- package/dist/plugins/schema-consistency.d.ts +42 -9
- package/dist/plugins/schema-consistency.js +212 -11
- package/dist/plugins/schema-drift-sentence.d.ts +4 -1
- package/dist/plugins/schema-drift-sentence.js +4 -4
- package/dist/plugins/schema-ensure-legs.d.ts +9 -0
- package/dist/plugins/schema-ensure-legs.js +1 -1
- package/dist/plugins/schema-indexes.js +3 -0
- package/dist/plugins/schema-live-columns.d.ts +14 -5
- package/dist/plugins/schema-live-columns.js +10 -10
- package/dist/plugins/send-user-file.js +2 -1
- package/dist/plugins/session-birth.d.ts +37 -0
- package/dist/plugins/session-birth.js +38 -0
- package/dist/plugins/session-epoch-anchor.d.ts +40 -12
- package/dist/plugins/session-epoch-anchor.js +33 -11
- package/dist/plugins/session-ext-table.d.ts +27 -3
- package/dist/plugins/session-ext-table.js +19 -6
- package/dist/plugins/session-fork.d.ts +15 -1
- package/dist/plugins/session-fork.js +3 -0
- package/dist/plugins/session-ownership.d.ts +1 -1
- package/dist/plugins/session-placement.d.ts +22 -16
- package/dist/plugins/session-placement.js +15 -12
- package/dist/plugins/session-row-sql.d.ts +12 -0
- package/dist/plugins/session-row-sql.js +3 -3
- package/dist/plugins/session-run-rollup.d.ts +29 -0
- package/dist/plugins/session-run-rollup.js +40 -0
- package/dist/plugins/session-store-sql.d.ts +38 -12
- package/dist/plugins/session-store-sql.js +130 -30
- package/dist/plugins/session-withdraw-sql.d.ts +36 -0
- package/dist/plugins/session-withdraw-sql.js +42 -0
- package/dist/plugins/shared-memory-store-sql.d.ts +0 -69
- package/dist/plugins/shared-memory-store-sql.js +2 -1
- package/dist/plugins/shell-sentinel-owner-m48.d.ts +20 -0
- package/dist/plugins/shell-sentinel-owner-m48.js +3 -0
- package/dist/plugins/snapshot-bucket-presence.d.ts +2 -1
- package/dist/plugins/sql-driver.d.ts +1 -1
- package/dist/plugins/sql-driver.js +2 -1
- package/dist/plugins/sql-errors.d.ts +32 -5
- package/dist/plugins/sql-errors.js +55 -7
- package/dist/plugins/sql-json-column.d.ts +8 -7
- package/dist/plugins/sql-json-column.js +10 -6
- package/dist/plugins/store-backend.d.ts +84 -15
- package/dist/plugins/store-backend.js +186 -55
- package/dist/plugins/store-contracts.d.ts +90 -30
- package/dist/plugins/store-contracts.js +22 -1
- package/dist/plugins/store-fault.d.ts +28 -2
- package/dist/plugins/store-fault.js +20 -2
- package/dist/plugins/task-attachment-store.d.ts +15 -3
- package/dist/plugins/task-attachment-store.js +22 -9
- package/dist/plugins/tidb-pool.js +23 -8
- package/dist/plugins/web-search.js +5 -3
- package/dist/plugins/workflow-run-store-sql.d.ts +6 -1
- package/dist/plugins/workflow-run-store-sql.js +11 -5
- package/dist/principal-jwt.d.ts +4 -4
- package/dist/principal-jwt.js +20 -5
- package/dist/principal-shape.d.ts +41 -0
- package/dist/principal-shape.js +19 -0
- package/dist/question.d.ts +13 -23
- package/dist/question.js +21 -39
- package/dist/request-declaration-refusal.d.ts +35 -12
- package/dist/request-declaration-refusal.js +21 -9
- package/dist/request-form.d.ts +58 -0
- package/dist/request-form.js +72 -0
- package/dist/request-image-urls.d.ts +8 -2
- package/dist/request-image-urls.js +2 -1
- package/dist/request-images.d.ts +20 -0
- package/dist/request-images.js +59 -0
- package/dist/request-key-closure.d.ts +6 -7
- package/dist/request-key-closure.js +15 -2
- package/dist/resource-suspend.d.ts +7 -16
- package/dist/resource-suspend.js +1 -1
- package/dist/retired-name-host-notice.d.ts +21 -0
- package/dist/retired-name-host-notice.js +12 -0
- package/dist/rule-entry-list.d.ts +2 -2
- package/dist/rule-entry-list.js +3 -4
- package/dist/rule-issue-reading.d.ts +58 -0
- package/dist/rule-issue-reading.js +14 -0
- package/dist/rules-consent.d.ts +5 -3
- package/dist/rules-consent.js +1 -0
- package/dist/run-acceptance.d.ts +3 -1
- package/dist/run-acceptance.js +3 -0
- package/dist/run-local.d.ts +14 -6
- package/dist/run-local.js +92 -80
- package/dist/run-stale-default.d.ts +7 -0
- package/dist/run-stale-default.js +2 -0
- package/dist/runs.d.ts +26 -15
- package/dist/runs.js +39 -27
- package/dist/runtime-caps-resolver.d.ts +21 -6
- package/dist/runtime-caps-resolver.js +17 -4
- package/dist/runtime-governance.d.ts +2 -2
- package/dist/runtime-governance.js +5 -3
- package/dist/sealed-key-layout.d.ts +12 -5
- package/dist/sealed-key-layout.js +5 -0
- package/dist/sealed-key.d.ts +12 -2
- package/dist/sealed-key.js +115 -27
- package/dist/security.d.ts +128 -158
- package/dist/security.js +163 -59
- package/dist/sema-config-dir.d.ts +20 -0
- package/dist/sema-config-dir.js +25 -0
- package/dist/server-secret-env.d.ts +21 -5
- package/dist/server-secret-env.js +14 -4
- package/dist/session-children-retire.d.ts +7 -5
- package/dist/session-children-retire.js +7 -2
- package/dist/session-deletion.d.ts +88 -0
- package/dist/session-deletion.js +8 -0
- package/dist/session-erase.d.ts +145 -0
- package/dist/session-erase.js +115 -0
- package/dist/session-error-wire.d.ts +5 -5
- package/dist/session-error-wire.js +1 -1
- package/dist/session-incarnation.d.ts +52 -5
- package/dist/session-incarnation.js +19 -2
- package/dist/session-policy-wire.d.ts +6 -3
- package/dist/session-policy-wire.js +11 -1
- package/dist/session-resident-background.d.ts +0 -71
- package/dist/session-resident-background.js +4 -3
- package/dist/session-row.d.ts +2 -1
- package/dist/session-rules-seat.d.ts +12 -0
- package/dist/session-rules-seat.js +19 -0
- package/dist/session-titler.d.ts +7 -15
- package/dist/session-titler.js +1 -1
- package/dist/spec-fields.d.ts +57 -3
- package/dist/spec-fields.js +72 -51
- package/dist/store-posture.d.ts +136 -20
- package/dist/store-posture.js +188 -3
- package/dist/stored-request-hooks-m20.js +2 -2
- package/dist/stores-sql/background-agent-store-sql.d.ts +11 -2
- package/dist/stores-sql/background-agent-store-sql.js +73 -20
- package/dist/stores-sql/checkpoint-store-sql.d.ts +33 -28
- package/dist/stores-sql/checkpoint-store-sql.js +75 -44
- package/dist/stores-sql/mailbox-store-sql.d.ts +7 -4
- package/dist/stores-sql/mailbox-store-sql.js +31 -32
- package/dist/stores-sql/pg-session-storage.d.ts +7 -5
- package/dist/stores-sql/pg-session-storage.js +54 -46
- package/dist/stores-sql/retention-store-sql.d.ts +87 -19
- package/dist/stores-sql/retention-store-sql.js +92 -27
- package/dist/stores-sql/session-policy-store-sql.d.ts +32 -10
- package/dist/stores-sql/session-policy-store-sql.js +44 -36
- package/dist/stores-sql/session-write-hooks.d.ts +12 -6
- package/dist/stores-sql/tidb-session-storage.d.ts +4 -4
- package/dist/stores-sql/tidb-session-storage.js +13 -8
- package/dist/stores-sql/tidb-session-store.d.ts +36 -17
- package/dist/stores-sql/tidb-session-store.js +69 -39
- package/dist/stores-sql/windowed-session-storage.d.ts +5 -0
- package/dist/stores-sql/windowed-session-storage.js +9 -0
- package/dist/submission-exit.d.ts +50 -0
- package/dist/submission-exit.js +108 -0
- package/dist/task-a2a.d.ts +1 -1
- package/dist/task-a2a.js +3 -3
- package/dist/task-cwd.d.ts +20 -0
- package/dist/task-cwd.js +8 -0
- package/dist/task-mcp.d.ts +1 -1
- package/dist/task-mcp.js +3 -3
- package/dist/task-settings.d.ts +14 -10
- package/dist/task-settings.js +18 -7
- package/dist/terminal.d.ts +25 -43
- package/dist/terminal.js +31 -11
- package/dist/tool-approval.d.ts +131 -129
- package/dist/tool-approval.js +189 -193
- package/dist/trace/core-keyset-guard.d.ts +13 -6
- package/dist/trace/core-vocab-wire.d.ts +95 -0
- package/dist/trace/core-vocab-wire.js +15 -0
- package/dist/trace/exit-seat.d.ts +30 -4
- package/dist/trace/exit-seat.js +40 -36
- package/dist/trace/extension-call-face.d.ts +3 -2
- package/dist/trace/extension-call-face.js +3 -1
- package/dist/trace/ledger-events.d.ts +4 -7
- package/dist/trace/ledger-sink.d.ts +1 -30
- package/dist/trace/ledger-sink.js +0 -11
- package/dist/trace/model-segment.d.ts +5 -5
- package/dist/trace/model-segment.js +5 -5
- package/dist/trace/project.d.ts +55 -42
- package/dist/trace/project.js +52 -19
- package/dist/trace/redact.d.ts +123 -27
- package/dist/trace/redact.js +880 -260
- package/dist/trace/self-minted-wire.d.ts +487 -19
- package/dist/trace/self-minted-wire.js +172 -23
- package/dist/trace/wire-projection-faces.d.ts +5 -6
- package/dist/trace/wire-projection-faces.js +2 -2
- package/dist/upstream-body.d.ts +23 -0
- package/dist/upstream-body.js +16 -0
- package/dist/url-refusal.d.ts +3 -3
- package/dist/url-refusal.js +11 -4
- package/dist/user-authored-text.d.ts +1 -1
- package/dist/user-input-ledger.d.ts +7 -8
- package/dist/user-input-ledger.js +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +6 -3
- package/dist/web-admin-client/apply-effective.js +13 -16
- package/dist/web-admin-client/apply-ledger.d.ts +16 -7
- package/dist/web-admin-client/apply-ledger.js +5 -2
- package/dist/web-admin-client/center-request.d.ts +2 -2
- package/dist/web-admin-client/center-request.js +15 -15
- package/dist/web-admin-client/effective-keys.d.ts +1 -1
- package/dist/web-admin-client/effective-keys.js +1 -1
- package/dist/web-admin-client/entry-metadata.d.ts +8 -0
- package/dist/web-admin-client/entry-metadata.js +13 -0
- package/dist/web-admin-client/http-client.d.ts +1 -1
- package/dist/web-admin-client/http-client.js +23 -4
- package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
- package/dist/web-admin-client/mcp-revocation.js +2 -1
- package/dist/web-admin-client/read-warnings.d.ts +1 -0
- package/dist/web-admin-client/read-warnings.js +1 -0
- package/dist/web-admin-client/restart-signal.js +8 -4
- package/dist/web-admin-client/skills-mcp.d.ts +2 -2
- package/dist/web-admin-client/types.d.ts +1 -2
- package/dist/workspace-space.d.ts +3 -2
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +4 -4
- package/package.json +6 -3
- package/scripts/drain-check-local.mjs +118 -147
- package/scripts/drain-check.mysql.sql +22 -2
- package/scripts/drain-check.pg.sql +22 -2
- package/wire-changes/server@7.148.0.json +1517 -0
- package/dist/http/memory-control-plane-corrupt-reply.d.ts +0 -25
- package/dist/http/memory-control-plane-corrupt-reply.js +0 -19
- package/dist/http/memory-layer-reply.d.ts +0 -30
- package/dist/http/memory-layer-reply.js +0 -24
- package/dist/lsp/e2b-bridge.d.ts +0 -57
- package/dist/lsp/e2b-bridge.js +0 -139
- package/dist/lsp/e2b-manager.d.ts +0 -93
- package/dist/lsp/e2b-manager.js +0 -178
- package/dist/lsp/lsp-frames.d.ts +0 -14
- package/dist/lsp/lsp-frames.js +0 -25
- package/dist/lsp/manager.d.ts +0 -129
- package/dist/lsp/manager.js +0 -127
- package/dist/lsp/types.d.ts +0 -12
- package/dist/lsp/types.js +0 -2
- package/dist/lsp/ws-transport.d.ts +0 -40
- package/dist/lsp/ws-transport.js +0 -210
package/dist/http/resume-legs.js
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
import { redactErrorMessage, redactHead } from "../observability/run-terminal.js";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
|
-
import { uuidv7, resumeWithVerification, CheckpointError, judgeCheckpointRow, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY } from "@sema-agent/core";
|
|
4
|
-
import { decideParkedAgent, denyWorkflowParkForked, denyWorkflowParksUnreadable, findParkOrigin, heldWorkflowParkDecisions, planWorkflowParkedDecide } from "../parked-decide.js";
|
|
3
|
+
import { uuidv7, resumeWithVerification, resumeCascade, CheckpointError, judgeCheckpointRow, defaultTaskRegistry, taskNotificationDedupKey, validatePendingSteer, GLOBAL_USAGE_KEY } from "@sema-agent/core";
|
|
4
|
+
import { decideParkedAgent, deliverToHoldingRun, 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
7
|
import { createSessionWorkspaceRecorder, sessionWorkspaceStoreOf } from "../session-workspace.js";
|
|
8
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";
|
|
9
|
-
import { HttpError, decodeCheckpointScope, CHECKPOINT_PUBLIC_SCOPE } from "../security.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { HttpError, checkpointPartsOf, decodeCheckpointScope, scopeCellOf, CHECKPOINT_PUBLIC_SCOPE } from "../security.js";
|
|
10
|
+
import { keyAdmits } from "../owner-faces.js";
|
|
11
|
+
import { personOf } from "../owner-brands.js";
|
|
12
|
+
import { recoveredSubject } from "../owner-faces.js";
|
|
13
|
+
import { beatRunHeartbeat, graftParkToolCallId, parkToolCallId, TurnAnchorCapture, HEARTBEAT_MS, markChildrenStoppedByUserOnAbort, voidHeldParkCard } from "../runs.js";
|
|
14
|
+
import { atHostBoundary, failureCodeOf, nestedPauseOf, sealResultForExit, outwardPlane, outwardThrownMessage } from "../terminal.js";
|
|
12
15
|
import { voidVerifierPauseCard } from "../verifier-pause-card.js";
|
|
13
16
|
import { buildCancelledLedgerRow, CARD_SETTLED_BY_CANCEL_MESSAGE, createRunAbort, mintCancelledResult, withCardSettledByCancelMessage } from "../run-cancel-context.js";
|
|
14
|
-
import { isTerminalRunStatus } from "../plugins/store-contracts.js";
|
|
17
|
+
import { isTerminalRunStatus, runProvenElsewhere } from "../plugins/store-contracts.js";
|
|
15
18
|
import { readTurnActivityMs, recordTurnActivity } from "../turn-activity.js";
|
|
16
19
|
import { recordResumeResourceWindow } from "../resource-window.js";
|
|
17
20
|
import { emitPendingWorkflowCompletions, taskNotificationInboxEntry, taskNotificationStreamKeyOf, NotifiedKeys } from "../orchestration/workflow-completion-inbox.js";
|
|
18
21
|
import { fleetRunPublisher, fleetRunLabels, fleetRunResiduals } from "../fleet/fleet-bus.js";
|
|
19
22
|
import { defaultSubagentTailBus } from "../fleet/subagent-tail-bus.js";
|
|
20
23
|
import { currentApprovalGateToken, currentGateFacesOf, sightsCurrentGate } from "../approval-gate-currency.js";
|
|
21
|
-
import { approverFacingArgs,
|
|
24
|
+
import { approverFacingArgs, declaredApprovalFrameFamilies, parkRowStandingAnswerFacts, resolveApprovalLeg, resolveStreamApprovalGate, standingAnswerDurablyRecordable } from "../tool-approval.js";
|
|
25
|
+
import { createHitlTransport } from "../hitl-delivery.js";
|
|
22
26
|
import { buildCheckpointAnchorHash } from "../approval-ask-audit-store.js";
|
|
23
27
|
import { APPROVAL_ENDING_CAUSES } from "../approval-deny-reasons.js";
|
|
24
28
|
import { serviceVersion } from "../service-version.js";
|
|
25
29
|
import { TERMINAL_PARK_GATE_KINDS, UnreadableCheckpointRowError } from "../plugins/checkpoint-store-face.js";
|
|
26
|
-
import {
|
|
30
|
+
import { withSubject } from "../observability/principal-context.js";
|
|
27
31
|
import { withModelReachScope } from "../model-reach-scope.js";
|
|
28
32
|
import { legFactsOf } from "../leg-facts.js";
|
|
29
33
|
import { createInstructionSelectionLeg } from "../instruction-selection.js";
|
|
@@ -35,7 +39,7 @@ import { registerEngineNoticeLeg } from "../trace/engine-notice-wire.js";
|
|
|
35
39
|
import { blockText, reasoningDeltaBytes, reasoningSegmentEventId } from "../trace/model-segment.js";
|
|
36
40
|
import { errorText } from "../observability/err-text.js";
|
|
37
41
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
38
|
-
import {
|
|
42
|
+
import { resumeCompositionOf } from "./resume-composition.js";
|
|
39
43
|
import { planReviewDecisionExitsPlan, storedBodyPermissionMode } from "../task-settings.js";
|
|
40
44
|
import { acceptedResumingReceipt, acceptedTaskIdOf } from "./route-ctx.js";
|
|
41
45
|
import { heldFor } from "../peer-seat.js";
|
|
@@ -46,7 +50,7 @@ import { createSessionsLocal } from "./routes/sessions.js";
|
|
|
46
50
|
import { createSessionSyncLocal } from "./routes/session-sync.js";
|
|
47
51
|
import { createImagesLocal } from "./routes/images.js";
|
|
48
52
|
import { createCapabilitiesLocal } from "./routes/capabilities.js";
|
|
49
|
-
import {
|
|
53
|
+
import { gatedSubject, explicitOperatorOk, runIdentityOf } from "./principal-gate.js";
|
|
50
54
|
import { buildActiveRunConflict, resumeEntryForGate } from "./active-run-conflict.js";
|
|
51
55
|
import { commitExecutionContext, isRootSessionGoneError, resolveExecutionContext, rootSessionAbsentAnswer, stampSpecRoot } from "./execution-context.js";
|
|
52
56
|
import { timeClaim } from "./claim-latency.js";
|
|
@@ -54,7 +58,7 @@ import { commitSessionInheritEnv } from "./session-inherit-env.js";
|
|
|
54
58
|
import { ASK_USER_QUESTION_TOOL_NAME, isApprovalGateKind, isEngineQuestionRow } from "../approval-content-kind.js";
|
|
55
59
|
import { deploymentListAsks } from "../approval.js";
|
|
56
60
|
import { isParkLedgerEventType } from "../trace/ledger-events.js";
|
|
57
|
-
import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnsealableAnswer } from "./resume-ctx-read.js";
|
|
61
|
+
import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnreadableAnswer, resumeCtxUnsealableAnswer, resumeStoreReadFailureOf } from "./resume-ctx-read.js";
|
|
58
62
|
import { objectiveWithheldIn } from "./submit-ctx.js";
|
|
59
63
|
import { buildCheckpointVersionKeys, resumeAssemblyRefusalAnswer, resumeRefusalWithCard, sealCheckpointCtx, storedBodyReplayAnswer, storedBodyReplayLogFields, withPermissionModeRewritten } from "./checkpoint-ctx.js";
|
|
60
64
|
import { refusalBody, resumeRefusalFacts } from "./refusal-body.js";
|
|
@@ -62,8 +66,12 @@ import { storedBodyReplayRefusal } from "./stored-body-replay.js";
|
|
|
62
66
|
import { restateResumeCtx } from "./resume-restatement.js";
|
|
63
67
|
import { httpErrorRefusal } from "./send.js";
|
|
64
68
|
import { createRunAcceptance } from "../run-acceptance.js";
|
|
69
|
+
import { createSubmissionSeat } from "../submission-exit.js";
|
|
65
70
|
import { fieldConflictFacts } from "../field-conflict.js";
|
|
66
71
|
import { createSessionNotifyDoor } from "../session-notify-door.js";
|
|
72
|
+
function compositionUnlinkedAnswer() {
|
|
73
|
+
return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context does not match this card — the run is a cascade but the card records no ladder rung, so the ladder cannot be continued" }) };
|
|
74
|
+
}
|
|
67
75
|
function legMayHaveReopenedCheckpoint(r) {
|
|
68
76
|
return r.terminal.kind === "failed" && nestedPauseOf(r.terminal) === undefined;
|
|
69
77
|
}
|
|
@@ -213,6 +221,11 @@ function rowRefusalAnswer(verdict, diagnostic, ctx) {
|
|
|
213
221
|
const refusal = new CheckpointError(verdict.code, diagnostic === undefined ? verdict.sentence : `${verdict.sentence} Diagnostic: ${diagnostic}`, verdict.reason === undefined ? undefined : { reason: verdict.reason });
|
|
214
222
|
return checkpointRefusalAnswer(refusal, { gate: "policy_ask", retriable: resumeRefusalDisposition(refusal) === "retriable", versionKeys: refusalVersionKeys(refusal, ctx) });
|
|
215
223
|
}
|
|
224
|
+
export function rowReadRefusalAnswer(e) {
|
|
225
|
+
if (e instanceof UnreadableCheckpointRowError && e.rowVerdict.kind !== "ok")
|
|
226
|
+
return rowRefusalAnswer(e.rowVerdict, errorText(e), {});
|
|
227
|
+
return { status: 409, body: refusalBody({ errorCode: "conflict.checkpoint_unreadable", message: errorText(e) }) };
|
|
228
|
+
}
|
|
216
229
|
function refusalVersionKeys(e, ctx) {
|
|
217
230
|
return e.code === "checkpoint.unsupported_version" ? buildCheckpointVersionKeys(ctx.writerVersion, serviceVersion()) : {};
|
|
218
231
|
}
|
|
@@ -249,9 +262,9 @@ export function decidedActionOf(binding) {
|
|
|
249
262
|
return missingKeys.length === 0 ? { action: { boundCallId: boundCallId, boundInputHash: boundInputHash } } : { missingKeys };
|
|
250
263
|
}
|
|
251
264
|
export function createResumeLegs(ctx) {
|
|
252
|
-
const { deps, runnerFor, idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters, readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode,
|
|
265
|
+
const { deps, runnerFor, idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters, readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode, prepareSpec, finalizeTaskResult, ownerCostQuotaDenied, ownerFleetLeaseDenied, usageWindowDenialFor } = ctx;
|
|
253
266
|
const ctxOpening = (sessionId) => ({ sessionId, opener: deps.checkpointCtxSealing });
|
|
254
|
-
const resumeFleetScope = (req, auth) => req ? (
|
|
267
|
+
const resumeFleetScope = (req, auth) => req ? (gatedSubject(req, deps.config) ?? "default") : (auth.subject ?? "default");
|
|
255
268
|
function createRememberIntent(sessionId, remember) {
|
|
256
269
|
let pending;
|
|
257
270
|
return {
|
|
@@ -302,8 +315,7 @@ export function createResumeLegs(ctx) {
|
|
|
302
315
|
return null;
|
|
303
316
|
});
|
|
304
317
|
const curPa = cur?.pendingAction;
|
|
305
|
-
const
|
|
306
|
-
const scopeOk = cur !== null && (decider.explicitOperator || curOwner === undefined || curOwner === decider.principal);
|
|
318
|
+
const scopeOk = cur != null && (await decisionRowAdmits(cs, token, decider, cur.scope));
|
|
307
319
|
if (cur && cur.sessionId === sessionId && !scopeOk) {
|
|
308
320
|
deps.logger?.info?.("approval_decide_no_pending", { sessionId, staleTokenEchoed: true, foreignCurrentSuppressed: true });
|
|
309
321
|
return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
|
|
@@ -323,10 +335,24 @@ export function createResumeLegs(ctx) {
|
|
|
323
335
|
return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
|
|
324
336
|
}
|
|
325
337
|
const cpPromise = cs.get(token);
|
|
326
|
-
const
|
|
338
|
+
const runSessionPromise = cs.hostSessionOfCard(token).then((id) => (typeof id === "string" ? { kind: "owned", id } : { kind: "unowned" }), (e) => ({ kind: "failed", failure: resumeStoreReadFailureOf(e) }));
|
|
339
|
+
const runCtxOf = async () => {
|
|
340
|
+
const owner = await runSessionPromise;
|
|
341
|
+
if (owner.kind === "unowned")
|
|
342
|
+
return undefined;
|
|
343
|
+
const read = owner.kind === "failed" ? owner.failure : await readResumeCtx(cs.getCtx(owner.id), ctxOpening(owner.id));
|
|
344
|
+
if (read.kind === "corrupt")
|
|
345
|
+
return { refusal: resumeCtxCorruptAnswer(read.where) };
|
|
346
|
+
if (read.kind === "unsealable")
|
|
347
|
+
return { refusal: resumeCtxUnsealableAnswer(read) };
|
|
348
|
+
if (read.kind === "unreadable")
|
|
349
|
+
return { refusal: resumeCtxUnreadableAnswer() };
|
|
350
|
+
return owner.kind === "owned" ? { runSessionId: owner.id, ctx: read.kind === "ok" ? read.ctx : null } : undefined;
|
|
351
|
+
};
|
|
352
|
+
const ctxPromise = runCtxOf();
|
|
327
353
|
void ctxPromise.catch(() => { });
|
|
328
354
|
const noApproval = { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
|
|
329
|
-
const rowOwnRefusal = async (verdict
|
|
355
|
+
const rowOwnRefusal = async (verdict) => rowRefusalAnswer(verdict, undefined, verdict.code === "checkpoint.unsupported_version" ? await ctxPromise.then((r) => (r !== undefined && "ctx" in r ? (r.ctx ?? {}) : {}), () => ({})) : {});
|
|
330
356
|
let cp;
|
|
331
357
|
try {
|
|
332
358
|
cp = await cpPromise;
|
|
@@ -337,31 +363,28 @@ export function createResumeLegs(ctx) {
|
|
|
337
363
|
deps.logger?.warn?.("approval_decide_unreadable_row_withheld", { sessionId, note: "row unreadable and the caller's ownership of THAT token is unproven — folded into the uniform 404" });
|
|
338
364
|
return noApproval;
|
|
339
365
|
}
|
|
340
|
-
|
|
341
|
-
return rowOwnRefusal(e.rowVerdict, errorText(e));
|
|
342
|
-
return { status: 409, body: refusalBody({ errorCode: "conflict.checkpoint_unreadable", message: errorText(e) }) };
|
|
366
|
+
return rowReadRefusalAnswer(e);
|
|
343
367
|
}
|
|
344
368
|
if (!cp) {
|
|
345
369
|
if (!(await mayDiscloseRowError(cs, token, decider)))
|
|
346
370
|
return noApproval;
|
|
347
371
|
return { status: 404, body: refusalBody({ errorCode: "not_found.checkpoint", message: "checkpoint not found" }) };
|
|
348
372
|
}
|
|
349
|
-
if (
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
deps.logger?.warn?.("approval_decide_row_scope_mismatch", { sessionId, note: "loaded pending row is foreign to the verified caller — TOCTOU fold" });
|
|
353
|
-
return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
|
|
354
|
-
}
|
|
373
|
+
if (!(await decisionRowAdmits(cs, token, decider, cp.scope))) {
|
|
374
|
+
deps.logger?.warn?.("approval_decide_row_scope_mismatch", { sessionId, note: "loaded pending row is foreign to the verified caller — TOCTOU fold" });
|
|
375
|
+
return { status: 404, body: refusalBody({ errorCode: "not_found.approval", message: "approval not found" }) };
|
|
355
376
|
}
|
|
377
|
+
const verdict = judgeCheckpointRow(cp);
|
|
378
|
+
if (verdict.kind !== "ok")
|
|
379
|
+
return rowOwnRefusal(verdict);
|
|
356
380
|
const decideGateKind = cp.gate?.kind;
|
|
357
381
|
if (!isApprovalGateKind(decideGateKind)) {
|
|
358
|
-
const verdict = judgeCheckpointRow(cp);
|
|
359
|
-
if (verdict.kind !== "ok")
|
|
360
|
-
return rowOwnRefusal(verdict);
|
|
361
382
|
if (typeof decideGateKind !== "string" || decideGateKind === "") {
|
|
362
383
|
return { status: 409, body: refusalBody({ errorCode: "gate_not_tool_approval", message: "task is suspended on a gate whose kind this engine cannot read, so it cannot say which endpoint resolves it" }) };
|
|
363
384
|
}
|
|
364
|
-
const
|
|
385
|
+
const ownerForPath = await runSessionPromise;
|
|
386
|
+
const runSessionForPath = ownerForPath.kind === "owned" ? ownerForPath.id : undefined;
|
|
387
|
+
const activeForPath = typeof runSessionForPath === "string" ? await deps.runStore?.getActiveTaskId(runSessionForPath).catch(() => undefined) : undefined;
|
|
365
388
|
const gnPath = activeForPath ? resumeEntryForGate(decideGateKind, { sessionId, taskId: activeForPath }) : null;
|
|
366
389
|
return {
|
|
367
390
|
status: 409,
|
|
@@ -432,10 +455,10 @@ export function createResumeLegs(ctx) {
|
|
|
432
455
|
noteLateSettleIfAccepted(committed);
|
|
433
456
|
return intent === undefined ? out : { ...out, rememberApplied: await intent.settle(committed) };
|
|
434
457
|
};
|
|
435
|
-
const parkedForkQuotaDenial = req !== undefined ? ownerCostQuotaDenied(
|
|
458
|
+
const parkedForkQuotaDenial = req !== undefined ? ownerCostQuotaDenied(checkpointPartsOf(cp.scope)?.person) : undefined;
|
|
436
459
|
if (parkedForkQuotaDenial)
|
|
437
460
|
return parkedForkQuotaDenial;
|
|
438
|
-
const parkedForkLeaseDenial = req !== undefined ? await ownerFleetLeaseDenied(
|
|
461
|
+
const parkedForkLeaseDenial = req !== undefined ? await ownerFleetLeaseDenied(checkpointPartsOf(cp.scope)?.person) : undefined;
|
|
439
462
|
if (parkedForkLeaseDenial)
|
|
440
463
|
return parkedForkLeaseDenial;
|
|
441
464
|
const ownerLeaseAdmittedHere = req !== undefined;
|
|
@@ -460,19 +483,18 @@ export function createResumeLegs(ctx) {
|
|
|
460
483
|
...(boundGrant && intent ? { remember: { anchor: (rootSessionId) => boundGrant(rootSessionId), laneCannotRecord: intent.laneCannotRecord } } : {}),
|
|
461
484
|
};
|
|
462
485
|
if (origin?.kind === "background" && parkedAgentStore !== undefined && parkedSurface !== undefined) {
|
|
463
|
-
const parked = await
|
|
486
|
+
const parked = await withSubject(checkpointPartsOf(cp.scope)?.subject, () => decideParkedAgent({
|
|
464
487
|
agentStore: parkedAgentStore,
|
|
465
488
|
checkpointStore: cs,
|
|
466
489
|
registry: defaultTaskRegistry,
|
|
467
490
|
reviveSurface: parkedSurface,
|
|
468
|
-
...(deps.parkedKnownAgentTypes ? { knownAgentTypes: deps.parkedKnownAgentTypes } : {}),
|
|
469
491
|
...(deps.parkedReviveInheritedGate ? { rebuildInheritedGate: deps.parkedReviveInheritedGate } : {}),
|
|
470
492
|
...(deps.toolApproval ? { approverSeatFor: windowZeroSeatOf(deps.toolApproval) } : {}),
|
|
471
493
|
execution: {
|
|
472
494
|
resolve: async (root) => {
|
|
473
495
|
let ctx;
|
|
474
496
|
try {
|
|
475
|
-
ctx = await resolveExecutionContext(deps, { kind: "continuation", root, principal:
|
|
497
|
+
ctx = await resolveExecutionContext(deps, { kind: "continuation", root, principal: checkpointPartsOf(cp.scope)?.person });
|
|
476
498
|
}
|
|
477
499
|
catch (e) {
|
|
478
500
|
if (isRootSessionGoneError(e))
|
|
@@ -507,12 +529,15 @@ export function createResumeLegs(ctx) {
|
|
|
507
529
|
const plan = planWorkflowParkedDecide(origin, parkedReq);
|
|
508
530
|
if (!plan.ok)
|
|
509
531
|
return plan.deny;
|
|
532
|
+
const fingerprint = parkDecisionFingerprint(plan.outcome, restatement);
|
|
533
|
+
const live = await deliverToHoldingRun(origin, { token, outcome: plan.outcome, decision: parkedReq.decision, fingerprint, restated: restatement !== undefined });
|
|
534
|
+
if (live.kind === "answered")
|
|
535
|
+
return live.answer;
|
|
510
536
|
const decisions = deps.workflowParkDecisions;
|
|
511
537
|
const runStore = deps.runStore;
|
|
512
538
|
if (decisions === undefined || runStore === undefined) {
|
|
513
539
|
return { status: 501, body: refusalBody({ errorCode: "capability.run_store_required", message: "delivering this decision requires a durable run store (DB_BACKEND=mysql|pg|local)" }) };
|
|
514
540
|
}
|
|
515
|
-
const fingerprint = parkDecisionFingerprint(plan.outcome, restatement);
|
|
516
541
|
const liveReceiptOf = async (held) => {
|
|
517
542
|
if (held === null || held.fingerprint !== fingerprint)
|
|
518
543
|
return undefined;
|
|
@@ -542,7 +567,7 @@ export function createResumeLegs(ctx) {
|
|
|
542
567
|
.catch(() => undefined);
|
|
543
568
|
const admittedPayer = decodeCheckpointScope(cp.scope);
|
|
544
569
|
const out = hostToken
|
|
545
|
-
? await resumeWake(plan.hostSessionId, plan.message, decider?.
|
|
570
|
+
? await resumeWake(plan.hostSessionId, plan.message, decider?.subject, req, acceptEarly, delivery, admittedPayer, restatement)
|
|
546
571
|
: await startFreshHostTurn(plan.hostSessionId, plan.message.text, admittedPayer, req, delivery, plan.runId, restatement);
|
|
547
572
|
if (recordFailure !== undefined)
|
|
548
573
|
throw recordFailure.err;
|
|
@@ -551,16 +576,14 @@ export function createResumeLegs(ctx) {
|
|
|
551
576
|
return out;
|
|
552
577
|
}
|
|
553
578
|
}
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
556
|
-
return
|
|
557
|
-
if (
|
|
558
|
-
return resumeCtxUnsealableAnswer(ctxRead0);
|
|
559
|
-
const storedCtx = ctxRead0.kind === "ok" ? ctxRead0.ctx : null;
|
|
560
|
-
if (!storedCtx)
|
|
579
|
+
const runCtx = await ctxPromise;
|
|
580
|
+
if (runCtx !== undefined && "refusal" in runCtx)
|
|
581
|
+
return runCtx.refusal;
|
|
582
|
+
if (runCtx === undefined || runCtx.ctx === null)
|
|
561
583
|
return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) };
|
|
584
|
+
const { runSessionId, ctx: storedCtx } = runCtx;
|
|
562
585
|
const ctx = restateResumeCtx(storedCtx, restatement);
|
|
563
|
-
const auth = { sessionId:
|
|
586
|
+
const auth = { sessionId: runSessionId, subject: checkpointPartsOf(cp.scope)?.subject, memoryScope: ctx.memoryScope };
|
|
564
587
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
565
588
|
if (!resolved.ok)
|
|
566
589
|
return resolved.answer;
|
|
@@ -586,8 +609,10 @@ export function createResumeLegs(ctx) {
|
|
|
586
609
|
...(answer !== undefined ? { answer } : {}),
|
|
587
610
|
hostDecision,
|
|
588
611
|
};
|
|
589
|
-
const
|
|
590
|
-
|
|
612
|
+
const composition = resumeCompositionOf(ctx.body, cp, deps.config.cascadeLadder);
|
|
613
|
+
if (composition?.entry === "cascade_unlinked")
|
|
614
|
+
return compositionUnlinkedAnswer();
|
|
615
|
+
const driven = await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: resolved.runner, legFacts: resolved.legFacts, token, sessionId: runSessionId, subject: auth.subject, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome, commitment: { kind: "gate_resolved", ...captureSelectedGate() }, composition, resumeCtx: { sessionId: runSessionId, ctx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(boundGrant ? { onResumeCommitted: boundGrant } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}), ...(ownerLeaseAdmittedHere ? { ownerLeaseAdmitted: true } : {}) });
|
|
591
616
|
return await landAfterCommit(driven);
|
|
592
617
|
}
|
|
593
618
|
finally {
|
|
@@ -598,7 +623,7 @@ export function createResumeLegs(ctx) {
|
|
|
598
623
|
const ONE_SHOT_SUBMIT_STRIP = Object.fromEntries(ONE_SHOT_SUBMIT_KEYS.map((k) => [k, undefined]));
|
|
599
624
|
const resolveResumeSpec = async (ctx, req, auth, lease) => {
|
|
600
625
|
const engineNotices = [];
|
|
601
|
-
const execution = await resolveExecutionContext(deps, { kind: "continuation", root: auth.sessionId, principal: auth.
|
|
626
|
+
const execution = await resolveExecutionContext(deps, { kind: "continuation", root: auth.sessionId, principal: auth.subject === undefined ? undefined : personOf(recoveredSubject(auth.subject)) });
|
|
602
627
|
const resolved = await deps.resolveSpec({ ...ctx.body, ...ONE_SHOT_SUBMIT_STRIP }, req, auth, {
|
|
603
628
|
leg: "resume",
|
|
604
629
|
onNotice: (n) => engineNotices.push(n),
|
|
@@ -608,7 +633,7 @@ export function createResumeLegs(ctx) {
|
|
|
608
633
|
});
|
|
609
634
|
const legFacts = legFactsOf(resolved);
|
|
610
635
|
const runner = runnerFor(resolved);
|
|
611
|
-
const spec = stampSpecRoot(resolved, execution);
|
|
636
|
+
const spec = stampSpecRoot(resolved, execution, ctx.body);
|
|
612
637
|
return { spec, runner, legFacts, engineNotices, execution };
|
|
613
638
|
};
|
|
614
639
|
const refuseStoredBodyReplay = (sessionId, refusal) => {
|
|
@@ -654,13 +679,22 @@ export function createResumeLegs(ctx) {
|
|
|
654
679
|
}
|
|
655
680
|
async function driveResumeLeg(args, onAccepted) {
|
|
656
681
|
const resumeLegStartedAt = Date.now();
|
|
657
|
-
const { runner: legRunner, token, sessionId,
|
|
682
|
+
const { runner: legRunner, token, sessionId, subject, fleetScope, taskConfig, resumeObjective, outcome, composition, resumeCtx, execution } = args;
|
|
683
|
+
const legSubject = recoveredSubject(subject);
|
|
684
|
+
const payer = legSubject === undefined ? undefined : personOf(legSubject);
|
|
658
685
|
const heldObjective = objectiveWithheldIn(resumeCtx.ctx) ? undefined : resumeObjective;
|
|
659
686
|
const reparkStatus = outcome.gate === "plan_review" ? "needs_review" : "suspended";
|
|
660
|
-
const
|
|
687
|
+
const resumeCtxNotPersisted = (why) => {
|
|
661
688
|
deps.metrics?.inc("resume_ctx_not_persisted_total");
|
|
662
|
-
deps.logger?.warn?.("resume_ctx_not_persisted", { sessionId: resumeCtx.sessionId, gate: outcome.gate, error:
|
|
663
|
-
}
|
|
689
|
+
deps.logger?.warn?.("resume_ctx_not_persisted", { sessionId: resumeCtx.sessionId, gate: outcome.gate, error: why, note: "this continuation runs with the body it was given; the durable rebuild input still holds the PREVIOUS body, so the NEXT continuation of this session rebuilds from that one — its permission mode is never wider than this leg's, but if this leg restated its MCP / A2A peer tables (mcpServers / a2aPeers on the resume request), a later continuation that does not restate them runs with the previous tables again" });
|
|
690
|
+
};
|
|
691
|
+
const commitResumeCtx = () => Promise.resolve().then(async () => {
|
|
692
|
+
const sealed = sealCheckpointCtx({ ...resumeCtx.ctx, writerVersion: serviceVersion() }, deps.checkpointCtxSealing, resumeCtx.sessionId);
|
|
693
|
+
const claim = claimedRow && taskId !== undefined && deps.runStore !== undefined ? { fence: deps.runStore, taskId, legHolds: (run) => !runProvenElsewhere(run, deps.instanceId) } : undefined;
|
|
694
|
+
const landed = await deps.checkpointStore.putCtx(resumeCtx.sessionId, sealed, claim);
|
|
695
|
+
if (landed === "claim_released")
|
|
696
|
+
resumeCtxNotPersisted("claim_released: this run no longer holds the session claim (settled or reaped before the write-back landed) — nothing written");
|
|
697
|
+
}).catch((e) => resumeCtxNotPersisted(errorText(e)));
|
|
664
698
|
const legKey = createHash("sha256").update(String(token)).digest("hex");
|
|
665
699
|
const streamApprovalOn = resolveStreamApprovalGate({
|
|
666
700
|
toolApprovalEnabled: Boolean(deps.toolApproval),
|
|
@@ -677,21 +711,21 @@ export function createResumeLegs(ctx) {
|
|
|
677
711
|
declaredFamilies: declaredApprovalFrameFamilies(resumeCtx.ctx.body.settings),
|
|
678
712
|
});
|
|
679
713
|
const legDeadlineMonotonic = approvalLeg.legDeadlineMonotonic;
|
|
680
|
-
const ownerQuotaDenial = args.callerInitiated === true ? ownerCostQuotaDenied(
|
|
714
|
+
const ownerQuotaDenial = args.callerInitiated === true ? ownerCostQuotaDenied(payer) : undefined;
|
|
681
715
|
if (ownerQuotaDenial)
|
|
682
716
|
return ownerQuotaDenial;
|
|
683
|
-
const ownerLeaseDenial = args.callerInitiated === true && args.ownerLeaseAdmitted !== true ? await ownerFleetLeaseDenied(
|
|
717
|
+
const ownerLeaseDenial = args.callerInitiated === true && args.ownerLeaseAdmitted !== true ? await ownerFleetLeaseDenied(payer) : undefined;
|
|
684
718
|
if (ownerLeaseDenial)
|
|
685
719
|
return ownerLeaseDenial;
|
|
686
720
|
const heldDecisions = await heldWorkflowParkDecisions(deps, sessionId, args.workflowDecision?.carried);
|
|
687
721
|
let taskId = await deps.runStore?.getActiveTaskId(sessionId);
|
|
688
722
|
let freshRunClaimed = false;
|
|
689
723
|
if (args.mintFreshRun && taskId && deps.runStore) {
|
|
690
|
-
return { status: 409, body: await buildActiveRunConflict({ runStore: deps.runStore, checkpointStore: deps.checkpointStore, governance: deps.config,
|
|
724
|
+
return { status: 409, body: await buildActiveRunConflict({ runStore: deps.runStore, checkpointStore: deps.checkpointStore, governance: deps.config, turnActivity: readTurnActivityMs }, sessionId, taskId) };
|
|
691
725
|
}
|
|
692
726
|
if (!taskId && args.mintFreshRun && deps.runStore) {
|
|
693
727
|
const freshId = uuidv7();
|
|
694
|
-
const created = await timeClaim(deps.metrics, "run_claim", deps.runStore.createRun(freshId, sessionId,
|
|
728
|
+
const created = await timeClaim(deps.metrics, "run_claim", deps.runStore.createRun(freshId, sessionId, subject ?? null, deps.instanceId ?? "default", {
|
|
695
729
|
source: args.mintFreshRun.source,
|
|
696
730
|
identity: args.mintFreshRun.identity,
|
|
697
731
|
objectivePreview: heldObjective === undefined ? null : buildRunObjectivePreview(heldObjective),
|
|
@@ -702,7 +736,7 @@ export function createResumeLegs(ctx) {
|
|
|
702
736
|
if (created.sessionAbsent)
|
|
703
737
|
return rootSessionAbsentAnswer();
|
|
704
738
|
if (!created.ok) {
|
|
705
|
-
return { status: 409, body: await buildActiveRunConflict({ runStore: deps.runStore, checkpointStore: deps.checkpointStore, governance: deps.config,
|
|
739
|
+
return { status: 409, body: await buildActiveRunConflict({ runStore: deps.runStore, checkpointStore: deps.checkpointStore, governance: deps.config, turnActivity: readTurnActivityMs }, sessionId, created.activeTaskId) };
|
|
706
740
|
}
|
|
707
741
|
const placementReject = await commitExecutionContext(deps, { kind: "run", runStore: deps.runStore, taskId: freshId }, execution);
|
|
708
742
|
if (placementReject)
|
|
@@ -717,9 +751,9 @@ export function createResumeLegs(ctx) {
|
|
|
717
751
|
if (deps.toolApproval && taskId) {
|
|
718
752
|
const toolApproval = deps.toolApproval;
|
|
719
753
|
resumeTaskConfig.onAsk = approvalLeg.unattended
|
|
720
|
-
? toolApproval.boundUnattendedAsk({ owner:
|
|
754
|
+
? toolApproval.boundUnattendedAsk({ owner: subject ?? null, taskId, sessionId, executionLane: execution.lane }, approvalLeg.unattended)
|
|
721
755
|
: toolApproval.boundAsk({
|
|
722
|
-
owner:
|
|
756
|
+
owner: subject ?? null,
|
|
723
757
|
taskId,
|
|
724
758
|
sessionId,
|
|
725
759
|
executionLane: execution.lane,
|
|
@@ -751,6 +785,8 @@ export function createResumeLegs(ctx) {
|
|
|
751
785
|
}
|
|
752
786
|
};
|
|
753
787
|
const settleCardForCancel = async () => {
|
|
788
|
+
if (freshRunClaimed)
|
|
789
|
+
return false;
|
|
754
790
|
const cs2 = deps.checkpointStore;
|
|
755
791
|
if (!cs2)
|
|
756
792
|
return false;
|
|
@@ -786,7 +822,7 @@ export function createResumeLegs(ctx) {
|
|
|
786
822
|
let resumeLegLive = false;
|
|
787
823
|
const subagentHandleEvictions = [];
|
|
788
824
|
let claimedRow = false;
|
|
789
|
-
const cancelCtrl = createRunAbort(
|
|
825
|
+
const cancelCtrl = createRunAbort(subject ?? null);
|
|
790
826
|
let cancelLedgerAppend;
|
|
791
827
|
const preemptCtrl = new AbortController();
|
|
792
828
|
if (taskId && deps.runStore) {
|
|
@@ -798,14 +834,14 @@ export function createResumeLegs(ctx) {
|
|
|
798
834
|
if (placementReject)
|
|
799
835
|
return placementReject;
|
|
800
836
|
}
|
|
801
|
-
markChildrenStoppedByUserOnAbort(cancelCtrl.signal, taskId,
|
|
837
|
+
markChildrenStoppedByUserOnAbort(cancelCtrl.signal, taskId, subject);
|
|
802
838
|
fleetPub?.onStart();
|
|
803
839
|
const rs = deps.runStore;
|
|
804
|
-
const owner =
|
|
840
|
+
const owner = subject ?? null;
|
|
805
841
|
inflightRuns.set(taskId, cancelCtrl);
|
|
806
842
|
preemptableRuns.set(taskId, preemptCtrl);
|
|
807
843
|
resumeHeartbeat = setInterval(() => {
|
|
808
|
-
|
|
844
|
+
beatRunHeartbeat(rs, taskId, owner, () => cancelCtrl.abort("stall_verdict"), () => undefined);
|
|
809
845
|
if (!cancelCtrl.signal.aborted) {
|
|
810
846
|
void rs.isCancelRequested(taskId, owner).then((c) => { if (c)
|
|
811
847
|
cancelCtrl.abort("cancel_verb"); }).catch(() => undefined);
|
|
@@ -834,12 +870,12 @@ export function createResumeLegs(ctx) {
|
|
|
834
870
|
try {
|
|
835
871
|
const instructionLeg = createInstructionSelectionLeg();
|
|
836
872
|
const legWiringSections = () => ({ instructions: instructionLeg.segment(), skills: args.legFacts?.skills });
|
|
837
|
-
result = await instructionLeg.run(sessionId, () => withModelReachScope({ sessionId, taskId }, () =>
|
|
873
|
+
result = await instructionLeg.run(sessionId, () => withModelReachScope({ sessionId, taskId }, () => withSubject(legSubject, async () => {
|
|
838
874
|
const resumeNotifiedKeys = new NotifiedKeys();
|
|
839
875
|
if (deps.runStore && taskId) {
|
|
840
876
|
const rs0 = deps.runStore;
|
|
841
877
|
let drainSeq = (await rs0.maxSeq(taskId)) + 1;
|
|
842
|
-
await emitPendingWorkflowCompletions(deps.workflowCompletionInbox, sessionId,
|
|
878
|
+
await emitPendingWorkflowCompletions(deps.workflowCompletionInbox, sessionId, subject ?? null, (frame) => {
|
|
843
879
|
const { type, ...rest } = frame;
|
|
844
880
|
const f = frame;
|
|
845
881
|
const write = rs0.appendEvent(taskId, drainSeq++, type, rest);
|
|
@@ -849,7 +885,7 @@ export function createResumeLegs(ctx) {
|
|
|
849
885
|
return write;
|
|
850
886
|
}, { route: "resume-open", connection: "durable-append", log: (m, x) => deps.logger?.info?.(m, x) });
|
|
851
887
|
}
|
|
852
|
-
if (
|
|
888
|
+
if (composition !== undefined) {
|
|
853
889
|
const rsV = deps.runStore;
|
|
854
890
|
const vSeqBase = rsV && taskId ? await rsV.maxSeq(taskId) : 0;
|
|
855
891
|
const verifySink = createLedgerSink({
|
|
@@ -891,7 +927,7 @@ export function createResumeLegs(ctx) {
|
|
|
891
927
|
const parked = !resumeLegLive && Boolean(deps.workflowCompletionInbox && sessionId);
|
|
892
928
|
deps.logger?.info?.("task_notification_observed", { route: "resume-verify", taskId: n.task_id, taskType: n.task_type, status: n.status, legLive: resumeLegLive, parkedDurable: parked });
|
|
893
929
|
if (parked) {
|
|
894
|
-
void deps.workflowCompletionInbox.enqueue(taskNotificationInboxEntry(sessionId,
|
|
930
|
+
void deps.workflowCompletionInbox.enqueue(taskNotificationInboxEntry(sessionId, subject ?? null, n, Date.now(), taskId, opts?.priority)).catch((err) => deps.logger?.warn?.("park_enqueue_failed", { route: "resume-verify", taskId: n.task_id, err: err instanceof Error ? err.message : String(err) }));
|
|
895
931
|
}
|
|
896
932
|
else if (resumeLegLive) {
|
|
897
933
|
const key = taskNotificationDedupKey(n);
|
|
@@ -909,10 +945,23 @@ export function createResumeLegs(ctx) {
|
|
|
909
945
|
: {}),
|
|
910
946
|
};
|
|
911
947
|
resumeLegLive = true;
|
|
912
|
-
const
|
|
948
|
+
const legSpec = { ...resumeTaskConfig, signal: cancelCtrl.signal, preemptSignal: preemptCtrl.signal };
|
|
949
|
+
let vrEngine;
|
|
950
|
+
switch (composition.entry) {
|
|
951
|
+
case "verify":
|
|
952
|
+
vrEngine = await resumeWithVerification(legRunner, token, outcome, legSpec, resumeObjective, composition.rounds, verifyInternals);
|
|
953
|
+
break;
|
|
954
|
+
case "cascade":
|
|
955
|
+
vrEngine = await resumeCascade(legRunner, token, outcome, stampSpecRoot({ ...legSpec, ...composition.objectiveInputs, objective: resumeObjective }, execution, resumeCtx.ctx.body), composition.config, composition.parkedLeg, verifyInternals);
|
|
956
|
+
break;
|
|
957
|
+
default: {
|
|
958
|
+
const unhandled = composition;
|
|
959
|
+
throw new Error(`unhandled resume composition: ${JSON.stringify(unhandled)}`);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
913
962
|
const vrCause = cancelCtrl.cause();
|
|
914
963
|
await voidVerifierPauseCard(vrEngine, legRunner);
|
|
915
|
-
const vrJudged = atHostBoundary(vrEngine
|
|
964
|
+
const vrJudged = atHostBoundary(vrEngine);
|
|
916
965
|
if (vrJudged.terminal.kind === "paused")
|
|
917
966
|
heldPark = vrJudged;
|
|
918
967
|
const vrMinted = vrCause !== undefined && taskId !== undefined ? mintCancelledResult({ taskId, sessionId, startedAtMs: resumeLegStartedAt, message: "cancelled by user", engineResult: vrJudged, cause: vrCause }) : vrJudged;
|
|
@@ -971,7 +1020,7 @@ export function createResumeLegs(ctx) {
|
|
|
971
1020
|
});
|
|
972
1021
|
if (deps.userInputLedger && taskId)
|
|
973
1022
|
await deps.userInputLedger.announceUndrained({ sessionId, taskId });
|
|
974
|
-
const anchorOwner =
|
|
1023
|
+
const anchorOwner = subject ?? null;
|
|
975
1024
|
const headOf = headReadOf(deps.sessionStorage);
|
|
976
1025
|
const captureTurnAnchor = deps.resumeAnchorStore && headOf
|
|
977
1026
|
? async (eventId) => { const leaf = (await headOf(sessionId))?.leafId; if (leaf)
|
|
@@ -1037,7 +1086,7 @@ export function createResumeLegs(ctx) {
|
|
|
1037
1086
|
const parked = !resumeLegLive && Boolean(deps.workflowCompletionInbox && sessionId);
|
|
1038
1087
|
deps.logger?.info?.("task_notification_observed", { route: "resume", taskId: n.task_id, taskType: n.task_type, status: n.status, legLive: resumeLegLive, parkedDurable: parked });
|
|
1039
1088
|
if (parked) {
|
|
1040
|
-
void deps.workflowCompletionInbox.enqueue(taskNotificationInboxEntry(sessionId,
|
|
1089
|
+
void deps.workflowCompletionInbox.enqueue(taskNotificationInboxEntry(sessionId, subject ?? null, n, Date.now(), taskId, opts?.priority)).catch((err) => deps.logger?.warn?.("park_enqueue_failed", { route: "resume", taskId: n.task_id, err: err instanceof Error ? err.message : String(err) }));
|
|
1041
1090
|
}
|
|
1042
1091
|
else if (resumeLegLive) {
|
|
1043
1092
|
const key = taskNotificationDedupKey(n);
|
|
@@ -1227,25 +1276,22 @@ export function createResumeLegs(ctx) {
|
|
|
1227
1276
|
}
|
|
1228
1277
|
return safe;
|
|
1229
1278
|
};
|
|
1230
|
-
const
|
|
1231
|
-
const { type, ...rest } = frame;
|
|
1232
|
-
return append(type, rest);
|
|
1233
|
-
};
|
|
1279
|
+
const hitlTransport = createHitlTransport({ ledger: append });
|
|
1234
1280
|
const withApproval = () => deps.toolApproval && taskId && approvalLeg.active && approvalLeg.unattended === undefined
|
|
1235
1281
|
? deps.toolApproval.runWithContext({
|
|
1236
1282
|
taskId,
|
|
1237
|
-
owner:
|
|
1283
|
+
owner: subject ?? null,
|
|
1238
1284
|
abortSignal: cancelCtrl.signal,
|
|
1239
1285
|
sessionId,
|
|
1240
1286
|
executionLane: execution.lane,
|
|
1241
|
-
|
|
1242
|
-
|
|
1287
|
+
family: "approval_request",
|
|
1288
|
+
transport: hitlTransport,
|
|
1243
1289
|
legKey,
|
|
1244
1290
|
...(legDeadlineMonotonic !== undefined ? { legDeadlineMonotonic } : {}),
|
|
1245
1291
|
}, driveResume)
|
|
1246
1292
|
: driveResume();
|
|
1247
1293
|
const withElicitation = () => deps.elicitation && taskId
|
|
1248
|
-
? deps.elicitation.runWithContext({ taskId, owner:
|
|
1294
|
+
? deps.elicitation.runWithContext({ taskId, owner: subject ?? null, transport: hitlTransport, abortSignal: cancelCtrl.signal }, withApproval)
|
|
1249
1295
|
: withApproval();
|
|
1250
1296
|
return await (deps.sendUserFile && taskId
|
|
1251
1297
|
? deps.sendUserFile.runWithContext({ taskId, emit: async (frame) => { const { type, ...rest } = frame; await append(type, rest); } }, withElicitation)
|
|
@@ -1301,7 +1347,7 @@ export function createResumeLegs(ctx) {
|
|
|
1301
1347
|
}
|
|
1302
1348
|
if (claimedRow && taskId && deps.runStore) {
|
|
1303
1349
|
await voidHeldParkCard(heldPark, sessionId, deps.checkpointStore, "resume");
|
|
1304
|
-
await deps.runStore.setTerminal(taskId, "failed", null, errorText(e)).catch(() => undefined);
|
|
1350
|
+
await deps.runStore.setTerminal(taskId, "failed", null, outwardThrownMessage(e, errorText(e))).catch(() => undefined);
|
|
1305
1351
|
}
|
|
1306
1352
|
settleFleet("failed");
|
|
1307
1353
|
throw e;
|
|
@@ -1339,7 +1385,7 @@ export function createResumeLegs(ctx) {
|
|
|
1339
1385
|
else
|
|
1340
1386
|
await deps.runStore.setTerminal(taskId, resumePlane.status, sealed, resumePlane.errorMessage ?? null);
|
|
1341
1387
|
}
|
|
1342
|
-
settleFleet(checkpointReopened ? reparkStatus : resumePlane.status, fleetRunResiduals(sealed));
|
|
1388
|
+
settleFleet(checkpointReopened ? reparkStatus : resumePlane.status, fleetRunResiduals(sealed, sealed ? failureCodeOf(sealed.terminal) : undefined));
|
|
1343
1389
|
return {
|
|
1344
1390
|
status: 200,
|
|
1345
1391
|
body: {
|
|
@@ -1353,7 +1399,7 @@ export function createResumeLegs(ctx) {
|
|
|
1353
1399
|
};
|
|
1354
1400
|
}
|
|
1355
1401
|
async function mayDiscloseRowError(cs, token, decider) {
|
|
1356
|
-
if (decider === undefined || decider.
|
|
1402
|
+
if (decider === undefined || decider.operator)
|
|
1357
1403
|
return true;
|
|
1358
1404
|
let scope;
|
|
1359
1405
|
try {
|
|
@@ -1365,24 +1411,28 @@ export function createResumeLegs(ctx) {
|
|
|
1365
1411
|
}
|
|
1366
1412
|
if (scope === undefined)
|
|
1367
1413
|
return false;
|
|
1368
|
-
|
|
1369
|
-
|
|
1414
|
+
return keyAdmits("scope.decide", decider, scopeCellOf(scope ?? CHECKPOINT_PUBLIC_SCOPE));
|
|
1415
|
+
}
|
|
1416
|
+
async function decisionRowAdmits(cs, token, who, bodyScope) {
|
|
1417
|
+
if (who === undefined)
|
|
1418
|
+
return true;
|
|
1419
|
+
const cell = bodyScope === undefined ? undefined : scopeCellOf(bodyScope);
|
|
1420
|
+
return cell !== undefined ? keyAdmits("scope.decide", who, cell) : mayDiscloseRowError(cs, token, who);
|
|
1370
1421
|
}
|
|
1371
1422
|
async function resumePreempted(sessionId, req, acceptEarly, decider, restatement) {
|
|
1372
1423
|
const cs = deps.checkpointStore;
|
|
1373
1424
|
const RESUMABLE_GATE_KIND = "resource_limit";
|
|
1374
|
-
const preemptBinding = { gateKinds: [RESUMABLE_GATE_KIND] };
|
|
1375
|
-
const token = (await cs.findPendingTokenBySession(sessionId, undefined, preemptBinding)) ?? (await cs.findPendingTokenBySession(sessionId));
|
|
1425
|
+
const preemptBinding = { gateKinds: [RESUMABLE_GATE_KIND], axis: "run" };
|
|
1426
|
+
const token = (await cs.findPendingTokenBySession(sessionId, undefined, preemptBinding)) ?? (await cs.findPendingTokenBySession(sessionId, undefined, { axis: "run" }));
|
|
1376
1427
|
const noSuspension = { status: 404, body: refusalBody({ errorCode: "not_found.suspension", message: "no resumable suspension for this task (already running, resumed, or expired)" }) };
|
|
1377
1428
|
if (!token)
|
|
1378
1429
|
return noSuspension;
|
|
1379
|
-
if (decider !== undefined && !decider.
|
|
1430
|
+
if (decider !== undefined && !decider.operator) {
|
|
1380
1431
|
const peeked = await cs
|
|
1381
1432
|
.peekPendingScope(sessionId, preemptBinding)
|
|
1382
|
-
.then((sc) => (sc === undefined ? cs.peekPendingScope(sessionId) : sc))
|
|
1433
|
+
.then((sc) => (sc === undefined ? cs.peekPendingScope(sessionId, { axis: "run" }) : sc))
|
|
1383
1434
|
.catch(() => undefined);
|
|
1384
|
-
|
|
1385
|
-
if (peekedOwner !== undefined && peekedOwner !== decider.principal) {
|
|
1435
|
+
if (!keyAdmits("scope.decide", decider, scopeCellOf(peeked ?? CHECKPOINT_PUBLIC_SCOPE))) {
|
|
1386
1436
|
deps.logger?.warn?.("assistant_resume_row_scope_mismatch", { sessionId, note: "pending row is foreign to the verified caller — owner gate ahead of the row load" });
|
|
1387
1437
|
return noSuspension;
|
|
1388
1438
|
}
|
|
@@ -1396,14 +1446,14 @@ export function createResumeLegs(ctx) {
|
|
|
1396
1446
|
deps.logger?.warn?.("assistant_resume_unreadable_row_withheld", { sessionId, note: "row unreadable and the caller's ownership of THAT token is unproven — folded into the uniform 404" });
|
|
1397
1447
|
return noSuspension;
|
|
1398
1448
|
}
|
|
1399
|
-
return
|
|
1449
|
+
return rowReadRefusalAnswer(e);
|
|
1400
1450
|
}
|
|
1401
1451
|
if (!cp) {
|
|
1402
1452
|
if (!(await mayDiscloseRowError(cs, token, decider)))
|
|
1403
1453
|
return noSuspension;
|
|
1404
1454
|
return { status: 404, body: refusalBody({ errorCode: "not_found.checkpoint", message: "checkpoint not found" }) };
|
|
1405
1455
|
}
|
|
1406
|
-
if (decider !== undefined && !
|
|
1456
|
+
if (decider !== undefined && !keyAdmits("scope.decide", decider, scopeCellOf(cp.scope))) {
|
|
1407
1457
|
deps.logger?.warn?.("assistant_resume_row_scope_mismatch", { sessionId, note: "loaded pending row is foreign to the verified caller — TOCTOU fold" });
|
|
1408
1458
|
return noSuspension;
|
|
1409
1459
|
}
|
|
@@ -1416,25 +1466,29 @@ export function createResumeLegs(ctx) {
|
|
|
1416
1466
|
return resumeCtxCorruptAnswer(ctxRead.where);
|
|
1417
1467
|
if (ctxRead.kind === "unsealable")
|
|
1418
1468
|
return resumeCtxUnsealableAnswer(ctxRead);
|
|
1469
|
+
if (ctxRead.kind === "unreadable")
|
|
1470
|
+
return resumeCtxUnreadableAnswer();
|
|
1419
1471
|
if (ctxRead.kind === "absent")
|
|
1420
1472
|
return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) };
|
|
1421
1473
|
const ctx = restateResumeCtx(ctxRead.ctx, restatement);
|
|
1422
|
-
const auth = { sessionId
|
|
1474
|
+
const auth = { sessionId, subject: checkpointPartsOf(cp.scope)?.subject, memoryScope: ctx.memoryScope };
|
|
1423
1475
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
1424
1476
|
if (!resolved.ok)
|
|
1425
1477
|
return resolved.answer;
|
|
1426
1478
|
try {
|
|
1427
1479
|
const { spec, engineNotices } = resolved;
|
|
1428
1480
|
const { objective: resumeObjective, sessionId: _sessionId, ...taskConfig } = spec;
|
|
1429
|
-
const
|
|
1481
|
+
const composition = resumeCompositionOf(ctx.body, cp, deps.config.cascadeLadder);
|
|
1482
|
+
if (composition?.entry === "cascade_unlinked")
|
|
1483
|
+
return compositionUnlinkedAnswer();
|
|
1430
1484
|
const selectedGate = durableRowIdentity("decision-receipt", cp.checkpointId, token);
|
|
1431
|
-
return await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: resolved.runner, legFacts: resolved.legFacts, token, sessionId
|
|
1485
|
+
return await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: resolved.runner, legFacts: resolved.legFacts, token, sessionId, subject: auth.subject, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome: { gate: "resource_limit", decision: "continue" }, commitment: { kind: "gate_resolved", ...selectedGate }, composition, resumeCtx: { sessionId, ctx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}) });
|
|
1432
1486
|
}
|
|
1433
1487
|
finally {
|
|
1434
1488
|
resolved.peerLease.release();
|
|
1435
1489
|
}
|
|
1436
1490
|
}
|
|
1437
|
-
async function startFreshHostTurn(sessionId, objective,
|
|
1491
|
+
async function startFreshHostTurn(sessionId, objective, subject, req, workflowDecision, runId, restatement) {
|
|
1438
1492
|
const cs = deps.checkpointStore;
|
|
1439
1493
|
if (!deps.runStore) {
|
|
1440
1494
|
return { status: 501, body: refusalBody({ errorCode: "capability.run_store_required", message: "delivering this decision requires a durable run store (DB_BACKEND=mysql|pg|local)" }) };
|
|
@@ -1444,6 +1498,8 @@ export function createResumeLegs(ctx) {
|
|
|
1444
1498
|
return resumeCtxCorruptAnswer(ctxRead.where);
|
|
1445
1499
|
if (ctxRead.kind === "unsealable")
|
|
1446
1500
|
return resumeCtxUnsealableAnswer(ctxRead);
|
|
1501
|
+
if (ctxRead.kind === "unreadable")
|
|
1502
|
+
return resumeCtxUnreadableAnswer();
|
|
1447
1503
|
const storedCtx = ctxRead.kind === "ok" ? ctxRead.ctx : null;
|
|
1448
1504
|
if (!storedCtx) {
|
|
1449
1505
|
return {
|
|
@@ -1459,10 +1515,10 @@ export function createResumeLegs(ctx) {
|
|
|
1459
1515
|
};
|
|
1460
1516
|
}
|
|
1461
1517
|
const ctx = restateResumeCtx(storedCtx, restatement);
|
|
1462
|
-
const windowDenial = await usageWindowDenialFor(
|
|
1518
|
+
const windowDenial = await usageWindowDenialFor(subject === undefined ? undefined : personOf(recoveredSubject(subject)));
|
|
1463
1519
|
if (windowDenial)
|
|
1464
1520
|
return { status: windowDenial.status, body: windowDenial.body };
|
|
1465
|
-
const auth = { sessionId,
|
|
1521
|
+
const auth = { sessionId, subject, memoryScope: ctx.memoryScope };
|
|
1466
1522
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
1467
1523
|
if (!resolved.ok)
|
|
1468
1524
|
return resolved.answer;
|
|
@@ -1470,11 +1526,11 @@ export function createResumeLegs(ctx) {
|
|
|
1470
1526
|
const { spec, engineNotices } = resolved;
|
|
1471
1527
|
const hostSpec = { ...spec, objective };
|
|
1472
1528
|
const out = await mintAndDriveDurableRun(routeCtxBase, deps.runStore, {
|
|
1473
|
-
prepared: { spec: hostSpec, runner: resolved.runner, legFacts: resolved.legFacts, auth, body: ctx.body, ...(objectiveWithheldIn(ctx) ? { bodyFromScreenedCtx: true } : {}), acceptance: createRunAcceptance({}, { objective, screened: false }), peerLease: resolved.peerLease, execution: resolved.execution, ...(engineNotices.length > 0 ? { engineNotices } : {}) },
|
|
1529
|
+
prepared: { spec: hostSpec, runner: resolved.runner, legFacts: resolved.legFacts, auth, body: ctx.body, ...(objectiveWithheldIn(ctx) ? { bodyFromScreenedCtx: true } : {}), seat: createSubmissionSeat({ deployment: deps.config }), acceptance: createRunAcceptance({}, { objective, screened: false }), peerLease: resolved.peerLease, execution: resolved.execution, ...(engineNotices.length > 0 ? { engineNotices } : {}) },
|
|
1474
1530
|
fleetScope: resumeFleetScope(req, auth),
|
|
1475
|
-
elicitOwner:
|
|
1531
|
+
elicitOwner: subject ?? null,
|
|
1476
1532
|
source: "workflow_parked_decide",
|
|
1477
|
-
identity: runIdentityOf(req, deps.config,
|
|
1533
|
+
identity: runIdentityOf(req, deps.config, subject ?? null),
|
|
1478
1534
|
workflowDecision,
|
|
1479
1535
|
});
|
|
1480
1536
|
if (out.existing) {
|
|
@@ -1495,11 +1551,10 @@ export function createResumeLegs(ctx) {
|
|
|
1495
1551
|
const token = (await cs.findPendingTokenBySession(sessionId, undefined, wakeBinding)) ?? (await cs.findPendingTokenBySession(sessionId));
|
|
1496
1552
|
if (!token)
|
|
1497
1553
|
return { status: 404, body: refusalBody({ errorCode: "not_found.parked_checkpoint", message: "no parked checkpoint for this session (nothing to wake)" }) };
|
|
1498
|
-
const
|
|
1499
|
-
if (!operator) {
|
|
1554
|
+
const who = { subject: caller, operator: explicitOperatorOk(caller === undefined ? undefined : personOf(caller), deps.config) };
|
|
1555
|
+
if (!who.operator) {
|
|
1500
1556
|
const scope = await cs.peekPendingScope(sessionId, wakeBinding).then((s) => (s === undefined ? cs.peekPendingScope(sessionId) : s)).catch(() => undefined);
|
|
1501
|
-
|
|
1502
|
-
if (decodedScope !== undefined && decodedScope !== caller) {
|
|
1557
|
+
if (!keyAdmits("scope.decide", who, scopeCellOf(scope ?? CHECKPOINT_PUBLIC_SCOPE))) {
|
|
1503
1558
|
return { status: 404, body: refusalBody({ errorCode: "not_found.parked_checkpoint", message: "no parked checkpoint for this session (nothing to wake)" }) };
|
|
1504
1559
|
}
|
|
1505
1560
|
}
|
|
@@ -1508,19 +1563,19 @@ export function createResumeLegs(ctx) {
|
|
|
1508
1563
|
cp = await cs.get(token);
|
|
1509
1564
|
}
|
|
1510
1565
|
catch (e) {
|
|
1511
|
-
if (!(await mayDiscloseRowError(cs, token,
|
|
1566
|
+
if (!(await mayDiscloseRowError(cs, token, who))) {
|
|
1512
1567
|
deps.logger?.warn?.("wake_unreadable_row_withheld", { sessionId, note: "row unreadable and the caller's ownership of THAT token is unproven — folded into the uniform 404" });
|
|
1513
1568
|
return { status: 404, body: refusalBody({ errorCode: "not_found.parked_checkpoint", message: "no parked checkpoint for this session (nothing to wake)" }) };
|
|
1514
1569
|
}
|
|
1515
|
-
return
|
|
1570
|
+
return rowReadRefusalAnswer(e);
|
|
1516
1571
|
}
|
|
1517
1572
|
if (!cp) {
|
|
1518
|
-
if (!(await mayDiscloseRowError(cs, token,
|
|
1573
|
+
if (!(await mayDiscloseRowError(cs, token, who))) {
|
|
1519
1574
|
return { status: 404, body: refusalBody({ errorCode: "not_found.parked_checkpoint", message: "no parked checkpoint for this session (nothing to wake)" }) };
|
|
1520
1575
|
}
|
|
1521
1576
|
return { status: 404, body: refusalBody({ errorCode: "not_found.checkpoint", message: "checkpoint not found" }) };
|
|
1522
1577
|
}
|
|
1523
|
-
if (!
|
|
1578
|
+
if (!keyAdmits("scope.decide", who, scopeCellOf(cp.scope))) {
|
|
1524
1579
|
return { status: 404, body: refusalBody({ errorCode: "not_found.parked_checkpoint", message: "no parked checkpoint for this session (nothing to wake)" }) };
|
|
1525
1580
|
}
|
|
1526
1581
|
const gateKind = cp.gate?.kind;
|
|
@@ -1543,10 +1598,12 @@ export function createResumeLegs(ctx) {
|
|
|
1543
1598
|
return resumeCtxCorruptAnswer(ctxRead.where);
|
|
1544
1599
|
if (ctxRead.kind === "unsealable")
|
|
1545
1600
|
return resumeCtxUnsealableAnswer(ctxRead);
|
|
1601
|
+
if (ctxRead.kind === "unreadable")
|
|
1602
|
+
return resumeCtxUnreadableAnswer();
|
|
1546
1603
|
if (ctxRead.kind === "absent")
|
|
1547
1604
|
return { status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) };
|
|
1548
1605
|
const ctx = restateResumeCtx(ctxRead.ctx, restatement);
|
|
1549
|
-
const auth = { sessionId: cp.sessionId,
|
|
1606
|
+
const auth = { sessionId: cp.sessionId, subject: checkpointPartsOf(cp.scope)?.subject, memoryScope: ctx.memoryScope };
|
|
1550
1607
|
const resolved = await resolveResumeSpecOrBlocked(ctx, req, auth);
|
|
1551
1608
|
if (!resolved.ok)
|
|
1552
1609
|
return resolved.answer;
|
|
@@ -1560,20 +1617,20 @@ export function createResumeLegs(ctx) {
|
|
|
1560
1617
|
legFacts: resolved.legFacts,
|
|
1561
1618
|
token,
|
|
1562
1619
|
sessionId: cp.sessionId,
|
|
1563
|
-
|
|
1620
|
+
subject: auth.subject,
|
|
1564
1621
|
fleetScope: resumeFleetScope(req, auth),
|
|
1565
1622
|
taskConfig,
|
|
1566
1623
|
resumeObjective,
|
|
1567
1624
|
outcome: { gate: "wake", ...(message !== undefined ? { message } : {}) },
|
|
1568
1625
|
commitment: { kind: "delivered" },
|
|
1569
|
-
|
|
1626
|
+
composition: undefined,
|
|
1570
1627
|
resumeCtx: { sessionId, ctx },
|
|
1571
|
-
mintFreshRun: { source: "wake", identity: runIdentityOf(req, deps.config, auth.
|
|
1628
|
+
mintFreshRun: { source: "wake", identity: runIdentityOf(req, deps.config, auth.subject ?? null) },
|
|
1572
1629
|
...(workflowDecision !== undefined ? { workflowDecision } : {}),
|
|
1573
1630
|
...(engineNotices.length > 0 ? { engineNotices } : {}),
|
|
1574
1631
|
...(acceptEarly === true ? { acceptEarly: true } : {}),
|
|
1575
1632
|
...(req !== undefined ? { callerInitiated: true } : {}),
|
|
1576
|
-
...(ownerLeaseAdmittedFor !== undefined && auth.
|
|
1633
|
+
...(ownerLeaseAdmittedFor !== undefined && auth.subject === ownerLeaseAdmittedFor ? { ownerLeaseAdmitted: true } : {}),
|
|
1577
1634
|
});
|
|
1578
1635
|
}
|
|
1579
1636
|
finally {
|
|
@@ -1589,20 +1646,19 @@ export function createResumeLegs(ctx) {
|
|
|
1589
1646
|
...(log?.principalPresent !== undefined ? { principalPresent: log.principalPresent } : {}),
|
|
1590
1647
|
});
|
|
1591
1648
|
const PLAN_REVIEW_GATE_KIND = "plan_review";
|
|
1592
|
-
const planReviewBinding = { gateKinds: [PLAN_REVIEW_GATE_KIND] };
|
|
1593
|
-
const token = (await cs.findPendingTokenBySession(sessionId, undefined, planReviewBinding)) ?? (await cs.findPendingTokenBySession(sessionId));
|
|
1649
|
+
const planReviewBinding = { gateKinds: [PLAN_REVIEW_GATE_KIND], axis: "run" };
|
|
1650
|
+
const token = (await cs.findPendingTokenBySession(sessionId, undefined, planReviewBinding)) ?? (await cs.findPendingTokenBySession(sessionId, undefined, { axis: "run" }));
|
|
1594
1651
|
const noPending = { status: 404, body: refusalBody({ errorCode: "not_found.plan_review", message: "no pending plan_review for this session (already decided or expired)" }) };
|
|
1595
1652
|
if (!token) {
|
|
1596
1653
|
log404("no-pending-checkpoint");
|
|
1597
1654
|
return refuse(noPending);
|
|
1598
1655
|
}
|
|
1599
|
-
if (decider !== undefined && !decider.
|
|
1656
|
+
if (decider !== undefined && !decider.operator) {
|
|
1600
1657
|
const peeked = await cs
|
|
1601
1658
|
.peekPendingScope(sessionId, planReviewBinding)
|
|
1602
|
-
.then((sc) => (sc === undefined ? cs.peekPendingScope(sessionId) : sc))
|
|
1659
|
+
.then((sc) => (sc === undefined ? cs.peekPendingScope(sessionId, { axis: "run" }) : sc))
|
|
1603
1660
|
.catch(() => undefined);
|
|
1604
|
-
|
|
1605
|
-
if (peekedOwner !== undefined && peekedOwner !== decider.principal) {
|
|
1661
|
+
if (!keyAdmits("scope.decide", decider, scopeCellOf(peeked ?? CHECKPOINT_PUBLIC_SCOPE))) {
|
|
1606
1662
|
deps.logger?.warn?.("plan_review_row_scope_mismatch", { sessionId, note: "pending row is foreign to the verified caller — owner gate ahead of the row load" });
|
|
1607
1663
|
return refuse(noPending);
|
|
1608
1664
|
}
|
|
@@ -1616,7 +1672,7 @@ export function createResumeLegs(ctx) {
|
|
|
1616
1672
|
deps.logger?.warn?.("plan_review_unreadable_row_withheld", { sessionId, note: "row unreadable and the caller's ownership of THAT token is unproven — folded into the uniform 404" });
|
|
1617
1673
|
return refuse(noPending);
|
|
1618
1674
|
}
|
|
1619
|
-
return refuse(
|
|
1675
|
+
return refuse(rowReadRefusalAnswer(e));
|
|
1620
1676
|
}
|
|
1621
1677
|
if (!cp) {
|
|
1622
1678
|
log404("checkpoint-missing");
|
|
@@ -1624,7 +1680,7 @@ export function createResumeLegs(ctx) {
|
|
|
1624
1680
|
return refuse(noPending);
|
|
1625
1681
|
return refuse({ status: 404, body: refusalBody({ errorCode: "not_found.checkpoint", message: "checkpoint not found" }) });
|
|
1626
1682
|
}
|
|
1627
|
-
if (decider !== undefined && !
|
|
1683
|
+
if (decider !== undefined && !keyAdmits("scope.decide", decider, scopeCellOf(cp.scope))) {
|
|
1628
1684
|
deps.logger?.warn?.("plan_review_row_scope_mismatch", { sessionId, note: "loaded pending row is foreign to the verified caller — TOCTOU fold" });
|
|
1629
1685
|
return refuse(noPending);
|
|
1630
1686
|
}
|
|
@@ -1650,6 +1706,8 @@ export function createResumeLegs(ctx) {
|
|
|
1650
1706
|
return refuse(resumeCtxCorruptAnswer(ctxRead.where));
|
|
1651
1707
|
if (ctxRead.kind === "unsealable")
|
|
1652
1708
|
return refuse(resumeCtxUnsealableAnswer(ctxRead));
|
|
1709
|
+
if (ctxRead.kind === "unreadable")
|
|
1710
|
+
return refuse(resumeCtxUnreadableAnswer());
|
|
1653
1711
|
if (ctxRead.kind === "absent")
|
|
1654
1712
|
return refuse({ status: 409, body: refusalBody({ errorCode: "conflict.resume_context_unavailable", message: "resume context missing — cannot rebuild task config" }) });
|
|
1655
1713
|
const ctx = restateResumeCtx(ctxRead.ctx, restatement);
|
|
@@ -1660,9 +1718,9 @@ export function createResumeLegs(ctx) {
|
|
|
1660
1718
|
}
|
|
1661
1719
|
async function drivePlanReview(prepared, decision, editedPlan, reason, hostDecision, req, acceptEarly, permissionModeAfter) {
|
|
1662
1720
|
const { sessionId, token, cp, ctx } = prepared;
|
|
1663
|
-
if ((await deps.checkpointStore.findPendingTokenBySession(sessionId, undefined, { gateKinds: ["plan_review"] })) !== token)
|
|
1721
|
+
if ((await deps.checkpointStore.findPendingTokenBySession(sessionId, undefined, { gateKinds: ["plan_review"], axis: "run" })) !== token)
|
|
1664
1722
|
return notResumableAnswer();
|
|
1665
|
-
const auth = { sessionId
|
|
1723
|
+
const auth = { sessionId, subject: checkpointPartsOf(cp.scope)?.subject, memoryScope: ctx.memoryScope };
|
|
1666
1724
|
const effMode = storedBodyPermissionMode(ctx.body);
|
|
1667
1725
|
if (permissionModeAfter !== undefined && effMode !== "plan") {
|
|
1668
1726
|
throw new Error("drivePlanReview: permissionModeAfter was passed for a task whose stored permission mode is not \"plan\" — the caller must refuse this before any state changes (see the plan_review route's pre-nonce gate)");
|
|
@@ -1675,7 +1733,9 @@ export function createResumeLegs(ctx) {
|
|
|
1675
1733
|
try {
|
|
1676
1734
|
const { spec, engineNotices } = resolved;
|
|
1677
1735
|
const { objective: resumeObjective, sessionId: _sessionId, ...taskConfig } = spec;
|
|
1678
|
-
const
|
|
1736
|
+
const composition = resumeCompositionOf(ctx.body, cp, deps.config.cascadeLadder);
|
|
1737
|
+
if (composition?.entry === "cascade_unlinked")
|
|
1738
|
+
return compositionUnlinkedAnswer();
|
|
1679
1739
|
const outcome = {
|
|
1680
1740
|
gate: "plan_review",
|
|
1681
1741
|
decision,
|
|
@@ -1684,7 +1744,7 @@ export function createResumeLegs(ctx) {
|
|
|
1684
1744
|
hostDecision,
|
|
1685
1745
|
};
|
|
1686
1746
|
const selectedGate = durableRowIdentity("decision-receipt", cp.checkpointId, token);
|
|
1687
|
-
const out = await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: resolved.runner, legFacts: resolved.legFacts, token, sessionId
|
|
1747
|
+
const out = await driveResumeIntoRunLog({ peerLease: resolved.peerLease, execution: resolved.execution, runner: resolved.runner, legFacts: resolved.legFacts, token, sessionId, subject: auth.subject, fleetScope: resumeFleetScope(req, auth), taskConfig, resumeObjective, outcome, commitment: { kind: "gate_resolved", ...selectedGate }, composition, resumeCtx: { sessionId, ctx: rebuildCtx }, ...(engineNotices.length > 0 ? { engineNotices } : {}), ...(acceptEarly === true ? { acceptEarly: true } : {}), ...(req !== undefined ? { callerInitiated: true } : {}) });
|
|
1688
1748
|
return out;
|
|
1689
1749
|
}
|
|
1690
1750
|
finally {
|
|
@@ -1700,10 +1760,10 @@ export function createResumeLegs(ctx) {
|
|
|
1700
1760
|
const routeCtxBase = {
|
|
1701
1761
|
deps,
|
|
1702
1762
|
registry: { idemCache, inflightRuns, preemptableRuns, steerableRuns, wakeParkMints, counters },
|
|
1703
|
-
helpers: { readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode
|
|
1763
|
+
helpers: { readJson, readRawBody, rateLimited, quotaExceeded, ownerQuotaDenied, leaseDenied, ownerLeaseDenied, usageWindowDenied, admitRun, safeDecode },
|
|
1704
1764
|
local: { images: createImagesLocal(deps), sessions: createSessionsLocal(), sessionSync: createSessionSyncLocal(), capabilities: createCapabilitiesLocal() },
|
|
1705
1765
|
legs: { prepareSpec, finalizeTaskResult, resumeCheckpoint, driveResumeIntoRunLog, resumePreempted, resumeWake, preparePlanReview, drivePlanReview, sessionNotify: sessionNotifyDoor },
|
|
1706
1766
|
};
|
|
1707
|
-
return { routeCtxBase, resumeCheckpoint, driveResumeIntoRunLog, driveResumeLeg,
|
|
1767
|
+
return { routeCtxBase, resumeCheckpoint, driveResumeIntoRunLog, driveResumeLeg, decisionRowAdmits, resumePreempted, startFreshHostTurn, resumeWake, preparePlanReview, drivePlanReview, sessionNotifyDoor };
|
|
1708
1768
|
}
|
|
1709
1769
|
//# sourceMappingURL=resume-legs.js.map
|