/**
 * AnalysisResult cache — the cross-process persistence layer for the
 * canonical analysis envelope.
 *
 * Two layers of caching:
 *
 *   1. **In-memory** (`Map<cacheKey, Promise<AnalysisResult>>`).
 *      Dedupes concurrent calls within one process. Survives across
 *      subcommands that share a Node process; cleared on process exit.
 *
 *   2. **On-disk JSON** under `<cwd>/.dxkit/cache/`. Persists across
 *      processes so a second subcommand minutes later can skip the
 *      gather entirely. Keyed by short commit SHA.
 *
 * Invalidation triggers (any one forces a rebuild + overwrites the
 * cached file):
 *
 *   - Commit SHA differs from the cached file's `commitSha`.
 *   - `.dxkit-ignore` mtime differs (changes affect what gets scanned).
 *   - Cached file's `dxkitVersion` differs from the running version
 *     (new tools or scoring formulas can change metrics).
 *   - Cached file's `schemaVersion` differs from
 *     `ANALYSIS_RESULT_SCHEMA_VERSION` (incompatible envelope shape).
 *   - Caller passes `rescan: true`.
 *
 * Dirty-tree behavior:
 *
 *   Working-tree-dirty results are NEVER persisted to disk and are
 *   NOT read back from disk. The commit SHA doesn't reflect the on-
 *   disk state, so a disk cache keyed by SHA would alias two genuinely-
 *   different states. In-memory caching still applies, so multiple
 *   subcommands within one process share the rebuild without thrashing.
 *
 * The cache module never invokes a gather itself. Callers supply a
 * `build` function returning `AnalysisResultBody`; the module stamps
 * provenance and handles persistence. This keeps the gather pipeline
 * decoupled from the cache layer and makes both unit-testable in
 * isolation.
 */
import { type AnalysisResult, type AnalysisResultBody } from '../analysis-result';
/**
 * Provenance fields the cache resolves before deciding hit vs miss.
 * Separate from `AnalysisResult` so the cache can compute it without
 * a build, then compare against the cached file's persisted shape.
 */
export interface ResolvedProvenance {
    commitSha: string;
    branch: string;
    cwd: string;
    dxkitVersion: string;
    ignoreFileMtime: number | null;
    workingTreeDirty: boolean;
}
/**
 * Builder contract. The cache calls this when it needs to (re)build
 * the body. Implementations live alongside the consumers that
 * orchestrate the gather pipeline (`analyzeHealthInternal` and
 * friends).
 */
export type AnalysisResultBuilder = (cwd: string) => Promise<AnalysisResultBody>;
export interface ReadOrBuildOptions {
    /** Force a rebuild even on cache hit. Mirrors the CLI `--rescan` flag. */
    rescan?: boolean;
    /** Override cache directory location. Defaults to `<cwd>/.dxkit/cache`.
     *  Tests use this to isolate cache state in a tmpdir; production
     *  callers should never set it. */
    cacheDir?: string;
    /** Override the provenance resolver. Tests use this to inject SHA /
     *  dirty-flag without spawning git. Production callers should never
     *  set it. */
    resolveProvenance?: (cwd: string) => ResolvedProvenance;
    /** Override the wall-clock used for `builtAt`. Tests use this to
     *  produce deterministic timestamps. Defaults to `new Date()`. */
    now?: () => Date;
}
/**
 * Resolve provenance fields needed to compute the cache key. Reads
 * git state via `git rev-parse` + `git status --porcelain`,
 * `.dxkit-ignore` mtime via `fs.statSync`, and pulls dxkit version
 * from the package constant.
 */
export declare function resolveProvenance(cwd: string): ResolvedProvenance;
/**
 * Main entry. Returns a cached `AnalysisResult` when the cache key
 * still matches, or rebuilds via `build` and persists. Dirty trees
 * bypass disk persistence; the in-memory layer still applies.
 */
export declare function readOrBuildAnalysisResult(args: {
    cwd: string;
    build: AnalysisResultBuilder;
    opts?: ReadOrBuildOptions;
}): Promise<AnalysisResult>;
/** Test seam — drop in-memory dedup state between test cases. */
export declare function clearInMemoryCache(): void;
//# sourceMappingURL=cache.d.ts.map