/**
 * WikiCleanupService — detect + remove low-quality pages from a wiki vault.
 *
 * Origin: the 2026-05-27 migration dumped every agent's `memory.json`
 * roleKnowledge entries as their own wiki page (~3,277 pages across 6
 * project vaults). Many are stream-of-consciousness daily memory rather
 * than team-level patterns. Symptom: each project vault has 500+ pages
 * under `patterns/`, most low-quality (confidence < 0.5, verbatim memory
 * dump shape). Karpathy's wiki spec says "frequently-read distilled
 * knowledge" — 500 stream-of-consciousness pages violates that.
 *
 * Detection is **rule-based + mechanical** (OSS does this). The actual
 * keep/delete decision can be deferred to an agent via the bridge —
 * this service exposes both `scan(rules)` (mechanical candidate list)
 * and `apply(pages)` (executes the explicit page list provided).
 *
 * Design rules (mirror WikiMigrateService):
 *  - Default DRY-RUN. Caller must pass `{ apply: true }` to delete.
 *  - Idempotent + reversible. Every deleted page body + frontmatter is
 *    archived to `<vault>/.wiki-cleanup-archive.json` BEFORE the file
 *    is removed. Re-running with the same input is a no-op.
 *  - Migrate manifest is updated so the SAME source entry is not
 *    re-imported by the next `wiki-migrate --apply` (would defeat the
 *    cleanup).
 *  - LEGACY FILES (`memory.json`, `.crewly/knowledge/*`) are NEVER
 *    touched. The cleanup ONLY removes pages from the wiki vault.
 *  - Frozen folders (`memory/`, `sop/`, `sop-overrides/`, `okr/`,
 *    `decisions/manual/`) are never scanned.
 *
 * @module services/wiki/wiki-cleanup.service
 */
export declare const WIKI_CLEANUP_ARCHIVE_FILENAME = ".wiki-cleanup-archive.json";
export declare const WIKI_CLEANUP_ARCHIVE_VERSION = 1;
export interface WikiCleanupRules {
    /** Drop pages whose frontmatter `confidence` is below this. Default 0.5. */
    minConfidence?: number;
    /** Drop pages whose `migrated_from` starts with `agent/`. Default true. */
    dropAgentMemoryDumps?: boolean;
    /**
     * Keep at most N pages per `original_author`. Pages outside the top-N
     * (sorted by confidence desc, then original_date desc) are flagged.
     * Default: 0 (cap disabled).
     */
    maxPerAgent?: number;
}
export interface WikiCleanupCandidate {
    /** Path relative to the vault root (e.g. `llm-curated/patterns/x.md`). */
    relPath: string;
    /** Why this page is a cleanup candidate (one or more rule names). */
    reasons: string[];
    /** Parsed `confidence` (if present in frontmatter), used for ranking. */
    confidence: number | null;
    /** Parsed `original_author` (if present), used by the per-agent cap. */
    originalAuthor: string | null;
    /** Parsed `migrated_from` (if present), used to invalidate manifest entry. */
    migratedFrom: string | null;
    /** Parsed `original_id` (if present), used to invalidate manifest entry. */
    originalId: string | null;
    /** File size in bytes. */
    bytes: number;
}
export interface WikiCleanupScanInput {
    /** Absolute vault path (the dir containing `SCHEMA.md`). */
    vaultPath: string;
    /** Rule overrides; defaults applied for any missing key. */
    rules?: WikiCleanupRules;
}
export interface WikiCleanupScanResult {
    ok: true;
    vaultPath: string;
    /** Pages flagged by at least one rule. Capped at {@link SCAN_HARD_CAP}. */
    candidates: WikiCleanupCandidate[];
    /** Total pages walked (whether candidate or not). */
    scannedCount: number;
    /** Did the scan hit {@link SCAN_HARD_CAP}? */
    truncated: boolean;
    /** Per-reason counts for quick eyeballing. */
    summary: {
        lowConfidence: number;
        agentMemoryDump: number;
        perAgentCapped: number;
    };
}
export interface WikiCleanupApplyInput {
    vaultPath: string;
    /**
     * Explicit list of relative paths to delete. The bridge / agent passes
     * this in after deciding which scan candidates to actually act on. We
     * deliberately do NOT take a rule set here — `apply` is the mechanical
     * deletion step, the decision happened upstream.
     */
    pages: string[];
}
export interface WikiCleanupApplyResult {
    ok: true;
    vaultPath: string;
    /** Pages actually deleted in this run. */
    deleted: string[];
    /** Pages requested but not deleted (missing on disk, already archived, etc). */
    skipped: Array<{
        relPath: string;
        reason: 'not_found' | 'outside_vault' | 'frozen';
    }>;
    archivePath: string;
    /** Migrate manifest entries removed so cleanup-deleted pages don't get re-migrated. */
    manifestEntriesInvalidated: number;
}
export type WikiCleanupOutcome = WikiCleanupScanResult | WikiCleanupApplyResult | {
    ok: false;
    reason: 'invalid_input' | 'vault_missing';
    message: string;
};
export declare class WikiCleanupService {
    private static instance;
    private readonly logger;
    constructor();
    static getInstance(): WikiCleanupService;
    /** Test-only reset. */
    static resetInstance(): void;
    /**
     * Walk the vault's `llm-curated/` tree, parse frontmatter, return all
     * pages matching at least one cleanup rule. Pure read — no writes.
     */
    scan(input: WikiCleanupScanInput): Promise<WikiCleanupOutcome>;
    /**
     * Delete the listed pages from the vault, archive each one (body +
     * frontmatter) to `.wiki-cleanup-archive.json`, and invalidate the
     * corresponding entry in the migrate manifest so the same source can't
     * resurrect the page on the next `wiki-migrate --apply`.
     */
    apply(input: WikiCleanupApplyInput): Promise<WikiCleanupOutcome>;
    private validateVault;
    /**
     * Best-effort safe-rel normalisation. Returns null if the path would
     * resolve outside the vault (`..` traversal etc).
     */
    private normalizeRelPath;
    /**
     * Walk the vault tree, parsing frontmatter on each `.md` file. Skips
     * frozen folders + non-md files. Returns true if the scan was truncated
     * by the hard cap.
     */
    private walkPages;
}
/**
 * Parse `confidence` from frontmatter into a number, or null if absent /
 * unparseable. Accepts both numeric (`0.3`) and string (`"0.3"`) shapes
 * because YAML quoting is inconsistent across older migrated pages.
 */
export declare function parseConfidence(raw: unknown): number | null;
/**
 * Minimal YAML frontmatter parser. Handles the shapes our migrate service
 * emits — `key: value` lines, with optional quotes around values. NOT a
 * general YAML parser. Returns `{}` when no frontmatter is present.
 */
export declare function parseFrontmatter(raw: string): {
    frontmatter: Record<string, unknown>;
    body: string;
};
//# sourceMappingURL=wiki-cleanup.service.d.ts.map