/** * PR Harvest Orchestrator — ties discovery -> extraction -> generalization -> catalog * into a complete pipeline for mining bug-fix PRs from public GitHub repos. * * PR-sourced rules are validated through the validation harness before promotion. * Fuzzy deduplication via Dice coefficient prevents near-duplicate rules. */ import type { LearnedRule } from '../learned-rules/types.js'; /** Per-repo set of processed PR numbers. */ export type PRProgress = Record; export declare function createPRProgress(): PRProgress; export declare function markPRProcessed(progress: PRProgress, repo: string, prNumber: number): PRProgress; export declare function isPRProcessed(progress: PRProgress, repo: string, prNumber: number): boolean; export declare function getPRProgressStats(progress: PRProgress, repo: string): { processedPRs: number; }; export declare function loadPRProgress(dir: string): Promise; export declare function savePRProgress(dir: string, progress: PRProgress): Promise; /** * Dice coefficient (bigram overlap) for fuzzy string similarity. * Returns a value between 0 (no overlap) and 1 (identical). */ export declare function diceCoefficient(a: string, b: string): number; /** * Find the most similar existing rule by description, if above threshold. */ export declare function findFuzzyDuplicate(existingRules: LearnedRule[], description: string, category: string): LearnedRule | null; export interface PRHarvestConfig { /** List of repos to mine PRs from. */ repoList: Array<{ owner: string; name: string; }>; /** Assay project root where rules go. */ catalogPath: string; /** Where pr-progress.json lives. */ progressDir: string; /** Where run reports go. */ runsDir: string; /** Model name for reporting. */ model: string; /** Max repos to process. */ limit?: number; /** Only scan these repos (owner/name format). */ repoFilter?: string[]; /** Skip already-processed PRs. */ resume?: boolean; /** Max PRs per repo. */ maxPRsPerRepo?: number; /** * Held-out multi-file corpus dir (recall fix-pair cache) for the * corpus over-firing gate. Gate is skipped when unset or empty. */ corpusDir?: string; /** Override the corpus gate's per-file fire cap (default 20). */ corpusMaxFiresPerFile?: number; /** Override the corpus gate's noisy-file cap (default 2). */ corpusMaxNoisyFiles?: number; /** Logging callback. */ onLog?: (msg: string) => void; } export declare function harvestPRs(config: PRHarvestConfig): Promise;