#!/usr/bin/env node
/**
 * seal-log (M7 наблюдаемость печати) — закрывает дыру «провал печати нигде не логируется».
 * Каждая запись плана/спеки порождает строку в ~/.claude/runtime/seal-attempts.jsonl:
 * был ли судья активен, был ли вердикт wired, пыталась ли печать, встала ли, и ПОЧЕМУ нет.
 * Чистый buildSealEntry (детерминирован, тестируется) + best-effort logSealAttempt (I/O).
 */
import { appendFileSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
import { runtimeDir } from './enforce-hook-helpers.mjs';

const SEAL_LOG = 'seal-attempts.jsonl';

/**
 * Чистая сборка записи попытки печати. Печать «пытается» ТОЛЬКО на wired GO; иначе
 * фиксируем причину пропуска (судья не активен / вердикт не wired / NO-GO / провал печати).
 */
export function buildSealEntry({ functionName, judgeActive, wired, decision, sealResult, cause = null, errorType = null, nowMs = null } = {}) {
  const active = judgeActive !== false;          // undefined → считаем активным (по умолчанию)
  const isWired = !!wired;
  const attempted = isWired && decision === 'GO'; // печать положена только на wired GO
  const sealed = !!(sealResult && sealResult.sealed === true);

  let reason = null;
  if (!active) reason = 'судья не активен (no-op, $0)';
  // M7 (2026-06-13): degraded больше не безымянный — причина (no_key / transport_error:<тип>)
  // протекает в reason, чтобы diagnose «почему судья недоступен» без других логов.
  else if (!isWired) reason = `вердикт не wired (судья недоступен/degraded${cause ? `: ${cause}${errorType ? `/${errorType}` : ''}` : ''}) — печать не пыталась`;
  else if (decision === 'NO-GO') reason = 'судья NO-GO — печать не положена';
  else if (sealResult && sealResult.sealed !== true) reason = sealResult.reason ?? 'печать не встала (причина не указана)';

  return {
    kind: 'seal_attempt',
    functionName: functionName ?? null,
    judge_active: active,
    wired: isWired,
    decision: decision ?? null,
    seal_attempted: attempted,
    sealed,
    kind_sealed: sealResult ? (sealResult.kind ?? null) : null,
    cause: cause ?? null,
    error_type: errorType ?? null,
    reason,
    at: nowMs,
  };
}

/** Best-effort append в ~/.claude/runtime/seal-attempts.jsonl (Node fs, не Write-tool). */
export function logSealAttempt(entry, { fsImpl = { appendFileSync, mkdirSync }, dir = runtimeDir() } = {}) {
  try {
    fsImpl.mkdirSync(dir, { recursive: true });
    fsImpl.appendFileSync(join(dir, SEAL_LOG), JSON.stringify(entry) + '\n');
  } catch { /* наблюдаемость best-effort — никогда не ломает хук */ }
}
