/**
 * SET 88 — LEGIBLE AGENT FAILURE (Andy, 2026-07-27: "why in the fuck this
 * happened"), corrected by SET 88f (Andy, same day: "8 triggers? Don't do any
 * hard fuckin numbers why do you hate the watcher so much").
 *
 * The original defect: three resident agents caught their engine's exception
 * with a bare `} catch {`, incremented a counter that was never reset, and
 * retired permanently at two failures. A run whose watcher died 77 seconds in
 * reported only "retired after repeated failures" — the log could not say what
 * threw, so the cause was undiagnosable from the run's own artifact.
 *
 * My first fix replaced permanent retirement with an exponential skip ladder
 * (1, 2, 4, 8 … triggers). That was the SAME defect in a friendlier costume: a
 * number I invented, deciding on the agent's behalf when it was allowed to
 * speak. SET 78 already settled this — every submission of context to a model
 * gets a full, fresh synthesis, every single time.
 *
 * So there is no skipping here, and no threshold of any kind. Every trigger
 * attempts the engine. A failure is recorded, named in the event line, and the
 * deterministic digest carries that trigger. The cost of an attempt is one
 * failed call; the cost of skipping is blindness, and blindness is what started
 * all of this. This module now only COUNTS and REMEMBERS — it never gates.
 */

export interface AgentHealth {
  /** Consecutive failures. Reset to 0 by any success. Reporting only. */
  consecutiveFailures: number;
  /** Message from the most recent failure — the thing the old code discarded. */
  lastError: string | null;
  /** Every failure this run, for the metrics strip. */
  totalFailures: number;
}

export function createAgentHealth(): AgentHealth {
  return { consecutiveFailures: 0, lastError: null, totalFailures: 0 };
}

/** Anything can be thrown; only a string can be read. */
export function errorMessage(err: unknown): string {
  const raw = err instanceof Error ? err.message : String(err);
  return raw.replace(/\s+/g, ' ').trim().slice(0, 200) || 'unknown error';
}

/** Records a failure. Returns the message for the log. Gates nothing. */
export function noteFailure(h: AgentHealth, err: unknown): string {
  h.consecutiveFailures += 1;
  h.totalFailures += 1;
  h.lastError = errorMessage(err);
  return h.lastError;
}

/** A reading got through: the streak is over. */
export function noteSuccess(h: AgentHealth): void {
  h.consecutiveFailures = 0;
}

/**
 * The detail a repeated failure carries. It reports the streak so a persistent
 * fault is visible at a glance — it does not announce a wait, because there
 * isn't one. The next trigger tries again.
 */
export function failureDetail(h: AgentHealth): string {
  const msg = h.lastError ?? 'unknown error';
  return h.consecutiveFailures > 1
    ? `${msg} (${h.consecutiveFailures} consecutive)`
    : msg;
}
