@mycadet/gateway 0.12.7 → 0.12.8

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 (167) hide show
  1. package/README.md +3 -3
  2. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/package.json +1 -1
  3. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/{platform-credential.ts → cloud-credential.ts} +9 -9
  4. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  5. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  6. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  7. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  8. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  9. package/node_modules/@mycadet/ces-client/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  10. package/node_modules/@mycadet/ces-client/src/rpc-client.ts +1 -1
  11. package/node_modules/@mycadet/environments/src/seeds.ts +6 -6
  12. package/node_modules/@mycadet/environments/src/shell.test.ts +1 -1
  13. package/node_modules/@mycadet/environments/src/types.ts +6 -6
  14. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/package.json +1 -1
  15. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/{platform-credential.ts → cloud-credential.ts} +9 -9
  16. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  17. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  18. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  19. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  20. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  21. package/node_modules/@mycadet/gateway-client/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  22. package/node_modules/@mycadet/gateway-client/src/binding-strength-contract.ts +5 -5
  23. package/node_modules/@mycadet/gateway-client/src/gateway-ipc-contracts.ts +1 -1
  24. package/node_modules/@mycadet/gateway-client/src/inbound-contract.ts +2 -2
  25. package/node_modules/@mycadet/gateway-client/src/outbound-contract.ts +1 -1
  26. package/node_modules/@mycadet/service-contracts/package.json +1 -1
  27. package/node_modules/@mycadet/service-contracts/src/{platform-credential.ts → cloud-credential.ts} +9 -9
  28. package/node_modules/@mycadet/service-contracts/src/handles.ts +3 -3
  29. package/node_modules/@mycadet/service-contracts/src/index.ts +1 -1
  30. package/node_modules/@mycadet/service-contracts/src/ingress.ts +11 -5
  31. package/node_modules/@mycadet/service-contracts/src/remote-web-pairing.ts +1 -1
  32. package/node_modules/@mycadet/service-contracts/src/rpc.ts +14 -14
  33. package/node_modules/@mycadet/service-contracts/src/trust-rules.ts +5 -5
  34. package/package.json +1 -1
  35. package/src/__tests__/actor-token-revocation.test.ts +0 -1
  36. package/src/__tests__/{backup-worker-platform-mode.test.ts → backup-worker-cloud-mode.test.ts} +4 -4
  37. package/src/__tests__/channel-verification-session-proxy.test.ts +0 -1
  38. package/src/__tests__/{platform-identity.test.ts → cloud-identity.test.ts} +72 -86
  39. package/src/__tests__/config.test.ts +0 -24
  40. package/src/__tests__/contacts-control-plane-proxy.test.ts +0 -1
  41. package/src/__tests__/credential-requests.test.ts +6 -6
  42. package/src/__tests__/{credential-watcher-managed-bootstrap.test.ts → credential-watcher-cloud-bootstrap.test.ts} +1 -1
  43. package/src/__tests__/edge-auth.test.ts +18 -18
  44. package/src/__tests__/edge-guardian-auth.test.ts +10 -10
  45. package/src/__tests__/guardian-init-lockfile.test.ts +6 -8
  46. package/src/__tests__/guardian-pin.test.ts +8 -8
  47. package/src/__tests__/handle-inbound-admission.test.ts +0 -1
  48. package/src/__tests__/handle-inbound-app-context.test.ts +0 -1
  49. package/src/__tests__/handle-inbound-invite-intercept.test.ts +0 -1
  50. package/src/__tests__/handle-inbound-trust-verdict.test.ts +0 -1
  51. package/src/__tests__/inbound-contact-seed.test.ts +1 -1
  52. package/src/__tests__/live-voice-websocket.test.ts +12 -12
  53. package/src/__tests__/load-guards.test.ts +0 -1
  54. package/src/__tests__/migration-teleport-gcs-proxy.test.ts +0 -1
  55. package/src/__tests__/oauth-callback.test.ts +0 -1
  56. package/src/__tests__/remote-feature-flag-sync.test.ts +35 -45
  57. package/src/__tests__/resolve-assistant.test.ts +0 -1
  58. package/src/__tests__/route-schema-guard.test.ts +4 -1
  59. package/src/__tests__/runtime-client.test.ts +1 -2
  60. package/src/__tests__/runtime-health-proxy.test.ts +0 -1
  61. package/src/__tests__/runtime-proxy-auth.test.ts +3 -2
  62. package/src/__tests__/runtime-proxy-device-stamp.test.ts +0 -1
  63. package/src/__tests__/runtime-proxy-error-body.test.ts +0 -1
  64. package/src/__tests__/runtime-proxy.test.ts +0 -1
  65. package/src/__tests__/runtime-stream-test-utils.ts +0 -1
  66. package/src/__tests__/shared-invite-registration.test.ts +15 -32
  67. package/src/__tests__/slack-control-plane-proxy.test.ts +0 -1
  68. package/src/__tests__/slack-display-name.test.ts +0 -1
  69. package/src/__tests__/slack-normalize.test.ts +0 -1
  70. package/src/__tests__/slack-reaction-normalize.test.ts +0 -1
  71. package/src/__tests__/slack-socket-mode-catchup.test.ts +0 -1
  72. package/src/__tests__/slack-socket-mode-group-dm.test.ts +0 -1
  73. package/src/__tests__/slack-socket-mode-liveness.test.ts +0 -1
  74. package/src/__tests__/slack-socket-mode-outbound-root.test.ts +0 -1
  75. package/src/__tests__/slack-socket-mode-thread-tracking.test.ts +0 -1
  76. package/src/__tests__/speech-relay-websocket.test.ts +16 -14
  77. package/src/__tests__/stt-stream-websocket.test.ts +5 -5
  78. package/src/__tests__/telegram-control-plane-proxy.test.ts +0 -1
  79. package/src/__tests__/telegram-webhook-drop-visibility.test.ts +0 -1
  80. package/src/__tests__/telegram-webhook-handler.test.ts +0 -1
  81. package/src/__tests__/telegram-webhook-manager.test.ts +79 -80
  82. package/src/__tests__/twilio-media-websocket.test.ts +0 -1
  83. package/src/__tests__/twilio-webhooks.test.ts +6 -7
  84. package/src/__tests__/whatsapp-download.test.ts +0 -1
  85. package/src/__tests__/whatsapp-webhook.test.ts +0 -1
  86. package/src/attachments/ingest.test.ts +0 -1
  87. package/src/auth/guardian-bootstrap.ts +17 -15
  88. package/src/auth/scopes.ts +1 -1
  89. package/src/auth-fallback-reporter.ts +1 -1
  90. package/src/backup/backup-worker.ts +2 -2
  91. package/src/channels/inbound-event.ts +3 -3
  92. package/src/channels/ingress-inbound-vendors.test.ts +2 -2
  93. package/src/channels/ingress-inbound.ts +1 -1
  94. package/src/channels/ingress-verification.test.ts +2 -2
  95. package/src/channels/ingress-verification.ts +4 -4
  96. package/src/channels/plugin-ingress-approvals.test.ts +1 -1
  97. package/src/channels/plugin-ingress-approvals.ts +1 -1
  98. package/src/channels/plugin-ingress.test.ts +3 -3
  99. package/src/channels/plugin-ingress.ts +3 -3
  100. package/src/channels/room-admission.ts +2 -2
  101. package/src/{platform-identity.ts → cloud-identity.ts} +60 -68
  102. package/src/cloud-url.ts +14 -0
  103. package/src/{platform-user-id.ts → cloud-user-id.ts} +4 -4
  104. package/src/config.ts +2 -4
  105. package/src/credential-reader.ts +2 -2
  106. package/src/db/assistant-db-proxy.ts +1 -1
  107. package/src/discord/forward.ts +1 -1
  108. package/src/email/normalize.ts +4 -4
  109. package/src/email/register-callback.test.ts +27 -34
  110. package/src/email/register-callback.ts +21 -26
  111. package/src/feature-flag-registry.json +5 -5
  112. package/src/feature-flag-remote-store.ts +2 -2
  113. package/src/feature-flag-resolver.ts +5 -5
  114. package/src/http/cadet-signature.ts +1 -1
  115. package/src/http/edge-forwarded-header.ts +1 -1
  116. package/src/http/loopback-guard.ts +1 -1
  117. package/src/http/middleware/auth.ts +22 -22
  118. package/src/http/router.ts +1 -1
  119. package/src/http/routes/cadet-identity.ts +2 -2
  120. package/src/http/routes/channel-ingress-routes.ts +1 -1
  121. package/src/http/routes/channel-ingress.test.ts +13 -2
  122. package/src/http/routes/channel-verification-session-proxy.ts +9 -9
  123. package/src/http/routes/{platform-push-proxy.test.ts → cloud-push-proxy.test.ts} +21 -22
  124. package/src/http/routes/{platform-push-proxy.ts → cloud-push-proxy.ts} +13 -14
  125. package/src/http/routes/contacts-control-plane-proxy.ts +2 -2
  126. package/src/http/routes/email-webhook.test.ts +2 -3
  127. package/src/http/routes/email-webhook.ts +4 -4
  128. package/src/http/routes/guardian-channel-create.ts +3 -3
  129. package/src/http/routes/guardian-pin.ts +9 -9
  130. package/src/http/routes/inbound-register.ts +2 -2
  131. package/src/http/routes/ingress-domains.test.ts +129 -0
  132. package/src/http/routes/ingress-domains.ts +73 -0
  133. package/src/http/routes/live-voice-websocket.ts +2 -2
  134. package/src/http/routes/log-export.test.ts +0 -1
  135. package/src/http/routes/log-tail.test.ts +0 -1
  136. package/src/http/routes/migration-proxy.ts +1 -1
  137. package/src/http/routes/plugin-webhook-websocket.test.ts +3 -3
  138. package/src/http/routes/plugin-webhook.test.ts +9 -8
  139. package/src/http/routes/plugin-webhook.ts +1 -1
  140. package/src/http/routes/speech-relay-websocket.ts +8 -11
  141. package/src/http/routes/stt-stream-websocket.ts +1 -1
  142. package/src/http/routes/telegram-webhook.test.ts +0 -1
  143. package/src/http/routes/twilio-voice-verify-callback.ts +3 -3
  144. package/src/http/routes/twilio-voice-webhook.test.ts +3 -4
  145. package/src/http/routes/twilio-voice-webhook.ts +3 -3
  146. package/src/http/routes/whatsapp-webhook.test.ts +0 -1
  147. package/src/index.ts +57 -56
  148. package/src/ipc/credential-request-handlers.ts +4 -4
  149. package/src/ipc/debug-export-handlers.test.ts +0 -1
  150. package/src/ipc/log-tail-handlers.test.ts +0 -1
  151. package/src/ipc/risk-classification-handlers.test.ts +4 -4
  152. package/src/ipc/risk-classification-handlers.ts +2 -2
  153. package/src/remote-feature-flag-sync.ts +16 -18
  154. package/src/risk/command-registry/commands/assistant.ts +2 -2
  155. package/src/risk/skill-risk-classifier.test.ts +24 -24
  156. package/src/risk/skill-risk-classifier.ts +10 -10
  157. package/src/runtime/client.ts +17 -17
  158. package/src/schema.ts +5 -5
  159. package/src/telegram/send.test.ts +0 -1
  160. package/src/telegram/webhook-manager.ts +33 -38
  161. package/src/tunnel/allowed-paths.test.ts +3 -3
  162. package/src/tunnel/allowed-paths.ts +1 -1
  163. package/src/tunnel/client.test.ts +20 -21
  164. package/src/tunnel/client.ts +17 -17
  165. package/src/verification/shared-invite-registration.ts +22 -17
  166. package/src/version.ts +1 -1
  167. package/src/platform-url.ts +0 -24
@@ -43,7 +43,6 @@ function makeConfig(): GatewayConfig {
43
43
  runtimeMaxRetries: 2,
44
44
  runtimeProxyRequireAuth: true,
45
45
  runtimeTimeoutMs: 30000,
46
- shutdownDrainMs: 5000,
47
46
  trustProxy: false,
48
47
  } as GatewayConfig;
49
48
  }
@@ -492,17 +492,17 @@ describe("skill classification", () => {
492
492
  expect(result.risk).toBe("low");
493
493
  });
494
494
 
495
- test("scaffold_managed_skill is high risk", async () => {
495
+ test("scaffold_cloud_skill is high risk", async () => {
496
496
  const result = await classify({
497
- tool: "scaffold_managed_skill",
497
+ tool: "scaffold_cloud_skill",
498
498
  skill: "new-skill",
499
499
  });
500
500
  expect(result.risk).toBe("high");
501
501
  });
502
502
 
503
- test("delete_managed_skill is high risk", async () => {
503
+ test("delete_cloud_skill is high risk", async () => {
504
504
  const result = await classify({
505
- tool: "delete_managed_skill",
505
+ tool: "delete_cloud_skill",
506
506
  skill: "old-skill",
507
507
  });
508
508
  expect(result.risk).toBe("high");
@@ -471,8 +471,8 @@ export async function handleClassifyRisk(
471
471
 
472
472
  // ── Skill tools ───────────────────────────────────────────────────────
473
473
  case "skill_load":
474
- case "scaffold_managed_skill":
475
- case "delete_managed_skill": {
474
+ case "scaffold_cloud_skill":
475
+ case "delete_cloud_skill": {
476
476
  const assessment = await skillLoadRiskClassifier.classify({
477
477
  toolName: tool,
478
478
  skillSelector: params.skill,
@@ -4,7 +4,7 @@ import { getDeviceId } from "./device-id.js";
4
4
  import { fetchImpl } from "./fetch.js";
5
5
  import { loadFeatureFlagDefaults } from "./feature-flag-defaults.js";
6
6
  import { writeRemoteFeatureFlags } from "./feature-flag-remote-store.js";
7
- import { arePlatformFeaturesEnabled } from "./feature-flag-resolver.js";
7
+ import { areCloudFeaturesEnabled } from "./feature-flag-resolver.js";
8
8
  import { getLogger } from "./logger.js";
9
9
 
10
10
  const log = getLogger("remote-feature-flag-sync");
@@ -49,7 +49,7 @@ export type RemoteFeatureFlagSyncConfig = {
49
49
  };
50
50
 
51
51
  /**
52
- * Manages the lifecycle of syncing remote feature flags from the platform.
52
+ * Manages the lifecycle of syncing remote feature flags from the cloud.
53
53
  *
54
54
  * On start, fetches the current flag state and persists it to disk via the
55
55
  * remote feature flag store, then polls with adaptive back-off: starts at
@@ -328,7 +328,7 @@ export class RemoteFeatureFlagSync {
328
328
  }
329
329
 
330
330
  private async fetchRemoteFeatureFlags(): Promise<RemoteFetchResult> {
331
- if (!arePlatformFeaturesEnabled()) {
331
+ if (!areCloudFeaturesEnabled()) {
332
332
  log.debug("Remote feature flag sync skipped: platform features disabled");
333
333
  return { status: "missing_credentials" };
334
334
  }
@@ -336,31 +336,29 @@ export class RemoteFeatureFlagSync {
336
336
  // Wrap credential reads so transient failures (CES unreachable, keychain
337
337
  // errors) are treated as retriable errors with backoff, not as "missing
338
338
  // credentials" which would pause polling indefinitely.
339
- let platformUrlRaw: string | undefined;
340
339
  let assistantApiKeyRaw: string | undefined;
341
340
  try {
342
- [platformUrlRaw, assistantApiKeyRaw] = await Promise.all([
343
- this.credentials.get(credentialKey("cadet", "platform_base_url")),
344
- this.credentials.get(credentialKey("cadet", "assistant_api_key")),
345
- ]);
341
+ assistantApiKeyRaw = await this.credentials.get(
342
+ credentialKey("cadet", "assistant_api_key"),
343
+ );
346
344
  } catch (err) {
347
345
  log.warn({ err }, "Failed to read credentials — will retry on next poll");
348
346
  return { status: "error" };
349
347
  }
350
348
 
351
- // Fall back to env vars when managed pod credentials are not yet cached.
352
- const platformUrl = (
353
- platformUrlRaw?.trim() ||
354
- process.env.CADET_PLATFORM_URL?.trim() ||
355
- ""
356
- ).replace(/\/+$/, "");
349
+ // The base URL resolves from the environment only — the credential store
350
+ // never carries it.
351
+ const cloudUrl = (process.env.CADET_CLOUD_URL?.trim() || "").replace(
352
+ /\/+$/,
353
+ "",
354
+ );
357
355
 
358
356
  const assistantCredential =
359
357
  assistantApiKeyRaw?.trim() ||
360
358
  process.env.ASSISTANT_API_KEY?.trim() ||
361
359
  undefined;
362
360
 
363
- if (!platformUrl) {
361
+ if (!cloudUrl) {
364
362
  log.debug("Remote feature flag sync skipped: no platform URL configured");
365
363
  return { status: "missing_credentials" };
366
364
  }
@@ -376,7 +374,7 @@ export class RemoteFeatureFlagSync {
376
374
  return { status: "error" };
377
375
  }
378
376
 
379
- const url = `${platformUrl}/v1/feature-flags/assistant-flag-values/`;
377
+ const url = `${cloudUrl}/v1/feature-flags/assistant-flag-values/`;
380
378
  const headers: Record<string, string> = { Accept: "application/json" };
381
379
  if (assistantCredential) {
382
380
  headers["Authorization"] = `Api-Key ${assistantCredential}`;
@@ -412,9 +410,9 @@ export class RemoteFeatureFlagSync {
412
410
  return { status: "error" };
413
411
  }
414
412
 
415
- // Accept boolean and string values from the platform. Prevent the
413
+ // Accept boolean and string values from the cloud. Prevent the
416
414
  // platform from disabling boolean flags that are already GA
417
- // (defaultEnabled: true in the registry). The platform uses a
415
+ // (defaultEnabled: true in the registry). The cloud uses a
418
416
  // blanket-deny posture, sending false for every flag it knows about.
419
417
  // GA normalization only applies to boolean false values; string flag
420
418
  // values pass through unchanged.
@@ -574,13 +574,13 @@ const riskOverrides: AssistantRiskOverride[] = [
574
574
  path: "inference profiles update",
575
575
  risk: "medium",
576
576
  reason:
577
- "Mutates a custom profile in llm.profiles; daemon rejects managed profiles",
577
+ "Mutates a custom profile in llm.profiles; daemon rejects cloud profiles",
578
578
  },
579
579
  {
580
580
  path: "inference profiles delete",
581
581
  risk: "medium",
582
582
  reason:
583
- "Deletes a custom profile from llm.profiles; daemon rejects managed profiles",
583
+ "Deletes a custom profile from llm.profiles; daemon rejects cloud profiles",
584
584
  },
585
585
  {
586
586
  path: "inference profiles active",
@@ -19,10 +19,10 @@ describe("SkillLoadRiskClassifier", () => {
19
19
  expect(result.matchType).toBe("registry");
20
20
  });
21
21
 
22
- test("scaffold_managed_skill is always High risk", async () => {
22
+ test("scaffold_cloud_skill is always High risk", async () => {
23
23
  const classifier = new SkillLoadRiskClassifier();
24
24
  const result = await classifier.classify({
25
- toolName: "scaffold_managed_skill",
25
+ toolName: "scaffold_cloud_skill",
26
26
  });
27
27
  expect(result.riskLevel).toBe("high");
28
28
  expect(result.reason).toBe(
@@ -32,10 +32,10 @@ describe("SkillLoadRiskClassifier", () => {
32
32
  expect(result.matchType).toBe("registry");
33
33
  });
34
34
 
35
- test("delete_managed_skill is always High risk", async () => {
35
+ test("delete_cloud_skill is always High risk", async () => {
36
36
  const classifier = new SkillLoadRiskClassifier();
37
37
  const result = await classifier.classify({
38
- toolName: "delete_managed_skill",
38
+ toolName: "delete_cloud_skill",
39
39
  });
40
40
  expect(result.riskLevel).toBe("high");
41
41
  expect(result.reason).toBe(
@@ -55,19 +55,19 @@ describe("SkillLoadRiskClassifier", () => {
55
55
  expect(result.reason).toBe("Skill load (default)");
56
56
  });
57
57
 
58
- test("scaffold_managed_skill with skillSelector is still High risk", async () => {
58
+ test("scaffold_cloud_skill with skillSelector is still High risk", async () => {
59
59
  const classifier = new SkillLoadRiskClassifier();
60
60
  const result = await classifier.classify({
61
- toolName: "scaffold_managed_skill",
61
+ toolName: "scaffold_cloud_skill",
62
62
  skillSelector: "new-skill",
63
63
  });
64
64
  expect(result.riskLevel).toBe("high");
65
65
  });
66
66
 
67
- test("delete_managed_skill with skillSelector is still High risk", async () => {
67
+ test("delete_cloud_skill with skillSelector is still High risk", async () => {
68
68
  const classifier = new SkillLoadRiskClassifier();
69
69
  const result = await classifier.classify({
70
- toolName: "delete_managed_skill",
70
+ toolName: "delete_cloud_skill",
71
71
  skillSelector: "old-skill",
72
72
  });
73
73
  expect(result.riskLevel).toBe("high");
@@ -163,56 +163,56 @@ describe("allowlistOptions", () => {
163
163
  ]);
164
164
  });
165
165
 
166
- test("scaffold_managed_skill produces skill-specific + wildcard options", async () => {
166
+ test("scaffold_cloud_skill produces skill-specific + wildcard options", async () => {
167
167
  const classifier = new SkillLoadRiskClassifier();
168
168
  const result = await classifier.classify({
169
- toolName: "scaffold_managed_skill",
169
+ toolName: "scaffold_cloud_skill",
170
170
  skillSelector: "new-skill",
171
171
  });
172
172
  expect(result.allowlistOptions).toEqual([
173
173
  {
174
174
  label: "new-skill",
175
175
  description: "This skill only",
176
- pattern: "scaffold_managed_skill:new-skill",
176
+ pattern: "scaffold_cloud_skill:new-skill",
177
177
  },
178
178
  {
179
- label: "scaffold_managed_skill:*",
179
+ label: "scaffold_cloud_skill:*",
180
180
  description: "All managed skill scaffolds",
181
- pattern: "scaffold_managed_skill:*",
181
+ pattern: "scaffold_cloud_skill:*",
182
182
  },
183
183
  ]);
184
184
  });
185
185
 
186
- test("delete_managed_skill produces skill-specific + wildcard options", async () => {
186
+ test("delete_cloud_skill produces skill-specific + wildcard options", async () => {
187
187
  const classifier = new SkillLoadRiskClassifier();
188
188
  const result = await classifier.classify({
189
- toolName: "delete_managed_skill",
189
+ toolName: "delete_cloud_skill",
190
190
  skillSelector: "old-skill",
191
191
  });
192
192
  expect(result.allowlistOptions).toEqual([
193
193
  {
194
194
  label: "old-skill",
195
195
  description: "This skill only",
196
- pattern: "delete_managed_skill:old-skill",
196
+ pattern: "delete_cloud_skill:old-skill",
197
197
  },
198
198
  {
199
- label: "delete_managed_skill:*",
199
+ label: "delete_cloud_skill:*",
200
200
  description: "All managed skill deletes",
201
- pattern: "delete_managed_skill:*",
201
+ pattern: "delete_cloud_skill:*",
202
202
  },
203
203
  ]);
204
204
  });
205
205
 
206
- test("scaffold_managed_skill without selector produces only wildcard", async () => {
206
+ test("scaffold_cloud_skill without selector produces only wildcard", async () => {
207
207
  const classifier = new SkillLoadRiskClassifier();
208
208
  const result = await classifier.classify({
209
- toolName: "scaffold_managed_skill",
209
+ toolName: "scaffold_cloud_skill",
210
210
  });
211
211
  expect(result.allowlistOptions).toEqual([
212
212
  {
213
- label: "scaffold_managed_skill:*",
213
+ label: "scaffold_cloud_skill:*",
214
214
  description: "All managed skill scaffolds",
215
- pattern: "scaffold_managed_skill:*",
215
+ pattern: "scaffold_cloud_skill:*",
216
216
  },
217
217
  ]);
218
218
  });
@@ -228,8 +228,8 @@ describe("singleton", () => {
228
228
  test("singleton produces same results as fresh instance", async () => {
229
229
  const inputs: SkillClassifierInput[] = [
230
230
  { toolName: "skill_load" },
231
- { toolName: "scaffold_managed_skill" },
232
- { toolName: "delete_managed_skill" },
231
+ { toolName: "scaffold_cloud_skill" },
232
+ { toolName: "delete_cloud_skill" },
233
233
  ];
234
234
 
235
235
  const fresh = new SkillLoadRiskClassifier();
@@ -4,8 +4,8 @@
4
4
  * Implements RiskClassifier<SkillClassifierInput> with constant risk levels
5
5
  * for each skill tool type:
6
6
  * - skill_load: Low (read-only skill loading)
7
- * - scaffold_managed_skill: High (writes persistent skill source code)
8
- * - delete_managed_skill: High (removes persistent skill source code)
7
+ * - scaffold_cloud_skill: High (writes persistent skill source code)
8
+ * - delete_cloud_skill: High (removes persistent skill source code)
9
9
  *
10
10
  * Gateway adaptation: accepts pre-resolved skill metadata via
11
11
  * SkillClassifierInput.resolvedMetadata instead of importing the assistant's
@@ -50,7 +50,7 @@ export interface ResolvedSkillMetadata {
50
50
  /** Input to the skill risk classifier. */
51
51
  export interface SkillClassifierInput {
52
52
  /** Which skill tool is being invoked. */
53
- toolName: "skill_load" | "scaffold_managed_skill" | "delete_managed_skill";
53
+ toolName: "skill_load" | "scaffold_cloud_skill" | "delete_cloud_skill";
54
54
  /** Optional skill selector (e.g. skill name or path). */
55
55
  skillSelector?: string;
56
56
  /**
@@ -134,12 +134,12 @@ function buildSkillLoadAllowlistOptions(
134
134
  /**
135
135
  * Build allowlist options for scaffold/delete managed skill tools.
136
136
  */
137
- function buildManagedSkillAllowlistOptions(
137
+ function buildCloudSkillAllowlistOptions(
138
138
  toolName: string,
139
139
  skillId?: string,
140
140
  ): AllowlistOption[] {
141
141
  const toolLabel =
142
- toolName === "scaffold_managed_skill" ? "scaffold" : "delete";
142
+ toolName === "scaffold_cloud_skill" ? "scaffold" : "delete";
143
143
  const options: AllowlistOption[] = [];
144
144
  if (skillId) {
145
145
  options.push({
@@ -200,25 +200,25 @@ export class SkillLoadRiskClassifier implements RiskClassifier<SkillClassifierIn
200
200
  };
201
201
  break;
202
202
  }
203
- case "scaffold_managed_skill":
203
+ case "scaffold_cloud_skill":
204
204
  assessment = {
205
205
  riskLevel: "high",
206
206
  reason: "Skill scaffold — writes persistent skill source code",
207
207
  scopeOptions: [],
208
208
  matchType: "registry",
209
- allowlistOptions: buildManagedSkillAllowlistOptions(
209
+ allowlistOptions: buildCloudSkillAllowlistOptions(
210
210
  toolName,
211
211
  skillSelector,
212
212
  ),
213
213
  };
214
214
  break;
215
- case "delete_managed_skill":
215
+ case "delete_cloud_skill":
216
216
  assessment = {
217
217
  riskLevel: "high",
218
218
  reason: "Skill delete — removes persistent skill source code",
219
219
  scopeOptions: [],
220
220
  matchType: "registry",
221
- allowlistOptions: buildManagedSkillAllowlistOptions(
221
+ allowlistOptions: buildCloudSkillAllowlistOptions(
222
222
  toolName,
223
223
  skillSelector,
224
224
  ),
@@ -227,7 +227,7 @@ export class SkillLoadRiskClassifier implements RiskClassifier<SkillClassifierIn
227
227
  }
228
228
 
229
229
  // User override is applied after normal classification. This means a user-defined
230
- // rule CAN lower a security-escalated risk (e.g., scaffold_managed_skill).
230
+ // rule CAN lower a security-escalated risk (e.g., scaffold_cloud_skill).
231
231
  // This is intentional — user overrides are authoritative for users who explicitly
232
232
  // created them. Uses resolved skillId from metadata (when available), and
233
233
  // skill_load_dynamic as the tool key for dynamic skills.
@@ -397,12 +397,12 @@ function extractPlatformCallbackAssistantId(
397
397
 
398
398
  function resolveTunnelBaseWssUrl(
399
399
  config: GatewayConfig,
400
- platformAssistantId?: string,
400
+ cloudAssistantId?: string,
401
401
  ): string | undefined {
402
- if (!config.tunnelBaseUrl || !platformAssistantId) return undefined;
402
+ if (!config.tunnelBaseUrl || !cloudAssistantId) return undefined;
403
403
 
404
404
  const withPath =
405
- config.tunnelBaseUrl.replace(/\/+$/, "") + "/" + platformAssistantId;
405
+ config.tunnelBaseUrl.replace(/\/+$/, "") + "/" + cloudAssistantId;
406
406
  const normalizedTunnelUrl = normalizePublicBaseUrl(withPath);
407
407
  return normalizedTunnelUrl
408
408
  ? toWebSocketBaseUrl(normalizedTunnelUrl)
@@ -418,7 +418,7 @@ function resolveTunnelBaseWssUrl(
418
418
  * 2. `ingress.publicBaseUrl` from the config file when it is a real public
419
419
  * gateway base URL — written by Tunnel after tunnel registration, or set
420
420
  * manually for self-hosted.
421
- * 3. `TUNNEL_BASE_URL` + the platform assistant ID from a configured callback
421
+ * 3. `TUNNEL_BASE_URL` + the cloud assistant ID from a configured callback
422
422
  * URL or credential cache.
423
423
  *
424
424
  * Returns `undefined` when no source provides a value — the placeholder
@@ -428,7 +428,7 @@ function resolveTunnelBaseWssUrl(
428
428
  export function resolvePublicBaseWssUrl(
429
429
  config: GatewayConfig,
430
430
  configFile?: ConfigFileCache,
431
- platformAssistantId?: string,
431
+ cloudAssistantId?: string,
432
432
  validatedPublicUrl?: string,
433
433
  ): string | undefined {
434
434
  const raw = configFile?.getString("ingress", "publicBaseUrl");
@@ -450,7 +450,7 @@ export function resolvePublicBaseWssUrl(
450
450
 
451
451
  return resolveTunnelBaseWssUrl(
452
452
  config,
453
- configuredCallbackAssistantId ?? platformAssistantId,
453
+ configuredCallbackAssistantId ?? cloudAssistantId,
454
454
  );
455
455
  }
456
456
 
@@ -462,12 +462,12 @@ export function resolvePublicBaseWssUrl(
462
462
  * Sources (in priority order):
463
463
  * 1. `ingress.publicBaseUrl` from the config file — written by Tunnel after
464
464
  * tunnel registration, or set manually for self-hosted.
465
- * 2. `TUNNEL_BASE_URL` + the platform assistant ID. This mirrors the Twilio
465
+ * 2. `TUNNEL_BASE_URL` + the cloud assistant ID. This mirrors the Twilio
466
466
  * resolver's fallback and stays valid even while the tunnel is briefly
467
467
  * disconnected (Tunnel clears the config value on every reconnect), so
468
468
  * these links no longer break on a tunnel flap.
469
469
  *
470
- * The platform assistant ID is read through a lazy getter so callers that
470
+ * The cloud assistant ID is read through a lazy getter so callers that
471
471
  * resolve from the config value (self-hosted / manual URL) never load
472
472
  * identity. A transient credential-store outage must not fail those callers.
473
473
  *
@@ -476,14 +476,14 @@ export function resolvePublicBaseWssUrl(
476
476
  export async function resolvePublicHttpBaseUrl(
477
477
  config: GatewayConfig,
478
478
  configFile?: ConfigFileCache,
479
- getPlatformAssistantId?: () => Promise<string | undefined>,
479
+ getCloudAssistantId?: () => Promise<string | undefined>,
480
480
  ): Promise<string | undefined> {
481
481
  const resolved =
482
482
  normalizeHttpPublicBaseUrl(
483
483
  configFile?.getString("ingress", "publicBaseUrl"),
484
484
  ) ??
485
485
  normalizeHttpPublicBaseUrl(
486
- await resolveTunnelHttpFallback(config, getPlatformAssistantId),
486
+ await resolveTunnelHttpFallback(config, getCloudAssistantId),
487
487
  );
488
488
 
489
489
  // Drop a root-path trailing slash so callers can append `/…` without
@@ -492,18 +492,18 @@ export async function resolvePublicHttpBaseUrl(
492
492
  }
493
493
 
494
494
  /**
495
- * Build the `TUNNEL_BASE_URL/<platform-assistant-id>` fallback base URL. Only
496
- * reads the platform assistant ID (via the getter) when `tunnelBaseUrl` is
495
+ * Build the `TUNNEL_BASE_URL/<cloud-assistant-id>` fallback base URL. Only
496
+ * reads the cloud assistant ID (via the getter) when `tunnelBaseUrl` is
497
497
  * configured, so it's skipped entirely on self-hosted deployments.
498
498
  */
499
499
  async function resolveTunnelHttpFallback(
500
500
  config: GatewayConfig,
501
- getPlatformAssistantId?: () => Promise<string | undefined>,
501
+ getCloudAssistantId?: () => Promise<string | undefined>,
502
502
  ): Promise<string | undefined> {
503
- if (!config.tunnelBaseUrl || !getPlatformAssistantId) return undefined;
504
- const platformAssistantId = await getPlatformAssistantId();
505
- if (!platformAssistantId) return undefined;
506
- return config.tunnelBaseUrl.replace(/\/+$/, "") + "/" + platformAssistantId;
503
+ if (!config.tunnelBaseUrl || !getCloudAssistantId) return undefined;
504
+ const cloudAssistantId = await getCloudAssistantId();
505
+ if (!cloudAssistantId) return undefined;
506
+ return config.tunnelBaseUrl.replace(/\/+$/, "") + "/" + cloudAssistantId;
507
507
  }
508
508
 
509
509
  /**
package/src/schema.ts CHANGED
@@ -1751,7 +1751,7 @@ export function buildSchema(): Record<string, unknown> {
1751
1751
  post: {
1752
1752
  summary: "Mark a contact channel as verified by guardian attestation",
1753
1753
  description:
1754
- "Guardian-only endpoint that attests a contact channel as verified without exchanging a challenge code. The caller must be the bound guardian — verified either by JWT actor principal (laptop / docker) or by `X-Cadet-User-Id` matching the stored platform user id (platform-managed). Idempotent: an already-verified channel returns 200 without re-writing. Mutation is gateway-DB primary with a best-effort dual-write to the assistant daemon DB for sync during the gateway-security-migration transition.",
1754
+ "Guardian-only endpoint that attests a contact channel as verified without exchanging a challenge code. The caller must be the bound guardian — verified either by JWT actor principal (laptop / docker) or by `X-Cadet-User-Id` matching the stored platform user id (cloud-managed). Idempotent: an already-verified channel returns 200 without re-writing. Mutation is gateway-DB primary with a best-effort dual-write to the assistant daemon DB for sync during the gateway-security-migration transition.",
1755
1755
  operationId: "contactsChannelVerify",
1756
1756
  security: [{ BearerAuth: [] }],
1757
1757
  parameters: [
@@ -2407,7 +2407,7 @@ export function buildSchema(): Record<string, unknown> {
2407
2407
  operationId: "oauthProvidersList",
2408
2408
  parameters: [
2409
2409
  {
2410
- name: "supports_managed_mode",
2410
+ name: "supports_cloud_mode",
2411
2411
  in: "query",
2412
2412
  required: false,
2413
2413
  schema: { type: "boolean" },
@@ -2509,7 +2509,7 @@ export function buildSchema(): Record<string, unknown> {
2509
2509
  post: {
2510
2510
  summary: "Create OAuth app",
2511
2511
  description:
2512
- "Authenticated gateway endpoint that creates or updates a user-managed OAuth app by proxying to the assistant runtime.",
2512
+ "Authenticated gateway endpoint that creates or updates a user-cloud OAuth app by proxying to the assistant runtime.",
2513
2513
  operationId: "oauthAppsCreate",
2514
2514
  security: [{ BearerAuth: [] }],
2515
2515
  requestBody: {
@@ -2546,7 +2546,7 @@ export function buildSchema(): Record<string, unknown> {
2546
2546
  delete: {
2547
2547
  summary: "Delete OAuth app",
2548
2548
  description:
2549
- "Authenticated gateway endpoint that deletes a user-managed OAuth app and disconnects its linked accounts by proxying to the assistant runtime.",
2549
+ "Authenticated gateway endpoint that deletes a user-cloud OAuth app and disconnects its linked accounts by proxying to the assistant runtime.",
2550
2550
  operationId: "oauthAppsDelete",
2551
2551
  parameters: [
2552
2552
  {
@@ -4346,7 +4346,7 @@ export function buildSchema(): Record<string, unknown> {
4346
4346
  post: {
4347
4347
  summary: "Auto-verify guardian email",
4348
4348
  description:
4349
- "Called by the platform to auto-verify the guardian's email channel. For BYO providers (resend, mailgun), validates the provider API key. For platform-managed email (cadet), the route's auth is sufficient. Creates a guardian email channel binding.",
4349
+ "Called by the cloud to auto-verify the guardian's email channel. For BYO providers (resend, mailgun), validates the provider API key. For cloud-managed email (cadet), the route's auth is sufficient. Creates a guardian email channel binding.",
4350
4350
  operationId: "inboundRegister",
4351
4351
  security: [{ BearerAuth: [] }],
4352
4352
  requestBody: {
@@ -39,7 +39,6 @@ const baseConfig: GatewayConfig = {
39
39
  runtimeMaxRetries: 2,
40
40
  runtimeProxyRequireAuth: true,
41
41
  runtimeTimeoutMs: 30000,
42
- shutdownDrainMs: 5000,
43
42
  trustProxy: false,
44
43
  };
45
44