@camstack/addon-post-analysis 1.2.98 → 1.2.100

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.
@@ -13038,7 +13038,20 @@ var NcRuleStore = class {
13038
13038
  * The operator's words stay on disk forever.
13039
13039
  */
13040
13040
  async load() {
13041
- const rules = await this.ledger.load();
13041
+ await this.ledger.load();
13042
+ this.logger.debug("notification rules loaded", { meta: { rules: this.ledger.size } });
13043
+ }
13044
+ /**
13045
+ * The identity NAME→ID migration, split out of {@link load} on 2026-08-19:
13046
+ * `readIdentityIds` reaches the identity gallery, and at boot that single
13047
+ * read cost 119 s — 74 s more than every other start() read combined —
13048
+ * while buying only an ENRICHMENT: the engine still matches by name (it
13049
+ * keeps that leg precisely for the gallery-cannot-answer case below). It
13050
+ * now runs as a back-fill phase; the rename-immunity ids arrive seconds
13051
+ * later instead of gating the intake.
13052
+ */
13053
+ async migrateIdentityIds() {
13054
+ const rules = this.ledger.snapshot();
13042
13055
  const idsByName = await this.readIdentityIds();
13043
13056
  let migrated = 0;
13044
13057
  const unresolved = /* @__PURE__ */ new Set();
@@ -13049,10 +13062,7 @@ var NcRuleStore = class {
13049
13062
  migrated += 1;
13050
13063
  this.ledger.stage(result.rule);
13051
13064
  }
13052
- this.logger.debug("notification rules loaded", { meta: {
13053
- rules: this.ledger.size,
13054
- ...migrated > 0 ? { identitiesResolvedToIds: migrated } : {}
13055
- } });
13065
+ if (migrated > 0) this.logger.info("notification rules migrated identity names to ids", { meta: { identitiesResolvedToIds: migrated } });
13056
13066
  if (unresolved.size > 0) this.logger.info("notification rules name identities the gallery does not know", { meta: { names: [...unresolved].join(", ") } });
13057
13067
  }
13058
13068
  /**
@@ -19588,23 +19598,24 @@ var NotificationCenter = class NotificationCenter {
19588
19598
  */
19589
19599
  async start(opts) {
19590
19600
  const t0 = Date.now();
19591
- let phaseT = t0;
19592
19601
  const timed = async (phase, run) => {
19602
+ const started = Date.now();
19593
19603
  await run();
19594
19604
  const now = Date.now();
19595
19605
  this.logger.info("notification start phase", { meta: {
19596
19606
  phase,
19597
- ms: now - phaseT,
19607
+ ms: now - started,
19598
19608
  sinceStartMs: now - t0
19599
19609
  } });
19600
- phaseT = now;
19601
- };
19602
- await timed("texts", () => this.reloadTexts());
19603
- await timed("rules", () => this.rules.load());
19604
- await timed("snoozes", () => this.snoozes.load());
19605
- await timed("deviceMutes", () => this.deviceMutes.load());
19606
- await timed("timelapseRules", () => this.timelapseRules.load());
19607
- await timed("summaryRules", () => this.summaryRules.load());
19610
+ };
19611
+ await Promise.all([
19612
+ timed("texts", () => this.reloadTexts()),
19613
+ timed("rules", () => this.rules.load()),
19614
+ timed("snoozes", () => this.snoozes.load()),
19615
+ timed("deviceMutes", () => this.deviceMutes.load()),
19616
+ timed("timelapseRules", () => this.timelapseRules.load()),
19617
+ timed("summaryRules", () => this.summaryRules.load())
19618
+ ]);
19608
19619
  this.refreshOccupancyWatch();
19609
19620
  if (!opts.evaluation) return;
19610
19621
  this.sceneStates.refresh();
@@ -19725,6 +19736,7 @@ var NotificationCenter = class NotificationCenter {
19725
19736
  if (!await phase("cooldowns", () => this.seedCooldowns())) return;
19726
19737
  if (!await phase("zoneOwners", () => this.zoneOwners.refresh())) return;
19727
19738
  if (!await phase("deviceStates", () => this.deviceStates.refresh())) return;
19739
+ if (!await phase("ruleIdentityIds", () => this.rules.migrateIdentityIds())) return;
19728
19740
  if (!await phase("reconcile", () => this.reconcile())) return;
19729
19741
  if (!await phase("prune", async () => {
19730
19742
  await this.outbox.pruneBefore(this.now() - OUTBOX_RETENTION_MS);
@@ -13031,7 +13031,20 @@ var NcRuleStore = class {
13031
13031
  * The operator's words stay on disk forever.
13032
13032
  */
13033
13033
  async load() {
13034
- const rules = await this.ledger.load();
13034
+ await this.ledger.load();
13035
+ this.logger.debug("notification rules loaded", { meta: { rules: this.ledger.size } });
13036
+ }
13037
+ /**
13038
+ * The identity NAME→ID migration, split out of {@link load} on 2026-08-19:
13039
+ * `readIdentityIds` reaches the identity gallery, and at boot that single
13040
+ * read cost 119 s — 74 s more than every other start() read combined —
13041
+ * while buying only an ENRICHMENT: the engine still matches by name (it
13042
+ * keeps that leg precisely for the gallery-cannot-answer case below). It
13043
+ * now runs as a back-fill phase; the rename-immunity ids arrive seconds
13044
+ * later instead of gating the intake.
13045
+ */
13046
+ async migrateIdentityIds() {
13047
+ const rules = this.ledger.snapshot();
13035
13048
  const idsByName = await this.readIdentityIds();
13036
13049
  let migrated = 0;
13037
13050
  const unresolved = /* @__PURE__ */ new Set();
@@ -13042,10 +13055,7 @@ var NcRuleStore = class {
13042
13055
  migrated += 1;
13043
13056
  this.ledger.stage(result.rule);
13044
13057
  }
13045
- this.logger.debug("notification rules loaded", { meta: {
13046
- rules: this.ledger.size,
13047
- ...migrated > 0 ? { identitiesResolvedToIds: migrated } : {}
13048
- } });
13058
+ if (migrated > 0) this.logger.info("notification rules migrated identity names to ids", { meta: { identitiesResolvedToIds: migrated } });
13049
13059
  if (unresolved.size > 0) this.logger.info("notification rules name identities the gallery does not know", { meta: { names: [...unresolved].join(", ") } });
13050
13060
  }
13051
13061
  /**
@@ -19566,23 +19576,24 @@ var NotificationCenter = class NotificationCenter {
19566
19576
  */
19567
19577
  async start(opts) {
19568
19578
  const t0 = Date.now();
19569
- let phaseT = t0;
19570
19579
  const timed = async (phase, run) => {
19580
+ const started = Date.now();
19571
19581
  await run();
19572
19582
  const now = Date.now();
19573
19583
  this.logger.info("notification start phase", { meta: {
19574
19584
  phase,
19575
- ms: now - phaseT,
19585
+ ms: now - started,
19576
19586
  sinceStartMs: now - t0
19577
19587
  } });
19578
- phaseT = now;
19579
- };
19580
- await timed("texts", () => this.reloadTexts());
19581
- await timed("rules", () => this.rules.load());
19582
- await timed("snoozes", () => this.snoozes.load());
19583
- await timed("deviceMutes", () => this.deviceMutes.load());
19584
- await timed("timelapseRules", () => this.timelapseRules.load());
19585
- await timed("summaryRules", () => this.summaryRules.load());
19588
+ };
19589
+ await Promise.all([
19590
+ timed("texts", () => this.reloadTexts()),
19591
+ timed("rules", () => this.rules.load()),
19592
+ timed("snoozes", () => this.snoozes.load()),
19593
+ timed("deviceMutes", () => this.deviceMutes.load()),
19594
+ timed("timelapseRules", () => this.timelapseRules.load()),
19595
+ timed("summaryRules", () => this.summaryRules.load())
19596
+ ]);
19586
19597
  this.refreshOccupancyWatch();
19587
19598
  if (!opts.evaluation) return;
19588
19599
  this.sceneStates.refresh();
@@ -19703,6 +19714,7 @@ var NotificationCenter = class NotificationCenter {
19703
19714
  if (!await phase("cooldowns", () => this.seedCooldowns())) return;
19704
19715
  if (!await phase("zoneOwners", () => this.zoneOwners.refresh())) return;
19705
19716
  if (!await phase("deviceStates", () => this.deviceStates.refresh())) return;
19717
+ if (!await phase("ruleIdentityIds", () => this.rules.migrateIdentityIds())) return;
19706
19718
  if (!await phase("reconcile", () => this.reconcile())) return;
19707
19719
  if (!await phase("prune", async () => {
19708
19720
  await this.outbox.pruneBefore(this.now() - OUTBOX_RETENTION_MS);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-post-analysis",
3
- "version": "1.2.98",
3
+ "version": "1.2.100",
4
4
  "description": "Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
5
5
  "keywords": [
6
6
  "camstack",