@stigmer/server 3.31.0 → 3.33.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 (109) hide show
  1. package/dist/authorization/model/data/authorization-model.json +16 -46
  2. package/dist/boot/compose.d.ts.map +1 -1
  3. package/dist/boot/compose.js +11 -1
  4. package/dist/boot/compose.js.map +1 -1
  5. package/dist/domain/agentexecution/create-execution-context-step.d.ts +7 -0
  6. package/dist/domain/agentexecution/create-execution-context-step.d.ts.map +1 -1
  7. package/dist/domain/agentexecution/create-execution-context-step.js +79 -4
  8. package/dist/domain/agentexecution/create-execution-context-step.js.map +1 -1
  9. package/dist/domain/apikey/controller.d.ts.map +1 -1
  10. package/dist/domain/apikey/controller.js +7 -2
  11. package/dist/domain/apikey/controller.js.map +1 -1
  12. package/dist/domain/apikey/verifier.d.ts +5 -0
  13. package/dist/domain/apikey/verifier.d.ts.map +1 -1
  14. package/dist/domain/apikey/verifier.js +32 -3
  15. package/dist/domain/apikey/verifier.js.map +1 -1
  16. package/dist/domain/iampolicy/constants.d.ts +11 -1
  17. package/dist/domain/iampolicy/constants.d.ts.map +1 -1
  18. package/dist/domain/iampolicy/constants.js +11 -1
  19. package/dist/domain/iampolicy/constants.js.map +1 -1
  20. package/dist/domain/iampolicy/controller.d.ts.map +1 -1
  21. package/dist/domain/iampolicy/controller.js +36 -12
  22. package/dist/domain/iampolicy/controller.js.map +1 -1
  23. package/dist/domain/iampolicy/steps.d.ts +98 -0
  24. package/dist/domain/iampolicy/steps.d.ts.map +1 -1
  25. package/dist/domain/iampolicy/steps.js +119 -4
  26. package/dist/domain/iampolicy/steps.js.map +1 -1
  27. package/dist/domain/platformclient/constants.d.ts +11 -1
  28. package/dist/domain/platformclient/constants.d.ts.map +1 -1
  29. package/dist/domain/platformclient/constants.js +11 -1
  30. package/dist/domain/platformclient/constants.js.map +1 -1
  31. package/dist/domain/platformclient/mint.d.ts.map +1 -1
  32. package/dist/domain/platformclient/mint.js +28 -1
  33. package/dist/domain/platformclient/mint.js.map +1 -1
  34. package/dist/domain/platformclient/resource-store.d.ts.map +1 -1
  35. package/dist/domain/platformclient/resource-store.js +13 -0
  36. package/dist/domain/platformclient/resource-store.js.map +1 -1
  37. package/dist/domain/platformclient/store-contract.d.ts.map +1 -1
  38. package/dist/domain/platformclient/store-contract.js +59 -0
  39. package/dist/domain/platformclient/store-contract.js.map +1 -1
  40. package/dist/domain/platformclient/store.d.ts +20 -0
  41. package/dist/domain/platformclient/store.d.ts.map +1 -1
  42. package/dist/domain/platformclient/store.js.map +1 -1
  43. package/dist/domain/platformclient/verifier.d.ts.map +1 -1
  44. package/dist/domain/platformclient/verifier.js +7 -2
  45. package/dist/domain/platformclient/verifier.js.map +1 -1
  46. package/dist/extensions/identity.d.ts +14 -0
  47. package/dist/extensions/identity.d.ts.map +1 -1
  48. package/dist/extensions/identity.js.map +1 -1
  49. package/dist/identity/credential-use.d.ts +74 -0
  50. package/dist/identity/credential-use.d.ts.map +1 -0
  51. package/dist/identity/credential-use.js +59 -0
  52. package/dist/identity/credential-use.js.map +1 -0
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +5 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/pipeline/steps/defaults.d.ts +15 -1
  58. package/dist/pipeline/steps/defaults.d.ts.map +1 -1
  59. package/dist/pipeline/steps/defaults.js +31 -1
  60. package/dist/pipeline/steps/defaults.js.map +1 -1
  61. package/dist/temporal/schedule/activities.d.ts.map +1 -1
  62. package/dist/temporal/schedule/activities.js +2 -1
  63. package/dist/temporal/schedule/activities.js.map +1 -1
  64. package/dist/temporal/schedule/run-starter.d.ts.map +1 -1
  65. package/dist/temporal/schedule/run-starter.js +2 -1
  66. package/dist/temporal/schedule/run-starter.js.map +1 -1
  67. package/dist/temporal/schedule/status-writes.d.ts +0 -6
  68. package/dist/temporal/schedule/status-writes.d.ts.map +1 -1
  69. package/dist/temporal/schedule/status-writes.js +8 -27
  70. package/dist/temporal/schedule/status-writes.js.map +1 -1
  71. package/dist/temporal/schedule/syncer.d.ts.map +1 -1
  72. package/dist/temporal/schedule/syncer.js +2 -1
  73. package/dist/temporal/schedule/syncer.js.map +1 -1
  74. package/package.json +6 -6
  75. package/src/authorization/__tests__/store-tests.test.ts +1 -0
  76. package/src/authorization/model/data/authorization-model.json +16 -46
  77. package/src/boot/compose.ts +11 -1
  78. package/src/domain/agentexecution/__tests__/create-execution-context-step.test.ts +329 -0
  79. package/src/domain/agentexecution/__tests__/lifecycle.test.ts +7 -0
  80. package/src/domain/agentexecution/create-execution-context-step.ts +110 -4
  81. package/src/domain/apikey/__tests__/apikey.test.ts +17 -2
  82. package/src/domain/apikey/__tests__/verifier.test.ts +86 -3
  83. package/src/domain/apikey/controller.ts +12 -2
  84. package/src/domain/apikey/verifier.ts +46 -3
  85. package/src/domain/iampolicy/__tests__/controller.test.ts +99 -3
  86. package/src/domain/iampolicy/__tests__/steps.test.ts +179 -0
  87. package/src/domain/iampolicy/constants.ts +15 -1
  88. package/src/domain/iampolicy/controller.ts +43 -9
  89. package/src/domain/iampolicy/steps.ts +164 -4
  90. package/src/domain/platformclient/__tests__/mint.test.ts +104 -12
  91. package/src/domain/platformclient/__tests__/resource-store.test.ts +4 -0
  92. package/src/domain/platformclient/__tests__/verifier-and-guard.test.ts +4 -2
  93. package/src/domain/platformclient/constants.ts +11 -1
  94. package/src/domain/platformclient/mint.ts +34 -1
  95. package/src/domain/platformclient/resource-store.ts +18 -0
  96. package/src/domain/platformclient/store-contract.ts +100 -0
  97. package/src/domain/platformclient/store.ts +23 -0
  98. package/src/domain/platformclient/verifier.ts +7 -2
  99. package/src/extensions/__tests__/role-reconciliation-composed.test.ts +18 -10
  100. package/src/extensions/identity.ts +14 -0
  101. package/src/identity/__tests__/credential-use.test.ts +186 -0
  102. package/src/identity/credential-use.ts +130 -0
  103. package/src/index.ts +5 -0
  104. package/src/pipeline/__tests__/steps.test.ts +72 -1
  105. package/src/pipeline/steps/defaults.ts +33 -1
  106. package/src/temporal/schedule/activities.ts +2 -1
  107. package/src/temporal/schedule/run-starter.ts +2 -1
  108. package/src/temporal/schedule/status-writes.ts +8 -31
  109. package/src/temporal/schedule/syncer.ts +2 -1
@@ -1,20 +1,16 @@
1
1
  /**
2
- * The clock's status-write helpers — port the ensureStatus/bumpStatusAudit
3
- * pair of pkg/domain/schedule/temporal/syncer.go.
2
+ * The clock's status-write helper — ports ensureStatus of
3
+ * pkg/domain/schedule/temporal/syncer.go.
4
4
  *
5
- * bumpStatusAudit is DELIBERATELY narrower than the shared
6
- * setAuditFieldsForUpdate: Go's clock stamps only status-audit
7
- * updated_at + event ("the same two leaves every cloud runtime patch
8
- * bumps") and never an actor — the clock is the platform, not an operator.
9
- * Controller-side status writes (trigger's last_fire_at stamp, resume's
10
- * clear) use the FULL shared helper instead, exactly as Go splits
11
- * steps.SetAuditFieldsForUpdate from the clock's bump. Two flavors, two
12
- * writers, both wire-visible — keep them distinct.
5
+ * The clock's audit stamp is the shared `bumpStatusAudit`
6
+ * (pipeline/steps/defaults.ts): status-audit updated_at + event only, never
7
+ * an actor — the clock is the platform, not an operator. Controller-side
8
+ * status writes (trigger's last_fire_at stamp, resume's clear) use the FULL
9
+ * setAuditFieldsForUpdate instead, exactly as Go splits
10
+ * steps.SetAuditFieldsForUpdate from the clock's bump.
13
11
  */
14
12
  import { create } from "@bufbuild/protobuf";
15
- import { timestampNow } from "@bufbuild/protobuf/wkt";
16
13
  import { ScheduleStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/status_pb";
17
- import { ApiResourceAuditInfoSchema, ApiResourceAuditSchema, } from "@stigmer/protos/ai/stigmer/commons/apiresource/status_pb";
18
14
  /**
19
15
  * Returns the schedule's status, materializing the nested message a fresh
20
16
  * row may lack (Go ensureStatus).
@@ -25,19 +21,4 @@ export function ensureStatus(schedule) {
25
21
  }
26
22
  return schedule.status;
27
23
  }
28
- /**
29
- * Stamps the status-audit trail for a runtime write — updated_at + event
30
- * "updated", nothing else (Go bumpStatusAudit; see the module header for
31
- * why this is not setAuditFieldsForUpdate).
32
- */
33
- export function bumpStatusAudit(status) {
34
- if (status.audit === undefined) {
35
- status.audit = create(ApiResourceAuditSchema);
36
- }
37
- if (status.audit.statusAudit === undefined) {
38
- status.audit.statusAudit = create(ApiResourceAuditInfoSchema);
39
- }
40
- status.audit.statusAudit.updatedAt = timestampNow();
41
- status.audit.statusAudit.event = "updated";
42
- }
43
24
  //# sourceMappingURL=status-writes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status-writes.js","sourceRoot":"","sources":["../../../src/temporal/schedule/status-writes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAGtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0DAA0D,CAAC;AAEhG,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,0DAA0D,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB;IAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,QAAQ,CAAC,MAAM,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAsB;IACpD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,GAAG,YAAY,EAAE,CAAC;IACpD,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,GAAG,SAAS,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"status-writes.js","sourceRoot":"","sources":["../../../src/temporal/schedule/status-writes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,0DAA0D,CAAC;AAGhG;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAkB;IAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,QAAQ,CAAC,MAAM,CAAC;AACzB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../../../src/temporal/schedule/syncer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,oBAAoB,CAAC;AAKtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uDAAuD,CAAC;AAGtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKtD;;;;GAIG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;;CAKlD;AAED,qBAAa,cAAc;IAEvB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;;IAJvB,+DAA+D;IAC9C,cAAc,EAAE,MAAM,MAAM,GAAG,SAAS,EACxC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,MAAM;IAGjC;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IA+CpE;;;;;OAKG;IACG,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAqBnE;;;;OAIG;IACG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBjD;;;;OAIG;YACW,gBAAgB;CA6B/B"}
1
+ {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../../../src/temporal/schedule/syncer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAuB,MAAM,oBAAoB,CAAC;AAKtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uDAAuD,CAAC;AAGtF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAGnD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAKtD;;;;GAIG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;;CAKlD;AAED,qBAAa,cAAc;IAEvB,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;;IAJvB,+DAA+D;IAC9C,cAAc,EAAE,MAAM,MAAM,GAAG,SAAS,EACxC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,MAAM;IAGjC;;;;;OAKG;IACG,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IA+CpE;;;;;OAKG;IACG,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;IAqBnE;;;;OAIG;IACG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBjD;;;;OAIG;YACW,gBAAgB;CA6B/B"}
@@ -2,10 +2,11 @@ import { ScheduleAlreadyRunning, ScheduleNotFoundError } from "@temporalio/clien
2
2
  import { timestampFromDate } from "@bufbuild/protobuf/wkt";
3
3
  import { ScheduleSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
4
4
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
5
+ import { bumpStatusAudit } from "../../pipeline/steps/defaults.js";
5
6
  import { ResourceNotFoundError } from "../../store/interface.js";
6
7
  import { desiredPaused, note } from "./artifact.js";
7
8
  import { artifactId } from "./names.js";
8
- import { bumpStatusAudit, ensureStatus } from "./status-writes.js";
9
+ import { ensureStatus } from "./status-writes.js";
9
10
  /**
10
11
  * The syncer's answer when no Temporal client exists right now (Go
11
12
  * ErrTemporalUnavailable). Callers on the write path treat it as "converge
@@ -1 +1 @@
1
- {"version":3,"file":"syncer.js","sourceRoot":"","sources":["../../../src/temporal/schedule/syncer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"syncer.js","sourceRoot":"","sources":["../../../src/temporal/schedule/syncer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stigmer/server",
3
- "version": "3.31.0",
3
+ "version": "3.33.0",
4
4
  "description": "The Stigmer OSS control plane as a composable library: composeServer, the extension registry and the driver seams a composition builds on. The self-contained deployable of the same server is @stigmer/server-slim.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -63,11 +63,11 @@
63
63
  "@connectrpc/connect-node": "^2.0.0",
64
64
  "@kubernetes/client-node": "2.0.0",
65
65
  "@opentelemetry/api": "^1.9.0",
66
- "@stigmer/outbound": "3.31.0",
67
- "@stigmer/plugin-package": "3.31.0",
68
- "@stigmer/protos": "3.31.0",
69
- "@stigmer/temporal-codecs": "3.31.0",
70
- "@stigmer/zip-structure": "3.31.0",
66
+ "@stigmer/outbound": "3.33.0",
67
+ "@stigmer/plugin-package": "3.33.0",
68
+ "@stigmer/protos": "3.33.0",
69
+ "@stigmer/temporal-codecs": "3.33.0",
70
+ "@stigmer/zip-structure": "3.33.0",
71
71
  "@temporalio/activity": "1.16.2",
72
72
  "@temporalio/client": "1.16.2",
73
73
  "@temporalio/common": "1.16.2",
@@ -64,6 +64,7 @@ const DOCUMENTS = [
64
64
  "memory-subject-only.fga.yaml",
65
65
  "org-admin-owner-inheritance.fga.yaml",
66
66
  "org-shared-environment.fga.yaml",
67
+ "organization-role-assignment.fga.yaml",
67
68
  "platform-visibility.fga.yaml",
68
69
  "plugin-owner.fga.yaml",
69
70
  "provider-standing-viewer.fga.yaml",
@@ -199,13 +199,7 @@
199
199
  }
200
200
  ]
201
201
  },
202
- "owner": {
203
- "directly_related_user_types": [
204
- {
205
- "type": "identity_account"
206
- }
207
- ]
208
- },
202
+ "owner": {},
209
203
  "platform_user": {},
210
204
  "viewer": {
211
205
  "directly_related_user_types": [
@@ -252,22 +246,13 @@
252
246
  "this": {}
253
247
  },
254
248
  "owner": {
255
- "union": {
256
- "child": [
257
- {
258
- "this": {}
259
- },
260
- {
261
- "tupleToUserset": {
262
- "computedUserset": {
263
- "relation": "admin"
264
- },
265
- "tupleset": {
266
- "relation": "organization"
267
- }
268
- }
269
- }
270
- ]
249
+ "tupleToUserset": {
250
+ "computedUserset": {
251
+ "relation": "admin"
252
+ },
253
+ "tupleset": {
254
+ "relation": "organization"
255
+ }
271
256
  }
272
257
  },
273
258
  "platform_user": {
@@ -660,13 +645,7 @@
660
645
  }
661
646
  ]
662
647
  },
663
- "owner": {
664
- "directly_related_user_types": [
665
- {
666
- "type": "identity_account"
667
- }
668
- ]
669
- },
648
+ "owner": {},
670
649
  "viewer": {}
671
650
  },
672
651
  "source_info": {
@@ -693,22 +672,13 @@
693
672
  "this": {}
694
673
  },
695
674
  "owner": {
696
- "union": {
697
- "child": [
698
- {
699
- "this": {}
700
- },
701
- {
702
- "tupleToUserset": {
703
- "computedUserset": {
704
- "relation": "admin"
705
- },
706
- "tupleset": {
707
- "relation": "organization"
708
- }
709
- }
710
- }
711
- ]
675
+ "tupleToUserset": {
676
+ "computedUserset": {
677
+ "relation": "admin"
678
+ },
679
+ "tupleset": {
680
+ "relation": "organization"
681
+ }
712
682
  }
713
683
  },
714
684
  "viewer": {
@@ -1492,6 +1492,9 @@ export async function composeServer(
1492
1492
  executionContextCreator: () =>
1493
1493
  requireInProcess().executionContextCreator,
1494
1494
  managedEnvService,
1495
+ // The minting client's environment layer reads the client through
1496
+ // the port, which a composition's driver may serve (#1256).
1497
+ platformClients,
1495
1498
  // The run-start token refresh dials the vendor's token endpoint;
1496
1499
  // it rides the same egress-guarded fetch as every other OAuth call.
1497
1500
  fetchImpl: asFetch(outboundFetch),
@@ -1690,7 +1693,14 @@ export async function composeServer(
1690
1693
  // own (the cloud's sandbox lanes).
1691
1694
  const identityVerifiers = [
1692
1695
  ...(requireAuthentication
1693
- ? [newApiKeyIdentityVerifier({ store, accounts: identityAccounts })]
1696
+ ? [
1697
+ newApiKeyIdentityVerifier({
1698
+ store,
1699
+ accounts: identityAccounts,
1700
+ logger,
1701
+ now: () => new Date(),
1702
+ }),
1703
+ ]
1694
1704
  : []),
1695
1705
  // The PlatformClient user-token lane rides the ring, which the keys
1696
1706
  // stage resolves only under an authentication posture. It sits before
@@ -11,6 +11,15 @@
11
11
  * agent's env united with the session servers' env, and a session
12
12
  * server's saved key reaching the run from the personal environment — for
13
13
  * an agent-bound run and for the built-in assistant alike.
14
+ *
15
+ * And the minting PlatformClient's layer (#1256): an execution whose audit
16
+ * names the client a minted user came through receives the client's
17
+ * environments BELOW the instance layer and runtime_env; a creator with no
18
+ * client reads no client at all; a deleted client or one of another
19
+ * organization contributes nothing; an unresolvable ref fails the create;
20
+ * and the layer survives the runner's status writes, so recovery — which
21
+ * rebuilds from the persisted execution with no minted caller — delivers
22
+ * it again.
14
23
  */
15
24
  import { mkdtempSync, rmSync } from "node:fs";
16
25
  import { tmpdir } from "node:os";
@@ -22,7 +31,10 @@ import { afterAll, beforeAll, expect, it } from "vitest";
22
31
 
23
32
  import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
24
33
  import { AgentInstanceSchema } from "@stigmer/protos/ai/stigmer/agentic/agentinstance/v1/api_pb";
34
+ import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
25
35
  import { AgentExecutionSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
36
+ import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
37
+ import { AgentExecutionUpdateStatusInputSchema } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
26
38
  import { EnvironmentSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
27
39
  import type { EnvironmentValue } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
28
40
  import { EnvironmentValueSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
@@ -30,6 +42,9 @@ import type { ExecutionContext } from "@stigmer/protos/ai/stigmer/agentic/execut
30
42
  import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
31
43
  import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
32
44
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
45
+ import type { ApiResourceReference } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
46
+ import type { PlatformClient } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
47
+ import { PlatformClientSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/api_pb";
33
48
 
34
49
  import { createLogger } from "../../../boot/logger.js";
35
50
  import { SqliteStore } from "../../../store/sqlite/store.js";
@@ -38,6 +53,7 @@ import type { ManagedEnvironmentService } from "../../mcpserver/oauth/managed-en
38
53
 
39
54
  import type { ExecutionContextBuilderDeps } from "../create-execution-context-step.js";
40
55
  import { buildAndPersistExecutionContext } from "../create-execution-context-step.js";
56
+ import { applyUpdateStatusMerge } from "../update-status.js";
41
57
 
42
58
  const silentLogger = createLogger({
43
59
  level: "error",
@@ -45,6 +61,16 @@ const silentLogger = createLogger({
45
61
  write: () => {},
46
62
  });
47
63
 
64
+ /**
65
+ * The client port for every execution no minted user created: the layer
66
+ * answers from the execution's own audit, so reaching this is a failure.
67
+ */
68
+ const unreadPlatformClients: ExecutionContextBuilderDeps["platformClients"] = {
69
+ findById: async () => {
70
+ throw new Error("no minting client: the client must not be read");
71
+ },
72
+ };
73
+
48
74
  let dir: string;
49
75
  let store: Store;
50
76
 
@@ -113,6 +139,7 @@ it("an unresolvable environment ref surfaces the inner status code with Go's wra
113
139
  readSecretValue: async () => "",
114
140
  updateSecrets: async () => {},
115
141
  } as unknown as ManagedEnvironmentService,
142
+ platformClients: unreadPlatformClients,
116
143
  };
117
144
 
118
145
  const execution = create(AgentExecutionSchema, {
@@ -251,6 +278,7 @@ it("assembles merge → filter → OAuth injection → EC persist over a non-emp
251
278
  },
252
279
  }),
253
280
  managedEnvService,
281
+ platformClients: unreadPlatformClients,
254
282
  // The vendor's token endpoint: rotates the refresh token and issues
255
283
  // a fresh access token.
256
284
  fetchImpl: async () =>
@@ -394,6 +422,7 @@ it("a session-level server's declared key saved in the personal environment reac
394
422
  readSecretValue: async () => "",
395
423
  updateSecrets: async () => {},
396
424
  } as unknown as ManagedEnvironmentService,
425
+ platformClients: unreadPlatformClients,
397
426
  };
398
427
  const execution = create(AgentExecutionSchema, {
399
428
  metadata: { id: "aexec_rule", org: ORG },
@@ -480,6 +509,7 @@ it("the built-in assistant: no instance, no agent, the session's servers are the
480
509
  readSecretValue: async () => "",
481
510
  updateSecrets: async () => {},
482
511
  } as unknown as ManagedEnvironmentService,
512
+ platformClients: unreadPlatformClients,
483
513
  };
484
514
  const execution = create(AgentExecutionSchema, {
485
515
  metadata: { id: "aexec_assistant", org: ORG },
@@ -500,3 +530,302 @@ it("the built-in assistant: no instance, no agent, the session's servers are the
500
530
  expect(data["STRAY"]).toBeUndefined();
501
531
  expect(reads).toEqual(["NOTES_TOKEN"]);
502
532
  });
533
+
534
+ // ---------------------------------------------------------------------------
535
+ // The minting PlatformClient's layer (#1256): keyed on the execution's
536
+ // audit created_by.platform_client_id, which the server stamped from the
537
+ // verified token, below every other layer.
538
+ // ---------------------------------------------------------------------------
539
+
540
+ const PC_ORG = "acme";
541
+
542
+ function environmentOf(
543
+ slug: string,
544
+ data: Record<string, string>,
545
+ org = PC_ORG,
546
+ ): ReturnType<typeof create<typeof EnvironmentSchema>> {
547
+ return create(EnvironmentSchema, {
548
+ metadata: { id: `env_${slug}`, org, slug },
549
+ spec: {
550
+ data: Object.fromEntries(
551
+ Object.entries(data).map(([key, value]) => [key, { value, isSecret: true }]),
552
+ ),
553
+ },
554
+ });
555
+ }
556
+
557
+ /** A PlatformClient of `org` whose environment_refs name `slugs`. */
558
+ function mintingClient(org: string, ...slugs: string[]): PlatformClient {
559
+ return create(PlatformClientSchema, {
560
+ metadata: { id: "pcl_dashboard", org, slug: "dashboard" },
561
+ spec: {
562
+ environmentRefs: slugs.map((slug) => ({
563
+ kind: ApiResourceKind.environment,
564
+ org,
565
+ slug,
566
+ })),
567
+ },
568
+ });
569
+ }
570
+
571
+ /** An execution in PC_ORG created by an actor who came through `platformClientId`. */
572
+ function executionCreatedThrough(
573
+ id: string,
574
+ platformClientId: string,
575
+ runtimeEnv: Record<string, string> = {},
576
+ ): AgentExecution {
577
+ return create(AgentExecutionSchema, {
578
+ metadata: { id, org: PC_ORG },
579
+ spec: {
580
+ sessionId: `ses_${id}`,
581
+ message: "hi",
582
+ runtimeEnv: Object.fromEntries(
583
+ Object.entries(runtimeEnv).map(([key, value]) => [key, { value, isSecret: true }]),
584
+ ),
585
+ },
586
+ status: {
587
+ audit: {
588
+ specAudit: { createdBy: { id: "ida_pat", platformClientId } },
589
+ },
590
+ },
591
+ });
592
+ }
593
+
594
+ /**
595
+ * Builder deps for an agent that declares nothing (every merged key passes
596
+ * the filter) over an instance whose one ref is `instance-secrets`. Every
597
+ * resolved reference and every client read is recorded.
598
+ */
599
+ function platformClientLayerDeps(opts: {
600
+ readonly client: PlatformClient | undefined;
601
+ readonly environments: ReadonlyArray<ReturnType<typeof environmentOf>>;
602
+ readonly resolved: ApiResourceReference[];
603
+ readonly clientReads: string[];
604
+ readonly createdEcs: ExecutionContext[];
605
+ }): ExecutionContextBuilderDeps {
606
+ return {
607
+ store,
608
+ logger: silentLogger,
609
+ agentLoader: () => ({
610
+ get: async () =>
611
+ create(AgentSchema, { metadata: { id: "agt_pc", org: PC_ORG } }),
612
+ }),
613
+ agentInstanceLoader: () => ({
614
+ get: async (instanceId) =>
615
+ create(AgentInstanceSchema, {
616
+ metadata: { id: instanceId, org: PC_ORG },
617
+ spec: {
618
+ agentId: "agt_pc",
619
+ environmentRefs: [
620
+ {
621
+ kind: ApiResourceKind.environment,
622
+ org: PC_ORG,
623
+ slug: "instance-secrets",
624
+ },
625
+ ],
626
+ },
627
+ }),
628
+ }),
629
+ sessionLoader: () => ({
630
+ get: async (sessionId) =>
631
+ create(SessionSchema, {
632
+ metadata: { id: sessionId, org: PC_ORG },
633
+ spec: { agentInstanceId: "agi_pc" },
634
+ }),
635
+ }),
636
+ environmentReader: () => ({
637
+ list: async () => {
638
+ throw new Error("personal-env lookup not needed in this test");
639
+ },
640
+ getSecretValue: async () => {
641
+ throw new Error("personal-env lookup not needed in this test");
642
+ },
643
+ }),
644
+ environmentResolution: {
645
+ resolveByReference: async (ref: ApiResourceReference) => {
646
+ opts.resolved.push(ref);
647
+ const found = opts.environments.find(
648
+ (env) => env.metadata?.slug === ref.slug && env.metadata?.org === ref.org,
649
+ );
650
+ if (found === undefined) {
651
+ throw new ConnectError(`environment not found: ${ref.slug}`, Code.NotFound);
652
+ }
653
+ return found;
654
+ },
655
+ } as unknown as ExecutionContextBuilderDeps["environmentResolution"],
656
+ executionContextCreator: () => ({
657
+ create: async (ec) => {
658
+ opts.createdEcs.push(ec);
659
+ return ec;
660
+ },
661
+ }),
662
+ managedEnvService: {
663
+ readSecretValue: async () => "",
664
+ updateSecrets: async () => {},
665
+ } as unknown as ManagedEnvironmentService,
666
+ platformClients: {
667
+ findById: async (id) => {
668
+ opts.clientReads.push(id);
669
+ return opts.client;
670
+ },
671
+ },
672
+ };
673
+ }
674
+
675
+ const instanceSecrets = environmentOf("instance-secrets", {
676
+ INSTANCE_WINS: "instance",
677
+ });
678
+ const clientSecrets = environmentOf("embed-secrets", {
679
+ SHARED_API_SECRET: "client-secret",
680
+ INSTANCE_WINS: "client",
681
+ RUNTIME_WINS: "client",
682
+ });
683
+
684
+ it("a minted user's execution receives its client's environments below the instance layer and runtime_env", async () => {
685
+ const resolved: ApiResourceReference[] = [];
686
+ const clientReads: string[] = [];
687
+ const createdEcs: ExecutionContext[] = [];
688
+ const deps = platformClientLayerDeps({
689
+ client: mintingClient(PC_ORG, "embed-secrets"),
690
+ environments: [instanceSecrets, clientSecrets],
691
+ resolved,
692
+ clientReads,
693
+ createdEcs,
694
+ });
695
+
696
+ await buildAndPersistExecutionContext(
697
+ deps,
698
+ executionCreatedThrough("aexec_pc_layer", "pcl_dashboard", {
699
+ RUNTIME_WINS: "runtime",
700
+ }),
701
+ "",
702
+ );
703
+
704
+ const data = createdEcs[0]?.spec?.data ?? {};
705
+ // The client's own key reaches the run.
706
+ expect(data["SHARED_API_SECRET"]?.value).toBe("client-secret");
707
+ // The precedence #1256 asks to pin: instance refs, then runtime_env,
708
+ // override the client on a key conflict.
709
+ expect(data["INSTANCE_WINS"]?.value).toBe("instance");
710
+ expect(data["RUNTIME_WINS"]?.value).toBe("runtime");
711
+ expect(clientReads).toEqual(["pcl_dashboard"]);
712
+ expect(resolved.map((ref) => `${ref.org}/${ref.slug}`)).toEqual([
713
+ "acme/instance-secrets",
714
+ "acme/embed-secrets",
715
+ ]);
716
+ });
717
+
718
+ it("no client, a deleted client and a client of another organization contribute nothing", async () => {
719
+ // A creator who came through no client: no client is read at all.
720
+ const noClient: ExecutionContext[] = [];
721
+ await buildAndPersistExecutionContext(
722
+ {
723
+ ...platformClientLayerDeps({
724
+ client: undefined,
725
+ environments: [instanceSecrets],
726
+ resolved: [],
727
+ clientReads: [],
728
+ createdEcs: noClient,
729
+ }),
730
+ platformClients: unreadPlatformClients,
731
+ },
732
+ executionCreatedThrough("aexec_pc_none", ""),
733
+ "",
734
+ );
735
+ expect(noClient[0]?.spec?.data["INSTANCE_WINS"]?.value).toBe("instance");
736
+
737
+ // The client was deleted since: the run proceeds without its layer.
738
+ const deleted: ExecutionContext[] = [];
739
+ const deletedReads: string[] = [];
740
+ await buildAndPersistExecutionContext(
741
+ platformClientLayerDeps({
742
+ client: undefined,
743
+ environments: [instanceSecrets, clientSecrets],
744
+ resolved: [],
745
+ clientReads: deletedReads,
746
+ createdEcs: deleted,
747
+ }),
748
+ executionCreatedThrough("aexec_pc_deleted", "pcl_dashboard"),
749
+ "",
750
+ );
751
+ expect(deletedReads).toEqual(["pcl_dashboard"]);
752
+ expect(deleted[0]?.spec?.data["SHARED_API_SECRET"]).toBeUndefined();
753
+ expect(deleted[0]?.spec?.data["INSTANCE_WINS"]?.value).toBe("instance");
754
+
755
+ // A client of another organization: no environment value crosses an
756
+ // organization, so its refs are never even resolved.
757
+ const foreign: ExecutionContext[] = [];
758
+ const foreignResolved: ApiResourceReference[] = [];
759
+ await buildAndPersistExecutionContext(
760
+ platformClientLayerDeps({
761
+ client: mintingClient("globex", "embed-secrets"),
762
+ environments: [instanceSecrets, environmentOf("embed-secrets", { SHARED_API_SECRET: "x" }, "globex")],
763
+ resolved: foreignResolved,
764
+ clientReads: [],
765
+ createdEcs: foreign,
766
+ }),
767
+ executionCreatedThrough("aexec_pc_foreign", "pcl_dashboard"),
768
+ "",
769
+ );
770
+ expect(foreign[0]?.spec?.data["SHARED_API_SECRET"]).toBeUndefined();
771
+ expect(foreignResolved.map((ref) => ref.org)).toEqual(["acme"]);
772
+ });
773
+
774
+ it("a client environment that no longer exists fails the create with the client named in the chain", async () => {
775
+ try {
776
+ await buildAndPersistExecutionContext(
777
+ platformClientLayerDeps({
778
+ client: mintingClient(PC_ORG, "gone-secrets"),
779
+ environments: [instanceSecrets],
780
+ resolved: [],
781
+ clientReads: [],
782
+ createdEcs: [],
783
+ }),
784
+ executionCreatedThrough("aexec_pc_gone", "pcl_dashboard"),
785
+ "",
786
+ );
787
+ expect.unreachable("expected NotFound");
788
+ } catch (error) {
789
+ const connectError = ConnectError.from(error);
790
+ expect(connectError.code).toBe(Code.NotFound);
791
+ expect(connectError.rawMessage).toBe(
792
+ "resolve platform client pcl_dashboard environment_refs: " +
793
+ "resolve environment ref (org=acme, slug=gone-secrets): " +
794
+ "rpc error: code = NotFound desc = environment not found: gone-secrets",
795
+ );
796
+ }
797
+ });
798
+
799
+ it("the layer survives the runner's status writes, so recovery delivers it again", async () => {
800
+ const execution = executionCreatedThrough("aexec_pc_recover", "pcl_dashboard");
801
+ // The runner's progressive status write, as UpdateStatus applies it.
802
+ applyUpdateStatusMerge(
803
+ execution,
804
+ create(AgentExecutionUpdateStatusInputSchema, {
805
+ executionId: "aexec_pc_recover",
806
+ status: { phase: ExecutionPhase.EXECUTION_FAILED, error: "boom" },
807
+ }),
808
+ silentLogger,
809
+ );
810
+ expect(
811
+ execution.status?.audit?.specAudit?.createdBy?.platformClientId,
812
+ ).toBe("pcl_dashboard");
813
+
814
+ // Recover rebuilds from the persisted execution with no pre-resolved
815
+ // instance and no minted caller (lifecycle.ts's recreate step).
816
+ const createdEcs: ExecutionContext[] = [];
817
+ await buildAndPersistExecutionContext(
818
+ platformClientLayerDeps({
819
+ client: mintingClient(PC_ORG, "embed-secrets"),
820
+ environments: [instanceSecrets, clientSecrets],
821
+ resolved: [],
822
+ clientReads: [],
823
+ createdEcs,
824
+ }),
825
+ execution,
826
+ "",
827
+ );
828
+ expect(createdEcs[0]?.spec?.data["SHARED_API_SECRET"]?.value).toBe(
829
+ "client-secret",
830
+ );
831
+ });
@@ -434,6 +434,13 @@ function stubBuilderDeps(overrides?: {
434
434
  readSecretValue: async () => "",
435
435
  updateSecrets: async () => {},
436
436
  } as unknown as ManagedEnvironmentService,
437
+ // No execution here was created by a minted user, so the minting
438
+ // client's layer answers from the audit without reading a client.
439
+ platformClients: {
440
+ findById: async () => {
441
+ throw new Error("no minting client in this test");
442
+ },
443
+ },
437
444
  };
438
445
  }
439
446