@stigmer/server 3.40.0 → 3.41.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/dist/authorization/authorizer.d.ts +16 -10
- package/dist/authorization/authorizer.d.ts.map +1 -1
- package/dist/authorization/authorizer.js +17 -9
- package/dist/authorization/authorizer.js.map +1 -1
- package/dist/authorization/derived-tuples.d.ts +7 -3
- package/dist/authorization/derived-tuples.d.ts.map +1 -1
- package/dist/authorization/derived-tuples.js +62 -6
- package/dist/authorization/derived-tuples.js.map +1 -1
- package/dist/authorization/evaluator.d.ts +11 -7
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js +16 -10
- package/dist/authorization/evaluator.js.map +1 -1
- package/dist/authorization/list-read-scope.d.ts +4 -0
- package/dist/authorization/list-read-scope.d.ts.map +1 -1
- package/dist/authorization/list-read-scope.js +1 -0
- package/dist/authorization/list-read-scope.js.map +1 -1
- package/dist/authorization/model/data/authorization-model.json +830 -67
- package/dist/authorization/model/execution-viewer.d.ts.map +1 -1
- package/dist/authorization/model/execution-viewer.js +26 -24
- package/dist/authorization/model/execution-viewer.js.map +1 -1
- package/dist/authorization/model/index.d.ts +4 -1
- package/dist/authorization/model/index.d.ts.map +1 -1
- package/dist/authorization/model/index.js +4 -1
- package/dist/authorization/model/index.js.map +1 -1
- package/dist/authorization/model/rewrite.d.ts +5 -3
- package/dist/authorization/model/rewrite.d.ts.map +1 -1
- package/dist/authorization/organization-directory.d.ts +44 -0
- package/dist/authorization/organization-directory.d.ts.map +1 -1
- package/dist/authorization/organization-directory.js +1 -0
- package/dist/authorization/organization-directory.js.map +1 -1
- package/dist/authorization/person.d.ts +14 -1
- package/dist/authorization/person.d.ts.map +1 -1
- package/dist/authorization/person.js +16 -0
- package/dist/authorization/person.js.map +1 -1
- package/dist/authorization/policy-check.d.ts +52 -0
- package/dist/authorization/policy-check.d.ts.map +1 -0
- package/dist/authorization/policy-check.js +35 -0
- package/dist/authorization/policy-check.js.map +1 -0
- package/dist/authorization/posture.d.ts +30 -4
- package/dist/authorization/posture.d.ts.map +1 -1
- package/dist/authorization/posture.js +58 -0
- package/dist/authorization/posture.js.map +1 -1
- package/dist/authorization/resource-creators.d.ts +4 -0
- package/dist/authorization/resource-creators.d.ts.map +1 -0
- package/dist/authorization/resource-creators.js +44 -0
- package/dist/authorization/resource-creators.js.map +1 -0
- package/dist/authorization/trusted-local-authorizer.d.ts +9 -0
- package/dist/authorization/trusted-local-authorizer.d.ts.map +1 -0
- package/dist/authorization/trusted-local-authorizer.js +70 -0
- package/dist/authorization/trusted-local-authorizer.js.map +1 -0
- package/dist/authorization/tuples.d.ts +12 -0
- package/dist/authorization/tuples.d.ts.map +1 -1
- package/dist/authorization/tuples.js +3 -0
- package/dist/authorization/tuples.js.map +1 -1
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +133 -43
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/config.d.ts +22 -7
- package/dist/boot/config.d.ts.map +1 -1
- package/dist/boot/config.js +2 -1
- package/dist/boot/config.js.map +1 -1
- package/dist/boot/inprocess.d.ts.map +1 -1
- package/dist/boot/inprocess.js +10 -4
- package/dist/boot/inprocess.js.map +1 -1
- package/dist/boot/list-indexes.d.ts.map +1 -1
- package/dist/boot/list-indexes.js +6 -1
- package/dist/boot/list-indexes.js.map +1 -1
- package/dist/boot/logger.d.ts +3 -1
- package/dist/boot/logger.d.ts.map +1 -1
- package/dist/boot/logger.js +3 -1
- package/dist/boot/logger.js.map +1 -1
- package/dist/boot/oauth-redirect-uri.d.ts +33 -12
- package/dist/boot/oauth-redirect-uri.d.ts.map +1 -1
- package/dist/boot/oauth-redirect-uri.js +43 -14
- package/dist/boot/oauth-redirect-uri.js.map +1 -1
- package/dist/boot/skill-transfer-origin.d.ts +46 -14
- package/dist/boot/skill-transfer-origin.d.ts.map +1 -1
- package/dist/boot/skill-transfer-origin.js +53 -13
- package/dist/boot/skill-transfer-origin.js.map +1 -1
- package/dist/domain/agentchannel/steps.d.ts +8 -6
- package/dist/domain/agentchannel/steps.d.ts.map +1 -1
- package/dist/domain/agentchannel/steps.js +9 -7
- package/dist/domain/agentchannel/steps.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts +7 -0
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +1 -1
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentexecution/create-steps.d.ts +26 -12
- package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
- package/dist/domain/agentexecution/create-steps.js +61 -43
- package/dist/domain/agentexecution/create-steps.js.map +1 -1
- package/dist/domain/agentexecution/submit-approval.d.ts.map +1 -1
- package/dist/domain/agentexecution/submit-approval.js +9 -6
- package/dist/domain/agentexecution/submit-approval.js.map +1 -1
- package/dist/domain/agentexecution/submit-file-decision.d.ts.map +1 -1
- package/dist/domain/agentexecution/submit-file-decision.js +5 -4
- package/dist/domain/agentexecution/submit-file-decision.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +5 -3
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +6 -4
- package/dist/domain/agentshare/steps.js.map +1 -1
- package/dist/domain/apikey/verifier.d.ts +7 -0
- package/dist/domain/apikey/verifier.d.ts.map +1 -1
- package/dist/domain/apikey/verifier.js +34 -1
- package/dist/domain/apikey/verifier.js.map +1 -1
- package/dist/domain/channelapp/controller.d.ts +9 -4
- package/dist/domain/channelapp/controller.d.ts.map +1 -1
- package/dist/domain/channelapp/controller.js +19 -9
- package/dist/domain/channelapp/controller.js.map +1 -1
- package/dist/domain/executioncontext/steps.d.ts +2 -1
- package/dist/domain/executioncontext/steps.d.ts.map +1 -1
- package/dist/domain/executioncontext/steps.js +2 -1
- package/dist/domain/executioncontext/steps.js.map +1 -1
- package/dist/domain/iampolicy/access-lists.d.ts.map +1 -1
- package/dist/domain/iampolicy/access-lists.js +57 -2
- package/dist/domain/iampolicy/access-lists.js.map +1 -1
- package/dist/domain/iampolicy/change.d.ts +53 -0
- package/dist/domain/iampolicy/change.d.ts.map +1 -0
- package/dist/domain/iampolicy/change.js +44 -0
- package/dist/domain/iampolicy/change.js.map +1 -0
- package/dist/domain/iampolicy/constants.d.ts +6 -0
- package/dist/domain/iampolicy/constants.d.ts.map +1 -1
- package/dist/domain/iampolicy/constants.js +6 -0
- package/dist/domain/iampolicy/constants.js.map +1 -1
- package/dist/domain/iampolicy/controller.d.ts.map +1 -1
- package/dist/domain/iampolicy/controller.js +9 -5
- package/dist/domain/iampolicy/controller.js.map +1 -1
- package/dist/domain/iampolicy/grant-path.d.ts +31 -13
- package/dist/domain/iampolicy/grant-path.d.ts.map +1 -1
- package/dist/domain/iampolicy/grant-path.js +216 -19
- package/dist/domain/iampolicy/grant-path.js.map +1 -1
- package/dist/domain/iampolicy/membership.d.ts +11 -3
- package/dist/domain/iampolicy/membership.d.ts.map +1 -1
- package/dist/domain/iampolicy/membership.js +18 -13
- package/dist/domain/iampolicy/membership.js.map +1 -1
- package/dist/domain/iampolicy/resource-store.d.ts.map +1 -1
- package/dist/domain/iampolicy/resource-store.js +4 -0
- package/dist/domain/iampolicy/resource-store.js.map +1 -1
- package/dist/domain/iampolicy/role-lifecycle.d.ts.map +1 -1
- package/dist/domain/iampolicy/role-lifecycle.js +2 -2
- package/dist/domain/iampolicy/role-lifecycle.js.map +1 -1
- package/dist/domain/iampolicy/roles.d.ts.map +1 -1
- package/dist/domain/iampolicy/roles.js +7 -0
- package/dist/domain/iampolicy/roles.js.map +1 -1
- package/dist/domain/iampolicy/steps.d.ts +4 -3
- package/dist/domain/iampolicy/steps.d.ts.map +1 -1
- package/dist/domain/iampolicy/steps.js +7 -7
- package/dist/domain/iampolicy/steps.js.map +1 -1
- package/dist/domain/iampolicy/store-contract.d.ts.map +1 -1
- package/dist/domain/iampolicy/store-contract.js +22 -1
- package/dist/domain/iampolicy/store-contract.js.map +1 -1
- package/dist/domain/iampolicy/store.d.ts +18 -5
- package/dist/domain/iampolicy/store.d.ts.map +1 -1
- package/dist/domain/iampolicy/store.js.map +1 -1
- package/dist/domain/identityaccount/constants.d.ts +15 -0
- package/dist/domain/identityaccount/constants.d.ts.map +1 -1
- package/dist/domain/identityaccount/constants.js +17 -0
- package/dist/domain/identityaccount/constants.js.map +1 -1
- package/dist/domain/identityaccount/controller.d.ts.map +1 -1
- package/dist/domain/identityaccount/controller.js +17 -6
- package/dist/domain/identityaccount/controller.js.map +1 -1
- package/dist/domain/identityaccount/resolve.d.ts +47 -0
- package/dist/domain/identityaccount/resolve.d.ts.map +1 -1
- package/dist/domain/identityaccount/resolve.js +38 -1
- package/dist/domain/identityaccount/resolve.js.map +1 -1
- package/dist/domain/identityaccount/resource-store.d.ts.map +1 -1
- package/dist/domain/identityaccount/resource-store.js +11 -1
- package/dist/domain/identityaccount/resource-store.js.map +1 -1
- package/dist/domain/identityaccount/steps.d.ts +2 -1
- package/dist/domain/identityaccount/steps.d.ts.map +1 -1
- package/dist/domain/identityaccount/steps.js +4 -3
- package/dist/domain/identityaccount/steps.js.map +1 -1
- package/dist/domain/identityaccount/store-contract.js +2 -2
- package/dist/domain/identityaccount/store-contract.js.map +1 -1
- package/dist/domain/identityaccount/store.d.ts +6 -1
- package/dist/domain/identityaccount/store.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect-sandbox.d.ts +67 -0
- package/dist/domain/mcpserver/connect-sandbox.d.ts.map +1 -0
- package/dist/domain/mcpserver/connect-sandbox.js +64 -0
- package/dist/domain/mcpserver/connect-sandbox.js.map +1 -0
- package/dist/domain/mcpserver/connect.d.ts +42 -10
- package/dist/domain/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +147 -40
- package/dist/domain/mcpserver/connect.js.map +1 -1
- package/dist/domain/mcpserver/controller.js +4 -2
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/mcpserver/engine.d.ts +26 -7
- package/dist/domain/mcpserver/engine.d.ts.map +1 -1
- package/dist/domain/mcpserver/engine.js.map +1 -1
- package/dist/domain/mcpserver/start-connect.d.ts +5 -0
- package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/start-connect.js +38 -15
- package/dist/domain/mcpserver/start-connect.js.map +1 -1
- package/dist/domain/memory/controller.js +2 -1
- package/dist/domain/memory/controller.js.map +1 -1
- package/dist/domain/memory/list-index.d.ts +2 -0
- package/dist/domain/memory/list-index.d.ts.map +1 -0
- package/dist/domain/memory/list-index.js +31 -0
- package/dist/domain/memory/list-index.js.map +1 -0
- package/dist/domain/memory/queries.d.ts +10 -0
- package/dist/domain/memory/queries.d.ts.map +1 -0
- package/dist/domain/memory/queries.js +54 -0
- package/dist/domain/memory/queries.js.map +1 -0
- package/dist/domain/memory/steps.d.ts +13 -11
- package/dist/domain/memory/steps.d.ts.map +1 -1
- package/dist/domain/memory/steps.js +26 -57
- package/dist/domain/memory/steps.js.map +1 -1
- package/dist/domain/organization/steps.d.ts.map +1 -1
- package/dist/domain/organization/steps.js +1 -1
- package/dist/domain/organization/steps.js.map +1 -1
- package/dist/domain/platformclient/mint.d.ts.map +1 -1
- package/dist/domain/platformclient/mint.js +2 -2
- package/dist/domain/platformclient/mint.js.map +1 -1
- package/dist/domain/platformclient/verifier.d.ts.map +1 -1
- package/dist/domain/platformclient/verifier.js +6 -3
- package/dist/domain/platformclient/verifier.js.map +1 -1
- package/dist/domain/plugin/push.d.ts.map +1 -1
- package/dist/domain/plugin/push.js +1 -0
- package/dist/domain/plugin/push.js.map +1 -1
- package/dist/domain/schedule/steps.d.ts +3 -1
- package/dist/domain/schedule/steps.d.ts.map +1 -1
- package/dist/domain/schedule/steps.js +3 -1
- package/dist/domain/schedule/steps.js.map +1 -1
- package/dist/domain/skill/push.d.ts.map +1 -1
- package/dist/domain/skill/push.js +1 -0
- package/dist/domain/skill/push.js.map +1 -1
- package/dist/domain/workflow/registry/data/task-kind-registry.json +27 -1
- package/dist/domain/workflowexecution/submit-approval.d.ts +5 -2
- package/dist/domain/workflowexecution/submit-approval.d.ts.map +1 -1
- package/dist/domain/workflowexecution/submit-approval.js +1 -1
- package/dist/domain/workflowexecution/submit-approval.js.map +1 -1
- package/dist/domain/workflowexecution/submit-file-decision.d.ts +5 -2
- package/dist/domain/workflowexecution/submit-file-decision.d.ts.map +1 -1
- package/dist/domain/workflowexecution/submit-file-decision.js +1 -1
- package/dist/domain/workflowexecution/submit-file-decision.js.map +1 -1
- package/dist/domain/workflowexecution/submit-workflow-task-approval.d.ts.map +1 -1
- package/dist/domain/workflowexecution/submit-workflow-task-approval.js +12 -1
- package/dist/domain/workflowexecution/submit-workflow-task-approval.js.map +1 -1
- package/dist/domain/workflowinstance/controller.d.ts +6 -3
- package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
- package/dist/domain/workflowinstance/controller.js +12 -7
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/domain/workflowinstance/steps.d.ts +31 -0
- package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
- package/dist/domain/workflowinstance/steps.js +88 -1
- package/dist/domain/workflowinstance/steps.js.map +1 -1
- package/dist/extensions/composed-services.d.ts +56 -0
- package/dist/extensions/composed-services.d.ts.map +1 -0
- package/dist/extensions/composed-services.js +2 -0
- package/dist/extensions/composed-services.js.map +1 -0
- package/dist/extensions/drivers.d.ts +32 -1
- package/dist/extensions/drivers.d.ts.map +1 -1
- package/dist/extensions/identity.d.ts +4 -1
- package/dist/extensions/identity.d.ts.map +1 -1
- package/dist/extensions/identity.js +4 -1
- package/dist/extensions/identity.js.map +1 -1
- package/dist/extensions/registry.d.ts +37 -0
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/extensions/registry.js +50 -0
- package/dist/extensions/registry.js.map +1 -1
- package/dist/extensions/resource-authorization.d.ts +78 -0
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/extensions/resource-row-reader.d.ts +43 -0
- package/dist/extensions/resource-row-reader.d.ts.map +1 -0
- package/dist/extensions/resource-row-reader.js +2 -0
- package/dist/extensions/resource-row-reader.js.map +1 -0
- package/dist/extensions/visitor-classifier.d.ts +41 -0
- package/dist/extensions/visitor-classifier.d.ts.map +1 -0
- package/dist/extensions/visitor-classifier.js +2 -0
- package/dist/extensions/visitor-classifier.js.map +1 -0
- package/dist/identity/oidc-userinfo.d.ts +6 -1
- package/dist/identity/oidc-userinfo.d.ts.map +1 -1
- package/dist/identity/oidc-userinfo.js.map +1 -1
- package/dist/identity/oidc-verifier.d.ts.map +1 -1
- package/dist/identity/oidc-verifier.js +37 -8
- package/dist/identity/oidc-verifier.js.map +1 -1
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -9
- package/dist/index.js.map +1 -1
- package/dist/pipeline/errors.d.ts +8 -0
- package/dist/pipeline/errors.d.ts.map +1 -1
- package/dist/pipeline/errors.js +25 -16
- package/dist/pipeline/errors.js.map +1 -1
- package/dist/pipeline/interceptors/auth.d.ts +17 -9
- package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
- package/dist/pipeline/interceptors/auth.js +17 -9
- package/dist/pipeline/interceptors/auth.js.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts +23 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.js +42 -0
- package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
- package/dist/pipeline/steps/authorize.d.ts +6 -5
- package/dist/pipeline/steps/authorize.d.ts.map +1 -1
- package/dist/pipeline/steps/authorize.js +6 -5
- package/dist/pipeline/steps/authorize.js.map +1 -1
- package/dist/pipeline/steps/defaults.d.ts +12 -0
- package/dist/pipeline/steps/defaults.d.ts.map +1 -1
- package/dist/pipeline/steps/defaults.js +42 -7
- package/dist/pipeline/steps/defaults.js.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.d.ts +13 -15
- package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.js +2 -3
- package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
- package/dist/runnerauth/built-in-runner-credential-provider.d.ts +0 -2
- package/dist/runnerauth/built-in-runner-credential-provider.d.ts.map +1 -1
- package/dist/runnerauth/built-in-runner-credential-provider.js +8 -17
- package/dist/runnerauth/built-in-runner-credential-provider.js.map +1 -1
- package/dist/runnerauth/runner-credential-provider.d.ts +17 -7
- package/dist/runnerauth/runner-credential-provider.d.ts.map +1 -1
- package/dist/runnerauth/runner-credential-provider.js.map +1 -1
- package/dist/sandbox/docker.d.ts.map +1 -1
- package/dist/sandbox/docker.js +3 -0
- package/dist/sandbox/docker.js.map +1 -1
- package/dist/sandbox/kubernetes.d.ts.map +1 -1
- package/dist/sandbox/kubernetes.js +3 -0
- package/dist/sandbox/kubernetes.js.map +1 -1
- package/dist/sandbox/local-process.d.ts.map +1 -1
- package/dist/sandbox/local-process.js +4 -0
- package/dist/sandbox/local-process.js.map +1 -1
- package/dist/sandbox/provisioner.d.ts +18 -6
- package/dist/sandbox/provisioner.d.ts.map +1 -1
- package/dist/sandbox/provisioner.js.map +1 -1
- package/dist/temporal/manager.d.ts +5 -0
- package/dist/temporal/manager.d.ts.map +1 -1
- package/dist/temporal/manager.js +9 -0
- package/dist/temporal/manager.js.map +1 -1
- package/dist/temporal/mcpserver/engine-client.d.ts +2 -2
- package/dist/temporal/mcpserver/engine-client.d.ts.map +1 -1
- package/dist/temporal/mcpserver/engine-client.js +6 -4
- package/dist/temporal/mcpserver/engine-client.js.map +1 -1
- package/dist/temporal/mcpserver/names.d.ts +13 -2
- package/dist/temporal/mcpserver/names.d.ts.map +1 -1
- package/dist/temporal/mcpserver/names.js +15 -2
- package/dist/temporal/mcpserver/names.js.map +1 -1
- package/dist/temporal/sdk-logger.d.ts +74 -0
- package/dist/temporal/sdk-logger.d.ts.map +1 -0
- package/dist/temporal/sdk-logger.js +143 -0
- package/dist/temporal/sdk-logger.js.map +1 -0
- package/package.json +6 -6
- package/src/authorization/README.md +18 -6
- package/src/authorization/__tests__/authorizer.test.ts +5 -1
- package/src/authorization/__tests__/derived-tuples.test.ts +26 -0
- package/src/authorization/__tests__/evaluator.test.ts +4 -0
- package/src/authorization/__tests__/list-read-scope.test.ts +11 -5
- package/src/authorization/__tests__/store-tests.test.ts +3 -1
- package/src/authorization/__tests__/trusted-local-authorizer.test.ts +155 -0
- package/src/authorization/__tests__/unit-owned-kinds.test.ts +420 -0
- package/src/authorization/__tests__/wire-permissions.test.ts +31 -2
- package/src/authorization/authorizer.ts +21 -10
- package/src/authorization/derived-tuples.ts +92 -18
- package/src/authorization/evaluator.ts +30 -15
- package/src/authorization/list-read-scope.ts +4 -0
- package/src/authorization/model/__tests__/registry.test.ts +23 -0
- package/src/authorization/model/data/authorization-model.json +830 -67
- package/src/authorization/model/execution-viewer.ts +32 -27
- package/src/authorization/model/index.ts +4 -1
- package/src/authorization/model/rewrite.ts +5 -3
- package/src/authorization/organization-directory.ts +4 -0
- package/src/authorization/person.ts +32 -1
- package/src/authorization/policy-check.ts +105 -0
- package/src/authorization/posture.ts +45 -4
- package/src/authorization/resource-creators.ts +48 -0
- package/src/authorization/trusted-local-authorizer.ts +91 -0
- package/src/authorization/tuples.ts +17 -0
- package/src/boot/__tests__/compose.test.ts +120 -4
- package/src/boot/__tests__/list-indexes.test.ts +4 -0
- package/src/boot/__tests__/oauth-redirect-uri.test.ts +121 -10
- package/src/boot/__tests__/skill-transfer-origin.test.ts +96 -25
- package/src/boot/compose.ts +154 -61
- package/src/boot/config.ts +28 -12
- package/src/boot/inprocess.ts +18 -4
- package/src/boot/list-indexes.ts +6 -1
- package/src/boot/logger.ts +3 -1
- package/src/boot/oauth-redirect-uri.ts +62 -17
- package/src/boot/skill-transfer-origin.ts +71 -16
- package/src/domain/agent/__tests__/agent.test.ts +42 -1
- package/src/domain/agentchannel/__tests__/agentchannel.test.ts +9 -0
- package/src/domain/agentchannel/__tests__/channel-runtime.test.ts +2 -0
- package/src/domain/agentchannel/__tests__/create-authorization.test.ts +7 -6
- package/src/domain/agentchannel/steps.ts +9 -7
- package/src/domain/agentexecution/__tests__/agentexecution.test.ts +148 -56
- package/src/domain/agentexecution/__tests__/create-steps.test.ts +175 -12
- package/src/domain/agentexecution/__tests__/file-review-seed.ts +91 -0
- package/src/domain/agentexecution/controller.ts +8 -0
- package/src/domain/agentexecution/create-steps.ts +74 -44
- package/src/domain/agentexecution/submit-approval.ts +9 -6
- package/src/domain/agentexecution/submit-file-decision.ts +5 -4
- package/src/domain/agentinstance/__tests__/agentinstance.test.ts +2 -0
- package/src/domain/agentshare/__tests__/agentshare.test.ts +17 -0
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +5 -4
- package/src/domain/agentshare/steps.ts +6 -4
- package/src/domain/apikey/__tests__/verifier.test.ts +73 -1
- package/src/domain/apikey/verifier.ts +45 -1
- package/src/domain/artifact/__tests__/artifact.test.ts +13 -24
- package/src/domain/channelapp/__tests__/channelapp.test.ts +7 -0
- package/src/domain/channelapp/controller.ts +35 -12
- package/src/domain/environment/__tests__/environment.test.ts +13 -0
- package/src/domain/executioncontext/__tests__/executioncontext.test.ts +2 -0
- package/src/domain/executioncontext/steps.ts +2 -1
- package/src/domain/iampolicy/__tests__/access-lists.test.ts +79 -0
- package/src/domain/iampolicy/__tests__/change.test.ts +63 -0
- package/src/domain/iampolicy/__tests__/controller.test.ts +39 -3
- package/src/domain/iampolicy/__tests__/grant-path.test.ts +595 -27
- package/src/domain/iampolicy/__tests__/iampolicy.test.ts +33 -2
- package/src/domain/iampolicy/__tests__/membership.test.ts +47 -5
- package/src/domain/iampolicy/__tests__/resource-store.test.ts +1 -0
- package/src/domain/iampolicy/__tests__/role-lifecycle.test.ts +41 -8
- package/src/domain/iampolicy/__tests__/roles.test.ts +3 -2
- package/src/domain/iampolicy/__tests__/steps.test.ts +75 -6
- package/src/domain/iampolicy/__tests__/support.ts +68 -4
- package/src/domain/iampolicy/access-lists.ts +70 -2
- package/src/domain/iampolicy/change.ts +109 -0
- package/src/domain/iampolicy/constants.ts +8 -0
- package/src/domain/iampolicy/controller.ts +17 -3
- package/src/domain/iampolicy/grant-path.ts +349 -31
- package/src/domain/iampolicy/membership.ts +32 -12
- package/src/domain/iampolicy/resource-store.ts +4 -0
- package/src/domain/iampolicy/role-lifecycle.ts +2 -0
- package/src/domain/iampolicy/roles.ts +8 -0
- package/src/domain/iampolicy/steps.ts +15 -5
- package/src/domain/iampolicy/store-contract.ts +37 -1
- package/src/domain/iampolicy/store.ts +19 -5
- package/src/domain/identityaccount/__tests__/resolve.test.ts +246 -2
- package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -1
- package/src/domain/identityaccount/constants.ts +20 -0
- package/src/domain/identityaccount/controller.ts +20 -5
- package/src/domain/identityaccount/resolve.ts +80 -1
- package/src/domain/identityaccount/resource-store.ts +14 -1
- package/src/domain/identityaccount/steps.ts +4 -3
- package/src/domain/identityaccount/store-contract.ts +4 -4
- package/src/domain/identityaccount/store.ts +6 -1
- package/src/domain/mcpserver/__tests__/connect-authorization.test.ts +1 -0
- package/src/domain/mcpserver/__tests__/connect.test.ts +358 -15
- package/src/domain/mcpserver/__tests__/mcpserver.test.ts +2 -0
- package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +2 -0
- package/src/domain/mcpserver/__tests__/store-faults.test.ts +2 -0
- package/src/domain/mcpserver/connect-sandbox.ts +135 -0
- package/src/domain/mcpserver/connect.ts +226 -56
- package/src/domain/mcpserver/controller.ts +8 -2
- package/src/domain/mcpserver/engine.ts +24 -6
- package/src/domain/mcpserver/start-connect.ts +49 -10
- package/src/domain/memory/__tests__/memory.test.ts +92 -22
- package/src/domain/memory/__tests__/queries.test.ts +173 -0
- package/src/domain/memory/controller.ts +2 -1
- package/src/domain/memory/list-index.ts +32 -0
- package/src/domain/memory/queries.ts +72 -0
- package/src/domain/memory/steps.ts +26 -63
- package/src/domain/oauthapp/__tests__/oauthapp.test.ts +14 -0
- package/src/domain/organization/__tests__/support.ts +41 -0
- package/src/domain/organization/steps.ts +1 -0
- package/src/domain/platformclient/mint.ts +6 -2
- package/src/domain/platformclient/verifier.ts +6 -3
- package/src/domain/plugin/__tests__/plugin.test.ts +11 -24
- package/src/domain/plugin/push.ts +1 -0
- package/src/domain/schedule/__tests__/schedule.composed.test.ts +2 -0
- package/src/domain/schedule/steps.ts +3 -1
- package/src/domain/session/__tests__/session.test.ts +2 -0
- package/src/domain/skill/__tests__/skill.test.ts +7 -25
- package/src/domain/skill/push.ts +1 -0
- package/src/domain/workflow/__tests__/workflow.test.ts +2 -0
- package/src/domain/workflow/registry/data/task-kind-registry.json +27 -1
- package/src/domain/workflowexecution/__tests__/forward-attribution-composed.test.ts +270 -0
- package/src/domain/workflowexecution/__tests__/submit-workflow-task-approval.test.ts +196 -0
- package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +3 -57
- package/src/domain/workflowexecution/submit-approval.ts +9 -2
- package/src/domain/workflowexecution/submit-file-decision.ts +6 -1
- package/src/domain/workflowexecution/submit-workflow-task-approval.ts +23 -5
- package/src/domain/workflowinstance/controller.ts +27 -9
- package/src/domain/workflowinstance/steps.ts +123 -1
- package/src/extensions/__tests__/apikey-before-sign-in-composed.test.ts +172 -0
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +80 -1
- package/src/extensions/__tests__/composed-services-composed.test.ts +236 -0
- package/src/extensions/__tests__/extension-composition.test.ts +229 -16
- package/src/extensions/__tests__/identity-account-composed.test.ts +84 -4
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +41 -1
- package/src/extensions/__tests__/registry.test.ts +147 -1
- package/src/extensions/__tests__/secret-cleanup-composed.test.ts +2 -0
- package/src/extensions/__tests__/visitor-classifier-points.test.ts +42 -0
- package/src/extensions/composed-services.ts +61 -0
- package/src/extensions/drivers.ts +33 -1
- package/src/extensions/identity.ts +4 -1
- package/src/extensions/registry.ts +105 -0
- package/src/extensions/resource-authorization.ts +87 -0
- package/src/extensions/resource-row-reader.ts +43 -0
- package/src/extensions/visitor-classifier.ts +41 -0
- package/src/identity/__tests__/oidc-verifier.test.ts +38 -12
- package/src/identity/oidc-userinfo.ts +6 -1
- package/src/identity/oidc-verifier.ts +42 -8
- package/src/index.ts +61 -6
- package/src/pipeline/__tests__/steps.test.ts +31 -4
- package/src/pipeline/errors.ts +30 -16
- package/src/pipeline/interceptors/auth.ts +17 -9
- package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +20 -0
- package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +72 -15
- package/src/pipeline/steps/authorization-tuples.ts +54 -0
- package/src/pipeline/steps/authorize.ts +6 -5
- package/src/pipeline/steps/defaults.ts +52 -7
- package/src/pipeline/steps/guard-memory-capture.ts +15 -20
- package/src/runnerauth/__tests__/built-in-runner-credential-provider.test.ts +1 -1
- package/src/runnerauth/__tests__/runner-subject-composed.test.ts +13 -0
- package/src/runnerauth/bound-execution.ts +2 -2
- package/src/runnerauth/built-in-runner-credential-provider.ts +8 -21
- package/src/runnerauth/runner-credential-provider.ts +17 -7
- package/src/sandbox/__tests__/docker.integration.test.ts +4 -0
- package/src/sandbox/__tests__/kubernetes.test.ts +18 -1
- package/src/sandbox/__tests__/local-process.integration.test.ts +4 -0
- package/src/sandbox/__tests__/provisioner.test.ts +1 -0
- package/src/sandbox/docker.ts +3 -0
- package/src/sandbox/kubernetes.ts +3 -0
- package/src/sandbox/local-process.ts +4 -0
- package/src/sandbox/provisioner.ts +18 -6
- package/src/store/postgres/__tests__/support.ts +11 -2
- package/src/temporal/README.md +1 -0
- package/src/temporal/__tests__/manager.test.ts +56 -4
- package/src/temporal/__tests__/sdk-log-workflows.ts +26 -0
- package/src/temporal/__tests__/sdk-logger.e2e.test.ts +150 -0
- package/src/temporal/__tests__/sdk-logger.test.ts +238 -0
- package/src/temporal/manager.ts +9 -0
- package/src/temporal/mcpserver/engine-client.ts +8 -3
- package/src/temporal/mcpserver/names.ts +16 -2
- package/src/temporal/sdk-logger.ts +173 -0
- package/dist/authorization/lane-admission.d.ts +0 -50
- package/dist/authorization/lane-admission.d.ts.map +0 -1
- package/dist/authorization/lane-admission.js +0 -13
- package/dist/authorization/lane-admission.js.map +0 -1
- package/src/authorization/__tests__/lane-admission.test.ts +0 -115
- package/src/authorization/lane-admission.ts +0 -73
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
* - DeriveAccountId (A1): `metadata.id = accountIdFor(spec.idp_id)`,
|
|
21
21
|
* replacing whatever the caller sent (the organization's CopySlugToId
|
|
22
22
|
* precedent, `metadata.proto`'s documented exception). Runs BEFORE
|
|
23
|
-
* BuildNewState
|
|
23
|
+
* BuildNewState and claims the id through `assignServerId`, the one
|
|
24
|
+
* way an id survives that step (stigmer/stigmer#1266).
|
|
24
25
|
* - CheckDuplicate: by SUBJECT, a primary-key read of the derived id —
|
|
25
26
|
* two accounts may share an email; the account's uniqueness is its
|
|
26
27
|
* subject, never its slug (the guideline's "domains with different
|
|
@@ -59,6 +60,7 @@ import {
|
|
|
59
60
|
} from "../../pipeline/errors.js";
|
|
60
61
|
import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
61
62
|
import type { RequestContext } from "../../pipeline/request-context.js";
|
|
63
|
+
import { assignServerId } from "../../pipeline/steps/defaults.js";
|
|
62
64
|
import { RESOURCE_ID_KEY } from "../../pipeline/steps/delete.js";
|
|
63
65
|
import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
|
|
64
66
|
import { TARGET_RESOURCE_KEY } from "../../pipeline/steps/load-target.js";
|
|
@@ -108,7 +110,6 @@ export function newDeriveAccountIdStep(): AccountStep {
|
|
|
108
110
|
return {
|
|
109
111
|
name: "DeriveAccountId",
|
|
110
112
|
execute(ctx: AccountContext): void {
|
|
111
|
-
const metadata = requireMetadata(ctx, "derive account id");
|
|
112
113
|
// ValidateProto ran upstream (idp_id is required), so an empty
|
|
113
114
|
// subject here is a pipeline-ordering bug, not bad client input.
|
|
114
115
|
const idpId = specOf(ctx).idpId;
|
|
@@ -118,7 +119,7 @@ export function newDeriveAccountIdStep(): AccountStep {
|
|
|
118
119
|
"derive account id",
|
|
119
120
|
);
|
|
120
121
|
}
|
|
121
|
-
|
|
122
|
+
assignServerId(ctx, accountIdFor(idpId));
|
|
122
123
|
},
|
|
123
124
|
};
|
|
124
125
|
}
|
|
@@ -360,7 +360,7 @@ const CASES: ReadonlyArray<PortContractDeclaration<IdentityAccountStore>> = [
|
|
|
360
360
|
},
|
|
361
361
|
],
|
|
362
362
|
[
|
|
363
|
-
"
|
|
363
|
+
"no subject lookup answers a federated account: its subject is its identity provider's",
|
|
364
364
|
async ({ store }) => {
|
|
365
365
|
await store.save(
|
|
366
366
|
federatedAccount({ idpId: "auth0|fed", email: "fed@example.com" }),
|
|
@@ -376,9 +376,9 @@ const CASES: ReadonlyArray<PortContractDeclaration<IdentityAccountStore>> = [
|
|
|
376
376
|
"the direct-email lookup must not resolve to a federated account",
|
|
377
377
|
);
|
|
378
378
|
assert.equal(
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
"the
|
|
379
|
+
await store.findByIdpId("auth0|fed"),
|
|
380
|
+
undefined,
|
|
381
|
+
"the subject lookup must not resolve to a federated account: a provider chooses its subjects, so one equal to a platform person's or a platform client user's would otherwise answer for them",
|
|
382
382
|
);
|
|
383
383
|
},
|
|
384
384
|
],
|
|
@@ -59,7 +59,12 @@ export interface IdentityAccountStore {
|
|
|
59
59
|
/** Removes the row; no error when it does not exist. */
|
|
60
60
|
deleteById(id: string): Promise<void>;
|
|
61
61
|
findById(id: string): Promise<IdentityAccount | undefined>;
|
|
62
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* The account under a subject in any mode but federated — the getByIdpId
|
|
64
|
+
* RPC's lookup and the platform-client mint's. A federated subject is its
|
|
65
|
+
* identity provider's to choose, so it is reached only through the
|
|
66
|
+
* federated natural key (provider and subject), never by a bare subject.
|
|
67
|
+
*/
|
|
63
68
|
findByIdpId(idpId: string): Promise<IdentityAccount | undefined>;
|
|
64
69
|
/** The platform's own subjects only (no federated, no platform-client) — the verifiers' and whoAmI's lookup. */
|
|
65
70
|
findDirectByIdpId(idpId: string): Promise<IdentityAccount | undefined>;
|
|
@@ -118,6 +118,7 @@ function deps(authorizer: Authorizer): McpServerConnectDeps {
|
|
|
118
118
|
pendingOAuthStates: store.pendingOAuthStates,
|
|
119
119
|
secretService: unreachable("secretService"),
|
|
120
120
|
oauthRedirectUri: "http://localhost:7233/oauth/callback",
|
|
121
|
+
sandboxLane: { enabled: false },
|
|
121
122
|
outboundFetch: async () => {
|
|
122
123
|
throw new Error("no outbound fetch in this harness");
|
|
123
124
|
},
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
* connect_status bookkeeping (attach skips CONNECTING; results and the
|
|
7
7
|
* terminal phase ride ONE atomic write; failure_code in CamelCase),
|
|
8
8
|
* tool-approval preserve-on-empty, the ephemeral EC lifecycle, and
|
|
9
|
-
* startConnect's two-layer idempotency + dead-runner warning
|
|
9
|
+
* startConnect's two-layer idempotency + dead-runner warning, and the
|
|
10
|
+
* connect route (connect-sandbox.ts, stigmer/stigmer#1474): the shared
|
|
11
|
+
* runner queue without a sandbox lane, and with one a connect sandbox
|
|
12
|
+
* per connect, acting as the person through an always-created
|
|
13
|
+
* ExecutionContext row and released exactly once on every exit.
|
|
10
14
|
*
|
|
11
15
|
* The wire-level halves are pinned by
|
|
12
16
|
* mcpserver-connect.conformance.test.ts on local-execution.
|
|
@@ -30,7 +34,19 @@ import { createLogger } from "../../../boot/logger.js";
|
|
|
30
34
|
import { SecretService } from "../../../encryption/encryption.js";
|
|
31
35
|
import type { CallerIdentity } from "../../../extensions/identity.js";
|
|
32
36
|
import { newExecutionScopedRunnerCredentialProvider } from "../../../runnerauth/runner-credential-provider.js";
|
|
33
|
-
import {
|
|
37
|
+
import type {
|
|
38
|
+
RunnerCredentialProvider,
|
|
39
|
+
SandboxCredentialRequest,
|
|
40
|
+
} from "../../../runnerauth/runner-credential-provider.js";
|
|
41
|
+
import {
|
|
42
|
+
RunnerAuthService,
|
|
43
|
+
TOKEN_TYPE_EXECUTION_SCOPED,
|
|
44
|
+
} from "../../../runnerauth/runnerauth.js";
|
|
45
|
+
import type { SandboxLane } from "../../../sandbox/lane.js";
|
|
46
|
+
import type {
|
|
47
|
+
SandboxEnvironment,
|
|
48
|
+
SandboxProvisioner,
|
|
49
|
+
} from "../../../sandbox/provisioner.js";
|
|
34
50
|
import { SqliteStore } from "../../../store/sqlite/store.js";
|
|
35
51
|
import { newPermissiveSingleTeamAuthorizer } from "../../../pipeline/steps/authorize.js";
|
|
36
52
|
import { testCallerIdentity } from "../../../pipeline/__tests__/support.js";
|
|
@@ -48,8 +64,10 @@ import {
|
|
|
48
64
|
RUNNER_QUEUE_WARNING,
|
|
49
65
|
startConnect as startConnectRpc,
|
|
50
66
|
} from "../start-connect.js";
|
|
67
|
+
import { CONNECT_SANDBOX_PROVISIONING_FAILED } from "../connect-sandbox.js";
|
|
51
68
|
import type {
|
|
52
69
|
ConnectRunOutcome,
|
|
70
|
+
ConnectTaskQueue,
|
|
53
71
|
ConnectWorkflowInput,
|
|
54
72
|
ConnectWorkflowOutput,
|
|
55
73
|
McpServerConnectEngine,
|
|
@@ -82,35 +100,93 @@ interface FakeEngineOptions {
|
|
|
82
100
|
attached?: boolean;
|
|
83
101
|
running?: boolean;
|
|
84
102
|
pollers?: boolean | undefined;
|
|
103
|
+
/** The start itself fails (Temporal refused the start). */
|
|
104
|
+
startError?: Error;
|
|
105
|
+
/** Runs when a lane begins awaiting the run — the moment an attached lane must already hold nothing. */
|
|
106
|
+
onAwait?: () => void;
|
|
85
107
|
}
|
|
86
108
|
|
|
87
109
|
interface FakeEngine extends McpServerConnectEngine {
|
|
88
110
|
readonly startedInputs: ConnectWorkflowInput[];
|
|
89
111
|
readonly startedTimeouts: number[];
|
|
112
|
+
readonly startedQueues: ConnectTaskQueue[];
|
|
113
|
+
pollerProbes: number;
|
|
90
114
|
}
|
|
91
115
|
|
|
92
116
|
function fakeEngine(options: FakeEngineOptions = {}): FakeEngine {
|
|
93
117
|
const startedInputs: ConnectWorkflowInput[] = [];
|
|
94
118
|
const startedTimeouts: number[] = [];
|
|
95
|
-
|
|
119
|
+
const startedQueues: ConnectTaskQueue[] = [];
|
|
120
|
+
const engine: FakeEngine = {
|
|
96
121
|
startedInputs,
|
|
97
122
|
startedTimeouts,
|
|
98
|
-
|
|
123
|
+
startedQueues,
|
|
124
|
+
pollerProbes: 0,
|
|
125
|
+
async startOrAttachConnect(mcpServerId, input, runTimeoutMs, taskQueue) {
|
|
126
|
+
if (options.startError !== undefined) {
|
|
127
|
+
throw options.startError;
|
|
128
|
+
}
|
|
99
129
|
startedInputs.push(input);
|
|
100
130
|
startedTimeouts.push(runTimeoutMs);
|
|
131
|
+
startedQueues.push(taskQueue);
|
|
101
132
|
return {
|
|
102
133
|
workflowId: `stigmer/mcp-server/connect/${mcpServerId}`,
|
|
103
134
|
attached: options.attached ?? false,
|
|
104
|
-
result: async () =>
|
|
135
|
+
result: async () => {
|
|
136
|
+
options.onAwait?.();
|
|
137
|
+
return options.outcome ?? { ok: true, output: OK_OUTPUT };
|
|
138
|
+
},
|
|
105
139
|
};
|
|
106
140
|
},
|
|
107
141
|
async isConnectRunRunning() {
|
|
108
142
|
return options.running ?? false;
|
|
109
143
|
},
|
|
110
144
|
async hasRunnerQueuePollers() {
|
|
145
|
+
engine.pollerProbes += 1;
|
|
111
146
|
return options.pollers;
|
|
112
147
|
},
|
|
113
148
|
};
|
|
149
|
+
return engine;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** A connect-scope provisioner that records every call; the other scopes are unreachable here. */
|
|
153
|
+
interface FakeConnectProvisioner extends SandboxProvisioner {
|
|
154
|
+
readonly created: Array<{ id: string; env: SandboxEnvironment }>;
|
|
155
|
+
readonly deprovisioned: string[];
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function fakeConnectProvisioner(options: { createError?: Error } = {}): FakeConnectProvisioner {
|
|
159
|
+
const created: Array<{ id: string; env: SandboxEnvironment }> = [];
|
|
160
|
+
const deprovisioned: string[] = [];
|
|
161
|
+
const unreachable = async (): Promise<never> => {
|
|
162
|
+
throw new Error("only the connect scope is reachable from the connect lanes");
|
|
163
|
+
};
|
|
164
|
+
return {
|
|
165
|
+
created,
|
|
166
|
+
deprovisioned,
|
|
167
|
+
ensureSessionSandbox: unreachable,
|
|
168
|
+
deprovisionSessionSandbox: unreachable,
|
|
169
|
+
ensureWorkflowSandbox: unreachable,
|
|
170
|
+
deprovisionWorkflowSandbox: unreachable,
|
|
171
|
+
async createConnectSandbox(id, env) {
|
|
172
|
+
if (options.createError !== undefined) {
|
|
173
|
+
throw options.createError;
|
|
174
|
+
}
|
|
175
|
+
created.push({ id, env });
|
|
176
|
+
return `sbx-${id}`;
|
|
177
|
+
},
|
|
178
|
+
async deprovisionConnectSandbox(sandboxId) {
|
|
179
|
+
deprovisioned.push(sandboxId);
|
|
180
|
+
},
|
|
181
|
+
probe: unreachable,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
interface HarnessOptions extends FakeEngineOptions {
|
|
186
|
+
/** Compose a sandbox lane over this provisioner (absent: the external-runner posture). */
|
|
187
|
+
provisioner?: SandboxProvisioner;
|
|
188
|
+
/** The lane's credential provider (default: the harness's execution-scoped runnerAuth). */
|
|
189
|
+
credentials?: RunnerCredentialProvider;
|
|
114
190
|
}
|
|
115
191
|
|
|
116
192
|
interface Harness {
|
|
@@ -149,8 +225,19 @@ const startConnect = (
|
|
|
149
225
|
input: Parameters<typeof startConnectRpc>[1],
|
|
150
226
|
) => startConnectRpc(deps, input, testCaller);
|
|
151
227
|
|
|
152
|
-
function makeHarness(options:
|
|
228
|
+
function makeHarness(options: HarnessOptions = {}): Harness {
|
|
153
229
|
const engine = fakeEngine(options);
|
|
230
|
+
const runnerAuth = newExecutionScopedRunnerCredentialProvider(
|
|
231
|
+
RunnerAuthService.fromEnv(),
|
|
232
|
+
);
|
|
233
|
+
const sandboxLane: SandboxLane =
|
|
234
|
+
options.provisioner === undefined
|
|
235
|
+
? { enabled: false }
|
|
236
|
+
: {
|
|
237
|
+
enabled: true,
|
|
238
|
+
provisioner: options.provisioner,
|
|
239
|
+
credentials: options.credentials ?? runnerAuth,
|
|
240
|
+
};
|
|
154
241
|
const harness: Harness = {
|
|
155
242
|
engine,
|
|
156
243
|
ecCreates: 0,
|
|
@@ -182,9 +269,7 @@ function makeHarness(options: FakeEngineOptions = {}): Harness {
|
|
|
182
269
|
return create(ExecutionContextSchema);
|
|
183
270
|
},
|
|
184
271
|
},
|
|
185
|
-
runnerAuth
|
|
186
|
-
RunnerAuthService.fromEnv(),
|
|
187
|
-
),
|
|
272
|
+
runnerAuth,
|
|
188
273
|
// The REAL service over a client backed by nothing: the refresh
|
|
189
274
|
// pre-flight arms that need it are exercised in the handshake
|
|
190
275
|
// composed test; here every read throws, which the pre-flight
|
|
@@ -210,6 +295,7 @@ function makeHarness(options: FakeEngineOptions = {}): Harness {
|
|
|
210
295
|
pendingOAuthStates: store.pendingOAuthStates,
|
|
211
296
|
secretService: SecretService.create(undefined),
|
|
212
297
|
oauthRedirectUri: "http://127.0.0.1:8234/auth/oauth/callback",
|
|
298
|
+
sandboxLane,
|
|
213
299
|
// No arm in this harness dials out; a call is a test bug, not a network.
|
|
214
300
|
outboundFetch: async () => {
|
|
215
301
|
throw new Error("no outbound fetch in this harness");
|
|
@@ -346,6 +432,8 @@ describe("connect (blocking lane)", () => {
|
|
|
346
432
|
expect(result.status?.connectStatus?.failureCode).toBe("");
|
|
347
433
|
// The sync lane passes the 420s budget to the engine.
|
|
348
434
|
expect(harness.engine.startedTimeouts[0]).toBe(CONNECT_TIMEOUT.ms);
|
|
435
|
+
// No sandbox lane: the shared runner queue, as always.
|
|
436
|
+
expect(harness.engine.startedQueues).toEqual([{ kind: "runner" }]);
|
|
349
437
|
});
|
|
350
438
|
|
|
351
439
|
it("preserves existing tool approvals when a reconnect returns none (a degraded runner cannot disarm gates)", async () => {
|
|
@@ -613,21 +701,21 @@ describe("startBestEffortConnect (apply tail)", () => {
|
|
|
613
701
|
const engine = harness.engine;
|
|
614
702
|
harness.deps = { ...harness.deps, engineState: () => MCP_SERVER_ENGINE_DISCONNECTED };
|
|
615
703
|
const server = await seedServer();
|
|
616
|
-
await startBestEffortConnect(harness.deps, server);
|
|
704
|
+
await startBestEffortConnect(harness.deps, server, testCaller);
|
|
617
705
|
expect(engine.startedInputs).toHaveLength(0);
|
|
618
706
|
});
|
|
619
707
|
|
|
620
|
-
it("skips servers with env declarations (
|
|
708
|
+
it("skips servers with env declarations (their credentials are the connecting person's, not the applier's)", async () => {
|
|
621
709
|
const harness = makeHarness();
|
|
622
710
|
const server = await seedServer({ env: true });
|
|
623
|
-
await startBestEffortConnect(harness.deps, server);
|
|
711
|
+
await startBestEffortConnect(harness.deps, server, testCaller);
|
|
624
712
|
expect(harness.engine.startedInputs).toHaveLength(0);
|
|
625
713
|
});
|
|
626
714
|
|
|
627
715
|
it("connects an env-less server and persists the result", async () => {
|
|
628
716
|
const harness = makeHarness();
|
|
629
717
|
const server = await seedServer();
|
|
630
|
-
await startBestEffortConnect(harness.deps, server);
|
|
718
|
+
await startBestEffortConnect(harness.deps, server, testCaller);
|
|
631
719
|
const after = await store.getResource(
|
|
632
720
|
ApiResourceKind.mcp_server,
|
|
633
721
|
server.metadata!.id,
|
|
@@ -642,7 +730,7 @@ describe("startBestEffortConnect (apply tail)", () => {
|
|
|
642
730
|
const server = await seedServer();
|
|
643
731
|
await store.deleteResource(ApiResourceKind.mcp_server, server.metadata!.id);
|
|
644
732
|
await expect(
|
|
645
|
-
startBestEffortConnect(harness.deps, server),
|
|
733
|
+
startBestEffortConnect(harness.deps, server, testCaller),
|
|
646
734
|
).resolves.toBeUndefined();
|
|
647
735
|
});
|
|
648
736
|
|
|
@@ -657,7 +745,7 @@ describe("startBestEffortConnect (apply tail)", () => {
|
|
|
657
745
|
},
|
|
658
746
|
});
|
|
659
747
|
const server = await seedServer({ stdio: false });
|
|
660
|
-
await startBestEffortConnect(harness.deps, server);
|
|
748
|
+
await startBestEffortConnect(harness.deps, server, testCaller);
|
|
661
749
|
const after = await store.getResource(
|
|
662
750
|
ApiResourceKind.mcp_server,
|
|
663
751
|
server.metadata!.id,
|
|
@@ -673,3 +761,258 @@ describe("startBestEffortConnect (apply tail)", () => {
|
|
|
673
761
|
);
|
|
674
762
|
});
|
|
675
763
|
});
|
|
764
|
+
|
|
765
|
+
describe("the connect route with a sandbox lane composed (stigmer/stigmer#1474)", () => {
|
|
766
|
+
/** The connect id every lane derives the sandbox, its queue and its credential from. */
|
|
767
|
+
function connectIdOf(harness: Harness): string {
|
|
768
|
+
const created = harness.engine.startedQueues[0];
|
|
769
|
+
expect(created?.kind).toBe("sandbox");
|
|
770
|
+
const name = created?.kind === "sandbox" ? created.name : "";
|
|
771
|
+
expect(name).toMatch(/^mcpconnect:connect-mcps_test_/);
|
|
772
|
+
return name.slice("mcpconnect:".length);
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
it("blocking connect of an env-less server: a binding-only row as the person, a sandbox on the connect's own queue, released once", async () => {
|
|
776
|
+
const provisioner = fakeConnectProvisioner();
|
|
777
|
+
const harness = makeHarness({ provisioner });
|
|
778
|
+
const server = await seedServer();
|
|
779
|
+
|
|
780
|
+
const result = await connect(harness.deps, connectInput(server.metadata!.id));
|
|
781
|
+
expect(result.status?.connectStatus?.phase).toBe(ConnectPhase.succeeded);
|
|
782
|
+
|
|
783
|
+
const connectId = connectIdOf(harness);
|
|
784
|
+
expect(isConnectExecutionId(connectId)).toBe(true);
|
|
785
|
+
// The row the sandbox credential binds through exists, created AS the
|
|
786
|
+
// person, even though the server declares no env.
|
|
787
|
+
expect(harness.ecCreators).toEqual([testCaller]);
|
|
788
|
+
// It is binding-only: the runner is handed no context to read and no
|
|
789
|
+
// payload token, the same no-env discovery path as without a lane.
|
|
790
|
+
expect(harness.engine.startedInputs[0]).toEqual({
|
|
791
|
+
mcp_server_id: server.metadata!.id,
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
expect(provisioner.created).toHaveLength(1);
|
|
795
|
+
const sandbox = provisioner.created[0]!;
|
|
796
|
+
expect(sandbox.id).toBe(connectId);
|
|
797
|
+
expect(sandbox.env.taskQueue).toBe(`mcpconnect:${connectId}`);
|
|
798
|
+
expect(sandbox.env.callerClass).toBe(testCaller.callerClass);
|
|
799
|
+
// The OSS execution-scoped mint, bound to this one connect.
|
|
800
|
+
expect(
|
|
801
|
+
harness.deps.runnerAuth.verify(
|
|
802
|
+
TOKEN_TYPE_EXECUTION_SCOPED,
|
|
803
|
+
sandbox.env.stigmerToken,
|
|
804
|
+
),
|
|
805
|
+
).toBe(connectId);
|
|
806
|
+
|
|
807
|
+
expect(provisioner.deprovisioned).toEqual([`sbx-${connectId}`]);
|
|
808
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
it("blocking connect with runtime_env: the row carries the values and the payload names it, and the sandbox is released once", async () => {
|
|
812
|
+
const provisioner = fakeConnectProvisioner();
|
|
813
|
+
const harness = makeHarness({ provisioner });
|
|
814
|
+
const server = await seedServer();
|
|
815
|
+
await connect(
|
|
816
|
+
harness.deps,
|
|
817
|
+
connectInput(server.metadata!.id, { API_KEY: { value: "k", isSecret: true } }),
|
|
818
|
+
);
|
|
819
|
+
const connectId = connectIdOf(harness);
|
|
820
|
+
const input = harness.engine.startedInputs[0];
|
|
821
|
+
expect(input?.execution_context_id).toBe(connectId);
|
|
822
|
+
expect(input?.execution_context_token).toBeTruthy();
|
|
823
|
+
expect(provisioner.deprovisioned).toEqual([`sbx-${connectId}`]);
|
|
824
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
825
|
+
});
|
|
826
|
+
|
|
827
|
+
it("hands a composed mintSandboxCredential the connect scope, the person and the org", async () => {
|
|
828
|
+
const provisioner = fakeConnectProvisioner();
|
|
829
|
+
const base = newExecutionScopedRunnerCredentialProvider(RunnerAuthService.fromEnv());
|
|
830
|
+
const requests: SandboxCredentialRequest[] = [];
|
|
831
|
+
const credentials: RunnerCredentialProvider = {
|
|
832
|
+
...base,
|
|
833
|
+
isEnabled: (lane) => base.isEnabled(lane),
|
|
834
|
+
mint: (lane, binding, ttl) => base.mint(lane, binding, ttl),
|
|
835
|
+
verify: (lane, token) => base.verify(lane, token),
|
|
836
|
+
mintSandboxCredential(request) {
|
|
837
|
+
requests.push(request);
|
|
838
|
+
return "edition-connect-token";
|
|
839
|
+
},
|
|
840
|
+
};
|
|
841
|
+
const harness = makeHarness({ provisioner, credentials });
|
|
842
|
+
const server = await seedServer();
|
|
843
|
+
await connect(harness.deps, connectInput(server.metadata!.id));
|
|
844
|
+
const connectId = connectIdOf(harness);
|
|
845
|
+
expect(requests).toEqual([
|
|
846
|
+
{
|
|
847
|
+
scope: "connect",
|
|
848
|
+
sessionId: "",
|
|
849
|
+
executionId: connectId,
|
|
850
|
+
org: "acme",
|
|
851
|
+
callerIdentityId: testCaller.identityId,
|
|
852
|
+
},
|
|
853
|
+
]);
|
|
854
|
+
expect(provisioner.created[0]?.env.stigmerToken).toBe("edition-connect-token");
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
it("releases the sandbox once when the run fails", async () => {
|
|
858
|
+
const provisioner = fakeConnectProvisioner();
|
|
859
|
+
const harness = makeHarness({
|
|
860
|
+
provisioner,
|
|
861
|
+
outcome: { ok: false, failure: { kind: "application", message: "401" } },
|
|
862
|
+
});
|
|
863
|
+
const server = await seedServer({ stdio: false });
|
|
864
|
+
await expectConnectError(
|
|
865
|
+
connect(harness.deps, connectInput(server.metadata!.id)),
|
|
866
|
+
Code.FailedPrecondition,
|
|
867
|
+
"401",
|
|
868
|
+
);
|
|
869
|
+
expect(provisioner.deprovisioned).toHaveLength(1);
|
|
870
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
871
|
+
});
|
|
872
|
+
|
|
873
|
+
it("gives its own sandbox back before awaiting another lane's run it attached to", async () => {
|
|
874
|
+
const provisioner = fakeConnectProvisioner();
|
|
875
|
+
const heldWhileAwaiting: number[] = [];
|
|
876
|
+
const harness = makeHarness({
|
|
877
|
+
provisioner,
|
|
878
|
+
attached: true,
|
|
879
|
+
onAwait: () =>
|
|
880
|
+
heldWhileAwaiting.push(provisioner.created.length - provisioner.deprovisioned.length),
|
|
881
|
+
});
|
|
882
|
+
const server = await seedServer();
|
|
883
|
+
await connect(harness.deps, connectInput(server.metadata!.id));
|
|
884
|
+
// Nothing idles for the other lane's whole run...
|
|
885
|
+
expect(heldWhileAwaiting).toEqual([0]);
|
|
886
|
+
// ...and the release stays exactly once.
|
|
887
|
+
expect(provisioner.deprovisioned).toHaveLength(1);
|
|
888
|
+
});
|
|
889
|
+
|
|
890
|
+
it("releases the sandbox once when the start itself fails", async () => {
|
|
891
|
+
const provisioner = fakeConnectProvisioner();
|
|
892
|
+
const harness = makeHarness({ provisioner, startError: new Error("frontend down") });
|
|
893
|
+
const server = await seedServer();
|
|
894
|
+
await expectConnectError(
|
|
895
|
+
connect(harness.deps, connectInput(server.metadata!.id)),
|
|
896
|
+
Code.Internal,
|
|
897
|
+
"failed to start connect workflow",
|
|
898
|
+
);
|
|
899
|
+
expect(provisioner.deprovisioned).toHaveLength(1);
|
|
900
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
it("fails fast with Unavailable, recorded on connect_status, when the sandbox cannot be provisioned", async () => {
|
|
904
|
+
const provisioner = fakeConnectProvisioner({ createError: new Error("quota exceeded") });
|
|
905
|
+
const harness = makeHarness({ provisioner });
|
|
906
|
+
const server = await seedServer();
|
|
907
|
+
await expectConnectError(
|
|
908
|
+
connect(harness.deps, connectInput(server.metadata!.id)),
|
|
909
|
+
Code.Unavailable,
|
|
910
|
+
CONNECT_SANDBOX_PROVISIONING_FAILED,
|
|
911
|
+
);
|
|
912
|
+
// No run was started, so nothing waits on a queue nobody serves.
|
|
913
|
+
expect(harness.engine.startedInputs).toHaveLength(0);
|
|
914
|
+
expect(provisioner.deprovisioned).toHaveLength(0);
|
|
915
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
916
|
+
const after = await store.getResource(
|
|
917
|
+
ApiResourceKind.mcp_server,
|
|
918
|
+
server.metadata!.id,
|
|
919
|
+
McpServerSchema,
|
|
920
|
+
);
|
|
921
|
+
expect(after.status?.connectStatus?.phase).toBe(ConnectPhase.failed);
|
|
922
|
+
expect(after.status?.connectStatus?.failureCode).toBe("Unavailable");
|
|
923
|
+
expect(after.status?.connectStatus?.failureMessage).toBe(
|
|
924
|
+
CONNECT_SANDBOX_PROVISIONING_FAILED,
|
|
925
|
+
);
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
it("startConnect: never probes the sandbox's fresh queue, and the settle releases the sandbox once", async () => {
|
|
929
|
+
const provisioner = fakeConnectProvisioner();
|
|
930
|
+
const harness = makeHarness({ provisioner, pollers: false });
|
|
931
|
+
const server = await seedServer();
|
|
932
|
+
const result = await startConnect(harness.deps, connectInput(server.metadata!.id));
|
|
933
|
+
expect(result.status?.connectStatus?.phase).toBe(ConnectPhase.connecting);
|
|
934
|
+
// The advisory describes the shared queue only; a sandbox created a
|
|
935
|
+
// moment ago has no poller by construction.
|
|
936
|
+
expect(result.status?.connectStatus?.warning).toBe("");
|
|
937
|
+
expect(harness.engine.pollerProbes).toBe(0);
|
|
938
|
+
const connectId = connectIdOf(harness);
|
|
939
|
+
await vi.waitFor(() =>
|
|
940
|
+
expect(provisioner.deprovisioned).toEqual([`sbx-${connectId}`]),
|
|
941
|
+
);
|
|
942
|
+
await vi.waitFor(() => expect(harness.ecDeletes).toEqual(["ectx_1"]));
|
|
943
|
+
});
|
|
944
|
+
|
|
945
|
+
it("startConnect: an attach releases the unused sandbox at once", async () => {
|
|
946
|
+
const provisioner = fakeConnectProvisioner();
|
|
947
|
+
const harness = makeHarness({ provisioner, attached: true });
|
|
948
|
+
const server = await seedServer();
|
|
949
|
+
await startConnect(harness.deps, connectInput(server.metadata!.id));
|
|
950
|
+
expect(provisioner.deprovisioned).toHaveLength(1);
|
|
951
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
it("startConnect: a sandbox that cannot be provisioned fails the RPC fast and deletes the row", async () => {
|
|
955
|
+
const provisioner = fakeConnectProvisioner({ createError: new Error("quota exceeded") });
|
|
956
|
+
const harness = makeHarness({ provisioner });
|
|
957
|
+
const server = await seedServer();
|
|
958
|
+
await expectConnectError(
|
|
959
|
+
startConnect(harness.deps, connectInput(server.metadata!.id)),
|
|
960
|
+
Code.Unavailable,
|
|
961
|
+
CONNECT_SANDBOX_PROVISIONING_FAILED,
|
|
962
|
+
);
|
|
963
|
+
expect(harness.engine.startedInputs).toHaveLength(0);
|
|
964
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
it("best-effort connect acts as the applier: its binding row, its sandbox, released once", async () => {
|
|
968
|
+
const provisioner = fakeConnectProvisioner();
|
|
969
|
+
const harness = makeHarness({ provisioner });
|
|
970
|
+
const server = await seedServer();
|
|
971
|
+
const applier = testCallerIdentity({ identityId: "the-applier" });
|
|
972
|
+
await startBestEffortConnect(harness.deps, server, applier);
|
|
973
|
+
|
|
974
|
+
expect(harness.ecCreators).toEqual([applier]);
|
|
975
|
+
const connectId = connectIdOf(harness);
|
|
976
|
+
expect(
|
|
977
|
+
harness.deps.runnerAuth.verify(
|
|
978
|
+
TOKEN_TYPE_EXECUTION_SCOPED,
|
|
979
|
+
provisioner.created[0]!.env.stigmerToken,
|
|
980
|
+
),
|
|
981
|
+
).toBe(connectId);
|
|
982
|
+
expect(provisioner.deprovisioned).toEqual([`sbx-${connectId}`]);
|
|
983
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
984
|
+
const after = await store.getResource(
|
|
985
|
+
ApiResourceKind.mcp_server,
|
|
986
|
+
server.metadata!.id,
|
|
987
|
+
McpServerSchema,
|
|
988
|
+
);
|
|
989
|
+
expect(after.status?.connectStatus?.phase).toBe(ConnectPhase.succeeded);
|
|
990
|
+
});
|
|
991
|
+
|
|
992
|
+
it("best-effort connect gives its sandbox back before awaiting a run it attached to", async () => {
|
|
993
|
+
const provisioner = fakeConnectProvisioner();
|
|
994
|
+
const heldWhileAwaiting: number[] = [];
|
|
995
|
+
const harness = makeHarness({
|
|
996
|
+
provisioner,
|
|
997
|
+
attached: true,
|
|
998
|
+
onAwait: () =>
|
|
999
|
+
heldWhileAwaiting.push(provisioner.created.length - provisioner.deprovisioned.length),
|
|
1000
|
+
});
|
|
1001
|
+
const server = await seedServer();
|
|
1002
|
+
await startBestEffortConnect(harness.deps, server, testCaller);
|
|
1003
|
+
expect(heldWhileAwaiting).toEqual([0]);
|
|
1004
|
+
expect(provisioner.deprovisioned).toHaveLength(1);
|
|
1005
|
+
expect(harness.ecDeletes).toEqual(["ectx_1"]);
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
it("best-effort connect without a lane creates no row and runs on the shared queue, as before", async () => {
|
|
1009
|
+
const harness = makeHarness();
|
|
1010
|
+
const server = await seedServer();
|
|
1011
|
+
await startBestEffortConnect(harness.deps, server, testCaller);
|
|
1012
|
+
expect(harness.ecCreates).toBe(0);
|
|
1013
|
+
expect(harness.engine.startedInputs).toEqual([
|
|
1014
|
+
{ mcp_server_id: server.metadata!.id },
|
|
1015
|
+
]);
|
|
1016
|
+
expect(harness.engine.startedQueues).toEqual([{ kind: "runner" }]);
|
|
1017
|
+
});
|
|
1018
|
+
});
|
|
@@ -40,6 +40,7 @@ import { loadConfig } from "../../../boot/config.js";
|
|
|
40
40
|
import { composeServer } from "../../../boot/compose.js";
|
|
41
41
|
import type { ComposedServer } from "../../../boot/compose.js";
|
|
42
42
|
import { createLogger } from "../../../boot/logger.js";
|
|
43
|
+
import { seedOrganizations } from "../../organization/__tests__/support.js";
|
|
43
44
|
|
|
44
45
|
const silentLogger = createLogger({
|
|
45
46
|
level: "error",
|
|
@@ -80,6 +81,7 @@ beforeAll(async () => {
|
|
|
80
81
|
const transport: Transport = createGrpcTransport({
|
|
81
82
|
baseUrl: `http://127.0.0.1:${port}`,
|
|
82
83
|
});
|
|
84
|
+
await seedOrganizations(transport, [ORG, "other-org"]);
|
|
83
85
|
command = createClient(McpServerCommandController, transport);
|
|
84
86
|
query = createClient(McpServerQueryController, transport);
|
|
85
87
|
});
|
|
@@ -40,6 +40,7 @@ import { loadConfig } from "../../../boot/config.js";
|
|
|
40
40
|
import { composeServer } from "../../../boot/compose.js";
|
|
41
41
|
import type { ComposedServer } from "../../../boot/compose.js";
|
|
42
42
|
import { createLogger } from "../../../boot/logger.js";
|
|
43
|
+
import { seedOrganizations } from "../../organization/__tests__/support.js";
|
|
43
44
|
|
|
44
45
|
const silentLogger = createLogger({
|
|
45
46
|
level: "error",
|
|
@@ -177,6 +178,7 @@ beforeAll(async () => {
|
|
|
177
178
|
const transport: Transport = createGrpcTransport({
|
|
178
179
|
baseUrl: `http://127.0.0.1:${port}`,
|
|
179
180
|
});
|
|
181
|
+
await seedOrganizations(transport, [ORG]);
|
|
180
182
|
command = createClient(McpServerCommandController, transport);
|
|
181
183
|
query = createClient(McpServerQueryController, transport);
|
|
182
184
|
});
|
|
@@ -98,6 +98,8 @@ function connectDeps(
|
|
|
98
98
|
oauthGrants: untouchable("oauthGrants"),
|
|
99
99
|
pendingOAuthStates: untouchable("pendingOAuthStates"),
|
|
100
100
|
secretService: untouchable("secretService"),
|
|
101
|
+
// The external-runner posture: no connect sandbox is provisioned.
|
|
102
|
+
sandboxLane: { enabled: false },
|
|
101
103
|
oauthRedirectUri: "http://127.0.0.1:8234/auth/oauth/callback",
|
|
102
104
|
outboundFetch: untouchable("outboundFetch"),
|
|
103
105
|
...overrides,
|