#!/usr/bin/env bash
# Task 1961 — the classless inline-write line is the recurring-deliverable
# arming signal.
#
# admin-authoring-observer.sh emits, on stderr, one line when the admin
# process (MAXY_SPECIALIST empty) writes under <accountDir>/output/:
#   [admin-authoring] inline-write path=<rel> priorSpecialistSpawnInTurn=<true|false|unknown>
#
# priorSpecialistSpawnInTurn=false is the arming signal: an inline output
# write with no specialist dispatched earlier in the turn. This suite pins
# fixture transcripts via ADMIN_AUTHORING_TRANSCRIPT_PATH and asserts:
#   - false when the transcript has no specialists: Task after the last user turn
#   - true  when it does
#   - unknown when no transcript is available
#   - no line at all for writes outside output/, or from a specialist process
set -u
HOOK="$(cd "$(dirname "$0")/.." && pwd)/admin-authoring-observer.sh"
[[ -x "$HOOK" ]] || { echo "FAIL: $HOOK not executable"; exit 1; }

PASS=0; FAIL=0
pass() { PASS=$((PASS+1)); echo "PASS: $1"; }
fail() { FAIL=$((FAIL+1)); echo "FAIL: $1" >&2; }

TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT
ACCT="$TMP/account"
mkdir -p "$ACCT/output"

# Fixture transcripts.
NO_SPECIALIST="$TMP/no-specialist.jsonl"
cat >"$NO_SPECIALIST" <<'JSON'
{"type":"user","message":{"role":"user","content":"draft a quote for the Smith job"}}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"On it."}]}}
JSON

WITH_SPECIALIST="$TMP/with-specialist.jsonl"
cat >"$WITH_SPECIALIST" <<'JSON'
{"type":"user","message":{"role":"user","content":"draft a quote for the Smith job"}}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"tool_use","name":"Task","input":{"subagent_type":"specialists:content-producer"}}]}}
JSON

# A Task whose subagent_type is not a specialist: must not count as a spawn.
NON_SPECIALIST_TASK="$TMP/non-specialist-task.jsonl"
cat >"$NON_SPECIALIST_TASK" <<'JSON'
{"type":"user","message":{"role":"user","content":"draft a quote for the Smith job"}}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"tool_use","name":"Task","input":{"subagent_type":"general-purpose"}}]}}
JSON

# A specialist dispatched in a PRIOR turn must not arm the current turn: the
# hook walks forward only from the last real-user turn.
PRIOR_TURN_SPECIALIST="$TMP/prior-turn-specialist.jsonl"
cat >"$PRIOR_TURN_SPECIALIST" <<'JSON'
{"type":"user","message":{"role":"user","content":"earlier request"}}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"tool_use","name":"Task","input":{"subagent_type":"specialists:content-producer"}}]}}
{"type":"user","message":{"role":"user","content":"draft a quote for the Smith job"}}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"On it."}]}}
JSON

# input <tool_name> <file_path> — builds the PostToolUse payload the hook parses.
mk_input() {
  python3 -c '
import json, sys
print(json.dumps({
  "hook_event_name": "PostToolUse",
  "tool_name": sys.argv[1],
  "tool_input": {"file_path": sys.argv[2]},
  "transcript_path": ""
}, separators=(",", ":")))
' "$1" "$2"
}

# run <transcript-or-empty> <MAXY_SPECIALIST> <tool_name> <file_path> — fires the
# hook from inside the account dir (its output/ scope keys off $PWD) and returns
# stderr.
run() {
  local transcript="$1" specialist="$2" tool="$3" fp="$4"
  ( cd "$ACCT" \
    && mk_input "$tool" "$fp" \
    | ADMIN_AUTHORING_TRANSCRIPT_PATH="$transcript" MAXY_SPECIALIST="$specialist" \
      bash "$HOOK" 2>&1 1>/dev/null )
}

ARM_RE='\[admin-authoring\] inline-write path=output/quote\.html priorSpecialistSpawnInTurn='

# 1. Arming signal: inline output write, no specialist in the turn.
OUT=$(run "$NO_SPECIALIST" "" Write "output/quote.html")
echo "$OUT" | grep -qE "${ARM_RE}false" \
  && pass "arming: priorSpecialistSpawnInTurn=false on inline output write" \
  || fail "arming false expected, got: $OUT"

# 2. Owned: a specialist was dispatched earlier in the same turn.
OUT=$(run "$WITH_SPECIALIST" "" Write "output/quote.html")
echo "$OUT" | grep -qE "${ARM_RE}true" \
  && pass "owned: priorSpecialistSpawnInTurn=true when specialist dispatched" \
  || fail "true expected, got: $OUT"

# 3. Unknown: no transcript available — line still fires, value is not the arming one.
OUT=$(run "$TMP/does-not-exist.jsonl" "" Write "output/quote.html")
echo "$OUT" | grep -qE "${ARM_RE}unknown" \
  && pass "unknown: priorSpecialistSpawnInTurn=unknown with no transcript" \
  || fail "unknown expected, got: $OUT"

# 4. Edit is observed like Write.
OUT=$(run "$NO_SPECIALIST" "" Edit "output/quote.html")
echo "$OUT" | grep -qE "${ARM_RE}false" \
  && pass "Edit under output/ is observed" \
  || fail "Edit expected arming line, got: $OUT"

# 4a. A non-specialist Task in the turn does not count as a spawn — still armed.
OUT=$(run "$NON_SPECIALIST_TASK" "" Write "output/quote.html")
echo "$OUT" | grep -qE "${ARM_RE}false" \
  && pass "arming: non-specialist Task does not disarm" \
  || fail "false expected for non-specialist Task, got: $OUT"

# 4b. A specialist in a PRIOR turn does not disarm the current turn.
OUT=$(run "$PRIOR_TURN_SPECIALIST" "" Write "output/quote.html")
echo "$OUT" | grep -qE "${ARM_RE}false" \
  && pass "arming: prior-turn specialist does not disarm current turn" \
  || fail "false expected for prior-turn specialist, got: $OUT"

# 5. Scope guard — write outside output/ emits no line.
OUT=$(run "$NO_SPECIALIST" "" Write "notes/scratch.txt")
echo "$OUT" | grep -q '\[admin-authoring\]' \
  && fail "write outside output/ must emit nothing, got: $OUT" \
  || pass "scope guard: write outside output/ emits no line"

# 6. Scope guard — a specialist process (MAXY_SPECIALIST set) emits no line.
OUT=$(run "$NO_SPECIALIST" "content-producer" Write "output/quote.html")
echo "$OUT" | grep -q '\[admin-authoring\]' \
  && fail "specialist process must emit nothing, got: $OUT" \
  || pass "scope guard: specialist process emits no line"

echo "----"
echo "PASS=$PASS FAIL=$FAIL"
[[ "$FAIL" -eq 0 ]]
