Files
BT411/context/playtest-tracker.md
T

131 lines
7.3 KiB
Markdown

---
id: playtest-tracker
title: "The playtest tracker sheet — the tester-facing issue board"
status: living
source_sections: "Established 2026-08-14/15 (session housekeeping); supersedes the .txt handout as the primary feedback channel"
related_topics: [operator-console, test-harness, project-overview]
key_terms: [gitea, tracker, playtest]
open_questions:
- "Should the OPEN tab auto-sync from gitea on a schedule, or stay a manual reconciliation before/after each playtest?"
---
# The playtest tracker sheet
Since **2026-08-14** the testers track issues in a shared Google Sheet instead of the annotated
`docs/OPEN_ISSUES_FOR_TESTERS.txt` handout. It is now the **primary feedback channel**; edited
.txt docs and pasted Discord logs are secondary ([[operator-console]] covers the session tooling
itself). The sheet is the testers' INPUT surface; **gitea remains the system of record.**
## Shape
Two tabs. Sheet ID and the write-bridge credentials live in the operator's local Claude memory
(`feedback-channels`), **never in this repo** — the bridge URL + token together grant write
access to the sheet.
- **OPEN** — `# | Priority | Test Status | Dev Status | Dev Comments | Tester Comments`,
ONE row per ticket, sorted by priority then ticket number.
- **CLOSED** — the same minus Priority, ascending by number. Also holds non-ticket records
(completed audits) under a text key like `AUDIT`.
**The split is driven by GITEA STATE, not by the Dev Status column** — the two drift constantly,
and the sheet's own column is the stale one.
## Dev Status vocabulary (dev-owned column)
The colour is **embedded in the label**, not applied as a cell fill:
| Label | Meaning |
|---|---|
| `🟡 PATCHED - RETEST` | code landed, needs a playtest to confirm — the testers' retest list |
| `🔴 FAILED RETEST` | a shipped fix did **not** hold; back on the bench (never collapse this into QUEUED — it understates a regression as "not started") |
| `🟠 NEED INFO` | blocked on testers for a repro, detail, or log |
| `🔵 YOUR CALL` | not a code question; needs their opinion or era memory |
| `⚪ QUEUED` | logged and understood, work not started |
| `🟢 WORKING` | actively being worked right now |
| `✅ DONE` | verified — **only ever appears on CLOSED** |
Priority: **P1** blocks a session / hits everyone · **P2** gameplay correctness confirmed in the
field · **P3** presentation and polish · **P4** era question or opinion call · **P5** latent or
internal with no field impact.
Test Status is TESTER-owned (`Pass` / `Fail` / `Test` = not yet retested / `Rework` / `Clarify`).
A **Fail on a ticket gitea has closed** is the highest-value signal in the whole sheet — it means
a shipped fix did not hold, or the tested build predated it.
## The Dev Comments contract
That column is what a player reads, so it is written for a player, in three lines:
```
<one sentence: what is wrong, or what changed if patched>
STATUS: <where it actually stands>
NEED FROM YOU: <a concrete, specific ask> <- omit for QUEUED
```
Under ~55 words, no addresses, no engine jargon. The ask must name what to capture (which mech,
which map, what time, what you expected vs saw, the boot-screen build number) — never "let us
know if it happens again". If the thread already answers it, do not ask again.
## Working rules (learned the hard way)
- **Read the gitea COMMENT THREAD, never the body alone.** Bodies are original reports and are
routinely superseded, retracted, or already fixed by comment 4. Triaging 53 tickets from
threads moved a third of the statuses and dropped P1 from 5 to 2. See
[[reconstruction-gotchas]] for the general form of this mistake.
- **Undated tester rows are historical.** Only rows explicitly prefixed with a date (`8/14 - `)
came from that session. Reading undated carried-forward rows as fresh evidence produced a false
"still crashing after the fix" report on #170 that had to be retracted across seven tickets.
Ask testers to date entries.
- **Never write `DONE` on OPEN.** A row that is done belongs on CLOSED; a `DONE` on the open page
is a contradiction that confuses everyone reading it.
- **Merge duplicates to one row per ticket** — linking loose reports to existing tickets creates
two rows for the same number otherwise.
- **Never use cell fills for status.** Fills belong to cells, labels to text; every re-sort moves
the text and leaves the paint, so they desync. This was re-fixed three times before the colour
was embedded in the label.
- **A leftover FILTER hides rows after a rewrite** — if rows appear to vanish and the row numbers
in the gutter SKIP, that is hidden rows, not lost data (Data → Remove filter).
- **Row heights**: autofit makes wrapped comment rows hundreds of pixels tall (≈4 visible rows).
Pin to ~63 px.
## The cycle
1. **Before a playtest** — regenerate/refresh: reconcile every row against gitea, clear stale
statuses, make sure each `NEED INFO` carries an ask the testers can act on that night.
2. **After a playtest — THE SWEEP.** Read the sheet, file the unfiled `New` rows as tickets, link
duplicates to existing numbers, post the field evidence onto the tickets, then resolve every
`🟡 PATCHED - RETEST` row by what the tester wrote in Test Status:
| Test Status | Meaning | Action |
|---|---|---|
| `Pass` | fix confirmed | close in gitea, move the row to CLOSED |
| `Fail` + detail | the fix did not hold | `🔴 FAILED RETEST`, reopen in gitea, raise to ≥P2, post their evidence |
| `Fail`, no detail | cannot act yet | `🟠 NEED INFO` with ONE discriminating question |
| blank | nobody tested it | leave `🟡`, roll to the next session |
**A Pass or Fail with no BUILD NUMBER is uninterpretable** — a Pass on an older build cannot
verify a fix that shipped later. Before treating a `Fail` as a regression, establish that the
tested build actually contained the fix; that ambiguity is why #27 and #38 sat at `NEED INFO`
(asking for the boot-screen build) rather than going straight to `🔴`. Stamp "shipped in build
NNN" into every `🟡` Dev Comment so the answer is checkable later.
3. Reconciling ~50 tickets against their threads is a fan-out job — one agent per batch of ~7,
returning `{num, dev_status, priority, dev_comment}`.
## Access
- **Read** — the sheet is public, so the CSV export works with no auth:
`https://docs.google.com/spreadsheets/d/<ID>/export?format=csv&gid=0` (307-redirects to a
`googleusercontent.com` host; follow it). The Claude **Google Drive connector cannot see it**
that connector is scoped to files it created itself, and it has no cell-write capability for any
file, so sharing the sheet to the account does not help.
- **Write** — a Google Apps Script web app bound to the sheet, called with `curl -sL -d` (never
`-X POST`). Actions: `ping`, `tabs`, `get`, `set`, `append`, `note`, `width`, `height`,
`autofit`, `format`. Extending it requires re-pasting the script AND
**Deploy → Manage deployments → pencil → Version: New version** — clicking Deploy alone keeps
the old code live on the same URL. Treat further script edits as expensive: the operator has
said the redeploy loop is not worth repeating for cosmetics.
## Key Relationships
- Feeds: the gitea tracker (system of record) · `docs/OPEN_ISSUES_FOR_TESTERS.txt` (now secondary)
- Uses: [[operator-console]] (session tooling) · [[test-harness]] (what "verified" means here)