#!/usr/bin/env bash
# Finish the live Wasm bootstrap after Native Core has projected Restricted C17.
#
# This is intentionally a replaceable seam. It consumes module_0.c emitted from
# the already-frozen Native Core program, builds a wasm32-WASI reactor twice,
# proves byte identity, and performs bounded reactor instantiation. It is NOT a
# direct Native-Core-to-Wasm emitter and never reports itself as one.

set -euo pipefail

BEAGLE_DIR="$(cd "$(dirname "$0")/.." && pwd)"
source "$BEAGLE_DIR/bin/_beagle-racket"
TOOLS="$BEAGLE_DIR/bin/beagle-wasm-tools"
SHIM="$BEAGLE_DIR/native-core/shim"
SEAMS="$BEAGLE_DIR/native-core/validation/wasm32/seams.clj"
ENTRY_CONTRACT="$BEAGLE_DIR/native-core/validation/wasm32/entry-contract.clj"
AST_VERIFIER="$BEAGLE_DIR/native-core/bin/verify-checked-ast.rkt"
FINALIZER="$BEAGLE_DIR/native-core/validation/build-finalize.clj"
SUPERVISOR="$BEAGLE_DIR/native-core/bin/run-bounded.rkt"

usage() {
    echo "usage: beagle-materialize-wasm --artifacts DIR" \
        "--compiled DIR --checked-source SOURCE AST... [--entry NS/NAME]..." >&2
}

artifacts=""
compiled=""
entries=()
checked_source_args=()
while [[ $# -gt 0 ]]; do
    case "$1" in
        --artifacts)
            [[ $# -ge 2 ]] || { usage; exit 2; }
            artifacts="$2"
            shift 2
            ;;
        --artifacts=*)
            artifacts="${1#*=}"
            shift
            ;;
        --entry)
            [[ $# -ge 2 ]] || { usage; exit 2; }
            entries+=("$2")
            shift 2
            ;;
        --entry=*)
            entries+=("${1#*=}")
            shift
            ;;
        --compiled)
            [[ $# -ge 2 ]] || { usage; exit 2; }
            compiled="$2"
            shift 2
            ;;
        --compiled=*)
            compiled="${1#*=}"
            shift
            ;;
        --checked-source)
            [[ $# -ge 3 ]] || { usage; exit 2; }
            checked_source_args+=("$2" "$3")
            shift 3
            ;;
        --help|-h)
            usage
            exit 0
            ;;
        *)
            echo "beagle wasm: unknown option: $1" >&2
            usage
            exit 2
            ;;
    esac
done

[[ -n "$artifacts" ]] || { usage; exit 2; }
[[ -n "$compiled" && -f "$compiled/native/core.clj" &&
   -f "$compiled/native/stages.clj" ]] || {
    echo "beagle wasm: --compiled must name the generated Native Core classpath" >&2
    exit 2
}
compiled="$(cd "$compiled" && pwd -P)"

# Every executable entry keeps the parameterless ()->i64 wasm ABI; the export
# name flattens the qualified source name into one C identifier deterministically.
mangle_identifier() {
    printf '%s' "$1" | LC_ALL=C sed 's/[^A-Za-z0-9]/_/g'
}

entry_export_name() {
    printf 'beagle_wasm_entry_v1__%s__%s' \
        "$(mangle_identifier "${1%/*}")" "$(mangle_identifier "${1##*/}")"
}

entry_exports=()
declare -A seen_entries=()
declare -A seen_entry_exports=()
for entry in "${entries[@]}"; do
    [[ "$entry" =~ ^[^[:space:]/]+/[^[:space:]/]+$ ]] || {
        echo "beagle wasm: --entry must be one whitespace-free NS/NAME" >&2
        exit 2
    }
    [[ -z "${seen_entries[$entry]:-}" ]] || {
        echo "beagle wasm: duplicate --entry: $entry" >&2
        exit 2
    }
    seen_entries["$entry"]=1
    entry_export="$(entry_export_name "$entry")"
    [[ -z "${seen_entry_exports[$entry_export]:-}" ]] || {
        echo "beagle wasm: entries ${seen_entry_exports[$entry_export]} and" \
            "$entry flatten to one Wasm export name ($entry_export)" >&2
        exit 2
    }
    seen_entry_exports["$entry_export"]="$entry"
    entry_exports+=("$entry_export")
done
if (( ${#checked_source_args[@]} == 0 || ${#checked_source_args[@]} % 2 != 0 )); then
    echo "beagle wasm: at least one complete --checked-source pair is required" >&2
    exit 2
fi
[[ -d "$artifacts" ]] || {
    echo "beagle wasm: artifacts directory is unavailable: $artifacts" >&2
    exit 2
}
artifacts="$(cd "$artifacts" && pwd -P)"
[[ "$artifacts" != "/" ]] || {
    echo "beagle wasm: artifacts directory may not be the filesystem root" >&2
    exit 2
}

report="$artifacts/wasm-report.txt"
audit="$artifacts/wasm-audit.txt"
artifact="$artifacts/module_0.wasm"
digest_file="$artifacts/module_0.wasm.sha256"
seams="$artifacts/module_0.wasm.seams"
wasm_receipt="$artifacts/wasm.receipt"
artifact_temporary="$artifacts/.module_0.wasm.$$"
digest_temporary="$artifacts/.module_0.wasm.sha256.$$"
seams_temporary="$artifacts/.module_0.wasm.seams.$$"
report_temporary="$artifacts/.wasm-report.txt.$$"
audit_temporary="$artifacts/.wasm-audit.txt.$$"
wasm_receipt_temporary="$artifacts/.wasm.receipt.$$"
wasm_aux_names=(
    native_shim.h native_shim.c native_unicode15_data.h
    wasm.retention.c wasm.adapter.c wasm.entry-contract.clj wasm.seams.clj
    wasm.ast-verifier.rkt wasm.receipt-finalizer.clj wasm.materializer.sh
    wasm.supervisor.rkt
    wasm.cc-identity.txt wasm.ld-identity.txt wasm.runtime-identity.txt
)
rm -f -- "$artifact" "$digest_file" "$seams" "$report" "$audit" \
    "$wasm_receipt" \
    "$artifact_temporary" "$digest_temporary" "$seams_temporary" \
    "$report_temporary" "$audit_temporary" "$wasm_receipt_temporary"
for wasm_aux_name in "${wasm_aux_names[@]}"; do
    rm -f -- "$artifacts/$wasm_aux_name" "$artifacts/.$wasm_aux_name.$$"
done

work="$(mktemp -d "${TMPDIR:-/tmp}/beagle-wasm-materialize.XXXXXX")"
output_committed=0
failure_receipt_published=0
cleanup() {
    local rc=$?
    if [[ "$output_committed" != "1" ]]; then
        rm -f -- "$artifact" "$digest_file" "$seams" "$wasm_receipt" \
            "$artifact_temporary" "$digest_temporary" \
            "$seams_temporary" "$wasm_receipt_temporary"
        if [[ "$failure_receipt_published" != "1" ]]; then
            rm -f -- "$report" "$audit"
        fi
        rm -f -- "$report_temporary" "$audit_temporary"
    fi
    if [[ "$output_committed" != "1" ]]; then
        for wasm_aux_name in "${wasm_aux_names[@]}"; do
            rm -f -- "$artifacts/$wasm_aux_name" "$artifacts/.$wasm_aux_name.$$"
        done
    fi
    rm -rf "${work:?}"
    return "$rc"
}
interrupted() { exit 143; }
trap cleanup EXIT
trap interrupted HUP INT TERM

report_lines=()
report_lines+=("wasm-materializer bootstrap-c17-wasi-clang")
report_lines+=("wasm-materializer-direct false")
report_lines+=("wasm-abi wasm32")
report_lines+=("wasm-input module.native-program")
report_lines+=("wasm-bootstrap-input module_0.c")
if [[ ${#entries[@]} -gt 0 ]]; then
    report_lines+=("wasm-projection-kind executable-entries-v1")
    report_lines+=("wasm-export-policy reactor-initialize-memory-and-entries-v1")
    report_lines+=("wasm-entry-count ${#entries[@]}")
    for entry in "${entries[@]}"; do
        report_lines+=("wasm-entry-name $entry")
    done
else
    report_lines+=("wasm-projection-kind non-executable-projection")
    report_lines+=("wasm-export-policy reactor-initialize-and-memory-only")
fi
report_lines+=("wasm-report-determinism pinned-tool-identities-no-environment-paths")
report_lines+=("wasm-audit wasm-audit.txt environment-specific-tool-paths")
audit_lines=()
audit_lines+=("wasm-audit-scope environment-specific-tool-resolution")

write_report_temporaries() {
    printf '%s\n' "${report_lines[@]}" >"$report_temporary"
    printf '%s\n' "${audit_lines[@]}" >"$audit_temporary"
}

publish_receipts() {
    write_report_temporaries
    mv -f -- "$audit_temporary" "$audit"
    mv -f -- "$report_temporary" "$report"
}

fail() {
    local code="$1"
    shift
    rm -f -- "$artifact" "$digest_file" "$seams" \
        "$wasm_receipt" \
        "$artifact_temporary" "$digest_temporary" "$seams_temporary" \
        "$report" "$audit" "$report_temporary" "$audit_temporary" \
        "$wasm_receipt_temporary"
    for wasm_aux_name in "${wasm_aux_names[@]}"; do
        rm -f -- "$artifacts/$wasm_aux_name" "$artifacts/.$wasm_aux_name.$$"
    done
    report_lines+=("wasm-result FAIL $code")
    publish_receipts
    failure_receipt_published=1
    echo "beagle wasm: $*" >&2
    exit 1
}

for required in \
    "$artifacts/source.facts" \
    "$artifacts/module.native-program" \
    "$artifacts/module.native-program.sha256" \
    "$artifacts/native.receipts" \
    "$artifacts/native.entry-map" \
    "$artifacts/c17.receipt" \
    "$artifacts/module_0.c" \
    "$artifacts/module_0.h" \
    "$SHIM/native_shim.c" \
    "$SHIM/native_shim.h" \
    "$SHIM/native_unicode15_data.h" \
    "$SEAMS" \
    "$AST_VERIFIER" \
    "$FINALIZER" \
    "$SUPERVISOR"; do
    [[ -f "$required" ]] || fail missing-input "bootstrap input is unavailable: $required"
done
if [[ ${#entries[@]} -gt 0 && ! -f "$ENTRY_CONTRACT" ]]; then
    fail missing-input "entry contract validator is unavailable: $ENTRY_CONTRACT"
fi

for command in awk bb cmp cp grep mktemp mv sed sha256sum sort tr wc; do
    command -v "$command" >/dev/null 2>&1 ||
        fail missing-tool "required command is unavailable: $command"
done

compile_timeout="${BEAGLE_WASM_COMPILE_TIMEOUT_SECONDS:-60}"
instantiate_timeout="${BEAGLE_WASM_INSTANTIATE_TIMEOUT_SECONDS:-10}"
identity_timeout="${BEAGLE_WASM_TOOL_IDENTITY_TIMEOUT_SECONDS:-5}"
validation_timeout="${BEAGLE_WASM_VALIDATION_TIMEOUT_SECONDS:-10}"
kill_grace="${BEAGLE_WASM_KILL_GRACE_SECONDS:-5}"
[[ "$compile_timeout" =~ ^[1-9][0-9]*$ ]] ||
    fail invalid-timeout "BEAGLE_WASM_COMPILE_TIMEOUT_SECONDS must be a positive integer"
[[ "$instantiate_timeout" =~ ^[1-9][0-9]*$ ]] ||
    fail invalid-timeout "BEAGLE_WASM_INSTANTIATE_TIMEOUT_SECONDS must be a positive integer"
[[ "$identity_timeout" =~ ^[1-9][0-9]*$ ]] ||
    fail invalid-timeout "BEAGLE_WASM_TOOL_IDENTITY_TIMEOUT_SECONDS must be a positive integer"
[[ "$validation_timeout" =~ ^[1-9][0-9]*$ ]] ||
    fail invalid-timeout "BEAGLE_WASM_VALIDATION_TIMEOUT_SECONDS must be a positive integer"
[[ "$kill_grace" =~ ^[1-9][0-9]*$ ]] ||
    fail invalid-timeout "BEAGLE_WASM_KILL_GRACE_SECONDS must be a positive integer"

# The pinned Racket supervisor prefers a private PID namespace and otherwise
# becomes a subreaper for one owned process group. Returning therefore means
# the complete command tree is gone, not merely that an intermediate shell
# exited.
run_bounded() {
    local seconds="$1"
    shift
    "$RACKET" "$SUPERVISOR" \
        "$seconds" "$kill_grace" -- "$@"
}

read_single_printable_line() {
    local path="$1"
    local destination="$2"
    local description="$3"
    local lines=()
    mapfile -t lines <"$path"
    [[ ${#lines[@]} -eq 1 && "${lines[0]}" =~ ^[[:print:]]+$ ]] ||
        fail unsafe-field "$description must be exactly one printable line"
    printf -v "$destination" '%s' "${lines[0]}"
}

read_native_receipt() {
    local pass="$1"
    local input_destination="$2"
    local output_destination="$3"
    local commit_destination="$4"
    local configuration_destination="$5"
    local rows=()
    mapfile -t rows < <(
        awk -F '\t' -v pass="$pass" \
            '$1 == pass && NF == 5 { print $2 "\t" $3 "\t" $4 "\t" $5 }' \
            "$work/native.receipts.index"
    )
    [[ ${#rows[@]} -eq 1 ]] ||
        fail provenance "native receipt index has no unique $pass receipt"
    IFS=$'\t' read -r receipt_input receipt_output receipt_commit receipt_configuration \
        <<<"${rows[0]}"
    [[ "$receipt_input" =~ ^sha256:[0-9a-f]{64}$ &&
       "$receipt_output" =~ ^sha256:[0-9a-f]{64}$ &&
       "$receipt_configuration" =~ ^sha256:[0-9a-f]{64}$ &&
       "$receipt_commit" =~ ^[[:print:]]+$ ]] ||
        fail provenance "native receipt index carries malformed $pass fields"
    printf -v "$input_destination" '%s' "$receipt_input"
    printf -v "$output_destination" '%s' "$receipt_output"
    printf -v "$commit_destination" '%s' "$receipt_commit"
    printf -v "$configuration_destination" '%s' "$receipt_configuration"
}

if ! run_bounded "$validation_timeout" \
        bb -cp "$compiled" "$FINALIZER" native-index \
        "$work/native.receipts.index" "$artifacts/native.receipts" \
        "$artifacts/module.native-program" >"$work/native-receipts.out" \
        2>"$work/native-receipts.err"; then
    sed -n '1,80p' "$work/native-receipts.err" >&2
    fail provenance "Native Core canonical receipt validation failed"
fi
[[ "$(awk -F '\t' 'NF == 5 { count += 1 } END { print count + 0 }' \
       "$work/native.receipts.index")" == "4" ]] ||
    fail provenance "native receipt index must contain exactly four receipts"
read_native_receipt source-freeze source_input source_output source_commit source_config
read_native_receipt source-to-typed typed_input typed_output typed_commit typed_config
read_native_receipt typed-to-native native_input native_output native_commit native_config
read_native_receipt native-to-epoch epoch_input epoch_output epoch_commit epoch_config
[[ "$source_input" == "$source_output" &&
   "$source_output" == "$typed_input" &&
   "$typed_output" == "$native_input" &&
   "$native_output" == "$epoch_input" &&
   "$source_commit" == "$typed_commit" &&
   "$typed_commit" == "$native_commit" &&
   "$native_commit" == "$epoch_commit" &&
   "$source_config" == "$typed_config" &&
   "$typed_config" == "$native_config" &&
   "$native_config" == "$epoch_config" ]] ||
    fail provenance "Native Core PassReceiptV0 chain is broken"

declare -A checked_source_ids=()
declare -A checked_namespaces=()
for ((source_index = 0; source_index < ${#checked_source_args[@]}; source_index += 2)); do
    checked_source="${checked_source_args[$source_index]}"
    checked_ast="${checked_source_args[$((source_index + 1))]}"
    [[ -f "$checked_source" && -f "$checked_ast" ]] ||
        fail missing-input \
            "checked source evidence is unavailable: $checked_source / $checked_ast"
    ast_metadata="$work/checked-$source_index.metadata"
    if ! run_bounded "$validation_timeout" \
            "$RACKET" "$AST_VERIFIER" "$checked_ast" "$checked_source" \
            >"$ast_metadata" 2>"$work/checked-$source_index.err"; then
        fail provenance "checked AST digest validation failed for $checked_source"
    fi
    mapfile -d '' -t checked_fields <"$ast_metadata"
    [[ ${#checked_fields[@]} -eq 4 ]] ||
        fail provenance "checked AST metadata is malformed for $checked_source"
    [[ -z "${checked_source_ids[${checked_fields[0]}]:-}" ]] ||
        fail provenance "checked sourceId is duplicated: ${checked_fields[0]}"
    [[ -z "${checked_namespaces[${checked_fields[1]}]:-}" ]] ||
        fail provenance "checked namespace is duplicated: ${checked_fields[1]}"
    checked_source_ids["${checked_fields[0]}"]=1
    checked_namespaces["${checked_fields[1]}"]=1
    mapfile -t fact_roots < <(
        awk -F '\t' -v source_id="${checked_fields[0]}" \
            '$2 == "relative-path" && $3 == "t" && $4 == source_id { print $1 }' \
            "$artifacts/source.facts"
    )
    [[ ${#fact_roots[@]} -eq 1 ]] ||
        fail provenance \
            "source.facts has no unique module for ${checked_fields[0]}"
    fact_root="${fact_roots[0]}"
    for fact_pair in \
        "relative-path=${checked_fields[0]}" \
        "namespace=${checked_fields[1]}" \
        "source-sha256=${checked_fields[2]}" \
        "checked-projection-sha256=${checked_fields[3]}"; do
        fact_predicate="${fact_pair%%=*}"
        fact_value="${fact_pair#*=}"
        fact_total="$(awk -F '\t' -v root="$fact_root" \
            -v predicate="$fact_predicate" \
            '$1 == root && $2 == predicate && $3 == "t" { count += 1 }
             END { print count + 0 }' "$artifacts/source.facts")"
        fact_count="$(awk -F '\t' -v root="$fact_root" \
            -v predicate="$fact_predicate" -v value="$fact_value" \
            '$1 == root && $2 == predicate && $3 == "t" && $4 == value { count += 1 }
             END { print count + 0 }' "$artifacts/source.facts")"
        [[ "$fact_total" == "1" && "$fact_count" == "1" ]] ||
            fail provenance \
                "source.facts does not preserve $fact_predicate for ${checked_fields[0]}"
    done
    checked_source_digest="$(sha256sum "$checked_source" | awk '{print $1}')"
    checked_ast_digest="$(sha256sum "$checked_ast" | awk '{print $1}')"
    report_lines+=("wasm-input-source-sha256 $checked_source_digest")
    report_lines+=("wasm-input-checked-ast-sha256 $checked_ast_digest")
done
facts_module_count="$(awk -F '\t' \
    '$2 == "form-kind" && $3 == "t" && $4 == "module-root" { count += 1 }
     END { print count + 0 }' "$artifacts/source.facts")"
[[ "$facts_module_count" == "${#checked_source_ids[@]}" &&
   "$facts_module_count" == "${#checked_namespaces[@]}" ]] ||
    fail provenance \
        "checked source/AST evidence does not cover every source.facts module root"

source_facts_actual="$(sha256sum "$artifacts/source.facts" | awk '{print $1}')"
mapfile -t facts_configuration < <(
    awk -F '\t' '$1 == "configuration" &&
                  $2 ~ /^source-facts-sha256=[0-9a-f]{64}$/ { print $2 }' \
        "$work/native.receipts.index"
)
[[ ${#facts_configuration[@]} -eq 1 &&
   "${facts_configuration[0]}" == "source-facts-sha256=$source_facts_actual" ]] ||
    fail provenance "source.facts does not match the Native Core receipt configuration"

read_single_printable_line "$artifacts/module.native-program.sha256" \
    native_digest "module.native-program.sha256"
[[ "$native_digest" =~ ^[0-9a-f]{64}$ ]] ||
    fail invalid-input "module.native-program.sha256 is not one lowercase SHA-256 digest"
native_actual="$(sha256sum "$artifacts/module.native-program" | awk '{print $1}')"
[[ "$native_actual" == "$native_digest" &&
   "sha256:$native_actual" == "$epoch_output" ]] ||
    fail provenance "frozen Native Core bytes, digest file, and epoch receipt disagree"

read_c17_field() {
    local kind="$1"
    local name="$2"
    local destination="$3"
    local rows=()
    if [[ "$kind" == "artifact" ]]; then
        mapfile -t rows < <(
            awk -F '\t' -v name="$name" \
                '$1 == "artifact" && $2 == name && NF == 3 { print $3 }' \
                "$work/c17.receipt.index"
        )
    else
        mapfile -t rows < <(
            awk -F '\t' -v kind="$kind" \
                '$1 == kind && NF == 2 { print $2 }' \
                "$work/c17.receipt.index"
        )
    fi
    [[ ${#rows[@]} -eq 1 && "${rows[0]}" =~ ^sha256:[0-9a-f]{64}$ ]] ||
        fail provenance "C17 receipt has no unique $kind ${name:-digest}"
    printf -v "$destination" '%s' "${rows[0]}"
}
if ! run_bounded "$validation_timeout" \
        bb -cp "$compiled" "$FINALIZER" c17-index \
        "$work/c17.receipt.index" "$artifacts/c17.receipt" \
        "$artifacts/native.receipts" "$artifacts/module.native-program" \
        "$artifacts" >"$work/c17-receipt.out" \
        2>"$work/c17-receipt.err"; then
    sed -n '1,80p' "$work/c17-receipt.err" >&2
    fail provenance "canonical C17 receipt validation failed"
fi
read_c17_field input "" c17_input
read_c17_field output "" c17_output
read_c17_field artifact module_0.h c17_header_expected
read_c17_field artifact module_0.c c17_source_expected
[[ "$c17_input" == "$epoch_output" ]] ||
    fail provenance "C17 receipt input does not equal the epoch receipt output"

c17_header_actual="$(sha256sum "$artifacts/module_0.h" | awk '{print $1}')"
c17_source_actual="$(sha256sum "$artifacts/module_0.c" | awk '{print $1}')"
[[ "sha256:$c17_header_actual" == "$c17_header_expected" ]] ||
    fail provenance "module_0.h does not match the compiler-owned C17 receipt"
[[ "sha256:$c17_source_actual" == "$c17_source_expected" ]] ||
    fail provenance "module_0.c does not match the compiler-owned C17 receipt"

report_lines+=("wasm-input-source-facts-sha256 $source_facts_actual")
report_lines+=("wasm-input-native-program-sha256 $native_actual")
report_lines+=("wasm-input-c17-header-sha256 $c17_header_actual")
report_lines+=("wasm-input-c17-source-sha256 $c17_source_actual")
report_lines+=("wasm-input-native-receipts-sha256 $(sha256sum "$artifacts/native.receipts" | awk '{print $1}')")
report_lines+=("wasm-input-c17-receipt-sha256 $(sha256sum "$artifacts/c17.receipt" | awk '{print $1}')")
report_lines+=("wasm-provenance PASS checked-projection-to-native-receipts-to-c17-receipt")

entry_link_flags=()
entry_compile_defines=()
entry_symbols=()
entry_lowered_abis=()
entry_call_arguments=()
adapter_needs_state=0
if [[ ${#entries[@]} -gt 0 ]]; then
    for entry_index in "${!entries[@]}"; do
        entry="${entries[$entry_index]}"
        entry_export="${entry_exports[$entry_index]}"
        entry_contract_error="$work/entry-contract-$entry_index.err"
        if ! run_bounded "$validation_timeout" \
                bb "$ENTRY_CONTRACT" "$entry" "${checked_source_args[@]}" \
                >"$work/entry-contract-$entry_index.out" \
                2>"$entry_contract_error"; then
            report_lines+=("wasm-entry-contract REFUSED $entry")
            entry_detail="$(sed -n '1s/^beagle wasm: //p' "$entry_contract_error")"
            fail unsupported-entry \
                "${entry_detail:-entry '$entry' failed source contract validation}"
        fi
        read_single_printable_line "$work/entry-contract-$entry_index.out" \
            entry_return "entry contract result"
        [[ "$entry_return" == "Int" ]] || {
            report_lines+=("wasm-entry-contract REFUSED $entry")
            fail unsupported-entry \
                "entry '$entry' has unsupported source return '$entry_return'"
        }

        source_entry_count="$(grep -Fxc -- "source-entry $entry" \
            "$artifacts/native.entry-map" || true)"
        [[ "$source_entry_count" == "1" ]] || {
            report_lines+=("wasm-entry-contract REFUSED $entry")
            fail unsupported-entry \
                "entry '$entry' is not uniquely bound to the frozen Core report"
        }
        entry_name="${entry##*/}"
        mapfile -t entry_rows < <(
            awk -v name="$entry_name" \
                '$1 == "lowered" && $2 ~ /^fn_[0-9]+$/ && $3 == name { print $2 }' \
                "$artifacts/native.entry-map"
        )
        [[ ${#entry_rows[@]} -eq 1 ]] || {
            report_lines+=("wasm-entry-contract REFUSED $entry")
            fail unsupported-entry \
                "entry '$entry' does not map to one unique lowered Core function"
        }
        function_index="${entry_rows[0]#fn_}"
        entry_symbol="native_m0_fn_$function_index"
        mapfile -t entry_prototypes < <(
            grep -E "^[A-Za-z_][A-Za-z0-9_]* ${entry_symbol}\\(.*\\);$" \
                "$artifacts/module_0.h" || true
        )
        [[ ${#entry_prototypes[@]} -eq 1 ]] || {
            report_lines+=("wasm-entry-contract REFUSED $entry")
            fail unsupported-entry \
                "entry '$entry' does not map to one unique generated C symbol ($entry_symbol)"
        }
        entry_prototype="${entry_prototypes[0]}"
        entry_pattern="^([A-Za-z_][A-Za-z0-9_]*)[[:space:]]+${entry_symbol}\\((.*)\\);$"
        if [[ "$entry_prototype" =~ $entry_pattern ]]; then
            entry_c_return="${BASH_REMATCH[1]}"
            entry_c_parameters="${BASH_REMATCH[2]}"
        else
            report_lines+=("wasm-entry-contract REFUSED $entry")
            fail unsupported-entry \
                "entry '$entry' generated malformed C ABI: $entry_prototype"
        fi
        # The four lowered resource shapes mirror beagle native-exe. The
        # adapter owns one instance arena and capability, so every shape still
        # exports the parameterless ()->i64 wasm ABI.
        case "$entry_c_parameters" in
            void)
                entry_lowered_abi="pure"
                entry_call="()"
                ;;
            "native_arena *arena")
                entry_lowered_abi="arena"
                entry_call="(&beagle_wasm_arena)"
                adapter_needs_state=1
                ;;
            "const native_capability *capability")
                entry_lowered_abi="capability"
                entry_call="(&beagle_wasm_capability)"
                adapter_needs_state=1
                ;;
            "native_arena *arena, const native_capability *capability")
                entry_lowered_abi="arena+capability"
                entry_call="(&beagle_wasm_arena, &beagle_wasm_capability)"
                adapter_needs_state=1
                ;;
            *)
                report_lines+=("wasm-entry-contract REFUSED $entry")
                fail unsupported-entry \
                    "entry '$entry' requires unsupported generated ABI parameters ($entry_c_parameters)"
                ;;
        esac
        [[ "$entry_c_return" =~ ^native_m0_type_[0-9]+$ ]] &&
            grep -Fqx "typedef int64_t $entry_c_return;" "$artifacts/module_0.h" || {
                report_lines+=("wasm-entry-contract REFUSED $entry")
                fail unsupported-entry \
                    "entry '$entry' Int result is not represented by the generated int64 ABI"
            }
        entry_symbols+=("$entry_symbol")
        entry_lowered_abis+=("$entry_lowered_abi")
        entry_call_arguments+=("$entry_call")
        entry_link_flags+=("-Wl,--export=$entry_export")
        report_lines+=("wasm-entry-contract PASS $entry source-ast-to-lowered-header")
        report_lines+=("wasm-entry-symbol $entry $entry_symbol")
        report_lines+=("wasm-entry-export $entry $entry_export")
        report_lines+=("wasm-entry-lowered-abi $entry $entry_lowered_abi")
    done
    report_lines+=("wasm-entry-abi parameterless-int-to-i64-v1")

    {
        cat <<'EOF'
/* Generated stable wasm-callable adapter for validated Beagle Int entries. */
#include "module_0.h"

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
EOF
        if [[ "$adapter_needs_state" == "1" ]]; then
            cat <<'EOF'

/* wasm-state-v1: one adapter-owned arena and capability live for the whole
   instance. The arena is fixed static storage initialized during _initialize
   (reactor constructors), is never reset by the adapter itself, and traps on
   exhaustion; the nonzero capability mirrors the beagle native-exe host. */
#define BEAGLE_WASM_ARENA_BYTES ((size_t)(16U * 1024U * 1024U))

static uint8_t beagle_wasm_arena_storage[BEAGLE_WASM_ARENA_BYTES];
static native_arena beagle_wasm_arena;
static const native_capability beagle_wasm_capability = { UINT64_C(1) };

__attribute__((constructor)) static void beagle_wasm_state_initialize(void) {
  native_arena_init(&beagle_wasm_arena, beagle_wasm_arena_storage,
                    BEAGLE_WASM_ARENA_BYTES);
}

int64_t beagle_wasm_arena_reset_v1(void) {
  native_arena_reset(&beagle_wasm_arena);
  return (int64_t)BEAGLE_WASM_ARENA_BYTES;
}

/* wasm-io-buffers-v1: live Buffer registrations in allocation order, read
   directly out of exported memory by the host. -1 marks an invalid index. */
int64_t beagle_wasm_buffer_count_v1(void) {
  return native_arena_buffer_registration_count(&beagle_wasm_arena);
}

int64_t beagle_wasm_buffer_address_v1(int64_t index) {
  const native_buffer *buffer =
      native_arena_buffer_registration_at(&beagle_wasm_arena, index);
  return (buffer == NULL) ? INT64_C(-1) : (int64_t)(uintptr_t)buffer->elements;
}

int64_t beagle_wasm_buffer_length_v1(int64_t index) {
  const native_buffer *buffer =
      native_arena_buffer_registration_at(&beagle_wasm_arena, index);
  return (buffer == NULL) ? INT64_C(-1) : buffer->length;
}

int64_t beagle_wasm_buffer_stride_v1(int64_t index) {
  const native_buffer *buffer =
      native_arena_buffer_registration_at(&beagle_wasm_arena, index);
  return (buffer == NULL) ? INT64_C(-1) : buffer->stride;
}
EOF
        fi
        cat <<'EOF'

/* wasm-io-env-v1: the host environment of a zero-import reactor is this
   exported record region, never an OS environment. Records are consecutive
   [u32le name-length][u32le value-length][name bytes][value bytes]; a zero
   name-length, exhausted capacity, or truncated record ends the sequence and
   the first matching name wins. The host writes records between entry calls;
   System/getenv inside the program reads them through this ABI. */
#define BEAGLE_WASM_ENV_BYTES ((size_t)(64U * 1024U))

static uint8_t beagle_wasm_env_records[BEAGLE_WASM_ENV_BYTES];

int64_t beagle_wasm_env_base_v1(void) {
  return (int64_t)(uintptr_t)beagle_wasm_env_records;
}

int64_t beagle_wasm_env_capacity_v1(void) {
  return (int64_t)BEAGLE_WASM_ENV_BYTES;
}

static uint32_t beagle_wasm_env_u32le(size_t offset) {
  return (uint32_t)beagle_wasm_env_records[offset] |
         ((uint32_t)beagle_wasm_env_records[offset + 1U] << 8) |
         ((uint32_t)beagle_wasm_env_records[offset + 2U] << 16) |
         ((uint32_t)beagle_wasm_env_records[offset + 3U] << 24);
}

bool native_host_environment_lookup_v0(
    native_arena *arena, const native_capability *capability,
    uint64_t name, uint64_t *out) {
  uint64_t name_length;
  const uint8_t *name_bytes;
  size_t cursor = 0U;

  if ((arena == NULL) || (capability == NULL) ||
      (capability->token == UINT64_C(0)) || (out == NULL)) {
    native_trap(NATIVE_TRAP_INVALID_ARGUMENT);
  }
  *out = UINT64_C(0);
  name_length = native_text_length(name);
  name_bytes = native_text_bytes(name);
  while ((cursor + 8U) <= BEAGLE_WASM_ENV_BYTES) {
    uint32_t record_name_length = beagle_wasm_env_u32le(cursor);
    uint32_t record_value_length = beagle_wasm_env_u32le(cursor + 4U);
    const uint8_t *record_name = beagle_wasm_env_records + cursor + 8U;
    if (record_name_length == UINT32_C(0)) {
      break;
    }
    if (((size_t)record_name_length >
         BEAGLE_WASM_ENV_BYTES - cursor - 8U) ||
        ((size_t)record_value_length >
         BEAGLE_WASM_ENV_BYTES - cursor - 8U - (size_t)record_name_length)) {
      break;
    }
    if (((uint64_t)record_name_length == name_length) &&
        (memcmp(record_name, name_bytes, (size_t)name_length) == 0)) {
      uint8_t *destination;
      uint64_t handle = native_text_alloc(arena, (uint64_t)record_value_length,
                                          &destination);
      if (record_value_length != UINT32_C(0)) {
        memcpy(destination, record_name + record_name_length,
               (size_t)record_value_length);
      }
      *out = handle;
      return true;
    }
    cursor += 8U + (size_t)record_name_length + (size_t)record_value_length;
  }
  return false;
}
EOF
        for entry_index in "${!entries[@]}"; do
            printf '\nint64_t %s(void) {\n  return (int64_t)%s%s;\n}\n' \
                "${entry_exports[$entry_index]}" \
                "${entry_symbols[$entry_index]}" \
                "${entry_call_arguments[$entry_index]}"
        done
    } >"$work/wasm.adapter.c"
    entry_compile_defines+=("-DNATIVE_HOST_ENVIRONMENT_LOOKUP_EXTERNAL")
    entry_link_flags+=(
        "-Wl,--export=beagle_wasm_env_base_v1"
        "-Wl,--export=beagle_wasm_env_capacity_v1"
    )
    report_lines+=("wasm-io-env env-records-v1 capacity-bytes=65536")
    report_lines+=("wasm-io-env-base beagle_wasm_env_base_v1")
    if [[ "$adapter_needs_state" == "1" ]]; then
        entry_link_flags+=(
            "-Wl,--export=beagle_wasm_arena_reset_v1"
            "-Wl,--export=beagle_wasm_buffer_count_v1"
            "-Wl,--export=beagle_wasm_buffer_address_v1"
            "-Wl,--export=beagle_wasm_buffer_length_v1"
            "-Wl,--export=beagle_wasm_buffer_stride_v1"
        )
        report_lines+=("wasm-state-arena static-bytes=16777216 lifetime=instance")
        report_lines+=("wasm-state-arena-reset beagle_wasm_arena_reset_v1")
        report_lines+=("wasm-state-capability constant-nonzero-token")
        report_lines+=("wasm-io-buffers registration-order-v1")
    fi
else
    printf '%s\n' '/* No executable source entry was requested. */' \
        >"$work/wasm.adapter.c"
fi

tool_error="$work/tool-error.txt"
tool_error_detail() {
    awk '!/^beagle supervisor:/ { print; exit }' "$tool_error"
}
tool_resolver="${BEAGLE_WASM_TOOL_RESOLVER:-$TOOLS}"
[[ -f "$tool_resolver" && -x "$tool_resolver" ]] ||
    fail missing-tool "Wasm tool resolver is unavailable: $tool_resolver"
if ! run_bounded "$validation_timeout" "$tool_resolver" cc \
        >"$work/cc-path.txt" 2>"$tool_error"; then
    report_lines+=("wasm-tool-cc unavailable")
    report_lines+=("wasm-tool-ld unresolved")
    report_lines+=("wasm-tool-runtime unresolved")
    fail missing-tool "$(tool_error_detail)"
fi
read_single_printable_line "$work/cc-path.txt" cc "wasm32-wasi compiler path"
printf -v cc_audit '%q' "$cc"
audit_lines+=("wasm-tool-cc-path-shell $cc_audit")

if ! run_bounded "$validation_timeout" "$tool_resolver" ld \
        >"$work/ld-path.txt" 2>"$tool_error"; then
    report_lines+=("wasm-tool-ld unavailable")
    report_lines+=("wasm-tool-runtime unresolved")
    fail missing-tool "$(tool_error_detail)"
fi
read_single_printable_line "$work/ld-path.txt" ld "wasm linker path"
printf -v ld_audit '%q' "$ld"
audit_lines+=("wasm-tool-ld-path-shell $ld_audit")

if ! run_bounded "$validation_timeout" "$tool_resolver" runtime \
        >"$work/runtime-path.txt" 2>"$tool_error"; then
    report_lines+=("wasm-tool-runtime unavailable")
    fail missing-tool "$(tool_error_detail)"
fi
read_single_printable_line "$work/runtime-path.txt" runtime \
    "WebAssembly runtime path"
printf -v runtime_audit '%q' "$runtime"
audit_lines+=("wasm-tool-runtime-path-shell $runtime_audit")

if ! run_bounded "$identity_timeout" "$cc" --version \
        >"$work/cc-version.txt" 2>"$work/cc-version.err"; then
    fail tool-identity \
        "wasm32-wasi compiler did not report its identity within ${identity_timeout}s"
fi
[[ -s "$work/cc-version.txt" && $(wc -c <"$work/cc-version.txt") -le 16384 ]] ||
    fail tool-identity "wasm32-wasi compiler identity is empty or exceeds 16 KiB"
cc_version="$(sha256sum "$work/cc-version.txt" | awk '{print $1}')"
report_lines+=("wasm-tool-cc-identity-sha256 $cc_version")

if ! run_bounded "$identity_timeout" "$ld" --version \
        >"$work/ld-version.txt" 2>"$work/ld-version.err"; then
    fail tool-identity \
        "wasm linker did not report its identity within ${identity_timeout}s"
fi
[[ -s "$work/ld-version.txt" && $(wc -c <"$work/ld-version.txt") -le 16384 ]] ||
    fail tool-identity "wasm linker identity is empty or exceeds 16 KiB"
ld_version="$(sha256sum "$work/ld-version.txt" | awk '{print $1}')"
report_lines+=("wasm-tool-ld-identity-sha256 $ld_version")

if ! run_bounded "$identity_timeout" "$runtime" --version \
        >"$work/runtime-version.txt" 2>"$work/runtime-version.err"; then
    fail tool-identity \
        "WebAssembly runtime did not report its identity within ${identity_timeout}s"
fi
[[ -s "$work/runtime-version.txt" &&
   $(wc -c <"$work/runtime-version.txt") -le 16384 ]] ||
    fail tool-identity "WebAssembly runtime identity is empty or exceeds 16 KiB"
runtime_version="$(sha256sum "$work/runtime-version.txt" | awk '{print $1}')"
report_lines+=("wasm-tool-runtime-identity-sha256 $runtime_version")

# Keep every generated Native Core function in the reactor. A constructor holds
# exact-type function pointers, making the generated functions (and only their
# reachable shim surface) linker roots. With one accepted entry, a separate
# narrow adapter exports only that entry's parameterless Int ABI. This avoids
# both dead-code elimination and --export-all's publication of wasi-libc and the
# whole shim.
mapfile -t native_symbols < <(
    sed -nE 's/.* (native_m0_fn_[0-9]+)\(.*/\1/p' \
        "$artifacts/module_0.h" | LC_ALL=C sort -u
)
{
    printf '#include "module_0.h"\n'
    native_index=0
    for native_symbol in "${native_symbols[@]}"; do
        printf 'static __typeof__(%s) *volatile beagle_wasm_root_%s = %s;\n' \
            "$native_symbol" "$native_index" "$native_symbol"
        native_index=$((native_index + 1))
    done
    printf '__attribute__((constructor)) static void beagle_wasm_retain_native_functions(void) {\n'
    native_index=0
    for _native_symbol in "${native_symbols[@]}"; do
        printf '  (void)beagle_wasm_root_%s;\n' "$native_index"
        native_index=$((native_index + 1))
    done
    printf '}\n'
} >"$work/wasm.retention.c"
report_lines+=("wasm-retained-native-functions ${#native_symbols[@]}")
report_lines+=("wasm-retention constructor-function-pointers")

compiler_input_names=(
    c17.receipt module_0.h module_0.c native.entry-map
    native_shim.h native_shim.c native_unicode15_data.h
    wasm.retention.c wasm.adapter.c wasm.entry-contract.clj wasm.seams.clj
    wasm.ast-verifier.rkt wasm.receipt-finalizer.clj wasm.materializer.sh
    wasm.supervisor.rkt
    wasm.cc-identity.txt wasm.ld-identity.txt wasm.runtime-identity.txt
)
compiler_input_paths=(
    "$artifacts/c17.receipt" "$artifacts/module_0.h" "$artifacts/module_0.c"
    "$artifacts/native.entry-map" "$SHIM/native_shim.h" "$SHIM/native_shim.c"
    "$SHIM/native_unicode15_data.h" "$work/wasm.retention.c"
    "$work/wasm.adapter.c" "$ENTRY_CONTRACT" "$SEAMS" "$AST_VERIFIER"
    "$FINALIZER" "$0" "$SUPERVISOR" "$work/cc-version.txt" "$work/ld-version.txt"
    "$work/runtime-version.txt"
)
wasm_aux_names=("${compiler_input_names[@]}")
compiler_snapshot_dir="$work/compiler-inputs"
mkdir -p "$compiler_snapshot_dir"
compiler_snapshot_paths=()
for input_index in "${!compiler_input_paths[@]}"; do
    compiler_snapshot_path="$compiler_snapshot_dir/${compiler_input_names[$input_index]}"
    cp -- "${compiler_input_paths[$input_index]}" "$compiler_snapshot_path"
    compiler_snapshot_paths+=("$compiler_snapshot_path")
done
compiler_input_digests=()
for input_index in "${!compiler_input_paths[@]}"; do
    compiler_input_digests+=("$(sha256sum "${compiler_snapshot_paths[$input_index]}" | awk '{print $1}')")
    [[ "$(sha256sum "${compiler_input_paths[$input_index]}" | awk '{print $1}')" == \
       "${compiler_input_digests[$input_index]}" ]] ||
        fail input-splice \
            "compiler input ${compiler_input_names[$input_index]} changed while snapshotted"
done

verify_compiler_inputs() {
    local input_index actual
    for input_index in "${!compiler_snapshot_paths[@]}"; do
        actual="$(sha256sum "${compiler_snapshot_paths[$input_index]}" | awk '{print $1}')"
        [[ "$actual" == "${compiler_input_digests[$input_index]}" ]] ||
            fail input-splice \
                "compiler snapshot ${compiler_input_names[$input_index]} changed during materialization"
    done
}

compile_once() {
    local ordinal="$1"
    local log="$work/compile-$ordinal.log"
    echo "beagle wasm: bootstrap compile $ordinal/2" >&2
    verify_compiler_inputs
    if ! run_bounded "$compile_timeout" \
        "$cc" \
        "-fuse-ld=$ld" \
        -mexec-model=reactor \
        -std=c17 -pedantic -Wall -Wextra -Werror \
        "${entry_compile_defines[@]}" \
        "${entry_link_flags[@]}" \
        -I "$compiler_snapshot_dir" \
        -o "$work/module_0.wasm" \
        "$compiler_snapshot_dir/module_0.c" \
        "$compiler_snapshot_dir/native_shim.c" \
        "$compiler_snapshot_dir/wasm.retention.c" \
        "$compiler_snapshot_dir/wasm.adapter.c" \
        >"$log" 2>&1; then
        sed -n '1,80p' "$log" >&2
        fail "compile-$ordinal" \
            "bootstrap C17-to-Wasm compile $ordinal failed or exceeded ${compile_timeout}s"
    fi
    [[ -s "$work/module_0.wasm" ]] ||
        fail "compile-$ordinal" "bootstrap compiler produced no WebAssembly artifact"
    cp "$work/module_0.wasm" "$work/module_0-$ordinal.wasm"
}

compile_once 1
compile_once 2
cmp -s "$work/module_0-1.wasm" "$work/module_0-2.wasm" ||
    fail nondeterministic "two identical bootstrap builds produced different WebAssembly bytes"
report_lines+=("wasm-determinism PASS repeated-identical-build")

if ! run_bounded "$validation_timeout" \
        bb "$SEAMS" "$work/module_0-1.wasm" >"$work/module_0.wasm.seams" \
        2>"$work/seams.err"; then
    sed -n '1,80p' "$work/seams.err" >&2
    fail invalid-artifact "could not read the WebAssembly import/export seam"
fi
awk '$1 == "export" { print }' "$work/module_0.wasm.seams" \
    >"$work/actual-exports.txt"
# Export names are ASCII by construction; the seam inventory carries them as
# lowercase hex so the comparison never trusts terminal-hostile bytes.
ascii_hex() {
    local text="$1" position
    for ((position = 0; position < ${#text}; position++)); do
        printf '%02x' "'${text:$position:1}"
    done
}
expected_function_exports=(_initialize)
if [[ ${#entries[@]} -gt 0 ]]; then
    expected_function_exports+=("${entry_exports[@]}")
    expected_function_exports+=(beagle_wasm_env_base_v1 beagle_wasm_env_capacity_v1)
    if [[ "$adapter_needs_state" == "1" ]]; then
        expected_function_exports+=(
            beagle_wasm_arena_reset_v1
            beagle_wasm_buffer_count_v1
            beagle_wasm_buffer_address_v1
            beagle_wasm_buffer_length_v1
            beagle_wasm_buffer_stride_v1
        )
    fi
fi
{
    for export_name in "${expected_function_exports[@]}"; do
        printf 'export func %s\n' "$(ascii_hex "$export_name")"
    done
    printf 'export memory %s\n' "$(ascii_hex "memory")"
} | LC_ALL=C sort >"$work/expected-exports.txt"
if ! cmp -s "$work/expected-exports.txt" "$work/actual-exports.txt"; then
    sed -n '1,80p' "$work/module_0.wasm.seams" >&2
    fail export-policy \
        "bootstrap reactor exported a surface beyond _initialize and memory"
fi
while read -r seam_kind seam_type seam_module seam_field seam_extra; do
    [[ "$seam_kind" =~ ^(import|export)$ &&
       "$seam_type" =~ ^(func|table|memory|global)$ ]] ||
        fail invalid-artifact "bootstrap seam carries an invalid kind tuple"
    if [[ "$seam_kind" == "import" ]]; then
        [[ -z "$seam_extra" && "$seam_module" =~ ^[0-9a-f]+$ &&
           "$seam_field" =~ ^[0-9a-f]+$ ]] ||
            fail invalid-artifact "bootstrap import seam is not a structured tuple"
        [[ "$seam_module" == "776173695f736e617073686f745f7072657669657731" ]] ||
            fail import-policy \
                "bootstrap reactor imported a module other than wasi_snapshot_preview1"
    else
        [[ -z "$seam_field" && -z "$seam_extra" &&
           "$seam_module" =~ ^[0-9a-f]+$ ]] ||
            fail invalid-artifact "bootstrap export seam is not a structured tuple"
    fi
done <"$work/module_0.wasm.seams"
import_count="$(awk '$1 == "import" { count += 1 } END { print count + 0 }' \
    "$work/module_0.wasm.seams")"
seams_digest="$(sha256sum "$work/module_0.wasm.seams" | awk '{print $1}')"
report_lines+=("wasm-seams module_0.wasm.seams")
report_lines+=("wasm-seams-sha256 $seams_digest")
report_lines+=("wasm-import-count $import_count")
report_lines+=("wasm-export-count $(( ${#expected_function_exports[@]} + 1 ))")
for export_name in "${expected_function_exports[@]}"; do
    report_lines+=("wasm-export func $export_name")
done
report_lines+=("wasm-export memory memory")

if [[ ${#entries[@]} -gt 0 ]]; then
    # Each entry is invoked in its own fresh instance, so every recorded
    # result is a function of that entry alone, not of invocation order.
    for entry_index in "${!entries[@]}"; do
        entry="${entries[$entry_index]}"
        entry_export="${entry_exports[$entry_index]}"
        echo "beagle wasm: bounded source entry invocation ($entry)" >&2
        if ! run_bounded "$instantiate_timeout" \
            "$runtime" run --invoke "$entry_export" "$work/module_0-1.wasm" \
            >"$work/runtime-$entry_index.stdout" \
            2>"$work/runtime-$entry_index.stderr"; then
            sed -n '1,80p' "$work/runtime-$entry_index.stderr" >&2
            fail invoke-entry \
                "entry '$entry' invocation failed or exceeded ${instantiate_timeout}s"
        fi
        mapfile -t entry_outputs < <(tr -d '\r' <"$work/runtime-$entry_index.stdout")
        [[ ${#entry_outputs[@]} -eq 1 &&
           "${entry_outputs[0]}" =~ ^(0|-?[1-9][0-9]*)$ ]] || {
            sed -n '1,80p' "$work/runtime-$entry_index.stdout" >&2
            fail entry-result \
                "entry '$entry' did not produce exactly one canonical i64 result"
        }
        report_lines+=("wasm-entry-result $entry ${entry_outputs[0]}")
    done
    report_lines+=("wasm-validation PASS source-entries-invoked")
    report_lines+=("wasm-validation-boundary executable-entries-v1-only")
else
    echo "beagle wasm: bounded reactor instantiation" >&2
    if ! run_bounded "$instantiate_timeout" \
        "$runtime" run "$work/module_0-1.wasm" \
        >"$work/runtime.stdout" 2>"$work/runtime.stderr"; then
        sed -n '1,80p' "$work/runtime.stderr" >&2
        fail instantiate \
            "reactor instantiation failed or exceeded ${instantiate_timeout}s"
    fi
    report_lines+=("wasm-validation PASS reactor-instantiate-initialize-only")
    report_lines+=("wasm-validation-boundary no-source-entry-requested")
fi

wasm_digest="$(sha256sum "$work/module_0-1.wasm" | awk '{print $1}')"
report_lines+=("wasm-artifact module_0.wasm")
report_lines+=("wasm-artifact-sha256 $wasm_digest")
verify_compiler_inputs
for input_index in "${!compiler_input_paths[@]}"; do
    cp -- "${compiler_snapshot_paths[$input_index]}" \
        "$artifacts/.${compiler_input_names[$input_index]}.$$"
done
verify_compiler_inputs
wasm_receipt_args=(
    wasm-receipt "$work/wasm.receipt" "$epoch_commit"
    --configuration "c17-output=$c17_output"
    --configuration "abi=wasm32"
    --configuration "entry-count=${#entries[@]}"
    --configuration "cc-identity-sha256=sha256:$cc_version"
    --configuration "ld-identity-sha256=sha256:$ld_version"
    --configuration "runtime-identity-sha256=sha256:$runtime_version"
    --configuration "export-policy=$(if [[ ${#entries[@]} -gt 0 ]]; then
        printf entries-v1
    else
        printf reactor-v0
    fi)"
)
for entry_index in "${!entries[@]}"; do
    wasm_receipt_args+=(--configuration
        "entry-$entry_index=${entries[$entry_index]}=${entry_lowered_abis[$entry_index]}")
done
for input_index in "${!compiler_input_paths[@]}"; do
    wasm_receipt_args+=(--input "${compiler_input_names[$input_index]}" \
                       "$artifacts/.${compiler_input_names[$input_index]}.$$")
done
wasm_receipt_args+=(
    --artifact module_0.wasm "$work/module_0-1.wasm"
    --artifact module_0.wasm.seams "$work/module_0.wasm.seams"
)
if ! run_bounded "$validation_timeout" \
        bb -cp "$compiled" "$FINALIZER" "${wasm_receipt_args[@]}" \
        >"$work/wasm-receipt.out" 2>"$work/wasm-receipt.err"; then
    sed -n '1,80p' "$work/wasm-receipt.err" >&2
    fail receipt-finalization "could not construct canonical Wasm PassReceiptV0"
fi
[[ -s "$work/wasm.receipt" ]] ||
    fail receipt-finalization "Wasm receipt finalizer produced no receipt"
wasm_receipt_digest="$(sha256sum "$work/wasm.receipt" | awk '{print $1}')"
report_lines+=("wasm-receipt wasm.receipt")
report_lines+=("wasm-receipt-sha256 $wasm_receipt_digest")
report_lines+=("wasm-result PASS")

cp "$work/module_0-1.wasm" "$artifact_temporary"
printf '%s\n' "$wasm_digest" >"$digest_temporary"
cp "$work/module_0.wasm.seams" "$seams_temporary"
cp "$work/wasm.receipt" "$wasm_receipt_temporary"
write_report_temporaries

publish_wasm_file() {
    local temporary="$1"
    local destination="$2"
    local boundary="$3"
    mv -f -- "$temporary" "$destination"
    if [[ "${BEAGLE_WASM_PUBLISH_FAILPOINT:-}" == "$boundary" ]]; then
        kill -TERM "$$"
    fi
}

publish_wasm_file "$artifact_temporary" "$artifact" after-artifact
publish_wasm_file "$digest_temporary" "$digest_file" after-digest
publish_wasm_file "$seams_temporary" "$seams" after-seams
publish_wasm_file "$wasm_receipt_temporary" "$wasm_receipt" after-receipt
for input_index in "${!compiler_input_names[@]}"; do
    publish_wasm_file "$artifacts/.${compiler_input_names[$input_index]}.$$" \
        "$artifacts/${compiler_input_names[$input_index]}" \
        "after-input-${compiler_input_names[$input_index]}"
done
publish_wasm_file "$audit_temporary" "$audit" after-audit
publish_wasm_file "$report_temporary" "$report" after-report
output_committed=1

echo "beagle wasm: wrote deterministic bootstrap reactor $artifact" >&2 || true
