diff --git a/.convoys/pick-a-name.md b/.convoys/pick-a-name.md new file mode 100644 index 0000000..9255682 --- /dev/null +++ b/.convoys/pick-a-name.md @@ -0,0 +1,141 @@ +# pick-a-name (P1 — pre-launch brand consistency) + +**Status:** in-progress +**Priority:** P1 (pre-launch; not a security blocker, but a brand-consistency +blocker that touches every user-facing surface) +**Convoy owner:** parent (orchestration); `role-architect` then +`role-implementer(s)` then `role-doc-writer` +**Opened:** 2026-05-24 +**Operator decision (gate-0, already ratified):** **Deck Hearth wins.** + +## Problem + +`AGENTS.md` line 5 has called this out since project setup: the repo, README, +seed data, package name, infrastructure, and admin email all say **"TCG +Vault"** (and the kebab `tcg-vault` / camel `tcgvault` variants), while the +actual rendered header brand in `components/Layout.js` says **"Deck Hearth"**. +Two distinct names, two distinct visual brands (the `AnimatedFireLogo.js` +component is also affected). Pre-launch this MUST be one name end-to-end. + +## Operator's brand decision (gate-0) + +**Deck Hearth wins.** Rationale (operator-stated): more distinctive, more +ownable, and the brand the human-facing surface (Layout header) already +renders. The trade is real: this is the higher-cost path because the +already-shipped infrastructure ID is the *losing* name. The architect's job +is to scope and minimize that cost — NOT to re-litigate the brand decision. + +## Initial surface inventory (architect to expand) + +Pre-architect rough hit-count from `rg`, scoped to non-vendor files: + +| Surface | Files (sample) | "TCG Vault" or `tcg(-)?vault` hits | +| --- | --- | --- | +| Marketing copy | `README.md`, `pages/index.js`, `pages/login.js`, `pages/signup.js` | 4 + 5 + 4 + 1 | +| Brand components | `components/AnimatedFireLogo.js`, `components/ShareModal.js` | 4 + 1 | +| Seed scripts (admin email) | `scripts/setup-neon-db.js`, `scripts/create-test-users.js`, `scripts/seed-collections-*.js` | 2 + 7 + 6 | +| Test guides | `TESTING_GUIDE.md` | 7 | +| **Infrastructure-bound (rename has external blast)** | `package.json`, `lib/rate-limit.js` (Redis prefix), `.github/workflows/*.yml` | 1 + 5 + 3 | +| **Already-correct (Deck Hearth)** | `components/Layout.js`, `styles/globals.css`, `components/AnimatedFireLogo.js` partial | n/a (these stay) | + +## Hard scoping rules + +- **Strictly NO re-litigating the brand decision.** Deck Hearth wins; the + architect ratifies *how* to rename, not *whether* to. +- **Keep the repo `tcg-vault` for now.** GitHub rename is a separate concern + (auto-redirects work, but Vercel-link / `gh` configs / local remotes / + bookmarks all need touching). Track as a queued follow-up convoy + `rename-repo-and-vercel-project`. This convoy renames the **product brand + in-app**; the repo/Vercel rename is a downstream convoy. +- **Redis prefix migration is in scope.** `lib/rate-limit.js` uses + `tcgvault:auth/search/upload/generate/import` as Redis key prefixes. These + must rename to `deckhearth:*` (or similar) atomically with the convoy. + Accept the one-time rate-limit-state reset (counters are per-15-min / + per-1-hour anyway; no user-perceptible impact). +- **Admin email migration is in scope.** `admin@tcgvault.com` rename to + `admin@deckhearth.com` (or similar — architect proposes the canonical + email, operator ratifies). Includes the in-DB UPDATE for any existing + `admin@tcgvault.com` row (write a one-off `scripts/migrations/YYYY-MM-DD- + rename-admin-email.js` per the no-go-zones rule for new migrations). +- **`package.json` name field:** rename to `deck-hearth` in this convoy + (npm package name; we don't publish, so blast is contained to lockfile + + any local script reference). +- **Lockfile regeneration:** the architect ratifies whether to regenerate + `package-lock.json` in this convoy or accept the rename mismatch + short-term. (Recommended: regenerate; cheap; matches package.json shape.) +- **DNS / domain:** out of scope — separate convoy + `point-domain-at-deckhearth` (you don't own a `deckhearth.*` domain yet + per operator's pre-convoy statement; if/when acquired, that triggers DNS). +- **Favicon / OG images / social cards:** in scope IF source files exist; + defer to follow-up convoy `regenerate-brand-assets` if they need new design. + +## Architect deliverables + +1. **Full surface inventory** — every occurrence of `TCG Vault`, `tcgvault`, + `tcg-vault`, plus every occurrence of `Deck Hearth` / `deck-hearth` / + `deckhearth` (the latter set tells you what's *already* correct and what + shape collisions need handling, e.g., if Layout.js has `Deck Hearth` but + AnimatedFireLogo.js has `DECKHEARTH` — pick canonical casing). +2. **Canonical-string ratification:** propose the canonical product name + ("Deck Hearth" with internal-cap; or "Deckhearth" one word; or other); + the canonical kebab (`deck-hearth`); the canonical camel/lower + (`deckhearth`); the canonical admin email (`admin@deckhearth.com` or + variant); the canonical Redis prefix (`deckhearth` or `dh`). Mark each as + D1-D5 (operator gate-1 for all five — they're naming choices, not + architectural ones). +3. **Slice plan:** probably 2-3 briefs. Suggested split (architect can + change): Brief 1 = in-repo string sweep + AnimatedFireLogo brand update + (mechanical); Brief 2 = Redis prefix migration in `lib/rate-limit.js` + + admin-email DB migration script + package.json rename + lockfile + regen (operationally riskier — needs careful testing). Brief 3 (if + needed) = visual baseline reset (because the smoke + visual-diff specs + will all fail with the new brand). +4. **Boot-the-brief verification** for each: confirm specs compile, lint + passes, vitest passes, smoke can still run against a preview. +5. **Out-of-scope queued follow-ups:** explicit list (repo rename, Vercel + project rename, DNS / domain acquisition, brand asset regeneration, + social card refresh). + +## Known constraints + +- **Cross-cutting smoke/visual diff blast.** PR-#18's Playwright smoke spec + ("sign-in page renders") + the visual-diff baseline are both predicated on + the *current* brand strings. Brief 2 (or Brief 3 if split) MUST update + the smoke spec expectations and either regenerate visual baselines or + accept temporary baseline drift (the `adopt-playwright-smoke` Decision 4 + `continue-on-error` swallow is still in effect, so visual-diff drift + won't fail CI — but the queued `seed-visual-baselines-on-linux` convoy + becomes harder to ship until *after* this convoy lands). +- **Smoke spec lives at `tests/smoke/app.smoke.spec.ts`.** Likely needs + one-or-two-character edits to text matchers. +- **`AGENTS.md` line 5's branding note** is the canonical historical record + of the inconsistency; the doc-writer pass MUST update it from "Pick one + before launch" to "Deck Hearth (decided 2026-05-24 in `pick-a-name` + convoy; commit X)." +- **Operator-action-required pre-merge:** smoke-test the rebranded preview + manually before merge (every public page should render "Deck Hearth"; + login + register should still work; admin import UI should still + function with the renamed admin user). + +## Out of scope (queued follow-ups) + +- `rename-repo-and-vercel-project` — GitHub repo rename + Vercel project + rename + local git remote update. P2 polish. Auto-redirects make this + low-risk-low-urgency. +- `point-domain-at-deckhearth` — DNS / domain. Blocked on domain + acquisition (operator pre-convoy: doesn't own `deckhearth.*` yet). +- `regenerate-brand-assets` — favicon, OG images, social cards. P2 + polish; requires design pass. +- `migrate-existing-user-emails` — if any existing user accounts have + `@tcgvault.com` emails (besides admin), propose a migration. Architect + to surface count via a `rg`/DB query during inventory. + +## Owns + +`role-architect` (decisions D1-D5, slice plan) → `role-implementer(s)` +(per brief) → `role-doc-writer` (AGENTS.md line 5 + this file's +As-shipped + ship-readiness Status summary footer). + +## As-shipped + +(To be appended post-merge by `role-doc-writer`.)