<!-- STATUS: COMPLETE -->

# Phase 18 UA Testing: Film Noir Theme and Narrative

## Quick Smoke Tests (5 min)

These verify the core functionality without requiring a real LLM.

### 1. Theme Module Imports

```bash
cd /project
python3 -c "from unfamiliar.tui.themes import NarrativeConfig, ThemeConfig, get_theme; print('OK')"
```

Expected: `OK`

### 2. NarrativeConfig and ThemeConfig Helpers

```bash
python3 -c "
from unfamiliar.tui.themes import get_theme
t = get_theme('film_noir')
print(f'tone[:30]: {t.narrative.tone[:30]}')
print(f'title_examples: {len(t.narrative.title_examples)}')
print(f'vocab(mission): {t.vocab(\"mission\")}')
print(f'alias(next): {t.alias(\"next\")}')
print(f'vocab(unknown): {t.vocab(\"nonexistent\")}')
"
```

Expected:
```
tone[:30]: Film Noir detective investigat
title_examples: 5
vocab(mission): lead
alias(next): investigate
vocab(unknown): nonexistent
```

### 3. build_theme_prompt_vars Fallback

```bash
python3 -c "
from unfamiliar.llm.missions.prompts import build_theme_prompt_vars

# Test with None (fallback)
fallback = build_theme_prompt_vars(None)
print(f'fallback theme_name: {fallback[\"theme_name\"]}')

# Test with Film Noir theme
from unfamiliar.tui.themes import get_theme
theme = get_theme('film_noir')
themed = build_theme_prompt_vars(theme)
print(f'themed theme_name: {themed[\"theme_name\"]}')
print(f'themed title_examples: {themed[\"theme_title_examples\"][:50]}...')
"
```

Expected:
```
fallback theme_name: Investigation
themed theme_name: Film Noir
themed title_examples: "The Password Vault", "Shadows in the Login Flow...
```

### 4. Test Suite

```bash
cd /project
coverage-wrapper run
```

Expected: 904 tests passing, no failures.

---

## Priority 1: End-to-End with Real LLM (15 min)

**Prerequisite:** GLM API key configured in environment.

### 1. Create New Campaign with Themed Narrative

```bash
cd /project
unfamiliar investigate /path/to/small/repo
```

**Watch for:**
- Campaign creation completes without errors
- Missions have Film Noir themed titles (e.g., "The Password Vault", "Shadows in...")
- Narrative intros have detective/moody tone

### 2. TUI: Themed Command Reference Panel

Launch TUI and observe the right panel:

```bash
unfamiliar resume
```

**Verify:**
- Panel shows themed aliases (e.g., "investigate", "file report", "case board")
- Each command shows alias + short description
- Canonical names NOT shown in panel

### 3. TUI: Themed Help Command

In the TUI, type the help command alias:

```
call in a marker
```

**Verify:**
- Shows "UNFAMILIAR — Case Commands" header (using vocab)
- Each command shows themed alias (bold) + canonical name (dim parentheses)
- Description on next line
- KEYBOARD SHORTCUTS section at bottom

### 4. TUI: In-Progress Missions in Next List

In the TUI:

1. Type `investigate` to see mission list
2. Select a mission: `investigate 1`
3. Without completing, type `investigate` again

**Verify:**
- In-progress mission appears at TOP of list
- Status marker shows `[ACTIVE]` (or themed equivalent)
- Selecting the in-progress mission resumes it without error

### 5. TUI: All User-Facing Strings Themed

In the TUI, observe various screens:

- `case board` — All status labels use themed terms (Open, Active, Sealed, Closed)
- Mission detail — Labels use themed terms (Evidence Files, Lead-ups)
- Completion screen — "Lead Closed" header, themed vocabulary throughout

---

## Priority 2: Theme Plugin Verification (Optional, 10 min)

### Verify New Theme Would Work Without Code Changes

1. Create a test theme directory structure:

```bash
mkdir -p /tmp/test_theme
```

2. Verify that the following would be sufficient for a new theme:
   - A `theme.py` with `NarrativeConfig`, `ThemeConfig`, aliases, vocabulary
   - A TCSS stylesheet
   - A `register_theme()` call

The key insight: `prompts.py` now uses `build_theme_prompt_vars()` which reads from `theme_config.narrative`. No hardcoded "Film Noir" references remain.

---

## Issues Discovered

*(Leave blank during testing — fill in any issues found)*

### Issue 1:

**Description:**
**Severity:**
**Steps to reproduce:**
**Expected:**
**Actual:**

---

## User Testing Notes

*(Fill in after completing UA tests)*

### Issues Found:

1. **[FIXED]** Closing the case crashes — `TypeError: CampaignRepository.update() got an unexpected keyword argument 'status'`. `_close_campaign()` called `update(campaign_id, status=...)` but the correct method is `update_status(campaign_id, status)`. Fixed in `app.py:520`.
2. **[FIXED]** After fix #1, closing the case crashes again — `MissingStyle: Failed to get style "bold color('#c9a227')"`. The markup in `_close_campaign()` used `color('#hex')` syntax which Rich doesn't support. Fixed to `#c9a227` in `app.py:531`. (Same bug class as Phase 16 UA issue #3.)
3. Polish phase: Keyboard navigation in quit modal: pressing arrow keys doesn't move selection between Cancel and Quit buttons.
4. Polish: Once the command input is defocused (Escape), there is no keyboard shortcut to return focus to it — requires mouse click.
5. Two missions with the same thematic title "The Testing Grounds" (different `title_plain` values). LLM collision, probabilistic — hard to prevent entirely, but would prefer this doesn't happen since it appears to be a mistake.
6. New bug noticed: Unfamiliar is adding lots of repos to the `~/.unfamiliar/campaigns` directory that the user hasn't added.
7. Command reference: "Commands" header should be larger or otherwise differentiated from the rest of the commands. This can be deferred to polish phase
8. Need a means of re-opening a closed case. `unfamiliar resume` is for picking up the last case, but there's no way to reopen a case that's been closed. This can also be deferred to the polish phase.

### Error Messages / Logs:

```
# Crash 1 (fixed)
TypeError: CampaignRepository.update() got an unexpected keyword argument 'status'
  at app.py:520 in _close_campaign()

# Crash 2 (fixed)
MissingStyle: Failed to get style "bold color('#c9a227')"; unable to parse "color('#c9a227')" as color
  at app.py:531 in _close_campaign() → show_text() → _clear_and_set()
```

### Questions:

*(none)*

### General Feedback:

TUI theming and vocabulary are working correctly. Film Noir language appears consistently across all screens. In-progress mission resumption works. The crash on close campaign was the only blocker and has been fixed inline.

### Result:

- [x] All good — ready to proceed
- [x] Issues found — see Follow-up Items below

---

## Follow-up Items

| # | Issue | Priority |
|---|-------|----------|
| 1 | ~~Close campaign crash — wrong repo method~~ | ~~Blocker~~ → **Fixed** |
| 2 | Modal keyboard navigation (arrow keys don't move button focus) | **Deferred** → polish phase |
| 3 | No keyboard shortcut to re-focus command input after Escape | **Deferred** → polish phase |
| 4 | Duplicate thematic mission titles from LLM (probabilistic) | **Deferred** → low priority |
| 5 | Spurious campaign directories being created | **Deferred** → investigate |
| 6 | Command reference header styling | **Deferred** → polish phase |
| 7 | Re-open closed case functionality | **Deferred** → polish phase |

---

## Phase Closure

**Date:** 2026-03-19
**Status:** Complete
**Result:** Approved — ready for Phase 19
