@weftlet/toolkit 0.6.1 → 0.7.1

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.
Files changed (196) hide show
  1. package/README.md +191 -18
  2. package/THIRD_PARTY_NOTICES.md +3 -1
  3. package/dist/application/application.d.ts +10 -0
  4. package/dist/application/application.js +20 -0
  5. package/dist/application/document-code-bindings.d.ts +11 -0
  6. package/dist/application/document-code-bindings.js +25 -0
  7. package/dist/application/document-obligations.d.ts +8 -0
  8. package/dist/application/document-obligations.js +11 -0
  9. package/dist/application/draft-facts.d.ts +3 -0
  10. package/dist/application/draft-facts.js +37 -0
  11. package/dist/application/extraction-identity.d.ts +2 -2
  12. package/dist/application/extraction-identity.js +7 -1
  13. package/dist/application/extractor-results.d.ts +6 -0
  14. package/dist/application/extractor-results.js +6 -0
  15. package/dist/application/hydrator.js +38 -18
  16. package/dist/application/mapping-proposals.d.ts +108 -0
  17. package/dist/application/mapping-proposals.js +142 -0
  18. package/dist/application/mapping-service.d.ts +2 -0
  19. package/dist/application/mapping-service.js +5 -0
  20. package/dist/application/overlay.js +43 -29
  21. package/dist/application/saved-code-coverage.d.ts +40 -0
  22. package/dist/application/saved-code-coverage.js +20 -0
  23. package/dist/application/saved-compatibility.d.ts +38 -0
  24. package/dist/application/saved-compatibility.js +20 -0
  25. package/dist/application/saved-evidence.d.ts +17 -11
  26. package/dist/application/saved-evidence.js +44 -40
  27. package/dist/application/saved-exploration.d.ts +57 -0
  28. package/dist/application/saved-exploration.js +21 -0
  29. package/dist/application/saved-paths.d.ts +58 -0
  30. package/dist/application/saved-paths.js +20 -0
  31. package/dist/application/semantic-run.d.ts +1 -1
  32. package/dist/extraction/call-syntax.d.ts +18 -0
  33. package/dist/extraction/call-syntax.js +61 -0
  34. package/dist/extraction/canonical-document-links.d.ts +5 -1
  35. package/dist/extraction/canonical-document-links.js +4 -4
  36. package/dist/extraction/code-inventory.d.ts +6 -0
  37. package/dist/extraction/code-inventory.js +26 -0
  38. package/dist/extraction/document-code-bindings.d.ts +14 -0
  39. package/dist/extraction/document-code-bindings.js +121 -0
  40. package/dist/extraction/document-obligations.d.ts +12 -0
  41. package/dist/extraction/document-obligations.js +112 -0
  42. package/dist/extraction/mapping-candidates.d.ts +13 -0
  43. package/dist/extraction/mapping-candidates.js +46 -0
  44. package/dist/extraction/mapping-output.d.ts +75 -0
  45. package/dist/extraction/mapping-output.js +53 -0
  46. package/dist/extraction/mapping-plan.d.ts +7 -0
  47. package/dist/extraction/mapping-plan.js +117 -0
  48. package/dist/extraction/mapping-prompt.d.ts +2 -0
  49. package/dist/extraction/mapping-prompt.js +17 -0
  50. package/dist/extraction/mapping-provider.d.ts +15 -0
  51. package/dist/extraction/mapping-provider.js +60 -0
  52. package/dist/extraction/mapping-request.d.ts +3 -0
  53. package/dist/extraction/mapping-request.js +32 -0
  54. package/dist/extraction/ontology.d.ts +2 -0
  55. package/dist/extraction/ontology.js +28 -13
  56. package/dist/extraction/routing.js +5 -20
  57. package/dist/extraction/scip-occurrences.d.ts +3 -0
  58. package/dist/extraction/scip-occurrences.js +102 -0
  59. package/dist/extraction/scip-ranges.d.ts +6 -0
  60. package/dist/extraction/scip-ranges.js +31 -0
  61. package/dist/extraction/scip-runtime.d.ts +39 -0
  62. package/dist/extraction/scip-runtime.js +8 -0
  63. package/dist/extraction/scip-symbols.d.ts +21 -0
  64. package/dist/extraction/scip-symbols.js +91 -0
  65. package/dist/extraction/semantic.d.ts +1 -1
  66. package/dist/extraction/semantic.js +5 -17
  67. package/dist/extraction/static-calls.d.ts +10 -0
  68. package/dist/extraction/static-calls.js +133 -0
  69. package/dist/extraction/static.d.ts +3 -20
  70. package/dist/extraction/static.js +8 -84
  71. package/dist/extraction/symbol-resolution.d.ts +12 -0
  72. package/dist/extraction/symbol-resolution.js +51 -0
  73. package/dist/extraction/symbol-selectors.d.ts +11 -0
  74. package/dist/extraction/symbol-selectors.js +51 -0
  75. package/dist/graph/binding-rdf.d.ts +7 -0
  76. package/dist/graph/binding-rdf.js +109 -0
  77. package/dist/graph/call-rdf.d.ts +4 -0
  78. package/dist/graph/call-rdf.js +94 -0
  79. package/dist/graph/call-shapes.d.ts +2 -0
  80. package/dist/graph/call-shapes.js +28 -0
  81. package/dist/graph/code-coverage-projection.d.ts +9 -0
  82. package/dist/graph/code-coverage-projection.js +117 -0
  83. package/dist/graph/code-coverage-renderer.d.ts +2 -0
  84. package/dist/graph/code-coverage-renderer.js +15 -0
  85. package/dist/graph/code-coverage-request.d.ts +6 -0
  86. package/dist/graph/code-coverage-request.js +19 -0
  87. package/dist/graph/code-coverage.d.ts +6 -0
  88. package/dist/graph/code-coverage.js +54 -0
  89. package/dist/graph/code-description.d.ts +4 -0
  90. package/dist/graph/code-description.js +24 -0
  91. package/dist/graph/code-rdf.d.ts +6 -0
  92. package/dist/graph/code-rdf.js +79 -0
  93. package/dist/graph/compatibility-context.d.ts +2 -0
  94. package/dist/graph/compatibility-context.js +18 -0
  95. package/dist/graph/compatibility-renderer.d.ts +2 -0
  96. package/dist/graph/compatibility-renderer.js +45 -0
  97. package/dist/graph/compatibility-request.d.ts +3 -0
  98. package/dist/graph/compatibility-request.js +18 -0
  99. package/dist/graph/compatibility.d.ts +7 -0
  100. package/dist/graph/compatibility.js +67 -0
  101. package/dist/graph/constraint-comparison.d.ts +7 -0
  102. package/dist/graph/constraint-comparison.js +49 -0
  103. package/dist/graph/coverage.d.ts +2 -2
  104. package/dist/graph/coverage.js +8 -3
  105. package/dist/graph/diagnostics.d.ts +1 -1
  106. package/dist/graph/diagnostics.js +10 -6
  107. package/dist/graph/evidence-description.d.ts +3 -0
  108. package/dist/graph/evidence-description.js +13 -0
  109. package/dist/graph/identity-preflight.js +1 -1
  110. package/dist/graph/neighborhood-renderer.d.ts +2 -0
  111. package/dist/graph/neighborhood-renderer.js +38 -0
  112. package/dist/graph/neighborhood-request.d.ts +9 -0
  113. package/dist/graph/neighborhood-request.js +37 -0
  114. package/dist/graph/neighborhood.d.ts +8 -0
  115. package/dist/graph/neighborhood.js +100 -0
  116. package/dist/graph/obligation-rdf.d.ts +5 -0
  117. package/dist/graph/obligation-rdf.js +67 -0
  118. package/dist/graph/obligation-shapes.d.ts +2 -0
  119. package/dist/graph/obligation-shapes.js +32 -0
  120. package/dist/graph/partitioned-shacl.d.ts +14 -0
  121. package/dist/graph/partitioned-shacl.js +66 -0
  122. package/dist/graph/path-request.d.ts +11 -0
  123. package/dist/graph/path-request.js +24 -0
  124. package/dist/graph/path-search.d.ts +45 -0
  125. package/dist/graph/path-search.js +101 -0
  126. package/dist/graph/paths-renderer.d.ts +2 -0
  127. package/dist/graph/paths-renderer.js +36 -0
  128. package/dist/graph/paths.d.ts +7 -0
  129. package/dist/graph/paths.js +74 -0
  130. package/dist/graph/query.js +23 -6
  131. package/dist/graph/rdf-partitions.d.ts +24 -0
  132. package/dist/graph/rdf-partitions.js +170 -0
  133. package/dist/graph/rdf-projection.d.ts +7 -0
  134. package/dist/graph/rdf-projection.js +27 -0
  135. package/dist/graph/rdf-records.d.ts +12 -0
  136. package/dist/graph/rdf-records.js +90 -0
  137. package/dist/graph/rdf.d.ts +10 -10
  138. package/dist/graph/rdf.js +84 -89
  139. package/dist/graph/shacl-shapes.js +70 -0
  140. package/dist/graph/snapshot-context.d.ts +3 -0
  141. package/dist/graph/snapshot-context.js +8 -0
  142. package/dist/graph/validation-progress.d.ts +4 -1
  143. package/dist/index.d.ts +23 -0
  144. package/dist/index.js +22 -0
  145. package/dist/infrastructure/json-digest.d.ts +3 -0
  146. package/dist/infrastructure/json-digest.js +3 -0
  147. package/dist/infrastructure/unique-json.d.ts +2 -0
  148. package/dist/infrastructure/unique-json.js +20 -0
  149. package/dist/interfaces/cli.js +33 -1
  150. package/dist/interfaces/code-coverage.d.ts +46 -0
  151. package/dist/interfaces/code-coverage.js +18 -0
  152. package/dist/interfaces/graph-compatibility.d.ts +35 -0
  153. package/dist/interfaces/graph-compatibility.js +21 -0
  154. package/dist/interfaces/graph-exploration.d.ts +59 -0
  155. package/dist/interfaces/graph-exploration.js +27 -0
  156. package/dist/interfaces/graph-paths.d.ts +77 -0
  157. package/dist/interfaces/graph-paths.js +31 -0
  158. package/dist/interfaces/graph-query-args.d.ts +2 -0
  159. package/dist/interfaces/graph-query-args.js +25 -0
  160. package/dist/interfaces/mapping-proposals.d.ts +204 -0
  161. package/dist/interfaces/mapping-proposals.js +74 -0
  162. package/dist/interfaces/mcp.js +31 -3
  163. package/dist/storage/mapping-proposals.d.ts +9 -0
  164. package/dist/storage/mapping-proposals.js +42 -0
  165. package/dist/storage/storage.d.ts +3 -0
  166. package/dist/storage/storage.js +37 -13
  167. package/dist/storage/streaming-json.d.ts +5 -0
  168. package/dist/storage/streaming-json.js +45 -0
  169. package/dist/visualization/evidence-sources.d.ts +6 -0
  170. package/dist/visualization/evidence-sources.js +19 -0
  171. package/dist/visualization/viewer-interaction.d.ts +5 -8
  172. package/dist/visualization/viewer-interaction.js +46 -44
  173. package/dist/visualization/visualization.js +14 -5
  174. package/docs/1.0-WORK-QUEUE.md +48 -0
  175. package/docs/ADR-029-exact-graph-neighborhoods.md +70 -0
  176. package/docs/ADR-030-bounded-evidence-paths.md +97 -0
  177. package/docs/ADR-031-code-extractor-selection.md +91 -0
  178. package/docs/ADR-032-scip-code-evidence.md +73 -0
  179. package/docs/ADR-033-document-symbol-bindings.md +83 -0
  180. package/docs/ADR-034-mapping-gaps.md +80 -0
  181. package/docs/ADR-035-static-call-evidence.md +78 -0
  182. package/docs/ADR-036-contract-obligation-declarations.md +124 -0
  183. package/docs/ADR-037-selected-contract-compatibility.md +93 -0
  184. package/docs/ADR-038-monorepo-code-coverage.md +105 -0
  185. package/docs/ADR-039-mapping-proposals.md +119 -0
  186. package/docs/ADR-040-bounded-graph-io.md +90 -0
  187. package/docs/GRAPHIFY-EVALUATION.md +21 -4
  188. package/docs/PRE-1.0-BASELINE.md +49 -2
  189. package/docs/RELEASE-1.0-PLAN.md +14 -2
  190. package/docs/RELEASING.md +3 -3
  191. package/docs/ROADMAP.md +27 -6
  192. package/docs/VALIDATION.md +521 -14
  193. package/docs/benchmarks/large-graph-2026-11-02/result.json +156 -0
  194. package/docs/extraction-manifest.json +266 -23
  195. package/package.json +10 -4
  196. package/templates/context-graph-development/SKILL.md +30 -1
package/README.md CHANGED
@@ -14,7 +14,7 @@ Proposed future capabilities are recorded in the [Weftlet 2.0 product plan](docs
14
14
  ## Set up a project
15
15
 
16
16
  <!-- weftlet:release:start -->
17
- Package versions in this checkout/archive: `@weftlet/toolkit@0.6.1` and `@weftlet/core@0.6.1`.
17
+ Package versions in this checkout/archive: `@weftlet/toolkit@0.7.1` and `@weftlet/core@0.7.1`.
18
18
  <!-- weftlet:release:end -->
19
19
 
20
20
  Weftlet uses `@weftlet/toolkit`; its neutral `@weftlet/core` dependency is installed
@@ -228,24 +228,31 @@ its sidecar policy is not automatically adopted by hydration. See
228
228
 
229
229
  Starting with **0.5.0**, identity preflight runs before ontology/RDF work.
230
230
  `hydrate --json --quiet` reports conflicts using opaque references; `--validation-details` explicitly
231
- includes local identities, producer versions and citations. Validation emits phase-boundary times
232
- and graph counts, without a percentage or live heartbeat. Full SHACL remains required after a
231
+ includes local identities, producer versions and citations. Validation emits phase timings,
232
+ graph counts and completed validation groups. These are not completion-time estimates. Full SHACL remains required after a
233
233
  passing preflight. See [ADR 021](docs/ADR-021-identity-preflight-and-validation-timing.md).
234
234
 
235
235
  Version 0.5.0 also accepts `semantic.timeoutMs: 600000` for an approved ten-minute extraction
236
236
  attempt; the default remains two minutes. See [provider limits and reuse](docs/PROVIDERS.md#limits-and-reuse)
237
237
  before retrying with compatible cached artifacts.
238
238
 
239
- Starting with 0.3.0, the toolkit indexes a temporary union to accelerate cold validation.
240
- The toolkit uses JavaScript `rdf-validate-shacl` and an in-memory
241
- N3 store. Each hydration validates the complete graph; semantic artifact reuse does not make
242
- validation incremental, and there is no validation-result cache, Rust engine or GraphDB service.
243
- Saved queries do not rerun SHACL.
239
+ The toolkit uses JavaScript `rdf-validate-shacl` with bounded N3 subject groups. Each hydration
240
+ validates the complete graph; semantic artifact reuse does not make validation incremental.
241
+ There is no validation-result cache, Rust engine or GraphDB service. Saved queries do not rerun SHACL.
244
242
 
245
- The current shapes use subject/predicate/object values independently of graph names. Validation
246
- now builds one temporary union graph so repeated property lookups avoid scanning every named
247
- assertion graph. The same shapes and validator run against that union. The original named dataset,
248
- assertion records and provenance remain the source for SPARQL, queries and serialization.
243
+ Complete identity groups preserve conflicting assertions, and graph-wide class membership retains
244
+ cross-record proof checks. The same strict shapes run on every target. The RDF encoder also serves
245
+ streamed N-Quads exports and SPARQL; traversal projections have SPARQL equivalence tests. Hashing and
246
+ snapshot JSON persistence/reload avoid a whole-graph string. Existing canonical digests, cache keys
247
+ and immutable snapshot bytes are preserved. See [ADR 040](docs/ADR-040-bounded-graph-io.md) for the
248
+ partition correctness boundary, public corpus regression and remaining memory limits.
249
+
250
+ For large programmatic RDF exports, use `await graph.serializeTo(writable)` or consume
251
+ `graph.serializeChunks()`. The `serialize()` convenience returns a single string and therefore
252
+ remains subject to JavaScript's string-size limit.
253
+
254
+ The 0.3.0 optimization built a complete temporary validation union. The measurements below describe
255
+ that earlier implementation; they are not timings for the current richer code graph.
249
256
 
250
257
  In bounded, single-run public experiments, 2,000 facts with unique subject/object nodes took
251
258
  31.50 seconds in the original SHACL path, compared with 0.153 seconds to build the union and
@@ -260,12 +267,11 @@ pnpm build
260
267
  pnpm benchmark:shacl
261
268
  ```
262
269
 
263
- The [T05 closeout](docs/ADR-027-validation-closeout.md) measures cold, repeated and changed inputs,
264
- plus worker, exact-result-key and Rust prototypes. Direct full validation remains the 1.0 choice:
270
+ The historical [T05 closeout](docs/ADR-027-validation-closeout.md) measures cold, repeated and changed inputs,
271
+ plus worker, exact-result-key and Rust prototypes:
265
272
  the 10,000-fact public cases measured about 2.9–5.7 seconds, with material memory use. These are
266
273
  fixture measurements, not a private consumer capacity guarantee. The prototypes are development
267
- tools, not runtime options; every hydration still performs full validation. Current progress reports
268
- phase boundaries because synchronous work blocks same-thread timers. Reproduce the lifecycle study
274
+ tools, not runtime options; every hydration still performs full validation. Reproduce that lifecycle study
269
275
  from a development checkout with `pnpm benchmark:validation`; raw results and commands are linked
270
276
  from the ADR.
271
277
 
@@ -349,6 +355,123 @@ context-graph impact scan --config context-graph.config.json --capability search
349
355
  context-graph visualize --config context-graph.config.json --capability search --output graph.html
350
356
  ```
351
357
 
358
+ **Available starting with 0.7.0:** for precise follow-up, copy the returned
359
+ snapshot ID and a node ID from a cited fact:
360
+
361
+ ```sh
362
+ weftlet graph neighbors --snapshot <snapshot-id> --node <node-id> --direction both --max-facts 20 --json
363
+ ```
364
+
365
+ MCP exposes the same read-only operation as `graph.neighbors` with `snapshotId` and `nodeId`.
366
+ Use `predicates` (CLI: repeat `--predicate`) to select relations and `direction` for incoming,
367
+ outgoing or both. Follow `selection.continuation` with the same arguments to retrieve more
368
+ assertions. `frontier.neighbors` identifies returned neighbors with other incident evidence;
369
+ query one of those IDs with the same snapshot to investigate another area. These are exact-ID,
370
+ one-hop reads of saved evidence: no model or indexer is invoked. Each assertion retains its own
371
+ citations, authority and review state, including multiple assertions about the same edge.
372
+ Page completion does not establish complete product coverage. See [the query contract](docs/ADR-029-exact-graph-neighborhoods.md).
373
+
374
+ Starting with 0.7.0, Weftlet preserves typed `CodeSymbol` definitions and individual SCIP
375
+ references, including local symbols, repeated same-file uses and one-based UTF-16 columns.
376
+ From a physical-file node, request incoming `definedBy` facts to discover its symbols; from a
377
+ symbol, request incoming/outgoing `references` to inspect exact occurrences. Native lexical
378
+ enclosure is not a call graph. Resolution distinguishes indexed definitions, declaration-only
379
+ targets and absent indexed definitions. Local ordinal IDs are scoped to the exact index; refresh
380
+ code evidence before comparing revisions. See [code evidence and limits](docs/ADR-032-scip-code-evidence.md).
381
+ Weftlet also resolves explicit Markdown symbol selectors in selected documents:
382
+
383
+ ```md
384
+ [helper](../src/worker.ts#weftlet-symbol=Engine.execute)
385
+ [implementation](../src/worker.ts#weftlet-symbol=execute "weftlet:implementedBy invariant:max-age")
386
+ [check](../test/worker.test.ts#weftlet-symbol=check "weftlet:verifiedBy invariant:max-age")
387
+ ```
388
+
389
+ The first link creates a Document→references→CodeSymbol relationship. The annotated forms require
390
+ an exact existing business-node ID from the graph; discover it with `impact.scan`/`graph.neighbors`.
391
+ They declare a mapping and retain its supporting assertions and review state. They do not prove
392
+ that the implementation fulfills the rule or that a test passed. No function name or nearby prose
393
+ automatically creates an implementation mapping. Approved source documents remain distinguishable
394
+ from unreviewed extracted assertions.
395
+
396
+ Selectors match an exact indexed name, symbol ID, or unambiguous native lexical name such as
397
+ `Engine.execute` in the named file. For an alias or a specific occurrence, supply both one-based
398
+ UTF-16 coordinates, for example `#weftlet-symbol=publicAlias&weftlet-line=1&weftlet-column=23`.
399
+ The graph retains both the selected occurrence and all indexed target definitions, with digests
400
+ and commit SHAs. Missing/ambiguous targets produce cited `implementationGaps`, with no guessed link.
401
+ An indexed `.d.ts` declaration stays declaration-only. These links use the existing configured
402
+ semantic/document-traversal scope and SCIP selection; they require no extra provider call.
403
+ Validation documents stay outside intent extraction and can declare `verifiedBy`, not `implementedBy`.
404
+ See [ADR 033](docs/ADR-033-document-symbol-bindings.md) for bounds and draft-overlay behavior.
405
+
406
+ Version 0.7.0 also derives
407
+ `calls` from actual TypeScript call/new syntax and exact SCIP identities. Query a function's
408
+ incoming/outgoing `calls` to inspect callers/callees, or follow a bounded path using `calls` and
409
+ `implementedBy`. Each assertion retains callsite and endpoint proofs, with explicit bodyless,
410
+ external, optional and member-dispatch limits. Runtime execution is not implied. Values, callbacks
411
+ and dynamic dispatch without a known target remain references and cited gaps. See
412
+ [ADR 035](docs/ADR-035-static-call-evidence.md). Optional inferred-mapping proposals are available separately; see
413
+ [ADR 039](docs/ADR-039-mapping-proposals.md).
414
+
415
+ Selected Markdown documents can now declare producer guarantees and consumer requirements in
416
+ optional `weftlet-obligation` JSON fences. Both sides name an exact scoped/versioned queue or
417
+ stored-data contract and a repository endpoint. Agents retrieve these through `emits`/`consumes`
418
+ neighborhoods and paths, with the original statement, citations and any documented domain, stage,
419
+ constraint/unit and consumer revalidation requirement. Missing fields remain unknown. Declarations
420
+ do not establish fulfillment, runtime delivery or compatibility; ordinary prose is not automatically
421
+ converted into this format. See [the declaration format and example](docs/ADR-036-contract-obligation-declarations.md).
422
+ These declarations are supported starting with 0.7.0.
423
+
424
+ For two retrieved obligation facts, the published CLI supports:
425
+
426
+ ```sh
427
+ weftlet graph compatibility --snapshot <snapshot-id> --producer-fact <fact-id> --consumer-fact <fact-id> --json
428
+ ```
429
+
430
+ MCP `graph.compatibility` uses `snapshotId`, `producerFactId` and `consumerFactId`. It compares
431
+ explicit numeric constraints with matching domain, measurement stage, units and contract version.
432
+ Results distinguish compatible limits, an insufficient guarantee, disjoint limits, required
433
+ consumer revalidation and unknowns. Both original citations and source approvals remain visible.
434
+ This advisory assessment does not establish code fulfillment or a CI policy violation. See
435
+ [comparison semantics and limits](docs/ADR-037-selected-contract-compatibility.md). The command
436
+ reads saved evidence during edits without rebuilding it and is available starting with 0.7.0.
437
+
438
+ Saved repository code coverage is separate from the returned-page relationship counts:
439
+
440
+ ```sh
441
+ weftlet graph coverage --snapshot <snapshot-id> --max-items 20 --json
442
+ weftlet graph coverage --snapshot <snapshot-id> --project services/api --max-items 50 --json
443
+ ```
444
+
445
+ MCP `graph.coverage` accepts the same snapshot and an optional exact `projectRoot`; follow
446
+ `selection.continuation` with identical arguments. It first pages package boundaries, then files
447
+ within a chosen boundary. Reports distinguish `codeRoots`, requested SCIP entries, actual indexed
448
+ documents, omitted files/packages, cross-package code references and unresolved/declaration-only
449
+ targets. A selected directory or an import does not guarantee its files were indexed: configure
450
+ `scip.sourceProject.include` and aliases for the intended code scope. Other indexer invocations
451
+ retain unknown entry selection. Old snapshots without inventory report unknown coverage.
452
+ The overview also appears in agent queries and the viewer; zero observations never prove no
453
+ business impact. This is TypeScript-family source coverage grouped by nearest `package.json`,
454
+ not universal language or compiler-project coverage. See [ADR 038](docs/ADR-038-monorepo-code-coverage.md).
455
+ This feature requires a fresh snapshot from 0.7.0 or later (assembly 12); unchanged semantic
456
+ artifacts remain reusable.
457
+
458
+ The CLI also supports paths between two exact IDs:
459
+
460
+ ```sh
461
+ weftlet graph paths --snapshot <snapshot-id> --from <node-id> --to <node-id> --direction both --max-depth 8 --json
462
+ ```
463
+
464
+ MCP `graph.paths` takes `snapshotId`, `fromNodeId` and `toNodeId`. Direction defaults to outgoing;
465
+ use `predicates` to select relations. `maxPaths` (default 5, up to 20) bounds page results;
466
+ `maxSteps` (default 1000, up to 10000) bounds new candidate-edge examinations. Depth is 1–32;
467
+ the search's total ceiling is 100,000 examinations. Responses report replay work separately.
468
+ Follow `search.continuation` with identical inputs even if a work page contains no completed
469
+ path. Depth cuts and total-work exhaustion remain explicit without pretending all dependencies
470
+ were checked; inspect `frontier` and restart with greater depth or narrower endpoints/relations.
471
+ Paths are deterministic cited associations, not shortest routes or proof of business compatibility.
472
+ The HTML viewer uses the same engine and continuation on its displayed facts and selected layers.
473
+ See [path semantics and limits](docs/ADR-030-bounded-evidence-paths.md).
474
+
352
475
  Semantic hydration requires a working configured provider. Direct RDF is the default;
353
476
  Docker/openCAESAR is an optional explicit backend. Run `context-graph doctor` for setup diagnostics.
354
477
  Committed indexing and ontology input use disposable archives, preserving the active checkout.
@@ -366,8 +489,8 @@ ahead of repeated detail and shared-import context. Ranking changes ordering, no
366
489
  the reachable scope. Responses identify the ranking version; after a ranking upgrade, restart
367
490
  scans whose old continuation tokens are rejected. No snapshot refresh is needed for new ordering.
368
491
 
369
- This source includes a [coverage reporting correction](docs/ADR-024-implementation-coverage.md)
370
- for the next release: code relationships displayed under contracts also count as implementation
492
+ The published toolkit includes a [coverage reporting correction](docs/ADR-024-implementation-coverage.md)
493
+ that counts code relationships displayed under contracts as implementation
371
494
  evidence. New reports identify `coverage.scope: "returned-page"` and `countsAreNonExclusive: true`.
372
495
  Counts can overlap and describe returned evidence; they are not completeness percentages or proof
373
496
  that behavior is correct. Document/model claims and test-only evidence do not establish production
@@ -413,3 +536,53 @@ for observed gaps and the distinction between retrieval measurements and live se
413
536
 
414
537
  Apache-2.0. See [LICENSE](LICENSE), [NOTICE](NOTICE), and the
415
538
  [source inventory](docs/SOURCE-INVENTORY.md) for attribution and extraction history.
539
+
540
+ ## Optional mapping proposals (0.7.0)
541
+
542
+ When an approved document describes a rule and links implementation files without naming the
543
+ function, Weftlet can propose an exact rule-to-function mapping. This is opt-in, unreviewed
544
+ inference; it never approves intent, proves compliance, or adds edges to the saved graph.
545
+ Live model accuracy and usefulness validation are tentative and deferred to acceptance testing.
546
+ The maintainer authorized including this optional feature in the 0.7.0 acceptance candidate;
547
+ existing Codex hydration results do not establish the quality of these new proposals.
548
+
549
+ Create `mapping-request.json` using a saved snapshot and its exact graph IDs:
550
+
551
+ ```json
552
+ {
553
+ "snapshotId": "<saved-snapshot-id>",
554
+ "ruleId": "invariant:freshness",
555
+ "documentPath": "docs/owner.md",
556
+ "files": ["src/observations.ts"],
557
+ "maxCandidates": 8,
558
+ "maxInputBytes": 32768
559
+ }
560
+ ```
561
+
562
+ ```sh
563
+ weftlet mappings plan --request mapping-request.json
564
+ # Review readiness, source/code proofs, exclusions, input size and expected requests.
565
+ weftlet mappings propose --request mapping-request.json --allow-model
566
+ weftlet mappings read --snapshot <saved-snapshot-id> --key <returned-key>
567
+ ```
568
+
569
+ No configuration switch enables automatic inference. The proposal command reuses the existing
570
+ `semantic` model, reasoning and explicit authentication selection: Codex ChatGPT login remains
571
+ the default; configured API-key mode is optional. A compatible module must separately export
572
+ `createMappingProposalProvider(config)` with matching `identity` and
573
+ `propose(input, { signal, timeoutMs })`; an ordinary semantic module is insufficient. There is
574
+ one provider request per invocation, no automatic retry, and cache hits require no `--allow-model`.
575
+ Prompt/schema bytes and candidate count are bounded; these do not represent a dollar/token cap.
576
+
577
+ MCP `mapping.plan` returns the same no-model preview; `mapping.proposals` reads a saved result by
578
+ snapshot/key. Neither MCP tool invokes a provider. Agents must treat rationale as untrusted model
579
+ content and follow the cited rule and exact symbol IDs. The CLI reports progress on stderr using
580
+ opaque IDs; `--quiet` suppresses progress. Provider failures preserve all existing graph evidence.
581
+
582
+ Refresh a committed snapshot using this candidate to record code coverage before proposing.
583
+ Missing indexing/ownership, unresolved document selectors and budget overflow block inference.
584
+ Historical evidence stays labeled historical; working edits are excluded and draft-overlay
585
+ proposal generation is not yet supported. Saved artifacts live in the configured graph storage
586
+ under `artifacts/mapping-proposals`; they may contain private rule/code identities and rationale.
587
+ Keep them with the consumer. See [ADR 039](docs/ADR-039-mapping-proposals.md) for exact scope,
588
+ caching and authority, and [the public evaluation protocol](evaluations/mapping-proposals/README.md).
@@ -20,7 +20,7 @@ Do not edit this file manually.
20
20
  | `@sourcegraph/scip-typescript` | 0.4.0 | Apache-2.0 | [link](https://github.com/sourcegraph/scip-typescript#readme) |
21
21
  | `@traqula/chevrotain` | 1.1.0 | Apache-2.0 | [link](https://github.com/comunica/traqula#readme) |
22
22
  | `canonicalize` | 1.0.8, 2.1.0 | Apache-2.0 | [link](https://github.com/erdtman/canonicalize#readme) |
23
- | `typescript` | 5.9.3 | Apache-2.0 | [link](https://www.typescriptlang.org/) |
23
+ | `typescript` | 5.5.4, 5.9.3 | Apache-2.0 | [link](https://www.typescriptlang.org/) |
24
24
  | `lru-cache` | 11.5.3 | BlueOak-1.0.0 | [link](https://github.com/isaacs/node-lru-cache#readme) |
25
25
  | `domelementtype` | 2.3.0 | BSD-2-Clause | [link](https://github.com/fb55/domelementtype#readme) |
26
26
  | `domhandler` | 5.0.3 | BSD-2-Clause | [link](https://github.com/fb55/domhandler#readme) |
@@ -363,6 +363,7 @@ Do not edit this file manually.
363
363
  | `@comunica/utils-metadata` | 5.4.0 | MIT | [link](https://comunica.dev/) |
364
364
  | `@comunica/utils-query-operation` | 5.4.0 | MIT | [link](https://comunica.dev/) |
365
365
  | `@dabh/diagnostics` | 2.0.9 | MIT | [link](https://github.com/DABH/diagnostics) |
366
+ | `@discoveryjs/json-ext` | 1.1.0 | MIT | [link](https://github.com/discoveryjs/json-ext#readme) |
366
367
  | `@hono/node-server` | 2.1.5 | MIT | [link](https://github.com/honojs/node-server) |
367
368
  | `@jeswr/prefixcc` | 1.2.1 | MIT | [link](https://github.com/jeswr/prefixcc.js#readme) |
368
369
  | `@jeswr/stream-to-string` | 2.0.0 | MIT | [link](https://github.com/jeswr/stream-to-string/README.md) |
@@ -376,6 +377,7 @@ Do not edit this file manually.
376
377
  | `@rdfjs/to-ntriples` | 3.0.1 | MIT | [link](https://github.com/rdfjs-base/to-ntriples) |
377
378
  | `@rdfjs/types` | 1.1.2, 2.0.1 | MIT | [link](http://rdf.js.org/) |
378
379
  | `@so-ric/colorspace` | 1.1.6 | MIT | [link](https://github.com/so-ric/colorspace) |
380
+ | `@streamparser/json` | 0.0.26 | MIT | [link](https://github.com/juanjoDiaz/jsonparse2#readme) |
379
381
  | `@tpluscode/rdf-ns-builders` | 5.1.0 | MIT | [link](https://github.com/tpluscode/rdf-ns-builders#readme) |
380
382
  | `@traqula/algebra-sparql-1-1` | 1.4.0 | MIT | [link](https://github.com/comunica/traqula#readme) |
381
383
  | `@traqula/algebra-sparql-1-2` | 1.4.0 | MIT | [link](https://github.com/comunica/traqula#readme) |
@@ -1,3 +1,7 @@
1
+ import { SavedGraphExplorationService } from "./saved-exploration.js";
2
+ import { SavedGraphPathService } from './saved-paths.js';
3
+ import { SavedContractCompatibilityService } from './saved-compatibility.js';
4
+ import { SavedCodeCoverageService } from './saved-code-coverage.js';
1
5
  import { SavedEvidenceQueryService } from "./saved-evidence.js";
2
6
  import { AgentSemanticScopeResolver } from "./agent-context.js";
3
7
  import type { ContextGraphAdapter, ContextGraphRepository } from "@weftlet/core";
@@ -6,6 +10,7 @@ import { ContextGraphHydrator } from "./hydrator.js";
6
10
  import { OpenCaesarOntologyCompiler, DirectRdfOntologyCompiler } from "../extraction/ontology.js";
7
11
  import { FileSnapshotStore } from "../storage/storage.js";
8
12
  import { SnapshotChecks } from "./snapshot-checks.js";
13
+ import { MappingProposalService } from './mapping-proposals.js';
9
14
  export declare function loadContextGraphAdapterModule(moduleSpecifier: string | undefined, repository: ContextGraphRepository, repositoryRoot?: string): Promise<ContextGraphAdapter>;
10
15
  export declare function createContextGraphApplication(configPath: string): Promise<{
11
16
  storageRoot: string;
@@ -14,9 +19,14 @@ export declare function createContextGraphApplication(configPath: string): Promi
14
19
  ontologyCompiler: OpenCaesarOntologyCompiler | DirectRdfOntologyCompiler;
15
20
  hydrator: ContextGraphHydrator;
16
21
  queryService: SavedEvidenceQueryService;
22
+ explorationService: SavedGraphExplorationService;
23
+ pathService: SavedGraphPathService;
24
+ compatibilityService: SavedContractCompatibilityService;
25
+ codeCoverageService: SavedCodeCoverageService;
17
26
  snapshotChecks: SnapshotChecks;
18
27
  scopeResolver: AgentSemanticScopeResolver | undefined;
19
28
  headName: string;
29
+ mappingProposalService: MappingProposalService;
20
30
  config: import("../configuration/config.js").ContextGraphConfig;
21
31
  configPath: string;
22
32
  repositoryRoot: string;
@@ -1,4 +1,12 @@
1
1
  // Modified for standalone extraction; see docs/extraction-manifest.json.
2
+ import { SavedGraphExplorationService } from "./saved-exploration.js";
3
+ import { SnapshotGraphExplorationService } from "../graph/neighborhood.js";
4
+ import { SnapshotGraphPathService } from '../graph/paths.js';
5
+ import { SavedGraphPathService } from './saved-paths.js';
6
+ import { SnapshotContractCompatibilityService } from '../graph/compatibility.js';
7
+ import { SavedContractCompatibilityService } from './saved-compatibility.js';
8
+ import { SnapshotCodeCoverageService } from '../graph/code-coverage.js';
9
+ import { SavedCodeCoverageService } from './saved-code-coverage.js';
2
10
  import { SavedEvidenceQueryService } from "./saved-evidence.js";
3
11
  import { sha256, stableJson } from "../infrastructure/util.js";
4
12
  import { AgentSemanticScopeResolver, PreparedImpactQueryService } from "./agent-context.js";
@@ -17,6 +25,9 @@ import { OtlpJsonRuntimeEvidenceProvider } from "../extraction/telemetry.js";
17
25
  import { SnapshotChecks } from "./snapshot-checks.js";
18
26
  import { resolveConsumerModule } from "../infrastructure/module-resolution.js";
19
27
  import { requiredSnapshotExtractorVersions } from './extraction-identity.js';
28
+ import { MappingProposalService } from './mapping-proposals.js';
29
+ import { FileMappingProposalStore } from '../storage/mapping-proposals.js';
30
+ import { createMappingProvider, mappingProviderIdentity } from '../extraction/mapping-provider.js';
20
31
  const emptyAdapter = {
21
32
  factExtractors: [],
22
33
  invariantEvaluators: [],
@@ -87,8 +98,17 @@ export async function createContextGraphApplication(configPath) {
87
98
  ontologyCompiler,
88
99
  hydrator,
89
100
  queryService,
101
+ explorationService: new SavedGraphExplorationService(new SnapshotGraphExplorationService(snapshotStore), repository, sha256(stableJson(config)), expectedExtractors),
102
+ pathService: new SavedGraphPathService(new SnapshotGraphPathService(snapshotStore), repository, sha256(stableJson(config)), expectedExtractors),
103
+ compatibilityService: new SavedContractCompatibilityService(new SnapshotContractCompatibilityService(snapshotStore), repository, sha256(stableJson(config)), expectedExtractors),
104
+ codeCoverageService: new SavedCodeCoverageService(new SnapshotCodeCoverageService(snapshotStore), repository, sha256(stableJson(config)), expectedExtractors),
90
105
  snapshotChecks: new SnapshotChecks(snapshotStore, repository, hydrator, scopeResolver, sha256(stableJson(config)), expectedExtractors),
91
106
  scopeResolver,
92
107
  headName,
108
+ mappingProposalService: new MappingProposalService(repository, snapshotStore, new FileMappingProposalStore(storageRoot), {
109
+ repositoryId: config.repositoryId, configurationDigest: sha256(stableJson(config)), expectedExtractors,
110
+ providerIdentity: mappingProviderIdentity(config.semantic), timeoutMs: config.semantic.timeoutMs ?? 120_000,
111
+ provider: () => createMappingProvider(config.semantic, repositoryRoot),
112
+ }),
93
113
  };
94
114
  }
@@ -0,0 +1,11 @@
1
+ import type { ExtractionContext, GraphFact } from '@weftlet/core';
2
+ import type { ContextGraphConfig } from '../configuration/config.js';
3
+ import type { GitRepository } from '../repository/git.js';
4
+ import type { HydrationInputs } from './hydration-inputs.js';
5
+ import { type BindingSource } from '../extraction/document-code-bindings.js';
6
+ /** Uses the already selected committed scope; validation documents remain separately classified. */
7
+ export declare function assembleDocumentCodeBindings(repository: GitRepository, context: ExtractionContext, inputs: HydrationInputs, config: ContextGraphConfig, codeFacts: readonly GraphFact[], subjectFacts: readonly GraphFact[]): Promise<{
8
+ facts: readonly GraphFact[];
9
+ diagnostics: readonly import("@weftlet/core").GraphDiagnostic[];
10
+ }>;
11
+ export declare function selectedDocumentSources(repository: GitRepository, context: ExtractionContext, inputs: HydrationInputs, config: ContextGraphConfig): Promise<readonly BindingSource[]>;
@@ -0,0 +1,25 @@
1
+ import { extractDocumentCodeBindings } from '../extraction/document-code-bindings.js';
2
+ import { matchesRepositoryGlob } from '../repository/glob.js';
3
+ /** Uses the already selected committed scope; validation documents remain separately classified. */
4
+ export async function assembleDocumentCodeBindings(repository, context, inputs, config, codeFacts, subjectFacts) {
5
+ return extractDocumentCodeBindings(repository, context, await selectedDocumentSources(repository, context, inputs, config), codeFacts, subjectFacts);
6
+ }
7
+ export async function selectedDocumentSources(repository, context, inputs, config) {
8
+ const byPath = new Map(inputs.sources.map(source => [source.path, source]));
9
+ const evidence = inputs.documentEvidence;
10
+ const classified = new Map(evidence?.classification.documents.map(document => [document.path, document]));
11
+ const sources = [];
12
+ const paths = evidence ? evidence.traversal.documents.filter(document => document.status === 'read').map(document => document.path) : [...byPath.keys()];
13
+ for (const path of paths) {
14
+ let source = byPath.get(path);
15
+ if (!source) {
16
+ const document = evidence.traversal.documents.find(document => document.path === path);
17
+ source = { path, content: await repository.readFileAt(context.commitSha, path), digest: document.digest, stableSemanticId: `document:${path}` };
18
+ }
19
+ const classification = classified.get(path);
20
+ sources.push({ ...source, metadata: classification ? { sourceAuthority: classification.sourceAuthority,
21
+ sourceRole: classification.sourceRole, sourceOwnership: classification.ownership, sourcePolicyDigest: evidence.classification.policyDigest }
22
+ : { sourceAuthority: config.approvedIntentSources?.some(pattern => matchesRepositoryGlob(path, pattern)) ? 'declared' : 'inferred' } });
23
+ }
24
+ return sources;
25
+ }
@@ -0,0 +1,8 @@
1
+ import type { ExtractionContext } from '@weftlet/core';
2
+ import type { ContextGraphConfig } from '../configuration/config.js';
3
+ import type { GitRepository } from '../repository/git.js';
4
+ import type { HydrationInputs } from './hydration-inputs.js';
5
+ export declare function assembleDocumentObligations(repository: GitRepository, context: ExtractionContext, inputs: HydrationInputs, config: ContextGraphConfig): Promise<{
6
+ facts: readonly import("@weftlet/core").GraphFact[];
7
+ diagnostics: readonly import("@weftlet/core").GraphDiagnostic[];
8
+ }>;
@@ -0,0 +1,11 @@
1
+ import { selectedDocumentSources } from './document-code-bindings.js';
2
+ import { matchesRepositoryGlob } from '../repository/glob.js';
3
+ import { extractDocumentObligations } from '../extraction/document-obligations.js';
4
+ export async function assembleDocumentObligations(repository, context, inputs, config) {
5
+ const sources = await selectedDocumentSources(repository, context, inputs, config);
6
+ const validation = (path) => config.evidenceRoots.some(root => root === '.' || path === root ||
7
+ path.startsWith(`${root.replace(/\/$/, '')}/`) || matchesRepositoryGlob(path, root) || matchesRepositoryGlob(path, `${root}/**`));
8
+ return extractDocumentObligations(repository, context, sources.map(source => ({ ...source,
9
+ metadata: { ...source.metadata, sourceRole: source.metadata.sourceRole ?? (validation(source.path) ? 'validation' :
10
+ source.metadata.sourceAuthority === 'declared' ? 'intent' : 'unclassified') } })));
11
+ }
@@ -0,0 +1,3 @@
1
+ import type { GraphFact } from '@weftlet/core';
2
+ /** Rewrite proof references after code facts receive draft identities; never retain disposable Git SHAs. */
3
+ export declare function draftFacts(facts: readonly GraphFact[], snapshotId: string, baseSha: string): readonly GraphFact[];
@@ -0,0 +1,37 @@
1
+ import { sha256, stableJson } from '../infrastructure/util.js';
2
+ /** Rewrite proof references after code facts receive draft identities; never retain disposable Git SHAs. */
3
+ export function draftFacts(facts, snapshotId, baseSha) {
4
+ const rewritten = new Map();
5
+ const span = (citation) => ({ ...citation, commitSha: baseSha });
6
+ const make = ({ id: previousId, ...fact }) => {
7
+ const rewrite = (binding) => {
8
+ const proofs = (items) => items.map(item => ({ ...item, factId: rewritten.get(item.factId)?.id ?? item.factId, provenance: span(item.provenance) }));
9
+ return { ...binding, documentCitations: binding.documentCitations.map(span), selectedOccurrences: proofs(binding.selectedOccurrences),
10
+ definitions: proofs(binding.definitions), subjectEvidence: binding.subjectEvidence.map(item => {
11
+ const updated = rewritten.get(item.factId);
12
+ return updated ? { factId: updated.id, provenance: updated.provenance,
13
+ ...(updated.authority === undefined ? {} : { authority: updated.authority }),
14
+ ...(updated.sourceAuthority === undefined ? {} : { sourceAuthority: updated.sourceAuthority }),
15
+ ...(updated.extractionReview === undefined ? {} : { extractionReview: updated.extractionReview }) } : item;
16
+ }) };
17
+ };
18
+ const draft = { ...fact, snapshotId, authority: 'draft',
19
+ ...(fact.codeBinding || fact.extractor.id === 'routing-declaration-extractor' || fact.sourceRole !== undefined ? { sourceAuthority: 'draft' } : {}),
20
+ ...(fact.codeBinding ? { codeBinding: rewrite(fact.codeBinding) } : {}), provenance: span(fact.provenance) };
21
+ if (draft.codeCall) {
22
+ const proofs = (items) => items.map(item => ({
23
+ factId: rewritten.get(item.factId)?.id ?? item.factId, provenance: span(item.provenance)
24
+ }));
25
+ draft.codeCall = { ...draft.codeCall, callerDefinitions: proofs(draft.codeCall.callerDefinitions),
26
+ targetOccurrences: proofs(draft.codeCall.targetOccurrences), targetDefinitions: proofs(draft.codeCall.targetDefinitions) };
27
+ }
28
+ if (draft.contractObligation)
29
+ draft.contractObligation = { ...draft.contractObligation,
30
+ endpointSource: span(draft.contractObligation.endpointSource) };
31
+ const result = { ...draft, id: sha256(stableJson(draft)) };
32
+ rewritten.set(previousId, result);
33
+ return result;
34
+ };
35
+ return [...facts.filter(fact => !fact.codeBinding && !fact.codeCall).map(make),
36
+ ...facts.filter(fact => fact.codeCall).map(make), ...facts.filter(fact => fact.codeBinding).map(make)];
37
+ }
@@ -1,6 +1,6 @@
1
1
  import type { ContextGraphConfig } from '../configuration/config.js';
2
- export declare const graphAssemblyVersion = 7;
3
- export declare const graphAssemblyIdentity = "standalone-graph-v7";
2
+ export declare const graphAssemblyVersion = 12;
3
+ export declare const graphAssemblyIdentity = "standalone-graph-v12";
4
4
  export declare function documentExtractionVersions(config?: Pick<ContextGraphConfig, 'documentTraversal'>): Readonly<Record<string, string>>;
5
5
  /** Runtime expectations are separate from source/configuration identity and artifact reuse. */
6
6
  export declare function requiredSnapshotExtractorVersions(config?: Pick<ContextGraphConfig, 'routingSources' | 'documentTraversal'>): Readonly<Record<string, string>>;
@@ -1,8 +1,11 @@
1
+ import { documentCodeBindingIdentity } from '../extraction/document-code-bindings.js';
2
+ import { staticCallIdentity } from '../extraction/static-calls.js';
3
+ import { documentObligationIdentity } from '../extraction/document-obligations.js';
1
4
  import { repositoryContractExtractorIdentity, scipSymbolExtractorIdentity } from '../extraction/static.js';
2
5
  import { routingExtractorIdentity } from '../extraction/routing.js';
3
6
  import { documentEvidenceExtractorIdentity } from '../extraction/document-evidence.js';
4
7
  import { documentSelectionIdentity } from './hydration-inputs.js';
5
- export const graphAssemblyVersion = 7;
8
+ export const graphAssemblyVersion = 12;
6
9
  export const graphAssemblyIdentity = `standalone-graph-v${graphAssemblyVersion}`;
7
10
  export function documentExtractionVersions(config) {
8
11
  return config?.documentTraversal ? { 'document-selection': documentSelectionIdentity,
@@ -11,6 +14,9 @@ export function documentExtractionVersions(config) {
11
14
  /** Runtime expectations are separate from source/configuration identity and artifact reuse. */
12
15
  export function requiredSnapshotExtractorVersions(config) {
13
16
  return { assembly: graphAssemblyIdentity,
17
+ [documentCodeBindingIdentity.id]: documentCodeBindingIdentity.version,
18
+ [staticCallIdentity.id]: staticCallIdentity.version,
19
+ [documentObligationIdentity.id]: documentObligationIdentity.version,
14
20
  ...documentExtractionVersions(config),
15
21
  [repositoryContractExtractorIdentity.id]: repositoryContractExtractorIdentity.version,
16
22
  [scipSymbolExtractorIdentity.id]: scipSymbolExtractorIdentity.version,
@@ -0,0 +1,6 @@
1
+ import type { ExtractionContext, FactExtractor } from '@weftlet/core';
2
+ /** Stateless per-invocation results retain adapter gaps without changing existing adapters. */
3
+ export declare function extractEvidence(extractors: readonly FactExtractor[], context: ExtractionContext): Promise<{
4
+ facts: import("@weftlet/core").GraphFact[];
5
+ diagnostics: import("@weftlet/core").GraphDiagnostic[];
6
+ }>;
@@ -0,0 +1,6 @@
1
+ /** Stateless per-invocation results retain adapter gaps without changing existing adapters. */
2
+ export async function extractEvidence(extractors, context) {
3
+ const results = await Promise.all(extractors.map(async (extractor) => extractor.extractWithDiagnostics
4
+ ? extractor.extractWithDiagnostics(context) : { facts: await extractor.extract(context), diagnostics: [] }));
5
+ return { facts: results.flatMap(result => result.facts), diagnostics: results.flatMap(result => result.diagnostics) };
6
+ }