import type { DiagnosticsPort } from "../../application/ports/diagnostics-port.ts"; import { projectDiagnosticRecord, safeErrorKind, type DiagnosticRecord, type DiagnosticRecordInput, } from "../../contracts/diagnostics.ts"; import { projectTelemetryEvent } from "../../contracts/telemetry.ts"; import { assertBoundedCapacity } from "../platform/bounded-capacity.ts"; export const noOpDiagnostics: DiagnosticsPort = Object.freeze({ record() {}, }); /** N-11. Documented absolute ceiling for bounded in-memory evidence. */ export const MAX_DIAGNOSTIC_ENTRIES = 10_000; export function createDiagnosticsAdapter( options: Readonly<{ maxEntries?: number; now?: () => number; sink?: (record: DiagnosticRecord) => void; }> = {}, ) { const maxEntries = assertBoundedCapacity( options.maxEntries ?? 100, MAX_DIAGNOSTIC_ENTRIES, "diagnostics maxEntries", ); const entries: DiagnosticRecord[] = []; const droppedReasons = new Map(); function drop(reason: string) { droppedReasons.set(reason, (droppedReasons.get(reason) ?? 0) + 1); } function record(input: DiagnosticRecordInput) { try { const projected = projectDiagnosticRecord(input, options.now); if (!projected.success) { drop(projected.reason); return; } if (entries.length >= maxEntries) { entries.shift(); drop("queue-full"); } entries.push(projected.record); try { options.sink?.(projected.record); } catch { drop("sink-failure"); } } catch { drop("serialization-failure"); } } return Object.freeze({ record, entries: () => structuredClone(entries) as readonly DiagnosticRecord[], dropped: () => Object.freeze(Object.fromEntries(droppedReasons)), }); } type BootSafeContext = Readonly<{ kind?: string; buildId?: string; configSchemaVersion?: string; supportReference?: string; }>; let lastBootEvidence: | Readonly<{ diagnostic: DiagnosticRecord | null; telemetry: Readonly> | null; }> | undefined; export function recordBootFailure( error: unknown, safe: BootSafeContext, now: () => number = Date.now, ) { const errorKind = typeof safe.kind === "string" ? safe.kind : safeErrorKind(error); const attributes = { error_kind: errorKind, build_id: safe.buildId ?? "unknown", config_schema_version: safe.configSchemaVersion ?? "unknown", }; const diagnostic = projectDiagnosticRecord( { level: "error", eventId: "app.boot.failed", context: attributes, }, now, ); const telemetry = projectTelemetryEvent("app.boot.failed", attributes, now); lastBootEvidence = Object.freeze({ diagnostic: diagnostic.success ? diagnostic.record : null, telemetry: telemetry.success ? telemetry.event : null, }); return lastBootEvidence; } export function getLastBootEvidence() { return lastBootEvidence ? structuredClone(lastBootEvidence) : undefined; }