@semiont/make-meaning 0.5.26 → 0.5.27

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
@@ -187,7 +187,7 @@ The EventBus is created by the backend (or script) and passed into `startMakeMea
187
187
 
188
188
  ### Pure projection validators
189
189
 
190
- The dispatcher in [`src/handlers/job-commands.ts`](src/handlers/job-commands.ts) does projection-validated job creation: when a `mark.assist` (linking) or `yield.fromAnnotation` job arrives with `entityTypes`, the dispatcher validates that every tag is registered; when a tagging job arrives with a `schemaId`, the dispatcher resolves it against the registered tag-schema set.
190
+ The dispatcher in [`src/handlers/job-commands.ts`](src/handlers/job-commands.ts) does projection-validated job creation: when a `mark.assist` (linking) or `yield.fromContext` job arrives with `entityTypes`, the dispatcher validates that every tag is registered; when a tagging job arrives with a `schemaId`, the dispatcher resolves it against the registered tag-schema set.
191
191
 
192
192
  Both rules are pure functions in [`src/views/projection-validators.ts`](src/views/projection-validators.ts):
193
193
 
package/dist/index.d.ts CHANGED
@@ -54,10 +54,26 @@ interface MakeMeaningConfig {
54
54
  gather: {
55
55
  settleTimeoutMs: number;
56
56
  };
57
+ /**
58
+ * Search policy. `semanticFloor` is the minimum cosine score a vector hit
59
+ * needs to appear in the semantic fallback (SEMANTIC-FALLBACK decision #1)
60
+ * — REQUIRED: the TOML loader owns the one default (0.6 at
61
+ * `[environments.<env>.make-meaning.search]`); hand-built configs
62
+ * (scripts, tests) state their policy explicitly.
63
+ */
64
+ search: {
65
+ semanticFloor: number;
66
+ };
57
67
  services: {
58
68
  graph?: GraphServiceConfig;
59
- vectors?: VectorsServiceConfig;
60
- embedding?: EmbeddingServiceConfig;
69
+ /** REQUIRED (MANDATORY-EMBEDDING D0+D1, type-level per the 2026-08-12
70
+ * ruling): the config NAMES its store — `memory` is a first-class
71
+ * explicit choice, never a fallback. The TOML loader refuses configs
72
+ * without it; the type makes hand-built configs state their choice. */
73
+ vectors: VectorsServiceConfig;
74
+ /** REQUIRED (same ruling): the embedding provider is the KB's semantic
75
+ * identity — always named, never detected or defaulted. */
76
+ embedding: EmbeddingServiceConfig;
61
77
  };
62
78
  /**
63
79
  * The KB's canonical identity domain — the SAME value `/api/tokens/agent`
@@ -181,14 +197,17 @@ interface KnowledgeBase {
181
197
  graph: GraphDatabase;
182
198
  weaveProgress: WeaveProgress;
183
199
  smeltProgress: SmeltProgress;
184
- vectors?: VectorStore;
200
+ vectors: VectorStore;
185
201
  projectionsDir: string;
186
202
  }
187
203
  interface CreateKnowledgeBaseOptions {
188
- vectorStore?: VectorStore;
204
+ /** Required (MANDATORY-EMBEDDING D0): a KB without vector search is not a
205
+ * configuration we support; `MemoryVectorStore` is the explicit named
206
+ * choice for stores that may rebuild on restart. */
207
+ vectorStore: VectorStore;
189
208
  skipRebuild?: boolean;
190
209
  }
191
- declare function createKnowledgeBase(eventStore: EventStore, project: SemiontProject, graphDb: GraphDatabase, eventBus: EventBus, logger: Logger, options?: CreateKnowledgeBaseOptions): Promise<KnowledgeBase>;
210
+ declare function createKnowledgeBase(eventStore: EventStore, project: SemiontProject, graphDb: GraphDatabase, eventBus: EventBus, logger: Logger, options: CreateKnowledgeBaseOptions): Promise<KnowledgeBase>;
192
211
 
193
212
  /**
194
213
  * Stower Actor
@@ -290,12 +309,12 @@ declare class Gatherer$1 {
290
309
  private inferenceClient;
291
310
  /** Settle bound for the resource-gather barrier — operator-owned config (D5), threaded from `MakeMeaningConfig.gather`. */
292
311
  private settleTimeoutMs;
293
- private embeddingProvider?;
312
+ private embeddingProvider;
294
313
  private subscriptions;
295
314
  private readonly logger;
296
315
  constructor(kb: KnowledgeBase, eventBus: EventBus, inferenceClient: InferenceClient,
297
316
  /** Settle bound for the resource-gather barrier — operator-owned config (D5), threaded from `MakeMeaningConfig.gather`. */
298
- settleTimeoutMs: number, logger: Logger, embeddingProvider?: EmbeddingProvider | undefined);
317
+ settleTimeoutMs: number, logger: Logger, embeddingProvider: EmbeddingProvider);
299
318
  initialize(): Promise<void>;
300
319
  private handleAnnotationGather;
301
320
  private handleResourceGather;
@@ -320,10 +339,10 @@ declare class Matcher {
320
339
  private kb;
321
340
  private eventBus;
322
341
  private inferenceClient;
323
- private embeddingProvider?;
342
+ private embeddingProvider;
324
343
  private subscriptions;
325
344
  private readonly logger;
326
- constructor(kb: KnowledgeBase, eventBus: EventBus, logger: Logger, inferenceClient: InferenceClient, embeddingProvider?: EmbeddingProvider | undefined);
345
+ constructor(kb: KnowledgeBase, eventBus: EventBus, logger: Logger, inferenceClient: InferenceClient, embeddingProvider: EmbeddingProvider);
327
346
  initialize(): Promise<void>;
328
347
  private handleSearch;
329
348
  /**
@@ -364,6 +383,31 @@ declare class Matcher {
364
383
  stop(): Promise<void>;
365
384
  }
366
385
 
386
+ /**
387
+ * LimitsDiscovery — the Browser's discovery pool for per-`(provider, model)`
388
+ * inference ceilings (INFERENCE-LIMITS-EXPOSURE P2).
389
+ *
390
+ * D1: the ONLY storage is in-memory — the pool's client instances, whose
391
+ * `limits()` single-flights and caches success internally, and deliberately
392
+ * clears its promise on failure so a briefly-down provider recovers on a
393
+ * later request (absent → present, no restart needed).
394
+ *
395
+ * D3: enrichment must never fail or block the directory reply. Three guards
396
+ * carry that, each pinned in `limits-discovery.test.ts`:
397
+ * - construction is guarded per pair — a throwing factory (e.g. an
398
+ * Anthropic section whose apiKey is left to worker-process env
399
+ * expansion) is a discovery failure, never a Browser startup failure;
400
+ * - every consult is raced against `LIMITS_ENRICH_BUDGET_MS`;
401
+ * - every failure path yields the entry WITHOUT `limits` — the same
402
+ * absence semantics `servesJobTypes` already has.
403
+ */
404
+
405
+ type CollaboratorEntry = components['schemas']['CollaboratorEntry'];
406
+ interface LimitsDiscovery {
407
+ /** The entries, each with `limits` attached where discovery answered within budget. */
408
+ enrich(entries: CollaboratorEntry[]): Promise<CollaboratorEntry[]>;
409
+ }
410
+
367
411
  /**
368
412
  * Browser Actor
369
413
  *
@@ -391,9 +435,17 @@ declare class Browser {
391
435
  private eventBus;
392
436
  private project;
393
437
  private config;
438
+ /** Discovered per-(provider, model) ceilings for the roster (INFERENCE-LIMITS-EXPOSURE P2). */
439
+ private limitsDiscovery;
440
+ /** For the semantic search fallback — mandatory (MANDATORY-EMBEDDING D0). */
441
+ private embeddingProvider;
394
442
  private subscriptions;
395
443
  private readonly logger;
396
- constructor(views: ViewStorage, kb: KnowledgeBase, eventBus: EventBus, project: SemiontProject, config: MakeMeaningConfig, logger: Logger);
444
+ constructor(views: ViewStorage, kb: KnowledgeBase, eventBus: EventBus, project: SemiontProject, config: MakeMeaningConfig,
445
+ /** Discovered per-(provider, model) ceilings for the roster (INFERENCE-LIMITS-EXPOSURE P2). */
446
+ limitsDiscovery: LimitsDiscovery,
447
+ /** For the semantic search fallback — mandatory (MANDATORY-EMBEDDING D0). */
448
+ embeddingProvider: EmbeddingProvider, logger: Logger);
397
449
  initialize(): Promise<void>;
398
450
  /**
399
451
  * Serve a resource's derived coordinate map (ANCHORED-TEXT-CACHE Lane 5).
@@ -580,7 +632,7 @@ declare class LocalTransport implements ITransport {
580
632
  private readonly bridgeSubs;
581
633
  private disposed;
582
634
  constructor(cfg: LocalTransportConfig);
583
- emit<K extends keyof EventMap>(channel: K, payload: EventMap[K], resourceScope?: ResourceId): Promise<void>;
635
+ emit<K extends keyof EventMap>(channel: K, payload: EventMap[K], resourceScope?: ResourceId): Promise<number>;
584
636
  on<K extends keyof EventMap>(channel: K, handler: (payload: EventMap[K]) => void): () => void;
585
637
  stream<K extends keyof EventMap>(channel: K): Observable<EventMap[K]>;
586
638
  subscribeToResource(_resourceId: ResourceId): () => void;
@@ -1380,8 +1432,11 @@ declare class AnnotationOperations {
1380
1432
  /**
1381
1433
  * Resource Context
1382
1434
  *
1383
- * Assembles resource context from view storage and content store
1384
- * Does NOT touch the graph - graph queries go through GraphContext
1435
+ * Assembles resource context from view storage and content store.
1436
+ * Graph queries go through GraphContext with one deliberate exception:
1437
+ * `listResources`' search path runs inside the graph engine, and its
1438
+ * semantic fallback (SEMANTIC-FALLBACK) reads the vector index. Both are
1439
+ * single-index reads; anything that FUSES sources belongs to the Matcher.
1385
1440
  */
1386
1441
 
1387
1442
  interface ListResourcesFilters {
@@ -1392,9 +1447,35 @@ interface ListResourcesFilters {
1392
1447
  limit?: number;
1393
1448
  }
1394
1449
  interface ListResourcesResult {
1395
- resources: ResourceDescriptor[];
1450
+ /** Semantic hits carry `content` — the passage that matched, not a preview. */
1451
+ resources: Array<ResourceDescriptor & {
1452
+ content?: string;
1453
+ }>;
1396
1454
  /** Size of the whole match set, not of the returned page. */
1397
1455
  total: number;
1456
+ /**
1457
+ * Which kind of answer this is (SEMANTIC-FALLBACK): 'lexical' for the
1458
+ * graph/view paths (including an honestly-empty page), 'semantic' when an
1459
+ * empty lexical search was answered from the vector index. REQUIRED — an
1460
+ * optional discriminator defaulting to lexical would let a missing value
1461
+ * silently read as lexical.
1462
+ */
1463
+ matchKind: 'lexical' | 'semantic';
1464
+ }
1465
+ /**
1466
+ * What the semantic fallback needs, passed as plain arguments (the
1467
+ * buildContext idiom — providers are parameters, not fields). Both the
1468
+ * provider and `kb.vectors` are mandatory (MANDATORY-EMBEDDING D0; the old
1469
+ * unconfigured branches — SEMANTIC-FALLBACK S3/S4 — were deliberately
1470
+ * retired with that change). What still degrades is FAILURE: a throwing
1471
+ * embed yields the empty lexical page (S5), because mandatory does not
1472
+ * mean always up.
1473
+ */
1474
+ interface SemanticFallbackDeps {
1475
+ embeddingProvider: EmbeddingProvider;
1476
+ /** Minimum cosine score for a hit to appear — `search.semanticFloor`. */
1477
+ semanticFloor: number;
1478
+ logger: Logger;
1398
1479
  }
1399
1480
  declare class ResourceContext {
1400
1481
  /**
@@ -1415,7 +1496,23 @@ declare class ResourceContext {
1415
1496
  * barrier-stamped projection, so an unsearched listing is read-your-writes
1416
1497
  * where the graph is only eventually consistent.
1417
1498
  */
1418
- static listResources(filters: ListResourcesFilters | undefined, kb: KnowledgeBase): Promise<ListResourcesResult>;
1499
+ static listResources(filters: ListResourcesFilters | undefined, kb: KnowledgeBase, semantic: SemanticFallbackDeps): Promise<ListResourcesResult>;
1500
+ /**
1501
+ * Answer an empty lexical search from the vector index (SEMANTIC-FALLBACK):
1502
+ * embed the query once, fold chunk hits per resource, floor them, and label
1503
+ * the answer 'semantic' so the UI can say "no title matches, but these
1504
+ * documents discuss it".
1505
+ *
1506
+ * Degradation is the contract (axioms S3–S5): unconfigured vectors, an
1507
+ * absent provider, or ANY failure inside the fallback yields the same
1508
+ * empty page the caller already had, labelled 'lexical' — a broken
1509
+ * fallback must never turn a working empty search into an error.
1510
+ *
1511
+ * The floor is applied HERE rather than passed as `scoreThreshold`, so the
1512
+ * below-floor hits exist to be counted — the debug line is the evidence
1513
+ * decision #1's guessed 0.6 gets tuned from.
1514
+ */
1515
+ private static semanticFallback;
1419
1516
  /**
1420
1517
  * Add content previews to resources (for search results)
1421
1518
  * Retrieves and decodes the first 200 characters of each resource's primary representation
@@ -1460,7 +1557,7 @@ declare class AnnotationContext {
1460
1557
  * @returns Rich context for LLM processing
1461
1558
  * @throws Error if annotation or resource not found
1462
1559
  */
1463
- static buildLLMContext(annotationId: AnnotationId, resourceId: ResourceId, kb: KnowledgeBase, options?: BuildContextOptions, inferenceClient?: InferenceClient, logger?: Logger, embeddingProvider?: EmbeddingProvider): Promise<GatheredContext>;
1560
+ static buildLLMContext(annotationId: AnnotationId, resourceId: ResourceId, kb: KnowledgeBase, embeddingProvider: EmbeddingProvider, options?: BuildContextOptions, inferenceClient?: InferenceClient, logger?: Logger): Promise<GatheredContext>;
1464
1561
  /**
1465
1562
  * Get resource annotations from view storage (fast path)
1466
1563
  * Throws if view missing