import { ATTRIBUTION_FILENAME, type AttributionRecord } from "./attribution"; import { sidecar, sidecarField } from "./sidecar-server"; // Validate the SHAPE, not just the parse. A half-written sidecar must read as // absent everywhere — the same rule diarization-server.ts's hasDiarization // encodes, and here it matters for a second reason: a malformed file that read // as "present" would also read as a DOWNGRADE guard, and could block the // diarized lane from ever writing a real record. export function coerceAttribution(value: unknown): AttributionRecord | null { const parsed = value as Partial | null; if ( typeof parsed?.videoId === "string" && typeof parsed.generatedAt === "string" && Array.isArray(parsed.speakers) && Array.isArray(parsed.segments) && !!parsed.provenance && typeof parsed.provenance.method === "string" ) { return parsed as AttributionRecord; } return null; } // Compact (one line + "\n"), as it always was. The write is atomic (tmp + // rename), which is what lets loadAttribution treat "parsed but wrong shape" // as a real anomaly rather than the expected state of a file being written. export const attributionSidecar = sidecar( ATTRIBUTION_FILENAME, sidecarField(coerceAttribution), { indent: 0 }, ); export const { path: attributionPath, load: loadAttribution, write: writeAttribution, } = attributionSidecar;