@harness-engineering/graph 0.6.0 → 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.
package/dist/index.d.mts CHANGED
@@ -512,6 +512,33 @@ declare class RequirementIngestor {
512
512
  private linkByKeywordOverlap;
513
513
  }
514
514
 
515
+ /**
516
+ * Domain inference for graph nodes.
517
+ *
518
+ * Precedence (highest to lowest):
519
+ * 1. node.metadata.domain (explicit)
520
+ * 2. extraPatterns (config-provided)
521
+ * 3. DEFAULT_PATTERNS (built-in)
522
+ * 4. Generic first non-blocklisted path segment
523
+ * 5. KnowledgeLinker connector source (path-less facts)
524
+ * 6. 'unknown'
525
+ *
526
+ * Pattern format: 'prefix/<dir>'. Single-segment prefix only. <dir> captures
527
+ * the segment immediately after the prefix.
528
+ */
529
+ interface DomainInferenceOptions {
530
+ /** Additional patterns beyond the built-in defaults. Format: 'prefix/<dir>'. */
531
+ extraPatterns?: readonly string[];
532
+ /** Additional blocklisted segments beyond the built-in defaults. */
533
+ extraBlocklist?: readonly string[];
534
+ }
535
+ declare const DEFAULT_PATTERNS: readonly string[];
536
+ declare const DEFAULT_BLOCKLIST: ReadonlySet<string>;
537
+ declare function inferDomain(node: {
538
+ path?: string;
539
+ metadata?: Record<string, unknown>;
540
+ }, options?: DomainInferenceOptions): string;
541
+
515
542
  type DriftClassification = 'new' | 'drifted' | 'stale' | 'contradicting';
516
543
  interface KnowledgeSnapshotEntry {
517
544
  readonly id: string;
@@ -591,7 +618,8 @@ interface AggregateResult {
591
618
  }
592
619
  declare class KnowledgeStagingAggregator {
593
620
  private readonly projectDir;
594
- constructor(projectDir: string);
621
+ private readonly inferenceOptions;
622
+ constructor(projectDir: string, inferenceOptions?: DomainInferenceOptions);
595
623
  aggregate(extractorResults: readonly StagedEntry[], linkerResults: readonly StagedEntry[], diagramResults: readonly StagedEntry[]): Promise<AggregateResult>;
596
624
  private extractDocName;
597
625
  generateGapReport(knowledgeDir: string, store?: GraphStore): Promise<GapReport>;
@@ -691,8 +719,9 @@ interface CoverageReport {
691
719
  readonly generatedAt: string;
692
720
  }
693
721
  declare class CoverageScorer {
722
+ private readonly inferenceOptions;
723
+ constructor(inferenceOptions?: DomainInferenceOptions);
694
724
  score(store: GraphStore): CoverageReport;
695
- private domainFromPath;
696
725
  }
697
726
 
698
727
  /**
@@ -725,7 +754,8 @@ interface SkippedEntry {
725
754
  }
726
755
  declare class KnowledgeDocMaterializer {
727
756
  private readonly store;
728
- constructor(store: GraphStore);
757
+ private readonly inferenceOptions;
758
+ constructor(store: GraphStore, inferenceOptions?: DomainInferenceOptions);
729
759
  materialize(gapEntries: readonly GapEntry[], options: MaterializeOptions): Promise<MaterializeResult>;
730
760
  private resolveEntry;
731
761
  inferDomain(node: GraphNode): string | null;
@@ -758,6 +788,13 @@ interface KnowledgePipelineOptions {
758
788
  readonly analyzeImages?: boolean;
759
789
  readonly analysisProvider?: AnalysisProvider;
760
790
  readonly imagePaths?: readonly string[];
791
+ /**
792
+ * Domain-inference overrides threaded into KnowledgeStagingAggregator,
793
+ * CoverageScorer, and KnowledgeDocMaterializer. Sourced by the CLI from
794
+ * `harness.config.json#knowledge.domainPatterns` (→ extraPatterns) and
795
+ * `knowledge.domainBlocklist` (→ extraBlocklist). Defaults to {} when absent.
796
+ */
797
+ readonly inferenceOptions?: DomainInferenceOptions;
761
798
  }
762
799
  interface ExtractionCounts {
763
800
  readonly codeSignals: number;
@@ -782,6 +819,8 @@ interface KnowledgePipelineResult {
782
819
  declare class KnowledgePipelineRunner {
783
820
  private readonly store;
784
821
  constructor(store: GraphStore);
822
+ /** Resolved per-`run()` inference options. Set on entry to `run()`. */
823
+ private inferenceOptions;
785
824
  run(options: KnowledgePipelineOptions): Promise<KnowledgePipelineResult>;
786
825
  /** Run the remediation convergence loop; returns iteration count and accumulated materialization. */
787
826
  private runRemediationLoop;
@@ -1827,4 +1866,4 @@ declare class CascadeSimulator {
1827
1866
 
1828
1867
  declare const VERSION = "0.6.0";
1829
1868
 
1830
- export { ALL_EXTRACTORS, type AggregateResult, type AnomalyDetectionOptions, type AnomalyReport, ApiPathExtractor, type ArticulationPoint, type AskGraphResult, type AssembledContext, Assembler, BusinessKnowledgeIngestor, CIConnector, CURRENT_SCHEMA_VERSION, type PackedEnvelope as CacheableEnvelope, type CascadeLayer, type CascadeNode, type CascadeResult, type CascadeSimulationOptions, CascadeSimulator, type ClassificationResult, CodeIngestor, CompositeProbabilityStrategy, type ConflictDetail, type ConflictPrediction, ConflictPredictor, type ConflictSeverity, type ConflictType, ConfluenceConnector, type ConnectorConfig, ContextQL, type ContextQLParams, type ContextQLResult, type Contradiction, ContradictionDetector, type ContradictionEntry, type ContradictionResult, type CoverageReport, CoverageScorer, D2Parser, DecisionIngestor, DesignConstraintAdapter, DesignIngestor, type DesignStrictness, type DesignViolation, type DetectedElement, type DiagramEntity, type DiagramFormatParser, type DiagramParseResult, DiagramParser, type DiagramRelationship, type DomainCoverage, type DomainCoverageScore, type DriftClassification, type DriftDetector, type DriftFinding, type DriftResult, EDGE_TYPES, type EdgeQuery, type EdgeType, EntityExtractor, EntityResolver, EnumConstantExtractor, type ExtractionCounts, type ExtractionRecord, ExtractionRunner, FigmaConnector, FusionLayer, type FusionResult, type GapEntry, type GapReport, GitIngestor, type GitRunner, GraphAnomalyAdapter, type GraphBudget, GraphComplexityAdapter, type GraphComplexityHotspot, type GraphComplexityResult, type GraphConnector, GraphConstraintAdapter, GraphCouplingAdapter, type GraphCouplingFileData, type GraphCouplingResult, type GraphCoverageReport, type GraphDeadCodeData, type GraphDependencyData, type GraphDriftData, type GraphEdge, GraphEdgeSchema, GraphEntropyAdapter, GraphFeedbackAdapter, type GraphFilterResult, type GraphHarnessCheckData, type GraphImpactData, type GraphLayerViolation, type GraphMetadata, type GraphNode, GraphNodeSchema, type GraphSnapshotSummary, type GraphStabilityTier, GraphStore, type HttpClient, INTENTS, ImageAnalysisExtractor, type ImageAnalysisExtractorOptions, type AnalysisProvider as ImageAnalysisProvider, type ImageAnalysisResult, type ImpactGroups, type IndependenceCheckParams, type IndependenceResult, type IngestResult, type Intent, IntentClassifier, JiraConnector, KnowledgeDocMaterializer, KnowledgeIngestor, type KnowledgePipelineOptions, type KnowledgePipelineResult, KnowledgePipelineRunner, type KnowledgeSnapshot, type KnowledgeSnapshotEntry, KnowledgeStagingAggregator, type Language, type LinkResult, type LoadGraphResult, type MaterializeOptions, type MaterializeResult, type MaterializedDoc, MermaidParser, MiroConnector, NODE_STABILITY, NODE_TYPES, type NodeCategory, type NodeQuery, type NodeType, OBSERVABILITY_TYPES, type OverlapDetail, PackedSummaryCache, type PairResult, PlantUmlParser, type ProbabilityStrategy, type ProjectionSpec, type RequirementCoverage, RequirementIngestor, type ResolvedEntity, ResponseFormatter, type SignalExtractor, type SkippedEntry, SlackConnector, type SourceLocation, type StagedEntry, type StatisticalOutlier, StructuralDriftDetector, SyncManager, type SyncMetadata, type TaskDefinition, TaskIndependenceAnalyzer, TestDescriptionExtractor, TopologicalLinker, type TraceabilityOptions, type TraceabilityResult, type TracedFile, VERSION, ValidationRuleExtractor, type VectorSearchResult, VectorStore, askGraph, classifyNodeCategory, createExtractionRunner, detectLanguage, groupNodesByImpact, linkToCode, loadGraph, normalizeIntent, project, queryTraceability, saveGraph };
1869
+ export { ALL_EXTRACTORS, type AggregateResult, type AnomalyDetectionOptions, type AnomalyReport, ApiPathExtractor, type ArticulationPoint, type AskGraphResult, type AssembledContext, Assembler, BusinessKnowledgeIngestor, CIConnector, CURRENT_SCHEMA_VERSION, type PackedEnvelope as CacheableEnvelope, type CascadeLayer, type CascadeNode, type CascadeResult, type CascadeSimulationOptions, CascadeSimulator, type ClassificationResult, CodeIngestor, CompositeProbabilityStrategy, type ConflictDetail, type ConflictPrediction, ConflictPredictor, type ConflictSeverity, type ConflictType, ConfluenceConnector, type ConnectorConfig, ContextQL, type ContextQLParams, type ContextQLResult, type Contradiction, ContradictionDetector, type ContradictionEntry, type ContradictionResult, type CoverageReport, CoverageScorer, D2Parser, DEFAULT_BLOCKLIST, DEFAULT_PATTERNS, DecisionIngestor, DesignConstraintAdapter, DesignIngestor, type DesignStrictness, type DesignViolation, type DetectedElement, type DiagramEntity, type DiagramFormatParser, type DiagramParseResult, DiagramParser, type DiagramRelationship, type DomainCoverage, type DomainCoverageScore, type DomainInferenceOptions, type DriftClassification, type DriftDetector, type DriftFinding, type DriftResult, EDGE_TYPES, type EdgeQuery, type EdgeType, EntityExtractor, EntityResolver, EnumConstantExtractor, type ExtractionCounts, type ExtractionRecord, ExtractionRunner, FigmaConnector, FusionLayer, type FusionResult, type GapEntry, type GapReport, GitIngestor, type GitRunner, GraphAnomalyAdapter, type GraphBudget, GraphComplexityAdapter, type GraphComplexityHotspot, type GraphComplexityResult, type GraphConnector, GraphConstraintAdapter, GraphCouplingAdapter, type GraphCouplingFileData, type GraphCouplingResult, type GraphCoverageReport, type GraphDeadCodeData, type GraphDependencyData, type GraphDriftData, type GraphEdge, GraphEdgeSchema, GraphEntropyAdapter, GraphFeedbackAdapter, type GraphFilterResult, type GraphHarnessCheckData, type GraphImpactData, type GraphLayerViolation, type GraphMetadata, type GraphNode, GraphNodeSchema, type GraphSnapshotSummary, type GraphStabilityTier, GraphStore, type HttpClient, INTENTS, ImageAnalysisExtractor, type ImageAnalysisExtractorOptions, type AnalysisProvider as ImageAnalysisProvider, type ImageAnalysisResult, type ImpactGroups, type IndependenceCheckParams, type IndependenceResult, type IngestResult, type Intent, IntentClassifier, JiraConnector, KnowledgeDocMaterializer, KnowledgeIngestor, type KnowledgePipelineOptions, type KnowledgePipelineResult, KnowledgePipelineRunner, type KnowledgeSnapshot, type KnowledgeSnapshotEntry, KnowledgeStagingAggregator, type Language, type LinkResult, type LoadGraphResult, type MaterializeOptions, type MaterializeResult, type MaterializedDoc, MermaidParser, MiroConnector, NODE_STABILITY, NODE_TYPES, type NodeCategory, type NodeQuery, type NodeType, OBSERVABILITY_TYPES, type OverlapDetail, PackedSummaryCache, type PairResult, PlantUmlParser, type ProbabilityStrategy, type ProjectionSpec, type RequirementCoverage, RequirementIngestor, type ResolvedEntity, ResponseFormatter, type SignalExtractor, type SkippedEntry, SlackConnector, type SourceLocation, type StagedEntry, type StatisticalOutlier, StructuralDriftDetector, SyncManager, type SyncMetadata, type TaskDefinition, TaskIndependenceAnalyzer, TestDescriptionExtractor, TopologicalLinker, type TraceabilityOptions, type TraceabilityResult, type TracedFile, VERSION, ValidationRuleExtractor, type VectorSearchResult, VectorStore, askGraph, classifyNodeCategory, createExtractionRunner, detectLanguage, groupNodesByImpact, inferDomain, linkToCode, loadGraph, normalizeIntent, project, queryTraceability, saveGraph };
package/dist/index.d.ts CHANGED
@@ -512,6 +512,33 @@ declare class RequirementIngestor {
512
512
  private linkByKeywordOverlap;
513
513
  }
514
514
 
515
+ /**
516
+ * Domain inference for graph nodes.
517
+ *
518
+ * Precedence (highest to lowest):
519
+ * 1. node.metadata.domain (explicit)
520
+ * 2. extraPatterns (config-provided)
521
+ * 3. DEFAULT_PATTERNS (built-in)
522
+ * 4. Generic first non-blocklisted path segment
523
+ * 5. KnowledgeLinker connector source (path-less facts)
524
+ * 6. 'unknown'
525
+ *
526
+ * Pattern format: 'prefix/<dir>'. Single-segment prefix only. <dir> captures
527
+ * the segment immediately after the prefix.
528
+ */
529
+ interface DomainInferenceOptions {
530
+ /** Additional patterns beyond the built-in defaults. Format: 'prefix/<dir>'. */
531
+ extraPatterns?: readonly string[];
532
+ /** Additional blocklisted segments beyond the built-in defaults. */
533
+ extraBlocklist?: readonly string[];
534
+ }
535
+ declare const DEFAULT_PATTERNS: readonly string[];
536
+ declare const DEFAULT_BLOCKLIST: ReadonlySet<string>;
537
+ declare function inferDomain(node: {
538
+ path?: string;
539
+ metadata?: Record<string, unknown>;
540
+ }, options?: DomainInferenceOptions): string;
541
+
515
542
  type DriftClassification = 'new' | 'drifted' | 'stale' | 'contradicting';
516
543
  interface KnowledgeSnapshotEntry {
517
544
  readonly id: string;
@@ -591,7 +618,8 @@ interface AggregateResult {
591
618
  }
592
619
  declare class KnowledgeStagingAggregator {
593
620
  private readonly projectDir;
594
- constructor(projectDir: string);
621
+ private readonly inferenceOptions;
622
+ constructor(projectDir: string, inferenceOptions?: DomainInferenceOptions);
595
623
  aggregate(extractorResults: readonly StagedEntry[], linkerResults: readonly StagedEntry[], diagramResults: readonly StagedEntry[]): Promise<AggregateResult>;
596
624
  private extractDocName;
597
625
  generateGapReport(knowledgeDir: string, store?: GraphStore): Promise<GapReport>;
@@ -691,8 +719,9 @@ interface CoverageReport {
691
719
  readonly generatedAt: string;
692
720
  }
693
721
  declare class CoverageScorer {
722
+ private readonly inferenceOptions;
723
+ constructor(inferenceOptions?: DomainInferenceOptions);
694
724
  score(store: GraphStore): CoverageReport;
695
- private domainFromPath;
696
725
  }
697
726
 
698
727
  /**
@@ -725,7 +754,8 @@ interface SkippedEntry {
725
754
  }
726
755
  declare class KnowledgeDocMaterializer {
727
756
  private readonly store;
728
- constructor(store: GraphStore);
757
+ private readonly inferenceOptions;
758
+ constructor(store: GraphStore, inferenceOptions?: DomainInferenceOptions);
729
759
  materialize(gapEntries: readonly GapEntry[], options: MaterializeOptions): Promise<MaterializeResult>;
730
760
  private resolveEntry;
731
761
  inferDomain(node: GraphNode): string | null;
@@ -758,6 +788,13 @@ interface KnowledgePipelineOptions {
758
788
  readonly analyzeImages?: boolean;
759
789
  readonly analysisProvider?: AnalysisProvider;
760
790
  readonly imagePaths?: readonly string[];
791
+ /**
792
+ * Domain-inference overrides threaded into KnowledgeStagingAggregator,
793
+ * CoverageScorer, and KnowledgeDocMaterializer. Sourced by the CLI from
794
+ * `harness.config.json#knowledge.domainPatterns` (→ extraPatterns) and
795
+ * `knowledge.domainBlocklist` (→ extraBlocklist). Defaults to {} when absent.
796
+ */
797
+ readonly inferenceOptions?: DomainInferenceOptions;
761
798
  }
762
799
  interface ExtractionCounts {
763
800
  readonly codeSignals: number;
@@ -782,6 +819,8 @@ interface KnowledgePipelineResult {
782
819
  declare class KnowledgePipelineRunner {
783
820
  private readonly store;
784
821
  constructor(store: GraphStore);
822
+ /** Resolved per-`run()` inference options. Set on entry to `run()`. */
823
+ private inferenceOptions;
785
824
  run(options: KnowledgePipelineOptions): Promise<KnowledgePipelineResult>;
786
825
  /** Run the remediation convergence loop; returns iteration count and accumulated materialization. */
787
826
  private runRemediationLoop;
@@ -1827,4 +1866,4 @@ declare class CascadeSimulator {
1827
1866
 
1828
1867
  declare const VERSION = "0.6.0";
1829
1868
 
1830
- export { ALL_EXTRACTORS, type AggregateResult, type AnomalyDetectionOptions, type AnomalyReport, ApiPathExtractor, type ArticulationPoint, type AskGraphResult, type AssembledContext, Assembler, BusinessKnowledgeIngestor, CIConnector, CURRENT_SCHEMA_VERSION, type PackedEnvelope as CacheableEnvelope, type CascadeLayer, type CascadeNode, type CascadeResult, type CascadeSimulationOptions, CascadeSimulator, type ClassificationResult, CodeIngestor, CompositeProbabilityStrategy, type ConflictDetail, type ConflictPrediction, ConflictPredictor, type ConflictSeverity, type ConflictType, ConfluenceConnector, type ConnectorConfig, ContextQL, type ContextQLParams, type ContextQLResult, type Contradiction, ContradictionDetector, type ContradictionEntry, type ContradictionResult, type CoverageReport, CoverageScorer, D2Parser, DecisionIngestor, DesignConstraintAdapter, DesignIngestor, type DesignStrictness, type DesignViolation, type DetectedElement, type DiagramEntity, type DiagramFormatParser, type DiagramParseResult, DiagramParser, type DiagramRelationship, type DomainCoverage, type DomainCoverageScore, type DriftClassification, type DriftDetector, type DriftFinding, type DriftResult, EDGE_TYPES, type EdgeQuery, type EdgeType, EntityExtractor, EntityResolver, EnumConstantExtractor, type ExtractionCounts, type ExtractionRecord, ExtractionRunner, FigmaConnector, FusionLayer, type FusionResult, type GapEntry, type GapReport, GitIngestor, type GitRunner, GraphAnomalyAdapter, type GraphBudget, GraphComplexityAdapter, type GraphComplexityHotspot, type GraphComplexityResult, type GraphConnector, GraphConstraintAdapter, GraphCouplingAdapter, type GraphCouplingFileData, type GraphCouplingResult, type GraphCoverageReport, type GraphDeadCodeData, type GraphDependencyData, type GraphDriftData, type GraphEdge, GraphEdgeSchema, GraphEntropyAdapter, GraphFeedbackAdapter, type GraphFilterResult, type GraphHarnessCheckData, type GraphImpactData, type GraphLayerViolation, type GraphMetadata, type GraphNode, GraphNodeSchema, type GraphSnapshotSummary, type GraphStabilityTier, GraphStore, type HttpClient, INTENTS, ImageAnalysisExtractor, type ImageAnalysisExtractorOptions, type AnalysisProvider as ImageAnalysisProvider, type ImageAnalysisResult, type ImpactGroups, type IndependenceCheckParams, type IndependenceResult, type IngestResult, type Intent, IntentClassifier, JiraConnector, KnowledgeDocMaterializer, KnowledgeIngestor, type KnowledgePipelineOptions, type KnowledgePipelineResult, KnowledgePipelineRunner, type KnowledgeSnapshot, type KnowledgeSnapshotEntry, KnowledgeStagingAggregator, type Language, type LinkResult, type LoadGraphResult, type MaterializeOptions, type MaterializeResult, type MaterializedDoc, MermaidParser, MiroConnector, NODE_STABILITY, NODE_TYPES, type NodeCategory, type NodeQuery, type NodeType, OBSERVABILITY_TYPES, type OverlapDetail, PackedSummaryCache, type PairResult, PlantUmlParser, type ProbabilityStrategy, type ProjectionSpec, type RequirementCoverage, RequirementIngestor, type ResolvedEntity, ResponseFormatter, type SignalExtractor, type SkippedEntry, SlackConnector, type SourceLocation, type StagedEntry, type StatisticalOutlier, StructuralDriftDetector, SyncManager, type SyncMetadata, type TaskDefinition, TaskIndependenceAnalyzer, TestDescriptionExtractor, TopologicalLinker, type TraceabilityOptions, type TraceabilityResult, type TracedFile, VERSION, ValidationRuleExtractor, type VectorSearchResult, VectorStore, askGraph, classifyNodeCategory, createExtractionRunner, detectLanguage, groupNodesByImpact, linkToCode, loadGraph, normalizeIntent, project, queryTraceability, saveGraph };
1869
+ export { ALL_EXTRACTORS, type AggregateResult, type AnomalyDetectionOptions, type AnomalyReport, ApiPathExtractor, type ArticulationPoint, type AskGraphResult, type AssembledContext, Assembler, BusinessKnowledgeIngestor, CIConnector, CURRENT_SCHEMA_VERSION, type PackedEnvelope as CacheableEnvelope, type CascadeLayer, type CascadeNode, type CascadeResult, type CascadeSimulationOptions, CascadeSimulator, type ClassificationResult, CodeIngestor, CompositeProbabilityStrategy, type ConflictDetail, type ConflictPrediction, ConflictPredictor, type ConflictSeverity, type ConflictType, ConfluenceConnector, type ConnectorConfig, ContextQL, type ContextQLParams, type ContextQLResult, type Contradiction, ContradictionDetector, type ContradictionEntry, type ContradictionResult, type CoverageReport, CoverageScorer, D2Parser, DEFAULT_BLOCKLIST, DEFAULT_PATTERNS, DecisionIngestor, DesignConstraintAdapter, DesignIngestor, type DesignStrictness, type DesignViolation, type DetectedElement, type DiagramEntity, type DiagramFormatParser, type DiagramParseResult, DiagramParser, type DiagramRelationship, type DomainCoverage, type DomainCoverageScore, type DomainInferenceOptions, type DriftClassification, type DriftDetector, type DriftFinding, type DriftResult, EDGE_TYPES, type EdgeQuery, type EdgeType, EntityExtractor, EntityResolver, EnumConstantExtractor, type ExtractionCounts, type ExtractionRecord, ExtractionRunner, FigmaConnector, FusionLayer, type FusionResult, type GapEntry, type GapReport, GitIngestor, type GitRunner, GraphAnomalyAdapter, type GraphBudget, GraphComplexityAdapter, type GraphComplexityHotspot, type GraphComplexityResult, type GraphConnector, GraphConstraintAdapter, GraphCouplingAdapter, type GraphCouplingFileData, type GraphCouplingResult, type GraphCoverageReport, type GraphDeadCodeData, type GraphDependencyData, type GraphDriftData, type GraphEdge, GraphEdgeSchema, GraphEntropyAdapter, GraphFeedbackAdapter, type GraphFilterResult, type GraphHarnessCheckData, type GraphImpactData, type GraphLayerViolation, type GraphMetadata, type GraphNode, GraphNodeSchema, type GraphSnapshotSummary, type GraphStabilityTier, GraphStore, type HttpClient, INTENTS, ImageAnalysisExtractor, type ImageAnalysisExtractorOptions, type AnalysisProvider as ImageAnalysisProvider, type ImageAnalysisResult, type ImpactGroups, type IndependenceCheckParams, type IndependenceResult, type IngestResult, type Intent, IntentClassifier, JiraConnector, KnowledgeDocMaterializer, KnowledgeIngestor, type KnowledgePipelineOptions, type KnowledgePipelineResult, KnowledgePipelineRunner, type KnowledgeSnapshot, type KnowledgeSnapshotEntry, KnowledgeStagingAggregator, type Language, type LinkResult, type LoadGraphResult, type MaterializeOptions, type MaterializeResult, type MaterializedDoc, MermaidParser, MiroConnector, NODE_STABILITY, NODE_TYPES, type NodeCategory, type NodeQuery, type NodeType, OBSERVABILITY_TYPES, type OverlapDetail, PackedSummaryCache, type PairResult, PlantUmlParser, type ProbabilityStrategy, type ProjectionSpec, type RequirementCoverage, RequirementIngestor, type ResolvedEntity, ResponseFormatter, type SignalExtractor, type SkippedEntry, SlackConnector, type SourceLocation, type StagedEntry, type StatisticalOutlier, StructuralDriftDetector, SyncManager, type SyncMetadata, type TaskDefinition, TaskIndependenceAnalyzer, TestDescriptionExtractor, TopologicalLinker, type TraceabilityOptions, type TraceabilityResult, type TracedFile, VERSION, ValidationRuleExtractor, type VectorSearchResult, VectorStore, askGraph, classifyNodeCategory, createExtractionRunner, detectLanguage, groupNodesByImpact, inferDomain, linkToCode, loadGraph, normalizeIntent, project, queryTraceability, saveGraph };
package/dist/index.js CHANGED
@@ -45,6 +45,8 @@ __export(index_exports, {
45
45
  ContradictionDetector: () => ContradictionDetector,
46
46
  CoverageScorer: () => CoverageScorer,
47
47
  D2Parser: () => D2Parser,
48
+ DEFAULT_BLOCKLIST: () => DEFAULT_BLOCKLIST,
49
+ DEFAULT_PATTERNS: () => DEFAULT_PATTERNS,
48
50
  DecisionIngestor: () => DecisionIngestor,
49
51
  DesignConstraintAdapter: () => DesignConstraintAdapter,
50
52
  DesignIngestor: () => DesignIngestor,
@@ -97,6 +99,7 @@ __export(index_exports, {
97
99
  createExtractionRunner: () => createExtractionRunner,
98
100
  detectLanguage: () => detectLanguage,
99
101
  groupNodesByImpact: () => groupNodesByImpact,
102
+ inferDomain: () => inferDomain,
100
103
  linkToCode: () => linkToCode,
101
104
  loadGraph: () => loadGraph,
102
105
  normalizeIntent: () => normalizeIntent,
@@ -2496,6 +2499,88 @@ var RequirementIngestor = class {
2496
2499
  }
2497
2500
  };
2498
2501
 
2502
+ // src/ingest/domain-inference.ts
2503
+ var DEFAULT_PATTERNS = [
2504
+ "packages/<dir>",
2505
+ "apps/<dir>",
2506
+ "services/<dir>",
2507
+ "src/<dir>",
2508
+ "lib/<dir>"
2509
+ ];
2510
+ var DEFAULT_BLOCKLIST = /* @__PURE__ */ new Set([
2511
+ "node_modules",
2512
+ ".harness",
2513
+ "dist",
2514
+ "build",
2515
+ ".git",
2516
+ "coverage",
2517
+ ".next",
2518
+ ".turbo",
2519
+ ".cache",
2520
+ "out",
2521
+ "tmp"
2522
+ ]);
2523
+ var CODE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
2524
+ function matchPattern(filePath, pattern) {
2525
+ const patternParts = pattern.split("/").filter((s) => s.length > 0);
2526
+ if (patternParts.length !== 2 || patternParts[1] !== "<dir>") {
2527
+ return null;
2528
+ }
2529
+ const prefix = patternParts[0];
2530
+ const pathParts = filePath.split("/").filter((s) => s.length > 0);
2531
+ if (pathParts.length < 2) return null;
2532
+ if (pathParts[0] !== prefix) return null;
2533
+ let dir = pathParts[1];
2534
+ if (dir.length === 0) return null;
2535
+ if (CODE_EXTENSIONS.some((ext) => dir.endsWith(ext))) {
2536
+ const dotIdx = dir.lastIndexOf(".");
2537
+ if (dotIdx > 0) dir = dir.slice(0, dotIdx);
2538
+ }
2539
+ if (dir.length === 0) return null;
2540
+ return dir;
2541
+ }
2542
+ function inferDomain(node, options = {}) {
2543
+ if (node.metadata?.domain && typeof node.metadata.domain === "string" && node.metadata.domain.length > 0) {
2544
+ return node.metadata.domain;
2545
+ }
2546
+ const filePath = typeof node.path === "string" ? node.path : "";
2547
+ const blocklist = new Set(DEFAULT_BLOCKLIST);
2548
+ if (options.extraBlocklist) {
2549
+ for (const seg of options.extraBlocklist) {
2550
+ if (seg && seg.length > 0) blocklist.add(seg);
2551
+ }
2552
+ }
2553
+ if (filePath.length > 0) {
2554
+ const extraPatterns = options.extraPatterns ?? [];
2555
+ for (const pattern of extraPatterns) {
2556
+ const dir = matchPattern(filePath, pattern);
2557
+ if (dir !== null) {
2558
+ if (blocklist.has(dir)) return "unknown";
2559
+ return dir;
2560
+ }
2561
+ }
2562
+ for (const pattern of DEFAULT_PATTERNS) {
2563
+ const dir = matchPattern(filePath, pattern);
2564
+ if (dir !== null) {
2565
+ if (blocklist.has(dir)) return "unknown";
2566
+ return dir;
2567
+ }
2568
+ }
2569
+ const segments = filePath.split("/").filter((s) => s.length > 0);
2570
+ if (segments.length > 0) {
2571
+ const first = segments[0];
2572
+ if (!blocklist.has(first)) return first;
2573
+ }
2574
+ }
2575
+ const source = node.metadata?.source;
2576
+ if (source === "knowledge-linker" || source === "connector") {
2577
+ const connector = node.metadata?.connectorName;
2578
+ if (typeof connector === "string" && connector.length > 0) return connector;
2579
+ return "general";
2580
+ }
2581
+ return "unknown";
2582
+ }
2583
+
2499
2584
  // src/ingest/KnowledgePipelineRunner.ts
2500
2585
  var fs11 = __toESM(require("fs/promises"));
2501
2586
  var path12 = __toESM(require("path"));
@@ -3308,10 +3393,12 @@ var BUSINESS_NODE_TYPES = [
3308
3393
  "business_fact"
3309
3394
  ];
3310
3395
  var KnowledgeStagingAggregator = class {
3311
- constructor(projectDir) {
3396
+ constructor(projectDir, inferenceOptions = {}) {
3312
3397
  this.projectDir = projectDir;
3398
+ this.inferenceOptions = inferenceOptions;
3313
3399
  }
3314
3400
  projectDir;
3401
+ inferenceOptions;
3315
3402
  async aggregate(extractorResults, linkerResults, diagramResults) {
3316
3403
  const all = [...extractorResults, ...linkerResults, ...diagramResults];
3317
3404
  const byHash = /* @__PURE__ */ new Map();
@@ -3380,7 +3467,7 @@ var KnowledgeStagingAggregator = class {
3380
3467
  for (const nodeType of BUSINESS_NODE_TYPES) {
3381
3468
  const nodes = store.findNodes({ type: nodeType });
3382
3469
  for (const node of nodes) {
3383
- const domain = node.metadata?.domain ?? "unknown";
3470
+ const domain = inferDomain(node, this.inferenceOptions);
3384
3471
  const list = extractedByDomain.get(domain) ?? [];
3385
3472
  list.push(node);
3386
3473
  extractedByDomain.set(domain, list);
@@ -5058,10 +5145,10 @@ function toGrade(score) {
5058
5145
  if (score >= 20) return "D";
5059
5146
  return "F";
5060
5147
  }
5061
- function groupByDomain(nodes, fallback) {
5148
+ function groupByDomain(nodes, _fallback, options = {}) {
5062
5149
  const map = /* @__PURE__ */ new Map();
5063
5150
  for (const node of nodes) {
5064
- const domain = node.metadata.domain ?? fallback(node);
5151
+ const domain = inferDomain(node, options);
5065
5152
  const group = map.get(domain) ?? [];
5066
5153
  group.push(node);
5067
5154
  map.set(domain, group);
@@ -5117,11 +5204,15 @@ function scoreDomain(domain, knEntries, codeEntries, store) {
5117
5204
  };
5118
5205
  }
5119
5206
  var CoverageScorer = class {
5207
+ constructor(inferenceOptions = {}) {
5208
+ this.inferenceOptions = inferenceOptions;
5209
+ }
5210
+ inferenceOptions;
5120
5211
  score(store) {
5121
5212
  const knowledgeNodes = KNOWLEDGE_TYPES.flatMap((t) => store.findNodes({ type: t }));
5122
- const domainMap = groupByDomain(knowledgeNodes, () => "unclassified");
5213
+ const domainMap = groupByDomain(knowledgeNodes, void 0, this.inferenceOptions);
5123
5214
  const codeNodes = CODE_TYPES2.flatMap((t) => store.findNodes({ type: t }));
5124
- const codeDomains = groupByDomain(codeNodes, (n) => this.domainFromPath(n.path));
5215
+ const codeDomains = groupByDomain(codeNodes, void 0, this.inferenceOptions);
5125
5216
  const allDomains = /* @__PURE__ */ new Set([...domainMap.keys(), ...codeDomains.keys()]);
5126
5217
  const domains = [];
5127
5218
  for (const domain of allDomains) {
@@ -5137,15 +5228,6 @@ var CoverageScorer = class {
5137
5228
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
5138
5229
  };
5139
5230
  }
5140
- domainFromPath(filePath) {
5141
- if (!filePath) return "unclassified";
5142
- const parts = filePath.split("/");
5143
- const pkgIdx = parts.indexOf("packages");
5144
- if (pkgIdx >= 0 && parts[pkgIdx + 1]) return parts[pkgIdx + 1];
5145
- const srcIdx = parts.indexOf("src");
5146
- if (srcIdx >= 0 && parts[srcIdx + 1]) return parts[srcIdx + 1];
5147
- return parts[0] ?? "unclassified";
5148
- }
5149
5231
  };
5150
5232
 
5151
5233
  // src/ingest/KnowledgeDocMaterializer.ts
@@ -5161,10 +5243,12 @@ var VALID_BUSINESS_TYPES = /* @__PURE__ */ new Set([
5161
5243
  var DEFAULT_MAX_DOCS = 50;
5162
5244
  var MAX_COLLISION_SUFFIX = 10;
5163
5245
  var KnowledgeDocMaterializer = class {
5164
- constructor(store) {
5246
+ constructor(store, inferenceOptions = {}) {
5165
5247
  this.store = store;
5248
+ this.inferenceOptions = inferenceOptions;
5166
5249
  }
5167
5250
  store;
5251
+ inferenceOptions;
5168
5252
  async materialize(gapEntries, options) {
5169
5253
  const maxDocs = options.maxDocs ?? DEFAULT_MAX_DOCS;
5170
5254
  const created = [];
@@ -5220,21 +5304,8 @@ var KnowledgeDocMaterializer = class {
5220
5304
  return { node, domain, domainDir, nameKey };
5221
5305
  }
5222
5306
  inferDomain(node) {
5223
- if (node.metadata?.domain && typeof node.metadata.domain === "string") {
5224
- return node.metadata.domain;
5225
- }
5226
- if (node.path) {
5227
- const pkgMatch = node.path.match(/^packages\/([^/]+)/);
5228
- if (pkgMatch) return pkgMatch[1];
5229
- const srcMatch = node.path.match(/^src\/([^/]+)/);
5230
- if (srcMatch) return srcMatch[1];
5231
- }
5232
- if (node.metadata?.source === "knowledge-linker" || node.metadata?.source === "connector") {
5233
- const connector = node.metadata.connectorName;
5234
- if (typeof connector === "string") return connector;
5235
- return "general";
5236
- }
5237
- return null;
5307
+ const result = inferDomain(node, this.inferenceOptions);
5308
+ return result === "unknown" ? null : result;
5238
5309
  }
5239
5310
  generateFilename(name) {
5240
5311
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
@@ -5328,7 +5399,10 @@ var KnowledgePipelineRunner = class {
5328
5399
  this.store = store;
5329
5400
  }
5330
5401
  store;
5402
+ /** Resolved per-`run()` inference options. Set on entry to `run()`. */
5403
+ inferenceOptions = {};
5331
5404
  async run(options) {
5405
+ this.inferenceOptions = options.inferenceOptions ?? {};
5332
5406
  const remediations = [];
5333
5407
  const preSnapshot = this.buildSnapshot(options.domain);
5334
5408
  const extraction = await this.extract(options);
@@ -5336,7 +5410,7 @@ var KnowledgePipelineRunner = class {
5336
5410
  let driftResult = this.reconcile(preSnapshot, postSnapshot);
5337
5411
  const contradictions = new ContradictionDetector().detect(this.store);
5338
5412
  let gapReport = await this.detect(options);
5339
- const coverage = new CoverageScorer().score(this.store);
5413
+ const coverage = new CoverageScorer(this.inferenceOptions).score(this.store);
5340
5414
  let materialization;
5341
5415
  let iterations = 1;
5342
5416
  if (options.fix) {
@@ -5499,7 +5573,7 @@ var KnowledgePipelineRunner = class {
5499
5573
  // ── Phase 3: DETECT ───────────────────────────────────────────────────────
5500
5574
  async detect(options) {
5501
5575
  const knowledgeDir = path12.join(options.projectDir, "docs", "knowledge");
5502
- const aggregator = new KnowledgeStagingAggregator(options.projectDir);
5576
+ const aggregator = new KnowledgeStagingAggregator(options.projectDir, this.inferenceOptions);
5503
5577
  const gapReport = await aggregator.generateGapReport(knowledgeDir, this.store);
5504
5578
  await aggregator.writeGapReport(gapReport);
5505
5579
  return gapReport;
@@ -5527,7 +5601,7 @@ var KnowledgePipelineRunner = class {
5527
5601
  const allGapEntries = gapReport.domains.flatMap((d) => d.gapEntries);
5528
5602
  const materializable = allGapEntries.filter((e) => e.hasContent);
5529
5603
  if (materializable.length > 0) {
5530
- const materializer = new KnowledgeDocMaterializer(this.store);
5604
+ const materializer = new KnowledgeDocMaterializer(this.store, this.inferenceOptions);
5531
5605
  const matResult = await materializer.materialize(materializable, {
5532
5606
  projectDir: options.projectDir,
5533
5607
  dryRun: false
@@ -5553,7 +5627,7 @@ var KnowledgePipelineRunner = class {
5553
5627
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
5554
5628
  }));
5555
5629
  if (stagedEntries.length > 0) {
5556
- const aggregator = new KnowledgeStagingAggregator(options.projectDir);
5630
+ const aggregator = new KnowledgeStagingAggregator(options.projectDir, this.inferenceOptions);
5557
5631
  await aggregator.aggregate(stagedEntries, [], []);
5558
5632
  }
5559
5633
  }
@@ -9527,6 +9601,8 @@ var VERSION = "0.6.0";
9527
9601
  ContradictionDetector,
9528
9602
  CoverageScorer,
9529
9603
  D2Parser,
9604
+ DEFAULT_BLOCKLIST,
9605
+ DEFAULT_PATTERNS,
9530
9606
  DecisionIngestor,
9531
9607
  DesignConstraintAdapter,
9532
9608
  DesignIngestor,
@@ -9579,6 +9655,7 @@ var VERSION = "0.6.0";
9579
9655
  createExtractionRunner,
9580
9656
  detectLanguage,
9581
9657
  groupNodesByImpact,
9658
+ inferDomain,
9582
9659
  linkToCode,
9583
9660
  loadGraph,
9584
9661
  normalizeIntent,
package/dist/index.mjs CHANGED
@@ -2388,6 +2388,88 @@ var RequirementIngestor = class {
2388
2388
  }
2389
2389
  };
2390
2390
 
2391
+ // src/ingest/domain-inference.ts
2392
+ var DEFAULT_PATTERNS = [
2393
+ "packages/<dir>",
2394
+ "apps/<dir>",
2395
+ "services/<dir>",
2396
+ "src/<dir>",
2397
+ "lib/<dir>"
2398
+ ];
2399
+ var DEFAULT_BLOCKLIST = /* @__PURE__ */ new Set([
2400
+ "node_modules",
2401
+ ".harness",
2402
+ "dist",
2403
+ "build",
2404
+ ".git",
2405
+ "coverage",
2406
+ ".next",
2407
+ ".turbo",
2408
+ ".cache",
2409
+ "out",
2410
+ "tmp"
2411
+ ]);
2412
+ var CODE_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
2413
+ function matchPattern(filePath, pattern) {
2414
+ const patternParts = pattern.split("/").filter((s) => s.length > 0);
2415
+ if (patternParts.length !== 2 || patternParts[1] !== "<dir>") {
2416
+ return null;
2417
+ }
2418
+ const prefix = patternParts[0];
2419
+ const pathParts = filePath.split("/").filter((s) => s.length > 0);
2420
+ if (pathParts.length < 2) return null;
2421
+ if (pathParts[0] !== prefix) return null;
2422
+ let dir = pathParts[1];
2423
+ if (dir.length === 0) return null;
2424
+ if (CODE_EXTENSIONS.some((ext) => dir.endsWith(ext))) {
2425
+ const dotIdx = dir.lastIndexOf(".");
2426
+ if (dotIdx > 0) dir = dir.slice(0, dotIdx);
2427
+ }
2428
+ if (dir.length === 0) return null;
2429
+ return dir;
2430
+ }
2431
+ function inferDomain(node, options = {}) {
2432
+ if (node.metadata?.domain && typeof node.metadata.domain === "string" && node.metadata.domain.length > 0) {
2433
+ return node.metadata.domain;
2434
+ }
2435
+ const filePath = typeof node.path === "string" ? node.path : "";
2436
+ const blocklist = new Set(DEFAULT_BLOCKLIST);
2437
+ if (options.extraBlocklist) {
2438
+ for (const seg of options.extraBlocklist) {
2439
+ if (seg && seg.length > 0) blocklist.add(seg);
2440
+ }
2441
+ }
2442
+ if (filePath.length > 0) {
2443
+ const extraPatterns = options.extraPatterns ?? [];
2444
+ for (const pattern of extraPatterns) {
2445
+ const dir = matchPattern(filePath, pattern);
2446
+ if (dir !== null) {
2447
+ if (blocklist.has(dir)) return "unknown";
2448
+ return dir;
2449
+ }
2450
+ }
2451
+ for (const pattern of DEFAULT_PATTERNS) {
2452
+ const dir = matchPattern(filePath, pattern);
2453
+ if (dir !== null) {
2454
+ if (blocklist.has(dir)) return "unknown";
2455
+ return dir;
2456
+ }
2457
+ }
2458
+ const segments = filePath.split("/").filter((s) => s.length > 0);
2459
+ if (segments.length > 0) {
2460
+ const first = segments[0];
2461
+ if (!blocklist.has(first)) return first;
2462
+ }
2463
+ }
2464
+ const source = node.metadata?.source;
2465
+ if (source === "knowledge-linker" || source === "connector") {
2466
+ const connector = node.metadata?.connectorName;
2467
+ if (typeof connector === "string" && connector.length > 0) return connector;
2468
+ return "general";
2469
+ }
2470
+ return "unknown";
2471
+ }
2472
+
2391
2473
  // src/ingest/KnowledgePipelineRunner.ts
2392
2474
  import * as fs11 from "fs/promises";
2393
2475
  import * as path12 from "path";
@@ -3200,10 +3282,12 @@ var BUSINESS_NODE_TYPES = [
3200
3282
  "business_fact"
3201
3283
  ];
3202
3284
  var KnowledgeStagingAggregator = class {
3203
- constructor(projectDir) {
3285
+ constructor(projectDir, inferenceOptions = {}) {
3204
3286
  this.projectDir = projectDir;
3287
+ this.inferenceOptions = inferenceOptions;
3205
3288
  }
3206
3289
  projectDir;
3290
+ inferenceOptions;
3207
3291
  async aggregate(extractorResults, linkerResults, diagramResults) {
3208
3292
  const all = [...extractorResults, ...linkerResults, ...diagramResults];
3209
3293
  const byHash = /* @__PURE__ */ new Map();
@@ -3272,7 +3356,7 @@ var KnowledgeStagingAggregator = class {
3272
3356
  for (const nodeType of BUSINESS_NODE_TYPES) {
3273
3357
  const nodes = store.findNodes({ type: nodeType });
3274
3358
  for (const node of nodes) {
3275
- const domain = node.metadata?.domain ?? "unknown";
3359
+ const domain = inferDomain(node, this.inferenceOptions);
3276
3360
  const list = extractedByDomain.get(domain) ?? [];
3277
3361
  list.push(node);
3278
3362
  extractedByDomain.set(domain, list);
@@ -4950,10 +5034,10 @@ function toGrade(score) {
4950
5034
  if (score >= 20) return "D";
4951
5035
  return "F";
4952
5036
  }
4953
- function groupByDomain(nodes, fallback) {
5037
+ function groupByDomain(nodes, _fallback, options = {}) {
4954
5038
  const map = /* @__PURE__ */ new Map();
4955
5039
  for (const node of nodes) {
4956
- const domain = node.metadata.domain ?? fallback(node);
5040
+ const domain = inferDomain(node, options);
4957
5041
  const group = map.get(domain) ?? [];
4958
5042
  group.push(node);
4959
5043
  map.set(domain, group);
@@ -5009,11 +5093,15 @@ function scoreDomain(domain, knEntries, codeEntries, store) {
5009
5093
  };
5010
5094
  }
5011
5095
  var CoverageScorer = class {
5096
+ constructor(inferenceOptions = {}) {
5097
+ this.inferenceOptions = inferenceOptions;
5098
+ }
5099
+ inferenceOptions;
5012
5100
  score(store) {
5013
5101
  const knowledgeNodes = KNOWLEDGE_TYPES.flatMap((t) => store.findNodes({ type: t }));
5014
- const domainMap = groupByDomain(knowledgeNodes, () => "unclassified");
5102
+ const domainMap = groupByDomain(knowledgeNodes, void 0, this.inferenceOptions);
5015
5103
  const codeNodes = CODE_TYPES2.flatMap((t) => store.findNodes({ type: t }));
5016
- const codeDomains = groupByDomain(codeNodes, (n) => this.domainFromPath(n.path));
5104
+ const codeDomains = groupByDomain(codeNodes, void 0, this.inferenceOptions);
5017
5105
  const allDomains = /* @__PURE__ */ new Set([...domainMap.keys(), ...codeDomains.keys()]);
5018
5106
  const domains = [];
5019
5107
  for (const domain of allDomains) {
@@ -5029,15 +5117,6 @@ var CoverageScorer = class {
5029
5117
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
5030
5118
  };
5031
5119
  }
5032
- domainFromPath(filePath) {
5033
- if (!filePath) return "unclassified";
5034
- const parts = filePath.split("/");
5035
- const pkgIdx = parts.indexOf("packages");
5036
- if (pkgIdx >= 0 && parts[pkgIdx + 1]) return parts[pkgIdx + 1];
5037
- const srcIdx = parts.indexOf("src");
5038
- if (srcIdx >= 0 && parts[srcIdx + 1]) return parts[srcIdx + 1];
5039
- return parts[0] ?? "unclassified";
5040
- }
5041
5120
  };
5042
5121
 
5043
5122
  // src/ingest/KnowledgeDocMaterializer.ts
@@ -5053,10 +5132,12 @@ var VALID_BUSINESS_TYPES = /* @__PURE__ */ new Set([
5053
5132
  var DEFAULT_MAX_DOCS = 50;
5054
5133
  var MAX_COLLISION_SUFFIX = 10;
5055
5134
  var KnowledgeDocMaterializer = class {
5056
- constructor(store) {
5135
+ constructor(store, inferenceOptions = {}) {
5057
5136
  this.store = store;
5137
+ this.inferenceOptions = inferenceOptions;
5058
5138
  }
5059
5139
  store;
5140
+ inferenceOptions;
5060
5141
  async materialize(gapEntries, options) {
5061
5142
  const maxDocs = options.maxDocs ?? DEFAULT_MAX_DOCS;
5062
5143
  const created = [];
@@ -5112,21 +5193,8 @@ var KnowledgeDocMaterializer = class {
5112
5193
  return { node, domain, domainDir, nameKey };
5113
5194
  }
5114
5195
  inferDomain(node) {
5115
- if (node.metadata?.domain && typeof node.metadata.domain === "string") {
5116
- return node.metadata.domain;
5117
- }
5118
- if (node.path) {
5119
- const pkgMatch = node.path.match(/^packages\/([^/]+)/);
5120
- if (pkgMatch) return pkgMatch[1];
5121
- const srcMatch = node.path.match(/^src\/([^/]+)/);
5122
- if (srcMatch) return srcMatch[1];
5123
- }
5124
- if (node.metadata?.source === "knowledge-linker" || node.metadata?.source === "connector") {
5125
- const connector = node.metadata.connectorName;
5126
- if (typeof connector === "string") return connector;
5127
- return "general";
5128
- }
5129
- return null;
5196
+ const result = inferDomain(node, this.inferenceOptions);
5197
+ return result === "unknown" ? null : result;
5130
5198
  }
5131
5199
  generateFilename(name) {
5132
5200
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 60);
@@ -5220,7 +5288,10 @@ var KnowledgePipelineRunner = class {
5220
5288
  this.store = store;
5221
5289
  }
5222
5290
  store;
5291
+ /** Resolved per-`run()` inference options. Set on entry to `run()`. */
5292
+ inferenceOptions = {};
5223
5293
  async run(options) {
5294
+ this.inferenceOptions = options.inferenceOptions ?? {};
5224
5295
  const remediations = [];
5225
5296
  const preSnapshot = this.buildSnapshot(options.domain);
5226
5297
  const extraction = await this.extract(options);
@@ -5228,7 +5299,7 @@ var KnowledgePipelineRunner = class {
5228
5299
  let driftResult = this.reconcile(preSnapshot, postSnapshot);
5229
5300
  const contradictions = new ContradictionDetector().detect(this.store);
5230
5301
  let gapReport = await this.detect(options);
5231
- const coverage = new CoverageScorer().score(this.store);
5302
+ const coverage = new CoverageScorer(this.inferenceOptions).score(this.store);
5232
5303
  let materialization;
5233
5304
  let iterations = 1;
5234
5305
  if (options.fix) {
@@ -5391,7 +5462,7 @@ var KnowledgePipelineRunner = class {
5391
5462
  // ── Phase 3: DETECT ───────────────────────────────────────────────────────
5392
5463
  async detect(options) {
5393
5464
  const knowledgeDir = path12.join(options.projectDir, "docs", "knowledge");
5394
- const aggregator = new KnowledgeStagingAggregator(options.projectDir);
5465
+ const aggregator = new KnowledgeStagingAggregator(options.projectDir, this.inferenceOptions);
5395
5466
  const gapReport = await aggregator.generateGapReport(knowledgeDir, this.store);
5396
5467
  await aggregator.writeGapReport(gapReport);
5397
5468
  return gapReport;
@@ -5419,7 +5490,7 @@ var KnowledgePipelineRunner = class {
5419
5490
  const allGapEntries = gapReport.domains.flatMap((d) => d.gapEntries);
5420
5491
  const materializable = allGapEntries.filter((e) => e.hasContent);
5421
5492
  if (materializable.length > 0) {
5422
- const materializer = new KnowledgeDocMaterializer(this.store);
5493
+ const materializer = new KnowledgeDocMaterializer(this.store, this.inferenceOptions);
5423
5494
  const matResult = await materializer.materialize(materializable, {
5424
5495
  projectDir: options.projectDir,
5425
5496
  dryRun: false
@@ -5445,7 +5516,7 @@ var KnowledgePipelineRunner = class {
5445
5516
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
5446
5517
  }));
5447
5518
  if (stagedEntries.length > 0) {
5448
- const aggregator = new KnowledgeStagingAggregator(options.projectDir);
5519
+ const aggregator = new KnowledgeStagingAggregator(options.projectDir, this.inferenceOptions);
5449
5520
  await aggregator.aggregate(stagedEntries, [], []);
5450
5521
  }
5451
5522
  }
@@ -9418,6 +9489,8 @@ export {
9418
9489
  ContradictionDetector,
9419
9490
  CoverageScorer,
9420
9491
  D2Parser,
9492
+ DEFAULT_BLOCKLIST,
9493
+ DEFAULT_PATTERNS,
9421
9494
  DecisionIngestor,
9422
9495
  DesignConstraintAdapter,
9423
9496
  DesignIngestor,
@@ -9470,6 +9543,7 @@ export {
9470
9543
  createExtractionRunner,
9471
9544
  detectLanguage,
9472
9545
  groupNodesByImpact,
9546
+ inferDomain,
9473
9547
  linkToCode,
9474
9548
  loadGraph,
9475
9549
  normalizeIntent,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harness-engineering/graph",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "license": "MIT",
5
5
  "description": "Knowledge graph for context assembly in Harness Engineering",
6
6
  "main": "./dist/index.js",