@sdux-vault/engine 0.13.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,13 @@
1
- import { registerVersion, vaultDebug, ControllerVotes, ControllerMessageTypes, OperationTypes, vaultWarn, VaultController, defineControllerKey, ControllerTypes, DevMode, DecisionOutcomeTypes, vaultError, defineBehaviorKey, DEVTOOLS_LOGGING_KEY_CONSTANT, DEVTOOLS_AGGREGATE_KEY_CONSTANT, createVaultError, EventTypes, EventBoundaryTypes, setVaultLogLevel, isTestEnv, BEHAVIOR_META, validateBehaviorKey, BehaviorTypes, VAULT_STOP, isVaultNoop, VaultLicenseError, VaultBehavior, VaultPrivateErrorService, isHttpResourceRef, isFunction, isStateInputShape, isolateValue, isVaultClearState, VAULT_CLEAR_STATE, VAULT_NOOP, VAULT_CONTINUE, isVaultContinue, isUndefined, isDefined, isNullish, ResolveTypes, isPromise, VaultUsagePromiseError, CONTROLLER_META, validateControllerKey } from '@sdux-vault/shared';
1
+ import { registerVersion, vaultDebug, ControllerVotes, ControllerMessageTypes, OperationTypes, vaultWarn, VaultController, defineControllerKey, ControllerTypes, DevMode, DecisionOutcomeTypes, vaultError, defineBehaviorKey, DEVTOOLS_LOGGING_KEY_CONSTANT, DEVTOOLS_AGGREGATE_KEY_CONSTANT, createVaultError, EventTypes, EventBoundaryTypes, setVaultLogLevel, isTestEnv, BEHAVIOR_META, BehaviorTypes, validateBehaviorKey, VAULT_STOP, isVaultNoop, VaultLicenseError, VaultBehavior, VaultPrivateErrorService, isHttpResourceRef, isFunction, isStateInputShape, isolateValue, isVaultClearState, VAULT_CLEAR_STATE, VAULT_NOOP, VAULT_CONTINUE, isVaultContinue, isUndefined, isDefined, isNullish, ResolveTypes, isPromise, VaultUsagePromiseError, CONTROLLER_META, validateControllerKey } from '@sdux-vault/shared';
2
2
  import { of, map, catchError, forkJoin, Subject, ReplaySubject, isObservable, firstValueFrom, tap } from 'rxjs';
3
3
  import { __decorate } from 'tslib';
4
4
  import { filter } from 'rxjs/operators';
5
5
  import { EventBus, initDevtoolsWidget } from '@sdux-vault/devtools';
6
6
 
7
- // --- AI Model File Path (DO NOT DELETE) ---
8
- // FilePath: projects > engine > src > lib > utils > version > version.register.ts
9
- // Updated: 2026-03-03 08:09
10
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
11
- // cmd+alt+j (see .vscode/keybindings.json)
12
- // --- END AI MODEL FILE PATH ---
7
+ /** Package name used for version registration. */
13
8
  const SDUX_PACKAGE = '@sdux-vault/engine';
14
- const SDUX_VERSION = '0.13.0';
9
+ /** Current package version registered with the Vault runtime. */
10
+ const SDUX_VERSION = '0.26.0';
15
11
  registerVersion(SDUX_PACKAGE, SDUX_VERSION);
16
12
 
17
13
  /**
@@ -24,11 +20,6 @@ var withCoreAbstainController_1;
24
20
  * Core abstain controller responsible for participating in controller vote resolution.
25
21
  * This controller observes incoming controller messages and emits a neutral vote without modifying pipeline flow.
26
22
  *
27
- * --RelatedStart--
28
- * ControllerMessageShape
29
- * ControllerVote
30
- * ControllerVotes
31
- * --RelatedEnd--
32
23
  */
33
24
  let withCoreAbstainController = class withCoreAbstainController {
34
25
  static { withCoreAbstainController_1 = this; }
@@ -57,7 +48,9 @@ let withCoreAbstainController = class withCoreAbstainController {
57
48
  * Unique controller key identifying this instance.
58
49
  */
59
50
  key;
51
+ /** Whether the FeatureCell has completed its initial pipeline cycle. */
60
52
  #isInitialized = false;
53
+ /** Whether the initialization pipeline cycle failed. */
61
54
  #initializationFailed = false;
62
55
  /**
63
56
  * Creates a new core conductor controller instance.
@@ -129,6 +122,11 @@ withCoreAbstainController = withCoreAbstainController_1 = __decorate([
129
122
  ], withCoreAbstainController);
130
123
 
131
124
  var withCoreErrorController_1;
125
+ /**
126
+ * Core error controller responsible for handling failure messages in the
127
+ * controller vote resolution pipeline. This controller requests an abort
128
+ * on failure and abstains from all other message types.
129
+ */
132
130
  let withCoreErrorController = class withCoreErrorController {
133
131
  static { withCoreErrorController_1 = this; }
134
132
  controllerCtx;
@@ -156,6 +154,7 @@ let withCoreErrorController = class withCoreErrorController {
156
154
  * Unique controller key identifying this instance.
157
155
  */
158
156
  key;
157
+ /** Controller class context providing execution metadata. */
159
158
  ctx;
160
159
  /**
161
160
  * Creates a new core conductor controller instance.
@@ -208,6 +207,7 @@ withCoreErrorController = withCoreErrorController_1 = __decorate([
208
207
  })
209
208
  ], withCoreErrorController);
210
209
 
210
+ /** Enumeration of license lifecycle event identifiers. */
211
211
  const LicenseEventTypes = {
212
212
  RequireLicense: 'requireLicense',
213
213
  ValidateLicense: 'validateLicense',
@@ -217,38 +217,79 @@ const LicenseEventTypes = {
217
217
  DescribeControllers: 'describe-controllers'
218
218
  };
219
219
 
220
+ /** Cached singleton instance of the licensing service. */
220
221
  //eslint-disable-next-line
221
222
  let singleton = null;
223
+ /**
224
+ * Initializes the global licensing service singleton.
225
+ *
226
+ * @param events$ - Subject used to emit licensing events.
227
+ * @param validation$ - Observable providing license validation results.
228
+ */
222
229
  function InitializeLicensingService(events$, validation$) {
223
230
  if (singleton)
224
231
  return;
225
232
  singleton = new LicensingServiceInstance(events$, validation$);
226
233
  }
234
+ /**
235
+ * Returns the global licensing service singleton.
236
+ *
237
+ * @returns The initialized licensing service contract.
238
+ */
227
239
  function LicensingService() {
228
240
  if (!singleton) {
229
241
  throw new Error('[vault] LicensingService not initialized.');
230
242
  }
231
243
  return singleton;
232
244
  }
245
+ /** Internal implementation of the licensing service contract. */
233
246
  class LicensingServiceInstance {
234
247
  events$;
235
248
  validation$;
249
+ /**
250
+ * Creates a new licensing service backed by the supplied event streams.
251
+ *
252
+ * @param events$ - Subject used to emit licensing events.
253
+ * @param validation$ - Observable providing license validation results.
254
+ */
236
255
  constructor(events$, validation$) {
237
256
  this.events$ = events$;
238
257
  this.validation$ = validation$;
239
258
  }
259
+ /**
260
+ * Emits a feature description event for licensing inspection.
261
+ *
262
+ * @param event - Feature description event to emit.
263
+ */
240
264
  describeFeature(event) {
241
265
  event.type = LicenseEventTypes.DescribeFeature;
242
266
  this.events$.next(event);
243
267
  }
268
+ /**
269
+ * Emits a behavior description event for licensing inspection.
270
+ *
271
+ * @param event - Behavior description event to emit.
272
+ */
244
273
  describeBehaviors(event) {
245
274
  event.type = LicenseEventTypes.DescribeBehaviors;
246
275
  this.events$.next(event);
247
276
  }
277
+ /**
278
+ * Emits a controller description event for licensing inspection.
279
+ *
280
+ * @param event - Controller description event to emit.
281
+ */
248
282
  describeControllers(event) {
249
283
  event.type = LicenseEventTypes.DescribeControllers;
250
284
  this.events$.next(event);
251
285
  }
286
+ /**
287
+ * Requests a license token for a behavior or controller.
288
+ *
289
+ * @param featureCellKey - Key of the FeatureCell requesting the license.
290
+ * @param key - Key of the behavior or controller requiring a license.
291
+ * @returns The generated license token.
292
+ */
252
293
  requestLicense(featureCellKey, key) {
253
294
  if (!key) {
254
295
  throw new Error('[vault] Cannot register controller license without a key.');
@@ -262,6 +303,14 @@ class LicensingServiceInstance {
262
303
  });
263
304
  return licenseToken;
264
305
  }
306
+ /**
307
+ * Validates a previously requested license token.
308
+ *
309
+ * @param featureCellKey - Key of the FeatureCell owning the license.
310
+ * @param key - Key of the behavior or controller being validated.
311
+ * @param licenseToken - License token to validate.
312
+ * @param valid - Whether the license is approved.
313
+ */
265
314
  validateLicense(featureCellKey, key, licenseToken, valid) {
266
315
  this.events$.next({
267
316
  featureCellKey,
@@ -271,15 +320,22 @@ class LicensingServiceInstance {
271
320
  valid
272
321
  });
273
322
  }
323
+ /** Generates a random alphanumeric license token. */
274
324
  #generateLicenseToken() {
275
325
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
276
326
  const randomPart = (length) => Array.from({ length }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
277
327
  return `${randomPart(5)}-${randomPart(5)}`;
278
328
  }
329
+ /**
330
+ * Returns an observable of license validation results.
331
+ *
332
+ * @returns Observable emitting validation outcomes.
333
+ */
279
334
  getLicenseValidation$() {
280
335
  return this.validation$;
281
336
  }
282
337
  }
338
+ /** Resets the licensing service singleton for test isolation. */
283
339
  const resetLicensingServiceForTests = () => {
284
340
  if (!DevMode.active)
285
341
  return;
@@ -287,17 +343,37 @@ const resetLicensingServiceForTests = () => {
287
343
  };
288
344
 
289
345
  var withCoreLicenseController_1;
346
+ /**
347
+ * Core license controller that gates pipeline execution based on the
348
+ * licensing service validation result. The controller subscribes to
349
+ * the license validation stream on construction and votes Deny until
350
+ * a license decision arrives, Abstain on approval, or Abort on denial.
351
+ */
290
352
  let withCoreLicenseController = class withCoreLicenseController {
291
353
  static { withCoreLicenseController_1 = this; }
292
354
  controllerCtx;
355
+ /** Static controller type assigned by the VaultController decorator. */
293
356
  static type;
357
+ /** Static controller key assigned by the VaultController decorator. */
294
358
  static key;
359
+ /** Static critical flag assigned by the VaultController decorator. */
295
360
  static critical;
361
+ /** Instance controller type mirrored from the static declaration. */
296
362
  type = withCoreLicenseController_1.type;
363
+ /** Instance critical flag mirrored from the static declaration. */
297
364
  critical = withCoreLicenseController_1.critical;
365
+ /** Unique key identifying this controller instance. */
298
366
  key;
367
+ /** Resolved license approval state: true, false, or null if pending. */
299
368
  #licenseApproved = null;
369
+ /** Subscription to the licensing validation stream. */
300
370
  #sub;
371
+ /**
372
+ * Subscribes to the licensing validation stream and signals approval or denial.
373
+ *
374
+ * @param key - Unique key for this controller instance.
375
+ * @param controllerCtx - Controller class context providing lifecycle hooks.
376
+ */
301
377
  constructor(key, controllerCtx) {
302
378
  this.controllerCtx = controllerCtx;
303
379
  this.key = key;
@@ -317,6 +393,12 @@ let withCoreLicenseController = class withCoreLicenseController {
317
393
  }
318
394
  });
319
395
  }
396
+ /**
397
+ * Evaluates a controller message and returns a license-based vote.
398
+ *
399
+ * @param msg - The incoming controller message.
400
+ * @returns An observable emitting the controller vote.
401
+ */
320
402
  handleMessage(msg) {
321
403
  vaultDebug(`${this.key} received "${msg.type}" for trace "${msg.traceId}".`);
322
404
  switch (msg.type) {
@@ -334,10 +416,12 @@ let withCoreLicenseController = class withCoreLicenseController {
334
416
  return of();
335
417
  }
336
418
  }
419
+ /** Unsubscribes from the licensing validation stream. */
337
420
  destroy() {
338
421
  this.#sub?.unsubscribe();
339
422
  vaultWarn(`${this.key} - destroy unsubscribe`);
340
423
  }
424
+ /** No-op reset handler for this controller. */
341
425
  reset() {
342
426
  vaultWarn(`${this.key} - reset noop`);
343
427
  }
@@ -437,28 +521,21 @@ class Arbitrator {
437
521
  }
438
522
  }
439
523
 
440
- // --- AI Model File Path ---
441
- // projects > engine > src > lib > types > monitor > vault-monitor-event-category.type.ts
524
+ /** Enumeration of monitor event category classifications. */
442
525
  const VaultMonitorEventCategoryType = {
443
526
  Boundary: 'boundary',
444
527
  State: 'state',
445
528
  Error: 'error'
446
529
  };
447
530
 
448
- // --- AI Model File Path ---
449
- // projects > engine > src > lib > types > monitor > vault-monitor-field-rule.type.ts
531
+ /** Enumeration of field emission rules for monitor event policies. */
450
532
  const FieldRuleTypes = {
451
533
  Never: 'never',
452
534
  Optional: 'optional',
453
535
  Required: 'required'
454
536
  };
455
537
 
456
- // --- AI Model File Path (DO NOT DELETE) ---
457
- // FilePath: projects > engine > src > lib > monitor > event-policy > vault-monitor-category-field-policy.constant.ts
458
- // Updated: 2026-03-06 16:29
459
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
460
- // cmd+alt+j (see .vscode/keybindings.json)
461
- // --- END AI MODEL FILE PATH ---
538
+ /** Field emission rules indexed by monitor event category. */
462
539
  const CATEGORY_FIELD_POLICY_CONSTANT = {
463
540
  [VaultMonitorEventCategoryType.Boundary]: {
464
541
  state: FieldRuleTypes.Never,
@@ -477,12 +554,7 @@ const CATEGORY_FIELD_POLICY_CONSTANT = {
477
554
  }
478
555
  };
479
556
 
480
- // --- AI Model File Path (DO NOT DELETE) ---
481
- // FilePath: projects > engine > src > lib > monitor > event-policy > vault-monitor-event-policy.constant.ts
482
- // Updated: 2026-03-06 16:30
483
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
484
- // cmd+alt+j (see .vscode/keybindings.json)
485
- // --- END AI MODEL FILE PATH ---
557
+ /** Maps normalized event names to their monitor event category classification. */
486
558
  const EVENT_POLICY_CONSTANT = {
487
559
  // ─────────────────────────────────────────────
488
560
  // STATE
@@ -564,11 +636,6 @@ const EVENT_POLICY_CONSTANT = {
564
636
  let instance$2 = null;
565
637
  /**
566
638
  * Returns the global VaultMonitorSharedState singleton instance.
567
- * This function ensures a single shared state instance is created and reused across the runtime.
568
- *
569
- * --RelatedStart--
570
- * VaultMonitorSharedStateInstance
571
- * --RelatedEnd--
572
639
  *
573
640
  * @returns The global VaultMonitorSharedState instance.
574
641
  */
@@ -578,6 +645,13 @@ function VaultMonitorSharedState() {
578
645
  }
579
646
  return instance$2;
580
647
  }
648
+ /**
649
+ * Mutable shared state consumed by all VaultMonitor instances.
650
+ *
651
+ * This class holds the global insight override and the per-cell
652
+ * insight registry so that every monitor operates on the same
653
+ * canonical state.
654
+ */
581
655
  class VaultMonitorSharedStateInstance {
582
656
  /**
583
657
  * Optional global insight definition that overrides per-cell insight
@@ -589,18 +663,11 @@ class VaultMonitorSharedStateInstance {
589
663
  * Registry of FeatureCell insight configurations keyed by cell ID.
590
664
  *
591
665
  * Each entry indicates whether insight is enabled and contains the
592
- * resolved list of {@link InsightConfig} values associated with
593
- * that FeatureCell.
666
+ * resolved list of InsightConfig values associated with that FeatureCell.
594
667
  */
595
668
  cellRegistry = new Map();
596
669
  }
597
670
 
598
- // --- AI Model File Path (DO NOT DELETE) ---
599
- // FilePath: projects > engine > src > lib > monitor > vault-monitor.helper.ts
600
- // Updated: 2026-03-06 16:27
601
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
602
- // cmd+alt+j (see .vscode/keybindings.json)
603
- // --- END AI MODEL FILE PATH ---
604
671
  /**
605
672
  * Abstract helper base class used by both `VaultMonitor` and
606
673
  * `VaultQueueMonitor`.
@@ -679,9 +746,22 @@ class VaultMonitorHelper {
679
746
  activateGlobalInsights(definition) {
680
747
  this.globalInsightOverride = definition;
681
748
  }
749
+ /**
750
+ * Determines whether the given cell key belongs to a Chrome DevTools channel.
751
+ *
752
+ * @param cell - The FeatureCell key to check.
753
+ * @returns True when the cell is a DevTools-internal channel.
754
+ */
682
755
  isChromeDevTools(cell) {
683
756
  return cell === DEVTOOLS_LOGGING_KEY_CONSTANT || cell === DEVTOOLS_AGGREGATE_KEY_CONSTANT;
684
757
  }
758
+ /**
759
+ * Applies field-level emission policy to a pipeline event.
760
+ *
761
+ * @param event - The raw event to filter.
762
+ * @param insight - Optional insight configuration controlling field visibility.
763
+ * @returns The policy-filtered event.
764
+ */
685
765
  applyPolicy(event, insight) {
686
766
  const category = EVENT_POLICY_CONSTANT[event.name]?.category ?? VaultMonitorEventCategoryType.Boundary;
687
767
  const policy = CATEGORY_FIELD_POLICY_CONSTANT[category];
@@ -715,12 +795,6 @@ class VaultMonitorHelper {
715
795
  }
716
796
  }
717
797
 
718
- // --- AI Model File Path (DO NOT DELETE) ---
719
- // FilePath: projects > engine > src > lib > monitor > vault-monitor.service.ts
720
- // Updated: 2026-03-03 09:10
721
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
722
- // cmd+alt+j (see .vscode/keybindings.json)
723
- // --- END AI MODEL FILE PATH ---
724
798
  /**
725
799
  * Holds the singleton VaultMonitor instance.
726
800
  */
@@ -729,9 +803,6 @@ let instance$1 = null;
729
803
  * Returns the global VaultMonitor singleton instance.
730
804
  * This function ensures a single monitor instance is created and reused across the runtime.
731
805
  *
732
- * --RelatedStart--
733
- * VaultMonitorContract
734
- * --RelatedEnd--
735
806
  *
736
807
  * @returns The global VaultMonitor instance.
737
808
  */
@@ -745,9 +816,6 @@ function VaultMonitor() {
745
816
  * Implements the VaultMonitorContract using shared helper functionality.
746
817
  * This class provides the concrete singleton implementation backing the VaultMonitor entry point.
747
818
  *
748
- * --RelatedStart--
749
- * VaultMonitorContract
750
- * --RelatedEnd--
751
819
  */
752
820
  class VaultMonitorInstance extends VaultMonitorHelper {
753
821
  /**
@@ -769,10 +837,7 @@ class VaultMonitorInstance extends VaultMonitorHelper {
769
837
  }
770
838
  /**
771
839
  * Maps a BehaviorContext into a StateSnapshot suitable for DevTools.
772
- * This ensures each pipeline event includes a normalized representation
773
- * of loading, value, error, and hasValue.
774
840
  *
775
- * @typeParam T - State value type.
776
841
  * @param ctx - Immutable behavior context provided by the orchestrator.
777
842
  * @returns A standardized StateSnapshot.
778
843
  */
@@ -1193,50 +1258,60 @@ class VaultMonitorInstance extends VaultMonitorHelper {
1193
1258
  const name = 'warn';
1194
1259
  this.#emitEventV2LifecycleNotification({ cell, behaviorKey, name, ctx, error: errorMessage });
1195
1260
  }
1261
+ /** Prepends event type and boundary to the event name. */
1196
1262
  #buildEventName(eventInput) {
1197
1263
  eventInput.name = `${eventInput.type}:${eventInput.boundary}:${eventInput.name}`;
1198
1264
  return eventInput;
1199
1265
  }
1266
+ /** Emits a stage-start monitoring event. */
1200
1267
  #emitEventV2StageStart(eventInput) {
1201
1268
  eventInput.type = EventTypes.Stage;
1202
1269
  eventInput.boundary = EventBoundaryTypes.Start;
1203
1270
  this.#emitEventV2(this.#buildEventName(eventInput));
1204
1271
  }
1272
+ /** Emits a stage-end monitoring event. */
1205
1273
  #emitEventV2StageEnd(eventInput) {
1206
1274
  eventInput.type = EventTypes.Stage;
1207
1275
  eventInput.boundary = EventBoundaryTypes.End;
1208
1276
  this.#emitEventV2(this.#buildEventName(eventInput));
1209
1277
  }
1278
+ /** Emits a lifecycle-start monitoring event. */
1210
1279
  #emitEventV2LifecycleStart(eventInput) {
1211
1280
  eventInput.type = EventTypes.Lifecycle;
1212
1281
  eventInput.boundary = EventBoundaryTypes.Start;
1213
1282
  this.#emitEventV2(this.#buildEventName(eventInput));
1214
1283
  }
1284
+ /** Emits a lifecycle-end monitoring event. */
1215
1285
  #emitEventV2LifecycleEnd(eventInput) {
1216
1286
  eventInput.type = EventTypes.Lifecycle;
1217
1287
  eventInput.boundary = EventBoundaryTypes.End;
1218
1288
  this.#emitEventV2(this.#buildEventName(eventInput));
1219
1289
  }
1290
+ /** Emits a lifecycle-notification monitoring event. */
1220
1291
  #emitEventV2LifecycleNotification(eventInput) {
1221
1292
  eventInput.type = EventTypes.Lifecycle;
1222
1293
  eventInput.boundary = EventBoundaryTypes.Notification;
1223
1294
  this.#emitEventV2(this.#buildEventName(eventInput));
1224
1295
  }
1296
+ /** Emits a conductor-notification monitoring event. */
1225
1297
  #emitEventV2ConductorNotification(eventInput) {
1226
1298
  eventInput.type = EventTypes.Conductor;
1227
1299
  eventInput.boundary = EventBoundaryTypes.Notification;
1228
1300
  this.#emitEventV2(this.#buildEventName(eventInput));
1229
1301
  }
1302
+ /** Emits a controller-start monitoring event. */
1230
1303
  #emitEventV2ControllerStart(eventInput) {
1231
1304
  eventInput.type = EventTypes.Controller;
1232
1305
  eventInput.boundary = EventBoundaryTypes.Start;
1233
1306
  this.#emitEventV2(this.#buildEventName(eventInput));
1234
1307
  }
1308
+ /** Emits a controller-end monitoring event. */
1235
1309
  #emitEventV2ControllerEnd(eventInput) {
1236
1310
  eventInput.type = EventTypes.Controller;
1237
1311
  eventInput.boundary = EventBoundaryTypes.End;
1238
1312
  this.#emitEventV2(this.#buildEventName(eventInput));
1239
1313
  }
1314
+ /** Emits a controller-notification monitoring event. */
1240
1315
  #emitEventV2ControllerNotification(eventInput) {
1241
1316
  eventInput.type = EventTypes.Controller;
1242
1317
  eventInput.boundary = EventBoundaryTypes.Notification;
@@ -1327,7 +1402,9 @@ const ControllerEventTypes = {
1327
1402
  class DecisionEngine {
1328
1403
  controllers;
1329
1404
  events$;
1405
+ /** Arbitrator responsible for aggregating controller votes. */
1330
1406
  #arbitrator = new Arbitrator();
1407
+ /** Vault monitor instance used to emit controller lifecycle events. */
1331
1408
  #vaultMonitor = VaultMonitor();
1332
1409
  /**
1333
1410
  * Creates a new decision engine instance.
@@ -1472,12 +1549,7 @@ const PROTECTED_FEATURE_CELL_KEYS = new Set([
1472
1549
  'hydrate'
1473
1550
  ]);
1474
1551
 
1475
- // --- AI Model File Path (DO NOT DELETE) ---
1476
- // FilePath: projects > engine > src > lib > types > vault-registration-license-status.type.ts
1477
- // Updated: 2026-03-03 10:09
1478
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
1479
- // cmd+alt+j (see .vscode/keybindings.json)
1480
- // --- END AI MODEL FILE PATH ---
1552
+ /** Enumeration of FeatureCell registration license validation statuses. */
1481
1553
  const VaultRegistrationLicenseStatusTypes = {
1482
1554
  NotRequired: 'not-required',
1483
1555
  Pending: 'pending',
@@ -1551,6 +1623,10 @@ const KNOWN_VAULT_KEYS = new Set([
1551
1623
  'SDUX::Controller::Policy::CoreError',
1552
1624
  'SDUX::Controller::Policy::CoreLicense',
1553
1625
  // ---------------------------------------------------------------------------
1626
+ // Core Controllers (libs/core)
1627
+ // ---------------------------------------------------------------------------
1628
+ 'SDUX::Controller::Policy::TabSync',
1629
+ // ---------------------------------------------------------------------------
1554
1630
  // Addon Controllers (libs/addons)
1555
1631
  // ---------------------------------------------------------------------------
1556
1632
  'SDUX::Controller::Policy::Delay',
@@ -1568,34 +1644,58 @@ const KNOWN_VAULT_KEYS = new Set([
1568
1644
  */
1569
1645
  const VAULT_LICENSE_ID = 'sdux-vault';
1570
1646
 
1571
- // --- AI Model File Path (DO NOT DELETE) ---
1572
- // FilePath: projects > engine > src > lib > factories > vault > vault-core.function.ts
1573
- // Updated: 2026-03-02 19:52
1574
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
1575
- // cmd+alt+j (see .vscode/keybindings.json)
1576
- // --- END AI MODEL FILE PATH ---
1647
+ /** Behavior key used to identify the core license behavior during validation. */
1577
1648
  const CORE_LICENSE_BEHAVIOR_KEY = 'SDUX::Behavior::Core::License';
1649
+ /** Cached singleton instance of the VaultCore runtime. */
1578
1650
  let instance = null;
1651
+ /**
1652
+ * Initializes the global Vault runtime singleton with the supplied configuration.
1653
+ *
1654
+ * @param config - Optional Vault configuration overriding defaults.
1655
+ */
1579
1656
  function VaultCore(config = {}) {
1580
1657
  if (!instance) {
1581
1658
  instance = new VaultCoreInstance(config);
1582
1659
  }
1583
1660
  }
1661
+ /**
1662
+ * Internal singleton managing Vault configuration, licensing, and the
1663
+ * FeatureCell registry. All mutable state is held in private fields and
1664
+ * exposed only through controlled public methods.
1665
+ */
1584
1666
  class VaultCoreInstance {
1667
+ /** Subscription to the licensing event bus. */
1585
1668
  #licensingSub;
1669
+ /** Subscription to the validation result bus. */
1586
1670
  #validaionSub;
1671
+ /** Map of license IDs to their decoded payloads. */
1587
1672
  #licenseMap = new Map();
1673
+ /** Tracks FeatureCells that have reached a terminal license status. */
1588
1674
  #terminalStatus = new Map();
1675
+ /** Whether AI-assist capabilities have been enabled. */
1589
1676
  #aiAssistEnabled = false;
1677
+ /** Whether licensing checks are bypassed in dev mode. */
1590
1678
  #bypassLicensing = false;
1679
+ /** Timeout duration in milliseconds for pending license evaluations. */
1591
1680
  #licenseTimeoutMs;
1681
+ /** Active timeout handles for pending license evaluations keyed by FeatureCell. */
1592
1682
  // eslint-disable-next-line
1593
1683
  #licenseTimers = new Map();
1684
+ /** Subject emitting licensing events to the licensing service. */
1594
1685
  #licensingBus$ = new Subject();
1686
+ /** ReplaySubject emitting license validation results. */
1595
1687
  #validationBus$ = new ReplaySubject();
1688
+ /** Last published license status per FeatureCell key. */
1596
1689
  #lastStatus = new Map();
1690
+ /** Frozen global Vault configuration. */
1597
1691
  #vaultConfig;
1692
+ /** Registry of FeatureCell registration records keyed by cell key. */
1598
1693
  #registry = new Map();
1694
+ /**
1695
+ * Creates the VaultCore singleton and initializes licensing infrastructure.
1696
+ *
1697
+ * @param config - Raw Vault configuration.
1698
+ */
1599
1699
  constructor(config) {
1600
1700
  InitializeLicensingService(this.#licensingBus$, this.#validationBus$.asObservable());
1601
1701
  this.setVaultConfig(config);
@@ -1630,6 +1730,7 @@ class VaultCoreInstance {
1630
1730
  this.#licenseTimeoutMs = config.licenseTimeoutMs ?? 15_000;
1631
1731
  this.#warnIfAccidentalDevMode();
1632
1732
  }
1733
+ /** Resets all internal state for test isolation. */
1633
1734
  resetForTesting() {
1634
1735
  this.#licensingSub?.unsubscribe();
1635
1736
  this.#licensingSub = undefined;
@@ -1640,40 +1741,87 @@ class VaultCoreInstance {
1640
1741
  this.#lastStatus.clear();
1641
1742
  this.#licenseMap.clear();
1642
1743
  }
1744
+ /** Clears the FeatureCell registration registry. */
1643
1745
  resetFeatureCellRegistry() {
1644
1746
  this.#registry.clear();
1645
1747
  }
1748
+ /**
1749
+ * Registers a FeatureCell key in the runtime registry.
1750
+ *
1751
+ * @param key - Unique FeatureCell identifier.
1752
+ */
1646
1753
  registerCellRuntime(key) {
1647
1754
  this.#ensureRecord(key);
1648
1755
  }
1756
+ /**
1757
+ * Registers behavior entities for a FeatureCell.
1758
+ *
1759
+ * @param key - FeatureCell key.
1760
+ * @param behaviors - Array of behavior entity descriptors.
1761
+ */
1649
1762
  registerBehaviors(key, behaviors) {
1650
1763
  const record = this.#ensureRecord(key);
1651
1764
  record.behaviors = this.#registerEntities(behaviors);
1652
1765
  record.behaviorsRegistered = true;
1653
1766
  }
1767
+ /**
1768
+ * Registers controller entities for a FeatureCell.
1769
+ *
1770
+ * @param key - FeatureCell key.
1771
+ * @param controllers - Array of controller entity descriptors.
1772
+ */
1654
1773
  registerControllers(key, controllers) {
1655
1774
  const record = this.#ensureRecord(key);
1656
1775
  record.controllers = this.#registerEntities(controllers);
1657
1776
  record.controllersRegistered = true;
1658
1777
  }
1778
+ /**
1779
+ * Registers fluent API callback counts for a FeatureCell.
1780
+ *
1781
+ * @param key - FeatureCell key.
1782
+ * @param summary - Object summarizing the count of each fluent API callback type.
1783
+ */
1659
1784
  registerFluentApis(key, summary) {
1660
1785
  const record = this.#ensureRecord(key);
1661
1786
  record.fluentApis = Object.freeze(summary);
1662
1787
  }
1788
+ /**
1789
+ * Retrieves the decoded license payload for a given license ID.
1790
+ *
1791
+ * @param licenseId - License identifier to look up.
1792
+ * @returns The decoded payload, or undefined if not found.
1793
+ */
1663
1794
  getLicensePayload(licenseId) {
1664
1795
  return this.#licenseMap.get(licenseId);
1665
1796
  }
1797
+ /**
1798
+ * Returns whether licensing checks are bypassed.
1799
+ *
1800
+ * @returns True when bypass licensing is active.
1801
+ */
1666
1802
  isBypassLicensing() {
1667
1803
  return this.#bypassLicensing;
1668
1804
  }
1805
+ /**
1806
+ * Checks whether a key belongs to the set of known Vault-internal keys.
1807
+ *
1808
+ * @param key - The key to check.
1809
+ * @returns True when the key is a recognized Vault key.
1810
+ */
1669
1811
  isAuthorizedKey(key) {
1670
1812
  return KNOWN_VAULT_KEYS.has(key);
1671
1813
  }
1814
+ /**
1815
+ * Returns whether a Vault-level license has been registered.
1816
+ *
1817
+ * @returns True when a Vault license exists.
1818
+ */
1672
1819
  hasVaultLicense() {
1673
1820
  return this.#licenseMap.has(VAULT_LICENSE_ID);
1674
1821
  }
1675
1822
  //#endregion
1676
1823
  //#region private Methods
1824
+ /** Populates the license map from the supplied license configurations. */
1677
1825
  #initializeLicenses(licenses) {
1678
1826
  if (!licenses?.length)
1679
1827
  return;
@@ -1683,6 +1831,7 @@ class VaultCoreInstance {
1683
1831
  this.#licenseMap.set(license.licenseId, license.payload);
1684
1832
  }
1685
1833
  }
1834
+ /** Freezes and registers an array of entity descriptors into a keyed map. */
1686
1835
  #registerEntities(entities) {
1687
1836
  return new Map(entities.map((entity) => {
1688
1837
  let needsLicense;
@@ -1704,6 +1853,7 @@ class VaultCoreInstance {
1704
1853
  return [entity.key, Object.freeze(frozen)];
1705
1854
  }));
1706
1855
  }
1856
+ /** Subscribes to the licensing bus and routes events to the appropriate handlers. */
1707
1857
  #subscribeToLicensingEvents() {
1708
1858
  this.#licensingSub = this.#licensingBus$.subscribe((event) => {
1709
1859
  switch (event.type) {
@@ -1737,6 +1887,7 @@ class VaultCoreInstance {
1737
1887
  }
1738
1888
  });
1739
1889
  }
1890
+ /** Starts a timeout timer for pending licenses on a FeatureCell. */
1740
1891
  #startLicenseTimeout(featureCellKey) {
1741
1892
  if (!this.#licenseTimeoutMs)
1742
1893
  return;
@@ -1748,6 +1899,7 @@ class VaultCoreInstance {
1748
1899
  }, this.#licenseTimeoutMs);
1749
1900
  this.#licenseTimers.set(featureCellKey, timer);
1750
1901
  }
1902
+ /** Expires all pending licenses for a FeatureCell and publishes a denial. */
1751
1903
  #expirePendingLicenses(featureCellKey) {
1752
1904
  const record = this.#registry.get(featureCellKey);
1753
1905
  if (!record)
@@ -1771,6 +1923,7 @@ class VaultCoreInstance {
1771
1923
  this.#clearLicenseTimer(featureCellKey);
1772
1924
  }
1773
1925
  // Do not evaluate until both sides registered
1926
+ /** Evaluates and emits the aggregate license status for a FeatureCell. */
1774
1927
  #emitLicenseStatus(featureCellKey) {
1775
1928
  const record = this.#registry.get(featureCellKey);
1776
1929
  if (!record)
@@ -1800,6 +1953,7 @@ class VaultCoreInstance {
1800
1953
  // All valid
1801
1954
  this.#publishStatus(featureCellKey, true);
1802
1955
  }
1956
+ /** Clears the license timeout timer for a FeatureCell. */
1803
1957
  #clearLicenseTimer(featureCellKey) {
1804
1958
  const timer = this.#licenseTimers.get(featureCellKey);
1805
1959
  if (timer) {
@@ -1807,6 +1961,7 @@ class VaultCoreInstance {
1807
1961
  this.#licenseTimers.delete(featureCellKey);
1808
1962
  }
1809
1963
  }
1964
+ /** Publishes a terminal license validation result for a FeatureCell. */
1810
1965
  #publishStatus(featureCellKey, approved) {
1811
1966
  if (this.#terminalStatus.has(featureCellKey))
1812
1967
  return;
@@ -1818,6 +1973,7 @@ class VaultCoreInstance {
1818
1973
  approved
1819
1974
  });
1820
1975
  }
1976
+ /** Routes a license validation event to the appropriate entity maps. */
1821
1977
  #handleLicenseValidation(event) {
1822
1978
  const { featureCellKey, key, licenseToken, valid } = event;
1823
1979
  if (this.#terminalStatus.has(event.featureCellKey))
@@ -1835,6 +1991,7 @@ class VaultCoreInstance {
1835
1991
  this.#enableAiAssist();
1836
1992
  }
1837
1993
  }
1994
+ /** Applies a license validation result to a single entity within a map. */
1838
1995
  #applyLicenseValidation(entities, key, licenseId, valid) {
1839
1996
  if (!entities?.has(key))
1840
1997
  return;
@@ -1857,6 +2014,7 @@ class VaultCoreInstance {
1857
2014
  validLicense: valid ? VaultRegistrationLicenseStatusTypes.Valid : VaultRegistrationLicenseStatusTypes.Revoked
1858
2015
  }));
1859
2016
  }
2017
+ /** Records a license token against the matching entity in the registry. */
1860
2018
  #recordLicenses(event) {
1861
2019
  const { featureCellKey, key, licenseToken } = event;
1862
2020
  const record = this.#registry.get(featureCellKey);
@@ -1869,6 +2027,7 @@ class VaultCoreInstance {
1869
2027
  this.#recordLicense(record.behaviors, key, licenseToken);
1870
2028
  this.#recordLicense(record.controllers, key, licenseToken);
1871
2029
  }
2030
+ /** Writes a license ID to a single entity if it requires a license. */
1872
2031
  #recordLicense(entities, key, licenseId) {
1873
2032
  if (!entities?.has(key))
1874
2033
  return;
@@ -1886,6 +2045,7 @@ class VaultCoreInstance {
1886
2045
  licenseId
1887
2046
  }));
1888
2047
  }
2048
+ /** Emits a console warning when dev mode is active outside a test environment. */
1889
2049
  #warnIfAccidentalDevMode() {
1890
2050
  if (DevMode.active && !isTestEnv.active) {
1891
2051
  // eslint-disable-next-line
@@ -1895,6 +2055,7 @@ class VaultCoreInstance {
1895
2055
  `If this is intentional, you can safely ignore this message.`);
1896
2056
  }
1897
2057
  }
2058
+ /** Summarizes fluent API callback counts from a feature description event. */
1898
2059
  #summarizeFluent(event) {
1899
2060
  const fluent = event?.fluentApis ?? {};
1900
2061
  return {
@@ -1906,12 +2067,14 @@ class VaultCoreInstance {
1906
2067
  errorCallbacks: Array.isArray(fluent?.errorCallbacks) ? fluent.errorCallbacks.length : 0
1907
2068
  };
1908
2069
  }
2070
+ /** Returns or creates the registry record for a FeatureCell key. */
1909
2071
  #ensureRecord(key) {
1910
2072
  if (!this.#registry.has(key)) {
1911
2073
  this.#registry.set(key, { key, behaviorsRegistered: false, controllersRegistered: false });
1912
2074
  }
1913
2075
  return this.#registry.get(key);
1914
2076
  }
2077
+ /** Enables AI-assist capabilities when a core license is validated. */
1915
2078
  #enableAiAssist() {
1916
2079
  if (this.#aiAssistEnabled)
1917
2080
  return;
@@ -1926,6 +2089,7 @@ class VaultCoreInstance {
1926
2089
  globalThis.sdux.debugWidget.aiAssistEnabled = true;
1927
2090
  document.dispatchEvent(new CustomEvent('sdux-license-resolved'));
1928
2091
  }
2092
+ /** Injects the DevTools debug widget into the global scope. */
1929
2093
  #injectDebugWidget() {
1930
2094
  if (!DevMode.active)
1931
2095
  return;
@@ -1941,10 +2105,21 @@ class VaultCoreInstance {
1941
2105
  }
1942
2106
  //#endregion
1943
2107
  //#region Public Testing Method
2108
+ /**
2109
+ * Registers a settled callback for a FeatureCell.
2110
+ *
2111
+ * @param key - FeatureCell key.
2112
+ * @param fn - Async function invoked when the cell settles.
2113
+ */
1944
2114
  registerVaultSettled(key, fn) {
1945
2115
  const record = this.#ensureRecord(key);
1946
2116
  record.vaultSettled = fn;
1947
2117
  }
2118
+ /**
2119
+ * Awaits the settled callback for a specific FeatureCell.
2120
+ *
2121
+ * @param key - FeatureCell key to await.
2122
+ */
1948
2123
  async awaitFeatureCellSettled(key) {
1949
2124
  const record = this.#registry.get(key);
1950
2125
  if (!record) {
@@ -1955,6 +2130,7 @@ class VaultCoreInstance {
1955
2130
  await Promise.resolve(); // flush microtasks
1956
2131
  }
1957
2132
  }
2133
+ /** Awaits settled callbacks for all registered FeatureCells. */
1958
2134
  async awaitAllSettled() {
1959
2135
  for (const record of this.#registry.values()) {
1960
2136
  if (typeof record.vaultSettled === 'function') {
@@ -1964,11 +2140,21 @@ class VaultCoreInstance {
1964
2140
  await Promise.resolve();
1965
2141
  }
1966
2142
  // TESTING ONLY — do not use in production code
2143
+ /**
2144
+ * Returns a shallow clone of the internal registry for test inspection.
2145
+ *
2146
+ * @returns A read-only copy of the FeatureCell registry.
2147
+ */
1967
2148
  getRegistrySnapshot() {
1968
2149
  // Return a shallow cloned map so tests cannot mutate internal state
1969
2150
  return new Map(this.#registry);
1970
2151
  }
1971
2152
  }
2153
+ /**
2154
+ * Registers a FeatureCell entry in the global Vault registry.
2155
+ *
2156
+ * @param entry - Registration descriptor containing the FeatureCell key.
2157
+ */
1972
2158
  function registerFeatureCell(entry) {
1973
2159
  if (!instance) {
1974
2160
  throw new Error('[vault] Vault not initialized.');
@@ -1981,6 +2167,12 @@ function registerFeatureCell(entry) {
1981
2167
  }
1982
2168
  instance.registerCellRuntime(entry.key);
1983
2169
  }
2170
+ /**
2171
+ * Retrieves the decoded license payload for a given license ID.
2172
+ *
2173
+ * @param licenseId - License identifier to look up.
2174
+ * @returns The decoded payload.
2175
+ */
1984
2176
  function getLicensePayload(licenseId) {
1985
2177
  if (!instance) {
1986
2178
  throw new Error('[vault] Vault not initialized.');
@@ -1990,17 +2182,29 @@ function getLicensePayload(licenseId) {
1990
2182
  }
1991
2183
  return instance.getLicensePayload(licenseId);
1992
2184
  }
2185
+ /** Awaits settled callbacks for all registered FeatureCells. */
1993
2186
  async function vaultAllSettled() {
1994
2187
  if (!instance)
1995
2188
  return;
1996
2189
  await instance.awaitAllSettled();
1997
2190
  }
2191
+ /**
2192
+ * Awaits the settled callback for a specific FeatureCell.
2193
+ *
2194
+ * @param key - FeatureCell key to await.
2195
+ */
1998
2196
  async function vaultSettled(key) {
1999
2197
  if (!instance) {
2000
2198
  throw new Error('[vault] Vault not initialized.');
2001
2199
  }
2002
2200
  await instance.awaitFeatureCellSettled(key);
2003
2201
  }
2202
+ /**
2203
+ * Registers a settled callback for a FeatureCell in the global Vault.
2204
+ *
2205
+ * @param key - FeatureCell key.
2206
+ * @param vaultSettled - Async function invoked when the cell settles.
2207
+ */
2004
2208
  function registerVaultSettled(key, vaultSettled) {
2005
2209
  if (!instance) {
2006
2210
  throw new Error('[vault] Vault not initialized.');
@@ -2024,15 +2228,27 @@ function resetVaultForTests() {
2024
2228
  instance?.resetForTesting();
2025
2229
  instance = null;
2026
2230
  }
2231
+ /** Clears the FeatureCell registration registry. */
2027
2232
  function resetFeatureCellRegistry() {
2028
2233
  instance?.resetFeatureCellRegistry();
2029
2234
  }
2235
+ /**
2236
+ * Returns a read-only snapshot of the FeatureCell registry for test inspection.
2237
+ *
2238
+ * @returns A read-only copy of the registry.
2239
+ */
2030
2240
  function getVaultRegistryForTests() {
2031
2241
  if (!instance) {
2032
2242
  throw new Error('[vault] Vault not initialized.');
2033
2243
  }
2034
2244
  return instance.getRegistrySnapshot();
2035
2245
  }
2246
+ /**
2247
+ * Checks whether a key is authorized by the Vault runtime.
2248
+ *
2249
+ * @param key - The key to check.
2250
+ * @returns True when the key is authorized or licensing is bypassed.
2251
+ */
2036
2252
  function isAuthorizedKey(key) {
2037
2253
  if (!instance)
2038
2254
  return false;
@@ -2040,11 +2256,21 @@ function isAuthorizedKey(key) {
2040
2256
  return true;
2041
2257
  return instance.isAuthorizedKey(key);
2042
2258
  }
2259
+ /**
2260
+ * Returns whether licensing checks are currently bypassed.
2261
+ *
2262
+ * @returns True when bypass licensing is active.
2263
+ */
2043
2264
  function isBypassLicensing() {
2044
2265
  if (!instance)
2045
2266
  return false;
2046
2267
  return instance.isBypassLicensing();
2047
2268
  }
2269
+ /**
2270
+ * Returns whether a Vault-level license has been registered.
2271
+ *
2272
+ * @returns True when a Vault license exists.
2273
+ */
2048
2274
  function hasVaultLicense() {
2049
2275
  if (!instance)
2050
2276
  return false;
@@ -2064,13 +2290,21 @@ class BehaviorInitializationClass {
2064
2290
  #initialized = false;
2065
2291
  /** FeatureCell identifier associated with this initializer. */
2066
2292
  #cellKey;
2293
+ /** Live reference to the FeatureCell's mutable last-snapshot object. */
2294
+ #lastSnapshot;
2295
+ /** Subject used by the FeatureCell to emit state snapshots. */
2296
+ #state$;
2067
2297
  /**
2068
2298
  * Creates a new behavior initializer for a specific FeatureCell.
2069
2299
  *
2070
2300
  * @param cellKey - The unique FeatureCell key.
2301
+ * @param lastSnapshot - Live reference to the FeatureCell's mutable state snapshot.
2302
+ * @param state$ - Subject used to emit state snapshots.
2071
2303
  */
2072
- constructor(cellKey) {
2304
+ constructor(cellKey, lastSnapshot, state$) {
2073
2305
  this.#cellKey = cellKey;
2306
+ this.#lastSnapshot = lastSnapshot;
2307
+ this.#state$ = state$;
2074
2308
  }
2075
2309
  /**
2076
2310
  * Instantiates and validates all behaviors declared for a FeatureCell.
@@ -2141,11 +2375,19 @@ class BehaviorInitializationClass {
2141
2375
  }
2142
2376
  let instance;
2143
2377
  try {
2144
- instance = new BehaviorClass(behaviorKey, {
2378
+ let behaviorContract = {
2145
2379
  featureCellKey: this.#cellKey,
2146
2380
  behaviorConfig,
2147
2381
  licensePayload
2148
- });
2382
+ };
2383
+ if (meta.type === BehaviorTypes.TabSyncState) {
2384
+ behaviorContract = {
2385
+ ...behaviorContract,
2386
+ lastSnapshot: this.#lastSnapshot,
2387
+ state$: this.#state$
2388
+ };
2389
+ }
2390
+ instance = new BehaviorClass(behaviorKey, behaviorContract);
2149
2391
  }
2150
2392
  catch (error) {
2151
2393
  isCritical = meta.critical;
@@ -2327,45 +2569,37 @@ const PublicKeys = {
2327
2569
  */
2328
2570
  pro: `
2329
2571
  -----BEGIN PUBLIC KEY-----
2572
+ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuXto+eRaFm9pObys/IEI ASwV1wgGvNGJsiyw/9hXsEd9mA76aQI1X9lpkZRKmBFovHdK2unPHFOPQM0k9vJo ieFMNXO9kmHn7UYZV98bDCcDTNURFHQ4SWlcAE/HEiNqcUb9LwotFbON7/mcthM8 QQQ4Lycdv+lm1uozQl8rl+i7FjfQzLaxJMuAkm9jFZK+ta6eoSy/lmXfhDem8RIo dE19aZWfY+LTXP9nn977XFah0z0S0D3NSvMv96gZsXTN2hTbFBl5dgDMAOW9R5OI wT6I+kGwrVqARXq2pTDHnZjqfO3a+rT4Lrb5/L58RjQ0EfA5puZ16EXGEUpOabqI KVT4Z/wv818P8eyat+LtTcy2G0zx/h0Fcz0QANzx3P9K7ezxeqdg4SsjkcNXRWZq PaJUhZHygN/Xuef9zfWwjuKobCBSdyyeXxF5XS0A0Y6NBmdhikyHc/YOY2iYupIt xiUvlHaq97B5wej3XcTmp4kmJUQyeQ8oD5Mj8Dmf69oa7vhI/ANNKWo9s8e7u7UX Dx74Eu3d8JBpACQ+Vvek6ZEGw+D0yCyLF6u/CaCw+cb2cBYAlM7jWZ5kpgsbQcWw YP2nbGV3OofcEspoEU704M4RW4v+nSRYrJbMEIJJ5Wuxk2/RuUgk/9uwgCHAvzXZ cmGomIf9dXZGoNhwT5uW1OECAwEAAQ==
2330
2573
  -----END PUBLIC KEY-----
2331
2574
  `,
2332
2575
  /**
2333
2576
  * the enterprise public key
2334
2577
  */
2335
2578
  enterprise: `
2336
- -----BEGIN PUBLIC KEY-----
2579
+ -----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA6k4XHyV4WE6Bd/fizN4Q c3C37LtskNTJ1c3FVxcziygAFd+fotRfbLHctwtJJhuO6+Pv+c1SPjrPeJsWRw4M IN7QHcBQHPbQDW/Erd1XjA0OVNbxs3xLVjtgMuVcd2sKYPp4nJqIyz5WLMde7v1g 1k8knI+ISrym0h4GcjkNSaHK5QKKpK7n3dzOXrjo1P6h1uOVsGAHC/ErVMQNHrAu dKgY+SDVn87oPIrd2pJb5SotI6H8HzODM/CDsF58hk/eK4zApnrtDViVb1j3oNCk hdDOnN98VIgwcHzHYZOhPFM0TFwudpi57Yu/PJJztI7WbsjpxTyX3JPvwVeWJR+Z tt6NEQ5ZaoBghGgHGiuRbhKR5qoznwsMkfb2jUbpbgRTinmtEjFmpIYSnROCixjq W1neupzBDrNi+JfoVsTwiP8SbzxHXWksN0gLMfL235l1LDMS/IrI3RmhcRkhB/Pu vPuc+jhPkwpbXaM9vDkkPWK1dmRYHWo3atYCWoSdK2705woo19oT8Dxm9OXKT+nh HsdOI+k9asBCqe4kQHi3OJ4Raesa6bFWWxKFLeUNKSAt7clJKo7GhrovnHIIAbty gk7ULdwLIlpjwB5mVUBBCts5z9KznHo+pumNoeEA8FGqq374a+jEPOHWjsshA678 RDYeqeRbh2VNcy/OwlqH/MUCAwEAAQ==
2337
2580
  -----END PUBLIC KEY-----
2338
2581
  `,
2339
2582
  /**
2340
2583
  * the development public key
2341
2584
  */
2342
2585
  development: `
2343
- -----BEGIN PUBLIC KEY-----
2344
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6RDckQGY38NrlPq70YfI
2345
- hIpBFmc9baNLS2HIeyKIU2m+Vvnt3AYcQJlQnzmO4ZLDOUkIP+VxAjaSCaUBeTOx
2346
- KDYXAK8ds0xEur0cRV4Kn26jhLveLZVpfVzhkOjJ6I9ggLeh5JRt7kj3NPgKwnSm
2347
- t5DxLh4JPyLfZdBDtW8tU2tCgCfEs2cArrVo/fg7Dei8FJ8w83PDhsKmX5UazSfj
2348
- MC57gkTZ/cZmKBvVoIhnqaWVXcRRL+wZPArIsO801DRiMAhROyQYyC3EKpGLyUc1
2349
- 1VSKqdmQLIUE1pt151EnmStB+VOsMzCLZH4TyU7cd1Afs2Siqu947W2w4Qpm5+Y/
2350
- FwIDAQAB
2586
+ -----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsAFRjQalSEZkCDPrdBEf IMQpY7ujGf4pqjuFk86rkZENr7kJ00RjVJxuhcafgygdmxVAhKS+d1WtsSAw6c9m AawI+sSyhAClB+wrwfuCrxt/ZlLbNMiMH5SD1YvoRaHstkLpMGbWnbsLDI+cCpaL hGKk+5LoJLikhf9ipBkGX8VSAT0xTMk06iaYtEV85H9cMWtfx7seyBw2Mps/8S6f Rtp3tLlbNJIyh9+5XjtkTqYNRWJtFW1rv75K9GN9dPVXrEXUGojqeV13G+z2R3Sr QvmhESkyC1DviZBxaYnEhpWoijJQFJUQ1DGRi29ugktYzf36Otw9gyz9jGb5MLNE W+meR2LdnbTBy83QNtaS5lCzNJVo2ohwbD+djblNVegH/Dr0rK4IHEYSgjdxjErY 6xqykJpKJ025CTU4kyI3aaaYB+l2CQMAKVAh2y2rgGyJSJnMDTR44aBIZ8rtTu2r wazjBJ/RiMr0OOkfBqEQPKZ6qzSWtBDebvD0iUyRAP8SXSdDo1DcaJNamLLmjIxr 3KCcwgJt2oLcdZZHKG3WbjqmIdp7tq03O4gajKJHd5GmyLWtHXKqBwaijAx9aNqr qDPWj/Qg/8C9qpSBs7EUod3slV6UhO4yEnb7FdD/O0o8mRMU0rtJ0KQTarpEh2bY MKVsYxByiFeAjUJUWLSqIX8CAwEAAQ==
2351
2587
  -----END PUBLIC KEY-----
2352
2588
  `
2353
2589
  };
2354
2590
 
2591
+ /** Whether license details have already been logged to the console. */
2592
+ let hasLoggedLicenseDetails = false;
2593
+ /** Resets the license details log flag for test isolation. */
2594
+ function resetLicenseDetailsLog() {
2595
+ if (!DevMode.active)
2596
+ return;
2597
+ hasLoggedLicenseDetails = false;
2598
+ }
2355
2599
  /**
2356
- * Static license verification utility used to validate signed license tokens
2357
- * against tier-specific public keys. Tokens use a dot-separated format:
2358
- * `base64(payload).base64(signature)`.
2359
- *
2360
- * The verification process:
2361
- * - Splits the token on `.` to extract the encoded payload and signature
2362
- * - Decodes the payload from base64 to determine the license tier
2363
- * - Rejects tokens with missing or unrecognized tier
2364
- * - Loads the appropriate PEM-encoded public key for the tier
2365
- * - Uses `crypto.subtle.verify()` (RSA-SHA256) to validate the signature
2366
- * against the raw base64-encoded payload string
2367
- *
2368
- * Verification failures return `false` rather than throwing.
2600
+ * Static license verification utility that validates signed license tokens
2601
+ * against tier-specific RSA public keys. Tokens use a dot-separated
2602
+ * base64(payload).base64(signature) format verified via crypto.subtle.
2369
2603
  */
2370
2604
  const VerifyLicenseToken = {
2371
2605
  /**
@@ -2392,6 +2626,11 @@ const VerifyLicenseToken = {
2392
2626
  if (!licenseType) {
2393
2627
  return false;
2394
2628
  }
2629
+ if (!DevMode.active && licenseType === 'development') {
2630
+ // eslint-disable-next-line
2631
+ console.error('[sdux-vault] Development license token rejected in production environment.');
2632
+ return false;
2633
+ }
2395
2634
  const keyPem = PublicKeys[licenseType];
2396
2635
  if (!keyPem)
2397
2636
  return false;
@@ -2400,9 +2639,45 @@ const VerifyLicenseToken = {
2400
2639
  name: 'RSASSA-PKCS1-v1_5',
2401
2640
  hash: 'SHA-256'
2402
2641
  }, key, signature, new TextEncoder().encode(encodedPayload));
2642
+ if (!hasLoggedLicenseDetails) {
2643
+ hasLoggedLicenseDetails = true;
2644
+ if (verified) {
2645
+ // eslint-disable-next-line
2646
+ console.info(`[sdux-vault] License verified — organization: "${payload.organization}", tier: "${payload.licenseType}"`);
2647
+ }
2648
+ else {
2649
+ // eslint-disable-next-line
2650
+ console.warn(`[sdux-vault] License signature invalid — organization: "${payload.organization}", tier: "${payload.licenseType}"`);
2651
+ }
2652
+ // eslint-disable-next-line
2653
+ console.info('[sdux-vault] License organization:', payload.organization);
2654
+ // eslint-disable-next-line
2655
+ console.info('[sdux-vault] License domain:', payload.domain);
2656
+ // eslint-disable-next-line
2657
+ console.info('[sdux-vault] License type:', payload.licenseType);
2658
+ // eslint-disable-next-line
2659
+ console.info('[sdux-vault] License issuedAt:', formatLicenseDate(payload.issuedAt));
2660
+ // eslint-disable-next-line
2661
+ console.info('[sdux-vault] License expires:', formatLicenseDate(payload.expires));
2662
+ }
2663
+ if (verified && payload.licenseType === 'enterprise' && typeof payload.expires === 'number') {
2664
+ const msUntilExpiry = payload.expires - Date.now();
2665
+ if (msUntilExpiry < 0) {
2666
+ // eslint-disable-next-line
2667
+ console.error(`[sdux-vault] Enterprise license expired — organization: "${payload.organization}", expired: ${formatLicenseDate(payload.expires)}`);
2668
+ return false;
2669
+ }
2670
+ const fifteenDaysMs = 15 * 24 * 60 * 60 * 1000;
2671
+ if (msUntilExpiry <= fifteenDaysMs) {
2672
+ // eslint-disable-next-line
2673
+ console.warn(`[sdux-vault] Enterprise license expiring soon — organization: "${payload.organization}", expires: ${formatLicenseDate(payload.expires)}`);
2674
+ }
2675
+ }
2403
2676
  return verified;
2404
2677
  }
2405
- catch {
2678
+ catch (error) {
2679
+ // eslint-disable-next-line
2680
+ console.error('[sdux-vault] License token verification failed:', error);
2406
2681
  return false;
2407
2682
  }
2408
2683
  }
@@ -2445,18 +2720,69 @@ function str2ab(str) {
2445
2720
  arr[i] = str.charCodeAt(i);
2446
2721
  return buf;
2447
2722
  }
2723
+ /**
2724
+ * Formats a license date value for display. Numeric timestamps are
2725
+ * formatted as locale-aware date strings; string values such as
2726
+ * `'forever'` are returned as-is.
2727
+ *
2728
+ * @param value - A Unix-epoch millisecond timestamp or a string literal.
2729
+ * @returns A human-readable date string.
2730
+ */
2731
+ function formatLicenseDate(value) {
2732
+ if (typeof value === 'string')
2733
+ return value;
2734
+ return new Intl.DateTimeFormat('en-US', {
2735
+ month: '2-digit',
2736
+ day: '2-digit',
2737
+ year: 'numeric'
2738
+ }).format(new Date(value));
2739
+ }
2740
+
2741
+ /**
2742
+ * Verifies a signed license payload string.
2743
+ *
2744
+ * @param licensePayload - The signed license token to verify.
2745
+ * @returns A promise resolving to true if the license is valid.
2746
+ */
2747
+ async function verifyLicensePayload(licensePayload) {
2748
+ try {
2749
+ if (!licensePayload) {
2750
+ return false;
2751
+ }
2752
+ return await VerifyLicenseToken.verify(licensePayload);
2753
+ }
2754
+ catch {
2755
+ return false;
2756
+ }
2757
+ }
2448
2758
 
2759
+ /**
2760
+ * Abstract base class providing license lifecycle management for behaviors
2761
+ * and controllers. Subclasses automatically request a license token during
2762
+ * construction when the static `needsLicense` flag is set.
2763
+ */
2449
2764
  class LicensingAbstract {
2765
+ /** Whether this class requires a valid license to operate. */
2450
2766
  static needsLicense;
2767
+ /** Static key assigned by the VaultBehavior or VaultController decorator. */
2451
2768
  static key;
2769
+ /** License token received from the licensing service. */
2452
2770
  #licenseToken;
2771
+ /** Key of the FeatureCell this instance belongs to. */
2453
2772
  #featureCellKey;
2773
+ /** Key identifying this behavior or controller. */
2454
2774
  #key;
2775
+ /** Licensing service used to request and validate licenses. */
2455
2776
  #licenseService;
2777
+ /**
2778
+ * Creates a new licensing-aware instance and requests a license if required.
2779
+ *
2780
+ * @param ctx - Context providing the FeatureCell key and optional license payload.
2781
+ */
2456
2782
  constructor(ctx) {
2457
2783
  const ctor = this.constructor;
2458
2784
  if (typeof ctor.key !== 'string' || !ctor.key.trim()) {
2459
- throw new VaultLicenseError(`LicensingClass requires a static "key". Did you forget @VaultBehavior?`);
2785
+ throw new VaultLicenseError(`LicensingClass requires a static "key". Did you forget @VaultBehavior or @VaultController?`);
2460
2786
  }
2461
2787
  this.#licenseService = LicensingService();
2462
2788
  this.#key = ctor.key;
@@ -2465,9 +2791,15 @@ class LicensingAbstract {
2465
2791
  this.#requestLicense();
2466
2792
  }
2467
2793
  }
2794
+ /** Requests a license token from the licensing service. */
2468
2795
  #requestLicense() {
2469
2796
  this.#licenseToken = this.#licenseService.requestLicense(this.#featureCellKey, this.#key);
2470
2797
  }
2798
+ /**
2799
+ * Validates the previously requested license token.
2800
+ *
2801
+ * @param valid - Whether the license should be marked as approved.
2802
+ */
2471
2803
  validateLicense(valid) {
2472
2804
  if (!this.#licenseToken) {
2473
2805
  throw new VaultLicenseError(`validateLicense() called but no license was requested for "${this.#featureCellKey}" and "${this.#key}".`);
@@ -2476,38 +2808,45 @@ class LicensingAbstract {
2476
2808
  }
2477
2809
  }
2478
2810
 
2811
+ /**
2812
+ * Core license behavior that validates the vault license payload on
2813
+ * construction. The behavior extends LicensingAbstract to integrate
2814
+ * with the licensing service and gates pipeline execution based on
2815
+ * the asynchronous verification result.
2816
+ */
2479
2817
  let withCoreLicenseBehavior = class withCoreLicenseBehavior extends LicensingAbstract {
2480
2818
  behaviorCtx;
2819
+ /** Static behavior type assigned by the VaultBehavior decorator. */
2481
2820
  static type;
2821
+ /** Static behavior key assigned by the VaultBehavior decorator. */
2482
2822
  static key;
2823
+ /** Static critical flag assigned by the VaultBehavior decorator. */
2483
2824
  static critical;
2825
+ /** Static license requirement flag assigned by the VaultBehavior decorator. */
2484
2826
  static needsLicense;
2827
+ /** Instance behavior type for core license evaluation. */
2485
2828
  type = BehaviorTypes.CoreLicense;
2829
+ /** Instance critical flag indicating this behavior is required. */
2486
2830
  critical = true;
2831
+ /** Unique key identifying this behavior instance. */
2487
2832
  key;
2833
+ /**
2834
+ * Verifies the license payload asynchronously and reports the result.
2835
+ *
2836
+ * @param key - Unique key for this behavior instance.
2837
+ * @param behaviorCtx - Behavior class context providing the license payload.
2838
+ */
2488
2839
  constructor(key, behaviorCtx) {
2489
2840
  super(behaviorCtx);
2490
2841
  this.behaviorCtx = behaviorCtx;
2491
2842
  this.key = key;
2492
- this.#performLicenseValidation();
2493
- }
2494
- async #performLicenseValidation() {
2495
- try {
2496
- const payload = this.behaviorCtx.licensePayload;
2497
- if (!payload?.token) {
2498
- this.validateLicense(false);
2499
- return;
2500
- }
2501
- const isValid = await VerifyLicenseToken.verify(payload.token);
2502
- this.validateLicense(isValid);
2503
- }
2504
- catch {
2505
- this.validateLicense(false);
2506
- }
2843
+ verifyLicensePayload(this.behaviorCtx.licensePayload).then((valid) => this.validateLicense(valid));
2507
2844
  }
2845
+ /** No-op destroy handler for this behavior. */
2508
2846
  destroy() {
2509
2847
  vaultWarn(`${this.key} - destroy noop`);
2510
2848
  }
2849
+ /** No-op reset handler for this behavior. */
2511
2850
  reset() {
2512
2851
  vaultWarn(`${this.key} - reset noop`);
2513
2852
  }
@@ -2522,32 +2861,56 @@ withCoreLicenseBehavior = __decorate([
2522
2861
  })
2523
2862
  ], withCoreLicenseBehavior);
2524
2863
 
2525
- // --- AI Model File Path (DO NOT DELETE) ---
2526
- // FilePath: lib > src > orchestrator > orchestrator.ts
2527
- // Updated: 2026-04-07 16:30
2528
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
2529
- // cmd+alt+j (see .vscode/keybindings.json)
2530
- // --- END AI MODEL FILE PATH ---
2864
+ /**
2865
+ * Abstract base class that executes the FeatureCell behavior pipeline in
2866
+ * a deterministic stage order. The Orchestrator resolves incoming state,
2867
+ * runs operators, filters, reducers, tap callbacks, and persistence
2868
+ * stages before committing the final state snapshot.
2869
+ */
2531
2870
  class Orchestrator {
2871
+ /** Registered after-tap callback functions executed post-reduce. */
2532
2872
  #afterTapCallbacks;
2873
+ /** Registered before-tap callback functions executed pre-reduce. */
2533
2874
  #beforeTapCallbacks;
2875
+ /** Full set of instantiated behavior instances for this FeatureCell. */
2534
2876
  #behaviors;
2877
+ /** Subset of behaviors eligible for stage-based pipeline execution. */
2535
2878
  #stageBehaviors;
2879
+ /** Unique key identifying the FeatureCell that owns this orchestrator. */
2536
2880
  cellKey;
2881
+ /** Decision engine used for controller vote evaluation. */
2537
2882
  decisionEngine;
2883
+ /** Core error behavior responsible for normalizing pipeline errors. */
2538
2884
  #coreErrorBehavior;
2885
+ /** Error callback behavior for dispatching errors to user callbacks. */
2539
2886
  #coreErrorCallbackBehavior;
2887
+ /** Emit-state callback behavior for notifying state change listeners. */
2540
2888
  #emitStateCallbackBehavior;
2889
+ /** User-provided emit-state callback functions. */
2541
2890
  #emitStateCallbacks;
2891
+ /** Core state behavior managing snapshot commits and signal emission. */
2542
2892
  #coreStateBehavior;
2893
+ /** Error transform behaviors for custom error shaping. */
2543
2894
  #errorTransformBehaviors;
2895
+ /** User-provided error callback functions. */
2544
2896
  #errorCallbacks;
2897
+ /** Global error service for broadcasting errors across FeatureCells. */
2545
2898
  privateErrorService = VaultPrivateErrorService();
2899
+ /** User-provided filter functions applied during the filter stage. */
2546
2900
  #filterFunctions = [];
2901
+ /** Initial state value or deferred factory for this FeatureCell. */
2547
2902
  #initialState;
2903
+ /** Merge behavior responsible for combining partial and current state. */
2548
2904
  #mergeBehavior;
2905
+ /** User-provided reducer functions applied during the reduce stage. */
2549
2906
  #reducerFunctions;
2907
+ /** Vault monitor instance for tracing pipeline lifecycle events. */
2550
2908
  vaultMonitor = VaultMonitor();
2909
+ /**
2910
+ * Initializes the orchestrator with configuration callbacks and initial state.
2911
+ *
2912
+ * @param config - Orchestrator configuration containing behaviors and callbacks.
2913
+ */
2551
2914
  constructor(config) {
2552
2915
  this.#afterTapCallbacks = config.afterTapCallbacks ?? [];
2553
2916
  this.#beforeTapCallbacks = config.beforeTapCallbacks ?? [];
@@ -2558,20 +2921,25 @@ class Orchestrator {
2558
2921
  this.#initialState = config.initialState;
2559
2922
  this.#reducerFunctions = config.reducerCallbacks ?? [];
2560
2923
  }
2924
+ /** Registers all behaviors from the orchestrator configuration. */
2561
2925
  initializeOrchestrator(config) {
2562
2926
  config.behaviors = config.behaviors ?? [];
2563
2927
  this.#registerBehaviors(config);
2564
2928
  }
2565
2929
  //#region Protected Methods
2930
+ /** Loads the initial state and runs the first pipeline cycle. */
2566
2931
  async initializeFeatureCell(ctx) {
2567
2932
  await this.#loadInitialState(ctx);
2568
2933
  }
2934
+ /** Invokes destroy on all registered behaviors. */
2569
2935
  destroyBehaviors(ctx) {
2570
2936
  this.#destroyBehaviors(ctx);
2571
2937
  }
2938
+ /** Invokes reset on all registered behaviors. */
2572
2939
  resetBehaviors(ctx) {
2573
2940
  this.#resetBehaviors(ctx);
2574
2941
  }
2942
+ /** Routes the pipeline context to the appropriate replace or merge orchestration flow. */
2575
2943
  async orchestrate(ctx, options) {
2576
2944
  // no controllers → pipeline behaves exactly as before
2577
2945
  if (ctx.operation === OperationTypes.Replace) {
@@ -2582,6 +2950,11 @@ class Orchestrator {
2582
2950
  }
2583
2951
  return;
2584
2952
  }
2953
+ /**
2954
+ * Builds a controller context from the current behavior context.
2955
+ *
2956
+ * @returns The controller context snapshot.
2957
+ */
2585
2958
  buildControllerCtx(ctx) {
2586
2959
  return {
2587
2960
  traceId: ctx.traceId,
@@ -2591,6 +2964,11 @@ class Orchestrator {
2591
2964
  operation: ctx.operation
2592
2965
  };
2593
2966
  }
2967
+ /**
2968
+ * Normalizes an incoming state input into a consistent shape.
2969
+ *
2970
+ * @returns The normalized state input value.
2971
+ */
2594
2972
  normalizeIncoming(incoming) {
2595
2973
  if (!incoming)
2596
2974
  return null;
@@ -2604,6 +2982,7 @@ class Orchestrator {
2604
2982
  value: incoming
2605
2983
  };
2606
2984
  }
2985
+ /** Notifies the core state behavior of a controller abort or deny outcome. */
2607
2986
  controllerOutcomeNotification(type, ctx) {
2608
2987
  switch (type) {
2609
2988
  case DecisionOutcomeTypes.Abort: {
@@ -2616,6 +2995,11 @@ class Orchestrator {
2616
2995
  }
2617
2996
  }
2618
2997
  }
2998
+ /**
2999
+ * Prepares the incoming value and handles noop and clear-state short-circuits.
3000
+ *
3001
+ * @returns The normalized incoming value or undefined for short-circuit paths.
3002
+ */
2619
3003
  prepareIncoming(ctx, incoming, operation) {
2620
3004
  ctx = this.#prepIncomingForOrchestration(ctx, incoming, operation);
2621
3005
  const normalizedIncoming = this.#coreStateBehavior.preparePipelineIncoming(ctx);
@@ -2635,12 +3019,14 @@ class Orchestrator {
2635
3019
  }
2636
3020
  //#endregion
2637
3021
  //#region Private Methods
3022
+ /** Attaches incoming, resolve type, and operation to the behavior context. */
2638
3023
  #prepIncomingForOrchestration(ctx, incoming, operation) {
2639
3024
  ctx.incoming = this.normalizeIncoming(incoming);
2640
3025
  ctx.resolveType = this.#getResolveType(incoming);
2641
3026
  ctx.operation = operation;
2642
3027
  return ctx;
2643
3028
  }
3029
+ /** Ensures at most one merge behavior is registered and adds it to the list. */
2644
3030
  #addDefaultMergeBehavior(behaviors, config) {
2645
3031
  const mergeBehaviors = config.behaviors.filter((behaviorClass) => {
2646
3032
  return behaviorClass.type === BehaviorTypes.Merge;
@@ -2658,6 +3044,7 @@ class Orchestrator {
2658
3044
  // ---------------------------------------------------------------------------
2659
3045
  // NORMALIZATION
2660
3046
  // ---------------------------------------------------------------------------
3047
+ /** Assembles the default behavior set from configuration and internal overrides. */
2661
3048
  #defineDefaultBehaviors(config) {
2662
3049
  let defaultBehaviors = config.defaultBehaviors ?? [];
2663
3050
  defaultBehaviors = this.#determineCoreCallbackErrorBehavior(defaultBehaviors, config);
@@ -2666,18 +3053,21 @@ class Orchestrator {
2666
3053
  defaultBehaviors = this.#addCoreLicenseBehavior(defaultBehaviors);
2667
3054
  return defaultBehaviors;
2668
3055
  }
3056
+ /** Removes the error callback behavior when no error callbacks are configured. */
2669
3057
  #determineCoreCallbackErrorBehavior(behaviors, config) {
2670
3058
  if (config?.errorCallbacks?.length === 0) {
2671
3059
  return behaviors.filter((behavior) => behavior.type !== BehaviorTypes.CoreErrorCallback);
2672
3060
  }
2673
3061
  return behaviors;
2674
3062
  }
3063
+ /** Removes the emit-state callback behavior when no emit-state callbacks are configured. */
2675
3064
  #addCoreEmitStateCallbackBehavior(behaviors, config) {
2676
3065
  if (config?.emitStateCallbacks?.length === 0) {
2677
3066
  return behaviors.filter((behavior) => behavior.type !== BehaviorTypes.CoreEmitState);
2678
3067
  }
2679
3068
  return behaviors;
2680
3069
  }
3070
+ /** Conditionally adds the core license behavior when a vault license is active. */
2681
3071
  #addCoreLicenseBehavior(behaviors) {
2682
3072
  behaviors = behaviors?.filter((behavior) => behavior.type !== BehaviorTypes.CoreLicense);
2683
3073
  if (hasVaultLicense()) {
@@ -2685,6 +3075,7 @@ class Orchestrator {
2685
3075
  }
2686
3076
  return behaviors;
2687
3077
  }
3078
+ /** Reports behavior metadata to the licensing service for license validation. */
2688
3079
  #registerBehaviorsWithVault(behaviors) {
2689
3080
  // eslint-disable-next-line
2690
3081
  const behaviorMetadata = behaviors.map((behavior) => {
@@ -2701,6 +3092,7 @@ class Orchestrator {
2701
3092
  behaviors: behaviorMetadata
2702
3093
  });
2703
3094
  }
3095
+ /** Initializes, filters, and registers all behaviors for this FeatureCell. */
2704
3096
  #registerBehaviors(config) {
2705
3097
  const defaultBehaviors = this.#defineDefaultBehaviors(config);
2706
3098
  // Strip out any user-provided reducers; they are passed separately via `reducers`
@@ -2731,7 +3123,7 @@ class Orchestrator {
2731
3123
  if (hasTabSync) {
2732
3124
  allBehaviors = allBehaviors.filter((behavior) => behavior.type !== BehaviorTypes.CoreState);
2733
3125
  }
2734
- const behaviorInit = new BehaviorInitializationClass(this.cellKey);
3126
+ const behaviorInit = new BehaviorInitializationClass(this.cellKey, config.lastSnapshot, config.state$);
2735
3127
  this.#registerBehaviorsWithVault(allBehaviors);
2736
3128
  this.#behaviors = behaviorInit.initializeBehaviors(allBehaviors, config.behaviorConfigs);
2737
3129
  this.#registerErrorBehavior();
@@ -2740,6 +3132,7 @@ class Orchestrator {
2740
3132
  this.#registerStateBehavior();
2741
3133
  behaviorInit.applyBehaviorExtensions(this.#behaviors, config.cell, this.vaultMonitor);
2742
3134
  }
3135
+ /** Filters behaviors to only those eligible for stage-based pipeline execution. */
2743
3136
  #registerStageBehaviors() {
2744
3137
  // Remove merge behavior from the pipeline list
2745
3138
  this.#stageBehaviors = this.#behaviors.filter((behavior) => !(behavior.type === BehaviorTypes.CoreState ||
@@ -2750,6 +3143,7 @@ class Orchestrator {
2750
3143
  behavior.type === BehaviorTypes.CoreErrorCallback ||
2751
3144
  behavior.type === BehaviorTypes.Merge));
2752
3145
  }
3146
+ /** Extracts and registers the core state and emit-state callback behaviors. */
2753
3147
  #registerStateBehavior() {
2754
3148
  const tabSyncState = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.TabSyncState);
2755
3149
  const coreState = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.CoreState);
@@ -2760,6 +3154,7 @@ class Orchestrator {
2760
3154
  this.#coreStateBehavior = stateBehaviors[0] ?? null;
2761
3155
  this.#emitStateCallbackBehavior = this.#behaviors.filter((behavior) => isCoreEmitStateCallbackBehavior(behavior))[0];
2762
3156
  }
3157
+ /** Extracts and registers the core error, error callback, and error transform behaviors. */
2763
3158
  #registerErrorBehavior() {
2764
3159
  // Extract and remove error behavior
2765
3160
  const coreErrors = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.CoreError);
@@ -2770,11 +3165,17 @@ class Orchestrator {
2770
3165
  this.#coreErrorCallbackBehavior = this.#behaviors.filter((behavior) => isCoreErrorCallbackBehavior(behavior))[0];
2771
3166
  this.#errorTransformBehaviors = this.#behaviors.filter((behavior) => isErrorTransformBehavior(behavior));
2772
3167
  }
3168
+ /** Extracts and registers the merge behavior from the behavior list. */
2773
3169
  #registerMergeBehavior() {
2774
3170
  // Extract and remove merge behavior
2775
3171
  const merges = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.Merge);
2776
3172
  this.#mergeBehavior = merges[0] ?? null;
2777
3173
  }
3174
+ /**
3175
+ * Runs a stepwise behavior and returns its pipeline signal.
3176
+ *
3177
+ * @returns A noop, clear-state, or continue signal.
3178
+ */
2778
3179
  async #runStepwise(behaviorType, ctx, current) {
2779
3180
  const stepwise = await this.#runUpstreamStage(behaviorType, ctx, current);
2780
3181
  if (isVaultClearState(stepwise)) {
@@ -2785,6 +3186,11 @@ class Orchestrator {
2785
3186
  }
2786
3187
  return VAULT_CONTINUE;
2787
3188
  }
3189
+ /**
3190
+ * Runs the post-resolve pipeline stages and returns the final state data.
3191
+ *
3192
+ * @returns The pipeline data flow result or a sentinel signal.
3193
+ */
2788
3194
  async #finishPipeline(ctx, resolved) {
2789
3195
  // Stage: operators
2790
3196
  let pipelineDataFlow;
@@ -2825,6 +3231,7 @@ class Orchestrator {
2825
3231
  // Commit the *cloned* pre-encrypted snapshot to signals
2826
3232
  return stateData;
2827
3233
  }
3234
+ /** Orchestrates a full replace pipeline cycle for the current attempt. */
2828
3235
  async #orchestrateReplace(ctx) {
2829
3236
  this.vaultMonitor.startReplace(this.cellKey, VAULT_ORCHESTRATOR, ctx);
2830
3237
  await this.#safeAsync(async () => {
@@ -2842,6 +3249,7 @@ class Orchestrator {
2842
3249
  return this.#handleFinalState(finalState, ctx);
2843
3250
  }, ctx);
2844
3251
  }
3252
+ /** Orchestrates a full merge pipeline cycle for the current attempt. */
2845
3253
  async #orchestrateMerge(ctx, options) {
2846
3254
  this.vaultMonitor.startMerge(this.cellKey, VAULT_ORCHESTRATOR, ctx);
2847
3255
  await this.#safeAsync(async () => {
@@ -2866,6 +3274,11 @@ class Orchestrator {
2866
3274
  return await this.#handleFinalState(finalState, ctx);
2867
3275
  }, ctx);
2868
3276
  }
3277
+ /**
3278
+ * Emits monitor events for the final pipeline state and returns the result.
3279
+ *
3280
+ * @returns The final state value passed through.
3281
+ */
2869
3282
  async #handleFinalState(finalState, ctx) {
2870
3283
  let payload;
2871
3284
  if (isSignalStop(finalState)) {
@@ -2885,6 +3298,7 @@ class Orchestrator {
2885
3298
  }
2886
3299
  return finalState;
2887
3300
  }
3301
+ /** Wraps an async pipeline function with error handling and state finalization. */
2888
3302
  async #safeAsync(fn, ctx) {
2889
3303
  try {
2890
3304
  const result = await fn();
@@ -2904,6 +3318,11 @@ class Orchestrator {
2904
3318
  await this.decisionEngine?.notifyFailure(this.buildControllerCtx(ctx), pipelineError);
2905
3319
  }
2906
3320
  }
3321
+ /**
3322
+ * Iterates through behaviors matching the given stage and applies each one.
3323
+ *
3324
+ * @returns The accumulated pipeline value after all stage behaviors execute.
3325
+ */
2907
3326
  async #runUpstreamStage(stage, ctx, current) {
2908
3327
  let stageBehaviors;
2909
3328
  if (stage === BehaviorTypes.Resolve) {
@@ -3000,6 +3419,11 @@ class Orchestrator {
3000
3419
  }
3001
3420
  return current;
3002
3421
  }
3422
+ /**
3423
+ * Runs interceptor behaviors and returns a stop signal if any interceptor halts the pipeline.
3424
+ *
3425
+ * @returns Undefined to continue or VAULT_STOP to halt.
3426
+ */
3003
3427
  async #runInterceptorStage(ctx) {
3004
3428
  const interceptorBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Interceptor);
3005
3429
  for (const behavior of interceptorBehaviors) {
@@ -3020,10 +3444,16 @@ class Orchestrator {
3020
3444
  }
3021
3445
  return;
3022
3446
  }
3447
+ /** Returns whether any operator behaviors are registered in the pipeline. */
3023
3448
  #containsOperators() {
3024
3449
  const operatorBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Operator);
3025
3450
  return operatorBehaviors.length > 0;
3026
3451
  }
3452
+ /**
3453
+ * Runs operator behaviors in sequence and returns the transformed value.
3454
+ *
3455
+ * @returns The pipeline value after all operators execute or undefined on noop.
3456
+ */
3027
3457
  async #runOperatorStage(ctx, current) {
3028
3458
  const operatorBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Operator);
3029
3459
  for (const behavior of operatorBehaviors) {
@@ -3046,6 +3476,11 @@ class Orchestrator {
3046
3476
  }
3047
3477
  return current;
3048
3478
  }
3479
+ /**
3480
+ * Runs encrypt and persist behaviors in sequence for state persistence.
3481
+ *
3482
+ * @returns The pipeline persist value after all stage behaviors execute.
3483
+ */
3049
3484
  async #runPersistStage(stage, ctx, current) {
3050
3485
  let stageBehaviors;
3051
3486
  stageBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === stage);
@@ -3080,6 +3515,7 @@ class Orchestrator {
3080
3515
  }
3081
3516
  return current;
3082
3517
  }
3518
+ /** Invokes destroy on each registered behavior with monitor tracing. */
3083
3519
  #destroyBehaviors(ctx) {
3084
3520
  for (const behavior of this.#behaviors) {
3085
3521
  this.vaultMonitor.startDestroy(this.cellKey, behavior.key, ctx);
@@ -3093,6 +3529,7 @@ class Orchestrator {
3093
3529
  }
3094
3530
  }
3095
3531
  }
3532
+ /** Invokes reset on each registered behavior with monitor tracing. */
3096
3533
  #resetBehaviors(ctx) {
3097
3534
  for (const behavior of this.#behaviors) {
3098
3535
  this.vaultMonitor.startReset(this.cellKey, behavior.key, ctx);
@@ -3106,6 +3543,7 @@ class Orchestrator {
3106
3543
  }
3107
3544
  }
3108
3545
  }
3546
+ /** Runs emit-state callbacks with an isolated snapshot clone. */
3109
3547
  async #runStateBehaviors(ctx) {
3110
3548
  if (this.#emitStateCallbacks?.length > 0) {
3111
3549
  const lastSnapshotClone = isolateValue(ctx.lastSnapshot);
@@ -3117,15 +3555,9 @@ class Orchestrator {
3117
3555
  }
3118
3556
  }
3119
3557
  /**
3120
- * Runs the error behaviors in sequence.
3121
- *
3122
- * - Starts from a normalized ResourceError produced by resourceError().
3123
- * - Each behavior gets (rawError, currentResourceError, ctx).
3124
- * - If a behavior returns:
3125
- * • ResourceError → becomes the next currentResourceError
3126
- * • VAULT_NOOP → previous ResourceError is kept
3558
+ * Runs error normalization, transforms, state commit, and callbacks in sequence.
3127
3559
  *
3128
- * Returns void
3560
+ * @returns The final normalized vault error shape.
3129
3561
  */
3130
3562
  async #runErrorBehaviors(rawError, ctx) {
3131
3563
  let current;
@@ -3206,6 +3638,11 @@ class Orchestrator {
3206
3638
  vaultDebug(`${this.cellKey} #runErrorBehaviors completed with final ResourceError: ${JSON.stringify(current)}`);
3207
3639
  return current;
3208
3640
  }
3641
+ /**
3642
+ * Determines the resolve type for the incoming state input.
3643
+ *
3644
+ * @returns The resolve type matching the incoming value shape.
3645
+ */
3209
3646
  #getResolveType(incoming) {
3210
3647
  if (isHttpResourceRef(incoming)) {
3211
3648
  return ResolveTypes.HttpResource;
@@ -3223,6 +3660,7 @@ class Orchestrator {
3223
3660
  return ResolveTypes.Value;
3224
3661
  }
3225
3662
  }
3663
+ /** Loads the initial state from persistence, configuration, or a deferred factory. */
3226
3664
  async #loadInitialState(ctx) {
3227
3665
  const incoming = {
3228
3666
  value: undefined,
@@ -3257,9 +3695,19 @@ class Orchestrator {
3257
3695
  this.decisionEngine?.notifySuccess(this.buildControllerCtx(ctx));
3258
3696
  }
3259
3697
  }
3698
+ /**
3699
+ * Returns persist behaviors registered for this FeatureCell.
3700
+ *
3701
+ * @returns Array of persist behavior instances.
3702
+ */
3260
3703
  #getPersistedBehaviors() {
3261
3704
  return this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Persist);
3262
3705
  }
3706
+ /**
3707
+ * Loads persisted state and decrypts it if encryption behaviors are registered.
3708
+ *
3709
+ * @returns The loaded and optionally decrypted state or undefined on failure.
3710
+ */
3263
3711
  async #loadInitialPersistedState(ctx, persistBehaviors) {
3264
3712
  let loaded = undefined;
3265
3713
  for (const behavior of persistBehaviors) {
@@ -3308,6 +3756,7 @@ class Orchestrator {
3308
3756
  }
3309
3757
  }
3310
3758
 
3759
+ /** Enumeration of conductor license evaluation statuses. */
3311
3760
  const ConductorLicenseStatusTypes = {
3312
3761
  Pending: 'pending',
3313
3762
  Approved: 'approved',
@@ -3464,20 +3913,32 @@ class ControllerInitializationClass {
3464
3913
  }
3465
3914
  }
3466
3915
 
3467
- // --- AI Model File Path (DO NOT DELETE) ---
3468
- // FilePath: lib > src > conductor > conductor.ts
3469
- // Updated: 2026-04-07 16:29
3470
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
3471
- // cmd+alt+j (see .vscode/keybindings.json)
3472
- // --- END AI MODEL FILE PATH ---
3916
+ /**
3917
+ * Coordinates pipeline execution, controller arbitration, and license
3918
+ * gating for a single FeatureCell. The Conductor serializes pipeline
3919
+ * attempts through a FIFO queue and delegates vote resolution to the
3920
+ * DecisionEngine.
3921
+ */
3473
3922
  class Conductor extends Orchestrator {
3923
+ /** FIFO queue of pending pipeline attempts awaiting controller evaluation. */
3474
3924
  #attemptQueue = [];
3925
+ /** Instantiated controller instances for this FeatureCell. */
3475
3926
  #controllers = [];
3927
+ /** Subject emitting controller lifecycle events to the decision engine. */
3476
3928
  #events$ = new Subject();
3929
+ /** Whether the conductor is currently processing an attempt. */
3477
3930
  #processing = false;
3931
+ /** Whether the conductor is in a deny state for test flushing. */
3478
3932
  #isDenyStateForTesting = false;
3933
+ /** Current license evaluation status for this conductor. */
3479
3934
  #conductorLicenseStatus = ConductorLicenseStatusTypes.Pending;
3935
+ /** Subject signaling when the conductor has settled for DevMode testing. */
3480
3936
  #settled$ = new Subject();
3937
+ /**
3938
+ * Creates a new Conductor and initializes controllers and licensing.
3939
+ *
3940
+ * @param config - Configuration describing behaviors, controllers, and callbacks.
3941
+ */
3481
3942
  constructor(config) {
3482
3943
  super(config);
3483
3944
  LicensingService().describeFeature({
@@ -3499,6 +3960,11 @@ class Conductor extends Orchestrator {
3499
3960
  this.vaultMonitor.conductorLicenseAttempt(this.cellKey, `${this.cellKey}::license`);
3500
3961
  this.initializeOrchestrator(config);
3501
3962
  }
3963
+ /**
3964
+ * Enqueues an initialization attempt for the FeatureCell pipeline.
3965
+ *
3966
+ * @param ctx - Behavior context for the initialization cycle.
3967
+ */
3502
3968
  initialize(ctx) {
3503
3969
  const initCtx = this.#buildPipelineCtx(ctx, OperationTypes.Initialize, undefined);
3504
3970
  this.#enqueueAttempt({
@@ -3508,6 +3974,14 @@ class Conductor extends Orchestrator {
3508
3974
  });
3509
3975
  }
3510
3976
  //#region public method
3977
+ /**
3978
+ * Enqueues a pipeline attempt for a merge or replace operation.
3979
+ *
3980
+ * @param ctx - Behavior context for the current pipeline cycle.
3981
+ * @param incoming - Incoming state input value.
3982
+ * @param operation - Pipeline operation type.
3983
+ * @param options - Optional merge or replace options.
3984
+ */
3511
3985
  conduct(ctx, incoming, operation, options) {
3512
3986
  const behaviorCtx = this.#buildPipelineCtx(ctx, operation, options);
3513
3987
  const preparedIncoming = this.prepareIncoming(behaviorCtx, incoming, operation);
@@ -3550,6 +4024,7 @@ class Conductor extends Orchestrator {
3550
4024
  }
3551
4025
  //#endregion
3552
4026
  //#region Private Methods
4027
+ /** Routes a pipeline attempt to the appropriate orchestrator method. */
3553
4028
  async #processEvent(ctx, options) {
3554
4029
  if (ctx.operation === OperationTypes.Initialize) {
3555
4030
  await this.initializeFeatureCell(ctx);
@@ -3562,6 +4037,7 @@ class Conductor extends Orchestrator {
3562
4037
  this.vaultMonitor.runtimeError(this.cellKey, VAULT_CONDUCTOR, ctx, new Error(`Unknown operation type: "${ctx.operation}"`));
3563
4038
  this.#completeCurrentAttempt(ctx);
3564
4039
  }
4040
+ /** Schedules a microtask to signal a deny-state completion. */
3565
4041
  #enqueueMicrotask() {
3566
4042
  queueMicrotask(() => {
3567
4043
  this.#denyAttemptCompleted();
@@ -3593,6 +4069,7 @@ class Conductor extends Orchestrator {
3593
4069
  this.#enqueueMicrotask();
3594
4070
  }
3595
4071
  }
4072
+ /** Finalizes the current attempt and advances the queue in a microtask. */
3596
4073
  #completeCurrentAttempt(ctx) {
3597
4074
  const head = this.#attemptQueue[0];
3598
4075
  /* istanbul ignore next */
@@ -3647,6 +4124,7 @@ class Conductor extends Orchestrator {
3647
4124
  this.#processQueue();
3648
4125
  });
3649
4126
  }
4127
+ /** Resets the processing flag and emits a restart-attempt monitor event. */
3650
4128
  #resetProcessingState(ctx, outcome) {
3651
4129
  this.vaultMonitor.restartControllerAttempt(this.cellKey, ctx.traceId, ctx, outcome);
3652
4130
  this.#processing = false;
@@ -3743,6 +4221,7 @@ class Conductor extends Orchestrator {
3743
4221
  this.#processQueue();
3744
4222
  }
3745
4223
  }
4224
+ /** Registers the decision engine and subscribes to controller lifecycle events. */
3746
4225
  #registerDecisionEngine() {
3747
4226
  this.decisionEngine = new DecisionEngine(this.#controllers, this.#events$);
3748
4227
  this.#events$.subscribe({
@@ -3751,6 +4230,8 @@ class Conductor extends Orchestrator {
3751
4230
  this.vaultMonitor.conductorLicenseDenied(this.cellKey, event.traceId);
3752
4231
  this.#conductorLicenseStatus = ConductorLicenseStatusTypes.Denied;
3753
4232
  const error = new Error(`${this.cellKey} Conductor Decision Engine: The FeatureCell received a "License Denied". Pipeline is disabled.`);
4233
+ // eslint-disable-next-line
4234
+ console.error(`[vault] ${error.message}`);
3754
4235
  vaultDebug(error.message);
3755
4236
  this.privateErrorService.setError(createVaultError(error, this.cellKey));
3756
4237
  this.#attemptQueue.length = 0;
@@ -3808,6 +4289,7 @@ class Conductor extends Orchestrator {
3808
4289
  }
3809
4290
  });
3810
4291
  }
4292
+ /** Builds an isolated pipeline context for a single attempt. */
3811
4293
  #buildPipelineCtx(ctx, operation, options) {
3812
4294
  const traceId = assignTraceId();
3813
4295
  return {
@@ -3826,10 +4308,12 @@ class Conductor extends Orchestrator {
3826
4308
  incoming: undefined
3827
4309
  };
3828
4310
  }
4311
+ /** Clears the attempt queue and resets the processing flag. */
3829
4312
  #resetConductor() {
3830
4313
  this.#attemptQueue.length = 0;
3831
4314
  this.#processing = false;
3832
4315
  }
4316
+ /** Invokes destroy on all registered controllers. */
3833
4317
  #destroyControllers(ctx) {
3834
4318
  for (const controller of this.#controllers) {
3835
4319
  this.vaultMonitor.startDestroy(this.cellKey, controller.key, ctx);
@@ -3843,6 +4327,7 @@ class Conductor extends Orchestrator {
3843
4327
  }
3844
4328
  }
3845
4329
  }
4330
+ /** Invokes reset on all registered controllers. */
3846
4331
  #resetControllers(ctx) {
3847
4332
  for (const controller of this.#controllers) {
3848
4333
  this.vaultMonitor.startReset(this.cellKey, controller.key, ctx);
@@ -3856,6 +4341,7 @@ class Conductor extends Orchestrator {
3856
4341
  }
3857
4342
  }
3858
4343
  }
4344
+ /** Adds the default or user-supplied error controller to the controller list. */
3859
4345
  #addDefaultErrorController(controllers, config) {
3860
4346
  const errorControllers = config.controllers.filter((controllerClass) => {
3861
4347
  return controllerClass.type === ControllerTypes.Error;
@@ -3871,6 +4357,7 @@ class Conductor extends Orchestrator {
3871
4357
  controllers.unshift(withCoreErrorController);
3872
4358
  }
3873
4359
  }
4360
+ /** Removes reserved controller types from the user-supplied list. */
3874
4361
  #filterRestrictedControllers(controllers) {
3875
4362
  return controllers.filter((controller) => {
3876
4363
  if (controller.type === ControllerTypes.License || controller.type === ControllerTypes.CoreAbstain) {
@@ -3883,6 +4370,7 @@ class Conductor extends Orchestrator {
3883
4370
  // ---------------------------------------------------------------------------
3884
4371
  // INTERNAL SCHEDULING
3885
4372
  // ---------------------------------------------------------------------------
4373
+ /** Initializes all controllers and registers the decision engine. */
3886
4374
  #registerControllers(config) {
3887
4375
  config.controllers = config.controllers ?? [];
3888
4376
  const allControllers = this.#filterRestrictedControllers(config.controllers);
@@ -3923,12 +4411,14 @@ class Conductor extends Orchestrator {
3923
4411
  this.vaultMonitor.endControllerVote(this.cellKey, pending.controllerCtx.traceId, pending.controllerCtx, decision);
3924
4412
  }), map((decision) => decision.outcome));
3925
4413
  }
4414
+ /** Signals a deny-state settlement for DevMode testing. */
3926
4415
  #denyAttemptCompleted() {
3927
4416
  if (!DevMode.active)
3928
4417
  return;
3929
4418
  this.#settled$.next();
3930
4419
  }
3931
4420
  // ADD
4421
+ /** Signals queue settlement when all attempts have been processed. */
3932
4422
  #attemptCompleted() {
3933
4423
  if (!DevMode.active || this.#attemptQueue.length > 0)
3934
4424
  return;
@@ -3936,6 +4426,7 @@ class Conductor extends Orchestrator {
3936
4426
  this.#settled$.next();
3937
4427
  });
3938
4428
  }
4429
+ /** Returns a promise that resolves when the conductor has settled. */
3939
4430
  #conductorSettled() {
3940
4431
  return firstValueFrom(this.#settled$);
3941
4432
  }
@@ -3987,27 +4478,46 @@ function featureCellValidation(descriptor, behaviors = []) {
3987
4478
  }
3988
4479
  }
3989
4480
 
3990
- // --- AI Model File Path (DO NOT DELETE) ---
3991
- // FilePath: projects > engine > src > lib > factories > feature-cell > feature-cell.builder.ts
3992
- // Updated: 2026-03-02 19:52
3993
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
3994
- // cmd+alt+j (see .vscode/keybindings.json)
3995
- // --- END AI MODEL FILE PATH ---
4481
+ /**
4482
+ * Abstract builder that assembles the fluent configuration API and
4483
+ * lifecycle wiring for a FeatureCell. Subclasses call setup() to obtain
4484
+ * a CellBuilderContract, then build the final FeatureCellShape from it.
4485
+ * The builder manages conductor creation, initialization guards, and
4486
+ * state operation dispatch.
4487
+ */
3996
4488
  class FeatureCellBuilder {
3997
4489
  featureCellConfiguration;
3998
4490
  defaultBehaviors;
3999
4491
  behaviors;
4000
4492
  controllers;
4493
+ /** Whether the cell encountered a critical failure and is permanently unusable. */
4001
4494
  #cellCorrupt = false;
4495
+ /** Conductor instance managing pipeline execution for this cell. */
4002
4496
  #conductor;
4497
+ /** Whether the cell has been initialized via the builder. */
4003
4498
  #initialized = false;
4499
+ /** Vault monitor instance for tracing lifecycle events. */
4004
4500
  #vaultMonitor = VaultMonitor();
4501
+ /** Reference to the constructed FeatureCellBaseShape. */
4005
4502
  cell;
4503
+ /** Unique key identifying this FeatureCell. */
4006
4504
  cellKey;
4505
+ /** Shared behavior context for pipeline execution. */
4007
4506
  ctx;
4507
+ /** Subject signaling cell destruction. */
4008
4508
  destroyed$ = new Subject();
4509
+ /** Subject signaling cell reset. */
4009
4510
  reset$ = new Subject();
4511
+ /** Subject emitting state snapshots to subscribers. */
4010
4512
  state$ = new Subject();
4513
+ /**
4514
+ * Creates the builder and initializes the shared behavior context.
4515
+ *
4516
+ * @param featureCellConfiguration - FeatureCell descriptor configuration.
4517
+ * @param defaultBehaviors - Default behavior classes provided by the framework.
4518
+ * @param behaviors - User-supplied behavior classes.
4519
+ * @param controllers - User-supplied controller classes.
4520
+ */
4011
4521
  constructor(
4012
4522
  // kept for parity with original API, even if not used directly
4013
4523
  featureCellConfiguration, defaultBehaviors, behaviors, controllers) {
@@ -4018,6 +4528,11 @@ class FeatureCellBuilder {
4018
4528
  this.cellKey = this.featureCellConfiguration.key;
4019
4529
  this.ctx = this.#buildCtx();
4020
4530
  }
4531
+ /**
4532
+ * Builds the initial behavior context with locked snapshot reference.
4533
+ *
4534
+ * @returns The constructed behavior context.
4535
+ */
4021
4536
  #buildCtx() {
4022
4537
  const destroyed$ = this.destroyed$.asObservable();
4023
4538
  const state$ = this.state$;
@@ -4055,6 +4570,7 @@ class FeatureCellBuilder {
4055
4570
  // ---------------------------------------------------------------------------
4056
4571
  // INTERNAL LIFECYCLE
4057
4572
  // ---------------------------------------------------------------------------
4573
+ /** Resets the conductor and emits a reset signal. */
4058
4574
  reset() {
4059
4575
  this.#vaultMonitor.startReset(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4060
4576
  vaultWarn(`${VAULT_FEATURE_CELL}: reset`);
@@ -4063,6 +4579,7 @@ class FeatureCellBuilder {
4063
4579
  this.#conductor?.reset(this.ctx);
4064
4580
  this.#vaultMonitor.endReset(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4065
4581
  }
4582
+ /** Destroys the conductor, completes all subjects, and emits destruction signals. */
4066
4583
  destroy() {
4067
4584
  this.#vaultMonitor.startDestroy(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4068
4585
  vaultWarn(`${VAULT_FEATURE_CELL}: destroy`);
@@ -4074,6 +4591,7 @@ class FeatureCellBuilder {
4074
4591
  this.state$.complete();
4075
4592
  this.#vaultMonitor.endDestroy(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4076
4593
  }
4594
+ /** Throws if the cell is corrupt or has not been initialized. */
4077
4595
  #ensureInitialized() {
4078
4596
  if (this.#cellCorrupt) {
4079
4597
  const errorMessage = `[vault] FeatureCell "${this.featureCellConfiguration.key}" encountered a critical initialization failure and is now in a corrupted state. Further use is blocked.`;
@@ -4086,6 +4604,7 @@ class FeatureCellBuilder {
4086
4604
  throw new Error(errorMessage);
4087
4605
  }
4088
4606
  }
4607
+ /** Creates the conductor, validates the cell, and starts the initialization lifecycle. */
4089
4608
  #initialize(ctx) {
4090
4609
  if (this.#initialized) {
4091
4610
  const errorMessage = `[vault] FeatureCell "${this.featureCellConfiguration.key}" already initialized.`;
@@ -4113,8 +4632,10 @@ class FeatureCellBuilder {
4113
4632
  filterCallbacks: ctx.filterFunctions,
4114
4633
  initialState: ctx.hydrate || this.featureCellConfiguration.initialState,
4115
4634
  interceptors: ctx.interceptors,
4635
+ lastSnapshot: this.ctx.lastSnapshot,
4116
4636
  operators: ctx.operators,
4117
- reducerCallbacks: ctx.reducerFunctions
4637
+ reducerCallbacks: ctx.reducerFunctions,
4638
+ state$: this.state$
4118
4639
  });
4119
4640
  this.#conductor.initialize(this.ctx);
4120
4641
  if (DevMode.active) {
@@ -4136,11 +4657,17 @@ class FeatureCellBuilder {
4136
4657
  throw err;
4137
4658
  }
4138
4659
  }
4660
+ /** Marks the cell as corrupt, logs a runtime error, and throws. */
4139
4661
  #handleCorruptionError(message) {
4140
4662
  this.#cellCorrupt = true;
4141
4663
  this.#vaultMonitor.runtimeError(this.cellKey, VAULT_FEATURE_CELL, this.ctx, message);
4142
4664
  throw new Error(message);
4143
4665
  }
4666
+ /**
4667
+ * Constructs the fluent CellBuilderContract with pre-initialization guards.
4668
+ *
4669
+ * @returns The builder contract exposing configuration and initialize methods.
4670
+ */
4144
4671
  setup() {
4145
4672
  const afterTapCallbacks = [];
4146
4673
  const beforeTapCallbacks = [];
@@ -4253,26 +4780,41 @@ class FeatureCellBuilder {
4253
4780
  // ---------------------------------------------------------------------------
4254
4781
  // STATE OPERATIONS
4255
4782
  // ---------------------------------------------------------------------------
4783
+ /** Dispatches a merge operation through the conductor pipeline. */
4256
4784
  mergeState(incoming, options) {
4257
4785
  this.#ensureInitialized();
4258
4786
  return this.#conductor.conduct(this.ctx, incoming, OperationTypes.Merge, options);
4259
4787
  }
4788
+ /** Dispatches a replace operation through the conductor pipeline. */
4260
4789
  replaceState(incoming, options) {
4261
4790
  this.#ensureInitialized();
4262
4791
  return this.#conductor.conduct(this.ctx, incoming, OperationTypes.Replace, options);
4263
4792
  }
4264
4793
  }
4265
4794
 
4266
- // --- AI Model File Path (DO NOT DELETE) ---
4267
- // FilePath: projects > engine > src > lib > factories > feature-cell > feature-cell.class.ts
4268
- // Updated: 2026-03-02 19:52
4269
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
4270
- // cmd+alt+j (see .vscode/keybindings.json)
4271
- // --- END AI MODEL FILE PATH ---
4795
+ /**
4796
+ * Concrete FeatureCell factory that extends the builder to produce a
4797
+ * fully configured FeatureCellShape instance. The class wires fluent
4798
+ * API extensions from behaviors and controllers onto the resulting
4799
+ * cell and attaches non-enumerable context and key properties.
4800
+ */
4272
4801
  class FeatureCellClass extends FeatureCellBuilder {
4802
+ /**
4803
+ * Creates a new FeatureCellClass with the provided descriptor and behavior/controller lists.
4804
+ *
4805
+ * @param descriptor - FeatureCell configuration descriptor.
4806
+ * @param defaultBehaviors - Default behavior classes provided by the framework.
4807
+ * @param behaviors - User-supplied behavior classes.
4808
+ * @param controllers - User-supplied controller classes.
4809
+ */
4273
4810
  constructor(descriptor, defaultBehaviors, behaviors, controllers) {
4274
4811
  super(descriptor, defaultBehaviors, behaviors, controllers);
4275
4812
  }
4813
+ /**
4814
+ * Assembles and returns a fully configured FeatureCellShape with fluent API extensions.
4815
+ *
4816
+ * @returns The constructed FeatureCellShape instance.
4817
+ */
4276
4818
  build() {
4277
4819
  const builder = this.setup();
4278
4820
  const ctx = this.ctx;
@@ -4403,12 +4945,6 @@ function resetFeatureCellToken() {
4403
4945
  featureCellTokenRequested.clear();
4404
4946
  }
4405
4947
 
4406
- // --- AI Model File Path (DO NOT DELETE) ---
4407
- // FilePath: lib > public-api.ts
4408
- // Updated: 2026-03-30 15:42
4409
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
4410
- // cmd+alt+j (see .vscode/keybindings.json)
4411
- // --- END AI MODEL FILE PATH ---
4412
4948
  /*
4413
4949
  * This is for version support in dev mode and tracking in the devtools
4414
4950
  */
@@ -4417,5 +4953,5 @@ function resetFeatureCellToken() {
4417
4953
  * Generated bundle index. Do not edit.
4418
4954
  */
4419
4955
 
4420
- export { Conductor, FeatureCellClass, LicensingAbstract, VAULT_LICENSE_ID, VaultCore, VerifyLicenseToken, createFeatureCellToken, getFeatureCellToken, getLicensePayload, getVaultRegistryForTests, hasVaultLicense, isAuthorizedKey, isBypassLicensing, isPipelineTerminal, registerFeatureCell, registerVaultSettled, resetFeatureCellRegistry, resetVaultForTests, vaultAllSettled, vaultSettled };
4956
+ export { Conductor, FeatureCellClass, LicensingAbstract, VAULT_LICENSE_ID, VaultCore, VerifyLicenseToken, createFeatureCellToken, getFeatureCellToken, getLicensePayload, getVaultRegistryForTests, hasVaultLicense, isAuthorizedKey, isBypassLicensing, isPipelineTerminal, registerFeatureCell, registerVaultSettled, resetFeatureCellRegistry, resetVaultForTests, vaultAllSettled, vaultSettled, verifyLicensePayload };
4421
4957
  //# sourceMappingURL=sdux-vault-engine.mjs.map