#!/usr/bin/env bash
TEST_CATEGORY=extended

level=$1
if [ -z "$level" ]; then
  level=1
fi
echo "starting: ${BASH_SOURCE[@]##*/} <LOG_LEVEL=$level>"

source this
source test.suite
source $OOSH_DIR/hiveMind

log.level $level

# ============================================================================
# Test hiveMind.list - lists all hive agents
# ============================================================================

test.case $level "hiveMind.list - returns agent IDs" \
  hiveMind.list

if ! command -v agentRoom &>/dev/null || agentRoom backend.status 2>/dev/null | grep -q "not running"; then
  expect.pass "hiveMind.list callable (skipped count check - agentRoom unavailable)"
else
  AGENT_COUNT=$(hiveMind.list 2>/dev/null | wc -l)
  if [ "$AGENT_COUNT" -ge 1 ]; then
    expect.pass "hiveMind.list found $AGENT_COUNT agents"
  else
    expect.fail "hiveMind.list should find at least 1 agent (queen)"
  fi
fi

# ============================================================================
# Test hiveMind.workers - lists only worker agents
# ============================================================================

test.case $level "hiveMind.workers - returns worker IDs only" \
  hiveMind.workers

WORKER_COUNT=$(hiveMind.workers 2>/dev/null | wc -l)
if [ "$WORKER_COUNT" -ge 0 ]; then
  expect.pass "hiveMind.workers found $WORKER_COUNT workers"
else
  expect.fail "hiveMind.workers should return a count >= 0"
fi

# ============================================================================
# Test hiveMind.queen - returns queen ID
# ============================================================================

test.case $level "hiveMind.queen - returns queen ID" \
  hiveMind.queen

if ! command -v agentRoom &>/dev/null || agentRoom backend.status 2>/dev/null | grep -q "not running"; then
  expect.pass "hiveMind.queen callable (skipped content check - agentRoom unavailable)"
else
  QUEEN_ID=$(hiveMind.queen 2>/dev/null)
  if [ -n "$QUEEN_ID" ] && echo "$QUEEN_ID" | grep -q "queen"; then
    expect.pass "hiveMind.queen returned: $QUEEN_ID"
  else
    expect.fail "hiveMind.queen should return queen ID containing 'queen'"
  fi
fi

# ============================================================================
# Test hiveMind.status - shows hive status
# ============================================================================

test.case $level "hiveMind.status - displays status" \
  hiveMind.status 0

if [ "$RETURN_VALUE" -eq 0 ]; then
  expect.pass "hiveMind.status returned success"
else
  expect.fail "hiveMind.status should return 0"
fi

# ============================================================================
# Test hiveMind.usage - displays usage information
# ============================================================================

test.case $level "hiveMind.usage - displays usage" \
  hiveMind.usage

USAGE_OUTPUT=$(hiveMind.usage 2>/dev/null)
if echo "$USAGE_OUTPUT" | grep -q "hiveMind"; then
  expect.pass "hiveMind.usage displays usage info"
else
  expect.fail "hiveMind.usage should display hiveMind info"
fi

# ============================================================================
# Test completion functions exist
# ============================================================================

test.case $level "hiveMind.focus.completion.agentId exists" \
  type -t hiveMind.focus.completion.agentId

if type -t hiveMind.focus.completion.agentId &>/dev/null; then
  expect.pass "hiveMind.focus.completion.agentId function exists"
else
  expect.fail "hiveMind.focus.completion.agentId should exist"
fi

test.case $level "hiveMind.spawn.completion.type exists" \
  type -t hiveMind.spawn.completion.type

SPAWN_TYPES=$(hiveMind.spawn.completion.type 2>/dev/null)
if echo "$SPAWN_TYPES" | grep -q "coder"; then
  expect.pass "hiveMind.spawn.completion.type returns valid types"
else
  expect.fail "hiveMind.spawn.completion.type should include 'coder'"
fi

# ============================================================================
# Test private functions exist
# ============================================================================

test.case $level "private.hiveMind.get.agents exists" \
  type -t private.hiveMind.get.agents

if type -t private.hiveMind.get.agents &>/dev/null; then
  expect.pass "private.hiveMind.get.agents function exists"
else
  expect.fail "private.hiveMind.get.agents should exist"
fi

# ============================================================================
# Test hiveMind.team.setup.oosh
# ============================================================================

test.case $level "hiveMind.team.setup.oosh function exists" \
  type -t hiveMind.team.setup.oosh

if type -t hiveMind.team.setup.oosh &>/dev/null; then
  expect.pass "hiveMind.team.setup.oosh function exists"
else
  expect.fail "hiveMind.team.setup.oosh should be defined"
fi

test.case $level "hiveMind.team.setup.oosh.completion.session exists and returns values" \
  type -t hiveMind.team.setup.oosh.completion.session

if type -t hiveMind.team.setup.oosh.completion.session &>/dev/null; then
  COMPLETIONS=$(hiveMind.team.setup.oosh.completion.session 2>/dev/null)
  if echo "$COMPLETIONS" | grep -q "cursorOrchestrator"; then
    expect.pass "completion returns cursorOrchestrator"
  else
    expect.fail "completion should include cursorOrchestrator"
  fi
else
  expect.fail "hiveMind.team.setup.oosh.completion.session should be defined"
fi

# Create a throwaway tmux session FIRST, then verify the method rejects it
TEST_SESSION="__test_setup_oosh_$$"
tmux new-session -d -s "$TEST_SESSION" 2>/dev/null
SETUP_OK=$?

test.case $level "hiveMind.team.setup.oosh rejects existing session" \
  hiveMind.team.setup.oosh "$TEST_SESSION"

if [ "$SETUP_OK" -eq 0 ]; then
  if [ "$RETURN_VALUE" -eq 1 ]; then
    expect.pass "team.setup.oosh rejects existing session"
  else
    expect.fail "team.setup.oosh should return 1 for existing session"
  fi
  tmux kill-session -t "$TEST_SESSION" 2>/dev/null
else
  expect.pass "team.setup.oosh rejects existing session (skipped - tmux unavailable)"
fi

test.case $level "role prompt lookup returns oosh-orchestrator" \
  private.hiveMind.get.role.prompt oosh-orchestrator

PROMPT_VAL=$(private.hiveMind.get.role.prompt oosh-orchestrator 2>/dev/null)
if [ -n "$PROMPT_VAL" ]; then
  expect.pass "oosh-orchestrator role prompt defined"
else
  expect.fail "private.hiveMind.get.role.prompt oosh-orchestrator should return a value"
fi

# ============================================================================
# Test role prompt lookup - all roles
# ============================================================================

test.case $level "role prompt lookup returns agent-teacher" \
  private.hiveMind.get.role.prompt agent-teacher

PROMPT_VAL=$(private.hiveMind.get.role.prompt agent-teacher 2>/dev/null)
if [ -n "$PROMPT_VAL" ]; then
  expect.pass "agent-teacher role prompt defined"
else
  expect.fail "private.hiveMind.get.role.prompt agent-teacher should return a value"
fi

test.case $level "role prompt lookup returns scrum-master" \
  private.hiveMind.get.role.prompt scrum-master

PROMPT_VAL=$(private.hiveMind.get.role.prompt scrum-master 2>/dev/null)
if [ -n "$PROMPT_VAL" ]; then
  expect.pass "scrum-master role prompt defined"
else
  expect.fail "private.hiveMind.get.role.prompt scrum-master should return a value"
fi

test.case $level "role prompt lookup returns product-owner" \
  private.hiveMind.get.role.prompt product-owner

PROMPT_VAL=$(private.hiveMind.get.role.prompt product-owner 2>/dev/null)
if [ -n "$PROMPT_VAL" ]; then
  expect.pass "product-owner role prompt defined"
else
  expect.fail "private.hiveMind.get.role.prompt product-owner should return a value"
fi

test.case $level "role prompt lookup returns developer" \
  private.hiveMind.get.role.prompt developer

PROMPT_VAL=$(private.hiveMind.get.role.prompt developer 2>/dev/null)
if [ -n "$PROMPT_VAL" ]; then
  expect.pass "developer role prompt defined"
else
  expect.fail "private.hiveMind.get.role.prompt developer should return a value"
fi

# ============================================================================
# Test hiveMind.role.list
# ============================================================================

test.case $level "hiveMind.role.list function exists" \
  type -t hiveMind.role.list

if type -t hiveMind.role.list &>/dev/null; then
  expect.pass "hiveMind.role.list function exists"
else
  expect.fail "hiveMind.role.list should be defined"
fi

test.case $level "hiveMind.role.list returns agent roles" \
  hiveMind.role.list

ROLE_OUTPUT=$(hiveMind.role.list 2>/dev/null)
if echo "$ROLE_OUTPUT" | grep -q "oosh-expert"; then
  expect.pass "role.list includes oosh-expert"
else
  expect.fail "role.list should include oosh-expert"
fi

if echo "$ROLE_OUTPUT" | grep -q "agent-teacher"; then
  expect.pass "role.list includes agent-teacher"
else
  expect.fail "role.list should include agent-teacher"
fi

if echo "$ROLE_OUTPUT" | grep -q "scrum-master"; then
  expect.pass "role.list includes scrum-master"
else
  expect.fail "role.list should include scrum-master"
fi

# ============================================================================
# Test hiveMind.role.prompt
# ============================================================================

test.case $level "hiveMind.role.prompt function exists" \
  type -t hiveMind.role.prompt

if type -t hiveMind.role.prompt &>/dev/null; then
  expect.pass "hiveMind.role.prompt function exists"
else
  expect.fail "hiveMind.role.prompt should be defined"
fi

test.case $level "hiveMind.role.prompt returns prompt for oosh-expert" \
  hiveMind.role.prompt oosh-expert

PROMPT_OUTPUT=$(hiveMind.role.prompt oosh-expert 2>/dev/null)
if echo "$PROMPT_OUTPUT" | grep -q "OOSH framework expert"; then
  expect.pass "role.prompt returns correct prompt for oosh-expert"
else
  expect.fail "role.prompt should return prompt containing 'OOSH framework expert'"
fi

test.case $level "hiveMind.role.prompt fails for unknown role" \
  hiveMind.role.prompt nonexistent-role

if [ "$RETURN_VALUE" -ne 0 ]; then
  expect.pass "role.prompt correctly rejects unknown role"
else
  expect.fail "role.prompt should fail for unknown role"
fi

# ============================================================================
# Test hiveMind.agent.bootstrap function exists
# ============================================================================

test.case $level "hiveMind.agent.bootstrap function exists" \
  type -t hiveMind.agent.bootstrap

if type -t hiveMind.agent.bootstrap &>/dev/null; then
  expect.pass "hiveMind.agent.bootstrap function exists"
else
  expect.fail "hiveMind.agent.bootstrap should be defined"
fi

# ============================================================================
# Test hiveMind.agent.verify function exists
# ============================================================================

test.case $level "hiveMind.agent.verify function exists" \
  type -t hiveMind.agent.verify

if type -t hiveMind.agent.verify &>/dev/null; then
  expect.pass "hiveMind.agent.verify function exists"
else
  expect.fail "hiveMind.agent.verify should be defined"
fi

# ============================================================================
# Test hiveMind.team.setup.full
# ============================================================================

test.case $level "hiveMind.team.setup.full function exists" \
  type -t hiveMind.team.setup.full

if type -t hiveMind.team.setup.full &>/dev/null; then
  expect.pass "hiveMind.team.setup.full function exists"
else
  expect.fail "hiveMind.team.setup.full should be defined"
fi

test.case $level "hiveMind.team.setup.full.completion.session exists and returns values" \
  type -t hiveMind.team.setup.full.completion.session

if type -t hiveMind.team.setup.full.completion.session &>/dev/null; then
  COMPLETIONS=$(hiveMind.team.setup.full.completion.session 2>/dev/null)
  if echo "$COMPLETIONS" | grep -q "cursorOrchestrator"; then
    expect.pass "completion returns cursorOrchestrator"
  else
    expect.fail "completion should include cursorOrchestrator"
  fi
else
  expect.fail "hiveMind.team.setup.full.completion.session should be defined"
fi

# Create a throwaway tmux session to test rejection
TEST_SESSION_FULL="__test_setup_full_$$"
tmux new-session -d -s "$TEST_SESSION_FULL" 2>/dev/null
SETUP_FULL_OK=$?

test.case $level "hiveMind.team.setup.full rejects existing session" \
  hiveMind.team.setup.full "$TEST_SESSION_FULL"

if [ "$SETUP_FULL_OK" -eq 0 ]; then
  if [ "$RETURN_VALUE" -eq 1 ]; then
    expect.pass "team.setup.full rejects existing session"
  else
    expect.fail "team.setup.full should return 1 for existing session"
  fi
  tmux kill-session -t "$TEST_SESSION_FULL" 2>/dev/null
else
  expect.pass "team.setup.full rejects existing session (skipped - tmux unavailable)"
fi

# ============================================================================
# Test hiveMind.team.status function exists
# ============================================================================

test.case $level "hiveMind.team.status function exists" \
  type -t hiveMind.team.status

if type -t hiveMind.team.status &>/dev/null; then
  expect.pass "hiveMind.team.status function exists"
else
  expect.fail "hiveMind.team.status should be defined"
fi

# ============================================================================
# Test hiveMind.monitor.approve function exists
# ============================================================================

test.case $level "hiveMind.monitor.approve function exists" \
  type -t hiveMind.monitor.approve

if type -t hiveMind.monitor.approve &>/dev/null; then
  expect.pass "hiveMind.monitor.approve function exists"
else
  expect.fail "hiveMind.monitor.approve should be defined"
fi

# ============================================================================
# Test HIVEMIND_AGENTS_DIR is set
# ============================================================================

test.case $level "HIVEMIND_AGENTS_DIR is configured" \
  echo "$HIVEMIND_AGENTS_DIR"

if [ -n "$HIVEMIND_AGENTS_DIR" ]; then
  expect.pass "HIVEMIND_AGENTS_DIR is set: $HIVEMIND_AGENTS_DIR"
else
  expect.fail "HIVEMIND_AGENTS_DIR should be set"
fi

# ============================================================================
# Test .claude/agents/ symlinks resolve
# ============================================================================

# .claude/agents/ and .cursor/skills/ live at the workspace root.
# Derive from HIVEMIND_AGENTS_DIR if set, otherwise fall back to OOSH_DIR hierarchy.
if [ -n "$HIVEMIND_AGENTS_DIR" ]; then
  WORKSPACE_ROOT="${HIVEMIND_AGENTS_DIR%/.claude/agents}"
else
  WORKSPACE_ROOT="${OOSH_DIR}/../../.."
fi

test.case $level ".claude/agents/ directory structure exists" \
  ls "$WORKSPACE_ROOT/.claude/agents/"

if [ -d "$WORKSPACE_ROOT/.claude/agents/oosh-expert" ] && [ -d "$WORKSPACE_ROOT/.claude/agents/agent-teacher" ] && [ -d "$WORKSPACE_ROOT/.claude/agents/scrum-master" ]; then
  expect.pass ".claude/agents/ has expected role directories"
else
  expect.fail ".claude/agents/ should contain role directories (checked $WORKSPACE_ROOT/.claude/agents/)"
fi

test.case $level ".cursor/skills/ symlinks resolve to .claude/agents/" \
  ls "$WORKSPACE_ROOT/.cursor/skills/oosh-expert/SKILL.md"

if [ -f "$WORKSPACE_ROOT/.cursor/skills/oosh-expert/SKILL.md" ] && [ -L "$WORKSPACE_ROOT/.cursor/skills/oosh-expert" ]; then
  expect.pass ".cursor/skills/oosh-expert is a symlink that resolves"
else
  expect.fail ".cursor/skills/oosh-expert should be a working symlink (checked $WORKSPACE_ROOT/.cursor/skills/)"
fi

# ============================================================================
# IDENTITY CHAIN CONSISTENCY TESTS
# Cross-compare all identity sources to catch drift between the 4 layers:
#   Layer 1: Pane → Role       (~/config/hivemind.roles.env)
#   Layer 2: Role → UUID       (~/config/hivemind.sessions.env)
#   Layer 3: UUID → Name       (~/.claude/projects/*/sessions-index.json)
#   Layer 4: PID → UUID        (ps args: --resume <uuid>)
# ============================================================================

REG_FILE="${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}"
SES_FILE="${HIVEMIND_SESSIONS:-${CONFIG_PATH:-$HOME/config}/hivemind.sessions.env}"
AGENTS_BASE="${HIVEMIND_AGENTS_DIR:-${CLAUDE_PROJECT_DIR:-$WORKSPACE_ROOT}/.claude/agents}"

# Detect a live session with Claude agents for testing
# Prefer hiveMindTeam02_03_26 (new live-discovery session), fall back to any session with agents
CONSIST_SESSION=""
for sess in $(tmux list-sessions -F '#{session_name}' 2>/dev/null | sort -r); do
  paneCount=$(tmux list-panes -t "$sess" -F '#{pane_index}' 2>/dev/null | wc -l | tr -d ' ')
  if [ "$paneCount" -ge 2 ]; then
    # Check registry OR live Claude processes on panes
    hasAgents=false
    if grep -q "^${sess}:" "$REG_FILE" 2>/dev/null; then
      hasAgents=true
    else
      # Live discovery: check if any pane has a Claude process
      for paneAddr in $(tmux list-panes -t "$sess" -F '#{session_name}:#{window_index}.#{pane_index}' 2>/dev/null); do
        panePid=$(tmux display-message -t "$paneAddr" -p '#{panePid}' 2>/dev/null)
        if [ -n "$panePid" ] && pgrep -P "$panePid" -f "claude" >/dev/null 2>&1; then
          hasAgents=true
          break
        fi
      done
    fi
    if $hasAgents; then
      CONSIST_SESSION="$sess"
      # Prefer the new hiveMindTeam session specifically
      echo "$sess" | grep -q "hiveMindTeam02" && break
    fi
  fi
done

# ── T-CONSIST-1: team.context.status shows ALL panes ─────────────────────
# Every pane in otmux pane.list must appear in team.context.status output.
# Bug 9: unregistered panes are invisible.

if [ -n "$CONSIST_SESSION" ]; then
  test.case $level "T-CONSIST-1: team.context.status shows all panes for $CONSIST_SESSION" \
    echo "checking pane coverage"

  # Get actual pane count from tmux
  ACTUAL_PANES=$(tmux list-panes -t "$CONSIST_SESSION" -F '#{window_index}.#{pane_index}' 2>/dev/null | wc -l | tr -d ' ')

  # Get reported pane count from team.context.status (count non-header, non-separator, non-alert lines)
  STATUS_OUTPUT=$(hiveMind team.context.status "$CONSIST_SESSION" 2>/dev/null)
  REPORTED_PANES=$(echo "$STATUS_OUTPUT" | grep -cE '^\S+\s+[0-9]+\.[0-9]+')

  if [ "$REPORTED_PANES" -ge "$ACTUAL_PANES" ]; then
    expect.pass "team.context.status shows $REPORTED_PANES panes (actual: $ACTUAL_PANES)"
  else
    expect.fail "team.context.status shows only $REPORTED_PANES of $ACTUAL_PANES panes — unregistered panes invisible"
  fi
else
  test.case $level "T-CONSIST-1: team.context.status pane coverage (skipped - no session with agents)" \
    echo "skipped"
  expect.pass "skipped — no live session with registered agents"
fi

# ── T-CONSIST-2: team.context.status uses OOSH wrappers (no raw tmux) ────
# Bug 8: raw tmux calls violate OOSH-only rule.

test.case $level "T-CONSIST-2: team.context.status has no raw tmux calls" \
  echo "checking hiveMind source"

# Extract team.context.status function body
# Extract function body: from declaration to next function declaration
TCS_START=$(grep -n '^hiveMind\.team\.context\.status()' "$OOSH_DIR/hiveMind" | head -1 | cut -d: -f1)
TCS_END=$(awk "NR>$TCS_START && /^hiveMind\./{print NR; exit}" "$OOSH_DIR/hiveMind")
if [ -n "$TCS_START" ] && [ -n "$TCS_END" ]; then
  RAW_TMUX_COUNT=$(sed -n "${TCS_START},${TCS_END}p" "$OOSH_DIR/hiveMind" | grep -cE '(^|[^a-zA-Z])tmux ' || true)
else
  RAW_TMUX_COUNT=0
fi

if [ "$RAW_TMUX_COUNT" -eq 0 ]; then
  expect.pass "team.context.status uses 0 raw tmux calls (OOSH-only compliant)"
else
  expect.fail "team.context.status has $RAW_TMUX_COUNT raw tmux calls — should use otmux wrappers"
fi

# ── T-CONSIST-3: Registry role names are valid ───────────────────────────
# Every role must be < 30 chars, no spaces, and match a .claude/agents/<role>/ directory.
# Bug 4: boot prompt text leaking into registry.

# Clean up stale __test_* entries from previous test runs first
if [ -f "$REG_FILE" ]; then
  grep -v '^__test_' "$REG_FILE" > "${REG_FILE}.tmp" 2>/dev/null && mv "${REG_FILE}.tmp" "$REG_FILE"
fi

# Role-to-directory mapping: some roles share agent directories
private.test.role.to.agent.dir() {
  case "$1" in
    orchestrator|oosh-orchestrator) echo "agent-teacher" ;;
    oosh-tester) echo "oosh-expert" ;;
    *) echo "$1" ;;
  esac
}

CONSIST3_TESTED=0
CONSIST3_FAILED=0

# Re-clean __test_ entries (earlier tests may have re-added them)
if [ -f "$REG_FILE" ]; then
  grep -v '^__test_' "$REG_FILE" > "${REG_FILE}.tmp" 2>/dev/null && mv "${REG_FILE}.tmp" "$REG_FILE"
fi

if [ -f "$REG_FILE" ]; then
  while IFS='|' read -r paneTarget role; do
    [ -z "$role" ] && continue
    [[ "$paneTarget" == __test_* ]] && continue
    CONSIST3_TESTED=$((CONSIST3_TESTED + 1))

    test.case $level "T-CONSIST-3: registry role valid: $paneTarget → $role" \
      echo "role='$role'"

    # Check length
    if [ "${#role}" -gt 30 ]; then
      expect.fail "registry GARBAGE $paneTarget: role ${#role} chars — '${role:0:40}...'"
      CONSIST3_FAILED=$((CONSIST3_FAILED + 1))
      continue
    fi

    # Check no spaces
    if echo "$role" | grep -q ' '; then
      expect.fail "registry GARBAGE $paneTarget: role has spaces: '$role'"
      CONSIST3_FAILED=$((CONSIST3_FAILED + 1))
      continue
    fi

    # Check agent dir exists (with role-to-directory mapping)
    local agentDir
    agentDir=$(private.test.role.to.agent.dir "$role")
    if [ -d "$AGENTS_BASE/$agentDir" ]; then
      expect.pass "registry $paneTarget = '$role' (valid, dir=$agentDir)"
    elif [ -d "$AGENTS_BASE/$role" ]; then
      expect.pass "registry $paneTarget = '$role' (valid)"
    else
      expect.fail "registry ORPHAN $paneTarget: '$role' has no agent directory"
      CONSIST3_FAILED=$((CONSIST3_FAILED + 1))
    fi
  done < "$REG_FILE"

  echo "  T-CONSIST-3 summary: $CONSIST3_TESTED entries, $CONSIST3_FAILED invalid"
fi

# ── T-CONSIST-4: Registry entries match live panes ───────────────────────
# Every pane in the registry must still exist in tmux.
# Bug 5: stale entries persist for dead panes.

CONSIST4_TESTED=0
CONSIST4_STALE=0

if [ -f "$REG_FILE" ]; then
  while IFS='|' read -r paneTarget role; do
    [ -z "$paneTarget" ] && continue
    [[ "$paneTarget" == __test_* ]] && continue
    CONSIST4_TESTED=$((CONSIST4_TESTED + 1))

    test.case $level "T-CONSIST-4: registry pane exists in tmux: $paneTarget" \
      echo "checking $paneTarget ($role)"

    if tmux display-message -t "$paneTarget" -p "#{pane_id}" >/dev/null 2>&1; then
      expect.pass "registry $paneTarget ($role) — pane exists"
    else
      expect.fail "registry STALE $paneTarget ($role) — pane gone from tmux"
      CONSIST4_STALE=$((CONSIST4_STALE + 1))
    fi
  done < "$REG_FILE"

  echo "  T-CONSIST-4 summary: $CONSIST4_TESTED entries, $CONSIST4_STALE stale"
fi

# ── T-CONSIST-5: otmux tree titles vs registry roles ────────────────────
# Pane titles (set by pane.identify) should match registry role names.

if [ -n "$CONSIST_SESSION" ]; then
  CONSIST5_TESTED=0
  CONSIST5_MISMATCH=0

  while IFS='|' read -r paneTarget role; do
    [ -z "$paneTarget" ] && continue
    # Only test panes in our consist session
    echo "$paneTarget" | grep -q "^${CONSIST_SESSION}:" || continue

    CONSIST5_TESTED=$((CONSIST5_TESTED + 1))

    # Get pane title from tmux
    paneTitle=$(tmux display-message -t "$paneTarget" -p '#{paneTitle}' 2>/dev/null)

    test.case $level "T-CONSIST-5: pane title vs registry for $paneTarget" \
      echo "title='$paneTitle' registry='$role'"

    # Pane title should contain or match the registry role
    if [ "$paneTitle" = "$role" ]; then
      expect.pass "title matches registry: $role"
    elif echo "$paneTitle" | grep -qi "$role"; then
      expect.pass "title '$paneTitle' contains registry role '$role'"
    else
      expect.fail "title MISMATCH $paneTarget: title='$paneTitle' registry='$role'"
      CONSIST5_MISMATCH=$((CONSIST5_MISMATCH + 1))
    fi
  done < "$REG_FILE"

  echo "  T-CONSIST-5 summary: $CONSIST5_TESTED tested, $CONSIST5_MISMATCH mismatched"
fi

# ── T-CONSIST-6: team.status agrees with team.context.status ────────────
# Both commands describe the same panes — agent names and pane count must match.

if [ -n "$CONSIST_SESSION" ]; then
  test.case $level "T-CONSIST-6: team.status vs team.context.status agent count" \
    echo "comparing for $CONSIST_SESSION"

  # Get agent names from team.context.status
  TCS_AGENTS=$(hiveMind team.context.status "$CONSIST_SESSION" 2>/dev/null | grep -E '^\S+\s+[0-9]+\.[0-9]+' | awk '{print $1}' | sort)
  TCS_COUNT=$(echo "$TCS_AGENTS" | grep -c . || true)

  # Get agent names from team.status
  TS_OUTPUT=$(hiveMind team.status "$CONSIST_SESSION" 2>/dev/null)
  TS_COUNT=$(echo "$TS_OUTPUT" | grep -cE '^\s*(├|└|│).*[0-9]+\.[0-9]+' || true)

  if [ "$TCS_COUNT" -gt 0 ] && [ "$TCS_COUNT" -eq "$TS_COUNT" ]; then
    expect.pass "both show $TCS_COUNT agents for $CONSIST_SESSION"
  elif [ "$TCS_COUNT" -eq 0 ] && [ "$TS_COUNT" -eq 0 ]; then
    expect.pass "both show 0 agents (no registered agents)"
  else
    expect.fail "count MISMATCH: team.context.status=$TCS_COUNT team.status=$TS_COUNT"
  fi
fi

# ── T-CONSIST-7: registry.set rejects invalid role names ────────────────
# Bug 4 fix: registry.set should reject entries > 30 chars or with spaces.

test.case $level "T-CONSIST-7: registry.set rejects garbage role name" \
  echo "testing validation"

# Source hiveMind to get access to private functions
source $OOSH_DIR/hiveMind 2>/dev/null

# Test: role name with spaces (simulating boot prompt leak)
GARBAGE_ROLE="You are oosh-expert on projectTeam"
private.hiveMind.registry.set "__test_garbage:0.0" "$GARBAGE_ROLE" 2>/dev/null
GARBAGE_EXIT=$?

if [ "$GARBAGE_EXIT" -ne 0 ]; then
  expect.pass "registry.set correctly rejected garbage role (exit $GARBAGE_EXIT)"
else
  # Check if it was actually written
  if grep -q "__test_garbage" "$REG_FILE" 2>/dev/null; then
    # Clean up
    grep -v "__test_garbage" "$REG_FILE" > "${REG_FILE}.tmp" 2>/dev/null && mv "${REG_FILE}.tmp" "$REG_FILE"
    expect.fail "registry.set ACCEPTED garbage role — validation missing"
  else
    expect.pass "registry.set did not write garbage role (silent rejection)"
  fi
fi

# Test: valid role name should be accepted
private.hiveMind.registry.set "__test_valid:0.0" "oosh-expert" 2>/dev/null
VALID_EXIT=$?

test.case $level "T-CONSIST-7: registry.set accepts valid role name" \
  echo "testing valid name"

if [ "$VALID_EXIT" -eq 0 ] || grep -q "__test_valid.*oosh-expert" "$REG_FILE" 2>/dev/null; then
  expect.pass "registry.set accepted valid role name 'oosh-expert'"
else
  expect.fail "registry.set rejected valid role name 'oosh-expert' (exit $VALID_EXIT)"
fi

# Clean up test entry
grep -v "__test_valid" "$REG_FILE" > "${REG_FILE}.tmp" 2>/dev/null && mv "${REG_FILE}.tmp" "$REG_FILE"

# ── T-CONSIST-8: session.id matches otmux tree.detailed UUID (BUG-10) ────
# For each Claude pane, claudeCode session.id should return a UUID whose
# first 8 chars match the truncated UUID shown by otmux tree.detailed.
# tree.detailed shows [8-char-hex] from ps args (ground truth for --resume).
# If session.id disagrees, it's returning stale data.

# Scan ALL sessions for Claude panes (not just CONSIST_SESSION)
CONSIST8_TESTED=0
CONSIST8_PASSED=0
CONSIST8_FAILED=0

TREE_OUTPUT=$(timeout 60 otmux tree.detailed 2>/dev/null || true)
CURRENT_SESS=""

while IFS= read -r line; do
  # Session header: "├── sessionName (...)" or "└── sessionName (...)"
  if echo "$line" | grep -qE '^[├└]── '; then
    CURRENT_SESS=$(echo "$line" | sed 's/^[├└]── //' | sed 's/ (.*//')
    continue
  fi

  # Pane line with Claude version: must have [digits.digits.digits]
  echo "$line" | grep -qE '\[[0-9]+\.[0-9]+\.[0-9]+\]' || continue

  # Extract pane address
  PANE_ADDR=$(echo "$line" | grep -oE '[0-9]+\.[0-9]+' | head -1)
  [ -z "$PANE_ADDR" ] && continue
  [ -z "$CURRENT_SESS" ] && continue

  FULL_PANE="${CURRENT_SESS}:${PANE_ADDR}"

  # Extract truncated UUID from tree.detailed: [8-hex-chars] on sub-lines
  # tree.detailed shows UUIDs like [75ce660f] on the line BELOW the pane line
  # But some formats put it inline. Check both: full UUID or 8-char truncated
  TREE_UUID_FULL=$(echo "$line" | grep -oE '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' | tail -1)
  TREE_UUID_SHORT=""

  # If no full UUID on this line, we'll check below
  if [ -z "$TREE_UUID_FULL" ]; then
    # Read ahead: the next line(s) may have the truncated UUID in brackets [8hexchars]
    continue
  fi

  # Get what session.id returns (timeout to prevent hanging)
  SID_UUID=$(timeout 10 claudeCode session.id "$FULL_PANE" 2>/dev/null || true)

  CONSIST8_TESTED=$((CONSIST8_TESTED + 1))

  test.case $level "T-CONSIST-8: session.id vs tree.detailed for $FULL_PANE" \
    echo "sid=${SID_UUID:-empty} tree=${TREE_UUID_FULL:0:8}"

  if [ -z "$SID_UUID" ]; then
    expect.fail "session.id returned EMPTY for $FULL_PANE (tree shows ${TREE_UUID_FULL:0:8}...)"
    CONSIST8_FAILED=$((CONSIST8_FAILED + 1))
  elif [ "$SID_UUID" = "$TREE_UUID_FULL" ]; then
    expect.pass "session.id $FULL_PANE = ${SID_UUID:0:8}... (exact match)"
    CONSIST8_PASSED=$((CONSIST8_PASSED + 1))
  elif [ "${SID_UUID:0:8}" = "${TREE_UUID_FULL:0:8}" ]; then
    expect.pass "session.id $FULL_PANE = ${SID_UUID:0:8}... (prefix match)"
    CONSIST8_PASSED=$((CONSIST8_PASSED + 1))
  else
    expect.fail "session.id STALE $FULL_PANE: sid=${SID_UUID:0:8}... tree=${TREE_UUID_FULL:0:8}..."
    CONSIST8_FAILED=$((CONSIST8_FAILED + 1))
  fi
done <<< "$TREE_OUTPUT"

# Also check sub-lines with truncated UUIDs: [8hexchars]
# tree.detailed puts UUID on indent lines like "│     └ role-name  [75ce660f]"
CURRENT_SESS=""
LAST_PANE=""

while IFS= read -r line; do
  if echo "$line" | grep -qE '^[├└]── '; then
    CURRENT_SESS=$(echo "$line" | sed 's/^[├└]── //' | sed 's/ (.*//')
    LAST_PANE=""
    continue
  fi

  # Track pane addresses from pane lines
  if echo "$line" | grep -qE '\[[0-9]+\.[0-9]+\.[0-9]+\]'; then
    LAST_PANE=$(echo "$line" | grep -oE '[0-9]+\.[0-9]+' | head -1)
    continue
  fi

  # Sub-line with truncated UUID: "│     └ name  [8hexchars]"
  SHORT_UUID=$(echo "$line" | grep -oE '\[[0-9a-f]{8}\]' | tr -d '[]')
  [ -z "$SHORT_UUID" ] && continue
  [ -z "$LAST_PANE" ] && continue
  [ -z "$CURRENT_SESS" ] && continue

  FULL_PANE="${CURRENT_SESS}:${LAST_PANE}"

  # Skip if already tested with full UUID
  # Get what session.id returns (timeout to prevent hanging)
  SID_UUID=$(timeout 10 claudeCode session.id "$FULL_PANE" 2>/dev/null || true)

  CONSIST8_TESTED=$((CONSIST8_TESTED + 1))

  test.case $level "T-CONSIST-8: session.id prefix vs tree for $FULL_PANE" \
    echo "sid=${SID_UUID:-empty} tree_short=${SHORT_UUID}"

  if [ -z "$SID_UUID" ]; then
    expect.fail "session.id returned EMPTY for $FULL_PANE (tree shows ${SHORT_UUID})"
    CONSIST8_FAILED=$((CONSIST8_FAILED + 1))
  elif [ "${SID_UUID:0:8}" = "$SHORT_UUID" ]; then
    expect.pass "session.id $FULL_PANE prefix ${SID_UUID:0:8} matches tree ${SHORT_UUID}"
    CONSIST8_PASSED=$((CONSIST8_PASSED + 1))
  else
    expect.fail "session.id STALE $FULL_PANE: sid=${SID_UUID:0:8} != tree=${SHORT_UUID}"
    CONSIST8_FAILED=$((CONSIST8_FAILED + 1))
  fi

  LAST_PANE=""  # reset to avoid double-testing
done <<< "$TREE_OUTPUT"

echo "  T-CONSIST-8 summary: $CONSIST8_TESTED tested, $CONSIST8_PASSED passed, $CONSIST8_FAILED failed"

# ============================================================================
# Consistency Tests Summary
# ============================================================================

echo ""
echo "  === Identity Consistency Tests Complete ==="
echo ""

# ============================================================================
# T-LIFECYCLE: Fixture-based tests — create sessions, test, tear down
# These tests are self-contained and work on ANY machine.
# ============================================================================

echo ""
echo "=== T-LIFECYCLE: Fixture-based session lifecycle tests ==="
echo ""

LIFECYCLE_TESTED=0
LIFECYCLE_PASSED=0
LIFECYCLE_FAILED=0

# Pre-set HIVEMIND_AGENTS_DIR to prevent EPERM from find.agents.dir in subprocesses
# hiveMind.start() skips the slow search if this is already set.
# Lifecycle/registry tests don't need the real path — any non-empty value works.
if [ -z "$HIVEMIND_AGENTS_DIR" ]; then
  export HIVEMIND_AGENTS_DIR=$(private.hiveMind.find.agents.dir 2>/dev/null || echo "/tmp/hivemind-test-agents")
fi

# Shared cleanup function
testCleanup() {
  local sess="$1"
  tmux kill-session -t "$sess" 2>/dev/null
  # Remove test entries from registry
  local reg="${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}"
  if [ -f "$reg" ]; then
    grep -v "^${sess}:" "$reg" > "/tmp/reg_clean_$$" 2>/dev/null && mv "/tmp/reg_clean_$$" "$reg"
  fi
  # Remove from teams registry
  local teams="${CONFIG_PATH:-$HOME/config}/hivemind.teams.env"
  if [ -f "$teams" ]; then
    grep -v "^${sess}|" "$teams" > "/tmp/teams_clean_$$" 2>/dev/null && mv "/tmp/teams_clean_$$" "$teams"
  fi
}

# ── T-LIFECYCLE-1: Create session and register team ──────────────────────
TEST_SESS="__test_hm_$$"
testCleanup "$TEST_SESS"  # ensure clean start

test.case $level "T-LIFECYCLE-1: create session and register team" \
  echo "session=$TEST_SESS"
LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))

otmux new "$TEST_SESS" -d 2>/dev/null
SESS_EXISTS=$(tmux has-session -t "$TEST_SESS" 2>/dev/null && echo "yes" || true)

if [ "$SESS_EXISTS" = "yes" ]; then
  hiveMind team.register "$TEST_SESS" "lifecycle test" 2>/dev/null || true
  TEAM_ENTRY=$(grep "^${TEST_SESS}|" "${CONFIG_PATH:-$HOME/config}/hivemind.teams.env" 2>/dev/null || true)
  if [ -n "$TEAM_ENTRY" ]; then
    expect.pass "session created + team registered: $TEAM_ENTRY"
    LIFECYCLE_PASSED=$((LIFECYCLE_PASSED + 1))
  else
    expect.fail "session created but team.register failed"
    LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
  fi
else
  expect.fail "otmux new $TEST_SESS failed — session not created"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
fi

# Cleanup T-LIFECYCLE-1
hiveMind team.remove "$TEST_SESS" 2>/dev/null || true
testCleanup "$TEST_SESS"

# ── T-LIFECYCLE-2: pane.identify sets registry + title ───────────────────
TEST_SESS="__test_hm_$$"
testCleanup "$TEST_SESS"

otmux new "$TEST_SESS" -d 2>/dev/null

test.case $level "T-LIFECYCLE-2: pane.identify sets registry and pane title" \
  echo "session=$TEST_SESS"
LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))

private.hiveMind.pane.identify "${TEST_SESS}:0.0" "test-expert" 2>/dev/null || true

REG_ENTRY=$(grep "^${TEST_SESS}:0.0|test-expert" "${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}" 2>/dev/null || true)
PANE_TITLE=$(tmux display-message -t "${TEST_SESS}:0.0" -p "#{paneTitle}" 2>/dev/null || true)

if [ -n "$REG_ENTRY" ] && [ "$PANE_TITLE" = "test-expert" ]; then
  expect.pass "registry='$REG_ENTRY' title='$PANE_TITLE'"
  LIFECYCLE_PASSED=$((LIFECYCLE_PASSED + 1))
elif [ -n "$REG_ENTRY" ]; then
  expect.fail "registry OK but title='$PANE_TITLE' (expected 'test-expert')"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
else
  expect.fail "registry entry not found for ${TEST_SESS}:0.0|test-expert"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
fi

testCleanup "$TEST_SESS"

# ── T-LIFECYCLE-3: registry.set rejects garbage, accepts valid ───────────
TEST_SESS="__test_hm_$$"
testCleanup "$TEST_SESS"

otmux new "$TEST_SESS" -d 2>/dev/null

test.case $level "T-LIFECYCLE-3a: registry.set rejects garbage role names" \
  echo "testing garbage rejection"
LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))

# Should reject: >30 chars, contains spaces, starts with prompt keywords
private.hiveMind.registry.set "${TEST_SESS}:0.0" "Read session/agents/boot-prompt-text that is way too long" 2>/dev/null || true
GARBAGE_ENTRY=$(grep "^${TEST_SESS}:0.0|Read session" "${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}" 2>/dev/null || true)

if [ -z "$GARBAGE_ENTRY" ]; then
  expect.pass "garbage role name correctly rejected"
  LIFECYCLE_PASSED=$((LIFECYCLE_PASSED + 1))
else
  expect.fail "garbage role accepted into registry: $GARBAGE_ENTRY"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
fi

test.case $level "T-LIFECYCLE-3b: registry.set accepts valid role names" \
  echo "testing valid acceptance"
LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))

private.hiveMind.registry.set "${TEST_SESS}:0.0" "valid-role" 2>/dev/null || true
VALID_ENTRY=$(grep "^${TEST_SESS}:0.0|valid-role" "${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}" 2>/dev/null || true)

if [ -n "$VALID_ENTRY" ]; then
  expect.pass "valid role accepted: $VALID_ENTRY"
  LIFECYCLE_PASSED=$((LIFECYCLE_PASSED + 1))
else
  expect.fail "valid role 'valid-role' was rejected"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
fi

testCleanup "$TEST_SESS"

# ── T-LIFECYCLE-4: registry entries for dead panes get pruned ────────────
# DISABLED: registry.refresh uses `tmux list-panes -a` (BUG: should be -s)
# which probes ALL sessions with /status, disrupting live agents.
# BUG REPORT: hiveMind line 1668 uses `-a` — same as BUG-C but in registry.refresh.
# Re-enable when expert fixes registry.refresh to use session-scoped `-s`.
if [ "${RUN_LIVE_TESTS:-0}" = "1" ]; then
TEST_SESS="__test_hm_$$"
testCleanup "$TEST_SESS"

otmux new "$TEST_SESS" -d 2>/dev/null

test.case $level "T-LIFECYCLE-4: dead pane entries pruned by registry.refresh" \
  echo "testing dead pane pruning"
LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))

REG_FILE="${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}"
echo "__test_DEAD_$$:99.99|ghost-agent" >> "$REG_FILE"

BEFORE=$(grep "ghost-agent" "$REG_FILE" 2>/dev/null || true)

hiveMind registry.refresh "$TEST_SESS" 2>/dev/null || true

AFTER=$(grep "ghost-agent" "$REG_FILE" 2>/dev/null || true)

if [ -n "$BEFORE" ] && [ -z "$AFTER" ]; then
  expect.pass "ghost entry injected then pruned by registry.refresh"
  LIFECYCLE_PASSED=$((LIFECYCLE_PASSED + 1))
elif [ -z "$BEFORE" ]; then
  expect.fail "injection failed — ghost entry not written"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
else
  expect.fail "ghost entry NOT pruned: $AFTER"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
  grep -v "ghost-agent" "$REG_FILE" > "/tmp/reg_fix_$$" && mv "/tmp/reg_fix_$$" "$REG_FILE"
fi

testCleanup "$TEST_SESS"
else
  echo "  T-LIFECYCLE-4 SKIPPED (RUN_LIVE_TESTS not set — registry.refresh probes all sessions)"
  LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))
fi # RUN_LIVE_TESTS gate

# ── T-LIFECYCLE-5: resolve scopes to specified session ───────────────────
TEST_SESS_A="__test_hm_A_$$"
TEST_SESS_B="__test_hm_B_$$"
testCleanup "$TEST_SESS_A"
testCleanup "$TEST_SESS_B"

otmux new "$TEST_SESS_A" -d 2>/dev/null
otmux new "$TEST_SESS_B" -d 2>/dev/null

test.case $level "T-LIFECYCLE-5: resolve scopes to specified session" \
  echo "testing session-scoped resolution"
LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))

# Register same role name in both sessions
private.hiveMind.pane.identify "${TEST_SESS_A}:0.0" "test-expert" 2>/dev/null || true
private.hiveMind.pane.identify "${TEST_SESS_B}:0.0" "test-expert" 2>/dev/null || true

# Resolve with session A — must return A's pane
# Filter ERROR lines from OOSH error handler (stdout noise from find.agents.dir)
RESOLVED=$(hiveMind resolve test-expert "$TEST_SESS_A" 2>/dev/null | grep -v '^ERROR>' || true)

if [ "$RESOLVED" = "${TEST_SESS_A}:0.0" ]; then
  expect.pass "resolve scoped correctly: $RESOLVED"
  LIFECYCLE_PASSED=$((LIFECYCLE_PASSED + 1))
elif [ "$RESOLVED" = "${TEST_SESS_B}:0.0" ]; then
  expect.fail "resolve returned WRONG session: $RESOLVED (expected ${TEST_SESS_A}:0.0)"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
else
  expect.fail "resolve returned unexpected: '$RESOLVED' (expected ${TEST_SESS_A}:0.0)"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
fi

testCleanup "$TEST_SESS_A"
testCleanup "$TEST_SESS_B"

# ── T-LIFECYCLE-6: team.remove cleans up ─────────────────────────────────
TEST_SESS="__test_hm_$$"
testCleanup "$TEST_SESS"

otmux new "$TEST_SESS" -d 2>/dev/null

test.case $level "T-LIFECYCLE-6: team.remove cleans team registry" \
  echo "testing team removal"
LIFECYCLE_TESTED=$((LIFECYCLE_TESTED + 1))

hiveMind team.register "$TEST_SESS" "test team" 2>/dev/null || true
hiveMind team.remove "$TEST_SESS" 2>/dev/null || true

REMAINING=$(grep "^${TEST_SESS}|" "${CONFIG_PATH:-$HOME/config}/hivemind.teams.env" 2>/dev/null || true)

if [ -z "$REMAINING" ]; then
  expect.pass "team.remove cleaned teams.env"
  LIFECYCLE_PASSED=$((LIFECYCLE_PASSED + 1))
else
  expect.fail "team entry still present after remove: $REMAINING"
  LIFECYCLE_FAILED=$((LIFECYCLE_FAILED + 1))
fi

testCleanup "$TEST_SESS"

echo ""
echo "  T-LIFECYCLE summary: $LIFECYCLE_TESTED tested, $LIFECYCLE_PASSED passed, $LIFECYCLE_FAILED failed"
echo ""

# ============================================================================
# T-PROCESS: process.lookup and process.list method tests
# Test the expert's PID-to-pane resolution methods (commit 6e25180)
# ============================================================================

echo ""
echo "=== T-PROCESS: PID resolution tests ==="
echo ""

# ── T-PROCESS-1: process.lookup function exists ──────────────────────────
test.case $level "T-PROCESS-1: process.lookup function exists" \
  type -t hiveMind.process.lookup
PROC_OUT=$(type -t hiveMind.process.lookup 2>/dev/null || true)
if [ "$PROC_OUT" = "function" ]; then
  expect.pass "hiveMind.process.lookup is a function"
else
  expect.fail "hiveMind.process.lookup not found (got: $PROC_OUT)"
fi

# ── T-PROCESS-2: process.lookup rejects missing PID ─────────────────────
# Capture exit code BEFORE test.case (test.case eats the return code)
hiveMind.process.lookup 2>/dev/null
RESULT_CODE=$?
test.case $level "T-PROCESS-2: process.lookup rejects missing PID" \
  echo "exit code: $RESULT_CODE"
if [ "$RESULT_CODE" -ne 0 ]; then
  expect.pass "process.lookup returns non-zero without PID arg (rc=$RESULT_CODE)"
else
  expect.fail "process.lookup should fail without PID arg (got rc=$RESULT_CODE)"
fi

# ── T-PROCESS-3: process.lookup rejects bogus PID ───────────────────────
hiveMind.process.lookup 999999 2>/dev/null
RESULT_CODE=$?
test.case $level "T-PROCESS-3: process.lookup rejects bogus PID" \
  echo "exit code: $RESULT_CODE"
if [ "$RESULT_CODE" -ne 0 ]; then
  expect.pass "process.lookup rejects non-existent PID 999999 (rc=$RESULT_CODE)"
else
  expect.fail "process.lookup should fail for PID 999999 (got rc=$RESULT_CODE)"
fi

# ── T-PROCESS-4 through T-PROCESS-6: LIVE tests (gated) ─────────────────
# These probe live Claude panes — only run with RUN_LIVE_TESTS=1
# Without the gate, process.find scans all panes and disrupts agents.
if [ "${RUN_LIVE_TESTS:-0}" = "1" ]; then

test.case $level "T-PROCESS-4: process.lookup resolves live Claude PID" \
  echo "finding a live Claude process"

LIVE_PID=""
LIVE_PANE=""
for paneTarget in $(tmux list-panes -a -F "#{session_name}:#{window_index}.#{pane_index}" 2>/dev/null); do
  LIVE_PID=$(claudeCode process.find "$paneTarget" 2>/dev/null || true)
  if [ -n "$LIVE_PID" ]; then
    LIVE_PANE="$paneTarget"
    break
  fi
done

if [ -n "$LIVE_PID" ]; then
  LOOKUP_OUT=$(hiveMind.process.lookup "$LIVE_PID" 2>/dev/null | grep -v '^ERROR>' || true)
  if echo "$LOOKUP_OUT" | grep -q "PID $LIVE_PID"; then
    expect.pass "process.lookup found PID $LIVE_PID → $LIVE_PANE"
  else
    expect.fail "process.lookup output missing PID reference: $LOOKUP_OUT"
  fi
else
  expect.pass "no live Claude process found (SKIP)"
fi

test.case $level "T-PROCESS-5: process.lookup output contains correct pane" \
  echo "verifying pane target in lookup output"

if [ -n "$LIVE_PID" ] && [ -n "$LIVE_PANE" ]; then
  LOOKUP_OUT=$(hiveMind.process.lookup "$LIVE_PID" 2>/dev/null | grep -v '^ERROR>' || true)
  if echo "$LOOKUP_OUT" | grep -q "$LIVE_PANE"; then
    expect.pass "output contains pane target $LIVE_PANE"
  else
    expect.fail "pane target $LIVE_PANE not in output: $LOOKUP_OUT"
  fi
else
  expect.pass "no live Claude — skipped"
fi

test.case $level "T-PROCESS-6: process.lookup output contains TTY line" \
  echo "verifying TTY in lookup output"

if [ -n "$LIVE_PID" ]; then
  LOOKUP_OUT=$(hiveMind.process.lookup "$LIVE_PID" 2>/dev/null | grep -v '^ERROR>' || true)
  if echo "$LOOKUP_OUT" | grep -q "TTY:"; then
    expect.pass "output contains TTY line"
  else
    expect.fail "TTY line missing from output: $LOOKUP_OUT"
  fi
else
  expect.pass "no live Claude — skipped"
fi

else
  echo "  T-PROCESS-4,5,6 SKIPPED (RUN_LIVE_TESTS not set)"
fi # RUN_LIVE_TESTS gate

# ── T-PROCESS-7: process.list function exists ────────────────────────────
test.case $level "T-PROCESS-7: process.list function exists" \
  type -t hiveMind.process.list
PROC_OUT=$(type -t hiveMind.process.list 2>/dev/null || true)
if [ "$PROC_OUT" = "function" ]; then
  expect.pass "hiveMind.process.list is a function"
else
  expect.fail "hiveMind.process.list not found (got: $PROC_OUT)"
fi

# ── T-PROCESS-8: process.list produces header ────────────────────────────
test.case $level "T-PROCESS-8: process.list produces table header" \
  echo "checking process.list output format"

LIST_OUT=$(hiveMind.process.list 2>/dev/null | grep -v '^ERROR>' || true)
if echo "$LIST_OUT" | head -1 | grep -q "PID"; then
  expect.pass "process.list header contains PID column"
else
  expect.fail "process.list header malformed: $(echo "$LIST_OUT" | head -1)"
fi

# ── T-PROCESS-9: process.list finds Claude processes ─────────────────────
test.case $level "T-PROCESS-9: process.list finds running Claude instances" \
  echo "counting process.list output"

LIST_LINES=$(hiveMind.process.list 2>/dev/null | grep -v '^ERROR>' | grep -v '^PID\|^---\|^(no' | grep -c '[0-9]' || true)
if [ "$LIST_LINES" -gt 0 ]; then
  expect.pass "process.list found $LIST_LINES Claude processes"
else
  expect.pass "no Claude processes found (SKIP)"
fi

# ── T-PROCESS-10: process.list session filter works ──────────────────────
test.case $level "T-PROCESS-10: process.list filters by session" \
  echo "testing session filter"

BOGUS_OUT=$(hiveMind.process.list "__nonexistent_session__" 2>/dev/null | grep -v '^ERROR>\|^PID\|^---' || true)
if echo "$BOGUS_OUT" | grep -q "no Claude processes"; then
  expect.pass "process.list returns empty for nonexistent session"
elif [ -z "$(echo "$BOGUS_OUT" | grep '[0-9]')" ]; then
  expect.pass "process.list returns no entries for nonexistent session"
else
  expect.fail "process.list returned data for nonexistent session: $BOGUS_OUT"
fi

# ── T-PROCESS-11: process.lookup completion function exists ──────────────
test.case $level "T-PROCESS-11: process.lookup.completion.pid exists" \
  type -t hiveMind.process.lookup.completion.pid
COMP_OUT=$(type -t hiveMind.process.lookup.completion.pid 2>/dev/null || true)
if [ "$COMP_OUT" = "function" ]; then
  expect.pass "completion function exists"
else
  expect.fail "process.lookup.completion.pid not found"
fi

# ── T-PROCESS-12: process.list completion function exists ────────────────
test.case $level "T-PROCESS-12: process.list.completion.session exists" \
  type -t hiveMind.process.list.completion.session
COMP_OUT=$(type -t hiveMind.process.list.completion.session 2>/dev/null || true)
if [ "$COMP_OUT" = "function" ]; then
  expect.pass "completion function exists"
else
  expect.fail "process.list.completion.session not found"
fi

# ============================================================================
# T-LIVE: Live discovery, team.status, and resolve consistency tests
# These verify that live-fact discovery methods return consistent data
# ============================================================================

echo ""
echo "=== T-LIVE: Live discovery and team.status consistency tests ==="
echo ""

# ── T-LIVE-1: team.status function exists ────────────────────────────────
test.case $level "T-LIVE-1: team.status function exists" \
  type -t hiveMind.team.status
TS_OUT=$(type -t hiveMind.team.status 2>/dev/null || true)
if [ "$TS_OUT" = "function" ]; then
  expect.pass "hiveMind.team.status is a function"
else
  expect.fail "hiveMind.team.status not found"
fi

# ── T-LIVE-2: team.status (LIVE — gated) ─────────────────────────────────
# team.status calls live.discover which probes Claude panes — gate it
if [ "${RUN_LIVE_TESTS:-0}" = "1" ]; then
test.case $level "T-LIVE-2: team.status produces output for active session" \
  echo "testing team.status with live session"

LIVE_TEAM=""
TEAMS_FILE="${CONFIG_PATH:-$HOME/config}/hivemind.teams.env"
if [ -f "$TEAMS_FILE" ]; then
  while IFS='|' read -r tname tdesc; do
    [ -z "$tname" ] && continue
    if tmux has-session -t "$tname" 2>/dev/null; then
      LIVE_TEAM="$tname"
      break
    fi
  done < "$TEAMS_FILE"
fi

if [ -n "$LIVE_TEAM" ]; then
  STATUS_OUT=$(hiveMind.team.status "$LIVE_TEAM" 2>/dev/null | grep -v '^ERROR>' || true)
  if [ -n "$STATUS_OUT" ]; then
    expect.pass "team.status produced output for $LIVE_TEAM"
  else
    expect.fail "team.status returned empty for live session $LIVE_TEAM"
  fi
else
  expect.pass "no live team session found (SKIP)"
fi
else
  echo "  T-LIVE-2 SKIPPED (RUN_LIVE_TESTS not set)"
fi # RUN_LIVE_TESTS gate

# ── T-LIVE-3: resolve function exists ────────────────────────────────────
test.case $level "T-LIVE-3: resolve function exists" \
  type -t hiveMind.resolve
RES_OUT=$(type -t hiveMind.resolve 2>/dev/null || true)
if [ "$RES_OUT" = "function" ]; then
  expect.pass "hiveMind.resolve is a function"
else
  expect.fail "hiveMind.resolve not found"
fi

# ── T-LIVE-4: resolve returns empty for nonexistent role ─────────────────
test.case $level "T-LIVE-4: resolve returns empty for nonexistent role" \
  echo "testing resolve with bogus role"

BOGUS_RESOLVE=$(hiveMind.resolve "__nonexistent_role_$$" 2>/dev/null | grep -v '^ERROR>' || true)
if [ -z "$BOGUS_RESOLVE" ]; then
  expect.pass "resolve returned empty for nonexistent role"
else
  expect.fail "resolve returned '$BOGUS_RESOLVE' for nonexistent role"
fi

# ── T-LIVE-5 through T-LIVE-7: LIVE tests (gated) ────────────────────────
# These probe live Claude panes via process.find, live.discover, process.list.
# Only run with RUN_LIVE_TESTS=1 to avoid disrupting active sessions.
if [ "${RUN_LIVE_TESTS:-0}" = "1" ]; then

test.case $level "T-LIVE-5: resolve finds a role from registry" \
  echo "testing resolve with real role"

REG_FILE="${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}"
REAL_ROLE=""
REAL_PANE=""
if [ -f "$REG_FILE" ]; then
  while IFS='|' read -r pt rl; do
    [ -z "$pt" ] || [ -z "$rl" ] && continue
    if tmux display-message -t "$pt" -p "#{pane_id}" >/dev/null 2>&1; then
      REAL_ROLE="$rl"
      REAL_PANE="$pt"
      break
    fi
  done < "$REG_FILE"
fi

if [ -n "$REAL_ROLE" ]; then
  REAL_SESS="${REAL_PANE%%:*}"
  RESOLVED=$(hiveMind.resolve "$REAL_ROLE" "$REAL_SESS" 2>/dev/null | grep -v '^ERROR>' || true)
  if [ -n "$RESOLVED" ]; then
    expect.pass "resolve found '$REAL_ROLE' in $REAL_SESS → $RESOLVED"
  else
    expect.fail "resolve returned empty for '$REAL_ROLE' in session $REAL_SESS (expected ~$REAL_PANE)"
  fi
else
  expect.pass "no live registered roles found (SKIP)"
fi

test.case $level "T-LIVE-6: live.discover returns role for Claude pane" \
  echo "testing live discovery"

LIVE_DISC_PANE=""
for paneTarget in $(tmux list-panes -a -F "#{session_name}:#{window_index}.#{pane_index}" 2>/dev/null); do
  HAS_CLAUDE=$(claudeCode process.find "$paneTarget" 2>/dev/null || true)
  if [ -n "$HAS_CLAUDE" ]; then
    LIVE_DISC_PANE="$paneTarget"
    break
  fi
done

if [ -n "$LIVE_DISC_PANE" ]; then
  DISC_ROLE=$(private.hiveMind.live.discover "$LIVE_DISC_PANE" 2>/dev/null || true)
  if [ -n "$DISC_ROLE" ]; then
    expect.pass "live.discover found role '$DISC_ROLE' at $LIVE_DISC_PANE"
  else
    expect.fail "live.discover returned empty for Claude pane $LIVE_DISC_PANE"
  fi
else
  expect.pass "no Claude panes found (SKIP)"
fi

test.case $level "T-LIVE-7: process.list roles agree with resolve" \
  echo "cross-checking process.list vs resolve"

CROSS_OK=true
CROSS_CHECKED=0
while read -r pid pane role sidRest; do
  [ -z "$pid" ] && continue
  [[ "$pid" == "PID" || "$pid" == "---" || "$pid" == "(no" ]] && continue
  [ "$role" = "-" ] && continue
  CROSS_CHECKED=$((CROSS_CHECKED + 1))
  crossSess="${pane%%:*}"
  RESOLVE_PANE=$(hiveMind.resolve "$role" "$crossSess" 2>/dev/null | grep -v '^ERROR>' || true)
  if [ -n "$RESOLVE_PANE" ] && [ "$RESOLVE_PANE" != "$pane" ]; then
    echo "  MISMATCH: process.list says $role at $pane, resolve $crossSess says $RESOLVE_PANE"
    CROSS_OK=false
  fi
done < <(hiveMind.process.list 2>/dev/null | grep -v '^ERROR>')

if [ "$CROSS_CHECKED" -eq 0 ]; then
  expect.pass "no roles to cross-check (SKIP)"
elif [ "$CROSS_OK" = "true" ]; then
  expect.pass "all $CROSS_CHECKED roles consistent between process.list and resolve"
else
  expect.fail "role mismatches found between process.list and resolve"
fi

else
  echo "  T-LIVE-5,6,7 SKIPPED (RUN_LIVE_TESTS not set)"
fi # RUN_LIVE_TESTS gate

echo ""
echo "=== All live discovery tests complete ==="
echo ""

# ============================================================================
# T-STATUS: hiveMind status method tests (BUG-H, BUG-I, BUG-J)
# ============================================================================

echo ""
echo "=== T-STATUS: hiveMind status tests ==="

# T-STATUS-1: status function exists
test.case $level "T-STATUS-1: hiveMind.status function exists" \
  type hiveMind.status
if type hiveMind.status &>/dev/null; then
  expect.pass "hiveMind.status exists"
else
  expect.fail "hiveMind.status not found"
fi

# T-STATUS-2: status accepts session argument
test.case $level "T-STATUS-2: hiveMind.status accepts session arg" \
  hiveMind.status hiveMindTeam02_03_26
STATUS_OUT=$(hiveMind.status hiveMindTeam02_03_26 2>/dev/null | grep -v '^ERROR>')
if echo "$STATUS_OUT" | grep -q "hiveMindTeam02_03_26"; then
  expect.pass "status shows hiveMindTeam02_03_26"
else
  expect.fail "status should show hiveMindTeam02_03_26, got: $STATUS_OUT"
fi

# T-STATUS-3: status shows correct agent count for hiveMindTeam02_03_26
test.case $level "T-STATUS-3: status shows registered agents" \
  echo "$STATUS_OUT"
AGENT_COUNT=$(echo "$STATUS_OUT" | grep -oE '[0-9]+ registered' | grep -oE '[0-9]+')
if [ -n "$AGENT_COUNT" ] && [ "$AGENT_COUNT" -ge 1 ]; then
  expect.pass "status shows $AGENT_COUNT registered agents"
else
  expect.fail "BUG-I: status shows 0 or missing agent count for hiveMindTeam02_03_26: $STATUS_OUT"
fi

# T-STATUS-4: active.team returns current team (BUG-H)
ACTIVE_TEAM=$(private.hiveMind.active.team 2>/dev/null)
test.case $level "T-STATUS-4: active.team returns current team" \
  echo "active.team=$ACTIVE_TEAM"
if [ "$ACTIVE_TEAM" = "hiveMindTeam02_03_26" ]; then
  expect.pass "active.team is hiveMindTeam02_03_26"
else
  expect.fail "BUG-H: active.team is '$ACTIVE_TEAM', should be hiveMindTeam02_03_26"
fi

# T-STATUS-5: hiveMindTeam02_03_26 is in teams.env (BUG-I)
TEAMS_FILE="${CONFIG_PATH:-$HOME/config}/hivemind.teams.env"
test.case $level "T-STATUS-5: current team in teams.env" \
  grep "hiveMindTeam02_03_26" "$TEAMS_FILE"
if grep -q "hiveMindTeam02_03_26" "$TEAMS_FILE" 2>/dev/null; then
  expect.pass "hiveMindTeam02_03_26 in teams.env"
else
  expect.fail "BUG-I: hiveMindTeam02_03_26 not in teams.env"
fi

# T-STATUS-6: status without args should show current active team
DEFAULT_STATUS=$(hiveMind.status 2>/dev/null | grep -v '^ERROR>')
test.case $level "T-STATUS-6: status default matches active team" \
  echo "$DEFAULT_STATUS"
if echo "$DEFAULT_STATUS" | grep -q "hiveMindTeam02_03_26"; then
  expect.pass "status default shows hiveMindTeam02_03_26"
else
  expect.fail "BUG-H: status default shows wrong team: $DEFAULT_STATUS"
fi

echo ""
echo "=== T-STATUS tests complete ==="
echo ""

# ============================================================================
# T-DRY: DRY refactor — test extracted private helper methods
# ============================================================================

echo ""
echo "=== T-DRY: DRY refactor helper method tests ==="
echo ""

# --- T-DRY-1: private.hiveMind.current.session exists ---
test.case $level "T-DRY-1: current.session function exists" \
  type -t private.hiveMind.current.session
if type -t private.hiveMind.current.session &>/dev/null; then
  expect.pass "private.hiveMind.current.session exists"
else
  expect.fail "private.hiveMind.current.session should exist after Phase 1"
fi

# --- T-DRY-2: current.session returns a session name inside tmux ---
if [ -n "$TMUX" ]; then
  CURR_SESS=$(private.hiveMind.current.session 2>/dev/null)
  test.case $level "T-DRY-2: current.session returns non-empty in tmux" \
    echo "$CURR_SESS"
  if [ -n "$CURR_SESS" ]; then
    expect.pass "current.session returned: $CURR_SESS"
  else
    expect.fail "current.session returned empty inside tmux"
  fi
else
  test.case $level "T-DRY-2: SKIP — not running inside tmux" echo "skipped"
  expect.pass "skipped — no TMUX env"
fi

# --- T-DRY-3: HIVEMIND_REGISTRY global is set (Phase 2 relies on this) ---
test.case $level "T-DRY-3: HIVEMIND_REGISTRY global is set" \
  echo "$HIVEMIND_REGISTRY"
if [ -n "$HIVEMIND_REGISTRY" ] && [ -f "$HIVEMIND_REGISTRY" ]; then
  expect.pass "HIVEMIND_REGISTRY=$HIVEMIND_REGISTRY (file exists)"
else
  expect.fail "HIVEMIND_REGISTRY not set or file missing: '$HIVEMIND_REGISTRY'"
fi

# --- T-DRY-4: HIVEMIND_SESSIONS global is set ---
test.case $level "T-DRY-4: HIVEMIND_SESSIONS global is set" \
  echo "$HIVEMIND_SESSIONS"
if [ -n "$HIVEMIND_SESSIONS" ] && [ -f "$HIVEMIND_SESSIONS" ]; then
  expect.pass "HIVEMIND_SESSIONS=$HIVEMIND_SESSIONS (file exists)"
else
  expect.fail "HIVEMIND_SESSIONS not set or file missing: '$HIVEMIND_SESSIONS'"
fi

# --- T-DRY-5: registry.get uses global, not local re-derivation ---
# After Phase 2, no function should re-derive HIVEMIND_REGISTRY locally
DRY_REDERIVE=$(grep -c 'local reg=.*HIVEMIND_REGISTRY.*CONFIG_PATH' $OOSH_DIR/hiveMind 2>/dev/null || echo 0)
test.case $level "T-DRY-5: no local re-derivations of HIVEMIND_REGISTRY" \
  echo "count=$DRY_REDERIVE"
if [ "$DRY_REDERIVE" -eq 0 ]; then
  expect.pass "zero local re-derivations of HIVEMIND_REGISTRY"
else
  expect.fail "found $DRY_REDERIVE local re-derivations — Phase 2 incomplete"
fi

# --- T-DRY-6: no local re-derivations of HIVEMIND_SESSIONS ---
DRY_SES_REDERIVE=$(grep -c 'local ses=.*HIVEMIND_SESSIONS.*CONFIG_PATH' $OOSH_DIR/hiveMind 2>/dev/null || echo 0)
DRY_SESSFILE_REDERIVE=$(grep -c 'local sessFile=.*CONFIG_PATH.*sessions' $OOSH_DIR/hiveMind 2>/dev/null || echo 0)
DRY_TOTAL=$((DRY_SES_REDERIVE + DRY_SESSFILE_REDERIVE))
test.case $level "T-DRY-6: no local re-derivations of HIVEMIND_SESSIONS" \
  echo "count=$DRY_TOTAL"
if [ "$DRY_TOTAL" -eq 0 ]; then
  expect.pass "zero local re-derivations of HIVEMIND_SESSIONS"
else
  expect.fail "found $DRY_TOTAL local re-derivations — Phase 2 incomplete"
fi

# --- T-DRY-7: no inline registry greps (Phase 3) ---
# After Phase 3, direct grep on HIVEMIND_REGISTRY should only be in private methods
DRY_INLINE=$(grep -n 'grep.*HIVEMIND_REGISTRY' $OOSH_DIR/hiveMind 2>/dev/null | grep -v 'private\.hiveMind\.' | grep -v '^#' | grep -v 'registry\.\(set\|get\|remove\|list\|refresh\)' | wc -l | tr -d ' ')
test.case $level "T-DRY-7: inline registry greps replaced with private methods" \
  echo "inline_count=$DRY_INLINE"
if [ "$DRY_INLINE" -le 2 ]; then
  expect.pass "at most 2 inline registry greps remaining (got $DRY_INLINE)"
else
  expect.fail "found $DRY_INLINE inline greps — Phase 3 may be incomplete"
fi

# --- T-DRY-8: private.hiveMind.pane.count exists (Phase 4) ---
test.case $level "T-DRY-8: pane.count function exists" \
  type -t private.hiveMind.pane.count
if type -t private.hiveMind.pane.count &>/dev/null; then
  expect.pass "private.hiveMind.pane.count exists"
  # Test it returns a number for a known session
  if [ -n "$TMUX" ]; then
    PCOUNT=$(private.hiveMind.pane.count "$(tmux display-message -p '#{session_name}'):0" 2>/dev/null)
    test.case $level "T-DRY-8b: pane.count returns numeric value" echo "$PCOUNT"
    if [[ "$PCOUNT" =~ ^[0-9]+$ ]] && [ "$PCOUNT" -gt 0 ]; then
      expect.pass "pane.count returned $PCOUNT"
    else
      expect.fail "pane.count returned non-numeric or zero: '$PCOUNT'"
    fi
  fi
else
  expect.fail "private.hiveMind.pane.count not found — Phase 4 not done yet"
fi

# --- T-DRY-9: list.panes function exists ---
test.case $level "T-DRY-9: list.panes function exists" \
  type -t private.hiveMind.list.panes
if type -t private.hiveMind.list.panes &>/dev/null; then
  expect.pass "private.hiveMind.list.panes exists"
else
  expect.fail "private.hiveMind.list.panes not found — Phase 5 not done yet"
fi

# --- T-DRY-10: ensure.pane function exists ---
test.case $level "T-DRY-10: ensure.pane function exists" \
  type -t private.hiveMind.ensure.pane
if type -t private.hiveMind.ensure.pane &>/dev/null; then
  expect.pass "private.hiveMind.ensure.pane exists"
else
  expect.fail "private.hiveMind.ensure.pane not found — Phase 6 not done yet"
fi

# --- T-DRY-11: list.panes addr format returns session:window.pane ---
if [ -n "$TMUX" ]; then
  LP_ADDR=$(private.hiveMind.list.panes addr 2>/dev/null | head -1)
  test.case $level "T-DRY-11: list.panes addr matches session:window.pane format" echo "$LP_ADDR"
  if [[ "$LP_ADDR" =~ ^[a-zA-Z0-9_]+:[0-9]+\.[0-9]+$ ]]; then
    expect.pass "addr format correct: $LP_ADDR"
  else
    expect.fail "addr format wrong: '$LP_ADDR' (expected session:win.pane)"
  fi
fi

# --- T-DRY-12: list.panes tty format returns /dev/ttysNNN + address ---
if [ -n "$TMUX" ]; then
  LP_TTY=$(private.hiveMind.list.panes tty 2>/dev/null | head -1)
  test.case $level "T-DRY-12: list.panes tty has TTY device + address" echo "$LP_TTY"
  if [[ "$LP_TTY" =~ ^/dev/ttys[0-9]+\ [a-zA-Z0-9_]+:[0-9]+\.[0-9]+$ ]]; then
    expect.pass "tty format correct: $LP_TTY"
  else
    expect.fail "tty format wrong: '$LP_TTY' (expected /dev/ttysNNN session:win.pane)"
  fi
fi

# --- T-DRY-13: list.panes tty+title format has 3 pipe-separated fields ---
if [ -n "$TMUX" ]; then
  LP_TTT=$(private.hiveMind.list.panes "tty+title" 2>/dev/null | head -1)
  test.case $level "T-DRY-13: list.panes tty+title has 3 pipe fields" echo "$LP_TTT"
  LP_FIELDS=$(echo "$LP_TTT" | awk -F'|' '{print NF}')
  if [ "$LP_FIELDS" -eq 3 ]; then
    expect.pass "tty+title has 3 fields: $LP_TTT"
  else
    expect.fail "tty+title has $LP_FIELDS fields (expected 3): '$LP_TTT'"
  fi
fi

# --- T-DRY-14: list.panes addr+cmd format has 2 pipe-separated fields ---
if [ -n "$TMUX" ]; then
  CURR_SESS=$(private.hiveMind.current.session 2>/dev/null)
  LP_CMD=$(private.hiveMind.list.panes "addr+cmd" "$CURR_SESS" 2>/dev/null | head -1)
  test.case $level "T-DRY-14: list.panes addr+cmd has 2 pipe fields" echo "$LP_CMD"
  LP_CMD_FIELDS=$(echo "$LP_CMD" | awk -F'|' '{print NF}')
  if [ "$LP_CMD_FIELDS" -eq 2 ]; then
    expect.pass "addr+cmd has 2 fields: $LP_CMD"
  else
    expect.fail "addr+cmd has $LP_CMD_FIELDS fields (expected 2): '$LP_CMD'"
  fi
fi

# --- T-DRY-15: list.panes session-scoped returns only that session ---
if [ -n "$TMUX" ]; then
  CURR_SESS=$(private.hiveMind.current.session 2>/dev/null)
  LP_SCOPED=$(private.hiveMind.list.panes addr "$CURR_SESS" 2>/dev/null)
  test.case $level "T-DRY-15: list.panes scoped to $CURR_SESS" echo "$(echo "$LP_SCOPED" | wc -l | tr -d ' ') panes"
  LP_OTHER=$(echo "$LP_SCOPED" | grep -v "^${CURR_SESS}:" | head -1)
  if [ -z "$LP_OTHER" ]; then
    expect.pass "all panes belong to $CURR_SESS"
  else
    expect.fail "found pane from other session: '$LP_OTHER'"
  fi
fi

# --- T-DRY-16: list.panes -a returns panes from multiple sessions ---
if [ -n "$TMUX" ]; then
  LP_ALL=$(private.hiveMind.list.panes addr 2>/dev/null)
  LP_SESSIONS=$(echo "$LP_ALL" | cut -d: -f1 | sort -u | wc -l | tr -d ' ')
  test.case $level "T-DRY-16: list.panes -a returns multiple sessions" echo "$LP_SESSIONS sessions"
  if [ "$LP_SESSIONS" -gt 1 ]; then
    expect.pass "list.panes -a covers $LP_SESSIONS sessions"
  else
    expect.fail "list.panes -a only covers $LP_SESSIONS session (expected >1)"
  fi
fi

# --- T-DRY-17: list.panes raw format passthrough ---
if [ -n "$TMUX" ]; then
  LP_RAW=$(private.hiveMind.list.panes "#{pane_id}" 2>/dev/null | head -1)
  test.case $level "T-DRY-17: list.panes raw format passthrough" echo "$LP_RAW"
  if [[ "$LP_RAW" =~ ^%[0-9]+$ ]]; then
    expect.pass "raw format returned pane_id: $LP_RAW"
  else
    expect.fail "raw format unexpected: '$LP_RAW' (expected %NNN)"
  fi
fi

# --- T-DRY-18: pane.count matches list.panes line count ---
if [ -n "$TMUX" ]; then
  CURR_SESS=$(private.hiveMind.current.session 2>/dev/null)
  PC_COUNT=$(private.hiveMind.pane.count "${CURR_SESS}:0" 2>/dev/null)
  LP_COUNT=$(private.hiveMind.list.panes addr "$CURR_SESS" 2>/dev/null | grep "^${CURR_SESS}:0\." | wc -l | tr -d ' ')
  test.case $level "T-DRY-18: pane.count matches list.panes line count for window 0" echo "count=$PC_COUNT list=$LP_COUNT"
  if [ "$PC_COUNT" -eq "$LP_COUNT" ]; then
    expect.pass "pane.count ($PC_COUNT) matches list.panes ($LP_COUNT)"
  else
    expect.fail "pane.count=$PC_COUNT but list.panes=$LP_COUNT for ${CURR_SESS}:0"
  fi
fi

# --- T-DRY-19: ensure.pane creates session + window + pane (fixture) ---
DRY_TEST_SESS="__test_dry_$$"
tmux kill-session -t "$DRY_TEST_SESS" 2>/dev/null
test.case $level "T-DRY-19: ensure.pane creates session:1.2 from scratch" \
  private.hiveMind.ensure.pane "${DRY_TEST_SESS}:1.2"
if private.hiveMind.ensure.pane "${DRY_TEST_SESS}:1.2" 2>/dev/null; then
  # Verify session exists
  DRY19_SESS_OK=$(tmux has-session -t "$DRY_TEST_SESS" 2>/dev/null && echo "yes" || echo "no")
  # Verify window 1 exists
  DRY19_WIN_OK=$(tmux list-windows -t "$DRY_TEST_SESS" -F "#{window_index}" 2>/dev/null | grep -qx "1" && echo "yes" || echo "no")
  # Verify at least 3 panes (indices 0,1,2)
  DRY19_PCOUNT=$(private.hiveMind.pane.count "${DRY_TEST_SESS}:1" 2>/dev/null)
  if [ "$DRY19_SESS_OK" = "yes" ] && [ "$DRY19_WIN_OK" = "yes" ] && [ "$DRY19_PCOUNT" -ge 3 ]; then
    expect.pass "session=$DRY19_SESS_OK win1=$DRY19_WIN_OK panes=$DRY19_PCOUNT"
  else
    expect.fail "ensure.pane incomplete: session=$DRY19_SESS_OK win1=$DRY19_WIN_OK panes=$DRY19_PCOUNT"
  fi
else
  expect.fail "ensure.pane returned non-zero for ${DRY_TEST_SESS}:1.2"
fi

# --- T-DRY-20: ensure.pane is idempotent (re-run doesn't break) ---
test.case $level "T-DRY-20: ensure.pane idempotent on existing pane" \
  private.hiveMind.ensure.pane "${DRY_TEST_SESS}:1.2"
DRY20_BEFORE=$(private.hiveMind.pane.count "${DRY_TEST_SESS}:1" 2>/dev/null)
private.hiveMind.ensure.pane "${DRY_TEST_SESS}:1.2" 2>/dev/null
DRY20_AFTER=$(private.hiveMind.pane.count "${DRY_TEST_SESS}:1" 2>/dev/null)
if [ "$DRY20_BEFORE" -eq "$DRY20_AFTER" ]; then
  expect.pass "idempotent: pane count $DRY20_BEFORE unchanged"
else
  expect.fail "not idempotent: before=$DRY20_BEFORE after=$DRY20_AFTER"
fi

# --- T-DRY-21: ensure.pane creates window at exact index ---
test.case $level "T-DRY-21: ensure.pane creates window at index 5" \
  private.hiveMind.ensure.pane "${DRY_TEST_SESS}:5.0"
private.hiveMind.ensure.pane "${DRY_TEST_SESS}:5.0" 2>/dev/null
DRY21_WIN5=$(tmux list-windows -t "$DRY_TEST_SESS" -F "#{window_index}" 2>/dev/null | grep -qx "5" && echo "yes" || echo "no")
if [ "$DRY21_WIN5" = "yes" ]; then
  expect.pass "window 5 created at exact index"
else
  expect.fail "window 5 not found at exact index"
fi

# --- T-DRY-22: ensure.pane session uses -x 200 -y 50 ---
DRY22_SIZE=$(tmux display-message -t "${DRY_TEST_SESS}" -p "#{window_width}x#{window_height}" 2>/dev/null)
test.case $level "T-DRY-22: ensure.pane session size is 200x50" echo "$DRY22_SIZE"
if [ "$DRY22_SIZE" = "200x50" ]; then
  expect.pass "session size correct: $DRY22_SIZE"
else
  expect.fail "session size wrong: '$DRY22_SIZE' (expected 200x50)"
fi

# Teardown fixture
tmux kill-session -t "$DRY_TEST_SESS" 2>/dev/null

# --- T-DRY-23: current.session returns non-empty value in tmux ---
if [ -n "$TMUX" ]; then
  DRY23_OUT=$(private.hiveMind.current.session 2>/dev/null)
  DRY23_RC=$?
  test.case $level "T-DRY-23: current.session returns valid session name" echo "rc=$DRY23_RC out='$DRY23_OUT'"
  if [ "$DRY23_RC" -eq 0 ] && [[ "$DRY23_OUT" =~ ^[a-zA-Z0-9_]+$ ]]; then
    expect.pass "current.session returned valid name: $DRY23_OUT"
  else
    expect.fail "current.session returned rc=$DRY23_RC name='$DRY23_OUT'"
  fi
fi

# --- T-DRY-24: pane.count returns 0 for non-existent session ---
DRY24_OUT=$(private.hiveMind.pane.count "__nonexistent_$$:0" 2>/dev/null)
test.case $level "T-DRY-24: pane.count returns 0 for missing session" echo "count='$DRY24_OUT'"
if [ "$DRY24_OUT" = "0" ]; then
  expect.pass "pane.count returns 0 for non-existent session"
else
  expect.fail "pane.count returned '$DRY24_OUT' (expected 0)"
fi

# --- T-DRY-25: list.panes returns empty for non-existent session ---
DRY25_OUT=$(private.hiveMind.list.panes addr "__nonexistent_$$" 2>/dev/null)
test.case $level "T-DRY-25: list.panes empty for missing session" echo "out='$DRY25_OUT'"
if [ -z "$DRY25_OUT" ]; then
  expect.pass "list.panes returns empty for non-existent session"
else
  expect.fail "list.panes returned data for non-existent session: '$DRY25_OUT'"
fi

# --- T-DRY-26: no inline tmux list-panes -a outside private methods (regression) ---
# Private methods are lines 95-162; anything after line 162 is outside
DRY26_INLINE=$(awk 'NR>162 && /tmux list-panes -a/ && !/^[[:space:]]*#/' $OOSH_DIR/hiveMind 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-DRY-26: no inline tmux list-panes -a after line 162" echo "count=$DRY26_INLINE"
if [ "$DRY26_INLINE" -eq 0 ]; then
  expect.pass "zero inline tmux list-panes -a outside private methods"
else
  expect.fail "found $DRY26_INLINE inline tmux list-panes -a calls — Phase 5b regression"
fi

# --- T-DRY-27: no inline tmux list-panes -t outside private methods (regression) ---
# Phase 7 eliminated all remaining calls
DRY27_INLINE=$(grep -n 'tmux list-panes -t' $OOSH_DIR/hiveMind 2>/dev/null | awk -F: '$1 > 170' | grep -v '#' | wc -l | tr -d ' ')
test.case $level "T-DRY-27: no inline tmux list-panes -t outside private methods" echo "count=$DRY27_INLINE"
if [ "$DRY27_INLINE" -eq 0 ]; then
  expect.pass "zero inline tmux list-panes -t outside private methods"
else
  expect.fail "found $DRY27_INLINE inline tmux list-panes -t calls — regression"
fi

# --- T-DRY-28: claude.processes function exists (Phase 7) ---
test.case $level "T-DRY-28: claude.processes function exists" \
  type -t private.hiveMind.claude.processes
if type -t private.hiveMind.claude.processes &>/dev/null; then
  expect.pass "private.hiveMind.claude.processes exists"
else
  expect.fail "private.hiveMind.claude.processes not found — Phase 7 not done"
fi

# --- T-DRY-29: claude.processes returns pipe-delimited output ---
if [ -n "$TMUX" ]; then
  CP_OUT=$(private.hiveMind.claude.processes 2>/dev/null | head -1)
  test.case $level "T-DRY-29: claude.processes returns pipe-delimited output" echo "$CP_OUT"
  CP_FIELDS=$(echo "$CP_OUT" | awk -F'|' '{print NF}')
  if [ -n "$CP_OUT" ] && [ "$CP_FIELDS" -eq 5 ]; then
    expect.pass "claude.processes has 5 pipe fields: $CP_OUT"
  elif [ -z "$CP_OUT" ]; then
    expect.fail "claude.processes returned empty (expected running Claude instances)"
  else
    expect.fail "claude.processes has $CP_FIELDS fields (expected 5): '$CP_OUT'"
  fi
fi

# --- T-DRY-30: claude.processes output contains valid pane targets ---
if [ -n "$TMUX" ]; then
  CP_PANE=$(private.hiveMind.claude.processes 2>/dev/null | head -1 | cut -d'|' -f3)
  test.case $level "T-DRY-30: claude.processes pane target format" echo "$CP_PANE"
  if [[ "$CP_PANE" =~ ^[a-zA-Z0-9_]+:[0-9]+\.[0-9]+$ ]]; then
    expect.pass "pane target valid: $CP_PANE"
  else
    expect.fail "pane target invalid: '$CP_PANE' (expected session:win.pane)"
  fi
fi

# --- T-DRY-31: claude.processes PID is numeric ---
if [ -n "$TMUX" ]; then
  CP_PID=$(private.hiveMind.claude.processes 2>/dev/null | head -1 | cut -d'|' -f1)
  test.case $level "T-DRY-31: claude.processes PID is numeric" echo "$CP_PID"
  if [[ "$CP_PID" =~ ^[0-9]+$ ]]; then
    expect.pass "PID is numeric: $CP_PID"
  else
    expect.fail "PID not numeric: '$CP_PID'"
  fi
fi

# --- T-DRY-32: claude.processes finds multiple instances ---
if [ -n "$TMUX" ]; then
  CP_COUNT=$(private.hiveMind.claude.processes 2>/dev/null | wc -l | tr -d ' ')
  test.case $level "T-DRY-32: claude.processes finds multiple Claude instances" echo "count=$CP_COUNT"
  if [ "$CP_COUNT" -gt 1 ]; then
    expect.pass "found $CP_COUNT Claude instances"
  else
    expect.fail "found only $CP_COUNT Claude instance (expected >1 with active agents)"
  fi
fi

# --- T-DRY-33: no inline tty-to-pane matching loops remain (Phase 7 regression) ---
# Phase 7 replaced 4 near-identical loops that did: list panes + match TTY + find process
# The pattern: ps -eo pid,tty paired with pane_tty mapping
# Note: line 1361 has a simple `ps -eo pid,args | grep claude` (PID list only, no TTY map) — OK
DRY33_INLINE=$(grep -n 'ps -eo pid,tty' $OOSH_DIR/hiveMind 2>/dev/null | awk -F: '$1 > 170' | wc -l | tr -d ' ')
test.case $level "T-DRY-33: no inline TTY-to-pane match loops outside private methods" echo "count=$DRY33_INLINE"
if [ "$DRY33_INLINE" -eq 0 ]; then
  expect.pass "zero inline TTY-to-pane match loops"
else
  expect.fail "found $DRY33_INLINE inline TTY-to-pane patterns — Phase 7 regression"
fi

echo ""
echo "=== T-DRY tests complete ==="
echo ""

# ============================================================================
# T-OTMUX: Raw tmux elimination — regression gates + behavioral tests
# Goal: zero raw tmux calls in hiveMind (all via otmux wrappers)
# ============================================================================

echo "=== T-OTMUX: Raw tmux elimination tests ==="
HIVEMIND_SCRIPT="$OOSH_DIR/hiveMind"

# --- Regression gates (grep-based) ---
# Count raw tmux subcommand calls outside private methods (line > 170)
# and inside private methods (lines 95-170) separately

# T-OTMUX-1: tmux has-session → otmux has
OTMUX1_COUNT=$(grep -n 'tmux has-session' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-1: zero raw tmux has-session calls" echo "count=$OTMUX1_COUNT"
if [ "$OTMUX1_COUNT" -eq 0 ]; then
  expect.pass "zero tmux has-session calls"
else
  expect.fail "found $OTMUX1_COUNT raw tmux has-session calls (expected 0)"
fi

# T-OTMUX-2: tmux new-session → otmux new
OTMUX2_COUNT=$(grep -n 'tmux new-session' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-2: zero raw tmux new-session calls" echo "count=$OTMUX2_COUNT"
if [ "$OTMUX2_COUNT" -eq 0 ]; then
  expect.pass "zero tmux new-session calls"
else
  expect.fail "found $OTMUX2_COUNT raw tmux new-session calls (expected 0)"
fi

# T-OTMUX-3: tmux kill-session → otmux kill
OTMUX3_COUNT=$(grep -n 'tmux kill-session' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-3: zero raw tmux kill-session calls" echo "count=$OTMUX3_COUNT"
if [ "$OTMUX3_COUNT" -eq 0 ]; then
  expect.pass "zero tmux kill-session calls"
else
  expect.fail "found $OTMUX3_COUNT raw tmux kill-session calls (expected 0)"
fi

# T-OTMUX-4: tmux select-pane → otmux pane.select
OTMUX4_COUNT=$(grep -n 'tmux select-pane' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-4: zero raw tmux select-pane calls" echo "count=$OTMUX4_COUNT"
if [ "$OTMUX4_COUNT" -eq 0 ]; then
  expect.pass "zero tmux select-pane calls"
else
  expect.fail "found $OTMUX4_COUNT raw tmux select-pane calls (expected 0)"
fi

# T-OTMUX-5: tmux list-sessions → otmux sessions
OTMUX5_COUNT=$(grep -n 'tmux list-sessions' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-5: zero raw tmux list-sessions calls" echo "count=$OTMUX5_COUNT"
if [ "$OTMUX5_COUNT" -eq 0 ]; then
  expect.pass "zero tmux list-sessions calls"
else
  expect.fail "found $OTMUX5_COUNT raw tmux list-sessions calls (expected 0)"
fi

# T-OTMUX-6: tmux split-window → otmux split / split.h / split.v
OTMUX6_COUNT=$(grep -n 'tmux split-window' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-6: zero raw tmux split-window calls" echo "count=$OTMUX6_COUNT"
if [ "$OTMUX6_COUNT" -eq 0 ]; then
  expect.pass "zero tmux split-window calls"
else
  expect.fail "found $OTMUX6_COUNT raw tmux split-window calls (expected 0)"
fi

# T-OTMUX-7: tmux rename-window → otmux window.rename
OTMUX7_COUNT=$(grep -n 'tmux rename-window' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-7: zero raw tmux rename-window calls" echo "count=$OTMUX7_COUNT"
if [ "$OTMUX7_COUNT" -eq 0 ]; then
  expect.pass "zero tmux rename-window calls"
else
  expect.fail "found $OTMUX7_COUNT raw tmux rename-window calls (expected 0)"
fi

# T-OTMUX-8: tmux display-message → otmux pane.get
OTMUX8_COUNT=$(grep -n 'tmux display-message' "$HIVEMIND_SCRIPT" 2>/dev/null | wc -l | tr -d ' ')
test.case $level "T-OTMUX-8: zero raw tmux display-message calls" echo "count=$OTMUX8_COUNT"
if [ "$OTMUX8_COUNT" -eq 0 ]; then
  expect.pass "zero tmux display-message calls"
else
  expect.fail "found $OTMUX8_COUNT raw tmux display-message calls (expected 0)"
fi

# T-OTMUX-9: TOTAL — zero raw tmux subcommand calls anywhere in hiveMind
# Counts all raw tmux calls (excluding otmux, comments, and variable refs like $TMUX)
OTMUX9_COUNT=$(grep -cE '[^o]tmux (has-session|new-session|kill-session|select-pane|list-sessions|split-window|rename-window|display-message|list-panes|list-windows|new-window|select-window|select-layout|attach-session|detach-client|capture-pane)|^tmux (has-session|new-session|kill-session|select-pane|list-sessions|split-window|rename-window|display-message|list-panes|list-windows|new-window|select-window|select-layout|attach-session|detach-client|capture-pane)' "$HIVEMIND_SCRIPT" 2>/dev/null || echo 0)
test.case $level "T-OTMUX-9: TOTAL zero raw tmux subcommand calls" echo "count=$OTMUX9_COUNT"
if [ "$OTMUX9_COUNT" -eq 0 ]; then
  expect.pass "ZERO raw tmux calls in hiveMind"
else
  expect.fail "found $OTMUX9_COUNT total raw tmux subcommand calls (expected 0)"
fi

# --- Behavioral tests (fixture session) ---
if [ -n "$TMUX" ]; then
  OTMUX_TEST_SESS="__test_otmux_$$"

  # T-OTMUX-10: otmux new creates detached session
  otmux new "$OTMUX_TEST_SESS" -d -x 200 -y 50 2>/dev/null
  test.case $level "T-OTMUX-10: otmux new creates detached session" \
    otmux has "$OTMUX_TEST_SESS"
  if otmux has "$OTMUX_TEST_SESS" 2>/dev/null; then
    expect.pass "session $OTMUX_TEST_SESS created"
  else
    expect.fail "otmux new did not create session $OTMUX_TEST_SESS"
  fi

  # T-OTMUX-11: otmux has returns 0 for existing, 1 for nonexistent
  test.case $level "T-OTMUX-11: otmux has returns correct status" \
    otmux has "$OTMUX_TEST_SESS"
  if otmux has "$OTMUX_TEST_SESS" 2>/dev/null; then
    if ! otmux has "__nonexistent_session_$$" 2>/dev/null; then
      expect.pass "otmux has: 0 for existing, 1 for nonexistent"
    else
      expect.fail "otmux has returned 0 for nonexistent session"
    fi
  else
    expect.fail "otmux has returned 1 for existing session"
  fi

  # T-OTMUX-12: otmux window.rename with target renames remote window
  otmux window.rename "${OTMUX_TEST_SESS}:0" "testwin" 2>/dev/null
  test.case $level "T-OTMUX-12: otmux window.rename with target" \
    echo "rename remote window"
  RENAMED=$(otmux windows -t "$OTMUX_TEST_SESS" -F "#{window_name}" 2>/dev/null | head -1)
  if [ "$RENAMED" = "testwin" ]; then
    expect.pass "window renamed to 'testwin'"
  else
    expect.fail "window name is '$RENAMED' (expected 'testwin')"
  fi

  # T-OTMUX-13: otmux tiled with target sets layout on remote window
  # Split first to have multiple panes
  otmux split.h -t "${OTMUX_TEST_SESS}:0" 2>/dev/null
  otmux tiled "${OTMUX_TEST_SESS}:0" 2>/dev/null
  test.case $level "T-OTMUX-13: otmux tiled with target" \
    echo "tiled layout on remote"
  LAYOUT=$(otmux windows -t "$OTMUX_TEST_SESS" -F "#{window_layout}" 2>/dev/null | head -1)
  if [ -n "$LAYOUT" ]; then
    expect.pass "layout set on remote window"
  else
    expect.fail "could not verify layout on remote window"
  fi

  # T-OTMUX-14: otmux kill destroys session
  otmux kill "$OTMUX_TEST_SESS" 2>/dev/null
  test.case $level "T-OTMUX-14: otmux kill destroys session" \
    echo "kill test"
  if ! otmux has "$OTMUX_TEST_SESS" 2>/dev/null; then
    expect.pass "session $OTMUX_TEST_SESS destroyed"
  else
    expect.fail "session $OTMUX_TEST_SESS still exists after kill"
    otmux kill "$OTMUX_TEST_SESS" 2>/dev/null  # cleanup
  fi

  # T-OTMUX-15: otmux panes passthrough with -t and -F
  otmux new "__test_otmux2_$$" -d 2>/dev/null
  otmux split.h -t "__test_otmux2_$$:0" 2>/dev/null
  test.case $level "T-OTMUX-15: otmux panes passthrough with -t -F" \
    echo "panes passthrough"
  PANE_LIST=$(otmux panes -t "__test_otmux2_$$:0" -F "#{pane_index}" 2>/dev/null)
  PANE_COUNT=$(echo "$PANE_LIST" | wc -l | tr -d ' ')
  if [ "$PANE_COUNT" -ge 2 ]; then
    expect.pass "otmux panes returned $PANE_COUNT panes"
  else
    expect.fail "otmux panes returned $PANE_COUNT panes (expected >= 2)"
  fi
  otmux kill "__test_otmux2_$$" 2>/dev/null

else
  echo "SKIP: T-OTMUX-10..15 behavioral tests require tmux"
fi

echo ""
echo "=== T-OTMUX tests complete ==="
echo ""

# ============================================================================
# T-RESTORE: teams.save / teams.restore / teams.migrate tests
# ============================================================================

echo ""
echo "=== T-RESTORE: teams.save/restore/migrate ==="
echo ""

# --- Function existence ---

test.case $level "T-RESTORE-1: teams.save method exists" \
  echo "checking"
if type -t hiveMind.teams.save | grep -q function; then
  expect.pass "hiveMind.teams.save is a function"
else
  expect.fail "hiveMind.teams.save not found"
fi

test.case $level "T-RESTORE-2: teams.restore method exists" \
  echo "checking"
if type -t hiveMind.teams.restore | grep -q function; then
  expect.pass "hiveMind.teams.restore is a function"
else
  expect.fail "hiveMind.teams.restore not found"
fi

test.case $level "T-RESTORE-3: teams.migrate method exists" \
  echo "checking"
if type -t hiveMind.teams.migrate | grep -q function; then
  expect.pass "hiveMind.teams.migrate is a function"
else
  expect.fail "hiveMind.teams.migrate not found"
fi

test.case $level "T-RESTORE-4: claudeCode.fork method exists" \
  echo "checking"
source "$OOSH_DIR/claudeCode"
if type -t claudeCode.fork | grep -q function; then
  expect.pass "claudeCode.fork is a function"
else
  expect.fail "claudeCode.fork not found"
fi

# --- Snapshot format validation ---

test.case $level "T-RESTORE-5: teams.save creates snapshot file" \
  hiveMind.teams.save
SNAPSHOT_FILE=$(ls -t "${CONFIG_PATH:-$HOME/config}"/hivemind.snapshot.*.env 2>/dev/null | head -1)
if [ -n "$SNAPSHOT_FILE" ] && [ -f "$SNAPSHOT_FILE" ]; then
  expect.pass "Snapshot created: $SNAPSHOT_FILE"
else
  expect.fail "No snapshot file created"
fi

test.case $level "T-RESTORE-6: snapshot has correct header format" \
  echo "checking snapshot header"
if [ -n "$SNAPSHOT_FILE" ] && head -1 "$SNAPSHOT_FILE" | grep -q "^# hiveMind snapshot"; then
  expect.pass "Header: $(head -1 "$SNAPSHOT_FILE")"
else
  expect.fail "Missing or wrong header in snapshot"
fi

test.case $level "T-RESTORE-7: snapshot has pipe-delimited records" \
  echo "checking snapshot format"
if [ -n "$SNAPSHOT_FILE" ]; then
  local dataLines
  dataLines=$(grep -v "^#" "$SNAPSHOT_FILE" | grep -c '|')
  if [ "$dataLines" -gt 0 ]; then
    expect.pass "$dataLines pipe-delimited records found"
  else
    expect.fail "No pipe-delimited records in snapshot"
  fi
else
  expect.fail "No snapshot file to check"
fi

test.case $level "T-RESTORE-8: snapshot records have 5 fields (session|addr|role|uuid|title)" \
  echo "checking field count"
if [ -n "$SNAPSHOT_FILE" ]; then
  local badLines
  badLines=$(grep -v "^#" "$SNAPSHOT_FILE" | grep -v "^$" | awk -F'|' 'NF != 5 {print NR": "$0}')
  if [ -z "$badLines" ]; then
    expect.pass "All records have 5 fields"
  else
    expect.fail "Bad records: $badLines"
  fi
else
  expect.fail "No snapshot file"
fi

# --- Cross-machine readiness checks ---

test.case $level "T-RESTORE-9: teams.restore uses claudeCode (not raw claude)" \
  echo "checking for raw claude in restore"
RAW_CLAUDE_COUNT=$(grep -c 'send.*"claude ' $OOSH_DIR/hiveMind 2>/dev/null || echo 0)
# teams.restore should use claudeCode join/fork, never raw claude
RESTORE_RAW=$(sed -n '1476,1552p' $OOSH_DIR/hiveMind | grep -c '"claude ')
if [ "$RESTORE_RAW" -eq 0 ]; then
  expect.pass "teams.restore uses claudeCode wrapper, not raw claude"
else
  expect.fail "teams.restore has $RESTORE_RAW raw claude calls — should use claudeCode"
fi

test.case $level "T-RESTORE-10: teams.migrate transfers JSONL session files" \
  echo "checking JSONL transfer in migrate"
# Check for JSONL transfer code in teams.migrate section (lines 1558-1650)
if sed -n '1558,1650p' $OOSH_DIR/hiveMind | grep -q 'jsonl\|JSONL'; then
  expect.pass "teams.migrate has JSONL transfer logic"
else
  expect.fail "teams.migrate does NOT transfer JSONL files — agents will fail with 'No conversation found'"
fi

test.case $level "T-RESTORE-11: teams.restore supports fork mode" \
  echo "checking fork support in restore"
if grep -q 'fork\|--fork' $OOSH_DIR/hiveMind | grep -q 'teams.restore' 2>/dev/null; then
  expect.pass "teams.restore supports fork mode"
else
  # Check if fork is used anywhere in restore
  FORK_IN_RESTORE=$(sed -n '1476,1552p' $OOSH_DIR/hiveMind | grep -c 'fork')
  if [ "$FORK_IN_RESTORE" -gt 0 ]; then
    expect.pass "teams.restore has fork support ($FORK_IN_RESTORE references)"
  else
    expect.fail "teams.restore has NO fork support — cross-machine restore will cause UUID conflicts"
  fi
fi

test.case $level "T-RESTORE-12: teams.migrate checks model compatibility" \
  echo "checking model check in migrate"
if grep -q 'opus\[1m\]\|settings\.json\|model.*check\|model.*compat' $OOSH_DIR/hiveMind 2>/dev/null; then
  expect.pass "teams.migrate has model compatibility check"
else
  expect.fail "teams.migrate does NOT check model setting — opus[1m] blocks all API calls"
fi

# --- Fixture-based restore test ---

RESTORE_SESS="__test_restore_$$"
if otmux sessions >/dev/null 2>&1; then

  # Create a minimal snapshot for testing
  RESTORE_SNAP="/tmp/hivemind.snapshot.test.$$.env"
  cat > "$RESTORE_SNAP" <<SNAP
# hiveMind snapshot test
# session|address|role|uuid|title
${RESTORE_SESS}|0.0|test-agent-alpha||alpha-pane
${RESTORE_SESS}|0.1|test-agent-beta||beta-pane
SNAP

  test.case $level "T-RESTORE-13: teams.restore creates session from snapshot" \
    hiveMind.teams.restore "$RESTORE_SNAP"
  if otmux has "$RESTORE_SESS" 2>/dev/null; then
    expect.pass "Session $RESTORE_SESS created"
  else
    expect.fail "Session $RESTORE_SESS NOT created from snapshot"
  fi

  test.case $level "T-RESTORE-14: teams.restore creates correct pane count" \
    echo "checking pane count"
  if otmux has "$RESTORE_SESS" 2>/dev/null; then
    PANE_COUNT=$(otmux panes -t "${RESTORE_SESS}:0" 2>/dev/null | wc -l | tr -d ' ')
    if [ "$PANE_COUNT" -ge 2 ]; then
      expect.pass "$PANE_COUNT panes created (expected 2)"
    else
      # ensure.pane may not split for addr 0.1 — check if at least session+pane0 exist
      expect.fail "Only $PANE_COUNT pane(s) — expected 2 (ensure.pane may need debugging)"
    fi
  else
    expect.fail "Session doesn't exist"
  fi

  test.case $level "T-RESTORE-15: teams.restore sets registry entries" \
    echo "checking registry"
  RESTORE_REG="${HIVEMIND_REGISTRY:-${CONFIG_PATH:-$HOME/config}/hivemind.roles.env}"
  if [ -f "$RESTORE_REG" ]; then
    if grep -q "test-agent-alpha" "$RESTORE_REG" 2>/dev/null; then
      expect.pass "test-agent-alpha found in registry"
    else
      expect.fail "test-agent-alpha NOT in registry after restore"
    fi
  else
    expect.fail "Registry file not found at $RESTORE_REG"
  fi

  # Teardown
  otmux kill "$RESTORE_SESS" 2>/dev/null
  rm -f "$RESTORE_SNAP"
  # Clean up registry entries
  [ -f "$RESTORE_REG" ] && sed -i '' '/test-agent-alpha/d;/test-agent-beta/d' "$RESTORE_REG" 2>/dev/null

else
  echo "SKIP: T-RESTORE-13..15 fixture tests require tmux"
fi

echo ""
echo "=== T-RESTORE tests complete ==="
echo ""

# ============================================================================
# T-HELPERS: DRY helper behavioral tests (backlog items 1-4)
# Tests: env.set, env.del, role.isGeneric, role.fromTitle,
#        session.store, session.lookup, liveUuid
# ============================================================================

echo ""
echo "=== T-HELPERS: DRY helper behavioral tests ==="
echo ""

# --- Fixtures ---
HELPERS_TMP="/tmp/test_hivemind_helpers_$$"
mkdir -p "$HELPERS_TMP"

helpersCleanup() {
  rm -rf "$HELPERS_TMP"
}

test.hiveMind.envSet() {
  local ENV_FILE="$HELPERS_TMP/test.env"
  > "$ENV_FILE"

  # T-HELPERS-1: env.set adds new entry to empty file
  private.hiveMind.env.set "$ENV_FILE" "pane0.0" "oosh-expert"
  local ENVSET1_RC=$?

  test.case $level "T-HELPERS-1: env.set adds new key to empty file" \
    echo "rc=$ENVSET1_RC"

  local ENTRY=$(cat "$ENV_FILE" 2>/dev/null)
  if echo "$ENTRY" | grep -q "^pane0.0|oosh-expert$"; then
    expect.pass "env.set wrote: $(cat "$ENV_FILE")"
  else
    expect.fail "env.set should write pane0.0|oosh-expert, got: '$ENTRY'"
  fi

  # T-HELPERS-2: env.set adds second entry (append)
  private.hiveMind.env.set "$ENV_FILE" "pane0.1" "scrum-master"

  test.case $level "T-HELPERS-2: env.set appends second key" \
    echo "lines=$(wc -l < "$ENV_FILE" | tr -d ' ')"

  local LINE_COUNT=$(wc -l < "$ENV_FILE" | tr -d ' ')
  if [ "$LINE_COUNT" -eq 2 ] && grep -q "^pane0.1|scrum-master$" "$ENV_FILE"; then
    expect.pass "env.set appended second entry ($LINE_COUNT lines)"
  else
    expect.fail "expected 2 lines with pane0.1|scrum-master, got $LINE_COUNT lines"
  fi

  # T-HELPERS-3: env.set replaces existing key with new value
  private.hiveMind.env.set "$ENV_FILE" "pane0.0" "developer"
  local ENVSET3_RC=$?

  test.case $level "T-HELPERS-3: env.set replaces value for existing key" \
    echo "rc=$ENVSET3_RC"

  local UPDATED=$(grep "^pane0.0|" "$ENV_FILE")
  if [ "$UPDATED" = "pane0.0|developer" ]; then
    expect.pass "env.set replaced: $UPDATED"
  else
    expect.fail "env.set should replace to pane0.0|developer, got: '$UPDATED'"
  fi

  # T-HELPERS-4: env.set returns 1 when value unchanged
  private.hiveMind.env.set "$ENV_FILE" "pane0.0" "developer"
  local NOCHANGE_RC=$?

  test.case $level "T-HELPERS-4: env.set returns 1 for no-change" \
    echo "rc=$NOCHANGE_RC"

  if [ "$NOCHANGE_RC" -eq 1 ]; then
    expect.pass "env.set returned 1 (no change needed)"
  else
    expect.fail "env.set should return 1 when value unchanged, got rc=$NOCHANGE_RC"
  fi
}
test.hiveMind.envSet

test.hiveMind.envDel() {
  # T-HELPERS-5: env.del removes entry by key only
  local ENV_DEL_FILE="$HELPERS_TMP/del.env"
  printf "pane0.0|expert\npane0.1|master\n" > "$ENV_DEL_FILE"

  private.hiveMind.env.del "$ENV_DEL_FILE" "pane0.0"

  test.case $level "T-HELPERS-5: env.del removes by key" \
    echo "checking"

  local REMAINING=$(cat "$ENV_DEL_FILE" 2>/dev/null)
  if ! echo "$REMAINING" | grep -q "^pane0.0|" && echo "$REMAINING" | grep -q "^pane0.1|master"; then
    expect.pass "env.del removed pane0.0, kept pane0.1"
  else
    expect.fail "env.del should remove only pane0.0, got: '$REMAINING'"
  fi

  # T-HELPERS-6: env.del removes by key+value (specific match)
  local ENV_DEL2_FILE="$HELPERS_TMP/del2.env"
  printf "pane0.0|uuid-aaa\npane0.0|uuid-bbb\npane0.1|uuid-ccc\n" > "$ENV_DEL2_FILE"

  private.hiveMind.env.del "$ENV_DEL2_FILE" "pane0.0" "uuid-aaa"

  test.case $level "T-HELPERS-6: env.del removes by key+value" \
    echo "checking"

  if grep -q "^pane0.0|uuid-bbb$" "$ENV_DEL2_FILE" && ! grep -q "uuid-aaa" "$ENV_DEL2_FILE"; then
    expect.pass "env.del removed only key+value match"
  else
    expect.fail "env.del should remove only pane0.0|uuid-aaa, got: $(cat "$ENV_DEL2_FILE")"
  fi
}
test.hiveMind.envDel

test.hiveMind.roleIsGeneric() {
  # T-HELPERS-7: role.isGeneric — empty string is generic
  private.hiveMind.role.isGeneric ""
  local GENERIC_EMPTY=$?

  test.case $level "T-HELPERS-7: role.isGeneric empty → true" \
    echo "rc=$GENERIC_EMPTY"

  if [ "$GENERIC_EMPTY" -eq 0 ]; then
    expect.pass "empty string is generic"
  else
    expect.fail "empty string should be generic (rc=$GENERIC_EMPTY)"
  fi

  # T-HELPERS-8: role.isGeneric — 'unknown' is generic
  private.hiveMind.role.isGeneric "unknown"
  local GENERIC_UNK=$?

  test.case $level "T-HELPERS-8: role.isGeneric 'unknown' → true" \
    echo "rc=$GENERIC_UNK"

  if [ "$GENERIC_UNK" -eq 0 ]; then
    expect.pass "'unknown' is generic"
  else
    expect.fail "'unknown' should be generic (rc=$GENERIC_UNK)"
  fi

  # T-HELPERS-9: role.isGeneric — 'ClaudeCode' is generic
  private.hiveMind.role.isGeneric "ClaudeCode"
  local GENERIC_CC=$?

  test.case $level "T-HELPERS-9: role.isGeneric 'ClaudeCode' → true" \
    echo "rc=$GENERIC_CC"

  if [ "$GENERIC_CC" -eq 0 ]; then
    expect.pass "'ClaudeCode' is generic"
  else
    expect.fail "'ClaudeCode' should be generic (rc=$GENERIC_CC)"
  fi

  # T-HELPERS-10: role.isGeneric — 'claude' is generic
  private.hiveMind.role.isGeneric "claude"
  local GENERIC_CL=$?

  test.case $level "T-HELPERS-10: role.isGeneric 'claude' → true" \
    echo "rc=$GENERIC_CL"

  if [ "$GENERIC_CL" -eq 0 ]; then
    expect.pass "'claude' is generic"
  else
    expect.fail "'claude' should be generic (rc=$GENERIC_CL)"
  fi

  # T-HELPERS-11: role.isGeneric — 'oosh-expert' is NOT generic
  private.hiveMind.role.isGeneric "oosh-expert"
  local GENERIC_EXPERT=$?

  test.case $level "T-HELPERS-11: role.isGeneric 'oosh-expert' → false" \
    echo "rc=$GENERIC_EXPERT"

  if [ "$GENERIC_EXPERT" -ne 0 ]; then
    expect.pass "'oosh-expert' is not generic"
  else
    expect.fail "'oosh-expert' should not be generic (rc=$GENERIC_EXPERT)"
  fi

  # T-HELPERS-12: role.isGeneric — 'scrum-master' is NOT generic
  private.hiveMind.role.isGeneric "scrum-master"
  local GENERIC_SM=$?

  test.case $level "T-HELPERS-12: role.isGeneric 'scrum-master' → false" \
    echo "rc=$GENERIC_SM"

  if [ "$GENERIC_SM" -ne 0 ]; then
    expect.pass "'scrum-master' is not generic"
  else
    expect.fail "'scrum-master' should not be generic (rc=$GENERIC_SM)"
  fi
}
test.hiveMind.roleIsGeneric

test.hiveMind.roleFromTitle() {
  # T-HELPERS-13: role.fromTitle — plain role name passes through
  local TITLE_PLAIN
  TITLE_PLAIN=$(private.hiveMind.role.fromTitle "oosh-expert" 2>/dev/null)
  local TITLE_PLAIN_RC=$?

  test.case $level "T-HELPERS-13: role.fromTitle plain name → passthrough" \
    echo "out='$TITLE_PLAIN' rc=$TITLE_PLAIN_RC"

  if [ "$TITLE_PLAIN" = "oosh-expert" ] && [ "$TITLE_PLAIN_RC" -eq 0 ]; then
    expect.pass "role.fromTitle returned: $TITLE_PLAIN"
  else
    expect.fail "expected 'oosh-expert', got '$TITLE_PLAIN' rc=$TITLE_PLAIN_RC"
  fi

  # T-HELPERS-14: role.fromTitle — strips ✳ prefix
  local TITLE_STAR
  TITLE_STAR=$(private.hiveMind.role.fromTitle "✳ scrum-master" 2>/dev/null)
  local TITLE_STAR_RC=$?

  test.case $level "T-HELPERS-14: role.fromTitle strips ✳ prefix" \
    echo "out='$TITLE_STAR' rc=$TITLE_STAR_RC"

  if [ "$TITLE_STAR" = "scrum-master" ] && [ "$TITLE_STAR_RC" -eq 0 ]; then
    expect.pass "role.fromTitle stripped prefix: $TITLE_STAR"
  else
    expect.fail "expected 'scrum-master', got '$TITLE_STAR' rc=$TITLE_STAR_RC"
  fi

  # T-HELPERS-15: role.fromTitle — strips ⠐ prefix
  local TITLE_DOT=$(private.hiveMind.role.fromTitle "⠐ developer" 2>/dev/null)

  test.case $level "T-HELPERS-15: role.fromTitle strips ⠐ prefix" \
    echo "out='$TITLE_DOT'"

  if [ "$TITLE_DOT" = "developer" ]; then
    expect.pass "stripped ⠐ prefix: $TITLE_DOT"
  else
    expect.fail "expected 'developer', got '$TITLE_DOT'"
  fi

  # T-HELPERS-16: role.fromTitle — strips @suffix
  local TITLE_AT=$(private.hiveMind.role.fromTitle "expert@hostname" 2>/dev/null)

  test.case $level "T-HELPERS-16: role.fromTitle strips @suffix" \
    echo "out='$TITLE_AT'"

  if [ "$TITLE_AT" = "expert" ]; then
    expect.pass "stripped @suffix: $TITLE_AT"
  else
    expect.fail "expected 'expert', got '$TITLE_AT'"
  fi

  # T-HELPERS-17: role.fromTitle — generic input → return 1
  local TITLE_GEN
  TITLE_GEN=$(private.hiveMind.role.fromTitle "unknown" 2>/dev/null)
  local TITLE_GEN_RC=$?

  test.case $level "T-HELPERS-17: role.fromTitle generic → returns 1" \
    echo "out='$TITLE_GEN' rc=$TITLE_GEN_RC"

  if [ "$TITLE_GEN_RC" -ne 0 ]; then
    expect.pass "role.fromTitle rejected generic input"
  else
    expect.fail "role.fromTitle should return 1 for generic input, got rc=$TITLE_GEN_RC"
  fi

  # T-HELPERS-18: role.fromTitle — empty input → return 1
  local TITLE_EMPTY
  TITLE_EMPTY=$(private.hiveMind.role.fromTitle "" 2>/dev/null)
  local TITLE_EMPTY_RC=$?

  test.case $level "T-HELPERS-18: role.fromTitle empty → returns 1" \
    echo "out='$TITLE_EMPTY' rc=$TITLE_EMPTY_RC"

  if [ "$TITLE_EMPTY_RC" -ne 0 ]; then
    expect.pass "role.fromTitle rejected empty input"
  else
    expect.fail "role.fromTitle should return 1 for empty, got rc=$TITLE_EMPTY_RC"
  fi

  # T-HELPERS-30: role.fromTitle — strips ✻ prefix
  local TITLE_STAR2=$(private.hiveMind.role.fromTitle "✻ orchestrator" 2>/dev/null)

  test.case $level "T-HELPERS-30: role.fromTitle strips ✻ prefix" \
    echo "out='$TITLE_STAR2'"

  if [ "$TITLE_STAR2" = "orchestrator" ]; then
    expect.pass "stripped ✻ prefix: $TITLE_STAR2"
  else
    expect.fail "expected 'orchestrator', got '$TITLE_STAR2'"
  fi

  # T-HELPERS-31: role.fromTitle — truncates to 30 chars
  local LONG_TITLE="a]very-long-role-name-that-exceeds-thirty-characters-total"
  local TITLE_LONG=$(private.hiveMind.role.fromTitle "$LONG_TITLE" 2>/dev/null)

  test.case $level "T-HELPERS-31: role.fromTitle truncates to 30 chars" \
    echo "len=${#TITLE_LONG}"

  if [ "${#TITLE_LONG}" -le 30 ]; then
    expect.pass "role.fromTitle truncated to ${#TITLE_LONG} chars"
  else
    expect.fail "role.fromTitle should truncate to 30 chars, got ${#TITLE_LONG}"
  fi

  # T-HELPERS-32: role.fromTitle — strips whitespace
  local TITLE_WS=$(private.hiveMind.role.fromTitle "  oosh-tester  " 2>/dev/null)

  test.case $level "T-HELPERS-32: role.fromTitle strips whitespace" \
    echo "out='$TITLE_WS'"

  if [ "$TITLE_WS" = "oosh-tester" ]; then
    expect.pass "stripped whitespace: $TITLE_WS"
  else
    expect.fail "expected 'oosh-tester', got '$TITLE_WS'"
  fi
}
test.hiveMind.roleFromTitle

test.hiveMind.sessionStore() {
  # Override HIVEMIND_SESSIONS to use temp file for isolation
  local ORIG_SESSIONS="$HIVEMIND_SESSIONS"
  HIVEMIND_SESSIONS="$HELPERS_TMP/sessions.env"
  echo "# test sessions" > "$HIVEMIND_SESSIONS"

  # T-HELPERS-19: session.store writes pane|uuid to file
  private.hiveMind.session.store "testSess:0.0" "a2c6b6c4-1234-5678-9abc-def012345678"

  test.case $level "T-HELPERS-19: session.store writes mapping" \
    echo "checking"

  if grep -q "^testSess:0.0|a2c6b6c4-1234-5678-9abc-def012345678$" "$HIVEMIND_SESSIONS"; then
    expect.pass "session.store wrote mapping"
  else
    expect.fail "session.store should write testSess:0.0|uuid, got: $(cat "$HIVEMIND_SESSIONS")"
  fi

  # T-HELPERS-20: session.store overwrites existing pane mapping
  private.hiveMind.session.store "testSess:0.0" "bbbbbbbb-2222-3333-4444-555555555555"

  test.case $level "T-HELPERS-20: session.store overwrites existing pane" \
    echo "checking"

  local OLD_COUNT=$(grep -c "^testSess:0.0|" "$HIVEMIND_SESSIONS")
  local NEW_UUID=$(grep "^testSess:0.0|" "$HIVEMIND_SESSIONS" | cut -d'|' -f2)

  if [ "$OLD_COUNT" -eq 1 ] && [ "$NEW_UUID" = "bbbbbbbb-2222-3333-4444-555555555555" ]; then
    expect.pass "session.store replaced: 1 entry, uuid=${NEW_UUID:0:8}..."
  else
    expect.fail "expected 1 entry with new uuid, got count=$OLD_COUNT uuid=$NEW_UUID"
  fi

  # T-HELPERS-21: session.store rejects empty pane
  private.hiveMind.session.store "" "some-uuid"
  local STORE_EMPTY_RC=$?

  test.case $level "T-HELPERS-21: session.store rejects empty pane" \
    echo "rc=$STORE_EMPTY_RC"

  if [ "$STORE_EMPTY_RC" -ne 0 ]; then
    expect.pass "session.store rejected empty pane (rc=$STORE_EMPTY_RC)"
  else
    expect.fail "session.store should reject empty pane (rc=$STORE_EMPTY_RC)"
  fi

  # T-HELPERS-22: session.store rejects empty sessionId
  private.hiveMind.session.store "testSess:0.0" ""
  local STORE_NOSID_RC=$?

  test.case $level "T-HELPERS-22: session.store rejects empty sessionId" \
    echo "rc=$STORE_NOSID_RC"

  if [ "$STORE_NOSID_RC" -ne 0 ]; then
    expect.pass "session.store rejected empty sessionId (rc=$STORE_NOSID_RC)"
  else
    expect.fail "session.store should reject empty sessionId (rc=$STORE_NOSID_RC)"
  fi

  # T-HELPERS-33: session.store preserves other pane entries
  # Multiple panes stored — updating one should not affect others
  HIVEMIND_SESSIONS="$HELPERS_TMP/sessions_multi.env"
  echo "# multi test" > "$HIVEMIND_SESSIONS"

  private.hiveMind.session.store "sess:0.0" "aaaa-uuid" 2>/dev/null
  private.hiveMind.session.store "sess:0.1" "bbbb-uuid" 2>/dev/null
  private.hiveMind.session.store "sess:0.2" "cccc-uuid" 2>/dev/null
  # Now update pane 0.1
  private.hiveMind.session.store "sess:0.1" "dddd-uuid" 2>/dev/null

  test.case $level "T-HELPERS-33: session.store preserves other entries" \
    echo "checking multi-pane"

  local PANE0=$(grep "^sess:0.0|" "$HIVEMIND_SESSIONS" | cut -d'|' -f2)
  local PANE1=$(grep "^sess:0.1|" "$HIVEMIND_SESSIONS" | cut -d'|' -f2)
  local PANE2=$(grep "^sess:0.2|" "$HIVEMIND_SESSIONS" | cut -d'|' -f2)

  if [ "$PANE0" = "aaaa-uuid" ] && [ "$PANE1" = "dddd-uuid" ] && [ "$PANE2" = "cccc-uuid" ]; then
    expect.pass "all entries correct after update"
  else
    expect.fail "entries corrupted: 0.0=$PANE0 0.1=$PANE1 0.2=$PANE2"
  fi

  # Restore HIVEMIND_SESSIONS
  HIVEMIND_SESSIONS="$ORIG_SESSIONS"
}
test.hiveMind.sessionStore

test.hiveMind.sessionLookup() {
  # Override HIVEMIND_SESSIONS to use temp file for isolation
  local ORIG_SESSIONS="$HIVEMIND_SESSIONS"
  HIVEMIND_SESSIONS="$HELPERS_TMP/sessions.env"
  echo "# test sessions" > "$HIVEMIND_SESSIONS"

  # Pre-populate with a known entry for lookup tests
  private.hiveMind.session.store "testSess:0.0" "bbbbbbbb-2222-3333-4444-555555555555"

  # T-HELPERS-23: session.lookup returns stored UUID
  local LOOKUP_UUID=$(private.hiveMind.session.lookup "testSess:0.0" 2>/dev/null)

  test.case $level "T-HELPERS-23: session.lookup returns stored UUID" \
    echo "uuid=$LOOKUP_UUID"

  if [ "$LOOKUP_UUID" = "bbbbbbbb-2222-3333-4444-555555555555" ]; then
    expect.pass "session.lookup returned: ${LOOKUP_UUID:0:8}..."
  else
    expect.fail "expected bbbbbbbb-..., got '$LOOKUP_UUID'"
  fi

  # T-HELPERS-24: session.lookup returns empty for missing pane
  local LOOKUP_MISS=$(private.hiveMind.session.lookup "nonexistent:9.9" 2>/dev/null)

  test.case $level "T-HELPERS-24: session.lookup empty for missing pane" \
    echo "out='$LOOKUP_MISS'"

  if [ -z "$LOOKUP_MISS" ]; then
    expect.pass "session.lookup returned empty for missing pane"
  else
    expect.fail "session.lookup should return empty, got '$LOOKUP_MISS'"
  fi

  # T-HELPERS-25: session.lookup fails when file doesn't exist
  HIVEMIND_SESSIONS="$HELPERS_TMP/nonexistent_sessions.env"

  private.hiveMind.session.lookup "testSess:0.0" 2>/dev/null
  local LOOKUP_NOFILE_RC=$?

  test.case $level "T-HELPERS-25: session.lookup returns 1 for missing file" \
    echo "rc=$LOOKUP_NOFILE_RC"

  if [ "$LOOKUP_NOFILE_RC" -ne 0 ]; then
    expect.pass "session.lookup returns 1 for missing file"
  else
    expect.fail "session.lookup should return 1 when file missing (rc=$LOOKUP_NOFILE_RC)"
  fi

  # Restore HIVEMIND_SESSIONS
  HIVEMIND_SESSIONS="$ORIG_SESSIONS"
}
test.hiveMind.sessionLookup

test.hiveMind.liveUuid() {
  # T-HELPERS-26: liveUuid extracts UUID from procArgs
  local PROC_UUID=$(private.hiveMind.liveUuid "testSess:0.0" "--resume a2c6b6c4-1234-5678-9abc-def012345678 --some-flag" 2>/dev/null)

  test.case $level "T-HELPERS-26: liveUuid extracts UUID from procArgs" \
    echo "uuid=$PROC_UUID"

  if [ "$PROC_UUID" = "a2c6b6c4-1234-5678-9abc-def012345678" ]; then
    expect.pass "liveUuid extracted: ${PROC_UUID:0:8}..."
  else
    expect.fail "expected a2c6b6c4-..., got '$PROC_UUID'"
  fi

  # T-HELPERS-27: liveUuid skips fork parent (no UUID from args)
  # Forked sessions skip args extraction, fall through to claudeCode session.id
  # which will fail in test env — so expect empty/failure
  local FORK_UUID
  FORK_UUID=$(private.hiveMind.liveUuid "testSess:0.0" "claudeCode fork --fork-session a2c6b6c4-1234-5678-9abc-def012345678" 2>/dev/null)
  local FORK_RC=$?

  test.case $level "T-HELPERS-27: liveUuid skips fork parent args" \
    echo "uuid='$FORK_UUID' rc=$FORK_RC"

  if [ -z "$FORK_UUID" ] || [ "$FORK_RC" -ne 0 ]; then
    expect.pass "liveUuid skipped fork parent (no direct UUID extraction)"
  else
    expect.fail "liveUuid should skip fork parent args, got '$FORK_UUID'"
  fi

  # T-HELPERS-28: liveUuid returns 1 when no UUID available
  local NOUUID
  NOUUID=$(private.hiveMind.liveUuid "testSess:0.0" "" 2>/dev/null)
  local NOUUID_RC=$?

  test.case $level "T-HELPERS-28: liveUuid returns 1 for empty procArgs" \
    echo "rc=$NOUUID_RC"

  if [ "$NOUUID_RC" -ne 0 ]; then
    expect.pass "liveUuid returns 1 when no UUID available"
  else
    expect.fail "liveUuid should return 1 with empty procArgs, got rc=$NOUUID_RC"
  fi

  # T-HELPERS-29: liveUuid extracts UUID regardless of position in args
  local MULTI_UUID=$(private.hiveMind.liveUuid "testSess:0.0" "node /path/to/claude --model opus --resume dddddddd-1111-2222-3333-444444444444 --verbose" 2>/dev/null)

  test.case $level "T-HELPERS-29: liveUuid extracts UUID from mid-args" \
    echo "uuid=$MULTI_UUID"

  if [ "$MULTI_UUID" = "dddddddd-1111-2222-3333-444444444444" ]; then
    expect.pass "liveUuid extracted mid-args UUID: ${MULTI_UUID:0:8}..."
  else
    expect.fail "expected dddddddd-..., got '$MULTI_UUID'"
  fi
}
test.hiveMind.liveUuid

# Teardown fixtures
helpersCleanup

echo ""
echo "=== T-HELPERS tests complete ==="
echo ""

# ============================================================================
# Test Summary
# ============================================================================

test.suite.save.results
