@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
|
@@ -131,10 +131,8 @@ function agentInput(overrides?: {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
* Seeds an MCP server straight into the store — the
|
|
135
|
-
*
|
|
136
|
-
* have stamped: an org-visible agent may reference it under the reference
|
|
137
|
-
* floor, as it would a server created through the API.
|
|
134
|
+
* Seeds an MCP server straight into the store — the mcpserver controller
|
|
135
|
+
* arrives with sub-project #9, and the agent pipelines only need the row.
|
|
138
136
|
*/
|
|
139
137
|
async function seedMcpServer(opts: {
|
|
140
138
|
id: string;
|
|
@@ -157,7 +155,6 @@ async function seedMcpServer(opts: {
|
|
|
157
155
|
name: opts.slug,
|
|
158
156
|
slug: opts.slug,
|
|
159
157
|
org: opts.org ?? ORG,
|
|
160
|
-
visibility: ApiResourceVisibility.visibility_org,
|
|
161
158
|
},
|
|
162
159
|
spec: { env: opts.env ?? {} },
|
|
163
160
|
status: connected
|
|
@@ -312,11 +309,11 @@ describe("agent enabled-tools validation (#402)", () => {
|
|
|
312
309
|
});
|
|
313
310
|
|
|
314
311
|
describe("agent cascade delete (oss#611)", () => {
|
|
315
|
-
it("sweeps ALL instances by spec.agent_id (cross-org included), deletes same-org shares, keeps
|
|
312
|
+
it("sweeps ALL instances by spec.agent_id (cross-org included), deletes same-org shares, keeps cross-org shares", async () => {
|
|
316
313
|
const agent = await command.create(
|
|
317
314
|
agentInput({
|
|
318
315
|
name: "Cascade Target",
|
|
319
|
-
visibility: ApiResourceVisibility.
|
|
316
|
+
visibility: ApiResourceVisibility.visibility_public,
|
|
320
317
|
}),
|
|
321
318
|
);
|
|
322
319
|
const agentId = agent.metadata!.id;
|
|
@@ -358,10 +355,6 @@ describe("agent cascade delete (oss#611)", () => {
|
|
|
358
355
|
AgentShareSchema,
|
|
359
356
|
sameOrgShare,
|
|
360
357
|
);
|
|
361
|
-
// A share in another organization is a row no create admits any more
|
|
362
|
-
// (a share's agent lives in the share's organization); one written
|
|
363
|
-
// before that rule is still another organization's row, and the
|
|
364
|
-
// cascade leaves it as it always did.
|
|
365
358
|
const crossOrgShare = create(AgentShareSchema, {
|
|
366
359
|
metadata: { id: "ash_cross_org", name: "cross-org-share", org: "globex" },
|
|
367
360
|
spec: {
|
|
@@ -42,6 +42,10 @@ import {
|
|
|
42
42
|
newAuthorizeResolvedTargetStep,
|
|
43
43
|
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
44
44
|
import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
|
|
45
|
+
import {
|
|
46
|
+
newAuthorizeVisibilityTransitionStep,
|
|
47
|
+
newGuardPublicVisibilityStep,
|
|
48
|
+
} from "../../pipeline/steps/visibility-gates.js";
|
|
45
49
|
import {
|
|
46
50
|
newBuildNewStateStep,
|
|
47
51
|
setAuditFieldsForUpdate,
|
|
@@ -73,8 +77,6 @@ import {
|
|
|
73
77
|
newLoadTargetStep,
|
|
74
78
|
} from "../../pipeline/steps/load-target.js";
|
|
75
79
|
import {
|
|
76
|
-
collectSpecReferences,
|
|
77
|
-
newGuardReferenceFloorOnEscalationStep,
|
|
78
80
|
newNormalizeReferencesStep,
|
|
79
81
|
newValidateReferencesStep,
|
|
80
82
|
} from "../../pipeline/steps/references.js";
|
|
@@ -166,6 +168,7 @@ async function createAgent(
|
|
|
166
168
|
.addStep(newResolveSlugStep())
|
|
167
169
|
.addStep(newCheckDuplicateStep(deps.store))
|
|
168
170
|
.addStep(newBuildNewStateStep())
|
|
171
|
+
.addStep(newGuardPublicVisibilityStep(deps.authorizer))
|
|
169
172
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
170
173
|
.addStep(newNormalizeReferencesStep())
|
|
171
174
|
.addStep(newValidateReferencesStep(deps.store))
|
|
@@ -358,13 +361,10 @@ async function updateVisibility(
|
|
|
358
361
|
)
|
|
359
362
|
.addStep(newRecordVisibilityBeforeUpdateStep(UPDATE_VISIBILITY_AGENT_KEY))
|
|
360
363
|
.addStep(newValidateVisibilityUpdateStep())
|
|
361
|
-
// The reference floor's second door: an agent may not be raised above
|
|
362
|
-
// the skills and MCP servers it runs with.
|
|
363
364
|
.addStep(
|
|
364
|
-
|
|
365
|
-
deps.store,
|
|
365
|
+
newAuthorizeVisibilityTransitionStep(
|
|
366
366
|
UPDATE_VISIBILITY_AGENT_KEY,
|
|
367
|
-
|
|
367
|
+
deps.authorizer,
|
|
368
368
|
),
|
|
369
369
|
)
|
|
370
370
|
.addStep(newSetAgentVisibilityStep())
|
|
@@ -39,10 +39,7 @@ import { ChannelMessageQueryController } from "@stigmer/protos/ai/stigmer/agenti
|
|
|
39
39
|
import { ChannelConversationCommandController } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/conversation_command_pb";
|
|
40
40
|
import { ChannelConversationQueryController } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/conversation_query_pb";
|
|
41
41
|
import { AgentChannelInstallState } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/status_pb";
|
|
42
|
-
import { ChannelAppSchema } from "@stigmer/protos/ai/stigmer/agentic/channelapp/v1/api_pb";
|
|
43
|
-
import { EnvironmentSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
|
|
44
42
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
45
|
-
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
46
43
|
|
|
47
44
|
import { loadConfig } from "../../../boot/config.js";
|
|
48
45
|
import { composeServer } from "../../../boot/compose.js";
|
|
@@ -62,11 +59,7 @@ import {
|
|
|
62
59
|
sameOrgInvariantMessage,
|
|
63
60
|
} from "../constants.js";
|
|
64
61
|
|
|
65
|
-
const silentLogger = createLogger({
|
|
66
|
-
level: "error",
|
|
67
|
-
pretty: false,
|
|
68
|
-
write: () => {},
|
|
69
|
-
});
|
|
62
|
+
const silentLogger = createLogger({ level: "error", pretty: false, write: () => {} });
|
|
70
63
|
|
|
71
64
|
const API_VERSION = "agentic.stigmer.ai/v1";
|
|
72
65
|
const ORG = "channel-test-org";
|
|
@@ -84,10 +77,7 @@ let dir: string;
|
|
|
84
77
|
beforeAll(async () => {
|
|
85
78
|
dir = mkdtempSync(path.join(tmpdir(), "agentchannel-domain-test-"));
|
|
86
79
|
vi.stubEnv("STIGMER_ENCRYPTION_KEY", Buffer.alloc(32, 7).toString("base64"));
|
|
87
|
-
vi.stubEnv(
|
|
88
|
-
"STIGMER_RUNNER_TOKEN_KEY",
|
|
89
|
-
Buffer.alloc(32, 8).toString("base64"),
|
|
90
|
-
);
|
|
80
|
+
vi.stubEnv("STIGMER_RUNNER_TOKEN_KEY", Buffer.alloc(32, 8).toString("base64"));
|
|
91
81
|
server = await composeServer({
|
|
92
82
|
config: loadConfig({
|
|
93
83
|
STIGMER_MODEL_REGISTRY_REFRESH: "off",
|
|
@@ -111,75 +101,10 @@ beforeAll(async () => {
|
|
|
111
101
|
agents = createClient(AgentCommandController, transport);
|
|
112
102
|
messageCommand = createClient(ChannelMessageCommandController, transport);
|
|
113
103
|
messageQuery = createClient(ChannelMessageQueryController, transport);
|
|
114
|
-
conversationCommand = createClient(
|
|
115
|
-
|
|
116
|
-
transport,
|
|
117
|
-
);
|
|
118
|
-
conversationQuery = createClient(
|
|
119
|
-
ChannelConversationQueryController,
|
|
120
|
-
transport,
|
|
121
|
-
);
|
|
122
|
-
await seedReferencedRows();
|
|
104
|
+
conversationCommand = createClient(ChannelConversationCommandController, transport);
|
|
105
|
+
conversationQuery = createClient(ChannelConversationQueryController, transport);
|
|
123
106
|
});
|
|
124
107
|
|
|
125
|
-
/**
|
|
126
|
-
* The environments and channel apps the specs below reference, seeded as
|
|
127
|
-
* rows so the write-time reference rule finds them: a reference to a row
|
|
128
|
-
* that does not exist is refused at create, and these tests are about the
|
|
129
|
-
* binding's shape, not about a missing target.
|
|
130
|
-
*/
|
|
131
|
-
async function seedReferencedRows(): Promise<void> {
|
|
132
|
-
for (const slug of [
|
|
133
|
-
"github-credentials",
|
|
134
|
-
"search-credentials",
|
|
135
|
-
"rotated-credentials",
|
|
136
|
-
]) {
|
|
137
|
-
await server.store.saveResource(
|
|
138
|
-
ApiResourceKind.environment,
|
|
139
|
-
`env_${slug}`,
|
|
140
|
-
EnvironmentSchema,
|
|
141
|
-
create(EnvironmentSchema, {
|
|
142
|
-
apiVersion: "agentic.stigmer.ai/v1",
|
|
143
|
-
kind: "Environment",
|
|
144
|
-
metadata: {
|
|
145
|
-
id: `env_${slug}`,
|
|
146
|
-
name: slug,
|
|
147
|
-
slug,
|
|
148
|
-
org: ORG,
|
|
149
|
-
visibility: ApiResourceVisibility.visibility_org,
|
|
150
|
-
},
|
|
151
|
-
}),
|
|
152
|
-
);
|
|
153
|
-
}
|
|
154
|
-
for (const slug of [
|
|
155
|
-
"acme-meta-app",
|
|
156
|
-
"acme-support-app",
|
|
157
|
-
"different-app",
|
|
158
|
-
"first-app",
|
|
159
|
-
"first-meta-app",
|
|
160
|
-
"granted-app",
|
|
161
|
-
"second-app",
|
|
162
|
-
"second-meta-app",
|
|
163
|
-
]) {
|
|
164
|
-
await server.store.saveResource(
|
|
165
|
-
ApiResourceKind.channel_app,
|
|
166
|
-
`chapp_${slug}`,
|
|
167
|
-
ChannelAppSchema,
|
|
168
|
-
create(ChannelAppSchema, {
|
|
169
|
-
apiVersion: "agentic.stigmer.ai/v1",
|
|
170
|
-
kind: "ChannelApp",
|
|
171
|
-
metadata: {
|
|
172
|
-
id: `chapp_${slug}`,
|
|
173
|
-
name: slug,
|
|
174
|
-
slug,
|
|
175
|
-
org: ORG,
|
|
176
|
-
visibility: ApiResourceVisibility.visibility_org,
|
|
177
|
-
},
|
|
178
|
-
}),
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
108
|
afterAll(async () => {
|
|
184
109
|
await server.shutdown();
|
|
185
110
|
rmSync(dir, { recursive: true, force: true });
|
|
@@ -192,10 +117,7 @@ function uniqueName(base: string): string {
|
|
|
192
117
|
return `${base} ${counter}`;
|
|
193
118
|
}
|
|
194
119
|
|
|
195
|
-
async function createTestAgent(
|
|
196
|
-
name: string,
|
|
197
|
-
org: string = ORG,
|
|
198
|
-
): Promise<Agent> {
|
|
120
|
+
async function createTestAgent(name: string, org: string = ORG): Promise<Agent> {
|
|
199
121
|
return agents.create({
|
|
200
122
|
apiVersion: API_VERSION,
|
|
201
123
|
kind: "Agent",
|
|
@@ -263,9 +185,7 @@ describe("model-pin existence (oss#774)", () => {
|
|
|
263
185
|
it("create refuses a pin unknown to every harness, with a did-you-mean", async () => {
|
|
264
186
|
const agent = await createTestAgent(uniqueName("pin-agent"));
|
|
265
187
|
const ch = channelFor(agent, uniqueName("typod-pin"), true);
|
|
266
|
-
(ch.spec as Record<string, unknown>).runConfig = {
|
|
267
|
-
modelName: "composr-2.5",
|
|
268
|
-
};
|
|
188
|
+
(ch.spec as Record<string, unknown>).runConfig = { modelName: "composr-2.5" };
|
|
269
189
|
|
|
270
190
|
const err = await grpcError(() => channels.create(ch));
|
|
271
191
|
expect(err.code).toBe(Code.InvalidArgument);
|
|
@@ -276,24 +196,18 @@ describe("model-pin existence (oss#774)", () => {
|
|
|
276
196
|
it("create accepts a pin valid under some harness", async () => {
|
|
277
197
|
const agent = await createTestAgent(uniqueName("pin-agent"));
|
|
278
198
|
const ch = channelFor(agent, uniqueName("valid-pin"), true);
|
|
279
|
-
(ch.spec as Record<string, unknown>).runConfig = {
|
|
280
|
-
modelName: "composer-2.5",
|
|
281
|
-
};
|
|
199
|
+
(ch.spec as Record<string, unknown>).runConfig = { modelName: "composer-2.5" };
|
|
282
200
|
await channels.create(ch);
|
|
283
201
|
});
|
|
284
202
|
|
|
285
203
|
it("update refuses the same typo", async () => {
|
|
286
204
|
const agent = await createTestAgent(uniqueName("pin-agent"));
|
|
287
|
-
const created = await channels.create(
|
|
288
|
-
channelFor(agent, uniqueName("update-pin-target"), true),
|
|
289
|
-
);
|
|
205
|
+
const created = await channels.create(channelFor(agent, uniqueName("update-pin-target"), true));
|
|
290
206
|
|
|
291
207
|
const update = channelFor(agent, created.metadata!.name, true);
|
|
292
208
|
(update.metadata as Record<string, string>).id = created.metadata!.id;
|
|
293
209
|
(update.metadata as Record<string, string>).slug = created.metadata!.slug;
|
|
294
|
-
(update.spec as Record<string, unknown>).runConfig = {
|
|
295
|
-
modelName: "composr-2.5",
|
|
296
|
-
};
|
|
210
|
+
(update.spec as Record<string, unknown>).runConfig = { modelName: "composr-2.5" };
|
|
297
211
|
|
|
298
212
|
const err = await grpcError(() => channels.update(update));
|
|
299
213
|
expect(err.code).toBe(Code.InvalidArgument);
|
|
@@ -308,15 +222,11 @@ describe("model-pin existence (oss#774)", () => {
|
|
|
308
222
|
describe("agentchannel create", () => {
|
|
309
223
|
it("creates with ach_ prefix, normalized ref, pending_install", async () => {
|
|
310
224
|
const agent = await createTestAgent(uniqueName("Create Basics Agent"));
|
|
311
|
-
const channel = await channels.create(
|
|
312
|
-
channelFor(agent, uniqueName("Slack Workspace"), true),
|
|
313
|
-
);
|
|
225
|
+
const channel = await channels.create(channelFor(agent, uniqueName("Slack Workspace"), true));
|
|
314
226
|
|
|
315
227
|
expect(channel.metadata?.id).toMatch(/^ach_/);
|
|
316
228
|
expect(channel.spec?.agentRef?.org).toBe(agent.metadata!.org);
|
|
317
|
-
expect(channel.status?.installState).toBe(
|
|
318
|
-
AgentChannelInstallState.pending_install,
|
|
319
|
-
);
|
|
229
|
+
expect(channel.status?.installState).toBe(AgentChannelInstallState.pending_install);
|
|
320
230
|
});
|
|
321
231
|
|
|
322
232
|
it("no slug default from the agent — name derives the slug (P7)", async () => {
|
|
@@ -324,17 +234,13 @@ describe("agentchannel create", () => {
|
|
|
324
234
|
const name = uniqueName("Team Slack");
|
|
325
235
|
const channel = await channels.create(channelFor(agent, name, true));
|
|
326
236
|
|
|
327
|
-
expect(channel.metadata?.slug).toBe(
|
|
328
|
-
name.toLowerCase().replace(/\s+/g, "-"),
|
|
329
|
-
);
|
|
237
|
+
expect(channel.metadata?.slug).toBe(name.toLowerCase().replace(/\s+/g, "-"));
|
|
330
238
|
expect(channel.metadata?.slug).not.toBe(agent.metadata!.slug);
|
|
331
239
|
});
|
|
332
240
|
|
|
333
241
|
it("nameless and slugless channel is INVALID_ARGUMENT, never agent-slug fallback", async () => {
|
|
334
242
|
const agent = await createTestAgent(uniqueName("No Name Agent"));
|
|
335
|
-
const err = await grpcError(() =>
|
|
336
|
-
channels.create(channelFor(agent, "", true)),
|
|
337
|
-
);
|
|
243
|
+
const err = await grpcError(() => channels.create(channelFor(agent, "", true)));
|
|
338
244
|
expect(err.code).toBe(Code.InvalidArgument);
|
|
339
245
|
});
|
|
340
246
|
|
|
@@ -344,9 +250,7 @@ describe("agentchannel create", () => {
|
|
|
344
250
|
...channelFor(agent, uniqueName("Forged Status Slack"), true),
|
|
345
251
|
status: { installState: AgentChannelInstallState.installed },
|
|
346
252
|
});
|
|
347
|
-
expect(created.status?.installState).toBe(
|
|
348
|
-
AgentChannelInstallState.pending_install,
|
|
349
|
-
);
|
|
253
|
+
expect(created.status?.installState).toBe(AgentChannelInstallState.pending_install);
|
|
350
254
|
});
|
|
351
255
|
|
|
352
256
|
it("missing org is INVALID_ARGUMENT with the shared copy", async () => {
|
|
@@ -393,16 +297,10 @@ describe("agentchannel create", () => {
|
|
|
393
297
|
});
|
|
394
298
|
|
|
395
299
|
it("cross-org agent_ref is FAILED_PRECONDITION with the shared copy", async () => {
|
|
396
|
-
const agent = await createTestAgent(
|
|
397
|
-
uniqueName("Foreign Agent"),
|
|
398
|
-
"channel-other-org",
|
|
399
|
-
);
|
|
300
|
+
const agent = await createTestAgent(uniqueName("Foreign Agent"), "channel-other-org");
|
|
400
301
|
const ch = channelFor(agent, uniqueName("Cross Org Channel"), true);
|
|
401
302
|
ch.metadata.org = ORG;
|
|
402
|
-
ch.spec.agentRef = {
|
|
403
|
-
...ch.spec.agentRef,
|
|
404
|
-
org: "channel-other-org",
|
|
405
|
-
} as never;
|
|
303
|
+
ch.spec.agentRef = { ...ch.spec.agentRef, org: "channel-other-org" } as never;
|
|
406
304
|
|
|
407
305
|
const err = await grpcError(() => channels.create(ch));
|
|
408
306
|
expect(err.code).toBe(Code.FailedPrecondition);
|
|
@@ -437,9 +335,7 @@ describe("agentchannel create", () => {
|
|
|
437
335
|
const name = uniqueName("Duplicate Slack");
|
|
438
336
|
await channels.create(channelFor(agent, name, true));
|
|
439
337
|
|
|
440
|
-
const err = await grpcError(() =>
|
|
441
|
-
channels.create(channelFor(agent, name, true)),
|
|
442
|
-
);
|
|
338
|
+
const err = await grpcError(() => channels.create(channelFor(agent, name, true)));
|
|
443
339
|
expect(err.code).toBe(Code.AlreadyExists);
|
|
444
340
|
});
|
|
445
341
|
|
|
@@ -461,12 +357,8 @@ describe("agentchannel create", () => {
|
|
|
461
357
|
|
|
462
358
|
it("two channels for one agent coexist under distinct slugs", async () => {
|
|
463
359
|
const agent = await createTestAgent(uniqueName("Multi Channel Agent"));
|
|
464
|
-
const first = await channels.create(
|
|
465
|
-
|
|
466
|
-
);
|
|
467
|
-
const second = await channels.create(
|
|
468
|
-
channelFor(agent, uniqueName("Support Slack"), true),
|
|
469
|
-
);
|
|
360
|
+
const first = await channels.create(channelFor(agent, uniqueName("Sales Slack"), true));
|
|
361
|
+
const second = await channels.create(channelFor(agent, uniqueName("Support Slack"), true));
|
|
470
362
|
expect(first.metadata?.slug).not.toBe(second.metadata?.slug);
|
|
471
363
|
});
|
|
472
364
|
});
|
|
@@ -478,32 +370,24 @@ describe("agentchannel create", () => {
|
|
|
478
370
|
describe("agentchannel update", () => {
|
|
479
371
|
it("disable is a config-preserving pause; status survives a status-less manifest", async () => {
|
|
480
372
|
const agent = await createTestAgent(uniqueName("Pause Agent"));
|
|
481
|
-
const created = await channels.create(
|
|
482
|
-
channelFor(agent, uniqueName("Pausable Slack"), true),
|
|
483
|
-
);
|
|
373
|
+
const created = await channels.create(channelFor(agent, uniqueName("Pausable Slack"), true));
|
|
484
374
|
|
|
485
375
|
created.spec!.enabled = false;
|
|
486
376
|
created.status = undefined; // a manifest apply sends no status
|
|
487
377
|
const updated = await channels.update(created);
|
|
488
378
|
expect(updated.spec?.enabled).toBe(false);
|
|
489
|
-
expect(updated.status?.installState).toBe(
|
|
490
|
-
AgentChannelInstallState.pending_install,
|
|
491
|
-
);
|
|
379
|
+
expect(updated.status?.installState).toBe(AgentChannelInstallState.pending_install);
|
|
492
380
|
});
|
|
493
381
|
|
|
494
382
|
it("agent_ref is immutable with the shared copy", async () => {
|
|
495
383
|
const agentA = await createTestAgent(uniqueName("Immutable Ref Agent A"));
|
|
496
384
|
const agentB = await createTestAgent(uniqueName("Immutable Ref Agent B"));
|
|
497
|
-
const created = await channels.create(
|
|
498
|
-
channelFor(agentA, uniqueName("Repoint Slack"), true),
|
|
499
|
-
);
|
|
385
|
+
const created = await channels.create(channelFor(agentA, uniqueName("Repoint Slack"), true));
|
|
500
386
|
|
|
501
387
|
const repointed = channelFor(agentB, "ignored", true);
|
|
502
388
|
(repointed.metadata as Record<string, string>).id = created.metadata!.id;
|
|
503
|
-
(repointed.metadata as Record<string, string>).slug =
|
|
504
|
-
|
|
505
|
-
(repointed.metadata as Record<string, string>).name =
|
|
506
|
-
created.metadata!.name;
|
|
389
|
+
(repointed.metadata as Record<string, string>).slug = created.metadata!.slug;
|
|
390
|
+
(repointed.metadata as Record<string, string>).name = created.metadata!.name;
|
|
507
391
|
repointed.spec.agentRef = {
|
|
508
392
|
kind: ApiResourceKind.agent,
|
|
509
393
|
org: agentB.metadata!.org,
|
|
@@ -543,9 +427,7 @@ describe("agentchannel update", () => {
|
|
|
543
427
|
|
|
544
428
|
it("provider arm is immutable — a real slack→whatsapp flip refuses with the shared copy", async () => {
|
|
545
429
|
const agent = await createTestAgent(uniqueName("Provider Flip Agent"));
|
|
546
|
-
const created = await channels.create(
|
|
547
|
-
channelFor(agent, uniqueName("Prov Slack"), true),
|
|
548
|
-
);
|
|
430
|
+
const created = await channels.create(channelFor(agent, uniqueName("Prov Slack"), true));
|
|
549
431
|
|
|
550
432
|
const flipped = whatsAppChannelFor(agent, created.metadata!.name);
|
|
551
433
|
(flipped.metadata as Record<string, string>).id = created.metadata!.id;
|
|
@@ -569,24 +451,17 @@ describe("agentchannel update", () => {
|
|
|
569
451
|
describe("apply semantics", () => {
|
|
570
452
|
it("apply creates (pending_install), re-apply updates in place preserving status", async () => {
|
|
571
453
|
const org = "channel-apply-org";
|
|
572
|
-
const agent = await createTestAgent(
|
|
573
|
-
uniqueName("Apply Semantics Agent"),
|
|
574
|
-
org,
|
|
575
|
-
);
|
|
454
|
+
const agent = await createTestAgent(uniqueName("Apply Semantics Agent"), org);
|
|
576
455
|
const name = uniqueName("Apply Slack");
|
|
577
456
|
|
|
578
457
|
const created = await channels.apply(channelFor(agent, name, true));
|
|
579
458
|
expect(created.metadata?.id).not.toBe("");
|
|
580
|
-
expect(created.status?.installState).toBe(
|
|
581
|
-
AgentChannelInstallState.pending_install,
|
|
582
|
-
);
|
|
459
|
+
expect(created.status?.installState).toBe(AgentChannelInstallState.pending_install);
|
|
583
460
|
|
|
584
461
|
const updated = await channels.apply(channelFor(agent, name, false));
|
|
585
462
|
expect(updated.metadata?.id).toBe(created.metadata!.id);
|
|
586
463
|
expect(updated.spec?.enabled).toBe(false);
|
|
587
|
-
expect(updated.status?.installState).toBe(
|
|
588
|
-
AgentChannelInstallState.pending_install,
|
|
589
|
-
);
|
|
464
|
+
expect(updated.status?.installState).toBe(AgentChannelInstallState.pending_install);
|
|
590
465
|
|
|
591
466
|
const list = await query.list({ org });
|
|
592
467
|
expect(list.totalCount).toBe(1);
|
|
@@ -605,11 +480,7 @@ describe("environment_refs (channel-bound credentials)", () => {
|
|
|
605
480
|
const withRefs = channelFor(agent, name, true);
|
|
606
481
|
(withRefs.spec as Record<string, unknown>).environmentRefs = [
|
|
607
482
|
{ kind: ApiResourceKind.environment, slug: "github-credentials" },
|
|
608
|
-
{
|
|
609
|
-
kind: ApiResourceKind.environment,
|
|
610
|
-
org: ORG,
|
|
611
|
-
slug: "search-credentials",
|
|
612
|
-
},
|
|
483
|
+
{ kind: ApiResourceKind.environment, org: ORG, slug: "search-credentials" },
|
|
613
484
|
];
|
|
614
485
|
const created = await channels.create(withRefs);
|
|
615
486
|
expect(created.spec?.environmentRefs).toHaveLength(2);
|
|
@@ -623,11 +494,7 @@ describe("environment_refs (channel-bound credentials)", () => {
|
|
|
623
494
|
// Apply replaces the refs wholesale — credentials are mutable.
|
|
624
495
|
const rebound = channelFor(agent, name, true);
|
|
625
496
|
(rebound.spec as Record<string, unknown>).environmentRefs = [
|
|
626
|
-
{
|
|
627
|
-
kind: ApiResourceKind.environment,
|
|
628
|
-
org: ORG,
|
|
629
|
-
slug: "rotated-credentials",
|
|
630
|
-
},
|
|
497
|
+
{ kind: ApiResourceKind.environment, org: ORG, slug: "rotated-credentials" },
|
|
631
498
|
];
|
|
632
499
|
const updated = await channels.apply(rebound);
|
|
633
500
|
expect(updated.spec?.environmentRefs).toHaveLength(1);
|
|
@@ -846,31 +713,23 @@ describe("whatsapp app_ref (BYO-only, DD-WA-2)", () => {
|
|
|
846
713
|
describe("delete and queries", () => {
|
|
847
714
|
it("delete returns the deleted channel; get after delete is NOT_FOUND", async () => {
|
|
848
715
|
const agent = await createTestAgent(uniqueName("Delete Agent"));
|
|
849
|
-
const created = await channels.create(
|
|
850
|
-
channelFor(agent, uniqueName("Doomed Slack"), true),
|
|
851
|
-
);
|
|
716
|
+
const created = await channels.create(channelFor(agent, uniqueName("Doomed Slack"), true));
|
|
852
717
|
|
|
853
718
|
const deleted = await channels.delete({ value: created.metadata!.id });
|
|
854
719
|
expect(deleted.metadata?.id).toBe(created.metadata!.id);
|
|
855
720
|
|
|
856
|
-
const err = await grpcError(() =>
|
|
857
|
-
query.get({ value: created.metadata!.id }),
|
|
858
|
-
);
|
|
721
|
+
const err = await grpcError(() => query.get({ value: created.metadata!.id }));
|
|
859
722
|
expect(err.code).toBe(Code.NotFound);
|
|
860
723
|
});
|
|
861
724
|
|
|
862
725
|
it("nonexistent channel delete is NOT_FOUND", async () => {
|
|
863
|
-
const err = await grpcError(() =>
|
|
864
|
-
channels.delete({ value: "ach_does_not_exist" }),
|
|
865
|
-
);
|
|
726
|
+
const err = await grpcError(() => channels.delete({ value: "ach_does_not_exist" }));
|
|
866
727
|
expect(err.code).toBe(Code.NotFound);
|
|
867
728
|
});
|
|
868
729
|
|
|
869
730
|
it("get by id and by reference round-trip", async () => {
|
|
870
731
|
const agent = await createTestAgent(uniqueName("Query Agent"));
|
|
871
|
-
const created = await channels.create(
|
|
872
|
-
channelFor(agent, uniqueName("Query Slack"), true),
|
|
873
|
-
);
|
|
732
|
+
const created = await channels.create(channelFor(agent, uniqueName("Query Slack"), true));
|
|
874
733
|
|
|
875
734
|
const fetched = await query.get({ value: created.metadata!.id });
|
|
876
735
|
expect(fetched.metadata?.slug).toBe(created.metadata!.slug);
|
|
@@ -904,12 +763,8 @@ describe("delete and queries", () => {
|
|
|
904
763
|
|
|
905
764
|
it("getByAgent finds every channel regardless of slug; org scope filters", async () => {
|
|
906
765
|
const agent = await createTestAgent(uniqueName("Get By Agent Agent"));
|
|
907
|
-
const first = await channels.create(
|
|
908
|
-
|
|
909
|
-
);
|
|
910
|
-
const second = await channels.create(
|
|
911
|
-
channelFor(agent, uniqueName("Secondary Slack"), false),
|
|
912
|
-
);
|
|
766
|
+
const first = await channels.create(channelFor(agent, uniqueName("Primary Slack"), true));
|
|
767
|
+
const second = await channels.create(channelFor(agent, uniqueName("Secondary Slack"), false));
|
|
913
768
|
|
|
914
769
|
const list = await query.getByAgent({ agentId: agent.metadata!.id });
|
|
915
770
|
expect(list.totalCount).toBe(2);
|
|
@@ -917,10 +772,7 @@ describe("delete and queries", () => {
|
|
|
917
772
|
expect(slugs).toContain(first.metadata!.slug);
|
|
918
773
|
expect(slugs).toContain(second.metadata!.slug);
|
|
919
774
|
|
|
920
|
-
const matching = await query.getByAgent({
|
|
921
|
-
agentId: agent.metadata!.id,
|
|
922
|
-
org: ORG,
|
|
923
|
-
});
|
|
775
|
+
const matching = await query.getByAgent({ agentId: agent.metadata!.id, org: ORG });
|
|
924
776
|
expect(matching.totalCount).toBe(2);
|
|
925
777
|
|
|
926
778
|
const foreign = await query.getByAgent({
|
|
@@ -943,17 +795,13 @@ describe("delete and queries", () => {
|
|
|
943
795
|
describe("install posture (§0-b)", () => {
|
|
944
796
|
it("the full contract: NOT_FOUND with the cloud copy, refusal on existing, nothing persisted", async () => {
|
|
945
797
|
const agent = await createTestAgent(uniqueName("Install Posture Agent"));
|
|
946
|
-
const created = await channels.create(
|
|
947
|
-
channelFor(agent, uniqueName("Installable Slack"), true),
|
|
948
|
-
);
|
|
798
|
+
const created = await channels.create(channelFor(agent, uniqueName("Installable Slack"), true));
|
|
949
799
|
|
|
950
800
|
const missErr = await grpcError(() =>
|
|
951
801
|
channels.initiateInstall({ resourceId: "ach_does_not_exist" }),
|
|
952
802
|
);
|
|
953
803
|
expect(missErr.code).toBe(Code.NotFound);
|
|
954
|
-
expect(missErr.rawMessage).toBe(
|
|
955
|
-
"AgentChannel not found: ach_does_not_exist",
|
|
956
|
-
);
|
|
804
|
+
expect(missErr.rawMessage).toBe("AgentChannel not found: ach_does_not_exist");
|
|
957
805
|
|
|
958
806
|
const refuseErr = await grpcError(() =>
|
|
959
807
|
channels.initiateInstall({ resourceId: created.metadata!.id }),
|
|
@@ -990,9 +838,7 @@ describe("install posture (§0-b)", () => {
|
|
|
990
838
|
|
|
991
839
|
// The refused install persists nothing.
|
|
992
840
|
const fetched = await query.get({ value: created.metadata!.id });
|
|
993
|
-
expect(fetched.status?.installState).toBe(
|
|
994
|
-
AgentChannelInstallState.pending_install,
|
|
995
|
-
);
|
|
841
|
+
expect(fetched.status?.installState).toBe(AgentChannelInstallState.pending_install);
|
|
996
842
|
});
|
|
997
843
|
});
|
|
998
844
|
|
|
@@ -1029,16 +875,11 @@ describe("channel messaging posture (cloud-only runtime)", () => {
|
|
|
1029
875
|
});
|
|
1030
876
|
|
|
1031
877
|
it("sendMessage contract violations are INVALID_ARGUMENT before the refusal", async () => {
|
|
1032
|
-
const cases: Array<
|
|
1033
|
-
[string, Parameters<typeof messageCommand.sendMessage>[0]]
|
|
1034
|
-
> = [
|
|
878
|
+
const cases: Array<[string, Parameters<typeof messageCommand.sendMessage>[0]]> = [
|
|
1035
879
|
["empty recipient", { payload: textPayload("hello") }],
|
|
1036
880
|
["missing payload", { recipient: "15551234567" }],
|
|
1037
881
|
["unset payload arm", { recipient: "15551234567", payload: {} }],
|
|
1038
|
-
[
|
|
1039
|
-
"empty text body",
|
|
1040
|
-
{ recipient: "15551234567", payload: textPayload("") },
|
|
1041
|
-
],
|
|
882
|
+
["empty text body", { recipient: "15551234567", payload: textPayload("") }],
|
|
1042
883
|
[
|
|
1043
884
|
"oversized text body",
|
|
1044
885
|
{ recipient: "15551234567", payload: textPayload("x".repeat(4097)) },
|
|
@@ -1059,10 +900,7 @@ describe("channel messaging posture (cloud-only runtime)", () => {
|
|
|
1059
900
|
|
|
1060
901
|
it("listTemplates refuses with FAILED_PRECONDITION and the documented copy", async () => {
|
|
1061
902
|
const err = await grpcError(() =>
|
|
1062
|
-
messageQuery.listTemplates({
|
|
1063
|
-
channel: "some-channel",
|
|
1064
|
-
approvedOnly: true,
|
|
1065
|
-
}),
|
|
903
|
+
messageQuery.listTemplates({ channel: "some-channel", approvedOnly: true }),
|
|
1066
904
|
);
|
|
1067
905
|
expect(err.code).toBe(Code.FailedPrecondition);
|
|
1068
906
|
expect(err.rawMessage).toBe(PROACTIVE_MESSAGING_UNAVAILABLE_MESSAGE);
|
|
@@ -1079,10 +917,7 @@ describe("channel messaging posture (cloud-only runtime)", () => {
|
|
|
1079
917
|
// ---------------------------------------------------------------------------
|
|
1080
918
|
|
|
1081
919
|
describe("channel conversation posture (cloud-only runtime)", () => {
|
|
1082
|
-
const controlInput = {
|
|
1083
|
-
agentChannelId: "ach-123",
|
|
1084
|
-
conversationKey: "15551234567",
|
|
1085
|
-
};
|
|
920
|
+
const controlInput = { agentChannelId: "ach-123", conversationKey: "15551234567" };
|
|
1086
921
|
|
|
1087
922
|
it("discovery reads answer truthful emptiness", async () => {
|
|
1088
923
|
const list = await conversationQuery.listConversations({ org: "acme" });
|
|
@@ -1124,17 +959,12 @@ describe("channel conversation posture (cloud-only runtime)", () => {
|
|
|
1124
959
|
conversationCommand.reply({
|
|
1125
960
|
agentChannelId: "ach-123",
|
|
1126
961
|
conversationKey: "15551234567",
|
|
1127
|
-
payload: {
|
|
1128
|
-
kind: { case: "text" as const, value: { body: "on my way" } },
|
|
1129
|
-
},
|
|
962
|
+
payload: { kind: { case: "text" as const, value: { body: "on my way" } } },
|
|
1130
963
|
}),
|
|
1131
964
|
],
|
|
1132
965
|
["takeOver", () => conversationCommand.takeOver(controlInput)],
|
|
1133
966
|
["handBack", () => conversationCommand.handBack(controlInput)],
|
|
1134
|
-
[
|
|
1135
|
-
"clearAttention",
|
|
1136
|
-
() => conversationCommand.clearAttention(controlInput),
|
|
1137
|
-
],
|
|
967
|
+
["clearAttention", () => conversationCommand.clearAttention(controlInput)],
|
|
1138
968
|
[
|
|
1139
969
|
"escalate",
|
|
1140
970
|
() =>
|
|
@@ -1146,18 +976,13 @@ describe("channel conversation posture (cloud-only runtime)", () => {
|
|
|
1146
976
|
for (const [name, call] of commands) {
|
|
1147
977
|
const err = await grpcError(call);
|
|
1148
978
|
expect(err.code, name).toBe(Code.FailedPrecondition);
|
|
1149
|
-
expect(err.rawMessage, name).toBe(
|
|
1150
|
-
CONVERSATION_PARTICIPATION_UNAVAILABLE_MESSAGE,
|
|
1151
|
-
);
|
|
979
|
+
expect(err.rawMessage, name).toBe(CONVERSATION_PARTICIPATION_UNAVAILABLE_MESSAGE);
|
|
1152
980
|
}
|
|
1153
981
|
});
|
|
1154
982
|
|
|
1155
983
|
it("contract violations are INVALID_ARGUMENT before the refusal", async () => {
|
|
1156
984
|
const cases: Array<[string, () => Promise<unknown>]> = [
|
|
1157
|
-
[
|
|
1158
|
-
"listConversations without org",
|
|
1159
|
-
() => conversationQuery.listConversations({}),
|
|
1160
|
-
],
|
|
985
|
+
["listConversations without org", () => conversationQuery.listConversations({})],
|
|
1161
986
|
[
|
|
1162
987
|
"getTimeline without conversation key",
|
|
1163
988
|
() => conversationQuery.getTimeline({ agentChannelId: "ach-123" }),
|
|
@@ -96,10 +96,7 @@ import {
|
|
|
96
96
|
TARGET_RESOURCE_KEY,
|
|
97
97
|
newLoadTargetStep,
|
|
98
98
|
} from "../../pipeline/steps/load-target.js";
|
|
99
|
-
import {
|
|
100
|
-
newNormalizeReferencesStep,
|
|
101
|
-
newValidateReferencesStep,
|
|
102
|
-
} from "../../pipeline/steps/references.js";
|
|
99
|
+
import { newNormalizeReferencesStep } from "../../pipeline/steps/references.js";
|
|
103
100
|
import {
|
|
104
101
|
newCleanupIamPoliciesStep,
|
|
105
102
|
newCreateAuthorizationTuplesStep,
|
|
@@ -213,7 +210,6 @@ async function createChannel(
|
|
|
213
210
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
214
211
|
.addStep(newInitInstallStateStep())
|
|
215
212
|
.addStep(newNormalizeReferencesStep())
|
|
216
|
-
.addStep(newValidateReferencesStep(deps.store))
|
|
217
213
|
.addStep(newPersistStep(deps.store))
|
|
218
214
|
.addStep(
|
|
219
215
|
newCreateAuthorizationTuplesStep(
|
|
@@ -262,7 +258,6 @@ async function update(
|
|
|
262
258
|
.addStep(newBuildUpdateStateStep())
|
|
263
259
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
264
260
|
.addStep(newNormalizeReferencesStep())
|
|
265
|
-
.addStep(newValidateReferencesStep(deps.store))
|
|
266
261
|
.addStep(newPersistStep(deps.store))
|
|
267
262
|
.build()
|
|
268
263
|
.execute(reqCtx);
|
|
@@ -66,10 +66,7 @@ import {
|
|
|
66
66
|
TARGET_RESOURCE_KEY,
|
|
67
67
|
newLoadTargetStep,
|
|
68
68
|
} from "../../pipeline/steps/load-target.js";
|
|
69
|
-
import {
|
|
70
|
-
newNormalizeReferencesStep,
|
|
71
|
-
newValidateReferencesStep,
|
|
72
|
-
} from "../../pipeline/steps/references.js";
|
|
69
|
+
import { newNormalizeReferencesStep } from "../../pipeline/steps/references.js";
|
|
73
70
|
import {
|
|
74
71
|
newCleanupIamPoliciesStep,
|
|
75
72
|
newCreateAuthorizationTuplesStep,
|
|
@@ -331,7 +328,6 @@ async function createExecution(
|
|
|
331
328
|
.addStep(newRecordRunnerLineageLabelsStep(deps.runnerCredentialProvider))
|
|
332
329
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
333
330
|
.addStep(newNormalizeReferencesStep())
|
|
334
|
-
.addStep(newValidateReferencesStep(deps.store))
|
|
335
331
|
.addStep(newEnsureEngineAvailableStep(deps.engineState));
|
|
336
332
|
// The ratified pre-side-effect gate slot (blueprint 03 §3a; O4): after
|
|
337
333
|
// every pure validation/resolution step, before the first side-effecting
|
|
@@ -437,7 +433,6 @@ async function update(
|
|
|
437
433
|
.addStep(newLoadExistingStep(deps.store))
|
|
438
434
|
.addStep(newBuildUpdateStateStep())
|
|
439
435
|
.addStep(newNormalizeReferencesStep())
|
|
440
|
-
.addStep(newValidateReferencesStep(deps.store))
|
|
441
436
|
.addStep(newPersistStep(deps.store))
|
|
442
437
|
.addStep(
|
|
443
438
|
newIndexSearchStep(
|