/** * Spec 14 R3, R4 — Import Graph, Community Detection, and Martin Metrics * * Builds a file-level import graph from `function_dependencies`, runs Louvain * community detection, computes directory purity vs community structure, and * calculates Martin instability/abstractness metrics. * * IMPORTANT (R4 abstractness gate): The `functions` entity_type column stores * only 'function' and 'component' — NOT type/interface declarations. Abstractness (A) * is computed from `is_exported` rows using a per-file AST scan for export type/interface * declarations. Without this, A = 0 everywhere (dead path). * * All advisory — zero violations. Reports and annotations only. */ import type Database from 'better-sqlite3'; import type { DirectoryPurity, MartinEntry } from '../types.js'; export interface ImportGraph { /** Adjacency: filePath → (neighborFilePath → edgeWeight) */ adjacency: Map>; /** Set of all file paths in the graph */ filePaths: Set; } export interface CommunityResult { /** filePath → community ID */ communities: Map; /** Number of communities detected */ communityCount: number; /** Final modularity score */ modularity: number; } export interface PurityResult { directoryPurities: DirectoryPurity[]; splitCandidates: Array<{ directory: string; communities: number[]; fileCounts: number[]; }>; mergeCandidates: Array<{ directories: string[]; community: number; fileCount: number; }>; agreementScore: number; } /** * Build a file-level import graph by aggregating `function_dependencies` * joined with `functions.file_path`. * * Edge weight = count of distinct dependency symbols between a file pair. */ export declare function buildImportGraph(db: Database.Database): ImportGraph; /** * Populate `graph_cache` with import graph edges. */ export declare function populateImportGraphCache(db: Database.Database): void; /** * Build an import graph from the persistent `graph_cache` table (fast path). */ export declare function buildImportGraphFromCache(db: Database.Database): ImportGraph; /** * Louvain community detection on weighted undirected graph. * * Standard two-phase algorithm: * Phase 1: Greedy modularity optimization (move nodes between communities) * Phase 2: Community aggregation (build super-graph) * Repeat until modularity gain < threshold. */ export declare function detectCommunities(adjacency: Map>, filePaths: Set): CommunityResult; /** * Compute directory purity against detected communities. * * For each directory, compute: share of its files in the plurality community. * Detects split candidates (directories spanning ≥2 communities) and * merge candidates (one community dominating ≥2 directories). */ export declare function computeDirectoryPurity(communities: Map, filePaths: Set): PurityResult; /** * Compute Martin metrics per directory (treated as package). * * Ce = efferent couplings: distinct directories this directory imports from * Ca = afferent couplings: distinct directories that import this directory * I = Ce / (Ca + Ce) — instability (0 if both zero) * A = abstractness: exported type/interface declarations ÷ total exported symbols * D = |A + I − 1| — distance from main sequence * * IMPORTANT: Abstractness computation uses an AST scan for export type/interface * declarations because the `functions` table does not index type/interface entities. * Uses a lightweight file-content scan. */ export declare function computeMartinMetrics(db: Database.Database, importGraph: ImportGraph): MartinEntry[]; //# sourceMappingURL=importGraph.d.ts.map