import type { AssetCatalogEntry, SourceDefinition } from "../../types.js"; import type { SourceSyncState } from "./source-sync.js"; /** * Describes one source's deterministic health and drift state. */ export interface SourceHealthEntry { sourceId: string; kind: SourceDefinition["kind"]; authorityTier: SourceDefinition["authorityTier"]; status: "active" | "dormant" | "never-synced" | "stale" | "broken" | "ambiguous-trust" | "newly-productive"; severity: "ok" | "warning" | "error"; coverageMode: string; syncStatus: string; harvestedEntries: number; indexedEntries: number; selectedEntries: number; rejectedEntries: number; duplicateRate: number; reasons: string[]; suggestedAction: "none" | "review-source" | "refresh-sync" | "disable-or-replace" | "verify-official-owner"; /** True when this report was generated in a CI/automation environment * where the state root is ephemeral and lacks persistent caches. * CI bot workflows use this flag to suppress false-positive dormant * source warnings instead of fragile reason-text matching. */ ciDetected: boolean; /** Structured reason code for the source's health status. * "ephemeral-ci-state-root": the source appears dormant because the * CI runner's state root lacks a persistent GitHub API cache. */ reasonCode?: string; } /** * Describes deterministic source/catalogue health outputs. Aggregate counter * names intentionally use the exact severity vocabulary (`error`, `warning`) * emitted by each source entry so machine and human reports stay in lockstep. */ export interface SourceHealthReport { schemaVersion: number; generatedAt: string; sourceCount: number; errorCount: number; warningCount: number; sources: SourceHealthEntry[]; } /** * Writes source health, drift, and maintenance-candidate reports. */ export declare function writeSourceHealthReports(projectRoot: string, enabledSources: SourceDefinition[], selectedEntries: AssetCatalogEntry[], rejectedEntries: AssetCatalogEntry[], sourceSyncState?: SourceSyncState): Promise; /** * Builds deterministic source/catalogue health from local lifecycle artifacts. */ export declare function buildSourceHealthReport(enabledSources: SourceDefinition[], catalogEntries: AssetCatalogEntry[], selectedEntries: AssetCatalogEntry[], rejectedEntries: AssetCatalogEntry[], sourceSyncState?: SourceSyncState): SourceHealthReport; declare function groupBySource(entries: AssetCatalogEntry[]): Map; declare function computeDuplicateRate(entries: AssetCatalogEntry[]): number; declare function defaultCoverageMode(kind: SourceDefinition["kind"]): string; declare function defaultSyncStatus(kind: SourceDefinition["kind"]): string; /** * Detects whether the given state-root path is ephemeral (CI/temp). * * Checks common temp-directory and CI-runner path patterns. * When the state root is ephemeral, dormant repo sources are expected * (no GitHub API cache) and should not generate bot issues. * * @param stateRoot — absolute path to check; defaults to AGENT_HARNESS_STATE_ROOT * env-var, falling back to process.cwd() at runtime. */ export declare function isEphemeralStateRoot(stateRoot?: string): boolean; /** Exports internals for unit testing. */ export declare const sourceHealthInternals: { readonly groupBySource: typeof groupBySource; readonly computeDuplicateRate: typeof computeDuplicateRate; readonly defaultCoverageMode: typeof defaultCoverageMode; readonly defaultSyncStatus: typeof defaultSyncStatus; readonly isEphemeralStateRoot: typeof isEphemeralStateRoot; }; export {};