@camstack/system 1.2.419 → 1.2.421

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 (77) hide show
  1. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  3. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  5. package/dist/builtins/alerts/alerts.addon.js +1 -1
  6. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  7. package/dist/builtins/autotrack/index.js +1 -1
  8. package/dist/builtins/autotrack/index.mjs +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  10. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  11. package/dist/builtins/calendars/calendars.addon.js +1 -1
  12. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  13. package/dist/builtins/camera-grid/index.js +1 -1
  14. package/dist/builtins/camera-grid/index.mjs +1 -1
  15. package/dist/builtins/composer/composer.addon.js +2 -2
  16. package/dist/builtins/composer/composer.addon.mjs +2 -2
  17. package/dist/builtins/console-logging/index.js +1 -1
  18. package/dist/builtins/console-logging/index.mjs +1 -1
  19. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  20. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  21. package/dist/builtins/device-manager/contribution-cache.d.ts +18 -1
  22. package/dist/builtins/device-manager/device-aggregation.d.ts +7 -1
  23. package/dist/builtins/device-manager/device-manager.addon.js +53 -8
  24. package/dist/builtins/device-manager/device-manager.addon.mjs +53 -8
  25. package/dist/builtins/hub-forwarder/index.js +1 -1
  26. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  27. package/dist/builtins/keychain/index.js +3 -3
  28. package/dist/builtins/keychain/index.mjs +3 -3
  29. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  30. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  31. package/dist/builtins/local-auth/local-auth.addon.js +2 -2
  32. package/dist/builtins/local-auth/local-auth.addon.mjs +2 -2
  33. package/dist/builtins/local-network/local-network.addon.js +1 -1
  34. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  35. package/dist/builtins/loki-logging/index.js +1 -1
  36. package/dist/builtins/loki-logging/index.mjs +1 -1
  37. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  38. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  39. package/dist/builtins/platform-probe/index.js +1 -1
  40. package/dist/builtins/platform-probe/index.mjs +1 -1
  41. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  42. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  43. package/dist/builtins/snapshot/index.js +1 -1
  44. package/dist/builtins/snapshot/index.mjs +1 -1
  45. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  46. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  47. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
  48. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
  49. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  50. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  51. package/dist/builtins/system-config/system-config.addon.js +138 -18
  52. package/dist/builtins/system-config/system-config.addon.mjs +138 -19
  53. package/dist/builtins/winston-logging/index.js +1 -1
  54. package/dist/builtins/winston-logging/index.mjs +1 -1
  55. package/dist/{composition-sources-562ib2dL.mjs → composition-sources-DoYpCPtl.mjs} +1 -1
  56. package/dist/{composition-sources-OaDYklhR.js → composition-sources-DxlTUSI1.js} +1 -1
  57. package/dist/{constants-BeQWXybC.mjs → constants-CtxNK2QJ.mjs} +1 -1
  58. package/dist/{constants-ik5xtasS.js → constants-GXZQRcjB.js} +1 -1
  59. package/dist/{dist-C0wYvAHC.mjs → dist-0OD9ue39.mjs} +106 -2
  60. package/dist/{dist-DLHPmdoV.js → dist-Df7s77se.js} +106 -2
  61. package/dist/index.js +187 -19
  62. package/dist/index.mjs +183 -21
  63. package/dist/{jwt-signing-key-CWmNKLQi.js → jwt-signing-key-BmyvxlDJ.js} +1 -1
  64. package/dist/{jwt-signing-key-dkTVfsLI.mjs → jwt-signing-key-W-WFzAoK.mjs} +1 -1
  65. package/dist/kernel/index.d.ts +5 -1
  66. package/dist/kernel/moleculer/agent-event-scope.d.ts +49 -0
  67. package/dist/kernel/moleculer/agent-mesh-authenticator.d.ts +15 -3
  68. package/dist/kernel/moleculer/broker-factory.d.ts +6 -0
  69. package/dist/kernel/moleculer/mesh-access-middleware.d.ts +8 -4
  70. package/dist/kernel/moleculer/mesh-join-hold.d.ts +85 -0
  71. package/dist/kernel/moleculer/mesh-mtls/index.d.ts +1 -1
  72. package/dist/kernel/moleculer/mesh-mtls/tls-tcp-transporter.d.ts +65 -4
  73. package/dist/{restore-archive-gGHgAZsz.mjs → restore-archive-BUMSox6L.mjs} +1 -1
  74. package/dist/{restore-archive-DZeFVS2l.js → restore-archive-W1Cg5y6C.js} +1 -1
  75. package/dist/{retired-settings-keys-DibNtLmU.js → retired-settings-keys-D-Xv1Zyv.js} +1 -1
  76. package/dist/{retired-settings-keys-BHlKEYNL.mjs → retired-settings-keys-Wz92bcuK.mjs} +1 -1
  77. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { i as __require } from "./chunk-CNf5ZN-e.mjs";
2
- import { At as extractNestedAddonId, Bt as isObjectInput, Cn as resolveMethodAuth, Dn as scopesAllowDeviceCap, Dr as emitDownForOwnedCaps, En as scopesAllowAddon, G as addonSettingsCapability, Gr as resolveCapMount, Hr as parseJsonUnknown, Ht as kebabToCamel$1, It as isArrayOutputSchema, Lt as isCollectionArrayMethod, O as LOG_LEVEL_RANK, Qt as looseSchema, Rn as supportedRuntimes, Vr as parseJsonObject, Vt as isVoidInput, Wr as readinessKey, Zt as logLevelAtMost, br as asString$1, cn as objectInputDeclaresRequiredDeviceId, dr as DEVICE_STATUS_METHOD, ei as EventCategory$1, hr as ReadinessTimeoutError, j as METHOD_ACCESS_MAP, kr as expandCapMethods, lr as DATAPLANE_SECRET_HEADER$1, mr as ReadinessRegistry, pn as procedureAuthKey, pr as RUNTIME_DEFAULTS, qr as scopeKey, qt as lifecycleJobSchema, sn as objectInputDeclaresAddonId, sr as errMsg$1, t as ALL_CAPABILITY_DEFINITIONS, ur as DEVICE_SETTINGS_CONTRIBUTION_METHODS, vr as asJsonObject$1, wr as createEvent$1, yr as asNumber } from "./dist-C0wYvAHC.mjs";
3
- import { c as staticJwtSigningKey, i as getProcessJwtSigningKeyState, n as JwtSigningKeyUnavailableError, o as processJwtSigningKey, r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "./jwt-signing-key-dkTVfsLI.mjs";
2
+ import { At as extractNestedAddonId, Bt as isObjectInput, Cn as resolveMethodAuth, Dn as scopesAllowDeviceCap, Dr as emitDownForOwnedCaps, En as scopesAllowAddon, G as addonSettingsCapability, Gr as resolveCapMount, Hr as parseJsonUnknown, Ht as kebabToCamel$1, It as isArrayOutputSchema, Lt as isCollectionArrayMethod, O as LOG_LEVEL_RANK, Qt as looseSchema, Rn as supportedRuntimes, Vr as parseJsonObject, Vt as isVoidInput, Wr as readinessKey, Zt as logLevelAtMost, br as asString$1, cn as objectInputDeclaresRequiredDeviceId, dr as DEVICE_STATUS_METHOD, ei as EventCategory$1, hr as ReadinessTimeoutError, j as METHOD_ACCESS_MAP, kr as expandCapMethods, lr as DATAPLANE_SECRET_HEADER$1, mr as ReadinessRegistry, pn as procedureAuthKey, pr as RUNTIME_DEFAULTS, qr as scopeKey, qt as lifecycleJobSchema, sn as objectInputDeclaresAddonId, sr as errMsg$1, t as ALL_CAPABILITY_DEFINITIONS, ur as DEVICE_SETTINGS_CONTRIBUTION_METHODS, vr as asJsonObject$1, wr as createEvent$1, yr as asNumber } from "./dist-0OD9ue39.mjs";
3
+ import { c as staticJwtSigningKey, i as getProcessJwtSigningKeyState, n as JwtSigningKeyUnavailableError, o as processJwtSigningKey, r as SYSTEM_SECRET_OWNER, t as JWT_SIGNING_KEY_REF } from "./jwt-signing-key-W-WFzAoK.mjs";
4
4
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
5
5
  import "./builtins/alerts/index.mjs";
6
6
  import { CalendarsAddon } from "./builtins/calendars/calendars.addon.mjs";
@@ -25,15 +25,15 @@ import { SqliteSettingsAddon, o as SqliteSettingsBackend, s as prefixRange } fro
25
25
  import { ConfigStore, DeviceStore } from "./builtins/sqlite-storage/index.mjs";
26
26
  import { StorageOrchestratorAddon, a as stripForwardedCaller, i as createHubCapForwardService, n as HUB_CAP_FWD_ACTION, o as buildStorageLocationRegistry, r as HUB_CAP_FWD_SERVICE, t as StorageOrchestratorService } from "./builtins/storage-orchestrator/storage-orchestrator.addon.mjs";
27
27
  import "./builtins/storage-orchestrator/index.mjs";
28
- import { _ as getProcessClusterSecretGate, a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, d as CLUSTER_SECRET_REF, f as CLUSTER_SECRET_REJECTED_EXIT_CODE, g as clusterSecretMatches, h as checkClusterSecret, i as MESH_CA_FIELD, m as CLUSTER_SECRET_UNAVAILABLE_TYPE, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, p as CLUSTER_SECRET_SETTINGS_KEY, u as CLUSTER_SECRET_MISMATCH_TYPE, v as hashClusterSecret, y as isClusterSecretMismatchError } from "./constants-BeQWXybC.mjs";
29
- import { A as AGENT_UI_UNLOCK_VERSION, B as parseMeshAuthMode, C as generateMeshKeyPair, D as AGENT_DASHBOARD_ORIGINS_FIELD, E as loadMeshCa, F as verifyAgentUiUnlockTicket, G as createCidrMatcher, H as setProcessMeshAuthMode, I as MESH_AUTH_MODE_FIELD, J as readCidrSetting, K as normalizeIp, L as getProcessMeshAuthMode, M as isAllowedAgentDashboardReturnTo, N as mintAgentUiUnlockTicket, O as AGENT_UI_UNLOCK_DOMAIN, P as parseAgentDashboardOrigins, R as getProcessMeshAuthStatus, S as generateMeshCa, SystemConfigAddon, T as issueMeshLeafFromCsr, U as setProcessMeshAuthStatusSource, V as requestProcessMeshEnforcement, W as setProcessMeshEnforcer, _ as requireProcessMeshCa, a as setProcessMeshTlsEnabler, b as createMeshCsrPem, c as mintMeshJoinToken, d as getProcessNodeMeshTransport, f as setProcessMeshPeerTransportLookup, g as getProcessMeshCaState, h as MeshCaKeeper, i as ServiceBroker, j as UnlockTicketJtiStore, k as AGENT_UI_UNLOCK_TTL_MS, l as processJoinTokenJtiStore, m as processMeshCrl, n as TlsTcpTransporter, o as enrollMeshNode, p as MeshCrl, q as parseCidrList, r as Errors, s as JoinTokenJtiStore, u as verifyMeshJoinToken, v as caFingerprint, w as issueMeshLeafForNode, x as exportMeshPrivateKeyPem, y as caFingerprintCompact, z as isMeshAuthMode } from "./builtins/system-config/system-config.addon.mjs";
28
+ import { _ as getProcessClusterSecretGate, a as MESH_CA_KEY_REF, b as setProcessClusterSecretGate, d as CLUSTER_SECRET_REF, f as CLUSTER_SECRET_REJECTED_EXIT_CODE, g as clusterSecretMatches, h as checkClusterSecret, i as MESH_CA_FIELD, m as CLUSTER_SECRET_UNAVAILABLE_TYPE, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY, p as CLUSTER_SECRET_SETTINGS_KEY, u as CLUSTER_SECRET_MISMATCH_TYPE, v as hashClusterSecret, y as isClusterSecretMismatchError } from "./constants-CtxNK2QJ.mjs";
29
+ import { A as AGENT_UI_UNLOCK_TTL_MS, B as isMeshAuthMode, C as generateMeshCa, D as loadMeshCa, E as issueMeshLeafFromCsr, F as parseAgentDashboardOrigins, G as setProcessMeshEnforcer, H as requestProcessMeshEnforcement, I as verifyAgentUiUnlockTicket, J as parseCidrList, K as createCidrMatcher, L as MESH_AUTH_MODE_FIELD, M as UnlockTicketJtiStore, N as isAllowedAgentDashboardReturnTo, O as AGENT_DASHBOARD_ORIGINS_FIELD, P as mintAgentUiUnlockTicket, R as getProcessMeshAuthMode, S as exportMeshPrivateKeyPem, SystemConfigAddon, T as issueMeshLeafForNode, U as setProcessMeshAuthMode, V as parseMeshAuthMode, W as setProcessMeshAuthStatusSource, Y as readCidrSetting, _ as getProcessMeshCaState, a as ServiceBroker, b as caFingerprintCompact, c as JoinTokenJtiStore, d as verifyMeshJoinToken, f as getProcessNodeMeshTransport, g as MeshCaKeeper, h as processMeshCrl, i as Errors, j as AGENT_UI_UNLOCK_VERSION, k as AGENT_UI_UNLOCK_DOMAIN, l as mintMeshJoinToken, m as MeshCrl, n as MESH_TLS_PORT_HELLO_FIELD, o as setProcessMeshTlsEnabler, p as setProcessMeshPeerTransportLookup, q as normalizeIp, r as TlsTcpTransporter, s as enrollMeshNode, u as processJoinTokenJtiStore, v as requireProcessMeshCa, w as generateMeshKeyPair, x as createMeshCsrPem, y as caFingerprint, z as getProcessMeshAuthStatus } from "./builtins/system-config/system-config.addon.mjs";
30
30
  import "./builtins/system-config/index.mjs";
31
31
  import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
32
32
  import { C as isModelDownloaded, T as revisionWeightUrl, _ as downloadFile, a as startEventLoopStallMonitor, b as fetchJson, c as createAuthenticatedFileServer, d as resolveFilePath, f as ModelDownloadService, g as deleteModelFromDisk, h as collectModelFiles, i as attributeStall, l as parseRangeHeader, m as adoptModelRevisions, n as STALL_REPORT_MS, o as createFileDataPlaneHandler, r as STALL_TICK_MS, s as contentTypeFor, t as CustomActionRegistry, u as parseTokenizedUrl, v as downloadModel, w as resolveFormatRevision, x as getModelFilePath, y as ensureModel } from "./custom-action-registry-BQnbN0DP.mjs";
33
33
  import { A as allFamiliesListenHost, C as collectCertIdentity, D as SERVER_AUTH_OID, E as MAX_LEAF_VALIDITY_DAYS, F as registerLanHttpHandler, M as bindPendingLanHttp, N as closeLanHttp, O as evaluateExistingCert, P as readLanHttpState, S as CA_COMMON_NAME, T as LEAF_RENEWAL_WINDOW_DAYS, _ as writeExtraSans, a as validateUploadedTls, b as loadTlsCert, c as registerHttpsListener, d as prepareBootTls, f as UPLOADED_CA_FILE, g as splitPemCertificates, h as readTlsMode, i as storeUploadedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, l as reloadHttpsListener, m as readTlsAccessStatus, n as regenerateCertificate, o as clearHttpsListener, p as readExtraSans, r as revertToGeneratedCertificate, s as leafFingerprintOf, t as applyCertificateToListener, u as servedHttpsLeafFingerprint, v as writeTlsMode, w as CA_VALIDITY_DAYS, x as reissueTlsLeaf, y as ensureTlsCert } from "./tls-CaOLZ09W.mjs";
34
34
  import { n as getPlatformKeychainKey, r as setPlatformKeychainKey, t as clearPlatformKeychainKey } from "./platform-key-source-BWlq0jjn.mjs";
35
35
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Di9daRwI.mjs";
36
- import { c as BackupKeyFormatError, d as generateBackupKeyPair, l as BackupKeyMismatchError, m as readBackupEncryptionHeader, o as SystemBackupService, r as prepareRestoreArchive, s as BackupDecryptError, t as BackupKeyRequiredError } from "./restore-archive-gGHgAZsz.mjs";
36
+ import { c as BackupKeyFormatError, d as generateBackupKeyPair, l as BackupKeyMismatchError, m as readBackupEncryptionHeader, o as SystemBackupService, r as prepareRestoreArchive, s as BackupDecryptError, t as BackupKeyRequiredError } from "./restore-archive-BUMSox6L.mjs";
37
37
  import { z } from "zod";
38
38
  import * as crypto$1 from "node:crypto";
39
39
  import { createHash, createHmac, randomBytes, randomUUID, timingSafeEqual } from "node:crypto";
@@ -15106,6 +15106,9 @@ function createBroker(config) {
15106
15106
  serializer: "MsgPack",
15107
15107
  transporter: new TlsTcpTransporter({
15108
15108
  port: agentListenPort,
15109
+ tlsPort: config.agentTlsListenPort ?? 6443,
15110
+ peerTlsPort: hubDialPort,
15111
+ hubOnlyPeers: true,
15109
15112
  maxPacketSize: 10 * 1024 * 1024,
15110
15113
  useHostname,
15111
15114
  debug: false,
@@ -24108,6 +24111,10 @@ function createMeshAccessMiddleware(options) {
24108
24111
  const sender = senderOf(ctx);
24109
24112
  if (sender === null || sender === ownNodeId) return next.call(this, ctx);
24110
24113
  const verdict = authenticator.admitCall(sender, name);
24114
+ if (verdict.verdict === "hold") return verdict.settled.then((settled) => runAdmitted.call(this, ctx, sender, settled));
24115
+ return runAdmitted.call(this, ctx, sender, verdict);
24116
+ };
24117
+ function runAdmitted(ctx, sender, verdict) {
24111
24118
  if (verdict.verdict === "deny") {
24112
24119
  logger?.warn("mesh call refused", {
24113
24120
  sender,
@@ -24119,23 +24126,119 @@ function createMeshAccessMiddleware(options) {
24119
24126
  if (name === "$hub.unregisterNode" && paramNodeId(ctx.params) !== sender) return Promise.reject(new Errors.MoleculerClientError(`node "${sender}" may unregister only itself`, 403, MESH_ACTION_FORBIDDEN_TYPE));
24120
24127
  ctx.params = stripForgedIdentity(name, ctx.params);
24121
24128
  return next.call(this, ctx);
24122
- };
24129
+ }
24123
24130
  },
24124
24131
  localEvent(next, event) {
24125
24132
  const name = event.name ?? "";
24126
24133
  return function meshGatedEvent(ctx) {
24127
24134
  const sender = senderOf(ctx);
24128
24135
  if (sender === null || sender === ownNodeId) return Promise.resolve(next.call(this, ctx));
24129
- if (authenticator.admitEvent(sender, name).verdict === "deny") {
24130
- noteDroppedEvent(sender, name);
24131
- return Promise.resolve();
24132
- }
24133
- return Promise.resolve(next.call(this, ctx));
24136
+ const verdict = authenticator.admitEvent(sender, name);
24137
+ const deliver = (settled) => {
24138
+ if (settled.verdict === "deny") {
24139
+ noteDroppedEvent(sender, name);
24140
+ return Promise.resolve();
24141
+ }
24142
+ return Promise.resolve(next.call(this, ctx));
24143
+ };
24144
+ return verdict.verdict === "hold" ? verdict.settled.then(deliver) : deliver(verdict);
24134
24145
  };
24135
24146
  }
24136
24147
  };
24137
24148
  }
24138
24149
  //#endregion
24150
+ //#region src/kernel/moleculer/mesh-join-hold.ts
24151
+ var DEFAULT_MESH_JOIN_MAX_HELD = 1e3;
24152
+ var DEFAULT_MESH_JOIN_MAX_HOLD_MS = 15e3;
24153
+ var MeshJoinHold = class {
24154
+ opts;
24155
+ waiters = [];
24156
+ firstHeldAt = null;
24157
+ overflow = 0;
24158
+ timer = null;
24159
+ /** Holding is open while a join is in flight; closed after a decision or the bound. */
24160
+ open = true;
24161
+ now;
24162
+ constructor(opts) {
24163
+ this.opts = opts;
24164
+ this.now = opts.now ?? Date.now;
24165
+ }
24166
+ /** Whether a request arriving now would be held (a join is in flight). */
24167
+ get holding() {
24168
+ return this.open;
24169
+ }
24170
+ /** How many requests wait right now. */
24171
+ get size() {
24172
+ return this.waiters.length;
24173
+ }
24174
+ /** A join started: hold again. */
24175
+ reopen() {
24176
+ this.open = true;
24177
+ }
24178
+ /** Hold one request; `null` when holding is closed (the caller refuses it). */
24179
+ hold(kind) {
24180
+ if (!this.open) return null;
24181
+ if (this.waiters.length >= (this.opts.maxHeld ?? 1e3)) {
24182
+ this.overflow++;
24183
+ return {
24184
+ verdict: "hold",
24185
+ settled: Promise.resolve(this.refusal("the hold before the mesh join is full"))
24186
+ };
24187
+ }
24188
+ if (this.firstHeldAt === null) {
24189
+ this.firstHeldAt = this.now();
24190
+ this.timer = setTimeout(() => this.refuse("bound"), this.opts.maxHoldMs ?? 15e3);
24191
+ this.timer.unref?.();
24192
+ }
24193
+ return {
24194
+ verdict: "hold",
24195
+ settled: new Promise((resolve) => {
24196
+ this.waiters.push({
24197
+ kind,
24198
+ resolve
24199
+ });
24200
+ })
24201
+ };
24202
+ }
24203
+ /** The join proved the hub: deliver everything held, in order. */
24204
+ release() {
24205
+ this.open = false;
24206
+ this.settle({ verdict: "allow" }, "delivered", "authenticated");
24207
+ }
24208
+ /** The join failed, or the bound ran out: refuse everything held. */
24209
+ refuse(reason) {
24210
+ this.open = false;
24211
+ this.settle(this.refusal(`the join ended "${reason}"`), "refused", reason);
24212
+ }
24213
+ refusal(why) {
24214
+ return {
24215
+ verdict: "deny",
24216
+ errorType: MESH_NODE_UNAUTHENTICATED_TYPE,
24217
+ message: `"${this.opts.hubNodeId}" sent this before the mesh join settled, and ${why}`
24218
+ };
24219
+ }
24220
+ settle(verdict, outcome, reason) {
24221
+ if (this.timer !== null) clearTimeout(this.timer);
24222
+ this.timer = null;
24223
+ const waiters = this.waiters;
24224
+ const overflow = this.overflow;
24225
+ const firstHeldAt = this.firstHeldAt;
24226
+ this.waiters = [];
24227
+ this.overflow = 0;
24228
+ this.firstHeldAt = null;
24229
+ if (waiters.length === 0 && overflow === 0) return;
24230
+ for (const w of waiters) w.resolve(verdict);
24231
+ this.opts.onReport?.({
24232
+ outcome,
24233
+ reason,
24234
+ events: waiters.filter((w) => w.kind === "event").length,
24235
+ calls: waiters.filter((w) => w.kind === "call").length,
24236
+ overflow,
24237
+ heldForMs: firstHeldAt === null ? 0 : this.now() - firstHeldAt
24238
+ });
24239
+ }
24240
+ };
24241
+ //#endregion
24139
24242
  //#region src/kernel/moleculer/agent-mesh-authenticator.ts
24140
24243
  /** The child's register action on its parent agent. */
24141
24244
  var AGENT_REGISTER_NODE_ACTION = "$agent.registerNode";
@@ -24155,10 +24258,22 @@ var AgentMeshAuthenticator = class {
24155
24258
  nodes = /* @__PURE__ */ new Map();
24156
24259
  hubNodeId;
24157
24260
  now;
24261
+ hold;
24158
24262
  constructor(deps) {
24159
24263
  this.deps = deps;
24160
24264
  this.hubNodeId = deps.hubNodeId ?? DEFAULT_HUB_NODE_ID;
24161
24265
  this.now = deps.now ?? Date.now;
24266
+ this.hold = new MeshJoinHold({
24267
+ hubNodeId: this.hubNodeId,
24268
+ now: this.now,
24269
+ ...deps.maxHeld !== void 0 ? { maxHeld: deps.maxHeld } : {},
24270
+ ...deps.maxHoldMs !== void 0 ? { maxHoldMs: deps.maxHoldMs } : {},
24271
+ ...deps.onHoldReport !== void 0 ? { onReport: deps.onHoldReport } : {}
24272
+ });
24273
+ }
24274
+ /** How many of the hub's requests wait for the join right now. */
24275
+ heldCount() {
24276
+ return this.hold.size;
24162
24277
  }
24163
24278
  /** Current mode: secret configured → enforce; else tolerate (upgrade path). */
24164
24279
  mode() {
@@ -24172,9 +24287,16 @@ var AgentMeshAuthenticator = class {
24172
24287
  noteHubJoinState(state) {
24173
24288
  if (state === "authenticated") {
24174
24289
  this.record(this.hubNodeId, "authenticated");
24290
+ this.hold.release();
24291
+ return;
24292
+ }
24293
+ if (state === "pending") {
24294
+ this.forget(this.hubNodeId);
24295
+ this.hold.reopen();
24175
24296
  return;
24176
24297
  }
24177
- if (state === "secret-mismatch" || state === "hub-unverified" || state === "pending") this.forget(this.hubNodeId);
24298
+ if (state === "secret-mismatch" || state === "hub-unverified") this.forget(this.hubNodeId);
24299
+ this.hold.refuse(state);
24178
24300
  }
24179
24301
  /** A child's `$agent.registerNode` was accepted (secret hash matched or none required). */
24180
24302
  noteChildRegistered(sender, proof = "authenticated") {
@@ -24193,11 +24315,11 @@ var AgentMeshAuthenticator = class {
24193
24315
  message: `"${action}" is not callable from another node (caller "${sender}")`
24194
24316
  };
24195
24317
  if (action === "$agent.registerNode" && isOwnChildNodeId(this.deps.ownNodeId, sender)) return { verdict: "allow" };
24196
- return this.admitSender(sender, action);
24318
+ return this.admitSender(sender, action, "call");
24197
24319
  }
24198
24320
  admitEvent(sender, eventName) {
24199
24321
  if (sender === this.deps.ownNodeId) return { verdict: "allow" };
24200
- return this.admitSender(sender, `event:${eventName}`);
24322
+ return this.admitSender(sender, `event:${eventName}`, "event");
24201
24323
  }
24202
24324
  stateOf(nodeId) {
24203
24325
  return this.nodes.get(nodeId)?.state ?? "unauthenticated";
@@ -24205,14 +24327,20 @@ var AgentMeshAuthenticator = class {
24205
24327
  authenticatedNodeIds() {
24206
24328
  return [...this.nodes].filter(([, r]) => r.state === "authenticated").map(([id]) => id);
24207
24329
  }
24208
- admitSender(sender, what) {
24330
+ admitSender(sender, what, kind) {
24209
24331
  const state = this.stateOf(sender);
24210
24332
  if (state === "authenticated" || state === "legacy") return { verdict: "allow" };
24211
- if (this.mode() === "enforced") return {
24212
- verdict: "deny",
24213
- errorType: MESH_NODE_UNAUTHENTICATED_TYPE,
24214
- message: `node "${sender}" has not authenticated to this agent — only the hub (after mutual mesh join) and this agent's own children may call it`
24215
- };
24333
+ if (this.mode() === "enforced") {
24334
+ if (sender === this.hubNodeId) {
24335
+ const held = this.hold.hold(kind);
24336
+ if (held !== null) return held;
24337
+ }
24338
+ return {
24339
+ verdict: "deny",
24340
+ errorType: MESH_NODE_UNAUTHENTICATED_TYPE,
24341
+ message: `node "${sender}" has not authenticated to this agent — only the hub (after mutual mesh join) and this agent's own children may call it`
24342
+ };
24343
+ }
24216
24344
  if (!this.nodes.has(sender)) {
24217
24345
  this.record(sender, "unauthenticated");
24218
24346
  this.deps.onTolerated?.(sender, what);
@@ -24232,6 +24360,40 @@ var AgentMeshAuthenticator = class {
24232
24360
  }
24233
24361
  };
24234
24362
  //#endregion
24363
+ //#region src/kernel/moleculer/agent-event-scope.ts
24364
+ /** Moleculer's EVENT packet type (`packets.PACKET_EVENT`). */
24365
+ var PACKET_EVENT = "EVENT";
24366
+ /** Is this an event packet addressed to a node other than the hub? */
24367
+ function isPeerEventPacket(packet, hubNodeId) {
24368
+ return packet.type === PACKET_EVENT && packet.target !== null && packet.target !== hubNodeId;
24369
+ }
24370
+ function createAgentEventScope(opts) {
24371
+ let toHub = 0;
24372
+ const withheld = /* @__PURE__ */ new Map();
24373
+ const gate = (next) => function agentEventScoped(packet) {
24374
+ if (packet.type !== PACKET_EVENT) return next(packet);
24375
+ if (!isPeerEventPacket(packet, opts.hubNodeId)) {
24376
+ if (packet.target === opts.hubNodeId) toHub++;
24377
+ return next(packet);
24378
+ }
24379
+ const peer = packet.target ?? "";
24380
+ const prev = withheld.get(peer) ?? 0;
24381
+ withheld.set(peer, prev + 1);
24382
+ if (prev === 0) opts.log?.(`mesh events: not sending events to node "${peer}" — an agent's events go to the hub only (D848)`);
24383
+ return Promise.resolve();
24384
+ };
24385
+ return {
24386
+ middleware: {
24387
+ name: "CamstackAgentEventScope",
24388
+ transitPublish: gate
24389
+ },
24390
+ stats: () => ({
24391
+ toHub,
24392
+ withheld: Object.fromEntries(withheld)
24393
+ })
24394
+ };
24395
+ }
24396
+ //#endregion
24235
24397
  //#region src/kernel/moleculer/mesh-join-client.ts
24236
24398
  /** States in which a call to the hub is refused locally. */
24237
24399
  var BLOCKING = new Set(["secret-mismatch", "hub-unverified"]);
@@ -26647,4 +26809,4 @@ var LifecycleJobEngine = class {
26647
26809
  */
26648
26810
  var CAP_METHOD_NOT_IMPLEMENTED = "CAP_METHOD_NOT_IMPLEMENTED";
26649
26811
  //#endregion
26650
- export { ADMIN_TOKEN_MAX_LIFETIME_MS, ADMIN_TOKEN_PREFIX, AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_READINESS_SERVICE_NAME, AGENT_REGISTER_NODE_ACTION, AGENT_UI_UNLOCK_DOMAIN, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_VERSION, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AdminTokenManager, AgentMeshAuthenticator, AlertCenterAddon, ApiKeyManager, AuthAuditLog, AuthManager, BackupDecryptError, BackupKeyFormatError, BackupKeyMismatchError, BackupKeyRequiredError, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REF, CLUSTER_SECRET_REJECTED_EXIT_CODE, CLUSTER_SECRET_SETTINGS_KEY, CLUSTER_SECRET_UNAVAILABLE_TYPE, CORE_CAP_SERVICE_NAME, CalendarsAddon, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_HUB_TLS_TCP_PORT, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FIRST_BOOT_ADMIN_PASSWORD, FIRST_BOOT_ADMIN_USERNAME, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JWT_SIGNING_KEY_REF, JobJournal, JoinTokenJtiStore, JwtSigningKeyUnavailableError, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LoginSessionManager, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_ACTION_FORBIDDEN_TYPE, MESH_AUTH_MODE_FIELD, MESH_AUTO_ENFORCE_GRACE_MS, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_JOIN_AUTHENTICATE_ACTION, MESH_JOIN_CHALLENGE_ACTION, MESH_JOIN_CHALLENGE_INVALID_TYPE, MESH_JOIN_CHALLENGE_TTL_MS, MESH_JOIN_PROTOCOL, MESH_NODE_UNAUTHENTICATED_TYPE, MESH_QUEUE_TOP_N, METHOD_ACCESS_MAP, MeshAuthenticator, MeshCaKeeper, MeshCrl, MeshJoinClient, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, REFRESH_TOKEN_PREFIX, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, STORE_READABLE_BOOTSTRAP_KEYS, SYSTEM_SECRET_OWNER, ScopedLogger, ScopedTokenManager, SettingsReadUnavailableError, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemBackupService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, TlsTcpTransporter, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UPLOADED_CA_FILE, USER_MANAGEMENT_INTERNAL, UdsLocalTransportClient, UdsLocalTransportServer, UnlockTicketJtiStore, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, adoptModelRevisions, afterWorkerOnlineAnnounce, allFamiliesListenHost, answerClaimedGetStatus, applyCertificateToListener, applyLanHttp, attachUserManagementInternal, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, builderMountedCapNames, caFingerprint, caFingerprintCompact, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, checkClusterSecret, classifyAddonDir, classifyCapRoute, clearHttpsListener, clearPendingRestart, clearPlatformKeychainKey, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, computeHubJoinProof, computeNodeJoinProof, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCidrMatcher, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createKernelInferenceEngine, createLocalTransport, createLoopDelayMeter, createMeshAccessMiddleware, createMeshCsrPem, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, decideMeshAutoEnforce, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, enrollMeshNode, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, exportMeshPrivateKeyPem, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, generateBackupKeyPair, generateMeshCa, generateMeshKeyPair, getBrokerEventBus, getBrokerTlsTransporter, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPlatformKeychainKey, getProcessClusterSecretGate, getProcessJwtSigningKeyState, getProcessMeshAuthMode, getProcessMeshAuthStatus, getProcessMeshCaState, getProcessNodeMeshTransport, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getUserManagementInternal, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hostNodeIdOf, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isAllowedAgentDashboardReturnTo, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isCredentialKeyName, isInfraCapability, isMeshAuthMode, isModelDownloaded, isOwnChildNodeId, isRemoteForbiddenAction, isRemoteForbiddenOnAgent, isSettingsReadUnavailable, isSourceNewer, isolatedBuiltinPhase, issueMeshLeafForNode, issueMeshLeafFromCsr, leafFingerprintOf, loadMeshCa, loadTlsCert, localEndpointPath, localProviderLink, localSupportedPythonRuntimes, mapSignalsToInferenceHardware, meshErrorType, mintAgentUiUnlockTicket, mintMeshJoinToken, mountNativeCapService, nextRssBudgetState, normalizeIp, overlayGetStatus, parseAgentDashboardOrigins, parseCapAction, parseCidrList, parseMeshAuthMode, parseRangeHeader, parseRssBudgetMb, parseTokenExpiry, parseTokenizedUrl, partitionIsolatedBuiltinIds, prepareBootTls, prepareRestoreArchive, probePlatform, processJoinTokenJtiStore, processJwtSigningKey, processMeshCrl, proxyToUpstream, quarantineAddonResidue, readBackupEncryptionHeader, readCidrSetting, readExtraSans, readHeapSpaces, readLanHttpState, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, redactLogEntry, redactLogMeta, redactLogText, regenerateCertificate, registerEventBusService, registerHttpsListener, registerLanHttpHandler, reissueTlsLeaf, reloadHttpsListener, requestProcessMeshEnforcement, requireProcessMeshCa, resolveFilePath, resolveFormatRevision, resolveHwAccel, resolveNpmInvocation, revertToGeneratedCertificate, revisionWeightUrl, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, servedHttpsLeafFingerprint, setHubConnected, setNodeEventInterest, setPlatformKeychainKey, setProcessClusterSecretGate, setProcessMeshAuthMode, setProcessMeshAuthStatusSource, setProcessMeshEnforcer, setProcessMeshPeerTransportLookup, setProcessMeshTlsEnabler, setWrapperActive, shouldReclaim, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, splitPemCertificates, stampCallerAddonId, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, staticJwtSigningKey, storeMayAnswer, storeUploadedCertificate, strandedMb, stripCamstackDeps, stripForgedIdentity, stripForwardedCaller, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, verifyAgentUiUnlockTicket, verifyMeshJoinToken, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
26812
+ export { ADMIN_TOKEN_MAX_LIFETIME_MS, ADMIN_TOKEN_PREFIX, AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_DASHBOARD_ORIGINS_FIELD, AGENT_READINESS_SERVICE_NAME, AGENT_REGISTER_NODE_ACTION, AGENT_UI_UNLOCK_DOMAIN, AGENT_UI_UNLOCK_TTL_MS, AGENT_UI_UNLOCK_VERSION, ALL_CAPABILITY_DEFINITIONS, ARRAY_BUFFER_CENSUS_COOLDOWN_MS, ARRAY_BUFFER_CENSUS_SUSTAIN_MS, ARRAY_BUFFER_CENSUS_THRESHOLD_MB, ARRAY_BUFFER_RELEASE_MIN_DROP_RATIO, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AdminTokenManager, AgentMeshAuthenticator, AlertCenterAddon, ApiKeyManager, AuthAuditLog, AuthManager, BackupDecryptError, BackupKeyFormatError, BackupKeyMismatchError, BackupKeyRequiredError, CAP_ACTION_OVERFLOW_LABEL, CAP_ACTION_UNLABELLED, CAP_METHOD_NOT_IMPLEMENTED, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REF, CLUSTER_SECRET_REJECTED_EXIT_CODE, CLUSTER_SECRET_SETTINGS_KEY, CLUSTER_SECRET_UNAVAILABLE_TYPE, CORE_CAP_SERVICE_NAME, CalendarsAddon, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ComposerAddon, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DECISIVE_HEAP_SPACES, DEFAULT_DATA_PATH, DEFAULT_HUB_TLS_TCP_PORT, DEFAULT_LAN_HTTP_PORT, DEFAULT_LOG_LEVEL, DEFAULT_MESH_JOIN_MAX_HELD, DEFAULT_MESH_JOIN_MAX_HOLD_MS, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EMPTY_CAP_ACTION_READING, EMPTY_SOCKET_DIRECTION, EMPTY_SOCKET_PLANE_BASELINE, EVENT_PLANE_TOP_N, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FIRST_BOOT_ADMIN_PASSWORD, FIRST_BOOT_ADMIN_USERNAME, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, GET_STATUS_METHOD, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_STEADY_STATE_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_SPACE_REPORT_MIN_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HUB_MAIN_HEAP_WATCH_LABEL, HUB_MAIN_RSS_BUDGET_MB, HUB_RSS_BUDGET_ENV, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JWT_SIGNING_KEY_REF, JobJournal, JoinTokenJtiStore, JwtSigningKeyUnavailableError, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LoggingGate, LoginSessionManager, LokiDestination, LokiLoggingAddon, MAX_CAP_ACTIONS_PER_PEER, MAX_LEAF_VALIDITY_DAYS, MESH_ACTION_FORBIDDEN_TYPE, MESH_AUTH_MODE_FIELD, MESH_AUTO_ENFORCE_GRACE_MS, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MESH_JOIN_AUTHENTICATE_ACTION, MESH_JOIN_CHALLENGE_ACTION, MESH_JOIN_CHALLENGE_INVALID_TYPE, MESH_JOIN_CHALLENGE_TTL_MS, MESH_JOIN_PROTOCOL, MESH_NODE_UNAUTHENTICATED_TYPE, MESH_QUEUE_TOP_N, MESH_TLS_PORT_HELLO_FIELD, METHOD_ACCESS_MAP, MeshAuthenticator, MeshCaKeeper, MeshCrl, MeshJoinClient, MeshJoinHold, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, OUTBOUND_QUEUE_COOLDOWN_MS, OUTBOUND_QUEUE_SUSTAIN_MS, OUTBOUND_QUEUE_THRESHOLD_BYTES, PARENT_ROUTED_PROVIDER_ADDON_ID, PYTHON_VERSION, PeerAnsweredError, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, REFRESH_TOKEN_PREFIX, RESTART_MARKER_FILE, RSS_BUDGET_REANNOUNCE_MIN_MS, RSS_BUDGET_RELEASE_RATIO, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNNER_RSS_BUDGET_ENV, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, SOCKET_PLANE_TOP_N, SOCKET_QUEUE_TOP_N, STALL_REPORT_MS, STALL_TICK_MS, STORE_READABLE_BOOTSTRAP_KEYS, SYSTEM_SECRET_OWNER, ScopedLogger, ScopedTokenManager, SettingsReadUnavailableError, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemBackupService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, TlsTcpTransporter, ToastService, UDS_NO_ROUTE_PREFIX, UNCLAIMED, UPLOADED_CA_FILE, USER_MANAGEMENT_INTERNAL, UdsLocalTransportClient, UdsLocalTransportServer, UnlockTicketJtiStore, UserManager, WinstonDestination, WinstonLoggingAddon, ZERO_LOOP_DELAY, __resetCapUsageRegistryForTests, __resetLoggingGateForTests, adaptBrokerToCluster, addonSettingsCapability, adoptModelRevisions, afterWorkerOnlineAnnounce, allFamiliesListenHost, answerClaimedGetStatus, applyCertificateToListener, applyLanHttp, attachUserManagementInternal, attributeStall, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildNpmChildEnv, buildStorageLocationRegistry, builderMountedCapNames, caFingerprint, caFingerprintCompact, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionLabel, capActionName, capActionSuffix, capBareAction, capServiceName, checkClusterSecret, classifyAddonDir, classifyCapRoute, clearHttpsListener, clearPendingRestart, clearPlatformKeychainKey, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, computeHubJoinProof, computeNodeJoinProof, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonPeerBytesFacility, createAddonService, createAgentEventScope, createArrayBufferCensusGate, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCapActionCensus, createCidrMatcher, createCoreCapService, createDeferredHeapWatchSink, createDoorSettingsView, createEventPlaneMeter, createEventPlaneReader, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createInspectorArrayBufferCensus, createKernelHwAccel, createKernelInferenceEngine, createLocalTransport, createLoopDelayMeter, createMeshAccessMiddleware, createMeshCsrPem, createMeshQueueReader, createOutboundQueueGate, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createSocketDirectionCounters, createSocketPlaneMeter, createSocketPlaneReader, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, decideMeshAutoEnforce, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, describeRss, detectWorkspacePackagesDir, deviceCapResolverLink, deviceOfGetStatus, diffCapActionCensus, diffEventPlane, diffSocketPlane, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, emitHeapDiagnosticReport, encodeFrame, enrollMeshNode, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, exportMeshPrivateKeyPem, fetchJson, findInPath, formatArrayBufferCensus, formatEventPlane, formatHeapSpaces, formatLogLine, formatMeshQueue, formatOutboundQueueVerdict, formatSocketPlane, generateBackupKeyPair, generateMeshCa, generateMeshKeyPair, getBrokerEventBus, getBrokerTlsTransporter, getCapUsageRegistry, getFfmpegDownloadUrl, getLoggingGate, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPlatformKeychainKey, getProcessClusterSecretGate, getProcessJwtSigningKeyState, getProcessMeshAuthMode, getProcessMeshAuthStatus, getProcessMeshCaState, getProcessNodeMeshTransport, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getUserManagementInternal, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, heapSpaceField, hostNodeIdOf, hubMainRssBudget, installManifestNativeDeps, installManifestPythonDeps, installManifestSystemDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcParentLink, isAddonDeploySource, isAllowedAgentDashboardReturnTo, isArrayBufferCensusReport, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isCredentialKeyName, isInfraCapability, isMeshAuthMode, isModelDownloaded, isOwnChildNodeId, isPeerEventPacket, isRemoteForbiddenAction, isRemoteForbiddenOnAgent, isSettingsReadUnavailable, isSourceNewer, isolatedBuiltinPhase, issueMeshLeafForNode, issueMeshLeafFromCsr, leafFingerprintOf, loadMeshCa, loadTlsCert, localEndpointPath, localProviderLink, localSupportedPythonRuntimes, mapSignalsToInferenceHardware, meshErrorType, mintAgentUiUnlockTicket, mintMeshJoinToken, mountNativeCapService, nextRssBudgetState, normalizeIp, overlayGetStatus, parseAgentDashboardOrigins, parseCapAction, parseCidrList, parseMeshAuthMode, parseRangeHeader, parseRssBudgetMb, parseTokenExpiry, parseTokenizedUrl, partitionIsolatedBuiltinIds, prepareBootTls, prepareRestoreArchive, probePlatform, processJoinTokenJtiStore, processJwtSigningKey, processMeshCrl, proxyToUpstream, quarantineAddonResidue, readBackupEncryptionHeader, readCidrSetting, readExtraSans, readHeapSpaces, readLanHttpState, readPendingRestart, readSocketQueues, readTlsAccessStatus, readTlsMode, readinessKey, reclaimIntervalMs, recordSocketFrame, redactLogEntry, redactLogMeta, redactLogText, regenerateCertificate, registerEventBusService, registerHttpsListener, registerLanHttpHandler, reissueTlsLeaf, reloadHttpsListener, requestProcessMeshEnforcement, requireProcessMeshCa, resolveFilePath, resolveFormatRevision, resolveHwAccel, resolveNpmInvocation, revertToGeneratedCertificate, revisionWeightUrl, runHubAddonBoot, runNpm, sampleSocketDirection, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, selectReportedSpaces, serializeTypedArrays, servedHttpsLeafFingerprint, setHubConnected, setNodeEventInterest, setPlatformKeychainKey, setProcessClusterSecretGate, setProcessMeshAuthMode, setProcessMeshAuthStatusSource, setProcessMeshEnforcer, setProcessMeshPeerTransportLookup, setProcessMeshTlsEnabler, setWrapperActive, shouldReclaim, signalAllRunnerGroups, socketDirectionBytes, socketDirectionMessages, splitPemCertificates, stampCallerAddonId, startEventLoopStallMonitor, startHeapWatch, startRunnerHeapWatch, staticJwtSigningKey, storeMayAnswer, storeUploadedCertificate, strandedMb, stripCamstackDeps, stripForgedIdentity, stripForwardedCaller, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, verifyAgentUiUnlockTicket, verifyMeshJoinToken, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
@@ -1,4 +1,4 @@
1
- const require_dist = require("./dist-DLHPmdoV.js");
1
+ const require_dist = require("./dist-Df7s77se.js");
2
2
  let node_crypto = require("node:crypto");
3
3
  //#region src/auth/jwt-signing-key.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { xr as buildSecretRef } from "./dist-C0wYvAHC.mjs";
1
+ import { xr as buildSecretRef } from "./dist-0OD9ue39.mjs";
2
2
  import { randomBytes } from "node:crypto";
3
3
  //#region src/auth/jwt-signing-key.ts
4
4
  /**
@@ -39,7 +39,7 @@ export { buildStorageLocationRegistry } from "./storage-location-registry.js";
39
39
  export type { StorageLocationRegistry } from "./storage-location-registry.js";
40
40
  export { createBroker, deriveAgentListenPort, getBrokerTlsTransporter } from "./moleculer/broker-factory.js";
41
41
  export type { BrokerConfig } from "./moleculer/broker-factory.js";
42
- export { caFingerprint, caFingerprintCompact, createMeshCsrPem, enrollMeshNode, exportMeshPrivateKeyPem, getProcessNodeMeshTransport, setProcessMeshPeerTransportLookup, generateMeshCa, generateMeshKeyPair, getProcessMeshCaState, issueMeshLeafForNode, issueMeshLeafFromCsr, JoinTokenJtiStore, loadMeshCa, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MeshCaKeeper, MeshCrl, mintMeshJoinToken, processMeshCrl, processJoinTokenJtiStore, requireProcessMeshCa, setProcessMeshTlsEnabler, TlsTcpTransporter, verifyMeshJoinToken, DEFAULT_HUB_TLS_TCP_PORT } from "./moleculer/mesh-mtls/index.js";
42
+ export { caFingerprint, caFingerprintCompact, createMeshCsrPem, enrollMeshNode, exportMeshPrivateKeyPem, getProcessNodeMeshTransport, setProcessMeshPeerTransportLookup, generateMeshCa, generateMeshKeyPair, getProcessMeshCaState, issueMeshLeafForNode, issueMeshLeafFromCsr, JoinTokenJtiStore, loadMeshCa, MESH_CA_FIELD, MESH_CA_KEY_REF, MESH_CA_SETTINGS_KEY, MeshCaKeeper, MeshCrl, mintMeshJoinToken, processMeshCrl, processJoinTokenJtiStore, requireProcessMeshCa, setProcessMeshTlsEnabler, TlsTcpTransporter, verifyMeshJoinToken, DEFAULT_HUB_TLS_TCP_PORT, MESH_TLS_PORT_HELLO_FIELD } from "./moleculer/mesh-mtls/index.js";
43
43
  export type { MeshCaSigner, MeshEnrollResult, MeshPeerTransportLookup, MeshTransport, MeshJoinTokenClaims, MeshTlsMaterial } from "./moleculer/mesh-mtls/index.js";
44
44
  export { type AddonDeploySource, isAddonDeploySource } from "./moleculer/addon-deploy-source.js";
45
45
  export { createAddonService, validateProviderRegistrations } from "./moleculer/addon-service-factory.js";
@@ -62,6 +62,10 @@ export { createMeshAccessMiddleware, stripForgedIdentity } from "./moleculer/mes
62
62
  export type { MeshAccessMiddlewareOptions, MeshCallGate } from "./moleculer/mesh-access-middleware.js";
63
63
  export { AgentMeshAuthenticator, AGENT_REGISTER_NODE_ACTION, isOwnChildNodeId, isRemoteForbiddenOnAgent } from "./moleculer/agent-mesh-authenticator.js";
64
64
  export type { AgentMeshAuthenticatorDeps } from "./moleculer/agent-mesh-authenticator.js";
65
+ export { DEFAULT_MESH_JOIN_MAX_HELD, DEFAULT_MESH_JOIN_MAX_HOLD_MS, MeshJoinHold } from "./moleculer/mesh-join-hold.js";
66
+ export type { MeshGateVerdict, MeshHeldKind, MeshHeldVerdict, MeshJoinHoldOptions, MeshJoinHoldReport } from "./moleculer/mesh-join-hold.js";
67
+ export { createAgentEventScope, isPeerEventPacket } from "./moleculer/agent-event-scope.js";
68
+ export type { AgentEventScope, AgentEventScopeOptions, AgentEventScopeStats, OutboundPacket, TransitPublish } from "./moleculer/agent-event-scope.js";
65
69
  export { MeshJoinClient } from "./moleculer/mesh-join-client.js";
66
70
  export type { MeshJoinCall, MeshJoinClientOptions, MeshJoinState } from "./moleculer/mesh-join-client.js";
67
71
  export { computeHubJoinProof, computeNodeJoinProof, meshErrorType, MESH_ACTION_FORBIDDEN_TYPE, MESH_JOIN_AUTHENTICATE_ACTION, MESH_JOIN_CHALLENGE_ACTION, MESH_JOIN_CHALLENGE_INVALID_TYPE, MESH_JOIN_PROTOCOL, MESH_NODE_UNAUTHENTICATED_TYPE } from "./moleculer/mesh-join-proof.js";
@@ -0,0 +1,49 @@
1
+ /**
2
+ * An agent's events go to the hub, and to no other node (D848).
3
+ *
4
+ * `getBrokerEventBus(...).emit` broadcasts `camstack.evt.<cat>` to every node
5
+ * whose `$event-bus` subscribes to it — and every node's does
6
+ * (`camstack.evt.**`). On an agent that meant every telemetry event
7
+ * (`pipeline.inference-result`, `pipeline.trace`, `motion.*`: ~3,000/min per
8
+ * agent on the 2026-10-13 cluster) was also written to every PEER agent, in
9
+ * clear text, where the peer's inbound gate (`AgentMeshAuthenticator`, D802)
10
+ * refused it by design: only the hub may send an agent anything. The bytes
11
+ * were paid for nothing.
12
+ *
13
+ * This middleware stops them at the source: an EVENT packet an agent
14
+ * publishes to any node other than the hub is not written. Nothing a peer
15
+ * agent receives changes — it refused every such packet already — and the
16
+ * hub, the only consumer, still gets every event. A packet to the agent's own
17
+ * node id never reaches the transport (Moleculer delivers it in-process).
18
+ *
19
+ * Counted, never silent: {@link AgentEventScope.stats} reports what was held
20
+ * back per peer, and the first event withheld from each peer is logged.
21
+ */
22
+ import type { Middleware } from "moleculer";
23
+ /** The part of a Moleculer `Packet` this gate reads. */
24
+ export interface OutboundPacket {
25
+ readonly type: string;
26
+ readonly target: string | null;
27
+ }
28
+ /** `Transit.publish` — what a `transitPublish` hook wraps. */
29
+ export type TransitPublish = (packet: OutboundPacket) => Promise<unknown>;
30
+ export interface AgentEventScopeOptions {
31
+ /** The only node an agent's events are written to. */
32
+ readonly hubNodeId: string;
33
+ /** Told once per peer, the first time an event to it is withheld. */
34
+ readonly log?: (message: string) => void;
35
+ }
36
+ export interface AgentEventScopeStats {
37
+ /** EVENT packets written to the hub. */
38
+ readonly toHub: number;
39
+ /** EVENT packets withheld, per peer node id. */
40
+ readonly withheld: Readonly<Record<string, number>>;
41
+ }
42
+ export interface AgentEventScope {
43
+ /** Pass to `createBroker({ middlewares })` on every agent broker. */
44
+ readonly middleware: Middleware;
45
+ stats(): AgentEventScopeStats;
46
+ }
47
+ /** Is this an event packet addressed to a node other than the hub? */
48
+ export declare function isPeerEventPacket(packet: OutboundPacket, hubNodeId: string): boolean;
49
+ export declare function createAgentEventScope(opts: AgentEventScopeOptions): AgentEventScope;
@@ -17,6 +17,10 @@
17
17
  * cluster secret, `transition` when it does not — so an upgrading agent
18
18
  * without a secret still serves the hub.
19
19
  *
20
+ * The hub's requests that arrive while a join is in flight are HELD, not
21
+ * refused (D848 §3, {@link MeshJoinHold}): delivered when the join proves the
22
+ * hub, refused and reported when it fails or the bound runs out.
23
+ *
20
24
  * Unlike the hub gate, `$process.*` is allowed from an authenticated hub:
21
25
  * the hub polls `$process.list` on agents. `$node.*` stays forbidden from
22
26
  * every remote peer. Forged `caller` / `callerAddonId` are stripped by the
@@ -26,8 +30,8 @@
26
30
  * (`docs/design/2026-10-09-mesh-mtls-plan.md`) — same residual as the hub.
27
31
  */
28
32
  import type { MeshAuthMode, MeshNodeAuthState } from "./mesh-auth-mode.js";
29
- import type { MeshCallVerdict } from "./mesh-authenticator.js";
30
33
  import type { MeshJoinState } from "./mesh-join-client.js";
34
+ import { type MeshGateVerdict, type MeshJoinHoldReport } from "./mesh-join-hold.js";
31
35
  /** The child's register action on its parent agent. */
32
36
  export declare const AGENT_REGISTER_NODE_ACTION = "$agent.registerNode";
33
37
  export declare function isRemoteForbiddenOnAgent(action: string): boolean;
@@ -40,13 +44,21 @@ export interface AgentMeshAuthenticatorDeps {
40
44
  readonly now?: () => number;
41
45
  /** First time a peer is tolerated without proof on this connection. */
42
46
  readonly onTolerated?: (nodeId: string, action: string) => void;
47
+ /** Every decision about the hub's requests held before the join settled. */
48
+ readonly onHoldReport?: (report: MeshJoinHoldReport) => void;
49
+ /** Bounds of that hold (defaults: 1000 items, 15 s). */
50
+ readonly maxHeld?: number;
51
+ readonly maxHoldMs?: number;
43
52
  }
44
53
  export declare class AgentMeshAuthenticator {
45
54
  private readonly deps;
46
55
  private readonly nodes;
47
56
  private readonly hubNodeId;
48
57
  private readonly now;
58
+ private readonly hold;
49
59
  constructor(deps: AgentMeshAuthenticatorDeps);
60
+ /** How many of the hub's requests wait for the join right now. */
61
+ heldCount(): number;
50
62
  /** Current mode: secret configured → enforce; else tolerate (upgrade path). */
51
63
  mode(): MeshAuthMode;
52
64
  /**
@@ -59,8 +71,8 @@ export declare class AgentMeshAuthenticator {
59
71
  noteChildRegistered(sender: string, proof?: "authenticated" | "legacy"): void;
60
72
  /** The peer's connection dropped. */
61
73
  forget(nodeId: string): void;
62
- admitCall(sender: string, action: string): MeshCallVerdict;
63
- admitEvent(sender: string, eventName: string): MeshCallVerdict;
74
+ admitCall(sender: string, action: string): MeshGateVerdict;
75
+ admitEvent(sender: string, eventName: string): MeshGateVerdict;
64
76
  stateOf(nodeId: string): MeshNodeAuthState;
65
77
  authenticatedNodeIds(): readonly string[];
66
78
  private admitSender;
@@ -25,6 +25,12 @@ interface BrokerConfig {
25
25
  */
26
26
  readonly agentListenPort?: number;
27
27
  /**
28
+ * Port an ENROLLED agent listens on for the hub's mutual-TLS dial (default
29
+ * 6443). It is advertised to the hub in every gossip HELLO, so two
30
+ * nodes on one host (a dev or test cluster) need not collide on 6443.
31
+ */
32
+ readonly agentTlsListenPort?: number;
33
+ /**
28
34
  * Broker middlewares (D802): the hub passes its mesh gate
29
35
  * (`createMeshAccessMiddleware`); an agent passes inbound access
30
36
  * (`AgentMeshAuthenticator` + the same middleware) and its outbound join
@@ -14,11 +14,15 @@
14
14
  * Calls a node makes to itself (`ctx.nodeID` = own) pass untouched.
15
15
  */
16
16
  import { type Middleware } from "moleculer";
17
- import type { MeshCallVerdict } from "./mesh-authenticator.js";
18
- /** Minimal surface the middleware needs — hub and agent authenticators both fit. */
17
+ import type { MeshGateVerdict } from "./mesh-join-hold.js";
18
+ /**
19
+ * Minimal surface the middleware needs — hub and agent authenticators both fit.
20
+ * Only the agent's ever answers `hold` (its hub's requests before the join
21
+ * settles, D848): the request waits for that verdict, then runs or is refused.
22
+ */
19
23
  export interface MeshCallGate {
20
- admitCall(sender: string, action: string): MeshCallVerdict;
21
- admitEvent(sender: string, eventName: string): MeshCallVerdict;
24
+ admitCall(sender: string, action: string): MeshGateVerdict;
25
+ admitEvent(sender: string, eventName: string): MeshGateVerdict;
22
26
  }
23
27
  /**
24
28
  * The params of a request from another node, with every identity it claimed
@@ -0,0 +1,85 @@
1
+ /**
2
+ * What an agent does with the hub's events and calls that arrive BEFORE its
3
+ * mesh join has settled (D848 §3).
4
+ *
5
+ * The agent's inbound gate admits the hub only once the mutual join has
6
+ * proven it (`AgentMeshAuthenticator`, D802). The hub, though, starts sending
7
+ * the moment it sees the agent's connection — a one-shot event broadcast at
8
+ * that instant reached a gate that had not yet heard the join's answer, and
9
+ * was refused: dropped, with only a rate-limited "mesh event refused" line.
10
+ * An ordering fix on the hub cannot close it: the agent verifies the hub's
11
+ * proof asynchronously, after the answer that carries it, so even an event
12
+ * the hub sends strictly after its answer can be decoded first.
13
+ *
14
+ * So the agent HOLDS what the hub sends while a join is in flight, and
15
+ * decides when the join decides:
16
+ * - the join proves the hub → everything held is delivered, in arrival order;
17
+ * - the join fails (mismatch, unverified hub, no answer) → everything held is
18
+ * refused, and said so with the count;
19
+ * - the bound runs out first ({@link MeshJoinHoldOptions.maxHoldMs} since the
20
+ * first item was held) → refused and said so, and nothing more is held until
21
+ * the next join starts;
22
+ * - more than {@link MeshJoinHoldOptions.maxHeld} items → the excess is refused
23
+ * on arrival and counted into the next report.
24
+ *
25
+ * The timer is the bound itself, never a wait for a node (D3): delivery is
26
+ * driven by the join settling. Nothing held is ever dropped without a report
27
+ * (D49).
28
+ */
29
+ import type { MeshCallVerdict } from "./mesh-authenticator.js";
30
+ /** The gate cannot answer yet: the request waits for the join. */
31
+ export interface MeshHeldVerdict {
32
+ readonly verdict: "hold";
33
+ readonly settled: Promise<MeshCallVerdict>;
34
+ }
35
+ /** Every verdict a mesh gate may give (`MeshCallGate`). */
36
+ export type MeshGateVerdict = MeshCallVerdict | MeshHeldVerdict;
37
+ export type MeshHeldKind = "call" | "event";
38
+ export interface MeshJoinHoldReport {
39
+ /** `delivered` when the join proved the hub, else `refused`. */
40
+ readonly outcome: "delivered" | "refused";
41
+ /** `authenticated`, the failed join state, or `bound` (time ran out). */
42
+ readonly reason: string;
43
+ readonly events: number;
44
+ readonly calls: number;
45
+ /** Refused on arrival because the hold was full. */
46
+ readonly overflow: number;
47
+ /** From the first held item to the decision. */
48
+ readonly heldForMs: number;
49
+ }
50
+ export interface MeshJoinHoldOptions {
51
+ readonly hubNodeId: string;
52
+ /** Most items held at once (default 1000). */
53
+ readonly maxHeld?: number;
54
+ /** Longest an item is held, from the first one (default 15 s). */
55
+ readonly maxHoldMs?: number;
56
+ readonly now?: () => number;
57
+ readonly onReport?: (report: MeshJoinHoldReport) => void;
58
+ }
59
+ export declare const DEFAULT_MESH_JOIN_MAX_HELD = 1e3;
60
+ export declare const DEFAULT_MESH_JOIN_MAX_HOLD_MS = 15e3;
61
+ export declare class MeshJoinHold {
62
+ private readonly opts;
63
+ private waiters;
64
+ private firstHeldAt;
65
+ private overflow;
66
+ private timer;
67
+ /** Holding is open while a join is in flight; closed after a decision or the bound. */
68
+ private open;
69
+ private readonly now;
70
+ constructor(opts: MeshJoinHoldOptions);
71
+ /** Whether a request arriving now would be held (a join is in flight). */
72
+ get holding(): boolean;
73
+ /** How many requests wait right now. */
74
+ get size(): number;
75
+ /** A join started: hold again. */
76
+ reopen(): void;
77
+ /** Hold one request; `null` when holding is closed (the caller refuses it). */
78
+ hold(kind: MeshHeldKind): MeshHeldVerdict | null;
79
+ /** The join proved the hub: deliver everything held, in order. */
80
+ release(): void;
81
+ /** The join failed, or the bound ran out: refuse everything held. */
82
+ refuse(reason: string): void;
83
+ private refusal;
84
+ private settle;
85
+ }
@@ -7,4 +7,4 @@ export { enrollMeshNode } from "./mesh-enroll.js";
7
7
  export type { EnrollMeshNodeDeps, MeshEnrollRequest, MeshEnrollResult } from "./mesh-enroll.js";
8
8
  export { JoinTokenJtiStore, mintMeshJoinToken, processJoinTokenJtiStore, verifyMeshJoinToken, type MeshJoinTokenClaims, type MintJoinTokenInput } from "./mesh-join-token.js";
9
9
  export { getProcessMeshTlsEnabler, requestProcessMeshTlsEnable, setProcessMeshTlsEnabler, type MeshTlsEnabler } from "./mesh-tls-enabler.js";
10
- export { TlsTcpTransporter, type MeshTlsMaterial, type TlsTcpTransporterOptions } from "./tls-tcp-transporter.js";
10
+ export { helloMeshTlsPort, keepOnlyGossipNodes, MESH_TLS_PORT_HELLO_FIELD, TlsTcpTransporter, type FilteredGossip, type MeshTlsMaterial, type TlsTcpTransporterOptions } from "./tls-tcp-transporter.js";