/**
 * Shared parsing and reference-validation primitives for the learning-loop fact
 * extractors (footguns, lessons, patterns, decisions). Owns the markdown reading,
 * frontmatter parsing, freshness computation, and the evidence-reference checks
 * that flag stale paths, out-of-bounds line numbers, and broken `(search: ...)`
 * anchors.
 *
 * Reference validation is intentionally conservative: ambiguous shorthand (bare
 * source filenames, gitignored task paths, URLs/hostnames) is skipped rather than
 * reported, because a false "stale" finding on a clean checkout erodes trust in the
 * whole audit. The regexes here are the canonical evidence grammar - footgun and
 * lesson extractors must reuse them so the same string is judged identically
 * everywhere. ADR-024 governs the line-number-versus-semantic-anchor policy these
 * checks enforce.
 */
import type { BucketFreshness, ReadonlyFS } from "../../types.js";
/** Strict YYYY-MM-DD format - rejects full ISO 8601 timestamps in `last_reviewed`. */
export declare const ISO_DATE_REGEX: RegExp;
/**
 * Matches file path evidence in multiple formats:
 * - `src/auth.ts` (backtick-wrapped file path)
 * - `src/auth.ts:42` (backtick-wrapped with line number)
 * - `src/auth.ts:42-50` (backtick-wrapped with line range)
 * - (lines 866-880) or (line 52) (prose-style)
 * Line numbers are discouraged per ADR-024; flagged for cleanup when found alongside a semantic anchor.
 * File paths alone remain valid evidence.
 */
export declare const EVIDENCE_PATTERN: RegExp;
/** Regex to extract file paths from backtick-wrapped references (with optional line numbers). */
export declare const FILE_REF_REGEX: RegExp;
/** One markdown file read from a learning-loop directory. */
export interface MarkdownEntry {
    path: string;
    content: string;
}
/** A learning-loop directory with its existence flag and contained markdown entries. */
export interface EntryDir {
    path: string;
    exists: boolean;
    files: MarkdownEntry[];
}
/** Aggregated file-reference validation results for footgun entries. */
export interface FootgunRefSummary {
    staleRefs: string[];
    invalidLineRefs: string[];
    totalRefs: number;
    validRefs: number;
}
/**
 * Decide whether a backtick-wrapped reference names a real file path rather than a
 * URL or hostname (which share the `host:port` shape). Used to gate staleness
 * checks so a `localhost:3000`-style token is never treated as a missing file.
 *
 * @param filePath - candidate reference text with any trailing `:line` already split off
 * @returns true for paths with a slash or a root-level filename extension; false for URLs, hostnames, and bare extensionless names
 */
export declare function isFileRef(filePath: string): boolean;
/**
 * Find learning-loop artifact surfaces that exist on disk but sit outside the
 * configured canonical location - the signal that a project is splitting one
 * concern across two directories. Returns nothing unless a canonical path is
 * actually present, so a project that simply hasn't adopted the surface yet is
 * not flagged. Trailing slashes are normalized before comparison.
 *
 * @param fs - read-only filesystem adapter for the target project
 * @param canonicalPaths - the configured/blessed locations; at least one must exist or the result is empty
 * @param knownPaths - candidate surfaces to test against the canonical set
 * @returns existing non-canonical paths, sorted lexicographically for deterministic output; empty when none compete
 */
export declare function findCompetingArtifactSurfaces(fs: ReadonlyFS, canonicalPaths: string[], knownPaths: string[]): string[];
/**
 * Read a learning-loop location into a stable, sorted set of markdown entries.
 * Handles both config shapes uniformly: a directory (every `.md` except the
 * README.md/INDEX.md metadata files, sorted lexicographically) and a single flat
 * `.md` file (one entry). INDEX.md is generated bucket metadata (`goat-flow index`),
 * not entry content - including it would count phantom legacy entries and force
 * entry frontmatter onto a generated file. The sort is load-bearing - downstream
 * entry ordering and report output must be deterministic across machines, so
 * directory listing order is never trusted.
 *
 * @param fs - read-only filesystem adapter for the target project
 * @param dir - directory path, or a single `.md` file path for flat-file config mode
 * @returns the location with its existence flag and entries; files is empty when the location is absent or unreadable
 */
export declare function listMarkdownEntries(fs: ReadonlyFS, dir: string): EntryDir;
/**
 * Separate a leading `---`-delimited YAML frontmatter block from the markdown body.
 * Recognizes frontmatter only at the very start of the content; a `---` later in
 * the document is left in the body untouched.
 *
 * @param content - raw markdown file content
 * @returns the frontmatter text without its `---` fences (null when there is none) and the remaining body
 */
export declare function parseMarkdownFrontmatter(content: string): {
    frontmatter: string | null;
    body: string;
};
/**
 * Parse simple `key: value` pairs from a YAML frontmatter block.
 * Only handles flat scalar fields (sufficient for goat-flow's single-level frontmatter);
 * nested structures, arrays, and multi-line scalars are intentionally unsupported.
 *
 * @param frontmatter - YAML frontmatter body without the surrounding `---` markers
 * @returns flat key/value fields parsed from the frontmatter block
 */
export declare function parseFrontmatterFields(frontmatter: string): Record<string, string>;
/**
 * Compute days-since-review and a coarse freshness band for a bucket file.
 * Returns `unknown` for missing or non-YYYY-MM-DD values so callers can flag them.
 *
 * @param lastReviewed - ISO date from bucket frontmatter, or null when absent
 * @param now - comparison clock for deterministic tests and reports
 */
export declare function computeFreshness(lastReviewed: string | null, now?: Date): {
    days: number | null;
    band: BucketFreshness["freshnessBand"];
};
/**
 * Count how many times a pattern matches across a string. Pass a global (`/g`)
 * regex - `matchAll` requires it, and without the flag the match count is not what
 * a caller expects.
 *
 * @param content - text to scan
 * @param pattern - global regular expression; non-global patterns will throw under matchAll
 * @returns the total number of non-overlapping matches; 0 when none match
 */
export declare function countMatches(content: string, pattern: RegExp): number;
/**
 * Remove `~~...~~` strikethrough spans before evidence is scanned, so a reference
 * an author has struck through (marked as historical) is not counted as live
 * evidence. Run this first in every reference check; otherwise retired anchors
 * resurface as findings.
 *
 * @param content - markdown that may contain strikethrough spans, including multi-line ones
 * @returns the content with all strikethrough spans removed
 */
export declare function stripStrikethrough(content: string): string;
/**
 * Validate every file reference in one footgun section and tally the result.
 * Reports a path as stale when the file no longer exists, and flags a `file:line`
 * reference when the line is out of bounds, lacks a semantic anchor, or carries a
 * line number made redundant by an anchor (the ADR-024 anchor-over-line-number
 * contract). Strikethrough is stripped first so struck evidence is ignored.
 *
 * @param fs - read-only filesystem adapter used to resolve and line-count referenced files
 * @param content - the footgun section's markdown
 * @returns counts plus the stale-path and invalid-line-reference lists; all empty when every reference is valid
 */
export declare function summarizeFootgunRefs(fs: ReadonlyFS, content: string): FootgunRefSummary;
/**
 * Validate the file references in one lesson or pattern section, sharing the same
 * staleness and ADR-024 line-reference rules as footguns. Lessons cite full
 * project-rooted paths (src/, lib/, docs/, .goat-flow/, ...), so this matches that
 * prefix grammar and skips glob-like or `...`-elided tokens that cannot be resolved
 * to a single file.
 *
 * @param fs - read-only filesystem adapter used to resolve and line-count referenced files
 * @param content - the lesson or pattern section's markdown
 * @returns counts plus the stale-path and invalid-line-reference lists; all empty when every reference is valid
 */
export declare function summarizeLessonRefs(fs: ReadonlyFS, content: string): FootgunRefSummary;
//# sourceMappingURL=learning-loop-common.d.ts.map