@stigmer/server 3.40.1 → 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 +132 -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 +4 -3
- package/dist/domain/channelapp/controller.d.ts.map +1 -1
- 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 +153 -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 +4 -3
- 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 +2 -0
- 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,6 +20,11 @@
|
|
|
20
20
|
* run) is not reconciled in place — the fresh start below overwrites it,
|
|
21
21
|
* which is both the repair and the caller's intent.
|
|
22
22
|
*
|
|
23
|
+
* With a sandbox lane composed the run is served by a connect sandbox
|
|
24
|
+
* provisioned for this connect (connect-sandbox.ts): the settle task
|
|
25
|
+
* releases it with the ExecutionContext, and every arm that never hands a
|
|
26
|
+
* run to the settler (a start failure, an attach) releases it at once.
|
|
27
|
+
*
|
|
23
28
|
* Proven by mcpserver-connect.conformance.test.ts
|
|
24
29
|
* (CONFORMANCE_TARGET=local-execution), __tests__/connect.test.ts and
|
|
25
30
|
* __tests__/store-faults.test.ts.
|
|
@@ -48,11 +53,13 @@ import {
|
|
|
48
53
|
import {
|
|
49
54
|
ASYNC_CONNECT_TIMEOUT,
|
|
50
55
|
BEST_EFFORT_CONNECT_GET_BUFFER_MS,
|
|
56
|
+
acquireConnectRouteFor,
|
|
51
57
|
deleteConnectExecutionContext,
|
|
52
58
|
mapConnectFailure,
|
|
53
59
|
prepareConnect,
|
|
54
60
|
} from "./connect.js";
|
|
55
61
|
import type { McpServerConnectDeps } from "./connect.js";
|
|
62
|
+
import type { ConnectRoute } from "./connect-sandbox.js";
|
|
56
63
|
import type { ConnectRun, McpServerConnectEngine } from "./engine.js";
|
|
57
64
|
|
|
58
65
|
/**
|
|
@@ -124,11 +131,34 @@ export async function startConnect(
|
|
|
124
131
|
|
|
125
132
|
const prepared = await prepareConnect(deps, mcpServer, input, identity);
|
|
126
133
|
|
|
134
|
+
let route: ConnectRoute;
|
|
135
|
+
try {
|
|
136
|
+
route = await acquireConnectRouteFor(deps, mcpServerId, {
|
|
137
|
+
connectExecutionId: prepared.executionId,
|
|
138
|
+
org: input.org,
|
|
139
|
+
caller: identity,
|
|
140
|
+
});
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (prepared.ecResourceId !== "") {
|
|
143
|
+
await deleteConnectExecutionContext(
|
|
144
|
+
deps,
|
|
145
|
+
prepared.ecResourceId,
|
|
146
|
+
prepared.executionId,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
|
|
127
152
|
// Taken before the start so the advisory describes the queue the run is
|
|
128
153
|
// about to join. Warn-only by design: a worker may be booting (the
|
|
129
154
|
// pre-flight has a startup false-negative race), so the operation
|
|
130
|
-
// proceeds either way and the poller renders the warning as context.
|
|
131
|
-
|
|
155
|
+
// proceeds either way and the poller renders the warning as context. A
|
|
156
|
+
// connect sandbox's queue is never probed: it was created a moment ago
|
|
157
|
+
// and has no poller yet by construction.
|
|
158
|
+
const warning =
|
|
159
|
+
route.taskQueue.kind === "runner"
|
|
160
|
+
? await runnerQueueWarning(engineState.engine)
|
|
161
|
+
: "";
|
|
132
162
|
|
|
133
163
|
let run: ConnectRun;
|
|
134
164
|
try {
|
|
@@ -136,8 +166,10 @@ export async function startConnect(
|
|
|
136
166
|
mcpServerId,
|
|
137
167
|
prepared.workflowInput,
|
|
138
168
|
ASYNC_CONNECT_TIMEOUT.ms,
|
|
169
|
+
route.taskQueue,
|
|
139
170
|
);
|
|
140
171
|
} catch (error) {
|
|
172
|
+
await route.release();
|
|
141
173
|
if (prepared.ecResourceId !== "") {
|
|
142
174
|
await deleteConnectExecutionContext(
|
|
143
175
|
deps,
|
|
@@ -153,8 +185,10 @@ export async function startConnect(
|
|
|
153
185
|
}
|
|
154
186
|
|
|
155
187
|
if (run.attached) {
|
|
156
|
-
// Lost the residual race to another lane: its run and
|
|
157
|
-
// record stand, and the
|
|
188
|
+
// Lost the residual race to another lane: its run, its sandbox and
|
|
189
|
+
// its CONNECTING record stand, and the route and ExecutionContext
|
|
190
|
+
// prepared here are unused.
|
|
191
|
+
await route.release();
|
|
158
192
|
if (prepared.ecResourceId !== "") {
|
|
159
193
|
await deleteConnectExecutionContext(
|
|
160
194
|
deps,
|
|
@@ -188,11 +222,11 @@ export async function startConnect(
|
|
|
188
222
|
// The workflow is already running; hand it to the background settler
|
|
189
223
|
// (which copes with a deleted resource) but fail the RPC honestly —
|
|
190
224
|
// a caller that cannot observe CONNECTING cannot poll.
|
|
191
|
-
detachSettle(deps, mcpServer, run, prepared);
|
|
225
|
+
detachSettle(deps, mcpServer, run, route, prepared);
|
|
192
226
|
throw internalError(error, "failed to record connect operation");
|
|
193
227
|
}
|
|
194
228
|
|
|
195
|
-
detachSettle(deps, mcpServer, run, prepared);
|
|
229
|
+
detachSettle(deps, mcpServer, run, route, prepared);
|
|
196
230
|
|
|
197
231
|
return persisted;
|
|
198
232
|
}
|
|
@@ -206,12 +240,14 @@ function detachSettle(
|
|
|
206
240
|
deps: McpServerConnectDeps,
|
|
207
241
|
mcpServer: McpServer,
|
|
208
242
|
run: ConnectRun,
|
|
243
|
+
route: ConnectRoute,
|
|
209
244
|
prepared: { readonly ecResourceId: string; readonly executionId: string },
|
|
210
245
|
): void {
|
|
211
246
|
void settleConnectAsync(
|
|
212
247
|
deps,
|
|
213
248
|
mcpServer,
|
|
214
249
|
run,
|
|
250
|
+
route,
|
|
215
251
|
prepared.ecResourceId,
|
|
216
252
|
prepared.executionId,
|
|
217
253
|
).catch((error: unknown) => {
|
|
@@ -232,13 +268,15 @@ function detachSettle(
|
|
|
232
268
|
* first; the slightly longer backstop only guarantees the settle task can
|
|
233
269
|
* never hang if Temporal becomes unreachable. If this process dies before
|
|
234
270
|
* settling, the CONNECTING record goes stale; the next startConnect
|
|
235
|
-
* overwrites it (the orphan contract on ConnectStatus)
|
|
271
|
+
* overwrites it (the orphan contract on ConnectStatus), and a connect
|
|
272
|
+
* sandbox it held is left to the edition's orphan sweep. Never throws —
|
|
236
273
|
* every failure lands on connect_status or the log.
|
|
237
274
|
*/
|
|
238
275
|
async function settleConnectAsync(
|
|
239
276
|
deps: McpServerConnectDeps,
|
|
240
277
|
mcpServer: McpServer,
|
|
241
278
|
run: ConnectRun,
|
|
279
|
+
route: ConnectRoute,
|
|
242
280
|
ecResourceId: string,
|
|
243
281
|
executionId: string,
|
|
244
282
|
): Promise<void> {
|
|
@@ -298,6 +336,7 @@ async function settleConnectAsync(
|
|
|
298
336
|
tool_approvals: toolApprovalCount,
|
|
299
337
|
});
|
|
300
338
|
} finally {
|
|
339
|
+
await route.release();
|
|
301
340
|
if (ecResourceId !== "") {
|
|
302
341
|
await deleteConnectExecutionContext(deps, ecResourceId, executionId);
|
|
303
342
|
}
|
|
@@ -306,9 +345,9 @@ async function settleConnectAsync(
|
|
|
306
345
|
|
|
307
346
|
/**
|
|
308
347
|
* The dead-runner advisory for connect_status, or "" when a worker is
|
|
309
|
-
* polling the runner task queue — or when the question cannot be
|
|
310
|
-
* (an unreachable Temporal should not cry wolf on an operation
|
|
311
|
-
* about to fail loudly anyway; Go runnerQueueWarning).
|
|
348
|
+
* polling the shared runner task queue — or when the question cannot be
|
|
349
|
+
* answered (an unreachable Temporal should not cry wolf on an operation
|
|
350
|
+
* that is about to fail loudly anyway; Go runnerQueueWarning).
|
|
312
351
|
*/
|
|
313
352
|
async function runnerQueueWarning(
|
|
314
353
|
engine: McpServerConnectEngine,
|
|
@@ -8,12 +8,16 @@
|
|
|
8
8
|
* state_changed_at set; the subject is forced to the OSS single-user
|
|
9
9
|
* sentinel "" (DD-005 D2); provenance is stored as supplied with
|
|
10
10
|
* tool_call_id force-cleared (the Stage 3 contract); an unnamed
|
|
11
|
-
* create defaults its name from the minted mem_ id
|
|
12
|
-
*
|
|
11
|
+
* create defaults its name from the minted mem_ id, and an id the
|
|
12
|
+
* request carried is replaced by that mint (stigmer#1266); a missing
|
|
13
|
+
* org is the exact InvalidArgument copy;
|
|
13
14
|
* - enablement fails CLOSED: org switch off is the exact formatted
|
|
14
15
|
* FailedPrecondition copy, an unknown org is NotFound;
|
|
15
16
|
* - the 100-per-subject-per-org ceiling refuses the 101st record with
|
|
16
|
-
* the exact copy and never blocks another org
|
|
17
|
+
* the exact copy and never blocks another org or counts another
|
|
18
|
+
* person's rows;
|
|
19
|
+
* - list answers one org's rows newest created first, the list index's
|
|
20
|
+
* order (stigmer#1405);
|
|
17
21
|
* - confirm/reject are one contract with opposite verdicts: idempotent
|
|
18
22
|
* re-decisions write NOTHING (no audit bump), cross-decisions are
|
|
19
23
|
* refused with the pinned copy;
|
|
@@ -29,6 +33,7 @@ import path from "node:path";
|
|
|
29
33
|
|
|
30
34
|
import { create } from "@bufbuild/protobuf";
|
|
31
35
|
import type { MessageInitShape } from "@bufbuild/protobuf";
|
|
36
|
+
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
|
|
32
37
|
import { Code, ConnectError, createClient } from "@connectrpc/connect";
|
|
33
38
|
import type { Client, Transport } from "@connectrpc/connect";
|
|
34
39
|
import { createGrpcTransport } from "@connectrpc/connect-node";
|
|
@@ -205,6 +210,19 @@ describe("memory create", () => {
|
|
|
205
210
|
expect(created.metadata?.name).toBe(created.metadata?.id);
|
|
206
211
|
});
|
|
207
212
|
|
|
213
|
+
it("replaces a client-supplied id with its own mint, which the name then follows", async () => {
|
|
214
|
+
const org = await createOrg(true);
|
|
215
|
+
const created = await command.create({
|
|
216
|
+
apiVersion: MEMORY_API_VERSION,
|
|
217
|
+
kind: MEMORY_KIND,
|
|
218
|
+
metadata: { org, id: "mem_chosen" },
|
|
219
|
+
spec: { content: "A fact whose id the caller tried to choose." },
|
|
220
|
+
});
|
|
221
|
+
expect(created.metadata?.id).toMatch(/^mem_[0-9a-hjkmnp-tv-z]{26}$/);
|
|
222
|
+
expect(created.metadata?.id).not.toBe("mem_chosen");
|
|
223
|
+
expect(created.metadata?.name).toBe(created.metadata?.id);
|
|
224
|
+
});
|
|
225
|
+
|
|
208
226
|
it("requires metadata.org with the exact InvalidArgument copy", async () => {
|
|
209
227
|
const error = await grpcError(() =>
|
|
210
228
|
command.create({
|
|
@@ -234,30 +252,36 @@ describe("memory enablement (fail-closed)", () => {
|
|
|
234
252
|
});
|
|
235
253
|
});
|
|
236
254
|
|
|
255
|
+
/**
|
|
256
|
+
* Seeds a full ceiling for `subject` in `org` directly through the store
|
|
257
|
+
* (the RPC path would be needlessly slow at 100 creates).
|
|
258
|
+
*/
|
|
259
|
+
async function seedCeiling(org: string, subject: string): Promise<void> {
|
|
260
|
+
for (let i = 0; i < MAX_MEMORIES_PER_SUBJECT; i++) {
|
|
261
|
+
const id = generateId("mem");
|
|
262
|
+
const seeded = create(MemorySchema, {
|
|
263
|
+
apiVersion: MEMORY_API_VERSION,
|
|
264
|
+
kind: MEMORY_KIND,
|
|
265
|
+
metadata: { id, name: id, slug: id, org },
|
|
266
|
+
spec: { content: `Seeded fact ${i}.`, subjectIdentityAccountId: subject },
|
|
267
|
+
});
|
|
268
|
+
await server.store.saveResource(
|
|
269
|
+
ApiResourceKind.memory,
|
|
270
|
+
id,
|
|
271
|
+
MemorySchema,
|
|
272
|
+
seeded,
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
237
277
|
describe("memory cap", () => {
|
|
238
278
|
it("refuses the record past the per-subject ceiling, visibly, without blocking other orgs", async () => {
|
|
239
279
|
const org = await createOrg(true);
|
|
240
280
|
const otherOrg = await createOrg(true);
|
|
241
281
|
|
|
242
|
-
//
|
|
243
|
-
//
|
|
244
|
-
|
|
245
|
-
// would derive.
|
|
246
|
-
for (let i = 0; i < MAX_MEMORIES_PER_SUBJECT; i++) {
|
|
247
|
-
const id = generateId("mem");
|
|
248
|
-
const seeded = create(MemorySchema, {
|
|
249
|
-
apiVersion: MEMORY_API_VERSION,
|
|
250
|
-
kind: MEMORY_KIND,
|
|
251
|
-
metadata: { id, name: id, slug: id, org },
|
|
252
|
-
spec: { content: `Seeded fact ${i}.`, subjectIdentityAccountId: "" },
|
|
253
|
-
});
|
|
254
|
-
await server.store.saveResource(
|
|
255
|
-
ApiResourceKind.memory,
|
|
256
|
-
id,
|
|
257
|
-
MemorySchema,
|
|
258
|
-
seeded,
|
|
259
|
-
);
|
|
260
|
-
}
|
|
282
|
+
// The refused create goes through the RPC. Seeded rows carry the
|
|
283
|
+
// sentinel subject "" the create path would derive.
|
|
284
|
+
await seedCeiling(org, "");
|
|
261
285
|
|
|
262
286
|
const error = await grpcError(() => createMemory(org, "One too many."));
|
|
263
287
|
expect(error.code).toBe(Code.FailedPrecondition);
|
|
@@ -270,6 +294,14 @@ describe("memory cap", () => {
|
|
|
270
294
|
);
|
|
271
295
|
expect(unblocked.metadata?.id).toMatch(/^mem_/);
|
|
272
296
|
});
|
|
297
|
+
|
|
298
|
+
it("counts only the subject's own rows: another person's full ceiling in the org does not block", async () => {
|
|
299
|
+
const org = await createOrg(true);
|
|
300
|
+
await seedCeiling(org, "ida_someone_else");
|
|
301
|
+
|
|
302
|
+
const created = await createMemory(org, "Plenty of room for me.");
|
|
303
|
+
expect(created.metadata?.id).toMatch(/^mem_/);
|
|
304
|
+
});
|
|
273
305
|
});
|
|
274
306
|
|
|
275
307
|
describe("memory confirm/reject", () => {
|
|
@@ -480,4 +512,42 @@ describe("memory list", () => {
|
|
|
480
512
|
expect(item.metadata?.org).toBe(org);
|
|
481
513
|
}
|
|
482
514
|
});
|
|
515
|
+
|
|
516
|
+
it("answers newest created first, whatever the write order", async () => {
|
|
517
|
+
const org = await createOrg(true);
|
|
518
|
+
// Seeded through the store so each row carries a chosen creation
|
|
519
|
+
// instant; written oldest-last to prove the order is not the write's.
|
|
520
|
+
const seeded = [
|
|
521
|
+
{ id: generateId("mem"), day: 3 },
|
|
522
|
+
{ id: generateId("mem"), day: 1 },
|
|
523
|
+
{ id: generateId("mem"), day: 2 },
|
|
524
|
+
];
|
|
525
|
+
for (const { id, day } of seeded) {
|
|
526
|
+
await server.store.saveResource(
|
|
527
|
+
ApiResourceKind.memory,
|
|
528
|
+
id,
|
|
529
|
+
MemorySchema,
|
|
530
|
+
create(MemorySchema, {
|
|
531
|
+
apiVersion: MEMORY_API_VERSION,
|
|
532
|
+
kind: MEMORY_KIND,
|
|
533
|
+
metadata: { id, name: id, slug: id, org },
|
|
534
|
+
spec: { content: `Fact of day ${day}.` },
|
|
535
|
+
status: {
|
|
536
|
+
audit: {
|
|
537
|
+
specAudit: {
|
|
538
|
+
createdAt: timestampFromDate(new Date(Date.UTC(2026, 8, day))),
|
|
539
|
+
},
|
|
540
|
+
},
|
|
541
|
+
},
|
|
542
|
+
}),
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const listed = await query.list({ org });
|
|
547
|
+
expect(listed.items.map((m) => m.spec?.content)).toEqual([
|
|
548
|
+
"Fact of day 3.",
|
|
549
|
+
"Fact of day 2.",
|
|
550
|
+
"Fact of day 1.",
|
|
551
|
+
]);
|
|
552
|
+
});
|
|
483
553
|
});
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins the memory kind's indexed reads (../queries.ts) over a real sqlite
|
|
3
|
+
* store opened with the server's list indexes (stigmer#1405): a subject's
|
|
4
|
+
* read answers that subject's rows in the one organization, in every
|
|
5
|
+
* lifecycle state, newest first; the "" sentinel reads by organization
|
|
6
|
+
* and stays exact against a named subject's rows; the organization read
|
|
7
|
+
* answers every subject's rows there and none elsewhere; and rows a
|
|
8
|
+
* binary that does not know the index wrote (a second handle opened with
|
|
9
|
+
* no declarations, the overlap of a roll) answer the same.
|
|
10
|
+
*/
|
|
11
|
+
import { DatabaseSync } from "node:sqlite";
|
|
12
|
+
|
|
13
|
+
import { create } from "@bufbuild/protobuf";
|
|
14
|
+
import { timestampFromDate } from "@bufbuild/protobuf/wkt";
|
|
15
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
16
|
+
|
|
17
|
+
import { MemorySchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
|
|
18
|
+
import type { Memory } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
|
|
19
|
+
import { MemoryLifecycleState } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/enum_pb";
|
|
20
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
21
|
+
|
|
22
|
+
import type { Store } from "../../../store/interface.js";
|
|
23
|
+
import { apiResourceKindName } from "../../../store/proto-fields.js";
|
|
24
|
+
import { SqliteStore } from "../../../store/sqlite/store.js";
|
|
25
|
+
import { tempStore } from "../../../store/sqlite/__tests__/support.js";
|
|
26
|
+
import type { TempStore } from "../../../store/sqlite/__tests__/support.js";
|
|
27
|
+
import { listOrganizationMemories, listSubjectMemories } from "../queries.js";
|
|
28
|
+
|
|
29
|
+
let temp: TempStore;
|
|
30
|
+
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
temp = tempStore();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(async () => {
|
|
36
|
+
await temp.cleanup();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
async function seed(
|
|
40
|
+
store: Store,
|
|
41
|
+
row: {
|
|
42
|
+
id: string;
|
|
43
|
+
org: string;
|
|
44
|
+
subject: string;
|
|
45
|
+
day: number;
|
|
46
|
+
state?: MemoryLifecycleState;
|
|
47
|
+
},
|
|
48
|
+
): Promise<void> {
|
|
49
|
+
await store.saveResource(
|
|
50
|
+
ApiResourceKind.memory,
|
|
51
|
+
row.id,
|
|
52
|
+
MemorySchema,
|
|
53
|
+
create(MemorySchema, {
|
|
54
|
+
metadata: { id: row.id, name: row.id, org: row.org },
|
|
55
|
+
spec: { content: row.id, subjectIdentityAccountId: row.subject },
|
|
56
|
+
status: {
|
|
57
|
+
lifecycleState:
|
|
58
|
+
row.state ?? MemoryLifecycleState.lifecycle_state_confirmed,
|
|
59
|
+
audit: {
|
|
60
|
+
specAudit: {
|
|
61
|
+
createdAt: timestampFromDate(new Date(Date.UTC(2026, 8, row.day))),
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
}),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Memory rows whose index facts are not proven under revision 1 (the store-contract reading). */
|
|
70
|
+
function unprovenMemoryRows(): number {
|
|
71
|
+
const db = new DatabaseSync(temp.dbPath);
|
|
72
|
+
try {
|
|
73
|
+
return (
|
|
74
|
+
db
|
|
75
|
+
.prepare(
|
|
76
|
+
`SELECT COUNT(*) AS count FROM resources
|
|
77
|
+
WHERE kind = ? AND (list_indexed_at IS NOT updated_at
|
|
78
|
+
OR list_index_revision IS NULL OR list_index_revision <> 1)`,
|
|
79
|
+
)
|
|
80
|
+
.get(apiResourceKindName(ApiResourceKind.memory)) as { count: number }
|
|
81
|
+
).count;
|
|
82
|
+
} finally {
|
|
83
|
+
db.close();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const ids = (memories: ReadonlyArray<Memory>): string[] =>
|
|
88
|
+
memories.map((memory) => memory.metadata?.id ?? "");
|
|
89
|
+
|
|
90
|
+
async function seedTwoOrganizations(store: Store): Promise<void> {
|
|
91
|
+
await seed(store, {
|
|
92
|
+
id: "mem_carol_1",
|
|
93
|
+
org: "acme",
|
|
94
|
+
subject: "ida_carol",
|
|
95
|
+
day: 1,
|
|
96
|
+
});
|
|
97
|
+
await seed(store, {
|
|
98
|
+
id: "mem_carol_2",
|
|
99
|
+
org: "acme",
|
|
100
|
+
subject: "ida_carol",
|
|
101
|
+
day: 3,
|
|
102
|
+
state: MemoryLifecycleState.lifecycle_state_proposed,
|
|
103
|
+
});
|
|
104
|
+
await seed(store, {
|
|
105
|
+
id: "mem_dave",
|
|
106
|
+
org: "acme",
|
|
107
|
+
subject: "ida_dave",
|
|
108
|
+
day: 2,
|
|
109
|
+
});
|
|
110
|
+
await seed(store, { id: "mem_local", org: "acme", subject: "", day: 4 });
|
|
111
|
+
await seed(store, {
|
|
112
|
+
id: "mem_carol_zeta",
|
|
113
|
+
org: "zeta",
|
|
114
|
+
subject: "ida_carol",
|
|
115
|
+
day: 5,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
describe("listSubjectMemories", () => {
|
|
120
|
+
it("answers one subject's rows in one organization, every state, newest first", async () => {
|
|
121
|
+
await seedTwoOrganizations(temp.store);
|
|
122
|
+
expect(
|
|
123
|
+
ids(await listSubjectMemories(temp.store, "acme", "ida_carol")),
|
|
124
|
+
).toEqual(["mem_carol_2", "mem_carol_1"]);
|
|
125
|
+
expect(
|
|
126
|
+
ids(await listSubjectMemories(temp.store, "zeta", "ida_carol")),
|
|
127
|
+
).toEqual(["mem_carol_zeta"]);
|
|
128
|
+
expect(await listSubjectMemories(temp.store, "zeta", "ida_dave")).toEqual(
|
|
129
|
+
[],
|
|
130
|
+
);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("reads the single-operator sentinel by organization, and only its own rows", async () => {
|
|
134
|
+
await seedTwoOrganizations(temp.store);
|
|
135
|
+
expect(ids(await listSubjectMemories(temp.store, "acme", ""))).toEqual([
|
|
136
|
+
"mem_local",
|
|
137
|
+
]);
|
|
138
|
+
expect(await listSubjectMemories(temp.store, "zeta", "")).toEqual([]);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("answers rows a binary without the index wrote", async () => {
|
|
142
|
+
const older = SqliteStore.open(temp.dbPath);
|
|
143
|
+
try {
|
|
144
|
+
await seedTwoOrganizations(older);
|
|
145
|
+
} finally {
|
|
146
|
+
await older.close();
|
|
147
|
+
}
|
|
148
|
+
expect(unprovenMemoryRows(), "the rows carry no memory index facts").toBe(
|
|
149
|
+
5,
|
|
150
|
+
);
|
|
151
|
+
expect(
|
|
152
|
+
ids(await listSubjectMemories(temp.store, "acme", "ida_carol")),
|
|
153
|
+
).toEqual(["mem_carol_2", "mem_carol_1"]);
|
|
154
|
+
expect(ids(await listSubjectMemories(temp.store, "acme", ""))).toEqual([
|
|
155
|
+
"mem_local",
|
|
156
|
+
]);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe("listOrganizationMemories", () => {
|
|
161
|
+
it("answers every subject's rows in the organization, newest first, and none elsewhere", async () => {
|
|
162
|
+
await seedTwoOrganizations(temp.store);
|
|
163
|
+
expect(ids(await listOrganizationMemories(temp.store, "acme"))).toEqual([
|
|
164
|
+
"mem_local",
|
|
165
|
+
"mem_carol_2",
|
|
166
|
+
"mem_dave",
|
|
167
|
+
"mem_carol_1",
|
|
168
|
+
]);
|
|
169
|
+
expect(ids(await listOrganizationMemories(temp.store, "zeta"))).toEqual([
|
|
170
|
+
"mem_carol_zeta",
|
|
171
|
+
]);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -185,7 +185,8 @@ function kindOf(ctx: HandlerContext): ApiResourceKind {
|
|
|
185
185
|
* content is subject-only and must not surface in org-visible search).
|
|
186
186
|
*
|
|
187
187
|
* Authorization: GuardMemoryCapture decides WHO may capture (the composed
|
|
188
|
-
* RunnerCredentialProvider
|
|
188
|
+
* RunnerCredentialProvider, then the first-party allow-list recall shares,
|
|
189
|
+
* extensions/identity.ts), AuthorizeResolvedTarget decides WHERE
|
|
189
190
|
* (can_create_session on the organization), and CreateAuthorizationTuples
|
|
190
191
|
* runs against the composed lifecycle. ResolveMemoryDefaults names the
|
|
191
192
|
* person the memory is about and CheckMemoryEnablement requires both
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The memory list index (store/list-index.ts): `subject` is the key
|
|
3
|
+
* recall and the per-subject cap read (queries.ts beside this file), so
|
|
4
|
+
* both answer from one person's rows instead of decoding every memory on
|
|
5
|
+
* the server — recall runs on every execution create in a memory-on
|
|
6
|
+
* organization (stigmer#1405). The organization needs no key: it is every
|
|
7
|
+
* declaration's first fact, which is how `memory.list` reads one
|
|
8
|
+
* organization's rows.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle state is not a key. A key reads a string field and the state
|
|
11
|
+
* is an enum; the rows it would narrow are one subject's in one
|
|
12
|
+
* organization, which the cap bounds (MAX_MEMORIES_PER_SUBJECT), so the
|
|
13
|
+
* readers filter it in process. The single-operator posture files every
|
|
14
|
+
* memory under the "" subject sentinel, and an empty value is no key
|
|
15
|
+
* (`listIndexFactsOf`), so that subject reads by organization alone.
|
|
16
|
+
*
|
|
17
|
+
* A change to `keys` bumps `revision` (boot/__tests__/list-indexes.test.ts
|
|
18
|
+
* pins the pair).
|
|
19
|
+
*/
|
|
20
|
+
import { MemorySchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
|
|
21
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
22
|
+
|
|
23
|
+
import { declareListIndex, field } from "../../store/list-index.js";
|
|
24
|
+
|
|
25
|
+
export const memoryListIndex = declareListIndex({
|
|
26
|
+
kind: ApiResourceKind.memory,
|
|
27
|
+
schema: MemorySchema,
|
|
28
|
+
revision: 1,
|
|
29
|
+
keys: {
|
|
30
|
+
subject: field("spec.subject_identity_account_id"),
|
|
31
|
+
},
|
|
32
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The memory kind's shared reads, all through the list index (list-index.ts
|
|
3
|
+
* beside this file; the store's contract in store/interface.ts): recall
|
|
4
|
+
* (domain/agentexecution/create-steps.ts) and the per-subject cap read one
|
|
5
|
+
* subject's rows in one organization, `memory.list` reads one
|
|
6
|
+
* organization's. Rows come newest created first, the index order, which
|
|
7
|
+
* is exactly `compareCreatedAtDesc` (store/list-index.ts states it).
|
|
8
|
+
*
|
|
9
|
+
* Every row is re-checked against the organization and the subject it was
|
|
10
|
+
* asked for, whatever the index returned, as the IamPolicy adapter
|
|
11
|
+
* re-checks its principal (domain/iampolicy/resource-store.ts): it keeps
|
|
12
|
+
* the "" subject exact, which reads the whole organization because an
|
|
13
|
+
* empty value is no key. Undecodable rows are skipped — one bad record
|
|
14
|
+
* must not take recall, the cap or the list down. A store fault is
|
|
15
|
+
* thrown as it came; each caller maps it with its own copy.
|
|
16
|
+
*
|
|
17
|
+
* Proven by __tests__/queries.test.ts and, end to end, by
|
|
18
|
+
* memory.conformance.test.ts.
|
|
19
|
+
*/
|
|
20
|
+
import { fromBinary } from "@bufbuild/protobuf";
|
|
21
|
+
|
|
22
|
+
import { MemorySchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
|
|
23
|
+
import type { Memory } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/api_pb";
|
|
24
|
+
|
|
25
|
+
import type { Store } from "../../store/interface.js";
|
|
26
|
+
import type { ListIndexRow } from "../../store/list-index.js";
|
|
27
|
+
import { memoryListIndex } from "./list-index.js";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Every memory `subject` holds in `org`, in every lifecycle state — the
|
|
31
|
+
* run's person's account id, or the single-operator "" sentinel.
|
|
32
|
+
*/
|
|
33
|
+
export async function listSubjectMemories(
|
|
34
|
+
store: Store,
|
|
35
|
+
org: string,
|
|
36
|
+
subject: string,
|
|
37
|
+
): Promise<Memory[]> {
|
|
38
|
+
const rows = await store.queryResources(memoryListIndex, {
|
|
39
|
+
org,
|
|
40
|
+
...(subject === ""
|
|
41
|
+
? {}
|
|
42
|
+
: { anyKey: [{ name: "subject" as const, value: subject }] }),
|
|
43
|
+
});
|
|
44
|
+
return decodeMemories(rows).filter(
|
|
45
|
+
(memory) =>
|
|
46
|
+
(memory.metadata?.org ?? "") === org &&
|
|
47
|
+
(memory.spec?.subjectIdentityAccountId ?? "") === subject,
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Every memory in `org`, whoever it is about. */
|
|
52
|
+
export async function listOrganizationMemories(
|
|
53
|
+
store: Store,
|
|
54
|
+
org: string,
|
|
55
|
+
): Promise<Memory[]> {
|
|
56
|
+
const rows = await store.queryResources(memoryListIndex, { org });
|
|
57
|
+
return decodeMemories(rows).filter(
|
|
58
|
+
(memory) => (memory.metadata?.org ?? "") === org,
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function decodeMemories(rows: ReadonlyArray<ListIndexRow>): Memory[] {
|
|
63
|
+
const memories: Memory[] = [];
|
|
64
|
+
for (const row of rows) {
|
|
65
|
+
try {
|
|
66
|
+
memories.push(fromBinary(MemorySchema, row.data));
|
|
67
|
+
} catch {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return memories;
|
|
72
|
+
}
|