export type KbxExternalDataFreshnessMode = 'strict' | 'stale-while-revalidate' | 'provider-defined' export type KbxExternalDataState = 'fresh' | 'stale' | 'expired' | 'unavailable' export type KbxRawSnapshotRetention = 'none' | 'hash-only' | 'encrypted-raw' export interface KbxExternalDataDatasetDefinition { id: string providerId: string providerOperationId: string canonicalType: string normalizer: string normalizerVersion: string cacheKeyFields: readonly string[] freshness: { mode: KbxExternalDataFreshnessMode freshForSeconds: number | null maxStaleSeconds: number | null backgroundRefresh: boolean requireExplicitServicePolicy?: boolean } snapshot: { rawRetention: KbxRawSnapshotRetention normalizedRetentionDays: number } ui: { sourceLabel: string showProviderObservedAt: boolean showReceivedAt: boolean } } export interface KbxExternalDataProvenance { datasetId: string providerId: string providerOperationId: string sourceLabel: string state: KbxExternalDataState providerObservedAt?: string | null requestedAt: string receivedAt: string ingestedAt: string freshUntil?: string | null usableUntil?: string | null payloadSha256: string normalizerVersion: string cacheHit: boolean refreshInProgress?: boolean warning?: string } export interface KbxExternalDataEnvelope { data: T | null provenance: KbxExternalDataProvenance } export interface KbxExternalDataStatusRow { datasetId: string providerId: string sourceLabel: string state: KbxExternalDataState cacheEntries: number lastReceivedAt?: string | null oldestFreshUntil?: string | null staleEntries: number unavailableEntries: number } export interface KbxExternalDataStatusResponse { items: KbxExternalDataStatusRow[] }