@sema-agent/server 7.132.0 → 7.134.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 +353 -0
- package/README.md +8 -9
- package/README.zh-CN.md +7 -6
- package/USAGE.md +301 -64
- package/deploy/sema-up/README.md +35 -1
- package/deploy/sema-up/chart/Chart.yaml +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +15 -0
- package/deploy/sema-up/chart/templates/_helpers.tpl +129 -0
- package/deploy/sema-up/chart/templates/sealed-key.yaml +24 -0
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +19 -2
- package/deploy/sema-up/chart/templates/server.yaml +19 -2
- package/deploy/sema-up/chart/values-full-single.yaml +5 -1
- package/deploy/sema-up/chart/values.yaml +34 -0
- package/deploy/sema-up/stack/compose.yaml +3 -0
- package/deploy/sema-up/stack/sema-stack-cluster.yaml +4 -2
- package/dist/adoption/plan.d.ts +3 -2
- package/dist/adoption/plan.js +7 -5
- package/dist/adoption/runner.js +3 -10
- package/dist/adoption/sql.d.ts +3 -2
- package/dist/adoption/sql.js +3 -5
- package/dist/adoption/wire.d.ts +4 -1
- package/dist/adoption/wire.js +1 -0
- package/dist/approval-ask-audit-store.d.ts +32 -14
- package/dist/approval-ask-audit-store.js +272 -74
- package/dist/approval-ask-machine.d.ts +15 -0
- package/dist/approval-ask-machine.js +6 -0
- package/dist/approval-ask-retention.d.ts +136 -0
- package/dist/approval-ask-retention.js +102 -0
- package/dist/approval-card.d.ts +83 -23
- package/dist/approval-card.js +45 -15
- package/dist/approval-content-kind.d.ts +5 -2
- package/dist/approval-content-kind.js +16 -3
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval-gate-currency.d.ts +72 -0
- package/dist/approval-gate-currency.js +94 -0
- package/dist/approval.d.ts +15 -0
- package/dist/approval.js +55 -17
- package/dist/audit.d.ts +27 -10
- package/dist/audit.js +12 -16
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/coordinators.d.ts +6 -1
- package/dist/boot/coordinators.js +6 -3
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/execution-env.js +9 -7
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.d.ts +2 -0
- package/dist/boot/leader.js +4 -1
- package/dist/boot/memory-boundary.js +2 -2
- package/dist/boot/memory-consolidation.d.ts +5 -4
- package/dist/boot/memory-consolidation.js +7 -6
- package/dist/boot/org-delivery.d.ts +28 -0
- package/dist/boot/org-delivery.js +20 -0
- package/dist/boot/read-deny-anchor-audit.js +2 -2
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +3 -0
- package/dist/boot/resolve-spec.js +60 -81
- package/dist/boot/runner-deps.d.ts +18 -5
- package/dist/boot/runner-deps.js +10 -0
- package/dist/boot/session-faces.d.ts +1 -0
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-06-runners.d.ts +6 -3
- package/dist/boot/stage-06-runners.js +20 -4
- package/dist/boot/stage-07-capability-layer.d.ts +4 -1
- package/dist/boot/stage-07-capability-layer.js +24 -3
- package/dist/boot/stage-08-reapers.d.ts +4 -1
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +5 -1
- package/dist/boot/stage-09-leader.js +2 -2
- package/dist/boot/stage-10-http-server.d.ts +5 -1
- package/dist/boot/stage-10-http-server.js +6 -6
- package/dist/boot/stores.d.ts +8 -0
- package/dist/boot/stores.js +10 -14
- package/dist/boot/web-admin.d.ts +10 -0
- package/dist/boot/web-admin.js +162 -65
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +8 -3
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/budget.js +5 -1
- package/dist/caller-text-echo.d.ts +11 -6
- package/dist/caller-text-echo.js +10 -12
- package/dist/canonical-json.d.ts +2 -41
- package/dist/canonical-json.js +2 -13
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +21 -0
- package/dist/capabilities/hands-lane.js +10 -0
- package/dist/capabilities/mcp-probe.d.ts +36 -4
- package/dist/capabilities/mcp-probe.js +29 -6
- package/dist/capabilities/scenarios.d.ts +63 -7
- package/dist/capabilities/scenarios.js +39 -7
- package/dist/capability-facts.d.ts +36 -4
- package/dist/capability-facts.js +30 -4
- package/dist/center-config-tier.d.ts +69 -0
- package/dist/center-config-tier.js +42 -0
- package/dist/checkpoint-ctx-seal-m28.d.ts +42 -0
- package/dist/checkpoint-ctx-seal-m28.js +19 -0
- package/dist/checkpoint-identity.d.ts +16 -0
- package/dist/checkpoint-identity.js +19 -0
- package/dist/config-catalog.d.ts +17 -10
- package/dist/config-catalog.js +43 -28
- package/dist/config-d-migration.d.ts +3 -1
- package/dist/config-d-migration.js +2 -2
- package/dist/config-dir-trust.d.ts +114 -0
- package/dist/config-dir-trust.js +388 -0
- package/dist/config-invariants.d.ts +18 -5
- package/dist/config-invariants.js +35 -3
- package/dist/config-provider.d.ts +6 -1
- package/dist/config-provider.js +6 -2
- package/dist/config-types.d.ts +71 -14
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +121 -59
- package/dist/delegated-session-owner.d.ts +185 -0
- package/dist/delegated-session-owner.js +119 -0
- package/dist/device-protocol.d.ts +5 -3
- package/dist/device-protocol.js +1 -1
- package/dist/device-ws-hub.js +21 -2
- package/dist/device-ws-protocol.d.ts +70 -6
- package/dist/device-ws-protocol.js +50 -23
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/execution-lane-caps.d.ts +49 -10
- package/dist/execution-lane-caps.js +43 -4
- package/dist/field-conflict.d.ts +44 -0
- package/dist/field-conflict.js +21 -0
- package/dist/file-history-disclosure.d.ts +34 -5
- package/dist/file-history-disclosure.js +2 -2
- package/dist/fleet/fleet-bus.d.ts +84 -6
- package/dist/fleet/fleet-bus.js +42 -9
- package/dist/hooks/classic-stations.d.ts +10 -5
- package/dist/hooks/classic-stations.js +4 -4
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.js +2 -2
- package/dist/hooks/hook-runner.d.ts +127 -25
- package/dist/hooks/hook-runner.js +668 -287
- package/dist/hooks/hook-source.d.ts +44 -0
- package/dist/hooks/hook-source.js +40 -0
- package/dist/http/active-run-conflict.d.ts +5 -13
- package/dist/http/active-run-conflict.js +17 -27
- package/dist/http/admission.js +111 -60
- package/dist/http/approval-sweeps.js +58 -19
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +173 -18
- package/dist/http/checkpoint-ctx.js +171 -12
- package/dist/http/claimed-run.d.ts +4 -3
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +2 -1
- package/dist/http/dispatch.js +13 -7
- package/dist/http/durable-run-leg.d.ts +4 -32
- package/dist/http/durable-run-leg.js +37 -12
- package/dist/http/idempotency.d.ts +2 -2
- package/dist/http/idempotency.js +2 -2
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +78 -27
- package/dist/http/principal-gate.js +64 -14
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/refusal-body.d.ts +12 -0
- package/dist/http/refusal-body.js +11 -0
- package/dist/http/request-guards.d.ts +16 -32
- package/dist/http/request-guards.js +31 -30
- package/dist/http/resume-ctx-read.d.ts +50 -6
- package/dist/http/resume-ctx-read.js +33 -7
- package/dist/http/resume-legs.d.ts +5 -5
- package/dist/http/resume-legs.js +163 -91
- package/dist/http/retired-service-deps.d.ts +43 -0
- package/dist/http/retired-service-deps.js +18 -0
- package/dist/http/route-ctx.d.ts +44 -37
- package/dist/http/route-ctx.js +4 -0
- package/dist/http/route-table.js +2 -0
- package/dist/http/routes/a2a-serve.js +3 -4
- package/dist/http/routes/admin-config-refresh.js +1 -1
- package/dist/http/routes/admin-drain.js +1 -1
- package/dist/http/routes/admin-memory-optout.js +5 -1
- package/dist/http/routes/adoption.js +2 -9
- package/dist/http/routes/agents-roster.js +2 -3
- package/dist/http/routes/approvals-assistant.js +91 -56
- package/dist/http/routes/background.js +3 -2
- package/dist/http/routes/capabilities.js +20 -4
- package/dist/http/routes/config-catalog.d.ts +3 -3
- package/dist/http/routes/config-catalog.js +1 -1
- package/dist/http/routes/devices.js +3 -17
- package/dist/http/routes/diagnostics.d.ts +3 -3
- package/dist/http/routes/diagnostics.js +6 -2
- package/dist/http/routes/fleet.js +4 -4
- package/dist/http/routes/images.js +6 -7
- package/dist/http/routes/leader.js +1 -8
- package/dist/http/routes/mcp-reconnect.d.ts +1 -1
- package/dist/http/routes/mcp-reconnect.js +3 -2
- package/dist/http/routes/memory-bundle.js +1 -1
- package/dist/http/routes/memory-compliance.js +1 -1
- package/dist/http/routes/memory-consolidation.js +1 -1
- package/dist/http/routes/memory-origin.d.ts +1 -1
- package/dist/http/routes/memory-origin.js +1 -1
- package/dist/http/routes/memory-policy.d.ts +1 -1
- package/dist/http/routes/memory-policy.js +3 -2
- package/dist/http/routes/notify-wake.js +8 -21
- package/dist/http/routes/observability.js +2 -2
- package/dist/http/routes/principal-inbox.d.ts +39 -0
- package/dist/http/routes/principal-inbox.js +76 -0
- package/dist/http/routes/retention-ops.js +2 -9
- package/dist/http/routes/rules.js +9 -22
- package/dist/http/routes/runs.d.ts +5 -0
- package/dist/http/routes/runs.js +63 -115
- package/dist/http/routes/session-sync.d.ts +3 -2
- package/dist/http/routes/session-sync.js +53 -48
- package/dist/http/routes/sessions-list.d.ts +1 -1
- package/dist/http/routes/sessions-list.js +3 -4
- package/dist/http/routes/sessions.js +33 -43
- package/dist/http/routes/side-query.js +6 -4
- package/dist/http/routes/tasks.js +71 -30
- package/dist/http/routes/trace-usage.js +7 -9
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/run-declared-families.d.ts +16 -0
- package/dist/http/run-declared-families.js +12 -0
- package/dist/http/send.d.ts +24 -3
- package/dist/http/send.js +14 -2
- package/dist/http/server.d.ts +23 -18
- package/dist/http/server.js +20 -15
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.d.ts +4 -3
- package/dist/http/submit-ctx.js +23 -6
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +17 -10
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/dist/lane-home-probe.d.ts +78 -9
- package/dist/lane-home-probe.js +78 -12
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/leader/wire.d.ts +4 -0
- package/dist/leader/wire.js +8 -7
- package/dist/limit-refusal.d.ts +17 -5
- package/dist/limit-refusal.js +4 -1
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +31 -10
- package/dist/mcp-assertion-header.js +10 -3
- package/dist/memory-origin-fence.js +2 -2
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +23 -16
- package/dist/memory-scope.js +24 -8
- package/dist/memory-sync-client.d.ts +27 -13
- package/dist/memory-sync-client.js +107 -18
- package/dist/model-compat.d.ts +1 -1
- package/dist/model-entry-refusal.d.ts +9 -1
- package/dist/model-entry-refusal.js +6 -1
- package/dist/model-plane-face.d.ts +51 -0
- package/dist/model-plane-face.js +24 -0
- package/dist/model-provider.d.ts +5 -0
- package/dist/model-provider.js +4 -2
- package/dist/model-route-endpoint.d.ts +8 -11
- package/dist/model-route-endpoint.js +4 -7
- package/dist/model-route-env.d.ts +22 -0
- package/dist/model-route-env.js +2 -0
- package/dist/model-route-gap.d.ts +60 -30
- package/dist/model-route-gap.js +21 -15
- package/dist/observability/corrupt-read-seat.d.ts +7 -0
- package/dist/observability/corrupt-read-seat.js +9 -0
- package/dist/observability/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +35 -9
- package/dist/observability/fail-open.js +35 -9
- package/dist/observability/metrics.js +1 -0
- package/dist/observability/prompt-manifest.d.ts +22 -25
- package/dist/observability/prompt-manifest.js +54 -50
- package/dist/observability/tool-trace.js +9 -10
- package/dist/operator-ask.d.ts +10 -0
- package/dist/operator-ask.js +3 -0
- package/dist/orchestration/workflow-agent-session-index.d.ts +12 -12
- package/dist/orchestration/workflow-agent-session-index.js +9 -13
- package/dist/orchestration/workflow-completion-inbox.d.ts +42 -15
- package/dist/orchestration/workflow-completion-inbox.js +13 -0
- package/dist/orchestration/workflow-notify-journal.d.ts +13 -32
- package/dist/orchestration/workflow-notify-journal.js +27 -34
- package/dist/orchestration/workflow-park-decision.d.ts +89 -0
- package/dist/orchestration/workflow-park-decision.js +119 -0
- package/dist/org-delivery-gate.d.ts +81 -0
- package/dist/org-delivery-gate.js +59 -0
- package/dist/panel-tool-names.d.ts +23 -0
- package/dist/panel-tool-names.js +8 -0
- package/dist/parked-decide.d.ts +43 -11
- package/dist/parked-decide.js +100 -51
- package/dist/parked-revive-surface.d.ts +9 -2
- package/dist/parked-revive-surface.js +11 -8
- package/dist/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- package/dist/permission-rule-vocab.d.ts +1 -23
- package/dist/permission-rule-vocab.js +0 -13
- package/dist/plugins/approval-ask-store-file.d.ts +16 -1
- package/dist/plugins/approval-ask-store-file.js +21 -0
- package/dist/plugins/approval-ask-store-memory.d.ts +18 -1
- package/dist/plugins/approval-ask-store-memory.js +34 -2
- package/dist/plugins/approval-ask-store-sql.d.ts +25 -0
- package/dist/plugins/approval-ask-store-sql.js +37 -1
- package/dist/plugins/approval-payload-fingerprint.d.ts +14 -6
- package/dist/plugins/approval-payload-fingerprint.js +1 -1
- package/dist/plugins/blob-backend.d.ts +38 -25
- package/dist/plugins/blob-backend.js +29 -19
- package/dist/plugins/breaker-state-sql.d.ts +2 -2
- package/dist/plugins/breaker-state-sql.js +4 -4
- package/dist/plugins/caching-session-store.d.ts +4 -1
- package/dist/plugins/caching-session-store.js +7 -3
- package/dist/plugins/checkpoint-store-sql.d.ts +36 -1
- package/dist/plugins/checkpoint-store-sql.js +65 -3
- package/dist/plugins/file-history-store-sql.d.ts +5 -2
- package/dist/plugins/file-history-store-sql.js +3 -1
- package/dist/plugins/file-run-store.d.ts +5 -13
- package/dist/plugins/file-run-store.js +9 -0
- package/dist/plugins/fork-routing-session-store.d.ts +9 -1
- package/dist/plugins/fork-routing-session-store.js +12 -1
- package/dist/plugins/host-platform.d.ts +2 -0
- package/dist/plugins/host-platform.js +2 -1
- package/dist/plugins/local-checkpoint-store.d.ts +15 -2
- package/dist/plugins/local-checkpoint-store.js +32 -1
- package/dist/plugins/local-session-store.d.ts +13 -10
- package/dist/plugins/local-session-store.js +23 -14
- package/dist/plugins/local-session-window.d.ts +45 -0
- package/dist/plugins/local-session-window.js +38 -0
- package/dist/plugins/mailbox-recipient-lifecycle.d.ts +3 -2
- package/dist/plugins/mailbox-store-sql.d.ts +30 -48
- package/dist/plugins/mailbox-store-sql.js +77 -52
- package/dist/plugins/memory-embedder-fingerprint.js +2 -1
- package/dist/plugins/memory-run-store.d.ts +5 -13
- package/dist/plugins/memory-run-store.js +8 -0
- package/dist/plugins/one-time-migrations.d.ts +121 -5
- package/dist/plugins/one-time-migrations.js +332 -8
- package/dist/plugins/org-delivery-quota-store.d.ts +123 -0
- package/dist/plugins/org-delivery-quota-store.js +228 -0
- package/dist/plugins/permission-rule-store-file.js +10 -6
- package/dist/plugins/permission-rule-store-sql.js +8 -8
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +18 -5
- package/dist/plugins/pg-session-storage.js +68 -23
- package/dist/plugins/remote-env-adb.d.ts +6 -12
- package/dist/plugins/remote-env-adb.js +12 -2
- package/dist/plugins/remote-env-device.d.ts +14 -7
- package/dist/plugins/remote-env-device.js +23 -15
- package/dist/plugins/remote-env-k8s.d.ts +8 -12
- package/dist/plugins/remote-env-k8s.js +23 -5
- package/dist/plugins/remote-env-local-docker.d.ts +10 -15
- package/dist/plugins/remote-env-local-docker.js +12 -9
- package/dist/plugins/remote-env-ssh.d.ts +10 -16
- package/dist/plugins/remote-env-ssh.js +17 -11
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- package/dist/plugins/schema-indexes.js +2 -0
- package/dist/plugins/send-user-file.js +2 -2
- package/dist/plugins/session-epoch-anchor.d.ts +32 -6
- package/dist/plugins/session-epoch-anchor.js +2 -3
- package/dist/plugins/session-ownership.d.ts +11 -0
- package/dist/plugins/session-ownership.js +11 -0
- package/dist/plugins/session-placement.d.ts +12 -14
- package/dist/plugins/session-placement.js +2 -15
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/sql-driver.d.ts +74 -11
- package/dist/plugins/sql-driver.js +210 -12
- package/dist/plugins/sql-errors.d.ts +23 -0
- package/dist/plugins/sql-errors.js +21 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +40 -14
- package/dist/plugins/store-contracts.d.ts +42 -0
- package/dist/plugins/store-contracts.js +1 -0
- package/dist/plugins/tidb-pool.d.ts +6 -1
- package/dist/plugins/tidb-pool.js +44 -10
- package/dist/plugins/tidb-session-storage.d.ts +3 -2
- package/dist/plugins/tidb-session-storage.js +2 -2
- package/dist/plugins/tidb-session-store.d.ts +25 -5
- package/dist/plugins/tidb-session-store.js +67 -21
- package/dist/plugins/workflow-journal-store-sql.d.ts +73 -19
- package/dist/plugins/workflow-journal-store-sql.js +19 -6
- package/dist/plugins/workflow-run-store-sql.d.ts +30 -8
- package/dist/plugins/workflow-run-store-sql.js +50 -9
- package/dist/posture-source.d.ts +18 -10
- package/dist/posture-source.js +4 -1
- package/dist/project-identity.d.ts +45 -6
- package/dist/project-identity.js +162 -8
- package/dist/project-layer-key.d.ts +28 -0
- package/dist/project-layer-key.js +29 -0
- package/dist/question.js +3 -2
- package/dist/read-deny-entry.d.ts +25 -0
- package/dist/read-deny-entry.js +12 -0
- package/dist/read-face-posture.d.ts +37 -11
- package/dist/read-face-posture.js +32 -3
- package/dist/request-key-closure.d.ts +7 -0
- package/dist/request-key-closure.js +9 -1
- package/dist/request-tool-axes.d.ts +12 -0
- package/dist/request-tool-axes.js +20 -0
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +26 -2
- package/dist/rule-entry-list.js +72 -12
- package/dist/rules-consent.js +3 -4
- package/dist/run-acceptance.d.ts +19 -3
- package/dist/run-acceptance.js +13 -1
- package/dist/run-local.js +37 -6
- package/dist/runs.d.ts +12 -10
- package/dist/runs.js +25 -6
- package/dist/runtime-caps-resolver.d.ts +16 -6
- package/dist/runtime-caps-resolver.js +18 -5
- package/dist/sandbox-pkg-source.d.ts +19 -1
- package/dist/sandbox-pkg-source.js +29 -7
- package/dist/sealed-key.d.ts +32 -0
- package/dist/sealed-key.js +55 -1
- package/dist/security.d.ts +95 -15
- package/dist/security.js +52 -9
- package/dist/session-error-wire.d.ts +31 -7
- package/dist/session-error-wire.js +9 -2
- package/dist/session-sync-kernel.d.ts +37 -10
- package/dist/session-sync-kernel.js +10 -0
- package/dist/session-titled-frame.d.ts +33 -0
- package/dist/session-titled-frame.js +4 -0
- package/dist/session-titler.d.ts +9 -1
- package/dist/session-titler.js +15 -4
- package/dist/spec-fields.js +21 -2
- package/dist/sql-engine-posture.d.ts +3 -1
- package/dist/task-a2a.js +4 -3
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +5 -5
- package/dist/task-mcp.js +27 -74
- package/dist/task-settings.d.ts +93 -88
- package/dist/task-settings.js +71 -63
- package/dist/text-bidi.d.ts +0 -4
- package/dist/text-bidi.js +1 -3
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +451 -136
- package/dist/tool-approval.js +733 -256
- package/dist/tool-rule-names.d.ts +6 -0
- package/dist/trace/core-keyset-guard.d.ts +108 -25
- package/dist/trace/exit-seat.d.ts +40 -0
- package/dist/trace/exit-seat.js +130 -0
- package/dist/trace/ledger-events.d.ts +6 -3
- package/dist/trace/project.d.ts +98 -13
- package/dist/trace/project.js +57 -32
- package/dist/trace/projection-table.d.ts +100 -0
- package/dist/trace/projection-table.js +130 -0
- package/dist/trace/redact.d.ts +57 -0
- package/dist/trace/redact.js +962 -168
- package/dist/trace/self-minted-wire.d.ts +349 -1
- package/dist/trace/self-minted-wire.js +118 -1
- package/dist/trace/wire-projection-faces.d.ts +304 -2
- package/dist/trace/wire-projection-faces.js +160 -13
- package/dist/url-refusal.js +2 -0
- package/dist/web-admin-client/apply-effective.d.ts +12 -0
- package/dist/web-admin-client/apply-effective.js +56 -5
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/skills-mcp.d.ts +1 -1
- package/dist/web-admin-client/skills-mcp.js +6 -8
- package/dist/web-admin-client/types.d.ts +1 -1
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +57 -9
- package/package.json +8 -4
- package/scripts/drain-check-local.mjs +34 -2
- package/scripts/drain-check.mysql.sql +20 -2
- package/scripts/drain-check.pg.sql +20 -2
- package/dist/mcp-tool-faces.d.ts +0 -69
- package/dist/mcp-tool-faces.js +0 -106
package/dist/boot/leader.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface LeaderCtx {
|
|
|
23
23
|
toolResultStore: ToolResultStoreFull | undefined;
|
|
24
24
|
sessionStore: ReturnType<typeof createSessionStore>;
|
|
25
25
|
checkpointStore: CheckpointStoreFull | undefined;
|
|
26
|
+
/** S-1907:停驻行凭据的封签器(与 HTTP 面 `ServiceDeps.checkpointCtxSealing` 同一只;起服第 6 段已对「店在、它不在」拒启)。必填键,值可为 undefined。 */
|
|
27
|
+
checkpointCtxSealing: import("../http/checkpoint-ctx.js").CheckpointCtxSealing | undefined;
|
|
26
28
|
/** [ref] 件B/C/D([ref],codex R2-F1):部署治理三座席 —— leader 车道的每一只 Runner 都要带上它,
|
|
27
29
|
* 否则开了 leader 端点的部署就有一条在部署治理**之外**的执行面(合规否决/锁都够不着)。 */
|
|
28
30
|
governanceSeams: import("./governance-seams.js").GovernanceSeams;
|
package/dist/boot/leader.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createLeaderEndpoint } from "../leader/endpoint.js";
|
|
2
|
+
import { createLeaderRunVisibility } from "../http/owner-access.js";
|
|
2
3
|
import { createLeaderRunner } from "../leader/wire.js";
|
|
3
4
|
import { buildDeploymentPostureSeats } from "./runner-deps.js";
|
|
4
5
|
import { hasApprovalListIntent } from "../approval.js";
|
|
@@ -21,7 +22,7 @@ export function assertLeaderDurableStore(leaderEnabled, hasLeaderRunStore) {
|
|
|
21
22
|
"(#193 车4 件2 capability gate; the DB_BACKEND literal check in config.ts is the intent half of the same rule)");
|
|
22
23
|
}
|
|
23
24
|
export function createLeaderFace(ctx) {
|
|
24
|
-
const { config, logger, brain, pricing, executionEnvFactory, toolResultStore, sessionStore, checkpointStore, governanceSeams } = ctx;
|
|
25
|
+
const { config, logger, brain, pricing, executionEnvFactory, toolResultStore, sessionStore, checkpointStore, checkpointCtxSealing, governanceSeams } = ctx;
|
|
25
26
|
const leaderMinio = process.env.MINIO_ENDPOINT && process.env.MINIO_ACCESS_KEY && process.env.MINIO_SECRET_KEY
|
|
26
27
|
? {
|
|
27
28
|
s3: {
|
|
@@ -73,6 +74,7 @@ export function createLeaderFace(ctx) {
|
|
|
73
74
|
durable: () => hasApprovalListIntent(config)
|
|
74
75
|
? {
|
|
75
76
|
checkpointStore,
|
|
77
|
+
ctxSealer: checkpointCtxSealing,
|
|
76
78
|
requireApproval: config.approvalRequire,
|
|
77
79
|
deny: config.approvalDeny,
|
|
78
80
|
autoBudget: config.approvalAutoBudget,
|
|
@@ -86,6 +88,7 @@ export function createLeaderFace(ctx) {
|
|
|
86
88
|
logger,
|
|
87
89
|
requiredFields: ["objective", "durableRemote", "testCmd", "seedCmd", "baseSha"],
|
|
88
90
|
...(leaderRunStore ? { store: leaderRunStore } : {}),
|
|
91
|
+
ownerVisible: createLeaderRunVisibility(config),
|
|
89
92
|
})
|
|
90
93
|
: undefined;
|
|
91
94
|
if (leaderEndpoint)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolve } from "node:path";
|
|
2
|
-
import { executionLaneCaps, executionLaneOf } from "../execution-lane-caps.js";
|
|
2
|
+
import { executionLaneCaps, executionLaneOf, laneWiresExecutionEnv } from "../execution-lane-caps.js";
|
|
3
3
|
export function effectiveMemoryPersistenceCapable(config) {
|
|
4
4
|
if (config.memoryPersistenceCapable !== undefined)
|
|
5
5
|
return config.memoryPersistenceCapable;
|
|
@@ -11,7 +11,7 @@ export function buildMemoryBoundaryLaneFacts(config, processCwd) {
|
|
|
11
11
|
return {
|
|
12
12
|
lane,
|
|
13
13
|
hostSemanticsLane: caps.hostFilePlane === "supported",
|
|
14
|
-
coreRemoteExecutionEnv:
|
|
14
|
+
coreRemoteExecutionEnv: laneWiresExecutionEnv(lane),
|
|
15
15
|
containmentRoots: lane === "in-process" ? [processCwd] : [],
|
|
16
16
|
};
|
|
17
17
|
}
|
|
@@ -298,9 +298,9 @@ export declare function judgeConsolidationValve(input: ConsolidationValveInput):
|
|
|
298
298
|
*
|
|
299
299
|
* consolidation 要后端自带引擎控制面归属 ⇒ 今天只有 file 记忆后端满足 ⇒ 本仓只在**单用户**形
|
|
300
300
|
* (`REQUIRE_PRINCIPAL !== true`)上装配记忆引擎 —— 而那种部署的 `OPERATOR_PRINCIPALS` 通常是**空的**。
|
|
301
|
-
*
|
|
302
|
-
* 「人人都是 operator」),于是:阀门开着、启动成功、两口挂着、**每一次调用 403
|
|
303
|
-
* `false` —— 唯独运维不知道为什么,而他刚刚显式拧了一根写着 "on" 的旋钮。
|
|
301
|
+
* 没有运维名册(名单空且没有单用户声明 `OPERATOR_SINGLE_USER`)时 `explicitOperatorOk` 对任何身份恒假(「谁是 operator」的唯一读法:空名单绝不等于
|
|
302
|
+
* 「人人都是 operator」),于是:阀门开着、启动成功、两口挂着、**每一次调用 501 `capability.operator_principals_required`**(运维面同一只拒发口;403 只留给名单非空而你不在名单上),
|
|
303
|
+
* 能力位诚实地报 `false` —— 唯独运维不知道为什么,而他刚刚显式拧了一根写着 "on" 的旋钮。
|
|
304
304
|
*
|
|
305
305
|
* ## 为什么是 warn 而不是拒启(与 D1 的三条拒启臂**刻意不同档**)
|
|
306
306
|
*
|
|
@@ -322,7 +322,8 @@ export declare function judgeConsolidationValve(input: ConsolidationValveInput):
|
|
|
322
322
|
export declare function buildConsolidationValveAudit(input: {
|
|
323
323
|
/** 阀门判决({@link resolveConsolidationValve} 的 `enabled` + `source`)。 */
|
|
324
324
|
valve: Pick<ConsolidationValve, "enabled" | "source">;
|
|
325
|
-
|
|
325
|
+
/** 这台部署有没有运维名册(`operatorRosterPresent`:名单非空 ∨ 单用户声明)—— 判据不在本函数里另写一份。 */
|
|
326
|
+
operatorRosterPresent: boolean;
|
|
326
327
|
/** 这台部署配了任何一把 service 凭证吗(`config.authToken` 或 `config.authTokens` 非空)。 */
|
|
327
328
|
hasServiceAuth: boolean;
|
|
328
329
|
/** 本地开发的显式逃生口(`ALLOW_UNAUTHED_WRITES=true`)。 */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { redactSecrets } from "../trace/redact.js";
|
|
2
2
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
3
|
+
import { buildOperatorRosterWayOut } from "../http/principal-gate.js";
|
|
3
4
|
import { memoryMountRootOf } from "../memory-scope.js";
|
|
4
5
|
import { executionLaneHomeDir } from "../execution-lane-caps.js";
|
|
5
6
|
import { DEFAULT_MODEL_REF, resolveMainModel } from "../model-select.js";
|
|
@@ -266,15 +267,15 @@ export function buildConsolidationValveAudit(input) {
|
|
|
266
267
|
if (!input.valve.enabled || input.valve.source !== "explicit")
|
|
267
268
|
return { warnings: [] };
|
|
268
269
|
const warnings = [];
|
|
269
|
-
if (input.
|
|
270
|
+
if (!input.operatorRosterPresent) {
|
|
270
271
|
warnings.push({
|
|
271
272
|
tag: "memory_consolidation_valve_unreachable",
|
|
272
273
|
detail: "MEMORY_CONSOLIDATION_DRIVER=on armed the consolidation valve and both admin endpoints are mounted, but " +
|
|
273
|
-
"OPERATOR_PRINCIPALS is EMPTY — an empty operator list means NO ONE
|
|
274
|
-
"not mean 'everyone'), so POST /v1/admin/memory/consolidation/run and GET /v1/admin/memory/consolidation " +
|
|
275
|
-
"answer
|
|
276
|
-
|
|
277
|
-
"
|
|
274
|
+
"this worker has no operator: OPERATOR_PRINCIPALS is EMPTY and OPERATOR_SINGLE_USER is not set — an empty operator list means NO ONE " +
|
|
275
|
+
"is an operator (it deliberately does not mean 'everyone'), so POST /v1/admin/memory/consolidation/run and GET /v1/admin/memory/consolidation " +
|
|
276
|
+
"answer 501 capability.operator_principals_required to every caller and capabilities.memoryConsolidationDriver reports false. " +
|
|
277
|
+
`To fix: ${buildOperatorRosterWayOut()}. With OPERATOR_PRINCIPALS, callers must send a listed principal in the configured principal header; a single-user declaration needs no principal. ` +
|
|
278
|
+
"(Not a startup refusal: the operator roster is shared by every operator " +
|
|
278
279
|
"endpoint on this worker, so one valve must not decide whether the whole worker starts.)",
|
|
279
280
|
});
|
|
280
281
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [ref] §10.2 —— 跨主体投递门的**装配点**(门本体与规则在 `src/org-delivery-gate.ts`)。
|
|
3
|
+
*
|
|
4
|
+
* 挂载规则(一条):**部署声明了 principal 收件箱的消费方 ⟺ 门在座**。声明 = `RunnerDeps.principalInboxConsumer`
|
|
5
|
+
* (由 `PRINCIPAL_INBOX_ASSISTANT` 铸,`boot/runner-deps.ts`);门要的四件 —— 消费方、耐久 mailbox、org 成员目录、配额店 ——
|
|
6
|
+
* 是这条声明的**前提**,不是可选项:声明在而任一件缺 ⇒ **拒启**,拒句点名缺哪件。不存在「声明了但门没挂」的静默半态:
|
|
7
|
+
* 那一形下收件箱有消费方却没有任何合法的写入方,运维以为跨主体投递开着,wire 上它恒 501。
|
|
8
|
+
*
|
|
9
|
+
* 消费方取自**同一个** `RunnerDeps` 对象(`principalInboxConsumerOf(runnerDeps)`),不从 config 再读一遍(core 契约原句:
|
|
10
|
+
* 「over the same RunnerDeps the deployment runs its legs with」)。
|
|
11
|
+
*/
|
|
12
|
+
import { type MailboxStore, type OrgDeliveryGate, type RunnerDeps } from "@sema-agent/core";
|
|
13
|
+
import type { OrgMemoryDirectory } from "../org-memory-admission.js";
|
|
14
|
+
import type { StoreBackend } from "../plugins/store-backend.js";
|
|
15
|
+
import type { Logger } from "../observability/logger.js";
|
|
16
|
+
export interface OrgDeliveryMountInput {
|
|
17
|
+
/** 主 Runner 的那一份 `RunnerDeps`(消费方声明从它读)。 */
|
|
18
|
+
readonly runnerDeps: Pick<RunnerDeps, "principalInboxConsumer">;
|
|
19
|
+
/** 记忆准入 / memory-policy / 共享记忆读面共用的那一个目录实例(`boot/org-memory.ts`)。 */
|
|
20
|
+
readonly directory: OrgMemoryDirectory | undefined;
|
|
21
|
+
/** 与引擎 `RunnerDeps.mailboxStore` 同一只店。 */
|
|
22
|
+
readonly mailboxStore: MailboxStore | undefined;
|
|
23
|
+
readonly backend: Pick<StoreBackend, "orgDeliveryQuota"> | undefined;
|
|
24
|
+
readonly logger: Pick<Logger, "info">;
|
|
25
|
+
}
|
|
26
|
+
/** 门在座 ⇒ 门;部署没声明消费方 ⇒ `undefined`;声明了而前提缺 ⇒ 抛(拒启)。 */
|
|
27
|
+
export declare function mountOrgDeliveryGate(input: OrgDeliveryMountInput): OrgDeliveryGate | undefined;
|
|
28
|
+
//# sourceMappingURL=org-delivery.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { principalInboxConsumerOf } from "@sema-agent/core";
|
|
2
|
+
import { createOrgDeliveryGate } from "../org-delivery-gate.js";
|
|
3
|
+
export function mountOrgDeliveryGate(input) {
|
|
4
|
+
const consumer = principalInboxConsumerOf(input.runnerDeps);
|
|
5
|
+
if (consumer.kind === "none")
|
|
6
|
+
return undefined;
|
|
7
|
+
const { mailboxStore, directory, backend } = input;
|
|
8
|
+
if (mailboxStore === undefined || directory === undefined || backend === undefined) {
|
|
9
|
+
const missing = [
|
|
10
|
+
...(mailboxStore === undefined ? ["a durable mailbox store (DB_BACKEND=mysql|pg|local)"] : []),
|
|
11
|
+
...(directory === undefined ? ["an organization membership directory (a web-admin center, or MEMORY_ORG_DIRECTORY_JSON)"] : []),
|
|
12
|
+
...(backend === undefined ? ["a store backend for the delivery quota (DB_BACKEND=mysql|pg|local)"] : []),
|
|
13
|
+
];
|
|
14
|
+
throw new Error(`PRINCIPAL_INBOX_ASSISTANT declares a principal-inbox consumer, so this deployment must mount the organization delivery gate — but it lacks ${missing.join("; ")}. ` +
|
|
15
|
+
`Refusing to boot rather than run with a declared inbox that nothing may legitimately write to; provide the missing pieces or unset PRINCIPAL_INBOX_ASSISTANT.`);
|
|
16
|
+
}
|
|
17
|
+
input.logger.info("org_delivery_gate_mounted", { consumer: consumer.kind });
|
|
18
|
+
return createOrgDeliveryGate({ directory, mailbox: mailboxStore, quota: backend.orgDeliveryQuota(), consumer });
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=org-delivery.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { compileReadDeny,
|
|
1
|
+
import { compileReadDeny, readDenyRowAnchor } from "@sema-agent/core";
|
|
2
2
|
import { echoCallerText } from "../caller-text-echo.js";
|
|
3
3
|
export const READ_DENY_AUDIT_MAX_NAMED_ROWS = 20;
|
|
4
4
|
const NAMED_ROW_ECHO_CHARS = 200;
|
|
5
5
|
function isAnchoredCanonicalRow(canonical) {
|
|
6
|
-
return
|
|
6
|
+
return readDenyRowAnchor(canonical) !== "none";
|
|
7
7
|
}
|
|
8
8
|
export function auditReadDenyAnchoring(ctx) {
|
|
9
9
|
if (ctx.rows === undefined || ctx.rows.length === 0)
|
package/dist/boot/reapers.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ import type { FileHistoryErasureFace } from "../file-history-capture.js";
|
|
|
25
25
|
import type { ApprovalNonceStore, CheckpointStoreFull, CostQuotaStore, ImageBake, RateLimiterStore, ServiceWorkflowJournalStore, StoreBackend, ToolResultStoreFull } from "../plugins/store-backend.js";
|
|
26
26
|
import type { ToolApprovalCoordinator } from "../tool-approval.js";
|
|
27
27
|
import type { ParkCommitWatch } from "../plugins/park-commit-watch.js";
|
|
28
|
+
import { type AuditRotationPort } from "../approval-ask-retention.js";
|
|
28
29
|
/** [ref] / [ref]§五(sema-comms `audits/failopen-governance-176.md` §7 "Z 类 1 条"):default consecutive-failure
|
|
29
30
|
* count before a reaper leg's swallowed error gets a `warn` line. The ~15 `.catch(() => undefined)` sites
|
|
30
31
|
* below are correct in DIRECTION (a hiccuping periodic sweep must never crash the whole tick loop — one bad
|
|
@@ -108,6 +109,8 @@ export interface ReapersCtx {
|
|
|
108
109
|
* 受理的最后一刻),所以存量是「到达率 × TTL」而不是历史总量,清扫无需分批。无 backend 的 env-only
|
|
109
110
|
* 部署 ⇒ undefined ⇒ 本腿零调用(那种部署也没有 durable 审批门)。 */
|
|
110
111
|
approvalNonceStore: ApprovalNonceStore | undefined;
|
|
112
|
+
/** local 车道的审批审计账(装配三合取见 `boot/coordinators.ts`;SQL 车道 / 审批关着 ⇒ undefined)—— 本 tick 只用它的**留存轮转**一手。 */
|
|
113
|
+
approvalAskAudit: AuditRotationPort | undefined;
|
|
111
114
|
/** 晚绑(server 造出来才有)——见文件头「位置即契约」①。 */
|
|
112
115
|
getRunDenySweep: () => ((now: number) => Promise<void>) | undefined;
|
|
113
116
|
}
|
package/dist/boot/reapers.js
CHANGED
|
@@ -4,6 +4,7 @@ import { CostQuota } from "../observability/cost-quota.js";
|
|
|
4
4
|
import { isAdoptionQuiescing, trackMaintenanceLeg } from "../adoption/quiesce.js";
|
|
5
5
|
import { createApprovalReconciler } from "../approval-reconciler.js";
|
|
6
6
|
import { createE2bOrphanSandboxProvider, reclaimOrphanE2bSandboxes, E2B_ORPHAN_GRACE_MS } from "../plugins/e2b-orphan-reclaim.js";
|
|
7
|
+
import { APPROVAL_ASK_RETENTION_PASS_MS, runApprovalAskRetentionPass } from "../approval-ask-retention.js";
|
|
7
8
|
export const REAPER_FAILURE_WARN_THRESHOLD = 5;
|
|
8
9
|
export function createThrottledReaperCatch(name, logger, threshold = REAPER_FAILURE_WARN_THRESHOLD) {
|
|
9
10
|
let streak = 0;
|
|
@@ -56,7 +57,7 @@ export function createPlacementAwareReapSessions(deps) {
|
|
|
56
57
|
};
|
|
57
58
|
}
|
|
58
59
|
export function startReapers(ctx) {
|
|
59
|
-
const { config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore, parkCommits, rateLimiter, costQuota, toolResultStore, fileHistoryErasure, taskAttachmentStore, imageBakes, worktreeReap, workflowNotifyGate, workflowRecoverOpts, workflowJournalStore, sqlWorkflowRunStore, workflowNotifyJournal, rosterStore, backgroundAgentStore, mailboxStore, toolApproval, permissionRuleStores, approvalNonceStore, getRunDenySweep, userInputLedger, } = ctx;
|
|
60
|
+
const { config, logger, metrics, localRoot, backend, subRunner, runStore, checkpointStore, parkCommits, rateLimiter, costQuota, toolResultStore, fileHistoryErasure, taskAttachmentStore, imageBakes, worktreeReap, workflowNotifyGate, workflowRecoverOpts, workflowJournalStore, sqlWorkflowRunStore, workflowNotifyJournal, rosterStore, backgroundAgentStore, mailboxStore, toolApproval, permissionRuleStores, approvalNonceStore, getRunDenySweep, userInputLedger, approvalAskAudit, } = ctx;
|
|
60
61
|
const leg = (p) => {
|
|
61
62
|
if (p !== undefined)
|
|
62
63
|
trackMaintenanceLeg(p);
|
|
@@ -101,6 +102,17 @@ export function startReapers(ctx) {
|
|
|
101
102
|
const leaderRunStaleGuard = createThrottledReaperCatch("leader_run_reap_stale", logger);
|
|
102
103
|
const leaderRunStore = config.leaderEnabled ? backend?.leaderRun?.() : undefined;
|
|
103
104
|
const scratchpadSweepStaleGuard = createThrottledReaperCatch("scratchpad_sweep_stale", logger);
|
|
105
|
+
const approvalAskRetentionMs = config.approvalAskRetentionMs;
|
|
106
|
+
const approvalAskRetentionGuard = createThrottledReaperCatch("approval_ask_retention", logger);
|
|
107
|
+
let approvalAskRetentionLastRunMs = Number.NEGATIVE_INFINITY;
|
|
108
|
+
let approvalAskRetentionInFlight = false;
|
|
109
|
+
logger.info("approval_ask_retention", {
|
|
110
|
+
windowMs: approvalAskRetentionMs,
|
|
111
|
+
ledgers: { asks: backend !== undefined, audit: approvalAskAudit !== undefined },
|
|
112
|
+
note: approvalAskRetentionMs > 0
|
|
113
|
+
? "settled approval asks quiet for longer than windowMs are deleted whole from the approval ledgers on the maintenance tick (at most once an hour); unsettled asks, and every ask hanging off something that can still move (a running / parked run or delegated child, by run id or session), are never aged out. APPROVAL_ASK_RETENTION_MS=0 keeps everything."
|
|
114
|
+
: "APPROVAL_ASK_RETENTION_MS=0 — the approval ledgers are kept forever (nothing is aged out).",
|
|
115
|
+
});
|
|
104
116
|
const approvalReconcileGuard = createThrottledReaperCatch("approval_reconcile", logger);
|
|
105
117
|
const approvalSuspendedPollGuard = createThrottledReaperCatch("approval_suspended_poll", logger);
|
|
106
118
|
let approvalSuspendedPollInFlight = false;
|
|
@@ -325,6 +337,14 @@ export function startReapers(ctx) {
|
|
|
325
337
|
if (permissionRuleStores?.reapExpired === undefined)
|
|
326
338
|
permissionRuleReapInFlight = false;
|
|
327
339
|
}
|
|
340
|
+
if (approvalAskRetentionMs > 0 && runStore !== undefined && !approvalAskRetentionInFlight && Date.now() - approvalAskRetentionLastRunMs >= APPROVAL_ASK_RETENTION_PASS_MS && (backend !== undefined || approvalAskAudit !== undefined)) {
|
|
341
|
+
approvalAskRetentionInFlight = true;
|
|
342
|
+
approvalAskRetentionLastRunMs = Date.now();
|
|
343
|
+
leg(Promise.resolve()
|
|
344
|
+
.then(() => runApprovalAskRetentionPass({ askStore: backend?.approvalAsk(), audit: approvalAskAudit, runs: runStore, backgroundAgents: backgroundAgentStore, checkpoints: backend?.checkpointReadView(), cutoffMs: Date.now() - approvalAskRetentionMs, logger, metrics }))
|
|
345
|
+
.then(() => approvalAskRetentionGuard.onSuccess(), approvalAskRetentionGuard.onError)
|
|
346
|
+
.finally(() => (approvalAskRetentionInFlight = false)));
|
|
347
|
+
}
|
|
328
348
|
if (config.scratchpadSweepTtlMs > 0) {
|
|
329
349
|
leg(sweepStaleScratchpads(config.localDataRoot ?? localRoot, { olderThanMs: config.scratchpadSweepTtlMs })
|
|
330
350
|
.then((removed) => {
|
|
@@ -16,6 +16,7 @@ import type { StoreBackend } from "../plugins/store-backend.js";
|
|
|
16
16
|
import { type TaskAttachmentStore } from "../plugins/task-attachment-store.js";
|
|
17
17
|
import { type createPrincipalEntitlementsClient } from "../runtime-caps-resolver.js";
|
|
18
18
|
import { type OwnerAwareSessionStore } from "../security.js";
|
|
19
|
+
import type { MemorySyncRunner } from "../memory-sync-client.js";
|
|
19
20
|
import type { RunnerDepsOnAsk } from "./runner-deps.js";
|
|
20
21
|
type PrincipalCaps = ReturnType<typeof createPrincipalEntitlementsClient>;
|
|
21
22
|
/** `resolveSpec` 原先从 `main()` 闭包里拿到的全部 boot 局部量。 */
|
|
@@ -56,6 +57,8 @@ export interface ResolveSpecCtx {
|
|
|
56
57
|
backend: MemoryBackend;
|
|
57
58
|
root: string;
|
|
58
59
|
} | undefined;
|
|
60
|
+
/** S-640:记忆同步腿(开 `MEMORY_SYNC_*` 且记忆引擎接线时在场)—— 项目层准备一步把本任务的项目层交给它跟踪(`memory-project-layer.ts`)。 */
|
|
61
|
+
memorySyncRunner: MemorySyncRunner | undefined;
|
|
59
62
|
durableEnabled: boolean;
|
|
60
63
|
/** [ref] ([ref] 案二):活体 AskUserQuestion 面(QuestionCoordinator 的判决探针切面)。在场(=
|
|
61
64
|
* ASK_QUESTION_ENABLED)时 durable question 门按活流上下文分腿、spec 不再 stamp QUESTION_AWAITS_RESUME
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { realpathSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { NodeExecutionEnv, QUESTION_AWAITS_RESUME,
|
|
3
|
+
import { NodeExecutionEnv, QUESTION_AWAITS_RESUME, deriveAskEffective, expandTiers, modePolicyOf, resolveAskSeamForm } from "@sema-agent/core";
|
|
4
4
|
import { cappedCeiling } from "../budget.js";
|
|
5
5
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
6
6
|
import { SessionEnvironmentSelection, selectEnvironmentTool } from "../capabilities/select-environment-tool.js";
|
|
7
7
|
import { sendUserFileTool } from "../capabilities/send-user-file-tool.js";
|
|
8
|
-
import { buildPromptSeats, createScenarioGate, mergeUserSkills, selectScenario } from "../capabilities/scenarios.js";
|
|
8
|
+
import { buildExcludeToolsSeat, buildPromptSeats, createScenarioGate, mergeUserSkills, selectScenario } from "../capabilities/scenarios.js";
|
|
9
9
|
import { stampHandsLane, toolPolicyForHands } from "../capabilities/hands-lane.js";
|
|
10
10
|
import { applyLongtailDefer } from "../capabilities/tool-defer.js";
|
|
11
11
|
import { assertGuardPatternsUsable, buildApprovalGrantNotice, buildOnlySensitiveBaselineWarning, createApprovalBaselinePolicy, createDeploymentGovernanceInputs } from "../deployment-governance.js";
|
|
@@ -17,7 +17,7 @@ import { HOST_POSTURE_REFUSED_CODE, taskInheritEnvRefusal, taskWriteFaceRefusal
|
|
|
17
17
|
import { headerStr } from "../http/principal-gate.js";
|
|
18
18
|
import { explicitOperatorOk } from "../http/server.js";
|
|
19
19
|
import { isAtMentionable, matchCatalogModel, modelSupportsImages, refusedCatalogEntry, resolveTaskModel, selectableCatalog, terminalCatalogName } from "../model-select.js";
|
|
20
|
-
import { modelUnavailableMessage } from "../model-entry-refusal.js";
|
|
20
|
+
import { echoModelRef, modelUnavailableMessage } from "../model-entry-refusal.js";
|
|
21
21
|
import { PerTaskImageRegistry, resolveSandboxImageRef } from "../per-task-image.js";
|
|
22
22
|
import { isRemoteScratchpadLane, remoteScratchpadDirFor } from "../plugins/remote-scratchpad.js";
|
|
23
23
|
import { bindAttachmentsForTask } from "../plugins/task-attachment-store.js";
|
|
@@ -27,7 +27,9 @@ import { tightenGoverned } from "../governance-overrides.js";
|
|
|
27
27
|
import { gateExecutionLane } from "../runtime-caps-resolver.js";
|
|
28
28
|
import { applyRuntimeGovernance } from "../runtime-governance.js";
|
|
29
29
|
import { HttpError, createCodedHttpError, encodeCheckpointScope } from "../security.js";
|
|
30
|
-
import {
|
|
30
|
+
import { sessionFaceReadOf } from "../session-incarnation.js";
|
|
31
|
+
import { memorySpecForRequest } from "../memory-scope.js";
|
|
32
|
+
import { createMemoryProjectLayers } from "../memory-project-layer.js";
|
|
31
33
|
import { inheritEnvFieldIssue, singleMemberOffFieldIssue } from "../request-value-closure.js";
|
|
32
34
|
import { a2aForScenario, mcpForScenario } from "../web-admin-client/facade.js";
|
|
33
35
|
import { normalizeAttachments, normalizeResilience, normalizeResumeAtMode, normalizeSuggestNextPrompts, promptProfileFromBody, resolveTaskLimits, retainBackgroundProcessesFromBody, taskAgentsSpecFragment, toolMaterializeStrategyFromBody, allowToolsSpecFragment, toolNameListFromBody } from "../spec-fields.js";
|
|
@@ -37,17 +39,21 @@ import { assertRequestA2aUnlocked, resolveRequestA2a } from "../task-a2a.js";
|
|
|
37
39
|
import { assertRequestMcpEntries, assertRequestMcpUnlocked, resolveRequestMcp } from "../task-mcp.js";
|
|
38
40
|
import { storedToolAxesRereadM19 } from "../stored-request-tool-axes-m19.js";
|
|
39
41
|
import { storedHooksRereadM20 } from "../stored-request-hooks-m20.js";
|
|
40
|
-
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, REQUEST_SETTINGS_REFUSAL_PREFIX, acceptAppendSystemPrompt, applyTaskSettings, effectivePermissionMode, effectiveThinking, parseTaskSettings, taskHooksHonored, settingsPermissionBucketIssue
|
|
42
|
+
import { MAX_SETTINGS_OUTPUT_STYLE_CHARS, REQUEST_SETTINGS_REFUSAL_PREFIX, SETTINGS_RULE_REFUSAL_CODE, SettingsRuleRefusalError, acceptAppendSystemPrompt, applyTaskSettings, createWorkflowAskPolicy, effectivePermissionMode, effectiveThinking, parseTaskSettings, taskHooksHonored, settingsPermissionBucketIssue } from "../task-settings.js";
|
|
43
|
+
import { tightenOnlySeatIssue } from "../tighten-only-seats.js";
|
|
44
|
+
import { entryProblemsFacts } from "../entry-problems.js";
|
|
41
45
|
import { inertToolListEntryOf } from "../rule-entry-list.js";
|
|
42
46
|
import { TENANCY_WALL_CLOCK_BASE_SEC, enableForkFromBody, normalizeRetainSubagentSessions, selfOrchestrationFromBody } from "../task-workflow.js";
|
|
43
47
|
import { redactSecrets } from "../trace/redact.js";
|
|
44
48
|
import { DeferredSandboxPathEnv, isSandboxPathAdjudicationLane, sandboxPathEnvSlots } from "./deferred-sandbox-path-env.js";
|
|
45
|
-
import {
|
|
49
|
+
import { executionLaneHomeDir, executionLaneOf, laneWiresExecutionEnv } from "../execution-lane-caps.js";
|
|
46
50
|
import { effectiveMemoryPersistenceCapable } from "./memory-boundary.js";
|
|
47
51
|
import { withUnattendedLeg } from "../unattended-permission-mode.js";
|
|
52
|
+
import { fieldConflictFacts } from "../field-conflict.js";
|
|
48
53
|
export function createResolveSpec(ctx) {
|
|
49
|
-
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, durableEnabled, approvalExemptionStore, checkpointStore, imageIndex, perTaskImage, sessionEnvSelection, liveQuestionFace, approverSeat, lockedKeys, } = ctx;
|
|
54
|
+
const { config, logger, metrics, localRoot, scenarios, principalCaps, centerRuntimeCapsResolver, getKeyResolver, taskAttachmentStore, perSessionCwd, setSessionCwd, setSessionShellEnv, fenceSessionOwner, hookLlm, hookAgent, fleetBus, hookWakeBus, resumeAnchorStore, ownerAware, taskLimitCaps, taskTimeoutSec, selectEnvTool, sendUserFileToolSpec, memoryEngine, memorySyncRunner, durableEnabled, approvalExemptionStore, checkpointStore, imageIndex, perTaskImage, sessionEnvSelection, liveQuestionFace, approverSeat, lockedKeys, } = ctx;
|
|
50
55
|
const scenarioGate = createScenarioGate({ config, scenarios, principalCaps, logger }, "enforce");
|
|
56
|
+
const readSessionFace = sessionFaceReadOf(ownerAware);
|
|
51
57
|
assertGuardPatternsUsable(config);
|
|
52
58
|
const onlySensitiveBaseline = buildOnlySensitiveBaselineWarning(config, {
|
|
53
59
|
approvalSeat: durableEnabled ? "durable" : "absent",
|
|
@@ -59,6 +65,7 @@ export function createResolveSpec(ctx) {
|
|
|
59
65
|
const sessionCwd = auth?.sessionId ? effectiveHostWorkspace(perSessionCwd.get(auth.sessionId), {}) : undefined;
|
|
60
66
|
return sessionCwd ?? (config.remoteExec === undefined ? process.cwd() : undefined);
|
|
61
67
|
};
|
|
68
|
+
const memoryProjectLayers = createMemoryProjectLayers({ backend: memoryEngine?.backend, syncRunner: memorySyncRunner, log: logger });
|
|
62
69
|
if (onlySensitiveBaseline)
|
|
63
70
|
logger.warn(onlySensitiveBaseline.event, onlySensitiveBaseline.fields);
|
|
64
71
|
const approvalGrantNotice = buildApprovalGrantNotice(config);
|
|
@@ -81,7 +88,7 @@ export function createResolveSpec(ctx) {
|
|
|
81
88
|
cwdHonored: cwdHonored(config),
|
|
82
89
|
});
|
|
83
90
|
if (conflict) {
|
|
84
|
-
throw new HttpError(400, `cwd "${conflict.cwd.asSpelled}" is inside this session's scratchpad "${conflict.scratchpadDir.asSpelled}" — the scratchpad is the fs-write gate's EXEMPT directory, so a task rooted there would auto-approve every write under its own root and the engine refuses to build the gate at all (config.write_exempt_dir_covers_root). Point cwd at the project directory instead (or send no cwd and let the session keep the one it has): this session registers the cwd you send, so a task that happens not to mount the write gate would still leave every LATER task on this session rooted in the exemption. A workflow that really is meant to write without prompts says so with a knob that means it (a permission mode, an open write face) and still keeps its root outside the scratchpad — those knobs do not lift this refusal, because the conflict is between two fields of this request, not a permission level.`, { code: "request.field_conflict", extra: { cwd: conflict.cwd, scratchpadDir: conflict.scratchpadDir } });
|
|
91
|
+
throw new HttpError(400, `cwd "${conflict.cwd.asSpelled}" is inside this session's scratchpad "${conflict.scratchpadDir.asSpelled}" — the scratchpad is the fs-write gate's EXEMPT directory, so a task rooted there would auto-approve every write under its own root and the engine refuses to build the gate at all (config.write_exempt_dir_covers_root). Point cwd at the project directory instead (or send no cwd and let the session keep the one it has): this session registers the cwd you send, so a task that happens not to mount the write gate would still leave every LATER task on this session rooted in the exemption. A workflow that really is meant to write without prompts says so with a knob that means it (a permission mode, an open write face) and still keeps its root outside the scratchpad — those knobs do not lift this refusal, because the conflict is between two fields of this request, not a permission level.`, { code: "request.field_conflict", extra: { ...fieldConflictFacts("scratchpad_root", body.scratchpadDir === conflict.scratchpadDir.asSpelled ? ["cwd", "scratchpadDir"] : ["cwd"]), cwd: conflict.cwd, scratchpadDir: conflict.scratchpadDir } });
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
const offFieldIssue = singleMemberOffFieldIssue(body);
|
|
@@ -109,6 +116,11 @@ export function createResolveSpec(ctx) {
|
|
|
109
116
|
if (bucketIssue)
|
|
110
117
|
throw new HttpError(400, bucketIssue.message, { code: "request.field_invalid", extra: bucketIssue.fields });
|
|
111
118
|
}
|
|
119
|
+
{
|
|
120
|
+
const seatIssue = tightenOnlySeatIssue(body.settings);
|
|
121
|
+
if (seatIssue)
|
|
122
|
+
throw new HttpError(400, seatIssue.message, { code: "request.field_invalid", extra: seatIssue.fields });
|
|
123
|
+
}
|
|
112
124
|
{
|
|
113
125
|
const replay = opts?.leg === "resume";
|
|
114
126
|
const inertList = inertToolListEntryOf(body, replay ? ["deny"] : undefined);
|
|
@@ -136,8 +148,9 @@ export function createResolveSpec(ctx) {
|
|
|
136
148
|
}
|
|
137
149
|
const lane = bindSettingsCwdEnvAndModel(body, auth, gated, opts);
|
|
138
150
|
const anchors = await resolveHistoryAnchors(body, auth);
|
|
139
|
-
const
|
|
140
|
-
const
|
|
151
|
+
const projectKey = memoryEngine ? await memoryProjectLayers.prepare(config, auth?.memoryScope, realTaskRootOf(auth)) : undefined;
|
|
152
|
+
const spec = assembleSpecLiteral(body, auth, req, opts, { ...gated, ...lane, ...anchors, projectKey }, effMode);
|
|
153
|
+
const folded = await foldGovernanceAndSettings(body, auth, spec, gated);
|
|
141
154
|
const final = await applyImageFactsAndRouting(body, auth, folded.governed, {
|
|
142
155
|
scenarioName: gated.scenarioName,
|
|
143
156
|
scratchpadDir: folded.scratchpadDir,
|
|
@@ -149,7 +162,7 @@ export function createResolveSpec(ctx) {
|
|
|
149
162
|
const gateScenarioAndAppend = async (body, auth, opts) => {
|
|
150
163
|
const scenarioName = await scenarioGate(auth?.principal, body.scenario);
|
|
151
164
|
gateExecutionLane(await principalCaps?.executionRuling(auth?.principal), executionLaneOf(config.remoteExec?.provider), logger);
|
|
152
|
-
const cap = selectScenario(scenarios, scenarioName)(body, auth?.principal, auth?.sessionId !== undefined ? { sessionId: auth.sessionId } : {});
|
|
165
|
+
const cap = selectScenario(scenarios, scenarioName)(body, auth?.principal, auth?.sessionId !== undefined ? { sessionId: auth.sessionId, delegationRoot: { sessionId: auth.sessionId, incarnation: (await readSessionFace?.(auth.sessionId))?.incarnation ?? null } } : {});
|
|
153
166
|
const acceptedAppend = acceptAppendSystemPrompt(body.appendSystemPrompt, (detail) => logger.warn("append_system_prompt_dropped", { detail, sessionId: auth?.sessionId ?? null }));
|
|
154
167
|
const objective = typeof body.objective === "string" ? body.objective : "";
|
|
155
168
|
const parsedSettings = parseTaskSettings(body.settings, opts?.leg === "fresh" || !taskHooksHonored(config) ? {} : { storedHooksReread: storedHooksRereadM20(new Date().toISOString().slice(0, 10)) });
|
|
@@ -274,22 +287,22 @@ export function createResolveSpec(ctx) {
|
|
|
274
287
|
if (picked.unavailable !== undefined) {
|
|
275
288
|
const { requested, name, refusal, source } = picked.unavailable;
|
|
276
289
|
if (opts?.leg === "fresh") {
|
|
277
|
-
throw new HttpError(400, modelUnavailableMessage(source === "mention" ? "@-mention" : "model", requested
|
|
290
|
+
throw new HttpError(400, modelUnavailableMessage(source === "mention" ? "@-mention" : "model", requested, name, refusal), { code: "request.model_unavailable" });
|
|
278
291
|
}
|
|
279
292
|
metrics.inc("task_model_unavailable_fallback_total");
|
|
280
|
-
logger.warn("task_model_unavailable_fallback", { requested: requested
|
|
293
|
+
logger.warn("task_model_unavailable_fallback", { requested: echoModelRef(requested), name, code: refusal.code, source, fallback: picked.model, sessionId: auth?.sessionId ?? null });
|
|
281
294
|
}
|
|
282
295
|
if (picked.notAllowed !== undefined) {
|
|
283
296
|
const { requested, resolved, source } = picked.notAllowed;
|
|
284
297
|
if (opts?.leg === "fresh") {
|
|
285
|
-
throw new HttpError(400, `model "${requested
|
|
298
|
+
throw new HttpError(400, `model "${echoModelRef(requested)}" is not @-mentionable on this deployment (it resolves to catalog model "${resolved}") — which models can be @-mentioned is configured by the operator (models.atMention)`, { code: "request.model_not_allowed" });
|
|
286
299
|
}
|
|
287
300
|
metrics.inc("task_model_not_allowlisted_resume_total");
|
|
288
|
-
logger.warn("task_model_not_allowlisted_resume", { requested: requested
|
|
301
|
+
logger.warn("task_model_not_allowlisted_resume", { requested: echoModelRef(requested), resolved, source, sessionId: auth?.sessionId ?? null, note: "resumed leg keeps running the model it was started on — the allowlist gates fresh picks only" });
|
|
289
302
|
}
|
|
290
303
|
if (picked.unknownExplicit !== undefined) {
|
|
291
304
|
metrics.inc("task_model_unknown_fallback_total");
|
|
292
|
-
logger.warn("task_model_unknown_fallback", { requested: picked.unknownExplicit
|
|
305
|
+
logger.warn("task_model_unknown_fallback", { requested: echoModelRef(picked.unknownExplicit), fallback: picked.model, sessionId: auth?.sessionId ?? null });
|
|
293
306
|
}
|
|
294
307
|
if (Array.isArray(body.images) && body.images.length > 0 && !modelSupportsImages(wireCatalog[picked.model])) {
|
|
295
308
|
metrics.inc("images_omitted_total", { model: picked.model });
|
|
@@ -338,7 +351,7 @@ export function createResolveSpec(ctx) {
|
|
|
338
351
|
return deriveAskEffective(askForm.form, "unresolved") === "human_reachable";
|
|
339
352
|
};
|
|
340
353
|
const assembleSpecLiteral = (body, auth, req, opts, parts, effMode) => {
|
|
341
|
-
const { scenarioName, cap, hands, acceptedAppend, parsedSettings, attachmentNotice, taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked, resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, } = parts;
|
|
354
|
+
const { scenarioName, cap, hands, acceptedAppend, parsedSettings, attachmentNotice, taskHooks, additionalDirectories, additionalReadDirectories, wireCatalog, picked, resumeAtEntryId, rewindFilesToEntryId, s4DefaultScopes, projectKey, } = parts;
|
|
342
355
|
const storedToolAxes = opts?.leg === "fresh" ? undefined : storedToolAxesRereadM19(new Date().toISOString().slice(0, 10));
|
|
343
356
|
const spec = {
|
|
344
357
|
objective: attachmentNotice ? `${picked.cleanedObjective}\n\n${attachmentNotice}` : picked.cleanedObjective,
|
|
@@ -380,7 +393,7 @@ export function createResolveSpec(ctx) {
|
|
|
380
393
|
? { retainBackgroundProcesses: true }
|
|
381
394
|
: {}),
|
|
382
395
|
...(body.excludeAllTools === true ? { excludeAllTools: true } : {}),
|
|
383
|
-
...(
|
|
396
|
+
...buildExcludeToolsSeat(cap.excludeTools, toolNameListFromBody(body.excludeTools)),
|
|
384
397
|
...allowToolsSpecFragment(body.allowTools),
|
|
385
398
|
...(() => { const v = toolNameListFromBody(body.deferTools); return v ? { deferTools: v } : {}; })(),
|
|
386
399
|
...(() => { const v = promptProfileFromBody(body.promptProfile); return v ? { promptProfile: v } : {}; })(),
|
|
@@ -389,7 +402,7 @@ export function createResolveSpec(ctx) {
|
|
|
389
402
|
...(declaresInteractivePosture(body, req, opts) ? { interactionPosture: "interactive" } : {}),
|
|
390
403
|
...(body.approvalReach !== undefined ? { approvalReach: body.approvalReach } : {}),
|
|
391
404
|
...(typeof body.oneShot === "boolean" ? { oneShot: body.oneShot } : {}),
|
|
392
|
-
resilience: normalizeResilience(body.resilience, explicitOperatorOk(auth?.principal, config
|
|
405
|
+
resilience: normalizeResilience(body.resilience, explicitOperatorOk(auth?.principal, config)),
|
|
393
406
|
finalVerification: cap.finalVerification === true || body.finalVerification === true ? true : undefined,
|
|
394
407
|
attachments: normalizeAttachments(body.attachments),
|
|
395
408
|
...(taskHooks ? { mods: [taskHooks] } : {}),
|
|
@@ -400,23 +413,23 @@ export function createResolveSpec(ctx) {
|
|
|
400
413
|
const cm = matchCatalogModel(body.compactionModel, wireCatalog, config.modelRefusals);
|
|
401
414
|
const refusedCm = cm === undefined ? refusedCatalogEntry(body.compactionModel, config.modelRefusals) : undefined;
|
|
402
415
|
if (refusedCm !== undefined && opts?.leg === "fresh") {
|
|
403
|
-
throw new HttpError(400, modelUnavailableMessage("compactionModel", body.compactionModel
|
|
416
|
+
throw new HttpError(400, modelUnavailableMessage("compactionModel", body.compactionModel, refusedCm.name, refusedCm.refusal), { code: "request.model_unavailable" });
|
|
404
417
|
}
|
|
405
418
|
if (cm === undefined) {
|
|
406
419
|
if (opts?.leg === "fresh") {
|
|
407
|
-
throw new HttpError(400, `unknown compactionModel "${body.compactionModel
|
|
420
|
+
throw new HttpError(400, `unknown compactionModel "${echoModelRef(body.compactionModel)}" — not in the configured catalog (name, tier word, or id; a catalog refresh may have removed it mid-request)`);
|
|
408
421
|
}
|
|
409
422
|
metrics.inc("task_model_unknown_fallback_total");
|
|
410
|
-
logger.warn("compaction_model_unknown_fallback", { requested: body.compactionModel
|
|
423
|
+
logger.warn("compaction_model_unknown_fallback", { requested: echoModelRef(body.compactionModel), sessionId: auth?.sessionId ?? null });
|
|
411
424
|
return {};
|
|
412
425
|
}
|
|
413
426
|
if (!isAtMentionable(cm, wireCatalog, config.atMention, config.modelRefusals)) {
|
|
414
427
|
const terminal = terminalCatalogName(cm, wireCatalog, config.modelRefusals) ?? cm;
|
|
415
428
|
if (opts?.leg === "fresh") {
|
|
416
|
-
throw new HttpError(400, `compactionModel "${body.compactionModel
|
|
429
|
+
throw new HttpError(400, `compactionModel "${echoModelRef(body.compactionModel)}" is not @-mentionable on this deployment (it resolves to catalog model "${terminal}") — which models can be @-mentioned is configured by the operator (models.atMention)`, { code: "request.model_not_allowed" });
|
|
417
430
|
}
|
|
418
431
|
metrics.inc("task_model_not_allowlisted_resume_total");
|
|
419
|
-
logger.warn("task_model_not_allowlisted_resume", { requested: body.compactionModel
|
|
432
|
+
logger.warn("task_model_not_allowlisted_resume", { requested: echoModelRef(body.compactionModel), resolved: terminal, source: "compaction", sessionId: auth?.sessionId ?? null, note: "resumed leg keeps the compaction model it was started with — the allowlist gates fresh picks only" });
|
|
420
433
|
}
|
|
421
434
|
return { compactionModel: cm };
|
|
422
435
|
})()),
|
|
@@ -459,7 +472,7 @@ export function createResolveSpec(ctx) {
|
|
|
459
472
|
})(),
|
|
460
473
|
...(config.requirePrincipal !== true ? { backgroundScope: "session" } : {}),
|
|
461
474
|
memory: memoryEngine
|
|
462
|
-
? memorySpecForRequest(auth?.memoryScope,
|
|
475
|
+
? memorySpecForRequest(auth?.memoryScope, projectKey, body.memoryWrite, s4DefaultScopes, { multiTenant: config.requirePrincipal === true }, { memory: body.memory, memoryCapture: body.memoryCapture })
|
|
463
476
|
: undefined,
|
|
464
477
|
...((v) => (v !== undefined ? { memoryPersistenceCapable: v } : {}))(effectiveMemoryPersistenceCapable(config)),
|
|
465
478
|
tools: ((base) => {
|
|
@@ -505,7 +518,7 @@ export function createResolveSpec(ctx) {
|
|
|
505
518
|
};
|
|
506
519
|
return spec;
|
|
507
520
|
};
|
|
508
|
-
const foldGovernanceAndSettings = async (body, auth, spec, gated
|
|
521
|
+
const foldGovernanceAndSettings = async (body, auth, spec, gated) => {
|
|
509
522
|
const { acceptedAppend, parsedSettings } = gated;
|
|
510
523
|
const hostSemanticsLane = !isSandboxPathAdjudicationLane(config.remoteExec?.provider);
|
|
511
524
|
const laneHomeBase = () => {
|
|
@@ -533,7 +546,7 @@ export function createResolveSpec(ctx) {
|
|
|
533
546
|
};
|
|
534
547
|
const governedBase = applyRuntimeGovernance(spec, createDeploymentGovernanceInputs(config, pathAdjudication));
|
|
535
548
|
let governed = governedBase;
|
|
536
|
-
let effectiveSettings =
|
|
549
|
+
let effectiveSettings = parsedSettings.settings;
|
|
537
550
|
if (effectiveSettings?.outputStyle && acceptedAppend && acceptedAppend.length + 2 + effectiveSettings.outputStyle.length > MAX_SETTINGS_OUTPUT_STYLE_CHARS) {
|
|
538
551
|
logger.warn("output_style_dropped", { detail: `combined append carriers exceed the ${MAX_SETTINGS_OUTPUT_STYLE_CHARS} cap (rider ${acceptedAppend.length} + style ${effectiveSettings.outputStyle.length}) — style dropped (pre-cap stored body on a resume leg?)`, sessionId: auth?.sessionId ?? null });
|
|
539
552
|
const { outputStyle: _dropped2, ...rest2 } = effectiveSettings;
|
|
@@ -549,65 +562,31 @@ export function createResolveSpec(ctx) {
|
|
|
549
562
|
? await ensureScratchpadDir(config.localDataRoot ?? localRoot, auth.sessionId, (msg, meta) => logger.warn(msg, { ...(meta ?? {}), sessionId: auth.sessionId }))
|
|
550
563
|
: undefined);
|
|
551
564
|
if (effectiveSettings) {
|
|
552
|
-
const
|
|
553
|
-
...(
|
|
554
|
-
|
|
555
|
-
isExempt: async (toolName) => {
|
|
556
|
-
const hit = await approvalExemptionStore.has(auth.sessionId, toolName);
|
|
557
|
-
if (hit)
|
|
558
|
-
logger.info("fs_write_gate_exempted", { toolName, sessionId: auth.sessionId });
|
|
559
|
-
return hit;
|
|
560
|
-
},
|
|
561
|
-
}
|
|
562
|
-
: {}),
|
|
565
|
+
const ruleBases = {
|
|
566
|
+
...(pathAdjudication.taskRoot !== undefined ? { taskRoot: pathAdjudication.taskRoot } : {}),
|
|
567
|
+
...(pathAdjudication.taskHome !== undefined ? { taskHome: pathAdjudication.taskHome } : {}),
|
|
563
568
|
};
|
|
564
|
-
const fsWriteGate = hostSemanticsLane
|
|
565
|
-
? {
|
|
566
|
-
env: pathAdjudication.env,
|
|
567
|
-
...(pathAdjudication.cwd !== undefined ? { cwd: pathAdjudication.cwd } : {}),
|
|
568
|
-
...(pathAdjudication.taskRoot !== undefined ? { taskRoot: pathAdjudication.taskRoot } : {}),
|
|
569
|
-
...(pathAdjudication.taskHome !== undefined ? { taskHome: pathAdjudication.taskHome } : {}),
|
|
570
|
-
...(scratchpadDir ? { scratchpadDir } : {}),
|
|
571
|
-
...gateCommon,
|
|
572
|
-
}
|
|
573
|
-
:
|
|
574
|
-
(() => {
|
|
575
|
-
const sandboxScratchpadDir = isRemoteScratchpadLane(config.remoteExec?.provider) ? remoteScratchpadDirFor(auth?.sessionId) : undefined;
|
|
576
|
-
return {
|
|
577
|
-
env: pathAdjudication.env,
|
|
578
|
-
...(pathAdjudication.taskHome !== undefined ? { taskHome: pathAdjudication.taskHome } : {}),
|
|
579
|
-
...gateCommon,
|
|
580
|
-
...(sandboxScratchpadDir ? { scratchpadDir: sandboxScratchpadDir } : {}),
|
|
581
|
-
...(gateCommon.isExempt
|
|
582
|
-
? {
|
|
583
|
-
isExempt: (toolName, canonicalPath) => canonicalPath.startsWith("/") ? gateCommon.isExempt(toolName) : false,
|
|
584
|
-
}
|
|
585
|
-
: {}),
|
|
586
|
-
};
|
|
587
|
-
})();
|
|
588
|
-
const workflowGate = approvalExemptionStore && auth?.sessionId
|
|
589
|
-
? {
|
|
590
|
-
isExempt: async (toolName) => {
|
|
591
|
-
const hit = await approvalExemptionStore.has(auth.sessionId, toolName);
|
|
592
|
-
if (hit)
|
|
593
|
-
logger.info("workflow_gate_exempted", { toolName, sessionId: auth.sessionId });
|
|
594
|
-
return hit;
|
|
595
|
-
},
|
|
596
|
-
}
|
|
597
|
-
: undefined;
|
|
598
569
|
try {
|
|
599
|
-
governed = applyTaskSettings(governedBase, effectiveSettings,
|
|
570
|
+
governed = applyTaskSettings(governedBase, effectiveSettings, ruleBases);
|
|
600
571
|
}
|
|
601
572
|
catch (e) {
|
|
602
|
-
if (e
|
|
603
|
-
throw new HttpError(
|
|
604
|
-
code: "request.field_conflict",
|
|
605
|
-
...(e.detail !== undefined ? { extra: { writeExemptDirCoversRoot: e.detail } } : {}),
|
|
606
|
-
});
|
|
607
|
-
}
|
|
573
|
+
if (e instanceof SettingsRuleRefusalError)
|
|
574
|
+
throw new HttpError(422, `${REQUEST_SETTINGS_REFUSAL_PREFIX}${e.message}`, { code: SETTINGS_RULE_REFUSAL_CODE, extra: { ...entryProblemsFacts(e.problems) } });
|
|
608
575
|
throw new HttpError(422, `${REQUEST_SETTINGS_REFUSAL_PREFIX}${e.message}`);
|
|
609
576
|
}
|
|
610
577
|
}
|
|
578
|
+
if (governed.selfOrchestration === true) {
|
|
579
|
+
governed = tightenGoverned(governed, {
|
|
580
|
+
toolPolicy: createWorkflowAskPolicy(approvalExemptionStore && auth?.sessionId
|
|
581
|
+
? async (toolName) => {
|
|
582
|
+
const hit = await approvalExemptionStore.has(auth.sessionId, toolName);
|
|
583
|
+
if (hit)
|
|
584
|
+
logger.info("workflow_gate_exempted", { toolName, sessionId: auth.sessionId });
|
|
585
|
+
return hit;
|
|
586
|
+
}
|
|
587
|
+
: undefined),
|
|
588
|
+
});
|
|
589
|
+
}
|
|
611
590
|
return { governed, scratchpadDir, hostSemanticsLane };
|
|
612
591
|
};
|
|
613
592
|
const applyImageFactsAndRouting = async (body, auth, governed, folded) => {
|
|
@@ -631,7 +610,7 @@ export function createResolveSpec(ctx) {
|
|
|
631
610
|
const resolved = await resolveSandboxImageRef({
|
|
632
611
|
profile: taskImageProfile,
|
|
633
612
|
...(capsNeeded && capsNeeded.length > 0 ? { capabilitiesNeeded: capsNeeded } : {}),
|
|
634
|
-
viewer: { operator: explicitOperatorOk(auth.principal, config
|
|
613
|
+
viewer: { operator: explicitOperatorOk(auth.principal, config), tenantId: auth.principal ?? null },
|
|
635
614
|
index: imageIndex,
|
|
636
615
|
});
|
|
637
616
|
if (!resolved.ok)
|
|
@@ -662,7 +641,7 @@ export function createResolveSpec(ctx) {
|
|
|
662
641
|
const isolatedExecEnv = isIsolatedExecEnv(config.remoteExec?.provider, config.remoteExec?.provider === "k8s" ? config.remoteExec.runtimeClass : undefined);
|
|
663
642
|
const decision = routeServiceTask({
|
|
664
643
|
isolatedExecEnv,
|
|
665
|
-
hasExecutionEnv:
|
|
644
|
+
hasExecutionEnv: laneWiresExecutionEnv(executionLaneOf(config.remoteExec?.provider)),
|
|
666
645
|
...(config.autonomy ? { autonomy: config.autonomy } : {}),
|
|
667
646
|
});
|
|
668
647
|
logger.info("orchestration_routed", { mode: decision.mode, reason: decision.reason, sessionId: auth?.sessionId ?? null });
|