/**
 * audit.ts — append-only NDJSON audit log of every meaningful step.
 *
 * Every write tool, every detective dispatch, every gate failure goes here.
 * The chief-detective trail is what makes the Investigation Bureau auditable
 * (per ADR-002 + agentic-layer-spec sec 5).
 */
import { appendFile, mkdir } from "node:fs/promises";
import path from "node:path";
import { env } from "./env";

const ensured = new Set<string>();

async function ensureDir(p: string): Promise<void> {
  if (ensured.has(p)) return;
  await mkdir(p, { recursive: true });
  ensured.add(p);
}

export interface AuditEvent {
  event: string;
  job_id?: string;
  detective?: string;
  /** Free-form payload — keep keys snake_case. */
  [k: string]: unknown;
}

export async function audit(ev: AuditEvent): Promise<void> {
  const row = { ts: new Date().toISOString(), worker_id: env.WORKER_ID, ...ev };
  const dir = path.dirname(env.AUDIT_LOG);
  try {
    await ensureDir(dir);
    await appendFile(env.AUDIT_LOG, JSON.stringify(row) + "\n", "utf-8");
  } catch (e) {
    // Audit must never break the worker. Log to stderr and move on.
    console.error(`[audit] append failed: ${(e as Error).message}`);
  }
}
