@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/project-identity.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { readFileSync, realpathSync, statSync } from "node:fs";
|
|
3
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
4
|
+
import { encodeScopeSegment } from "@sema-agent/core";
|
|
5
|
+
import { mintProjectLayerKey, PROJECT_LAYER_KEY_PREFIX, projectLayerOwnerOf } from "./project-layer-key.js";
|
|
4
6
|
const UNREADABLE = { absent: "unreadable" };
|
|
5
7
|
const BARE = { absent: "bare" };
|
|
6
8
|
function isMissing(err) {
|
|
@@ -53,7 +55,7 @@ function identityOfGitFile(dir) {
|
|
|
53
55
|
const gitDir = gitDirFact.ok;
|
|
54
56
|
const commonText = readTextFact(join(gitDir, "commondir"));
|
|
55
57
|
if (commonText === "missing")
|
|
56
|
-
return { root: dir };
|
|
58
|
+
return { root: dir, gitConfig: join(gitDir, "config") };
|
|
57
59
|
if (commonText === "unreadable")
|
|
58
60
|
return UNREADABLE;
|
|
59
61
|
const commonFact = realpathFact(resolve(gitDir, commonText.ok));
|
|
@@ -68,7 +70,7 @@ function identityOfGitFile(dir) {
|
|
|
68
70
|
const backFact = realpathFact(resolve(gitDir, back.ok));
|
|
69
71
|
if (typeof backFact !== "object" || backFact.ok !== join(dir, ".git"))
|
|
70
72
|
return UNREADABLE;
|
|
71
|
-
return { root: basename(common) !== ".git" ? common : dirname(common) };
|
|
73
|
+
return { root: basename(common) !== ".git" ? common : dirname(common), gitConfig: join(common, "config") };
|
|
72
74
|
}
|
|
73
75
|
function canonicalTaskRoot(taskRoot) {
|
|
74
76
|
const rest = [];
|
|
@@ -86,6 +88,10 @@ function canonicalTaskRoot(taskRoot) {
|
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
export function resolveProjectIdentity(taskRoot) {
|
|
91
|
+
const located = locateProject(taskRoot);
|
|
92
|
+
return "root" in located ? { root: located.root } : located;
|
|
93
|
+
}
|
|
94
|
+
function locateProject(taskRoot) {
|
|
89
95
|
const root = canonicalTaskRoot(taskRoot);
|
|
90
96
|
if (root === "unreadable")
|
|
91
97
|
return UNREADABLE;
|
|
@@ -96,7 +102,7 @@ export function resolveProjectIdentity(taskRoot) {
|
|
|
96
102
|
return UNREADABLE;
|
|
97
103
|
if (typeof dotGit === "object") {
|
|
98
104
|
if (dotGit.ok === "dir")
|
|
99
|
-
return { root: dir };
|
|
105
|
+
return { root: dir, gitConfig: join(dir, ".git", "config") };
|
|
100
106
|
if (dotGit.ok === "file")
|
|
101
107
|
return identityOfGitFile(dir);
|
|
102
108
|
}
|
|
@@ -108,13 +114,161 @@ export function resolveProjectIdentity(taskRoot) {
|
|
|
108
114
|
dir = parent;
|
|
109
115
|
}
|
|
110
116
|
}
|
|
117
|
+
function digest24(text) {
|
|
118
|
+
return createHash("sha256").update(text, "utf8").digest("hex").slice(0, 24);
|
|
119
|
+
}
|
|
120
|
+
const RETIRED_PROJECT_KEY_PREFIX = "repo:";
|
|
111
121
|
export function mintRepoScopeKey(projectRoot) {
|
|
112
|
-
return
|
|
122
|
+
return `${RETIRED_PROJECT_KEY_PREFIX}${digest24(projectRoot)}`;
|
|
123
|
+
}
|
|
124
|
+
export function isServerMintedProjectKey(key) {
|
|
125
|
+
return key.startsWith(PROJECT_LAYER_KEY_PREFIX) || key.startsWith(RETIRED_PROJECT_KEY_PREFIX);
|
|
126
|
+
}
|
|
127
|
+
export function assertProjectLayerOwnable(scope, envName) {
|
|
128
|
+
if (isServerMintedProjectKey(scope)) {
|
|
129
|
+
throw new Error(`${envName}=${JSON.stringify(scope)} names a server-minted project-layer key (the "${PROJECT_LAYER_KEY_PREFIX}" family, or the retired "${RETIRED_PROJECT_KEY_PREFIX}" family) — ` +
|
|
130
|
+
"project layers are derived per task from the project identity and cannot be named as a deployment scope. Use a user key (user:<principal>) or a plain name.");
|
|
131
|
+
}
|
|
132
|
+
const owner = ownerSegmentFact(scope);
|
|
133
|
+
if (!owner.ok) {
|
|
134
|
+
throw new Error(`${envName}=${JSON.stringify(scope)} cannot own per-project memory layers: ${owner.why} — ` +
|
|
135
|
+
"the layer owner (the principal of a user: key, otherwise the name itself) must encode to at most 64 scope-segment characters.");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function ownerSegmentFact(scope) {
|
|
139
|
+
try {
|
|
140
|
+
encodeScopeSegment(projectLayerOwnerOf(scope));
|
|
141
|
+
return { ok: true };
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
return { ok: false, why: err instanceof Error ? err.message : String(err) };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const GIT_CONFIG_MAX_BYTES = 256 * 1024;
|
|
148
|
+
function readOriginRemoteUrl(configPath) {
|
|
149
|
+
const st = statFact(configPath);
|
|
150
|
+
if (st === "missing")
|
|
151
|
+
return "missing";
|
|
152
|
+
if (st === "unreadable" || st.ok !== "file")
|
|
153
|
+
return "unreadable";
|
|
154
|
+
let size;
|
|
155
|
+
try {
|
|
156
|
+
size = statSync(configPath).size;
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
return isMissing(err) ? "missing" : "unreadable";
|
|
160
|
+
}
|
|
161
|
+
if (size > GIT_CONFIG_MAX_BYTES)
|
|
162
|
+
return "unreadable";
|
|
163
|
+
const text = readTextFact(configPath);
|
|
164
|
+
if (typeof text !== "object")
|
|
165
|
+
return text;
|
|
166
|
+
let inOrigin = false;
|
|
167
|
+
for (const raw of gitConfigLogicalLines(text.ok)) {
|
|
168
|
+
const line = raw.trim();
|
|
169
|
+
if (line.startsWith("[")) {
|
|
170
|
+
const header = /^\[\s*([A-Za-z0-9.-]+)(?:\s+"((?:[^"\\]|\\.)*)")?\s*\]/.exec(line);
|
|
171
|
+
inOrigin = header !== null && header[1].toLowerCase() === "remote" && header[2] !== undefined && header[2].replace(/\\(.)/g, "$1") === "origin";
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (!inOrigin)
|
|
175
|
+
continue;
|
|
176
|
+
const kv = /^([A-Za-z][A-Za-z0-9-]*)\s*=\s*(.*)$/.exec(line);
|
|
177
|
+
if (kv === null || kv[1].toLowerCase() !== "url")
|
|
178
|
+
continue;
|
|
179
|
+
const value = gitConfigValue(kv[2]);
|
|
180
|
+
if (value !== "")
|
|
181
|
+
return { ok: value };
|
|
182
|
+
}
|
|
183
|
+
return { ok: undefined };
|
|
184
|
+
}
|
|
185
|
+
function gitConfigLogicalLines(text) {
|
|
186
|
+
const out = [];
|
|
187
|
+
let pending = "";
|
|
188
|
+
for (const physical of text.split(/\r?\n/)) {
|
|
189
|
+
const trailing = /\\*$/.exec(physical)[0].length;
|
|
190
|
+
if (trailing % 2 === 1) {
|
|
191
|
+
pending += physical.slice(0, -1);
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
out.push(pending + physical);
|
|
195
|
+
pending = "";
|
|
196
|
+
}
|
|
197
|
+
if (pending !== "")
|
|
198
|
+
out.push(pending);
|
|
199
|
+
return out;
|
|
200
|
+
}
|
|
201
|
+
function gitConfigValue(raw) {
|
|
202
|
+
let out = "";
|
|
203
|
+
let quoted = false;
|
|
204
|
+
for (let i = 0; i < raw.length; i++) {
|
|
205
|
+
const c = raw[i];
|
|
206
|
+
if (c === "\\" && i + 1 < raw.length) {
|
|
207
|
+
out += raw[++i];
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (c === '"') {
|
|
211
|
+
quoted = !quoted;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (!quoted && (c === "#" || c === ";"))
|
|
215
|
+
break;
|
|
216
|
+
out += c;
|
|
217
|
+
}
|
|
218
|
+
return out.trim();
|
|
219
|
+
}
|
|
220
|
+
const DEFAULT_REMOTE_PORTS = { ssh: "22", "git+ssh": "22", "ssh+git": "22", https: "443", http: "80", git: "9418" };
|
|
221
|
+
export function normalizeGitRemoteUrl(url) {
|
|
222
|
+
const u = url.trim();
|
|
223
|
+
const scheme = /^([A-Za-z][A-Za-z0-9+.-]*):\/\/(.*)$/.exec(u);
|
|
224
|
+
if (scheme !== null) {
|
|
225
|
+
const name = scheme[1].toLowerCase();
|
|
226
|
+
if (name === "file")
|
|
227
|
+
return undefined;
|
|
228
|
+
const rest = scheme[2];
|
|
229
|
+
const slash = rest.indexOf("/");
|
|
230
|
+
const authority = slash < 0 ? rest : rest.slice(0, slash);
|
|
231
|
+
const hostPort = authority.slice(authority.lastIndexOf("@") + 1);
|
|
232
|
+
const port = /:(\d*)$/.exec(hostPort);
|
|
233
|
+
const host = (port === null ? hostPort : hostPort.slice(0, port.index)).toLowerCase();
|
|
234
|
+
if (host === "")
|
|
235
|
+
return undefined;
|
|
236
|
+
const keptPort = port !== null && port[1] !== "" && port[1] !== DEFAULT_REMOTE_PORTS[name] ? `:${port[1]}` : "";
|
|
237
|
+
return `${host}${keptPort}/${cleanRemotePath(slash < 0 ? "" : rest.slice(slash))}`;
|
|
238
|
+
}
|
|
239
|
+
const scp = /^(?:[^@/]+@)?([^:/]{2,}):(.*)$/.exec(u);
|
|
240
|
+
if (scp !== null)
|
|
241
|
+
return `${scp[1].toLowerCase()}/${cleanRemotePath(scp[2])}`;
|
|
242
|
+
return undefined;
|
|
113
243
|
}
|
|
114
|
-
|
|
244
|
+
function cleanRemotePath(p) {
|
|
245
|
+
return p.replace(/\/+/g, "/").replace(/^\/+|\/+$/g, "").replace(/\.git$/, "");
|
|
246
|
+
}
|
|
247
|
+
export function projectLayerIdentityOf(taskRoot) {
|
|
248
|
+
const located = locateProject(taskRoot);
|
|
249
|
+
if (!("root" in located))
|
|
250
|
+
return located;
|
|
251
|
+
const path = { tier: "p", digest: digest24(located.root) };
|
|
252
|
+
const origin = located.gitConfig !== undefined ? readOriginRemoteUrl(located.gitConfig) : "missing";
|
|
253
|
+
if (origin === "unreadable")
|
|
254
|
+
return UNREADABLE;
|
|
255
|
+
const remote = origin === "missing" || origin.ok === undefined ? undefined : normalizeGitRemoteUrl(origin.ok);
|
|
256
|
+
if (remote === undefined)
|
|
257
|
+
return { root: located.root, identity: path, lowerTiers: [] };
|
|
258
|
+
return { root: located.root, identity: { tier: "r", digest: digest24(remote) }, lowerTiers: [path] };
|
|
259
|
+
}
|
|
260
|
+
export function projectLayerForTaskRoot(taskRoot, owner) {
|
|
115
261
|
if (taskRoot === undefined)
|
|
116
|
-
return {
|
|
117
|
-
const id =
|
|
118
|
-
|
|
262
|
+
return { key: UNREADABLE, foldFrom: [] };
|
|
263
|
+
const id = projectLayerIdentityOf(taskRoot);
|
|
264
|
+
if (!("identity" in id))
|
|
265
|
+
return { key: { absent: id.absent }, foldFrom: [] };
|
|
266
|
+
return {
|
|
267
|
+
key: { scope: mintProjectLayerKey(owner, id.identity) },
|
|
268
|
+
foldFrom: [mintRepoScopeKey(id.root), ...id.lowerTiers.map((tier) => mintProjectLayerKey(owner, tier))],
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
export function projectKeyForTaskRoot(taskRoot, owner) {
|
|
272
|
+
return projectLayerForTaskRoot(taskRoot, owner).key;
|
|
119
273
|
}
|
|
120
274
|
//# sourceMappingURL=project-identity.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** 项目层键的前缀(改名链的前缀词表也读它)。 */
|
|
2
|
+
export declare const PROJECT_LAYER_KEY_PREFIX = "userrepo:";
|
|
3
|
+
/** 身份档:`r` = 仓库身份(origin 远端,跨设备),`p` = 项目根路径(本机)。 */
|
|
4
|
+
export type ProjectIdentityTier = "r" | "p";
|
|
5
|
+
/** 一个项目的身份段(档 + 24 位小写十六进制摘要)。 */
|
|
6
|
+
export interface ProjectLayerIdentity {
|
|
7
|
+
readonly tier: ProjectIdentityTier;
|
|
8
|
+
readonly digest: string;
|
|
9
|
+
}
|
|
10
|
+
/** 解出的项目层键。 */
|
|
11
|
+
export interface ParsedProjectLayerKey {
|
|
12
|
+
/** 解码后的属主(主体名,或不透明全局层名本身)。 */
|
|
13
|
+
readonly owner: string;
|
|
14
|
+
readonly identity: ProjectLayerIdentity;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 全局层 → 它的属主(见文件头文法)。`user:` 形用 core 的解析(段解码、规范形校验);坏的 `user:` 形照 core 原样抛
|
|
18
|
+
* (`config.memory_scope_key`)—— 起服经 `project-identity.ts` `assertProjectLayerOwnable` 在第一刻接住,不留到任务期。
|
|
19
|
+
*/
|
|
20
|
+
export declare function projectLayerOwnerOf(globalScope: string): string;
|
|
21
|
+
/** 铸项目层键。属主编码超长 / 空 ⇒ core 段编码原样抛(起服已由 `assertProjectLayerOwnable` 拦住)。 */
|
|
22
|
+
export declare function mintProjectLayerKey(owner: string, identity: ProjectLayerIdentity): string;
|
|
23
|
+
/**
|
|
24
|
+
* 解项目层键。**严格**:前缀 + 恰好一个 `/` + 规范形属主段(`%41` 这类第二种拼法不认 —— 一个属主不许有两把键)+ 档文法。
|
|
25
|
+
* 不合任何一条 ⇒ `undefined`(调用方读作「不是项目层」;属主门据此答与其余拒绝同体的 404)。
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseProjectLayerKey(key: string): ParsedProjectLayerKey | undefined;
|
|
28
|
+
//# sourceMappingURL=project-layer-key.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { decodeScopeSegment, encodeScopeSegment, parseScopeKey } from "@sema-agent/core";
|
|
2
|
+
export const PROJECT_LAYER_KEY_PREFIX = "userrepo:";
|
|
3
|
+
const DIGEST = /^[0-9a-f]{24}$/;
|
|
4
|
+
const KEY = /^userrepo:((?:[A-Za-z0-9._-]|%[0-9A-F]{2})+)\/([rp])\.([0-9a-f]{24})$/;
|
|
5
|
+
export function projectLayerOwnerOf(globalScope) {
|
|
6
|
+
const parsed = parseScopeKey(globalScope);
|
|
7
|
+
return parsed.kind === "user" ? parsed.principal : globalScope;
|
|
8
|
+
}
|
|
9
|
+
export function mintProjectLayerKey(owner, identity) {
|
|
10
|
+
if (!DIGEST.test(identity.digest))
|
|
11
|
+
throw new Error(`project layer identity digest must be 24 lowercase hex characters, got ${JSON.stringify(identity.digest)}`);
|
|
12
|
+
return `${PROJECT_LAYER_KEY_PREFIX}${encodeScopeSegment(owner)}/${identity.tier}.${identity.digest}`;
|
|
13
|
+
}
|
|
14
|
+
export function parseProjectLayerKey(key) {
|
|
15
|
+
const m = KEY.exec(key);
|
|
16
|
+
if (m === null)
|
|
17
|
+
return undefined;
|
|
18
|
+
const owner = decodeOwnerSegment(m[1]);
|
|
19
|
+
return owner.ok ? { owner: owner.owner, identity: { tier: m[2], digest: m[3] } } : undefined;
|
|
20
|
+
}
|
|
21
|
+
function decodeOwnerSegment(segment) {
|
|
22
|
+
try {
|
|
23
|
+
return { ok: true, owner: decodeScopeSegment(segment) };
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
return { ok: false, why: err instanceof Error ? err.message : String(err) };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=project-layer-key.js.map
|
package/dist/question.js
CHANGED
|
@@ -2,6 +2,7 @@ import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
2
2
|
import { uuidv7 } from "@sema-agent/core";
|
|
3
3
|
import { redactDeep } from "./trace/redact.js";
|
|
4
4
|
import { recordFailOpen } from "./observability/fail-open.js";
|
|
5
|
+
import { refusalBody } from "./http/refusal-body.js";
|
|
5
6
|
const MAX_QUESTIONS_BYTES = 16384;
|
|
6
7
|
function isFaceReachable(ctx) {
|
|
7
8
|
if (ctx.deliverable === undefined)
|
|
@@ -150,10 +151,10 @@ export class QuestionCoordinator {
|
|
|
150
151
|
respond(id, principal, body) {
|
|
151
152
|
const parsed = parseQuestionResponse(body);
|
|
152
153
|
if (!parsed.ok)
|
|
153
|
-
return { status: 400, body: {
|
|
154
|
+
return { status: 400, body: refusalBody({ errorCode: "request.body_shape", message: parsed.error }) };
|
|
154
155
|
const entry = this.pending.get(id);
|
|
155
156
|
if (!entry || (entry.owner !== null && entry.owner !== principal)) {
|
|
156
|
-
return { status: 404, body: {
|
|
157
|
+
return { status: 404, body: refusalBody({ errorCode: "question.not_pending", message: "no pending question for this id (answered, expired, or not on this replica)" }) };
|
|
157
158
|
}
|
|
158
159
|
entry.settle(parsed.value, "answered");
|
|
159
160
|
return { status: 200, body: { questionId: id, delivery: "applied" } };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **读拒模式条目的归一**(全仓唯一一只读法)—— `READ_DENY_PATTERNS` 的 env 腿(`config.ts`)、中心下发 `readFace.denyPatterns` 的腿(`web-admin-client/read-face.ts`)、
|
|
3
|
+
* 请求 `settings.readDenyPatterns` 的腿(`tighten-only-seats.ts`)三处读同一份元素文法:`"pattern"` 裸串简写 ≡ `{ pattern, caseSensitive: false }`,
|
|
4
|
+
* 对象形 `{ pattern: string, caseSensitive?: boolean }`(与 core `ReadDenyEntry = string | {…}` 同宽)。三份手抄的元素读法就是三个会各自漂的真源,所以收成这一只。
|
|
5
|
+
*
|
|
6
|
+
* 只管**元素形**(串 / 带串 `pattern` 的对象 / 布尔 `caseSensitive`);模式编不编得过由调用方交给 core 的 `compileReadDeny`(引擎同一套规则,宿主不自造第二份校验语义)。
|
|
7
|
+
* 返回的是**接在坐标后面的原因尾巴**(` must be a string or an object with a string 'pattern'` / `.caseSensitive must be boolean when present`),不带坐标 —— 调用方自己前缀坐标
|
|
8
|
+
* (`READ_DENY_PATTERNS[2]` / `readFace.denyPatterns[2]` / `settings.readDenyPatterns[2]`),各腿既有的拒句字节不变。叶模块,零 import。
|
|
9
|
+
*/
|
|
10
|
+
/** 归一后的一行(core `compileReadDeny` 收的对象形)。 */
|
|
11
|
+
export interface NormalizedReadDenyEntry {
|
|
12
|
+
readonly pattern: string;
|
|
13
|
+
readonly caseSensitive: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** 一个元素的读数:归一后的行,或接在调用方坐标后面成句的原因尾巴(`after` 自带连接符:空格或点)。 */
|
|
16
|
+
export type ReadDenyEntryReading = {
|
|
17
|
+
readonly ok: true;
|
|
18
|
+
readonly entry: NormalizedReadDenyEntry;
|
|
19
|
+
} | {
|
|
20
|
+
readonly ok: false;
|
|
21
|
+
readonly after: string;
|
|
22
|
+
};
|
|
23
|
+
/** 读一个元素。裸串 ⇒ 大小写默认不敏感(与对象形缺席 `caseSensitive` 一致);坏形 ⇒ 原因子句,不抛、不丢。 */
|
|
24
|
+
export declare function readReadDenyEntry(it: unknown): ReadDenyEntryReading;
|
|
25
|
+
//# sourceMappingURL=read-deny-entry.d.ts.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function readReadDenyEntry(it) {
|
|
2
|
+
if (typeof it === "string")
|
|
3
|
+
return { ok: true, entry: { pattern: it, caseSensitive: false } };
|
|
4
|
+
if (typeof it !== "object" || it === null || typeof it.pattern !== "string") {
|
|
5
|
+
return { ok: false, after: " must be a string or an object with a string 'pattern'" };
|
|
6
|
+
}
|
|
7
|
+
const cs = it.caseSensitive;
|
|
8
|
+
if (cs !== undefined && typeof cs !== "boolean")
|
|
9
|
+
return { ok: false, after: ".caseSensitive must be boolean when present" };
|
|
10
|
+
return { ok: true, entry: { pattern: it.pattern, caseSensitive: cs === true } };
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=read-deny-entry.js.map
|
|
@@ -17,9 +17,14 @@
|
|
|
17
17
|
* ② 运维面:`GET /v1/diagnostics/wiring` 报 `{face, source, note}`,「为什么这台机器是 open」有答案
|
|
18
18
|
* (裁定的补偿项:升级即放开,得让运维看得见并知道怎么钉回)。
|
|
19
19
|
*
|
|
20
|
-
* ## 优先序(
|
|
21
|
-
* `env 显式` > `center 发布` > `posture 派生` > `引擎默认`。env 恒赢的论证逐字见 `web-admin-client/read-face.ts`
|
|
20
|
+
* ## 优先序(与 `config.ts` 的 `postureOn` 同形)
|
|
21
|
+
* `env 显式` > `center 发布` > `lane 声明` > `posture 派生` > `引擎默认`。env 恒赢的论证逐字见 `web-admin-client/read-face.ts`
|
|
22
22
|
* 头注①(READ 容纳面描述的是**这台机器的磁盘上有什么**,组织的下发面不知道)。
|
|
23
|
+
* 🔴 **`lane` 一臂(S-1492,clay 裁 [ref])**:隔离型执行车道(`e2b` / `k8s` / `local-docker`)的契约行**显式声明**读面缺省 `open`
|
|
24
|
+
* (`execution-lane-caps.ts` 的 `laneReadFaceDefault`;沙箱内部就是模型的整个世界)。运维没写 `READ_FACE` 时,车道声明比整机 posture 更具体 ⇒ 排在它前面;
|
|
25
|
+
* 声明 `roots` 的车道(`host` / `ssh` / `adb` / `device` / 未设车道)不替运维声明缺省,回到既有的 posture 派生,**一个字节不变**。
|
|
26
|
+
* 缺席这一态的派生**只有一只函数**({@link readFaceDefaultFor}),且读的是**最终生效的车道**(`loadConfig` 装配完 `remoteExec` 之后一次;
|
|
27
|
+
* local 形 `config.d/remote-exec.json` 覆写之后由车道合成步再派一次 —— 同一只 {@link settleDerivedReadFace})。
|
|
23
28
|
*
|
|
24
29
|
* ## 定界
|
|
25
30
|
* 本模块**只**管 `face` 一档。内建读拒表(`readDenyPatterns` / `readDenyBuiltinTiers` /
|
|
@@ -31,13 +36,14 @@
|
|
|
31
36
|
* 本模块的定界不变:并列的那一侧开着哪几档,是那张表自己的缺省说了算。core 的 `config.read_face_deployment_clamped`
|
|
32
37
|
* (只读挂载钳制)同样不受本件影响。
|
|
33
38
|
*/
|
|
39
|
+
import { type LaneReadFaceDefault, type RemoteExecProvider } from "./execution-lane-caps.js";
|
|
34
40
|
import { type PostureSource } from "./posture-source.js";
|
|
35
41
|
/**
|
|
36
42
|
* 档位来源的闭集词表 —— **S-178 起转 `posture-source.ts` 的共享件**(本模块只是给这一档取个本地名字,
|
|
37
43
|
* 不再持第二份词表:同一张四词表抄两遍的那天,两份会在加词时分家)。
|
|
38
44
|
*/
|
|
39
|
-
export declare const READ_FACE_SOURCE_WORDS: readonly ["env", "center", "posture", "engine-default"];
|
|
40
|
-
/** 档位的来源(
|
|
45
|
+
export declare const READ_FACE_SOURCE_WORDS: readonly ["env", "center", "lane", "posture", "engine-default"];
|
|
46
|
+
/** 档位的来源(闭集五词)。加词 ⇒ {@link postureSourceNote} 的穷举 switch 编译红。 */
|
|
41
47
|
export type ReadFaceSource = PostureSource;
|
|
42
48
|
/** 一台 worker 的 READ 面档位事实(值 + 来源)。`ServiceConfigFlat` 结构上满足本形。 */
|
|
43
49
|
export interface ReadFacePostureFacts {
|
|
@@ -45,10 +51,29 @@ export interface ReadFacePostureFacts {
|
|
|
45
51
|
readonly readFaceSource: ReadFaceSource;
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
48
|
-
* 缺席 `READ_FACE`
|
|
49
|
-
*
|
|
54
|
+
* 缺席 `READ_FACE` 时读面缺省的**唯一派生函数**(显式 env 值不经此口):
|
|
55
|
+
* · 车道声明 `open`(隔离型车道)⇒ `open`,来源 `lane`(不论单用户还是多租户 —— 更具体的出处胜 posture);
|
|
56
|
+
* · 车道声明 `roots` ⇒ 既有 posture 派生,逐字不变。
|
|
50
57
|
*/
|
|
51
|
-
export declare function
|
|
58
|
+
export declare function readFaceDefaultFor(input: {
|
|
59
|
+
readonly laneDefault: LaneReadFaceDefault;
|
|
60
|
+
readonly singleUserTurnkey: boolean;
|
|
61
|
+
}): ReadFacePostureFacts;
|
|
62
|
+
/** {@link settleDerivedReadFace} 动的那几格(`ServiceConfig` 结构上满足本形)。 */
|
|
63
|
+
export interface ReadFaceDeploymentSeat {
|
|
64
|
+
readFace?: "open" | "roots" | undefined;
|
|
65
|
+
readFaceSource: ReadFaceSource;
|
|
66
|
+
remoteExec?: {
|
|
67
|
+
readonly provider: RemoteExecProvider;
|
|
68
|
+
} | undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 把**派生的**读面缺省按这台部署**最终生效的车道**落到配置上(显式 env / center 发布的值与来源原样不动)。返回值 = 这一次有没有改动。
|
|
72
|
+
* 两个调用点,同一只函数:`loadConfig` 装配完 `remoteExec` 之后(env 三元链定的车道);车道合成步在 local 形文件覆写之后
|
|
73
|
+
* (`config.d/remote-exec.json` 能把车道换成 `host` / `local-docker`,读面缺省随最终车道重派 —— 否则它停在已作废的车道上)。
|
|
74
|
+
* 幂等:同一份配置再调一次不改。值与来源**同一处写**(`readFace` 缺席 ⟺ 来源 `engine-default`)。
|
|
75
|
+
*/
|
|
76
|
+
export declare function settleDerivedReadFace(seat: ReadFaceDeploymentSeat, singleUserTurnkey: boolean): boolean;
|
|
52
77
|
/** 本档的运维指路句 —— 骨架由共享件 {@link postureSourceNote} 给(四词穷举在那里,加词即编译红);
|
|
53
78
|
* 本函数提供两条**键专属**臂(`center` / `posture`)的事实句。
|
|
54
79
|
*
|
|
@@ -67,13 +92,14 @@ export declare function buildReadFaceWiring(facts: ReadFacePostureFacts): {
|
|
|
67
92
|
note: string;
|
|
68
93
|
};
|
|
69
94
|
/**
|
|
70
|
-
* S-176 —— posture
|
|
95
|
+
* S-176 —— 派生的档位(`posture` 单机 ⇒ open,或 S-1492 的 `lane` 隔离车道 ⇒ open)在 **boot 期推送面**的那一行(`config.ts` 经既有 `CONFIG_NOTICES` 以 info 级排空)。
|
|
71
96
|
*
|
|
72
97
|
* 为什么要有:S-167 的补偿项是「升级即放开,得让运维看得见并知道怎么钉回」,可此前唯一看得见的是**拉取**面
|
|
73
|
-
* (`GET /v1/diagnostics/wiring`)—— 只对会去拉的人成立。单机 boot 日志里零字。
|
|
74
|
-
*
|
|
98
|
+
* (`GET /v1/diagnostics/wiring`)—— 只对会去拉的人成立。单机 boot 日志里零字。S-1492 的 `lane` 臂同一个补偿:多租户沙箱部署升级后读面从 `roots` 变 `open`,
|
|
99
|
+
* 指路句带挂载告诫与钉回出路。
|
|
100
|
+
* 为什么只在 `posture` / `lane` 两词上说:另外三词都不是「没人表态、服务替它选了一个更宽的档」——`env` 是运维自己写的,
|
|
75
101
|
* `engine-default` 是本服务没铸(引擎默认接管),`center` 在 boot 这一拍还没到货(它有自己的换席通告)。
|
|
76
|
-
* 为什么是 info 不是 warn
|
|
102
|
+
* 为什么是 info 不是 warn:每一台照常配置的部署每次启动都成立,是常态事实不是异常(与执行车道落点同级)。
|
|
77
103
|
*
|
|
78
104
|
* 字段与极性表的 posture 行同名(`knob` / `value` / `source`),另带指路句;三格由 {@link buildReadFaceWiring} 投影出 ——
|
|
79
105
|
* 拉取面与推送面**同一只函数**,不各算一次。`value` 是字符串:只有 `face` 在场的那一形才会走到这里。
|
|
@@ -1,13 +1,42 @@
|
|
|
1
|
+
import { LANE_OPEN_READ_FACE_CAUTION, executionLaneOf, laneReadFaceDefault } from "./execution-lane-caps.js";
|
|
1
2
|
import { POSTURE_SOURCE_WORDS, postureSourceNote } from "./posture-source.js";
|
|
2
3
|
export const READ_FACE_SOURCE_WORDS = POSTURE_SOURCE_WORDS;
|
|
3
|
-
|
|
4
|
+
function readFaceForPosture(singleUserTurnkey) {
|
|
4
5
|
return singleUserTurnkey ? { readFace: "open", readFaceSource: "posture" } : { readFaceSource: "engine-default" };
|
|
5
6
|
}
|
|
7
|
+
export function readFaceDefaultFor(input) {
|
|
8
|
+
return input.laneDefault === "open" ? { readFace: "open", readFaceSource: "lane" } : readFaceForPosture(input.singleUserTurnkey);
|
|
9
|
+
}
|
|
10
|
+
function isDerivedSource(source) {
|
|
11
|
+
switch (source) {
|
|
12
|
+
case "env":
|
|
13
|
+
case "center":
|
|
14
|
+
return false;
|
|
15
|
+
case "lane":
|
|
16
|
+
case "posture":
|
|
17
|
+
case "engine-default":
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function settleDerivedReadFace(seat, singleUserTurnkey) {
|
|
22
|
+
if (!isDerivedSource(seat.readFaceSource))
|
|
23
|
+
return false;
|
|
24
|
+
const next = readFaceDefaultFor({ laneDefault: laneReadFaceDefault(executionLaneOf(seat.remoteExec?.provider)), singleUserTurnkey });
|
|
25
|
+
if (next.readFace === seat.readFace && next.readFaceSource === seat.readFaceSource)
|
|
26
|
+
return false;
|
|
27
|
+
if (next.readFace === undefined)
|
|
28
|
+
delete seat.readFace;
|
|
29
|
+
else
|
|
30
|
+
seat.readFace = next.readFace;
|
|
31
|
+
seat.readFaceSource = next.readFaceSource;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
6
34
|
export function readFaceSourceNote(source) {
|
|
7
35
|
return postureSourceNote({
|
|
8
36
|
knob: "READ_FACE",
|
|
9
37
|
source,
|
|
10
38
|
centerMeaning: "published by the web-admin and applied HOT — the containment FACE is a swappable engine seat (core 7.10.0), so the next refresh (or POST /v1/admin/config/refresh) swaps it into every Runner with NO restart; set READ_FACE on this machine to take the key back",
|
|
39
|
+
laneMeaning: `declared by the isolated execution lane this deployment runs on (REMOTE_EXEC=e2b|k8s|local-docker): the sandbox is the model's whole world, so reads are not fenced to the workspace roots by default; ${LANE_OPEN_READ_FACE_CAUTION}`,
|
|
11
40
|
postureMeaning: "derived from the single-user turnkey posture (REQUIRE_PRINCIPAL is not set): reads outside the workspace roots are allowed by default — set READ_FACE=roots to pin the containing posture back",
|
|
12
41
|
});
|
|
13
42
|
}
|
|
@@ -15,11 +44,11 @@ export function buildReadFaceWiring(facts) {
|
|
|
15
44
|
return { face: facts.readFace ?? null, source: facts.readFaceSource, note: readFaceSourceNote(facts.readFaceSource) };
|
|
16
45
|
}
|
|
17
46
|
export function buildReadFacePostureNotice(facts) {
|
|
18
|
-
if (facts.readFaceSource !== "posture")
|
|
47
|
+
if (facts.readFaceSource !== "posture" && facts.readFaceSource !== "lane")
|
|
19
48
|
return undefined;
|
|
20
49
|
const wiring = buildReadFaceWiring(facts);
|
|
21
50
|
if (wiring.face === null) {
|
|
22
|
-
throw new Error(
|
|
51
|
+
throw new Error(`read-face derived notice: source is \`${facts.readFaceSource}\` but no face was minted — readFaceDefaultFor's invariant broke`);
|
|
23
52
|
}
|
|
24
53
|
return { event: "config_knob_posture_derived", fields: { knob: "READ_FACE", value: wiring.face, source: wiring.source, note: wiring.note } };
|
|
25
54
|
}
|
|
@@ -58,5 +58,12 @@ export type InterruptSteerBody = {
|
|
|
58
58
|
export type SteerBodyForm = "run" | "content" | "interrupt";
|
|
59
59
|
/** 送话口的顶层键裁决(各形同一只;`form` 选受理集)。 */
|
|
60
60
|
export declare function steerBodyKeyIssue(raw: unknown, form: SteerBodyForm): KeyClosureIssue | null;
|
|
61
|
+
declare const PRINCIPAL_INBOX_BODY_KEYS: readonly ["to", "content", "urgent"];
|
|
62
|
+
/** 受理口的体形(键 = 受理集,值形由路由逐键判)。 */
|
|
63
|
+
export type PrincipalInboxBody = {
|
|
64
|
+
readonly [K in (typeof PRINCIPAL_INBOX_BODY_KEYS)[number]]?: unknown;
|
|
65
|
+
};
|
|
66
|
+
/** 受理口的顶层键裁决(与提交口 / 送话口同一只组句器)。 */
|
|
67
|
+
export declare function principalInboxBodyKeyIssue(raw: unknown): KeyClosureIssue | null;
|
|
61
68
|
export {};
|
|
62
69
|
//# sourceMappingURL=request-key-closure.d.ts.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { echoCallerText } from "./caller-text-echo.js";
|
|
2
|
+
import { tightenOnlySeatField } from "./tighten-only-seats.js";
|
|
2
3
|
export const MAX_KEY_ECHO = 20;
|
|
3
4
|
export function echoKeyName(prefix, key) {
|
|
4
5
|
return `${prefix}${echoCallerText(key)}`;
|
|
@@ -31,6 +32,7 @@ const TASK_BODY_DECLARED_KEYS = [
|
|
|
31
32
|
const TASK_BODY_SCENARIO_KEYS = ["repo"];
|
|
32
33
|
const ACCEPTED_BODY = new Set([...TASK_BODY_DECLARED_KEYS, ...TASK_BODY_SCENARIO_KEYS]);
|
|
33
34
|
const UNSUPPORTED_BODY_KEYS = ["handsReadOnly", "readDenyPatterns", "readFace", "shellGate", "writeFace"];
|
|
35
|
+
const BODY_KEY_SETTINGS_SEAT = { readDenyPatterns: tightenOnlySeatField("readDenyPatterns") };
|
|
34
36
|
const UNSUPPORTED_BODY = {
|
|
35
37
|
keys: new Set(UNSUPPORTED_BODY_KEYS),
|
|
36
38
|
label: "unsupported (an engine seat this door does not read from the request body — set by the deployment)",
|
|
@@ -49,9 +51,10 @@ function closedBodyKeyIssue(raw, accepted, unsupported, door) {
|
|
|
49
51
|
...(buckets.unknown.length > 0 ? [keyClosureClause(buckets.unknown, `unknown (not ${door} key — check the spelling)`)] : []),
|
|
50
52
|
...(buckets.unsupported.length > 0 ? [keyClosureClause(buckets.unsupported, unsupported.label)] : []),
|
|
51
53
|
];
|
|
54
|
+
const seatHints = buckets.unsupported.flatMap((key) => (Object.hasOwn(BODY_KEY_SETTINGS_SEAT, key) ? [` \`${key}\` rides ${BODY_KEY_SETTINGS_SEAT[key]} instead.`] : []));
|
|
52
55
|
return {
|
|
53
56
|
message: `body: unrecognized top-level key(s) — refused rather than dropped, because a dropped key reads as "in effect" to the caller. ` +
|
|
54
|
-
`${parts.join("; ")}. ` +
|
|
57
|
+
`${parts.join("; ")}.${seatHints.join("")} ` +
|
|
55
58
|
`Accepted: ${[...accepted].sort().join(",")}`,
|
|
56
59
|
unknownKeys: buckets.unknown.slice(0, MAX_KEY_ECHO),
|
|
57
60
|
unsupportedKeys: buckets.unsupported.slice(0, MAX_KEY_ECHO),
|
|
@@ -75,4 +78,9 @@ const STEER_UNSUPPORTED = {
|
|
|
75
78
|
export function steerBodyKeyIssue(raw, form) {
|
|
76
79
|
return closedBodyKeyIssue(raw, STEER_DOORS[form].accepted, STEER_UNSUPPORTED, STEER_DOORS[form].door);
|
|
77
80
|
}
|
|
81
|
+
const PRINCIPAL_INBOX_BODY_KEYS = ["to", "content", "urgent"];
|
|
82
|
+
const PRINCIPAL_INBOX_UNSUPPORTED = { keys: new Set(), label: "unsupported" };
|
|
83
|
+
export function principalInboxBodyKeyIssue(raw) {
|
|
84
|
+
return closedBodyKeyIssue(raw, new Set(PRINCIPAL_INBOX_BODY_KEYS), PRINCIPAL_INBOX_UNSUPPORTED, "a principal-inbox message");
|
|
85
|
+
}
|
|
78
86
|
//# sourceMappingURL=request-key-closure.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 请求侧 `toolAxes` 声明的读法 —— `mcpServers[].toolAxes`(`task-mcp.ts`)与 `a2aPeers[].toolAxes`(`task-a2a.ts`)同一只。
|
|
3
|
+
*
|
|
4
|
+
* 律(一句):判官是引擎包根的 `readToolAxes(declared, at)`;请求侧再多一条 —— **不许写 `boundaryFlow`**。
|
|
5
|
+
* `boundaryFlow: "engine"`(须同条 `egress: false`)声明一只引擎专用工具:名册行读成零条腿,设备车道的发射闸对它的调用不欠任何东西。
|
|
6
|
+
* 引擎分不出一条声明来自请求还是部署,所以这个位只许部署声明(`config.d` / 配置中心)写 —— 那两条腿原样交引擎(由引擎判 `egress: false`)。
|
|
7
|
+
* 读数形与引擎判官同一只(`ToolAxesRead`):请求侧写了这个位 ⇒ `ok: false`,原因句点名工具(或 skill)与出路;各腿按自己既有的「判不过」处置读它
|
|
8
|
+
* (MCP 新提交 400 点名 / 续跑重放整条 server 不进;A2A 整条对端不挂、warn 点名)。
|
|
9
|
+
*/
|
|
10
|
+
import { type ToolAxesRead, type ToolAxesSurface } from "@sema-agent/core";
|
|
11
|
+
export declare function readRequestToolAxes(declared: unknown, at: ToolAxesSurface): ToolAxesRead;
|
|
12
|
+
//# sourceMappingURL=request-tool-axes.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readToolAxes } from "@sema-agent/core";
|
|
2
|
+
import { stripControlAndBidi } from "@sema-agent/settings-schema";
|
|
3
|
+
import { MAX_KEY_ECHO } from "./request-key-closure.js";
|
|
4
|
+
const KEY_NOUN = { mcp: "tool", a2a: "skill" };
|
|
5
|
+
export function readRequestToolAxes(declared, at) {
|
|
6
|
+
const read = readToolAxes(declared, at);
|
|
7
|
+
if (!read.ok || read.toolAxes === undefined)
|
|
8
|
+
return read;
|
|
9
|
+
for (const [name, axes] of Object.entries(read.toolAxes)) {
|
|
10
|
+
if (axes !== undefined && Object.hasOwn(axes, "boundaryFlow")) {
|
|
11
|
+
return {
|
|
12
|
+
ok: false,
|
|
13
|
+
problem: `the axes declared for ${KEY_NOUN[at]} ${JSON.stringify(stripControlAndBidi(name).slice(0, MAX_KEY_ECHO))} carry "boundaryFlow", which only a deployment's declaration may state ` +
|
|
14
|
+
`(it declares an engine-only ${KEY_NOUN[at]}, so the device lane's launch gate would owe its calls nothing; the engine cannot tell a request's entry from a deployment's) — drop "boundaryFlow"`,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return read;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=request-tool-axes.js.map
|
|
@@ -71,6 +71,11 @@ export declare const FILE_HISTORY_DISABLED_NO_RESTORE = "fileHistory: 'disabled'
|
|
|
71
71
|
* 正是这个词关掉的记录 —— 两义都与关断词矛盾)。调用前值形已由上面的单成员表与既有布尔门判过。
|
|
72
72
|
*/
|
|
73
73
|
export declare function fileHistoryRestoreConflict(body: Pick<TaskRequestBody, "fileHistory" | "restoreFiles" | "rewindFiles" | "rewindFilesTo">): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* 还原键里请求**真带了的**那几个(顺序固定:`restoreFiles` · `rewindFilesTo` · 退役的 `rewindFiles`)。{@link fileHistoryRestoreConflict} 的「还原」一半就是它非空 ——
|
|
76
|
+
* 判据只有这一份,拒体的 `detail.fields` 点名的也是它(判与点名不会各读各的)。
|
|
77
|
+
*/
|
|
78
|
+
export declare function fileHistoryRestoreKeysInBody(body: Pick<TaskRequestBody, "restoreFiles" | "rewindFiles" | "rewindFilesTo">): Array<"restoreFiles" | "rewindFilesTo" | "rewindFiles">;
|
|
74
79
|
/**
|
|
75
80
|
* **单成员闭集键表** —— 每键合法值只有它自己那一个关断词(`word`),缺席=照常,没有「开」的拼法。
|
|
76
81
|
*
|
|
@@ -3,9 +3,17 @@ export const MEMORY_OFF_SPELLING_MESSAGE = "memory must be the string 'off' when
|
|
|
3
3
|
export const FILE_HISTORY_OFF_SPELLING_MESSAGE = "fileHistory must be the string 'disabled' when present (the request-level declaration that this run records no file history — no backup of an edited file, and no file restore in the same request; absent = the deployment's setting — there is no 'enabled' spelling)";
|
|
4
4
|
export const FILE_HISTORY_DISABLED_NO_RESTORE = "fileHistory: 'disabled' cannot ride with a file restore (restoreFiles, rewindFilesTo, or the retired rewindFiles) — the request turns this run's file history off and asks to restore files from it in the same breath; the engine would refuse it (rewind.capture_disabled) only after the session had already been branched at resumeAt, which it does not undo, so it is refused here, before any side effect. Drop fileHistory to restore, or drop the restore to run without file history";
|
|
5
5
|
export function fileHistoryRestoreConflict(body) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
return body.fileHistory === "disabled" && fileHistoryRestoreKeysInBody(body).length > 0;
|
|
7
|
+
}
|
|
8
|
+
export function fileHistoryRestoreKeysInBody(body) {
|
|
9
|
+
const out = [];
|
|
10
|
+
if (body.restoreFiles === true)
|
|
11
|
+
out.push("restoreFiles");
|
|
12
|
+
if (typeof body.rewindFilesTo === "string" && body.rewindFilesTo.length > 0)
|
|
13
|
+
out.push("rewindFilesTo");
|
|
14
|
+
if (body.rewindFiles === true)
|
|
15
|
+
out.push("rewindFiles");
|
|
16
|
+
return out;
|
|
9
17
|
}
|
|
10
18
|
const SINGLE_MEMBER_OFF_FIELDS = [
|
|
11
19
|
{ field: "memoryCapture", word: "off", message: MEMORY_CAPTURE_SPELLING_MESSAGE },
|