@sema-agent/server 7.131.0 → 7.133.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 +575 -0
- package/README.md +12 -9
- package/README.zh-CN.md +9 -6
- package/USAGE.md +326 -98
- package/deploy/sema-up/README.md +19 -1
- package/deploy/sema-up/chart/templates/server-v4pro.yaml +5 -2
- package/deploy/sema-up/chart/templates/server.yaml +5 -2
- 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 +31 -13
- 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 +82 -20
- package/dist/approval-card.js +46 -16
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval.d.ts +9 -0
- package/dist/approval.js +24 -3
- package/dist/audit.d.ts +33 -19
- package/dist/audit.js +12 -16
- package/dist/auth-bridge.d.ts +4 -0
- package/dist/auth-bridge.js +10 -11
- package/dist/bake-runner/main.js +3 -2
- package/dist/boot/deferred-sandbox-path-env.js +1 -1
- package/dist/boot/deployment-mods.d.ts +31 -0
- package/dist/boot/deployment-mods.js +26 -0
- package/dist/boot/execution-env.d.ts +1 -1
- package/dist/boot/execution-env.js +27 -12
- package/dist/boot/execution-lane.js +11 -0
- package/dist/boot/leader.js +2 -0
- package/dist/boot/memory-boundary.d.ts +2 -2
- 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.d.ts +17 -0
- package/dist/boot/read-deny-anchor-audit.js +36 -0
- package/dist/boot/reapers.d.ts +3 -0
- package/dist/boot/reapers.js +21 -1
- package/dist/boot/resolve-spec.d.ts +4 -5
- package/dist/boot/resolve-spec.js +74 -123
- package/dist/boot/runner-deps.d.ts +19 -8
- package/dist/boot/runner-deps.js +15 -2
- package/dist/boot/session-faces.d.ts +2 -7
- package/dist/boot/session-faces.js +4 -2
- package/dist/boot/stage-02-web-admin-pull.js +4 -1
- package/dist/boot/stage-03-store-backend.d.ts +1 -1
- package/dist/boot/stage-03-store-backend.js +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +4 -4
- package/dist/boot/stage-05-execution-env.js +7 -10
- package/dist/boot/stage-06-runners.d.ts +4 -2
- package/dist/boot/stage-06-runners.js +11 -7
- package/dist/boot/stage-07-capability-layer.d.ts +4 -2
- package/dist/boot/stage-07-capability-layer.js +27 -6
- package/dist/boot/stage-08-reapers.d.ts +4 -2
- package/dist/boot/stage-08-reapers.js +2 -2
- package/dist/boot/stage-09-leader.d.ts +6 -9
- package/dist/boot/stage-10-http-server.d.ts +6 -9
- package/dist/boot/stage-10-http-server.js +7 -9
- package/dist/boot/stores.d.ts +1 -1
- package/dist/boot/stores.js +7 -8
- package/dist/boot/web-admin.d.ts +4 -3
- package/dist/boot/web-admin.js +186 -98
- package/dist/boot/workflow-orchestration.d.ts +2 -0
- package/dist/boot/workflow-orchestration.js +2 -1
- package/dist/brain.js +25 -25
- package/dist/breaker-key.d.ts +6 -0
- package/dist/breaker-key.js +29 -0
- package/dist/budget.js +5 -4
- package/dist/caller-text-echo.d.ts +23 -0
- package/dist/caller-text-echo.js +21 -0
- package/dist/capabilities/brand-identity.d.ts +26 -0
- package/dist/capabilities/brand-identity.js +27 -0
- package/dist/capabilities/center-plugins.d.ts +7 -0
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +32 -59
- package/dist/capabilities/center-prompts.js +18 -32
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/composite-members.js +1 -1
- package/dist/capabilities/engine-capabilities.js +2 -1
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +30 -6
- package/dist/capabilities/hands-lane.js +11 -1
- package/dist/capabilities/mcp-probe.d.ts +48 -3
- package/dist/capabilities/mcp-probe.js +47 -135
- package/dist/capabilities/scenarios.d.ts +95 -45
- package/dist/capabilities/scenarios.js +53 -38
- package/dist/capabilities/skills.d.ts +19 -4
- package/dist/capabilities/skills.js +30 -10
- package/dist/capability-facts.d.ts +34 -4
- package/dist/capability-facts.js +28 -2
- package/dist/center-config-tier.d.ts +69 -0
- package/dist/center-config-tier.js +42 -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 +47 -32
- 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-lkg.d.ts +9 -9
- package/dist/config-lkg.js +20 -4
- package/dist/config-provider.d.ts +9 -2
- package/dist/config-provider.js +18 -6
- package/dist/config-types.d.ts +75 -20
- package/dist/config-types.js +8 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.js +137 -62
- 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 -22
- package/dist/elicitation.js +3 -2
- package/dist/entry-problems.d.ts +34 -0
- package/dist/entry-problems.js +14 -0
- package/dist/env-name-allowlist-knobs.d.ts +12 -2
- package/dist/env-name-allowlist-knobs.js +5 -4
- package/dist/exec-bounds.d.ts +15 -3
- package/dist/exec-bounds.js +4 -0
- package/dist/execution-lane-caps.d.ts +56 -10
- package/dist/execution-lane-caps.js +50 -0
- package/dist/field-conflict.d.ts +43 -0
- package/dist/field-conflict.js +20 -0
- package/dist/fleet/fleet-bus.d.ts +80 -6
- package/dist/fleet/fleet-bus.js +41 -9
- package/dist/hooks/classic-stations.d.ts +91 -0
- package/dist/hooks/classic-stations.js +27 -0
- package/dist/hooks/command-spawn.d.ts +57 -0
- package/dist/hooks/command-spawn.js +139 -0
- package/dist/hooks/hook-llm.d.ts +8 -5
- package/dist/hooks/hook-llm.js +79 -36
- package/dist/hooks/hook-runner.d.ts +349 -95
- package/dist/hooks/hook-runner.js +855 -568
- 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.d.ts +8 -2
- package/dist/http/admission.js +188 -101
- package/dist/http/approval-sweeps.js +99 -21
- package/dist/http/caller-trust.d.ts +77 -0
- package/dist/http/caller-trust.js +143 -0
- package/dist/http/checkpoint-ctx.d.ts +41 -24
- package/dist/http/checkpoint-ctx.js +23 -16
- package/dist/http/claimed-run.d.ts +14 -0
- package/dist/http/claimed-run.js +15 -0
- package/dist/http/device-placement.d.ts +2 -4
- package/dist/http/device-placement.js +7 -11
- package/dist/http/dispatch.d.ts +0 -4
- package/dist/http/dispatch.js +15 -13
- package/dist/http/durable-run-leg.d.ts +6 -33
- package/dist/http/durable-run-leg.js +36 -10
- package/dist/http/health-self-report.d.ts +7 -5
- package/dist/http/health-self-report.js +4 -18
- package/dist/http/owner-access.d.ts +56 -0
- package/dist/http/owner-access.js +42 -0
- package/dist/http/principal-gate.d.ts +70 -28
- package/dist/http/principal-gate.js +61 -15
- package/dist/http/readiness.d.ts +11 -5
- package/dist/http/readiness.js +10 -3
- package/dist/http/refusal-body.d.ts +21 -0
- package/dist/http/refusal-body.js +4 -0
- package/dist/http/request-guards.d.ts +43 -23
- package/dist/http/request-guards.js +53 -17
- package/dist/http/resume-ctx-read.d.ts +2 -5
- package/dist/http/resume-ctx-read.js +7 -4
- package/dist/http/resume-legs.d.ts +28 -4
- package/dist/http/resume-legs.js +169 -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 -28
- 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/approvals-assistant.js +49 -48
- package/dist/http/routes/background.js +3 -2
- package/dist/http/routes/capabilities.js +21 -5
- 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.js +6 -2
- 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.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 +5 -18
- package/dist/http/routes/runs.d.ts +5 -0
- package/dist/http/routes/runs.js +34 -107
- package/dist/http/routes/session-sync.js +15 -26
- package/dist/http/routes/sessions.js +30 -40
- package/dist/http/routes/shared-memory.js +2 -13
- package/dist/http/routes/side-query.js +8 -7
- package/dist/http/routes/tasks.js +67 -21
- package/dist/http/routes/workflows.d.ts +351 -0
- package/dist/http/routes/workflows.js +153 -119
- package/dist/http/send.d.ts +33 -10
- package/dist/http/send.js +21 -4
- package/dist/http/server.d.ts +27 -18
- package/dist/http/server.js +34 -6
- package/dist/http/stored-body-replay.js +17 -4
- package/dist/http/submit-ctx.d.ts +25 -0
- package/dist/http/submit-ctx.js +40 -0
- package/dist/http/submit-replay.d.ts +4 -3
- package/dist/http/submit-replay.js +5 -4
- package/dist/http/wire-types.d.ts +11 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -2
- package/dist/lane-home-probe.d.ts +112 -0
- package/dist/lane-home-probe.js +101 -0
- package/dist/leader/endpoint.d.ts +4 -1
- package/dist/leader/endpoint.js +11 -10
- package/dist/limit-refusal.d.ts +59 -0
- package/dist/limit-refusal.js +15 -0
- package/dist/main.js +1 -1
- package/dist/mcp-assertion-header.d.ts +32 -19
- package/dist/mcp-assertion-header.js +10 -9
- package/dist/mcp-tool-faces.d.ts +5 -0
- package/dist/mcp-tool-faces.js +6 -4
- package/dist/memory-project-layer.d.ts +37 -0
- package/dist/memory-project-layer.js +46 -0
- package/dist/memory-scope.d.ts +24 -17
- 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-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 +44 -12
- package/dist/model-provider.js +21 -2
- package/dist/model-route-endpoint.d.ts +9 -12
- package/dist/model-route-endpoint.js +8 -11
- 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/cost-taxonomy.d.ts +7 -7
- package/dist/observability/err-text.d.ts +6 -0
- package/dist/observability/err-text.js +18 -4
- package/dist/observability/fail-open.d.ts +76 -14
- package/dist/observability/fail-open.js +76 -14
- package/dist/observability/metrics.js +4 -1
- package/dist/observability/prompt-manifest.d.ts +33 -82
- package/dist/observability/prompt-manifest.js +122 -17
- package/dist/observability/run-terminal.js +14 -6
- package/dist/observability/secret-env-scrub.d.ts +13 -1
- package/dist/observability/secret-env-scrub.js +13 -1
- package/dist/observability/tool-trace.d.ts +16 -21
- package/dist/observability/tool-trace.js +58 -49
- 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 +118 -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 +39 -6
- package/dist/parked-decide.js +98 -51
- package/dist/parked-revive-surface.d.ts +9 -2
- package/dist/parked-revive-surface.js +11 -8
- package/dist/per-task-image.d.ts +7 -1
- package/dist/per-task-image.js +3 -3
- package/dist/permission-rule-list.d.ts +1 -1
- package/dist/permission-rule-list.js +2 -2
- package/dist/plain-string-record.d.ts +25 -0
- package/dist/plain-string-record.js +32 -0
- 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/blob-backend.d.ts +83 -15
- package/dist/plugins/blob-backend.js +68 -15
- 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 +3 -0
- package/dist/plugins/caching-session-store.js +3 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +28 -4
- package/dist/plugins/checkpoint-store-sql.js +59 -28
- 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/k8s-bg-scripts.d.ts +11 -0
- package/dist/plugins/k8s-bg-scripts.js +22 -0
- package/dist/plugins/local-checkpoint-store.d.ts +2 -0
- package/dist/plugins/local-checkpoint-store.js +11 -3
- package/dist/plugins/local-session-store.d.ts +1 -1
- package/dist/plugins/local-session-store.js +1 -1
- package/dist/plugins/local-session-window.d.ts +39 -0
- package/dist/plugins/local-session-window.js +54 -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 +245 -93
- package/dist/plugins/one-time-migrations.js +668 -207
- 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-sql.d.ts +13 -7
- package/dist/plugins/permission-rule-store-sql.js +4 -18
- package/dist/plugins/pg-pool.js +39 -7
- package/dist/plugins/pg-session-storage.d.ts +20 -8
- package/dist/plugins/pg-session-storage.js +34 -21
- package/dist/plugins/remote-env-adb.d.ts +12 -12
- package/dist/plugins/remote-env-adb.js +21 -6
- package/dist/plugins/remote-env-device.js +3 -0
- package/dist/plugins/remote-env-e2b.d.ts +1 -1
- package/dist/plugins/remote-env-e2b.js +21 -9
- package/dist/plugins/remote-env-host.d.ts +9 -9
- package/dist/plugins/remote-env-host.js +10 -32
- package/dist/plugins/remote-env-k8s.d.ts +103 -38
- package/dist/plugins/remote-env-k8s.js +288 -95
- package/dist/plugins/remote-env-local-docker.d.ts +27 -13
- package/dist/plugins/remote-env-local-docker.js +82 -11
- package/dist/plugins/remote-env-ssh.d.ts +21 -12
- package/dist/plugins/remote-env-ssh.js +117 -5
- package/dist/plugins/remote-shell.d.ts +0 -1
- package/dist/plugins/remote-shell.js +1 -2
- package/dist/plugins/retention-store-sql.js +6 -2
- package/dist/plugins/run-store-sql.d.ts +16 -14
- package/dist/plugins/run-store-sql.js +22 -2
- package/dist/plugins/schema-consistency.d.ts +54 -0
- package/dist/plugins/schema-consistency.js +52 -0
- 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 +39 -0
- package/dist/plugins/session-epoch-anchor.js +22 -0
- package/dist/plugins/session-store.d.ts +18 -8
- package/dist/plugins/session-store.js +15 -4
- package/dist/plugins/shared-memory-store-sql.d.ts +9 -3
- package/dist/plugins/shared-memory-store-sql.js +5 -16
- package/dist/plugins/sql-driver.d.ts +205 -1
- package/dist/plugins/sql-driver.js +325 -13
- package/dist/plugins/sql-errors.d.ts +64 -0
- package/dist/plugins/sql-errors.js +57 -0
- package/dist/plugins/store-backend.d.ts +36 -1
- package/dist/plugins/store-backend.js +42 -15
- 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 +8 -11
- package/dist/plugins/tidb-session-storage.js +6 -16
- package/dist/plugins/tidb-session-store.d.ts +24 -4
- package/dist/plugins/tidb-session-store.js +29 -5
- 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/prompts-domain-validate.d.ts +17 -61
- package/dist/prompts-domain-validate.js +9 -119
- 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 +9 -2
- package/dist/request-key-closure.js +11 -5
- package/dist/request-value-closure.d.ts +5 -0
- package/dist/request-value-closure.js +11 -3
- package/dist/rule-entry-list.d.ts +38 -11
- package/dist/rule-entry-list.js +106 -30
- 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 +54 -24
- package/dist/runs.d.ts +15 -8
- package/dist/runs.js +35 -1
- 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/security.d.ts +87 -9
- package/dist/security.js +52 -9
- package/dist/server-secret-env.d.ts +44 -18
- package/dist/server-secret-env.js +49 -8
- package/dist/session-error-wire.d.ts +19 -2
- package/dist/session-error-wire.js +5 -1
- package/dist/session-incarnation.d.ts +15 -5
- package/dist/session-incarnation.js +16 -9
- 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 +27 -6
- package/dist/spec-fields.d.ts +28 -16
- package/dist/spec-fields.js +66 -54
- package/dist/sql-engine-posture.d.ts +31 -4
- package/dist/sql-engine-posture.js +36 -1
- package/dist/stored-request-tool-axes-m19.d.ts +19 -4
- package/dist/stored-request-tool-axes-m19.js +30 -2
- package/dist/task-a2a.d.ts +9 -1
- package/dist/task-a2a.js +73 -47
- package/dist/task-cwd.d.ts +1 -1
- package/dist/task-mcp.d.ts +46 -58
- package/dist/task-mcp.js +82 -107
- package/dist/task-settings.d.ts +95 -108
- package/dist/task-settings.js +77 -98
- package/dist/text-bidi.d.ts +1 -48
- package/dist/text-bidi.js +3 -5
- package/dist/tighten-only-seats.d.ts +150 -0
- package/dist/tighten-only-seats.js +196 -0
- package/dist/tool-approval.d.ts +304 -88
- package/dist/tool-approval.js +623 -239
- package/dist/trace/core-keyset-guard.d.ts +122 -20
- package/dist/trace/engine-notice-wire.d.ts +11 -3
- package/dist/trace/engine-notice-wire.js +8 -1
- package/dist/trace/exit-seat.d.ts +28 -0
- package/dist/trace/exit-seat.js +76 -0
- package/dist/trace/ledger-events.d.ts +6 -3
- package/dist/trace/ledger-sink.js +4 -1
- package/dist/trace/model-segment.js +1 -1
- package/dist/trace/project.d.ts +98 -17
- package/dist/trace/project.js +98 -50
- package/dist/trace/projection-table.d.ts +100 -0
- package/dist/trace/projection-table.js +130 -0
- package/dist/trace/redact.d.ts +54 -0
- package/dist/trace/redact.js +778 -152
- package/dist/trace/self-minted-wire.d.ts +345 -1
- package/dist/trace/self-minted-wire.js +117 -1
- package/dist/trace/wire-projection-faces.d.ts +377 -3
- package/dist/trace/wire-projection-faces.js +164 -1
- 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/candidate-gate.d.ts +6 -6
- package/dist/web-admin-client/candidate-gate.js +3 -3
- package/dist/web-admin-client/facade.d.ts +1 -1
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/http-client.js +0 -6
- package/dist/web-admin-client/read-face.js +5 -9
- package/dist/web-admin-client/read-warnings.d.ts +13 -0
- package/dist/web-admin-client/read-warnings.js +10 -0
- package/dist/web-admin-client/skills-mcp.d.ts +3 -0
- package/dist/web-admin-client/skills-mcp.js +11 -9
- package/dist/web-admin-client/types.d.ts +2 -3
- package/dist/workspace-cache.d.ts +35 -0
- package/dist/workspace-cache.js +36 -0
- package/dist/workspace-space.d.ts +3 -2
- package/dist/workspace-space.js +2 -0
- package/docs/DEVICE-EXECUTOR-PROTOCOL.md +65 -10
- package/package.json +8 -4
- package/scripts/drain-check-local.mjs +34 -1
- package/scripts/drain-check.mysql.sql +30 -2
- package/scripts/drain-check.pg.sql +29 -2
- package/dist/capabilities/memory-notice.d.ts +0 -138
- package/dist/capabilities/memory-notice.js +0 -64
- package/dist/capabilities/prompt.d.ts +0 -17
- package/dist/capabilities/prompt.js +0 -6
- package/dist/mcp-content-origin.d.ts +0 -34
- package/dist/mcp-content-origin.js +0 -10
- package/dist/tool-axis-words.d.ts +0 -27
- package/dist/tool-axis-words.js +0 -9
- package/dist/wire-name-bound.d.ts +0 -14
- package/dist/wire-name-bound.js +0 -13
package/dist/auth-bridge.js
CHANGED
|
@@ -8,7 +8,8 @@ export function authBridgeIssuerOf(config) {
|
|
|
8
8
|
return { issuer: config.webAdmin.baseUrl, source: "fallback" };
|
|
9
9
|
return undefined;
|
|
10
10
|
}
|
|
11
|
-
const DEFAULT_JWKS_TTL_SEC = 15 * 60;
|
|
11
|
+
export const DEFAULT_JWKS_TTL_SEC = 15 * 60;
|
|
12
|
+
export const JWKS_FETCH_TIMEOUT_MS = 10_000;
|
|
12
13
|
const MAX_JWKS_BYTES = 256 * 1024;
|
|
13
14
|
const MAX_TOKEN_CHARS = 16 * 1024;
|
|
14
15
|
const MAX_SEGMENT_BYTES = 64 * 1024;
|
|
@@ -39,6 +40,7 @@ export function createWebAdminJwtVerifier(opts) {
|
|
|
39
40
|
let lastFetchAttemptMs;
|
|
40
41
|
let lastFetchSuccessMs;
|
|
41
42
|
let inflight;
|
|
43
|
+
const withinGrace = () => lastFetchSuccessMs !== undefined && jwksWithinOfflineGrace({ lastFetchSuccessMs, nowMs: now() }, { offlineGraceSec });
|
|
42
44
|
const fail = (error, kid) => {
|
|
43
45
|
opts.metrics?.inc("auth_bridge_verify_total", { outcome: error });
|
|
44
46
|
opts.logger?.warn?.("auth_bridge_rejected", { error, ...(kid ? { kid: kid.slice(0, 128) } : {}), iss: displayIssuer });
|
|
@@ -50,7 +52,7 @@ export function createWebAdminJwtVerifier(opts) {
|
|
|
50
52
|
inflight = (async () => {
|
|
51
53
|
lastFetchAttemptMs = now();
|
|
52
54
|
try {
|
|
53
|
-
const res = await doFetch(jwksUrl, { redirect: "error", signal: AbortSignal.timeout(
|
|
55
|
+
const res = await doFetch(jwksUrl, { redirect: "error", signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS) });
|
|
54
56
|
if (!res.ok)
|
|
55
57
|
throw new Error(`jwks HTTP ${res.status}`);
|
|
56
58
|
const cl = Number(res.headers.get("content-length"));
|
|
@@ -112,8 +114,9 @@ export function createWebAdminJwtVerifier(opts) {
|
|
|
112
114
|
return fail("unknown_issuer", kid);
|
|
113
115
|
if (classifyTimeClaims(payload, Math.floor(now() / 1000), clockSkewSec) !== "ok")
|
|
114
116
|
return fail("expired", kid);
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
+
const usableKey = () => (withinGrace() ? keys.get(kid) : undefined);
|
|
118
|
+
const snapshot = () => ({ cachedKids: withinGrace() ? [...keys.keys()] : [], lastFetchAttemptMs, nowMs: now() });
|
|
119
|
+
if (usableKey()) {
|
|
117
120
|
const ttlStale = lastFetchSuccessMs === undefined || now() - lastFetchSuccessMs > jwksTtlSec * 1000;
|
|
118
121
|
if (ttlStale && !inflight && (lastFetchAttemptMs === undefined || now() - lastFetchAttemptMs >= refreshMin * 1000)) {
|
|
119
122
|
void refreshJwks();
|
|
@@ -122,16 +125,12 @@ export function createWebAdminJwtVerifier(opts) {
|
|
|
122
125
|
else {
|
|
123
126
|
if (inflight)
|
|
124
127
|
await inflight;
|
|
125
|
-
if (!
|
|
128
|
+
if (!usableKey() && shouldForceJwksRefresh(kid, snapshot(), { jwksRefreshMinIntervalSec: refreshMin }))
|
|
126
129
|
await refreshJwks();
|
|
127
130
|
}
|
|
128
|
-
const key =
|
|
131
|
+
const key = usableKey();
|
|
129
132
|
if (!key) {
|
|
130
|
-
|
|
131
|
-
return graceOk ? fail("invalid_signature", kid) : fail("jwks_unavailable", kid);
|
|
132
|
-
}
|
|
133
|
-
if (lastFetchSuccessMs !== undefined && !jwksWithinOfflineGrace({ lastFetchSuccessMs, nowMs: now() }, { offlineGraceSec })) {
|
|
134
|
-
return fail("jwks_unavailable", kid);
|
|
133
|
+
return withinGrace() ? fail("invalid_signature", kid) : fail("jwks_unavailable", kid);
|
|
135
134
|
}
|
|
136
135
|
let sigOk = false;
|
|
137
136
|
try {
|
package/dist/bake-runner/main.js
CHANGED
|
@@ -5,6 +5,7 @@ import { logConfigDiagnostics, parseEnvNameAllowlist, parseNumOrFailNonNegative
|
|
|
5
5
|
import { installSecretEnvScrubRecorder } from "../observability/secret-env-scrub.js";
|
|
6
6
|
import { declareServerWithheldEnv, hostSubprocessEnv } from "../server-secret-env.js";
|
|
7
7
|
import { shellQuote as shellSafe } from "../plugins/remote-shell.js";
|
|
8
|
+
import { echoCallerText } from "../caller-text-echo.js";
|
|
8
9
|
import { BakeRunner, } from "./runner.js";
|
|
9
10
|
const BAKE_CLAIM_INGEST_FETCH_TIMEOUT_MS = 30_000;
|
|
10
11
|
const BAKE_HEARTBEAT_FETCH_TIMEOUT_MS = 10_000;
|
|
@@ -181,9 +182,9 @@ export async function execGroup(cmd, timeoutMs, envAllow) {
|
|
|
181
182
|
try {
|
|
182
183
|
const { code, signal } = await child.exited;
|
|
183
184
|
if (timedOut)
|
|
184
|
-
throw new Error(`host exec timed out after ${timeoutMs}ms (group killed): ${cmd
|
|
185
|
+
throw new Error(`host exec timed out after ${timeoutMs}ms (group killed): ${echoCallerText(cmd, { maxChars: 120 })}`);
|
|
185
186
|
if (code !== 0)
|
|
186
|
-
throw new Error(`host exec exited ${code ?? signal}: ${cmd
|
|
187
|
+
throw new Error(`host exec exited ${code ?? signal}: ${echoCallerText(cmd, { maxChars: 120 })}${stderr.trim() ? ` — ${stderr.trim().slice(-400)}` : ""}`);
|
|
187
188
|
return { stdout };
|
|
188
189
|
}
|
|
189
190
|
finally {
|
|
@@ -118,7 +118,7 @@ export class DeferredSandboxPathEnv extends StubExecutionEnv {
|
|
|
118
118
|
reason: found.reason,
|
|
119
119
|
face,
|
|
120
120
|
sessionId: this.sessionId ?? null,
|
|
121
|
-
note: "the sandbox
|
|
121
|
+
note: "the sandbox path adjudication has no task environment to read — the sensitive-path guard fails closed (deny) on every write target until one is bound",
|
|
122
122
|
});
|
|
123
123
|
}
|
|
124
124
|
return {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 部署座(`RunnerDeps.mods`)的注册:**铸**({@link createDeploymentMods})与**起服自证**({@link assertDeploymentModsAdmitted})都在这一处。
|
|
3
|
+
*
|
|
4
|
+
* 起服自证(律三:拒形只有引擎一种读法,本仓只负责「不写」与「启动时自证」):
|
|
5
|
+
* 部署座上的注册是本仓自己铸的。它们坏了
|
|
6
|
+
* —— 坏名、坏档、缺 `uses.calls`、`on` 越出 `uses`、只选无站的名字、`register` 抛 —— 引擎在每条腿的 prepare 里拒
|
|
7
|
+
* (`config.mods_invalid`),那就是每个请求都失败。所以起服时让引擎的 admission 判一次:判官仍是引擎(`admitModChain`),
|
|
8
|
+
* 本函数不判形,只把它的拒折成一句起服错误、拒启。两个起服入口(server 第五段、本地 CLI)同调这一只。
|
|
9
|
+
*
|
|
10
|
+
* 也拒启的两形(同一个理由:部署注册一张都不该缺席,也不该带病挂上):
|
|
11
|
+
* · admission 期的报告(引擎对坏 `budgetMs` 只报告、回落缺省,不拒)—— 部署注册不设 `budgetMs`,报告出现就是铸法坏了;
|
|
12
|
+
* · 被 `plugin.register` 判拒的注册(本部署没有这种判官;出现即装配错)。
|
|
13
|
+
* 腿外 admission 只建一只总线并跑一次各注册的 `register`(本仓的 `register` 是纯函数),不碰任何腿。
|
|
14
|
+
*/
|
|
15
|
+
import { type EngineDollar, type ModRegistration } from "@sema-agent/core";
|
|
16
|
+
import type { Logger } from "../observability/logger.js";
|
|
17
|
+
import type { Metrics } from "../observability/metrics.js";
|
|
18
|
+
/**
|
|
19
|
+
* 部署座上的注册列表 —— 两个起服入口(server 第五段与本地 CLI)同一只铸法,哪几张、什么顺序只写在这里:
|
|
20
|
+
* · 拒绝计量恒挂、在前;工具追踪(`TOOL_TRACE=true`,交 `traceLogger`)在后。两张都是 `prepend` 档的观察者,引擎按「档 → 部署先于任务 → 座内顺序」
|
|
21
|
+
* 串行跑观察者、且都在链之前 ⇒ 同一次拒绝先计数、后写追踪行;
|
|
22
|
+
* · 品牌行(`brandIdentity`:品牌部署 = local / TOC)—— `prompt.compose` 上的一条部署类 overlay(`capabilities/brand-identity.ts`),与两只观察者
|
|
23
|
+
* 不在同一个事件上,顺序不影响它们。部署开不开品牌只在这一个入参表态。
|
|
24
|
+
*/
|
|
25
|
+
export declare function createDeploymentMods(input: {
|
|
26
|
+
readonly metrics: Pick<Metrics, "inc">;
|
|
27
|
+
readonly traceLogger?: Logger | undefined;
|
|
28
|
+
readonly brandIdentity?: boolean | undefined;
|
|
29
|
+
}): readonly ModRegistration<EngineDollar>[];
|
|
30
|
+
export declare function assertDeploymentModsAdmitted(mods: readonly ModRegistration<EngineDollar>[]): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=deployment-mods.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { admitModChain } from "@sema-agent/core";
|
|
2
|
+
import { createBrandIdentityRegistration } from "../capabilities/brand-identity.js";
|
|
3
|
+
import { createPermissionDeniedMeter, createToolTracer } from "../observability/tool-trace.js";
|
|
4
|
+
export function createDeploymentMods(input) {
|
|
5
|
+
return [
|
|
6
|
+
createPermissionDeniedMeter(input.metrics),
|
|
7
|
+
...(input.traceLogger !== undefined ? [createToolTracer(input.traceLogger)] : []),
|
|
8
|
+
...(input.brandIdentity === true ? [createBrandIdentityRegistration()] : []),
|
|
9
|
+
];
|
|
10
|
+
}
|
|
11
|
+
const REFUSED = "deployment extension registration refused";
|
|
12
|
+
export async function assertDeploymentModsAdmitted(mods) {
|
|
13
|
+
const reports = [];
|
|
14
|
+
let records;
|
|
15
|
+
try {
|
|
16
|
+
({ records } = await admitModChain({ deployment: mods }, (err) => void reports.push(err.message)));
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
throw new Error(`${REFUSED}: ${e instanceof Error ? e.message : String(e)}`);
|
|
20
|
+
}
|
|
21
|
+
const refused = records.flatMap((r) => ("refusedBy" in r ? [`"${r.name}" refused by ${r.refusedBy}: ${r.reason}`] : []));
|
|
22
|
+
const problems = [...reports, ...refused];
|
|
23
|
+
if (problems.length > 0)
|
|
24
|
+
throw new Error(`${REFUSED}: ${problems.join("; ")}`);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=deployment-mods.js.map
|
|
@@ -62,7 +62,7 @@ export declare function createSessionScopedRegistries(maxEntries?: number): Sess
|
|
|
62
62
|
* · **工作区空间的分区 = 会话化身**(`spaceOccupant.incarnation`):建这只 env 时按 id 读一次会话店的 `incarnationOf`(会话行上的那一格,
|
|
63
63
|
* `session-incarnation.ts`;本工厂不取会话,正是 core 给「没取会话的读者」的那只读)。读数是闭集三臂(`SpaceOccupant`,适配器那边逐臂处置):
|
|
64
64
|
* 答令牌 ⇒ 已知;答 `undefined`(没有这只会话)⇒ `{ unread: "incarnation_unknown" }` —— 没有空间:空间车道不开、缓存卷不挂,各一行;
|
|
65
|
-
* 读抛 / 答出的不是非空串 ⇒ `{ fault: <code> }` —— 读不到空间 ≠ 没有空间:开着的空间车道 / 缓存卷让这只 env 一只 pod 都不建,
|
|
65
|
+
* 读抛 / 超时(`rpcTimeoutMs`,同一次 connect 里读围栏行与 `latest` 的那一只墙)/ 答出的不是非空串 ⇒ `{ fault: <code> }` —— 读不到空间 ≠ 没有空间:开着的空间车道 / 缓存卷让这只 env 一只 pod 都不建,
|
|
66
66
|
* connect 与 resumeVM 都答 `connect_failed`(与 `latest` 读失败同一铸点),一行 `workspace_space_unreadable_occupant`;`code` 是店的错误码,
|
|
67
67
|
* 从不带正文、从不带令牌。**绝不**以会话 id 代替;
|
|
68
68
|
* 同时开这只 env 在空间提交围栏上的座(`spaceOccupant.fence`,run 店的 `workspace_space_commit` 行;法见 `workspace-space-commit.ts`);
|
|
@@ -10,7 +10,7 @@ import { adbExecutionEnvFactory } from "../plugins/remote-env-adb.js";
|
|
|
10
10
|
import { deviceExecutionEnvFactory } from "../plugins/remote-env-device.js";
|
|
11
11
|
import { e2bExecutionEnvFactory } from "../plugins/remote-env-e2b.js";
|
|
12
12
|
import { hostExecutionEnvFactory, RemoteHostExecutionEnv } from "../plugins/remote-env-host.js";
|
|
13
|
-
import { checkSandboxEgressPolicy, createSpaceReclaimer, K8S_SANDBOX_NAMESPACE_DEFAULT, k8sExecutionEnvFactory } from "../plugins/remote-env-k8s.js";
|
|
13
|
+
import { boundedStoreCall, checkSandboxEgressPolicy, createSpaceReclaimer, K8S_SANDBOX_NAMESPACE_DEFAULT, k8sExecutionEnvFactory, rpcTimeoutMsOf } from "../plugins/remote-env-k8s.js";
|
|
14
14
|
import { createRunWorkspaceSnapshotSeat } from "../fleet/workspace-snapshot-residual.js";
|
|
15
15
|
import { createSpaceCommitFence } from "../workspace-space-commit.js";
|
|
16
16
|
import { localDockerExecutionEnvFactory } from "../plugins/remote-env-local-docker.js";
|
|
@@ -20,13 +20,15 @@ import { FileSchedulerBackend, defaultSchedulerStorePath } from "../plugins/sche
|
|
|
20
20
|
import * as facts from "../capability-facts.js";
|
|
21
21
|
import { materializeAttachmentsInto } from "../plugins/task-attachment-store.js";
|
|
22
22
|
import { reapOrphanWorktrees, withWorktreeIsolation } from "../plugins/worktree-isolation.js";
|
|
23
|
-
import {
|
|
23
|
+
import { derivePkgSourceEnv } from "../sandbox-pkg-source.js";
|
|
24
24
|
import { effectiveHostWorkspace } from "../task-cwd.js";
|
|
25
25
|
import { taskInheritEnvRefusal } from "../hosted-posture.js";
|
|
26
|
+
import { createCacheMissMemory } from "../workspace-cache.js";
|
|
26
27
|
import { workspaceSnapshotTimeoutOf } from "../workspace-space.js";
|
|
27
28
|
import { sayEgressPolicyReading } from "../sandbox-egress-policy.js";
|
|
28
29
|
import { isSandboxPathAdjudicationLane, sandboxPathEnvSlots, withSandboxPathEnvSlot } from "./deferred-sandbox-path-env.js";
|
|
29
|
-
import {
|
|
30
|
+
import { LANE_HOME_UNDECLARED_EVENT, createLaneHomeAbsenceReporter } from "../lane-home-probe.js";
|
|
31
|
+
import { REMOTE_EXEC_PROVIDER_WORDS, buildUndeclaredHomeNote, executionLaneHomeDir, executionLaneOf, isSingleMachineDefaultLane, laneBindsReads, laneIsolated } from "../execution-lane-caps.js";
|
|
30
32
|
function boundedSessionSetter(map, maxEntries) {
|
|
31
33
|
return (sid, value) => {
|
|
32
34
|
map.delete(sid);
|
|
@@ -54,7 +56,7 @@ function forwardedSandboxEnvKeys(remoteExec) {
|
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
function buildSandboxLaneEnv(config, explicit) {
|
|
57
|
-
const merged = { ...derivePkgSourceEnv(config.sandboxPkgSource,
|
|
59
|
+
const merged = { ...derivePkgSourceEnv(config.sandboxPkgSource, config.sandboxPkgSourceCustom), ...(explicit ?? {}) };
|
|
58
60
|
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
59
61
|
}
|
|
60
62
|
const MAX_CWD_SESSIONS = 4096;
|
|
@@ -108,15 +110,16 @@ export function createSessionScopedRegistries(maxEntries = MAX_CWD_SESSIONS) {
|
|
|
108
110
|
};
|
|
109
111
|
}
|
|
110
112
|
export function createK8sRunEnvFactory(k8sCfg, seats, deps) {
|
|
113
|
+
const cacheMisses = createCacheMissMemory();
|
|
111
114
|
return async (ctx) => {
|
|
112
115
|
const onWorkspaceSnapshot = createRunWorkspaceSnapshotSeat(ctx.sessionId);
|
|
113
116
|
const child = ctx.placementRootSessionId !== ctx.sessionId;
|
|
114
117
|
const s3Snapshot = child && k8sCfg.s3Snapshot !== undefined ? spaceOff(k8sCfg.s3Snapshot) : k8sCfg.s3Snapshot;
|
|
115
|
-
const spaceOccupant = child ? undefined : await occupantOf(seats, ctx.sessionId, ctx.taskId);
|
|
118
|
+
const spaceOccupant = child ? undefined : await occupantOf(seats, ctx.sessionId, ctx.taskId, rpcTimeoutMsOf(k8sCfg));
|
|
116
119
|
const { cache, ...deploymentCfg } = k8sCfg;
|
|
117
120
|
return k8sExecutionEnvFactory({
|
|
118
121
|
...deploymentCfg,
|
|
119
|
-
...(cache !== undefined && !child ? { cache } : {}),
|
|
122
|
+
...(cache !== undefined && !child ? { cache, cacheMisses } : {}),
|
|
120
123
|
...(s3Snapshot !== undefined ? { s3Snapshot } : {}),
|
|
121
124
|
image: seats.imageOf(ctx.sessionId) ?? k8sCfg.image,
|
|
122
125
|
...(spaceOccupant !== undefined ? { spaceOccupant } : {}),
|
|
@@ -125,10 +128,18 @@ export function createK8sRunEnvFactory(k8sCfg, seats, deps) {
|
|
|
125
128
|
};
|
|
126
129
|
}
|
|
127
130
|
const STORE_ERROR_CODE = /^[A-Za-z0-9_.:-]{1,64}$/;
|
|
128
|
-
|
|
131
|
+
const INCARNATION_READ_TIMEOUT = "incarnation_read_timeout";
|
|
132
|
+
async function occupantOf(seats, sessionId, taskId, boundMs) {
|
|
129
133
|
let answer;
|
|
130
134
|
try {
|
|
131
|
-
|
|
135
|
+
const read = seats.incarnationOf;
|
|
136
|
+
answer =
|
|
137
|
+
read === undefined
|
|
138
|
+
? undefined
|
|
139
|
+
: await boundedStoreCall(() => read(sessionId), {
|
|
140
|
+
ms: boundMs,
|
|
141
|
+
onTimeout: () => Object.assign(new Error(`session occupant read did not answer within ${boundMs}ms`), { code: INCARNATION_READ_TIMEOUT }),
|
|
142
|
+
});
|
|
132
143
|
}
|
|
133
144
|
catch (e) {
|
|
134
145
|
const code = e?.code;
|
|
@@ -187,6 +198,7 @@ export function createExecutionEnv(ctx) {
|
|
|
187
198
|
const { config, logger, metrics, taskAttachmentStore } = ctx;
|
|
188
199
|
const laneHomeDir = executionLaneHomeDir(config);
|
|
189
200
|
const homeDirSeat = laneHomeDir !== undefined ? { homeDir: laneHomeDir } : {};
|
|
201
|
+
const homeAbsentNotice = { onHomeAbsent: createLaneHomeAbsenceReporter((event, fields) => logger.warn(event, fields)) };
|
|
190
202
|
const perTaskImage = new PerTaskImageRegistry();
|
|
191
203
|
const sessionEnvSelection = new SessionEnvironmentSelection();
|
|
192
204
|
const sessionScoped = createSessionScopedRegistries();
|
|
@@ -213,7 +225,7 @@ export function createExecutionEnv(ctx) {
|
|
|
213
225
|
else if (config.remoteExec?.provider === "k8s") {
|
|
214
226
|
const k8sCfg = {
|
|
215
227
|
image: config.remoteExec.image,
|
|
216
|
-
...homeDirSeat,
|
|
228
|
+
...homeDirSeat, ...homeAbsentNotice,
|
|
217
229
|
...(config.remoteExec.apiUrl ? { apiUrl: config.remoteExec.apiUrl } : {}),
|
|
218
230
|
...(config.remoteExec.token ? { token: config.remoteExec.token } : {}),
|
|
219
231
|
...(config.remoteExec.caCert ? { caCert: config.remoteExec.caCert } : {}),
|
|
@@ -244,7 +256,7 @@ export function createExecutionEnv(ctx) {
|
|
|
244
256
|
executionEnvFactory = sshExecutionEnvFactory({
|
|
245
257
|
host: config.remoteExec.host,
|
|
246
258
|
username: config.remoteExec.username,
|
|
247
|
-
...homeDirSeat,
|
|
259
|
+
...homeDirSeat, ...homeAbsentNotice,
|
|
248
260
|
privateKey: config.remoteExec.privateKey,
|
|
249
261
|
...(config.remoteExec.port != null ? { port: config.remoteExec.port } : {}),
|
|
250
262
|
...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
|
|
@@ -268,7 +280,7 @@ export function createExecutionEnv(ctx) {
|
|
|
268
280
|
else if (config.remoteExec?.provider === "adb") {
|
|
269
281
|
executionEnvFactory = adbExecutionEnvFactory({
|
|
270
282
|
serial: config.remoteExec.serial,
|
|
271
|
-
...homeDirSeat,
|
|
283
|
+
...homeDirSeat, ...homeAbsentNotice,
|
|
272
284
|
...(config.remoteExec.adbPath ? { adbPath: config.remoteExec.adbPath } : {}),
|
|
273
285
|
...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
|
|
274
286
|
});
|
|
@@ -317,7 +329,7 @@ export function createExecutionEnv(ctx) {
|
|
|
317
329
|
executionEnvFactory = localDockerExecutionEnvFactory({
|
|
318
330
|
image: config.remoteExec.image,
|
|
319
331
|
...(config.remoteExec.mountPath ? { mountPath: config.remoteExec.mountPath } : {}),
|
|
320
|
-
...homeDirSeat,
|
|
332
|
+
...homeDirSeat, ...homeAbsentNotice,
|
|
321
333
|
...(config.remoteExec.dockerPath ? { dockerPath: config.remoteExec.dockerPath } : {}),
|
|
322
334
|
...(config.remoteExec.dockerHost ? { dockerHost: config.remoteExec.dockerHost } : {}),
|
|
323
335
|
...(config.remoteExec.memory ? { memory: config.remoteExec.memory } : {}),
|
|
@@ -404,6 +416,9 @@ export function createExecutionEnv(ctx) {
|
|
|
404
416
|
logger.info("remote_exec_enabled", { provider: config.remoteExec.provider, isolated, suspendable, ...(sandboxEnvKeys.length > 0 ? { sandboxEnvKeys } : {}) });
|
|
405
417
|
if (!isolated)
|
|
406
418
|
logger.warn("remote_exec_real_system", { provider: config.remoteExec.provider, note: buildRealSystemNote(config.remoteExec) });
|
|
419
|
+
const homeNote = buildUndeclaredHomeNote(config);
|
|
420
|
+
if (homeNote !== undefined)
|
|
421
|
+
logger.warn(LANE_HOME_UNDECLARED_EVENT, { provider: config.remoteExec.provider, note: homeNote });
|
|
407
422
|
if (executionLaneOf(config.remoteExec.provider) === "host")
|
|
408
423
|
logger.info("task_inherit_env_honored", { honored: taskInheritEnvRefusal(config) === undefined });
|
|
409
424
|
}
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { loadRemoteExec } from "@sema-agent/settings-schema/node";
|
|
2
|
+
import { assertLocalConfigDirTrusted } from "../config-dir-trust.js";
|
|
2
3
|
import { crossInvariant } from "../config-invariants.js";
|
|
3
4
|
import { executionLaneOf, laneIsolated } from "../execution-lane-caps.js";
|
|
5
|
+
import { buildReadFacePostureNotice, settleDerivedReadFace } from "../read-face-posture.js";
|
|
4
6
|
import { settleHostShellAtBoot } from "../plugins/host-platform.js";
|
|
5
7
|
export const FILE_SOURCED_LANES = ["host", "local-docker"];
|
|
6
8
|
export async function composeExecutionLane(config, ctx) {
|
|
7
9
|
if (ctx.configSource === "local")
|
|
8
10
|
await applyRemoteExecFile(config, ctx);
|
|
11
|
+
settleReadFaceForFinalLane(config, ctx.logger);
|
|
9
12
|
assertExecutionLaneInvariants(config);
|
|
10
13
|
}
|
|
14
|
+
function settleReadFaceForFinalLane(config, logger) {
|
|
15
|
+
if (!settleDerivedReadFace(config, config.requirePrincipal !== true))
|
|
16
|
+
return;
|
|
17
|
+
const notice = buildReadFacePostureNotice(config);
|
|
18
|
+
if (notice !== undefined)
|
|
19
|
+
logger.info(notice.event, notice.fields);
|
|
20
|
+
}
|
|
11
21
|
export async function settleHostLaneShell(config, logger) {
|
|
12
22
|
if (config.remoteExec?.provider !== "host")
|
|
13
23
|
return;
|
|
@@ -34,6 +44,7 @@ export function assertExecutionLaneInvariants(config) {
|
|
|
34
44
|
}
|
|
35
45
|
async function applyRemoteExecFile(config, ctx) {
|
|
36
46
|
const { localRoot, logger } = ctx;
|
|
47
|
+
await assertLocalConfigDirTrusted({ root: localRoot, declaredOwnerUid: config.configLocalOwnerUid });
|
|
37
48
|
let fileRx;
|
|
38
49
|
try {
|
|
39
50
|
fileRx = await loadRemoteExec(localRoot);
|
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";
|
|
@@ -86,6 +87,7 @@ export function createLeaderFace(ctx) {
|
|
|
86
87
|
logger,
|
|
87
88
|
requiredFields: ["objective", "durableRemote", "testCmd", "seedCmd", "baseSha"],
|
|
88
89
|
...(leaderRunStore ? { store: leaderRunStore } : {}),
|
|
90
|
+
ownerVisible: createLeaderRunVisibility(config),
|
|
89
91
|
})
|
|
90
92
|
: undefined;
|
|
91
93
|
if (leaderEndpoint)
|
|
@@ -75,8 +75,8 @@ import type { MemoryEngineBackend } from "@sema-agent/settings-schema/execution-
|
|
|
75
75
|
* 而且它断言的是 per-task 事实,不是本键的车道级语义。
|
|
76
76
|
*
|
|
77
77
|
* ## 位置与纪律
|
|
78
|
-
* 单源:resolve-spec 的 spec
|
|
79
|
-
*
|
|
78
|
+
* 单源:resolve-spec 的 spec 直通(引擎据它判「本会话没有持久记忆」的披露与四只记忆面臂)、boot 审计的 declared 位
|
|
79
|
+
* 两处都必须读本函数,禁各自重算(operator-knob 律:显式 env 的优先权在这一个函数里执法一次)。
|
|
80
80
|
* 自动补位在 boot 日志上必须可见(stores.ts 的 info 行),部署方随时可用显式 env 覆盖。
|
|
81
81
|
*/
|
|
82
82
|
export declare function effectiveMemoryPersistenceCapable(config: {
|
|
@@ -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
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Logger } from "../observability/logger.js";
|
|
2
|
+
/** 一行 warn 里最多点名的行数(超出只报总数与省略数):一份中心发布可以带很多行,启动日志的一行不随之变长。 */
|
|
3
|
+
export declare const READ_DENY_AUDIT_MAX_NAMED_ROWS = 20;
|
|
4
|
+
export interface ReadDenyAnchorAuditCtx {
|
|
5
|
+
/** 部署读拒行(`config.readDenyPatterns`);缺席 / 空 ⇒ 无话可说。 */
|
|
6
|
+
readonly rows: readonly {
|
|
7
|
+
readonly pattern: string;
|
|
8
|
+
readonly caseSensitive: boolean;
|
|
9
|
+
}[] | undefined;
|
|
10
|
+
readonly logger: Pick<Logger, "warn">;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 只由 `announceReadDenyRows` 调(一份值一次)。返回非锚定行的规范形(按配置顺序;无 ⇒ 空),并在有时打**恰一行** warn `read_deny_unanchored_rows`
|
|
14
|
+
* (`rows` 点名前 {@link READ_DENY_AUDIT_MAX_NAMED_ROWS} 行、`count` 总数、超出时 `omitted`;`note` 引 MIGRATION 第 45 条的改法)。绝不抛。
|
|
15
|
+
*/
|
|
16
|
+
export declare function auditReadDenyAnchoring(ctx: ReadDenyAnchorAuditCtx): readonly string[];
|
|
17
|
+
//# sourceMappingURL=read-deny-anchor-audit.d.ts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { compileReadDeny, readDenyPatternRun } from "@sema-agent/core";
|
|
2
|
+
import { echoCallerText } from "../caller-text-echo.js";
|
|
3
|
+
export const READ_DENY_AUDIT_MAX_NAMED_ROWS = 20;
|
|
4
|
+
const NAMED_ROW_ECHO_CHARS = 200;
|
|
5
|
+
function isAnchoredCanonicalRow(canonical) {
|
|
6
|
+
return readDenyPatternRun(canonical).homeAnchored || canonical.startsWith("/");
|
|
7
|
+
}
|
|
8
|
+
export function auditReadDenyAnchoring(ctx) {
|
|
9
|
+
if (ctx.rows === undefined || ctx.rows.length === 0)
|
|
10
|
+
return [];
|
|
11
|
+
let canonical;
|
|
12
|
+
try {
|
|
13
|
+
canonical = compileReadDeny(ctx.rows, "boot read-deny anchor audit", { tiers: [] }).entries.map((e) => e.pattern);
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
ctx.logger.warn("read_deny_anchor_audit_failed", {
|
|
17
|
+
error: echoCallerText(err instanceof Error ? err.message : String(err), { maxChars: 400 }),
|
|
18
|
+
note: "the boot audit could not read the deployment read-deny rows, so it names none and changes nothing; the engine itself refuses a row it cannot read when the Runner is built",
|
|
19
|
+
});
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
const unanchored = canonical.filter((p) => !isAnchoredCanonicalRow(p));
|
|
23
|
+
if (unanchored.length === 0)
|
|
24
|
+
return [];
|
|
25
|
+
const named = unanchored.slice(0, READ_DENY_AUDIT_MAX_NAMED_ROWS).map((p) => echoCallerText(p, { maxChars: NAMED_ROW_ECHO_CHARS }));
|
|
26
|
+
ctx.logger.warn("read_deny_unanchored_rows", {
|
|
27
|
+
rows: named,
|
|
28
|
+
count: unanchored.length,
|
|
29
|
+
...(unanchored.length > named.length ? { omitted: unanchored.length - named.length } : {}),
|
|
30
|
+
note: "recursive shell reads (grep -r and the like) are judged by the root the command names: a read-deny row spelled without a root or home anchor does not protect files below that root " +
|
|
31
|
+
"(reading from a parent directory returns their content; naming the directory or file itself is still refused). Anchor the row to protect it — `<workspace root>/…` or `~/…` — see MIGRATION 7.132.0 item 45. " +
|
|
32
|
+
"This notice changes nothing: enforcement is unchanged and the start is not refused",
|
|
33
|
+
});
|
|
34
|
+
return unanchored;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=read-deny-anchor-audit.js.map
|
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) => {
|