# Coach V2 Launch UI/UX Readiness

## Goal

Complete launch-readiness work items 1–3 for Coach V2 Telegram nutrition
surfaces. Verify buttons, labels, state transitions, error guidance, and
compact mobile rendering; make only the smallest launch-blocking UI/UX fixes.
The user owns item 4: subjective real-phone review.

## Constraints

- Work in the existing shared dirty worktree:
  `/home/cube/projects/richard/hermes-agent`.
- Do not reset, stash, clean, commit, or push.
- Do not call a live provider/customer, send Telegram messages, or enable
  delivery.
- Preserve unrelated dirty changes.
- Use deterministic local provider and transport doubles only.
- Every behavior edit requires RED before production changes and GREEN after.

## Success Criteria

### Functional button and state QA

Run:

```bash
cd /home/cube/projects/richard/hermes-agent
.venv/bin/pytest -q -p no:cacheprovider \
  tests/gateway/test_telegram_nutrition_onboarding.py \
  tests/gateway/test_nutrition_coaching.py \
  tests/gateway/test_adaptive_nutrition.py \
  -k 'operator_card or callback or coach_v2 or approve or edit or hold or regenerate or stale'
```

PASS when pending, edited, approved, and held states expose only legal
controls; callbacks work; stale, replayed, wrong-actor, and wrong-route actions
fail closed; and preapproval customer sends remain zero.

Evidence:

- `/tmp/ulw-coach-uiux-evidence/button-state-baseline.txt`
- `/tmp/ulw-coach-uiux-evidence/red-mobile-button-rows.txt`
- `/tmp/ulw-coach-uiux-evidence/green-mobile-button-rows.txt`
- `/tmp/ulw-coach-uiux-evidence/button-state-tests.txt`

### Deterministic Telegram surface QA

Run:

```bash
cd /home/cube/projects/richard/hermes-agent
.venv/bin/python /tmp/ulw_coach_uiux_qa.py \
  | tee /tmp/ulw-coach-uiux-evidence/telegram-surface.txt
```

PASS when the production renderer and callback/lifecycle seams report:

- `pending_controls=pass`
- `edited_reapproval=pass`
- `approved_publication=pass`
- `held_delivery_blocked=pass`
- `stale_action_guidance=pass`
- `unauthorized_action_blocked=pass`
- `mobile_button_rows=pass`
- `customer_free_text_ai_replies=0`
- `trainer_internal_only=pass`
- `cleanup=pass`

Evidence:

- `/tmp/ulw-coach-uiux-evidence/telegram-surface-red.txt`
- `/tmp/ulw-coach-uiux-evidence/telegram-surface.txt`

### Regression and static integrity

Run Ruff, compileall, and `git diff --check`, then run the full gateway suite.

PASS when all commands exit 0 and no unrelated regression appears.

Evidence:

- `/tmp/ulw-coach-uiux-evidence/static.txt`
- `/tmp/ulw-coach-uiux-evidence/full-gateway.txt`

### Cleanup and handoff

Remove `/tmp/ulw_coach_uiux_qa.py` and every QA-only process, session, and
port. Retain the evidence directory. Record proof that no live delivery or
provider activity occurred. Give the user a concise 5–10 minute real-phone
checklist for item 4.

Evidence:

- `/tmp/ulw-coach-uiux-evidence/cleanup.txt`

## Ordered Work

1. Inventory production card states and legal controls.
2. Map authorization, stale, replay, and wrong-route callback coverage.
3. Capture the unchanged focused baseline.
4. Build and run the deterministic local Telegram surface driver.
5. Capture each confirmed defect through a focused RED test.
6. Implement the smallest production fix.
7. Capture focused GREEN and final surface evidence.
8. Run focused, static, and full gateway verification once final inputs settle.
9. Obtain unconditional Momus approval.
10. Remove QA artifacts and record cleanup.
11. Audit every criterion and complete the registered goal.

## Current Verified Delta

The initial surface driver showed all functional and authorization checks
passing, with only mobile grouping failing:

```text
pending_button_grid=[['수정', '재생성', '승인', '보류']]
mobile_button_rows=fail
```

The focused integration test failed on that exact row mismatch before the
production edit. The smallest fix changed only
`TelegramAdapter._nutrition_draft_markup` so pending and edited controls render
as:

```text
[['수정', '재생성'], ['승인', '보류']]
```

Callback data, authorization, state policy, approved controls, held controls,
and delivery behavior are unchanged.

Current evidence:

- Focused suite: `93 passed, 221 deselected`
- Production surface: all named observables PASS
- Ruff, compileall, and diff check: PASS
- Full gateway: `8018 passed, 59 skipped`

## Stop Condition

Stop immediately when all success criteria pass, cleanup is proven, and Momus
returns unconditional approval; otherwise stop at an exact criterion-cited
blocker.
