#!/bin/sh
# bp — REPL shorthand for the bullpen room. Expands to `room-ask`.
#   bp <worker> <task...>            ask a worker (@/# prefix optional), block for the reply
#   bp --from NICK <worker> <task>   set your nick (default: $BP_NICK, else markus)
#   bp --timeout N <worker> <task>   override the wait (researcher auto-bumps to 200s)
#   bp --route <task...>             ask @dispatcher who to use, then RUN it as yourself
#   bp                               show the roster (@dispatcher)
# Over sic a rich agent calls:  sic hertz bp --from noether researcher "..."
#
# --route exists INSTEAD of a relay mode in @dispatcher. The room contract is deliberately
# "reply-only, NEVER relays" (bin/bullpen-dispatcher): a misroute costs one wasted hop rather
# than a wrong answer stated as fact. @reviewer's design pass 2026-08-02 found a relay would be
# strictly worse than that, not better — @dispatcher is itself PRIVILEGED and in TRUST, so
# relaying turns a single-keyword regex hit into an authenticated order every worker accepts
# (confused deputy), and it has no good answer for identity: posting as `dispatcher` breaks
# in_reply_to for the real asker, posting as the asker means forging `from` and signing the
# forgery with the room secret — the exact attack the post-secret gate exists to stop.
#
# The problem worth solving was never "the human types too much"; it is that a rich agent
# sometimes IMPROVISES instead of running the command @dispatcher handed back. That is a
# compliance defect at the CALLER, so it is fixed at the caller: --route asks, SHOWS the route,
# and runs it here, as you, with your nick — TRUST, verified and reply-routing all unchanged,
# and the inspect-before-work checkpoint survives because the route is printed first.
# Heavyweight workers are NOT auto-run: @herder reaches live hosts and @reviewer costs real
# money per call, so a misroute there must still pass a human before it fires.
FROM="${BP_NICK:-markus}"
TIMEOUT=""
ROUTE=0
while [ "${1:-}" = "--from" ] || [ "${1:-}" = "--timeout" ] || [ "${1:-}" = "--route" ]; do
    case "$1" in
        --from)    FROM="$2";    shift 2 ;;
        --timeout) TIMEOUT="$2"; shift 2 ;;
        --route)   ROUTE=1;      shift   ;;
    esac
done
if [ $# -eq 0 ]; then exec bullpen-dispatcher --roster; fi

# Workers a misroute must never fire unattended: live fleet reach, or real money per call.
NO_AUTORUN="herder reviewer"

pick_timeout() {
    case "$1" in researcher) echo 200 ;; herder) echo 280 ;; testdesigner) echo 340 ;;
                 py) echo 340 ;; foreman) echo 1500 ;; reviewer) echo 600 ;; *) echo 60 ;; esac
}

if [ "$ROUTE" = "1" ]; then
    ROUTING=$(bullpen-dispatcher --once "$*" 2>/dev/null)
    [ -n "$ROUTING" ] || { echo "bp --route: @dispatcher returned nothing" >&2; exit 1; }
    printf '%s\n' "$ROUTING"
    # _route_line's format is machine-readable on purpose: "→ @nick — description."
    WORKER=$(printf '%s' "$ROUTING" | sed -n 's/^→ @\([A-Za-z0-9_-]*\).*/\1/p' | head -1)
    if [ -z "$WORKER" ]; then
        echo "" >&2
        echo "bp --route: no single worker named — the roster above IS the answer." >&2
        echo "            Ambiguity is a real result here; pick one and run bp <worker> \"…\"." >&2
        exit 2
    fi
    for w in $NO_AUTORUN; do
        if [ "$w" = "$WORKER" ]; then
            echo "" >&2
            echo "bp --route: @$WORKER is heavyweight (live host reach / real cost) — NOT auto-run." >&2
            echo "            Read the route above, then run it deliberately." >&2
            exit 3
        fi
    done
    echo ""
    echo "bp --route: running it as @$FROM …"
    [ -n "$TIMEOUT" ] || TIMEOUT=$(pick_timeout "$WORKER")
    exec room-ask --from "$FROM" --timeout "$TIMEOUT" "@$WORKER" "$*"
fi

WORKER=$(printf '%s' "$1" | sed 's/^[@#]//'); shift
[ -n "$TIMEOUT" ] || TIMEOUT=$(pick_timeout "$WORKER")
exec room-ask --from "$FROM" --timeout "$TIMEOUT" "@$WORKER" "$*"
