# P5 Full Test Guide — Master (LLMHosts.com + External Alienware)

**This is the single source of truth for P5 testing.** All other test docs in `docs/testing/` point here. Keeps app, code, and testing objectives in sync; failures spawn GitHub issues and we loop until all pass.

- **Issue:** [#255](https://github.com/LookNoHandsMom/LLMHosts.com/issues/255) (P0-blocker)
- **Runners:** AI (browser + terminal) or human — including **external AI devs** (see Audience below)
- **Output:** Datetime-stamped recap (Part C) + **unresolved issues** + **suggestions**; failures → GitHub issue → fix → re-run → repeat until 100% confidence

---

## Quality bar and audience

**Quality bar:** The product must **"just work, masterfully"** for users every time. This test proves and defends that. Any friction or failure is a bug or doc gap; we fix and re-run until 100% confidence. Over time, run the same battery on different hosts (Alienware first, then e.g. Mac Mini, other OS/setup) to cover configuration and platform diversity.

**Audience (including external AI dev):** Instructions are written so that an **external AI or human** with **web access** (llmhosts.com) and **full machine access** (terminal, browser, ability to install and run commands) can:
- Follow every step by **Step ID** without ambiguity
- Run commands exactly as written (substituting only placeholders like `<TUNNEL_URL>`, `<MODEL>`, `<API_KEY>`)
- Record **Pass/Fail** and **Actual** (exact output or error) for each step
- Produce the **recap document** (Part C) and the **report-back** (unresolved issues + suggestions)
- So the **project owner** can share that report back with the development agent to fix unresolved issues and consider suggestions until the experience is "it just works, masterfully" every time.

**Assumptions:** Runner has access to: https://llmhosts.com (browser), the Alienware laptop (terminal + browser), and optionally another host machine; credentials (password, API key) from secure storage when needed; ability to create GitHub issues and commit/push recap files if requested.

---

## Testing objectives (what we prove)

- **Site readiness:** LLMHosts.com (SaaS) is up; test account can log in; plan is correct; dashboard routes (Overview, Settings, API Keys, Devices, Topology, Marketplace, etc.) load and behave per app.
- **External client (Scenario A):** A machine on an external network (Alienware on neighbor WiFi/hotspot) can call a host’s tunnel URL and get health, models, and completions (streaming and non-streaming, latency, reconnect, sequential/concurrent, large context).
- **External host (Scenario B):** The Alienware as LLMHosts host (Ollama + serve + tunnel) is reachable via its tunnel URL and serves inference on its GPU.
- **Cross-check:** Dashboard (Topology, Devices, Marketplace) reflects state consistent with the test when the proxy reports to llmhosts.com.
- **User journey:** Login → account/plan → API keys → devices/topology/marketplace and external API usage are coherent end-to-end.

---

## Host configuration (different configs, full scenario coverage)

The **host** (machine running `llmhosts serve` + `llmhosts tunnel start`) can have different inference backends or none. The proxy discovers backends automatically (see `llmhosts/discovery/scanner.py`: Ollama, vLLM, LM Studio, llama.cpp, LocalAI, TGI, generic OpenAI). Completions only work if at least one backend or BYOK cloud is available.

| Host profile | What the host has | What to validate | Scenario A (client calls host) | Scenario B (Alienware as host) |
|--------------|-------------------|------------------|--------------------------------|---------------------------------|
| **Ollama** | Ollama on default port (11434), ≥1 model | `ollama list`; `llmhosts doctor` shows Ollama PASS | Use a model from `GET /v1/models` (Ollama model id) for completions | Alienware must have Ollama (or another backend) for B.2 |
| **Other local** | vLLM (8000), LM Studio (1234), llama.cpp (8080), LocalAI (8080), TGI (8080), or generic OpenAI-compat | Proxy discovers on serve; `GET /v1/models` returns list | Use a model id from that list for completions | Alienware must have at least one such backend for B.2 |
| **Cloud only (BYOK)** | No local inference; BYOK keys configured | `GET /v1/models` may list cloud models; completions route to cloud | Completions work if cloud models returned; latency may differ | N/A for "Alienware as host" unless Alienware has local or cloud |
| **None / unprovisioned** | No local engine, no BYOK | `GET /v1/models` empty or error; completions fail | Health and models (empty) only; completion steps fail (expected) | B.2 requires Alienware to have at least one backend |

**Phase 0 (Host discovery)** — Before Part B, on **each** machine that will act as host:
1. Run `llmhosts doctor` (or start `llmhosts serve` and check startup output) to see what was discovered (Ollama, vLLM, etc., or "No backends").
2. If the host has no inference and no BYOK, Scenario A completion steps (B.1.4–B.1.9) will fail unless you add a backend or BYOK; Scenario B requires the Alienware to have a backend. Record the **Host profile** (e.g. "Ollama, 3 models" / "vLLM:8000" / "Cloud only" / "None") in the recap so we have full scenario coverage and no assumed config.
3. **Branch:** For B.0.1 / B.2.1 use the appropriate check: `ollama list` if Ollama, or confirm the proxy’s `/v1/models` returns ≥1 model for the host you are testing. For completion steps, use a **model id** from `GET /v1/models` on that host (Ollama name, vLLM id, or cloud model).

**OS and environment:** The host may be Windows, macOS, or Linux; commands in this guide use `curl` and shell. On Windows use PowerShell or WSL and equivalent (e.g. `Invoke-RestMethod` or `curl.exe`). Record **OS** and **stack** (e.g. "Windows 11, Ollama 0.3") in the recap so subsequent campaigns (e.g. Mac Mini) can be compared.

---

## Campaign strategy: Alienware-first, then broader coverage

**First campaign (Alienware as primary host):** Use the **Alienware laptop** as the main host for this guide. Goal: validate and confirm everything on this machine; fix any failure (create issue, fix, re-run) until **100% pass** on Part A and Part B. Record Alienware’s **Host profile** (OS, GPU, Ollama or other backend, tunnel provider). This gives a baseline "it just works" on one real setup.

**Subsequent campaigns:** Run the **same** guide on different hosts (e.g. **Mac Mini** — different OS, different setup). Each run: record **Host profile** (machine, OS, inference stack), run Part A + Part B (and Phase 0 discovery), produce recap + unresolved issues + suggestions. Over time we cover multiple configs and platforms; any regression or platform-specific bug shows up and is fixed. No change to the steps — only the host and the recorded profile change.

---

## Base URL and credentials (canonical)

**Never commit passwords or API keys.** Store in secure storage (e.g. 1Password, env vars, or prompt at run time).

| Item | Value | Source / notes |
|------|--------|-----------------|
| **Site (production)** | `https://llmhosts.com` | Canonical; matches `NEXTAUTH_URL` in production. |
| **Site (local dev)** | `http://localhost:3000` | When testing against local frontend; set `NEXTAUTH_URL` and `NEXT_PUBLIC_APP_URL` accordingly. |
| **Test account email** | `brendonurban@gmail.com` | Primary test account for P5. |
| **Test account password** | *(not stored in repo)* | From secure storage only. Use when prompted at login. |
| **API key (proxy auth)** | *(not stored in repo)* | After login: **Dashboard → API Keys** (https://llmhosts.com/dashboard/keys). Create or copy a key; use as `Authorization: Bearer <key>` when proxy returns 401. |
| **Tunnel URL (host)** | e.g. `https://<hostname>.ts.net` or Cloudflare URL | From `llmhosts tunnel start` on the host machine. |
| **Tunnel URL (Alienware)** | Same format | From `llmhosts tunnel start` on the Alienware when it is the host (Scenario B). |

**Login flow (app):** Open base URL → if not logged in, redirect to `/auth/login` → submit email + password (from secure storage) → on success redirect to `/dashboard`.

---

## Dashboard URLs (canonical — matches `DashboardLayoutClient`)

All paths are relative to base URL (production: `https://llmhosts.com`).

| Route | Full URL (production) | Purpose |
|-------|------------------------|---------|
| Landing | https://llmhosts.com | Home; redirects to login or dashboard. |
| Login | https://llmhosts.com/auth/login | Email + password. |
| Register | https://llmhosts.com/auth/register | Sign up. |
| Forgot password | https://llmhosts.com/auth/forgot-password | Reset flow. |
| Dashboard (Overview) | https://llmhosts.com/dashboard | Main dashboard. |
| Spending | https://llmhosts.com/dashboard/spending | Cost entries. |
| Savings | https://llmhosts.com/dashboard/savings | Savings view. |
| Add Entry | https://llmhosts.com/dashboard/add | Add cost entry. |
| Projections | https://llmhosts.com/dashboard/projections | Projections. |
| Achievements | https://llmhosts.com/dashboard/achievements | Achievements. |
| API Keys | https://llmhosts.com/dashboard/keys | List/create API keys for proxy auth. |
| Cache | https://llmhosts.com/dashboard/cache | Cache stats. |
| Feedback | https://llmhosts.com/dashboard/feedback | Feedback. |
| Topology | https://llmhosts.com/dashboard/topology | Backends/nodes (from proxy when configured). |
| Devices | https://llmhosts.com/dashboard/devices | Registered devices; marketplace opt-in. |
| Marketplace | https://llmhosts.com/dashboard/marketplace | Usage, credits (Phase 5). |
| LAN Nodes | https://llmhosts.com/dashboard/lan-nodes | LAN discovery. |
| Token | https://llmhosts.com/dashboard/token | Token AI. |
| Team | https://llmhosts.com/dashboard/team | Team. |
| Settings | https://llmhosts.com/dashboard/settings | Account, plan, billing (Stripe portal from here). |

Plan is also shown in the dashboard sidebar (footer “Current Plan”); upgrade links to `/dashboard/settings`.

---

## Failure handling loop (until all pass)

1. **On any step failure:** Do not continue the battery as if it passed. Record: Step ID, Expected, Actual, timestamp (UTC), and environment (tunnel URL, which machine, browser/terminal).
2. **Create a GitHub issue:** Title: `[P5] <short description>` (e.g. `[P5] Dashboard Topology returns 500`). Body (minimal):
   - **Step ID:** (e.g. A.3.4)
   - **Expected:** (from this guide)
   - **Actual:** (response body, status code, or screenshot)
   - **Run:** (recap file name or date)
   - **Environment:** base URL, tunnel URL if relevant
3. **Fix:** Implement or configure fix; link PR to the issue.
4. **Re-run:** From the failed step (or from the start of the part that failed). Re-use this guide and the same recap format.
5. **Update docs:** If the app or flow changed (e.g. new route, new step), update this guide and any referenced runbook/checklist so they stay in sync.
6. **Repeat** until Part A and Part B (and optional C) all pass, then close #255 and archive the recap.

---

# Part A — LLMHosts.com site prep and readiness

Use **production** base URL unless you are testing local dev (then use `http://localhost:3000` and the same paths below).

## A.1 — Log in and account identity

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| A.1.1 | Browser | Open **https://llmhosts.com** (or local base URL). | Site loads; if unauthenticated, redirect to login. | Pass/Fail |
| A.1.2 | Browser | Go to **https://llmhosts.com/auth/login**. Enter email **brendonurban@gmail.com** and password (from secure storage). Submit. | Login succeeds; redirect to **https://llmhosts.com/dashboard**. | Pass/Fail |
| A.1.3 | Browser | In dashboard sidebar (footer), confirm **email** and **name** shown. | Matches test account. | Email: … Name: … |

## A.2 — Account type and plan

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| A.2.1 | Browser | Open **https://llmhosts.com/dashboard/settings**. | Settings page loads. | Pass/Fail |
| A.2.2 | Browser | In Settings, find **Plan** (Free / Pro / Team / Enterprise). Sidebar also shows “Current Plan”. | Plan displayed and correct for test account. | Plan: … |
| A.2.3 | Browser | Confirm email/name in Settings match A.1.3. | Consistent. | Pass/Fail |
| A.2.4 | Browser | If paid plan: use “Manage billing” / Stripe portal from Settings. Confirm subscription active. | Portal loads; status correct. | Pass/Fail / N/A |
| A.2.5 | Browser | If testing marketplace: open **https://llmhosts.com/dashboard/marketplace**. Confirm page and (if applicable) credits/usage. | Visible and correct for plan. | Pass/Fail / N/A |

## A.3 — Dashboard health and capabilities

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| A.3.1 | Browser | **https://llmhosts.com/dashboard** (Overview). | Overview loads; no critical console errors (F12). | Pass/Fail |
| A.3.2 | Browser | **https://llmhosts.com/dashboard/keys** (API Keys). | Page loads; can list/create keys. Create one if needed for Part B (proxy auth). | Pass/Fail |
| A.3.3 | Browser | **https://llmhosts.com/dashboard/devices**. | Page loads; 0+ devices; no 5xx. | Pass/Fail; device count: … |
| A.3.4 | Browser | **https://llmhosts.com/dashboard/topology**. | Page loads; empty or nodes; no 5xx. | Pass/Fail; what you see: … |
| A.3.5 | Browser | **https://llmhosts.com/dashboard/marketplace**. | Page loads; no 5xx. | Pass/Fail |
| A.3.6 | Browser | Optional: **Spending**, **Savings**, **Add Entry**, **Projections**, **Achievements** (see Dashboard URLs table). Each loads. | No 5xx or broken layout. | Pass/Fail (or skip) |

## A.4 — Readiness summary (Part A)

| Item | Ready? | Notes |
|------|--------|-------|
| Logged in (brendonurban@gmail.com) | Y/N | |
| Account / plan correct | Y/N | |
| API Keys page works | Y/N | |
| Devices page works | Y/N | |
| Topology page works | Y/N | |
| Marketplace works | Y/N / N/A | |
| No blocking console errors | Y/N | |

**Part A done.** If any step failed, follow **Failure handling loop** (create issue, fix, re-run). Then proceed to Part B.

---

# Part B — Full testing battery from external Alienware

**Where** = Browser | Alienware (terminal) | Host machine (terminal). **Host** = machine running `llmhosts serve` + `llmhosts tunnel start` for Scenario A.

## Phase 0 — Host discovery (do first; record in recap)

On **each** machine that will act as host (for Scenario A: the "other" host; for Scenario B: the Alienware), determine and record its **Host profile** so tests branch correctly and we get full scenario coverage.

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| P0.1 | Host (terminal) | Run `llmhosts doctor`. If not installed yet, install LLMHosts and run it. | Output shows: Ollama and/or other backends, or "No backends" / warnings. | **Host profile:** e.g. "Ollama, 3 models" / "vLLM:8000" / "Cloud only" / "None". Note OS and GPU if shown. |
| P0.2 | Host (terminal) | If Ollama may be present: `ollama list` (or equivalent for other engines). If nothing local, skip. | Either list of models or "Ollama not running" / N/A. | Model names or "none" for this host. |
| P0.3 | — | Decide: This host has **inference** (local and/or cloud) so completions can succeed, or **no inference** (completion steps will fail until backend added). | Clear decision for branching. | Inference: Y / N. |

Record **Host profile** and **Inference (Y/N)** in the recap for each host used. Use a **model id** from `GET <TUNNEL_URL>/v1/models` for any completion step (B.1.4, B.1.5, B.2.4, etc.); that works for Ollama, vLLM, LM Studio, or cloud models.

## B.0 — Get a tunnel URL (if needed)

**Skip if** you already have a host tunnel URL. Otherwise on the **host** machine:

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| B.0.1 | Host (terminal) | Confirm at least one inference backend or BYOK so completions can succeed: run `llmhosts doctor` or start `llmhosts serve` and check startup; if Ollama, `ollama list`; if other (vLLM, LM Studio, etc.), ensure that service is running. | Either ≥1 local model/backend or BYOK cloud. If none, note "Host has no inference" — completion steps will fail until added. | Pass/Fail; backend(s): … |
| B.0.2 | Host (terminal) | `llmhosts serve` or `llmhosts serve --no-tui`. Leave running. | Process up. | Pass/Fail |
| B.0.3 | Host (second terminal) | `llmhosts tunnel start`. Wait for URL. | e.g. `https://….ts.net`. | **TUNNEL_URL (host):** … |
| B.0.4 | Host (terminal) | `curl -s "<TUNNEL_URL>/health"` or with auth: `curl -s -H "Authorization: Bearer <API_KEY>" "<TUNNEL_URL>/health"`. | 200, `"status":"ok"`. | Pass/Fail |
| B.0.5 | Host (terminal) | `curl -s "<TUNNEL_URL>/v1/models"` (add `-H "Authorization: Bearer <API_KEY>"` if 401). | 200, `"data":[...]` (≥1 model for completions) or `[]`. | Pass/Fail; one **model id** to use in B.1.4/B.1.5: … |

## B.1 — Scenario A: Alienware as client only

Alienware **does not** run serve/tunnel; it **calls** the host’s TUNNEL_URL from an **external** network. Replace `<TUNNEL_URL>` and `<API_KEY>` (only if proxy requires auth).

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| B.1.1 | Alienware (terminal) | Connect to neighbor WiFi or hotspot. `curl -s ifconfig.me` on Alienware; same on host. | Different IPs if two machines. | Alienware IP: … Host IP: … Pass/Fail |
| B.1.2 | Alienware (terminal) | `curl -s "<TUNNEL_URL>/health"` (add `-H "Authorization: Bearer <API_KEY>"` if 401). | 200, `"status":"ok"`. | Pass/Fail |
| B.1.3 | Alienware (terminal) | `curl -s "<TUNNEL_URL>/v1/models"` (auth if 401). | 200, model list (may be from Ollama, vLLM, cloud, etc.). | Pass/Fail; one **model id** for next steps: … |
| B.1.4 | Alienware (terminal) | `curl -s -X POST "<TUNNEL_URL>/v1/chat/completions" -H "Content-Type: application/json" -d '{"model":"<MODEL>","messages":[{"role":"user","content":"Say hello in one word."}]}'` (add `-H "Authorization: Bearer <API_KEY>"` if 401). Use `<MODEL>` = one model id from B.1.3 (or B.0.5). Skip if host has no inference (profile "None"). | 200, `choices[0].message.content`. | Pass/Fail / Skip (no inference) |
| B.1.5 | Alienware (terminal) | Same as B.1.4 with `"stream":true` in JSON. | Chunks received. | Pass/Fail |
| B.1.6 | Alienware (terminal) | Time one completion (e.g. `time curl -s -X POST ...`). | &lt; 10 s. | Latency: … s Pass/Fail |
| B.1.7 | Alienware (terminal) | Disconnect network; retry (expect fail). Reconnect; retry (expect success). | Fail then success. | Pass/Fail |
| B.1.8 | Alienware (terminal) | 5 sequential then 3 concurrent completion requests. | All succeed. | Pass/Fail |
| B.1.9 | Alienware (terminal) | One request with long prompt (2000+ tokens). | 200, completion. | Pass/Fail |

**Note:** If the host has **no inference** (Phase 0: Inference N), steps B.1.4–B.1.9 cannot succeed; mark them **Skip** and note in recap. All other B.1 steps still validate tunnel and external reachability.

## B.2 — Scenario B: Alienware as LLMHosts host

Alienware runs **at least one inference backend** (Ollama, vLLM, LM Studio, etc.) + serve + tunnel; gets its **own** tunnel URL. Call that URL to run inference on Alienware. If Alienware has no backend, B.2.4/B.2.5 fail until one is added (record in recap).

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| B.2.1 | Alienware (terminal) | Ensure one inference backend is available: e.g. `ollama serve` and `ollama list`, or start vLLM/LM Studio/etc. per host profile. | ≥1 model available (Ollama or other). | Pass/Fail; backend: … |
| B.2.2 | Alienware (terminal) | `llmhosts doctor`. | Backend(s) and GPU/hardware reported (e.g. Ollama PASS, 4090). | Pass/Fail |
| B.2.3 | Alienware (terminal) | `llmhosts serve` or `llmhosts serve --no-tui`. Second terminal: `llmhosts tunnel start`. Note URL. | Tunnel URL printed. | **TUNNEL_URL (Alienware):** … |
| B.2.4 | Any machine | `curl -s "<ALIENWARE_TUNNEL_URL>/v1/models"` to get a model id; then `curl -s -X POST "<ALIENWARE_TUNNEL_URL>/v1/chat/completions" -H "Content-Type: application/json" -d '{"model":"<MODEL>","messages":[{"role":"user","content":"Hello"}]}'` with that model. | 200, completion from Alienware. | Pass/Fail |
| B.2.5 | Same | Request with `"stream":true`; then disconnect Alienware network briefly, retry, reconnect, retry. | Stream works; reconnect works. | Pass/Fail |

## B.3 — Cross-check in LLMHosts.com (browser)

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| B.3.1 | Browser | **https://llmhosts.com/dashboard/topology**. | Loads; backends/nodes or empty; no 5xx. | Pass/Fail; what you see: … |
| B.3.2 | Browser | **https://llmhosts.com/dashboard/devices**. | Alienware or host may appear if registered; no 5xx. | Pass/Fail; devices: … |
| B.3.3 | Browser | **https://llmhosts.com/dashboard/marketplace**. | Usage/credits consistent if applicable. | Pass/Fail / N/A |

## B.4 — Scenario C (optional): full loop

| Step ID | Where | Action | Expected | Record |
|---------|--------|--------|----------|--------|
| B.4.1 | Alienware + host | Alienware (client) → host URL; and another caller → Alienware URL. At least one full loop. | Both directions work. | Pass/Fail / Skipped |

**Part B done.** Any failure → **Failure handling loop** (issue, fix, re-run). Then do Part C.

---

# Part C — Recap document and report-back (for project owner and dev agent)

## C.1 — Data to capture

- **Environment:** Run date/time (UTC), runner (Human/AI), **Host profile(s)** from Phase 0 (e.g. Alienware: "Ollama, 3 models, Windows 11"; other host: "vLLM:8000, Linux"), Alienware OS and public IP, host description and IP, tunnel URLs (host and Alienware if B ran), tunnel provider.
- **Phase 0:** For each host: Host profile, Inference (Y/N), model ids used.
- **Part A:** Account email (brendonurban@gmail.com), plan, A.4 table, any A failure (step ID, what happened).
- **Part B:** P0.1–P0.3, B.0–B.4 pass/fail per step; latency (B.1.6); any failure (step ID, command, full error, timestamp UTC).
- **Summary:** Overall (All passed / Partial / Blocked), what worked / what didn’t (2–4 sentences), suggested next step.
- **Unresolved issues:** For each failure that was **not** fixed in this run: Step ID, what was tried, suggested fix (so project owner can hand to dev agent).
- **Suggestions:** Improvement, optimization, or transformative UX ideas (so project owner can report back and we improve toward "it just works, masterfully" every time).

## C.2 — Create and share recap file

1. **Filename:** `docs/testing/P5-test-run-YYYY-MM-DDTHHmmss.md` (e.g. `P5-test-run-2026-02-27T140530.md`).
2. **Contents:** Use the template in C.3; fill all bracketed parts, including **Unresolved issues** and **Suggestions**.
3. **Share:** Paste full contents into a comment on **GitHub issue #255**, or commit the file and give the path, or paste into chat. This spawns the datetime-based recap for that run.
4. **Report-back to project owner:** The report is intended for the **project owner** to share with the **development agent**. The agent should: fix all **Unresolved issues** (create/use GitHub issues, implement fix, re-run from failed step); consider **Suggestions** for improvement/optimization/transformative UX; update this guide if steps or behavior changed; repeat until 100% confidence — "it just works, masterfully" every time.

## C.3 — Copy-paste recap template

```markdown
# P5 Test Run — YYYY-MM-DD HH:MM UTC

## Environment
- **Run date (UTC):** YYYY-MM-DD
- **Run time (UTC):** HH:MM
- **Runner:** Human / AI
- **Campaign:** [e.g. Alienware-first / Mac Mini / ...]
- **Alienware:** [OS], public IP [from B.1.1], Host profile (Phase 0): [e.g. Ollama, 3 models]
- **Host machine (if different):** [description], public IP [from B.1.1], Host profile: [e.g. vLLM:8000 / None]
- **Tunnel URL (host):** [from B.0.3 or existing]
- **Tunnel URL (Alienware):** [from B.2.3 or N/A]
- **Tunnel provider:** Tailscale / Cloudflare

## Phase 0 — Host discovery
- **Host(s) profile:** [paste P0.1/P0.2/P0.3 results; Inference Y/N per host]

## Part A — LLMHosts.com readiness
- **Account email:** brendonurban@gmail.com
- **Plan:** Free / Pro / Team / Enterprise
- **Readiness:** [paste A.4 table with Y/N and notes]
- **Part A failures:** [step ID, what happened; or "None"]

## Part B — External battery
- **B.0:** Skipped / Done. [Pass/Fail per step if done]
- **B.1 (Scenario A):** [Pass/Fail for B.1.1–B.1.9]; latency [value] s
- **B.2 (Scenario B):** [Pass/Fail for B.2.1–B.2.5]
- **B.3:** [Pass/Fail; what Topology/Devices showed]
- **B.4 (Scenario C):** Pass / Fail / Skipped
- **Part B failures:** [step ID, command, full error, timestamp; or "None"]

## Summary
- **Overall:** All passed / Partial / Blocked
- **What worked / what didn't:** [2–4 sentences]
- **Suggested next step:** [e.g. "Close #255" or "Fix issue #NNN and re-run from step X"]

## Unresolved issues (for dev agent)
List each failure that was not resolved in this run. For each:
- **Step ID:** (e.g. A.3.4)
- **What was tried:** [brief]
- **Suggested fix:** [so dev agent can implement]

(If none: "None.")

## Suggestions (improvement / optimization / transformative UX)
List any ideas to make the product "just work, masterfully" for users. Examples: clearer error messages, one-click setup, better docs, UI tweaks.

(If none: "None.")
```

---

## Quick reference — URLs and API

| What | URL or command |
|------|-----------------|
| Phase 0 (discovery) | On host: `llmhosts doctor`; `ollama list` if Ollama. Record Host profile. |
| Production site | https://llmhosts.com |
| Login | https://llmhosts.com/auth/login |
| Dashboard | https://llmhosts.com/dashboard |
| Settings | https://llmhosts.com/dashboard/settings |
| API Keys | https://llmhosts.com/dashboard/keys |
| Devices | https://llmhosts.com/dashboard/devices |
| Topology | https://llmhosts.com/dashboard/topology |
| Marketplace | https://llmhosts.com/dashboard/marketplace |
| Proxy health | `GET <TUNNEL_URL>/health` |
| Proxy models | `GET <TUNNEL_URL>/v1/models` |
| Proxy completion | `POST <TUNNEL_URL>/v1/chat/completions` |
| Issue #255 | https://github.com/LookNoHandsMom/LLMHosts.com/issues/255 |

---

## Doc hierarchy (no conflicting legacy)

| Doc | Role |
|-----|------|
| **docs/testing/P5-full-test-guide.md** | **Master.** Part A (site) + Part B (battery) + Part C (recap) + credentials + URLs + failure loop. Single source of truth. |
| docs/testing/P5-external-connectivity-runbook.md | Expanded scenario reference and codebase refs; points to master guide for execution and recap. |
| docs/testing/P5-external-connectivity-human-checklist.md | Abbreviated Alienware-only flow; points to master guide for site prep, full battery, and recap. |
| docs/testing/P5-external-connectivity-results-template.md | Optional per-step log; recap format is in master guide C.2/C.3. |

All test runs and recap documents use the master guide; any change to steps or URLs is made here first, then other docs updated if they duplicate those steps.

**OS note:** Commands are written for a Unix-style shell (`curl`, etc.). On **Windows** use PowerShell or WSL: e.g. `curl.exe` or `Invoke-RestMethod` with equivalent args. Record **OS** in the recap so multi-platform coverage (Alienware, Mac Mini, etc.) is explicit.
