#!/usr/bin/env bash
# ╔═══════════════════════════════════════════════════════════════════════════╗
# ║  sw-patrol-meta.sh — Shipwright Self-Improvement Patrol                ║
# ║  Sourced by sw-daemon.sh during patrol — creates improvement issues    ║
# ╚═══════════════════════════════════════════════════════════════════════════╝
# NOTE: This file is sourced (not executed). Do NOT add set -euo pipefail.
# All functions from the parent (sw-daemon.sh) are available.

SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
# Canonical helpers (colors, output, events)
# shellcheck source=lib/helpers.sh
[[ -f "$SCRIPT_DIR/lib/helpers.sh" ]] && source "$SCRIPT_DIR/lib/helpers.sh"
# Fallbacks when helpers not loaded (e.g. test env with overridden SCRIPT_DIR)
[[ "$(type -t info 2>/dev/null)" == "function" ]]    || info()    { echo -e "\033[38;2;0;212;255m\033[1m▸\033[0m $*"; }
[[ "$(type -t success 2>/dev/null)" == "function" ]] || success() { echo -e "\033[38;2;74;222;128m\033[1m✓\033[0m $*"; }
[[ "$(type -t warn 2>/dev/null)" == "function" ]]    || warn()    { echo -e "\033[38;2;250;204;21m\033[1m⚠\033[0m $*"; }
[[ "$(type -t error 2>/dev/null)" == "function" ]]   || error()   { echo -e "\033[38;2;248;113;113m\033[1m✗\033[0m $*" >&2; }
if [[ "$(type -t now_iso 2>/dev/null)" != "function" ]]; then
  now_iso()   { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
  now_epoch() { date +%s; }
fi
if [[ "$(type -t emit_event 2>/dev/null)" != "function" ]]; then
  emit_event() {
    local event_type="$1"; shift; mkdir -p "${HOME}/.shipwright"
    # shellcheck disable=SC2155
    local payload="{\"ts\":\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",\"type\":\"$event_type\""
    while [[ $# -gt 0 ]]; do local key="${1%%=*}" val="${1#*=}"; payload="${payload},\"${key}\":\"${val}\""; shift; done
    echo "${payload}}" >> "${HOME}/.shipwright/events.jsonl"
  }
fi
# ─── Helper: Create issue if not duplicate ─────────────────────────────────
patrol_meta_create_issue() {
    local title="$1"
    local body="$2"
    local extra_labels="${3:-}"

    if [[ "${NO_GITHUB:-false}" == "true" ]]; then
        info "  [dry-run] Would create: $title"
        return 0
    fi

    # Dedup: check if an open issue with this exact title already exists
    local existing
    existing=$(gh issue list --state open --search "$title" --json number,title --jq ".[].title" 2>/dev/null || echo "")
    if echo "$existing" | grep -qF "$title" 2>/dev/null; then
        info "  Skipping duplicate: $title"
        return 0
    fi

    local labels="auto-patrol,meta-improvement,ready-to-build"
    if [[ -n "$extra_labels" ]]; then
        labels="${labels},${extra_labels}"
    fi

    gh issue create \
        --title "$title" \
        --body "$body" \
        --label "$labels" 2>/dev/null || {
        warn "  Failed to create issue: $title"
        return 1
    }

    issues_created=$((issues_created + 1))
    total_findings=$((total_findings + 1))
    emit_event "patrol.meta_issue_created" "title=$title"
    success "  Created issue: $title"
}

# ─── Check 1: Untested Scripts ──────────────────────────────────────────────
patrol_meta_untested_scripts() {
    info "  Checking for untested Shipwright scripts..."
    local count=0

    for script in "$SCRIPT_DIR"/sw-*.sh; do
        [[ ! -f "$script" ]] && continue
        local base
        base=$(basename "$script" .sh)

        # Skip test scripts themselves
        [[ "$base" == *-test ]] && continue
        # Skip sourced provider scripts (no standalone execution)
        [[ "$base" == sw-tracker-linear ]] && continue
        [[ "$base" == sw-tracker-jira ]] && continue
        [[ "$base" == sw-patrol-meta ]] && continue

        local test_file="$SCRIPT_DIR/${base}-test.sh"
        if [[ ! -f "$test_file" ]]; then
            count=$((count + 1))
            patrol_meta_create_issue \
                "[Meta] Add tests for ${base}.sh" \
                "## Missing Test Suite

The script \`scripts/${base}.sh\` does not have a corresponding test file \`scripts/${base}-test.sh\`.

### Requirements
- Create \`scripts/${base}-test.sh\` following the existing test patterns
- Use mock environment (TEMP_DIR with mock binaries on PATH)
- Include PASS/FAIL counters, colored output, summary section
- Add ERR trap: \`trap 'echo \"ERROR: \\\$BASH_SOURCE:\\\$LINENO exited with status \\\$?\" >&2' ERR\`
- Register in \`package.json\` test script chain
- Aim for at least 10 meaningful test cases

### Context
All other Shipwright scripts follow this test pattern. See \`scripts/sw-daemon-test.sh\` as a reference.

_Auto-generated by Shipwright meta-patrol_"
        fi
    done

    if [[ "$count" -eq 0 ]]; then
        echo -e "    ${GREEN}●${RESET} All scripts have test suites"
    else
        echo -e "    ${CYAN}●${RESET} Found ${count} untested script(s)"
    fi
}

# ─── Check 2: Bash 3.2 Compatibility ───────────────────────────────────────
patrol_meta_bash_compat() {
    info "  Checking Bash 3.2 compatibility..."
    local count=0

    for script in "$SCRIPT_DIR"/sw-*.sh; do
        [[ ! -f "$script" ]] && continue
        local base
        base=$(basename "$script")

        # Look for Bash 4+ patterns
        local violations=""
        local v

        # declare -A (associative arrays)
        v=$(grep -n 'declare -A' "$script" 2>/dev/null | head -3 || true)
        [[ -n "$v" ]] && violations="${violations}\n- \`declare -A\` (associative arrays): ${v}"

        # readarray / mapfile
        v=$(grep -n 'readarray\|mapfile' "$script" 2>/dev/null | head -3 || true)
        [[ -n "$v" ]] && violations="${violations}\n- \`readarray/mapfile\`: ${v}"

        # ${var,,} lowercase
        v=$(grep -n '${[a-zA-Z_]*,,}' "$script" 2>/dev/null | head -3 || true)
        [[ -n "$v" ]] && violations="${violations}\n- \`\${var,,}\` lowercase: ${v}"

        # ${var^^} uppercase
        v=$(grep -n '${[a-zA-Z_]*\^\^}' "$script" 2>/dev/null | head -3 || true)
        [[ -n "$v" ]] && violations="${violations}\n- \`\${var^^}\` uppercase: ${v}"

        if [[ -n "$violations" ]]; then
            count=$((count + 1))
            patrol_meta_create_issue \
                "[Meta] Fix Bash 3.2 incompatibility in ${base}" \
                "## Bash 3.2 Compatibility Issue

The script \`scripts/${base}\` uses Bash 4+ features that break on macOS default Bash (3.2).

### Violations Found
$(echo -e "$violations")

### Required Changes
- Replace \`declare -A\` with indexed arrays or separate variables
- Replace \`readarray\` with \`while IFS= read -r\` loops
- Replace \`\${var,,}\` with \`echo \"\$var\" | tr '[:upper:]' '[:lower:]'\`
- Replace \`\${var^^}\` with \`echo \"\$var\" | tr '[:lower:]' '[:upper:]'\`

_Auto-generated by Shipwright meta-patrol_"
        fi
    done

    if [[ "$count" -eq 0 ]]; then
        echo -e "    ${GREEN}●${RESET} All scripts are Bash 3.2 compatible"
    else
        echo -e "    ${CYAN}●${RESET} Found ${count} script(s) with Bash 4+ patterns"
    fi
}

# ─── Check 3: VERSION Sync ─────────────────────────────────────────────────
patrol_meta_version_sync() {
    info "  Checking VERSION consistency..."
    # shellcheck disable=SC2034
    local versions=""
    local mismatches=""
    local reference_version=""

    for script in "$SCRIPT_DIR"/sw-*.sh "$SCRIPT_DIR/sw"; do
        [[ ! -f "$script" ]] && continue
        local base
        base=$(basename "$script")
        local ver
        ver=$(grep -m1 '^VERSION=' "$script" 2>/dev/null | sed 's/VERSION="//' | sed 's/"//' || true)
        if [[ -n "$ver" ]]; then
            if [[ -z "$reference_version" ]]; then
                reference_version="$ver"
            elif [[ "$ver" != "$reference_version" ]]; then
                mismatches="${mismatches}\n- \`${base}\`: ${ver} (expected ${reference_version})"
            fi
        fi
    done

    if [[ -n "$mismatches" ]]; then
        patrol_meta_create_issue \
            "[Meta] Fix VERSION mismatch across scripts" \
            "## VERSION Mismatch

Some scripts have different VERSION values. All scripts should use the same version.

### Reference Version: \`${reference_version}\`

### Mismatches
$(echo -e "$mismatches")

### Fix
Update all VERSION= lines to match the reference version.

_Auto-generated by Shipwright meta-patrol_"
        echo -e "    ${CYAN}●${RESET} VERSION mismatch detected"
    else
        echo -e "    ${GREEN}●${RESET} All script versions match: ${reference_version:-unknown}"
    fi
}

# ─── Check 4: DORA Trends (30-day) ─────────────────────────────────────────
patrol_meta_dora_trends() {
    info "  Analyzing 30-day DORA trends..."

    if [[ ! -f "$EVENTS_FILE" ]]; then
        echo -e "    ${DIM}●${RESET} No events data available"
        return
    fi

    local now_e
    now_e=$(now_epoch)
    local thirty_days_ago=$(( now_e - 2592000 ))
    local fifteen_days_ago=$(( now_e - 1296000 ))

    # Compare first half (days 16-30) vs second half (days 1-15)
    local first_half_lt second_half_lt
    first_half_lt=$(jq -s "[.[] | select(.type == \"pipeline.completed\" and .result == \"success\" and (.ts_epoch // 0) >= $thirty_days_ago and (.ts_epoch // 0) < $fifteen_days_ago) | .duration_s // 0] | if length > 0 then (add / length) else 0 end" "$EVENTS_FILE" 2>/dev/null || echo "0")
    second_half_lt=$(jq -s "[.[] | select(.type == \"pipeline.completed\" and .result == \"success\" and (.ts_epoch // 0) >= $fifteen_days_ago) | .duration_s // 0] | if length > 0 then (add / length) else 0 end" "$EVENTS_FILE" 2>/dev/null || echo "0")

    # Check if lead time regressed > 20%
    if [[ "$first_half_lt" != "0" ]] && [[ "$second_half_lt" != "0" ]]; then
        local increase_pct
        increase_pct=$(echo "$first_half_lt $second_half_lt" | awk '{if ($1 > 0) printf "%.0f", (($2 - $1) / $1) * 100; else print "0"}')

        if [[ "$increase_pct" -gt 20 ]]; then
            patrol_meta_create_issue \
                "[Meta] Investigate lead time regression (+${increase_pct}%)" \
                "## DORA Lead Time Regression

Average pipeline lead time has increased by **${increase_pct}%** over the last 30 days.

| Period | Avg Lead Time |
|--------|--------------|
| Days 16-30 | ${first_half_lt}s |
| Days 1-15 | ${second_half_lt}s |

### Suggested Actions
- Check if pipeline template complexity has increased
- Review build stage iteration counts
- Look for test suite slowdowns
- Check if retry rates have increased

_Auto-generated by Shipwright meta-patrol_"
            echo -e "    ${CYAN}●${RESET} Lead time regression: +${increase_pct}%"
        else
            echo -e "    ${GREEN}●${RESET} Lead time stable (${increase_pct}% change)"
        fi
    else
        echo -e "    ${DIM}●${RESET} Insufficient data for trend analysis"
    fi
}

# ─── Check 5: Template Effectiveness ───────────────────────────────────────
patrol_meta_template_effectiveness() {
    info "  Analyzing pipeline template effectiveness..."

    if [[ ! -f "$EVENTS_FILE" ]]; then
        echo -e "    ${DIM}●${RESET} No events data available"
        return
    fi

    # Get success rates by template from the last 30 days
    local template_stats
    template_stats=$(jq -s '
        [.[] | select(.type == "pipeline.completed" and (.ts_epoch // 0) > (now - 2592000))]
        | group_by(.template // "unknown")
        | map({
            template: .[0].template // "unknown",
            total: length,
            successes: [.[] | select(.result == "success")] | length
        })
        | map(. + { rate: (if .total > 0 then (.successes * 100 / .total) else 0 end) })
        | sort_by(-.rate)
    ' "$EVENTS_FILE" 2>/dev/null || echo "[]")

    local template_count
    template_count=$(echo "$template_stats" | jq 'length' 2>/dev/null || echo "0")

    if [[ "$template_count" -gt 1 ]]; then
        local best_template best_rate worst_template worst_rate
        best_template=$(echo "$template_stats" | jq -r '.[0].template' 2>/dev/null || echo "unknown")
        best_rate=$(echo "$template_stats" | jq -r '.[0].rate' 2>/dev/null || echo "0")
        # shellcheck disable=SC2034
        worst_template=$(echo "$template_stats" | jq -r '.[-1].template' 2>/dev/null || echo "unknown")
        worst_rate=$(echo "$template_stats" | jq -r '.[-1].rate' 2>/dev/null || echo "0")

        local best_int=${best_rate%.*}
        local worst_int=${worst_rate%.*}
        [[ "$best_int" =~ ^[0-9]+$ ]] || best_int=0
        [[ "$worst_int" =~ ^[0-9]+$ ]] || worst_int=0
        local rate_diff=$(( best_int - worst_int ))

        if [[ "$rate_diff" -gt 30 ]]; then
            patrol_meta_create_issue \
                "[Meta] Consider defaulting to '${best_template}' pipeline template" \
                "## Template Effectiveness Analysis

The **${best_template}** template significantly outperforms other templates.

### Success Rates (Last 30 Days)
$(echo "$template_stats" | jq -r '.[] | "| \(.template) | \(.successes)/\(.total) | \(.rate)% |"' 2>/dev/null || echo "No data")

### Recommendation
Consider setting \`pipeline_template: \"${best_template}\"\` as the default in \`daemon-config.json\`.

_Auto-generated by Shipwright meta-patrol_"
            echo -e "    ${CYAN}●${RESET} '${best_template}' outperforms by ${rate_diff}%"
        else
            echo -e "    ${GREEN}●${RESET} Templates performing similarly (${rate_diff}% spread)"
        fi
    else
        echo -e "    ${DIM}●${RESET} Not enough template variety for comparison"
    fi
}

# ─── Check 6: Memory Pruning ───────────────────────────────────────────────
patrol_meta_memory_pruning() {
    info "  Checking memory file sizes..."

    local memory_dir="$HOME/.shipwright/memory"
    if [[ ! -d "$memory_dir" ]]; then
        echo -e "    ${DIM}●${RESET} No memory directory"
        return
    fi

    local total_size
    total_size=$(du -sk "$memory_dir" 2>/dev/null | awk '{print $1}' || echo "0")
    local total_mb=$(( total_size / 1024 ))

    if [[ "$total_mb" -gt 10 ]]; then
        patrol_meta_create_issue \
            "[Meta] Prune memory files (${total_mb}MB)" \
            "## Memory Storage Cleanup Needed

The Shipwright memory directory has grown to **${total_mb}MB**.

### Location
\`~/.shipwright/memory/\`

### Suggested Actions
- Archive old memory files (older than 90 days)
- Deduplicate similar failure patterns
- Compress rarely-accessed memories
- Consider implementing automatic memory rotation

_Auto-generated by Shipwright meta-patrol_"
        echo -e "    ${CYAN}●${RESET} Memory files: ${total_mb}MB (needs pruning)"
    else
        echo -e "    ${GREEN}●${RESET} Memory files: ${total_mb}MB (healthy)"
    fi
}

# ─── Check 7: Event Analysis (Top Recurring Failures) ──────────────────────
patrol_meta_event_analysis() {
    info "  Analyzing recurring failure patterns..."

    if [[ ! -f "$EVENTS_FILE" ]]; then
        echo -e "    ${DIM}●${RESET} No events data available"
        return
    fi

    # Find top 3 most common failure reasons in the last 7 days
    local now_e
    now_e=$(now_epoch)
    local seven_days_ago=$(( now_e - 604800 ))

    local top_failures
    top_failures=$(jq -s "
        [.[] | select(.type == \"pipeline.completed\" and .result != \"success\" and (.ts_epoch // 0) >= $seven_days_ago)]
        | group_by(.failed_stage // \"unknown\")
        | map({ stage: .[0].failed_stage // \"unknown\", count: length })
        | sort_by(-.count)
        | .[0:3]
    " "$EVENTS_FILE" 2>/dev/null || echo "[]")

    local failure_count
    failure_count=$(echo "$top_failures" | jq 'length' 2>/dev/null || echo "0")

    if [[ "$failure_count" -gt 0 ]]; then
        local created=0
        while IFS= read -r failure; do
            local stage count
            stage=$(echo "$failure" | jq -r '.stage' 2>/dev/null || echo "unknown")
            count=$(echo "$failure" | jq -r '.count' 2>/dev/null || echo "0")

            if [[ "$count" -ge 3 ]]; then
                patrol_meta_create_issue \
                    "[Meta] Investigate recurring '${stage}' stage failures (${count}x in 7d)" \
                    "## Recurring Pipeline Failure

The **${stage}** stage has failed **${count} times** in the last 7 days.

### Suggested Investigation
- Check events.jsonl for error details: \`jq 'select(.type == \"pipeline.completed\" and .failed_stage == \"${stage}\")' ~/.shipwright/events.jsonl\`
- Review memory patterns: \`shipwright memory search \"${stage}\"\`
- Check if a specific issue type triggers this failure

_Auto-generated by Shipwright meta-patrol_"
                created=$((created + 1))
            fi
        done < <(echo "$top_failures" | jq -c '.[]' 2>/dev/null)

        if [[ "$created" -gt 0 ]]; then
            echo -e "    ${CYAN}●${RESET} Created ${created} issue(s) for recurring failures"
        else
            echo -e "    ${GREEN}●${RESET} No recurring failures above threshold"
        fi
    else
        echo -e "    ${GREEN}●${RESET} No failures in last 7 days"
    fi
}

# ─── Score Impact: Estimate DORA Metric Impact ────────────────────────────
patrol_meta_score_impact() {
    local title="$1"
    local category="${2:-general}"

    # Assign impact scores (0-100) based on category and title keywords
    local score=50  # Default

    case "$category" in
        bash-compat)
            # Bash compatibility affects reliability
            score=65
            ;;
        version-sync)
            # Version inconsistencies affect deployment
            score=55
            ;;
        untested-scripts)
            # Test coverage directly affects change failure rate
            score=75
            ;;
        dora-regression)
            # DORA regressions are critical
            score=85
            ;;
        template-effectiveness)
            # Template improvements affect lead time
            score=70
            ;;
        memory-pruning)
            # Memory cleanup affects reliability
            score=45
            ;;
        recurring-failures)
            # Recurring failures directly affect MTTR and CFR
            score=80
            ;;
    esac

    # Adjust based on title keywords
    if echo "$title" | grep -qi "critical\|regression\|failure"; then
        score=$((score + 15))
    fi
    if echo "$title" | grep -qi "lead.*time\|deployment"; then
        score=$((score + 10))
    fi

    # Cap at 100
    [[ $score -gt 100 ]] && score=100

    echo "$score"
}

# ─── Execute Fix: Trigger Pipeline for Improvement Issue ──────────────────
patrol_meta_execute_fix() {
    local issue_number="$1"
    local title="$2"

    if [[ "${NO_GITHUB:-false}" == "true" ]]; then
        info "  [dry-run] Would start pipeline for issue #${issue_number}"
        return 0
    fi

    if ! command -v shipwright >/dev/null 2>&1 && ! command -v sw >/dev/null 2>&1; then
        warn "  shipwright CLI not available, skipping pipeline execution"
        return 1
    fi

    info "  Starting pipeline for issue #${issue_number}: ${title}"

    # Run pipeline in isolated worktree to avoid conflicts
    if shipwright pipeline start --issue "$issue_number" --worktree 2>/dev/null; then
        emit_event "patrol.meta_pipeline_started" "issue=$issue_number" "title=$title"
        return 0
    else
        warn "  Failed to start pipeline for issue #${issue_number}"
        return 1
    fi
}

# ─── Verify Fix: Re-run Relevant Check After Fix ──────────────────────────
patrol_meta_verify_fix() {
    local category="$1"
    local issue_number="$2"

    if [[ "${NO_GITHUB:-false}" == "true" ]]; then
        info "  [dry-run] Would verify fix for issue #${issue_number}"
        return 0
    fi

    info "  Verifying fix for issue #${issue_number} (category: ${category})"

    case "$category" in
        untested-scripts)
            patrol_meta_untested_scripts > /dev/null 2>&1
            ;;
        bash-compat)
            patrol_meta_bash_compat > /dev/null 2>&1
            ;;
        version-sync)
            patrol_meta_version_sync > /dev/null 2>&1
            ;;
        dora-regression)
            patrol_meta_dora_trends > /dev/null 2>&1
            ;;
        template-effectiveness)
            patrol_meta_template_effectiveness > /dev/null 2>&1
            ;;
        memory-pruning)
            patrol_meta_memory_pruning > /dev/null 2>&1
            ;;
        recurring-failures)
            patrol_meta_event_analysis > /dev/null 2>&1
            ;;
        *)
            warn "  Unknown category: ${category}"
            return 1
            ;;
    esac

    emit_event "patrol.meta_verified" "issue=$issue_number" "category=$category"
    return 0
}

# ─── Rollback on Regression: Auto-revert if Metrics Regress ────────────────
patrol_meta_rollback() {
    local issue_number="$1"

    if [[ "${NO_GITHUB:-false}" == "true" ]]; then
        info "  [dry-run] Would rollback issue #${issue_number}"
        return 0
    fi

    warn "  Metrics regression detected for issue #${issue_number}"

    # Get the PR associated with this issue
    local pr_number
    pr_number=$(gh issue view "$issue_number" --json "pullRequests" --jq ".pullRequests[0].number" 2>/dev/null || echo "")

    if [[ -n "$pr_number" ]]; then
        info "  Reverting PR #${pr_number} due to metric regression"

        # Check out the branch, revert the PR commit, force push
        local branch
        branch=$(gh pr view "$pr_number" --json "headRefName" --jq ".headRefName" 2>/dev/null || echo "")

        if [[ -n "$branch" ]]; then
            (
                git fetch origin "$branch" 2>/dev/null || true
                git checkout "$branch" 2>/dev/null || return 1
                git revert HEAD --no-edit 2>/dev/null || return 1
                git push origin "$branch" --force 2>/dev/null || return 1
                emit_event "patrol.meta_rollback" "issue=$issue_number" "pr=$pr_number"
            ) || {
                warn "  Failed to rollback PR #${pr_number}"
                return 1
            }
        fi
    fi

    return 0
}

# ─── Learn: Record Outcome in Memory System ────────────────────────────────
patrol_meta_learn() {
    local issue_number="$1"
    local category="$2"
    local success="$3"
    local metrics_change="${4:-}"

    local memory_dir="$HOME/.shipwright/memory"
    mkdir -p "$memory_dir"

    local learning_file="$memory_dir/self-improvements.jsonl"
    local ts
    ts=$(now_iso)

    local outcome="success"
    [[ "$success" != "true" ]] && outcome="failure"

    # Append to learning log
    local entry
    entry=$(jq -n \
        --arg issue "$issue_number" \
        --arg category "$category" \
        --arg outcome "$outcome" \
        --arg metrics "$metrics_change" \
        --arg ts "$ts" \
        '{issue:$issue, category:$category, outcome:$outcome, metrics_impact:$metrics, timestamp:$ts}')

    echo "$entry" >> "$learning_file"
    emit_event "patrol.meta_learned" "issue=$issue_number" "category=$category" "outcome=$outcome"

    success "  Recorded learning: issue #${issue_number} ${outcome}"
}

# ─── Batch Improve: Process Multiple Issues in Parallel ─────────────────────
patrol_meta_batch_improve() {
    local -a issues_to_fix
    local count=0

    info "  Collecting recent meta-patrol issues to fix..."

    if [[ "${NO_GITHUB:-false}" == "true" ]]; then
        info "  [dry-run] Would process batch improvements"
        return 0
    fi

    # Find recent open meta-improvement issues
    while IFS= read -r line; do
        if [[ -z "$line" ]]; then continue; fi
        local issue_num category title
        issue_num=$(echo "$line" | jq -r '.number' 2>/dev/null || echo "")
        title=$(echo "$line" | jq -r '.title' 2>/dev/null || echo "")

        if [[ -n "$issue_num" && -n "$title" ]]; then
            # Determine category from title
            if echo "$title" | grep -qi "test"; then
                category="untested-scripts"
            elif echo "$title" | grep -qi "bash"; then
                category="bash-compat"
            elif echo "$title" | grep -qi "version"; then
                category="version-sync"
            elif echo "$title" | grep -qi "lead.*time\|regression"; then
                category="dora-regression"
            elif echo "$title" | grep -qi "template"; then
                category="template-effectiveness"
            elif echo "$title" | grep -qi "memory"; then
                category="memory-pruning"
            else
                category="recurring-failures"
            fi

            issues_to_fix+=("$issue_num|$category|$title")
            count=$((count + 1))
        fi
    done < <(gh issue list --label "meta-improvement" --state open --json "number,title" --jq ".[]" 2>/dev/null || echo "")

    if [[ $count -eq 0 ]]; then
        info "  No meta-improvement issues to process"
        return 0
    fi

    info "  Found ${count} issue(s) to process, executing in parallel..."

    # Sort by impact score (descending) - use temp file for Bash 3.2 compat
    local scored_file
    scored_file=$(mktemp)

    for issue_spec in "${issues_to_fix[@]}"; do
        local issue_num category title
        issue_num="${issue_spec%%|*}"
        category="${issue_spec#*|}"
        category="${category%%|*}"
        title="${issue_spec##*|}"

        local score
        score=$(patrol_meta_score_impact "$title" "$category")
        echo "$score|$issue_num|$category|$title" >> "$scored_file"
    done

    # Sort by score (highest first) using temp file (Bash 3.2 compatible)
    local sorted_file
    sorted_file=$(mktemp)
    printf '%s\n' "${scored_issues[@]}" | sort -rn > "$sorted_file"

    # Process in parallel (limit to 3 concurrent pipelines)
    local active_count=0
    local max_parallel=3

    while IFS= read -r item; do
        local score issue_num category title
        score="${item%%|*}"
        issue_num="${item#*|}"
        issue_num="${issue_num%%|*}"
        category="${issue_num#*|}"
        category="${category%%|*}"
        title="${item##*|}"

        # Wait if we have max_parallel active jobs
        while [[ $active_count -ge $max_parallel ]]; do
            # Count running background jobs
            active_count=$(jobs -r 2>/dev/null | wc -l)
            [[ $active_count -ge $max_parallel ]] && sleep 2
        done

        # Start pipeline in background
        (
            patrol_meta_execute_fix "$issue_num" "$title"
            sleep 2
            patrol_meta_verify_fix "$category" "$issue_num"
        ) &

        active_count=$((active_count + 1))
    done < "$sorted_file"

    rm -f "$sorted_file"

    # Wait for all to complete
    wait

    success "  Batch processing complete"
}

# ─── Main Autonomous Loop: Detect → Score → Fix → Verify → Learn ──────────
patrol_meta_auto() {
    echo -e "\n  ${BOLD}Meta Self-Improvement Autonomous Loop${RESET}"

    info "Stage 1: Detection"
    patrol_meta_untested_scripts
    patrol_meta_bash_compat
    patrol_meta_version_sync
    patrol_meta_dora_trends
    patrol_meta_template_effectiveness
    patrol_meta_memory_pruning
    patrol_meta_event_analysis

    echo ""
    info "Stage 2: Impact Scoring & Batch Processing"
    patrol_meta_batch_improve

    echo ""
    info "Stage 3: Learning from Outcomes"
    # This would be populated by results from batch_improve
    # For now, log that autonomous loop completed
    emit_event "patrol.meta_autonomous_complete" "timestamp=$(now_iso)"

    success "Autonomous self-improvement loop completed"
    echo ""
}

# ─── Main Entry Point ──────────────────────────────────────────────────────
patrol_meta_run() {
    echo -e "\n  ${BOLD}Meta Self-Improvement Checks${RESET}"

    patrol_meta_untested_scripts
    patrol_meta_bash_compat
    patrol_meta_version_sync
    patrol_meta_dora_trends
    patrol_meta_template_effectiveness
    patrol_meta_memory_pruning
    patrol_meta_event_analysis

    echo ""
}
