# Comment evaluation corpus -- shell, needs labels
#
# Real own-line comments with the code that follows. Mark every `verdict:` as:
#
#   slop  - should not exist: restates the code, narrates an edit, labels a
#           section, leaks process, records history, or is a long explanation
#           where a short one would do
#   keep  - deleting it would lose a fact not recoverable from the code
#   skip  - genuinely cannot tell without more context
#
# Leave `?` on anything you do not reach; partial labelling still scores.
#
# Nothing here reveals which rule (if any) fires on a case, or how the case
# was sampled.

### 1  dev tools/test_with_tilt.sh:227
# Cleanup function
    cleanup() {
    if [ ! -z "$TILT_PID" ]; then
    print_status "Cleaning up Tilt process..."
    kill $TILT_PID 2>/dev/null || true
verdict: slop

### 2  frontend/scripts/build-csp-hosts.sh:26
# The result is validated, not just extracted. A CSP is a single header string
# with `;`-separated directives, so an unchecked value containing `;` or a space
# would splice in a whole new directive — re-opening the wildcard hole this
    origin_of() {
    origin=$(printf '%s' "$1" | sed -E 's#^([a-zA-Z][a-zA-Z0-9+.-]*://[^/]+).*#\1#')
verdict: ?

### 3  frontend/scripts/build-csp-hosts.sh:90
# A multi-label prefix is not a project ref; the backend's
# `^([^.]+)\.supabase\.co$` would not match it either.
    supabase_storage_origin="${supabase_scheme}://${ref}.storage.supabase.co${supabase_port}"
    ;;
    esac
    ;;
verdict: ?

### 4  frontend/scripts/build-csp-hosts.sh:141
# posthog-js splits ingest from asset delivery: api_host us.i.posthog.com serves
# events, us-assets.i.posthog.com serves the extension bundles. Allow both.
    posthog_origin=$(origin_of "${VITE_PUBLIC_POSTHOG_HOST:-https://us.i.posthog.com}")
    posthog_hosts="$posthog_origin"
    case "$posthog_origin" in
    https://*.i.posthog.com)
verdict: ?

### 5  frontend/scripts/build-csp-hosts.test.sh:57
# --------------------------------------------------------------------------
    csp=$(render "https://api.ionworks.com" "https://abc123.supabase.co")
    check "hosted: storage host in connect-src" \
verdict: slop

### 6  frontend/scripts/build-csp-hosts.test.sh:111
# --------------------------------------------------------------------------
    if VITE_BACKEND_API_URL="https://ok.com" VITE_SUPABASE_URL="not-a-url" \
    sh "$script" "$template" "$tmp/bad" >/dev/null 2>&1; then
    printf 'FAIL validation: a non-URL was accepted\n'
    failures=$((failures + 1))
verdict: slop

### 7  frontend/scripts/start-backend-for-tests.sh:14
# Verify uv is available
    if ! command -v uv &> /dev/null; then
    echo "Error: uv is not installed or not in PATH" >&2
    exit 1
    fi
verdict: keep

### 8  infra/ecr/provision-porter.sh:273
# Tolerate the failure rather than let `set -e` abort mid-sweep: an exit here would
# leave the earlier repositories applied, the rest untouched, and print no summary.
    if put_err=$(aws ecr put-lifecycle-policy \
    --repository-name "$repo" --region "$REGION" \
    --lifecycle-policy-text "file://$policy" 2>&1 >/dev/null); then
    applied=$((applied + 1))
verdict: keep

### 9  infra/ecr/provision.sh:70
# Every mutating call below is either create-if-absent or an idempotent put/update, so
# a re-run converges rather than erroring.
    provision_oidc_provider() {
    local arn="arn:aws:iam::$ACCOUNT_ID:oidc-provider/$OIDC_HOST"
    local audiences
    if audiences=$(aws iam get-open-id-connect-provider \
verdict: keep

### 10  ray-local/common.sh:1
# !/bin/bash
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
verdict: ?

### 11  ray-local/common.sh:9
# Ray refuses to connect across a Python patch mismatch, so the cluster must run the
# same interpreter as the project. Asked of uv rather than pinned, so a project upgrade
# cannot desynchronise the cluster. Override with RAY_PYTHON_VERSION.
    _project_python_version() {
    [[ -f "$PROJECT_ROOT/pyproject.toml" ]] || return 1
    uv run --project "$PROJECT_ROOT" python -c \
    'import sys; print(".".join(map(str, sys.version_info[:3])))' 2>/dev/null
verdict: slop

### 12  ray-local/common.sh:38
# Multi-node configuration
# Default to 2 workers (3-node cluster: 1 head + 2 workers)
    RAY_NUM_WORKERS="${RAY_NUM_WORKERS:-2}"
    RAY_CPUS_PER_NODE="${RAY_CPUS_PER_NODE:-2}"
    LOCK_DIR="${SCRIPT_DIR}/.ray.lock"
verdict: keep

### 13  ray-local/common.sh:59
# Stale lock — previous holder is gone
    rm -rf "$LOCK_DIR"
    if mkdir "$LOCK_DIR" 2>/dev/null; then
    echo $$ > "$LOCK_DIR/pid"
    return 0
verdict: ?

### 14  ray-local/common.sh:106
# Convert Docker-internal URLs to localhost for native Ray
# The backend container uses host.docker.internal, but native Ray needs localhost
    convert_docker_urls_to_localhost() {
    if [[ "$SUPABASE_URL" == *"host.docker.internal"* ]]; then
    export SUPABASE_URL="${SUPABASE_URL//host.docker.internal/localhost}"
    echo "Converted SUPABASE_URL to use localhost: $SUPABASE_URL"
verdict: ?

### 15  ray-local/common.sh:133
# Check all Ray ports are available
    check_ray_ports() {
    local has_error=0
    check_port_available "$RAY_GCS_PORT" "Ray GCS" || has_error=1
    check_port_available "$RAY_DASHBOARD_PORT" "Ray Dashboard" || has_error=1
verdict: keep

### 16  ray-local/common.sh:305
# Unset RAY_ADDRESS - cluster should use 'auto' or no address
    unset RAY_ADDRESS
    echo "  Ports — GCS: $RAY_GCS_PORT  dashboard: $RAY_DASHBOARD_PORT  client: $RAY_CLIENT_PORT  metrics: $RAY_METRICS_PORT"
    validate_python_version || return 1
verdict: ?

### 17  ray-local/serve.sh:2
# Tilt serve script for Ray cluster
# Starts Ray, waits, and stops Ray on SIGTERM/SIGINT
    set -eo pipefail
    export PATH="$HOME/.local/bin:$HOME/.cargo/bin:/usr/local/bin:$PATH"
verdict: keep

### 18  ray-local/start.sh:1
# !/bin/bash
    set -eo pipefail
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    source "${SCRIPT_DIR}/common.sh"
verdict: ?

### 19  ray-local/start.sh:11
# Track ownership so cleanup doesn't clobber another instance
    OWNS_LOCK=false
    STARTED_RAY=false
    cleanup() {
    if [[ "$STARTED_RAY" == "true" ]]; then
verdict: ?

### 20  ray-local/status.sh:1
# !/bin/bash
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    source "${SCRIPT_DIR}/common.sh"
    cd "$SCRIPT_DIR"
verdict: ?

### 21  scripts/check-api-conventions.sh:25
# Helpers
    grep_check() {
verdict: ?

### 22  scripts/check-api-conventions.sh:211
# ---------------------------------------------------------------------------
    check_backend_file() {
    local file="$1"
    grep_check "$file" \
    '@\w*router\.put\(' '^\s*#' \
verdict: slop

### 23  scripts/check-api-conventions.sh:227
# Duplicate/conflict errors using the wrong exception type
# Catches patterns like: raise BadRequestError("...already exists...")
# raise AppError("...duplicate...")
# raise HTTPException(..., detail="...already exists...")
    grep_check "$file" \
    'raise (BadRequestError|AppError|HTTPException).*([Aa]lready exists|[Dd]uplicate|[Uu]nique constraint)' \
    '^\s*#' \
    "Raises a non-conflict exception for a duplicate/conflict error." \
verdict: ?

### 24  scripts/check-sdk-no-dotenv.sh:10
# Applications, examples, scripts, and tests may use `load_dotenv()`
# freely. Only the SDK source under `packages/ionworks-api/ionworks/`
# is forbidden from calling it. The hook in .pre-commit-config.yaml
# is scoped to that path, so pre-commit only invokes this script with
# files inside the SDK.
    set -euo pipefail
    status=0
    for file in "$@"; do
    if grep -nE '(^|[^a-zA-Z0-9_.])load_dotenv\s*\(' "$file" >/dev/null 2>&1; then
verdict: ?

### 25  scripts/check-skills-version-parity.sh:10
# Usage: check-skills-version-parity.sh [skills-dir]
# skills-dir defaults to "packages/skills" (the public package).
    set -euo pipefail
    SKILLS_DIR="${1:-packages/skills}"
    MANIFESTS=(
    "$SKILLS_DIR/.claude-plugin/plugin.json"
verdict: ?

### 26  scripts/iw-db.sh:5
# Usage: ./scripts/iw-db.sh <env> [psql args...]
# env: internal | staging | stage | production
    set -euo pipefail
    [[ $# -ge 1 ]] || { echo "Usage: $0 <internal|staging|stage|production|prod> [psql args...]"; exit 1; }
    case "$1" in
verdict: ?

### 27  scripts/local-studio/run-frontend.sh:2
# Run the Vite dev server natively (no Docker/Tilt).
# Merges k8s/env.yaml + k8s/env-override.yaml and exports VITE_* vars,
# which Vite picks up from the process environment same as .env files.
    set -euo pipefail
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
    eval "$(cd "$REPO_ROOT" && uv run --with pyyaml python3 - <<'PYEOF'
verdict: ?

### 28  scripts/local-studio/run-worker.sh:7
# Assumes Supabase is already up and migrated — `ensure-db.sh` owns that, and
# start-studio.sh runs it before launching this script (including for
# `--only worker`). Standalone, run `scripts/local-studio/ensure-db.sh` first.
    set -euo pipefail
    SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
verdict: ?

### 29  scripts/local-studio/run-worker.sh:15
# Capture into a var so a loader failure (which prints nothing) is caught here,
# instead of `eval ""` silently succeeding and booting a half-configured worker.
    ENV_EXPORTS="$(cd "$REPO_ROOT" && uv run --with pyyaml python3 - <<'PYEOF'
    import shlex, yaml
    def load_data(path):
    with open(path) as f:
verdict: ?

### 30  scripts/local-studio/start-studio.sh:53
# Ray cluster (ray-local/.venv) and backend (root .venv) MUST run the same Ray
# version. ray-local/uv.lock is gitignored and floats `ray[serve]>=2.54,<3`, so a
# fresh `uv sync` there can drift ahead of the committed root lock. A skew makes
# placement-group actors fail to boot and the job hangs "spinning up a placement
# group". Force ray-local to match the root .venv before starting.
    ensure_ray_aligned() {
    local root_venv="$REPO_ROOT/.venv/bin/python"
    local local_venv="$REPO_ROOT/ray-local/.venv/bin/python"
    if [[ ! -x "$root_venv" ]]; then
verdict: slop

### 31  scripts/local-studio/start-studio.sh:110
# serve.sh keeps Ray alive; its EXIT trap stops Ray when killed
    bash "$REPO_ROOT/ray-local/serve.sh" &
    echo "Waiting for Ray..."
    RAY_WAIT=0
    RAY_TIMEOUT="${RAY_TIMEOUT:-120}"
verdict: keep

### 32  scripts/local-studio/start-studio.sh:138
# Worker shares the DB with the backend, which is already up and migrated by
# this point, so parallel launch is safe.
    [[ "$START_WORKER" == true ]]   && bash "$SCRIPT_DIR/run-worker.sh" &
    wait
verdict: keep

### 33  scripts/prod_daily_summary_cron.sh:11
# SUMMARY_EMAIL_TO=team@ionworks.com
# SUMMARY_EMAIL_FROM=reports@ionworks.com
# SUMMARY_SMTP_HOST=smtp.example.com
# SUMMARY_SMTP_USER=...
# SUMMARY_SMTP_PASSWORD=...
# 2. Test it by hand:  ./scripts/prod_daily_summary_cron.sh --dry-run
# 3. Schedule (08:30 local, after the UTC day has closed):
# 30 8 * * * /Users/vsulzer/Code/ionworks-app/scripts/prod_daily_summary_cron.sh
    set -uo pipefail
verdict: ?

### 34  scripts/prod_daily_summary_cron.sh:83
# SUMMARY_BACKFILL_DAYS bounds the lookback so a long holiday cannot fire off
# dozens of messages at once; days older than the window are noted and skipped.
    BACKFILL_DAYS="${SUMMARY_BACKFILL_DAYS:-7}"
    status=0
    sent_any=0
    for ((i = BACKFILL_DAYS; i >= 1; i--)); do
verdict: ?

### 35  scripts/prod_daily_summary_cron.sh:149
# "skipped" (the channel is not configured) also writes a marker: that is a
# permanent condition, so retrying it every run would keep the day open
# forever and hold the exit code red with no way to distinguish a missing
# env var from a real outage.
    grep -qE '^CHANNEL slack (ok|skipped)$' <<<"$run_out" && : >"$slack_done"
    grep -qE '^CHANNEL email (ok|skipped)$' <<<"$run_out" && : >"$email_done"
    if grep -q '^CHANNEL .* skipped$' <<<"$run_out"; then
    log "NOTE $day: $(grep -c '^CHANNEL .* skipped$' <<<"$run_out") channel(s) not configured -- not retrying"
verdict: slop

### 36  scripts/wait-for-supabase.sh:2
# Wait for Supabase services to be fully responsive before DB operations.
# `supabase start` returns when containers are running, but PostgREST/GoTrue
# may still be initializing — especially on fast machines where Docker startup
# is near-instant and there's no pull-time buffer.
    MAX_WAIT=60
    INTERVAL=2
    ELAPSED=0
verdict: slop

### 37  scripts/wait-for-supabase.sh:7
# Usage: source scripts/wait-for-supabase.sh
    MAX_WAIT=60
    INTERVAL=2
    ELAPSED=0
    echo "Waiting for Supabase services to be ready..."
verdict: ?

### 38  scripts/wait-for-supabase.sh:15
# Any HTTP response (even 4xx) means PostgREST is up and connected to Postgres.
# curl returns "000" when the connection is refused (service not yet listening).
    HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:54321/rest/v1/ 2>/dev/null)
    if [ "$HTTP_CODE" != "000" ] && [ -n "$HTTP_CODE" ]; then
    echo "Supabase API ready after ${ELAPSED}s (HTTP $HTTP_CODE)"
    return 0 2>/dev/null || exit 0
verdict: keep
