/**
 * DecisionTraceStore — persists policy decisions for forensic replay.
 *
 * Storage:
 *   .omk/runs/<runId>/decisions.jsonl   — DecisionTraceEntry lines
 */
import { appendFileSync, existsSync, mkdirSync, readFileSync, statSync } from "fs";
import { join, dirname } from "path";
export function createDecisionTraceStore(runsDir = ".omk/runs") {
    function ensureDir(dir) {
        if (!existsSync(dir)) {
            mkdirSync(dir, { recursive: true });
        }
    }
    function decisionsPath(runId) {
        return join(runsDir, runId, "decisions.jsonl");
    }
    function record(runId, entry) {
        const full = {
            ...entry,
            at: entry.at ?? new Date().toISOString(),
        };
        const path = decisionsPath(runId);
        ensureDir(dirname(path));
        const MAX_DECISION_TRACE_SIZE = 50 * 1024 * 1024;
        if (existsSync(path)) {
            try {
                const stats = statSync(path);
                if (stats.size > MAX_DECISION_TRACE_SIZE)
                    return;
            }
            catch { /* ignore stat errors */ }
        }
        appendFileSync(path, JSON.stringify(full) + "\n", "utf-8");
    }
    function load(runId) {
        const path = decisionsPath(runId);
        if (!existsSync(path))
            return [];
        const content = readFileSync(path, "utf-8");
        return content
            .trim()
            .split("\n")
            .filter((l) => l.length > 0)
            .map((line) => JSON.parse(line));
    }
    function loadForNode(runId, nodeId) {
        return load(runId).filter((d) => d.nodeId === nodeId);
    }
    function loadForAttempt(runId, attemptId) {
        return load(runId).filter((d) => d.attemptId === attemptId);
    }
    return { record, load, loadForNode, loadForAttempt };
}
