@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
|
@@ -2,12 +2,11 @@ import { hookNoticeWire } from "../../fleet/fleet-bus.js";
|
|
|
2
2
|
import { FLEET_SNAPSHOT_TERMINAL_MAX_ROWS, isTerminalWorkflowRowStatus, recentTerminalWorkflowRows } from "../../fleet/fleet-terminal-window.js";
|
|
3
3
|
import { taskNotificationFoldKey } from "../../orchestration/workflow-completion-inbox.js";
|
|
4
4
|
import { sendJson, sendError, sseHeaders } from "../send.js";
|
|
5
|
-
import { gatedPrincipal, sendPrincipalRefusal } from "../principal-gate.js";
|
|
5
|
+
import { fleetViewOf, gatedPrincipal, sendPrincipalRefusal } from "../principal-gate.js";
|
|
6
6
|
import { assertNever } from "../route-ctx.js";
|
|
7
7
|
import * as facts from "../../capability-facts.js";
|
|
8
8
|
export async function handleFleet(req, res, match, ctx) {
|
|
9
9
|
const { deps } = ctx;
|
|
10
|
-
const { sessionOwnerScope } = ctx.helpers;
|
|
11
10
|
switch (match.decl.id) {
|
|
12
11
|
case "fleet-stream": {
|
|
13
12
|
const fleet = facts.fleetStream(deps);
|
|
@@ -15,7 +14,7 @@ export async function handleFleet(req, res, match, ctx) {
|
|
|
15
14
|
sendError(res, 501, "capability.self_orchestration_required", "fleet stream requires self-orchestration / fleet wiring");
|
|
16
15
|
return;
|
|
17
16
|
}
|
|
18
|
-
const { fleetWide } =
|
|
17
|
+
const { fleetWide } = fleetViewOf(req, deps, "read");
|
|
19
18
|
const principal = gatedPrincipal(req, deps.config);
|
|
20
19
|
if (deps.config.requirePrincipal && !principal && !fleetWide) {
|
|
21
20
|
sendPrincipalRefusal(res, req, deps.config);
|
|
@@ -77,7 +76,7 @@ function streamFleet(req, res, bus, callerScope, callerSession = null, completio
|
|
|
77
76
|
return rest;
|
|
78
77
|
};
|
|
79
78
|
const SCOPED_WORKFLOW_KEY_DISPOSITION = {
|
|
80
|
-
id: "keep", status: "keep", doneCount: "keep", totalCount: "keep", failedCount: "keep",
|
|
79
|
+
id: "keep", status: "keep", errorCode: "keep", doneCount: "keep", totalCount: "keep", failedCount: "keep",
|
|
81
80
|
startedCount: "keep", elapsedMs: "keep", tokens: "keep",
|
|
82
81
|
name: "rewrite", scope: "strip", sessionId: "strip",
|
|
83
82
|
description: "scrub",
|
|
@@ -90,6 +89,7 @@ function streamFleet(req, res, bus, callerScope, callerSession = null, completio
|
|
|
90
89
|
id: rest.id,
|
|
91
90
|
status: rest.status,
|
|
92
91
|
name: "(unattributed)",
|
|
92
|
+
...(rest.errorCode !== undefined ? { errorCode: rest.errorCode } : {}),
|
|
93
93
|
...(rest.doneCount !== undefined ? { doneCount: rest.doneCount } : {}),
|
|
94
94
|
...(rest.totalCount !== undefined ? { totalCount: rest.totalCount } : {}),
|
|
95
95
|
...(rest.failedCount !== undefined ? { failedCount: rest.failedCount } : {}),
|
|
@@ -49,8 +49,7 @@ export async function handleImages(req, res, match, ctx) {
|
|
|
49
49
|
const bakes = deps.imageBakes;
|
|
50
50
|
const idx = deps.imageIndex;
|
|
51
51
|
const principal = gatedPrincipal(req, deps.config);
|
|
52
|
-
const
|
|
53
|
-
const isExplicitOperator = explicitOperatorOk(principal, operators);
|
|
52
|
+
const isExplicitOperator = explicitOperatorOk(principal, deps.config);
|
|
54
53
|
const operatorLane = facts.operatorLane(deps);
|
|
55
54
|
const cfg = deps.config.imageBakes;
|
|
56
55
|
const isRunner = source !== undefined && source !== null && source === cfg.runnerPrincipal;
|
|
@@ -239,12 +238,12 @@ export async function handleImages(req, res, match, ctx) {
|
|
|
239
238
|
if (line.event === "heartbeat") {
|
|
240
239
|
const fresh = await bakes.getBake(bakeId);
|
|
241
240
|
if (!fresh || fresh.status !== "running") {
|
|
242
|
-
|
|
241
|
+
sendError(res, 409, "conflict.bake_not_running", "bake is not running", { accepted: false, leaseValid: false, cancelRequested: fresh?.cancelRequested ?? false });
|
|
243
242
|
return;
|
|
244
243
|
}
|
|
245
244
|
const ok = bake.runnerId ? await bakes.heartbeatLease(bakeId, bake.runnerId, cfg.leaseMs) : false;
|
|
246
245
|
if (!ok) {
|
|
247
|
-
|
|
246
|
+
sendError(res, 409, "conflict.bake_lease_lost", "bake lease lost", { accepted: false, leaseValid: false, cancelRequested: fresh.cancelRequested });
|
|
248
247
|
return;
|
|
249
248
|
}
|
|
250
249
|
sendJson(res, 200, { accepted: true, leaseValid: true, cancelRequested: fresh.cancelRequested });
|
|
@@ -252,7 +251,7 @@ export async function handleImages(req, res, match, ctx) {
|
|
|
252
251
|
}
|
|
253
252
|
const fresh = await bakes.getBake(bakeId);
|
|
254
253
|
if (!fresh || fresh.status !== "running") {
|
|
255
|
-
|
|
254
|
+
sendError(res, 409, "conflict.bake_not_running", "bake is not running", { accepted: false, leaseValid: false, cancelRequested: fresh?.cancelRequested ?? false });
|
|
256
255
|
return;
|
|
257
256
|
}
|
|
258
257
|
if (fresh.runnerId) {
|
|
@@ -291,7 +290,7 @@ export async function handleImages(req, res, match, ctx) {
|
|
|
291
290
|
if (pool.available && isIndexRouteId(match.decl.id)) {
|
|
292
291
|
const idx = pool.imageIndex;
|
|
293
292
|
const principal = gatedPrincipal(req, deps.config);
|
|
294
|
-
const operator = explicitOperatorOk(principal, deps.config
|
|
293
|
+
const operator = explicitOperatorOk(principal, deps.config);
|
|
295
294
|
const viewer = { operator, tenantId: principal ?? null };
|
|
296
295
|
const q = new URLSearchParams(match.search);
|
|
297
296
|
if (match.decl.id === "images-index") {
|
|
@@ -345,7 +344,7 @@ export async function handleImages(req, res, match, ctx) {
|
|
|
345
344
|
sendOperatorPrincipalsRequired(res);
|
|
346
345
|
return;
|
|
347
346
|
}
|
|
348
|
-
if (!explicitOperatorOk(principal, deps.config
|
|
347
|
+
if (!explicitOperatorOk(principal, deps.config)) {
|
|
349
348
|
sendError(res, 403, "auth.operator_only", "operator only");
|
|
350
349
|
return;
|
|
351
350
|
}
|
|
@@ -30,14 +30,7 @@ export async function handleLeader(req, res, match, ctx) {
|
|
|
30
30
|
if (match.decl.id === "leader-submit") {
|
|
31
31
|
if (rateLimited(req, res) || quotaExceeded(req, res) || (await leaseDenied(req, res)) || (await usageWindowDenied(req, res)))
|
|
32
32
|
return;
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
body = await readJson(req);
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
33
|
+
const body = await readJson(req);
|
|
41
34
|
const laneRefusal = leaderEntryRefusal(leaderRunEntry(deps.config.autonomy));
|
|
42
35
|
if (laneRefusal !== undefined) {
|
|
43
36
|
sendError(res, 422, "request.autonomy_lane_refused", laneRefusal);
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* 404 无 oracle,与 `POST /v1/sessions/:id/notify` 逐字同形)→ `getActiveTaskId` 取本会话的活 run →
|
|
35
35
|
* `steerableRuns` 取本副本活流。非 live 的四臂一码 409 `steering.not_running`,判据取词表属主
|
|
36
36
|
* (`isParkedRunStatus` / `isTerminalRunStatus`)与 `runProvenElsewhere`(手抄已收编成一只谓词,S-430 起同住 `plugins/store-contracts.ts`)。
|
|
37
|
-
* 显式 operator 可重拨任何租户的会话(监督动作,与 notify / steer
|
|
37
|
+
* 显式 operator 可重拨任何租户的会话(监督动作,与 notify / steer 同臂;「谁是 operator」的唯一读法 `explicitOperatorOk`)。
|
|
38
38
|
*
|
|
39
39
|
* ── 应答期限(S-431)────────────────────────────────────────────────────────────────────────────
|
|
40
40
|
* 修前这一口对 `live.reconnectMcpServer(server)` 是裸 `await`:server 侧没有期限,上界只来自 core 自己的启动期钟
|
|
@@ -7,6 +7,7 @@ import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal } from "../pri
|
|
|
7
7
|
import {} from "../route-ctx.js";
|
|
8
8
|
import { assertNever, SESSION_NOT_FOUND_MESSAGE } from "../route-ctx.js";
|
|
9
9
|
import * as facts from "../../capability-facts.js";
|
|
10
|
+
import { sessionOwnerCellOf } from "../../security.js";
|
|
10
11
|
const BodySchema = z.object({ server: z.string().min(1).max(190) }).strict();
|
|
11
12
|
const NEUTRALIZED_TEXT_MAX = 200;
|
|
12
13
|
const humanText = (s) => redactSecrets(s).slice(0, NEUTRALIZED_TEXT_MAX);
|
|
@@ -93,8 +94,8 @@ export async function handleMcpReconnect(req, res, match, ctx) {
|
|
|
93
94
|
sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
|
|
94
95
|
return;
|
|
95
96
|
}
|
|
96
|
-
const
|
|
97
|
-
if (!
|
|
97
|
+
const operator = explicitOperatorOk(principal, deps.config);
|
|
98
|
+
if (!operator && !ctx.helpers.sessionOwnerOk(req, res, await sessionOwnerCellOf(sessionStorage, sessionId, owner)))
|
|
98
99
|
return;
|
|
99
100
|
const activeTaskId = await runStore.getActiveTaskId(sessionId);
|
|
100
101
|
const live = activeTaskId === undefined ? undefined : ctx.registry.steerableRuns.get(activeTaskId);
|
|
@@ -73,7 +73,7 @@ export async function handleMemoryBundle(req, res, match, ctx) {
|
|
|
73
73
|
sendOperatorPrincipalsRequired(res);
|
|
74
74
|
return;
|
|
75
75
|
}
|
|
76
|
-
if (!explicitOperatorOk(principal, deps.config
|
|
76
|
+
if (!explicitOperatorOk(principal, deps.config)) {
|
|
77
77
|
sendError(res, 403, "auth.operator_only", "memory governance bundles are an operator-only deployment action");
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
@@ -29,7 +29,7 @@ export async function handleMemoryCompliance(req, res, match, ctx) {
|
|
|
29
29
|
sendOperatorPrincipalsRequired(res);
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
if (!explicitOperatorOk(principal, deps.config
|
|
32
|
+
if (!explicitOperatorOk(principal, deps.config)) {
|
|
33
33
|
sendError(res, 403, "auth.operator_only", "memory provenance and erasure are operator-only deployment actions");
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
@@ -92,7 +92,7 @@ export async function handleMemoryConsolidation(req, res, match, ctx) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
const faces = fact.valve;
|
|
95
|
-
if (!explicitOperatorOk(principal, deps.config
|
|
95
|
+
if (!explicitOperatorOk(principal, deps.config)) {
|
|
96
96
|
sendError(res, 403, "auth.operator_only", "memory consolidation is operator-only: the caller principal is not in OPERATOR_PRINCIPALS");
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
@@ -114,7 +114,7 @@ export declare function buildClearanceRowWire(r: OriginClearanceRow): {
|
|
|
114
114
|
baseRev: string;
|
|
115
115
|
origin: {
|
|
116
116
|
at: number;
|
|
117
|
-
cause?: "static" | "
|
|
117
|
+
cause?: "static" | "observed" | "unattributed" | "derived" | undefined;
|
|
118
118
|
taint: "external";
|
|
119
119
|
};
|
|
120
120
|
};
|
|
@@ -122,7 +122,7 @@ export async function handleMemoryOrigin(req, res, match, ctx) {
|
|
|
122
122
|
sendOperatorPrincipalsRequired(res);
|
|
123
123
|
return;
|
|
124
124
|
}
|
|
125
|
-
if (!explicitOperatorOk(principal, deps.config
|
|
125
|
+
if (!explicitOperatorOk(principal, deps.config)) {
|
|
126
126
|
sendError(res, 403, "auth.operator_only", "memory origin marking and clearance are operator-only deployment actions");
|
|
127
127
|
return;
|
|
128
128
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* [ref] A9 域模块 —— memory 导出/同步 + 只读策略面。
|
|
3
3
|
*
|
|
4
4
|
* 路由:`GET /v1/memory/export`、`POST /v1/memory/sync/:scope`、`GET /v1/policy`。
|
|
5
|
-
* owner 门 = 「本人 user scope / 显式 operator / `org:` 键的目录成员」(见 {@link gateMemoryScope}),
|
|
5
|
+
* owner 门 = 「本人 user scope / 本人的项目层 / 显式 operator / `org:` 键的目录成员」(见 {@link gateMemoryScope}),
|
|
6
6
|
* 越界一律 404(零存在性 oracle)。本域零可变状态。
|
|
7
7
|
*/
|
|
8
8
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
@@ -2,6 +2,7 @@ import { formatUserScope } from "@sema-agent/core";
|
|
|
2
2
|
import { parseMemorySyncRequest } from "../../memory-sync.js";
|
|
3
3
|
import { sendJson, sendError } from "../send.js";
|
|
4
4
|
import { buildOriginFence, readOriginAware } from "../../memory-origin-fence.js";
|
|
5
|
+
import { parseProjectLayerKey } from "../../project-layer-key.js";
|
|
5
6
|
import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sendUnauthorized } from "../principal-gate.js";
|
|
6
7
|
import { assertNever } from "../route-ctx.js";
|
|
7
8
|
const ORG_PREFIX = "org:";
|
|
@@ -33,9 +34,9 @@ function directoryDecidesThisFace(mode) {
|
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
async function gateMemoryScope(deps, principal, scope, need) {
|
|
36
|
-
if (scope === formatUserScope(principal))
|
|
37
|
+
if (scope === formatUserScope(principal) || parseProjectLayerKey(scope)?.owner === principal)
|
|
37
38
|
return { kind: "allow" };
|
|
38
|
-
if (explicitOperatorOk(principal, deps.config
|
|
39
|
+
if (explicitOperatorOk(principal, deps.config))
|
|
39
40
|
return { kind: "allow" };
|
|
40
41
|
const directory = deps.orgMemoryDirectory;
|
|
41
42
|
if (!scope.startsWith(ORG_PREFIX) || directory === undefined || !directoryDecidesThisFace(deps.config.memoryOrgAdmissionMode)) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { externalNotificationInboxEntry } from "../../orchestration/workflow-completion-inbox.js";
|
|
2
2
|
import { sendJson, sendError } from "../send.js";
|
|
3
|
-
import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal } from "../principal-gate.js";
|
|
3
|
+
import { gatedPrincipal, explicitOperatorOk, sendPrincipalRefusal, sessionCallerOf } from "../principal-gate.js";
|
|
4
|
+
import { ownerlessRowOpen, sessionOwnerCellOf } from "../../security.js";
|
|
4
5
|
import { sendResumeOutcome } from "../route-ctx.js";
|
|
5
6
|
import { assertNever, SESSION_NOT_FOUND_MESSAGE } from "../route-ctx.js";
|
|
6
7
|
import * as facts from "../../capability-facts.js";
|
|
@@ -23,14 +24,7 @@ export async function handleNotifyWake(req, res, match, ctx) {
|
|
|
23
24
|
sendError(res, 400, "request.path_malformed", "session id segment is not valid percent-encoding");
|
|
24
25
|
return;
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
nb = (await readJson(req));
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
sendError(res, 400, "request.body_shape", "body must be JSON: { task_id, status, summary, result?, seq?, source? }");
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
27
|
+
const nb = (await readJson(req));
|
|
34
28
|
if (typeof nb.task_id !== "string" || nb.task_id.trim().length === 0 || nb.task_id.length > 190) {
|
|
35
29
|
sendError(res, 400, "request.field_invalid", "task_id must be a non-empty string of at most 190 characters");
|
|
36
30
|
return;
|
|
@@ -68,8 +62,8 @@ export async function handleNotifyWake(req, res, match, ctx) {
|
|
|
68
62
|
sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
|
|
69
63
|
return;
|
|
70
64
|
}
|
|
71
|
-
const notifyOperator = explicitOperatorOk(principal, deps.config
|
|
72
|
-
if (!notifyOperator && notifyOwner !==
|
|
65
|
+
const notifyOperator = explicitOperatorOk(principal, deps.config);
|
|
66
|
+
if (!notifyOperator && notifyOwner !== principal && !ownerlessRowOpen(await sessionOwnerCellOf(owned.sessionStorage, notifySession, notifyOwner), sessionCallerOf(req, deps))) {
|
|
73
67
|
sendError(res, 404, "not_found.session", SESSION_NOT_FOUND_MESSAGE);
|
|
74
68
|
return;
|
|
75
69
|
}
|
|
@@ -101,7 +95,7 @@ export async function handleNotifyWake(req, res, match, ctx) {
|
|
|
101
95
|
sendError(res, 501, "capability.workflow_store_required", "external notify requires the workflow completion inbox (WORKFLOW_RUN_STORE)");
|
|
102
96
|
return;
|
|
103
97
|
}
|
|
104
|
-
await deps.workflowCompletionInbox.enqueue(
|
|
98
|
+
await deps.workflowCompletionInbox.enqueue(externalNotificationInboxEntry(notifySession, notifyOwner ?? principal ?? null, { task_type: "external", ...payload }, Date.now()));
|
|
105
99
|
sendJson(res, 202, { sessionId: notifySession, delivery: "parked", note: "no live stream — parked in the session inbox; drained as a task_notification on the next stream open" });
|
|
106
100
|
return;
|
|
107
101
|
}
|
|
@@ -122,14 +116,7 @@ export async function handleNotifyWake(req, res, match, ctx) {
|
|
|
122
116
|
sendError(res, 400, "request.path_malformed", "session id segment is not valid percent-encoding");
|
|
123
117
|
return;
|
|
124
118
|
}
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
wakeBody = (await readJson(req));
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
sendError(res, 400, "request.body_shape", "body must be JSON: { message?: string }");
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
119
|
+
const wakeBody = (await readJson(req));
|
|
133
120
|
if (wakeBody.message !== undefined && (typeof wakeBody.message !== "string" || wakeBody.message.length === 0)) {
|
|
134
121
|
sendError(res, 400, "request.field_invalid", "message must be a non-empty string when present");
|
|
135
122
|
return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { sendJson, sendError } from "../send.js";
|
|
2
|
-
import { gatedPrincipal,
|
|
2
|
+
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendPrincipalRefusal } from "../principal-gate.js";
|
|
3
3
|
import { assertNever } from "../route-ctx.js";
|
|
4
4
|
import * as facts from "../../capability-facts.js";
|
|
5
5
|
import { quotaWindowResetsAt } from "../../observability/cost-quota.js";
|
|
@@ -14,7 +14,7 @@ export async function handleObservability(req, res, match, ctx) {
|
|
|
14
14
|
}
|
|
15
15
|
if (deps.config.requirePrincipal) {
|
|
16
16
|
const principal = gatedPrincipal(req, deps.config);
|
|
17
|
-
if (!explicitOperatorOk(principal, deps.config
|
|
17
|
+
if (!explicitOperatorOk(principal, deps.config)) {
|
|
18
18
|
sendError(res, 403, "auth.operator_only", "outcomes view is operator-only on a multi-tenant worker");
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 跨主体投递门的**受理口**:`POST /v1/principal-inbox/messages`。
|
|
3
|
+
*
|
|
4
|
+
* 本口只做三件事,其余全归门(`src/org-delivery-gate.ts`,规则全文在它的头注):
|
|
5
|
+
* ① 取发件人 —— **只**取自验过的身份面(`gatedPrincipal`),交给门的 `authedFrom` 就是 `{ scope: <那位主体> }`;
|
|
6
|
+
* 体里没有发件人这个键(写了 = 词表外键,400)。没有验过的身份 ⇒ 401(身份面那一句),不论部署是否要求 principal ——
|
|
7
|
+
* 门要一个发件人 scope,匿名者没有。无凭证部署上 principal 头只是调用方自报 ⇒ 本口在分派器的无凭证写门内
|
|
8
|
+
* (声明行 `credentialGated`,503 `auth.service_token_required`;本地开发显式 `ALLOW_UNAUTHED_WRITES=true` 才放行);
|
|
9
|
+
* ② 判体形 —— `{ to: 非空串, content: 非空串(≤ {@link PRINCIPAL_INBOX_CONTENT_MAX_CHARS} 字), urgent?: 布尔 }`,
|
|
10
|
+
* 键闭集与提交口同一只组句器(`principalInboxBodyKeyIssue`);
|
|
11
|
+
* ③ 调门、投影门的答案 —— 回执 ⇒ 200 `{ receiptId }`;拒绝 ⇒ core 的词原样做 `errorCode`、门的那一句原样做 `error`。
|
|
12
|
+
* 本口**不碰**任何店:一个店名、一个 `.append` 都没有(`test/org-delivery-gate-single-path.test.ts` 按源码钉)。
|
|
13
|
+
*
|
|
14
|
+
* 回执**不**带门回执里的 `seq`:那是收件人箱的序号,原样交给发件人就是把「收件人这只箱收过多少封」泄给 org 里的任何人。
|
|
15
|
+
*
|
|
16
|
+
* 拒绝词 → HTTP 状态(穷举 `switch`,core 加词 ⇒ 编译红):
|
|
17
|
+
* · `not_member` → 404:「不同 org」「查无此人」「目录答不上来」同一份字节(门保证),404 与本仓反枚举的既有形一致;
|
|
18
|
+
* · `rate_limited` → 429;
|
|
19
|
+
* · `inbox_full` → 409(收件人那一侧的状态,不是发件人的速率;与 `steering.queue_full` 同档);
|
|
20
|
+
* · `recipient_tombstoned` → 410(收件人正在被删除,这条路关了)。
|
|
21
|
+
* 门缺席(本部署没声明收件箱消费方)⇒ 501 `capability.unavailable`,能力位 `principalInboxDelivery` 读同一只事实。
|
|
22
|
+
*/
|
|
23
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
24
|
+
import type { RouteCtx, RouteMatch, RouteIdsOf } from "../route-ctx.js";
|
|
25
|
+
/**
|
|
26
|
+
* 一封信正文的字符上界。全局请求体上界(8 MiB)对一只收件箱太宽:箱里最多 50 封,而读它的是收件人的助理 ——
|
|
27
|
+
* 一封信是一段话,不是一份附件(要转一份长文,发它的出处)。
|
|
28
|
+
*/
|
|
29
|
+
export declare const PRINCIPAL_INBOX_CONTENT_MAX_CHARS = 32000;
|
|
30
|
+
export declare function handlePrincipalInbox(req: IncomingMessage, res: ServerResponse, match: RouteMatch<PrincipalInboxRouteId>, ctx: RouteCtx): Promise<void>;
|
|
31
|
+
export declare const PRINCIPAL_INBOX_ROUTES: readonly [{
|
|
32
|
+
readonly id: "principal-inbox-messages";
|
|
33
|
+
readonly path: "/v1/principal-inbox/messages";
|
|
34
|
+
readonly credentialGated: readonly ["POST"];
|
|
35
|
+
readonly methods: readonly ["POST"];
|
|
36
|
+
}];
|
|
37
|
+
/** 本域可分派行的 `id` 闭集 —— handler 的 `switch` 按它判穷尽。 */
|
|
38
|
+
export type PrincipalInboxRouteId = RouteIdsOf<typeof PRINCIPAL_INBOX_ROUTES>;
|
|
39
|
+
//# sourceMappingURL=principal-inbox.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { sendJson, sendError } from "../send.js";
|
|
2
|
+
import { gatedPrincipal, sendUnauthorized } from "../principal-gate.js";
|
|
3
|
+
import { assertNever } from "../route-ctx.js";
|
|
4
|
+
import * as facts from "../../capability-facts.js";
|
|
5
|
+
import { principalInboxBodyKeyIssue } from "../../request-key-closure.js";
|
|
6
|
+
export const PRINCIPAL_INBOX_CONTENT_MAX_CHARS = 32_000;
|
|
7
|
+
function sendRefusal(res, outcome) {
|
|
8
|
+
switch (outcome.code) {
|
|
9
|
+
case "org_delivery.not_member":
|
|
10
|
+
sendError(res, 404, "org_delivery.not_member", outcome.message);
|
|
11
|
+
return;
|
|
12
|
+
case "org_delivery.rate_limited":
|
|
13
|
+
sendError(res, 429, "org_delivery.rate_limited", outcome.message);
|
|
14
|
+
return;
|
|
15
|
+
case "org_delivery.inbox_full":
|
|
16
|
+
sendError(res, 409, "org_delivery.inbox_full", outcome.message);
|
|
17
|
+
return;
|
|
18
|
+
case "org_delivery.recipient_tombstoned":
|
|
19
|
+
sendError(res, 410, "org_delivery.recipient_tombstoned", outcome.message);
|
|
20
|
+
return;
|
|
21
|
+
default:
|
|
22
|
+
return assertNever(outcome.code);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export async function handlePrincipalInbox(req, res, match, ctx) {
|
|
26
|
+
const { deps } = ctx;
|
|
27
|
+
const { readJson } = ctx.helpers;
|
|
28
|
+
switch (match.decl.id) {
|
|
29
|
+
case "principal-inbox-messages": {
|
|
30
|
+
const principal = gatedPrincipal(req, deps.config);
|
|
31
|
+
if (principal === undefined) {
|
|
32
|
+
sendUnauthorized(res, "identity");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const fact = facts.principalInboxDelivery(deps);
|
|
36
|
+
if (!fact.available) {
|
|
37
|
+
sendError(res, 501, "capability.unavailable", "cross-principal delivery is not available on this deployment (it declares no principal-inbox consumer, so no organization delivery gate is mounted)");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const raw = await readJson(req);
|
|
41
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
42
|
+
sendError(res, 400, "request.field_invalid", "body must be a JSON object { to: string, content: string, urgent?: boolean }");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const keyIssue = principalInboxBodyKeyIssue(raw);
|
|
46
|
+
if (keyIssue) {
|
|
47
|
+
sendError(res, 400, "request.body_shape", keyIssue.message, { unknownKeys: keyIssue.unknownKeys, unsupportedKeys: keyIssue.unsupportedKeys });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const body = raw;
|
|
51
|
+
if (typeof body.to !== "string" || body.to === "") {
|
|
52
|
+
sendError(res, 400, "request.field_invalid", "to must be a non-empty string naming the recipient principal");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
if (typeof body.content !== "string" || body.content === "" || body.content.length > PRINCIPAL_INBOX_CONTENT_MAX_CHARS) {
|
|
56
|
+
sendError(res, 400, "request.field_invalid", `content must be a non-empty string of at most ${PRINCIPAL_INBOX_CONTENT_MAX_CHARS} characters`);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (body.urgent !== undefined && typeof body.urgent !== "boolean") {
|
|
60
|
+
sendError(res, 400, "request.field_invalid", "urgent must be a boolean when present");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const outcome = await fact.gate.deliverCrossPrincipal({ scope: principal }, body.to, { content: body.content, ...(body.urgent !== undefined ? { urgent: body.urgent } : {}) });
|
|
64
|
+
if (!outcome.ok) {
|
|
65
|
+
sendRefusal(res, outcome);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
sendJson(res, 200, { receiptId: outcome.receipt.receiptId });
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
default:
|
|
72
|
+
return assertNever(match.decl.id);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export const PRINCIPAL_INBOX_ROUTES = [{ id: "principal-inbox-messages", path: "/v1/principal-inbox/messages", credentialGated: ["POST"], methods: ["POST"] }];
|
|
76
|
+
//# sourceMappingURL=principal-inbox.js.map
|
|
@@ -36,7 +36,7 @@ export async function handleRetention(req, res, match, ctx) {
|
|
|
36
36
|
sendOperatorPrincipalsRequired(res);
|
|
37
37
|
return;
|
|
38
38
|
}
|
|
39
|
-
if (!explicitOperatorOk(principal, deps.config
|
|
39
|
+
if (!explicitOperatorOk(principal, deps.config)) {
|
|
40
40
|
sendError(res, 403, "auth.operator_only", OPERATOR_ONLY_MESSAGE);
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
@@ -71,14 +71,7 @@ async function handleHold(req, res, ctx, store, rawDomain, principal, held) {
|
|
|
71
71
|
}
|
|
72
72
|
let note;
|
|
73
73
|
if (held) {
|
|
74
|
-
|
|
75
|
-
try {
|
|
76
|
-
raw = await ctx.helpers.readJson(req);
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
sendError(res, 400, "request.invalid_json", "invalid JSON body");
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
74
|
+
const raw = await ctx.helpers.readJson(req);
|
|
82
75
|
if (raw !== undefined && raw !== null && raw !== "") {
|
|
83
76
|
if (typeof raw !== "object" || Array.isArray(raw)) {
|
|
84
77
|
sendError(res, 400, "request.body_shape", "invalid retention hold body — expected an object with an optional `note` string");
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { sendJson, sendError
|
|
2
|
+
import { sendJson, sendError } from "../send.js";
|
|
3
3
|
import { gatedPrincipal, explicitOperatorOk, sendOperatorPrincipalsRequired, sendUnauthorized } from "../principal-gate.js";
|
|
4
4
|
import { assertNever } from "../route-ctx.js";
|
|
5
5
|
import * as facts from "../../capability-facts.js";
|
|
6
6
|
import { createLogger } from "../../observability/logger.js";
|
|
7
7
|
import { RULE_IMPORT_RETRY_AFTER_SEC, RULE_SCOPE_REFUSAL_SENTENCE, MAX_RULE_SCOPE_CHARS, buildCcImportLayerRootRefusal, parseRuleScope, serializeRuleScope } from "../../rules-consent.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { PERSISTED_RULE_MATCHES, isPersistedRuleTool, isDirectWritableRuleBehavior } from "../../permission-rule-vocab.js";
|
|
8
|
+
import { hasControlOrBidi } from "@sema-agent/settings-schema";
|
|
9
|
+
import { IMPORTED_SETTINGS_LAYERS, MAX_RULE_TEXT_CHARS, PERSISTED_RULE_MATCHES, RULE_ADD_ORIGINS, RULE_BEHAVIORS, isValidDurableScope } from "@sema-agent/core";
|
|
10
|
+
import { isPersistedRuleTool, isDirectWritableRuleBehavior } from "../../permission-rule-vocab.js";
|
|
12
11
|
const logger = createLogger();
|
|
13
12
|
export const RULES_CC_IMPORT_PREPARE_PATH = "/v1/rules/cc-import/prepare";
|
|
14
13
|
export const RULES_CC_IMPORT_REDEEM_PATH = "/v1/rules/cc-import/redeem";
|
|
@@ -24,7 +23,7 @@ const CcImportPrepareBodySchema = z
|
|
|
24
23
|
layers: z
|
|
25
24
|
.array(z
|
|
26
25
|
.object({
|
|
27
|
-
layer: z.enum(
|
|
26
|
+
layer: z.enum(IMPORTED_SETTINGS_LAYERS),
|
|
28
27
|
path: z.string().min(1).max(1024),
|
|
29
28
|
root: z.string().max(1024),
|
|
30
29
|
content: z.string().max(MAX_LAYER_CONTENT_CHARS),
|
|
@@ -37,13 +36,12 @@ const CcImportPrepareBodySchema = z
|
|
|
37
36
|
function ccImportRootRefused(layer) {
|
|
38
37
|
return !isValidDurableScope({ kind: "project", root: layer.root });
|
|
39
38
|
}
|
|
40
|
-
const
|
|
41
|
-
const TicketStringSchema = z.string().min(1).max(190).refine((t) => !TICKET_CONTROL_CHARS_RE.test(t));
|
|
39
|
+
const TicketStringSchema = z.string().min(1).max(190).refine((t) => !hasControlOrBidi(t));
|
|
42
40
|
const CcImportRedeemBodySchema = z.object({ ticket: TicketStringSchema }).strict();
|
|
43
41
|
const LocalImportAddSchema = z
|
|
44
42
|
.object({
|
|
45
43
|
dot: z.object({ actor: z.string().min(1).max(190), counter: z.number().int().nonnegative().safe() }).strict(),
|
|
46
|
-
origin: z.enum(
|
|
44
|
+
origin: z.enum(RULE_ADD_ORIGINS),
|
|
47
45
|
createdAt: z.string().min(1).max(64),
|
|
48
46
|
})
|
|
49
47
|
.strict();
|
|
@@ -107,18 +105,7 @@ export async function handleRules(req, res, match, ctx) {
|
|
|
107
105
|
await handleRuleList(res, match.search, principal, lane, deps.config);
|
|
108
106
|
return;
|
|
109
107
|
}
|
|
110
|
-
|
|
111
|
-
try {
|
|
112
|
-
rawBody = await readJson(req);
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
if (err instanceof HttpError && err.status !== 400) {
|
|
116
|
-
sendHttpError(res, err);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
sendError(res, 400, "request.body_shape", "body must be valid JSON");
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
108
|
+
const rawBody = await readJson(req);
|
|
122
109
|
if (match.decl.id === "rules-revoke") {
|
|
123
110
|
await handleRuleRevoke(res, rawBody, principal, lane, deps.config);
|
|
124
111
|
return;
|
|
@@ -216,7 +203,7 @@ function resolveTargetPrincipal(requested, caller, config) {
|
|
|
216
203
|
return { ok: true, principal: caller };
|
|
217
204
|
if (!facts.operatorLane({ config }).available)
|
|
218
205
|
return { ok: false, why: "operator_principals_empty" };
|
|
219
|
-
if (!explicitOperatorOk(caller, config
|
|
206
|
+
if (!explicitOperatorOk(caller, config))
|
|
220
207
|
return { ok: false, why: "not_operator" };
|
|
221
208
|
return { ok: true, principal: requested };
|
|
222
209
|
}
|
|
@@ -133,6 +133,11 @@ export declare const RUN_VERBS_ROUTES: readonly [{
|
|
|
133
133
|
readonly pattern: RegExp;
|
|
134
134
|
readonly label: "/v1/tool-approvals/:id/respond";
|
|
135
135
|
readonly methods: readonly ["POST"];
|
|
136
|
+
}, {
|
|
137
|
+
readonly id: "tool-approval-read";
|
|
138
|
+
readonly pattern: RegExp;
|
|
139
|
+
readonly label: "/v1/tool-approvals/:id";
|
|
140
|
+
readonly methods: readonly ["GET"];
|
|
136
141
|
}, {
|
|
137
142
|
readonly id: "task-ask-decision";
|
|
138
143
|
readonly pattern: RegExp;
|