@sema-agent/server 7.149.0 → 7.151.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 +307 -9
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/USAGE.md +92 -40
- package/deploy/sema-up/README.md +7 -1
- package/deploy/sema-up/chart/Chart.yaml +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +5 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +15 -16
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -3
- package/deploy/sema-up/chart/templates/server.yaml +5 -3
- package/deploy/sema-up/chart/values-full-single.yaml +3 -1
- package/deploy/sema-up/chart/values.yaml +8 -1
- package/deploy/sema-up/cluster-up.sh +1 -0
- package/deploy/sema-up/kube-up.sh +1 -1
- package/deploy/sema-up/lib/flagshape.sh +1 -1
- package/deploy/sema-up/lib/helm-values-cluster.py +2 -0
- package/deploy/sema-up/lib/helm-values-kube.py +2 -0
- package/dist/adoption/import.js +3 -3
- package/dist/approval-ask-machine.d.ts +1 -1
- package/dist/approval-card.d.ts +3 -3
- package/dist/approval-gate-currency.d.ts +2 -2
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +2 -2
- package/dist/auth-bridge.d.ts +20 -0
- package/dist/auth-bridge.js +9 -0
- package/dist/background-session-reap.d.ts +2 -2
- package/dist/bake-runner/main.d.ts +4 -2
- package/dist/bind-host.d.ts +2 -3
- package/dist/bind-host.js +2 -4
- package/dist/boot/budget-tracing.js +1 -1
- package/dist/boot/deferred-sandbox-path-env.d.ts +5 -3
- package/dist/boot/deferred-sandbox-path-env.js +1 -2
- package/dist/boot/engine-lease.d.ts +5 -0
- package/dist/boot/engine-lease.js +1 -0
- package/dist/boot/execution-env.d.ts +8 -14
- package/dist/boot/execution-env.js +54 -17
- package/dist/boot/execution-lane.js +32 -5
- package/dist/boot/late-binds.d.ts +8 -4
- package/dist/boot/late-binds.js +7 -1
- package/dist/boot/memory-consolidation.d.ts +3 -2
- package/dist/boot/memory-consolidation.js +6 -6
- package/dist/boot/parked-revive-gate.d.ts +5 -5
- package/dist/boot/parked-revive-gate.js +2 -3
- package/dist/boot/reapers.d.ts +5 -0
- package/dist/boot/reapers.js +12 -1
- package/dist/boot/resolve-spec.d.ts +7 -8
- package/dist/boot/resolve-spec.js +80 -35
- package/dist/boot/retention-lane.d.ts +1 -1
- package/dist/boot/runner-deps.d.ts +9 -2
- package/dist/boot/runner-deps.js +3 -3
- package/dist/boot/session-age-out.d.ts +36 -0
- package/dist/boot/session-age-out.js +101 -0
- package/dist/boot/session-faces.d.ts +5 -14
- package/dist/boot/session-faces.js +28 -24
- package/dist/boot/stage-01-config.js +2 -0
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-05-execution-env.d.ts +5 -3
- package/dist/boot/stage-05-execution-env.js +2 -2
- package/dist/boot/stage-06-runners.d.ts +7 -4
- package/dist/boot/stage-06-runners.js +16 -8
- package/dist/boot/stage-07-capability-layer.d.ts +7 -4
- package/dist/boot/stage-07-capability-layer.js +3 -2
- package/dist/boot/stage-08-reapers.d.ts +7 -4
- package/dist/boot/stage-08-reapers.js +4 -2
- package/dist/boot/stage-09-leader.d.ts +11 -5
- package/dist/boot/stage-09-leader.js +12 -3
- package/dist/boot/stage-10-http-server.d.ts +44 -6
- package/dist/boot/stage-10-http-server.js +12 -10
- package/dist/boot/web-admin.d.ts +1 -1
- package/dist/boot/web-admin.js +3 -1
- package/dist/boot/workflow-orchestration.d.ts +7 -2
- package/dist/boot/workflow-orchestration.js +24 -7
- package/dist/bounded-rotation.d.ts +29 -0
- package/dist/bounded-rotation.js +24 -0
- package/dist/capability-facts.d.ts +84 -66
- package/dist/capability-facts.js +58 -41
- package/dist/center-credential.d.ts +25 -6
- package/dist/center-credential.js +25 -5
- package/dist/config-catalog.d.ts +26 -7
- package/dist/config-catalog.js +15 -12
- package/dist/config-invariants.d.ts +2 -1
- package/dist/config-invariants.js +4 -4
- package/dist/config-types.d.ts +22 -15
- package/dist/config.d.ts +51 -2
- package/dist/config.js +35 -24
- package/dist/deployment-governance.d.ts +7 -28
- package/dist/deployment-governance.js +1 -14
- package/dist/deployment-shape.d.ts +9 -1
- package/dist/deployment-shape.js +2 -1
- package/dist/device-protocol.d.ts +5 -4
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.d.ts +1 -0
- package/dist/device-ws-hub.js +66 -29
- package/dist/device-ws-protocol.d.ts +79 -12
- package/dist/device-ws-protocol.js +64 -26
- package/dist/engine-identity.d.ts +23 -5
- package/dist/engine-identity.js +13 -0
- package/dist/entry-mode-clamp-notice.d.ts +2 -1
- package/dist/execution-env-refusal.d.ts +23 -0
- package/dist/execution-env-refusal.js +5 -0
- package/dist/execution-lane-caps.d.ts +3 -1
- package/dist/field-conflict.d.ts +3 -3
- package/dist/file-history-capture.d.ts +11 -4
- package/dist/file-history-capture.js +9 -6
- package/dist/file-history-disclosure.d.ts +7 -5
- package/dist/file-history-disclosure.js +7 -5
- package/dist/fleet/drain-entry.d.ts +4 -0
- package/dist/fleet/engine-signal.d.ts +14 -1
- package/dist/fleet/engine-signal.js +5 -1
- package/dist/fleet/fleet-reconciler.d.ts +1 -1
- package/dist/fleet/serving-lease.d.ts +18 -3
- package/dist/fleet/serving-lease.js +81 -35
- package/dist/fleet-client.d.ts +13 -11
- package/dist/fleet-client.js +53 -33
- package/dist/history-anchor.js +1 -1
- package/dist/hitl-delivery.d.ts +1 -3
- package/dist/hitl-delivery.js +1 -1
- package/dist/hooks/hook-runner.js +2 -2
- package/dist/host-lsp-manager.d.ts +2 -2
- package/dist/http/active-run-conflict.d.ts +3 -7
- package/dist/http/active-run-conflict.js +2 -2
- package/dist/http/admission.js +19 -4
- package/dist/http/approval-sweeps.js +7 -6
- package/dist/http/caller-trust.d.ts +2 -2
- package/dist/http/caller-trust.js +3 -3
- package/dist/http/checkpoint-ctx.d.ts +20 -63
- package/dist/http/checkpoint-ctx.js +2 -24
- package/dist/http/claim-heartbeat.d.ts +4 -4
- package/dist/http/claim-heartbeat.js +3 -3
- package/dist/http/dispatch.d.ts +2 -1
- package/dist/http/dispatch.js +36 -29
- package/dist/http/durable-run-leg.js +17 -17
- package/dist/http/health-self-report.d.ts +9 -1
- package/dist/http/health-self-report.js +2 -0
- package/dist/http/owner-access.d.ts +264 -20
- package/dist/http/owner-access.js +215 -5
- package/dist/http/readiness.d.ts +4 -2
- package/dist/http/resume-ctx-read.js +38 -1
- package/dist/http/resume-legs.d.ts +2 -1
- package/dist/http/resume-legs.js +273 -89
- package/dist/http/route-ctx.d.ts +41 -19
- package/dist/http/route-table.d.ts +1 -1
- package/dist/http/routes/a2a-serve.js +15 -14
- package/dist/http/routes/admin-memory-optout.d.ts +1 -1
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.d.ts +3 -2
- package/dist/http/routes/approvals-assistant.js +12 -12
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/capabilities.js +10 -6
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/fleet.js +10 -8
- package/dist/http/routes/mcp-reconnect.js +2 -2
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -3
- package/dist/http/routes/projects.d.ts +4 -2
- package/dist/http/routes/projects.js +7 -6
- package/dist/http/routes/retention-ops.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.d.ts +1 -1
- package/dist/http/routes/run-permission-mode.js +2 -2
- package/dist/http/routes/runs.d.ts +1 -1
- package/dist/http/routes/runs.js +125 -66
- package/dist/http/routes/session-memory-sync.js +4 -5
- package/dist/http/routes/session-sync.d.ts +4 -3
- package/dist/http/routes/session-sync.js +174 -83
- package/dist/http/routes/sessions-list.js +13 -7
- package/dist/http/routes/sessions.d.ts +1 -1
- package/dist/http/routes/sessions.js +26 -48
- package/dist/http/routes/tasks.js +38 -23
- package/dist/http/routes/trace-usage.js +14 -14
- package/dist/http/routes/workflows.d.ts +1 -0
- package/dist/http/routes/workflows.js +20 -38
- package/dist/http/server.d.ts +28 -30
- package/dist/http/server.js +7 -3
- package/dist/http/stored-body-replay.d.ts +3 -24
- package/dist/http/stored-body-replay.js +2 -12
- package/dist/http/submit-ctx.d.ts +1 -2
- package/dist/http/submit-ctx.js +8 -6
- package/dist/http/submit-replay.d.ts +15 -2
- package/dist/http/submit-replay.js +10 -4
- package/dist/http/wire-types.d.ts +19 -6
- package/dist/identity-source.d.ts +20 -3
- package/dist/identity-source.js +14 -0
- package/dist/index.d.ts +4 -0
- package/dist/lane-home-probe.d.ts +3 -7
- package/dist/lane-home-probe.js +0 -1
- package/dist/leader/endpoint.js +9 -8
- package/dist/leader/leader.d.ts +2 -1
- package/dist/leg-facts.d.ts +19 -5
- package/dist/leg-facts.js +3 -1
- package/dist/mcp-authorization-face.d.ts +18 -14
- package/dist/mcp-authorization-face.js +3 -2
- package/dist/memory-scope.d.ts +5 -4
- package/dist/memory-scope.js +4 -4
- package/dist/memory-store-refusal.d.ts +1 -1
- package/dist/memory-sync-client.d.ts +30 -2
- package/dist/memory-sync-client.js +16 -9
- package/dist/observability/corrupt-read-seat.d.ts +1 -1
- package/dist/observability/err-text.d.ts +7 -0
- package/dist/observability/err-text.js +5 -0
- package/dist/observability/fail-open.d.ts +12 -8
- package/dist/observability/fail-open.js +12 -8
- package/dist/observability/logger.d.ts +7 -0
- package/dist/observability/logger.js +3 -1
- package/dist/observability/metrics.js +1 -0
- package/dist/observability/run-terminal.d.ts +1 -1
- package/dist/orchestration/workflow-notify-journal.d.ts +18 -1
- package/dist/orchestration/workflow-notify-journal.js +12 -1
- package/dist/orchestration/workflow-park-decision.d.ts +70 -18
- package/dist/orchestration/workflow-park-decision.js +49 -10
- package/dist/orchestration/workflow-park-holder.d.ts +65 -0
- package/dist/orchestration/workflow-park-holder.js +98 -0
- package/dist/orchestration/workflow-record-fence.d.ts +36 -0
- package/dist/orchestration/workflow-record-fence.js +42 -0
- package/dist/owner-faces.d.ts +28 -4
- package/dist/owner-faces.js +2 -0
- package/dist/parked-decide.d.ts +104 -53
- package/dist/parked-decide.js +153 -117
- package/dist/peer-directory.d.ts +2 -2
- package/dist/peer-inbound-face.d.ts +2 -6
- package/dist/peer-inbound-face.js +0 -3
- package/dist/peer-seat.d.ts +1 -1
- package/dist/peer-seat.js +52 -59
- package/dist/permission-mode-admission.d.ts +41 -5
- package/dist/permission-mode-admission.js +29 -3
- package/dist/plugins/adoption-log-sql.d.ts +3 -1
- package/dist/plugins/adoption-log-sql.js +7 -1
- package/dist/plugins/approval-ask-store-file.d.ts +10 -2
- package/dist/plugins/approval-ask-store-file.js +8 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +6 -1
- package/dist/plugins/approval-ask-store-memory.js +28 -9
- package/dist/plugins/approval-ask-store-sql.d.ts +43 -2
- package/dist/plugins/approval-ask-store-sql.js +34 -5
- package/dist/plugins/approval-exemption-store.js +3 -0
- package/dist/plugins/approval-nonce-store.js +2 -0
- package/dist/plugins/breaker-state-sql.js +2 -0
- package/dist/plugins/caching-session-store.d.ts +9 -15
- package/dist/plugins/caching-session-store.js +6 -0
- package/dist/plugins/device-store-sql.js +6 -0
- package/dist/plugins/error-origin.d.ts +18 -0
- package/dist/plugins/error-origin.js +10 -0
- package/dist/plugins/exec-path-law.d.ts +34 -0
- package/dist/plugins/exec-path-law.js +13 -0
- package/dist/plugins/execution-placement-sql.js +6 -6
- package/dist/plugins/file-run-store.js +1 -1
- package/dist/plugins/image-bake-store-sql.js +6 -0
- package/dist/plugins/image-index-sql.js +4 -0
- package/dist/plugins/landed-attendants.d.ts +212 -0
- package/dist/plugins/landed-attendants.js +161 -0
- package/dist/plugins/leader-run-store-sql.js +4 -0
- package/dist/plugins/local-checkpoint-store.d.ts +4 -1
- package/dist/plugins/local-checkpoint-store.js +3 -0
- package/dist/plugins/local-session-live-reference.d.ts +40 -0
- package/dist/plugins/local-session-live-reference.js +39 -0
- package/dist/plugins/local-session-store.d.ts +71 -33
- package/dist/plugins/local-session-store.js +129 -27
- package/dist/plugins/memory-engine-pg.js +4 -0
- package/dist/plugins/memory-engine-sql-apply.js +5 -2
- package/dist/plugins/memory-engine-tidb.js +4 -0
- package/dist/plugins/memory-optout-grant-store-sql.js +4 -0
- package/dist/plugins/memory-run-store.js +1 -1
- package/dist/plugins/memory-sync-store-pg.js +5 -0
- package/dist/plugins/memory-sync-store-tidb.js +5 -0
- package/dist/plugins/one-time-migrations.d.ts +80 -61
- package/dist/plugins/one-time-migrations.js +241 -104
- package/dist/plugins/org-delivery-quota-store.js +4 -1
- package/dist/plugins/outcome-ledger-sql.js +2 -0
- package/dist/plugins/permission-rule-store-sql.js +11 -4
- package/dist/plugins/pg-cost-quota.js +4 -0
- package/dist/plugins/pg-pool.js +28 -1
- package/dist/plugins/pg-rate-limiter.js +2 -0
- package/dist/plugins/posix-shell-fs.d.ts +6 -1
- package/dist/plugins/posix-shell-fs.js +8 -3
- package/dist/plugins/remote-env-adb.d.ts +19 -15
- package/dist/plugins/remote-env-adb.js +44 -17
- package/dist/plugins/remote-env-connect-seat.d.ts +105 -0
- package/dist/plugins/remote-env-connect-seat.js +72 -0
- package/dist/plugins/remote-env-device.d.ts +22 -5
- package/dist/plugins/remote-env-device.js +114 -14
- package/dist/plugins/remote-env-e2b.d.ts +18 -7
- package/dist/plugins/remote-env-e2b.js +53 -40
- package/dist/plugins/remote-env-file-error.js +6 -2
- package/dist/plugins/remote-env-host.d.ts +18 -1
- package/dist/plugins/remote-env-host.js +48 -47
- package/dist/plugins/remote-env-k8s.d.ts +41 -39
- package/dist/plugins/remote-env-k8s.js +56 -32
- package/dist/plugins/remote-env-local-docker.d.ts +13 -8
- package/dist/plugins/remote-env-local-docker.js +37 -43
- package/dist/plugins/remote-env-ssh.d.ts +18 -12
- package/dist/plugins/remote-env-ssh.js +64 -62
- package/dist/plugins/remote-shell.d.ts +101 -2
- package/dist/plugins/remote-shell.js +221 -3
- package/dist/plugins/replica-registration.d.ts +35 -0
- package/dist/plugins/replica-registration.js +48 -0
- package/dist/plugins/resume-anchor-store-sql.d.ts +11 -2
- package/dist/plugins/resume-anchor-store-sql.js +12 -5
- package/dist/plugins/retention-lane-store-sql.d.ts +1 -1
- package/dist/plugins/retention-lane-store-sql.js +4 -0
- package/dist/plugins/retention-sql.d.ts +20 -2
- package/dist/plugins/retention-sql.js +11 -0
- package/dist/plugins/run-store-sql.d.ts +22 -3
- package/dist/plugins/run-store-sql.js +33 -9
- package/dist/plugins/scenario-prefix-switch-m42.d.ts +6 -12
- package/dist/plugins/scenario-prefix-switch-m42.js +7 -5
- package/dist/plugins/schema-consistency.d.ts +9 -5
- package/dist/plugins/schema-consistency.js +48 -18
- package/dist/plugins/schema-drift-sentence.js +1 -1
- package/dist/plugins/send-file-ledger.js +3 -0
- package/dist/plugins/serving-requirement.d.ts +68 -0
- package/dist/plugins/serving-requirement.js +60 -0
- package/dist/plugins/session-birth.d.ts +6 -2
- package/dist/plugins/session-capture-record-store-sql.js +2 -0
- package/dist/plugins/session-ext-table.d.ts +14 -1
- package/dist/plugins/session-ext-table.js +5 -1
- package/dist/plugins/session-row-sql.d.ts +49 -2
- package/dist/plugins/session-row-sql.js +56 -13
- package/dist/plugins/session-store-sql.d.ts +34 -18
- package/dist/plugins/session-store-sql.js +98 -17
- package/dist/plugins/shared-memory-store-sql.d.ts +1 -0
- package/dist/plugins/shared-memory-store-sql.js +6 -2
- package/dist/plugins/sql-driver.d.ts +2 -1
- package/dist/plugins/sql-driver.js +18 -3
- package/dist/plugins/sql-errors.d.ts +11 -6
- package/dist/plugins/sql-errors.js +5 -6
- package/dist/plugins/stop-then-start-sentence.d.ts +48 -3
- package/dist/plugins/stop-then-start-sentence.js +48 -0
- package/dist/plugins/stop-then-start.d.ts +109 -0
- package/dist/plugins/stop-then-start.js +104 -0
- package/dist/plugins/store-backend.d.ts +40 -13
- package/dist/plugins/store-backend.js +169 -27
- package/dist/plugins/store-boundary.d.ts +57 -0
- package/dist/plugins/store-boundary.js +139 -0
- package/dist/plugins/store-contracts.d.ts +29 -2
- package/dist/plugins/store-contracts.js +3 -0
- package/dist/plugins/store-fault-sentence-m53.d.ts +7 -0
- package/dist/plugins/store-fault-sentence-m53.js +25 -0
- package/dist/plugins/store-fault.d.ts +26 -7
- package/dist/plugins/store-fault.js +18 -2
- package/dist/plugins/task-attachment-store.js +9 -0
- package/dist/plugins/task-list-store-sql.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.js +10 -8
- package/dist/plugins/tidb-cost-quota.js +4 -0
- package/dist/plugins/tidb-pool.js +6 -1
- package/dist/plugins/tidb-rate-limiter.js +4 -0
- package/dist/plugins/user-input-ledger-sql.js +4 -0
- package/dist/plugins/workflow-run-store-sql.d.ts +28 -10
- package/dist/plugins/workflow-run-store-sql.js +64 -4
- package/dist/plugins/workspace-fill.d.ts +4 -7
- package/dist/plugins/workspace-fill.js +2 -1
- package/dist/plugins/write-behind-counter.js +5 -0
- package/dist/process-instance.d.ts +3 -0
- package/dist/process-instance.js +7 -0
- package/dist/project-context.d.ts +64 -0
- package/dist/project-context.js +66 -0
- package/dist/project-registry.d.ts +46 -0
- package/dist/project-registry.js +44 -0
- package/dist/question.d.ts +9 -21
- package/dist/question.js +28 -19
- package/dist/request-key-closure.js +1 -1
- package/dist/request-value-closure.d.ts +4 -0
- package/dist/request-value-closure.js +10 -0
- package/dist/run-acceptance.d.ts +3 -2
- package/dist/run-acceptance.js +4 -6
- package/dist/run-cancel-card.d.ts +1 -1
- package/dist/run-cancel-card.js +2 -1
- package/dist/run-local.js +1 -0
- package/dist/runs.d.ts +37 -8
- package/dist/runs.js +53 -12
- package/dist/runtime-governance.d.ts +5 -4
- package/dist/security.d.ts +31 -33
- package/dist/security.js +41 -7
- package/dist/server-secret-env.d.ts +12 -10
- package/dist/server-secret-env.js +24 -15
- package/dist/session-agent.d.ts +1 -10
- package/dist/session-agent.js +0 -6
- package/dist/session-bindings.d.ts +82 -0
- package/dist/session-bindings.js +18 -0
- package/dist/session-children-retire.d.ts +2 -2
- package/dist/session-children-retire.js +2 -6
- package/dist/session-deletion.d.ts +16 -1
- package/dist/session-error-wire.d.ts +3 -3
- package/dist/session-error-wire.js +3 -3
- package/dist/session-incarnation.d.ts +28 -4
- package/dist/session-incarnation.js +14 -2
- package/dist/session-kind.d.ts +57 -0
- package/dist/session-kind.js +22 -0
- package/dist/session-notify-door.d.ts +4 -4
- package/dist/session-notify-door.js +5 -6
- package/dist/session-row.d.ts +21 -1
- package/dist/session-row.js +7 -1
- package/dist/session-rules-seat.d.ts +4 -3
- package/dist/session-rules-seat.js +3 -11
- package/dist/session-sync-kernel.d.ts +24 -14
- package/dist/session-sync-kernel.js +3 -6
- package/dist/session-sync.d.ts +4 -98
- package/dist/session-sync.js +4 -74
- package/dist/session-titler.d.ts +10 -3
- package/dist/session-titler.js +19 -6
- package/dist/ssh-host-key.d.ts +5 -0
- package/dist/ssh-host-key.js +3 -0
- package/dist/stores-sql/checkpoint-store-sql.d.ts +21 -2
- package/dist/stores-sql/checkpoint-store-sql.js +106 -18
- package/dist/stores-sql/file-history-store-sql.d.ts +52 -2
- package/dist/stores-sql/file-history-store-sql.js +108 -70
- package/dist/stores-sql/pg-session-storage.d.ts +34 -7
- package/dist/stores-sql/pg-session-storage.js +37 -13
- package/dist/stores-sql/retention-store-sql.d.ts +2 -10
- package/dist/stores-sql/retention-store-sql.js +2 -10
- package/dist/stores-sql/session-policy-store-sql.d.ts +30 -7
- package/dist/stores-sql/session-policy-store-sql.js +61 -44
- package/dist/stores-sql/session-write-hooks.d.ts +11 -0
- package/dist/stores-sql/tidb-session-store.d.ts +58 -7
- package/dist/stores-sql/tidb-session-store.js +37 -13
- package/dist/submission-exit.d.ts +3 -2
- package/dist/submission-exit.js +9 -1
- package/dist/task-cwd.d.ts +6 -5
- package/dist/task-settings.d.ts +19 -5
- package/dist/task-settings.js +13 -7
- package/dist/terminal.d.ts +33 -2
- package/dist/terminal.js +139 -9
- package/dist/tool-approval.d.ts +147 -12
- package/dist/tool-approval.js +206 -109
- package/dist/trace/engine-notice-wire.d.ts +14 -0
- package/dist/trace/engine-notice-wire.js +18 -1
- package/dist/trace/project.d.ts +4 -3
- package/dist/trace/project.js +3 -2
- package/dist/trace/projection-table.d.ts +33 -2
- package/dist/trace/self-minted-wire.d.ts +422 -26
- package/dist/trace/self-minted-wire.js +149 -23
- package/dist/trace/tool-card.d.ts +3 -0
- package/dist/trace/tool-card.js +24 -0
- package/dist/trace/tool-output-media.d.ts +2 -1
- package/dist/unattended-permission-mode.d.ts +1 -1
- package/dist/web-admin-client/apply-effective.d.ts +1 -1
- package/dist/web-admin-client/effective-keys.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +120 -41
- package/package.json +3 -3
- package/wire-changes/server@7.150.0.json +335 -0
- package/wire-changes/server@7.151.0.json +762 -0
- package/dist/http/session-inherit-env.d.ts +0 -36
- package/dist/http/session-inherit-env.js +0 -6
|
@@ -4,6 +4,7 @@ import { sendUnauthorized } from "../principal-gate.js";
|
|
|
4
4
|
import { routeListFilter } from "../owner-access.js";
|
|
5
5
|
import { assertNever } from "../route-ctx.js";
|
|
6
6
|
import * as facts from "../../capability-facts.js";
|
|
7
|
+
import { projectVisibleTo, visibleProjectOf } from "../../project-registry.js";
|
|
7
8
|
import { projectByTable } from "../../trace/projection-table.js";
|
|
8
9
|
export const PROJECT_NOT_FOUND_MESSAGE = "no such project";
|
|
9
10
|
export const PROJECT_ROW_DISPOSITIONS = {
|
|
@@ -19,6 +20,7 @@ export const PROJECT_ROW_DISPOSITIONS = {
|
|
|
19
20
|
registeredBy: "forward",
|
|
20
21
|
registeredAt: "forward",
|
|
21
22
|
archivedAt: "forward",
|
|
23
|
+
contentAttestedAt: "forward",
|
|
22
24
|
};
|
|
23
25
|
export function projectRowOf(id, registration) {
|
|
24
26
|
return projectByTable("project", PROJECT_ROW_DISPOSITIONS, registration, { id });
|
|
@@ -37,8 +39,8 @@ function readArchivedQuery(raw) {
|
|
|
37
39
|
export async function handleProjects(req, res, match, ctx) {
|
|
38
40
|
const { deps } = ctx;
|
|
39
41
|
const { safeDecode } = ctx.helpers;
|
|
40
|
-
const
|
|
41
|
-
if (!fleetWide && gateOwner === null) {
|
|
42
|
+
const viewer = routeListFilter(req, deps, match.decl.id);
|
|
43
|
+
if (!viewer.fleetWide && viewer.gateOwner === null) {
|
|
42
44
|
sendUnauthorized(res, "identity");
|
|
43
45
|
return;
|
|
44
46
|
}
|
|
@@ -47,7 +49,6 @@ export async function handleProjects(req, res, match, ctx) {
|
|
|
47
49
|
sendError(res, 501, "capability.unavailable", "the project registry is not available on this deployment: projects are published only by the configuration center, and no center configuration is applied here");
|
|
48
50
|
return;
|
|
49
51
|
}
|
|
50
|
-
const visible = (registration) => fleetWide || registration.registeredBy === gateOwner;
|
|
51
52
|
switch (match.decl.id) {
|
|
52
53
|
case "projects-list": {
|
|
53
54
|
const archived = readArchivedQuery(new URLSearchParams(match.search).get("archived"));
|
|
@@ -56,7 +57,7 @@ export async function handleProjects(req, res, match, ctx) {
|
|
|
56
57
|
return;
|
|
57
58
|
}
|
|
58
59
|
const projects = Object.entries(registry.registry)
|
|
59
|
-
.filter(([, registration]) =>
|
|
60
|
+
.filter(([, registration]) => projectVisibleTo(viewer, registration) && (registration.archivedAt !== undefined) === archived)
|
|
60
61
|
.map(([id, registration]) => projectRowOf(id, registration));
|
|
61
62
|
sendJson(res, 200, { projects });
|
|
62
63
|
return;
|
|
@@ -68,8 +69,8 @@ export async function handleProjects(req, res, match, ctx) {
|
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
70
71
|
const id = raw.toLowerCase();
|
|
71
|
-
const registration =
|
|
72
|
-
if (registration === undefined
|
|
72
|
+
const registration = visibleProjectOf(registry.registry, id, viewer);
|
|
73
|
+
if (registration === undefined) {
|
|
73
74
|
sendError(res, 404, "not_found.project", PROJECT_NOT_FOUND_MESSAGE);
|
|
74
75
|
return;
|
|
75
76
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* [ref] 车2 —— **托管留存的 operator 治理面**(设计稿 `docs/
|
|
2
|
+
* [ref] 车2 —— **托管留存的 operator 治理面**(设计稿 `docs/[ref]-retention-lane.md` §5/§6)。
|
|
3
3
|
*
|
|
4
4
|
* · `PUT /v1/ops/retention/holds/:domain` —— 放置 legal hold;
|
|
5
5
|
* · `DELETE /v1/ops/retention/holds/:domain` —— 解除;
|
|
@@ -43,7 +43,7 @@ export type PermissionModePersistMiss = (typeof PERMISSION_MODE_PERSIST_MISSES)[
|
|
|
43
43
|
* · run 行仍在本副本(`runProvenElsewhere` 的反面 —— 别的副本续跑了它,续跑的 CAS 赢点把行上的副本改成它自己);
|
|
44
44
|
* · 本副本这条 run 此刻登记的活流仍是接下切档的那一只(本副本上续跑的新腿登记的是另一只流对象;腿收场时按对象身份摘掉自己的)。
|
|
45
45
|
*/
|
|
46
|
-
export declare function switchLegHolds<S extends object>(fenced: FencedRun, thisInstanceId: string | undefined, liveNow: S | undefined, switched: S): boolean;
|
|
46
|
+
export declare function switchLegHolds<S extends object>(fenced: Pick<FencedRun, "instanceId">, thisInstanceId: string | undefined, liveNow: S | undefined, switched: S): boolean;
|
|
47
47
|
/** 本判官改了词时回执旁的那一格(`admission`)。 */
|
|
48
48
|
interface PermissionModeAdmissionNote {
|
|
49
49
|
readonly requested: PermissionMode;
|
|
@@ -7,7 +7,7 @@ import * as facts from "../../capability-facts.js";
|
|
|
7
7
|
import { PERMISSION_MODE_WORDS, coercePermissionModeStrict, parseTaskSettings } from "../../task-settings.js";
|
|
8
8
|
import { admitPermissionModeWord } from "../../permission-mode-admission.js";
|
|
9
9
|
import { readResumeCtx, resumeCtxCorruptAnswer, resumeCtxUnreadableAnswer, resumeCtxUnsealableAnswer } from "../resume-ctx-read.js";
|
|
10
|
-
import { sealCheckpointCtx
|
|
10
|
+
import { sealCheckpointCtx } from "../checkpoint-ctx.js";
|
|
11
11
|
import { serviceVersion } from "../../service-version.js";
|
|
12
12
|
import { recordFailOpen } from "../../observability/fail-open.js";
|
|
13
13
|
export const PERMISSION_MODE_PERSIST_MISSES = ["claim_released", "context_absent", "store_failed"];
|
|
@@ -114,7 +114,7 @@ export async function handlePermissionMode(req, res, match, ctx) {
|
|
|
114
114
|
}
|
|
115
115
|
let persistMiss;
|
|
116
116
|
try {
|
|
117
|
-
const next = sealCheckpointCtx({ ...
|
|
117
|
+
const next = sealCheckpointCtx({ ...stored, body: { ...stored.body, permissionMode: admitted }, writerVersion: serviceVersion() }, deps.checkpointCtxSealing, sessionId);
|
|
118
118
|
const rewrite = await checkpointStore.rewriteCtxWhileClaimed(sessionId, next, { fence: runStore, taskId, legHolds: (fenced) => switchLegHolds(fenced, deps.instanceId, ctx.registry.steerableRuns.get(taskId), live) });
|
|
119
119
|
persistMiss = rewrite === "written" ? undefined : rewrite;
|
|
120
120
|
}
|
|
@@ -13,7 +13,7 @@ export declare function handleRuns(req: IncomingMessage, res: ServerResponse, ma
|
|
|
13
13
|
/** 同上纪律(子代理 / 任务句柄 / HITL 应答段)。 */
|
|
14
14
|
export declare function handleRunVerbs(req: IncomingMessage, res: ServerResponse, match: RouteMatch<RunVerbsRouteId>, ctx: RouteCtx): Promise<void>;
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
16
|
+
* [ref] 车2 件2 —— `POST /v1/runs` 的**建行 + 驱动**段,从路由体里原样搬出来的具名腿。
|
|
17
17
|
*
|
|
18
18
|
* 🔴 为什么提取:A2A 的 `message/send`(routes/a2a-serve.ts)必须走**同一条**提交链 —— 第二条提交
|
|
19
19
|
* 路径就是第二个写者,而这条链上挂着 durable taskId 幂等重放、lease/治理窗 pre-admission、
|
package/dist/http/routes/runs.js
CHANGED
|
@@ -16,8 +16,8 @@ import { idemCallerOf, idemKeyOf, inflightKeyOf, submissionIdemOf } from "../ide
|
|
|
16
16
|
import { streamSseLog } from "../sse-log.js";
|
|
17
17
|
import { bindSseLifecycle } from "../sse-lifecycle.js";
|
|
18
18
|
import { buildApprovalPreamble, buildApprovalPreambleSseFrames, readClosedWordSeat, storedCardDemandsAPerson } from "../../approval-card.js";
|
|
19
|
-
import { heldAskOf,
|
|
20
|
-
import { ASK_DECISION_CONSUMER_ABSENT, approvalPreambleReplays, outcomeOfDecidedRow, parkSessionOf, presentedApprovalFrameFamily, resolveStreamApprovalGate } from "../../tool-approval.js";
|
|
19
|
+
import { heldAskOf, readDecider, retiredDecisionKeyFacts, DECIDED_BY_NOT_IN_PROOF, POLICY_CANNOT_ALLOW_PERSON_ASK } from "../../host-decision.js";
|
|
20
|
+
import { ASK_DECISION_CONSUMER_ABSENT, approvalPreambleReplays, decidedRowFacts, outcomeOfDecidedRow, parkSessionOf, presentedApprovalFrameFamily, resolveStreamApprovalGate } from "../../tool-approval.js";
|
|
21
21
|
import { MAX_DECISION_NOTE_CHARS, noteLandedOnRow, noteRecordedReceipt } from "../../approval-ask-machine.js";
|
|
22
22
|
import { askRowEndingCause } from "../../approval-deny-reasons.js";
|
|
23
23
|
import { normalizeRunEventType, screenedStoredEventData } from "../../trace/project.js";
|
|
@@ -30,16 +30,16 @@ import { ActorAssertionWire } from "@sema-agent/settings-schema";
|
|
|
30
30
|
import * as facts from "../../capability-facts.js";
|
|
31
31
|
import { assertNever } from "../route-ctx.js";
|
|
32
32
|
import { readRunFace } from "../run-read-face.js";
|
|
33
|
-
import { replayOfExistingRun } from "../submit-replay.js";
|
|
33
|
+
import { replayOfExistingRun, replayOfKey } from "../submit-replay.js";
|
|
34
34
|
import { mintAndDriveDurableRun } from "../durable-run-leg.js";
|
|
35
35
|
import { SUBMISSION_CLAIM_FACE } from "../execution-context.js";
|
|
36
|
-
import { admitRunById,
|
|
36
|
+
import { admitRunById, admitRunByIdem, enter, readVisibleRun, sessionFactsReadOf } from "../owner-access.js";
|
|
37
37
|
import { keyAdmission, ownerCellOf, recoveredSubject } from "../../owner-faces.js";
|
|
38
|
+
import { engineScopeOfOwner } from "../../engine-identity.js";
|
|
38
39
|
import { personOf } from "../../owner-brands.js";
|
|
39
40
|
import { withSubject } from "../../observability/principal-context.js";
|
|
40
41
|
import { readResumeCtx, resumeCtxUnreadableAnswer } from "../resume-ctx-read.js";
|
|
41
42
|
import { storedBodyReplayAnswer, storedBodyReplayLogFields } from "../checkpoint-ctx.js";
|
|
42
|
-
import { headReadOf } from "../../session-incarnation.js";
|
|
43
43
|
import { serviceVersion } from "../../service-version.js";
|
|
44
44
|
import { storedBodyReplayRefusal } from "../stored-body-replay.js";
|
|
45
45
|
import { haltBodyIssue, steerBodyKeyIssue } from "../../request-key-closure.js";
|
|
@@ -50,6 +50,11 @@ const STEER_PRIORITY_CHOICES = STEER_PRIORITY_WORDS.length <= 2 ? STEER_PRIORITY
|
|
|
50
50
|
const ASK_PARKING_RETRY_AFTER_SEC = 2;
|
|
51
51
|
const ASK_ACTOR_LABEL_MAX = 256;
|
|
52
52
|
const AskDecisionActorSchema = ActorAssertionWire.strip();
|
|
53
|
+
function mirrorRetryAfter(res, body) {
|
|
54
|
+
const retryAfterSec = body !== null && typeof body === "object" ? body.retryAfterSec : undefined;
|
|
55
|
+
if (typeof retryAfterSec === "number" && Number.isFinite(retryAfterSec) && retryAfterSec >= 0)
|
|
56
|
+
res.setHeader("retry-after", String(Math.ceil(retryAfterSec)));
|
|
57
|
+
}
|
|
53
58
|
const AskDecisionBodySchema = z
|
|
54
59
|
.object({
|
|
55
60
|
decision: z.enum(["approve", "deny"]),
|
|
@@ -106,7 +111,7 @@ function sendHandleMiss(res, run, thisInstanceId) {
|
|
|
106
111
|
}
|
|
107
112
|
return false;
|
|
108
113
|
}
|
|
109
|
-
async function streamRunEvents(req, res, deps, runStore, taskId) {
|
|
114
|
+
async function streamRunEvents(req, res, deps, runStore, entry, taskId) {
|
|
110
115
|
await streamSseLog(req, res, {
|
|
111
116
|
preamble: async (signal) => {
|
|
112
117
|
const gate = resolveStreamApprovalGate({
|
|
@@ -135,10 +140,7 @@ async function streamRunEvents(req, res, deps, runStore, taskId) {
|
|
|
135
140
|
return buildApprovalPreambleSseFrames(frames);
|
|
136
141
|
},
|
|
137
142
|
onPreambleFailure: (reason, err) => deps.logger?.warn?.("approval_preamble_failed", { taskId, reason, face: "run.events", error: err instanceof Error ? err.message : String(err ?? "") }),
|
|
138
|
-
statusOf: async (id) =>
|
|
139
|
-
const run = await runStore.getRun(id);
|
|
140
|
-
return run ? runRowAt("run-events", runStore, run) : undefined;
|
|
141
|
-
},
|
|
143
|
+
statusOf: async (id) => (await readVisibleRun(entry, runStore, id))?.row,
|
|
142
144
|
getEvents: (id, after) => runStore.getEvents(id, after),
|
|
143
145
|
formatEvent: (ev) => {
|
|
144
146
|
const type = normalizeRunEventType(ev.type);
|
|
@@ -208,9 +210,9 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
208
210
|
return;
|
|
209
211
|
}
|
|
210
212
|
const inflight = idemCache.peek(inflightKeyOf(idem, "durable", clientTaskId));
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
213
|
+
const replayed = inflight ? undefined : await replayOfKey({ idemKey: idem.key }, { subject: submitter, idem, ...(clientTaskId !== undefined ? { clientTaskId } : {}) }, "durable", deps, runStore);
|
|
214
|
+
const resp = inflight ? await inflight : replayed;
|
|
215
|
+
if (resp !== undefined) {
|
|
214
216
|
sendJson(res, resp.status, resp.body);
|
|
215
217
|
return;
|
|
216
218
|
}
|
|
@@ -246,26 +248,23 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
246
248
|
const entry = enter(req, res, deps, match.decl.id);
|
|
247
249
|
if (entry === undefined)
|
|
248
250
|
return;
|
|
249
|
-
let
|
|
250
|
-
let pathId;
|
|
251
|
+
let admitted;
|
|
251
252
|
if (match.decl.id === "runs-by-idem") {
|
|
252
253
|
const rawKey = new URLSearchParams(match.search).get("idempotencyKey");
|
|
253
254
|
if (!rawKey) {
|
|
254
255
|
sendError(res, 400, "request.query_invalid", "idempotencyKey is required: pass the raw Idempotency-Key the submission was sent with");
|
|
255
256
|
return;
|
|
256
257
|
}
|
|
257
|
-
|
|
258
|
+
admitted = await admitRunByIdem(entry, res, runStore, idemKeyOf(rawKey, idemCallerOf(req, ctx), "run"));
|
|
258
259
|
}
|
|
259
260
|
else {
|
|
260
|
-
|
|
261
|
-
run = await runStore.getRun(pathId);
|
|
261
|
+
admitted = await admitRunById(entry, res, runStore, match.params.taskId);
|
|
262
262
|
}
|
|
263
|
-
const admitted = await admitRunRow(entry, res, runStore, run, pathId);
|
|
264
263
|
if (admitted === undefined)
|
|
265
264
|
return;
|
|
266
265
|
const taskId = admitted.row.taskId;
|
|
267
266
|
if (match.decl.id === "run-events") {
|
|
268
|
-
await streamRunEvents(req, res, deps, runStore, taskId);
|
|
267
|
+
await streamRunEvents(req, res, deps, runStore, entry, taskId);
|
|
269
268
|
}
|
|
270
269
|
else {
|
|
271
270
|
sendJson(res, 200, await readRunFace(deps, runStore, admitted.row));
|
|
@@ -296,7 +295,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
296
295
|
if (token) {
|
|
297
296
|
const won = (await expireCardUnderStoredScope(cs, token)) === CARD_EXPIRE_OUTCOME.expired;
|
|
298
297
|
if (!won) {
|
|
299
|
-
const now = await rs
|
|
298
|
+
const now = (await readVisibleRun(entry, rs, taskId))?.row;
|
|
300
299
|
const st = now?.status;
|
|
301
300
|
if (st !== undefined && (isParkedRunStatus(st) || st === "running")) {
|
|
302
301
|
sendError(res, 409, "conflict.approval_settled", "pending approval was settled concurrently (decided or expired) — re-check the run and retry cancel if it is still active", { taskId, status: st });
|
|
@@ -310,7 +309,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
310
309
|
else {
|
|
311
310
|
const claimed = await rs.markResuming(taskId, deps.instanceId ?? "default");
|
|
312
311
|
if (!claimed) {
|
|
313
|
-
const now = await rs
|
|
312
|
+
const now = (await readVisibleRun(entry, rs, taskId))?.row;
|
|
314
313
|
const st = now?.status;
|
|
315
314
|
if (st !== undefined && (st === "running" || isParkedRunStatus(st))) {
|
|
316
315
|
sendError(res, 409, "conflict.approval_settled", "pending approval was settled concurrently (decided or expired) — re-check the run and retry cancel if it is still active", { taskId, status: st });
|
|
@@ -350,7 +349,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
350
349
|
sendError(res, 500, "internal.cancel_not_terminalized", `cancel progressed (${note}) but could not terminalize the run row (retried) — retry cancel; a stuck row is reaped after the stale window (${e instanceof Error ? e.message : String(e)})`, { taskId });
|
|
351
350
|
return;
|
|
352
351
|
}
|
|
353
|
-
const finalRow = await rs
|
|
352
|
+
const finalRow = (await readVisibleRun(entry, rs, taskId).catch(() => undefined))?.row;
|
|
354
353
|
if (finalRow && finalRow.errorCode !== "cancelled" && isTerminalRunStatus(finalRow.status)) {
|
|
355
354
|
sendJson(res, 202, { taskId, status: finalRow.status, errorCode: finalRow.errorCode ?? null, cancelRequested: finalRow.cancelRequested, note: `session unlocked; the run was terminalized concurrently (${finalRow.errorCode ?? finalRow.status}) before this cancel's write — reporting the actual ledger state` });
|
|
356
355
|
return;
|
|
@@ -361,7 +360,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
361
360
|
let flagged = await runStore.requestCancel(taskId, run.owner);
|
|
362
361
|
const CANCEL_RECLASSIFY_ATTEMPTS = 3;
|
|
363
362
|
for (let attempt = 0; !flagged; attempt++) {
|
|
364
|
-
const now = await runStore
|
|
363
|
+
const now = (await readVisibleRun(entry, runStore, taskId))?.row;
|
|
365
364
|
if (now !== undefined && isParkedRunStatus(now.status)) {
|
|
366
365
|
await cancelSuspended(now.result);
|
|
367
366
|
return;
|
|
@@ -505,7 +504,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
505
504
|
}
|
|
506
505
|
if (code !== "steering.not_running")
|
|
507
506
|
throw e;
|
|
508
|
-
const freshBeforePark = await runStore
|
|
507
|
+
const freshBeforePark = (await readVisibleRun(entry, runStore, taskId).catch(() => undefined))?.row;
|
|
509
508
|
const raced = await tryPark();
|
|
510
509
|
if (raced === "parked") {
|
|
511
510
|
sendParked(freshBeforePark?.status ?? run.status);
|
|
@@ -554,8 +553,8 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
554
553
|
}
|
|
555
554
|
return;
|
|
556
555
|
}
|
|
557
|
-
const
|
|
558
|
-
if (deps.checkpointStore &&
|
|
556
|
+
const sessionFactsOf = sessionFactsReadOf(deps.sessionStorage);
|
|
557
|
+
if (deps.checkpointStore && sessionFactsOf) {
|
|
559
558
|
const activeTaskId = await runStore.getActiveTaskId?.(run.sessionId).catch(() => undefined);
|
|
560
559
|
if (activeTaskId !== undefined && activeTaskId !== null && activeTaskId !== taskId) {
|
|
561
560
|
sendNotRunning(`run is ${run.status} and its session has an ACTIVE run (${activeTaskId}) — steer that run instead`);
|
|
@@ -605,7 +604,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
605
604
|
mintResult.duplicateKey = true;
|
|
606
605
|
return;
|
|
607
606
|
}
|
|
608
|
-
const leafId = await
|
|
607
|
+
const leafId = await sessionFactsOf(run.sessionId).then((h) => h?.leafId).catch(() => undefined);
|
|
609
608
|
if (leafId === undefined || leafId === null)
|
|
610
609
|
return;
|
|
611
610
|
const resumeRead = await readResumeCtx(cs.getCtx(run.sessionId), { sessionId: run.sessionId, opener: deps.checkpointCtxSealing });
|
|
@@ -779,7 +778,7 @@ export async function handleRuns(req, res, match, ctx) {
|
|
|
779
778
|
catch (e) {
|
|
780
779
|
if (e.code !== "steering.not_running")
|
|
781
780
|
throw e;
|
|
782
|
-
const freshRun = await runStore
|
|
781
|
+
const freshRun = (await readVisibleRun(entry, runStore, taskId).catch(() => undefined))?.row;
|
|
783
782
|
sendNoLiveTurn(freshRun?.status ?? run.status, true);
|
|
784
783
|
return;
|
|
785
784
|
}
|
|
@@ -892,7 +891,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
892
891
|
if (!gated)
|
|
893
892
|
return;
|
|
894
893
|
const { run } = gated;
|
|
895
|
-
const out = await subagentTaskOutput(target, { owner: runId, scope: run.owner
|
|
894
|
+
const out = await subagentTaskOutput(target, { owner: runId, scope: engineScopeOfOwner(run.owner), ...(run.sessionId ? { sessionId: run.sessionId } : {}) });
|
|
896
895
|
const details = out.details;
|
|
897
896
|
if (details?.error === "not_found" || details?.type !== "background_agent") {
|
|
898
897
|
if (!sendHandleMiss(res, run, deps.instanceId))
|
|
@@ -921,7 +920,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
921
920
|
return;
|
|
922
921
|
const { run } = gatedTail;
|
|
923
922
|
const it = defaultSubagentTailBus.subscribe(target);
|
|
924
|
-
const probe = await subagentTaskOutput(target, { owner: runId, scope: run.owner
|
|
923
|
+
const probe = await subagentTaskOutput(target, { owner: runId, scope: engineScopeOfOwner(run.owner), ...(run.sessionId ? { sessionId: run.sessionId } : {}) });
|
|
925
924
|
const probeDetails = probe.details;
|
|
926
925
|
if (probeDetails?.error === "not_found" || probeDetails?.type !== "background_agent") {
|
|
927
926
|
void it.return?.();
|
|
@@ -989,7 +988,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
989
988
|
return;
|
|
990
989
|
const { run } = gatedB;
|
|
991
990
|
const q = new URLSearchParams(match.search);
|
|
992
|
-
const access = { owner: runId, scope: run.owner
|
|
991
|
+
const access = { owner: runId, scope: engineScopeOfOwner(run.owner), ...(run.sessionId ? { sessionId: run.sessionId } : {}) };
|
|
993
992
|
if (q.get("filter") !== null) {
|
|
994
993
|
sendError(res, 400, "request.param_unsupported", "filter is not accepted on the wire — fetch the output and filter client-side (note: the wire serves the clipped projection)");
|
|
995
994
|
return;
|
|
@@ -1196,10 +1195,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1196
1195
|
}
|
|
1197
1196
|
const body = await readJson(req);
|
|
1198
1197
|
const { status, body: respBody } = await approvalFact.coordinator.respond(id, principal, body, req, { readRootGrantAccepted: facts.readRootGrant(deps).available });
|
|
1199
|
-
|
|
1200
|
-
if (typeof retryAfterSec === "number" && Number.isFinite(retryAfterSec) && retryAfterSec >= 0) {
|
|
1201
|
-
res.setHeader("retry-after", String(Math.ceil(retryAfterSec)));
|
|
1202
|
-
}
|
|
1198
|
+
mirrorRetryAfter(res, respBody);
|
|
1203
1199
|
sendJson(res, status, respBody);
|
|
1204
1200
|
return;
|
|
1205
1201
|
}
|
|
@@ -1212,6 +1208,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1212
1208
|
return;
|
|
1213
1209
|
}
|
|
1214
1210
|
const askStore = streamFact.askStore;
|
|
1211
|
+
const coordinator = streamFact.coordinator;
|
|
1215
1212
|
const principal = gatedSubject(req, deps.config);
|
|
1216
1213
|
if (deps.config.requirePrincipal && principal === undefined) {
|
|
1217
1214
|
sendPrincipalRefusal(res, req, deps.config);
|
|
@@ -1254,7 +1251,8 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1254
1251
|
askNotFound();
|
|
1255
1252
|
return;
|
|
1256
1253
|
}
|
|
1257
|
-
const
|
|
1254
|
+
const callerIsOperator = explicitOperatorOk(principal === undefined ? undefined : personOf(principal), deps.config);
|
|
1255
|
+
const askAdmission = keyAdmission("ask.decide", { subject: principal, operator: callerIsOperator }, ownerCellOf(row0.owner));
|
|
1258
1256
|
if (askAdmission === undefined) {
|
|
1259
1257
|
askNotFound();
|
|
1260
1258
|
return;
|
|
@@ -1266,7 +1264,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1266
1264
|
via: askAdmission === "row" ? "owner" : "operator",
|
|
1267
1265
|
};
|
|
1268
1266
|
const decidedRowIsAuthoritative = (row) => {
|
|
1269
|
-
if (row
|
|
1267
|
+
if (decidedRowFacts(row) === undefined) {
|
|
1270
1268
|
deps.logger?.error?.("ask_decision_row_not_authoritative", {
|
|
1271
1269
|
taskId,
|
|
1272
1270
|
askId,
|
|
@@ -1297,8 +1295,8 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1297
1295
|
const replayDecided = (row) => {
|
|
1298
1296
|
const storedActor = projectDecisionActor(row.decisionActor);
|
|
1299
1297
|
sendJson(res, 200, {
|
|
1300
|
-
askId
|
|
1301
|
-
taskId
|
|
1298
|
+
askId,
|
|
1299
|
+
taskId,
|
|
1302
1300
|
decision: row.decision,
|
|
1303
1301
|
decidedAtMs: row.decidedAtMs,
|
|
1304
1302
|
...(storedActor ? { actor: storedActor } : {}),
|
|
@@ -1306,7 +1304,78 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1306
1304
|
...noteReceipt(row),
|
|
1307
1305
|
});
|
|
1308
1306
|
};
|
|
1309
|
-
const
|
|
1307
|
+
const policyMayNotApprove = (row) => body.decision === "approve" && policyCannotAnswer(heldAskOf(storedCardDemandsAPerson(row.cardJson)), decider.decidedBy);
|
|
1308
|
+
const refusePolicyApprove = () => sendError(res, 400, "request.field_conflict", POLICY_CANNOT_ALLOW_PERSON_ASK, fieldConflictFacts("policy_person_ask", ["decidedBy", "decision"]));
|
|
1309
|
+
const conflictWithFirst = (row) => {
|
|
1310
|
+
const first = projectDecisionActor(row.decisionActor);
|
|
1311
|
+
sendError(res, 409, "conflict.ask_decided", "this ask was already decided — the first decision stands and is echoed here", {
|
|
1312
|
+
decision: row.decision,
|
|
1313
|
+
decidedAtMs: row.decidedAtMs,
|
|
1314
|
+
...(first ? { actor: first } : {}),
|
|
1315
|
+
...decisionNoteEcho(row),
|
|
1316
|
+
});
|
|
1317
|
+
};
|
|
1318
|
+
const answerParked = async (row) => {
|
|
1319
|
+
const answer = await coordinator.decideParkedAsk(askStore, row, {
|
|
1320
|
+
write: { decision: body.decision, decider, ...(body.note !== undefined ? { note: body.note } : {}), actor, ...(body.idempotencyKey !== undefined ? { idempotencyKey: body.idempotencyKey } : {}) },
|
|
1321
|
+
...(body.decision === "approve" && hasUpdatedInput ? { updatedInput: body.updatedInput } : {}),
|
|
1322
|
+
...(principal !== undefined ? { principal } : {}),
|
|
1323
|
+
operator: callerIsOperator,
|
|
1324
|
+
policyMayNotApprove: policyMayNotApprove(row),
|
|
1325
|
+
httpReq: req,
|
|
1326
|
+
}, body.idempotencyKey);
|
|
1327
|
+
switch (answer.kind) {
|
|
1328
|
+
case "standing": {
|
|
1329
|
+
const first = { decision: answer.decision, decidedAtMs: answer.decidedAtMs, decisionActor: answer.actor ?? null, decisionNote: answer.decisionNote ?? null };
|
|
1330
|
+
if (answer.byThisRequest)
|
|
1331
|
+
replayDecided(first);
|
|
1332
|
+
else
|
|
1333
|
+
conflictWithFirst(first);
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
case "refused":
|
|
1337
|
+
if (answer.status === 404) {
|
|
1338
|
+
askNotFound();
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
mirrorRetryAfter(res, answer.body);
|
|
1342
|
+
sendJson(res, answer.status, answer.body);
|
|
1343
|
+
return;
|
|
1344
|
+
case "gone":
|
|
1345
|
+
askNotFound();
|
|
1346
|
+
return;
|
|
1347
|
+
case "policy_refused":
|
|
1348
|
+
refusePolicyApprove();
|
|
1349
|
+
return;
|
|
1350
|
+
case "gate_only":
|
|
1351
|
+
sendError(res, 410, "gone.ask_parked", "the in-stream window closed and this ask was parked onto the durable approval gate — decide it through that gate for the session echoed here", {
|
|
1352
|
+
sessionId: parkSessionOf(row),
|
|
1353
|
+
gateBoundCallId: row.gateBoundCallId,
|
|
1354
|
+
gateBoundInputHash: row.gateBoundInputHash,
|
|
1355
|
+
});
|
|
1356
|
+
return;
|
|
1357
|
+
case "accepted": {
|
|
1358
|
+
const recorded = answer.recorded ?? { decisionNote: null };
|
|
1359
|
+
sendJson(res, 200, {
|
|
1360
|
+
...answer.body,
|
|
1361
|
+
askId,
|
|
1362
|
+
taskId,
|
|
1363
|
+
decision: body.decision,
|
|
1364
|
+
decidedAtMs: answer.recorded?.decidedAtMs ?? Date.now(),
|
|
1365
|
+
actor,
|
|
1366
|
+
accepted: "parked_redeemed",
|
|
1367
|
+
...decisionNoteEcho(recorded),
|
|
1368
|
+
...noteReceipt(recorded),
|
|
1369
|
+
});
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
default: {
|
|
1373
|
+
const unhandled = answer;
|
|
1374
|
+
throw new Error(`unhandled parked ask answer: ${JSON.stringify(unhandled)}`);
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
};
|
|
1378
|
+
const sendTerminal = async (row) => {
|
|
1310
1379
|
switch (row.state) {
|
|
1311
1380
|
case "DECIDED": {
|
|
1312
1381
|
if (!syncLiveFromDecidedRow(row))
|
|
@@ -1315,21 +1384,11 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1315
1384
|
replayDecided(row);
|
|
1316
1385
|
return;
|
|
1317
1386
|
}
|
|
1318
|
-
|
|
1319
|
-
sendError(res, 409, "conflict.ask_decided", "this ask was already decided — the first decision stands and is echoed here", {
|
|
1320
|
-
decision: row.decision,
|
|
1321
|
-
decidedAtMs: row.decidedAtMs,
|
|
1322
|
-
...(first ? { actor: first } : {}),
|
|
1323
|
-
...decisionNoteEcho(row),
|
|
1324
|
-
});
|
|
1387
|
+
conflictWithFirst(row);
|
|
1325
1388
|
return;
|
|
1326
1389
|
}
|
|
1327
1390
|
case "PARKED":
|
|
1328
|
-
|
|
1329
|
-
sessionId: parkSessionOf(row),
|
|
1330
|
-
gateBoundCallId: row.gateBoundCallId,
|
|
1331
|
-
gateBoundInputHash: row.gateBoundInputHash,
|
|
1332
|
-
});
|
|
1391
|
+
await answerParked(row);
|
|
1333
1392
|
return;
|
|
1334
1393
|
case "DENIED":
|
|
1335
1394
|
case "VOID": {
|
|
@@ -1374,23 +1433,23 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1374
1433
|
}
|
|
1375
1434
|
}
|
|
1376
1435
|
if (row0.state !== "STREAM_PENDING") {
|
|
1377
|
-
sendTerminal(row0);
|
|
1436
|
+
await sendTerminal(row0);
|
|
1378
1437
|
return;
|
|
1379
1438
|
}
|
|
1380
|
-
if (
|
|
1381
|
-
|
|
1439
|
+
if (policyMayNotApprove(row0)) {
|
|
1440
|
+
refusePolicyApprove();
|
|
1382
1441
|
return;
|
|
1383
1442
|
}
|
|
1384
1443
|
let outcome;
|
|
1385
1444
|
const releaseEditMark = body.decision === "approve" && hasUpdatedInput ? deps.toolApproval?.markEditedDecisionInFlight(askId) : undefined;
|
|
1386
1445
|
try {
|
|
1387
|
-
outcome = await
|
|
1446
|
+
outcome = await coordinator.writeAskDecision(askStore, askId, { kind: "live", batchId: row0.batchId }, row0.owner, {
|
|
1388
1447
|
decision: body.decision,
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
...
|
|
1393
|
-
...(
|
|
1448
|
+
decider,
|
|
1449
|
+
actor,
|
|
1450
|
+
...(body.note !== undefined ? { note: body.note } : {}),
|
|
1451
|
+
...(body.idempotencyKey !== undefined ? { idempotencyKey: body.idempotencyKey } : {}),
|
|
1452
|
+
...(hasUpdatedInput ? { updatedInput: body.updatedInput } : {}),
|
|
1394
1453
|
});
|
|
1395
1454
|
}
|
|
1396
1455
|
catch (err) {
|
|
@@ -1450,7 +1509,7 @@ export async function handleRunVerbs(req, res, match, ctx) {
|
|
|
1450
1509
|
askNotFound();
|
|
1451
1510
|
return;
|
|
1452
1511
|
}
|
|
1453
|
-
sendTerminal(outcome.row);
|
|
1512
|
+
await sendTerminal(outcome.row);
|
|
1454
1513
|
return;
|
|
1455
1514
|
}
|
|
1456
1515
|
if (!decidedRowIsAuthoritative(outcome.row))
|
|
@@ -1509,9 +1568,9 @@ async function createDurableRunHeld(req, res, ctx, prepared, idem) {
|
|
|
1509
1568
|
const submitter = gatedSubject(req, deps.config);
|
|
1510
1569
|
const caller = { subject: submitter, idem, ...(clientTaskId !== undefined ? { clientTaskId } : {}) };
|
|
1511
1570
|
if (clientTaskId) {
|
|
1512
|
-
const
|
|
1513
|
-
if (
|
|
1514
|
-
return
|
|
1571
|
+
const replayed = await replayOfKey({ taskId: clientTaskId }, caller, "durable", deps, runStore);
|
|
1572
|
+
if (replayed !== undefined)
|
|
1573
|
+
return replayed;
|
|
1515
1574
|
}
|
|
1516
1575
|
if ((await leaseDenied(req, res, seat)) || (await usageWindowDenied(req, res, seat)))
|
|
1517
1576
|
return null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { memorySyncReportOf } from "@sema-agent/core";
|
|
2
2
|
import { sendJson, sendError } from "../send.js";
|
|
3
|
-
import { admitSessionById, enter } from "../owner-access.js";
|
|
3
|
+
import { admitSessionById, enter, latestRunIdOf, readVisibleSession } from "../owner-access.js";
|
|
4
4
|
import { assertNever } from "../route-ctx.js";
|
|
5
5
|
import * as facts from "../../capability-facts.js";
|
|
6
6
|
import { leafOfAdmittedHead } from "../../session-incarnation.js";
|
|
@@ -94,7 +94,6 @@ export async function handleSessionMemorySync(req, res, match, ctx) {
|
|
|
94
94
|
sendError(res, 400, "request.path_malformed", "session id segment is not valid percent-encoding");
|
|
95
95
|
return;
|
|
96
96
|
}
|
|
97
|
-
const readHead = () => sessionStorage.headOf(sessionId);
|
|
98
97
|
const admitted = await admitSessionById(entry, res, sessionStorage, sessionId);
|
|
99
98
|
if (admitted === undefined)
|
|
100
99
|
return;
|
|
@@ -122,10 +121,10 @@ export async function handleSessionMemorySync(req, res, match, ctx) {
|
|
|
122
121
|
const quiet = async () => {
|
|
123
122
|
if ((await runStore.getActiveTaskId(sessionId)) !== undefined)
|
|
124
123
|
return false;
|
|
125
|
-
if ((await runStore
|
|
124
|
+
if ((await latestRunIdOf(runStore, sessionId)) !== observedTaskId)
|
|
126
125
|
return false;
|
|
127
|
-
const now = await
|
|
128
|
-
return now !== undefined && leafOfAdmittedHead(now) === sourceRevision;
|
|
126
|
+
const now = await readVisibleSession(entry, sessionStorage, sessionId);
|
|
127
|
+
return now !== undefined && leafOfAdmittedHead(now.row) === sourceRevision;
|
|
129
128
|
};
|
|
130
129
|
const fenced = () => reportOf({ target, sourceRevision, scopes, refused: { code: "session_active", message: SESSION_ACTIVE_SYNC_MESSAGE } });
|
|
131
130
|
let report;
|
|
@@ -13,6 +13,7 @@ import { type ImportAnchor, type StagingHandle } from "../../session-sync-kernel
|
|
|
13
13
|
import type { DurableOwnerKey } from "../../owner-brands.js";
|
|
14
14
|
import type { RouteCtx, RouteMatch, RouteIdsOf } from "../route-ctx.js";
|
|
15
15
|
import { type SessionRowPatch } from "../../session-row.js";
|
|
16
|
+
import { type SessionFace } from "../../session-incarnation.js";
|
|
16
17
|
export type PendingStaging = {
|
|
17
18
|
handle: StagingHandle;
|
|
18
19
|
realSessionId: string;
|
|
@@ -33,9 +34,9 @@ export type PendingStaging = {
|
|
|
33
34
|
/** The principal that opened this staging, kept as the handle's owner key (`null` = a fleet caller opened it) — a different caller may not drive it
|
|
34
35
|
* (404, no oracle; compared through `owner-faces.ts` `sameKey` only). */
|
|
35
36
|
openedBy: DurableOwnerKey | null;
|
|
36
|
-
/** The
|
|
37
|
-
* this same
|
|
38
|
-
|
|
37
|
+
/** The live occupant the gate judged when it opened this staging (owner ∧ incarnation, the head read: `undefined` = no live session) — the commit lands only on
|
|
38
|
+
* this same occupant (`StagedCommitOptions.expectedOccupant`, `session-sync-kernel.ts`); `owner` above (the re-stamped importing principal) is derived from its owner for a fleet caller. */
|
|
39
|
+
expectedOccupant: SessionFace | undefined;
|
|
39
40
|
/** 开这张暂存时占下的导入租约的键({@link importLeaseKey});续期与放掉都按它,不再从会话 id 重算。 */
|
|
40
41
|
leaseKey: string;
|
|
41
42
|
};
|