import type { BaselineCatalogComponent } from "./catalog.js"; import type { BaselineComponentEvidence, BaselineEvidenceLock, BaselineSourceEvidence } from "./schema.js"; /** * Closed reason enum surfaced in the reuse summary (Decision 5). `full` covers * every component whenever `--full` disables reuse outright; the others record * why one component's prior receipt either was or was not carried forward. */ export type BaselineReuseReason = "unchanged" | "content-changed" | "new-component" | "full" | `analyzer-identity-changed:${string}`; export interface BaselineComponentReuseDecision { readonly reuse: boolean; readonly reason: BaselineReuseReason; readonly priorEntry?: BaselineComponentEvidence; } export interface ReuseTally { readonly total: number; readonly reused: number; readonly rescanned: number; } export interface ComponentReuseRecord { readonly componentId: string; readonly decision: BaselineComponentReuseDecision; readonly currentTreeSha256: string; readonly priorTreeSha256?: string; readonly analyzerNames: readonly string[]; } /** * Find the prior evidence for one catalog source, matched by (id, owner, repo) — * deliberately NOT `pinnedSha` (Decision 4). `generate.ts` always vets a source at * its catalog's pinned SHA, so a real content change can only arrive via a pin * rebind; keying reuse on the pin would make every rebind reuse nothing and fail * acceptance bullet 2. */ export declare function findPriorSource(priorLock: Pick | undefined, catalog: { id: string; owner: string; repo: string; }): BaselineSourceEvidence | undefined; /** * Decide whether one component's prior receipt may be reused verbatim. Pure: the * caller supplies the component's CURRENT tree hash (already computed once by * `vetBaselineCatalog` for the rescan path) instead of this function touching the * filesystem itself, so content is never hashed twice and the decision stays * trivially unit-testable. Reuse iff: same id AND same ordered `paths` AND same * `treeSha256` AND the exact same required-analyzer name/version set (Decision 4). */ export declare function decideComponentReuse(input: { priorSource: BaselineSourceEvidence | undefined; component: Pick; currentTreeSha256: string; requiredAnalyzers: readonly string[]; analyzerVersions: Readonly>; full: boolean; }): BaselineComponentReuseDecision; /** * Reconstruct a reused receipt in canonical schema field order so a fully-reused * lock serializes byte-identical to the prior one — `generate.ts`'s `--check` * byte-diff and the migration verdict-stability gate both depend on this. Never * fabricates: every field is copied verbatim from `prior`. */ export declare function spliceReusedComponent(prior: BaselineComponentEvidence): BaselineComponentEvidence; /** * Post-hoc reuse tally for a whole source, derived from the FINAL evidence rather * than from live per-component decisions — this is what lets `generate.ts` report * a cross-catalog TOTAL line without `vetBaselineCatalog` widening its return type. * Sound because reuse always splices the prior entry verbatim: whenever a rescan * happens (content or analyzer identity changed), the fresh receipt provably * differs from the prior one in the very field that changed, so byte-equality to * the prior entry is exactly equivalent to "this component was reused." */ export declare function tallyReuse(priorSource: BaselineSourceEvidence | undefined, evidence: BaselineSourceEvidence, full: boolean): ReuseTally; /** Catalog-scoped reuse summary block (Decision 5): one header line plus one * deterministically-ordered line per component, meant to be emitted through the * existing `progress` hook so every reuse decision is visible in CI logs. */ export declare function formatCatalogReuseSummary(catalog: { id: string; pinnedSha: string; }, records: readonly ComponentReuseRecord[]): string[]; /** Cross-catalog TOTAL line (Decision 5), summed from each source's `tallyReuse`. */ export declare function formatTotalReuseSummary(tallies: readonly ReuseTally[], full: boolean): string;