#!/bin/sh
#
# S37board_setup - checked Amlogic A113D safe baseline and board pinmux
#
# GPIO437 levels come from the generated exact-target/revision authority.
# Undriven input is not an OFF command. A qualified OFF command/readback is
# software evidence only; it does not measure the physical rail.

PATH=/usr/bin:/bin:/usr/sbin:/sbin

GPIO_ROOT=/sys/class/gpio
PWM_ROOT=/sys/class/pwm/pwmchip0
IDENTITY_ROOT=/etc/dcentos
RECEIPT_DIR=/run/dcentos
RECEIPT=$RECEIPT_DIR/amlogic-boot-safe-state-v2
MUTATION_POLICY_FILE=$IDENTITY_ROOT/mutation_policy
MUTATION_POLICY_HELPER=/usr/libexec/dcentos/mutation-policy.sh
PWR_GPIO=437

GPIO437_POLICY_HELPER=/usr/share/dcentos/amlogic-gpio437.sh

psu_polarity_class() {
    [ -r "$GPIO437_POLICY_HELPER" ] || return 1
    . "$GPIO437_POLICY_HELPER" || return 1
    dcent_gpio437_policy_state "$1"
}

read_psu_recipe() {
    [ -r "$GPIO437_POLICY_HELPER" ] || {
        log_error 'GPIO437 polarity authority is missing'
        return 1
    }
    . "$GPIO437_POLICY_HELPER" || return 1
    PSU_CLASS=$(dcent_gpio437_policy_state "$BOARD_TARGET") || {
        log_error "GPIO437 refuse: missing or unsealed board_target='$BOARD_TARGET'"
        return 1
    }
    PWR_ON_VALUE=
    PWR_OFF_VALUE=
    PWR_OFF_DIRECTION=
    case "$PSU_CLASS" in
        qualified-software)
            LEVELS=$(dcent_gpio437_drive_levels "$BOARD_TARGET") || return 1
            case "$LEVELS" in
                '0 1 high'|'1 0 low') ;;
                *) return 1 ;;
            esac
            set -- $LEVELS
            PWR_ON_VALUE=$1
            PWR_OFF_VALUE=$2
            PWR_OFF_DIRECTION=$3
            ;;
        undriven) ;;
        *) return 1 ;;
    esac
}
FAN_PERIOD_NS=100000
FAN_BOOT_DUTY_NS=30000

log_error() {
    printf '  [FAIL] S37board_setup: %s\n' "$*" >&2
}

read_trimmed() {
    [ -r "$1" ] || return 1
    VALUE=$(cat "$1" 2>/dev/null) || return 1
    printf '%s' "$VALUE"
}

require_mutation_authority() {
    # Seal the complete platform:target:rail tuple before any electrical
    # mutation. A board_target-only peek is not sufficient: a cross-paired
    # mismatched platform and target must fail before any GPIO437 mutation.
    read_identity || {
        log_error 'exact Amlogic platform:target:rail identity is required before mutation'
        return 1
    }
    if [ ! -r "$MUTATION_POLICY_HELPER" ]; then
        log_error 'mutation-policy helper is missing; refusing electrical mutation'
        return 1
    fi
    . "$MUTATION_POLICY_HELPER"
    if ! dcent_mutation_policy_has "$MUTATION_POLICY_FILE" boot-safeoff; then
        log_error 'boot-safeoff capability is missing or insecure; refusing electrical mutation'
        return 1
    fi
    case "$PLATFORM:$BOARD_TARGET" in
        am3-aml-t21:*|*:am3-t21)
            log_error 'target controller/rail ownership is unresolved; refusing electrical mutation'
            return 1
            ;;
    esac
}

read_identity() {
    PLATFORM=$(read_trimmed "$IDENTITY_ROOT/platform") || {
        log_error 'missing exact platform marker'
        return 1
    }
    BOARD_TARGET=$(read_trimmed "$IDENTITY_ROOT/board_target") || {
        log_error 'missing exact board_target marker'
        return 1
    }
    RAIL_GPIO=$(read_trimmed "$IDENTITY_ROOT/rail_gpio") || {
        log_error 'missing rail_gpio marker'
        return 1
    }

    [ "$RAIL_GPIO" = "$PWR_GPIO" ] || {
        log_error "rail_gpio=$RAIL_GPIO does not match sealed Amlogic GPIO$PWR_GPIO profile"
        return 1
    }

    case "$PLATFORM:$BOARD_TARGET" in
        am3-aml-s19jpro:am3-s19jpro-aml|\
        am3-aml-s19k:am3-s19k|\
        am3-aml-s19kpro:am3-s19kpro|\
        am3-aml-s21:am3-s21|\
        am3-aml-s21pro:am3-s21pro|\
        am3-aml-s21xp:am3-s21xp|\
        am3-aml-s19xp:am3-s19xp|\
        am3-aml-s19jxp:am3-s19jxp|\
        am3-aml-s19jproa:am3-s19jproa|\
        am3-aml-s19jproplus:am3-s19jproplus)
            ;;
        *)
            log_error "unsealed Amlogic identity platform=$PLATFORM board_target=$BOARD_TARGET"
            return 1
            ;;
    esac
}

export_gpio_checked() {
    GPIO=$1
    GPIO_DIR=$GPIO_ROOT/gpio$GPIO
    if [ ! -d "$GPIO_DIR" ]; then
        printf '%s\n' "$GPIO" > "$GPIO_ROOT/export" 2>/dev/null || true
        [ -d "$GPIO_DIR" ] || sleep 1
    fi
    [ -d "$GPIO_DIR" ] || {
        log_error "GPIO$GPIO did not appear after export"
        return 1
    }
}

set_gpio_direction_checked() {
    GPIO=$1
    REQUESTED=$2
    EXPECTED=$3
    DIR_PATH=$GPIO_ROOT/gpio$GPIO/direction
    printf '%s\n' "$REQUESTED" > "$DIR_PATH" 2>/dev/null || {
        log_error "GPIO$GPIO direction=$REQUESTED write failed"
        return 1
    }
    OBSERVED=$(read_trimmed "$DIR_PATH") || {
        log_error "GPIO$GPIO direction readback failed"
        return 1
    }
    [ "$OBSERVED" = "$EXPECTED" ] || {
        log_error "GPIO$GPIO direction readback=$OBSERVED expected=$EXPECTED"
        return 1
    }
}

set_gpio_value_checked() {
    GPIO=$1
    EXPECTED=$2
    VALUE_PATH=$GPIO_ROOT/gpio$GPIO/value
    printf '%s\n' "$EXPECTED" > "$VALUE_PATH" 2>/dev/null || {
        log_error "GPIO$GPIO value=$EXPECTED write failed"
        return 1
    }
    OBSERVED=$(read_trimmed "$VALUE_PATH") || {
        log_error "GPIO$GPIO value readback failed"
        return 1
    }
    [ "$OBSERVED" = "$EXPECTED" ] || {
        log_error "GPIO$GPIO value readback=$OBSERVED expected=$EXPECTED"
        return 1
    }
}

force_psu_safe_low() {
    # Resolve before any GPIO mutation; an unknown target supplies no level.
    read_psu_recipe || return 1
    export_gpio_checked "$PWR_GPIO" || return 1
    if [ "$PSU_CLASS" = undriven ] || [ "$(read_trimmed "$GPIO_ROOT/gpio$PWR_GPIO/active_low")" != 0 ]; then
        set_gpio_direction_checked "$PWR_GPIO" in in || return 1
    fi
    ACTIVE_LOW_PATH=$GPIO_ROOT/gpio$PWR_GPIO/active_low
    [ -e "$ACTIVE_LOW_PATH" ] || {
        log_error "GPIO$PWR_GPIO active_low control is unavailable"
        return 1
    }
    write_and_check "$ACTIVE_LOW_PATH" 0 || {
        log_error "GPIO$PWR_GPIO active_low=0 write/readback failed"
        return 1
    }
    if [ "$PSU_CLASS" = qualified-software ]; then
        # Kernel direction high/low establishes output without an out/value glitch.
        set_gpio_direction_checked "$PWR_GPIO" "$PWR_OFF_DIRECTION" out || return 1
        set_gpio_value_checked "$PWR_GPIO" "$PWR_OFF_VALUE" || return 1
    else
        log_error "GPIO$PWR_GPIO left undriven for board_target='$BOARD_TARGET': exact revision coverage is incomplete; no OFF level is claimed"
    fi
}

configure_input_gpio() {
    GPIO=$1
    export_gpio_checked "$GPIO" || return 1
    set_gpio_direction_checked "$GPIO" in in
}

configure_output_low_gpio() {
    GPIO=$1
    export_gpio_checked "$GPIO" || return 1
    set_gpio_direction_checked "$GPIO" low out || return 1
    set_gpio_value_checked "$GPIO" 0
}

configure_reset_output_low_gpio() {
    GPIO=$1
    export_gpio_checked "$GPIO" || return 1
    ACTIVE_LOW_PATH=$GPIO_ROOT/gpio$GPIO/active_low
    [ -e "$ACTIVE_LOW_PATH" ] || {
        log_error "GPIO$GPIO reset active_low control is unavailable"
        return 1
    }
    write_and_check "$ACTIVE_LOW_PATH" 0 || {
        log_error "GPIO$GPIO reset active_low=0 write/readback failed"
        return 1
    }
    set_gpio_direction_checked "$GPIO" low out || return 1
    set_gpio_value_checked "$GPIO" 0
}

hold_hashboards_reset_low() {
    RESET_OK=true
    for GPIO in 454 455 456; do
        if ! configure_reset_output_low_gpio "$GPIO"; then
            RESET_OK=false
        fi
    done
    [ "$RESET_OK" = true ]
}

verify_hashboards_reset_low() {
    for GPIO in 454 455 456; do
        RESET_DIRECTION=$(read_trimmed "$GPIO_ROOT/gpio$GPIO/direction") || return 1
        RESET_VALUE=$(read_trimmed "$GPIO_ROOT/gpio$GPIO/value") || return 1
        RESET_ACTIVE_LOW=$(read_trimmed "$GPIO_ROOT/gpio$GPIO/active_low") || return 1
        [ "$RESET_DIRECTION" = out ] \
            && [ "$RESET_VALUE" = 0 ] \
            && [ "$RESET_ACTIVE_LOW" = 0 ] || {
            log_error "GPIO$GPIO reset-low revalidation failed direction=$RESET_DIRECTION value=$RESET_VALUE active_low=$RESET_ACTIVE_LOW"
            return 1
        }
    done
}

set_optional_attribute_checked() {
    GPIO=$1
    ATTRIBUTE=$2
    EXPECTED=$3
    PATHNAME=$GPIO_ROOT/gpio$GPIO/$ATTRIBUTE
    [ -e "$PATHNAME" ] || return 0
    printf '%s\n' "$EXPECTED" > "$PATHNAME" 2>/dev/null || {
        log_error "GPIO$GPIO $ATTRIBUTE=$EXPECTED write failed"
        return 1
    }
    OBSERVED=$(read_trimmed "$PATHNAME") || return 1
    [ "$OBSERVED" = "$EXPECTED" ] || {
        log_error "GPIO$GPIO $ATTRIBUTE readback=$OBSERVED expected=$EXPECTED"
        return 1
    }
}

write_and_check() {
    PATHNAME=$1
    EXPECTED=$2
    printf '%s\n' "$EXPECTED" > "$PATHNAME" 2>/dev/null || return 1
    OBSERVED=$(read_trimmed "$PATHNAME") || return 1
    [ "$OBSERVED" = "$EXPECTED" ]
}

configure_fan_channel() {
    CHANNEL=$1
    PWM_DIR=$PWM_ROOT/pwm$CHANNEL
    if [ ! -d "$PWM_DIR" ]; then
        printf '%s\n' "$CHANNEL" > "$PWM_ROOT/export" 2>/dev/null || true
        [ -d "$PWM_DIR" ] || sleep 1
    fi
    [ -d "$PWM_DIR" ] || {
        log_error "fan PWM channel $CHANNEL did not appear after export"
        return 1
    }

    ENABLED=$(read_trimmed "$PWM_DIR/enable") || return 1
    PERIOD=$(read_trimmed "$PWM_DIR/period") || return 1
    if [ "$ENABLED" = 1 ] && [ "$PERIOD" != "$FAN_PERIOD_NS" ]; then
        write_and_check "$PWM_DIR/enable" 0 || {
            log_error "fan PWM$CHANNEL disable before period change failed"
            return 1
        }
        ENABLED=0
    fi
    if [ "$PERIOD" != "$FAN_PERIOD_NS" ]; then
        # Reduce duty before shrinking the period; sysfs rejects period < duty.
        write_and_check "$PWM_DIR/duty_cycle" 0 || {
            log_error "fan PWM$CHANNEL zero-duty transition failed"
            return 1
        }
        write_and_check "$PWM_DIR/period" "$FAN_PERIOD_NS" || {
            log_error "fan PWM$CHANNEL period setup failed"
            return 1
        }
    fi
    write_and_check "$PWM_DIR/duty_cycle" "$FAN_BOOT_DUTY_NS" || {
        log_error "fan PWM$CHANNEL duty setup/readback failed"
        return 1
    }
    if [ "$ENABLED" != 1 ]; then
        write_and_check "$PWM_DIR/enable" 1 || {
            log_error "fan PWM$CHANNEL enable/readback failed"
            return 1
        }
    fi
}

configure_fans_checked() {
    configure_fan_channel 0 || return 1
    configure_fan_channel 1 || return 1
}

dcentrald_may_execute() {
    for PID in $(pidof dcentrald 2>/dev/null || true); do
        case "$PID" in
            ''|*[!0-9]*) return 0 ;;
        esac
        STATE=$(awk '{print $3}' "/proc/$PID/stat" 2>/dev/null) || return 0
        [ "$STATE" = Z ] || return 0
    done
    return 1
}

write_receipt() {
    STATE=$1
    read_psu_recipe || return 1
    if [ "$STATE" = terminal-safe ] && [ "$PSU_CLASS" != qualified-software ]; then
        log_error 'undriven GPIO437 cannot establish terminal SafeOff'
        return 1
    fi
    verify_hashboards_reset_low || {
        log_error 'refusing safe-state receipt without all three checked reset-low legs'
        return 1
    }
    BOOT_ID=$(read_trimmed /proc/sys/kernel/random/boot_id) || {
        log_error 'boot_id unavailable; refusing an unbound safety receipt'
        return 1
    }
    mkdir -p "$RECEIPT_DIR" || return 1
    chmod 0700 "$RECEIPT_DIR" || return 1
    TMP=$RECEIPT.tmp.$$
    umask 077
    {
        printf 'schema=dcentos.amlogic-safe-state/v2\n'
        printf 'state=%s\n' "$STATE"
        printf 'boot_id=%s\n' "$BOOT_ID"
        printf 'platform=%s\n' "$PLATFORM"
        printf 'board_target=%s\n' "$BOARD_TARGET"
        printf 'resource=amlogic-gpio437-power-gate\n'
        printf 'gpio_active_low=0\n'
        printf 'psu_polarity_class=%s\n' "$PSU_CLASS"
        case "$PSU_CLASS" in
            qualified-software)
                printf 'gpio_direction=out\n'
                printf 'commanded_value=%s\n' "$PWR_OFF_VALUE"
                printf 'readback_value=%s\n' "$PWR_OFF_VALUE"
                ;;
            undriven)
                printf 'gpio_direction=in\n'
                printf 'commanded_value=undriven\n'
                printf 'readback_value=%s\n' "$(read_trimmed "$GPIO_ROOT/gpio$PWR_GPIO/value" 2>/dev/null || printf 'unknown\n')"
                ;;
            *) return 1 ;;
        esac
        printf 'fan0_duty_ns=%s\n' "$FAN_BOOT_DUTY_NS"
        printf 'fan0_period_ns=%s\n' "$FAN_PERIOD_NS"
        printf 'fan0_enabled=1\n'
        printf 'fan1_duty_ns=%s\n' "$FAN_BOOT_DUTY_NS"
        printf 'fan1_period_ns=%s\n' "$FAN_PERIOD_NS"
        printf 'fan1_enabled=1\n'
        printf 'hashboard_reset_gpio454_direction=out\n'
        printf 'hashboard_reset_gpio454_active_low=0\n'
        printf 'hashboard_reset_gpio454_value=0\n'
        printf 'hashboard_reset_gpio455_direction=out\n'
        printf 'hashboard_reset_gpio455_active_low=0\n'
        printf 'hashboard_reset_gpio455_value=0\n'
        printf 'hashboard_reset_gpio456_direction=out\n'
        printf 'hashboard_reset_gpio456_active_low=0\n'
        printf 'hashboard_reset_gpio456_value=0\n'
        printf 'hashboard_reset_low_bitmap=0x7\n'
        printf 'evidence_grade=software-readback\n'
        printf 'physical_rail_measured=false\n'
    } > "$TMP" || {
        rm -f "$TMP"
        return 1
    }
    chmod 0600 "$TMP" || {
        rm -f "$TMP"
        return 1
    }
    mv "$TMP" "$RECEIPT" || {
        rm -f "$TMP"
        return 1
    }
}

receipt_field_is() {
    KEY=$1
    EXPECTED=$2
    COUNT=$(grep -c "^$KEY=" "$RECEIPT" 2>/dev/null) || return 1
    [ "$COUNT" = 1 ] || return 1
    grep -Fqx "$KEY=$EXPECTED" "$RECEIPT" 2>/dev/null
}

verify_safe_receipt() {
    read_identity || return 1
    [ -f "$RECEIPT" ] && [ ! -L "$RECEIPT" ] || {
        log_error 'boot-safe receipt is absent or unsafe'
        return 1
    }
    BOOT_ID=$(read_trimmed /proc/sys/kernel/random/boot_id) || return 1
    receipt_field_is schema dcentos.amlogic-safe-state/v2 || return 1
    receipt_field_is boot_id "$BOOT_ID" || return 1
    receipt_field_is platform "$PLATFORM" || return 1
    receipt_field_is board_target "$BOARD_TARGET" || return 1
    receipt_field_is resource amlogic-gpio437-power-gate || return 1
    receipt_field_is gpio_active_low 0 || return 1
    read_psu_recipe || return 1
    receipt_field_is psu_polarity_class "$PSU_CLASS" || return 1
    case "$PSU_CLASS" in
        qualified-software)
            receipt_field_is gpio_direction out || return 1
            receipt_field_is commanded_value "$PWR_OFF_VALUE" || return 1
            receipt_field_is readback_value "$PWR_OFF_VALUE" || return 1
            SAFE_OFF_VALUE=$PWR_OFF_VALUE
            ;;
        undriven)
            receipt_field_is gpio_direction in || return 1
            receipt_field_is commanded_value undriven || return 1
            # Input readback may follow the external pull; it is not an OFF proof.
            SAFE_OFF_VALUE=
            ;;
        *) return 1 ;;
    esac
    receipt_field_is fan0_duty_ns "$FAN_BOOT_DUTY_NS" || return 1
    receipt_field_is fan0_period_ns "$FAN_PERIOD_NS" || return 1
    receipt_field_is fan0_enabled 1 || return 1
    receipt_field_is fan1_duty_ns "$FAN_BOOT_DUTY_NS" || return 1
    receipt_field_is fan1_period_ns "$FAN_PERIOD_NS" || return 1
    receipt_field_is fan1_enabled 1 || return 1
    receipt_field_is hashboard_reset_gpio454_direction out || return 1
    receipt_field_is hashboard_reset_gpio454_active_low 0 || return 1
    receipt_field_is hashboard_reset_gpio454_value 0 || return 1
    receipt_field_is hashboard_reset_gpio455_direction out || return 1
    receipt_field_is hashboard_reset_gpio455_active_low 0 || return 1
    receipt_field_is hashboard_reset_gpio455_value 0 || return 1
    receipt_field_is hashboard_reset_gpio456_direction out || return 1
    receipt_field_is hashboard_reset_gpio456_active_low 0 || return 1
    receipt_field_is hashboard_reset_gpio456_value 0 || return 1
    receipt_field_is hashboard_reset_low_bitmap 0x7 || return 1
    receipt_field_is evidence_grade software-readback || return 1
    receipt_field_is physical_rail_measured false || return 1
    receipt_field_is state boot-safe \
        || receipt_field_is state runtime-handoff \
        || receipt_field_is state terminal-safe \
        || return 1

    DIRECTION=$(read_trimmed "$GPIO_ROOT/gpio$PWR_GPIO/direction") || return 1
    VALUE=$(read_trimmed "$GPIO_ROOT/gpio$PWR_GPIO/value") || return 1
    ACTIVE_LOW=$(read_trimmed "$GPIO_ROOT/gpio$PWR_GPIO/active_low") || return 1
    if [ -n "$SAFE_OFF_VALUE" ]; then
        [ "$DIRECTION" = out ] && [ "$VALUE" = "$SAFE_OFF_VALUE" ] && [ "$ACTIVE_LOW" = 0 ] || {
            log_error "GPIO$PWR_GPIO revalidation failed direction=$DIRECTION value=$VALUE want=$SAFE_OFF_VALUE active_low=$ACTIVE_LOW"
            return 1
        }
    else
        # Unqualified target: the invariant is that nothing has started
        # driving the pin behind our back, not that it sits at a level we
        # cannot justify calling safe.
        [ "$DIRECTION" = in ] && [ "$ACTIVE_LOW" = 0 ] || {
            log_error "GPIO$PWR_GPIO revalidation failed: expected an undriven pin for unqualified board_target='$BOARD_TARGET' but found direction=$DIRECTION value=$VALUE active_low=$ACTIVE_LOW"
            return 1
        }
    fi
    for CHANNEL in 0 1; do
        PWM_DIR=$PWM_ROOT/pwm$CHANNEL
        DUTY=$(read_trimmed "$PWM_DIR/duty_cycle") || return 1
        PERIOD=$(read_trimmed "$PWM_DIR/period") || return 1
        ENABLED=$(read_trimmed "$PWM_DIR/enable") || return 1
        [ "$DUTY" = "$FAN_BOOT_DUTY_NS" ] \
            && [ "$PERIOD" = "$FAN_PERIOD_NS" ] \
            && [ "$ENABLED" = 1 ] || {
            log_error "fan PWM$CHANNEL revalidation failed duty=$DUTY period=$PERIOD enable=$ENABLED"
            return 1
        }
    done
    verify_hashboards_reset_low || return 1
}

pinmux_init() {
    # Buttons.
    for GPIO in 446 445; do
        configure_input_gpio "$GPIO" || return 1
        set_optional_attribute_checked "$GPIO" edge rising || return 1
    done

    # Hashboard plug detect, active HIGH with optional pull-down.
    for GPIO in 439 440 441; do
        configure_input_gpio "$GPIO" || return 1
        set_optional_attribute_checked "$GPIO" pull down || return 1
    done

    # Hold hashboards in reset (active LOW) until the runtime owner admits them.
    hold_hashboards_reset_low || return 1

    # Status LEDs default LOW. Identity is LED_GREEN=453 / LED_RED=438
    # (S21 Braiins names). Ash cannot resolve gpio-line-names; HAL
    # write_amlogic_status_led does name-first at runtime.
    for GPIO in 453 438; do
        configure_output_low_gpio "$GPIO" || return 1
    done

    # Fan tach inputs.
    for GPIO in 447 448 449 450; do
        configure_input_gpio "$GPIO" || return 1
        set_optional_attribute_checked "$GPIO" edge falling || return 1
    done

    # I2C_SCL=476 / I2C_SDA=477 pinmux guards. Verified stock S21 and the
    # retained runtime both require input, not the old output-high sequence.
    # HAL prepare_management_i2c_pinmux resolves those names first.
    for GPIO in 476 477; do
        configure_input_gpio "$GPIO" || return 1
    done
}

start_board() {
    require_mutation_authority || return 1
    # First safety-critical mutation: remove the hash-power gate.
    if ! force_psu_safe_low; then
        # Power is still UnknownInherited. Preserve the maximum verified home
        # emergency cooling command and refuse all later board initialization.
        configure_fans_checked || true
        return 1
    fi
    configure_fans_checked || return 1
    # Recheck exact identity after the independently fallible power and cooling
    # operations, before the wider shared pinmux surface is touched.
    read_identity || return 1
    pinmux_init || return 1
    write_receipt boot-safe || return 1
}

emergency_safe_off() {
    require_mutation_authority || return 1
    if dcentrald_may_execute; then
        log_error 'refusing a competing emergency owner while dcentrald is live'
        return 1
    fi
    # On the sealed S19k route, assert every hashboard reset before cutting its
    # rail. A failed reset leg must not prevent the independent GPIO437 SafeOff
    # attempt. Other AML targets retain the old cut-first ordering until their
    # reset/rail relation is independently sealed.
    RESET_LOW_OK=true
    case "${TARGET_HINT:-${BOARD_TARGET:-}}" in
        am3-s19k|am3-s19kpro|am3-aml-s19kpro)
            if ! hold_hashboards_reset_low; then
                RESET_LOW_OK=false
                log_error 'one or more hashboard reset-low legs failed; continuing to GPIO437 SafeOff'
            fi
            ;;
    esac
    if ! force_psu_safe_low; then
        configure_fans_checked || true
        return 1
    fi
    configure_fans_checked || return 1
    read_identity || return 1
    case "$BOARD_TARGET" in
        am3-s19k|am3-s19kpro|am3-aml-s19kpro) ;;
        *) hold_hashboards_reset_low || RESET_LOW_OK=false ;;
    esac
    [ "$RESET_LOW_OK" = true ] || {
        log_error 'GPIO437 SafeOff succeeded but reset-low was incomplete; refusing terminal-safe receipt'
        return 1
    }
    write_receipt terminal-safe
}

mark_runtime_handoff() {
    require_mutation_authority || return 1
    # S82 prepares the persistent session before this transition. A checked
    # terminal baseline may serve the next session; its receipt alone cannot
    # clear a crashed or unresolved hardware session.
    verify_start_safe_receipt || return 1
    configure_fans_checked || return 1
    # Revalidate the power gate after cooling and immediately before the
    # supervisor publishes the runtime owner.
    DIRECTION=$(read_trimmed "$GPIO_ROOT/gpio$PWR_GPIO/direction") || return 1
    VALUE=$(read_trimmed "$GPIO_ROOT/gpio$PWR_GPIO/value") || return 1
    read_identity || return 1
    read_psu_recipe || return 1
    case "$PSU_CLASS" in
        qualified-software)
            [ "$DIRECTION" = out ] && [ "$VALUE" = "$PWR_OFF_VALUE" ] || return 1
            ;;
        undriven)
            [ "$DIRECTION" = in ] || {
                log_error "GPIO$PWR_GPIO runtime handoff refused: unqualified board_target='$BOARD_TARGET' must remain undriven"
                return 1
            }
            ;;
        *) return 1 ;;
    esac
    write_receipt runtime-handoff
}

verify_boot_safe_receipt() {
    verify_safe_receipt || return 1
    receipt_field_is state boot-safe
}

verify_start_safe_receipt() {
    verify_safe_receipt || return 1
    receipt_field_is state boot-safe && return 0
    [ "$PSU_CLASS" = qualified-software ] && receipt_field_is state terminal-safe
}

verify_terminal_safe_receipt() {
    verify_safe_receipt || return 1
    [ "$PSU_CLASS" = qualified-software ] || return 1
    receipt_field_is state terminal-safe
}

case "${1:-start}" in
    start)
        printf '  Establishing checked Amlogic boot-safe baseline...\n'
        if start_board; then
            printf '  [OK] GPIO437 policy baseline checked; fan PWM <=30; pinmux checked\n'
        else
            log_error 'safe baseline incomplete; dcentrald admission must remain blocked'
            exit 1
        fi
        ;;
    verify-safe-state)
        verify_boot_safe_receipt || {
            log_error 'boot-safe receipt or live GPIO revalidation failed'
            exit 1
        }
        ;;
    verify-start-safe-state)
        verify_start_safe_receipt || {
            log_error 'start requires a boot-safe or terminal-safe receipt and full live revalidation'
            exit 1
        }
        ;;
    mark-runtime-handoff)
        mark_runtime_handoff || {
            log_error 'runtime handoff revalidation failed'
            exit 1
        }
        ;;
    verify-terminal-safe-state)
        verify_terminal_safe_receipt || {
            log_error 'terminal SafeOff receipt/revalidation failed'
            exit 1
        }
        ;;
    emergency-safe-off)
        emergency_safe_off || exit 1
        ;;
    stop)
        # Runtime teardown owns the normal SafeOff transition.  S82 invokes
        # emergency-safe-off only after the runtime owner is confirmed dead.
        :
        ;;
    *)
        echo "Usage: $0 {start|stop|verify-safe-state|verify-start-safe-state|mark-runtime-handoff|verify-terminal-safe-state|emergency-safe-off}" >&2
        exit 64
        ;;
esac

exit 0
