#!/bin/bash

set -u

IPZ_DIR="plugins/international-press-zone"
TRUST_DEPTH=5
TRUST_REF="refs/remotes/origin/master"
GATE_PRECOMMIT_SRC=".dev-config/hooks/pre-commit"
GATE_REFERENCE_SRC=".dev-config/hooks/reference-transaction"
GATE_HELPER_SRC=".dev-config/bin/ipz-remote-php-gate"

# Print the blob OIDs of $1 across the last TRUST_DEPTH landed versions on TRUST_REF.
trusted_blobs_for_path() {
    local path=$1 commit blob
    git rev-list -n "$TRUST_DEPTH" "$TRUST_REF" -- "$path" 2>/dev/null |
    while read -r commit; do
        blob=$(git rev-parse -q --verify "$commit:$path" 2>/dev/null) || continue
        printf '%s\n' "$blob"
    done
}

# Installed file $1 must byte-match some landed version of source path $2.
installed_blob_is_trusted() {
    local active=$1 tracked=$2 active_oid blob matched=1
    active_oid=$(git hash-object --no-filters "$active" 2>/dev/null) || return 1
    while read -r blob; do
        [ -n "$blob" ] && [ "$active_oid" = "$blob" ] && matched=0
    done < <(trusted_blobs_for_path "$tracked")
    return "$matched"
}

GATE_PATH="$GATE_HELPER_SRC"
PRECOMMIT_PATH="$GATE_PRECOMMIT_SRC"
REFERENCE_PATH="$GATE_REFERENCE_SRC"
TRUSTED_INSTALL_NAME="ipz-remote-gate-hooks"
ESLINT_TOOLCHAIN_DIR=".dev-config/node_modules"
AST_GREP_COMPAT_PATH="node_modules/.bin/ast-grep"
AST_TOOLCHAIN_PACKAGE_SHA="0f1805432c39a6cb878e258d0558964e005fbe2373493ded4e7f8dfdc367b7d7"
AST_TOOLCHAIN_LOCK_SHA="fa879faf4b56d9a25f8e970ea6037ff2144fc84810c516feec0fe62c91fb2aaf"
LOCAL_GATE="/home/user/.claude/bin/local-gate"
CONTRACT_FILES=(
    "$GATE_PATH"
    "$PRECOMMIT_PATH"
    "$REFERENCE_PATH"
    ".dev-config/package.json"
    ".dev-config/package-lock.json"
    "$IPZ_DIR/composer.json"
    "$IPZ_DIR/composer.lock"
    "$IPZ_DIR/phpcs.xml.dist"
    "$IPZ_DIR/phpcs-baseline.json"
    "$IPZ_DIR/tools/phpcs-baseline.php"
    "$IPZ_DIR/phpstan.neon.dist"
    "$IPZ_DIR/phpstan-baseline.neon"
    ".slopgate/config.toml"
    ".slopgate/rules/project.json"
    ".slopgate/suppressions.json"
)

# A PHPStan baseline entry whose error can no longer occur (its code path was
# removed upstream) blocks every commit touching the file it names, while the
# immutable-policy rule blocks removing the dead entry: a landing deadlock.
# Permit ONLY strictly deletion-shaped diffs of the line-oriented PHPStan
# baseline; any added or modified line still fails closed, so debt can never
# be hidden through this path.
policy_change_is_pure_deletion() {
    local parent_tree=$1 current_tree=$2 path=$3 added deleted rest
    case "$path" in
        */phpstan-baseline.neon) ;;
        *) return 1 ;;
    esac
    read -r added deleted rest < <(git -C "${TREE_REPO_ROOT:-.}" diff --numstat "$parent_tree" "$current_tree" -- "$path" 2>/dev/null) || return 1
    [ -n "$added" ] && [ -n "$deleted" ] || return 1
    case "$added$deleted" in *[!0-9]*) return 1 ;; esac
    [ "$added" -eq 0 ] && [ "$deleted" -gt 0 ]
}

IMMUTABLE_POLICY_FILES=(
    "$IPZ_DIR/composer.json"
    "$IPZ_DIR/composer.lock"
    "$IPZ_DIR/phpcs.xml.dist"
    "$IPZ_DIR/phpcs-baseline.json"
    "$IPZ_DIR/tools/phpcs-baseline.php"
    "$IPZ_DIR/phpstan.neon.dist"
    "$IPZ_DIR/phpstan-baseline.neon"
    ".slopgate/config.toml"
    ".slopgate/rules/project.json"
    ".slopgate/suppressions.json"
)

CLAIM_TTL=300

fail() {
    echo "IPZ remote gate: $*" >&2
    return 1
}

hash_identity() {
    local digest
    digest=$(sha256sum <<<"$1") || return 1
    printf '%s\n' "${digest%% *}"
}

tree_regular_blob_oid() {
    local tree=$1 path=$2 record mode type oid listed
    record=$(git -C "${TREE_REPO_ROOT:-.}" ls-tree "$tree" -- "$path" 2>/dev/null) || return 1
    [ -n "$record" ] || return 1
    IFS=$' \t' read -r mode type oid listed <<<"$record"
    case "$mode" in 100644|100755) ;; *) return 1 ;; esac
    [ "$type" = blob ] && [ "$listed" = "$path" ] || return 1
    claim_oid "$oid" || return 1
    printf '%s\n' "$oid"
}

validate_ast_toolchain_policy() {
    local tree=$1 path expected oid tmp digest rc
    for path in .dev-config/package.json .dev-config/package-lock.json; do
        case "$path" in
            .dev-config/package.json) expected=$AST_TOOLCHAIN_PACKAGE_SHA ;;
            .dev-config/package-lock.json) expected=$AST_TOOLCHAIN_LOCK_SHA ;;
        esac
        oid=$(tree_regular_blob_oid "$tree" "$path") || return 1
        tmp=$(mktemp) || return 1
        git -C "${TREE_REPO_ROOT:-.}" cat-file blob "$oid" >"$tmp"
        rc=$?
        if [ "$rc" -ne 0 ]; then rm -f "$tmp"; return "$rc"; fi
        digest=$(sha256sum "$tmp") || { rm -f "$tmp"; return 1; }
        rm -f "$tmp" || return 1
        [ "${digest%% *}" = "$expected" ] || return 1
    done
}

TRUSTED_INSTALL_DIR=""
TRUSTED_PRECOMMIT_PATH=""
TRUSTED_HELPER_PATH=""
REFERENCE_PATH_RESOLVED=""
TRUSTED_PRECOMMIT_SHA=""
TRUSTED_HELPER_SHA=""
REFERENCE_SHA=""
TRUSTED_INSTALL_IDENTITY=""
capture_trusted_install_snapshot() {
    local repo_root=$1 git_dir=$2 common install_top hooks_path rc path metadata digest identities=""
    common=$(git rev-parse --git-common-dir 2>/dev/null) || return 1
    common=$(realpath "$common" 2>/dev/null) || return 1
    git_dir=$(realpath "$git_dir" 2>/dev/null) || return 1
    hooks_path=$(git config --path --get core.hooksPath 2>/dev/null)
    rc=$?
    [ "$rc" -eq 0 ] && [ -n "$hooks_path" ] || return 1
    if [ "${hooks_path#/}" = "$hooks_path" ]; then hooks_path="$repo_root/$hooks_path"; fi
    [ ! -L "$hooks_path" ] || return 1
    hooks_path=$(realpath "$hooks_path" 2>/dev/null) || return 1
    install_top="$common/$TRUSTED_INSTALL_NAME"
    [ -d "$install_top" ] && [ ! -L "$install_top" ] || return 1
    [ "$(realpath "$install_top" 2>/dev/null)" = "$install_top" ] || return 1
    [ "$(stat -c %u "$install_top" 2>/dev/null)" = "$(id -u)" ] || return 1
    [ "$(stat -c %a "$install_top" 2>/dev/null)" = 700 ] || return 1
    case "$hooks_path" in
        "$install_top")
            [ -d "$hooks_path" ] && [ "$(stat -c %a "$hooks_path" 2>/dev/null)" = 700 ] || return 1
            ;;
        "$install_top"/*)
            [ "$(dirname "$hooks_path")" = "$install_top" ] || return 1
            [[ "$(basename "$hooks_path")" =~ ^[0-9a-f]{12}$ ]] || return 1
            [ -d "$hooks_path" ] && [ "$(stat -c %a "$hooks_path" 2>/dev/null)" = 500 ] || return 1
            ;;
        *) return 1 ;;
    esac
    [ "$(stat -c %u "$hooks_path" 2>/dev/null)" = "$(id -u)" ] || return 1
    TRUSTED_INSTALL_DIR="$hooks_path"
    metadata=$(stat -c '%d:%i:%u:%a' "$hooks_path" 2>/dev/null) || return 1
    identities="$hooks_path:$metadata"

    TRUSTED_PRECOMMIT_PATH="$hooks_path/pre-commit"
    TRUSTED_HELPER_PATH="$hooks_path/ipz-remote-php-gate"
    REFERENCE_PATH_RESOLVED="$hooks_path/reference-transaction"
    for path in "$TRUSTED_PRECOMMIT_PATH" "$TRUSTED_HELPER_PATH" "$REFERENCE_PATH_RESOLVED"; do
        [ -f "$path" ] && [ ! -L "$path" ] && [ -x "$path" ] || return 1
        [ "$(realpath "$path" 2>/dev/null)" = "$path" ] || return 1
        [ "$(stat -c %u "$path" 2>/dev/null)" = "$(id -u)" ] || return 1
        [ "$(stat -c %a "$path" 2>/dev/null)" = 500 ] || return 1
        case "$path" in
            "$TRUSTED_PRECOMMIT_PATH") installed_blob_is_trusted "$path" "$GATE_PRECOMMIT_SRC" || return 1 ;;
            "$TRUSTED_HELPER_PATH") installed_blob_is_trusted "$path" "$GATE_HELPER_SRC" || return 1 ;;
            "$REFERENCE_PATH_RESOLVED") installed_blob_is_trusted "$path" "$GATE_REFERENCE_SRC" || return 1 ;;
        esac
        digest=$(sha256sum "$path" 2>/dev/null) || return 1
        digest=${digest%% *}
        claim_hex_length "$digest" 64 || return 1
        metadata=$(stat -c '%d:%i:%u:%a' "$path" 2>/dev/null) || return 1
        identities="$identities:$path:$metadata:$digest"
        case "$path" in
            "$TRUSTED_PRECOMMIT_PATH") TRUSTED_PRECOMMIT_SHA=$digest ;;
            "$TRUSTED_HELPER_PATH") TRUSTED_HELPER_SHA=$digest ;;
            "$REFERENCE_PATH_RESOLVED") REFERENCE_SHA=$digest ;;
        esac
    done
    [ "$(realpath "${BASH_SOURCE[0]}" 2>/dev/null)" = "$TRUSTED_HELPER_PATH" ] || return 1
    TRUSTED_INSTALL_IDENTITY=$(hash_identity "$identities") || return 1
}

claim_hex_length() {
    case "$1" in *[!0-9a-f]*|'') return 1 ;; esac
    [ "${#1}" -eq "$2" ]
}

claim_oid() {
    claim_hex_length "$1" 40 || claim_hex_length "$1" 64
}

claim_parent_vector() {
    local vector=$1 expected_head=$2 parent
    local -a parents
    case "$vector" in ,*|*,|*,,*) return 1 ;; esac
    IFS=, read -r -a parents <<<"$vector"
    [ ${#parents[@]} -gt 0 ] && [ ${#parents[@]} -le 32 ] || return 1
    [ "${parents[0]}" = "$expected_head" ] || return 1
    for parent in "${parents[@]}"; do claim_oid "$parent" || return 1; done
}

expected_parent_vector() {
    local head=$1 merge_head parent extra count=1 vector=$1
    merge_head=$(git rev-parse --git-path MERGE_HEAD 2>/dev/null) || return 1
    if [ ! -e "$merge_head" ] && [ ! -L "$merge_head" ]; then
        printf '%s\n' "$vector"
        return 0
    fi
    [ -f "$merge_head" ] && [ ! -L "$merge_head" ] || return 1
    while IFS=' ' read -r parent extra; do
        [ -n "$parent" ] && [ -z "${extra:-}" ] && claim_oid "$parent" || return 1
        count=$((count + 1))
        [ "$count" -le 32 ] || return 1
        vector="$vector,$parent"
    done <"$merge_head"
    [ "$count" -gt 1 ] || return 1
    printf '%s\n' "$vector"
}

burn_claim_file() {
    local path=$1 burned
    [ ! -L "$path" ] || return 1
    burned="$path.burned.$$.$RANDOM"
    mv "$path" "$burned" || return 1
    rm -f "$burned"
}

claim_is_stale() {
    local path=$1 expected_repo=$2 expected_worktree=$3 key value now
    local version="" head="" tree="" parents="" contract="" hook="" nonce="" repo="" worktree="" created="" ref_state="" ref="" new="" lines=0 new_count=0
    local seen_version=0 seen_head=0 seen_tree=0 seen_parents=0 seen_contract=0 seen_hook=0 seen_nonce=0
    local seen_repo=0 seen_worktree=0 seen_created=0 seen_ref_state=0 seen_ref=0

    [ ! -L "$path" ] && [ -f "$path" ] || return 1
    [ "$(stat -c %u "$path" 2>/dev/null)" = "$(id -u)" ] || return 1
    [ "$(stat -c %a "$path" 2>/dev/null)" = 600 ] || return 1
    while IFS='=' read -r key value; do
        lines=$((lines + 1))
        [ "$lines" -le 13 ] || return 1
        case "$key" in
            version) [ "$seen_version" -eq 0 ] || return 1; version=$value; seen_version=1 ;;
            head) [ "$seen_head" -eq 0 ] || return 1; head=$value; seen_head=1 ;;
            tree) [ "$seen_tree" -eq 0 ] || return 1; tree=$value; seen_tree=1 ;;
            parents) [ "$seen_parents" -eq 0 ] || return 1; parents=$value; seen_parents=1 ;;
            contract) [ "$seen_contract" -eq 0 ] || return 1; contract=$value; seen_contract=1 ;;
            hook) [ "$seen_hook" -eq 0 ] || return 1; hook=$value; seen_hook=1 ;;
            nonce) [ "$seen_nonce" -eq 0 ] || return 1; nonce=$value; seen_nonce=1 ;;
            repo) [ "$seen_repo" -eq 0 ] || return 1; repo=$value; seen_repo=1 ;;
            worktree) [ "$seen_worktree" -eq 0 ] || return 1; worktree=$value; seen_worktree=1 ;;
            created) [ "$seen_created" -eq 0 ] || return 1; created=$value; seen_created=1 ;;
            ref_state) [ "$seen_ref_state" -eq 0 ] || return 1; ref_state=$value; case "$value" in symbolic|detached) ;; *) return 1 ;; esac; seen_ref_state=1 ;;
            ref) [ "$seen_ref" -eq 0 ] || return 1; ref=$value; case "$value" in HEAD|refs/*) ;; *) return 1 ;; esac; seen_ref=1 ;;
            new) new_count=$((new_count + 1)); [ "$new_count" -eq 1 ] || return 1; new=$value ;;
            *) return 1 ;;
        esac
    done <"$path"
    [ "$version" = 2 ] && [ "$seen_head" -eq 1 ] && [ "$seen_tree" -eq 1 ] && [ "$seen_parents" -eq 1 ] \
        && [ "$seen_contract" -eq 1 ] && [ "$seen_hook" -eq 1 ] && [ "$seen_nonce" -eq 1 ] && [ "$seen_repo" -eq 1 ] \
        && [ "$seen_worktree" -eq 1 ] && [ "$seen_created" -eq 1 ] && [ "$seen_ref_state" -eq 1 ] \
        && [ "$seen_ref" -eq 1 ] || return 1
    claim_oid "$head" && claim_oid "$tree" && claim_parent_vector "$parents" "$head" || return 1
    claim_hex_length "$contract" 64 && claim_hex_length "$hook" 64 && claim_hex_length "$nonce" 64 || return 1
    claim_hex_length "$repo" 64 && claim_hex_length "$worktree" 64 || return 1
    if [ "$new_count" -eq 1 ]; then claim_oid "$new" || return 1; fi
    case "$ref_state:$ref" in symbolic:refs/*|detached:HEAD) ;; *) return 1 ;; esac
    [ "$repo" = "$expected_repo" ] && [ "$worktree" = "$expected_worktree" ] || return 1
    case "$created" in *[!0-9]*|'') return 1 ;; esac
    case "$created" in 0|[1-9]*) ;; *) return 1 ;; esac
    [ "${#created}" -le 12 ] || return 1
    now=$(date +%s) || return 1
    [ "$created" -le "$now" ] && [ $((now - created)) -gt "$CLAIM_TTL" ]
}

reference_claim_slot_is_available() (
    local repo_root=$1 git_dir=$2 common_dir repo_identity worktree_identity claim inflight lock existing
    common_dir=$(git rev-parse --git-common-dir 2>/dev/null) || return 1
    common_dir=$(realpath "$common_dir" 2>/dev/null) || return 1
    repo_root=$(realpath "$repo_root" 2>/dev/null) || return 1
    git_dir=$(realpath "$git_dir" 2>/dev/null) || return 1
    repo_identity=$(hash_identity "$common_dir:$repo_root") || return 1
    worktree_identity=$(hash_identity "$git_dir:$repo_root") || return 1
    claim="$git_dir/ipz-remote-gate.claim"
    inflight="$git_dir/ipz-remote-gate.inflight"
    lock="$git_dir/ipz-remote-gate.claim.lock"
    exec 7>"$lock" || return 1
    flock -w 30 7 || return 1
    for existing in "$claim" "$inflight"; do
        if [ -e "$existing" ] || [ -L "$existing" ]; then
            if claim_is_stale "$existing" "$repo_identity" "$worktree_identity"; then
                burn_claim_file "$existing" || return 1
            else
                fail "an existing live or unknown reference claim blocks this commit"
                return 1
            fi
        fi
    done
)

create_reference_claim() (
    local repo_root=$1 git_dir=$2 head=$3 tree=$4 parents=$5 contract=$6 hook=$7 nonce=$8 ref_state=$9 expected_ref=${10}
    local common_dir repo_identity worktree_identity claim inflight lock temp created existing
    common_dir=$(git rev-parse --git-common-dir 2>/dev/null) || return 1
    common_dir=$(realpath "$common_dir" 2>/dev/null) || return 1
    repo_root=$(realpath "$repo_root" 2>/dev/null) || return 1
    git_dir=$(realpath "$git_dir" 2>/dev/null) || return 1
    repo_identity=$(hash_identity "$common_dir:$repo_root") || return 1
    worktree_identity=$(hash_identity "$git_dir:$repo_root") || return 1
    claim="$git_dir/ipz-remote-gate.claim"
    inflight="$git_dir/ipz-remote-gate.inflight"
    lock="$git_dir/ipz-remote-gate.claim.lock"
    exec 8>"$lock" || return 1
    flock -w 30 8 || return 1
    for existing in "$claim" "$inflight"; do
        if [ -e "$existing" ] || [ -L "$existing" ]; then
            if claim_is_stale "$existing" "$repo_identity" "$worktree_identity"; then
                burn_claim_file "$existing" || return 1
            else
                fail "an existing live or unknown reference claim blocks this commit"
                return 1
            fi
        fi
    done
    created=$(date +%s) || return 1
    temp="$claim.tmp.$nonce"
    [ ! -e "$temp" ] && [ ! -L "$temp" ] || return 1
    (
        set -C
        umask 077
        printf 'version=2\nhead=%s\ntree=%s\nparents=%s\ncontract=%s\nhook=%s\nnonce=%s\nrepo=%s\nworktree=%s\ncreated=%s\nref_state=%s\nref=%s\n' \
            "$head" "$tree" "$parents" "$contract" "$hook" "$nonce" "$repo_identity" "$worktree_identity" "$created" "$ref_state" "$expected_ref" >"$temp"
    ) || { rm -f "$temp"; return 1; }
    chmod 600 "$temp" || { rm -f "$temp"; return 1; }
    mv "$temp" "$claim" || { rm -f "$temp"; return 1; }
)

burn_pending_reference_claim() (
    local git_dir=$1 claim lock
    git_dir=$(realpath "$git_dir" 2>/dev/null) || return 1
    claim="$git_dir/ipz-remote-gate.claim"
    lock="$git_dir/ipz-remote-gate.claim.lock"
    exec 7>"$lock" || return 1
    flock -w 30 7 || return 1
    if [ -e "$claim" ] || [ -L "$claim" ]; then
        burn_claim_file "$claim" || return 1
    fi
)

is_phpcs_path() {
    case "$1" in
        includes/*.php|examples/*.php|international-press-zone.php|uninstall.php) return 0 ;;
        *) return 1 ;;
    esac
}

is_phpstan_path() {
    case "$1" in
        includes/*.php|international-press-zone.php|uninstall.php) return 0 ;;
        *) return 1 ;;
    esac
}

is_slopgate_path() {
    case "$1" in
        includes/*.php|includes/*.js|includes/*.jsx|includes/*.scss|admin/src/*.php|admin/src/*.js|admin/src/*.jsx|admin/src/*.scss) return 0 ;;
        *) return 1 ;;
    esac
}

collect_applicable_paths() {
    local output=$1
    local status old_path path relative
    : >"$output" || return 1

    while IFS= read -r -d '' status; do
        case "$status" in
            R*|C*)
                IFS= read -r -d '' old_path || return 1
                IFS= read -r -d '' path || return 1
                ;;
            *)
                IFS= read -r -d '' path || return 1
                ;;
        esac
        case "$status" in
            A*|C*|M*|R*|T*) ;;
            *) continue ;;
        esac
        case "$path" in
            "$IPZ_DIR"/*) ;;
            *) continue ;;
        esac
        relative=${path#"$IPZ_DIR"/}
        case "/$relative/" in
            */../*|*/./*|*//*) return 1 ;;
        esac
        if is_phpcs_path "$relative" || is_phpstan_path "$relative" || is_slopgate_path "$relative"; then
            printf '%s\0' "$relative" >>"$output" || return 1
        fi
    done
}

validate_remote_contract_file() {
    local repo_root=$1 path=$2 resolved
    [ -f "$repo_root/$path" ] && [ ! -L "$repo_root/$path" ] || return 1
    resolved=$(realpath "$repo_root/$path" 2>/dev/null) || return 1
    [ "$resolved" = "$repo_root/$path" ]
}

validate_remote_runner_metadata() {
    local path=$1 value size mode owner group
    local LC_ALL=C
    [ -f "$path" ] && [ ! -L "$path" ] || return 1
    owner=$(stat -c %u "$path" 2>/dev/null) || return 1
    mode=$(stat -c %a "$path" 2>/dev/null) || return 1
    size=$(stat -c %s "$path" 2>/dev/null) || return 1
    [ "$owner" = "$(id -u)" ] || return 1
    case "$mode" in
        600|644) ;;
        660|664)
            group=$(stat -c %g "$path" 2>/dev/null) || return 1
            [ "$group" = "$(id -g)" ] || return 1
            ;;
        *) return 1 ;;
    esac
    value=$(<"$path") || return 1
    [ "$size" -eq "${#value}" ] || return 1
    case "${path##*/}" in
        .rb-epoch)
            [ "$size" -gt 0 ] && [ "$size" -le 32 ] || return 1
            case "$value" in *[!0-9]*) return 1 ;; esac
            ;;
        .rb-origin)
            [ "$size" -gt 0 ] && [ "$size" -le 4096 ] || return 1
            case "$value" in /*) ;; *) return 1 ;; esac
            ;;
        .rb-lockhash)
            [ "$size" -eq 64 ] || return 1
            case "$value" in *[!0-9a-f]*) return 1 ;; esac
            ;;
        *) return 1 ;;
    esac
}

capture_remote_state() {
    local repo_root=$1 expected_tree=$2 allow_vendor=$3 output=$4 compare=${5-} stable_output=${6-} stable_compare=${7-} stable_scope=${8-all}
    local tree path kind metadata digest resolved target paths dependency_root stable_path seen_epoch=0 seen_origin=0
    tree=$(git -C "$repo_root" write-tree 2>/dev/null) || return 1
    [ "$tree" = "$expected_tree" ] || return 1
    git -C "$repo_root" diff --quiet --no-ext-diff -- || return 1
    git -C "$repo_root" diff --cached --quiet --no-ext-diff -- || return 1
    paths=$(mktemp) || return 1
    git -C "$repo_root" ls-files --others -z >"$paths" || { rm -f "$paths"; return 1; }
    : >"$output" || { rm -f "$paths"; return 1; }
    if [ -n "$stable_output" ]; then : >"$stable_output" || { rm -f "$paths"; return 1; }; fi
    while IFS= read -r -d '' path; do
        stable_path=0
        case "$path" in
            .rb-epoch) validate_remote_runner_metadata "$repo_root/$path" || { rm -f "$paths"; return 1; }; seen_epoch=1; stable_path=1 ;;
            .rb-origin) validate_remote_runner_metadata "$repo_root/$path" || { rm -f "$paths"; return 1; }; seen_origin=1; stable_path=1 ;;
            .rb-lockhash) validate_remote_runner_metadata "$repo_root/$path" || { rm -f "$paths"; return 1; }; stable_path=1 ;;
            "$IPZ_DIR/vendor"/*) [ "$allow_vendor" -eq 1 ] || { rm -f "$paths"; return 1; } ;;
            "$ESLINT_TOOLCHAIN_DIR"/*) [ "$stable_scope" = all ] && stable_path=1 ;;
            "$AST_GREP_COMPAT_PATH") [ "$stable_scope" = all ] && stable_path=1 ;;
            *) rm -f "$paths"; return 1 ;;
        esac
        if [ -L "$repo_root/$path" ]; then
            case "$path" in
                "$IPZ_DIR/vendor"/*) dependency_root="$repo_root/$IPZ_DIR/vendor" ;;
                "$ESLINT_TOOLCHAIN_DIR"/*|"$AST_GREP_COMPAT_PATH") dependency_root="$repo_root/$ESLINT_TOOLCHAIN_DIR" ;;
                *) rm -f "$paths"; return 1 ;;
            esac
            resolved=$(realpath "$repo_root/$path" 2>/dev/null) || { rm -f "$paths"; return 1; }
            case "$resolved" in "$dependency_root"/*) ;; *) rm -f "$paths"; return 1 ;; esac
            target=$(readlink "$repo_root/$path") || { rm -f "$paths"; return 1; }
            metadata=$(stat -c '%F:%a:%u:%s' "$repo_root/$path" 2>/dev/null) || { rm -f "$paths"; return 1; }
            digest=$(sha256sum <<<"$target") || { rm -f "$paths"; return 1; }
            kind=symlink
        elif [ -f "$repo_root/$path" ]; then
            metadata=$(stat -c '%F:%a:%u:%s' "$repo_root/$path" 2>/dev/null) || { rm -f "$paths"; return 1; }
            digest=$(sha256sum "$repo_root/$path" 2>/dev/null) || { rm -f "$paths"; return 1; }
            kind=file
        else
            rm -f "$paths"
            return 1
        fi
        printf '%s\0%s:%s\0%s\0' "$path" "$kind" "$metadata" "${digest%% *}" >>"$output" || { rm -f "$paths"; return 1; }
        if [ "$stable_path" -eq 1 ] && [ -n "$stable_output" ]; then
            printf '%s\0%s:%s\0%s\0' "$path" "$kind" "$metadata" "${digest%% *}" >>"$stable_output" || { rm -f "$paths"; return 1; }
        fi
    done <"$paths"
    rm -f "$paths" || return 1
    [ "$seen_epoch" -eq 1 ] && [ "$seen_origin" -eq 1 ] || return 1
    if [ -n "$compare" ]; then
        cmp -s "$compare" "$output" || return 1
    fi
    if [ -n "$stable_compare" ]; then
        [ -n "$stable_output" ] && cmp -s "$stable_compare" "$stable_output" || return 1
    fi
}

remote_gate() (
    [ "$#" -eq 3 ] || { fail "invalid remote invocation"; return 2; }
    [ "${GATE0_REMOTE_ACTIVE-}" = 1 ] || { fail "canonical remote execution context is missing"; return 2; }
    umask 077
    local nonce=$1 expected_tree=$2 expected_contract=$3
    local repo_root actual_tree actual_contract manifest status old_path path relative resolved rc
    local state_before state_after_setup state_step state_stable_before state_stable_after state_metadata_before state_metadata_after trusted_gate trusted_phpcs policy parent_oid current_oid trusted_oid
    local ast_grep ast_grep_resolved ast_grep_package ast_grep_native system_name machine_name compat_dir compat_target
    local allow_vendor_state=0
    local -a cleanup_files=()
    local -a phpcs_files=() phpstan_files=() slopgate_files=()
    trap 'rm -f "${cleanup_files[@]}"' EXIT

    case "$nonce" in (*[!0-9a-f]*|'') fail "invalid invocation nonce"; return 2 ;; esac
    [ "${#nonce}" -eq 64 ] || { fail "invalid invocation nonce"; return 2; }
    case "$expected_tree" in (*[!0-9a-f]*|'') fail "invalid staged tree OID"; return 2 ;; esac
    case "$expected_contract" in (*[!0-9a-f]*|'') fail "invalid contract digest"; return 2 ;; esac
    [ "${#expected_contract}" -eq 64 ] || { fail "invalid contract digest"; return 2; }

    repo_root=$(git rev-parse --show-toplevel 2>/dev/null) || { fail "remote checkout is not a Git worktree"; return 1; }
    TREE_REPO_ROOT=$repo_root
    [ "$PWD" = "$repo_root/$IPZ_DIR" ] || { fail "remote command did not start in the lock-owning plugin directory"; return 1; }
    trusted_gate="$repo_root/$GATE_PATH"
    trusted_phpcs="$repo_root/$IPZ_DIR/tools/phpcs-baseline.php"
    validate_remote_contract_file "$repo_root" "$GATE_PATH" \
        && validate_remote_contract_file "$repo_root" "$IPZ_DIR/tools/phpcs-baseline.php" \
        || { fail "remote policy source is missing, symlinked, or escaped"; return 1; }
    [ "$(realpath "${BASH_SOURCE[0]}" 2>/dev/null)" = "$trusted_gate" ] || { fail "remote gate did not execute from the staged contract path"; return 1; }
    actual_tree=$(git rev-parse 'HEAD^{tree}' 2>/dev/null) || { fail "remote staged tree is unavailable"; return 1; }
    [ "$actual_tree" = "$expected_tree" ] || { fail "remote tree does not match the staged tree"; return 1; }
    actual_contract=$(sha256sum "$trusted_gate" 2>/dev/null) || { fail "trusted gate contract cannot be hashed"; return 1; }
    actual_contract=${actual_contract%% *}
    [ "$actual_contract" = "$expected_contract" ] || { fail "remote gate contract digest does not match"; return 1; }

    local required
    for required in "${CONTRACT_FILES[@]}"; do
        validate_remote_contract_file "$repo_root" "$required" || {
            fail "required contract file is missing, symlinked, or escaped: $required"
            return 1
        }
    done
    validate_ast_toolchain_policy HEAD || { fail "staged AST toolchain policy does not match the trusted gate contract"; return 1; }
    for policy in "${IMMUTABLE_POLICY_FILES[@]}"; do
        parent_oid=$(tree_regular_blob_oid 'HEAD^' "$policy") || { fail "trusted parent policy is missing or unsafe: $policy"; return 1; }
        current_oid=$(tree_regular_blob_oid HEAD "$policy") || { fail "staged policy is missing or unsafe: $policy"; return 1; }
        if [ "$current_oid" != "$parent_oid" ]; then
            policy_change_is_pure_deletion 'HEAD^' HEAD "$policy" || { fail "staged analyzer policy changes are not allowed: $policy"; return 1; }
        fi
    done
    parent_oid=$(tree_regular_blob_oid 'HEAD^' "$IPZ_DIR/tools/phpcs-baseline.php") || return 1
    trusted_oid=$(git hash-object "$trusted_phpcs" 2>/dev/null) || return 1
    [ "$trusted_oid" = "$parent_oid" ] || {
        fail "trusted PHPCS bootstrap does not match the immutable parent policy"
        return 1
    }
    state_before=$(mktemp) || { fail "cannot create remote state snapshot"; return 1; }
    cleanup_files+=("$state_before")
    state_after_setup=$(mktemp) || { fail "cannot create remote setup snapshot"; return 1; }
    cleanup_files+=("$state_after_setup")
    state_step=$(mktemp) || { fail "cannot create remote analysis snapshot"; return 1; }
    cleanup_files+=("$state_step")
    state_stable_before=$(mktemp) || { fail "cannot create remote runner metadata snapshot"; return 1; }
    cleanup_files+=("$state_stable_before")
    state_stable_after=$(mktemp) || { fail "cannot create remote runner metadata comparison"; return 1; }
    cleanup_files+=("$state_stable_after")
    state_metadata_before=$(mktemp) || { fail "cannot create pre-npm metadata snapshot"; return 1; }
    cleanup_files+=("$state_metadata_before")
    state_metadata_after=$(mktemp) || { fail "cannot create post-npm metadata snapshot"; return 1; }
    cleanup_files+=("$state_metadata_after")
    capture_remote_state "$repo_root" "$expected_tree" 0 "$state_before" "" "$state_stable_before" || {
        rm -f "$state_before" "$state_after_setup" "$state_step" "$state_stable_before" "$state_stable_after"
        fail "remote repository state is not pristine before setup"
        return 1
    }

    manifest=$(mktemp) || { fail "cannot create remote path manifest"; return 1; }
    cleanup_files+=("$manifest" "$manifest.diff")
    chmod 600 "$manifest" || { rm -f "$manifest"; fail "cannot protect remote path manifest"; return 1; }
    if ! git diff-tree --no-commit-id --name-status -z -r -M 'HEAD^' HEAD >"$manifest.diff"; then
        rm -f "$manifest" "$manifest.diff"
        fail "cannot derive staged paths from the synthetic commit"
        return 1
    fi

    while IFS= read -r -d '' status; do
        case "$status" in
            R*|C*)
                IFS= read -r -d '' old_path || { rm -f "$manifest" "$manifest.diff"; fail "malformed rename record"; return 1; }
                IFS= read -r -d '' path || { rm -f "$manifest" "$manifest.diff"; fail "malformed rename record"; return 1; }
                ;;
            *)
                IFS= read -r -d '' path || { rm -f "$manifest" "$manifest.diff"; fail "malformed path record"; return 1; }
                ;;
        esac
        case "$status" in A*|C*|M*|R*|T*) ;; *) continue ;; esac
        case "$path" in "$IPZ_DIR"/*) ;; *) continue ;; esac
        relative=${path#"$IPZ_DIR"/}
        if ! is_phpcs_path "$relative" && ! is_phpstan_path "$relative" && ! is_slopgate_path "$relative"; then
            continue
        fi
        case "/$relative/" in
            */../*|*/./*|*//*)
                rm -f "$manifest" "$manifest.diff"
                fail "unsafe staged gate path"
                return 1
                ;;
        esac
        [ -f "$repo_root/$path" ] && [ ! -L "$repo_root/$path" ] || {
            rm -f "$manifest" "$manifest.diff"
            fail "staged gate candidate is not a regular file: $relative"
            return 1
        }
        resolved=$(realpath "$repo_root/$path" 2>/dev/null) || {
            rm -f "$manifest" "$manifest.diff"
            fail "cannot resolve staged gate candidate: $relative"
            return 1
        }
        case "$resolved" in "$repo_root/$IPZ_DIR"/*) ;; *)
            rm -f "$manifest" "$manifest.diff"
            fail "staged gate candidate escapes the plugin directory"
            return 1
            ;;
        esac
        if is_phpcs_path "$relative"; then phpcs_files+=("$relative"); fi
        if is_phpstan_path "$relative"; then phpstan_files+=("$relative"); fi
        if is_slopgate_path "$relative"; then slopgate_files+=("$path"); fi
    done <"$manifest.diff"
    rm -f "$manifest" "$manifest.diff"

    [ $(( ${#phpcs_files[@]} + ${#phpstan_files[@]} + ${#slopgate_files[@]} )) -gt 0 ] || { fail "staged IPZ changes have no applicable remote gate"; return 1; }

    if [ ${#slopgate_files[@]} -gt 0 ]; then
        command -v npm >/dev/null 2>&1 || { fail "npm is unavailable for slopgate setup"; return 1; }
        capture_remote_state "$repo_root" "$expected_tree" 0 "$state_step" "$state_before" "$state_metadata_before" "" metadata || { fail "remote repository state changed before slopgate dependency setup"; return 1; }
        npm --version
        rc=$?
        [ "$rc" -eq 0 ] || { fail "npm version check failed (exit $rc)"; return "$rc"; }
        sha256sum "$repo_root/.dev-config/package-lock.json"
        rc=$?
        [ "$rc" -eq 0 ] || { fail "AST toolchain lock digest failed (exit $rc)"; return "$rc"; }
        npm ci --prefix "$repo_root/.dev-config" --ignore-scripts --no-audit --no-fund
        rc=$?
        [ "$rc" -eq 0 ] || { fail "AST toolchain installation failed (exit $rc)"; return "$rc"; }
        system_name=$(uname -s 2>/dev/null) || { fail "AST toolchain platform cannot be identified"; return 1; }
        machine_name=$(uname -m 2>/dev/null) || { fail "AST toolchain architecture cannot be identified"; return 1; }
        case "$system_name:$machine_name" in
            Linux:x86_64|Linux:amd64) ast_grep_package=@ast-grep/cli-linux-x64-gnu ;;
            Linux:aarch64|Linux:arm64) ast_grep_package=@ast-grep/cli-linux-arm64-gnu ;;
            *) fail "AST toolchain platform is unsupported: $system_name/$machine_name"; return 1 ;;
        esac
        ast_grep_native="$repo_root/$ESLINT_TOOLCHAIN_DIR/$ast_grep_package/ast-grep"
        [ -f "$ast_grep_native" ] && [ ! -L "$ast_grep_native" ] && [ -x "$ast_grep_native" ] || { fail "lock-owned native ast-grep executable is missing, symlinked, or not executable"; return 1; }
        ast_grep_resolved=$(realpath "$ast_grep_native" 2>/dev/null) || { fail "lock-owned native ast-grep executable cannot be resolved"; return 1; }
        [ "$ast_grep_resolved" = "$ast_grep_native" ] || { fail "lock-owned native ast-grep executable escapes its package path"; return 1; }

        compat_dir="$repo_root/${AST_GREP_COMPAT_PATH%/*}"
        mkdir -p "$compat_dir" || { fail "repository-local ast-grep compatibility directory cannot be created"; return 1; }
        [ -d "$repo_root/node_modules" ] && [ ! -L "$repo_root/node_modules" ] \
            && [ "$(realpath "$repo_root/node_modules" 2>/dev/null)" = "$repo_root/node_modules" ] \
            && [ -d "$compat_dir" ] && [ ! -L "$compat_dir" ] \
            && [ "$(realpath "$compat_dir" 2>/dev/null)" = "$compat_dir" ] \
            || { fail "repository-local ast-grep compatibility directory is unsafe"; return 1; }
        ast_grep="$repo_root/$AST_GREP_COMPAT_PATH"
        compat_target="../../$ESLINT_TOOLCHAIN_DIR/$ast_grep_package/ast-grep"
        ln -s "$compat_target" "$ast_grep" || { fail "repository-local ast-grep compatibility link cannot be created"; return 1; }
        [ "$(readlink "$ast_grep" 2>/dev/null)" = "$compat_target" ] || { fail "repository-local ast-grep compatibility link has an unexpected target"; return 1; }
        ast_grep_resolved=$(realpath "$ast_grep" 2>/dev/null) || { fail "repository-local ast-grep compatibility link cannot be resolved"; return 1; }
        [ "$ast_grep_resolved" = "$ast_grep_native" ] || { fail "repository-local ast-grep compatibility link escapes the lock-owned native package"; return 1; }
        capture_remote_state "$repo_root" "$expected_tree" 0 "$state_before" "" "$state_metadata_after" "$state_metadata_before" metadata || { fail "remote repository state changed outside slopgate dependency setup boundaries"; return 1; }
        capture_remote_state "$repo_root" "$expected_tree" 0 "$state_step" "$state_before" "$state_stable_before" || { fail "remote repository state changed after slopgate dependency setup"; return 1; }
        "$ast_grep_native" --version
        rc=$?
        [ "$rc" -eq 0 ] || { fail "native ast-grep version check failed (exit $rc)"; return "$rc"; }
    fi

    echo "IPZ remote gate: tree=$expected_tree contract=$expected_contract"
    if [ $(( ${#phpcs_files[@]} + ${#phpstan_files[@]} )) -gt 0 ]; then
        command -v composer >/dev/null 2>&1 || { fail "Composer is unavailable"; return 1; }
        command -v php >/dev/null 2>&1 || { fail "PHP is unavailable"; return 1; }
        local php_version
        php_version=$(php --version)
        rc=$?
        [ "$rc" -eq 0 ] || { fail "PHP version check failed (exit $rc)"; return "$rc"; }
        php_version=${php_version%%$'\n'*}
        printf '%s\n' "$php_version"
        composer --version
        rc=$?
        [ "$rc" -eq 0 ] || { fail "Composer version check failed (exit $rc)"; return "$rc"; }
        sha256sum composer.lock
        rc=$?
        [ "$rc" -eq 0 ] || { fail "composer.lock digest failed (exit $rc)"; return "$rc"; }
        composer install --no-interaction --no-progress --prefer-dist --no-scripts --no-plugins
        rc=$?
        [ "$rc" -eq 0 ] || { fail "Composer install failed (exit $rc)"; return "$rc"; }
        [ -x vendor/bin/phpcs ] || { fail "installed PHPCS executable is missing"; return 1; }
        [ -x vendor/bin/phpstan ] || { fail "installed PHPStan executable is missing"; return 1; }
        local phpcs_standard_dir phpcs_standard_resolved
        local phpstan_wordpress_extension phpstan_wordpress_resolved phpstan_config
        for phpcs_standard_dir in vendor/wp-coding-standards/wpcs vendor/phpcsstandards/phpcsextra vendor/phpcsstandards/phpcsutils; do
            [ -d "$phpcs_standard_dir" ] && [ ! -L "$phpcs_standard_dir" ] || { fail "installed PHPCS standard directory is missing or symlinked: $phpcs_standard_dir"; return 1; }
            phpcs_standard_resolved=$(realpath "$phpcs_standard_dir" 2>/dev/null) || { fail "installed PHPCS standard directory cannot be resolved: $phpcs_standard_dir"; return 1; }
            case "$phpcs_standard_resolved" in "$repo_root/$IPZ_DIR/vendor"/*) ;; *) fail "installed PHPCS standard directory escapes vendor: $phpcs_standard_dir"; return 1 ;; esac
        done
        vendor/bin/phpcs --config-set installed_paths ../../wp-coding-standards/wpcs,../../phpcsstandards/phpcsextra,../../phpcsstandards/phpcsutils
        rc=$?
        [ "$rc" -eq 0 ] || { fail "PHPCS standard registration failed (exit $rc)"; return "$rc"; }
        vendor/bin/phpcs --standard=WordPress -e >/dev/null
        rc=$?
        [ "$rc" -eq 0 ] || { fail "WordPress PHPCS standard is unavailable after registration (exit $rc)"; return "$rc"; }
        phpstan_wordpress_extension=vendor/szepeviktor/phpstan-wordpress/extension.neon
        [ -f "$phpstan_wordpress_extension" ] && [ ! -L "$phpstan_wordpress_extension" ] || { fail "installed PHPStan WordPress extension is missing or symlinked"; return 1; }
        phpstan_wordpress_resolved=$(realpath "$phpstan_wordpress_extension" 2>/dev/null) || { fail "installed PHPStan WordPress extension cannot be resolved"; return 1; }
        [ "$phpstan_wordpress_resolved" = "$repo_root/$IPZ_DIR/$phpstan_wordpress_extension" ] || { fail "installed PHPStan WordPress extension escapes its lock-owned path"; return 1; }
        phpstan_config=vendor/ipz-phpstan.neon
        rm -f "$phpstan_config" || { fail "existing PHPStan extension registration cannot be removed safely"; return 1; }
        (umask 077 && printf '%s\n' 'includes:' '    - ../phpstan.neon.dist' '    - szepeviktor/phpstan-wordpress/extension.neon' >"$phpstan_config") || { fail "PHPStan extension registration failed"; return 1; }
        [ -f "$phpstan_config" ] && [ ! -L "$phpstan_config" ] || { fail "PHPStan extension registration is not a regular file"; return 1; }
        allow_vendor_state=1
        capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_after_setup" "" "$state_stable_after" "$state_stable_before" || {
            fail "remote repository state changed outside dependency setup boundaries"
            return 1
        }
        vendor/bin/phpcs --version
        rc=$?
        [ "$rc" -eq 0 ] || { fail "PHPCS version check failed (exit $rc)"; return "$rc"; }
        vendor/bin/phpstan --version
        rc=$?
        [ "$rc" -eq 0 ] || { fail "PHPStan version check failed (exit $rc)"; return "$rc"; }
        capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_step" "$state_after_setup" || {
            fail "remote repository state changed during analyzer setup verification"
            return 1
        }

        if [ ${#phpcs_files[@]} -gt 0 ]; then
            capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_step" "$state_after_setup" || {
                fail "remote repository state changed before PHPCS"
                return 1
            }
            php "$trusted_phpcs" check "${phpcs_files[@]}"
            rc=$?
            [ "$rc" -eq 0 ] || { fail "PHPCS failed (exit $rc)"; return "$rc"; }
            capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_step" "$state_after_setup" || {
                fail "remote repository state changed during PHPCS"
                return 1
            }
        fi
        if [ ${#phpstan_files[@]} -gt 0 ]; then
            capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_step" "$state_after_setup" || {
                fail "remote repository state changed before PHPStan"
                return 1
            }
            vendor/bin/phpstan analyse --configuration="$phpstan_config" --no-progress -- "${phpstan_files[@]}"
            rc=$?
            [ "$rc" -eq 0 ] || { fail "PHPStan failed (exit $rc)"; return "$rc"; }
            capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_step" "$state_after_setup" || {
                fail "remote repository state changed during PHPStan"
                return 1
            }
        fi
    fi

    if [ "$allow_vendor_state" -eq 0 ]; then
        cp "$state_before" "$state_after_setup" || { fail "cannot retain the pre-analysis state snapshot"; return 1; }
    fi
    if [ ${#slopgate_files[@]} -gt 0 ]; then
        command -v slopgate >/dev/null 2>&1 || { fail "slopgate is unavailable"; return 1; }
        slopgate --version
        rc=$?
        [ "$rc" -eq 0 ] || { fail "slopgate version check failed (exit $rc)"; return "$rc"; }
        local slopgate_file
        for slopgate_file in "${slopgate_files[@]}"; do
            capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_step" "$state_after_setup" || {
                fail "remote repository state changed before slopgate"
                return 1
            }
            (cd "$repo_root" && slopgate --file "$slopgate_file" --tier commit --config "$repo_root/.slopgate/config.toml")
            rc=$?
            [ "$rc" -eq 0 ] || { fail "slopgate failed for $slopgate_file (exit $rc)"; return "$rc"; }
            capture_remote_state "$repo_root" "$expected_tree" "$allow_vendor_state" "$state_step" "$state_after_setup" || {
                fail "remote repository state changed during slopgate"
                return 1
            }
        done
    fi

    rm -f "$state_before" "$state_after_setup" "$state_step" "$state_stable_before" "$state_stable_after"
    printf 'IPZ_REMOTE_PHP_GATE_OK nonce=%s tree=%s contract=%s\n' "$nonce" "$expected_tree" "$expected_contract"
)

cleanup_root=""
cleanup_worktree=""
cleanup_repo_root=""
cleanup() {
    local rc=${1:-$?}
    trap - EXIT HUP INT TERM
    if [ -n "$cleanup_worktree" ]; then
        env -u GIT_DIR -u GIT_INDEX_FILE -u GIT_WORK_TREE -u GIT_PREFIX \
            git -C "$cleanup_repo_root" worktree remove --force "$cleanup_worktree" >/dev/null 2>&1 || rc=1
        if [ -e "$cleanup_worktree" ]; then
            rm -rf "$cleanup_worktree" >/dev/null 2>&1 || true
            rc=1
        fi
        local listed_line found=0
        env -u GIT_DIR -u GIT_INDEX_FILE -u GIT_WORK_TREE -u GIT_PREFIX \
            git -C "$cleanup_repo_root" worktree list --porcelain >"$cleanup_root/worktrees.after" 2>/dev/null || rc=1
        while IFS= read -r listed_line; do
            [ "$listed_line" = "worktree $cleanup_worktree" ] && found=1
        done <"$cleanup_root/worktrees.after"
        [ "$found" -eq 0 ] || rc=1
    fi
    if [ -n "$cleanup_root" ]; then
        rm -rf "$cleanup_root" >/dev/null 2>&1 || rc=1
        [ ! -e "$cleanup_root" ] || rc=1
    fi
    exit "$rc"
}

local_gate() {
    local claim_only=0
    if [ "$#" -eq 1 ] && [ "$1" = --claim-only ]; then
        claim_only=1
    elif [ "$#" -ne 0 ]; then
        fail "this gate accepts only --claim-only as a local argument"
        return 2
    fi
    local repo_root git_dir lock_file head_before parents_before parents_after tree_before tree_after nonce key synthetic_commit
    local head_ref_before head_ref_after ref_state_before ref_state_after
    local manifest_before manifest_after output expected_sentinel contract_copy contract_digest rc count exact_count line
    local install_dir_before install_dir_after install_identity_before install_identity_after
    local precommit_path_before helper_path_before reference_path_before
    local precommit_sha_before helper_sha_before reference_sha_before source_copy listed_line found
    local -a config_oids=() after_oids=()

    umask 077
    repo_root=$(git rev-parse --show-toplevel 2>/dev/null) || { fail "not inside a Git worktree"; return 1; }
    cleanup_repo_root=$repo_root
    cd "$repo_root" || { fail "cannot enter repository root"; return 1; }
    git_dir=$(git rev-parse --absolute-git-dir 2>/dev/null) || { fail "cannot resolve worktree Git directory"; return 1; }
    lock_file="$git_dir/ipz-remote-php-gate.lock"
    exec 9>"$lock_file" || { fail "cannot open worktree gate lock"; return 1; }
    flock -w 600 9 || { fail "timed out waiting for the worktree gate lock"; return 1; }
    reference_claim_slot_is_available "$repo_root" "$git_dir" || {
        fail "cannot reserve a fresh reference claim slot"
        return 1
    }

    head_before=$(git rev-parse --verify HEAD 2>/dev/null) || { fail "HEAD is unavailable"; return 1; }
    parents_before=$(expected_parent_vector "$head_before") || { fail "cannot determine the exact commit parent vector"; return 1; }
    if head_ref_before=$(git symbolic-ref -q HEAD 2>/dev/null); then
        ref_state_before=symbolic
    else
        rc=$?
        [ "$rc" -eq 1 ] || { fail "cannot determine checked-out ref state"; return 1; }
        ref_state_before=detached
        head_ref_before=HEAD
    fi
    tree_before=$(git write-tree 2>/dev/null) || { fail "cannot record the staged tree"; return 1; }
    cleanup_root=$(mktemp -d "$git_dir/ipz-remote-php-gate.XXXXXX") || { fail "cannot create private gate directory"; return 1; }
    chmod 700 "$cleanup_root" || { fail "cannot protect private gate directory"; return 1; }
    cleanup_worktree=""
    trap 'cleanup $?' EXIT
    trap 'cleanup 129' HUP
    trap 'cleanup 130' INT
    trap 'cleanup 143' TERM

    manifest_before="$cleanup_root/applicable.before"
    if ! git diff --cached --name-status -z --diff-filter=ACMRT -M >"$cleanup_root/diff.before"; then
        fail "cannot read staged paths"
        return 1
    fi
    if ! collect_applicable_paths "$manifest_before" <"$cleanup_root/diff.before"; then
        fail "cannot derive applicable staged IPZ PHP paths"
        return 1
    fi
    if [ "$claim_only" -eq 1 ]; then
        [ ! -s "$manifest_before" ] || { fail "claim-only mode found applicable staged IPZ candidates"; return 1; }
    else
        [ -s "$manifest_before" ] || { fail "no applicable staged IPZ candidates"; return 1; }
    fi

    local file oid parent_oid path name active
    for file in "${CONTRACT_FILES[@]}"; do
        oid=$(tree_regular_blob_oid "$tree_before" "$file") || { fail "required staged contract file is missing or unsafe: $file"; return 1; }
        config_oids+=("$oid")
    done
    validate_ast_toolchain_policy "$tree_before" || { fail "staged AST toolchain policy does not match the trusted gate contract"; return 1; }
    for file in "${IMMUTABLE_POLICY_FILES[@]}"; do
        oid=$(tree_regular_blob_oid "$tree_before" "$file") || { fail "staged analyzer policy is missing or unsafe: $file"; return 1; }
        parent_oid=$(tree_regular_blob_oid "$head_before" "$file") || { fail "trusted analyzer policy is missing or unsafe: $file"; return 1; }
        if [ "$oid" != "$parent_oid" ]; then
            policy_change_is_pure_deletion "$head_before" "$tree_before" "$file" || { fail "staged analyzer policy changes are not allowed: $file"; return 1; }
        fi
    done
    contract_copy="$cleanup_root/contract"
    git show "$tree_before:$GATE_PATH" >"$contract_copy"
    rc=$?
    [ "$rc" -eq 0 ] || { fail "cannot read the staged gate contract"; return 1; }
    contract_digest=$(sha256sum "$contract_copy") || { fail "cannot hash the staged gate contract"; return 1; }
    contract_digest=${contract_digest%% *}

    capture_trusted_install_snapshot "$repo_root" "$git_dir" || {
        fail "cannot capture the trusted gate installation"
        return 1
    }
    install_dir_before=$TRUSTED_INSTALL_DIR
    install_identity_before=$TRUSTED_INSTALL_IDENTITY
    precommit_path_before=$TRUSTED_PRECOMMIT_PATH
    helper_path_before=$TRUSTED_HELPER_PATH
    reference_path_before=$REFERENCE_PATH_RESOLVED
    precommit_sha_before=$TRUSTED_PRECOMMIT_SHA
    helper_sha_before=$TRUSTED_HELPER_SHA
    reference_sha_before=$REFERENCE_SHA
    nonce=$(od -An -N32 -tx1 /dev/urandom 2>/dev/null) || { fail "cannot generate a gate nonce"; return 1; }
    nonce=${nonce//[[:space:]]/}
    [ "${#nonce}" -eq 64 ] || { fail "gate nonce generation was incomplete"; return 1; }
    if [ "$claim_only" -eq 0 ]; then
        cleanup_worktree="$cleanup_root/worktree"
        key="ipz-remote-php-$nonce"
    printf '%s\n' 'IPZ staged-tree remote PHP gate' >"$cleanup_root/message"
    synthetic_commit=$(git commit-tree "$tree_before" -p "$head_before" -F "$cleanup_root/message" 2>/dev/null) || { fail "cannot create the synthetic staged-tree commit"; return 1; }
    env -u GIT_DIR -u GIT_INDEX_FILE -u GIT_WORK_TREE -u GIT_PREFIX \
        git -C "$repo_root" worktree add --quiet --detach "$cleanup_worktree" "$synthetic_commit"
    rc=$?
    [ "$rc" -eq 0 ] || { fail "cannot materialize the synthetic staged tree"; return 1; }

    output="$cleanup_root/remote.output"
    (
        cd "$cleanup_worktree/$IPZ_DIR" || exit 125
        env -u GIT_DIR -u GIT_INDEX_FILE -u GIT_WORK_TREE -u GIT_PREFIX \
            "$LOCAL_GATE" --remote-only --key "$key" -- \
            ../../"$GATE_PATH" --remote "$nonce" "$tree_before" "$contract_digest"
    ) >"$output" 2>&1
    rc=$?
    while IFS= read -r line || [ -n "$line" ]; do printf '%s\n' "$line"; done <"$output"
    [ "$rc" -eq 0 ] || { fail "canonical remote runner failed (exit $rc)"; return 1; }

    expected_sentinel="IPZ_REMOTE_PHP_GATE_OK nonce=$nonce tree=$tree_before contract=$contract_digest"
    count=0
    exact_count=0
    while IFS= read -r line || [ -n "$line" ]; do
        case "$line" in IPZ_REMOTE_PHP_GATE_OK*) count=$((count + 1)) ;; esac
        [ "$line" = "$expected_sentinel" ] && exact_count=$((exact_count + 1))
    done <"$output"
    [ "$count" -eq 1 ] || { fail "remote completion sentinel count is $count, expected 1"; return 1; }
    [ "$exact_count" -eq 1 ] || { fail "remote completion sentinel is missing, malformed, or conflicting"; return 1; }

    env -u GIT_DIR -u GIT_INDEX_FILE -u GIT_WORK_TREE -u GIT_PREFIX \
        git -C "$repo_root" worktree remove --force "$cleanup_worktree" >/dev/null 2>&1
    rc=$?
    [ "$rc" -eq 0 ] || { fail "cannot remove the synthetic staged-tree worktree before issuing a claim"; return 1; }
    [ ! -e "$cleanup_worktree" ] || { fail "synthetic staged-tree worktree remained after removal"; return 1; }
    env -u GIT_DIR -u GIT_INDEX_FILE -u GIT_WORK_TREE -u GIT_PREFIX \
        git -C "$repo_root" worktree list --porcelain >"$cleanup_root/worktrees.final" 2>/dev/null
    rc=$?
    [ "$rc" -eq 0 ] || { fail "cannot verify synthetic worktree removal"; return 1; }
    found=0
    while IFS= read -r listed_line; do
        [ "$listed_line" = "worktree $cleanup_worktree" ] && found=1
    done <"$cleanup_root/worktrees.final"
    [ "$found" -eq 0 ] || { fail "synthetic staged-tree worktree is still registered"; return 1; }
    cleanup_worktree=""
    fi

    [ "$(git rev-parse --verify HEAD 2>/dev/null)" = "$head_before" ] || { fail "HEAD changed while the remote gate ran"; return 1; }
    parents_after=$(expected_parent_vector "$head_before") || { fail "cannot re-read the commit parent vector"; return 1; }
    [ "$parents_after" = "$parents_before" ] || { fail "commit parent vector changed while the remote gate ran"; return 1; }
    tree_after=$(git write-tree 2>/dev/null) || { fail "cannot re-read the staged tree"; return 1; }
    [ "$tree_after" = "$tree_before" ] || { fail "staged tree changed while the remote gate ran"; return 1; }
    manifest_after="$cleanup_root/applicable.after"
    git diff --cached --name-status -z --diff-filter=ACMRT -M >"$cleanup_root/diff.after"
    rc=$?
    [ "$rc" -eq 0 ] || { fail "cannot re-read staged paths"; return 1; }
    collect_applicable_paths "$manifest_after" <"$cleanup_root/diff.after" || { fail "cannot re-derive applicable paths"; return 1; }
    cmp -s "$manifest_before" "$manifest_after" || { fail "applicable staged PHP paths changed while the remote gate ran"; return 1; }
    for file in "${CONTRACT_FILES[@]}"; do
        oid=$(tree_regular_blob_oid "$tree_after" "$file") || { fail "required staged contract file disappeared or became unsafe: $file"; return 1; }
        after_oids+=("$oid")
    done
    [ "${config_oids[*]}" = "${after_oids[*]}" ] || { fail "a staged gate contract blob changed while the remote gate ran"; return 1; }
    if head_ref_after=$(git symbolic-ref -q HEAD 2>/dev/null); then
        ref_state_after=symbolic
    else
        rc=$?
        [ "$rc" -eq 1 ] || { fail "cannot re-read checked-out ref state"; return 1; }
        ref_state_after=detached
        head_ref_after=HEAD
    fi
    [ "$ref_state_after" = "$ref_state_before" ] && [ "$head_ref_after" = "$head_ref_before" ] || {
        fail "checked-out ref changed while the remote gate ran"
        return 1
    }
    capture_trusted_install_snapshot "$repo_root" "$git_dir" || {
        fail "cannot revalidate the trusted gate installation before claim creation"
        return 1
    }
    install_dir_after=$TRUSTED_INSTALL_DIR
    install_identity_after=$TRUSTED_INSTALL_IDENTITY
    [ "$install_dir_after" = "$install_dir_before" ] \
        && [ "$install_identity_after" = "$install_identity_before" ] \
        && [ "$TRUSTED_PRECOMMIT_PATH" = "$precommit_path_before" ] \
        && [ "$TRUSTED_HELPER_PATH" = "$helper_path_before" ] \
        && [ "$REFERENCE_PATH_RESOLVED" = "$reference_path_before" ] \
        && [ "$TRUSTED_PRECOMMIT_SHA" = "$precommit_sha_before" ] \
        && [ "$TRUSTED_HELPER_SHA" = "$helper_sha_before" ] \
        && [ "$REFERENCE_SHA" = "$reference_sha_before" ] || {
        fail "trusted gate installation changed while the remote gate ran"
        return 1
    }
    create_reference_claim "$repo_root" "$git_dir" "$head_before" "$tree_before" "$parents_before" "$contract_digest" "$reference_sha_before" "$nonce" "$ref_state_before" "$head_ref_before" || {
        fail "cannot create the one-use reference claim"
        return 1
    }
    capture_trusted_install_snapshot "$repo_root" "$git_dir" || {
        burn_pending_reference_claim "$git_dir" || { fail "cannot burn a claim after trusted-install revalidation failed"; return 1; }
        fail "cannot revalidate the trusted gate installation after claim creation"
        return 1
    }
    [ "$TRUSTED_INSTALL_DIR" = "$install_dir_before" ] \
        && [ "$TRUSTED_INSTALL_IDENTITY" = "$install_identity_before" ] \
        && [ "$TRUSTED_PRECOMMIT_PATH" = "$precommit_path_before" ] \
        && [ "$TRUSTED_HELPER_PATH" = "$helper_path_before" ] \
        && [ "$REFERENCE_PATH_RESOLVED" = "$reference_path_before" ] \
        && [ "$TRUSTED_PRECOMMIT_SHA" = "$precommit_sha_before" ] \
        && [ "$TRUSTED_HELPER_SHA" = "$helper_sha_before" ] \
        && [ "$REFERENCE_SHA" = "$reference_sha_before" ] || {
        burn_pending_reference_claim "$git_dir" || { fail "cannot burn a claim after trusted-install mutation"; return 1; }
        fail "trusted gate installation changed after claim creation"
        return 1
    }

    if [ "$claim_only" -eq 1 ]; then
        echo "IPZ reference claim created for non-applicable staged tree $tree_before"
    else
        echo "IPZ remote PHP gate passed for staged tree $tree_before"
    fi
}

if [ "${1-}" = "--remote" ]; then
    shift
    remote_gate "$@"
    exit $?
fi

local_gate "$@"
exit $?
