/**
 * Per-owner realize-context snapshot.
 *
 * Phase 3 of 2026-05-13-VERIFIER-DIAGNOSTIC-TREATMENT-SPLIT.
 *
 * The per-owner emit prompt has TARGET RUNTIME, [PRE-BAKED] step bullets,
 * cross-service operation signatures, available capabilities, library
 * whitelist — everything the LLM needs to emit a real action body. The
 * post-emit feedback runner's `buildLlmReemit` historically had NONE of
 * this; the reemit prompt provided only the previous bad output + the
 * verifier errors.
 *
 * Empirical consequence: sonnet still bridged the gap via inference;
 * smaller models (Ollama qwen3-coder:30b, MarrBox) drifted further from
 * the realize-emit skill's contract, introducing cross-file tsc
 * regressions when asked to fix STUB002 stubs (measured 2026-05-13 at
 * engines 6.54.0 on idle-meta).
 *
 * Phase 3 closes the gap by SNAPSHOTTING the per-owner context to disk
 * at emit time and READING it at reemit time. The snapshot lives at
 * `<outputDir>/.realize-context/<OwnerName>.md` and contains a compact
 * markdown blob — directly embeddable in the reemit user prompt.
 *
 * Decoupling: the snapshot writer (called from per-owner-runner)
 * doesn't know about reemit; the snapshot loader (called from reemit
 * factory) doesn't know about per-owner-emit. They share only the
 * file layout convention.
 */
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
import { dirname, join } from 'path';
const CONTEXT_DIR_NAME = '.realize-context';
/**
 * Render the context as a compact markdown blob suitable for direct
 * embedding in the reemit prompt body. Mirrors the section headings
 * used in the per-owner-emit prompt template so the LLM sees the same
 * structural cues.
 */
export function formatContextSnapshot(ctx) {
    const lines = [];
    lines.push(`# Realize context for owner: ${ctx.ownerName}`);
    lines.push('');
    lines.push(`## TARGET RUNTIME`);
    lines.push(ctx.targetRuntime);
    lines.push('');
    lines.push(`## AVAILABLE SPEC SURFACE`);
    lines.push(ctx.availableSpecSurface);
    lines.push('');
    lines.push(`## AVAILABLE CAPABILITIES`);
    lines.push(ctx.availableCapabilities);
    lines.push('');
    lines.push(`## AVAILABLE CLIENTS`);
    lines.push(ctx.availableClients);
    lines.push('');
    lines.push(`## ACTIONS`);
    lines.push(ctx.perActionScaffolding);
    return lines.join('\n');
}
/** Resolve the per-owner snapshot path. Owner names are
 *  always TypeScript identifiers, so no path-sanitization concerns. */
function snapshotPath(outputDir, ownerName) {
    return join(outputDir, CONTEXT_DIR_NAME, `${ownerName}.md`);
}
/**
 * Persist a context snapshot to disk. Best-effort — caller should
 * never crash on snapshot failure (the reemit prompt degrades to the
 * pre-Phase-3 behavior cleanly).
 */
export function writeContextSnapshot(outputDir, ctx) {
    try {
        const path = snapshotPath(outputDir, ctx.ownerName);
        const dir = dirname(path);
        if (!existsSync(dir))
            mkdirSync(dir, { recursive: true });
        writeFileSync(path, formatContextSnapshot(ctx));
    }
    catch {
        // best-effort; reemit falls back to the Phase 1/2 prompt shape
    }
}
/**
 * Load a previously-written snapshot. Returns the raw markdown blob,
 * or `null` if no snapshot exists for the owner. Callers (the reemit
 * factory) include the blob in the prompt body when present.
 */
export function loadContextSnapshot(outputDir, ownerName) {
    try {
        const path = snapshotPath(outputDir, ownerName);
        if (!existsSync(path))
            return null;
        return readFileSync(path, 'utf8');
    }
    catch {
        return null;
    }
}
//# sourceMappingURL=realize-context-snapshot.js.map