@weftlet/toolkit 0.6.1 → 0.7.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.
Files changed (177) hide show
  1. package/README.md +168 -1
  2. package/THIRD_PARTY_NOTICES.md +1 -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 +20 -3
  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 +36 -22
  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/extraction/call-syntax.d.ts +18 -0
  32. package/dist/extraction/call-syntax.js +61 -0
  33. package/dist/extraction/canonical-document-links.d.ts +5 -1
  34. package/dist/extraction/canonical-document-links.js +4 -4
  35. package/dist/extraction/code-inventory.d.ts +6 -0
  36. package/dist/extraction/code-inventory.js +26 -0
  37. package/dist/extraction/document-code-bindings.d.ts +14 -0
  38. package/dist/extraction/document-code-bindings.js +121 -0
  39. package/dist/extraction/document-obligations.d.ts +12 -0
  40. package/dist/extraction/document-obligations.js +112 -0
  41. package/dist/extraction/mapping-candidates.d.ts +13 -0
  42. package/dist/extraction/mapping-candidates.js +46 -0
  43. package/dist/extraction/mapping-output.d.ts +75 -0
  44. package/dist/extraction/mapping-output.js +53 -0
  45. package/dist/extraction/mapping-plan.d.ts +7 -0
  46. package/dist/extraction/mapping-plan.js +117 -0
  47. package/dist/extraction/mapping-prompt.d.ts +2 -0
  48. package/dist/extraction/mapping-prompt.js +17 -0
  49. package/dist/extraction/mapping-provider.d.ts +15 -0
  50. package/dist/extraction/mapping-provider.js +60 -0
  51. package/dist/extraction/mapping-request.d.ts +3 -0
  52. package/dist/extraction/mapping-request.js +32 -0
  53. package/dist/extraction/routing.js +5 -20
  54. package/dist/extraction/scip-occurrences.d.ts +3 -0
  55. package/dist/extraction/scip-occurrences.js +102 -0
  56. package/dist/extraction/scip-ranges.d.ts +6 -0
  57. package/dist/extraction/scip-ranges.js +31 -0
  58. package/dist/extraction/scip-runtime.d.ts +39 -0
  59. package/dist/extraction/scip-runtime.js +8 -0
  60. package/dist/extraction/scip-symbols.d.ts +21 -0
  61. package/dist/extraction/scip-symbols.js +91 -0
  62. package/dist/extraction/semantic.d.ts +1 -1
  63. package/dist/extraction/semantic.js +5 -17
  64. package/dist/extraction/static-calls.d.ts +10 -0
  65. package/dist/extraction/static-calls.js +133 -0
  66. package/dist/extraction/static.d.ts +3 -20
  67. package/dist/extraction/static.js +8 -84
  68. package/dist/extraction/symbol-resolution.d.ts +12 -0
  69. package/dist/extraction/symbol-resolution.js +51 -0
  70. package/dist/extraction/symbol-selectors.d.ts +11 -0
  71. package/dist/extraction/symbol-selectors.js +51 -0
  72. package/dist/graph/binding-rdf.d.ts +7 -0
  73. package/dist/graph/binding-rdf.js +109 -0
  74. package/dist/graph/call-rdf.d.ts +4 -0
  75. package/dist/graph/call-rdf.js +94 -0
  76. package/dist/graph/call-shapes.d.ts +2 -0
  77. package/dist/graph/call-shapes.js +28 -0
  78. package/dist/graph/code-coverage-projection.d.ts +9 -0
  79. package/dist/graph/code-coverage-projection.js +117 -0
  80. package/dist/graph/code-coverage-renderer.d.ts +2 -0
  81. package/dist/graph/code-coverage-renderer.js +15 -0
  82. package/dist/graph/code-coverage-request.d.ts +6 -0
  83. package/dist/graph/code-coverage-request.js +19 -0
  84. package/dist/graph/code-coverage.d.ts +6 -0
  85. package/dist/graph/code-coverage.js +54 -0
  86. package/dist/graph/code-description.d.ts +4 -0
  87. package/dist/graph/code-description.js +24 -0
  88. package/dist/graph/code-rdf.d.ts +5 -0
  89. package/dist/graph/code-rdf.js +72 -0
  90. package/dist/graph/compatibility-context.d.ts +2 -0
  91. package/dist/graph/compatibility-context.js +18 -0
  92. package/dist/graph/compatibility-renderer.d.ts +2 -0
  93. package/dist/graph/compatibility-renderer.js +45 -0
  94. package/dist/graph/compatibility-request.d.ts +3 -0
  95. package/dist/graph/compatibility-request.js +18 -0
  96. package/dist/graph/compatibility.d.ts +7 -0
  97. package/dist/graph/compatibility.js +67 -0
  98. package/dist/graph/constraint-comparison.d.ts +7 -0
  99. package/dist/graph/constraint-comparison.js +49 -0
  100. package/dist/graph/coverage.d.ts +2 -2
  101. package/dist/graph/coverage.js +8 -3
  102. package/dist/graph/diagnostics.d.ts +1 -1
  103. package/dist/graph/diagnostics.js +10 -6
  104. package/dist/graph/evidence-description.d.ts +3 -0
  105. package/dist/graph/evidence-description.js +13 -0
  106. package/dist/graph/identity-preflight.js +1 -1
  107. package/dist/graph/neighborhood-renderer.d.ts +2 -0
  108. package/dist/graph/neighborhood-renderer.js +38 -0
  109. package/dist/graph/neighborhood-request.d.ts +9 -0
  110. package/dist/graph/neighborhood-request.js +37 -0
  111. package/dist/graph/neighborhood.d.ts +8 -0
  112. package/dist/graph/neighborhood.js +100 -0
  113. package/dist/graph/obligation-rdf.d.ts +5 -0
  114. package/dist/graph/obligation-rdf.js +67 -0
  115. package/dist/graph/obligation-shapes.d.ts +2 -0
  116. package/dist/graph/obligation-shapes.js +32 -0
  117. package/dist/graph/path-request.d.ts +11 -0
  118. package/dist/graph/path-request.js +24 -0
  119. package/dist/graph/path-search.d.ts +45 -0
  120. package/dist/graph/path-search.js +101 -0
  121. package/dist/graph/paths-renderer.d.ts +2 -0
  122. package/dist/graph/paths-renderer.js +36 -0
  123. package/dist/graph/paths.d.ts +7 -0
  124. package/dist/graph/paths.js +74 -0
  125. package/dist/graph/query.js +23 -6
  126. package/dist/graph/rdf.js +26 -0
  127. package/dist/graph/shacl-shapes.js +70 -0
  128. package/dist/graph/snapshot-context.d.ts +3 -0
  129. package/dist/graph/snapshot-context.js +8 -0
  130. package/dist/index.d.ts +23 -0
  131. package/dist/index.js +22 -0
  132. package/dist/infrastructure/json-digest.d.ts +2 -0
  133. package/dist/infrastructure/json-digest.js +3 -0
  134. package/dist/infrastructure/unique-json.d.ts +2 -0
  135. package/dist/infrastructure/unique-json.js +20 -0
  136. package/dist/interfaces/cli.js +33 -1
  137. package/dist/interfaces/code-coverage.d.ts +46 -0
  138. package/dist/interfaces/code-coverage.js +18 -0
  139. package/dist/interfaces/graph-compatibility.d.ts +35 -0
  140. package/dist/interfaces/graph-compatibility.js +21 -0
  141. package/dist/interfaces/graph-exploration.d.ts +59 -0
  142. package/dist/interfaces/graph-exploration.js +27 -0
  143. package/dist/interfaces/graph-paths.d.ts +77 -0
  144. package/dist/interfaces/graph-paths.js +31 -0
  145. package/dist/interfaces/graph-query-args.d.ts +2 -0
  146. package/dist/interfaces/graph-query-args.js +25 -0
  147. package/dist/interfaces/mapping-proposals.d.ts +204 -0
  148. package/dist/interfaces/mapping-proposals.js +74 -0
  149. package/dist/interfaces/mcp.js +31 -3
  150. package/dist/storage/mapping-proposals.d.ts +9 -0
  151. package/dist/storage/mapping-proposals.js +42 -0
  152. package/dist/visualization/evidence-sources.d.ts +6 -0
  153. package/dist/visualization/evidence-sources.js +19 -0
  154. package/dist/visualization/viewer-interaction.d.ts +5 -8
  155. package/dist/visualization/viewer-interaction.js +46 -44
  156. package/dist/visualization/visualization.js +14 -5
  157. package/docs/1.0-WORK-QUEUE.md +38 -0
  158. package/docs/ADR-029-exact-graph-neighborhoods.md +70 -0
  159. package/docs/ADR-030-bounded-evidence-paths.md +97 -0
  160. package/docs/ADR-031-code-extractor-selection.md +91 -0
  161. package/docs/ADR-032-scip-code-evidence.md +73 -0
  162. package/docs/ADR-033-document-symbol-bindings.md +83 -0
  163. package/docs/ADR-034-mapping-gaps.md +80 -0
  164. package/docs/ADR-035-static-call-evidence.md +78 -0
  165. package/docs/ADR-036-contract-obligation-declarations.md +124 -0
  166. package/docs/ADR-037-selected-contract-compatibility.md +93 -0
  167. package/docs/ADR-038-monorepo-code-coverage.md +105 -0
  168. package/docs/ADR-039-mapping-proposals.md +119 -0
  169. package/docs/GRAPHIFY-EVALUATION.md +21 -4
  170. package/docs/PRE-1.0-BASELINE.md +49 -2
  171. package/docs/RELEASE-1.0-PLAN.md +14 -2
  172. package/docs/RELEASING.md +3 -3
  173. package/docs/ROADMAP.md +27 -6
  174. package/docs/VALIDATION.md +437 -14
  175. package/docs/extraction-manifest.json +248 -21
  176. package/package.json +8 -4
  177. package/templates/context-graph-development/SKILL.md +30 -1
@@ -0,0 +1,2 @@
1
+ /** Shapes target only obligation records, keeping ordinary-fact validation cost unchanged. */
2
+ export declare const obligationShapes = "\ncg:ContractObligationShape a sh:NodeShape; sh:targetClass cg:ContractObligation;\n sh:property [ sh:path cg:obligationVersion; sh:minCount 1; sh:maxCount 1; sh:hasValue 1 ];\n sh:property [ sh:path cg:obligationMethod; sh:minCount 1; sh:maxCount 1; sh:hasValue \"explicit-markdown\" ];\n sh:property [ sh:path cg:obligationRole; sh:minCount 1; sh:maxCount 1; sh:in (\"guarantee\" \"requirement\") ];\n sh:property [ sh:path cg:obligationId; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationStatement; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationRepository; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationScope; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationContract; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationTransport; sh:minCount 1; sh:maxCount 1; sh:in (\"queue\" \"stored-data\") ];\n sh:property [ sh:path cg:obligationContractVersion; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationDomain; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationStage; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationRevalidation; sh:maxCount 1; sh:in (\"required\" \"not-required\") ];\n sh:property [ sh:path cg:obligationEndpoint; sh:minCount 1; sh:maxCount 1; sh:class cg:ObligationEndpoint ];\n sh:property [ sh:path cg:authority; sh:in (\"inferred\" \"draft\") ];\n sh:property [ sh:path cg:extractionReview; sh:minCount 1; sh:hasValue \"deterministic\" ];\n sh:property [ sh:path rdf:predicate; sh:in (cg:emits cg:consumes) ].\ncg:ObligationEndpointShape a sh:NodeShape; sh:targetClass cg:ObligationEndpoint;\n sh:property [ sh:path cg:path; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:digest; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:commitSha; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:startLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];\n sh:property [ sh:path cg:endLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ].\ncg:ObligationConstraintShape a sh:NodeShape; sh:targetSubjectsOf cg:obligationMetric, cg:obligationOperator, cg:obligationValue, cg:obligationUnit;\n sh:property [ sh:path cg:obligationMetric; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];\n sh:property [ sh:path cg:obligationOperator; sh:minCount 1; sh:maxCount 1; sh:in (\"at-most\" \"at-least\" \"equal\") ];\n sh:property [ sh:path cg:obligationValue; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:double ];\n sh:property [ sh:path cg:obligationUnit; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ].\n";
@@ -0,0 +1,32 @@
1
+ /** Shapes target only obligation records, keeping ordinary-fact validation cost unchanged. */
2
+ export const obligationShapes = `
3
+ cg:ContractObligationShape a sh:NodeShape; sh:targetClass cg:ContractObligation;
4
+ sh:property [ sh:path cg:obligationVersion; sh:minCount 1; sh:maxCount 1; sh:hasValue 1 ];
5
+ sh:property [ sh:path cg:obligationMethod; sh:minCount 1; sh:maxCount 1; sh:hasValue "explicit-markdown" ];
6
+ sh:property [ sh:path cg:obligationRole; sh:minCount 1; sh:maxCount 1; sh:in ("guarantee" "requirement") ];
7
+ sh:property [ sh:path cg:obligationId; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
8
+ sh:property [ sh:path cg:obligationStatement; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
9
+ sh:property [ sh:path cg:obligationRepository; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
10
+ sh:property [ sh:path cg:obligationScope; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
11
+ sh:property [ sh:path cg:obligationContract; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
12
+ sh:property [ sh:path cg:obligationTransport; sh:minCount 1; sh:maxCount 1; sh:in ("queue" "stored-data") ];
13
+ sh:property [ sh:path cg:obligationContractVersion; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
14
+ sh:property [ sh:path cg:obligationDomain; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
15
+ sh:property [ sh:path cg:obligationStage; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
16
+ sh:property [ sh:path cg:obligationRevalidation; sh:maxCount 1; sh:in ("required" "not-required") ];
17
+ sh:property [ sh:path cg:obligationEndpoint; sh:minCount 1; sh:maxCount 1; sh:class cg:ObligationEndpoint ];
18
+ sh:property [ sh:path cg:authority; sh:in ("inferred" "draft") ];
19
+ sh:property [ sh:path cg:extractionReview; sh:minCount 1; sh:hasValue "deterministic" ];
20
+ sh:property [ sh:path rdf:predicate; sh:in (cg:emits cg:consumes) ].
21
+ cg:ObligationEndpointShape a sh:NodeShape; sh:targetClass cg:ObligationEndpoint;
22
+ sh:property [ sh:path cg:path; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
23
+ sh:property [ sh:path cg:digest; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
24
+ sh:property [ sh:path cg:commitSha; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
25
+ sh:property [ sh:path cg:startLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
26
+ sh:property [ sh:path cg:endLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ].
27
+ cg:ObligationConstraintShape a sh:NodeShape; sh:targetSubjectsOf cg:obligationMetric, cg:obligationOperator, cg:obligationValue, cg:obligationUnit;
28
+ sh:property [ sh:path cg:obligationMetric; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
29
+ sh:property [ sh:path cg:obligationOperator; sh:minCount 1; sh:maxCount 1; sh:in ("at-most" "at-least" "equal") ];
30
+ sh:property [ sh:path cg:obligationValue; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:double ];
31
+ sh:property [ sh:path cg:obligationUnit; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ].
32
+ `;
@@ -0,0 +1,11 @@
1
+ export declare function parseGraphPathsRequest(value: unknown): {
2
+ continuation?: string | undefined;
3
+ snapshotId: string;
4
+ fromNodeId: string;
5
+ toNodeId: string;
6
+ direction: "incoming" | "outgoing" | "both";
7
+ predicates: ("references" | "realizes" | "implementedBy" | "consumes" | "emits" | "persistsTo" | "governedBy" | "definedBy" | "verifiedBy" | "operationallyOwnedBy" | "decisionAuthority" | "routesThrough" | "authorizedBy" | "sourcedFrom" | "contains" | "calls")[];
8
+ maxDepth: number;
9
+ maxPaths: number;
10
+ maxSteps: number;
11
+ };
@@ -0,0 +1,24 @@
1
+ import { parseGraphNeighborsRequest } from './neighborhood-request.js';
2
+ const fields = new Set(['snapshotId', 'fromNodeId', 'toNodeId', 'direction', 'predicates', 'maxDepth', 'maxPaths', 'maxSteps', 'continuation']);
3
+ export function parseGraphPathsRequest(value) {
4
+ if (!value || typeof value !== 'object' || Array.isArray(value))
5
+ throw new Error('graph.paths arguments must be an object');
6
+ const record = value;
7
+ if (Object.keys(record).some(key => !fields.has(key)))
8
+ throw new Error('Unknown graph.paths field');
9
+ const common = { snapshotId: record.snapshotId, direction: record.direction === undefined ? 'outgoing' : record.direction,
10
+ predicates: record.predicates, continuation: record.continuation };
11
+ const from = parseGraphNeighborsRequest({ ...common, nodeId: record.fromNodeId });
12
+ const to = parseGraphNeighborsRequest({ ...common, nodeId: record.toNodeId });
13
+ const bound = (name, fallback, maximum) => {
14
+ const item = record[name] === undefined ? fallback : record[name];
15
+ if (!Number.isInteger(item) || Number(item) < 1 || Number(item) > maximum) {
16
+ throw new Error(`${name} must be an integer between 1 and ${maximum}`);
17
+ }
18
+ return Number(item);
19
+ };
20
+ return { snapshotId: from.snapshotId, fromNodeId: from.nodeId, toNodeId: to.nodeId,
21
+ direction: from.direction, predicates: from.predicates, maxDepth: bound('maxDepth', 8, 32),
22
+ maxPaths: bound('maxPaths', 5, 20), maxSteps: bound('maxSteps', 1000, 10_000),
23
+ ...(from.continuation ? { continuation: from.continuation } : {}) };
24
+ }
@@ -0,0 +1,45 @@
1
+ import type { EvidencePath } from '@weftlet/core';
2
+ export interface PathEdge {
3
+ readonly id: string;
4
+ readonly from: string;
5
+ readonly to: string;
6
+ }
7
+ export interface PathSearchOptions {
8
+ readonly maxDepth: number;
9
+ readonly maxPaths: number;
10
+ readonly maxSteps: number;
11
+ readonly offset?: number;
12
+ }
13
+ /** Pure, dependency-free search shared verbatim with the offline viewer. No global visited set:
14
+ * distinct simple paths and parallel assertions survive; cycles do not repeat a node. */
15
+ export declare function searchEvidencePaths(edges: readonly PathEdge[], start: string, target: string, options: PathSearchOptions, knownNodeIds?: ReadonlySet<string>): {
16
+ paths: EvidencePath[];
17
+ frontier: {
18
+ pending: {
19
+ nodeId: string;
20
+ viaFactIds: string[];
21
+ nextFactId: string;
22
+ remainingCandidates: number;
23
+ }[];
24
+ depthLimited: {
25
+ count: number;
26
+ examples: {
27
+ readonly nodeId: string;
28
+ readonly viaFactIds: readonly string[];
29
+ readonly nextFactId: string;
30
+ readonly nextNodeId: string;
31
+ }[];
32
+ omitted: number;
33
+ };
34
+ };
35
+ search: {
36
+ searchLimit: number;
37
+ replayedSteps: number;
38
+ examinedSteps: number;
39
+ totalSteps: number;
40
+ stopReason: "exhausted" | "search-limit" | "path-page-limit" | "work-page-limit";
41
+ exhaustedWithinDepth: boolean;
42
+ depthLimitReached: boolean;
43
+ truncated: boolean;
44
+ };
45
+ };
@@ -0,0 +1,101 @@
1
+ /** Pure, dependency-free search shared verbatim with the offline viewer. No global visited set:
2
+ * distinct simple paths and parallel assertions survive; cycles do not repeat a node. */
3
+ export function searchEvidencePaths(edges, start, target, options, knownNodeIds) {
4
+ const searchLimit = 100_000;
5
+ const offset = options.offset ?? 0;
6
+ const validateBounds = () => {
7
+ for (const [value, maximum] of [[options.maxDepth, 32], [options.maxPaths, 20], [options.maxSteps, 10_000]]) {
8
+ if (!Number.isInteger(value) || value < 1 || value > maximum)
9
+ throw new Error('Invalid path search bound');
10
+ }
11
+ if (!Number.isInteger(offset) || offset < 0 || offset >= searchLimit)
12
+ throw new Error('Invalid path continuation offset');
13
+ };
14
+ validateBounds();
15
+ const adjacency = new Map();
16
+ const nodeIds = new Set();
17
+ for (const edge of [...edges].sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0)) {
18
+ const entries = adjacency.get(edge.from) ?? [];
19
+ entries.push(edge);
20
+ adjacency.set(edge.from, entries);
21
+ nodeIds.add(edge.from);
22
+ nodeIds.add(edge.to);
23
+ }
24
+ const paths = [];
25
+ const stack = nodeIds.has(start) && nodeIds.has(target) && start !== target ? [{ nodeId: start, next: 0 }] : [];
26
+ const depthExamples = [];
27
+ let depthCount = 0;
28
+ let totalSteps = 0;
29
+ const trim = () => {
30
+ while (stack.length && stack.at(-1).next >= (adjacency.get(stack.at(-1).nodeId)?.length ?? 0))
31
+ stack.pop();
32
+ };
33
+ const step = () => {
34
+ const frame = stack.at(-1);
35
+ const edge = adjacency.get(frame.nodeId)[frame.next++];
36
+ totalSteps++;
37
+ if (stack.some(item => item.nodeId === edge.to))
38
+ return;
39
+ const viaFactIds = stack.slice(1).map(item => item.via);
40
+ if (viaFactIds.length === options.maxDepth) {
41
+ depthCount++;
42
+ if (depthExamples.length < 20)
43
+ depthExamples.push({ nodeId: frame.nodeId, viaFactIds,
44
+ nextFactId: edge.id, nextNodeId: edge.to });
45
+ }
46
+ else if (edge.to === target) {
47
+ return { nodeIds: [...stack.map(item => item.nodeId), target], factIds: [...viaFactIds, edge.id] };
48
+ }
49
+ else {
50
+ stack.push({ nodeId: edge.to, next: 0, via: edge.id });
51
+ }
52
+ };
53
+ trim();
54
+ // Reconstruct only bounded search state. Never accept a caller-supplied stack or facts.
55
+ const replay = () => {
56
+ let replayPageSteps = 0;
57
+ let replayPagePaths = 0;
58
+ while (totalSteps < offset && stack.length) {
59
+ if (step())
60
+ replayPagePaths++;
61
+ replayPageSteps++;
62
+ if (replayPagePaths === options.maxPaths || replayPageSteps === options.maxSteps) {
63
+ replayPagePaths = 0;
64
+ replayPageSteps = 0;
65
+ }
66
+ trim();
67
+ }
68
+ if (totalSteps !== offset || (offset && (!stack.length || replayPagePaths || replayPageSteps))) {
69
+ throw new Error('Invalid path continuation boundary');
70
+ }
71
+ };
72
+ replay();
73
+ if (!offset && start === target && (nodeIds.has(start) || knownNodeIds?.has(start)))
74
+ paths.push({ nodeIds: [start], factIds: [] });
75
+ while (stack.length && paths.length < options.maxPaths && totalSteps - offset < options.maxSteps && totalSteps < searchLimit) {
76
+ const path = step();
77
+ if (path)
78
+ paths.push(path);
79
+ trim();
80
+ }
81
+ const pending = stack.flatMap((frame, index) => {
82
+ const entries = adjacency.get(frame.nodeId) ?? [];
83
+ return frame.next < entries.length ? [{ nodeId: frame.nodeId,
84
+ viaFactIds: stack.slice(1, index + 1).map(item => item.via), nextFactId: entries[frame.next].id,
85
+ remainingCandidates: entries.length - frame.next }] : [];
86
+ });
87
+ const exhaustedWithinDepth = stack.length === 0;
88
+ const stopReason = () => {
89
+ if (exhaustedWithinDepth)
90
+ return 'exhausted';
91
+ if (totalSteps === searchLimit)
92
+ return 'search-limit';
93
+ if (paths.length === options.maxPaths)
94
+ return 'path-page-limit';
95
+ return 'work-page-limit';
96
+ };
97
+ return { paths, frontier: { pending, depthLimited: { count: depthCount, examples: depthExamples,
98
+ omitted: depthCount - depthExamples.length } }, search: { searchLimit, replayedSteps: offset,
99
+ examinedSteps: totalSteps - offset, totalSteps, stopReason: stopReason(), exhaustedWithinDepth,
100
+ depthLimitReached: depthCount > 0, truncated: !exhaustedWithinDepth || depthCount > 0 } };
101
+ }
@@ -0,0 +1,2 @@
1
+ import type { GraphPaths } from '@weftlet/core';
2
+ export declare function renderGraphPaths(result: Omit<GraphPaths, 'markdown'>): string;
@@ -0,0 +1,36 @@
1
+ import { factEvidenceDescription } from './evidence-description.js';
2
+ import { sourceLocation } from '@weftlet/core';
3
+ import { contextPackEvidenceAuthority } from './authority.js';
4
+ import { coverageDescription } from './coverage.js';
5
+ import { diagnosticSummary } from './diagnostics.js';
6
+ import { documentSelectionDescription } from './document-role-description.js';
7
+ const quoted = (value) => JSON.stringify(value).replace(/[\\`*_{}\[\]()<>!|]/g, '\\$&');
8
+ export function renderGraphPaths(result) {
9
+ const { snapshot, endpoints, search, frontier, evidenceState } = result;
10
+ return [
11
+ '# Cited evidence paths',
12
+ `Snapshot: ${quoted(snapshot.snapshotId)} (${snapshot.commitSha}); configuration: ${snapshot.configurationDigest ?? 'unknown'}`,
13
+ `Scope: ${snapshot.scope?.map(quoted).join(', ') ?? 'unknown'}`,
14
+ documentSelectionDescription(snapshot.documentSelection),
15
+ `From ${quoted(endpoints.from.nodeId)} (${endpoints.from.status}) to ${quoted(endpoints.to.nodeId)} (${endpoints.to.status})`,
16
+ `Direction: ${search.direction}; predicates: ${search.predicates.join(', ') || 'all'}; order: ${search.order}`,
17
+ `Depth: ${search.maxDepth}; paths on page: ${result.paths.length}/${search.maxPaths}; stop: ${search.stopReason}; truncated: ${search.truncated}`,
18
+ `Candidate steps: ${search.examinedSteps} new + ${search.replayedSteps} replay; ${search.totalSteps}/${search.searchLimit} total ceiling.`,
19
+ `Unexamined prefixes: ${frontier.pending.length}; depth-limited extensions: ${frontier.depthLimited.count} (${frontier.depthLimited.omitted} examples omitted).`,
20
+ ...(search.continuation ? [`Continuation (same request): ${search.continuation}`] : []),
21
+ ...(search.depthLimitReached ? ['Depth limit reached: restart with a larger maxDepth or explore a frontier node. Continuation does not lift the depth bound.'] : []),
22
+ ...(search.stopReason === 'search-limit' ? ['Total search limit reached: narrow the relations or explore an intermediate node; no further continuation is available.'] : []),
23
+ ...(evidenceState ? [`Stale: ${evidenceState.stale}; configuration matches: ${evidenceState.configurationMatches}; extraction compatible: ${evidenceState.extractionCompatible ?? 'unknown'}; overlay freshness: ${evidenceState.overlayFreshness ?? 'not an overlay'}`,
24
+ `Excluded working changes: ${evidenceState.excludedWorkingChanges.map(quoted).join(', ') || '(none)'}`] : []),
25
+ 'Paths are cited associations, not proof of causality, business compatibility or current-diff validation. A completed search covers only the selected saved facts and depth; absence is not proof of no product dependency.',
26
+ coverageDescription(result.coverage), ...result.coverage.gaps.map(quoted),
27
+ '', '## Paths',
28
+ ...result.paths.map((path, index) => `${index + 1}. ${path.nodeIds.map(quoted).join(' → ')}; facts: ${path.factIds.map(quoted).join(', ') || '(zero-length identity path)'}`),
29
+ '', '## Supporting assertions',
30
+ ...result.facts.map(fact => `- ${quoted(fact.id)} [${contextPackEvidenceAuthority(fact)}] ${quoted(fact.subject.id)} —${fact.predicate}→ ${quoted(fact.object.id)} (${quoted(sourceLocation(fact.provenance))}–${fact.provenance.endLine}${fact.provenance.endColumn === undefined ? '' : `:${fact.provenance.endColumn}`}; confidence ${fact.confidence}; source ${fact.sourceAuthority ?? 'unspecified'}; extraction ${fact.extractionReview ?? 'unspecified'}${factEvidenceDescription(fact) ? `; ${factEvidenceDescription(fact)}` : ''})`),
31
+ '', '## Unexplored frontier',
32
+ ...frontier.pending.map(item => `- ${quoted(item.nodeId)} via ${item.viaFactIds.map(quoted).join(', ') || '(start)'}: ${item.remainingCandidates} candidates; next ${quoted(item.nextFactId)}`),
33
+ ...frontier.depthLimited.examples.map(item => `- Depth boundary: ${quoted(item.nodeId)} → ${quoted(item.nextNodeId)} via ${quoted(item.nextFactId)}`),
34
+ '', '## Scoped diagnostics', ...diagnosticSummary(result).map(quoted),
35
+ ].filter(line => line !== undefined).join('\n');
36
+ }
@@ -0,0 +1,7 @@
1
+ import type { GraphPathQueryService, GraphPaths, GraphPathsRequest, SnapshotStore } from '@weftlet/core';
2
+ export declare const GRAPH_PATHS_VERSION = "simple-evidence-paths-v1";
3
+ export declare class SnapshotGraphPathService implements GraphPathQueryService {
4
+ private readonly store;
5
+ constructor(store: Pick<SnapshotStore, 'read'>);
6
+ paths(input: GraphPathsRequest): Promise<GraphPaths>;
7
+ }
@@ -0,0 +1,74 @@
1
+ import { snapshotContext } from './snapshot-context.js';
2
+ import { sha256, stableJson } from '../infrastructure/util.js';
3
+ import { RdfEvidenceGraph } from './rdf.js';
4
+ import { coverageForFacts } from './coverage.js';
5
+ import { selectDiagnostics } from './diagnostics.js';
6
+ import { parseGraphPathsRequest } from './path-request.js';
7
+ import { searchEvidencePaths } from './path-search.js';
8
+ import { renderGraphPaths } from './paths-renderer.js';
9
+ export const GRAPH_PATHS_VERSION = 'simple-evidence-paths-v1';
10
+ function continuationOffset(token, binding) {
11
+ if (!token)
12
+ return 0;
13
+ try {
14
+ if (!/^[A-Za-z0-9_-]+$/.test(token))
15
+ throw new Error();
16
+ const value = JSON.parse(Buffer.from(token, 'base64url').toString('utf8'));
17
+ if (!value || typeof value !== 'object' || Array.isArray(value) ||
18
+ Object.keys(value).sort().join(',') !== 'binding,offset,version' ||
19
+ value.version !== GRAPH_PATHS_VERSION || value.binding !== binding ||
20
+ !Number.isInteger(value.offset) || value.offset < 1 || value.offset >= 100_000)
21
+ throw new Error();
22
+ return value.offset;
23
+ }
24
+ catch {
25
+ throw new Error('Invalid graph.paths continuation or query/snapshot mismatch; restart graph.paths');
26
+ }
27
+ }
28
+ export class SnapshotGraphPathService {
29
+ store;
30
+ constructor(store) {
31
+ this.store = store;
32
+ }
33
+ async paths(input) {
34
+ const request = parseGraphPathsRequest(input);
35
+ const saved = await this.store.read(request.snapshotId);
36
+ if (!saved)
37
+ throw new Error('No graph snapshot is available for that identifier');
38
+ if (saved.manifest.snapshotId !== request.snapshotId)
39
+ throw new Error('Saved snapshot identity does not match the requested identifier');
40
+ const all = await new RdfEvidenceGraph(saved).facts();
41
+ if (new Set(all.map(fact => fact.id)).size !== all.length)
42
+ throw new Error('Duplicate fact identities prevent stable graph.paths pagination');
43
+ const { continuation, ...query } = request;
44
+ const binding = sha256(stableJson({ version: GRAPH_PATHS_VERSION, query, manifest: saved.manifest,
45
+ facts: all, diagnostics: saved.diagnostics, unresolved: saved.unresolved }));
46
+ const offset = continuationOffset(continuation, binding);
47
+ const selected = all.filter(fact => !request.predicates.length || request.predicates.includes(fact.predicate));
48
+ const edges = selected.flatMap(fact => {
49
+ const forward = { id: fact.id, from: fact.subject.id, to: fact.object.id };
50
+ const reverse = { id: fact.id, from: fact.object.id, to: fact.subject.id };
51
+ return request.direction === 'incoming' ? [reverse] : request.direction === 'outgoing' || forward.from === forward.to
52
+ ? [forward] : [forward, reverse];
53
+ });
54
+ const nodes = new Set(all.flatMap(fact => [fact.subject.id, fact.object.id]));
55
+ const result = searchEvidencePaths(edges, request.fromNodeId, request.toNodeId, { ...request, offset }, nodes);
56
+ const factIds = new Set(result.paths.flatMap(path => path.factIds));
57
+ const facts = all.filter(fact => factIds.has(fact.id));
58
+ const endpoint = (nodeId) => ({ nodeId, status: nodes.has(nodeId) ? 'present' : 'absent-from-snapshot' });
59
+ const next = !result.search.exhaustedWithinDepth && result.search.stopReason !== 'search-limit'
60
+ ? Buffer.from(JSON.stringify({ version: GRAPH_PATHS_VERSION, binding, offset: result.search.totalSteps })).toString('base64url') : undefined;
61
+ const manifest = saved.manifest;
62
+ const plain = {
63
+ snapshot: snapshotContext(manifest),
64
+ endpoints: { from: endpoint(request.fromNodeId), to: endpoint(request.toNodeId) },
65
+ paths: result.paths, facts, coverage: coverageForFacts(facts, saved),
66
+ diagnostics: selectDiagnostics(saved, {}, facts, [], [], new Set([request.fromNodeId, request.toNodeId,
67
+ ...facts.flatMap(fact => [fact.subject.id, fact.object.id])])),
68
+ search: { version: GRAPH_PATHS_VERSION, order: 'fact-id-depth-first', direction: request.direction,
69
+ predicates: request.predicates, maxDepth: request.maxDepth, maxPaths: request.maxPaths, maxSteps: request.maxSteps,
70
+ ...result.search, ...(next ? { continuation: next } : {}) }, frontier: result.frontier,
71
+ };
72
+ return { ...plain, markdown: renderGraphPaths(plain) };
73
+ }
74
+ }
@@ -1,4 +1,7 @@
1
1
  // Modified for standalone extraction; see docs/extraction-manifest.json.
2
+ import { unexpandedCodeDescription } from './code-description.js';
3
+ import { factEvidenceDescription } from './evidence-description.js';
4
+ import { sourceLocation } from '@weftlet/core';
2
5
  import { contextPackEvidenceAuthority } from "./authority.js";
3
6
  import { RdfEvidenceGraph } from "./rdf.js";
4
7
  import { sha256, stableJson } from "../infrastructure/util.js";
@@ -61,7 +64,8 @@ function markdownFactDetails(fact) {
61
64
  const document = sourceDocumentDescription(fact)?.replace(/[\\`*_{}\[\]()<>!|]/g, '\\$&').replace(/[\r\n]/g, ' ');
62
65
  return `confidence ${fact.confidence}` +
63
66
  (fact.sourceAuthority ? `; source ${fact.sourceAuthority}; extraction ${fact.extractionReview ?? 'unknown'}` : '') +
64
- (document ? `; ${document}` : '');
67
+ (document ? `; ${document}` : '') +
68
+ (factEvidenceDescription(fact) ? `; ${factEvidenceDescription(fact)}` : '');
65
69
  }
66
70
  export class MarkdownContextPackRenderer {
67
71
  render(pack) {
@@ -106,7 +110,7 @@ export class MarkdownContextPackRenderer {
106
110
  ...pack.facts
107
111
  .filter((fact) => contextPackLaneForFact(fact) === lane)
108
112
  .map((fact) => `- [${contextPackEvidenceAuthority(fact)}] ${fact.subject.label} —${fact.predicate}→ ${fact.object.label} ` +
109
- `(\`${fact.provenance.path}:${fact.provenance.startLine}\`, ${markdownFactDetails(fact)})`),
113
+ `(\`${sourceLocation(fact.provenance)}\`, ${markdownFactDetails(fact)})`),
110
114
  ]),
111
115
  '',
112
116
  '## Runtime evidence',
@@ -122,6 +126,7 @@ export class MarkdownContextPackRenderer {
122
126
  '## Suggested files',
123
127
  ...pack.suggestedFiles.map((path) => `- \`${path}\``),
124
128
  '',
129
+ ...unexpandedCodeDescription(pack.exploration),
125
130
  '## Scoped diagnostics',
126
131
  ...diagnosticSummary(pack).map((item) => `- ${item}`),
127
132
  ];
@@ -165,8 +170,16 @@ export class SnapshotImpactQueryService {
165
170
  const directTerms = anchorTerms.length > 0 ? anchorTerms : focus;
166
171
  const direct = snapshot.facts.filter((fact) => this.matches(fact, directTerms));
167
172
  const ranked = new Map(direct.map((fact) => [fact.id, fact]));
173
+ const unexpandedCodeTargets = new Set();
174
+ const expand = (node) => {
175
+ if (node.kind === 'CodeSymbol' && node.codeSymbol?.resolution === 'no-indexed-definition') {
176
+ unexpandedCodeTargets.add(node.id);
177
+ return false;
178
+ }
179
+ return node.kind !== 'Project';
180
+ };
168
181
  let frontier = new Set(direct.flatMap((fact) => [fact.subject, fact.object]
169
- .filter((node) => node.kind !== 'Project')
182
+ .filter(expand)
170
183
  .map((node) => node.id)));
171
184
  const visitedNodes = new Set(frontier);
172
185
  for (let depth = 0; depth < maxDepth && frontier.size > 0; depth += 1) {
@@ -176,7 +189,7 @@ export class SnapshotImpactQueryService {
176
189
  continue;
177
190
  ranked.set(fact.id, fact);
178
191
  for (const node of [fact.subject, fact.object]) {
179
- if (node.kind !== 'Project' && !visitedNodes.has(node.id))
192
+ if (expand(node) && !visitedNodes.has(node.id))
180
193
  next.add(node.id);
181
194
  }
182
195
  }
@@ -196,7 +209,7 @@ export class SnapshotImpactQueryService {
196
209
  ...tier.filter((fact) => contextPackLaneForFact(fact) === undefined),
197
210
  ]);
198
211
  const { continuation: _continuation, snapshotId: _snapshotId, ...query } = request;
199
- const queryDigest = sha256(stableJson({ ranking: IMPACT_RANKING_VERSION, query }));
212
+ const queryDigest = sha256(stableJson({ ranking: IMPACT_RANKING_VERSION, codeTraversal: 'indexed-symbols-v1', query }));
200
213
  let offset = 0;
201
214
  if (request.continuation) {
202
215
  if (request.continuation.length > 2048)
@@ -215,7 +228,7 @@ export class SnapshotImpactQueryService {
215
228
  offset = token.offset;
216
229
  }
217
230
  const facts = allBalanced.slice(offset, offset + maxFacts);
218
- const coverage = coverageForFacts(facts);
231
+ const coverage = coverageForFacts(facts, snapshot);
219
232
  const nextOffset = offset + facts.length;
220
233
  const continuation = nextOffset < allBalanced.length ? Buffer.from(JSON.stringify({
221
234
  snapshot: snapshot.manifest.snapshotId, digest: snapshot.manifest.contentDigest,
@@ -306,6 +319,10 @@ export class SnapshotImpactQueryService {
306
319
  diagnostics: selectDiagnostics(snapshot, request, facts, focus, queryDiagnostics),
307
320
  exploration: {
308
321
  rankingVersion: IMPACT_RANKING_VERSION,
322
+ codeTraversalVersion: 'indexed-symbols-v1',
323
+ unexpandedCodeTargets: [...unexpandedCodeTargets].sort().slice(0, 100),
324
+ unexpandedCodeTargetCount: unexpandedCodeTargets.size,
325
+ unexpandedCodeTargetsTruncated: unexpandedCodeTargets.size > 100,
309
326
  returned: facts.length, reachableFacts: allBalanced.length, maxDepth,
310
327
  depthLimitReached: frontier.size > 0, truncated: Boolean(continuation) || frontier.size > 0,
311
328
  continuation,
package/dist/graph/rdf.js CHANGED
@@ -6,6 +6,10 @@ import { stableJson } from "../infrastructure/util.js";
6
6
  import { createRequire } from 'node:module';
7
7
  import { CG, RDF, XSD, evidenceShapes } from './shacl-shapes.js';
8
8
  import { measureValidationPhase } from './validation-progress.js';
9
+ import { addBindingEvidence, bindingEvidenceIssues } from './binding-rdf.js';
10
+ import { addCallEvidence, callEvidenceIssues } from './call-rdf.js';
11
+ import { addObligationEvidence, obligationEvidenceIssues } from './obligation-rdf.js';
12
+ import { addCodeEvidence, codeEvidenceIssues, invalidCodeRange } from './code-rdf.js';
9
13
  const { namedNode: iri, literal } = DataFactory;
10
14
  export { CG } from './shacl-shapes.js';
11
15
  export const nodeIri = (id) => `urn:context-graph:node:${encodeURIComponent(id)}`;
@@ -53,6 +57,10 @@ export class RdfEvidenceGraph {
53
57
  this.dataset.addQuad(record, iri(CG + p), literal(String(value), iri(XSD + 'integer')));
54
58
  }
55
59
  this.dataset.addQuad(record, iri(CG + 'confidence'), literal(String(fact.confidence), iri(XSD + 'decimal')));
60
+ addCodeEvidence(this.dataset, record, fact, nodeIri);
61
+ addBindingEvidence(this.dataset, record, fact, factIri);
62
+ addCallEvidence(this.dataset, record, fact, factIri);
63
+ addObligationEvidence(this.dataset, record, fact);
56
64
  for (const node of [fact.subject, fact.object]) {
57
65
  const term = iri(nodeIri(node.id));
58
66
  this.dataset.addQuad(term, iri(RDF + 'type'), iri(CG + 'Node'));
@@ -92,7 +100,25 @@ export class RdfEvidenceGraph {
92
100
  path: result.path?.value,
93
101
  message: result.message.map((message) => message.value).join('; '),
94
102
  }));
103
+ const byId = new Map(this.snapshot.facts.map(fact => [fact.id, fact]));
95
104
  for (const fact of this.snapshot.facts) {
105
+ for (const message of obligationEvidenceIssues(fact, this.snapshot.manifest.repositoryId))
106
+ issues.push({ category: 'extraction-gap',
107
+ focus: factIri(fact.id), path: CG + 'obligationRole', message });
108
+ for (const message of callEvidenceIssues(fact, byId))
109
+ issues.push({ category: 'extraction-gap',
110
+ focus: factIri(fact.id), path: CG + 'callTarget', message });
111
+ for (const message of bindingEvidenceIssues(fact, byId))
112
+ issues.push({ category: 'extraction-gap',
113
+ focus: factIri(fact.id), path: CG + 'bindingDefinition', message });
114
+ for (const message of codeEvidenceIssues(fact))
115
+ issues.push({ category: 'extraction-gap',
116
+ focus: factIri(fact.id), path: CG + 'codeRole', message });
117
+ if (invalidCodeRange(fact.provenance) ||
118
+ (fact.codeOccurrence?.declarationRange && invalidCodeRange(fact.codeOccurrence.declarationRange))) {
119
+ issues.push({ category: 'extraction-gap', focus: factIri(fact.id), path: CG + 'startColumn',
120
+ message: 'Invalid UTF-16 source range' });
121
+ }
96
122
  if (fact.provenance.endLine < fact.provenance.startLine) {
97
123
  issues.push({ category: 'extraction-gap', focus: factIri(fact.id), path: CG + 'endLine',
98
124
  message: 'Citation ends before it starts' });
@@ -1,4 +1,6 @@
1
1
  import { Parser } from 'n3';
2
+ import { callShapes } from './call-shapes.js';
3
+ import { obligationShapes } from './obligation-shapes.js';
2
4
  export const CG = 'https://context-graph.dev/record#';
3
5
  export const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
4
6
  export const XSD = 'http://www.w3.org/2001/XMLSchema#';
@@ -8,6 +10,8 @@ export const evidenceShapes = new Parser().parse(`
8
10
  @prefix rdf: <${RDF}>.
9
11
  @prefix sh: <http://www.w3.org/ns/shacl#>.
10
12
  @prefix xsd: <${XSD}>.
13
+ ${callShapes}
14
+ ${obligationShapes}
11
15
  cg:FactShape a sh:NodeShape; sh:targetClass rdf:Statement;
12
16
  sh:property [ sh:path cg:record; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string ];
13
17
  sh:property [ sh:path rdf:subject; sh:minCount 1; sh:maxCount 1; sh:nodeKind sh:IRI ];
@@ -25,6 +29,72 @@ cg:FactShape a sh:NodeShape; sh:targetClass rdf:Statement;
25
29
  cg:NodeShape a sh:NodeShape; sh:targetClass cg:Node;
26
30
  sh:property [ sh:path cg:kind; sh:minCount 1; sh:maxCount 1 ].
27
31
 
32
+ cg:ColumnsShape a sh:NodeShape;
33
+ sh:targetSubjectsOf cg:startColumn, cg:endColumn, cg:columnEncoding;
34
+ sh:property [ sh:path cg:startColumn; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
35
+ sh:property [ sh:path cg:endColumn; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
36
+ sh:property [ sh:path cg:columnEncoding; sh:minCount 1; sh:maxCount 1; sh:in ("utf-16") ].
37
+ cg:CodeRangeShape a sh:NodeShape; sh:targetClass cg:CodeRange;
38
+ sh:property [ sh:path cg:startLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
39
+ sh:property [ sh:path cg:endLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
40
+ sh:property [ sh:path cg:columnEncoding; sh:minCount 1; sh:hasValue "utf-16" ].
41
+ cg:CodeOccurrenceShape a sh:NodeShape; sh:targetClass cg:CodeOccurrence; sh:targetSubjectsOf cg:codeRole;
42
+ sh:property [ sh:path cg:codeVersion; sh:minCount 1; sh:maxCount 1; sh:hasValue 1 ];
43
+ sh:property [ sh:path cg:codeRole; sh:minCount 1; sh:maxCount 1; sh:in ("definition" "reference") ];
44
+ sh:property [ sh:path cg:codeLocationKind; sh:minCount 1; sh:maxCount 1; sh:in ("name" "zero-width-anchor") ];
45
+ sh:property [ sh:path cg:codeNativeRoles; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 0 ];
46
+ sh:property [ sh:path cg:columnEncoding; sh:minCount 1; sh:hasValue "utf-16" ];
47
+ sh:property [ sh:path cg:codeEnclosure; sh:minCount 1; sh:maxCount 1; sh:in ("native-range" "file" "ambiguous") ];
48
+ sh:property [ sh:path cg:enclosingSymbol; sh:maxCount 1; sh:class cg:CodeSymbol ];
49
+ sh:property [ sh:path cg:declarationRange; sh:maxCount 1; sh:class cg:CodeRange ];
50
+ sh:or (
51
+ [ sh:property [ sh:path cg:codeEnclosure; sh:hasValue "native-range" ]; sh:property [ sh:path cg:enclosingSymbol; sh:minCount 1 ] ]
52
+ [ sh:property [ sh:path cg:codeEnclosure; sh:in ("file" "ambiguous") ]; sh:property [ sh:path cg:enclosingSymbol; sh:maxCount 0 ] ]
53
+ );
54
+ sh:or (
55
+ [ sh:property [ sh:path cg:codeRole; sh:hasValue "definition" ]; sh:property [ sh:path rdf:subject; sh:class cg:CodeSymbol ]; sh:property [ sh:path rdf:predicate; sh:hasValue cg:definedBy ] ]
56
+ [ sh:property [ sh:path cg:codeRole; sh:hasValue "reference" ]; sh:property [ sh:path rdf:object; sh:class cg:CodeSymbol ]; sh:property [ sh:path rdf:predicate; sh:hasValue cg:references ] ]
57
+ ).
58
+ cg:CodeSymbolShape a sh:NodeShape; sh:targetClass cg:CodeSymbol;
59
+ sh:property [ sh:path cg:kind; sh:hasValue "CodeSymbol" ];
60
+ sh:property [ sh:path cg:codeVersion; sh:minCount 1; sh:maxCount 1; sh:hasValue 1 ];
61
+ sh:property [ sh:path cg:codeProvider; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
62
+ sh:property [ sh:path cg:codeRepository; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
63
+ sh:property [ sh:path cg:nativeSymbol; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
64
+ sh:property [ sh:path cg:codeResolution; sh:minCount 1; sh:maxCount 1; sh:in ("indexed-definition" "declaration-only" "no-indexed-definition") ];
65
+ sh:property [ sh:path cg:codeIdentityScope; sh:minCount 1; sh:maxCount 1; sh:in ("repository" "index-document") ];
66
+ sh:or (
67
+ [ sh:property [ sh:path cg:codeIdentityScope; sh:hasValue "repository" ]; sh:property [ sh:path cg:codeDocument; sh:maxCount 0 ]; sh:property [ sh:path cg:codeIndex; sh:maxCount 0 ] ]
68
+ [ sh:property [ sh:path cg:codeIdentityScope; sh:hasValue "index-document" ];
69
+ sh:property [ sh:path cg:codeDocument; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
70
+ sh:property [ sh:path cg:codeIndex; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ] ]
71
+ ).
72
+
73
+ cg:DocumentCodeBindingShape a sh:NodeShape; sh:targetClass cg:DocumentCodeBinding;
74
+ sh:property [ sh:path cg:bindingVersion; sh:minCount 1; sh:maxCount 1; sh:hasValue 1 ];
75
+ sh:property [ sh:path cg:bindingMethod; sh:minCount 1; sh:maxCount 1; sh:hasValue "explicit-markdown" ];
76
+ sh:property [ sh:path <${CG}bindingSelector/path>; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
77
+ sh:property [ sh:path <${CG}bindingSelector/symbol>; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
78
+ sh:property [ sh:path cg:bindingDocument; sh:minCount 1; sh:class cg:BindingCitation ];
79
+ sh:property [ sh:path cg:bindingSelection; sh:minCount 1; sh:class cg:BindingCitation ];
80
+ sh:property [ sh:path cg:bindingDefinition; sh:minCount 1; sh:class cg:BindingCitation ];
81
+ sh:property [ sh:path cg:bindingSubject; sh:class cg:BindingCitation ];
82
+ sh:property [ sh:path rdf:object; sh:class cg:CodeSymbol ];
83
+ sh:property [ sh:path rdf:predicate; sh:in (cg:references cg:implementedBy cg:verifiedBy) ];
84
+ sh:property [ sh:path cg:authority; sh:in ("inferred" "draft") ];
85
+ sh:property [ sh:path cg:extractionReview; sh:minCount 1; sh:in ("deterministic" "unreviewed") ].
86
+ cg:BindingCitationShape a sh:NodeShape; sh:targetClass cg:BindingCitation;
87
+ sh:property [ sh:path cg:path; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
88
+ sh:property [ sh:path cg:digest; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
89
+ sh:property [ sh:path cg:commitSha; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:string; sh:minLength 1 ];
90
+ sh:property [ sh:path cg:startLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
91
+ sh:property [ sh:path cg:endLine; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
92
+ sh:property [ sh:path cg:bindingFact; sh:maxCount 1; sh:class rdf:Statement ].
93
+ cg:BindingSelectorPositionShape a sh:NodeShape;
94
+ sh:targetSubjectsOf <${CG}bindingSelector/line>, <${CG}bindingSelector/column>;
95
+ sh:property [ sh:path <${CG}bindingSelector/line>; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ];
96
+ sh:property [ sh:path <${CG}bindingSelector/column>; sh:minCount 1; sh:maxCount 1; sh:datatype xsd:integer; sh:minInclusive 1 ].
97
+
28
98
  # Optional source metadata targets only assertions that carry those predicates.
29
99
  # Legacy facts do not acquire additional property or ownership consistency checks.
30
100
  cg:SourceRoleShape a sh:NodeShape; sh:targetSubjectsOf cg:sourceRole;
@@ -0,0 +1,3 @@
1
+ import type { ContextPack, SnapshotManifest } from '@weftlet/core';
2
+ /** The saved identity/scope carried by exact graph queries; never resolve a new head. */
3
+ export declare function snapshotContext(manifest: SnapshotManifest): ContextPack['snapshot'];
@@ -0,0 +1,8 @@
1
+ /** The saved identity/scope carried by exact graph queries; never resolve a new head. */
2
+ export function snapshotContext(manifest) {
3
+ return { snapshotId: manifest.snapshotId, commitSha: manifest.commitSha, contentDigest: manifest.contentDigest,
4
+ configurationDigest: manifest.configurationDigest, scope: manifest.scope, baseSha: manifest.baseSha,
5
+ overlayDigest: manifest.overlayDigest, overlayCapture: manifest.overlayCapture,
6
+ extractorVersions: manifest.extractorVersions,
7
+ ...(manifest.documentSelection ? { documentSelection: manifest.documentSelection } : {}) };
8
+ }
package/dist/index.d.ts CHANGED
@@ -20,3 +20,26 @@ export * from './extraction/document-traversal.js';
20
20
  export * from './extraction/document-classification.js';
21
21
  export * from './extraction/document-evidence.js';
22
22
  export type { DocumentTraversalConfig } from './configuration/document-traversal.js';
23
+ export * from './graph/neighborhood.js';
24
+ export * from './graph/neighborhood-request.js';
25
+ export * from './graph/neighborhood-renderer.js';
26
+ export * from './graph/paths.js';
27
+ export * from './graph/path-request.js';
28
+ export * from './graph/paths-renderer.js';
29
+ export * from './extraction/document-code-bindings.js';
30
+ export * from './extraction/document-obligations.js';
31
+ export * from './graph/compatibility.js';
32
+ export * from './graph/compatibility-request.js';
33
+ export * from './graph/compatibility-renderer.js';
34
+ export * from './graph/code-coverage.js';
35
+ export * from './graph/code-coverage-projection.js';
36
+ export * from './graph/code-coverage-request.js';
37
+ export * from './graph/code-coverage-renderer.js';
38
+ export { MappingProposalService } from './application/mapping-proposals.js';
39
+ export { createMappingProposalService } from './application/mapping-service.js';
40
+ export type { MappingOperationOptions } from './application/mapping-proposals.js';
41
+ export { prepareMappingProposal } from './extraction/mapping-plan.js';
42
+ export { createMappingProvider, mappingProviderIdentity } from './extraction/mapping-provider.js';
43
+ export { parseMappingRequest } from './extraction/mapping-request.js';
44
+ export { validateMappingOutput } from './extraction/mapping-output.js';
45
+ export { FileMappingProposalStore } from './storage/mapping-proposals.js';