@stigmer/server 3.19.1-dev.20260920100552 → 3.21.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.
Files changed (91) hide show
  1. package/dist/boot/compose.d.ts.map +1 -1
  2. package/dist/boot/compose.js +0 -1
  3. package/dist/boot/compose.js.map +1 -1
  4. package/dist/boot/inprocess.d.ts +0 -2
  5. package/dist/boot/inprocess.d.ts.map +1 -1
  6. package/dist/boot/inprocess.js +0 -6
  7. package/dist/boot/inprocess.js.map +1 -1
  8. package/dist/domain/agent/controller.d.ts +2 -2
  9. package/dist/domain/agent/controller.d.ts.map +1 -1
  10. package/dist/domain/agent/controller.js +1 -17
  11. package/dist/domain/agent/controller.js.map +1 -1
  12. package/dist/domain/agent/steps.d.ts +0 -1
  13. package/dist/domain/agent/steps.d.ts.map +1 -1
  14. package/dist/domain/agent/steps.js +1 -40
  15. package/dist/domain/agent/steps.js.map +1 -1
  16. package/dist/domain/agentexecution/controller.d.ts.map +1 -1
  17. package/dist/domain/agentexecution/controller.js +7 -9
  18. package/dist/domain/agentexecution/controller.js.map +1 -1
  19. package/dist/domain/agentexecution/create-execution-context-step.d.ts +0 -2
  20. package/dist/domain/agentexecution/create-execution-context-step.d.ts.map +1 -1
  21. package/dist/domain/agentexecution/create-execution-context-step.js +179 -60
  22. package/dist/domain/agentexecution/create-execution-context-step.js.map +1 -1
  23. package/dist/domain/agentexecution/create-steps.d.ts +16 -31
  24. package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
  25. package/dist/domain/agentexecution/create-steps.js +36 -102
  26. package/dist/domain/agentexecution/create-steps.js.map +1 -1
  27. package/dist/domain/agentexecution/run-target.d.ts +7 -3
  28. package/dist/domain/agentexecution/run-target.d.ts.map +1 -1
  29. package/dist/domain/agentexecution/run-target.js.map +1 -1
  30. package/dist/domain/environment/personal.d.ts +42 -0
  31. package/dist/domain/environment/personal.d.ts.map +1 -0
  32. package/dist/domain/environment/personal.js +96 -0
  33. package/dist/domain/environment/personal.js.map +1 -0
  34. package/dist/domain/mcpserver/connect.d.ts +0 -2
  35. package/dist/domain/mcpserver/connect.d.ts.map +1 -1
  36. package/dist/domain/mcpserver/connect.js +16 -72
  37. package/dist/domain/mcpserver/connect.js.map +1 -1
  38. package/dist/domain/plugin/overlay/sanitize.js +2 -2
  39. package/dist/domain/session/controller.d.ts +0 -7
  40. package/dist/domain/session/controller.d.ts.map +1 -1
  41. package/dist/domain/session/controller.js +11 -16
  42. package/dist/domain/session/controller.js.map +1 -1
  43. package/dist/domain/session/run-target.d.ts +9 -8
  44. package/dist/domain/session/run-target.d.ts.map +1 -1
  45. package/dist/domain/session/run-target.js.map +1 -1
  46. package/dist/domain/session/steps.d.ts +0 -27
  47. package/dist/domain/session/steps.d.ts.map +1 -1
  48. package/dist/domain/session/steps.js +10 -151
  49. package/dist/domain/session/steps.js.map +1 -1
  50. package/dist/domain/workflowexecution/create-steps.d.ts +4 -3
  51. package/dist/domain/workflowexecution/create-steps.d.ts.map +1 -1
  52. package/dist/domain/workflowexecution/create-steps.js +4 -3
  53. package/dist/domain/workflowexecution/create-steps.js.map +1 -1
  54. package/dist/pipeline/apiresource-labels.d.ts +2 -2
  55. package/dist/pipeline/apiresource-labels.js +2 -2
  56. package/dist/pipeline/errors.d.ts +2 -2
  57. package/dist/pipeline/errors.js +2 -2
  58. package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
  59. package/dist/pipeline/steps/guard-reserved-labels.js +6 -5
  60. package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
  61. package/package.json +6 -6
  62. package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +1 -1
  63. package/src/boot/compose.ts +0 -1
  64. package/src/boot/inprocess.ts +0 -9
  65. package/src/domain/agent/__tests__/agent.test.ts +0 -68
  66. package/src/domain/agent/controller.ts +3 -38
  67. package/src/domain/agent/steps.ts +1 -60
  68. package/src/domain/agentexecution/__tests__/create-execution-context-step.test.ts +216 -0
  69. package/src/domain/agentexecution/__tests__/create-steps.test.ts +70 -145
  70. package/src/domain/agentexecution/controller.ts +6 -10
  71. package/src/domain/agentexecution/create-execution-context-step.ts +271 -83
  72. package/src/domain/agentexecution/create-steps.ts +38 -138
  73. package/src/domain/agentexecution/run-target.ts +7 -3
  74. package/src/domain/environment/__tests__/personal.test.ts +143 -0
  75. package/src/domain/environment/personal.ts +141 -0
  76. package/src/domain/mcpserver/connect.ts +21 -82
  77. package/src/domain/plugin/overlay/sanitize.ts +2 -2
  78. package/src/domain/session/__tests__/run-gate.test.ts +19 -52
  79. package/src/domain/session/__tests__/session.test.ts +27 -203
  80. package/src/domain/session/controller.ts +10 -30
  81. package/src/domain/session/run-target.ts +9 -8
  82. package/src/domain/session/steps.ts +9 -235
  83. package/src/domain/workflowexecution/create-steps.ts +4 -3
  84. package/src/pipeline/apiresource-labels.ts +2 -2
  85. package/src/pipeline/errors.ts +2 -2
  86. package/src/pipeline/steps/guard-reserved-labels.ts +6 -5
  87. package/dist/domain/agent/defaultagent.d.ts +0 -37
  88. package/dist/domain/agent/defaultagent.d.ts.map +0 -1
  89. package/dist/domain/agent/defaultagent.js +0 -104
  90. package/dist/domain/agent/defaultagent.js.map +0 -1
  91. package/src/domain/agent/defaultagent.ts +0 -135
@@ -1,13 +1,14 @@
1
1
  /**
2
- * The session run-target resolver (P1 sp.run-gate): a session is a
3
- * conversation bound to ONE agent instance, so its run target is that
4
- * instance — agent_instance#can_execute on spec.agent_instance_id.
2
+ * The session run-target resolver (P1 sp.run-gate): a session bound to an
3
+ * agent instance has that instance as its run target —
4
+ * agent_instance#can_execute on spec.agent_instance_id.
5
5
  *
6
- * Pure over the record being built. ResolveDefaultAgentInstance runs before
7
- * the gate and guarantees the id (the caller's, or the platform default
8
- * agent's default instance), so an empty id here is that step's own
9
- * refusal already thrown, never a check to make. Read from newState, where
10
- * the resolution writes — the same clone gotcha steps.ts records.
6
+ * Pure over the record being built. An empty id is the built-in assistant
7
+ * (session/v1/spec.proto): there is no blueprint to spend, so the answer is
8
+ * "no target" and the gate makes no check. What admits the conversation is
9
+ * the Authorize step ahead of the gate — can_create_session on the
10
+ * organization — and each turn is admitted by the session's own
11
+ * can_create_execution_in on the execution chain.
11
12
  */
12
13
  import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
13
14
 
@@ -6,22 +6,22 @@
6
6
  * record_harness_state_history.go) and its steps/ package
7
7
  * (filter_by_agent_instance.go, filter_by_channel.go). Shared steps stay
8
8
  * in src/pipeline/steps/; these exist because they embody
9
- * session-specific contracts: the default-agent-instance resolution, the
10
- * harness/execution-target immutability sentinels, the server-owned
11
- * harness-state history, the active-execution delete guard with its
12
- * execution cascade, and the list filters.
9
+ * session-specific contracts: the harness/execution-target immutability
10
+ * sentinels, the server-owned harness-state history, the active-execution
11
+ * delete guard with its execution cascade, and the list filters.
12
+ *
13
+ * An empty spec.agent_instance_id is a legal shape and stays empty: the
14
+ * session runs the built-in assistant (session/v1/spec.proto). No step here
15
+ * resolves it into an instance, and no step guards it on update, because
16
+ * a conversation may gain an agent or drop back to the assistant; the
17
+ * immutable fields are the harness and the execution target below.
13
18
  */
14
- import { Code, ConnectError } from "@connectrpc/connect";
15
19
  import { create, fromBinary } from "@bufbuild/protobuf";
16
20
  import type { DescMessage } from "@bufbuild/protobuf";
17
21
 
18
- import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
19
- import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
20
- import { AgentStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/status_pb";
21
22
  import { AgentExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
22
23
  import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
23
24
  import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
24
- import type { AgentInstance } from "@stigmer/protos/ai/stigmer/agentic/agentinstance/v1/api_pb";
25
25
  import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
26
26
  import type { Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
27
27
  import {
@@ -30,7 +30,6 @@ import {
30
30
  } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
31
31
  import { SessionListSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/io_pb";
32
32
  import { SessionQueryController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/query_pb";
33
- import { SessionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
34
33
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
35
34
  import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
36
35
 
@@ -38,29 +37,19 @@ import type { Logger } from "../../boot/logger.js";
38
37
  import type { AgentExecutionTemporalConfig } from "../agentexecution/temporal/config.js";
39
38
  import {
40
39
  failedPreconditionError,
41
- goWrappedStatusError,
42
40
  internalError,
43
41
  invalidArgumentError,
44
42
  } from "../../pipeline/errors.js";
45
43
  import type { PipelineStep } from "../../pipeline/pipeline.js";
46
- import type { CallerIdentity } from "../../extensions/identity.js";
47
44
  import type { Authorizer } from "../../extensions/authorizer.js";
48
45
  import type { ListReadScope } from "../../extensions/list-read-scope.js";
49
46
  import { restrictListByReadScope } from "../../extensions/list-read-scope.js";
50
- import type { ResourceAuthorizationLifecycle } from "../../extensions/resource-authorization.js";
51
47
  import { authorizeResolvedResource } from "../../pipeline/steps/authorize.js";
52
- import { notifyDefaultInstanceLinked } from "../../pipeline/steps/authorization-tuples.js";
53
48
  import type { RequestContext } from "../../pipeline/request-context.js";
54
49
  import { RESOURCE_ID_KEY } from "../../pipeline/steps/delete.js";
55
50
  import { compareCreatedAtDesc } from "../../pipeline/steps/helpers.js";
56
51
  import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
57
52
  import type { Store } from "../../store/interface.js";
58
- import { buildDefaultInstanceRequest } from "../agentinstance/defaultinstance.js";
59
- import {
60
- DefaultAgentNotConfiguredError,
61
- DefaultAgentNotPublicError,
62
- findDefaultAgent,
63
- } from "../agent/defaultagent.js";
64
53
 
65
54
  type SessionDesc = typeof SessionSchema;
66
55
 
@@ -74,221 +63,6 @@ export const LIST_RESULT_KEY = "listResult";
74
63
  */
75
64
  const CHANNEL_ID_LABEL_KEY = "stigmer.ai/channel-id";
76
65
 
77
- /**
78
- * The narrow in-process surface the session domain needs from
79
- * agentinstance — consumer-defined so the dependency reads at the domain
80
- * boundary (the Go twin is pkg/downstream/agentinstance.Client). This is
81
- * the CREATE RPC (Go CreateAsSystem), not apply: the resolve step only
82
- * reaches it when the default instance is known to be missing, and a
83
- * duplicate-slug collision must surface as AlreadyExists, not silently
84
- * update. Calls ride the in-process router transport, traversing the full
85
- * interceptor chain (DD-002).
86
- */
87
- export interface AgentInstanceCreator {
88
- /**
89
- * Creates AS THE ORIGINAL CALLER (C2 Stage 3, ruling R5 — the Java
90
- * createAsCaller posture): the propagated identity gives the created
91
- * instance real owner attribution under an enforcing Authorizer.
92
- */
93
- createAsCaller(
94
- instance: AgentInstance,
95
- caller: CallerIdentity,
96
- ): Promise<AgentInstance>;
97
- }
98
-
99
- /**
100
- * Lazy provider for the in-process agentinstance edge — resolved at call
101
- * time, never at construction (the ratified DI story, D2 §2).
102
- */
103
- export type AgentInstanceCreatorProvider = () => AgentInstanceCreator;
104
-
105
- // ---------------------------------------------------------------------------
106
- // ResolveDefaultAgentInstance — create.go:62-182: when agent_instance_id is
107
- // not provided, resolve the platform default agent (shared defaultagent
108
- // implementation: label stigmer.ai/default-agent=true, visibility_public,
109
- // deterministic incumbent-wins tie-break), get or create its default
110
- // instance, and set agent_instance_id on the session spec. This enables the
111
- // session-first UX where users create a session (with workspace entries)
112
- // without knowing the agent instance — the backend resolves it
113
- // automatically.
114
- //
115
- // Runs FIRST in the create chain, before ValidateProto — resolution must
116
- // fill agent_instance_id before validation sees the spec.
117
- //
118
- // The id lands on ctx.newState.spec, NEVER on input: the pipeline cloned
119
- // input into newState at construction and Persist saves newState, so
120
- // mutating input does not propagate (Go's documented clone gotcha,
121
- // create.go:168-170).
122
- // ---------------------------------------------------------------------------
123
-
124
- export function newResolveDefaultAgentInstanceStep(
125
- store: Store,
126
- creator: AgentInstanceCreatorProvider,
127
- logger: Logger,
128
- authorizationLifecycle?: ResourceAuthorizationLifecycle,
129
- ): PipelineStep<SessionDesc> {
130
- return {
131
- name: "ResolveDefaultAgentInstance",
132
- async execute(ctx: RequestContext<SessionDesc>): Promise<void> {
133
- if ((ctx.input.spec?.agentInstanceId ?? "") !== "") {
134
- return;
135
- }
136
-
137
- logger.info(
138
- "agent_instance_id not provided on session, resolving platform default agent",
139
- );
140
-
141
- // 1. Resolve the default agent. The error copy is Go WrapError's
142
- // "%s: %v" — the sentinel's text RIDES the wire message, and the
143
- // NotFound arm carries Go's DOUBLE wrap (fmt.Errorf("no default
144
- // agent available on this platform: %w", err) inside WrapError).
145
- // Byte-pinned.
146
- let defaultAgent: Agent;
147
- try {
148
- defaultAgent = await findDefaultAgent(store, logger);
149
- } catch (error) {
150
- if (error instanceof DefaultAgentNotConfiguredError) {
151
- logger.error("No platform default agent configured", {
152
- error: error.message,
153
- });
154
- throw new ConnectError(
155
- `No default agent available. Ensure an agent with label stigmer.ai/default-agent=true and visibility_public exists: no default agent available on this platform: ${error.message}`,
156
- Code.NotFound,
157
- );
158
- }
159
- if (error instanceof DefaultAgentNotPublicError) {
160
- logger.error("Default agent is not visibility_public", {
161
- error: error.message,
162
- });
163
- throw new ConnectError(
164
- `Default agent exists but is not visibility_public: ${error.message}`,
165
- Code.FailedPrecondition,
166
- );
167
- }
168
- // Store/decode failure — an internal fault, not "no default
169
- // agent". InternalError keeps the cause off the wire
170
- // (stigmer/stigmer#478).
171
- logger.error("Failed to resolve platform default agent", {
172
- error: error instanceof Error ? error.message : String(error),
173
- });
174
- throw internalError(
175
- error,
176
- "failed to resolve the platform default agent",
177
- );
178
- }
179
-
180
- const metadata = defaultAgent.metadata;
181
- if (metadata === undefined) {
182
- // Unreachable: findDefaultAgent only returns public-visibility
183
- // candidates, whose metadata is necessarily set.
184
- throw internalError(
185
- new Error("default agent metadata is nil"),
186
- "failed to resolve the platform default agent",
187
- );
188
- }
189
- const agentId = metadata.id;
190
- logger.info("Resolved platform default agent", {
191
- agentId,
192
- agentName: metadata.name,
193
- });
194
-
195
- // 2. Get or create the default instance.
196
- let defaultInstanceId = defaultAgent.status?.defaultInstanceId ?? "";
197
- if (defaultInstanceId === "") {
198
- logger.info("Default instance missing, creating one", { agentId });
199
-
200
- const instanceRequest = buildDefaultInstanceRequest(metadata);
201
-
202
- // Go create.go:144-148 wraps the downstream error with fmt.Errorf
203
- // ("failed to create default instance for default agent: %w") and
204
- // PipelineError.GRPCStatus's errors.As branch keeps the inner
205
- // CODE but rewrites the wire MESSAGE to the wrapped text —
206
- // transport formatting (`rpc error: code = X desc = ...`)
207
- // included. Mirrored byte-for-byte via goWrappedStatusError; the
208
- // leak is stigmer/stigmer#852 (both-editions post-cutover fix).
209
- // Unstatused failures fall to the pipeline's Internal fallback,
210
- // exactly Go's plain-error path.
211
- let createdInstance: AgentInstance;
212
- try {
213
- createdInstance = await creator().createAsCaller(
214
- instanceRequest,
215
- ctx.callerIdentity,
216
- );
217
- } catch (error) {
218
- logger.error("Failed to create default instance", {
219
- agentId,
220
- error: error instanceof Error ? error.message : String(error),
221
- });
222
- if (error instanceof ConnectError) {
223
- throw goWrappedStatusError(
224
- "failed to create default instance for default agent",
225
- error,
226
- );
227
- }
228
- throw new Error(
229
- `failed to create default instance for default agent: ${error instanceof Error ? error.message : String(error)}`,
230
- );
231
- }
232
-
233
- defaultInstanceId = createdInstance.metadata?.id ?? "";
234
-
235
- // Persist default_instance_id on the agent — EXPLICITLY the agent
236
- // kind: this pipeline's ctx kind is session (Go hardcodes
237
- // ApiResourceKind_agent here too).
238
- if (defaultAgent.status === undefined) {
239
- defaultAgent.status = create(AgentStatusSchema, {});
240
- }
241
- defaultAgent.status.defaultInstanceId = defaultInstanceId;
242
- try {
243
- await store.saveResource(
244
- ApiResourceKind.agent,
245
- agentId,
246
- AgentSchema,
247
- defaultAgent,
248
- );
249
- } catch (error) {
250
- logger.error("Failed to persist agent with default_instance_id", {
251
- agentId,
252
- error: error instanceof Error ? error.message : String(error),
253
- });
254
- // Go wraps as a plain error → the pipeline's Internal fallback.
255
- throw new Error(
256
- `failed to persist agent with default instance: ${error instanceof Error ? error.message : String(error)}`,
257
- );
258
- }
259
-
260
- // The default_of invariant rides the pointer persist (C2 Stage 3).
261
- await notifyDefaultInstanceLinked(authorizationLifecycle, {
262
- instanceKind: ApiResourceKind.agent_instance,
263
- instanceId: defaultInstanceId,
264
- blueprintKind: ApiResourceKind.agent,
265
- blueprintId: agentId,
266
- });
267
-
268
- logger.info("Created default instance for default agent", {
269
- instanceId: defaultInstanceId,
270
- agentId,
271
- });
272
- }
273
-
274
- // 3. Set agent_instance_id on the session's newState (not input) —
275
- // see the module-level clone gotcha note.
276
- const newState = ctx.newState;
277
- if (newState.spec === undefined) {
278
- newState.spec = create(SessionSpecSchema, {});
279
- }
280
- newState.spec.agentInstanceId = defaultInstanceId;
281
-
282
- logger.info(
283
- "Set agent_instance_id on session from platform default agent",
284
- {
285
- agentInstanceId: defaultInstanceId,
286
- },
287
- );
288
- },
289
- };
290
- }
291
-
292
66
  // ---------------------------------------------------------------------------
293
67
  // ValidateHarnessImmutability — validate_harness_immutability.go: rejects
294
68
  // session updates that attempt to change the harness after the session has
@@ -62,9 +62,10 @@ export type ExecutionWorkflowInstanceCreatorProvider =
62
62
  /**
63
63
  * ValidateWorkflowOrInstance — at least one of workflow_id /
64
64
  * workflow_instance_id must be provided. Matches the cloud
65
- * WorkflowExecutionCreateHandler. AgentExecution differs: it has a
66
- * ResolveDefaultAgent step, so its guard is an unreachable invariant
67
- * (Internal), not reachable InvalidArgument validation (issue #196).
65
+ * WorkflowExecutionCreateHandler. AgentExecution differs on purpose: its
66
+ * all-empty shape is legal (the built-in assistant), so it has no such
67
+ * step; a workflow execution has no built-in workflow to fall back to
68
+ * (issue #196).
68
69
  */
69
70
  export function newValidateWorkflowOrInstanceStep(): PipelineStep<ExecutionDesc> {
70
71
  return {
@@ -23,8 +23,8 @@ import type { ApiResourceMetadata } from "@stigmer/protos/ai/stigmer/commons/api
23
23
 
24
24
  /**
25
25
  * The platform-reserved label key namespace. Keys under this prefix carry
26
- * platform semantics (default-agent resolution, personal-environment
27
- * uniqueness, default-instance marking) and are written by the server —
26
+ * platform semantics (personal-environment uniqueness, default-instance
27
+ * marking, plugin membership and lineage) and are written by the server —
28
28
  * never introduced by ordinary client requests on the cloud edition.
29
29
  */
30
30
  export const RESERVED_LABEL_PREFIX = "stigmer.ai/";
@@ -100,8 +100,8 @@ export function grpcCodeName(code: Code): string {
100
100
  * errors.As branch keeps the INNER code but rewrites the message to the
101
101
  * full wrapped text — and the inner client error's Error() renders as
102
102
  * `rpc error: code = <CodeName> desc = <message>`. Byte-parity with Go on
103
- * the two arms that hit this (agent create's CreateDefaultInstance,
104
- * session create's ResolveDefaultAgentInstance). The transport-formatting
103
+ * the arms that hit this (agent create's CreateDefaultInstance, agent
104
+ * execution create's default-instance and session bootstrap). The transport-formatting
105
105
  * leak is filed as stigmer/stigmer#852 for a both-editions post-cutover
106
106
  * fix; until then this shim IS the wire contract.
107
107
  *
@@ -3,11 +3,12 @@
3
3
  * `stigmer.ai/*` label namespace (the Java GuardReservedLabelsStep port,
4
4
  * cloud#320/#386; C2 Stage 3, 20260827.10).
5
5
  *
6
- * Reserved labels carry platform semantics — the motivating one is
7
- * `stigmer.ai/default-agent`, which the default-agent resolution reads
8
- * GLOBALLY (label + visibility_public), so a tenant labeling its own
9
- * public agent would enter every organization's default-agent candidate
10
- * set. Only rejecting the write closes that.
6
+ * Reserved labels carry platform semantics the server reads and acts on
7
+ * (the personal-environment marker, the default-instance marker, the
8
+ * membership and lineage labels): a client that could write one would be
9
+ * writing a platform decision, and any reader trusting the label would be
10
+ * trusting the client. Only rejecting the write closes that; the label is
11
+ * not authorization, the server is.
11
12
  *
12
13
  * Behavior (the Java matrix verbatim):
13
14
  * - ECHOES pass — clients read-modify-write whole resources, so a
@@ -1,37 +0,0 @@
1
- import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
2
- import type { Logger } from "../../boot/logger.js";
3
- import type { Store } from "../../store/interface.js";
4
- /** Marks the platform default agent; the value must be DEFAULT_AGENT_LABEL_VALUE. */
5
- export declare const DEFAULT_AGENT_LABEL = "stigmer.ai/default-agent";
6
- /** The only value of DEFAULT_AGENT_LABEL that marks an agent as the default. */
7
- export declare const DEFAULT_AGENT_LABEL_VALUE = "true";
8
- /**
9
- * No agent carries the default-agent label. Call sites map this to
10
- * NotFound with their own caller-facing copy (Go ErrNotConfigured).
11
- */
12
- export declare class DefaultAgentNotConfiguredError extends Error {
13
- constructor();
14
- }
15
- /**
16
- * Labeled agents exist but none is visibility_public. Call sites map this
17
- * to FailedPrecondition — a deliberate divergence from the cloud edition,
18
- * whose SQL predicate collapses this state into "not found": the distinct
19
- * code tells a self-hosting operator the label is present but the
20
- * visibility is wrong (Go ErrNotPublic).
21
- */
22
- export declare class DefaultAgentNotPublicError extends Error {
23
- constructor();
24
- }
25
- /**
26
- * Resolves the platform default agent per the module contract: candidates
27
- * are all agents labeled DEFAULT_AGENT_LABEL=true, only visibility_public
28
- * candidates are eligible, and among those the lowest metadata.id wins.
29
- *
30
- * Throws DefaultAgentNotConfiguredError when nothing carries the label,
31
- * DefaultAgentNotPublicError when labeled agents exist but none is public,
32
- * and lets store/decode failures propagate (a store failure is an internal
33
- * fault, not a "no default agent" condition — callers must not map it to
34
- * NotFound).
35
- */
36
- export declare function findDefaultAgent(store: Store, logger: Logger): Promise<Agent>;
37
- //# sourceMappingURL=defaultagent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaultagent.d.ts","sourceRoot":"","sources":["../../../src/domain/agent/defaultagent.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oDAAoD,CAAC;AAIhF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,qFAAqF;AACrF,eAAO,MAAM,mBAAmB,6BAA6B,CAAC;AAE9D,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,SAAS,CAAC;AAEhD;;;GAGG;AACH,qBAAa,8BAA+B,SAAQ,KAAK;;CAOxD;AAED;;;;;;GAMG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;;CAOpD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,KAAK,CAAC,CAkDhB"}
@@ -1,104 +0,0 @@
1
- /**
2
- * Platform default-agent resolution — ports
3
- * pkg/domain/agent/defaultagent/defaultagent.go: the single resolution
4
- * implementation behind Agent.GetDefault, AgentExecution create (#17), and
5
- * Session create.
6
- *
7
- * The default agent is a platform-level singleton: the agent labeled
8
- * stigmer.ai/default-agent: "true" with visibility_public, seeded in the
9
- * system org and served to callers of every org. Resolution is deliberately
10
- * GLOBAL — GetDefaultAgentRequest.org exists for authorization scoping only
11
- * (see apis/ai/stigmer/agentic/agent/v1/io.proto). It powers the
12
- * session-first UX where a user starts a conversation without picking an
13
- * agent. The cloud twin is AgentRepo.findDefault(); keep the two in sync.
14
- *
15
- * Determinism contract (stigmer/stigmer#356): multiple labeled agents is a
16
- * reachable state, not an error — safe label rotation applies the new
17
- * default before retiring the old one. Among public candidates the winner
18
- * is the one with the LOWEST metadata.id — the incumbent. Rejected
19
- * alternatives (recorded in the Go package doc): first-match depends on row
20
- * insertion order; newest-wins lets any newly labeled public agent capture
21
- * the platform-wide default (nothing guards the reserved stigmer.ai/*
22
- * namespace at OSS write boundaries); creation time is not trustworthy as
23
- * an ordering key (pre-#453 rows may carry rewritten timestamps).
24
- * metadata.id never changes and is time-ordered for server-generated ULIDs.
25
- */
26
- import { fromBinary } from "@bufbuild/protobuf";
27
- import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
28
- import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
29
- import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
30
- /** Marks the platform default agent; the value must be DEFAULT_AGENT_LABEL_VALUE. */
31
- export const DEFAULT_AGENT_LABEL = "stigmer.ai/default-agent";
32
- /** The only value of DEFAULT_AGENT_LABEL that marks an agent as the default. */
33
- export const DEFAULT_AGENT_LABEL_VALUE = "true";
34
- /**
35
- * No agent carries the default-agent label. Call sites map this to
36
- * NotFound with their own caller-facing copy (Go ErrNotConfigured).
37
- */
38
- export class DefaultAgentNotConfiguredError extends Error {
39
- constructor() {
40
- super(`no agent labeled ${DEFAULT_AGENT_LABEL}=${DEFAULT_AGENT_LABEL_VALUE}`);
41
- this.name = "DefaultAgentNotConfiguredError";
42
- }
43
- }
44
- /**
45
- * Labeled agents exist but none is visibility_public. Call sites map this
46
- * to FailedPrecondition — a deliberate divergence from the cloud edition,
47
- * whose SQL predicate collapses this state into "not found": the distinct
48
- * code tells a self-hosting operator the label is present but the
49
- * visibility is wrong (Go ErrNotPublic).
50
- */
51
- export class DefaultAgentNotPublicError extends Error {
52
- constructor() {
53
- super(`agents labeled ${DEFAULT_AGENT_LABEL}=${DEFAULT_AGENT_LABEL_VALUE} exist but none is visibility_public`);
54
- this.name = "DefaultAgentNotPublicError";
55
- }
56
- }
57
- /**
58
- * Resolves the platform default agent per the module contract: candidates
59
- * are all agents labeled DEFAULT_AGENT_LABEL=true, only visibility_public
60
- * candidates are eligible, and among those the lowest metadata.id wins.
61
- *
62
- * Throws DefaultAgentNotConfiguredError when nothing carries the label,
63
- * DefaultAgentNotPublicError when labeled agents exist but none is public,
64
- * and lets store/decode failures propagate (a store failure is an internal
65
- * fault, not a "no default agent" condition — callers must not map it to
66
- * NotFound).
67
- */
68
- export async function findDefaultAgent(store, logger) {
69
- const raws = await store.findAllByLabel(ApiResourceKind.agent, DEFAULT_AGENT_LABEL, DEFAULT_AGENT_LABEL_VALUE, AgentSchema);
70
- if (raws.length === 0) {
71
- throw new DefaultAgentNotConfiguredError();
72
- }
73
- let publicCount = 0;
74
- let winner;
75
- for (const raw of raws) {
76
- // findAllByLabel already unmarshaled every returned row to match the
77
- // label, so a decode failure here is store corruption. Fail loudly
78
- // (propagate): skipping a row could silently change which agent wins.
79
- const candidate = fromBinary(AgentSchema, raw);
80
- if (candidate.metadata?.visibility !==
81
- ApiResourceVisibility.visibility_public) {
82
- continue;
83
- }
84
- publicCount++;
85
- if (winner === undefined ||
86
- (candidate.metadata?.id ?? "") < (winner.metadata?.id ?? "")) {
87
- winner = candidate;
88
- }
89
- }
90
- if (winner === undefined) {
91
- throw new DefaultAgentNotPublicError();
92
- }
93
- if (publicCount > 1) {
94
- // Expected briefly mid-rotation; persistent duplicates mean someone
95
- // forgot to retire the old label after applying the new default.
96
- logger.warn("Multiple public agents carry the default-agent label; serving the incumbent (lowest id). Retire the stale label to complete rotation.", {
97
- publicLabeledAgents: publicCount,
98
- winnerId: winner.metadata?.id ?? "",
99
- winnerName: winner.metadata?.name ?? "",
100
- });
101
- }
102
- return winner;
103
- }
104
- //# sourceMappingURL=defaultagent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"defaultagent.js","sourceRoot":"","sources":["../../../src/domain/agent/defaultagent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AAEjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,wDAAwD,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AAKtH,qFAAqF;AACrF,MAAM,CAAC,MAAM,mBAAmB,GAAG,0BAA0B,CAAC;AAE9D,gFAAgF;AAChF,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAC;AAEhD;;;GAGG;AACH,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD;QACE,KAAK,CACH,oBAAoB,mBAAmB,IAAI,yBAAyB,EAAE,CACvE,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IACnD;QACE,KAAK,CACH,kBAAkB,mBAAmB,IAAI,yBAAyB,sCAAsC,CACzG,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAY,EACZ,MAAc;IAEd,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,cAAc,CACrC,eAAe,CAAC,KAAK,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,WAAW,CACZ,CAAC;IACF,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,8BAA8B,EAAE,CAAC;IAC7C,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,MAAyB,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,qEAAqE;QACrE,mEAAmE;QACnE,sEAAsE;QACtE,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC/C,IACE,SAAS,CAAC,QAAQ,EAAE,UAAU;YAC9B,qBAAqB,CAAC,iBAAiB,EACvC,CAAC;YACD,SAAS;QACX,CAAC;QACD,WAAW,EAAE,CAAC;QACd,IACE,MAAM,KAAK,SAAS;YACpB,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,EAC5D,CAAC;YACD,MAAM,GAAG,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;IACD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,0BAA0B,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,oEAAoE;QACpE,iEAAiE;QACjE,MAAM,CAAC,IAAI,CACT,uIAAuI,EACvI;YACE,mBAAmB,EAAE,WAAW;YAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE;YACnC,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE;SACxC,CACF,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}