/** * Shared daemon logging and best-effort escalation delivery. * * Split out of `daemon.ts` so the extracted admission module (and any future * extracted concern) can log and escalate without importing the composition * root back — which would be the circular-import failure mode the daemon split * (#571) exists to rule out. `daemon.ts` composes; the leaf modules talk only * to other leaves. */ import { escalationIssueRef } from "./escalate.ts"; import type { Escalation } from "./types.ts"; /** One timestamped line to stderr — the daemon's canonical log sink. */ export function log(msg: string): void { process.stderr.write(`[conductor ${new Date().toISOString()}] ${msg}\n`); } /** A stable one-line rendering of an unknown thrown value. */ export function errText(e: unknown): string { return e instanceof Error ? (e.stack ?? e.message) : String(e); } /** * Best-effort escalation delivery: never let a failed page take down the * pass, and say in the log that it failed. Structural `escalate` only — the * caller's full dep object satisfies it without importing anything back. */ export async function safeEscalate( d: { escalate(e: Escalation): Promise }, e: Escalation, ): Promise { try { await d.escalate(e); return true; } catch (err) { log(`escalation for ${escalationIssueRef(e.issue)} could not be delivered: ${errText(err)}`); return false; } }