#!/usr/bin/env bash
# Admin-authoring observer (Task 486).
#
# Observation-only PostToolUse hook. When the admin agent (not a specialist
# subagent) writes or edits a file under <accountDir>/output/, emit one
# stderr line capturing whether a specialist was dispatched earlier in the
# current turn. A `priorSpecialistSpawnInTurn=false` value on a long-form
# prose file is the regression signal Task 486 was designed to make visible
# without relying on operator complaint — it surfaces the same failure mode
# the BioSymm proposal session exhibited (admin authored a customer-facing
# proposal inline despite content-producer being installed).
#
# This hook never blocks. Exit code is always 0.
#
# Output line shape (on stderr, no stdout):
#   [admin-authoring] inline-write path=<rel> priorSpecialistSpawnInTurn=<true|false|unknown>

set -uo pipefail

# Empty stdin (terminal invocation) — silent no-op for safety in tests.
if [ -t 0 ]; then
  exit 0
fi
INPUT=$(cat)

# Only PostToolUse on Write or Edit is observed.
HOOK_EVENT=$(printf '%s' "$INPUT" | python3 -c '
import sys, json
try:
    print(json.load(sys.stdin).get("hook_event_name", "") or "")
except Exception:
    print("")
' 2>/dev/null)
TOOL_NAME=$(printf '%s' "$INPUT" | python3 -c '
import sys, json
try:
    print(json.load(sys.stdin).get("tool_name", "") or "")
except Exception:
    print("")
' 2>/dev/null)
if [ "$HOOK_EVENT" != "PostToolUse" ]; then
  exit 0
fi
if [ "$TOOL_NAME" != "Write" ] && [ "$TOOL_NAME" != "Edit" ]; then
  exit 0
fi

# Subagent writes are out of scope. pty-spawner stamps MAXY_SPECIALIST on
# every specialist process; only the admin process sees it empty.
if [ -n "${MAXY_SPECIALIST:-}" ]; then
  exit 0
fi

FILE_PATH=$(printf '%s' "$INPUT" | python3 -c '
import sys, json
try:
    d = json.load(sys.stdin)
    print((d.get("tool_input", {}) or {}).get("file_path", "") or "")
except Exception:
    print("")
' 2>/dev/null)
[ -z "$FILE_PATH" ] && exit 0

# Resolve to absolute. The hook fires in the account dir (PWD), which is the
# claude project root (each account has its own .git).
case "$FILE_PATH" in
  /*) ABS="$FILE_PATH" ;;
  *)  ABS="$PWD/$FILE_PATH" ;;
esac

# Only files under <accountDir>/output/ are in scope.
case "$ABS" in
  "$PWD/output/"*) REL="${ABS#$PWD/}" ;;
  *) exit 0 ;;
esac

TRANSCRIPT_PATH=$(printf '%s' "$INPUT" | python3 -c '
import sys, json
try:
    print(json.load(sys.stdin).get("transcript_path", "") or "")
except Exception:
    print("")
' 2>/dev/null)
# Test override so the .test.sh suite can pin a fixture transcript.
if [ -n "${ADMIN_AUTHORING_TRANSCRIPT_PATH:-}" ]; then
  TRANSCRIPT_PATH="$ADMIN_AUTHORING_TRANSCRIPT_PATH"
fi

if [ -z "$TRANSCRIPT_PATH" ] || [ ! -f "$TRANSCRIPT_PATH" ]; then
  echo "[admin-authoring] inline-write path=${REL} priorSpecialistSpawnInTurn=unknown" >&2
  exit 0
fi

# Walk the transcript: from the latest real-user turn forward, find any
# assistant `tool_use` whose `name == "Task"` and whose
# `input.subagent_type` starts with `specialists:`.
PRIOR=$(TRANSCRIPT_PATH="$TRANSCRIPT_PATH" python3 - <<'PY'
import os, json, sys

path = os.environ["TRANSCRIPT_PATH"]
records = []
try:
    with open(path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if line:
                records.append(json.loads(line))
except Exception:
    print("unknown"); sys.exit(0)

def is_real_user(d):
    if d.get("type") != "user":
        return False
    msg = d.get("message", {}) or {}
    if msg.get("role") != "user":
        return False
    content = msg.get("content")
    if isinstance(content, str):
        return True
    if isinstance(content, list):
        for b in content:
            if isinstance(b, dict) and b.get("type") != "tool_result":
                return True
        return False
    return True

last_user = -1
for i in range(len(records) - 1, -1, -1):
    if is_real_user(records[i]):
        last_user = i
        break

for d in records[last_user + 1:]:
    if d.get("type") != "assistant":
        continue
    msg = d.get("message", {}) or {}
    if msg.get("role") != "assistant":
        continue
    for b in (msg.get("content") or []):
        if not isinstance(b, dict):
            continue
        if b.get("type") != "tool_use":
            continue
        if b.get("name") != "Task":
            continue
        sub = (b.get("input") or {}).get("subagent_type")
        if isinstance(sub, str) and sub.startswith("specialists:"):
            print("true"); sys.exit(0)

print("false")
PY
)

echo "[admin-authoring] inline-write path=${REL} priorSpecialistSpawnInTurn=${PRIOR}" >&2
exit 0
