@sdux-vault/engine 0.25.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.
@@ -4,14 +4,10 @@ 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.25.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',
@@ -1572,34 +1644,58 @@ const KNOWN_VAULT_KEYS = new Set([
1572
1644
  */
1573
1645
  const VAULT_LICENSE_ID = 'sdux-vault';
1574
1646
 
1575
- // --- AI Model File Path (DO NOT DELETE) ---
1576
- // FilePath: projects > engine > src > lib > factories > vault > vault-core.function.ts
1577
- // Updated: 2026-03-02 19:52
1578
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
1579
- // cmd+alt+j (see .vscode/keybindings.json)
1580
- // --- END AI MODEL FILE PATH ---
1647
+ /** Behavior key used to identify the core license behavior during validation. */
1581
1648
  const CORE_LICENSE_BEHAVIOR_KEY = 'SDUX::Behavior::Core::License';
1649
+ /** Cached singleton instance of the VaultCore runtime. */
1582
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
+ */
1583
1656
  function VaultCore(config = {}) {
1584
1657
  if (!instance) {
1585
1658
  instance = new VaultCoreInstance(config);
1586
1659
  }
1587
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
+ */
1588
1666
  class VaultCoreInstance {
1667
+ /** Subscription to the licensing event bus. */
1589
1668
  #licensingSub;
1669
+ /** Subscription to the validation result bus. */
1590
1670
  #validaionSub;
1671
+ /** Map of license IDs to their decoded payloads. */
1591
1672
  #licenseMap = new Map();
1673
+ /** Tracks FeatureCells that have reached a terminal license status. */
1592
1674
  #terminalStatus = new Map();
1675
+ /** Whether AI-assist capabilities have been enabled. */
1593
1676
  #aiAssistEnabled = false;
1677
+ /** Whether licensing checks are bypassed in dev mode. */
1594
1678
  #bypassLicensing = false;
1679
+ /** Timeout duration in milliseconds for pending license evaluations. */
1595
1680
  #licenseTimeoutMs;
1681
+ /** Active timeout handles for pending license evaluations keyed by FeatureCell. */
1596
1682
  // eslint-disable-next-line
1597
1683
  #licenseTimers = new Map();
1684
+ /** Subject emitting licensing events to the licensing service. */
1598
1685
  #licensingBus$ = new Subject();
1686
+ /** ReplaySubject emitting license validation results. */
1599
1687
  #validationBus$ = new ReplaySubject();
1688
+ /** Last published license status per FeatureCell key. */
1600
1689
  #lastStatus = new Map();
1690
+ /** Frozen global Vault configuration. */
1601
1691
  #vaultConfig;
1692
+ /** Registry of FeatureCell registration records keyed by cell key. */
1602
1693
  #registry = new Map();
1694
+ /**
1695
+ * Creates the VaultCore singleton and initializes licensing infrastructure.
1696
+ *
1697
+ * @param config - Raw Vault configuration.
1698
+ */
1603
1699
  constructor(config) {
1604
1700
  InitializeLicensingService(this.#licensingBus$, this.#validationBus$.asObservable());
1605
1701
  this.setVaultConfig(config);
@@ -1634,6 +1730,7 @@ class VaultCoreInstance {
1634
1730
  this.#licenseTimeoutMs = config.licenseTimeoutMs ?? 15_000;
1635
1731
  this.#warnIfAccidentalDevMode();
1636
1732
  }
1733
+ /** Resets all internal state for test isolation. */
1637
1734
  resetForTesting() {
1638
1735
  this.#licensingSub?.unsubscribe();
1639
1736
  this.#licensingSub = undefined;
@@ -1644,40 +1741,87 @@ class VaultCoreInstance {
1644
1741
  this.#lastStatus.clear();
1645
1742
  this.#licenseMap.clear();
1646
1743
  }
1744
+ /** Clears the FeatureCell registration registry. */
1647
1745
  resetFeatureCellRegistry() {
1648
1746
  this.#registry.clear();
1649
1747
  }
1748
+ /**
1749
+ * Registers a FeatureCell key in the runtime registry.
1750
+ *
1751
+ * @param key - Unique FeatureCell identifier.
1752
+ */
1650
1753
  registerCellRuntime(key) {
1651
1754
  this.#ensureRecord(key);
1652
1755
  }
1756
+ /**
1757
+ * Registers behavior entities for a FeatureCell.
1758
+ *
1759
+ * @param key - FeatureCell key.
1760
+ * @param behaviors - Array of behavior entity descriptors.
1761
+ */
1653
1762
  registerBehaviors(key, behaviors) {
1654
1763
  const record = this.#ensureRecord(key);
1655
1764
  record.behaviors = this.#registerEntities(behaviors);
1656
1765
  record.behaviorsRegistered = true;
1657
1766
  }
1767
+ /**
1768
+ * Registers controller entities for a FeatureCell.
1769
+ *
1770
+ * @param key - FeatureCell key.
1771
+ * @param controllers - Array of controller entity descriptors.
1772
+ */
1658
1773
  registerControllers(key, controllers) {
1659
1774
  const record = this.#ensureRecord(key);
1660
1775
  record.controllers = this.#registerEntities(controllers);
1661
1776
  record.controllersRegistered = true;
1662
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
+ */
1663
1784
  registerFluentApis(key, summary) {
1664
1785
  const record = this.#ensureRecord(key);
1665
1786
  record.fluentApis = Object.freeze(summary);
1666
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
+ */
1667
1794
  getLicensePayload(licenseId) {
1668
1795
  return this.#licenseMap.get(licenseId);
1669
1796
  }
1797
+ /**
1798
+ * Returns whether licensing checks are bypassed.
1799
+ *
1800
+ * @returns True when bypass licensing is active.
1801
+ */
1670
1802
  isBypassLicensing() {
1671
1803
  return this.#bypassLicensing;
1672
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
+ */
1673
1811
  isAuthorizedKey(key) {
1674
1812
  return KNOWN_VAULT_KEYS.has(key);
1675
1813
  }
1814
+ /**
1815
+ * Returns whether a Vault-level license has been registered.
1816
+ *
1817
+ * @returns True when a Vault license exists.
1818
+ */
1676
1819
  hasVaultLicense() {
1677
1820
  return this.#licenseMap.has(VAULT_LICENSE_ID);
1678
1821
  }
1679
1822
  //#endregion
1680
1823
  //#region private Methods
1824
+ /** Populates the license map from the supplied license configurations. */
1681
1825
  #initializeLicenses(licenses) {
1682
1826
  if (!licenses?.length)
1683
1827
  return;
@@ -1687,6 +1831,7 @@ class VaultCoreInstance {
1687
1831
  this.#licenseMap.set(license.licenseId, license.payload);
1688
1832
  }
1689
1833
  }
1834
+ /** Freezes and registers an array of entity descriptors into a keyed map. */
1690
1835
  #registerEntities(entities) {
1691
1836
  return new Map(entities.map((entity) => {
1692
1837
  let needsLicense;
@@ -1708,6 +1853,7 @@ class VaultCoreInstance {
1708
1853
  return [entity.key, Object.freeze(frozen)];
1709
1854
  }));
1710
1855
  }
1856
+ /** Subscribes to the licensing bus and routes events to the appropriate handlers. */
1711
1857
  #subscribeToLicensingEvents() {
1712
1858
  this.#licensingSub = this.#licensingBus$.subscribe((event) => {
1713
1859
  switch (event.type) {
@@ -1741,6 +1887,7 @@ class VaultCoreInstance {
1741
1887
  }
1742
1888
  });
1743
1889
  }
1890
+ /** Starts a timeout timer for pending licenses on a FeatureCell. */
1744
1891
  #startLicenseTimeout(featureCellKey) {
1745
1892
  if (!this.#licenseTimeoutMs)
1746
1893
  return;
@@ -1752,6 +1899,7 @@ class VaultCoreInstance {
1752
1899
  }, this.#licenseTimeoutMs);
1753
1900
  this.#licenseTimers.set(featureCellKey, timer);
1754
1901
  }
1902
+ /** Expires all pending licenses for a FeatureCell and publishes a denial. */
1755
1903
  #expirePendingLicenses(featureCellKey) {
1756
1904
  const record = this.#registry.get(featureCellKey);
1757
1905
  if (!record)
@@ -1775,6 +1923,7 @@ class VaultCoreInstance {
1775
1923
  this.#clearLicenseTimer(featureCellKey);
1776
1924
  }
1777
1925
  // Do not evaluate until both sides registered
1926
+ /** Evaluates and emits the aggregate license status for a FeatureCell. */
1778
1927
  #emitLicenseStatus(featureCellKey) {
1779
1928
  const record = this.#registry.get(featureCellKey);
1780
1929
  if (!record)
@@ -1804,6 +1953,7 @@ class VaultCoreInstance {
1804
1953
  // All valid
1805
1954
  this.#publishStatus(featureCellKey, true);
1806
1955
  }
1956
+ /** Clears the license timeout timer for a FeatureCell. */
1807
1957
  #clearLicenseTimer(featureCellKey) {
1808
1958
  const timer = this.#licenseTimers.get(featureCellKey);
1809
1959
  if (timer) {
@@ -1811,6 +1961,7 @@ class VaultCoreInstance {
1811
1961
  this.#licenseTimers.delete(featureCellKey);
1812
1962
  }
1813
1963
  }
1964
+ /** Publishes a terminal license validation result for a FeatureCell. */
1814
1965
  #publishStatus(featureCellKey, approved) {
1815
1966
  if (this.#terminalStatus.has(featureCellKey))
1816
1967
  return;
@@ -1822,6 +1973,7 @@ class VaultCoreInstance {
1822
1973
  approved
1823
1974
  });
1824
1975
  }
1976
+ /** Routes a license validation event to the appropriate entity maps. */
1825
1977
  #handleLicenseValidation(event) {
1826
1978
  const { featureCellKey, key, licenseToken, valid } = event;
1827
1979
  if (this.#terminalStatus.has(event.featureCellKey))
@@ -1839,6 +1991,7 @@ class VaultCoreInstance {
1839
1991
  this.#enableAiAssist();
1840
1992
  }
1841
1993
  }
1994
+ /** Applies a license validation result to a single entity within a map. */
1842
1995
  #applyLicenseValidation(entities, key, licenseId, valid) {
1843
1996
  if (!entities?.has(key))
1844
1997
  return;
@@ -1861,6 +2014,7 @@ class VaultCoreInstance {
1861
2014
  validLicense: valid ? VaultRegistrationLicenseStatusTypes.Valid : VaultRegistrationLicenseStatusTypes.Revoked
1862
2015
  }));
1863
2016
  }
2017
+ /** Records a license token against the matching entity in the registry. */
1864
2018
  #recordLicenses(event) {
1865
2019
  const { featureCellKey, key, licenseToken } = event;
1866
2020
  const record = this.#registry.get(featureCellKey);
@@ -1873,6 +2027,7 @@ class VaultCoreInstance {
1873
2027
  this.#recordLicense(record.behaviors, key, licenseToken);
1874
2028
  this.#recordLicense(record.controllers, key, licenseToken);
1875
2029
  }
2030
+ /** Writes a license ID to a single entity if it requires a license. */
1876
2031
  #recordLicense(entities, key, licenseId) {
1877
2032
  if (!entities?.has(key))
1878
2033
  return;
@@ -1890,6 +2045,7 @@ class VaultCoreInstance {
1890
2045
  licenseId
1891
2046
  }));
1892
2047
  }
2048
+ /** Emits a console warning when dev mode is active outside a test environment. */
1893
2049
  #warnIfAccidentalDevMode() {
1894
2050
  if (DevMode.active && !isTestEnv.active) {
1895
2051
  // eslint-disable-next-line
@@ -1899,6 +2055,7 @@ class VaultCoreInstance {
1899
2055
  `If this is intentional, you can safely ignore this message.`);
1900
2056
  }
1901
2057
  }
2058
+ /** Summarizes fluent API callback counts from a feature description event. */
1902
2059
  #summarizeFluent(event) {
1903
2060
  const fluent = event?.fluentApis ?? {};
1904
2061
  return {
@@ -1910,12 +2067,14 @@ class VaultCoreInstance {
1910
2067
  errorCallbacks: Array.isArray(fluent?.errorCallbacks) ? fluent.errorCallbacks.length : 0
1911
2068
  };
1912
2069
  }
2070
+ /** Returns or creates the registry record for a FeatureCell key. */
1913
2071
  #ensureRecord(key) {
1914
2072
  if (!this.#registry.has(key)) {
1915
2073
  this.#registry.set(key, { key, behaviorsRegistered: false, controllersRegistered: false });
1916
2074
  }
1917
2075
  return this.#registry.get(key);
1918
2076
  }
2077
+ /** Enables AI-assist capabilities when a core license is validated. */
1919
2078
  #enableAiAssist() {
1920
2079
  if (this.#aiAssistEnabled)
1921
2080
  return;
@@ -1930,6 +2089,7 @@ class VaultCoreInstance {
1930
2089
  globalThis.sdux.debugWidget.aiAssistEnabled = true;
1931
2090
  document.dispatchEvent(new CustomEvent('sdux-license-resolved'));
1932
2091
  }
2092
+ /** Injects the DevTools debug widget into the global scope. */
1933
2093
  #injectDebugWidget() {
1934
2094
  if (!DevMode.active)
1935
2095
  return;
@@ -1945,10 +2105,21 @@ class VaultCoreInstance {
1945
2105
  }
1946
2106
  //#endregion
1947
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
+ */
1948
2114
  registerVaultSettled(key, fn) {
1949
2115
  const record = this.#ensureRecord(key);
1950
2116
  record.vaultSettled = fn;
1951
2117
  }
2118
+ /**
2119
+ * Awaits the settled callback for a specific FeatureCell.
2120
+ *
2121
+ * @param key - FeatureCell key to await.
2122
+ */
1952
2123
  async awaitFeatureCellSettled(key) {
1953
2124
  const record = this.#registry.get(key);
1954
2125
  if (!record) {
@@ -1959,6 +2130,7 @@ class VaultCoreInstance {
1959
2130
  await Promise.resolve(); // flush microtasks
1960
2131
  }
1961
2132
  }
2133
+ /** Awaits settled callbacks for all registered FeatureCells. */
1962
2134
  async awaitAllSettled() {
1963
2135
  for (const record of this.#registry.values()) {
1964
2136
  if (typeof record.vaultSettled === 'function') {
@@ -1968,11 +2140,21 @@ class VaultCoreInstance {
1968
2140
  await Promise.resolve();
1969
2141
  }
1970
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
+ */
1971
2148
  getRegistrySnapshot() {
1972
2149
  // Return a shallow cloned map so tests cannot mutate internal state
1973
2150
  return new Map(this.#registry);
1974
2151
  }
1975
2152
  }
2153
+ /**
2154
+ * Registers a FeatureCell entry in the global Vault registry.
2155
+ *
2156
+ * @param entry - Registration descriptor containing the FeatureCell key.
2157
+ */
1976
2158
  function registerFeatureCell(entry) {
1977
2159
  if (!instance) {
1978
2160
  throw new Error('[vault] Vault not initialized.');
@@ -1985,6 +2167,12 @@ function registerFeatureCell(entry) {
1985
2167
  }
1986
2168
  instance.registerCellRuntime(entry.key);
1987
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
+ */
1988
2176
  function getLicensePayload(licenseId) {
1989
2177
  if (!instance) {
1990
2178
  throw new Error('[vault] Vault not initialized.');
@@ -1994,17 +2182,29 @@ function getLicensePayload(licenseId) {
1994
2182
  }
1995
2183
  return instance.getLicensePayload(licenseId);
1996
2184
  }
2185
+ /** Awaits settled callbacks for all registered FeatureCells. */
1997
2186
  async function vaultAllSettled() {
1998
2187
  if (!instance)
1999
2188
  return;
2000
2189
  await instance.awaitAllSettled();
2001
2190
  }
2191
+ /**
2192
+ * Awaits the settled callback for a specific FeatureCell.
2193
+ *
2194
+ * @param key - FeatureCell key to await.
2195
+ */
2002
2196
  async function vaultSettled(key) {
2003
2197
  if (!instance) {
2004
2198
  throw new Error('[vault] Vault not initialized.');
2005
2199
  }
2006
2200
  await instance.awaitFeatureCellSettled(key);
2007
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
+ */
2008
2208
  function registerVaultSettled(key, vaultSettled) {
2009
2209
  if (!instance) {
2010
2210
  throw new Error('[vault] Vault not initialized.');
@@ -2028,15 +2228,27 @@ function resetVaultForTests() {
2028
2228
  instance?.resetForTesting();
2029
2229
  instance = null;
2030
2230
  }
2231
+ /** Clears the FeatureCell registration registry. */
2031
2232
  function resetFeatureCellRegistry() {
2032
2233
  instance?.resetFeatureCellRegistry();
2033
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
+ */
2034
2240
  function getVaultRegistryForTests() {
2035
2241
  if (!instance) {
2036
2242
  throw new Error('[vault] Vault not initialized.');
2037
2243
  }
2038
2244
  return instance.getRegistrySnapshot();
2039
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
+ */
2040
2252
  function isAuthorizedKey(key) {
2041
2253
  if (!instance)
2042
2254
  return false;
@@ -2044,11 +2256,21 @@ function isAuthorizedKey(key) {
2044
2256
  return true;
2045
2257
  return instance.isAuthorizedKey(key);
2046
2258
  }
2259
+ /**
2260
+ * Returns whether licensing checks are currently bypassed.
2261
+ *
2262
+ * @returns True when bypass licensing is active.
2263
+ */
2047
2264
  function isBypassLicensing() {
2048
2265
  if (!instance)
2049
2266
  return false;
2050
2267
  return instance.isBypassLicensing();
2051
2268
  }
2269
+ /**
2270
+ * Returns whether a Vault-level license has been registered.
2271
+ *
2272
+ * @returns True when a Vault license exists.
2273
+ */
2052
2274
  function hasVaultLicense() {
2053
2275
  if (!instance)
2054
2276
  return false;
@@ -2366,27 +2588,19 @@ MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuXto+eRaFm9pObys/IEI ASwV1wgGvNGJsiy
2366
2588
  `
2367
2589
  };
2368
2590
 
2369
- /**
2370
- * Static license verification utility used to validate signed license tokens
2371
- * against tier-specific public keys. Tokens use a dot-separated format:
2372
- * `base64(payload).base64(signature)`.
2373
- *
2374
- * The verification process:
2375
- * - Splits the token on `.` to extract the encoded payload and signature
2376
- * - Decodes the payload from base64 to determine the license tier
2377
- * - Rejects tokens with missing or unrecognized tier
2378
- * - Loads the appropriate PEM-encoded public key for the tier
2379
- * - Uses `crypto.subtle.verify()` (RSA-SHA256) to validate the signature
2380
- * against the raw base64-encoded payload string
2381
- *
2382
- * Verification failures return `false` rather than throwing.
2383
- */
2591
+ /** Whether license details have already been logged to the console. */
2384
2592
  let hasLoggedLicenseDetails = false;
2593
+ /** Resets the license details log flag for test isolation. */
2385
2594
  function resetLicenseDetailsLog() {
2386
2595
  if (!DevMode.active)
2387
2596
  return;
2388
2597
  hasLoggedLicenseDetails = false;
2389
2598
  }
2599
+ /**
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.
2603
+ */
2390
2604
  const VerifyLicenseToken = {
2391
2605
  /**
2392
2606
  * Verifies the supplied signed license token using the public key associated
@@ -2524,6 +2738,12 @@ function formatLicenseDate(value) {
2524
2738
  }).format(new Date(value));
2525
2739
  }
2526
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
+ */
2527
2747
  async function verifyLicensePayload(licensePayload) {
2528
2748
  try {
2529
2749
  if (!licensePayload) {
@@ -2536,13 +2756,29 @@ async function verifyLicensePayload(licensePayload) {
2536
2756
  }
2537
2757
  }
2538
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
+ */
2539
2764
  class LicensingAbstract {
2765
+ /** Whether this class requires a valid license to operate. */
2540
2766
  static needsLicense;
2767
+ /** Static key assigned by the VaultBehavior or VaultController decorator. */
2541
2768
  static key;
2769
+ /** License token received from the licensing service. */
2542
2770
  #licenseToken;
2771
+ /** Key of the FeatureCell this instance belongs to. */
2543
2772
  #featureCellKey;
2773
+ /** Key identifying this behavior or controller. */
2544
2774
  #key;
2775
+ /** Licensing service used to request and validate licenses. */
2545
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
+ */
2546
2782
  constructor(ctx) {
2547
2783
  const ctor = this.constructor;
2548
2784
  if (typeof ctor.key !== 'string' || !ctor.key.trim()) {
@@ -2555,9 +2791,15 @@ class LicensingAbstract {
2555
2791
  this.#requestLicense();
2556
2792
  }
2557
2793
  }
2794
+ /** Requests a license token from the licensing service. */
2558
2795
  #requestLicense() {
2559
2796
  this.#licenseToken = this.#licenseService.requestLicense(this.#featureCellKey, this.#key);
2560
2797
  }
2798
+ /**
2799
+ * Validates the previously requested license token.
2800
+ *
2801
+ * @param valid - Whether the license should be marked as approved.
2802
+ */
2561
2803
  validateLicense(valid) {
2562
2804
  if (!this.#licenseToken) {
2563
2805
  throw new VaultLicenseError(`validateLicense() called but no license was requested for "${this.#featureCellKey}" and "${this.#key}".`);
@@ -2566,24 +2808,45 @@ class LicensingAbstract {
2566
2808
  }
2567
2809
  }
2568
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
+ */
2569
2817
  let withCoreLicenseBehavior = class withCoreLicenseBehavior extends LicensingAbstract {
2570
2818
  behaviorCtx;
2819
+ /** Static behavior type assigned by the VaultBehavior decorator. */
2571
2820
  static type;
2821
+ /** Static behavior key assigned by the VaultBehavior decorator. */
2572
2822
  static key;
2823
+ /** Static critical flag assigned by the VaultBehavior decorator. */
2573
2824
  static critical;
2825
+ /** Static license requirement flag assigned by the VaultBehavior decorator. */
2574
2826
  static needsLicense;
2827
+ /** Instance behavior type for core license evaluation. */
2575
2828
  type = BehaviorTypes.CoreLicense;
2829
+ /** Instance critical flag indicating this behavior is required. */
2576
2830
  critical = true;
2831
+ /** Unique key identifying this behavior instance. */
2577
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
+ */
2578
2839
  constructor(key, behaviorCtx) {
2579
2840
  super(behaviorCtx);
2580
2841
  this.behaviorCtx = behaviorCtx;
2581
2842
  this.key = key;
2582
2843
  verifyLicensePayload(this.behaviorCtx.licensePayload).then((valid) => this.validateLicense(valid));
2583
2844
  }
2845
+ /** No-op destroy handler for this behavior. */
2584
2846
  destroy() {
2585
2847
  vaultWarn(`${this.key} - destroy noop`);
2586
2848
  }
2849
+ /** No-op reset handler for this behavior. */
2587
2850
  reset() {
2588
2851
  vaultWarn(`${this.key} - reset noop`);
2589
2852
  }
@@ -2598,32 +2861,56 @@ withCoreLicenseBehavior = __decorate([
2598
2861
  })
2599
2862
  ], withCoreLicenseBehavior);
2600
2863
 
2601
- // --- AI Model File Path (DO NOT DELETE) ---
2602
- // FilePath: lib > src > orchestrator > orchestrator.ts
2603
- // Updated: 2026-04-07 16:30
2604
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
2605
- // cmd+alt+j (see .vscode/keybindings.json)
2606
- // --- 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
+ */
2607
2870
  class Orchestrator {
2871
+ /** Registered after-tap callback functions executed post-reduce. */
2608
2872
  #afterTapCallbacks;
2873
+ /** Registered before-tap callback functions executed pre-reduce. */
2609
2874
  #beforeTapCallbacks;
2875
+ /** Full set of instantiated behavior instances for this FeatureCell. */
2610
2876
  #behaviors;
2877
+ /** Subset of behaviors eligible for stage-based pipeline execution. */
2611
2878
  #stageBehaviors;
2879
+ /** Unique key identifying the FeatureCell that owns this orchestrator. */
2612
2880
  cellKey;
2881
+ /** Decision engine used for controller vote evaluation. */
2613
2882
  decisionEngine;
2883
+ /** Core error behavior responsible for normalizing pipeline errors. */
2614
2884
  #coreErrorBehavior;
2885
+ /** Error callback behavior for dispatching errors to user callbacks. */
2615
2886
  #coreErrorCallbackBehavior;
2887
+ /** Emit-state callback behavior for notifying state change listeners. */
2616
2888
  #emitStateCallbackBehavior;
2889
+ /** User-provided emit-state callback functions. */
2617
2890
  #emitStateCallbacks;
2891
+ /** Core state behavior managing snapshot commits and signal emission. */
2618
2892
  #coreStateBehavior;
2893
+ /** Error transform behaviors for custom error shaping. */
2619
2894
  #errorTransformBehaviors;
2895
+ /** User-provided error callback functions. */
2620
2896
  #errorCallbacks;
2897
+ /** Global error service for broadcasting errors across FeatureCells. */
2621
2898
  privateErrorService = VaultPrivateErrorService();
2899
+ /** User-provided filter functions applied during the filter stage. */
2622
2900
  #filterFunctions = [];
2901
+ /** Initial state value or deferred factory for this FeatureCell. */
2623
2902
  #initialState;
2903
+ /** Merge behavior responsible for combining partial and current state. */
2624
2904
  #mergeBehavior;
2905
+ /** User-provided reducer functions applied during the reduce stage. */
2625
2906
  #reducerFunctions;
2907
+ /** Vault monitor instance for tracing pipeline lifecycle events. */
2626
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
+ */
2627
2914
  constructor(config) {
2628
2915
  this.#afterTapCallbacks = config.afterTapCallbacks ?? [];
2629
2916
  this.#beforeTapCallbacks = config.beforeTapCallbacks ?? [];
@@ -2634,20 +2921,25 @@ class Orchestrator {
2634
2921
  this.#initialState = config.initialState;
2635
2922
  this.#reducerFunctions = config.reducerCallbacks ?? [];
2636
2923
  }
2924
+ /** Registers all behaviors from the orchestrator configuration. */
2637
2925
  initializeOrchestrator(config) {
2638
2926
  config.behaviors = config.behaviors ?? [];
2639
2927
  this.#registerBehaviors(config);
2640
2928
  }
2641
2929
  //#region Protected Methods
2930
+ /** Loads the initial state and runs the first pipeline cycle. */
2642
2931
  async initializeFeatureCell(ctx) {
2643
2932
  await this.#loadInitialState(ctx);
2644
2933
  }
2934
+ /** Invokes destroy on all registered behaviors. */
2645
2935
  destroyBehaviors(ctx) {
2646
2936
  this.#destroyBehaviors(ctx);
2647
2937
  }
2938
+ /** Invokes reset on all registered behaviors. */
2648
2939
  resetBehaviors(ctx) {
2649
2940
  this.#resetBehaviors(ctx);
2650
2941
  }
2942
+ /** Routes the pipeline context to the appropriate replace or merge orchestration flow. */
2651
2943
  async orchestrate(ctx, options) {
2652
2944
  // no controllers → pipeline behaves exactly as before
2653
2945
  if (ctx.operation === OperationTypes.Replace) {
@@ -2658,6 +2950,11 @@ class Orchestrator {
2658
2950
  }
2659
2951
  return;
2660
2952
  }
2953
+ /**
2954
+ * Builds a controller context from the current behavior context.
2955
+ *
2956
+ * @returns The controller context snapshot.
2957
+ */
2661
2958
  buildControllerCtx(ctx) {
2662
2959
  return {
2663
2960
  traceId: ctx.traceId,
@@ -2667,6 +2964,11 @@ class Orchestrator {
2667
2964
  operation: ctx.operation
2668
2965
  };
2669
2966
  }
2967
+ /**
2968
+ * Normalizes an incoming state input into a consistent shape.
2969
+ *
2970
+ * @returns The normalized state input value.
2971
+ */
2670
2972
  normalizeIncoming(incoming) {
2671
2973
  if (!incoming)
2672
2974
  return null;
@@ -2680,6 +2982,7 @@ class Orchestrator {
2680
2982
  value: incoming
2681
2983
  };
2682
2984
  }
2985
+ /** Notifies the core state behavior of a controller abort or deny outcome. */
2683
2986
  controllerOutcomeNotification(type, ctx) {
2684
2987
  switch (type) {
2685
2988
  case DecisionOutcomeTypes.Abort: {
@@ -2692,6 +2995,11 @@ class Orchestrator {
2692
2995
  }
2693
2996
  }
2694
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
+ */
2695
3003
  prepareIncoming(ctx, incoming, operation) {
2696
3004
  ctx = this.#prepIncomingForOrchestration(ctx, incoming, operation);
2697
3005
  const normalizedIncoming = this.#coreStateBehavior.preparePipelineIncoming(ctx);
@@ -2711,12 +3019,14 @@ class Orchestrator {
2711
3019
  }
2712
3020
  //#endregion
2713
3021
  //#region Private Methods
3022
+ /** Attaches incoming, resolve type, and operation to the behavior context. */
2714
3023
  #prepIncomingForOrchestration(ctx, incoming, operation) {
2715
3024
  ctx.incoming = this.normalizeIncoming(incoming);
2716
3025
  ctx.resolveType = this.#getResolveType(incoming);
2717
3026
  ctx.operation = operation;
2718
3027
  return ctx;
2719
3028
  }
3029
+ /** Ensures at most one merge behavior is registered and adds it to the list. */
2720
3030
  #addDefaultMergeBehavior(behaviors, config) {
2721
3031
  const mergeBehaviors = config.behaviors.filter((behaviorClass) => {
2722
3032
  return behaviorClass.type === BehaviorTypes.Merge;
@@ -2734,6 +3044,7 @@ class Orchestrator {
2734
3044
  // ---------------------------------------------------------------------------
2735
3045
  // NORMALIZATION
2736
3046
  // ---------------------------------------------------------------------------
3047
+ /** Assembles the default behavior set from configuration and internal overrides. */
2737
3048
  #defineDefaultBehaviors(config) {
2738
3049
  let defaultBehaviors = config.defaultBehaviors ?? [];
2739
3050
  defaultBehaviors = this.#determineCoreCallbackErrorBehavior(defaultBehaviors, config);
@@ -2742,18 +3053,21 @@ class Orchestrator {
2742
3053
  defaultBehaviors = this.#addCoreLicenseBehavior(defaultBehaviors);
2743
3054
  return defaultBehaviors;
2744
3055
  }
3056
+ /** Removes the error callback behavior when no error callbacks are configured. */
2745
3057
  #determineCoreCallbackErrorBehavior(behaviors, config) {
2746
3058
  if (config?.errorCallbacks?.length === 0) {
2747
3059
  return behaviors.filter((behavior) => behavior.type !== BehaviorTypes.CoreErrorCallback);
2748
3060
  }
2749
3061
  return behaviors;
2750
3062
  }
3063
+ /** Removes the emit-state callback behavior when no emit-state callbacks are configured. */
2751
3064
  #addCoreEmitStateCallbackBehavior(behaviors, config) {
2752
3065
  if (config?.emitStateCallbacks?.length === 0) {
2753
3066
  return behaviors.filter((behavior) => behavior.type !== BehaviorTypes.CoreEmitState);
2754
3067
  }
2755
3068
  return behaviors;
2756
3069
  }
3070
+ /** Conditionally adds the core license behavior when a vault license is active. */
2757
3071
  #addCoreLicenseBehavior(behaviors) {
2758
3072
  behaviors = behaviors?.filter((behavior) => behavior.type !== BehaviorTypes.CoreLicense);
2759
3073
  if (hasVaultLicense()) {
@@ -2761,6 +3075,7 @@ class Orchestrator {
2761
3075
  }
2762
3076
  return behaviors;
2763
3077
  }
3078
+ /** Reports behavior metadata to the licensing service for license validation. */
2764
3079
  #registerBehaviorsWithVault(behaviors) {
2765
3080
  // eslint-disable-next-line
2766
3081
  const behaviorMetadata = behaviors.map((behavior) => {
@@ -2777,6 +3092,7 @@ class Orchestrator {
2777
3092
  behaviors: behaviorMetadata
2778
3093
  });
2779
3094
  }
3095
+ /** Initializes, filters, and registers all behaviors for this FeatureCell. */
2780
3096
  #registerBehaviors(config) {
2781
3097
  const defaultBehaviors = this.#defineDefaultBehaviors(config);
2782
3098
  // Strip out any user-provided reducers; they are passed separately via `reducers`
@@ -2816,6 +3132,7 @@ class Orchestrator {
2816
3132
  this.#registerStateBehavior();
2817
3133
  behaviorInit.applyBehaviorExtensions(this.#behaviors, config.cell, this.vaultMonitor);
2818
3134
  }
3135
+ /** Filters behaviors to only those eligible for stage-based pipeline execution. */
2819
3136
  #registerStageBehaviors() {
2820
3137
  // Remove merge behavior from the pipeline list
2821
3138
  this.#stageBehaviors = this.#behaviors.filter((behavior) => !(behavior.type === BehaviorTypes.CoreState ||
@@ -2826,6 +3143,7 @@ class Orchestrator {
2826
3143
  behavior.type === BehaviorTypes.CoreErrorCallback ||
2827
3144
  behavior.type === BehaviorTypes.Merge));
2828
3145
  }
3146
+ /** Extracts and registers the core state and emit-state callback behaviors. */
2829
3147
  #registerStateBehavior() {
2830
3148
  const tabSyncState = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.TabSyncState);
2831
3149
  const coreState = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.CoreState);
@@ -2836,6 +3154,7 @@ class Orchestrator {
2836
3154
  this.#coreStateBehavior = stateBehaviors[0] ?? null;
2837
3155
  this.#emitStateCallbackBehavior = this.#behaviors.filter((behavior) => isCoreEmitStateCallbackBehavior(behavior))[0];
2838
3156
  }
3157
+ /** Extracts and registers the core error, error callback, and error transform behaviors. */
2839
3158
  #registerErrorBehavior() {
2840
3159
  // Extract and remove error behavior
2841
3160
  const coreErrors = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.CoreError);
@@ -2846,11 +3165,17 @@ class Orchestrator {
2846
3165
  this.#coreErrorCallbackBehavior = this.#behaviors.filter((behavior) => isCoreErrorCallbackBehavior(behavior))[0];
2847
3166
  this.#errorTransformBehaviors = this.#behaviors.filter((behavior) => isErrorTransformBehavior(behavior));
2848
3167
  }
3168
+ /** Extracts and registers the merge behavior from the behavior list. */
2849
3169
  #registerMergeBehavior() {
2850
3170
  // Extract and remove merge behavior
2851
3171
  const merges = this.#behaviors.filter((behavior) => behavior.type === BehaviorTypes.Merge);
2852
3172
  this.#mergeBehavior = merges[0] ?? null;
2853
3173
  }
3174
+ /**
3175
+ * Runs a stepwise behavior and returns its pipeline signal.
3176
+ *
3177
+ * @returns A noop, clear-state, or continue signal.
3178
+ */
2854
3179
  async #runStepwise(behaviorType, ctx, current) {
2855
3180
  const stepwise = await this.#runUpstreamStage(behaviorType, ctx, current);
2856
3181
  if (isVaultClearState(stepwise)) {
@@ -2861,6 +3186,11 @@ class Orchestrator {
2861
3186
  }
2862
3187
  return VAULT_CONTINUE;
2863
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
+ */
2864
3194
  async #finishPipeline(ctx, resolved) {
2865
3195
  // Stage: operators
2866
3196
  let pipelineDataFlow;
@@ -2901,6 +3231,7 @@ class Orchestrator {
2901
3231
  // Commit the *cloned* pre-encrypted snapshot to signals
2902
3232
  return stateData;
2903
3233
  }
3234
+ /** Orchestrates a full replace pipeline cycle for the current attempt. */
2904
3235
  async #orchestrateReplace(ctx) {
2905
3236
  this.vaultMonitor.startReplace(this.cellKey, VAULT_ORCHESTRATOR, ctx);
2906
3237
  await this.#safeAsync(async () => {
@@ -2918,6 +3249,7 @@ class Orchestrator {
2918
3249
  return this.#handleFinalState(finalState, ctx);
2919
3250
  }, ctx);
2920
3251
  }
3252
+ /** Orchestrates a full merge pipeline cycle for the current attempt. */
2921
3253
  async #orchestrateMerge(ctx, options) {
2922
3254
  this.vaultMonitor.startMerge(this.cellKey, VAULT_ORCHESTRATOR, ctx);
2923
3255
  await this.#safeAsync(async () => {
@@ -2942,6 +3274,11 @@ class Orchestrator {
2942
3274
  return await this.#handleFinalState(finalState, ctx);
2943
3275
  }, ctx);
2944
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
+ */
2945
3282
  async #handleFinalState(finalState, ctx) {
2946
3283
  let payload;
2947
3284
  if (isSignalStop(finalState)) {
@@ -2961,6 +3298,7 @@ class Orchestrator {
2961
3298
  }
2962
3299
  return finalState;
2963
3300
  }
3301
+ /** Wraps an async pipeline function with error handling and state finalization. */
2964
3302
  async #safeAsync(fn, ctx) {
2965
3303
  try {
2966
3304
  const result = await fn();
@@ -2980,6 +3318,11 @@ class Orchestrator {
2980
3318
  await this.decisionEngine?.notifyFailure(this.buildControllerCtx(ctx), pipelineError);
2981
3319
  }
2982
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
+ */
2983
3326
  async #runUpstreamStage(stage, ctx, current) {
2984
3327
  let stageBehaviors;
2985
3328
  if (stage === BehaviorTypes.Resolve) {
@@ -3076,6 +3419,11 @@ class Orchestrator {
3076
3419
  }
3077
3420
  return current;
3078
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
+ */
3079
3427
  async #runInterceptorStage(ctx) {
3080
3428
  const interceptorBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Interceptor);
3081
3429
  for (const behavior of interceptorBehaviors) {
@@ -3096,10 +3444,16 @@ class Orchestrator {
3096
3444
  }
3097
3445
  return;
3098
3446
  }
3447
+ /** Returns whether any operator behaviors are registered in the pipeline. */
3099
3448
  #containsOperators() {
3100
3449
  const operatorBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Operator);
3101
3450
  return operatorBehaviors.length > 0;
3102
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
+ */
3103
3457
  async #runOperatorStage(ctx, current) {
3104
3458
  const operatorBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Operator);
3105
3459
  for (const behavior of operatorBehaviors) {
@@ -3122,6 +3476,11 @@ class Orchestrator {
3122
3476
  }
3123
3477
  return current;
3124
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
+ */
3125
3484
  async #runPersistStage(stage, ctx, current) {
3126
3485
  let stageBehaviors;
3127
3486
  stageBehaviors = this.#stageBehaviors.filter((behavior) => behavior.type === stage);
@@ -3156,6 +3515,7 @@ class Orchestrator {
3156
3515
  }
3157
3516
  return current;
3158
3517
  }
3518
+ /** Invokes destroy on each registered behavior with monitor tracing. */
3159
3519
  #destroyBehaviors(ctx) {
3160
3520
  for (const behavior of this.#behaviors) {
3161
3521
  this.vaultMonitor.startDestroy(this.cellKey, behavior.key, ctx);
@@ -3169,6 +3529,7 @@ class Orchestrator {
3169
3529
  }
3170
3530
  }
3171
3531
  }
3532
+ /** Invokes reset on each registered behavior with monitor tracing. */
3172
3533
  #resetBehaviors(ctx) {
3173
3534
  for (const behavior of this.#behaviors) {
3174
3535
  this.vaultMonitor.startReset(this.cellKey, behavior.key, ctx);
@@ -3182,6 +3543,7 @@ class Orchestrator {
3182
3543
  }
3183
3544
  }
3184
3545
  }
3546
+ /** Runs emit-state callbacks with an isolated snapshot clone. */
3185
3547
  async #runStateBehaviors(ctx) {
3186
3548
  if (this.#emitStateCallbacks?.length > 0) {
3187
3549
  const lastSnapshotClone = isolateValue(ctx.lastSnapshot);
@@ -3193,15 +3555,9 @@ class Orchestrator {
3193
3555
  }
3194
3556
  }
3195
3557
  /**
3196
- * Runs the error behaviors in sequence.
3197
- *
3198
- * - Starts from a normalized ResourceError produced by resourceError().
3199
- * - Each behavior gets (rawError, currentResourceError, ctx).
3200
- * - If a behavior returns:
3201
- * • ResourceError → becomes the next currentResourceError
3202
- * • VAULT_NOOP → previous ResourceError is kept
3558
+ * Runs error normalization, transforms, state commit, and callbacks in sequence.
3203
3559
  *
3204
- * Returns void
3560
+ * @returns The final normalized vault error shape.
3205
3561
  */
3206
3562
  async #runErrorBehaviors(rawError, ctx) {
3207
3563
  let current;
@@ -3282,6 +3638,11 @@ class Orchestrator {
3282
3638
  vaultDebug(`${this.cellKey} #runErrorBehaviors completed with final ResourceError: ${JSON.stringify(current)}`);
3283
3639
  return current;
3284
3640
  }
3641
+ /**
3642
+ * Determines the resolve type for the incoming state input.
3643
+ *
3644
+ * @returns The resolve type matching the incoming value shape.
3645
+ */
3285
3646
  #getResolveType(incoming) {
3286
3647
  if (isHttpResourceRef(incoming)) {
3287
3648
  return ResolveTypes.HttpResource;
@@ -3299,6 +3660,7 @@ class Orchestrator {
3299
3660
  return ResolveTypes.Value;
3300
3661
  }
3301
3662
  }
3663
+ /** Loads the initial state from persistence, configuration, or a deferred factory. */
3302
3664
  async #loadInitialState(ctx) {
3303
3665
  const incoming = {
3304
3666
  value: undefined,
@@ -3333,9 +3695,19 @@ class Orchestrator {
3333
3695
  this.decisionEngine?.notifySuccess(this.buildControllerCtx(ctx));
3334
3696
  }
3335
3697
  }
3698
+ /**
3699
+ * Returns persist behaviors registered for this FeatureCell.
3700
+ *
3701
+ * @returns Array of persist behavior instances.
3702
+ */
3336
3703
  #getPersistedBehaviors() {
3337
3704
  return this.#stageBehaviors.filter((behavior) => behavior.type === BehaviorTypes.Persist);
3338
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
+ */
3339
3711
  async #loadInitialPersistedState(ctx, persistBehaviors) {
3340
3712
  let loaded = undefined;
3341
3713
  for (const behavior of persistBehaviors) {
@@ -3384,6 +3756,7 @@ class Orchestrator {
3384
3756
  }
3385
3757
  }
3386
3758
 
3759
+ /** Enumeration of conductor license evaluation statuses. */
3387
3760
  const ConductorLicenseStatusTypes = {
3388
3761
  Pending: 'pending',
3389
3762
  Approved: 'approved',
@@ -3540,20 +3913,32 @@ class ControllerInitializationClass {
3540
3913
  }
3541
3914
  }
3542
3915
 
3543
- // --- AI Model File Path (DO NOT DELETE) ---
3544
- // FilePath: lib > src > conductor > conductor.ts
3545
- // Updated: 2026-04-07 16:29
3546
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
3547
- // cmd+alt+j (see .vscode/keybindings.json)
3548
- // --- 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
+ */
3549
3922
  class Conductor extends Orchestrator {
3923
+ /** FIFO queue of pending pipeline attempts awaiting controller evaluation. */
3550
3924
  #attemptQueue = [];
3925
+ /** Instantiated controller instances for this FeatureCell. */
3551
3926
  #controllers = [];
3927
+ /** Subject emitting controller lifecycle events to the decision engine. */
3552
3928
  #events$ = new Subject();
3929
+ /** Whether the conductor is currently processing an attempt. */
3553
3930
  #processing = false;
3931
+ /** Whether the conductor is in a deny state for test flushing. */
3554
3932
  #isDenyStateForTesting = false;
3933
+ /** Current license evaluation status for this conductor. */
3555
3934
  #conductorLicenseStatus = ConductorLicenseStatusTypes.Pending;
3935
+ /** Subject signaling when the conductor has settled for DevMode testing. */
3556
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
+ */
3557
3942
  constructor(config) {
3558
3943
  super(config);
3559
3944
  LicensingService().describeFeature({
@@ -3575,6 +3960,11 @@ class Conductor extends Orchestrator {
3575
3960
  this.vaultMonitor.conductorLicenseAttempt(this.cellKey, `${this.cellKey}::license`);
3576
3961
  this.initializeOrchestrator(config);
3577
3962
  }
3963
+ /**
3964
+ * Enqueues an initialization attempt for the FeatureCell pipeline.
3965
+ *
3966
+ * @param ctx - Behavior context for the initialization cycle.
3967
+ */
3578
3968
  initialize(ctx) {
3579
3969
  const initCtx = this.#buildPipelineCtx(ctx, OperationTypes.Initialize, undefined);
3580
3970
  this.#enqueueAttempt({
@@ -3584,6 +3974,14 @@ class Conductor extends Orchestrator {
3584
3974
  });
3585
3975
  }
3586
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
+ */
3587
3985
  conduct(ctx, incoming, operation, options) {
3588
3986
  const behaviorCtx = this.#buildPipelineCtx(ctx, operation, options);
3589
3987
  const preparedIncoming = this.prepareIncoming(behaviorCtx, incoming, operation);
@@ -3626,6 +4024,7 @@ class Conductor extends Orchestrator {
3626
4024
  }
3627
4025
  //#endregion
3628
4026
  //#region Private Methods
4027
+ /** Routes a pipeline attempt to the appropriate orchestrator method. */
3629
4028
  async #processEvent(ctx, options) {
3630
4029
  if (ctx.operation === OperationTypes.Initialize) {
3631
4030
  await this.initializeFeatureCell(ctx);
@@ -3638,6 +4037,7 @@ class Conductor extends Orchestrator {
3638
4037
  this.vaultMonitor.runtimeError(this.cellKey, VAULT_CONDUCTOR, ctx, new Error(`Unknown operation type: "${ctx.operation}"`));
3639
4038
  this.#completeCurrentAttempt(ctx);
3640
4039
  }
4040
+ /** Schedules a microtask to signal a deny-state completion. */
3641
4041
  #enqueueMicrotask() {
3642
4042
  queueMicrotask(() => {
3643
4043
  this.#denyAttemptCompleted();
@@ -3669,6 +4069,7 @@ class Conductor extends Orchestrator {
3669
4069
  this.#enqueueMicrotask();
3670
4070
  }
3671
4071
  }
4072
+ /** Finalizes the current attempt and advances the queue in a microtask. */
3672
4073
  #completeCurrentAttempt(ctx) {
3673
4074
  const head = this.#attemptQueue[0];
3674
4075
  /* istanbul ignore next */
@@ -3723,6 +4124,7 @@ class Conductor extends Orchestrator {
3723
4124
  this.#processQueue();
3724
4125
  });
3725
4126
  }
4127
+ /** Resets the processing flag and emits a restart-attempt monitor event. */
3726
4128
  #resetProcessingState(ctx, outcome) {
3727
4129
  this.vaultMonitor.restartControllerAttempt(this.cellKey, ctx.traceId, ctx, outcome);
3728
4130
  this.#processing = false;
@@ -3819,6 +4221,7 @@ class Conductor extends Orchestrator {
3819
4221
  this.#processQueue();
3820
4222
  }
3821
4223
  }
4224
+ /** Registers the decision engine and subscribes to controller lifecycle events. */
3822
4225
  #registerDecisionEngine() {
3823
4226
  this.decisionEngine = new DecisionEngine(this.#controllers, this.#events$);
3824
4227
  this.#events$.subscribe({
@@ -3886,6 +4289,7 @@ class Conductor extends Orchestrator {
3886
4289
  }
3887
4290
  });
3888
4291
  }
4292
+ /** Builds an isolated pipeline context for a single attempt. */
3889
4293
  #buildPipelineCtx(ctx, operation, options) {
3890
4294
  const traceId = assignTraceId();
3891
4295
  return {
@@ -3904,10 +4308,12 @@ class Conductor extends Orchestrator {
3904
4308
  incoming: undefined
3905
4309
  };
3906
4310
  }
4311
+ /** Clears the attempt queue and resets the processing flag. */
3907
4312
  #resetConductor() {
3908
4313
  this.#attemptQueue.length = 0;
3909
4314
  this.#processing = false;
3910
4315
  }
4316
+ /** Invokes destroy on all registered controllers. */
3911
4317
  #destroyControllers(ctx) {
3912
4318
  for (const controller of this.#controllers) {
3913
4319
  this.vaultMonitor.startDestroy(this.cellKey, controller.key, ctx);
@@ -3921,6 +4327,7 @@ class Conductor extends Orchestrator {
3921
4327
  }
3922
4328
  }
3923
4329
  }
4330
+ /** Invokes reset on all registered controllers. */
3924
4331
  #resetControllers(ctx) {
3925
4332
  for (const controller of this.#controllers) {
3926
4333
  this.vaultMonitor.startReset(this.cellKey, controller.key, ctx);
@@ -3934,6 +4341,7 @@ class Conductor extends Orchestrator {
3934
4341
  }
3935
4342
  }
3936
4343
  }
4344
+ /** Adds the default or user-supplied error controller to the controller list. */
3937
4345
  #addDefaultErrorController(controllers, config) {
3938
4346
  const errorControllers = config.controllers.filter((controllerClass) => {
3939
4347
  return controllerClass.type === ControllerTypes.Error;
@@ -3949,6 +4357,7 @@ class Conductor extends Orchestrator {
3949
4357
  controllers.unshift(withCoreErrorController);
3950
4358
  }
3951
4359
  }
4360
+ /** Removes reserved controller types from the user-supplied list. */
3952
4361
  #filterRestrictedControllers(controllers) {
3953
4362
  return controllers.filter((controller) => {
3954
4363
  if (controller.type === ControllerTypes.License || controller.type === ControllerTypes.CoreAbstain) {
@@ -3961,6 +4370,7 @@ class Conductor extends Orchestrator {
3961
4370
  // ---------------------------------------------------------------------------
3962
4371
  // INTERNAL SCHEDULING
3963
4372
  // ---------------------------------------------------------------------------
4373
+ /** Initializes all controllers and registers the decision engine. */
3964
4374
  #registerControllers(config) {
3965
4375
  config.controllers = config.controllers ?? [];
3966
4376
  const allControllers = this.#filterRestrictedControllers(config.controllers);
@@ -4001,12 +4411,14 @@ class Conductor extends Orchestrator {
4001
4411
  this.vaultMonitor.endControllerVote(this.cellKey, pending.controllerCtx.traceId, pending.controllerCtx, decision);
4002
4412
  }), map((decision) => decision.outcome));
4003
4413
  }
4414
+ /** Signals a deny-state settlement for DevMode testing. */
4004
4415
  #denyAttemptCompleted() {
4005
4416
  if (!DevMode.active)
4006
4417
  return;
4007
4418
  this.#settled$.next();
4008
4419
  }
4009
4420
  // ADD
4421
+ /** Signals queue settlement when all attempts have been processed. */
4010
4422
  #attemptCompleted() {
4011
4423
  if (!DevMode.active || this.#attemptQueue.length > 0)
4012
4424
  return;
@@ -4014,6 +4426,7 @@ class Conductor extends Orchestrator {
4014
4426
  this.#settled$.next();
4015
4427
  });
4016
4428
  }
4429
+ /** Returns a promise that resolves when the conductor has settled. */
4017
4430
  #conductorSettled() {
4018
4431
  return firstValueFrom(this.#settled$);
4019
4432
  }
@@ -4065,27 +4478,46 @@ function featureCellValidation(descriptor, behaviors = []) {
4065
4478
  }
4066
4479
  }
4067
4480
 
4068
- // --- AI Model File Path (DO NOT DELETE) ---
4069
- // FilePath: projects > engine > src > lib > factories > feature-cell > feature-cell.builder.ts
4070
- // Updated: 2026-03-02 19:52
4071
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
4072
- // cmd+alt+j (see .vscode/keybindings.json)
4073
- // --- 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
+ */
4074
4488
  class FeatureCellBuilder {
4075
4489
  featureCellConfiguration;
4076
4490
  defaultBehaviors;
4077
4491
  behaviors;
4078
4492
  controllers;
4493
+ /** Whether the cell encountered a critical failure and is permanently unusable. */
4079
4494
  #cellCorrupt = false;
4495
+ /** Conductor instance managing pipeline execution for this cell. */
4080
4496
  #conductor;
4497
+ /** Whether the cell has been initialized via the builder. */
4081
4498
  #initialized = false;
4499
+ /** Vault monitor instance for tracing lifecycle events. */
4082
4500
  #vaultMonitor = VaultMonitor();
4501
+ /** Reference to the constructed FeatureCellBaseShape. */
4083
4502
  cell;
4503
+ /** Unique key identifying this FeatureCell. */
4084
4504
  cellKey;
4505
+ /** Shared behavior context for pipeline execution. */
4085
4506
  ctx;
4507
+ /** Subject signaling cell destruction. */
4086
4508
  destroyed$ = new Subject();
4509
+ /** Subject signaling cell reset. */
4087
4510
  reset$ = new Subject();
4511
+ /** Subject emitting state snapshots to subscribers. */
4088
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
+ */
4089
4521
  constructor(
4090
4522
  // kept for parity with original API, even if not used directly
4091
4523
  featureCellConfiguration, defaultBehaviors, behaviors, controllers) {
@@ -4096,6 +4528,11 @@ class FeatureCellBuilder {
4096
4528
  this.cellKey = this.featureCellConfiguration.key;
4097
4529
  this.ctx = this.#buildCtx();
4098
4530
  }
4531
+ /**
4532
+ * Builds the initial behavior context with locked snapshot reference.
4533
+ *
4534
+ * @returns The constructed behavior context.
4535
+ */
4099
4536
  #buildCtx() {
4100
4537
  const destroyed$ = this.destroyed$.asObservable();
4101
4538
  const state$ = this.state$;
@@ -4133,6 +4570,7 @@ class FeatureCellBuilder {
4133
4570
  // ---------------------------------------------------------------------------
4134
4571
  // INTERNAL LIFECYCLE
4135
4572
  // ---------------------------------------------------------------------------
4573
+ /** Resets the conductor and emits a reset signal. */
4136
4574
  reset() {
4137
4575
  this.#vaultMonitor.startReset(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4138
4576
  vaultWarn(`${VAULT_FEATURE_CELL}: reset`);
@@ -4141,6 +4579,7 @@ class FeatureCellBuilder {
4141
4579
  this.#conductor?.reset(this.ctx);
4142
4580
  this.#vaultMonitor.endReset(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4143
4581
  }
4582
+ /** Destroys the conductor, completes all subjects, and emits destruction signals. */
4144
4583
  destroy() {
4145
4584
  this.#vaultMonitor.startDestroy(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4146
4585
  vaultWarn(`${VAULT_FEATURE_CELL}: destroy`);
@@ -4152,6 +4591,7 @@ class FeatureCellBuilder {
4152
4591
  this.state$.complete();
4153
4592
  this.#vaultMonitor.endDestroy(this.cellKey, VAULT_FEATURE_CELL, this.ctx);
4154
4593
  }
4594
+ /** Throws if the cell is corrupt or has not been initialized. */
4155
4595
  #ensureInitialized() {
4156
4596
  if (this.#cellCorrupt) {
4157
4597
  const errorMessage = `[vault] FeatureCell "${this.featureCellConfiguration.key}" encountered a critical initialization failure and is now in a corrupted state. Further use is blocked.`;
@@ -4164,6 +4604,7 @@ class FeatureCellBuilder {
4164
4604
  throw new Error(errorMessage);
4165
4605
  }
4166
4606
  }
4607
+ /** Creates the conductor, validates the cell, and starts the initialization lifecycle. */
4167
4608
  #initialize(ctx) {
4168
4609
  if (this.#initialized) {
4169
4610
  const errorMessage = `[vault] FeatureCell "${this.featureCellConfiguration.key}" already initialized.`;
@@ -4216,11 +4657,17 @@ class FeatureCellBuilder {
4216
4657
  throw err;
4217
4658
  }
4218
4659
  }
4660
+ /** Marks the cell as corrupt, logs a runtime error, and throws. */
4219
4661
  #handleCorruptionError(message) {
4220
4662
  this.#cellCorrupt = true;
4221
4663
  this.#vaultMonitor.runtimeError(this.cellKey, VAULT_FEATURE_CELL, this.ctx, message);
4222
4664
  throw new Error(message);
4223
4665
  }
4666
+ /**
4667
+ * Constructs the fluent CellBuilderContract with pre-initialization guards.
4668
+ *
4669
+ * @returns The builder contract exposing configuration and initialize methods.
4670
+ */
4224
4671
  setup() {
4225
4672
  const afterTapCallbacks = [];
4226
4673
  const beforeTapCallbacks = [];
@@ -4333,26 +4780,41 @@ class FeatureCellBuilder {
4333
4780
  // ---------------------------------------------------------------------------
4334
4781
  // STATE OPERATIONS
4335
4782
  // ---------------------------------------------------------------------------
4783
+ /** Dispatches a merge operation through the conductor pipeline. */
4336
4784
  mergeState(incoming, options) {
4337
4785
  this.#ensureInitialized();
4338
4786
  return this.#conductor.conduct(this.ctx, incoming, OperationTypes.Merge, options);
4339
4787
  }
4788
+ /** Dispatches a replace operation through the conductor pipeline. */
4340
4789
  replaceState(incoming, options) {
4341
4790
  this.#ensureInitialized();
4342
4791
  return this.#conductor.conduct(this.ctx, incoming, OperationTypes.Replace, options);
4343
4792
  }
4344
4793
  }
4345
4794
 
4346
- // --- AI Model File Path (DO NOT DELETE) ---
4347
- // FilePath: projects > engine > src > lib > factories > feature-cell > feature-cell.class.ts
4348
- // Updated: 2026-03-02 19:52
4349
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
4350
- // cmd+alt+j (see .vscode/keybindings.json)
4351
- // --- 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
+ */
4352
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
+ */
4353
4810
  constructor(descriptor, defaultBehaviors, behaviors, controllers) {
4354
4811
  super(descriptor, defaultBehaviors, behaviors, controllers);
4355
4812
  }
4813
+ /**
4814
+ * Assembles and returns a fully configured FeatureCellShape with fluent API extensions.
4815
+ *
4816
+ * @returns The constructed FeatureCellShape instance.
4817
+ */
4356
4818
  build() {
4357
4819
  const builder = this.setup();
4358
4820
  const ctx = this.ctx;
@@ -4483,12 +4945,6 @@ function resetFeatureCellToken() {
4483
4945
  featureCellTokenRequested.clear();
4484
4946
  }
4485
4947
 
4486
- // --- AI Model File Path (DO NOT DELETE) ---
4487
- // FilePath: lib > public-api.ts
4488
- // Updated: 2026-03-30 15:42
4489
- // Generated by pathcomment [tab] (see .vscode/typescript.code-snippets) or
4490
- // cmd+alt+j (see .vscode/keybindings.json)
4491
- // --- END AI MODEL FILE PATH ---
4492
4948
  /*
4493
4949
  * This is for version support in dev mode and tracking in the devtools
4494
4950
  */