// engine/frontmatter-sha/verify-terminal.ts — SPEC-723: Tamper detection for terminal specs
import { computeFrontmatterSha } from './compute-sha.js';
import { FROZEN_FIELDS } from './frozen-fields.js';
import { readTransitionLog } from '../../storage/transition-log.js';
/**
 * Verify that the frontmatter of a terminal spec has not been tampered with
 * since it was sealed (transitioned to done/discarded).
 *
 * Reads the last `transitioned_to_terminal` or `frontmatter_resealed` entry from
 * the transition log and compares its SHA to the current metadata SHA.
 *
 * Returns {ok: true} if:
 *   - No transition log entry exists for this spec (spec was never sealed — not terminal yet).
 *   - The SHA matches.
 *
 * Returns {ok: false, expectedSha, actualSha, divergedFields} if there is a mismatch.
 */
export async function verifyTerminalFrontmatter(args) {
    const { projectId, specId, currentMetadata } = args;
    const entries = await readTransitionLog(projectId, specId);
    // Find the last seal event (terminal transition or reseal)
    const sealEvent = [...entries]
        .reverse()
        .find((e) => (e.eventType === 'transitioned_to_terminal' || e.eventType === 'frontmatter_resealed') &&
        e.frontmatterSha !== undefined);
    if (sealEvent?.frontmatterSha === undefined) {
        // No seal record — assume not yet frozen (ok)
        return { ok: true };
    }
    const expectedSha = sealEvent.frontmatterSha;
    const actualSha = computeFrontmatterSha(currentMetadata);
    if (expectedSha === actualSha) {
        return { ok: true };
    }
    // Identify which frozen fields diverged by comparing field-level hashes
    const divergedFields = findDivergedFields(sealEvent, currentMetadata);
    return { ok: false, expectedSha, actualSha, divergedFields };
}
/**
 * Find which frozen fields have changed since the seal event.
 * Since we only store the composite SHA (not per-field hashes), we cannot
 * reconstruct the original values. We report all frozen fields as candidates
 * that the caller should inspect manually.
 * When the stored sha was computed from the same FROZEN_FIELDS set, any change
 * to those fields will cause a mismatch — we return them all as potentially diverged.
 */
function findDivergedFields(_sealEvent, _currentMetadata) {
    // We cannot reconstruct the original values from just the composite SHA.
    // Return all frozen fields to indicate any of them may have changed.
    return [...FROZEN_FIELDS];
}
//# sourceMappingURL=verify-terminal.js.map