@stigmer/server 3.21.0 → 3.22.1-dev.20260922095755
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 +4 -8
- package/dist/authorization/authorizer.d.ts.map +1 -1
- package/dist/authorization/authorizer.js +5 -9
- package/dist/authorization/authorizer.js.map +1 -1
- package/dist/authorization/derived-tuples.d.ts.map +1 -1
- package/dist/authorization/derived-tuples.js +10 -25
- package/dist/authorization/derived-tuples.js.map +1 -1
- package/dist/authorization/evaluator.d.ts +13 -8
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js +4 -20
- 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 +24 -20
- 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 +4 -5
- 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/organization.d.ts.map +1 -1
- package/dist/authorization/model/organization.js +2 -0
- package/dist/authorization/model/organization.js.map +1 -1
- package/dist/authorization/model/plugin.d.ts.map +1 -1
- package/dist/authorization/model/plugin.js +3 -4
- package/dist/authorization/model/plugin.js.map +1 -1
- package/dist/authorization/model/rewrite.d.ts +8 -10
- package/dist/authorization/model/rewrite.d.ts.map +1 -1
- package/dist/authorization/model/rewrite.js +0 -3
- 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 +2 -3
- package/dist/authorization/organization-directory.js.map +1 -1
- package/dist/authorization/store-test-kit.d.ts +0 -6
- package/dist/authorization/store-test-kit.d.ts.map +1 -1
- package/dist/authorization/store-test-kit.js +16 -62
- package/dist/authorization/store-test-kit.js.map +1 -1
- package/dist/authorization/tuples.d.ts +13 -32
- package/dist/authorization/tuples.d.ts.map +1 -1
- package/dist/authorization/tuples.js +3 -11
- package/dist/authorization/tuples.js.map +1 -1
- package/dist/domain/agent/controller.d.ts.map +1 -1
- package/dist/domain/agent/controller.js +6 -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 +9 -2
- package/dist/domain/agentchannel/controller.js.map +1 -1
- package/dist/domain/agentchannel/steps.d.ts +19 -0
- package/dist/domain/agentchannel/steps.d.ts.map +1 -1
- package/dist/domain/agentchannel/steps.js +32 -0
- package/dist/domain/agentchannel/steps.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +3 -1
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentinstance/controller.d.ts +5 -5
- package/dist/domain/agentinstance/controller.d.ts.map +1 -1
- package/dist/domain/agentinstance/controller.js +9 -5
- package/dist/domain/agentinstance/controller.js.map +1 -1
- package/dist/domain/agentinstance/steps.d.ts +43 -8
- package/dist/domain/agentinstance/steps.d.ts.map +1 -1
- package/dist/domain/agentinstance/steps.js +71 -8
- package/dist/domain/agentinstance/steps.js.map +1 -1
- package/dist/domain/agentshare/constants.d.ts +6 -11
- package/dist/domain/agentshare/constants.d.ts.map +1 -1
- package/dist/domain/agentshare/constants.js +8 -16
- 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 +10 -2
- package/dist/domain/agentshare/controller.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +61 -10
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +121 -117
- package/dist/domain/agentshare/steps.js.map +1 -1
- package/dist/domain/artifact/controller.js +21 -25
- package/dist/domain/artifact/controller.js.map +1 -1
- package/dist/domain/channelapp/controller.d.ts.map +1 -1
- package/dist/domain/channelapp/controller.js +2 -0
- package/dist/domain/channelapp/controller.js.map +1 -1
- package/dist/domain/environment/controller.d.ts.map +1 -1
- package/dist/domain/environment/controller.js +4 -3
- 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 +4 -1
- package/dist/domain/executioncontext/controller.js.map +1 -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/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +8 -7
- package/dist/domain/mcpserver/connect.js.map +1 -1
- package/dist/domain/mcpserver/controller.d.ts.map +1 -1
- package/dist/domain/mcpserver/controller.js +5 -4
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/start-connect.js +8 -7
- package/dist/domain/mcpserver/start-connect.js.map +1 -1
- package/dist/domain/memory/controller.d.ts.map +1 -1
- package/dist/domain/memory/controller.js +6 -1
- package/dist/domain/memory/controller.js.map +1 -1
- package/dist/domain/memory/steps.d.ts +23 -0
- package/dist/domain/memory/steps.d.ts.map +1 -1
- package/dist/domain/memory/steps.js +35 -0
- package/dist/domain/memory/steps.js.map +1 -1
- package/dist/domain/oauthapp/controller.d.ts.map +1 -1
- package/dist/domain/oauthapp/controller.js +2 -0
- package/dist/domain/oauthapp/controller.js.map +1 -1
- package/dist/domain/plugin/controller.d.ts.map +1 -1
- package/dist/domain/plugin/controller.js +6 -27
- package/dist/domain/plugin/controller.js.map +1 -1
- package/dist/domain/plugin/push.d.ts +7 -5
- package/dist/domain/plugin/push.d.ts.map +1 -1
- package/dist/domain/plugin/push.js +8 -14
- 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 +10 -2
- package/dist/domain/schedule/controller.js.map +1 -1
- package/dist/domain/schedule/steps.d.ts +19 -0
- package/dist/domain/schedule/steps.d.ts.map +1 -1
- package/dist/domain/schedule/steps.js +32 -0
- package/dist/domain/schedule/steps.js.map +1 -1
- package/dist/domain/session/controller.d.ts.map +1 -1
- package/dist/domain/session/controller.js +3 -2
- package/dist/domain/session/controller.js.map +1 -1
- package/dist/domain/session/steps.d.ts +8 -9
- package/dist/domain/session/steps.d.ts.map +1 -1
- package/dist/domain/session/steps.js +17 -21
- package/dist/domain/session/steps.js.map +1 -1
- package/dist/domain/skill/controller.d.ts.map +1 -1
- package/dist/domain/skill/controller.js +8 -19
- package/dist/domain/skill/controller.js.map +1 -1
- package/dist/domain/workflow/agent-call-references.d.ts +54 -0
- package/dist/domain/workflow/agent-call-references.d.ts.map +1 -0
- package/dist/domain/workflow/agent-call-references.js +97 -0
- package/dist/domain/workflow/agent-call-references.js.map +1 -0
- package/dist/domain/workflow/controller.d.ts.map +1 -1
- package/dist/domain/workflow/controller.js +44 -113
- 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 +10 -1
- package/dist/domain/workflow/validation/task-config-constraints.d.ts.map +1 -1
- package/dist/domain/workflow/validation/task-config-constraints.js +3 -2
- package/dist/domain/workflow/validation/task-config-constraints.js.map +1 -1
- package/dist/domain/workflow/version-resolution.d.ts +5 -0
- package/dist/domain/workflow/version-resolution.d.ts.map +1 -0
- package/dist/domain/workflow/version-resolution.js +113 -0
- package/dist/domain/workflow/version-resolution.js.map +1 -0
- package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
- package/dist/domain/workflowexecution/controller.js +4 -2
- 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 +9 -5
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/domain/workflowinstance/steps.d.ts +20 -0
- package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
- package/dist/domain/workflowinstance/steps.js +39 -0
- package/dist/domain/workflowinstance/steps.js.map +1 -1
- package/dist/extensions/authorization-queries.d.ts +6 -5
- package/dist/extensions/authorization-queries.d.ts.map +1 -1
- package/dist/extensions/identity.d.ts +19 -0
- package/dist/extensions/identity.d.ts.map +1 -1
- package/dist/extensions/identity.js +22 -3
- package/dist/extensions/identity.js.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +42 -8
- package/dist/extensions/list-read-scope.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.js +13 -2
- package/dist/extensions/list-read-scope.js.map +1 -1
- package/dist/extensions/resource-authorization.d.ts +3 -2
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pipeline/apiresource-meta.d.ts +12 -3
- package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
- package/dist/pipeline/apiresource-meta.js +21 -10
- package/dist/pipeline/apiresource-meta.js.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts +9 -3
- package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.js +9 -11
- package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
- package/dist/pipeline/steps/authorize-resolved-target.d.ts +88 -0
- package/dist/pipeline/steps/authorize-resolved-target.d.ts.map +1 -0
- package/dist/pipeline/steps/authorize-resolved-target.js +36 -0
- package/dist/pipeline/steps/authorize-resolved-target.js.map +1 -0
- package/dist/pipeline/steps/authorize.d.ts +27 -0
- package/dist/pipeline/steps/authorize.d.ts.map +1 -1
- package/dist/pipeline/steps/authorize.js +49 -10
- package/dist/pipeline/steps/authorize.js.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.js +2 -1
- package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.js +6 -7
- package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
- package/dist/pipeline/steps/helpers.d.ts +9 -5
- package/dist/pipeline/steps/helpers.d.ts.map +1 -1
- package/dist/pipeline/steps/helpers.js +11 -15
- package/dist/pipeline/steps/helpers.js.map +1 -1
- package/dist/pipeline/steps/references.d.ts +178 -20
- package/dist/pipeline/steps/references.d.ts.map +1 -1
- package/dist/pipeline/steps/references.js +344 -43
- package/dist/pipeline/steps/references.js.map +1 -1
- package/dist/pipeline/steps/version-history.d.ts +11 -0
- package/dist/pipeline/steps/version-history.d.ts.map +1 -1
- package/dist/pipeline/steps/version-history.js +26 -0
- package/dist/pipeline/steps/version-history.js.map +1 -1
- package/dist/query/search/controller.js +0 -1
- package/dist/query/search/controller.js.map +1 -1
- package/dist/query/search/criteria.d.ts +1 -5
- package/dist/query/search/criteria.d.ts.map +1 -1
- package/dist/query/search/criteria.js +3 -13
- package/dist/query/search/criteria.js.map +1 -1
- package/dist/query/search/handler.d.ts +5 -4
- package/dist/query/search/handler.d.ts.map +1 -1
- package/dist/query/search/handler.js +7 -6
- 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 +0 -2
- package/dist/query/search/query-store.js.map +1 -1
- package/dist/store/interface.d.ts +3 -6
- package/dist/store/interface.d.ts.map +1 -1
- package/dist/store/interface.js.map +1 -1
- package/dist/store/postgres/migrations.d.ts +3 -1
- package/dist/store/postgres/migrations.d.ts.map +1 -1
- package/dist/store/postgres/migrations.js +35 -1
- 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 +4 -9
- package/dist/store/postgres/store.js.map +1 -1
- package/dist/store/public-visibility-retired.d.ts +67 -0
- package/dist/store/public-visibility-retired.d.ts.map +1 -0
- package/dist/store/public-visibility-retired.js +55 -0
- package/dist/store/public-visibility-retired.js.map +1 -0
- package/dist/store/sqlite/migrations.d.ts +3 -1
- package/dist/store/sqlite/migrations.d.ts.map +1 -1
- package/dist/store/sqlite/migrations.js +36 -1
- 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 +4 -8
- package/dist/store/sqlite/store.js.map +1 -1
- package/package.json +6 -6
- package/src/authorization/README.md +24 -26
- package/src/authorization/__tests__/authorizer.test.ts +10 -9
- package/src/authorization/__tests__/derived-tuples.test.ts +4 -11
- package/src/authorization/__tests__/evaluator.test.ts +14 -73
- package/src/authorization/__tests__/facts.test.ts +2 -2
- package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +6 -98
- package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +4 -61
- package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +1 -21
- package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +1 -25
- package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +1 -3
- package/src/authorization/__tests__/list-read-scope.test.ts +41 -29
- package/src/authorization/__tests__/skip-lane-inventory.test.ts +160 -0
- package/src/authorization/__tests__/store-tests.test.ts +1 -6
- package/src/authorization/__tests__/tuples.test.ts +12 -11
- package/src/authorization/__tests__/wire-permissions.test.ts +5 -5
- package/src/authorization/authorizer.ts +4 -9
- package/src/authorization/derived-tuples.ts +14 -31
- package/src/authorization/evaluator.ts +15 -44
- package/src/authorization/list-read-scope.ts +27 -22
- package/src/authorization/model/__tests__/registry.test.ts +2 -0
- package/src/authorization/model/agent.ts +2 -5
- package/src/authorization/model/agent_instance.ts +0 -2
- package/src/authorization/model/mcp_server.ts +0 -2
- package/src/authorization/model/organization.ts +2 -0
- package/src/authorization/model/plugin.ts +1 -4
- package/src/authorization/model/rewrite.ts +8 -13
- package/src/authorization/model/skill.ts +0 -2
- package/src/authorization/model/workflow.ts +0 -2
- package/src/authorization/model/workflow_instance.ts +0 -2
- package/src/authorization/organization-directory.ts +1 -3
- package/src/authorization/store-test-kit.ts +16 -75
- package/src/authorization/tuples.ts +16 -39
- package/src/domain/agent/__tests__/agent.test.ts +11 -4
- package/src/domain/agent/controller.ts +17 -7
- package/src/domain/agentchannel/__tests__/agentchannel.test.ts +223 -48
- package/src/domain/agentchannel/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/agentchannel/controller.ts +25 -1
- package/src/domain/agentchannel/steps.ts +40 -0
- package/src/domain/agentexecution/controller.ts +6 -1
- package/src/domain/agentinstance/__tests__/create-authorization.composed.test.ts +243 -0
- package/src/domain/agentinstance/__tests__/create-authorization.test.ts +144 -0
- package/src/domain/agentinstance/controller.ts +30 -17
- package/src/domain/agentinstance/steps.ts +82 -8
- package/src/domain/agentshare/__tests__/agentshare.test.ts +196 -172
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +71 -0
- package/src/domain/agentshare/__tests__/member-audience.test.ts +113 -0
- package/src/domain/agentshare/constants.ts +14 -26
- package/src/domain/agentshare/controller.ts +27 -1
- package/src/domain/agentshare/steps.ts +168 -155
- package/src/domain/artifact/controller.ts +18 -22
- package/src/domain/channelapp/controller.ts +10 -0
- package/src/domain/environment/controller.ts +15 -8
- package/src/domain/executioncontext/__tests__/executioncontext.test.ts +1 -0
- package/src/domain/executioncontext/controller.ts +15 -1
- package/src/domain/executioncontext/steps.ts +2 -1
- package/src/domain/mcpserver/__tests__/mcpserver.test.ts +115 -28
- package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +53 -18
- package/src/domain/mcpserver/connect.ts +11 -10
- package/src/domain/mcpserver/controller.ts +19 -13
- package/src/domain/mcpserver/start-connect.ts +17 -11
- package/src/domain/memory/__tests__/create-authorization.test.ts +59 -0
- package/src/domain/memory/controller.ts +11 -0
- package/src/domain/memory/steps.ts +41 -0
- package/src/domain/oauthapp/controller.ts +10 -0
- package/src/domain/plugin/controller.ts +23 -44
- package/src/domain/plugin/push.ts +8 -16
- package/src/domain/schedule/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/schedule/controller.ts +26 -1
- package/src/domain/schedule/steps.ts +45 -2
- package/src/domain/session/controller.ts +12 -4
- package/src/domain/session/steps.ts +24 -32
- package/src/domain/skill/controller.ts +24 -30
- package/src/domain/workflow/__tests__/agent-call-references.test.ts +222 -0
- package/src/domain/workflow/agent-call-references.ts +157 -0
- package/src/domain/workflow/controller.ts +86 -155
- package/src/domain/workflow/registry/data/task-kind-registry.json +1 -1
- package/src/domain/workflow/validation/task-config-constraints.ts +7 -3
- package/src/domain/workflow/version-resolution.ts +166 -0
- package/src/domain/workflowexecution/controller.ts +7 -2
- package/src/domain/workflowinstance/__tests__/create-authorization.test.ts +109 -0
- package/src/domain/workflowinstance/controller.ts +25 -12
- package/src/domain/workflowinstance/steps.ts +49 -1
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +32 -19
- package/src/extensions/__tests__/composed-support.ts +38 -4
- package/src/extensions/__tests__/extension-composition.test.ts +4 -4
- package/src/extensions/__tests__/identity.test.ts +44 -1
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +96 -7
- package/src/extensions/__tests__/list-read-scope.test.ts +63 -0
- package/src/extensions/authorization-queries.ts +6 -5
- package/src/extensions/identity.ts +23 -5
- package/src/extensions/list-read-scope.ts +48 -8
- package/src/extensions/resource-authorization.ts +3 -5
- package/src/index.ts +0 -1
- package/src/pipeline/__tests__/supports-visibility.test.ts +112 -0
- package/src/pipeline/apiresource-meta.ts +21 -10
- package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +18 -31
- package/src/pipeline/steps/__tests__/authorize-resolved-target.test.ts +285 -0
- package/src/pipeline/steps/__tests__/references.test.ts +703 -0
- package/src/pipeline/steps/authorization-tuples.ts +9 -11
- package/src/pipeline/steps/authorize-resolved-target.ts +129 -0
- package/src/pipeline/steps/authorize.ts +70 -13
- package/src/pipeline/steps/guard-memory-capture.ts +2 -1
- package/src/pipeline/steps/guard-reserved-labels.ts +6 -9
- package/src/pipeline/steps/helpers.ts +11 -15
- package/src/pipeline/steps/references.ts +578 -70
- package/src/pipeline/steps/version-history.ts +34 -0
- package/src/query/search/__tests__/criteria.test.ts +0 -4
- package/src/query/search/__tests__/query-store.test.ts +11 -40
- package/src/query/search/controller.ts +0 -1
- package/src/query/search/criteria.ts +0 -14
- package/src/query/search/handler.ts +6 -7
- package/src/query/search/query-store.ts +0 -2
- package/src/store/__tests__/public-visibility-retired.test.ts +127 -0
- package/src/store/__tests__/store-contract.ts +6 -51
- package/src/store/interface.ts +3 -6
- package/src/store/postgres/__tests__/migrations.test.ts +187 -6
- package/src/store/postgres/__tests__/store-contract.test.ts +0 -2
- package/src/store/postgres/migrations.ts +48 -1
- package/src/store/postgres/store.ts +4 -11
- package/src/store/public-visibility-retired.ts +119 -0
- package/src/store/sqlite/__tests__/migrations.test.ts +191 -5
- package/src/store/sqlite/migrations.ts +45 -1
- package/src/store/sqlite/store.ts +4 -10
- package/dist/pipeline/steps/visibility-gates.d.ts +0 -27
- package/dist/pipeline/steps/visibility-gates.d.ts.map +0 -1
- package/dist/pipeline/steps/visibility-gates.js +0 -139
- package/dist/pipeline/steps/visibility-gates.js.map +0 -1
- package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +0 -98
- package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +0 -52
- package/src/pipeline/steps/__tests__/visibility-gates.test.ts +0 -187
- package/src/pipeline/steps/visibility-gates.ts +0 -174
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
* Semantics the controller and the conformance suite rely on (the Java
|
|
33
33
|
* check-handler posture the cloud's client already implements):
|
|
34
34
|
*
|
|
35
|
-
* - `check`
|
|
36
|
-
* "may I read this
|
|
37
|
-
*
|
|
35
|
+
* - `check` resolves usersets (a grant to `organization:acme#member`
|
|
36
|
+
* answers true for a member), so "may I read this" is the model's
|
|
37
|
+
* answer and not a lookup of who was named.
|
|
38
|
+
* - the two listings never expand usersets, and `listPrincipalIds`
|
|
38
39
|
* answers DIRECT principals only — a listing is an inventory of who
|
|
39
40
|
* was named, never a resolution of who could reach.
|
|
40
41
|
* - contextual policies are evaluated as if held, and nothing is written.
|
|
@@ -74,7 +75,7 @@ export interface AuthorizationQueryEngine {
|
|
|
74
75
|
): Promise<boolean>;
|
|
75
76
|
/**
|
|
76
77
|
* The ids of `resourceKind` resources on which `principal` holds
|
|
77
|
-
* `relation` (ListAuthorizedResourceIdsInput's field order).
|
|
78
|
+
* `relation` (ListAuthorizedResourceIdsInput's field order). Usersets
|
|
78
79
|
* are not expanded.
|
|
79
80
|
*/
|
|
80
81
|
listResourceIds(
|
|
@@ -86,7 +87,7 @@ export interface AuthorizationQueryEngine {
|
|
|
86
87
|
/**
|
|
87
88
|
* The ids of `principalKind` principals holding `relation` on `resource`
|
|
88
89
|
* (ListAuthorizedPrincipalIdsInput's field order). Direct principals
|
|
89
|
-
* only;
|
|
90
|
+
* only; usersets are not expanded.
|
|
90
91
|
*/
|
|
91
92
|
listPrincipalIds(
|
|
92
93
|
resource: ApiResourceRef,
|
|
@@ -112,9 +112,27 @@ export interface IdentityVerifier {
|
|
|
112
112
|
* rule is load-bearing in open source.
|
|
113
113
|
*/
|
|
114
114
|
export function isPlatformPipelineCaller(caller: CallerIdentity): boolean {
|
|
115
|
-
return (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
115
|
+
return caller.callerClass === "machine" || isServerComposedRequest(caller);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Whether the request `caller` arrived on was composed by the server's own
|
|
120
|
+
* code rather than presented on the wire: the `internal` class (the server
|
|
121
|
+
* acting as itself) or ANY identity that entered through the in-process
|
|
122
|
+
* transport (a propagated person the server is building a request for,
|
|
123
|
+
* such as the default-instance self-heal that creates as the run's human
|
|
124
|
+
* for attribution). The serving chassis strips the propagation header, so
|
|
125
|
+
* the wire cannot claim this.
|
|
126
|
+
*
|
|
127
|
+
* This is the trust arm the label guard, the memory-capture gate and the
|
|
128
|
+
* execution-context create check share: what a server-composed request
|
|
129
|
+
* carries was decided by the service code that built it, and the
|
|
130
|
+
* entry-point request already passed its own gate. It is NARROWER than
|
|
131
|
+
* `isPlatformPipelineCaller`: a wire `machine` account is one of the
|
|
132
|
+
* platform's pipelines but its request is still the wire's, so a step
|
|
133
|
+
* that trusts server-composed state (a reserved label, a default
|
|
134
|
+
* instance's provenance) must key on this predicate and never on that one.
|
|
135
|
+
*/
|
|
136
|
+
export function isServerComposedRequest(caller: CallerIdentity): boolean {
|
|
137
|
+
return caller.callerClass === "internal" || caller.origin === "in-process";
|
|
120
138
|
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* is yours). On a multi-tenant edition the same scans serve OTHER
|
|
9
9
|
* tenants' rows, so the cloud baseline (the Java list handlers) narrows
|
|
10
10
|
* every one of them to the caller's FGA-authorized id set (ListObjects
|
|
11
|
-
* on can_view
|
|
11
|
+
* on can_view), with a second guest
|
|
12
12
|
* cookie-label rule on the session and agent-execution lanes.
|
|
13
13
|
*
|
|
14
14
|
* This port is the ONE seam for that fork (DD-007 addendum 3: every
|
|
@@ -48,11 +48,27 @@
|
|
|
48
48
|
* authorization-backend outage surfaces as the pipeline's sanitized
|
|
49
49
|
* INTERNAL, exactly the Java baseline (DD-007: unavailable is never
|
|
50
50
|
* softened).
|
|
51
|
-
* -
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
51
|
+
* - THE `internal` CLASS IS ANSWERED HERE, NEVER OFFERED TO
|
|
52
|
+
* `restrictListEntries`. The server acting as itself over the
|
|
53
|
+
* in-process transport (boot/inprocess.ts mints the class; nothing
|
|
54
|
+
* else can) is the server's own trust domain, on list lanes exactly
|
|
55
|
+
* as on the Authorize step, which returns for the class before any
|
|
56
|
+
* Authorizer is asked (pipeline/steps/authorize.ts). The helper
|
|
57
|
+
* below returns the org-narrowed rows for that class before the
|
|
58
|
+
* scope is consulted. The rule is class-only, like the step's: a
|
|
59
|
+
* caller PROPAGATED through the in-process header keeps its own
|
|
60
|
+
* class and stays scoped. Why here and not in a driver: a driver
|
|
61
|
+
* answering "every offered id" for the class must be written once
|
|
62
|
+
* per edition and is a silent short list the day one edition
|
|
63
|
+
* forgets (stigmer#1207: a composed driver scoped the class and
|
|
64
|
+
* every server-internal list read came back empty — the
|
|
65
|
+
* personal-environment reads at execution-context creation and MCP
|
|
66
|
+
* connect in this repository, and a composition's own in-process
|
|
67
|
+
* readers of a session's executions).
|
|
68
|
+
* The enumeration verb is a wire caller's verb: no in-process edge
|
|
69
|
+
* reaches `authorizedResourceIds`, and only a scanning driver can
|
|
70
|
+
* say "all", so that verb's internal arm stays the driver's and is
|
|
71
|
+
* stated in its doc below.
|
|
56
72
|
* - THE SCOPE IS THE LAST PER-ROW PREDICATE IN A LANE (stigmer-cloud
|
|
57
73
|
* 20260913.04 T02, Q-LB-11). Every request predicate a lane applies
|
|
58
74
|
* — the request's org, a phase, labels, a parent id, filter criteria
|
|
@@ -157,6 +173,13 @@ export interface ListReadScope {
|
|
|
157
173
|
* answer — consumers map it to their lane's empty shape without
|
|
158
174
|
* touching the store. A scope may throw on a kind it was never ruled
|
|
159
175
|
* to serve (a consumer bug by contract).
|
|
176
|
+
*
|
|
177
|
+
* The `internal` class CAN reach this verb (no helper stands between a
|
|
178
|
+
* consumer and it), and the driver owns that arm: a scanning driver
|
|
179
|
+
* answers every id of the kind, an engine-backed one answers what its
|
|
180
|
+
* engine holds for the class. No in-process edge reaches an
|
|
181
|
+
* enumeration lane today, so the two answers have never met a caller;
|
|
182
|
+
* a consumer that adds one reads this line first.
|
|
160
183
|
*/
|
|
161
184
|
authorizedResourceIds(
|
|
162
185
|
caller: CallerIdentity,
|
|
@@ -168,6 +191,12 @@ export interface ListReadScope {
|
|
|
168
191
|
* baseline: the authorized-ids intersection plus the guest
|
|
169
192
|
* cookie-label rule where the lane carries it). The result must be a
|
|
170
193
|
* subset of the offered ids — a scope only narrows.
|
|
194
|
+
*
|
|
195
|
+
* `caller` is never the `internal` class: `restrictListByReadScope`,
|
|
196
|
+
* the one consumption idiom, answers that class before any driver is
|
|
197
|
+
* asked (the header's contract line). A driver that is offered it has
|
|
198
|
+
* been reached around the idiom and should refuse loudly rather than
|
|
199
|
+
* evaluate the server as a person (the built-in driver does).
|
|
171
200
|
*/
|
|
172
201
|
restrictListEntries(
|
|
173
202
|
caller: CallerIdentity,
|
|
@@ -209,8 +238,13 @@ export interface ScopedListResource {
|
|
|
209
238
|
* permission-bounded across orgs, verified per lane in the entry's
|
|
210
239
|
* census — lanes Java does not org-narrow pass ""), then to the kept
|
|
211
240
|
* ids. The same set either way (both are per-row predicates); the
|
|
212
|
-
* order is the header's
|
|
213
|
-
*
|
|
241
|
+
* order is the header's contract line: the scope sees the org's
|
|
242
|
+
* rows, not the kind's;
|
|
243
|
+
* - scope composed, caller `internal` → the org-narrowed rows, the
|
|
244
|
+
* scope never asked and no candidate built (the header's contract
|
|
245
|
+
* line). The org predicate is the REQUEST's, not the caller's, so
|
|
246
|
+
* the server's own read of a cross-org lane still honours the org
|
|
247
|
+
* it asked for; only the caller predicate is skipped;
|
|
214
248
|
* - every candidate carries the row's authorization facts, and the
|
|
215
249
|
* candidates of a kind whose authorization is its parent's name that
|
|
216
250
|
* parent again as `authorizationParent` — one of the facts' parent
|
|
@@ -231,6 +265,12 @@ export async function restrictListByReadScope<T extends ScopedListResource>(
|
|
|
231
265
|
requestOrg === ""
|
|
232
266
|
? resources
|
|
233
267
|
: resources.filter((resource) => resource.metadata?.org === requestOrg);
|
|
268
|
+
// The server acting as itself: the trust-domain rule of the Authorize
|
|
269
|
+
// step, applied to a list answer — the caller predicate is skipped, the
|
|
270
|
+
// request's org predicate above is not (the header's contract line).
|
|
271
|
+
if (caller.callerClass === "internal") {
|
|
272
|
+
return [...offered];
|
|
273
|
+
}
|
|
234
274
|
const parentOf = authorizationParentReader(kind);
|
|
235
275
|
const entries: ListEntryMeta[] = offered.map((resource) => {
|
|
236
276
|
const entry: ListEntryMeta = {
|
|
@@ -65,14 +65,12 @@ import type { CallerIdentity } from "./identity.js";
|
|
|
65
65
|
* The visibility tuple shapes of the shared FGA model, named
|
|
66
66
|
* edition-neutrally. The driver maps each to its tuple:
|
|
67
67
|
* - org-viewer: <kind>:<id>#viewer@organization:<org>#viewer
|
|
68
|
-
* - public-viewer: <kind>:<id>#viewer@identity_account:* (conditional)
|
|
69
68
|
* - platform-viewer: <kind>:<id>#platform_viewer@identity_provider:<idp>#platform_user
|
|
70
69
|
* (fans out per IdP the org owns — the driver's lookup, not OSS's)
|
|
70
|
+
* Every shape names a bounded set of readers; the model has no shape that
|
|
71
|
+
* reaches every account.
|
|
71
72
|
*/
|
|
72
|
-
export type VisibilityTupleShape =
|
|
73
|
-
| "org-viewer"
|
|
74
|
-
| "public-viewer"
|
|
75
|
-
| "platform-viewer";
|
|
73
|
+
export type VisibilityTupleShape = "org-viewer" | "platform-viewer";
|
|
76
74
|
|
|
77
75
|
/**
|
|
78
76
|
* One resolved structural link from the created resource to a parent
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins `supportsVisibility` and `supportedVisibilityLevels`
|
|
3
|
+
* (pipeline/apiresource-meta.ts), the one predicate behind the
|
|
4
|
+
* ValidateVisibility doors on every create and updateVisibility chain.
|
|
5
|
+
*
|
|
6
|
+
* The retired public level is the reason this file exists: no kind config
|
|
7
|
+
* declares it any more, so the predicate cannot read a flag for it and must
|
|
8
|
+
* answer from its own text. The first test walks EVERY kind that has
|
|
9
|
+
* `kind_meta` and asserts the level is refused; the door is one function,
|
|
10
|
+
* and this is the pin that it holds for kinds nobody thought to try. The
|
|
11
|
+
* rest of the file pins the levels that remain against the proto's
|
|
12
|
+
* declarations for the kinds whose configs differ (a blueprint, an
|
|
13
|
+
* instance, an org-only kind, a kind with no config), and the copy fragment
|
|
14
|
+
* both editions build the INVALID_ARGUMENT sentence from.
|
|
15
|
+
*/
|
|
16
|
+
import { describe, expect, it } from "vitest";
|
|
17
|
+
|
|
18
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
19
|
+
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
20
|
+
|
|
21
|
+
import {
|
|
22
|
+
getKindMeta,
|
|
23
|
+
supportedVisibilityLevels,
|
|
24
|
+
supportsVisibility,
|
|
25
|
+
} from "../apiresource-meta.js";
|
|
26
|
+
|
|
27
|
+
const V = ApiResourceVisibility;
|
|
28
|
+
|
|
29
|
+
/** Every enum member that carries kind_meta (the unknown kind does not). */
|
|
30
|
+
const KINDS_WITH_META: ApiResourceKind[] = Object.values(ApiResourceKind)
|
|
31
|
+
.filter((value): value is ApiResourceKind => typeof value === "number")
|
|
32
|
+
.filter((kind) => {
|
|
33
|
+
try {
|
|
34
|
+
getKindMeta(kind);
|
|
35
|
+
return true;
|
|
36
|
+
} catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe("supportsVisibility", () => {
|
|
42
|
+
it("refuses the retired public level for every kind", () => {
|
|
43
|
+
expect(KINDS_WITH_META.length).toBeGreaterThan(20);
|
|
44
|
+
for (const kind of KINDS_WITH_META) {
|
|
45
|
+
expect(supportsVisibility(kind, V.visibility_public)).toBe(false);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("private and unspecified are supported by every kind", () => {
|
|
50
|
+
for (const kind of KINDS_WITH_META) {
|
|
51
|
+
expect(supportsVisibility(kind, V.visibility_private)).toBe(true);
|
|
52
|
+
expect(
|
|
53
|
+
supportsVisibility(kind, V.api_resource_visibility_unspecified),
|
|
54
|
+
).toBe(true);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("a blueprint kind holds org and platform", () => {
|
|
59
|
+
expect(supportsVisibility(ApiResourceKind.agent, V.visibility_org)).toBe(
|
|
60
|
+
true,
|
|
61
|
+
);
|
|
62
|
+
expect(
|
|
63
|
+
supportsVisibility(ApiResourceKind.agent, V.visibility_platform),
|
|
64
|
+
).toBe(true);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("an instance kind holds org but never platform (tenant isolation)", () => {
|
|
68
|
+
expect(
|
|
69
|
+
supportsVisibility(ApiResourceKind.agent_instance, V.visibility_org),
|
|
70
|
+
).toBe(true);
|
|
71
|
+
expect(
|
|
72
|
+
supportsVisibility(ApiResourceKind.agent_instance, V.visibility_platform),
|
|
73
|
+
).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("an org-only kind holds org alone (environment: secrets never cross the org)", () => {
|
|
77
|
+
expect(
|
|
78
|
+
supportsVisibility(ApiResourceKind.environment, V.visibility_org),
|
|
79
|
+
).toBe(true);
|
|
80
|
+
expect(
|
|
81
|
+
supportsVisibility(ApiResourceKind.environment, V.visibility_platform),
|
|
82
|
+
).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("a kind with no visibility config is private-only", () => {
|
|
86
|
+
expect(supportsVisibility(ApiResourceKind.session, V.visibility_org)).toBe(
|
|
87
|
+
false,
|
|
88
|
+
);
|
|
89
|
+
expect(
|
|
90
|
+
supportsVisibility(ApiResourceKind.session, V.visibility_platform),
|
|
91
|
+
).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("supportedVisibilityLevels (the copy fragment)", () => {
|
|
96
|
+
it("names the levels that remain, private first, never the retired one", () => {
|
|
97
|
+
expect(supportedVisibilityLevels(ApiResourceKind.agent)).toBe(
|
|
98
|
+
"visibility_private, visibility_org, visibility_platform",
|
|
99
|
+
);
|
|
100
|
+
expect(supportedVisibilityLevels(ApiResourceKind.agent_instance)).toBe(
|
|
101
|
+
"visibility_private, visibility_org",
|
|
102
|
+
);
|
|
103
|
+
expect(supportedVisibilityLevels(ApiResourceKind.session)).toBe(
|
|
104
|
+
"visibility_private",
|
|
105
|
+
);
|
|
106
|
+
for (const kind of KINDS_WITH_META) {
|
|
107
|
+
expect(supportedVisibilityLevels(kind)).not.toContain(
|
|
108
|
+
"visibility_public",
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
@@ -266,9 +266,18 @@ function tierRank(tier: ResourceTier): number {
|
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
/**
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
269
|
+
* Whether a kind may hold a visibility level — the one predicate behind the
|
|
270
|
+
* ValidateVisibility doors on every create and updateVisibility chain.
|
|
271
|
+
*
|
|
272
|
+
* PRIVATE and UNSPECIFIED are always supported (no visibility grant is
|
|
273
|
+
* written for them); ORG and PLATFORM require the matching supports_* flag
|
|
274
|
+
* on the kind's VisibilityConfig, so kinds with no config are private-only.
|
|
275
|
+
* PUBLIC is refused for every kind: the level is retired (it made a row
|
|
276
|
+
* readable to every account on the server), no config may declare it, and
|
|
277
|
+
* the answer is fixed here rather than read from a flag that no longer
|
|
278
|
+
* exists. Every level is named so a level added to the enum must be taught
|
|
279
|
+
* here before any row can hold it; the closing arm is unreachable by wire
|
|
280
|
+
* input, because both doors validate the field `defined_only` first.
|
|
272
281
|
*/
|
|
273
282
|
export function supportsVisibility(
|
|
274
283
|
kind: ApiResourceKind,
|
|
@@ -276,14 +285,19 @@ export function supportsVisibility(
|
|
|
276
285
|
): boolean {
|
|
277
286
|
const config = getKindMeta(kind).authorization?.visibility;
|
|
278
287
|
switch (visibility) {
|
|
279
|
-
case ApiResourceVisibility.
|
|
280
|
-
|
|
288
|
+
case ApiResourceVisibility.api_resource_visibility_unspecified:
|
|
289
|
+
case ApiResourceVisibility.visibility_private:
|
|
290
|
+
return true;
|
|
281
291
|
case ApiResourceVisibility.visibility_org:
|
|
282
292
|
return config?.supportsOrg === true;
|
|
283
293
|
case ApiResourceVisibility.visibility_platform:
|
|
284
294
|
return config?.supportsPlatform === true;
|
|
285
|
-
|
|
286
|
-
return
|
|
295
|
+
case ApiResourceVisibility.visibility_public:
|
|
296
|
+
return false;
|
|
297
|
+
default: {
|
|
298
|
+
const exhaustive: never = visibility;
|
|
299
|
+
throw new Error(`unknown visibility level: ${String(exhaustive)}`);
|
|
300
|
+
}
|
|
287
301
|
}
|
|
288
302
|
}
|
|
289
303
|
|
|
@@ -298,9 +312,6 @@ export function supportedVisibilityLevels(kind: ApiResourceKind): string {
|
|
|
298
312
|
if (config?.supportsOrg === true) {
|
|
299
313
|
levels += ", visibility_org";
|
|
300
314
|
}
|
|
301
|
-
if (config?.supportsPublic === true) {
|
|
302
|
-
levels += ", visibility_public";
|
|
303
|
-
}
|
|
304
315
|
if (config?.supportsPlatform === true) {
|
|
305
316
|
levels += ", visibility_platform";
|
|
306
317
|
}
|
|
@@ -41,15 +41,10 @@ const caller: CallerIdentity = {
|
|
|
41
41
|
const V = ApiResourceVisibility;
|
|
42
42
|
|
|
43
43
|
describe("visibilityShapesFor (the reconciler's level→shape policy)", () => {
|
|
44
|
-
it("agent (blueprint with org floor): org /
|
|
44
|
+
it("agent (blueprint with org floor): org / platform expansions", () => {
|
|
45
45
|
expect([
|
|
46
46
|
...visibilityShapesFor(ApiResourceKind.agent, V.visibility_org),
|
|
47
47
|
]).toEqual(["org-viewer"]);
|
|
48
|
-
expect(
|
|
49
|
-
[
|
|
50
|
-
...visibilityShapesFor(ApiResourceKind.agent, V.visibility_public),
|
|
51
|
-
].sort(),
|
|
52
|
-
).toEqual(["org-viewer", "public-viewer"]);
|
|
53
48
|
expect(
|
|
54
49
|
[
|
|
55
50
|
...visibilityShapesFor(ApiResourceKind.agent, V.visibility_platform),
|
|
@@ -60,25 +55,27 @@ describe("visibilityShapesFor (the reconciler's level→shape policy)", () => {
|
|
|
60
55
|
]).toEqual([]);
|
|
61
56
|
});
|
|
62
57
|
|
|
63
|
-
it("
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
])
|
|
58
|
+
it("the retired public level expands to nothing for every kind — no wildcard shape exists", () => {
|
|
59
|
+
for (const kind of [
|
|
60
|
+
ApiResourceKind.agent,
|
|
61
|
+
ApiResourceKind.workflow_instance,
|
|
62
|
+
ApiResourceKind.plugin,
|
|
63
|
+
ApiResourceKind.session,
|
|
64
|
+
]) {
|
|
65
|
+
expect([...visibilityShapesFor(kind, V.visibility_public)]).toEqual([]);
|
|
66
|
+
}
|
|
70
67
|
});
|
|
71
68
|
|
|
72
69
|
it("session (no visibility config): every level yields nothing, silently", () => {
|
|
73
70
|
expect([
|
|
74
|
-
...visibilityShapesFor(ApiResourceKind.session, V.
|
|
71
|
+
...visibilityShapesFor(ApiResourceKind.session, V.visibility_org),
|
|
75
72
|
]).toEqual([]);
|
|
76
73
|
expect([
|
|
77
|
-
...visibilityShapesFor(ApiResourceKind.session, V.
|
|
74
|
+
...visibilityShapesFor(ApiResourceKind.session, V.visibility_platform),
|
|
78
75
|
]).toEqual([]);
|
|
79
76
|
});
|
|
80
77
|
|
|
81
|
-
it("agent_instance supports org
|
|
78
|
+
it("agent_instance supports org but never platform (tenant isolation)", () => {
|
|
82
79
|
expect([
|
|
83
80
|
...visibilityShapesFor(
|
|
84
81
|
ApiResourceKind.agent_instance,
|
|
@@ -101,15 +98,15 @@ describe("diffVisibilityShapes (the reconciler's transition matrix, re-pinned)",
|
|
|
101
98
|
expect(diff.shapesToDelete).toEqual([]);
|
|
102
99
|
});
|
|
103
100
|
|
|
104
|
-
it("unspecified→
|
|
101
|
+
it("unspecified→platform creates the platform shape + the org floor", () => {
|
|
105
102
|
const diff = diffVisibilityShapes(
|
|
106
103
|
agent,
|
|
107
104
|
V.api_resource_visibility_unspecified,
|
|
108
|
-
V.
|
|
105
|
+
V.visibility_platform,
|
|
109
106
|
);
|
|
110
107
|
expect([...diff.shapesToCreate].sort()).toEqual([
|
|
111
108
|
"org-viewer",
|
|
112
|
-
"
|
|
109
|
+
"platform-viewer",
|
|
113
110
|
]);
|
|
114
111
|
expect(diff.shapesToDelete).toEqual([]);
|
|
115
112
|
});
|
|
@@ -124,23 +121,13 @@ describe("diffVisibilityShapes (the reconciler's transition matrix, re-pinned)",
|
|
|
124
121
|
expect(diff.shapesToDelete).toEqual(["org-viewer"]);
|
|
125
122
|
});
|
|
126
123
|
|
|
127
|
-
it("
|
|
124
|
+
it("platform→org deletes ONLY the platform shape — the shared org floor stays untouched", () => {
|
|
128
125
|
const diff = diffVisibilityShapes(
|
|
129
126
|
agent,
|
|
130
|
-
V.
|
|
127
|
+
V.visibility_platform,
|
|
131
128
|
V.visibility_org,
|
|
132
129
|
);
|
|
133
130
|
expect(diff.shapesToCreate).toEqual([]);
|
|
134
|
-
expect(diff.shapesToDelete).toEqual(["public-viewer"]);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("platform→public swaps the family shape and never touches the org floor", () => {
|
|
138
|
-
const diff = diffVisibilityShapes(
|
|
139
|
-
agent,
|
|
140
|
-
V.visibility_platform,
|
|
141
|
-
V.visibility_public,
|
|
142
|
-
);
|
|
143
|
-
expect(diff.shapesToCreate).toEqual(["public-viewer"]);
|
|
144
131
|
expect(diff.shapesToDelete).toEqual(["platform-viewer"]);
|
|
145
132
|
});
|
|
146
133
|
|