Gap Analysis Report #331

Closed
opened 2026-06-19 02:53:31 +00:00 by PlasticDigits · 21 comments
PlasticDigits commented 2026-06-19 02:53:31 +00:00 (Migrated from gitlab.com)

Focus on a fun, clear ux that can be played in short bursts throughout the day, has a clear sense of progression, clear visual hierarchy for someone making a quick glance in between other tasks, and has a clear sense of "a battle is happening" whenever the dapp is opened.

Focus on a fun, clear ux that can be played in short bursts throughout the day, has a clear sense of progression, clear visual hierarchy for someone making a quick glance in between other tasks, and has a clear sense of "a battle is happening" whenever the dapp is opened.
PlasticDigits commented 2026-06-19 03:09:44 +00:00 (Migrated from gitlab.com)

Gap Analysis Report — GitLab #331

Date: 2026-06-19
Scope: Fun, glanceable play UX for short daily bursts — progression clarity, visual hierarchy, and a persistent “battle is happening” feel on open.
Branch: main (synced)
Report path: gaps/GAP_1781838538.md


Executive summary

Yieldomega’s Arena v2 stack is mechanically mature: onchain TimeArena covers four podium timers, XP/level progression (L1–L5), WarBow PvP, and rich buy events; the indexer exposes timers, podiums, buys, activity, wallet stats, and platform usage; the play surface (/ → ArenaSimplePage) is a polished command console with hero countdown, podium carousel, inline CHARM buy, progression gates (#299), and WarBow at L4+.

Against issue #331’s UX goals, the largest gaps are spectator energy and glance hierarchy on the play route, not missing core game logic:

#331 goal Today Gap severity
Short bursts throughout the day Inline buy + carousel; production 5 min buy cooldown limits same-wallet pacing Medium (product constant vs burst intent)
Clear progression XP bar + level gates exist; tier roadmap data defined but not rendered; progression buried in side card High
Quick-glance hierarchy Competing timer headline + digits; dense side chips; carousel hides 3/4 podiums High
“Battle is happening” on open Peer-buy SFX + trophy shake; no live activity strip on /; steals/guards invisible; static first paint until polls Critical

Test health (local run): contracts (non-fork) ~200+ PASS; TimeArenaTest 115/115; indexer 80/80; frontend Vitest 694/694; frontend lint 1 error (prefer-const in useArenaPendingRevengeTargets.ts) would fail CI merge gate. Anvil E2E and arena verify scripts are not merge-gated.

Strategic takeaway: Close #331 primarily on the frontend play surface by reusing existing indexer feeds and components already shipped on AUDIT (/arena/protocol), plus small API polish (polled_at_ms, optional “since last visit”). Onchain/indexer foundations are sufficient; the product gap is what the player sees in the first 3 seconds on /.


Findings by theme

1. “Battle is happening” — Critical

What works

  • ArenaTimerHero urgency styling (timer-hero--warning / --critical) and rising sparks.
  • useLastBuyHeadShakeNonce + trophy shake on new Last Buy head.
  • usePeerBuyHeadSfx / useArenaSimplePageSfx — bell on peer head buy; timer heartbeat under 13m / 2m.
  • timeArenaUx.ts — rich battle narratives (hard reset, ambush, streak break).
  • ArenaWarbowHeroPanel — steal/guard/revenge at L4+.
  • Indexer chain_timer poller: 1s fast near deadlines, 3s idle max (chain_timer_poll.rs).

Gaps

Finding Severity Evidence
Live activity feed only on AUDIT Critical ArenaLiveBuysActivitySection wired in ArenaProtocolPage.tsx; E2E explicitly asserts arena-live-buys-activity count 0 on / (e2e/arena.spec.ts L45–46). Play route polls buys only (fetchArenaBuysAsBuyItems, 5s backoff) — not fetchArenaActivity (steals/guards/revenges).
ActivePlayerIndicator never mounted High Component exists (ActivePlayerIndicator.tsx) and is exported; no imports elsewhere in frontend/.
No push / SSE layer High MegaETH WSS/SSE deferred (#237); opening the dapp always waits on HTTP poll latency.
Static first paint High Timers/podiums show placeholders (—) until indexer responds; no skeleton “last buy 12s ago” strip.
platform-usage API built but unused on play Medium fetchArenaPlatformUsage in indexerApi.ts; PlatformUsageSubsection.tsx orphaned — network velocity never surfaces on /.
WarBow PvP gated to L4 Medium Early sessions feel solo; ArenaWarbowGatePreview is decorative (aria-hidden) not live indexer head.
AUDIT rank-burst motion not on play carousel Medium useChangedRankBurst on ArenaSimplePodiumSection (AUDIT grid); carousel slides lack equivalent motion.

2. Quick-glance visual hierarchy — High

What works

  • Intentional play vs AUDIT split documented in docs/frontend/arena-views.md (#291): carousel on /, four-podium grid on /arena/protocol.
  • arena-command-console glass layout with Last Buy as primary column (ArenaSimplePage.tsx).
  • ArenaTimerChips — compact per-podium countdown + top-3 rows in side rail.

Gaps

Finding Severity Evidence
Competing focal points in timer panel High Prize hook in <h2> (formatTimerSectionTitle / useTimerPodiumSlideMeta) competes with hero digits inside carousel.
No “Arena live” badge on play Medium phaseBadge("saleActive") used on ArenaProtocolPage, not ArenaSimplePage.
Side-rail chips information-dense Medium ArenaPodiumTimerChip.tsx — epoch, countdown, viewer score, 3 places with prize + score per chip.
WarBow lane may be below fold Medium arena-command-console__warbow-lane after main grid.
Play route hides global footer Low RootLayout.tsx — no IndexerStatusBar on / during play.
Carousel shows 1 of 4 podiums Medium (tradeoff) Good for focus; weak for multi-front “war on four fronts” glance. Four-card grid deliberately AUDIT-only.

3. Progression sense — High

What works

  • Onchain: XpGained, LevelUp, FeatureUnlocked events; level cap 5 (arena-v2.md, TimeArena.t.sol).
  • Indexer: GET /v1/arena/wallet/{address}/stats — level, xp_toward_next, prizes, epoch CHARM/CRED.
  • Frontend: FEATURE_UNLOCK_LEVEL matrix (#299), LockedUntilLevel, FeatureMechanicModal on level-up, buy projected-effects pills.

Gaps

Finding Severity Evidence
XP hero buried in side card High ArenaXpHero inside ArenaCharmCredCard (“YOUR WALLET”), not adjacent to timer/buy CTA.
Progression tier row not rendered High ARENA_PROGRESSION_TIERS defined in arenaProgression.ts (“shown in the XP hero lock row”) but only referenced in tests; indexerFirstDisplay.test.ts asserts arena-xp-hero__tiers absent.
Locks dominate new wallets Medium Carousel/chip locks + lockWalletSurface before first buy — little “do one thing now” path.
Level-up celebration is text modal Medium FeatureMechanicModal — paragraphs, not a quick burst reward moment.
Level cap 5 ends arc quickly Medium Progression plateaus; no post-L5 goals surfaced in UI.
Feature-unlock history ingested, not served Low idx_arena_feature_unlocked persisted (persist.rs); wallet stats echo current level only.

4. Short-burst playability — Medium

What works

  • Inline CHARM buy (no modal-first flow) on primary column.
  • Min/max slider, DOUB/CRED/ETH/USDM pay paths.
  • Anvil/dev: YIELDOMEGA_DEPLOY_NO_COOLDOWN=1 for rapid QA buys.

Gaps

Finding Severity Evidence
Production 5 min buy cooldown Medium TimeArena.buyCooldownSec default 300 (DeployProduction.s.sol, DevStackIntegration.t.sol); conflicts with “several actions per day” burst fantasy on mainnet.
Buy panel checkout-heavy Medium Long swap stack (pay field, slider, receive, pills, errors) in ArenaSimplePage.tsx for a 30-second session.
No post-buy micro-moment on play Medium Session has projected-effects data; no brief inline toast for timer extension + XP gained.
No “while you were away” summary Medium No indexer endpoint for session delta; re-open feels cold.

5. Contracts & onchain — Low (for #331)

Strengths: 115 TimeArenaTest cases covering timers, podiums, XP, WarBow, routing, gas bounds (test_xp_high_level_buy_gas_bounded_no_level_up, TimeArenaWarbowBenchmark.t.sol). Four independent podium deadlines; scoring/timer split documented in PARAMETERS.md.

Minor gaps relevant to UX delivery:

  • Level cap 5 is a product ceiling, not a bug.
  • buyCooldownSec is intentional anti-spam; tune for burst UX if #331 is authoritative over cooldown policy.
  • Large TimeArena ABI surface — correct per spec but increases integrator/audit load.

6. Indexer & API — Medium

Strengths: Routes for timers, podiums, buys, activity (union SQL), wallet stats, WarBow, platform-usage; integration smoke in integration_stage2.rs.

Gaps

Finding Severity Evidence
polled_at_ms not in /v1/arena/timers HTTP body Medium Internal in chain_timer.rs; frontend uses Date.now() (indexerApi.ts) — countdown drift vs indexer poll time.
Shallow API integration tests Medium Stage2 asserts 200s, not UX-critical JSON shapes for activity kinds or timer field parity.
No real-time push (#237) High Documented deferral; play relies on poll loops with mismatched cadences (timers ~1s, buys 5s, AUDIT activity 3s).
Indexer-first hard dependency (#301) Medium Without VITE_INDEXER_URL, display hooks return empty — correct architecture, weak offline/battle-resumed story.

7. Frontend engineering quality — Medium

Finding Severity Evidence
Lint error on main Medium useArenaPendingRevengeTargets.ts L41 prefer-const — CI npm run lint fails.
DRY XP math Low ArenaXp.sol + arenaXpMath.ts — drift risk for progression UI.
Legacy type shims Low fetchLegacyArenaSaleState / coreReadRowsFromArenaTimers bridge TimeCurve-shaped types.
Dead platform-usage UI Low CSS + API client without play-route consumer.

8. Testing & CI — High

What runs and passes locally

Layer Command Result
Contracts FOUNDRY_PROFILE=ci forge test --no-match-contract Fork All suites PASS (~200+ tests)
Indexer cargo test 80 PASS
Frontend npm test 694 PASS (130 files)
Frontend npm run typecheck PASS
Frontend npm run lint FAIL (1 error)

Coverage holes for #331 UX

Area Gap
E2E play feel arena.spec.ts checks mount + intentional absence of activity feed; no assertions for XP bar, carousel navigation, peer-buy visual feedback, progression unlock, WarBow flows.
WarBow E2E No dedicated Anvil spec for steal/guard/revenge.
Anvil verify scripts verify-podium-live-anvil.sh, verify-wallet-profile-anvil.sh, etc. exist locally but not in .github/workflows/unit-tests.yml.
Anvil E2E CI e2e-anvil.yml is workflow_dispatch only — not merge gate.
Indexer-first E2E YIELDOMEGA_E2E_INDEXER=1 path documented but optional.
UX content audit (#298) Manual checklist in frontend-content-audit.md; not automated in CI.
Frontend UX unit tests Strong on mechanics (timeArenaUx.test.ts, carousel locks, head-shake nonce); weak on “battle on open” and progression glance.

P0 — Battle energy on / (closes #331 core)

  1. Add compact live strip on play — 1–3 row version of ArenaLiveBuysActivitySection (or wire ActivePlayerIndicator + last buy) above/below ArenaTimerHero, reusing listBuyImpactTicks from timeArenaUx.ts. Keep dense feed on AUDIT.
  2. Show live badge on play — reuse phaseBadge("saleActive") near timer panel title (parity with AUDIT).
  3. Poll unified activity on play — extend ArenaSimplePage buy loop to fetchArenaActivity (or faster dedicated endpoint) at ≤3s to include steals/guards/revenges.
  4. Surface ActivePlayerIndicator on peer head buy / timer extension (same recentBuys source as SFX/shake).

P1 — Glance hierarchy & progression

  1. Render ARENA_PROGRESSION_TIERS in ArenaXpHero — 5-icon unlock roadmap (unlocked / next / locked); update indexerFirstDisplay.test.ts expectation.
  2. Move XP hero adjacent to timer or buy CTA — keep wallet stats in side card.
  3. Simplify timer panel headline — static category label + prize as secondary line; let ArenaTimerHero own the countdown glance.
  4. Mini four-podium status row — dot + abbreviated countdown per podium (data already in ArenaTimerChips / indexer timers) without full AUDIT grid.
  5. Post-buy micro-moment — brief toast: timer extension + XP (data in session + buildArenaBuyProjectedEffectLines).

P2 — Backend polish & burst policy

  1. Expose polled_at_ms in /v1/arena/timers — align client countdown with indexer poll instant.
  2. Evaluate buy cooldown for burst UX — if #331 is authoritative, consider shorter cooldown or burst-specific mechanic (product decision; onchain constant today).
  3. “Since last visit” summary endpoint — optional GET /v1/arena/session-summary?address=&since= for re-open energy.
  4. Wire platform-usage on play — compact “arena intensity” chip using existing API.

P3 — Testing & CI

  1. Fix lint error on useArenaPendingRevengeTargets.ts (const not let).
  2. E2E: play live strip — extend anvil-arena-03-wallet-writes.spec.ts to assert visible activity after Anvil buy on /.
  3. E2E: progression + carousel — level-gated slide locks; mock/seed L2 wallet unlock.
  4. Add #331 acceptance rows to frontend-content-audit.md — live strip, progression glance, battle-on-open checklist.
  5. Consider gating one arena verify script in CI (e.g. verify-wallet-profile-anvil.sh) when Postgres + Anvil runner available.

Test run log

Branch: main @ origin/main (up to date)
contracts:  FOUNDRY_PROFILE=ci forge test --no-match-contract Fork — PASS (TimeArenaTest 115/115, all suites green)
indexer:    cargo test — 76 unit + 4 integration PASS
frontend:   npm test — 694/694 PASS (130 files)
frontend:   npm run typecheck — PASS
frontend:   npm run lint — FAIL (prefer-const, useArenaPendingRevengeTargets.ts:41)

Generated by gap-analysis agent workflow for GitLab #331. No MR opened; no commit made per issue instructions.

# Gap Analysis Report — GitLab #331 **Date:** 2026-06-19 **Scope:** Fun, glanceable play UX for short daily bursts — progression clarity, visual hierarchy, and a persistent “battle is happening” feel on open. **Branch:** `main` (synced) **Report path:** `gaps/GAP_1781838538.md` --- ## Executive summary Yieldomega’s Arena v2 stack is **mechanically mature**: onchain `TimeArena` covers four podium timers, XP/level progression (L1–L5), WarBow PvP, and rich buy events; the indexer exposes timers, podiums, buys, activity, wallet stats, and platform usage; the play surface (`/` → `ArenaSimplePage`) is a polished **command console** with hero countdown, podium carousel, inline CHARM buy, progression gates (#299), and WarBow at L4+. Against issue #331’s UX goals, the largest gaps are **spectator energy and glance hierarchy on the play route**, not missing core game logic: | #331 goal | Today | Gap severity | |-----------|-------|--------------| | Short bursts throughout the day | Inline buy + carousel; production **5 min buy cooldown** limits same-wallet pacing | **Medium** (product constant vs burst intent) | | Clear progression | XP bar + level gates exist; tier roadmap data defined but **not rendered**; progression buried in side card | **High** | | Quick-glance hierarchy | Competing timer headline + digits; dense side chips; carousel hides 3/4 podiums | **High** | | “Battle is happening” on open | Peer-buy SFX + trophy shake; **no live activity strip on `/`**; steals/guards invisible; static first paint until polls | **Critical** | **Test health (local run):** contracts (non-fork) **~200+ PASS**; `TimeArenaTest` **115/115**; indexer **80/80**; frontend Vitest **694/694**; frontend **lint 1 error** (`prefer-const` in `useArenaPendingRevengeTargets.ts`) would fail CI merge gate. Anvil E2E and arena verify scripts are **not** merge-gated. **Strategic takeaway:** Close #331 primarily on the **frontend play surface** by reusing existing indexer feeds and components already shipped on AUDIT (`/arena/protocol`), plus small API polish (`polled_at_ms`, optional “since last visit”). Onchain/indexer foundations are sufficient; the product gap is **what the player sees in the first 3 seconds on `/`**. --- ## Findings by theme ### 1. “Battle is happening” — Critical **What works** - `ArenaTimerHero` urgency styling (`timer-hero--warning` / `--critical`) and rising sparks. - `useLastBuyHeadShakeNonce` + trophy shake on new Last Buy head. - `usePeerBuyHeadSfx` / `useArenaSimplePageSfx` — bell on peer head buy; timer heartbeat under 13m / 2m. - `timeArenaUx.ts` — rich battle narratives (hard reset, ambush, streak break). - `ArenaWarbowHeroPanel` — steal/guard/revenge at L4+. - Indexer `chain_timer` poller: **1s fast** near deadlines, **3s idle** max (`chain_timer_poll.rs`). **Gaps** | Finding | Severity | Evidence | |---------|----------|----------| | **Live activity feed only on AUDIT** | Critical | `ArenaLiveBuysActivitySection` wired in `ArenaProtocolPage.tsx`; E2E explicitly asserts `arena-live-buys-activity` count **0** on `/` (`e2e/arena.spec.ts` L45–46). Play route polls **buys only** (`fetchArenaBuysAsBuyItems`, 5s backoff) — not `fetchArenaActivity` (steals/guards/revenges). | | **`ActivePlayerIndicator` never mounted** | High | Component exists (`ActivePlayerIndicator.tsx`) and is exported; **no imports** elsewhere in `frontend/`. | | **No push / SSE layer** | High | MegaETH WSS/SSE deferred (#237); opening the dapp always waits on HTTP poll latency. | | **Static first paint** | High | Timers/podiums show placeholders (`—`) until indexer responds; no skeleton “last buy 12s ago” strip. | | **`platform-usage` API built but unused on play** | Medium | `fetchArenaPlatformUsage` in `indexerApi.ts`; `PlatformUsageSubsection.tsx` orphaned — network velocity never surfaces on `/`. | | **WarBow PvP gated to L4** | Medium | Early sessions feel solo; `ArenaWarbowGatePreview` is decorative (`aria-hidden`) not live indexer head. | | **AUDIT rank-burst motion not on play carousel** | Medium | `useChangedRankBurst` on `ArenaSimplePodiumSection` (AUDIT grid); carousel slides lack equivalent motion. | --- ### 2. Quick-glance visual hierarchy — High **What works** - Intentional play vs AUDIT split documented in `docs/frontend/arena-views.md` (#291): carousel on `/`, four-podium grid on `/arena/protocol`. - `arena-command-console` glass layout with Last Buy as primary column (`ArenaSimplePage.tsx`). - `ArenaTimerChips` — compact per-podium countdown + top-3 rows in side rail. **Gaps** | Finding | Severity | Evidence | |---------|----------|----------| | **Competing focal points in timer panel** | High | Prize hook in `<h2>` (`formatTimerSectionTitle` / `useTimerPodiumSlideMeta`) competes with hero digits inside carousel. | | **No “Arena live” badge on play** | Medium | `phaseBadge("saleActive")` used on `ArenaProtocolPage`, not `ArenaSimplePage`. | | **Side-rail chips information-dense** | Medium | `ArenaPodiumTimerChip.tsx` — epoch, countdown, viewer score, 3 places with prize + score per chip. | | **WarBow lane may be below fold** | Medium | `arena-command-console__warbow-lane` after main grid. | | **Play route hides global footer** | Low | `RootLayout.tsx` — no `IndexerStatusBar` on `/` during play. | | **Carousel shows 1 of 4 podiums** | Medium (tradeoff) | Good for focus; weak for multi-front “war on four fronts” glance. Four-card grid deliberately AUDIT-only. | --- ### 3. Progression sense — High **What works** - Onchain: `XpGained`, `LevelUp`, `FeatureUnlocked` events; level cap 5 (`arena-v2.md`, `TimeArena.t.sol`). - Indexer: `GET /v1/arena/wallet/{address}/stats` — `level`, `xp_toward_next`, prizes, epoch CHARM/CRED. - Frontend: `FEATURE_UNLOCK_LEVEL` matrix (#299), `LockedUntilLevel`, `FeatureMechanicModal` on level-up, buy projected-effects pills. **Gaps** | Finding | Severity | Evidence | |---------|----------|----------| | **XP hero buried in side card** | High | `ArenaXpHero` inside `ArenaCharmCredCard` (“YOUR WALLET”), not adjacent to timer/buy CTA. | | **Progression tier row not rendered** | High | `ARENA_PROGRESSION_TIERS` defined in `arenaProgression.ts` (“shown in the XP hero lock row”) but **only referenced in tests**; `indexerFirstDisplay.test.ts` asserts `arena-xp-hero__tiers` **absent**. | | **Locks dominate new wallets** | Medium | Carousel/chip locks + `lockWalletSurface` before first buy — little “do one thing now” path. | | **Level-up celebration is text modal** | Medium | `FeatureMechanicModal` — paragraphs, not a quick burst reward moment. | | **Level cap 5 ends arc quickly** | Medium | Progression plateaus; no post-L5 goals surfaced in UI. | | **Feature-unlock history ingested, not served** | Low | `idx_arena_feature_unlocked` persisted (`persist.rs`); wallet stats echo current level only. | --- ### 4. Short-burst playability — Medium **What works** - Inline CHARM buy (no modal-first flow) on primary column. - Min/max slider, DOUB/CRED/ETH/USDM pay paths. - Anvil/dev: `YIELDOMEGA_DEPLOY_NO_COOLDOWN=1` for rapid QA buys. **Gaps** | Finding | Severity | Evidence | |---------|----------|----------| | **Production 5 min buy cooldown** | Medium | `TimeArena.buyCooldownSec` default **300** (`DeployProduction.s.sol`, `DevStackIntegration.t.sol`); conflicts with “several actions per day” burst fantasy on mainnet. | | **Buy panel checkout-heavy** | Medium | Long swap stack (pay field, slider, receive, pills, errors) in `ArenaSimplePage.tsx` for a 30-second session. | | **No post-buy micro-moment on play** | Medium | Session has projected-effects data; no brief inline toast for timer extension + XP gained. | | **No “while you were away” summary** | Medium | No indexer endpoint for session delta; re-open feels cold. | --- ### 5. Contracts & onchain — Low (for #331) **Strengths:** 115 `TimeArenaTest` cases covering timers, podiums, XP, WarBow, routing, gas bounds (`test_xp_high_level_buy_gas_bounded_no_level_up`, `TimeArenaWarbowBenchmark.t.sol`). Four independent podium deadlines; scoring/timer split documented in `PARAMETERS.md`. **Minor gaps relevant to UX delivery:** - Level cap 5 is a product ceiling, not a bug. - `buyCooldownSec` is intentional anti-spam; tune for burst UX if #331 is authoritative over cooldown policy. - Large `TimeArena` ABI surface — correct per spec but increases integrator/audit load. --- ### 6. Indexer & API — Medium **Strengths:** Routes for timers, podiums, buys, activity (union SQL), wallet stats, WarBow, platform-usage; integration smoke in `integration_stage2.rs`. **Gaps** | Finding | Severity | Evidence | |---------|----------|----------| | **`polled_at_ms` not in `/v1/arena/timers` HTTP body** | Medium | Internal in `chain_timer.rs`; frontend uses `Date.now()` (`indexerApi.ts`) — countdown drift vs indexer poll time. | | **Shallow API integration tests** | Medium | Stage2 asserts 200s, not UX-critical JSON shapes for activity kinds or timer field parity. | | **No real-time push (#237)** | High | Documented deferral; play relies on poll loops with mismatched cadences (timers ~1s, buys 5s, AUDIT activity 3s). | | **Indexer-first hard dependency (#301)** | Medium | Without `VITE_INDEXER_URL`, display hooks return empty — correct architecture, weak offline/battle-resumed story. | --- ### 7. Frontend engineering quality — Medium | Finding | Severity | Evidence | |---------|----------|----------| | **Lint error on `main`** | Medium | `useArenaPendingRevengeTargets.ts` L41 `prefer-const` — CI `npm run lint` fails. | | **DRY XP math** | Low | `ArenaXp.sol` + `arenaXpMath.ts` — drift risk for progression UI. | | **Legacy type shims** | Low | `fetchLegacyArenaSaleState` / `coreReadRowsFromArenaTimers` bridge TimeCurve-shaped types. | | **Dead platform-usage UI** | Low | CSS + API client without play-route consumer. | --- ### 8. Testing & CI — High **What runs and passes locally** | Layer | Command | Result | |-------|---------|--------| | Contracts | `FOUNDRY_PROFILE=ci forge test --no-match-contract Fork` | All suites PASS (~200+ tests) | | Indexer | `cargo test` | 80 PASS | | Frontend | `npm test` | 694 PASS (130 files) | | Frontend | `npm run typecheck` | PASS | | Frontend | `npm run lint` | **FAIL** (1 error) | **Coverage holes for #331 UX** | Area | Gap | |------|-----| | **E2E play feel** | `arena.spec.ts` checks mount + intentional absence of activity feed; no assertions for XP bar, carousel navigation, peer-buy visual feedback, progression unlock, WarBow flows. | | **WarBow E2E** | No dedicated Anvil spec for steal/guard/revenge. | | **Anvil verify scripts** | `verify-podium-live-anvil.sh`, `verify-wallet-profile-anvil.sh`, etc. exist locally but **not** in `.github/workflows/unit-tests.yml`. | | **Anvil E2E CI** | `e2e-anvil.yml` is `workflow_dispatch` only — not merge gate. | | **Indexer-first E2E** | `YIELDOMEGA_E2E_INDEXER=1` path documented but optional. | | **UX content audit (#298)** | Manual checklist in `frontend-content-audit.md`; not automated in CI. | | **Frontend UX unit tests** | Strong on mechanics (`timeArenaUx.test.ts`, carousel locks, head-shake nonce); weak on “battle on open” and progression glance. | --- ## Recommended next steps ### P0 — Battle energy on `/` (closes #331 core) 1. **Add compact live strip on play** — 1–3 row version of `ArenaLiveBuysActivitySection` (or wire `ActivePlayerIndicator` + last buy) above/below `ArenaTimerHero`, reusing `listBuyImpactTicks` from `timeArenaUx.ts`. Keep dense feed on AUDIT. 2. **Show live badge on play** — reuse `phaseBadge("saleActive")` near timer panel title (parity with AUDIT). 3. **Poll unified activity on play** — extend `ArenaSimplePage` buy loop to `fetchArenaActivity` (or faster dedicated endpoint) at ≤3s to include steals/guards/revenges. 4. **Surface `ActivePlayerIndicator`** on peer head buy / timer extension (same `recentBuys` source as SFX/shake). ### P1 — Glance hierarchy & progression 5. **Render `ARENA_PROGRESSION_TIERS` in `ArenaXpHero`** — 5-icon unlock roadmap (unlocked / next / locked); update `indexerFirstDisplay.test.ts` expectation. 6. **Move XP hero adjacent to timer or buy CTA** — keep wallet stats in side card. 7. **Simplify timer panel headline** — static category label + prize as secondary line; let `ArenaTimerHero` own the countdown glance. 8. **Mini four-podium status row** — dot + abbreviated countdown per podium (data already in `ArenaTimerChips` / indexer timers) without full AUDIT grid. 9. **Post-buy micro-moment** — brief toast: timer extension + XP (data in session + `buildArenaBuyProjectedEffectLines`). ### P2 — Backend polish & burst policy 10. **Expose `polled_at_ms` in `/v1/arena/timers`** — align client countdown with indexer poll instant. 11. **Evaluate buy cooldown for burst UX** — if #331 is authoritative, consider shorter cooldown or burst-specific mechanic (product decision; onchain constant today). 12. **“Since last visit” summary endpoint** — optional `GET /v1/arena/session-summary?address=&since=` for re-open energy. 13. **Wire `platform-usage` on play** — compact “arena intensity” chip using existing API. ### P3 — Testing & CI 14. **Fix lint error** on `useArenaPendingRevengeTargets.ts` (`const` not `let`). 15. **E2E: play live strip** — extend `anvil-arena-03-wallet-writes.spec.ts` to assert visible activity after Anvil buy on `/`. 16. **E2E: progression + carousel** — level-gated slide locks; mock/seed L2 wallet unlock. 17. **Add #331 acceptance rows to `frontend-content-audit.md`** — live strip, progression glance, battle-on-open checklist. 18. **Consider gating one arena verify script in CI** (e.g. `verify-wallet-profile-anvil.sh`) when Postgres + Anvil runner available. --- ## Test run log ``` Branch: main @ origin/main (up to date) contracts: FOUNDRY_PROFILE=ci forge test --no-match-contract Fork — PASS (TimeArenaTest 115/115, all suites green) indexer: cargo test — 76 unit + 4 integration PASS frontend: npm test — 694/694 PASS (130 files) frontend: npm run typecheck — PASS frontend: npm run lint — FAIL (prefer-const, useArenaPendingRevengeTargets.ts:41) ``` --- *Generated by gap-analysis agent workflow for GitLab #331. No MR opened; no commit made per issue instructions.*
PlasticDigits commented 2026-06-19 04:13:46 +00:00 (Migrated from gitlab.com)

Tradeoff is complexity - users want activity but not excessive ux elements. Most of the proposed ideas involve increasing the complexity of the ux, which is not acceptable. Additionally, warbow is an advanced play feature, and users battle for timers immediately - all 4 are competitive. The side cards are visually large and visible, so do not need to be updated.

Approved ONLY:

SYSTEM: Must include full unit, e2e, fuzz, and happy/sad path tests

polled_at_ms not in /v1/arena/timers HTTP body: Fix

Shallow API integration tests: Fix

Frontend UX unit tests: Add for existing features & for new visual ones, must be done after all visual issues closed

E2E play feel: Add for existing features & for new visual ones, must be done after all visual issues closed

VISUAL: As these are VISUAL they must comply with our Cyberminimalist Glass System global design standard, and verification must include uploading a screenshot to the issue demonstrating compliance on both desktop, tablet, and mobile.

Locks dominate new wallets: Instead, locked elements except for the next level (eg if level 1, only show locks on level 2) to reduce visual load.

Level-up celebration is text modal: Create a confetti burst popover with Level Up and verty concise text explaining unlocked feature. But only for Level 2+ (since Level 1 is just connecting new wallet)

Feature-unlock history ingested, not served: Store the UTC timestamp in our database for each wallet when it reached a levelup, and deliver that via the indexer to be displayed in the account view modal we already have (shown when users click a player in the app). Show in a Level History session with 1, 2, 3, 4,5 where level 1 is there first buy, and levels 2-5 is when they leveld up. Shown in local time.

No post-buy micro-moment on play: Add a toast for each effect the buy had, that fades fairly quickly

No “while you were away” summary: Indexer should store delta between now and last time that browser was closed, stored per browser not per wallet. :While You Were Away" Modal opens when reopened. Should show time passed, if an epoch ended for any of the podiums (if so then who the winners were, the prizes, and a congratulations if they were a winner), their ranking change (if any), show number of buys, updates to podiums, number of unique players,

Tradeoff is complexity - users want activity but not excessive ux elements. Most of the proposed ideas involve increasing the complexity of the ux, which is not acceptable. Additionally, warbow is an advanced play feature, and users battle for timers immediately - all 4 are competitive. The side cards are visually large and visible, so do not need to be updated. Approved ONLY: SYSTEM: Must include full unit, e2e, fuzz, and happy/sad path tests polled_at_ms not in /v1/arena/timers HTTP body: Fix Shallow API integration tests: Fix Frontend UX unit tests: Add for existing features & for new visual ones, must be done after all visual issues closed E2E play feel: Add for existing features & for new visual ones, must be done after all visual issues closed VISUAL: As these are VISUAL they must comply with our Cyberminimalist Glass System global design standard, and verification must include uploading a screenshot to the issue demonstrating compliance on both desktop, tablet, and mobile. Locks dominate new wallets: Instead, locked elements except for the next level (eg if level 1, only show locks on level 2) to reduce visual load. Level-up celebration is text modal: Create a confetti burst popover with Level Up and verty concise text explaining unlocked feature. But only for Level 2+ (since Level 1 is just connecting new wallet) Feature-unlock history ingested, not served: Store the UTC timestamp in our database for each wallet when it reached a levelup, and deliver that via the indexer to be displayed in the account view modal we already have (shown when users click a player in the app). Show in a Level History session with 1, 2, 3, 4,5 where level 1 is there first buy, and levels 2-5 is when they leveld up. Shown in local time. No post-buy micro-moment on play: Add a toast for each effect the buy had, that fades fairly quickly No “while you were away” summary: Indexer should store delta between now and last time that browser was closed, stored per browser not per wallet. :While You Were Away" Modal opens when reopened. Should show time passed, if an epoch ended for any of the podiums (if so then who the winners were, the prizes, and a congratulations if they were a winner), their ranking change (if any), show number of buys, updates to podiums, number of unique players,
PlasticDigits commented 2026-06-19 04:26:30 +00:00 (Migrated from gitlab.com)

mentioned in issue #332

mentioned in issue #332
PlasticDigits commented 2026-06-19 04:27:38 +00:00 (Migrated from gitlab.com)

mentioned in issue #333

mentioned in issue #333
PlasticDigits commented 2026-06-19 04:27:43 +00:00 (Migrated from gitlab.com)

mentioned in issue #334

mentioned in issue #334
PlasticDigits commented 2026-06-19 04:27:44 +00:00 (Migrated from gitlab.com)

mentioned in issue #335

mentioned in issue #335
PlasticDigits commented 2026-06-19 04:27:45 +00:00 (Migrated from gitlab.com)

mentioned in issue #336

mentioned in issue #336
PlasticDigits commented 2026-06-19 04:27:50 +00:00 (Migrated from gitlab.com)

mentioned in issue #337

mentioned in issue #337
PlasticDigits commented 2026-06-19 04:27:51 +00:00 (Migrated from gitlab.com)

mentioned in issue #338

mentioned in issue #338
PlasticDigits commented 2026-06-19 04:27:52 +00:00 (Migrated from gitlab.com)

mentioned in issue #339

mentioned in issue #339
PlasticDigits commented 2026-06-19 04:27:53 +00:00 (Migrated from gitlab.com)

mentioned in issue #340

mentioned in issue #340
PlasticDigits commented 2026-06-19 04:28:08 +00:00 (Migrated from gitlab.com)

Child issues opened from gap analysis triage

Reviewed parent comment (2026-06-19) — approved items only. Related work bundled; rejected complexity / undecided UX expansions skipped.

Opened (8)

Issue Bundle Scope
#333 Indexer API quality Expose polled_at_ms on GET /v1/arena/timers + deepen integration test JSON shape assertions
#334 VISUAL — progression Show LockedUntilLevel only on next unlock tier (not L3–L5 when at L1)
#335 VISUAL — progression Confetti glass level-up popover for L2+ (replace auto-trigger text modal)
#336 Indexer + VISUAL Wallet Level History (L1=first buy, L2–5=level-ups) in profile modal
#337 VISUAL — burst feedback Post-buy effect toasts (one per effect, quick fade) on /
#338 Indexer + VISUAL While You Were Away modal + session-summary endpoint (since_ms, per-browser localStorage)
#339 SYSTEM — tests (blocked) Frontend UX unit tests for #331 visuals — after #334–338 closed
#340 SYSTEM — tests (blocked) Anvil E2E play-feel coverage — after #334–338 closed, --workers=5

Bundles: (1) indexer timer/API hardening → #333; (2) progression visuals → #334, #335, #336; (3) session feedback visuals → #337, #338; (4) test gate → #339, #340 (depend on visuals).

All issues include parent SYSTEM requirement: unit + integration/E2E + happy/sad paths in their test plans.

Skipped — rejected (UX complexity / explicit review)

Parent: "Tradeoff is complexity… Most proposed ideas involve increasing the complexity of the ux, which is not acceptable." Also: WarBow is advanced; users battle all 4 timers immediately; side cards are visually large — do not update.

Gap / proposal Reason
Compact live activity strip on / Rejected — UX complexity
Live badge (phaseBadge) on play Rejected
Poll unified fetchArenaActivity on play Rejected
Mount ActivePlayerIndicator Rejected
Render ARENA_PROGRESSION_TIERS in XP hero Rejected
Move XP hero adjacent to timer/buy CTA Rejected
Simplify timer panel headline hierarchy Rejected
Mini four-podium status row Rejected
Wire platform-usage intensity chip on play Rejected
Side-rail / side-card layout changes Rejected — already visible
Buy cooldown tuning for burst play Rejected — not in approved list
AUDIT rank-burst motion on play carousel Rejected

Skipped — not listed in approved-only comment

Item Status
Fix prefer-const lint in useArenaPendingRevengeTargets.ts Not approved — track separately if needed
SSE / real-time push (#237) Undecided / deferred
Gating arena verify scripts in CI Not approved
#331 rows in content audit only Deferred to #339/#340

Execution order (suggested)

  1. #333 (indexer/API — unblocks accurate countdowns)
  2. #334–#338 (visual features — parallelizable; each needs desktop/tablet/mobile screenshots)
  3. #339 → #340 (test consolidation after visuals land)

No MR opened; no commit made per parent instructions.

## Child issues opened from gap analysis triage Reviewed parent comment (2026-06-19) — **approved items only**. Related work bundled; rejected complexity / undecided UX expansions skipped. ### Opened (8) | Issue | Bundle | Scope | |-------|--------|-------| | [#333](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/333) | Indexer API quality | Expose `polled_at_ms` on `GET /v1/arena/timers` + deepen integration test JSON shape assertions | | [#334](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/334) | VISUAL — progression | Show `LockedUntilLevel` only on **next** unlock tier (not L3–L5 when at L1) | | [#335](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/335) | VISUAL — progression | Confetti glass level-up popover for **L2+** (replace auto-trigger text modal) | | [#336](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/336) | Indexer + VISUAL | Wallet **Level History** (L1=first buy, L2–5=level-ups) in profile modal | | [#337](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/337) | VISUAL — burst feedback | Post-buy **effect toasts** (one per effect, quick fade) on `/` | | [#338](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/338) | Indexer + VISUAL | **While You Were Away** modal + `session-summary` endpoint (`since_ms`, per-browser localStorage) | | [#339](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/339) | SYSTEM — tests (blocked) | Frontend **UX unit tests** for #331 visuals — **after #334–338 closed** | | [#340](https://gitlab.com/PlasticDigits/yieldomega/-/work_items/340) | SYSTEM — tests (blocked) | **Anvil E2E** play-feel coverage — **after #334–338 closed**, `--workers=5` | **Bundles:** (1) indexer timer/API hardening → #333; (2) progression visuals → #334, #335, #336; (3) session feedback visuals → #337, #338; (4) test gate → #339, #340 (depend on visuals). All issues include parent **SYSTEM** requirement: unit + integration/E2E + happy/sad paths in their test plans. ### Skipped — rejected (UX complexity / explicit review) Parent: *"Tradeoff is complexity… Most proposed ideas involve increasing the complexity of the ux, which is not acceptable."* Also: WarBow is advanced; users battle all 4 timers immediately; **side cards are visually large — do not update.** | Gap / proposal | Reason | |----------------|--------| | Compact live activity strip on `/` | Rejected — UX complexity | | Live badge (`phaseBadge`) on play | Rejected | | Poll unified `fetchArenaActivity` on play | Rejected | | Mount `ActivePlayerIndicator` | Rejected | | Render `ARENA_PROGRESSION_TIERS` in XP hero | Rejected | | Move XP hero adjacent to timer/buy CTA | Rejected | | Simplify timer panel headline hierarchy | Rejected | | Mini four-podium status row | Rejected | | Wire `platform-usage` intensity chip on play | Rejected | | Side-rail / side-card layout changes | Rejected — already visible | | Buy cooldown tuning for burst play | Rejected — not in approved list | | AUDIT rank-burst motion on play carousel | Rejected | ### Skipped — not listed in approved-only comment | Item | Status | |------|--------| | Fix `prefer-const` lint in `useArenaPendingRevengeTargets.ts` | Not approved — track separately if needed | | SSE / real-time push (#237) | Undecided / deferred | | Gating arena verify scripts in CI | Not approved | | `#331` rows in content audit only | Deferred to #339/#340 | ### Execution order (suggested) 1. **#333** (indexer/API — unblocks accurate countdowns) 2. **#334–#338** (visual features — parallelizable; each needs desktop/tablet/mobile screenshots) 3. **#339 → #340** (test consolidation after visuals land) No MR opened; no commit made per parent instructions.
PlasticDigits commented 2026-06-19 06:35:34 +00:00 (Migrated from gitlab.com)

mentioned in merge request !509

mentioned in merge request !509
PlasticDigits commented 2026-06-19 06:36:59 +00:00 (Migrated from gitlab.com)

mentioned in merge request !510

mentioned in merge request !510
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-19 10:45:09 +00:00
PlasticDigits commented 2026-06-19 10:58:45 +00:00 (Migrated from gitlab.com)

mentioned in commit 916025477a

mentioned in commit 916025477a294aaf3cd285404c2c775c9fb7427d
PlasticDigits commented 2026-06-19 10:59:42 +00:00 (Migrated from gitlab.com)

mentioned in merge request !514

mentioned in merge request !514
PlasticDigits commented 2026-06-19 11:03:16 +00:00 (Migrated from gitlab.com)

mentioned in commit bbf6bbb3f7

mentioned in commit bbf6bbb3f7a14a5750d8247263a0b9ef2e9796bd
PlasticDigits commented 2026-06-19 11:55:16 +00:00 (Migrated from gitlab.com)

mentioned in commit f2d5283eae

mentioned in commit f2d5283eae044b50d1ce90ee4e56261817c7ca01
PlasticDigits commented 2026-06-19 11:55:54 +00:00 (Migrated from gitlab.com)

mentioned in merge request !515

mentioned in merge request !515
PlasticDigits commented 2026-06-19 12:42:39 +00:00 (Migrated from gitlab.com)

mentioned in commit 8f69524756

mentioned in commit 8f695247562c29822c912a83052bfa5d01101f56
PlasticDigits commented 2026-07-02 12:52:19 +00:00 (Migrated from gitlab.com)

mentioned in commit 0c307de8a5

mentioned in commit 0c307de8a50011235c42edc6843c1b6cc94be4d2
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#331
No description provided.