@stigmer/server 3.22.1-dev.20260922095755 → 3.23.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/artifactstorage/artifact-storage.d.ts +29 -31
- package/dist/artifactstorage/artifact-storage.d.ts.map +1 -1
- package/dist/artifactstorage/artifact-storage.js +5 -7
- package/dist/artifactstorage/artifact-storage.js.map +1 -1
- package/dist/artifactstorage/r2-storage.d.ts +12 -7
- package/dist/artifactstorage/r2-storage.d.ts.map +1 -1
- package/dist/artifactstorage/r2-storage.js +6 -14
- package/dist/artifactstorage/r2-storage.js.map +1 -1
- package/dist/authorization/authorizer.d.ts +8 -4
- package/dist/authorization/authorizer.d.ts.map +1 -1
- package/dist/authorization/authorizer.js +9 -5
- package/dist/authorization/authorizer.js.map +1 -1
- package/dist/authorization/derived-tuples.d.ts.map +1 -1
- package/dist/authorization/derived-tuples.js +25 -10
- package/dist/authorization/derived-tuples.js.map +1 -1
- package/dist/authorization/evaluator.d.ts +8 -7
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js +20 -4
- package/dist/authorization/evaluator.js.map +1 -1
- package/dist/authorization/list-read-scope.d.ts.map +1 -1
- package/dist/authorization/list-read-scope.js +9 -5
- package/dist/authorization/list-read-scope.js.map +1 -1
- package/dist/authorization/model/agent.d.ts.map +1 -1
- package/dist/authorization/model/agent.js +5 -4
- package/dist/authorization/model/agent.js.map +1 -1
- package/dist/authorization/model/agent_instance.d.ts.map +1 -1
- package/dist/authorization/model/agent_instance.js +2 -2
- package/dist/authorization/model/agent_instance.js.map +1 -1
- package/dist/authorization/model/mcp_server.d.ts.map +1 -1
- package/dist/authorization/model/mcp_server.js +2 -2
- package/dist/authorization/model/mcp_server.js.map +1 -1
- package/dist/authorization/model/plugin.d.ts.map +1 -1
- package/dist/authorization/model/plugin.js +4 -3
- package/dist/authorization/model/plugin.js.map +1 -1
- package/dist/authorization/model/rewrite.d.ts +10 -8
- package/dist/authorization/model/rewrite.d.ts.map +1 -1
- package/dist/authorization/model/rewrite.js +3 -0
- package/dist/authorization/model/rewrite.js.map +1 -1
- package/dist/authorization/model/skill.d.ts.map +1 -1
- package/dist/authorization/model/skill.js +2 -2
- package/dist/authorization/model/skill.js.map +1 -1
- package/dist/authorization/model/workflow.d.ts.map +1 -1
- package/dist/authorization/model/workflow.js +2 -2
- package/dist/authorization/model/workflow.js.map +1 -1
- package/dist/authorization/model/workflow_instance.d.ts.map +1 -1
- package/dist/authorization/model/workflow_instance.js +2 -2
- package/dist/authorization/model/workflow_instance.js.map +1 -1
- package/dist/authorization/organization-directory.d.ts.map +1 -1
- package/dist/authorization/organization-directory.js +3 -2
- package/dist/authorization/organization-directory.js.map +1 -1
- package/dist/authorization/store-test-kit.d.ts +6 -0
- package/dist/authorization/store-test-kit.d.ts.map +1 -1
- package/dist/authorization/store-test-kit.js +62 -16
- package/dist/authorization/store-test-kit.js.map +1 -1
- package/dist/authorization/tuples.d.ts +32 -13
- package/dist/authorization/tuples.d.ts.map +1 -1
- package/dist/authorization/tuples.js +11 -3
- package/dist/authorization/tuples.js.map +1 -1
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +49 -24
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/config.d.ts +4 -3
- package/dist/boot/config.d.ts.map +1 -1
- package/dist/boot/config.js.map +1 -1
- package/dist/boot/skill-transfer-origin.d.ts +52 -0
- package/dist/boot/skill-transfer-origin.d.ts.map +1 -0
- package/dist/boot/skill-transfer-origin.js +54 -0
- package/dist/boot/skill-transfer-origin.js.map +1 -0
- package/dist/domain/agent/controller.d.ts.map +1 -1
- package/dist/domain/agent/controller.js +4 -4
- package/dist/domain/agent/controller.js.map +1 -1
- package/dist/domain/agentchannel/controller.d.ts.map +1 -1
- package/dist/domain/agentchannel/controller.js +1 -3
- package/dist/domain/agentchannel/controller.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +1 -3
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentinstance/controller.d.ts.map +1 -1
- package/dist/domain/agentinstance/controller.js +4 -3
- package/dist/domain/agentinstance/controller.js.map +1 -1
- package/dist/domain/agentshare/constants.d.ts +11 -6
- package/dist/domain/agentshare/constants.d.ts.map +1 -1
- package/dist/domain/agentshare/constants.js +16 -8
- package/dist/domain/agentshare/constants.js.map +1 -1
- package/dist/domain/agentshare/controller.d.ts.map +1 -1
- package/dist/domain/agentshare/controller.js +1 -3
- package/dist/domain/agentshare/controller.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +25 -18
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +142 -41
- package/dist/domain/agentshare/steps.js.map +1 -1
- package/dist/domain/environment/controller.d.ts.map +1 -1
- package/dist/domain/environment/controller.js +3 -2
- package/dist/domain/environment/controller.js.map +1 -1
- package/dist/domain/executioncontext/controller.d.ts.map +1 -1
- package/dist/domain/executioncontext/controller.js +1 -2
- package/dist/domain/executioncontext/controller.js.map +1 -1
- package/dist/domain/mcpserver/controller.d.ts.map +1 -1
- package/dist/domain/mcpserver/controller.js +4 -3
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/plugin/controller.d.ts +3 -7
- package/dist/domain/plugin/controller.d.ts.map +1 -1
- package/dist/domain/plugin/controller.js +11 -9
- package/dist/domain/plugin/controller.js.map +1 -1
- package/dist/domain/plugin/push.d.ts +5 -7
- package/dist/domain/plugin/push.d.ts.map +1 -1
- package/dist/domain/plugin/push.js +14 -8
- package/dist/domain/plugin/push.js.map +1 -1
- package/dist/domain/schedule/controller.d.ts.map +1 -1
- package/dist/domain/schedule/controller.js +1 -3
- package/dist/domain/schedule/controller.js.map +1 -1
- package/dist/domain/session/controller.d.ts.map +1 -1
- package/dist/domain/session/controller.js +2 -3
- package/dist/domain/session/controller.js.map +1 -1
- package/dist/domain/skill/constants.d.ts +26 -3
- package/dist/domain/skill/constants.d.ts.map +1 -1
- package/dist/domain/skill/constants.js +26 -3
- package/dist/domain/skill/constants.js.map +1 -1
- package/dist/domain/skill/controller.d.ts +6 -11
- package/dist/domain/skill/controller.d.ts.map +1 -1
- package/dist/domain/skill/controller.js +35 -22
- package/dist/domain/skill/controller.js.map +1 -1
- package/dist/domain/skill/push.d.ts +2 -2
- package/dist/domain/skill/push.d.ts.map +1 -1
- package/dist/domain/skill/push.js +2 -2
- package/dist/domain/skill/push.js.map +1 -1
- package/dist/domain/skill/transfer/handler.d.ts +17 -9
- package/dist/domain/skill/transfer/handler.d.ts.map +1 -1
- package/dist/domain/skill/transfer/handler.js +19 -8
- package/dist/domain/skill/transfer/handler.js.map +1 -1
- package/dist/domain/skill/transfer/slots.d.ts +26 -41
- package/dist/domain/skill/transfer/slots.d.ts.map +1 -1
- package/dist/domain/skill/transfer/slots.js +80 -87
- package/dist/domain/skill/transfer/slots.js.map +1 -1
- package/dist/domain/skill/transfer/staging.d.ts +48 -0
- package/dist/domain/skill/transfer/staging.d.ts.map +1 -0
- package/dist/domain/skill/transfer/staging.js +127 -0
- package/dist/domain/skill/transfer/staging.js.map +1 -0
- package/dist/domain/workflow/controller.d.ts.map +1 -1
- package/dist/domain/workflow/controller.js +6 -14
- package/dist/domain/workflow/controller.js.map +1 -1
- package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -1
- package/dist/domain/workflow/validation/task-config-constraints.d.ts +1 -10
- package/dist/domain/workflow/validation/task-config-constraints.d.ts.map +1 -1
- package/dist/domain/workflow/validation/task-config-constraints.js +2 -3
- package/dist/domain/workflow/validation/task-config-constraints.js.map +1 -1
- package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
- package/dist/domain/workflowexecution/controller.js +2 -4
- package/dist/domain/workflowexecution/controller.js.map +1 -1
- package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
- package/dist/domain/workflowinstance/controller.js +4 -3
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/extensions/authorization-queries.d.ts +5 -6
- package/dist/extensions/authorization-queries.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +1 -1
- package/dist/extensions/resource-authorization.d.ts +2 -3
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/apiresource-meta.d.ts +3 -12
- package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
- package/dist/pipeline/apiresource-meta.js +10 -21
- package/dist/pipeline/apiresource-meta.js.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts +3 -9
- package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.js +11 -9
- package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
- package/dist/pipeline/steps/references.d.ts +20 -178
- package/dist/pipeline/steps/references.d.ts.map +1 -1
- package/dist/pipeline/steps/references.js +43 -344
- package/dist/pipeline/steps/references.js.map +1 -1
- package/dist/pipeline/steps/resolve-artifact-source.d.ts +11 -8
- package/dist/pipeline/steps/resolve-artifact-source.d.ts.map +1 -1
- package/dist/pipeline/steps/resolve-artifact-source.js +8 -4
- package/dist/pipeline/steps/resolve-artifact-source.js.map +1 -1
- package/dist/pipeline/steps/visibility-gates.d.ts +27 -0
- package/dist/pipeline/steps/visibility-gates.d.ts.map +1 -0
- package/dist/pipeline/steps/visibility-gates.js +139 -0
- package/dist/pipeline/steps/visibility-gates.js.map +1 -0
- package/dist/query/search/controller.js +1 -0
- package/dist/query/search/controller.js.map +1 -1
- package/dist/query/search/criteria.d.ts +5 -1
- package/dist/query/search/criteria.d.ts.map +1 -1
- package/dist/query/search/criteria.js +13 -3
- package/dist/query/search/criteria.js.map +1 -1
- package/dist/query/search/handler.d.ts +4 -5
- package/dist/query/search/handler.d.ts.map +1 -1
- package/dist/query/search/handler.js +6 -7
- package/dist/query/search/handler.js.map +1 -1
- package/dist/query/search/query-store.d.ts.map +1 -1
- package/dist/query/search/query-store.js +2 -0
- package/dist/query/search/query-store.js.map +1 -1
- package/dist/store/interface.d.ts +6 -3
- package/dist/store/interface.d.ts.map +1 -1
- package/dist/store/interface.js.map +1 -1
- package/dist/store/postgres/migrations.d.ts +1 -3
- package/dist/store/postgres/migrations.d.ts.map +1 -1
- package/dist/store/postgres/migrations.js +1 -35
- package/dist/store/postgres/migrations.js.map +1 -1
- package/dist/store/postgres/store.d.ts.map +1 -1
- package/dist/store/postgres/store.js +9 -4
- package/dist/store/postgres/store.js.map +1 -1
- package/dist/store/sqlite/migrations.d.ts +1 -3
- package/dist/store/sqlite/migrations.d.ts.map +1 -1
- package/dist/store/sqlite/migrations.js +1 -36
- package/dist/store/sqlite/migrations.js.map +1 -1
- package/dist/store/sqlite/store.d.ts.map +1 -1
- package/dist/store/sqlite/store.js +8 -4
- package/dist/store/sqlite/store.js.map +1 -1
- package/package.json +6 -6
- package/src/artifactstorage/__tests__/artifact-storage.test.ts +36 -33
- package/src/artifactstorage/__tests__/r2-storage.test.ts +11 -13
- package/src/artifactstorage/artifact-storage.ts +37 -33
- package/src/artifactstorage/r2-storage.ts +6 -15
- package/src/authorization/README.md +26 -24
- package/src/authorization/__tests__/authorizer.test.ts +9 -10
- package/src/authorization/__tests__/derived-tuples.test.ts +11 -4
- package/src/authorization/__tests__/evaluator.test.ts +73 -14
- package/src/authorization/__tests__/facts.test.ts +2 -2
- package/src/authorization/__tests__/fixtures/fga/agent-instance-creation.fga.yaml +185 -0
- package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +98 -6
- package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +98 -0
- package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +61 -4
- package/src/authorization/__tests__/fixtures/fga/mcp-server-authoring.fga.yaml +143 -0
- package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +21 -1
- package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +25 -1
- package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +52 -0
- package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +3 -1
- package/src/authorization/__tests__/list-read-scope.test.ts +17 -18
- package/src/authorization/__tests__/store-tests.test.ts +8 -1
- package/src/authorization/__tests__/tuples.test.ts +11 -12
- package/src/authorization/authorizer.ts +9 -4
- package/src/authorization/derived-tuples.ts +31 -14
- package/src/authorization/evaluator.ts +44 -8
- package/src/authorization/list-read-scope.ts +11 -5
- package/src/authorization/model/agent.ts +5 -2
- package/src/authorization/model/agent_instance.ts +2 -0
- package/src/authorization/model/mcp_server.ts +2 -0
- package/src/authorization/model/plugin.ts +4 -1
- package/src/authorization/model/rewrite.ts +13 -8
- package/src/authorization/model/skill.ts +2 -0
- package/src/authorization/model/workflow.ts +2 -0
- package/src/authorization/model/workflow_instance.ts +2 -0
- package/src/authorization/organization-directory.ts +3 -1
- package/src/authorization/store-test-kit.ts +75 -16
- package/src/authorization/tuples.ts +39 -16
- package/src/boot/__tests__/skill-transfer-origin.test.ts +72 -0
- package/src/boot/compose.ts +62 -25
- package/src/boot/config.ts +4 -3
- package/src/boot/skill-transfer-origin.ts +76 -0
- package/src/domain/agent/__tests__/agent.test.ts +4 -11
- package/src/domain/agent/controller.ts +7 -7
- package/src/domain/agentchannel/__tests__/agentchannel.test.ts +48 -223
- package/src/domain/agentchannel/controller.ts +1 -6
- package/src/domain/agentexecution/controller.ts +1 -6
- package/src/domain/agentinstance/controller.ts +12 -6
- package/src/domain/agentshare/__tests__/agentshare.test.ts +172 -196
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +31 -16
- package/src/domain/agentshare/constants.ts +26 -14
- package/src/domain/agentshare/controller.ts +1 -6
- package/src/domain/agentshare/steps.ts +194 -41
- package/src/domain/environment/controller.ts +8 -5
- package/src/domain/executioncontext/controller.ts +1 -5
- package/src/domain/mcpserver/__tests__/mcpserver.test.ts +28 -115
- package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +18 -53
- package/src/domain/mcpserver/controller.ts +12 -6
- package/src/domain/plugin/controller.ts +23 -18
- package/src/domain/plugin/push.ts +16 -8
- package/src/domain/schedule/controller.ts +1 -6
- package/src/domain/session/controller.ts +4 -12
- package/src/domain/skill/__tests__/skill.test.ts +5 -3
- package/src/domain/skill/__tests__/slots.test.ts +113 -60
- package/src/domain/skill/__tests__/staging.test.ts +304 -0
- package/src/domain/skill/constants.ts +28 -3
- package/src/domain/skill/controller.ts +51 -35
- package/src/domain/skill/push.ts +3 -3
- package/src/domain/skill/transfer/handler.ts +33 -15
- package/src/domain/skill/transfer/slots.ts +89 -100
- package/src/domain/skill/transfer/staging.ts +191 -0
- package/src/domain/workflow/controller.ts +10 -28
- package/src/domain/workflow/registry/data/task-kind-registry.json +1 -1
- package/src/domain/workflow/validation/task-config-constraints.ts +3 -7
- package/src/domain/workflowexecution/controller.ts +2 -7
- package/src/domain/workflowinstance/controller.ts +12 -6
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +19 -32
- package/src/extensions/__tests__/extension-composition.test.ts +4 -4
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +6 -9
- package/src/extensions/authorization-queries.ts +5 -6
- package/src/extensions/list-read-scope.ts +1 -1
- package/src/extensions/resource-authorization.ts +5 -3
- package/src/index.ts +14 -0
- package/src/pipeline/apiresource-meta.ts +10 -21
- package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +31 -18
- package/src/pipeline/steps/__tests__/visibility-gates.test.ts +187 -0
- package/src/pipeline/steps/authorization-tuples.ts +11 -9
- package/src/pipeline/steps/references.ts +70 -578
- package/src/pipeline/steps/resolve-artifact-source.ts +20 -13
- package/src/pipeline/steps/visibility-gates.ts +174 -0
- package/src/query/search/__tests__/criteria.test.ts +4 -0
- package/src/query/search/__tests__/query-store.test.ts +40 -11
- package/src/query/search/controller.ts +1 -0
- package/src/query/search/criteria.ts +14 -0
- package/src/query/search/handler.ts +7 -6
- package/src/query/search/query-store.ts +2 -0
- package/src/store/__tests__/store-contract.ts +51 -6
- package/src/store/interface.ts +6 -3
- package/src/store/postgres/__tests__/migrations.test.ts +6 -187
- package/src/store/postgres/__tests__/store-contract.test.ts +2 -0
- package/src/store/postgres/migrations.ts +1 -48
- package/src/store/postgres/store.ts +11 -4
- package/src/store/sqlite/__tests__/migrations.test.ts +5 -191
- package/src/store/sqlite/migrations.ts +1 -45
- package/src/store/sqlite/store.ts +10 -4
- package/src/transport/registry/__tests__/lanes.test.ts +1 -1
- package/dist/domain/workflow/agent-call-references.d.ts +0 -54
- package/dist/domain/workflow/agent-call-references.d.ts.map +0 -1
- package/dist/domain/workflow/agent-call-references.js +0 -97
- package/dist/domain/workflow/agent-call-references.js.map +0 -1
- package/dist/store/public-visibility-retired.d.ts +0 -67
- package/dist/store/public-visibility-retired.d.ts.map +0 -1
- package/dist/store/public-visibility-retired.js +0 -55
- package/dist/store/public-visibility-retired.js.map +0 -1
- package/src/domain/workflow/__tests__/agent-call-references.test.ts +0 -222
- package/src/domain/workflow/agent-call-references.ts +0 -157
- package/src/pipeline/__tests__/supports-visibility.test.ts +0 -112
- package/src/pipeline/steps/__tests__/references.test.ts +0 -703
- package/src/store/__tests__/public-visibility-retired.test.ts +0 -127
- package/src/store/public-visibility-retired.ts +0 -119
|
@@ -52,6 +52,10 @@ import {
|
|
|
52
52
|
newAuthorizeResolvedTargetStep,
|
|
53
53
|
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
54
54
|
import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
|
|
55
|
+
import {
|
|
56
|
+
newAuthorizeVisibilityTransitionStep,
|
|
57
|
+
newGuardPublicVisibilityStep,
|
|
58
|
+
} from "../../pipeline/steps/visibility-gates.js";
|
|
55
59
|
import {
|
|
56
60
|
newBuildNewStateStep,
|
|
57
61
|
setAuditFieldsForUpdate,
|
|
@@ -81,10 +85,7 @@ import {
|
|
|
81
85
|
TARGET_RESOURCE_KEY,
|
|
82
86
|
newLoadTargetStep,
|
|
83
87
|
} from "../../pipeline/steps/load-target.js";
|
|
84
|
-
import {
|
|
85
|
-
newNormalizeReferencesStep,
|
|
86
|
-
newValidateReferencesStep,
|
|
87
|
-
} from "../../pipeline/steps/references.js";
|
|
88
|
+
import { newNormalizeReferencesStep } from "../../pipeline/steps/references.js";
|
|
88
89
|
import {
|
|
89
90
|
newCleanupIamPoliciesStep,
|
|
90
91
|
newCreateAuthorizationTuplesStep,
|
|
@@ -195,9 +196,9 @@ async function createInstance(
|
|
|
195
196
|
)
|
|
196
197
|
.addStep(newCheckDuplicateStep(deps.store))
|
|
197
198
|
.addStep(newBuildNewStateStep())
|
|
199
|
+
.addStep(newGuardPublicVisibilityStep(deps.authorizer))
|
|
198
200
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
199
201
|
.addStep(newNormalizeReferencesStep())
|
|
200
|
-
.addStep(newValidateReferencesStep(deps.store))
|
|
201
202
|
.addStep(newPersistStep(deps.store))
|
|
202
203
|
.addStep(
|
|
203
204
|
newCreateAuthorizationTuplesStep(
|
|
@@ -242,7 +243,6 @@ async function update(
|
|
|
242
243
|
.addStep(newBuildUpdateStateStep())
|
|
243
244
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
244
245
|
.addStep(newNormalizeReferencesStep())
|
|
245
|
-
.addStep(newValidateReferencesStep(deps.store))
|
|
246
246
|
.addStep(newPersistStep(deps.store))
|
|
247
247
|
.addStep(
|
|
248
248
|
newIndexSearchStep(deps.store, agentInstanceSearchExtractor, deps.logger),
|
|
@@ -383,6 +383,12 @@ async function updateVisibility(
|
|
|
383
383
|
)
|
|
384
384
|
.addStep(newRejectDefaultInstanceVisibilityUpdateStep(deps.store))
|
|
385
385
|
.addStep(newValidateVisibilityUpdateStep())
|
|
386
|
+
.addStep(
|
|
387
|
+
newAuthorizeVisibilityTransitionStep(
|
|
388
|
+
UPDATE_VISIBILITY_INSTANCE_KEY,
|
|
389
|
+
deps.authorizer,
|
|
390
|
+
),
|
|
391
|
+
)
|
|
386
392
|
.addStep(newSetInstanceVisibilityStep())
|
|
387
393
|
.addStep(newPersistInstanceForVisibilityUpdateStep(deps.store))
|
|
388
394
|
.addStep(
|
|
@@ -33,10 +33,8 @@ import { AgentCommandController } from "@stigmer/protos/ai/stigmer/agentic/agent
|
|
|
33
33
|
import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
34
34
|
import { AgentShareCommandController } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/command_pb";
|
|
35
35
|
import { AgentShareQueryController } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/query_pb";
|
|
36
|
-
import { AgentShareSchema } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/api_pb";
|
|
37
36
|
import type { AgentShare } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/api_pb";
|
|
38
37
|
import { AgentShareAudience } from "@stigmer/protos/ai/stigmer/agentic/agentshare/v1/spec_pb";
|
|
39
|
-
import { EnvironmentSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
|
|
40
38
|
import { SkillSchema } from "@stigmer/protos/ai/stigmer/agentic/skill/v1/api_pb";
|
|
41
39
|
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
42
40
|
import { ApiResourceReferenceSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
|
|
@@ -49,15 +47,11 @@ import { createLogger } from "../../../boot/logger.js";
|
|
|
49
47
|
import type { Store } from "../../../store/interface.js";
|
|
50
48
|
import {
|
|
51
49
|
ORG_REQUIRED_FOR_LOOKUP_MESSAGE,
|
|
52
|
-
|
|
50
|
+
crossOrgAudienceMessage,
|
|
53
51
|
} from "../constants.js";
|
|
54
52
|
import { findShareByOrgAndSlug, sharingLinkTokenAllowed } from "../steps.js";
|
|
55
53
|
|
|
56
|
-
const silentLogger = createLogger({
|
|
57
|
-
level: "error",
|
|
58
|
-
pretty: false,
|
|
59
|
-
write: () => {},
|
|
60
|
-
});
|
|
54
|
+
const silentLogger = createLogger({ level: "error", pretty: false, write: () => {} });
|
|
61
55
|
|
|
62
56
|
const API_VERSION = "agentic.stigmer.ai/v1";
|
|
63
57
|
|
|
@@ -74,10 +68,7 @@ let dir: string;
|
|
|
74
68
|
beforeAll(async () => {
|
|
75
69
|
dir = mkdtempSync(path.join(tmpdir(), "agentshare-domain-test-"));
|
|
76
70
|
vi.stubEnv("STIGMER_ENCRYPTION_KEY", Buffer.alloc(32, 7).toString("base64"));
|
|
77
|
-
vi.stubEnv(
|
|
78
|
-
"STIGMER_RUNNER_TOKEN_KEY",
|
|
79
|
-
Buffer.alloc(32, 8).toString("base64"),
|
|
80
|
-
);
|
|
71
|
+
vi.stubEnv("STIGMER_RUNNER_TOKEN_KEY", Buffer.alloc(32, 8).toString("base64"));
|
|
81
72
|
server = await composeServer({
|
|
82
73
|
config: loadConfig({
|
|
83
74
|
STIGMER_MODEL_REGISTRY_REFRESH: "off",
|
|
@@ -127,6 +118,13 @@ async function createTestAgent(name: string, org: string): Promise<Agent> {
|
|
|
127
118
|
}
|
|
128
119
|
|
|
129
120
|
/** Flips the agent marketplace-public through the real pipeline (D1). */
|
|
121
|
+
async function makeAgentPublic(agent: Agent): Promise<void> {
|
|
122
|
+
await agents.updateVisibility({
|
|
123
|
+
resourceId: agent.metadata!.id,
|
|
124
|
+
visibility: ApiResourceVisibility.visibility_public,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
130
128
|
/**
|
|
131
129
|
* Writes a skill fixture directly to the store — the established
|
|
132
130
|
* cross-domain fixture pattern (the skill domain is not ported yet, and
|
|
@@ -144,12 +142,7 @@ async function saveSkill(
|
|
|
144
142
|
kind: "Skill",
|
|
145
143
|
metadata: { id, name: slug, slug, org, visibility },
|
|
146
144
|
});
|
|
147
|
-
await server.store.saveResource(
|
|
148
|
-
ApiResourceKind.skill,
|
|
149
|
-
id,
|
|
150
|
-
SkillSchema,
|
|
151
|
-
skill,
|
|
152
|
-
);
|
|
145
|
+
await server.store.saveResource(ApiResourceKind.skill, id, SkillSchema, skill);
|
|
153
146
|
}
|
|
154
147
|
|
|
155
148
|
/** Minimal canonical share: no slug, no name — both default from the agent. */
|
|
@@ -185,10 +178,7 @@ describe("agentshare create", () => {
|
|
|
185
178
|
const ORG = "create-test-org";
|
|
186
179
|
|
|
187
180
|
it("canonical share defaults slug and name from the agent; ash_ id; ref normalized", async () => {
|
|
188
|
-
const agent = await createTestAgent(
|
|
189
|
-
uniqueName("Canonical Default Agent"),
|
|
190
|
-
ORG,
|
|
191
|
-
);
|
|
181
|
+
const agent = await createTestAgent(uniqueName("Canonical Default Agent"), ORG);
|
|
192
182
|
const share = await shares.create(shareFor(agent, true));
|
|
193
183
|
|
|
194
184
|
expect(share.metadata?.slug).toBe(agent.metadata!.slug);
|
|
@@ -212,20 +202,13 @@ describe("agentshare create", () => {
|
|
|
212
202
|
expect(err.rawMessage).toBe("Agent not found: no-such-agent");
|
|
213
203
|
});
|
|
214
204
|
|
|
215
|
-
it("
|
|
216
|
-
const agent = await createTestAgent(
|
|
217
|
-
uniqueName("Cross Org Ghost Agent"),
|
|
218
|
-
ORG,
|
|
219
|
-
);
|
|
205
|
+
it("cross-org ref to a nonexistent agent is NOT_FOUND — no cross-org fallback", async () => {
|
|
206
|
+
const agent = await createTestAgent(uniqueName("Cross Org Ghost Agent"), ORG);
|
|
220
207
|
const share = shareFor(agent, true);
|
|
221
|
-
share.spec.agentRef = {
|
|
222
|
-
...share.spec.agentRef,
|
|
223
|
-
org: "some-other-org",
|
|
224
|
-
} as never;
|
|
208
|
+
share.spec.agentRef = { ...share.spec.agentRef, org: "some-other-org" } as never;
|
|
225
209
|
|
|
226
210
|
const err = await grpcError(() => shares.create(share));
|
|
227
|
-
expect(err.code).toBe(Code.
|
|
228
|
-
expect(err.rawMessage).toBe(sameOrgInvariantMessage("some-other-org"));
|
|
211
|
+
expect(err.code).toBe(Code.NotFound);
|
|
229
212
|
});
|
|
230
213
|
|
|
231
214
|
it("stamps the agent-id pin on the created share", async () => {
|
|
@@ -253,10 +236,7 @@ describe("agentshare create", () => {
|
|
|
253
236
|
});
|
|
254
237
|
|
|
255
238
|
it("second canonical share for the same agent is ALREADY_EXISTS", async () => {
|
|
256
|
-
const agent = await createTestAgent(
|
|
257
|
-
uniqueName("Duplicate Share Agent"),
|
|
258
|
-
ORG,
|
|
259
|
-
);
|
|
239
|
+
const agent = await createTestAgent(uniqueName("Duplicate Share Agent"), ORG);
|
|
260
240
|
await shares.create(shareFor(agent, true));
|
|
261
241
|
|
|
262
242
|
const err = await grpcError(() => shares.create(shareFor(agent, true)));
|
|
@@ -268,8 +248,7 @@ describe("agentshare create", () => {
|
|
|
268
248
|
await shares.create(shareFor(agent, true));
|
|
269
249
|
|
|
270
250
|
const named = shareFor(agent, true);
|
|
271
|
-
(named.metadata as Record<string, string>).name =
|
|
272
|
-
uniqueName("Docs Site Channel");
|
|
251
|
+
(named.metadata as Record<string, string>).name = uniqueName("Docs Site Channel");
|
|
273
252
|
const second = await shares.create(named);
|
|
274
253
|
expect(second.metadata?.slug).not.toBe(agent.metadata!.slug);
|
|
275
254
|
});
|
|
@@ -285,10 +264,7 @@ describe("launch-gate config", () => {
|
|
|
285
264
|
const ORG = "launchgate-test-org";
|
|
286
265
|
|
|
287
266
|
it("allowed_origins and messages persist and round-trip", async () => {
|
|
288
|
-
const agent = await createTestAgent(
|
|
289
|
-
uniqueName("Launch Gate Config Agent"),
|
|
290
|
-
ORG,
|
|
291
|
-
);
|
|
267
|
+
const agent = await createTestAgent(uniqueName("Launch Gate Config Agent"), ORG);
|
|
292
268
|
const created = await shares.create({
|
|
293
269
|
...shareFor(agent, true),
|
|
294
270
|
spec: {
|
|
@@ -313,10 +289,7 @@ describe("launch-gate config", () => {
|
|
|
313
289
|
});
|
|
314
290
|
|
|
315
291
|
it("malformed origins are INVALID_ARGUMENT", async () => {
|
|
316
|
-
const agent = await createTestAgent(
|
|
317
|
-
uniqueName("Origin Validation Agent"),
|
|
318
|
-
ORG,
|
|
319
|
-
);
|
|
292
|
+
const agent = await createTestAgent(uniqueName("Origin Validation Agent"), ORG);
|
|
320
293
|
for (const origin of [
|
|
321
294
|
"docs.example.com", // missing scheme
|
|
322
295
|
"https://example.com/path", // path not allowed
|
|
@@ -335,10 +308,7 @@ describe("launch-gate config", () => {
|
|
|
335
308
|
});
|
|
336
309
|
|
|
337
310
|
it("overlong custom message is INVALID_ARGUMENT", async () => {
|
|
338
|
-
const agent = await createTestAgent(
|
|
339
|
-
uniqueName("Message Length Agent"),
|
|
340
|
-
ORG,
|
|
341
|
-
);
|
|
311
|
+
const agent = await createTestAgent(uniqueName("Message Length Agent"), ORG);
|
|
342
312
|
const err = await grpcError(() =>
|
|
343
313
|
shares.create({
|
|
344
314
|
...shareFor(agent, true),
|
|
@@ -352,27 +322,7 @@ describe("launch-gate config", () => {
|
|
|
352
322
|
});
|
|
353
323
|
|
|
354
324
|
it("environment_refs on an org-audience share is INVALID_ARGUMENT; public persists", async () => {
|
|
355
|
-
const agent = await createTestAgent(
|
|
356
|
-
uniqueName("Env Refs Audience Agent"),
|
|
357
|
-
ORG,
|
|
358
|
-
);
|
|
359
|
-
// The environment must exist when the share is written (the reference rule).
|
|
360
|
-
await server.store.saveResource(
|
|
361
|
-
ApiResourceKind.environment,
|
|
362
|
-
"env_shared_credentials",
|
|
363
|
-
EnvironmentSchema,
|
|
364
|
-
create(EnvironmentSchema, {
|
|
365
|
-
apiVersion: "agentic.stigmer.ai/v1",
|
|
366
|
-
kind: "Environment",
|
|
367
|
-
metadata: {
|
|
368
|
-
id: "env_shared_credentials",
|
|
369
|
-
name: "shared-credentials",
|
|
370
|
-
slug: "shared-credentials",
|
|
371
|
-
org: ORG,
|
|
372
|
-
visibility: ApiResourceVisibility.visibility_org,
|
|
373
|
-
},
|
|
374
|
-
}),
|
|
375
|
-
);
|
|
325
|
+
const agent = await createTestAgent(uniqueName("Env Refs Audience Agent"), ORG);
|
|
376
326
|
const envRef = {
|
|
377
327
|
kind: ApiResourceKind.environment,
|
|
378
328
|
org: ORG,
|
|
@@ -428,14 +378,8 @@ describe("agentshare update", () => {
|
|
|
428
378
|
});
|
|
429
379
|
|
|
430
380
|
it("agent_ref is immutable — FAILED_PRECONDITION with the pinned copy", async () => {
|
|
431
|
-
const agentA = await createTestAgent(
|
|
432
|
-
|
|
433
|
-
ORG,
|
|
434
|
-
);
|
|
435
|
-
const agentB = await createTestAgent(
|
|
436
|
-
uniqueName("Immutable Ref Agent B"),
|
|
437
|
-
ORG,
|
|
438
|
-
);
|
|
381
|
+
const agentA = await createTestAgent(uniqueName("Immutable Ref Agent A"), ORG);
|
|
382
|
+
const agentB = await createTestAgent(uniqueName("Immutable Ref Agent B"), ORG);
|
|
439
383
|
const created = await shares.create(shareFor(agentA, true));
|
|
440
384
|
|
|
441
385
|
created.spec!.agentRef = create(ApiResourceReferenceSchema, {
|
|
@@ -453,83 +397,146 @@ describe("agentshare update", () => {
|
|
|
453
397
|
// Cross-org contract (Go TestAgentShareController_CrossOrg, decision 013).
|
|
454
398
|
// ---------------------------------------------------------------------------
|
|
455
399
|
|
|
456
|
-
describe("
|
|
400
|
+
describe("cross-org shares (decision 013)", () => {
|
|
457
401
|
const PROVIDER = "provider-org";
|
|
458
402
|
const CONSUMER = "consumer-org";
|
|
459
403
|
|
|
460
|
-
function
|
|
404
|
+
function crossOrgShare(agent: Agent, enabled: boolean) {
|
|
461
405
|
const share = shareFor(agent, enabled);
|
|
462
406
|
share.metadata.org = CONSUMER;
|
|
463
|
-
share.spec.agentRef = {
|
|
464
|
-
...share.spec.agentRef,
|
|
465
|
-
org: agent.metadata!.org,
|
|
466
|
-
} as never;
|
|
407
|
+
share.spec.agentRef = { ...share.spec.agentRef, org: agent.metadata!.org } as never;
|
|
467
408
|
return share;
|
|
468
409
|
}
|
|
469
410
|
|
|
470
|
-
it("
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
);
|
|
478
|
-
expect(
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
411
|
+
it("public agent is shareable cross-org: pin stamped, slug defaulted, profile resolves", async () => {
|
|
412
|
+
const agent = await createTestAgent(uniqueName("Public Provider Agent"), PROVIDER);
|
|
413
|
+
await makeAgentPublic(agent);
|
|
414
|
+
|
|
415
|
+
const created = await shares.create(crossOrgShare(agent, true));
|
|
416
|
+
expect(created.metadata?.org).toBe(CONSUMER);
|
|
417
|
+
expect(created.spec?.agentRef?.org).toBe(PROVIDER);
|
|
418
|
+
expect(created.metadata?.slug).toBe(agent.metadata!.slug);
|
|
419
|
+
expect(created.status?.agentId).toBe(agent.metadata!.id);
|
|
420
|
+
|
|
421
|
+
const profile = await query.getSharedProfile({
|
|
422
|
+
org: CONSUMER,
|
|
423
|
+
slug: created.metadata!.slug,
|
|
424
|
+
});
|
|
425
|
+
expect(profile.org).toBe(CONSUMER);
|
|
426
|
+
expect(profile.name).toBe(agent.metadata!.name);
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
it("non-public agent is NOT_FOUND, indistinguishable from absence", async () => {
|
|
430
|
+
const agent = await createTestAgent(uniqueName("Private Provider Agent"), PROVIDER);
|
|
431
|
+
|
|
432
|
+
const err = await grpcError(() => shares.create(crossOrgShare(agent, true)));
|
|
433
|
+
expect(err.code).toBe(Code.NotFound);
|
|
434
|
+
|
|
435
|
+
// The refusal must match a genuinely missing agent — no existence
|
|
436
|
+
// probe for private slugs (the T09 indistinguishability contract).
|
|
437
|
+
const ghost = crossOrgShare(agent, true);
|
|
438
|
+
ghost.spec.agentRef = { ...ghost.spec.agentRef, org: "empty-provider-org" } as never;
|
|
488
439
|
const ghostErr = await grpcError(() => shares.create(ghost));
|
|
489
|
-
expect(
|
|
490
|
-
expect(ghostErr.rawMessage).toBe(sameOrgInvariantMessage(PROVIDER));
|
|
440
|
+
expect(err.rawMessage).toBe(ghostErr.rawMessage);
|
|
491
441
|
});
|
|
492
442
|
|
|
493
|
-
it("
|
|
494
|
-
const agent = await createTestAgent(
|
|
495
|
-
|
|
443
|
+
it("org audience is refused cross-org, on create and on update", async () => {
|
|
444
|
+
const agent = await createTestAgent(uniqueName("Audience Rule Agent"), PROVIDER);
|
|
445
|
+
await makeAgentPublic(agent);
|
|
446
|
+
|
|
447
|
+
const orgAudience = crossOrgShare(agent, true);
|
|
448
|
+
(orgAudience.spec as Record<string, unknown>).audience = AgentShareAudience.org;
|
|
449
|
+
const createErr = await grpcError(() => shares.create(orgAudience));
|
|
450
|
+
expect(createErr.code).toBe(Code.FailedPrecondition);
|
|
451
|
+
expect(createErr.rawMessage).toBe(crossOrgAudienceMessage(PROVIDER));
|
|
452
|
+
|
|
453
|
+
const created = await shares.create(crossOrgShare(agent, true));
|
|
454
|
+
created.spec!.audience = AgentShareAudience.org;
|
|
455
|
+
const updateErr = await grpcError(() => shares.update(created));
|
|
456
|
+
expect(updateErr.code).toBe(Code.FailedPrecondition);
|
|
457
|
+
expect(updateErr.rawMessage).toBe(crossOrgAudienceMessage(PROVIDER));
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
it("non-public dependencies block creation, naming every blocker sorted", async () => {
|
|
461
|
+
await saveSkill(
|
|
462
|
+
"skl_private_dep",
|
|
496
463
|
PROVIDER,
|
|
464
|
+
"private-skill",
|
|
465
|
+
ApiResourceVisibility.visibility_private,
|
|
497
466
|
);
|
|
498
|
-
|
|
499
|
-
|
|
467
|
+
await saveSkill(
|
|
468
|
+
"skl_public_dep",
|
|
469
|
+
PROVIDER,
|
|
470
|
+
"public-skill",
|
|
471
|
+
ApiResourceVisibility.visibility_public,
|
|
472
|
+
);
|
|
473
|
+
|
|
474
|
+
const agent = await agents.create({
|
|
500
475
|
apiVersion: API_VERSION,
|
|
501
|
-
kind: "
|
|
502
|
-
metadata: {
|
|
503
|
-
id: "ash_legacy_cross_org",
|
|
504
|
-
name: "legacy-cross-org",
|
|
505
|
-
slug: "legacy-cross-org",
|
|
506
|
-
org: CONSUMER,
|
|
507
|
-
},
|
|
476
|
+
kind: "Agent",
|
|
477
|
+
metadata: { name: uniqueName("Tooling Agent"), org: PROVIDER },
|
|
508
478
|
spec: {
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
enabled: true,
|
|
515
|
-
audience: AgentShareAudience.public,
|
|
479
|
+
instructions: "You are a tool-using cross-org test agent.",
|
|
480
|
+
skillRefs: [
|
|
481
|
+
{ kind: ApiResourceKind.skill, slug: "private-skill" },
|
|
482
|
+
{ kind: ApiResourceKind.skill, slug: "public-skill" },
|
|
483
|
+
],
|
|
516
484
|
},
|
|
517
|
-
status: { agentId: agent.metadata!.id },
|
|
518
485
|
});
|
|
519
|
-
await
|
|
520
|
-
ApiResourceKind.agent_share,
|
|
521
|
-
legacy.metadata!.id,
|
|
522
|
-
AgentShareSchema,
|
|
523
|
-
legacy,
|
|
524
|
-
);
|
|
486
|
+
await makeAgentPublic(agent);
|
|
525
487
|
|
|
526
|
-
const err = await grpcError(() =>
|
|
527
|
-
|
|
528
|
-
);
|
|
488
|
+
const err = await grpcError(() => shares.create(crossOrgShare(agent, true)));
|
|
489
|
+
expect(err.code).toBe(Code.FailedPrecondition);
|
|
490
|
+
expect(err.rawMessage).toContain("provider-org/private-skill");
|
|
491
|
+
expect(err.rawMessage).not.toContain("public-skill");
|
|
492
|
+
|
|
493
|
+
// Same-org sharing of the same agent stays unaffected — the sweep is
|
|
494
|
+
// a cross-org rule only.
|
|
495
|
+
await shares.create(shareFor(agent, true));
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
it("visibility flip fails the profile closed", async () => {
|
|
499
|
+
const agent = await createTestAgent(uniqueName("Revocable Agent"), PROVIDER);
|
|
500
|
+
await makeAgentPublic(agent);
|
|
501
|
+
const created = await shares.create(crossOrgShare(agent, true));
|
|
502
|
+
|
|
503
|
+
const ref = { org: CONSUMER, slug: created.metadata!.slug };
|
|
504
|
+
await query.getSharedProfile(ref);
|
|
505
|
+
|
|
506
|
+
await agents.updateVisibility({
|
|
507
|
+
resourceId: agent.metadata!.id,
|
|
508
|
+
visibility: ApiResourceVisibility.visibility_private,
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
const err = await grpcError(() => query.getSharedProfile(ref));
|
|
529
512
|
expect(err.code).toBe(Code.NotFound);
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
it("agent delete leaves the cross-org share failing closed; recreate never rebinds", async () => {
|
|
516
|
+
const name = uniqueName("Ephemeral Provider Agent");
|
|
517
|
+
const agent = await createTestAgent(name, PROVIDER);
|
|
518
|
+
await makeAgentPublic(agent);
|
|
519
|
+
const created = await shares.create(crossOrgShare(agent, true));
|
|
520
|
+
const ref = { org: CONSUMER, slug: created.metadata!.slug };
|
|
521
|
+
|
|
522
|
+
await agents.delete({ value: agent.metadata!.id });
|
|
523
|
+
|
|
524
|
+
// The consumer org's share survives the provider's delete (cross-org
|
|
525
|
+
// shares are NOT cascaded — not the provider's resource to destroy)
|
|
526
|
+
// but fails closed.
|
|
527
|
+
const survived = await query.get({ value: created.metadata!.id });
|
|
528
|
+
expect(survived.status?.agentId).toBe(agent.metadata!.id);
|
|
529
|
+
const danglingErr = await grpcError(() => query.getSharedProfile(ref));
|
|
530
|
+
expect(danglingErr.code).toBe(Code.NotFound);
|
|
531
|
+
|
|
532
|
+
// A DIFFERENT public agent later claims the same org/slug: the pin
|
|
533
|
+
// must keep the old share dark.
|
|
534
|
+
const recreated = await createTestAgent(name, PROVIDER);
|
|
535
|
+
await makeAgentPublic(recreated);
|
|
536
|
+
expect(recreated.metadata!.slug).toBe(agent.metadata!.slug);
|
|
537
|
+
|
|
538
|
+
const rebindErr = await grpcError(() => query.getSharedProfile(ref));
|
|
539
|
+
expect(rebindErr.code).toBe(Code.NotFound);
|
|
533
540
|
});
|
|
534
541
|
});
|
|
535
542
|
|
|
@@ -541,18 +548,13 @@ describe("getSharedProfile (anonymous lane)", () => {
|
|
|
541
548
|
const ORG = "profile-test-org";
|
|
542
549
|
|
|
543
550
|
it("uniform NotFound across no-share / disabled / deleted; enabled resolves trimmed", async () => {
|
|
544
|
-
const agent = await createTestAgent(
|
|
545
|
-
uniqueName("Shared Profile Agent"),
|
|
546
|
-
ORG,
|
|
547
|
-
);
|
|
551
|
+
const agent = await createTestAgent(uniqueName("Shared Profile Agent"), ORG);
|
|
548
552
|
const ref = { org: ORG, slug: agent.metadata!.slug };
|
|
549
553
|
|
|
550
554
|
// No share yet.
|
|
551
555
|
const noShareErr = await grpcError(() => query.getSharedProfile(ref));
|
|
552
556
|
expect(noShareErr.code).toBe(Code.NotFound);
|
|
553
|
-
expect(noShareErr.rawMessage).toBe(
|
|
554
|
-
`Agent not found: ${agent.metadata!.slug}`,
|
|
555
|
-
);
|
|
557
|
+
expect(noShareErr.rawMessage).toBe(`Agent not found: ${agent.metadata!.slug}`);
|
|
556
558
|
|
|
557
559
|
// Enabled share resolves to the trimmed profile — display fields from
|
|
558
560
|
// the AGENT, URL identity from the SHARE, never the full Agent.
|
|
@@ -607,10 +609,7 @@ describe("audience and the member resolution lane", () => {
|
|
|
607
609
|
const ORG = "audience-test-org";
|
|
608
610
|
|
|
609
611
|
it("audience persists and round-trips", async () => {
|
|
610
|
-
const agent = await createTestAgent(
|
|
611
|
-
uniqueName("Audience Round Trip Agent"),
|
|
612
|
-
ORG,
|
|
613
|
-
);
|
|
612
|
+
const agent = await createTestAgent(uniqueName("Audience Round Trip Agent"), ORG);
|
|
614
613
|
const created = await shares.create({
|
|
615
614
|
...shareFor(agent, true),
|
|
616
615
|
spec: { ...shareFor(agent, true).spec, audience: AgentShareAudience.org },
|
|
@@ -622,15 +621,10 @@ describe("audience and the member resolution lane", () => {
|
|
|
622
621
|
});
|
|
623
622
|
|
|
624
623
|
it("member path resolves shares in either audience (OSS: membership always holds)", async () => {
|
|
625
|
-
const agent = await createTestAgent(
|
|
626
|
-
uniqueName("Member Resolution Agent"),
|
|
627
|
-
ORG,
|
|
628
|
-
);
|
|
624
|
+
const agent = await createTestAgent(uniqueName("Member Resolution Agent"), ORG);
|
|
629
625
|
const ref = { org: ORG, slug: agent.metadata!.slug };
|
|
630
626
|
|
|
631
|
-
const noShareErr = await grpcError(() =>
|
|
632
|
-
query.getSharedProfileForMember(ref),
|
|
633
|
-
);
|
|
627
|
+
const noShareErr = await grpcError(() => query.getSharedProfileForMember(ref));
|
|
634
628
|
expect(noShareErr.code).toBe(Code.NotFound);
|
|
635
629
|
|
|
636
630
|
await shares.create({
|
|
@@ -643,10 +637,7 @@ describe("audience and the member resolution lane", () => {
|
|
|
643
637
|
});
|
|
644
638
|
|
|
645
639
|
it("the ANONYMOUS path collapses an org-audience share to the uniform NotFound (C2 close-out — the proto's audience contract)", async () => {
|
|
646
|
-
const agent = await createTestAgent(
|
|
647
|
-
uniqueName("Org Audience Anon Agent"),
|
|
648
|
-
ORG,
|
|
649
|
-
);
|
|
640
|
+
const agent = await createTestAgent(uniqueName("Org Audience Anon Agent"), ORG);
|
|
650
641
|
await shares.create({
|
|
651
642
|
...shareFor(agent, true),
|
|
652
643
|
spec: { ...shareFor(agent, true).spec, audience: AgentShareAudience.org },
|
|
@@ -715,9 +706,7 @@ describe("rotateShareLink", () => {
|
|
|
715
706
|
|
|
716
707
|
// Capture the no-share NOT_FOUND before creating — the locked-link
|
|
717
708
|
// refusal must be byte-identical to it.
|
|
718
|
-
const noShareErr = await grpcError(() =>
|
|
719
|
-
query.getSharedProfile(request("")),
|
|
720
|
-
);
|
|
709
|
+
const noShareErr = await grpcError(() => query.getSharedProfile(request("")));
|
|
721
710
|
|
|
722
711
|
const share = await shares.create(shareFor(agent, true));
|
|
723
712
|
|
|
@@ -725,31 +714,23 @@ describe("rotateShareLink", () => {
|
|
|
725
714
|
await query.getSharedProfile(request("stray-token"));
|
|
726
715
|
|
|
727
716
|
// Rotation locks the link: 27 url-safe chars, status-resident.
|
|
728
|
-
const rotated = await shares.rotateShareLink({
|
|
729
|
-
resourceId: share.metadata!.id,
|
|
730
|
-
});
|
|
717
|
+
const rotated = await shares.rotateShareLink({ resourceId: share.metadata!.id });
|
|
731
718
|
const firstToken = rotated.status?.shareLinkToken ?? "";
|
|
732
719
|
expect(firstToken).toHaveLength(27);
|
|
733
720
|
expect(firstToken).toMatch(/^[A-Za-z0-9_-]+$/);
|
|
734
721
|
|
|
735
|
-
const lockedErr = await grpcError(() =>
|
|
736
|
-
query.getSharedProfile(request("")),
|
|
737
|
-
);
|
|
722
|
+
const lockedErr = await grpcError(() => query.getSharedProfile(request("")));
|
|
738
723
|
expect(lockedErr.code).toBe(Code.NotFound);
|
|
739
724
|
expect(lockedErr.rawMessage).toBe(noShareErr.rawMessage);
|
|
740
725
|
|
|
741
726
|
await query.getSharedProfile(request(firstToken));
|
|
742
727
|
|
|
743
728
|
// Re-rotation kills the previous token.
|
|
744
|
-
const reRotated = await shares.rotateShareLink({
|
|
745
|
-
resourceId: share.metadata!.id,
|
|
746
|
-
});
|
|
729
|
+
const reRotated = await shares.rotateShareLink({ resourceId: share.metadata!.id });
|
|
747
730
|
const secondToken = reRotated.status?.shareLinkToken ?? "";
|
|
748
731
|
expect(secondToken).not.toBe(firstToken);
|
|
749
732
|
|
|
750
|
-
const deadErr = await grpcError(() =>
|
|
751
|
-
query.getSharedProfile(request(firstToken)),
|
|
752
|
-
);
|
|
733
|
+
const deadErr = await grpcError(() => query.getSharedProfile(request(firstToken)));
|
|
753
734
|
expect(deadErr.code).toBe(Code.NotFound);
|
|
754
735
|
await query.getSharedProfile(request(secondToken));
|
|
755
736
|
|
|
@@ -776,10 +757,7 @@ describe("rotateShareLink", () => {
|
|
|
776
757
|
});
|
|
777
758
|
|
|
778
759
|
it("member path stays open for org-audience shares even when a token exists", async () => {
|
|
779
|
-
const agent = await createTestAgent(
|
|
780
|
-
uniqueName("Org Audience Rotate Agent"),
|
|
781
|
-
ORG,
|
|
782
|
-
);
|
|
760
|
+
const agent = await createTestAgent(uniqueName("Org Audience Rotate Agent"), ORG);
|
|
783
761
|
const created = await shares.create({
|
|
784
762
|
...shareFor(agent, true),
|
|
785
763
|
spec: { ...shareFor(agent, true).spec, audience: AgentShareAudience.org },
|
|
@@ -800,15 +778,11 @@ describe("rotateShareLink", () => {
|
|
|
800
778
|
|
|
801
779
|
describe("getByAgent", () => {
|
|
802
780
|
it("finds the canonical share and a renamed share", async () => {
|
|
803
|
-
const agent = await createTestAgent(
|
|
804
|
-
uniqueName("Get By Agent Agent"),
|
|
805
|
-
"gba-org",
|
|
806
|
-
);
|
|
781
|
+
const agent = await createTestAgent(uniqueName("Get By Agent Agent"), "gba-org");
|
|
807
782
|
const canonical = await shares.create(shareFor(agent, true));
|
|
808
783
|
|
|
809
784
|
const renamed = shareFor(agent, true);
|
|
810
|
-
(renamed.metadata as Record<string, string>).name =
|
|
811
|
-
uniqueName("Renamed Channel");
|
|
785
|
+
(renamed.metadata as Record<string, string>).name = uniqueName("Renamed Channel");
|
|
812
786
|
const second = await shares.create(renamed);
|
|
813
787
|
|
|
814
788
|
const list = await query.getByAgent({ agentId: agent.metadata!.id });
|
|
@@ -828,21 +802,25 @@ describe("getByAgent", () => {
|
|
|
828
802
|
uniqueName("Org Scoped List Agent"),
|
|
829
803
|
"gba-provider-org",
|
|
830
804
|
);
|
|
805
|
+
await makeAgentPublic(agent);
|
|
831
806
|
await shares.create(shareFor(agent, true));
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
807
|
+
|
|
808
|
+
const crossOrg = shareFor(agent, true);
|
|
809
|
+
crossOrg.metadata.org = "gba-consumer-org";
|
|
810
|
+
crossOrg.spec.agentRef = {
|
|
811
|
+
...crossOrg.spec.agentRef,
|
|
812
|
+
org: agent.metadata!.org,
|
|
813
|
+
} as never;
|
|
814
|
+
await shares.create(crossOrg);
|
|
835
815
|
|
|
836
816
|
const cases: Array<{ org: string; want: number; wantOrg: string }> = [
|
|
837
817
|
{ org: "", want: 2, wantOrg: "" },
|
|
838
|
-
{ org: "gba-provider-org", want:
|
|
818
|
+
{ org: "gba-provider-org", want: 1, wantOrg: "gba-provider-org" },
|
|
819
|
+
{ org: "gba-consumer-org", want: 1, wantOrg: "gba-consumer-org" },
|
|
839
820
|
{ org: "gba-bystander-org", want: 0, wantOrg: "" },
|
|
840
821
|
];
|
|
841
822
|
for (const tt of cases) {
|
|
842
|
-
const list = await query.getByAgent({
|
|
843
|
-
agentId: agent.metadata!.id,
|
|
844
|
-
org: tt.org,
|
|
845
|
-
});
|
|
823
|
+
const list = await query.getByAgent({ agentId: agent.metadata!.id, org: tt.org });
|
|
846
824
|
expect(list.totalCount, `org ${tt.org}`).toBe(tt.want);
|
|
847
825
|
for (const item of list.items) {
|
|
848
826
|
if (tt.wantOrg !== "") {
|
|
@@ -870,9 +848,7 @@ describe("apply semantics", () => {
|
|
|
870
848
|
expect(created.metadata?.id).not.toBe("");
|
|
871
849
|
|
|
872
850
|
const again = shareFor(agent, true);
|
|
873
|
-
(again.spec as Record<string, unknown>).allowedOrigins = [
|
|
874
|
-
"https://docs.example.com",
|
|
875
|
-
];
|
|
851
|
+
(again.spec as Record<string, unknown>).allowedOrigins = ["https://docs.example.com"];
|
|
876
852
|
const updated = await shares.apply(again);
|
|
877
853
|
expect(updated.metadata?.id).toBe(created.metadata!.id);
|
|
878
854
|
expect(updated.spec?.allowedOrigins).toHaveLength(1);
|