@semiont/make-meaning 0.5.29 → 0.5.31

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,9 +1,14 @@
1
- import { createTomlConfigLoader, accessToken, baseUrl as baseUrl$1, retryWithBackoff, isTransientFetchError, STARTUP_FETCH_RETRY, errField, burstBuffer, busRequest, resourceId, didToAgent, annotationId, findBodyItem } from '@semiont/core';
1
+ import { replyChannelsFor, createTomlConfigLoader, accessToken, baseUrl as baseUrl$1, retryWithBackoff, isTransientFetchError, STARTUP_FETCH_RETRY, errField, burstBuffer, busRequest, resourceId, didToAgent, annotationId, findBodyItem } from '@semiont/core';
2
+ import { getGraphDatabase, intendedGraphAnnotation } from '@semiont/graph';
2
3
  import { existsSync, readFileSync, promises } from 'fs';
3
4
  import * as path from 'path';
4
5
  import { join } from 'path';
6
+ import '@semiont/observability';
7
+ import '@semiont/ontology';
8
+ import '@semiont/content';
9
+ import '@semiont/vectors';
10
+ import '@semiont/event-sourcing';
5
11
  import { HttpTransport } from '@semiont/http-transport';
6
- import { getGraphDatabase } from '@semiont/graph';
7
12
  import { createServer } from 'http';
8
13
  import { homedir } from 'os';
9
14
  import { createProcessLogger } from '@semiont/observability/process-logger';
@@ -9910,18 +9915,18 @@ var Weaver = class _Weaver {
9910
9915
  set.add(seq);
9911
9916
  }
9912
9917
  }
9913
- noteApplied(resourceId, sequenceNumber) {
9914
- const failed = this.failedSeqs.get(resourceId);
9918
+ noteApplied(resourceId6, sequenceNumber) {
9919
+ const failed = this.failedSeqs.get(resourceId6);
9915
9920
  let capped = sequenceNumber;
9916
9921
  if (failed && failed.size > 0) {
9917
9922
  capped = Math.min(capped, Math.min(...failed) - 1);
9918
9923
  }
9919
- const current = this.lastProcessed.get(resourceId);
9924
+ const current = this.lastProcessed.get(resourceId6);
9920
9925
  if (current !== void 0 && current >= capped) return;
9921
- this.lastProcessed.set(resourceId, capped);
9926
+ this.lastProcessed.set(resourceId6, capped);
9922
9927
  this.checkpointDirty = true;
9923
- this.bus.emit("weave:applied", { resourceId, sequenceNumber: capped }).catch((err) => {
9924
- this.logger.warn("weave:applied emit failed", { resourceId, sequenceNumber: capped, error: errField(err) });
9928
+ this.bus.emit("weave:applied", { resourceId: resourceId6, sequenceNumber: capped }).catch((err) => {
9929
+ this.logger.warn("weave:applied emit failed", { resourceId: resourceId6, sequenceNumber: capped, error: errField(err) });
9925
9930
  });
9926
9931
  }
9927
9932
  async flushCheckpoint() {
@@ -9967,8 +9972,8 @@ var Weaver = class _Weaver {
9967
9972
  return resources;
9968
9973
  }
9969
9974
  /** A resource's full event history over the bus, sorted by sequence. */
9970
- async fetchResourceEvents(resourceId) {
9971
- const reply = await busRequest(this.bus, "browse:events-requested", { resourceId });
9975
+ async fetchResourceEvents(resourceId6) {
9976
+ const reply = await busRequest(this.bus, "browse:events-requested", { resourceId: resourceId6 });
9972
9977
  return [...reply.events].sort((a, b) => a.metadata.sequenceNumber - b.metadata.sequenceNumber);
9973
9978
  }
9974
9979
  async catchUp() {
@@ -10076,6 +10081,7 @@ var Weaver = class _Weaver {
10076
10081
  let divergent = 0;
10077
10082
  let healed = 0;
10078
10083
  let healFailures = 0;
10084
+ let orphaned = 0;
10079
10085
  for (const resource of resources) {
10080
10086
  const rid = resource["@id"];
10081
10087
  if (!rid) continue;
@@ -10084,11 +10090,17 @@ var Weaver = class _Weaver {
10084
10090
  divergent++;
10085
10091
  this.logger.warn("Reconcile divergence \u2014 healing from the log", { resourceId: String(rid), reason });
10086
10092
  const result = await this.rebuildResource(resourceId(String(rid)));
10087
- if (result.eventsFailed === 0) healed++;
10093
+ if (result.eventCount === 0) {
10094
+ orphaned++;
10095
+ this.logger.warn(
10096
+ "Reconcile found an orphaned view \u2014 the log has no events for this resource, so healing wrote nothing",
10097
+ { resourceId: String(rid), reason, remedy: "semiont stop && semiont clean --store state && semiont start" }
10098
+ );
10099
+ } else if (result.eventsFailed === 0) healed++;
10088
10100
  else healFailures++;
10089
10101
  }
10090
- const summary = { resourcesChecked: resources.length, divergent, healed, healFailures };
10091
- if (divergent > 0 || healFailures > 0) {
10102
+ const summary = { resourcesChecked: resources.length, divergent, healed, healFailures, orphaned };
10103
+ if (divergent > 0 || healFailures > 0 || orphaned > 0) {
10092
10104
  this.logger.warn("Weaver reconcile found divergence", summary);
10093
10105
  } else {
10094
10106
  this.logger.info("Weaver reconcile complete \u2014 projection matches the catalog", summary);
@@ -10130,13 +10142,13 @@ var Weaver = class _Weaver {
10130
10142
  for (const id of viewIds) {
10131
10143
  if (!graphIds.has(id)) return "annotation-set-mismatch";
10132
10144
  }
10133
- const bodyKey = (a) => _Weaver.canonicalJson(a.body ?? []);
10134
10145
  const viewById = new Map(annotations.map((a) => [String(a.id), a]));
10135
10146
  for (const graphAnnotation of graphAnnotations) {
10136
10147
  const viewAnnotation = viewById.get(String(graphAnnotation.id));
10137
10148
  if (!viewAnnotation) continue;
10138
- if (bodyKey(graphAnnotation) !== bodyKey(viewAnnotation)) {
10139
- return "annotation-body-mismatch";
10149
+ const intended = intendedGraphAnnotation({ ...viewAnnotation, creator: graphAnnotation.creator });
10150
+ if (_Weaver.canonicalJson(graphAnnotation) !== _Weaver.canonicalJson(intended)) {
10151
+ return "annotation-content-mismatch";
10140
10152
  }
10141
10153
  }
10142
10154
  return null;
@@ -10466,30 +10478,30 @@ var Weaver = class _Weaver {
10466
10478
  * Rebuild entire resource from events.
10467
10479
  * Bypasses the live pipeline — reads directly from event store.
10468
10480
  */
10469
- async rebuildResource(resourceId) {
10481
+ async rebuildResource(resourceId6) {
10470
10482
  const graphDb = this.ensureInitialized();
10471
- this.logger.info("Rebuilding resource from events", { resourceId });
10483
+ this.logger.info("Rebuilding resource from events", { resourceId: resourceId6 });
10472
10484
  try {
10473
- await graphDb.deleteResource(resourceId);
10485
+ await graphDb.deleteResource(resourceId6);
10474
10486
  } catch (error) {
10475
- this.logger.debug("No existing resource to delete", { resourceId });
10487
+ this.logger.debug("No existing resource to delete", { resourceId: resourceId6 });
10476
10488
  }
10477
- const events = await this.fetchResourceEvents(String(resourceId));
10489
+ const events = await this.fetchResourceEvents(String(resourceId6));
10478
10490
  let eventsFailed = 0;
10479
10491
  for (const storedEvent of events) {
10480
10492
  if (!await this.safeApplyEvent(storedEvent)) eventsFailed++;
10481
10493
  }
10482
10494
  if (events.length > 0 && eventsFailed === 0) {
10483
- this.noteApplied(String(resourceId), Math.max(...events.map((e) => e.metadata.sequenceNumber)));
10495
+ this.noteApplied(String(resourceId6), Math.max(...events.map((e) => e.metadata.sequenceNumber)));
10484
10496
  }
10485
10497
  if (eventsFailed > 0) {
10486
10498
  this.logger.error("Resource rebuild dropped events \u2014 graph incomplete for this resource", {
10487
- resourceId,
10499
+ resourceId: resourceId6,
10488
10500
  eventsFailed
10489
10501
  });
10490
10502
  }
10491
- this.logger.info("Resource rebuild complete", { resourceId, eventCount: events.length, eventsFailed });
10492
- return { eventsApplied: events.length - eventsFailed, eventsFailed };
10503
+ this.logger.info("Resource rebuild complete", { resourceId: resourceId6, eventCount: events.length, eventsFailed });
10504
+ return { eventCount: events.length, eventsApplied: events.length - eventsFailed, eventsFailed };
10493
10505
  }
10494
10506
  /**
10495
10507
  * Rebuild entire GraphDB from all events.
@@ -10510,15 +10522,15 @@ var Weaver = class _Weaver {
10510
10522
  this.logger.info("Found resources to rebuild", { count: allResourceIds.length });
10511
10523
  const ledger = /* @__PURE__ */ new Map();
10512
10524
  this.logger.info("PASS 1: Creating all nodes (resources + annotations)");
10513
- for (const resourceId of allResourceIds) {
10514
- const events = await this.fetchResourceEvents(String(resourceId));
10525
+ for (const resourceId6 of allResourceIds) {
10526
+ const events = await this.fetchResourceEvents(String(resourceId6));
10515
10527
  if (events.length === 0) continue;
10516
10528
  const entry = {
10517
10529
  maxSeq: Math.max(...events.map((e) => e.metadata.sequenceNumber)),
10518
10530
  attempted: 0,
10519
10531
  failed: 0
10520
10532
  };
10521
- ledger.set(String(resourceId), entry);
10533
+ ledger.set(String(resourceId6), entry);
10522
10534
  for (const storedEvent of events) {
10523
10535
  if (storedEvent.type === "mark:body-updated") {
10524
10536
  continue;
@@ -10529,11 +10541,11 @@ var Weaver = class _Weaver {
10529
10541
  }
10530
10542
  this.logger.info("Pass 1 complete - all nodes created");
10531
10543
  this.logger.info("PASS 2: Creating all REFERENCES edges");
10532
- for (const resourceId of allResourceIds) {
10533
- const events = await this.fetchResourceEvents(String(resourceId));
10544
+ for (const resourceId6 of allResourceIds) {
10545
+ const events = await this.fetchResourceEvents(String(resourceId6));
10534
10546
  for (const storedEvent of events) {
10535
10547
  if (storedEvent.type === "mark:body-updated") {
10536
- const entry = ledger.get(String(resourceId));
10548
+ const entry = ledger.get(String(resourceId6));
10537
10549
  if (entry) entry.attempted++;
10538
10550
  if (!await this.safeApplyEvent(storedEvent)) {
10539
10551
  if (entry) entry.failed++;
@@ -10561,8 +10573,8 @@ var Weaver = class _Weaver {
10561
10573
  * Get consumer health metrics.
10562
10574
  */
10563
10575
  /** Highest applied sequence for a resource, if any — diagnostics/tests. */
10564
- appliedUpTo(resourceId) {
10565
- return this.lastProcessed.get(resourceId);
10576
+ appliedUpTo(resourceId6) {
10577
+ return this.lastProcessed.get(resourceId6);
10566
10578
  }
10567
10579
  getHealthMetrics() {
10568
10580
  return {
@@ -10614,6 +10626,110 @@ var FileWeaverCheckpoint = class {
10614
10626
  await promises.rename(tmp, this.filePath);
10615
10627
  }
10616
10628
  };
10629
+ var MATCHER_CHANNELS = [
10630
+ "match:search-requested"
10631
+ ];
10632
+
10633
+ // src/gatherer.ts
10634
+ var GATHERER_CHANNELS = [
10635
+ "gather:requested",
10636
+ "gather:resource-requested"
10637
+ ];
10638
+ var STOWER_CHANNELS = [
10639
+ "yield:create",
10640
+ "yield:clone-persist",
10641
+ "yield:update",
10642
+ "yield:mv",
10643
+ "mark:create",
10644
+ "mark:commit",
10645
+ "mark:delete",
10646
+ "mark:update-body",
10647
+ "frame:add-entity-type",
10648
+ "frame:add-tag-schema",
10649
+ "mark:archive",
10650
+ "mark:unarchive",
10651
+ "mark:update-entity-types",
10652
+ "job:start",
10653
+ "job:complete",
10654
+ "job:fail"
10655
+ ];
10656
+
10657
+ // src/browser.ts
10658
+ var BROWSER_CHANNELS = [
10659
+ "browse:resource-requested",
10660
+ "browse:anchored-text-requested",
10661
+ "browse:resources-requested",
10662
+ "browse:annotations-requested",
10663
+ "browse:annotation-requested",
10664
+ "browse:events-requested",
10665
+ "browse:annotation-history-requested",
10666
+ "browse:referenced-by-requested",
10667
+ "browse:entity-types-requested",
10668
+ "browse:tag-schemas-requested",
10669
+ "browse:agents-requested",
10670
+ "browse:directory-requested"
10671
+ ];
10672
+
10673
+ // src/clone-token-manager.ts
10674
+ var CLONE_TOKEN_CHANNELS = [
10675
+ "yield:clone-token-requested",
10676
+ "yield:clone-resource-requested",
10677
+ "yield:clone-create"
10678
+ ];
10679
+
10680
+ // src/service-channels.ts
10681
+ var SMELTER_AWAITED_OPERATIONS = [
10682
+ "browse:resource-requested",
10683
+ "browse:annotations-requested",
10684
+ "browse:resources-requested"
10685
+ ];
10686
+ replyChannelsFor(SMELTER_AWAITED_OPERATIONS);
10687
+ var WEAVER_AWAITED_OPERATIONS = [
10688
+ "browse:resources-requested",
10689
+ "browse:events-requested",
10690
+ "browse:annotations-requested"
10691
+ ];
10692
+ var WEAVER_REPLY_CHANNELS = replyChannelsFor(WEAVER_AWAITED_OPERATIONS);
10693
+ var LIBRARIAN_INBOUND_CHANNELS = [
10694
+ ...MATCHER_CHANNELS,
10695
+ ...GATHERER_CHANNELS,
10696
+ "gather:summary-requested",
10697
+ "weave:applied",
10698
+ "smelt:settled"
10699
+ ];
10700
+ replyChannelsFor(LIBRARIAN_INBOUND_CHANNELS);
10701
+ var ARCHIVIST_INBOUND_CHANNELS = [
10702
+ ...STOWER_CHANNELS,
10703
+ ...BROWSER_CHANNELS,
10704
+ ...CLONE_TOKEN_CHANNELS,
10705
+ "mark:create-request",
10706
+ "smelt:settled",
10707
+ // The annotation-context read moved here with the bytes (SINGLE-KB-MOUNT D5).
10708
+ "browse:annotation-context-requested"
10709
+ ];
10710
+ var ARCHIVIST_OUTBOUND_STRAYS = [
10711
+ "mark:body-update-failed",
10712
+ // op keyed 'bind:update-body' (gateway handler re-emits mark:update-body)
10713
+ "yield:move-failed"
10714
+ // yield:mv has no registered operation; failure is direct-subscribed
10715
+ ];
10716
+ [
10717
+ ...ARCHIVIST_OUTBOUND_STRAYS,
10718
+ ...replyChannelsFor(ARCHIVIST_INBOUND_CHANNELS)
10719
+ ];
10720
+ async function runBootPass(pass, run, logger2, onState) {
10721
+ onState?.({ phase: "running" });
10722
+ try {
10723
+ const summary = await run();
10724
+ onState?.({ phase: "done", summary });
10725
+ } catch (error) {
10726
+ onState?.({ phase: "failed", error: error instanceof Error ? error.message : String(error) });
10727
+ logger2.error(`Boot pass '${pass}' failed \u2014 continuing with a store that may be behind`, {
10728
+ pass,
10729
+ error: errField(error)
10730
+ });
10731
+ }
10732
+ }
10617
10733
  var configPath = join(homedir(), ".semiontconfig");
10618
10734
  var tomlReader = {
10619
10735
  readIfExists: (p) => existsSync(p) ? readFileSync(p, "utf-8") : null
@@ -10637,7 +10753,7 @@ if (maybeGraphConfig.type === "memory") {
10637
10753
  }
10638
10754
  var graphConfig = maybeGraphConfig;
10639
10755
  var workerSecret = process.env.SEMIONT_WORKER_SECRET ?? "";
10640
- var healthPort = 9092;
10756
+ var healthPort = 24102;
10641
10757
  var stateHome = process.env.XDG_STATE_HOME ?? join(homedir(), ".local", "state");
10642
10758
  var checkpointPath = join(stateHome, "semiont", "weaver-checkpoint.json");
10643
10759
  var logger = createProcessLogger("weaver");
@@ -10698,7 +10814,12 @@ async function main() {
10698
10814
  const httpTransport = new HttpTransport({
10699
10815
  baseUrl: baseUrl$1(baseUrl),
10700
10816
  token$: tokenSubject,
10701
- tokenRefresher: refreshToken
10817
+ tokenRefresher: refreshToken,
10818
+ // Only the reply channels this process awaits — not the full bridged
10819
+ // set, whose global reply fan-out is the worker-OOM failure mode. See
10820
+ // WEAVER_AWAITED_OPERATIONS. The domain-event channels are added by
10821
+ // the actor state unit's start() below.
10822
+ channels: WEAVER_REPLY_CHANNELS
10702
10823
  });
10703
10824
  const actorStateUnit = createWeaverActorStateUnit({
10704
10825
  bus: httpTransport.actor
@@ -10755,22 +10876,12 @@ async function main() {
10755
10876
  };
10756
10877
  process.on("SIGTERM", shutdown);
10757
10878
  process.on("SIGINT", shutdown);
10758
- catchUpState = { phase: "running" };
10759
- try {
10760
- const summary = await weaver.catchUp();
10761
- catchUpState = { phase: "done", summary };
10762
- } catch (error) {
10763
- catchUpState = { phase: "failed", error: error instanceof Error ? error.message : String(error) };
10764
- throw error;
10765
- }
10766
- reconcileState = { phase: "running" };
10767
- try {
10768
- const summary = await weaver.reconcile();
10769
- reconcileState = { phase: "done", summary };
10770
- } catch (error) {
10771
- reconcileState = { phase: "failed", error: error instanceof Error ? error.message : String(error) };
10772
- throw error;
10773
- }
10879
+ await runBootPass("catch-up", () => weaver.catchUp(), logger, (s) => {
10880
+ catchUpState = s;
10881
+ });
10882
+ await runBootPass("reconcile", () => weaver.reconcile(), logger, (s) => {
10883
+ reconcileState = s;
10884
+ });
10774
10885
  }
10775
10886
  main().catch((error) => {
10776
10887
  logger.error("Fatal", { error: error instanceof Error ? error.message : String(error), stack: error instanceof Error ? error.stack : void 0 });