<?php
declare(strict_types=1);

/** Pure fail-closed decision; caller must independently prove observations. */
function raceWriteRecoveryDecision(array $journal, array $seen): array
{
    $deny = static function (string $reason): array {
        return ['allowed' => false, 'action' => 'deny', 'reason' => $reason];
    };
    $marker = (string)($journal['marker'] ?? '');
    $phase = (string)($journal['phase'] ?? '');
    if (!in_array(($journal['lane'] ?? null), ['A', 'B', 'C'], true)
        || preg_match('/^CDXEMRACE[A-F0-9]{12}$/D', $marker) !== 1
        || preg_match('/^[A-F0-9]{32}$/D', (string)($journal['menu_uuid'] ?? '')) !== 1
        || preg_match('/^[a-f0-9]{64}$/D', (string)($journal['public_token'] ?? '')) !== 1
        || preg_match('/^[a-f0-9]{64}$/D', (string)($journal['code_hash'] ?? '')) !== 1
        || ($journal['device_ids'][1] ?? null) !== $marker . 'A'
        || ($journal['device_ids'][2] ?? null) !== $marker . 'B'
        || !in_array($phase, ['fixture_intent', 'menu_inserted',
            'bind_code_inserted', 'both_worker_barriers_confirmed'], true)) {
        return $deny('journal_identity_or_phase');
    }
    if (!is_array($seen['menus'] ?? null) || !is_array($seen['codes'] ?? null)
        || count($seen['menus']) > 1 || count($seen['codes']) > 1
        || ($seen['device_count'] ?? -1) !== 0
        || ($seen['log_count'] ?? -1) !== 0
        || ($seen['workers_quiescent'] ?? false) !== true) {
        return $deny('unexpected_rows_or_worker_state');
    }
    $menus = $seen['menus'];
    $codes = $seen['codes'];
    $beforeHttp = in_array($phase,
        ['fixture_intent', 'menu_inserted', 'bind_code_inserted'], true);
    if ($beforeHttp && ($seen['router_pristine'] ?? false) !== true) {
        return $deny('router_not_pristine');
    }
    if ($phase === 'both_worker_barriers_confirmed'
        && ($menus !== [] || $codes !== [])) {
        return $deny('post_http_rows_need_separate_recovery');
    }
    if ($menus !== []) {
        $m = $menus[0];
        if (!is_array($m) || (int)($m['id'] ?? 0) <= 0
            || (string)($m['uuid'] ?? '') !== $journal['menu_uuid']
            || (string)($m['public_token'] ?? '') !== $journal['public_token']
            || (string)($m['create_by'] ?? '') !== $marker
            || (int)($m['store_id'] ?? 0) !== 10001
            || ((int)($journal['menu_id'] ?? 0) > 0
                && (int)$journal['menu_id'] !== (int)$m['id'])) {
            return $deny('menu_identity_mismatch');
        }
    }
    if ($codes !== []) {
        $c = $codes[0];
        if ($menus === [] || !is_array($c) || (int)($c['id'] ?? 0) <= 0
            || (int)($c['menu_id'] ?? 0) !== (int)$menus[0]['id']
            || (string)($c['code_hash'] ?? '') !== $journal['code_hash']
            || (string)($c['create_by'] ?? '') !== $marker
            || (int)($c['store_id'] ?? 0) !== 10001
            || ((int)($journal['code_id'] ?? 0) > 0
                && (int)$journal['code_id'] !== (int)$c['id'])) {
            return $deny('bind_identity_mismatch');
        }
    }
    if ($menus === [] && $codes === []) {
        return ($seen['baseline_equal'] ?? false) === true
            ? ['allowed' => true, 'action' => 'advance_clean_zero']
            : $deny('baseline_changed');
    }
    return ['allowed' => true, 'action' => 'cleanup_pre_http'];
}
