@stigmer/server 3.23.1-dev.20260923075205 → 3.25.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 (226) hide show
  1. package/dist/authorization/authorizer.d.ts +10 -4
  2. package/dist/authorization/authorizer.d.ts.map +1 -1
  3. package/dist/authorization/authorizer.js +11 -4
  4. package/dist/authorization/authorizer.js.map +1 -1
  5. package/dist/authorization/model/index.d.ts +4 -4
  6. package/dist/authorization/model/index.d.ts.map +1 -1
  7. package/dist/authorization/model/index.js +2 -0
  8. package/dist/authorization/model/index.js.map +1 -1
  9. package/dist/authorization/model/oauth_app.d.ts.map +1 -1
  10. package/dist/authorization/model/oauth_app.js +3 -2
  11. package/dist/authorization/model/oauth_app.js.map +1 -1
  12. package/dist/authorization/model/platform_client.d.ts +2 -0
  13. package/dist/authorization/model/platform_client.d.ts.map +1 -0
  14. package/dist/authorization/model/platform_client.js +31 -0
  15. package/dist/authorization/model/platform_client.js.map +1 -0
  16. package/dist/boot/compose.d.ts.map +1 -1
  17. package/dist/boot/compose.js +88 -5
  18. package/dist/boot/compose.js.map +1 -1
  19. package/dist/boot/route-shadowing.d.ts +25 -0
  20. package/dist/boot/route-shadowing.d.ts.map +1 -0
  21. package/dist/boot/route-shadowing.js +17 -0
  22. package/dist/boot/route-shadowing.js.map +1 -0
  23. package/dist/domain/iampolicy/membership.d.ts +6 -1
  24. package/dist/domain/iampolicy/membership.d.ts.map +1 -1
  25. package/dist/domain/iampolicy/membership.js +8 -2
  26. package/dist/domain/iampolicy/membership.js.map +1 -1
  27. package/dist/domain/identityaccount/constants.d.ts +13 -0
  28. package/dist/domain/identityaccount/constants.d.ts.map +1 -1
  29. package/dist/domain/identityaccount/constants.js +17 -0
  30. package/dist/domain/identityaccount/constants.js.map +1 -1
  31. package/dist/domain/identityaccount/controller.d.ts +3 -1
  32. package/dist/domain/identityaccount/controller.d.ts.map +1 -1
  33. package/dist/domain/identityaccount/controller.js +15 -6
  34. package/dist/domain/identityaccount/controller.js.map +1 -1
  35. package/dist/domain/identityaccount/operator.d.ts.map +1 -1
  36. package/dist/domain/identityaccount/operator.js +1 -0
  37. package/dist/domain/identityaccount/operator.js.map +1 -1
  38. package/dist/domain/identityaccount/provisioning.d.ts +18 -0
  39. package/dist/domain/identityaccount/provisioning.d.ts.map +1 -1
  40. package/dist/domain/identityaccount/provisioning.js +1 -0
  41. package/dist/domain/identityaccount/provisioning.js.map +1 -1
  42. package/dist/domain/identityaccount/resource-store.js +9 -5
  43. package/dist/domain/identityaccount/resource-store.js.map +1 -1
  44. package/dist/domain/identityaccount/steps.d.ts +11 -2
  45. package/dist/domain/identityaccount/steps.d.ts.map +1 -1
  46. package/dist/domain/identityaccount/steps.js +42 -4
  47. package/dist/domain/identityaccount/steps.js.map +1 -1
  48. package/dist/domain/identityaccount/store-contract.d.ts.map +1 -1
  49. package/dist/domain/identityaccount/store-contract.js +33 -0
  50. package/dist/domain/identityaccount/store-contract.js.map +1 -1
  51. package/dist/domain/identityaccount/store.d.ts +7 -5
  52. package/dist/domain/identityaccount/store.d.ts.map +1 -1
  53. package/dist/domain/identityaccount/store.js.map +1 -1
  54. package/dist/domain/platform/controller.d.ts +10 -0
  55. package/dist/domain/platform/controller.d.ts.map +1 -1
  56. package/dist/domain/platform/controller.js +2 -1
  57. package/dist/domain/platform/controller.js.map +1 -1
  58. package/dist/domain/platformclient/constants.d.ts +60 -0
  59. package/dist/domain/platformclient/constants.d.ts.map +1 -0
  60. package/dist/domain/platformclient/constants.js +78 -0
  61. package/dist/domain/platformclient/constants.js.map +1 -0
  62. package/dist/domain/platformclient/controller.d.ts +59 -0
  63. package/dist/domain/platformclient/controller.d.ts.map +1 -0
  64. package/dist/domain/platformclient/controller.js +191 -0
  65. package/dist/domain/platformclient/controller.js.map +1 -0
  66. package/dist/domain/platformclient/credentials.d.ts +13 -0
  67. package/dist/domain/platformclient/credentials.d.ts.map +1 -0
  68. package/dist/domain/platformclient/credentials.js +56 -0
  69. package/dist/domain/platformclient/credentials.js.map +1 -0
  70. package/dist/domain/platformclient/mint.d.ts +23 -0
  71. package/dist/domain/platformclient/mint.d.ts.map +1 -0
  72. package/dist/domain/platformclient/mint.js +254 -0
  73. package/dist/domain/platformclient/mint.js.map +1 -0
  74. package/dist/domain/platformclient/origin-guard.d.ts +9 -0
  75. package/dist/domain/platformclient/origin-guard.d.ts.map +1 -0
  76. package/dist/domain/platformclient/origin-guard.js +81 -0
  77. package/dist/domain/platformclient/origin-guard.js.map +1 -0
  78. package/dist/domain/platformclient/resource-store.d.ts +4 -0
  79. package/dist/domain/platformclient/resource-store.d.ts.map +1 -0
  80. package/dist/domain/platformclient/resource-store.js +117 -0
  81. package/dist/domain/platformclient/resource-store.js.map +1 -0
  82. package/dist/domain/platformclient/steps.d.ts +51 -0
  83. package/dist/domain/platformclient/steps.d.ts.map +1 -0
  84. package/dist/domain/platformclient/steps.js +339 -0
  85. package/dist/domain/platformclient/steps.js.map +1 -0
  86. package/dist/domain/platformclient/store-contract.d.ts +8 -0
  87. package/dist/domain/platformclient/store-contract.d.ts.map +1 -0
  88. package/dist/domain/platformclient/store-contract.js +208 -0
  89. package/dist/domain/platformclient/store-contract.js.map +1 -0
  90. package/dist/domain/platformclient/store.d.ts +58 -0
  91. package/dist/domain/platformclient/store.d.ts.map +1 -0
  92. package/dist/domain/platformclient/store.js +13 -0
  93. package/dist/domain/platformclient/store.js.map +1 -0
  94. package/dist/domain/platformclient/system-managed.d.ts +18 -0
  95. package/dist/domain/platformclient/system-managed.d.ts.map +1 -0
  96. package/dist/domain/platformclient/system-managed.js +80 -0
  97. package/dist/domain/platformclient/system-managed.js.map +1 -0
  98. package/dist/domain/platformclient/token-controller.d.ts +11 -0
  99. package/dist/domain/platformclient/token-controller.d.ts.map +1 -0
  100. package/dist/domain/platformclient/token-controller.js +32 -0
  101. package/dist/domain/platformclient/token-controller.js.map +1 -0
  102. package/dist/domain/platformclient/verifier.d.ts +10 -0
  103. package/dist/domain/platformclient/verifier.d.ts.map +1 -0
  104. package/dist/domain/platformclient/verifier.js +76 -0
  105. package/dist/domain/platformclient/verifier.js.map +1 -0
  106. package/dist/domain/workflow/agent-call-references.d.ts +60 -33
  107. package/dist/domain/workflow/agent-call-references.d.ts.map +1 -1
  108. package/dist/domain/workflow/agent-call-references.js +43 -23
  109. package/dist/domain/workflow/agent-call-references.js.map +1 -1
  110. package/dist/domain/workflow/registry/data/task-kind-registry.json +2 -2
  111. package/dist/encryption/key-manager.d.ts +20 -3
  112. package/dist/encryption/key-manager.d.ts.map +1 -1
  113. package/dist/encryption/key-manager.js +64 -42
  114. package/dist/encryption/key-manager.js.map +1 -1
  115. package/dist/extensions/caller-guards.d.ts +8 -3
  116. package/dist/extensions/caller-guards.d.ts.map +1 -1
  117. package/dist/extensions/drivers.d.ts +37 -0
  118. package/dist/extensions/drivers.d.ts.map +1 -1
  119. package/dist/extensions/guest-token-minting.d.ts +26 -0
  120. package/dist/extensions/guest-token-minting.d.ts.map +1 -0
  121. package/dist/extensions/guest-token-minting.js +2 -0
  122. package/dist/extensions/guest-token-minting.js.map +1 -0
  123. package/dist/extensions/identity.d.ts +6 -4
  124. package/dist/extensions/identity.d.ts.map +1 -1
  125. package/dist/extensions/identity.js.map +1 -1
  126. package/dist/extensions/registry.d.ts +30 -1
  127. package/dist/extensions/registry.d.ts.map +1 -1
  128. package/dist/extensions/registry.js +34 -1
  129. package/dist/extensions/registry.js.map +1 -1
  130. package/dist/index.d.ts +13 -1
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +6 -0
  133. package/dist/index.js.map +1 -1
  134. package/dist/pipeline/apiresource-labels.d.ts +10 -9
  135. package/dist/pipeline/apiresource-labels.d.ts.map +1 -1
  136. package/dist/pipeline/apiresource-labels.js +10 -9
  137. package/dist/pipeline/apiresource-labels.js.map +1 -1
  138. package/dist/pipeline/interceptors/auth.d.ts +14 -0
  139. package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
  140. package/dist/pipeline/interceptors/auth.js +24 -0
  141. package/dist/pipeline/interceptors/auth.js.map +1 -1
  142. package/dist/pipeline/steps/build-update-state.d.ts +11 -1
  143. package/dist/pipeline/steps/build-update-state.d.ts.map +1 -1
  144. package/dist/pipeline/steps/build-update-state.js +5 -2
  145. package/dist/pipeline/steps/build-update-state.js.map +1 -1
  146. package/dist/pipeline/steps/references.d.ts +30 -4
  147. package/dist/pipeline/steps/references.d.ts.map +1 -1
  148. package/dist/pipeline/steps/references.js +13 -1
  149. package/dist/pipeline/steps/references.js.map +1 -1
  150. package/dist/platformtoken/envelope.d.ts +100 -0
  151. package/dist/platformtoken/envelope.d.ts.map +1 -0
  152. package/dist/platformtoken/envelope.js +184 -0
  153. package/dist/platformtoken/envelope.js.map +1 -0
  154. package/dist/platformtoken/key-ring.d.ts +85 -0
  155. package/dist/platformtoken/key-ring.d.ts.map +1 -0
  156. package/dist/platformtoken/key-ring.js +164 -0
  157. package/dist/platformtoken/key-ring.js.map +1 -0
  158. package/package.json +6 -6
  159. package/src/authorization/README.md +1 -1
  160. package/src/authorization/__tests__/authorizer.test.ts +6 -2
  161. package/src/authorization/__tests__/wire-permissions.test.ts +1 -0
  162. package/src/authorization/authorizer.ts +11 -4
  163. package/src/authorization/model/__tests__/registry.test.ts +8 -1
  164. package/src/authorization/model/index.ts +6 -4
  165. package/src/authorization/model/oauth_app.ts +3 -2
  166. package/src/authorization/model/platform_client.ts +43 -0
  167. package/src/boot/__tests__/auth-enabled-composition.test.ts +2 -1
  168. package/src/boot/__tests__/route-shadowing.test.ts +67 -0
  169. package/src/boot/compose.ts +90 -5
  170. package/src/boot/route-shadowing.ts +47 -0
  171. package/src/domain/iampolicy/__tests__/membership.test.ts +7 -0
  172. package/src/domain/iampolicy/membership.ts +8 -2
  173. package/src/domain/identityaccount/__tests__/platform-client-accounts.test.ts +124 -0
  174. package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -0
  175. package/src/domain/identityaccount/constants.ts +20 -0
  176. package/src/domain/identityaccount/controller.ts +16 -4
  177. package/src/domain/identityaccount/operator.ts +1 -0
  178. package/src/domain/identityaccount/provisioning.ts +17 -0
  179. package/src/domain/identityaccount/resource-store.ts +9 -5
  180. package/src/domain/identityaccount/steps.ts +58 -3
  181. package/src/domain/identityaccount/store-contract.ts +51 -0
  182. package/src/domain/identityaccount/store.ts +7 -5
  183. package/src/domain/platform/__tests__/platform.test.ts +7 -1
  184. package/src/domain/platform/controller.ts +12 -1
  185. package/src/domain/platformclient/__tests__/controller.test.ts +397 -0
  186. package/src/domain/platformclient/__tests__/credentials.test.ts +46 -0
  187. package/src/domain/platformclient/__tests__/mint.test.ts +415 -0
  188. package/src/domain/platformclient/__tests__/resource-store.test.ts +140 -0
  189. package/src/domain/platformclient/__tests__/system-managed.test.ts +101 -0
  190. package/src/domain/platformclient/__tests__/verifier-and-guard.test.ts +207 -0
  191. package/src/domain/platformclient/constants.ts +120 -0
  192. package/src/domain/platformclient/controller.ts +449 -0
  193. package/src/domain/platformclient/credentials.ts +68 -0
  194. package/src/domain/platformclient/mint.ts +412 -0
  195. package/src/domain/platformclient/origin-guard.ts +117 -0
  196. package/src/domain/platformclient/resource-store.ts +150 -0
  197. package/src/domain/platformclient/steps.ts +472 -0
  198. package/src/domain/platformclient/store-contract.ts +318 -0
  199. package/src/domain/platformclient/store.ts +63 -0
  200. package/src/domain/platformclient/system-managed.ts +115 -0
  201. package/src/domain/platformclient/token-controller.ts +49 -0
  202. package/src/domain/platformclient/verifier.ts +106 -0
  203. package/src/domain/workflow/__tests__/agent-call-references.test.ts +178 -27
  204. package/src/domain/workflow/agent-call-references.ts +95 -48
  205. package/src/domain/workflow/registry/data/task-kind-registry.json +2 -2
  206. package/src/encryption/key-manager.ts +87 -44
  207. package/src/extensions/__tests__/extension-composition.test.ts +3 -2
  208. package/src/extensions/__tests__/platform-client-composed.test.ts +288 -0
  209. package/src/extensions/__tests__/registry.test.ts +4 -1
  210. package/src/extensions/__tests__/tier-truthfulness.test.ts +8 -0
  211. package/src/extensions/caller-guards.ts +8 -3
  212. package/src/extensions/drivers.ts +37 -0
  213. package/src/extensions/guest-token-minting.ts +32 -0
  214. package/src/extensions/identity.ts +6 -4
  215. package/src/extensions/registry.ts +77 -3
  216. package/src/index.ts +55 -0
  217. package/src/pipeline/apiresource-labels.ts +10 -9
  218. package/src/pipeline/interceptors/auth.ts +27 -0
  219. package/src/pipeline/steps/__tests__/references.test.ts +37 -1
  220. package/src/pipeline/steps/build-update-state.ts +5 -2
  221. package/src/pipeline/steps/references.ts +49 -5
  222. package/src/platformtoken/__tests__/envelope.test.ts +277 -0
  223. package/src/platformtoken/__tests__/key-ring.test.ts +205 -0
  224. package/src/platformtoken/envelope.ts +276 -0
  225. package/src/platformtoken/key-ring.ts +266 -0
  226. package/src/runnerauth/__tests__/runner-subject-composed.test.ts +9 -3
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The PlatformClientStore PORT: the storage contract the platform-client
3
+ * domain writes and reads through, so the cloud serves the same chains
4
+ * over its own `cloud.iam_platform_client` table by registering an
5
+ * implementation as `drivers.platformClientStore` (the identity-account
6
+ * and IamPolicy precedent: a port for an IAM kind whose rows an edition
7
+ * keeps in its own table). Open source's implementation is
8
+ * resource-store.ts over the generic Store.
9
+ *
10
+ * The methods are exactly the lookups the domain asks: by id (every
11
+ * chain, and the verifier's liveness read), by client_id (the mint), by
12
+ * org-scoped slug (getByReference, update addressed by slug, the
13
+ * duplicate check), by organization (listByOrg). A port carries nothing
14
+ * only one edition calls.
15
+ *
16
+ * Contract every implementation must satisfy — proven by the port-contract
17
+ * kit (store-contract.ts, exported), which the OSS adapter's test iterates
18
+ * on both drivers and a composition's driver test iterates too:
19
+ * - `save` is create-only in effect: a held id, a held (org, slug) or a
20
+ * held client_id raises DuplicatePlatformClientError, never a silent
21
+ * overwrite;
22
+ * - `update` replaces by id and never creates: an unknown id writes
23
+ * nothing;
24
+ * - `deleteById` of an unknown id resolves;
25
+ * - `findByOrg` answers every client of the organization and no other,
26
+ * in no promised order (the chain sorts);
27
+ * - a typed not-found reads as `undefined`; any other storage failure
28
+ * propagates as the infrastructure fault it is (the ratified
29
+ * store-fault mapping — an outage must never read as "no client", which
30
+ * on the verifier's path would revoke every live token).
31
+ */
32
+ import type { PlatformClient } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
33
+ /**
34
+ * Raised by `save` when the id, the (org, slug) pair or the client_id is
35
+ * already held, so the create chain answers ALREADY_EXISTS. `cause`
36
+ * carries a driver's own error (the cloud's SQLSTATE 23505) for the logs;
37
+ * the message is the port's.
38
+ */
39
+ export declare class DuplicatePlatformClientError extends Error {
40
+ constructor(message: string, options?: {
41
+ cause?: unknown;
42
+ });
43
+ }
44
+ export interface PlatformClientStore {
45
+ /** Insert; a held id, (org, slug) or client_id raises DuplicatePlatformClientError. */
46
+ save(client: PlatformClient): Promise<void>;
47
+ /** Full-row replace by id; an unknown id writes nothing. */
48
+ update(client: PlatformClient): Promise<void>;
49
+ /** Removes the row; no error when it does not exist. */
50
+ deleteById(id: string): Promise<void>;
51
+ findById(id: string): Promise<PlatformClient | undefined>;
52
+ /** The client holding this public identifier — the mint's lookup. */
53
+ findByClientId(clientId: string): Promise<PlatformClient | undefined>;
54
+ findByOrgAndSlug(org: string, slug: string): Promise<PlatformClient | undefined>;
55
+ /** Every client of the organization, in no promised order. */
56
+ findByOrg(org: string): Promise<ReadonlyArray<PlatformClient>>;
57
+ }
58
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/domain/platformclient/store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yDAAyD,CAAC;AAE9F;;;;;GAKG;AACH,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAI3D;AAED,MAAM,WAAW,mBAAmB;IAClC,uFAAuF;IACvF,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,4DAA4D;IAC5D,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,wDAAwD;IACxD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC1D,qEAAqE;IACrE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACtE,gBAAgB,CACd,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACvC,8DAA8D;IAC9D,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC;CAChE"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Raised by `save` when the id, the (org, slug) pair or the client_id is
3
+ * already held, so the create chain answers ALREADY_EXISTS. `cause`
4
+ * carries a driver's own error (the cloud's SQLSTATE 23505) for the logs;
5
+ * the message is the port's.
6
+ */
7
+ export class DuplicatePlatformClientError extends Error {
8
+ constructor(message, options) {
9
+ super(message, options);
10
+ this.name = "DuplicatePlatformClientError";
11
+ }
12
+ }
13
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/domain/platformclient/store.ts"],"names":[],"mappings":"AAiCA;;;;;GAKG;AACH,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACrD,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;IAC7C,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import type { PlatformClient } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
2
+ export interface SystemManagedPlatformClientInput {
3
+ /** The owning organization. */
4
+ readonly org: string;
5
+ /** A reserved slug (RESERVED_PLATFORM_CLIENT_SLUGS); anything else throws. */
6
+ readonly slug: string;
7
+ /** The display name a console would show. */
8
+ readonly name: string;
9
+ /** The creation instant stamped on both audit slots; defaults to the wall clock. */
10
+ readonly now?: Date;
11
+ }
12
+ /**
13
+ * A new system-managed client, ready for a store's `save`. Throws on an
14
+ * empty organization or a slug that is not reserved — an edition's
15
+ * programming error, never a request's.
16
+ */
17
+ export declare function newSystemManagedPlatformClient(input: SystemManagedPlatformClientInput): PlatformClient;
18
+ //# sourceMappingURL=system-managed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-managed.d.ts","sourceRoot":"","sources":["../../../src/domain/platformclient/system-managed.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yDAAyD,CAAC;AAsB9F,MAAM,WAAW,gCAAgC;IAC/C,+BAA+B;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,gCAAgC,GACtC,cAAc,CAuChB"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The one builder of a system-managed PlatformClient: the row an edition
3
+ * creates for itself, never through the create chain, so the tokens it
4
+ * signs on the platform's own behalf (a guest's, a schedule fire's) name a
5
+ * client that exists. Stigmer Cloud keeps one per organization under
6
+ * SYSTEM_SHARE_CLIENT_SLUG and persists it through its store driver.
7
+ *
8
+ * The domain already owns what such a client is — the create chain refuses
9
+ * its reserved slug (RefuseReservedSlug) and every mutation refuses its
10
+ * label (RefuseSystemManaged) — so the row is built here too, and the
11
+ * rules that make it safe hold by construction:
12
+ * - it lives only under a reserved slug, which no user can create, so a
13
+ * user client can never be mistaken for one;
14
+ * - it carries the reserved `stigmer.ai/system-managed` label, so update,
15
+ * delete and rotate refuse it;
16
+ * - its credentials are real (a `client_id` unique like any other, a
17
+ * hash, a fingerprint), but the secret is discarded here: nobody ever
18
+ * authenticates as the platform's own client;
19
+ * - its id is spelled like every other (`pcl_` + ULID, generateId);
20
+ * - its audit names no actor, because no caller made it: the platform did.
21
+ *
22
+ * Who decides when one exists, and where it is stored, is the edition's:
23
+ * this function writes nothing. It writes no authorization tuples either —
24
+ * nothing authorizes against a system-managed client, and with none it
25
+ * stays out of every list and reference read a person makes.
26
+ */
27
+ import { create } from "@bufbuild/protobuf";
28
+ import { timestampFromDate } from "@bufbuild/protobuf/wkt";
29
+ import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
30
+ import { ApiResourceAuditInfoSchema, ApiResourceAuditSchema, } from "@stigmer/protos/ai/stigmer/commons/apiresource/status_pb";
31
+ import { PlatformClientSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
32
+ import { RESERVED_LABEL_TRUE, SYSTEM_MANAGED_LABEL, } from "../../pipeline/apiresource-labels.js";
33
+ import { defaultVisibilityFor, getIdPrefix, } from "../../pipeline/apiresource-meta.js";
34
+ import { generateId } from "../../pipeline/steps/defaults.js";
35
+ import { PLATFORM_CLIENT_KIND_NAME, RESERVED_PLATFORM_CLIENT_SLUGS, } from "./constants.js";
36
+ import { generateClientId, generateClientSecret, hashClientSecret, secretFingerprint, } from "./credentials.js";
37
+ /**
38
+ * A new system-managed client, ready for a store's `save`. Throws on an
39
+ * empty organization or a slug that is not reserved — an edition's
40
+ * programming error, never a request's.
41
+ */
42
+ export function newSystemManagedPlatformClient(input) {
43
+ if (input.org === "") {
44
+ throw new Error("a system-managed platform client needs an organization");
45
+ }
46
+ if (!RESERVED_PLATFORM_CLIENT_SLUGS.has(input.slug)) {
47
+ throw new Error(`'${input.slug}' is not a reserved platform-client slug; a system-managed client lives only under one (${[...RESERVED_PLATFORM_CLIENT_SLUGS].join(", ")})`);
48
+ }
49
+ const secret = generateClientSecret();
50
+ const created = timestampFromDate(input.now ?? new Date());
51
+ const audit = create(ApiResourceAuditInfoSchema, {
52
+ createdAt: created,
53
+ updatedAt: created,
54
+ event: "created",
55
+ });
56
+ return create(PlatformClientSchema, {
57
+ apiVersion: "iam.stigmer.ai/v1",
58
+ kind: PLATFORM_CLIENT_KIND_NAME,
59
+ metadata: {
60
+ id: generateId(getIdPrefix(ApiResourceKind.platform_client)),
61
+ org: input.org,
62
+ name: input.name,
63
+ slug: input.slug,
64
+ labels: { [SYSTEM_MANAGED_LABEL]: RESERVED_LABEL_TRUE },
65
+ visibility: defaultVisibilityFor(ApiResourceKind.platform_client),
66
+ },
67
+ spec: {
68
+ clientId: generateClientId(),
69
+ clientSecretHash: hashClientSecret(secret),
70
+ secretFingerprint: secretFingerprint(secret),
71
+ },
72
+ status: {
73
+ audit: create(ApiResourceAuditSchema, {
74
+ specAudit: audit,
75
+ statusAudit: audit,
76
+ }),
77
+ },
78
+ });
79
+ }
80
+ //# sourceMappingURL=system-managed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-managed.js","sourceRoot":"","sources":["../../../src/domain/platformclient/system-managed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AACtH,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,0DAA0D,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yDAAyD,CAAC;AAG/F,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,oBAAoB,EACpB,WAAW,GACZ,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EACL,yBAAyB,EACzB,8BAA8B,GAC/B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAa1B;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC5C,KAAuC;IAEvC,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,CAAC,8BAA8B,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACb,IAAI,KAAK,CAAC,IAAI,2FAA2F,CAAC,GAAG,8BAA8B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAC3J,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,0BAA0B,EAAE;QAC/C,SAAS,EAAE,OAAO;QAClB,SAAS,EAAE,OAAO;QAClB,KAAK,EAAE,SAAS;KACjB,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,oBAAoB,EAAE;QAClC,UAAU,EAAE,mBAAmB;QAC/B,IAAI,EAAE,yBAAyB;QAC/B,QAAQ,EAAE;YACR,EAAE,EAAE,UAAU,CAAC,WAAW,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;YAC5D,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,EAAE,CAAC,oBAAoB,CAAC,EAAE,mBAAmB,EAAE;YACvD,UAAU,EAAE,oBAAoB,CAAC,eAAe,CAAC,eAAe,CAAC;SAClE;QACD,IAAI,EAAE;YACJ,QAAQ,EAAE,gBAAgB,EAAE;YAC5B,gBAAgB,EAAE,gBAAgB,CAAC,MAAM,CAAC;YAC1C,iBAAiB,EAAE,iBAAiB,CAAC,MAAM,CAAC;SAC7C;QACD,MAAM,EAAE;YACN,KAAK,EAAE,MAAM,CAAC,sBAAsB,EAAE;gBACpC,SAAS,EAAE,KAAK;gBAChB,WAAW,EAAE,KAAK;aACnB,CAAC;SACH;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ConnectRouter } from "@connectrpc/connect";
2
+ import type { GuestTokenMinting } from "../../extensions/guest-token-minting.js";
3
+ import type { PlatformClientMintDeps } from "./mint.js";
4
+ export interface PlatformClientTokenControllerDeps {
5
+ readonly mint: PlatformClientMintDeps;
6
+ /** The composed capability; undefined = mintGuestToken refuses UNIMPLEMENTED. */
7
+ readonly guestTokenMinting: GuestTokenMinting | undefined;
8
+ }
9
+ /** Registers the token service on the router (routes stage). */
10
+ export declare function registerPlatformClientTokenService(router: ConnectRouter, deps: PlatformClientTokenControllerDeps): void;
11
+ //# sourceMappingURL=token-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-controller.d.ts","sourceRoot":"","sources":["../../../src/domain/platformclient/token-controller.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAGjF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtC,iFAAiF;IACjF,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC3D;AAED,gEAAgE;AAChE,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,aAAa,EACrB,IAAI,EAAE,iCAAiC,GACtC,IAAI,CAaN"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * PlatformClientTokenController — the two public token RPCs, registered in
3
+ * every composition so the service has one owner (the routes stage refuses
4
+ * an extension that registers it again, boot/route-shadowing.ts):
5
+ *
6
+ * - mintUserToken: the PlatformClient mint (mint.ts). Public on the wire
7
+ * — the client authenticates with its credentials in the body, not a
8
+ * bearer token — so there is no annotation to evaluate; the mint never
9
+ * reads the chain's caller.
10
+ * - mintGuestToken: the credential-free mint for anonymous visitors of a
11
+ * shared agent's hosted page, dispatched to the composed guest-token
12
+ * capability (extensions/guest-token-minting.ts). Without one — open
13
+ * source hosts no shared-agent pages — it answers UNIMPLEMENTED with
14
+ * the edition sentence, the identityFederation absent shape.
15
+ */
16
+ import { Code, ConnectError } from "@connectrpc/connect";
17
+ import { PlatformClientTokenController } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/token_pb";
18
+ import { GUEST_MINT_UNIMPLEMENTED_MESSAGE } from "./constants.js";
19
+ import { mintUserToken } from "./mint.js";
20
+ /** Registers the token service on the router (routes stage). */
21
+ export function registerPlatformClientTokenService(router, deps) {
22
+ router.service(PlatformClientTokenController, {
23
+ mintUserToken: (request) => mintUserToken(deps.mint, request),
24
+ mintGuestToken: (request, ctx) => {
25
+ if (deps.guestTokenMinting === undefined) {
26
+ throw new ConnectError(GUEST_MINT_UNIMPLEMENTED_MESSAGE, Code.Unimplemented);
27
+ }
28
+ return deps.guestTokenMinting.mintGuestToken(request, ctx.requestHeader);
29
+ },
30
+ });
31
+ }
32
+ //# sourceMappingURL=token-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-controller.js","sourceRoot":"","sources":["../../../src/domain/platformclient/token-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,6BAA6B,EAAE,MAAM,2DAA2D,CAAC;AAG1G,OAAO,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAS1C,gEAAgE;AAChE,MAAM,UAAU,kCAAkC,CAChD,MAAqB,EACrB,IAAuC;IAEvC,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE;QAC5C,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC;QAC7D,cAAc,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE;YAC/B,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE,CAAC;gBACzC,MAAM,IAAI,YAAY,CACpB,gCAAgC,EAChC,IAAI,CAAC,aAAa,CACnB,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3E,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { IdentityVerifier } from "../../extensions/identity.js";
2
+ import type { PlatformTokenKeyRing } from "../../platformtoken/key-ring.js";
3
+ import type { PlatformClientStore } from "./store.js";
4
+ export interface PlatformClientTokenVerifierDeps {
5
+ readonly keys: PlatformTokenKeyRing;
6
+ readonly clients: Pick<PlatformClientStore, "findById">;
7
+ readonly now?: () => Date;
8
+ }
9
+ export declare function newPlatformClientTokenVerifier(deps: PlatformClientTokenVerifierDeps): IdentityVerifier;
10
+ //# sourceMappingURL=verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../../../src/domain/platformclient/verifier.ts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAOtC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAM5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,UAAU,CAAC,CAAC;IACxD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,+BAA+B,GACpC,gBAAgB,CA8ClB"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The PlatformClient user-token verifier: open source's one platform-token
3
+ * lane. It claims a token with `iss: "stigmer"` and NO `token_type` — the
4
+ * user token the mint signs — and passes every other token on:
5
+ * - a token that is not a platform token is another verifier's (the
6
+ * OIDC verifier's, an API key's);
7
+ * - a typed platform token (guest, schedule, channel, the sandbox
8
+ * family) belongs to the edition that mints it; open source verifies
9
+ * only its own vocabulary, and on a server with no verifier for that
10
+ * lane the chain refuses it as unclaimed.
11
+ * A platform token whose signature, expiry, audience or subject fails is
12
+ * refused here with the envelope's pinned copy, whichever lane it names —
13
+ * the refusal the cloud's verifier has always answered for it.
14
+ *
15
+ * Liveness is the verifier's (not a guard's), so every lane that
16
+ * authenticates — the serving chain and the extension HTTP edges that run
17
+ * the verifier chain without guards — refuses a deleted client's tokens on
18
+ * the next request, with the cloud's copy. A store fault propagates as the
19
+ * infrastructure fault it is, never as a revocation.
20
+ *
21
+ * Composed between `apikey` and `oidc`, only under an authentication
22
+ * posture (compose.ts): the OIDC verifier claims every JWT-shaped token and
23
+ * throws on one it cannot verify, so a platform token must be claimed
24
+ * before it gets there (stigmer#1137's lesson).
25
+ *
26
+ * The identity is the account the token was minted for: `sub` IS the
27
+ * account id (the mint signs it), so no account read is needed; class
28
+ * `user`, issuer "stigmer", the token carried (the memory-capture gate and
29
+ * the origin guard read its `platform_client_id`), and the email and name
30
+ * the platform asserted, for display only.
31
+ */
32
+ import { Code, ConnectError } from "@connectrpc/connect";
33
+ import { PLATFORM_TOKEN_ISSUER, platformTokenRefusalError, stringClaim, verifyPlatformToken, } from "../../platformtoken/envelope.js";
34
+ import { DELETED_CLIENT_MESSAGE, TOKEN_NAMES_NO_CLIENT_MESSAGE, USER_TOKEN_CLAIMS, } from "./constants.js";
35
+ export function newPlatformClientTokenVerifier(deps) {
36
+ return {
37
+ name: "platform-client",
38
+ async verify(token) {
39
+ const result = verifyPlatformToken(deps.keys, token, deps.now?.());
40
+ switch (result.outcome) {
41
+ case "foreign":
42
+ return null;
43
+ case "refused":
44
+ throw platformTokenRefusalError(result.refusal);
45
+ case "verified":
46
+ break;
47
+ default: {
48
+ const exhaustive = result;
49
+ throw new Error(`unknown verification ${JSON.stringify(exhaustive)}`);
50
+ }
51
+ }
52
+ const verified = result.token;
53
+ if (verified.tokenType !== undefined) {
54
+ return null;
55
+ }
56
+ const platformClientId = stringClaim(verified.payload, USER_TOKEN_CLAIMS.platformClientId);
57
+ if (platformClientId === undefined) {
58
+ throw new ConnectError(TOKEN_NAMES_NO_CLIENT_MESSAGE, Code.Unauthenticated);
59
+ }
60
+ if ((await deps.clients.findById(platformClientId)) === undefined) {
61
+ throw new ConnectError(DELETED_CLIENT_MESSAGE, Code.Unauthenticated);
62
+ }
63
+ const email = stringClaim(verified.payload, USER_TOKEN_CLAIMS.email);
64
+ const displayName = stringClaim(verified.payload, USER_TOKEN_CLAIMS.name);
65
+ return {
66
+ identityId: verified.subject,
67
+ callerClass: "user",
68
+ issuer: PLATFORM_TOKEN_ISSUER,
69
+ rawToken: token,
70
+ ...(email !== undefined ? { email } : {}),
71
+ ...(displayName !== undefined ? { displayName } : {}),
72
+ };
73
+ },
74
+ };
75
+ }
76
+ //# sourceMappingURL=verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.js","sourceRoot":"","sources":["../../../src/domain/platformclient/verifier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAMzD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,WAAW,EACX,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AASxB,MAAM,UAAU,8BAA8B,CAC5C,IAAqC;IAErC,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,KAAK,CAAC,MAAM,CAAC,KAAa;YACxB,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACnE,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;gBACvB,KAAK,SAAS;oBACZ,OAAO,IAAI,CAAC;gBACd,KAAK,SAAS;oBACZ,MAAM,yBAAyB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAClD,KAAK,UAAU;oBACb,MAAM;gBACR,OAAO,CAAC,CAAC,CAAC;oBACR,MAAM,UAAU,GAAU,MAAM,CAAC;oBACjC,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBACxE,CAAC;YACH,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;YAC9B,IAAI,QAAQ,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACrC,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,gBAAgB,GAAG,WAAW,CAClC,QAAQ,CAAC,OAAO,EAChB,iBAAiB,CAAC,gBAAgB,CACnC,CAAC;YACF,IAAI,gBAAgB,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM,IAAI,YAAY,CACpB,6BAA6B,EAC7B,IAAI,CAAC,eAAe,CACrB,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBAClE,MAAM,IAAI,YAAY,CAAC,sBAAsB,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACrE,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAC1E,OAAO;gBACL,UAAU,EAAE,QAAQ,CAAC,OAAO;gBAC5B,WAAW,EAAE,MAAM;gBACnB,MAAM,EAAE,qBAAqB;gBAC7B,QAAQ,EAAE,KAAK;gBACf,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtD,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -1,53 +1,80 @@
1
1
  /**
2
2
  * ValidateAgentCallReferences — the second collector for the reference rule
3
3
  * (pipeline/steps/references.ts): a workflow's `agent_call` tasks name their
4
- * agent as a STRING, `"slug"` or `"org/slug"`, inside a `google.protobuf.Struct`
5
- * config the generic spec walker cannot see, so the rule would never meet
6
- * them. This step parses each task's config through the converter's own
7
- * strict decoder (`unmarshalTaskConfig`, the one reader of a task config),
8
- * walks nested control-flow tasks exactly as the constraint validator does,
9
- * turns every `agent` string into a reference with the workflow as parent,
10
- * and asks the rule's one function — same clauses, same copy. It lives in
11
- * the workflow domain and not inside `InProcessValidator` because the
12
- * validator is pure over the spec by design and a rule that reads the
4
+ * agent as a STRING inside a `google.protobuf.Struct` config the generic
5
+ * spec walker cannot see, so the rule would never meet them. This step
6
+ * parses each task's config through the converter's own strict decoder
7
+ * (`unmarshalTaskConfig`, the one reader of a task config), walks nested
8
+ * control-flow tasks exactly as the constraint validator does, turns every
9
+ * `agent` string the write can judge into a reference with the workflow as
10
+ * parent, and asks the rule's one function — same clauses, same copy. It
11
+ * lives in the workflow domain and not inside `InProcessValidator` because
12
+ * the validator is pure over the spec by design and a rule that reads the
13
13
  * target's row cannot be.
14
14
  *
15
- * The parser here is STRICT: exactly `slug` or `org/slug`, both segments
16
- * non-empty, anything else refused at write naming the task. Two lenient
17
- * readers of the same string exist downstream and disagree with each other
18
- * (the runner's `parseAgentReference` in activities/call-agent.ts splits on
19
- * the first `/` and drops a third segment; the CLI's `parseReference` in
20
- * client-apps/cli/src/resources/reference.ts refuses a leading slash);
21
- * refusing every malformed shape here means neither ever meets one. The
22
- * three cannot share code — the packages share only the protos — so the
23
- * execution conformance suite is where their agreement is proven.
15
+ * The string has three forms (the `agent` field's contract in
16
+ * agent_call.proto), told apart by `classifyAgentReference`:
17
+ *
18
+ * - `org/slug`, a LITERAL: judged now, like any stored reference;
19
+ * - a bare `slug`, RELATIVE: the runner resolves it in the organization
20
+ * the workflow runs in (`__stigmer_org_id`, the execution's), which is
21
+ * not the workflow's when a person runs it from another organization by
22
+ * id. It is judged now in the workflow's own organization with its
23
+ * floor capped at org (references.ts, "RELATIVE");
24
+ * - a value holding `${`, fixed only AT RUN: the runner's jq phase
25
+ * (`${ expr }`, whole or embedded) or its activity phase
26
+ * (`${.env_vars.KEY}`, `${.secrets.KEY}`) produces the reference when
27
+ * the task runs. The write collects nothing for it; the run reads the
28
+ * resolved agent as the person who ran the workflow, as it reads every
29
+ * id-bound binding. The slug grammar (metadata.proto) can never contain
30
+ * `${`, so the test is exact. It deliberately does not recognise only
31
+ * the runner's shapes: that would be a second copy of the runner's
32
+ * grammar in a package that shares only the protos with it, and a
33
+ * mistyped expression already fails at run with the read's not-found.
34
+ *
35
+ * Anything else is refused at write naming the task. The runner's own
36
+ * parser (`parseAgentReference` in runner/src/activities/call-agent.ts) is
37
+ * lenient — it splits on the first `/` and drops a third segment — and the
38
+ * CLI's `parseReference` (client-apps/cli/src/resources/reference.ts)
39
+ * refuses a leading slash; refusing every malformed literal here means
40
+ * neither ever meets one. The three cannot share code; the conformance
41
+ * suites are where their agreement is proven.
24
42
  *
25
43
  * Runs after NormalizeReferences and ValidateReferences on the workflow
26
- * create and update chains, so the org the walk sees is the workflow's own
27
- * for a bare slug. Proven by __tests__/agent-call-references.test.ts and
28
- * the workflow conformance suite's reference arm.
44
+ * create and update chains, and feeds the workflow's escalation door
45
+ * (controller.ts). Proven by __tests__/agent-call-references.test.ts, the
46
+ * workflow conformance suite's agent_call reference arm, and the
47
+ * runner-as-subject execution arm for a reference fixed only at run.
29
48
  */
30
49
  import type { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
31
50
  import type { WorkflowSpec } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/spec_pb";
32
51
  import type { Store } from "../../store/interface.js";
33
52
  import type { PipelineStep } from "../../pipeline/pipeline.js";
34
53
  import type { SpecReference } from "../../pipeline/steps/references.js";
35
- /** The one sentence for an `agent` string that is neither `slug` nor `org/slug`. */
54
+ /** The one sentence for an `agent` string that is none of the three forms. */
36
55
  export declare function malformedAgentReferenceMessage(taskName: string, agent: string): string;
37
- /**
38
- * `slug` or `org/slug` → the reference, with `org` empty for the bare form
39
- * (the caller fills the parent's). Returns undefined for any other shape.
40
- */
41
- export declare function parseAgentReference(agent: string): {
56
+ /** What an `agent` string is before the rule reads it (the module header). */
57
+ export type AgentReferenceForm = {
58
+ readonly kind: "literal";
42
59
  readonly org: string;
43
60
  readonly slug: string;
44
- } | undefined;
61
+ } | {
62
+ readonly kind: "relative";
63
+ readonly slug: string;
64
+ } | {
65
+ readonly kind: "run-time";
66
+ } | {
67
+ readonly kind: "malformed";
68
+ };
69
+ export declare function classifyAgentReference(agent: string): AgentReferenceForm;
45
70
  /**
46
- * Every `agent_call` task's agent as a reference, nested tasks included in
47
- * declaration order, the bare form resolved to `parentOrg`. Throws
48
- * INVALID_ARGUMENT on the first malformed string. A config that does not
49
- * decode is skipped: the spec validation step has already refused the
50
- * workflow for it, and this collector never double-reports.
71
+ * Every `agent_call` task's agent the write can judge, as a reference,
72
+ * nested tasks included in declaration order: a literal as written, a
73
+ * relative slug in `parentOrg` and marked relative, a value fixed only at
74
+ * run not at all. Throws INVALID_ARGUMENT on the first malformed string. A
75
+ * config that does not decode is skipped: the spec validation step has
76
+ * already refused the workflow for it, and this collector never
77
+ * double-reports.
51
78
  */
52
79
  export declare function collectAgentCallReferences(spec: WorkflowSpec | undefined, parentOrg: string): SpecReference[];
53
80
  export declare function newValidateAgentCallReferencesStep(store: Store): PipelineStep<typeof WorkflowSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-call-references.d.ts","sourceRoot":"","sources":["../../../src/domain/workflow/agent-call-references.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uDAAuD,CAAC;AAE5F,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,wDAAwD,CAAC;AAIhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,KAAK,EAEV,aAAa,EACd,MAAM,oCAAoC,CAAC;AAM5C,oFAAoF;AACpF,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,CAER;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,GACZ;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAS7D;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAChB,aAAa,EAAE,CAyCjB;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,KAAK,GACX,YAAY,CAAC,OAAO,cAAc,CAAC,CAyBrC"}
1
+ {"version":3,"file":"agent-call-references.d.ts","sourceRoot":"","sources":["../../../src/domain/workflow/agent-call-references.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uDAAuD,CAAC;AAE5F,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,wDAAwD,CAAC;AAIhE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,KAAK,EAEV,aAAa,EACd,MAAM,oCAAoC,CAAC;AAM5C,8EAA8E;AAC9E,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,MAAM,CAER;AAED,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC;AAKnC,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAYxE;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAChB,aAAa,EAAE,CA4DjB;AAED,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,KAAK,GACX,YAAY,CAAC,OAAO,cAAc,CAAC,CAyBrC"}
@@ -5,30 +5,33 @@ import { checkReferences } from "../../pipeline/steps/references.js";
5
5
  import { metadataOf } from "../../pipeline/steps/shapes.js";
6
6
  import { unmarshalTaskConfig } from "./converter/unmarshal.js";
7
7
  import { nestedTasks } from "./validation/task-config-constraints.js";
8
- /** The one sentence for an `agent` string that is neither `slug` nor `org/slug`. */
8
+ /** The one sentence for an `agent` string that is none of the three forms. */
9
9
  export function malformedAgentReferenceMessage(taskName, agent) {
10
10
  return `task '${taskName}': agent '${agent}' is not a reference; write 'slug' for an agent of this organization or 'org/slug' for another organization's.`;
11
11
  }
12
- /**
13
- * `slug` or `org/slug` → the reference, with `org` empty for the bare form
14
- * (the caller fills the parent's). Returns undefined for any other shape.
15
- */
16
- export function parseAgentReference(agent) {
12
+ /** Opens every runtime expression and placeholder the runner evaluates; never part of a slug. */
13
+ const RUNTIME_EXPRESSION_MARKER = "${";
14
+ export function classifyAgentReference(agent) {
15
+ if (agent.includes(RUNTIME_EXPRESSION_MARKER)) {
16
+ return { kind: "run-time" };
17
+ }
17
18
  const parts = agent.split("/");
18
- if (parts.length === 1) {
19
- return parts[0] === "" ? undefined : { org: "", slug: parts[0] };
19
+ if (parts.length === 1 && parts[0] !== "") {
20
+ return { kind: "relative", slug: parts[0] };
20
21
  }
21
22
  if (parts.length === 2 && parts[0] !== "" && parts[1] !== "") {
22
- return { org: parts[0], slug: parts[1] };
23
+ return { kind: "literal", org: parts[0], slug: parts[1] };
23
24
  }
24
- return undefined;
25
+ return { kind: "malformed" };
25
26
  }
26
27
  /**
27
- * Every `agent_call` task's agent as a reference, nested tasks included in
28
- * declaration order, the bare form resolved to `parentOrg`. Throws
29
- * INVALID_ARGUMENT on the first malformed string. A config that does not
30
- * decode is skipped: the spec validation step has already refused the
31
- * workflow for it, and this collector never double-reports.
28
+ * Every `agent_call` task's agent the write can judge, as a reference,
29
+ * nested tasks included in declaration order: a literal as written, a
30
+ * relative slug in `parentOrg` and marked relative, a value fixed only at
31
+ * run not at all. Throws INVALID_ARGUMENT on the first malformed string. A
32
+ * config that does not decode is skipped: the spec validation step has
33
+ * already refused the workflow for it, and this collector never
34
+ * double-reports.
32
35
  */
33
36
  export function collectAgentCallReferences(spec, parentOrg) {
34
37
  const refs = [];
@@ -47,15 +50,32 @@ export function collectAgentCallReferences(spec, parentOrg) {
47
50
  if (config !== undefined) {
48
51
  if (task.kind === WorkflowTaskKind.agent_call) {
49
52
  const agent = config.agent;
50
- const parsed = parseAgentReference(agent);
51
- if (parsed === undefined) {
52
- throw invalidArgumentError(malformedAgentReferenceMessage(task.name, agent));
53
+ const form = classifyAgentReference(agent);
54
+ switch (form.kind) {
55
+ case "literal":
56
+ refs.push({
57
+ kind: ApiResourceKind.agent,
58
+ org: form.org,
59
+ slug: form.slug,
60
+ });
61
+ break;
62
+ case "relative":
63
+ refs.push({
64
+ kind: ApiResourceKind.agent,
65
+ org: parentOrg,
66
+ slug: form.slug,
67
+ resolvesIn: "running-organization",
68
+ });
69
+ break;
70
+ case "run-time":
71
+ break;
72
+ case "malformed":
73
+ throw invalidArgumentError(malformedAgentReferenceMessage(task.name, agent));
74
+ default: {
75
+ const exhaustive = form;
76
+ throw new Error(`unknown agent reference form: ${JSON.stringify(exhaustive)}`);
77
+ }
53
78
  }
54
- refs.push({
55
- kind: ApiResourceKind.agent,
56
- org: parsed.org === "" ? parentOrg : parsed.org,
57
- slug: parsed.slug,
58
- });
59
79
  }
60
80
  for (const nested of nestedTasks(config)) {
61
81
  visit(nested);
@@ -1 +1 @@
1
- {"version":3,"file":"agent-call-references.js","sourceRoot":"","sources":["../../../src/domain/workflow/agent-call-references.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-call-references.js","sourceRoot":"","sources":["../../../src/domain/workflow/agent-call-references.ts"],"names":[],"mappings":"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"}
@@ -1362,7 +1362,7 @@
1362
1362
  {
1363
1363
  "name": "agent",
1364
1364
  "displayName": "Agent",
1365
- "description": "Agent reference in \"org/slug\" or \"slug\" format. - \"slug\" only: uses the workflow's organization - \"org/slug\": explicit organization reference Examples: \"code-reviewer\", \"stigmer/code-reviewer\", \"acme/data-analyst\" Required field.",
1365
+ "description": "Agent to invoke, as \"slug\", \"org/slug\", or a value holding a runtime expression. - \"slug\": an agent of the organization the workflow runs in; checked when the workflow is saved, against the workflow's own organization - \"org/slug\": that organization's agent; checked when the workflow is saved, and another organization's agent must be shared at platform visibility - a value holding \"${ ... }\", \"${.env_vars.KEY}\" or \"${.secrets.KEY}\": resolved to \"slug\" or \"org/slug\" when the task runs, and read as the person who ran the workflow Examples: \"code-reviewer\", \"acme/data-analyst\", \"${.env_vars.TEAM_ORG}/assistant\" Required field.",
1366
1366
  "type": "string",
1367
1367
  "required": true,
1368
1368
  "groupId": "core",
@@ -1470,7 +1470,7 @@
1470
1470
  "additionalProperties": false,
1471
1471
  "properties": {
1472
1472
  "agent": {
1473
- "description": "Agent reference in \"org/slug\" or \"slug\" format. - \"slug\" only: uses the workflow's organization - \"org/slug\": explicit organization reference Examples: \"code-reviewer\", \"stigmer/code-reviewer\", \"acme/data-analyst\" Required field.",
1473
+ "description": "Agent to invoke, as \"slug\", \"org/slug\", or a value holding a runtime expression. - \"slug\": an agent of the organization the workflow runs in; checked when the workflow is saved, against the workflow's own organization - \"org/slug\": that organization's agent; checked when the workflow is saved, and another organization's agent must be shared at platform visibility - a value holding \"${ ... }\", \"${.env_vars.KEY}\" or \"${.secrets.KEY}\": resolved to \"slug\" or \"org/slug\" when the task runs, and read as the person who ran the workflow Examples: \"code-reviewer\", \"acme/data-analyst\", \"${.env_vars.TEAM_ORG}/assistant\" Required field.",
1474
1474
  "maxLength": 127,
1475
1475
  "minLength": 1,
1476
1476
  "type": "string"