@stigmer/server 3.20.0 → 3.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authorization/evaluator.d.ts +7 -1
- package/dist/authorization/evaluator.d.ts.map +1 -1
- 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 +19 -11
- package/dist/authorization/list-read-scope.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/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +0 -1
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/inprocess.d.ts +0 -2
- package/dist/boot/inprocess.d.ts.map +1 -1
- package/dist/boot/inprocess.js +0 -6
- package/dist/boot/inprocess.js.map +1 -1
- package/dist/domain/agent/controller.d.ts +2 -2
- package/dist/domain/agent/controller.d.ts.map +1 -1
- package/dist/domain/agent/controller.js +3 -17
- package/dist/domain/agent/controller.js.map +1 -1
- package/dist/domain/agent/steps.d.ts +0 -1
- package/dist/domain/agent/steps.d.ts.map +1 -1
- package/dist/domain/agent/steps.js +1 -40
- package/dist/domain/agent/steps.js.map +1 -1
- package/dist/domain/agentchannel/controller.d.ts.map +1 -1
- package/dist/domain/agentchannel/controller.js +6 -1
- 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 +7 -9
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentexecution/create-execution-context-step.d.ts +0 -2
- package/dist/domain/agentexecution/create-execution-context-step.d.ts.map +1 -1
- package/dist/domain/agentexecution/create-execution-context-step.js +179 -60
- package/dist/domain/agentexecution/create-execution-context-step.js.map +1 -1
- package/dist/domain/agentexecution/create-steps.d.ts +16 -31
- package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
- package/dist/domain/agentexecution/create-steps.js +36 -102
- package/dist/domain/agentexecution/create-steps.js.map +1 -1
- package/dist/domain/agentexecution/run-target.d.ts +7 -3
- package/dist/domain/agentexecution/run-target.d.ts.map +1 -1
- package/dist/domain/agentexecution/run-target.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 +6 -1
- 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/controller.d.ts.map +1 -1
- package/dist/domain/agentshare/controller.js +7 -1
- package/dist/domain/agentshare/controller.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +58 -0
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +109 -4
- 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 +2 -0
- package/dist/domain/environment/controller.js.map +1 -1
- package/dist/domain/environment/personal.d.ts +42 -0
- package/dist/domain/environment/personal.d.ts.map +1 -0
- package/dist/domain/environment/personal.js +96 -0
- package/dist/domain/environment/personal.js.map +1 -0
- package/dist/domain/executioncontext/controller.d.ts.map +1 -1
- package/dist/domain/executioncontext/controller.js +2 -0
- 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 +0 -2
- package/dist/domain/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +24 -79
- 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 +2 -0
- 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 +5 -24
- package/dist/domain/plugin/controller.js.map +1 -1
- package/dist/domain/plugin/overlay/sanitize.js +2 -2
- package/dist/domain/schedule/controller.d.ts.map +1 -1
- package/dist/domain/schedule/controller.js +7 -1
- 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 +0 -7
- package/dist/domain/session/controller.d.ts.map +1 -1
- package/dist/domain/session/controller.js +11 -16
- package/dist/domain/session/controller.js.map +1 -1
- package/dist/domain/session/run-target.d.ts +9 -8
- package/dist/domain/session/run-target.d.ts.map +1 -1
- package/dist/domain/session/run-target.js.map +1 -1
- package/dist/domain/session/steps.d.ts +8 -36
- package/dist/domain/session/steps.d.ts.map +1 -1
- package/dist/domain/session/steps.js +27 -172
- 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 -17
- package/dist/domain/skill/controller.js.map +1 -1
- package/dist/domain/workflow/controller.d.ts.map +1 -1
- package/dist/domain/workflow/controller.js +30 -107
- package/dist/domain/workflow/controller.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/create-steps.d.ts +4 -3
- package/dist/domain/workflowexecution/create-steps.d.ts.map +1 -1
- package/dist/domain/workflowexecution/create-steps.js +4 -3
- package/dist/domain/workflowexecution/create-steps.js.map +1 -1
- package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
- package/dist/domain/workflowinstance/controller.js +6 -1
- 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/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 +41 -7
- 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/pipeline/apiresource-labels.d.ts +2 -2
- package/dist/pipeline/apiresource-labels.js +2 -2
- package/dist/pipeline/errors.d.ts +2 -2
- package/dist/pipeline/errors.js +2 -2
- 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 +12 -12
- 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/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/package.json +6 -6
- package/src/authorization/__tests__/list-read-scope.test.ts +23 -12
- package/src/authorization/__tests__/skip-lane-inventory.test.ts +160 -0
- package/src/authorization/__tests__/wire-permissions.test.ts +5 -5
- package/src/authorization/evaluator.ts +7 -0
- package/src/authorization/list-read-scope.ts +22 -11
- package/src/authorization/model/__tests__/registry.test.ts +2 -0
- package/src/authorization/model/organization.ts +2 -0
- package/src/boot/compose.ts +0 -1
- package/src/boot/inprocess.ts +0 -9
- package/src/domain/agent/__tests__/agent.test.ts +0 -68
- package/src/domain/agent/controller.ts +11 -36
- package/src/domain/agent/steps.ts +1 -60
- package/src/domain/agentchannel/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/agentchannel/controller.ts +19 -0
- package/src/domain/agentchannel/steps.ts +40 -0
- package/src/domain/agentexecution/__tests__/create-execution-context-step.test.ts +216 -0
- package/src/domain/agentexecution/__tests__/create-steps.test.ts +70 -145
- package/src/domain/agentexecution/controller.ts +6 -10
- package/src/domain/agentexecution/create-execution-context-step.ts +271 -83
- package/src/domain/agentexecution/create-steps.ts +38 -138
- package/src/domain/agentexecution/run-target.ts +7 -3
- 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 +24 -5
- package/src/domain/agentinstance/steps.ts +82 -8
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +86 -0
- package/src/domain/agentshare/__tests__/member-audience.test.ts +113 -0
- package/src/domain/agentshare/controller.ts +21 -0
- package/src/domain/agentshare/steps.ts +181 -15
- package/src/domain/artifact/controller.ts +18 -22
- package/src/domain/channelapp/controller.ts +10 -0
- package/src/domain/environment/__tests__/personal.test.ts +143 -0
- package/src/domain/environment/controller.ts +10 -0
- package/src/domain/environment/personal.ts +141 -0
- package/src/domain/executioncontext/__tests__/executioncontext.test.ts +1 -0
- package/src/domain/executioncontext/controller.ts +10 -0
- package/src/domain/executioncontext/steps.ts +2 -1
- package/src/domain/mcpserver/connect.ts +32 -92
- package/src/domain/mcpserver/controller.ts +13 -1
- 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 +22 -36
- package/src/domain/plugin/overlay/sanitize.ts +2 -2
- package/src/domain/schedule/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/schedule/controller.ts +20 -0
- package/src/domain/schedule/steps.ts +45 -2
- package/src/domain/session/__tests__/run-gate.test.ts +19 -52
- package/src/domain/session/__tests__/session.test.ts +27 -203
- package/src/domain/session/controller.ts +10 -30
- package/src/domain/session/run-target.ts +9 -8
- package/src/domain/session/steps.ts +33 -267
- package/src/domain/skill/controller.ts +24 -23
- package/src/domain/workflow/controller.ts +58 -145
- package/src/domain/workflow/version-resolution.ts +166 -0
- package/src/domain/workflowexecution/create-steps.ts +4 -3
- package/src/domain/workflowinstance/__tests__/create-authorization.test.ts +109 -0
- package/src/domain/workflowinstance/controller.ts +19 -0
- package/src/domain/workflowinstance/steps.ts +49 -1
- package/src/extensions/__tests__/composed-support.ts +38 -4
- package/src/extensions/__tests__/identity.test.ts +44 -1
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +87 -1
- package/src/extensions/__tests__/list-read-scope.test.ts +63 -0
- package/src/extensions/identity.ts +23 -5
- package/src/extensions/list-read-scope.ts +47 -7
- package/src/pipeline/apiresource-labels.ts +2 -2
- package/src/pipeline/errors.ts +2 -2
- package/src/pipeline/steps/__tests__/authorize-resolved-target.test.ts +285 -0
- 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 +12 -14
- package/src/pipeline/steps/helpers.ts +11 -15
- package/src/pipeline/steps/version-history.ts +34 -0
- package/dist/domain/agent/defaultagent.d.ts +0 -37
- package/dist/domain/agent/defaultagent.d.ts.map +0 -1
- package/dist/domain/agent/defaultagent.js +0 -104
- package/dist/domain/agent/defaultagent.js.map +0 -1
- package/src/domain/agent/defaultagent.ts +0 -135
|
@@ -51,7 +51,6 @@ import type {
|
|
|
51
51
|
ApiResourceReference,
|
|
52
52
|
UpdateVisibilityInput,
|
|
53
53
|
} from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
|
|
54
|
-
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
55
54
|
|
|
56
55
|
import type { ContentAddressedArchiveStore } from "../../archive/content-store.js";
|
|
57
56
|
import { MAX_ZIP_SIZE } from "../../archive/limits.js";
|
|
@@ -74,10 +73,7 @@ import {
|
|
|
74
73
|
newRecordVisibilityBeforeUpdateStep,
|
|
75
74
|
newUpdateVisibilityTuplesStep,
|
|
76
75
|
} from "../../pipeline/steps/authorization-tuples.js";
|
|
77
|
-
import {
|
|
78
|
-
authorizeResolvedResource,
|
|
79
|
-
newAuthorizeStep,
|
|
80
|
-
} from "../../pipeline/steps/authorize.js";
|
|
76
|
+
import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
|
|
81
77
|
import { setAuditFieldsForUpdate } from "../../pipeline/steps/defaults.js";
|
|
82
78
|
import {
|
|
83
79
|
newDeleteResourceStep,
|
|
@@ -96,12 +92,16 @@ import { newValidateProtoStep } from "../../pipeline/steps/validation.js";
|
|
|
96
92
|
import { newValidateVisibilityUpdateStep } from "../../pipeline/steps/validate-visibility.js";
|
|
97
93
|
import { newDeleteVersionArchivesStep } from "../../pipeline/steps/version-archive.js";
|
|
98
94
|
import {
|
|
99
|
-
LIST_VERSIONS_RESOURCE_ID_KEY,
|
|
100
95
|
LIST_VERSIONS_RESPONSE_KEY,
|
|
101
96
|
newLoadAndMapVersionsStep,
|
|
102
97
|
newLoadByReferenceWithVersionStep,
|
|
103
98
|
newResolveBySlugForVersionsStep,
|
|
99
|
+
versionHistoryTarget,
|
|
104
100
|
} from "../../pipeline/steps/version-history.js";
|
|
101
|
+
import {
|
|
102
|
+
loadedTargetAsMethod,
|
|
103
|
+
newAuthorizeResolvedTargetStep,
|
|
104
|
+
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
105
105
|
import type { VersionHistoryBinding } from "../../pipeline/steps/version-history.js";
|
|
106
106
|
import { newAuthorizeVisibilityTransitionStep } from "../../pipeline/steps/visibility-gates.js";
|
|
107
107
|
import { metadataOf } from "../../pipeline/steps/shapes.js";
|
|
@@ -718,22 +718,13 @@ async function getByReference(
|
|
|
718
718
|
"LoadPluginByReference",
|
|
719
719
|
),
|
|
720
720
|
)
|
|
721
|
-
.addStep(
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
{
|
|
729
|
-
permission: IamPermission.can_view,
|
|
730
|
-
resourceKind: ApiResourceKind.plugin,
|
|
731
|
-
resourceId: resolved.metadata?.id ?? "",
|
|
732
|
-
},
|
|
733
|
-
"unauthorized to get plugin",
|
|
734
|
-
);
|
|
735
|
-
},
|
|
736
|
-
})
|
|
721
|
+
.addStep(
|
|
722
|
+
newAuthorizeResolvedTargetStep(
|
|
723
|
+
deps.authorizer,
|
|
724
|
+
loadedTargetAsMethod(PluginQueryController.method.get),
|
|
725
|
+
"AuthorizeResolvedPlugin",
|
|
726
|
+
),
|
|
727
|
+
)
|
|
737
728
|
.build()
|
|
738
729
|
.execute(reqCtx);
|
|
739
730
|
return reqCtx.get(TARGET_RESOURCE_KEY) as Plugin;
|
|
@@ -817,21 +808,16 @@ async function listVersions(
|
|
|
817
808
|
"ResolvePluginBySlug",
|
|
818
809
|
),
|
|
819
810
|
)
|
|
820
|
-
.addStep(
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
stepCtx.callerIdentity,
|
|
826
|
-
{
|
|
827
|
-
permission: IamPermission.can_view,
|
|
828
|
-
resourceKind: ApiResourceKind.plugin,
|
|
829
|
-
resourceId: stepCtx.get(LIST_VERSIONS_RESOURCE_ID_KEY) as string,
|
|
830
|
-
},
|
|
811
|
+
.addStep(
|
|
812
|
+
newAuthorizeResolvedTargetStep(
|
|
813
|
+
deps.authorizer,
|
|
814
|
+
versionHistoryTarget(
|
|
815
|
+
ApiResourceKind.plugin,
|
|
831
816
|
"unauthorized to view plugin version history",
|
|
832
|
-
)
|
|
833
|
-
|
|
834
|
-
|
|
817
|
+
),
|
|
818
|
+
"AuthorizeResolvedPlugin",
|
|
819
|
+
),
|
|
820
|
+
)
|
|
835
821
|
.addStep(
|
|
836
822
|
newLoadAndMapVersionsStep(
|
|
837
823
|
deps.store,
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* lane passes GuardReservedLabels structurally (the controller stamps the
|
|
6
6
|
* membership labels by design), so this module is the one place plugin-
|
|
7
7
|
* provided metadata is judged before it can ride that lane. Without it an
|
|
8
|
-
* archive could carry `stigmer.ai
|
|
9
|
-
*
|
|
8
|
+
* archive could carry any `stigmer.ai/*` label in its overlays and have
|
|
9
|
+
* the server act on a platform decision the plugin's author made.
|
|
10
10
|
*
|
|
11
11
|
* Four rules, each one sentence with the document's path:
|
|
12
12
|
* - a `stigmer.ai/*` label costs `can_write_reserved_labels` on
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins the create lane's authorization question (steps.ts,
|
|
3
|
+
* resolveScheduleCreateTargets): can_edit on the REFERENCED AGENT with the
|
|
4
|
+
* Java handler's copy, and nothing on the organization (the same-org
|
|
5
|
+
* invariant already binds the schedule to the agent's); a missing
|
|
6
|
+
* referenced agent throws.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
import { create } from "@bufbuild/protobuf";
|
|
10
|
+
|
|
11
|
+
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
12
|
+
import { ScheduleSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
13
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
14
|
+
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
15
|
+
|
|
16
|
+
import { testCallerIdentity } from "../../../pipeline/__tests__/support.js";
|
|
17
|
+
import { RequestContext } from "../../../pipeline/request-context.js";
|
|
18
|
+
import {
|
|
19
|
+
REFERENCED_AGENT_KEY,
|
|
20
|
+
SCHEDULE_CREATE_DENIED_MESSAGE,
|
|
21
|
+
resolveScheduleCreateTargets,
|
|
22
|
+
} from "../steps.js";
|
|
23
|
+
|
|
24
|
+
const agent = create(AgentSchema, {
|
|
25
|
+
metadata: { id: "agt_01target", name: "helper", org: "acme" },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function ctxFor(stash = true) {
|
|
29
|
+
const ctx = new RequestContext(
|
|
30
|
+
ScheduleSchema,
|
|
31
|
+
create(ScheduleSchema, { metadata: { name: "nightly", org: "acme" } }),
|
|
32
|
+
testCallerIdentity(),
|
|
33
|
+
ApiResourceKind.schedule,
|
|
34
|
+
);
|
|
35
|
+
if (stash) {
|
|
36
|
+
ctx.set(REFERENCED_AGENT_KEY, agent);
|
|
37
|
+
}
|
|
38
|
+
return ctx;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe("resolveScheduleCreateTargets", () => {
|
|
42
|
+
it("asks can_edit on the referenced agent and nothing else", () => {
|
|
43
|
+
expect(resolveScheduleCreateTargets(ctxFor())).toEqual([
|
|
44
|
+
{
|
|
45
|
+
permission: IamPermission.can_edit,
|
|
46
|
+
resourceKind: ApiResourceKind.agent,
|
|
47
|
+
resourceId: "agt_01target",
|
|
48
|
+
deniedMessage: SCHEDULE_CREATE_DENIED_MESSAGE,
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("a missing referenced agent is a broken chain invariant and throws", () => {
|
|
54
|
+
expect(() => resolveScheduleCreateTargets(ctxFor(false))).toThrow(
|
|
55
|
+
"referenced agent not found in context",
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -62,6 +62,10 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
|
62
62
|
import { callerIdentityOf } from "../../pipeline/interceptors/auth.js";
|
|
63
63
|
import { RequestContext } from "../../pipeline/request-context.js";
|
|
64
64
|
import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
|
|
65
|
+
import {
|
|
66
|
+
loadedTargetAsMethod,
|
|
67
|
+
newAuthorizeResolvedTargetStep,
|
|
68
|
+
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
65
69
|
import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
|
|
66
70
|
import { newBuildNewStateStep } from "../../pipeline/steps/defaults.js";
|
|
67
71
|
import { newBuildUpdateStateStep } from "../../pipeline/steps/build-update-state.js";
|
|
@@ -116,6 +120,7 @@ import { newClearSchedulePauseStep } from "./resume.js";
|
|
|
116
120
|
import {
|
|
117
121
|
newResolveScheduleDefaultsStep,
|
|
118
122
|
newValidateScheduleUpdateStep,
|
|
123
|
+
resolveScheduleCreateTargets,
|
|
119
124
|
} from "./steps.js";
|
|
120
125
|
import {
|
|
121
126
|
TRIGGER_RESULT_KEY,
|
|
@@ -201,6 +206,15 @@ async function createSchedule(
|
|
|
201
206
|
.addStep(newValidateProtoStep())
|
|
202
207
|
.addStep(newValidateVisibilityStep())
|
|
203
208
|
.addStep(newResolveScheduleDefaultsStep(deps))
|
|
209
|
+
// Before the duplicate check and before ArmSchedule: a refused caller
|
|
210
|
+
// learns nothing about existing slugs and costs no Temporal schedule
|
|
211
|
+
// (steps.ts, resolveScheduleCreateTargets).
|
|
212
|
+
.addStep(
|
|
213
|
+
newAuthorizeResolvedTargetStep(
|
|
214
|
+
deps.authorizer,
|
|
215
|
+
resolveScheduleCreateTargets,
|
|
216
|
+
),
|
|
217
|
+
)
|
|
204
218
|
.addStep(newResolveSlugStep())
|
|
205
219
|
.addStep(newCheckDuplicateStep(deps.store))
|
|
206
220
|
.addStep(newBuildNewStateStep())
|
|
@@ -477,6 +491,12 @@ async function getByReference(
|
|
|
477
491
|
)
|
|
478
492
|
.addStep(newValidateProtoStep())
|
|
479
493
|
.addStep(newLoadByReferenceStep(deps.store, ScheduleSchema))
|
|
494
|
+
.addStep(
|
|
495
|
+
newAuthorizeResolvedTargetStep(
|
|
496
|
+
deps.authorizer,
|
|
497
|
+
loadedTargetAsMethod(ScheduleQueryController.method.get),
|
|
498
|
+
),
|
|
499
|
+
)
|
|
480
500
|
.build()
|
|
481
501
|
.execute(reqCtx);
|
|
482
502
|
return reqCtx.get(TARGET_RESOURCE_KEY) as Schedule;
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
* __tests__/schedule.composed.test.ts.
|
|
9
9
|
*/
|
|
10
10
|
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
11
|
+
import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
11
12
|
import { ScheduleSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
12
13
|
import type { Schedule } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
13
14
|
import type { ScheduleSpec } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/spec_pb";
|
|
14
15
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
16
|
+
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
15
17
|
|
|
16
18
|
import {
|
|
17
19
|
failedPreconditionError,
|
|
@@ -21,6 +23,7 @@ import {
|
|
|
21
23
|
} from "../../pipeline/errors.js";
|
|
22
24
|
import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
23
25
|
import type { RequestContext } from "../../pipeline/request-context.js";
|
|
26
|
+
import type { AuthorizationTarget } from "../../pipeline/steps/authorize.js";
|
|
24
27
|
import { findResourceBySlug } from "../../pipeline/steps/helpers.js";
|
|
25
28
|
import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
|
|
26
29
|
import type { Store } from "../../store/interface.js";
|
|
@@ -128,10 +131,47 @@ export function newResolveScheduleDefaultsStep(
|
|
|
128
131
|
if (agentRef !== undefined) {
|
|
129
132
|
agentRef.org = refOrg;
|
|
130
133
|
}
|
|
134
|
+
ctx.set(REFERENCED_AGENT_KEY, found);
|
|
131
135
|
},
|
|
132
136
|
};
|
|
133
137
|
}
|
|
134
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Context key for the agent ResolveScheduleDefaults resolved from
|
|
141
|
+
* spec.agent.agent_ref, read by the create lane's authorization step.
|
|
142
|
+
*/
|
|
143
|
+
export const REFERENCED_AGENT_KEY = "scheduleReferencedAgent";
|
|
144
|
+
|
|
145
|
+
/** The deny copy of the create bar, the Java ScheduleCreateHandler's. */
|
|
146
|
+
export const SCHEDULE_CREATE_DENIED_MESSAGE =
|
|
147
|
+
"You don't have permission to schedule this agent";
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The create lane's authorization question, for AuthorizeResolvedTarget
|
|
151
|
+
* after ResolveScheduleDefaults: can_edit on the REFERENCED AGENT. The RPC
|
|
152
|
+
* is is_skip_authorization because its target is that agent, resolved from
|
|
153
|
+
* a slug, not a request field; and there is deliberately no organization
|
|
154
|
+
* bar — a schedule is unattended spend on an agent, an editor's act, and
|
|
155
|
+
* the same-org invariant the resolve step enforces already binds the
|
|
156
|
+
* schedule's organization to the agent's (command.proto).
|
|
157
|
+
*/
|
|
158
|
+
export function resolveScheduleCreateTargets(
|
|
159
|
+
ctx: RequestContext<typeof ScheduleSchema>,
|
|
160
|
+
): ReadonlyArray<AuthorizationTarget> {
|
|
161
|
+
const agent = ctx.get(REFERENCED_AGENT_KEY) as Agent | undefined;
|
|
162
|
+
if (agent === undefined) {
|
|
163
|
+
throw new Error("referenced agent not found in context");
|
|
164
|
+
}
|
|
165
|
+
return [
|
|
166
|
+
{
|
|
167
|
+
permission: IamPermission.can_edit,
|
|
168
|
+
resourceKind: ApiResourceKind.agent,
|
|
169
|
+
resourceId: agent.metadata?.id ?? "",
|
|
170
|
+
deniedMessage: SCHEDULE_CREATE_DENIED_MESSAGE,
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
|
|
135
175
|
/**
|
|
136
176
|
* Enforces the schedule-specific workspace constraint on the shared
|
|
137
177
|
* AgentInvocation (DD-018 D-3): every workspace entry must be a git_repo
|
|
@@ -140,7 +180,9 @@ export function newResolveScheduleDefaultsStep(
|
|
|
140
180
|
* deterministic provisioning failure at 3 AM. Copy is cross-edition
|
|
141
181
|
* contract (Go validateScheduleWorkspace).
|
|
142
182
|
*/
|
|
143
|
-
export function validateScheduleWorkspace(
|
|
183
|
+
export function validateScheduleWorkspace(
|
|
184
|
+
spec: ScheduleSpec | undefined,
|
|
185
|
+
): void {
|
|
144
186
|
const entries =
|
|
145
187
|
spec?.target.case === "agent" ? spec.target.value.workspaceEntries : [];
|
|
146
188
|
for (const [i, entry] of entries.entries()) {
|
|
@@ -174,7 +216,8 @@ export function validateScheduleModelPinning(
|
|
|
174
216
|
if (presence !== "") {
|
|
175
217
|
throw invalidArgumentError(presence);
|
|
176
218
|
}
|
|
177
|
-
const invocation =
|
|
219
|
+
const invocation =
|
|
220
|
+
spec?.target.case === "agent" ? spec.target.value : undefined;
|
|
178
221
|
const existence = unknownModelPinRefusal(
|
|
179
222
|
modelRegistry,
|
|
180
223
|
"spec.agent.run_config.model_name",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Pins the run gate's SPLICE in session-create over the real router (P1
|
|
3
|
-
* sp.run-gate): the AuthorizeRunTarget step sits after
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
3
|
+
* sp.run-gate): the AuthorizeRunTarget step sits right after Authorize
|
|
4
|
+
* and before Persist, so (1) a denied caller answers PERMISSION_DENIED
|
|
5
|
+
* with the domain's byte-pinned copy and leaves no session row; (2) the
|
|
6
|
+
* built-in-assistant shape (empty spec) makes NO run-gate check and
|
|
7
|
+
* creates the session even under a denying run-gate authorizer — the
|
|
8
|
+
* organization's own create permission admitted it in the Authorize step;
|
|
9
9
|
* (3) an allowed caller creates the session exactly as before. The
|
|
10
10
|
* authorizer under test answers only run-gate checks (runGateOnlyAuthorizer),
|
|
11
11
|
* so every refusal here is the run gate's and nobody else's.
|
|
@@ -20,11 +20,9 @@ import { Code, ConnectError, createClient } from "@connectrpc/connect";
|
|
|
20
20
|
import { createGrpcTransport } from "@connectrpc/connect-node";
|
|
21
21
|
|
|
22
22
|
import { AgentCommandController } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/command_pb";
|
|
23
|
-
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
24
23
|
import { AgentQueryController } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/query_pb";
|
|
25
24
|
import { SessionCommandController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/command_pb";
|
|
26
25
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
27
|
-
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
28
26
|
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
29
27
|
|
|
30
28
|
import { loadConfig } from "../../../boot/config.js";
|
|
@@ -33,10 +31,6 @@ import type { ComposedServer } from "../../../boot/compose.js";
|
|
|
33
31
|
import { createLogger } from "../../../boot/logger.js";
|
|
34
32
|
import type { AuthzDecision } from "../../../extensions/authorizer.js";
|
|
35
33
|
import { runGateOnlyAuthorizer } from "../../../pipeline/__tests__/support.js";
|
|
36
|
-
import {
|
|
37
|
-
DEFAULT_AGENT_LABEL,
|
|
38
|
-
DEFAULT_AGENT_LABEL_VALUE,
|
|
39
|
-
} from "../../agent/defaultagent.js";
|
|
40
34
|
import { runAgentInstanceDeniedMessage } from "../constants.js";
|
|
41
35
|
|
|
42
36
|
const silentLogger = createLogger({
|
|
@@ -99,23 +93,6 @@ async function createAgent(name: string): Promise<string> {
|
|
|
99
93
|
return agent.metadata!.id;
|
|
100
94
|
}
|
|
101
95
|
|
|
102
|
-
/** The default-agent label is operator-seeded state; stamp it on the row. */
|
|
103
|
-
async function markDefaultAgent(agentId: string): Promise<void> {
|
|
104
|
-
const stored = await server.store.getResource(
|
|
105
|
-
ApiResourceKind.agent,
|
|
106
|
-
agentId,
|
|
107
|
-
AgentSchema,
|
|
108
|
-
);
|
|
109
|
-
stored.metadata!.labels[DEFAULT_AGENT_LABEL] = DEFAULT_AGENT_LABEL_VALUE;
|
|
110
|
-
stored.metadata!.visibility = ApiResourceVisibility.visibility_public;
|
|
111
|
-
await server.store.saveResource(
|
|
112
|
-
ApiResourceKind.agent,
|
|
113
|
-
agentId,
|
|
114
|
-
AgentSchema,
|
|
115
|
-
stored,
|
|
116
|
-
);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
96
|
async function captureError(
|
|
120
97
|
run: () => Promise<unknown>,
|
|
121
98
|
): Promise<ConnectError> {
|
|
@@ -154,33 +131,23 @@ describe("session-create run gate (composed server)", () => {
|
|
|
154
131
|
expect(await sessionCount(), "no row behind a denial").toBe(before);
|
|
155
132
|
});
|
|
156
133
|
|
|
157
|
-
it("
|
|
134
|
+
it("makes no check for the built-in assistant (empty spec) and creates the session", async () => {
|
|
158
135
|
decision = { kind: "deny", reason: "" };
|
|
159
136
|
gate.runGateChecks.length = 0;
|
|
160
|
-
const
|
|
161
|
-
await markDefaultAgent(agentId);
|
|
137
|
+
const before = await sessionCount();
|
|
162
138
|
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}),
|
|
170
|
-
);
|
|
139
|
+
const session = await sessionCommand.create({
|
|
140
|
+
apiVersion: API_VERSION,
|
|
141
|
+
kind: "Session",
|
|
142
|
+
metadata: { name: "Session-first", org: ORG },
|
|
143
|
+
spec: {},
|
|
144
|
+
});
|
|
171
145
|
|
|
172
|
-
|
|
173
|
-
//
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
const resolvedInstanceId = agent.status?.defaultInstanceId ?? "";
|
|
178
|
-
expect(resolvedInstanceId).not.toBe("");
|
|
179
|
-
expect(gate.runGateChecks).toHaveLength(1);
|
|
180
|
-
expect(gate.runGateChecks[0].resourceId).toBe(resolvedInstanceId);
|
|
181
|
-
expect(err.rawMessage).toBe(
|
|
182
|
-
runAgentInstanceDeniedMessage(resolvedInstanceId),
|
|
183
|
-
);
|
|
146
|
+
// No instance, no blueprint to spend, no target: the gate is silent
|
|
147
|
+
// and the denying authorizer is never asked.
|
|
148
|
+
expect(gate.runGateChecks).toHaveLength(0);
|
|
149
|
+
expect(session.spec?.agentInstanceId).toBe("");
|
|
150
|
+
expect(await sessionCount()).toBe(before + 1);
|
|
184
151
|
});
|
|
185
152
|
|
|
186
153
|
it("not-found answers NOT_FOUND naming the instance (the stigmer#224 order)", async () => {
|