@equationalapplications/core-llm-wiki 6.1.0 → 6.3.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.
package/README.md CHANGED
@@ -535,7 +535,11 @@ const wikiMemory = new WikiMemory(db, {
535
535
  });
536
536
  ```
537
537
 
538
- `seedManifests` entries are written to SQLite on first access when no row exists for that entity.
538
+ `seedManifests` entries are written to SQLite the first time an entity's ontology is
539
+ resolved *inside a transaction* (ingest, heal) and no row exists for it. A read outside a
540
+ transaction — including `getOntologyManifest` — resolves the seed without persisting it, so
541
+ a configured entity can report a manifest while still having no row in `entity_manifests`.
542
+ That distinction matters for `ifAbsent` below.
539
543
 
540
544
  ### Public API
541
545
 
@@ -559,6 +563,37 @@ await wikiMemory.setOntologyManifest('team-alpha', {
559
563
  }, { mode: 'strict' });
560
564
  ```
561
565
 
566
+ Seed several entities atomically — all manifests are written in one transaction,
567
+ so a failure partway through leaves none of them behind:
568
+
569
+ ```typescript
570
+ const { written, skipped } = await wikiMemory.setOntologyManifests(
571
+ [
572
+ { entityId: 'tier_fact', manifest, mode: 'strict' },
573
+ { entityId: 'tier_wisdom', manifest, mode: 'strict' },
574
+ ],
575
+ { ifAbsent: true },
576
+ );
577
+ // written: entities whose manifest this call wrote
578
+ // skipped: entities that already had a persisted manifest (only under `ifAbsent`)
579
+ ```
580
+
581
+ `ifAbsent` makes each write create-if-absent rather than an upsert, so a
582
+ concurrent initializer loses the race by writing nothing instead of overwriting
583
+ a manifest it never read. Omit it for replace-on-conflict, which is what
584
+ `setOntologyManifest` does.
585
+
586
+ **`ifAbsent` tests for a persisted row, not for an effective manifest.** An entity
587
+ whose manifest comes from `WikiConfig.ontology.seedManifests` has no row until an
588
+ ingest materializes one, so `ifAbsent` writes over the configured seed and reports
589
+ the entity in `written`; after an ingest has run for that entity the same call
590
+ reports it in `skipped`. Don't mix the two seeding routes for one entity: seed it
591
+ through the config, or through this method, not both.
592
+
593
+ The method takes data, never a transaction handle: `WikiMemory` serializes
594
+ transactions on the adapter it is given, so a transaction opened on the adapter
595
+ you passed to `createWiki` would not participate in that serialization.
596
+
562
597
  ### Fact Shape Extensions
563
598
 
564
599
  In **Strict** and **Emergent** modes, librarian and ingest JSON may include typed facts with inline edges:
@@ -1211,6 +1246,7 @@ The flowchart shows:
1211
1246
  | [@equationalapplications/core-llm-tools](https://github.com/equationalapplications/expo-llm-wiki/blob/main/packages/core-llm-tools/README.md) | Gemini tool schemas and capability injector |
1212
1247
  | [@equationalapplications/core-okf](https://github.com/equationalapplications/expo-llm-wiki/blob/main/packages/okf/README.md) | Zero-dependency Open Knowledge Format (OKF) v0.1 + v0.2 primitives — parse and produce interoperable knowledge bundles. |
1213
1248
  | [@equationalapplications/schema-org-llm-wiki](https://github.com/equationalapplications/expo-llm-wiki/blob/main/packages/schema-org/README.md) | Curated schema.org warm-agent ontology manifest |
1249
+ | [@equationalapplications/schema-software-org](https://github.com/equationalapplications/expo-llm-wiki/blob/main/packages/schema-software-org/README.md) | Software-organization executive ontology manifest — 17 node types, 40 edges, warm-agent superset, data-only |
1214
1250
 
1215
1251
  ## OKF v0.2 conformance (llm-wiki/2)
1216
1252
 
@@ -2337,15 +2337,29 @@ var MetadataRepository = class extends BaseRepository {
2337
2337
  manifest
2338
2338
  };
2339
2339
  }
2340
- async setManifest(entityId, data, tx) {
2340
+ /**
2341
+ * Write an entity's manifest.
2342
+ *
2343
+ * `opts.ifAbsent` selects the conflict behaviour:
2344
+ * - omitted / `false` — upsert. An existing row is replaced.
2345
+ * - `true` — create-if-absent. An existing row is left exactly as it is.
2346
+ *
2347
+ * Returns whether this call actually wrote a row. Under `ifAbsent` a `false`
2348
+ * result means another writer got there first; the check and the write are one
2349
+ * statement, so there is no window between them.
2350
+ */
2351
+ async setManifest(entityId, data, tx, opts) {
2341
2352
  validateManifest(data.manifest);
2342
2353
  const executor = this.getExecutor(tx);
2343
- await executor.runAsync(
2354
+ const conflictClause = opts?.ifAbsent ? "ON CONFLICT(entity_id) DO NOTHING" : `ON CONFLICT(entity_id) DO UPDATE SET
2355
+ mode = excluded.mode, manifest_json = excluded.manifest_json, updated_at = excluded.updated_at`;
2356
+ const result = await executor.runAsync(
2344
2357
  `INSERT INTO ${this.prefix}entity_manifests (entity_id, mode, manifest_json, updated_at)
2345
2358
  VALUES (?, ?, ?, ?)
2346
- ON CONFLICT(entity_id) DO UPDATE SET mode = excluded.mode, manifest_json = excluded.manifest_json, updated_at = excluded.updated_at`,
2359
+ ${conflictClause}`,
2347
2360
  [entityId, data.mode, JSON.stringify(data.manifest), Date.now()]
2348
2361
  );
2362
+ return result.changes > 0;
2349
2363
  }
2350
2364
  async mergeManifestUpdates(entityId, updates, tx) {
2351
2365
  const current = await this.getManifest(entityId, tx) ?? {
@@ -4620,5 +4634,5 @@ var WriteService = class {
4620
4634
  };
4621
4635
 
4622
4636
  export { BaseRepository, DEFAULT_CHUNK_OVERLAP, DEFAULT_MAX_CHUNK_LENGTH, EmbeddingService, HEAL_ANCHORS_PER_CANDIDATE, HEAL_BATCH_SIZE, HEAL_MAX_FACT_BODY_CHARS_L3, HEAL_MAX_TASKS, HEAL_RECHECK_MS, HOOK_TIMEOUT_MARKER, ImportExportService, IngestionService, JobManager, MaintenanceService, MetadataRepository, ONTOLOGY_BACKFILL_BATCH_SIZE, ONTOLOGY_BACKFILL_MAX_PROMPT_CHARS, ONTOLOGY_BACKFILL_RECHECK_MS, ONTOLOGY_BACKFILL_SYSTEM_PROMPT, PromptService, PrunePartialFailureError, RetrievalService, SearchService, WikiBusyError, WikiDuplicateHashError, WikiIngestEmptyError, WikiParseError, WikiSourceRefHashCollision, WikiStrictOntologyViolation, WikiTransactionError, WriteService, __privateAdd, __privateGet, __privateSet, chunkText, configureRandomSource, emptyManifest, entitySummaryMetaKey, extractSqliteCode, generateId, normalizeSourceHash, normalizeSourceRef, normalizeTitleKey, parseEmbedding, resolveEdgeDefinitions, resolveNodeType, safeSlice, typeSatisfies, validateInlineEdges, validateManifest };
4623
- //# sourceMappingURL=chunk-YEESP6J2.mjs.map
4624
- //# sourceMappingURL=chunk-YEESP6J2.mjs.map
4637
+ //# sourceMappingURL=chunk-YDTJ2OO4.mjs.map
4638
+ //# sourceMappingURL=chunk-YDTJ2OO4.mjs.map