Commit graph

167 commits

Author SHA1 Message Date
jedarden
62a5aa52ac feat(bot): add Scout bot (Python) — fog exploration archetype
Exploration-maximizing bot that maintains per-cell last-seen tick counters,
moves toward the stalest unobserved territory using forward-cone staleness
scoring, flees from enemies within extended combat range, and distributes
multiple bots across angular zones for maximum map coverage.

Archetype: Low Aggression, Low Economy, High Exploration, Low Formation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:40:35 -04:00
jedarden
5a1130c77a feat(bot): add Pacifist bot (JavaScript) — non-aggressive attrition archetype
PacifistBot never attacks; it survives by maximizing distance from enemies
and retreating toward own core when cornered. Pure evasion strategy that
wins via opponent elimination by third parties.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:32:50 -04:00
jedarden
5362b6c011 feat(bot): add Farmer bot (Go) — economy-maximizer archetype
Economy-maximizing bot that prioritizes energy collection and spawning
while avoiding combat entirely. Seeks nearest uncontested energy via BFS,
flees enemies within 3 cells, avoids contested energy tiles, and stays
near active cores for maximum spawn throughput. Includes 12 unit tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:30:26 -04:00
jedarden
968af06522 feat(evolution): add progressive disclosure to generation log and below-fold sections per §16.15
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:22:01 -04:00
jedarden
3cefabb9ed feat(bot): add Defender bot (C#) — core-hugging perimeter archetype
Core-defense strategy: bots patrol evenly-spaced slots around their
own core, intercept enemies entering the perimeter radius, and never
chase past the perimeter. Falls back to energy gathering when cores
are lost.

MAP-Elites profile: Low Aggression, Low Economy, Low Exploration, High Formation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:19:08 -04:00
jedarden
7f2407ed00 feat: add Prometheus metrics instrumentation across services
Add metrics server startup and HTTP middleware to acb-api, generation
counter metric to evolver, and R2 cache size metric to index builder.

Also remove dead measureR2CacheSize reference from index builder main.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:16:03 -04:00
jedarden
fff795ba6c fix(index-builder): improve rivalry recency test isolation + add metrics
The RecencyBoost test now uses balanced 5-5 splits for both pairs so
recency is the sole differentiating factor (previously one pair was 10-0
which conflated balance and recency). Also wires Prometheus build
duration metric in main loop.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:07:18 -04:00
jedarden
7a0de02059 feat(evolver): persist cross-pollination state to Postgres per §10.2
Add crosspoll_state table to persist per-island generation counters
across evolver restarts. Load state on startup and save after each
cross-pollination check. Add persistence pattern and translation
structure tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 16:04:15 -04:00
jedarden
582b4c010d fix(worker): remove unused net/http import in acb-worker
Pre-existing issue blocking go vet and go test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:55:45 -04:00
jedarden
80334c6e34 feat(evolver): expand MAP-Elites from 2-D to 4-D grid per §10.2
- Add Exploration and Formation axis definitions with feature extraction
  from source code pattern matching (exploration/formation indicators)
- Extend Grid key from (x,y) to (x,y,z,w) with 3⁴=81-cell behavior grid
- Update bin assignment, promotion gate, and persistence (JSON snapshot)
- Add Slice() for 2-D dashboard visualization across any axis pair
- Migration: old 2-D archives project at z=middle, w=middle
- Update cross-pollination to pad 2-element behavior vectors to 4
- Add Prometheus metrics to matchmaker (bot crashes, stale job count)
- Add rivalry detection to index builder (data/meta/rivalries.json)
- Web: batched bot list loading, leaderboard keyboard accessibility,
  improved ARIA attributes on match/playlist cards

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:44:39 -04:00
jedarden
4a92539c6f feat(web): progressive disclosure for dense pages per §16.15
Leaderboard, bot directory, match history, and playlist pages now use
expandable rows/cards, IntersectionObserver lazy rendering, windowed
virtual scrolling (for 1000+ leaderboard entries), and batched "Show
more" affordances. All expand/collapse transitions respect
prefers-reduced-motion. Keyboard accessibility (Enter/Space to toggle)
and ARIA attributes (aria-expanded, aria-controls) added throughout.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:43:50 -04:00
jedarden
e90d2e37c9 test(evolver): integration tests for cross-pollination logic per §10.2
Adds mock store/LLM implementations and tests for CheckAndPollinate:
generation boundaries, fitness penalties, translation triggers,
multi-boundary catch-up, and empty island handling.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:26:18 -04:00
jedarden
c56cc8bae6 fix(matchmaker): multi-match crash cooldown (3 strikes / 30 min) per §4.5 + §6.1
Add crash_strikes and cooldown_until columns to bots table. Worker
increments strikes on crash (cooldown at 3), resets on success.
Matchmaker excludes cooldown bots from pairing, series scheduling,
and championship brackets. Fix erroneous cooldown filter on series
table in finalizeCompletedSeries (column only exists on bots).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:22:12 -04:00
jedarden
da824f7360 fix(web): remove unused BATCH_SIZE constant in bots page
The bots page was refactored to use lazySection but left behind an
unused BATCH_SIZE = 50 constant, causing a TS6133 build error.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:17:20 -04:00
jedarden
fb707b8461 test: integration tests for multi-match crash cooldown (3 strikes / 30 min) per §4.5 + §6.1
The crash cooldown system was already implemented across engine, worker,
and matchmaker. This adds comprehensive integration tests that verify:

- Single crash does not trigger cooldown
- Two crashes do not trigger cooldown
- Three consecutive crashes trigger 30-min cooldown
- Successful match resets strike counter
- Interleaved crash/success resets counter correctly
- Cooldown extends on repeated crashes while on cooldown
- Matchmaker eligibility query excludes bots on active cooldown
- Matchmaker eligibility query includes bots with expired cooldown
- Full end-to-end flow: 3 crashes → excluded → cooldown expires → re-pair

Tests use ACB_TEST_DATABASE_URL env var for PostgreSQL integration tests
and skip gracefully when not configured.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:14:03 -04:00
jedarden
d43cf83471 feat(evolver): island cross-pollination every 50 generations per §10.2
Adds cross-pollination logic that copies the top program from each island
to a random other island every 50 generations. When source and target
islands use different languages, the LLM translates the code. Generation
boundaries are tracked per-island to prevent duplicate events.

- New crosspoll package with boundary detection, migration, and LLM translation
- Added MaxGenerationByIsland DB query for generation counter tracking
- Integrated into RunEvolutionLoop with observability logging
- Tests for boundary logic, translation prompts, and target selection

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:13:27 -04:00
jedarden
04927a76b0 feat(web): progressive disclosure — lazy-load, expand details, windowed lists per §16.15
Virtual list tracks expanded row heights for correct spacer calculations.
Leaderboard mobile cards use event delegation so toggles work inside lazy
sections. Mobile card details animate with max-height instead of display
toggle. Reduced-motion rules cover all expand/collapse patterns.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:06:55 -04:00
jedarden
c618f0b7a1 feat(worker): gzip replay compression at upload per §7.1
Worker now gzip-compresses replays before uploading to B2 with
key replays/{match_id}.json.gz and Content-Encoding: gzip.
Updated B2 client Upload to accept contentEncoding parameter.
Fixed downstream web consumers (matches, bot-profile, playlists)
to reference .json.gz URLs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 15:00:09 -04:00
jedarden
1451ca5a50 feat(web): mobile swipe-through playlist carousel per §16.16
TikTok-style full-screen vertical carousel for playlist matches on mobile.
Swipe up/down advances between replays, horizontal swipe reveals metadata
panel with match details. Director mode auto-adjusts speed based on action
density. Auto-advance with animated countdown ring after replay completion.
Desktop layout unaffected — carousel only activates on mobile (<768px).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 14:54:38 -04:00
jedarden
677fde5245 fix(engine): use core1 variable in spawn priority tiebreak test
The TestSpawnPriority_LowerIDBreaksTie test declared core1 but never
referenced it, causing a compile error. Added an assertion that
core1.LastSpawnedTurn remains 0 (confirming it didn't spawn).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 14:45:06 -04:00
jedarden
67d94cebbd feat(web): add theater component and playlist carousel
Commit the TheaterMode component (§16.17) and playlist carousel
referenced by recent commits. Includes bots page and playlists
page enhancements.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 14:31:08 -04:00
jedarden
4930d7a841 feat(web): integrate theater mode into replay viewer per §16.17
Wire the existing TheaterMode component into the replay page — adds
fullscreen toggle button on canvas, F key shortcut, auto-hiding
controls with 3s inactivity, vignette pulse on critical moments,
and mobile Fullscreen API support.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 14:28:54 -04:00
jedarden
5cf9a786d5 feat(web): progressive disclosure — lazy sections, expandable details per §16.15
Wire IntersectionObserver-based lazy rendering into bot profile (recent
matches below fold) and leaderboard (mobile cards). All three dense pages
(leaderboard, matches, bot-profile) now use expandable rows/cards for
secondary detail, windowed rendering for long lists, and keyboard-accessible
"Show more" affordances. Expand/collapse animations respect reduced-motion.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 14:01:13 -04:00
jedarden
28f6d99bff feat(replay): smooth 400ms cross-fade between view modes per §16.11
Implement double-buffered canvas cross-fade when switching between
dots, Voronoi territory, and influence gradient views. Old layer fades
out while new layer fades in with ease-in-out cubic easing over 400ms.
Respects prefers-reduced-motion by snapping instantly when set.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:57:42 -04:00
jedarden
a06129132e feat(k8s): add deployment manifests for acb-evolver and acb-api per §9.2
Staging manifests for sync to declarative-config/k8s/apexalgo-iad/ai-code-battle/:
- acb-evolver: Deployment + ServiceAccount with LLM/PG/R2 secrets
- acb-api: Deployment + Service + IngressRoute for api.ai-code-battle.ardenone.com

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:50:20 -04:00
jedarden
81940a1598 fix(api): fix getEnv stub and Dockerfile Go version for deployment readiness
The getEnv() function in server.go always returned the default value,
preventing ACB_R2_ENDPOINT/ACB_B2_ENDPOINT from being read at runtime.
Also updated Dockerfile from golang:1.24 to golang:1.25 to match go.mod.

K8s manifests for acb-evolver and acb-api already exist in
declarative-config/k8s/iad-acb/ai-code-battle/ (added Apr 21).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:29:45 -04:00
jedarden
9750d29618 feat(web): performance trifecta — preload-on-hover, skeleton screens, back-cache per §16.14
Three perceived-performance features:
- Preload on hover: internal links prefetch target JSON data after 150ms
  hover debounce using <link rel=prefetch>. Touch events prefetch
  immediately.
- Skeleton screens: every async page shows a shimmer-animated placeholder
  matching the final content layout (leaderboard rows, bot profile card,
  replay canvas, playlist grid, etc.) instead of generic "Loading..." text.
- Instant back-cache: back/forward navigation restores scroll position and
  cached HTML from an in-memory LRU cache (8 pages), making back navigation
  0ms.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:28:43 -04:00
jedarden
f6ce4588f4 fix(api): rename /api/ui-feedback to /api/feedback per plan §13.6
The community feedback endpoint was registered as /api/ui-feedback in
the Go API but the plan and annotation.ts client both use /api/feedback.
Rename the route and update agentation-overlay.ts to match. Add a
route-level test asserting the canonical path and that the old path
returns 404.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:22:47 -04:00
jedarden
5443e4d0ed fix(engine): enforce strict HMAC response signature verification per §4.4
Remove the lenient fallback that accepted bot responses missing the
X-ACB-Signature header. Missing or invalid signatures now cause the
response to be discarded and count toward the crash threshold (§4.5).
Add tests for missing-header, bad-signature, and crash-after-10 cases.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 13:18:10 -04:00
jedarden
80733f673e feat(replay): wire AnnotationOverlay to EventTimeline with annotation badges per §16.8
Sync annotations to both the canvas renderer (spatial markers) and the
event timeline (colored badge markers) so user feedback appears in both
the replay canvas and the timeline ribbon.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 18:07:44 -04:00
jedarden
d3f2068f8b feat(replay): implement Director Mode adaptive auto-speed playback per §16.10
Add director.ts component with action density computation, speed schedule
generation, and eased speed transitions. Integrate into replay viewer with
Director option in speed selector, target duration presets (30s/1min/2min/5min),
speed indicator display, and scrubbing pause/resume.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 17:57:10 -04:00
jedarden
eaa8193cac feat(replay): restore annotation imports for debug telemetry panel
Working tree had removed the annotation component imports while the
initAnnotations function and ANNOTATION_OVERLAY_STYLES template
reference still depended on them, causing TS build failures.
2026-04-21 17:25:20 -04:00
jedarden
30f2c63b20 feat(replay/enrichment): fix TS build, align annotations with §8.3
- Fix TS6133: rename _matchId → matchId in AnnotationOverlay and use
  this.matchId in filter so the field is actually read
- Align ANNOTATION_TAGS in feedback.ts to four types from plan §8.3:
  insight, mistake, idea, highlight (matching components/annotation.ts)
- Update LS_KEY to acb_annotations_v2 to avoid stale-format conflicts
- Fix duplicate import block in api-types.ts (re-exported evolution types)
- Remove unused debugPanelChevron ref in replay.ts; add annotation
  imports for AnnotationOverlay and createAnnotationForm

The AI commentary generation backend (enrichment.go) and client-side
subtitle display (replay-viewer.ts, embed.ts, home.ts) were already
complete in prior commits.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:20:22 -04:00
jedarden
d8812b98ee feat(playlists/replay): n-player win prob, annotations, evolver metrics
Playlist curation per §10 is fully implemented in the index builder:
- generatePlaylists() writes /data/playlists/index.json and {slug}.json
- curateWeeklyHighlights() selects best-of-week by upsets, elite
  clashes, marathon turns, and closest finishes (last 7 days)
- persistGeneratedPlaylists() upserts to playlists/playlist_matches DB tables
- /data/playlists/ stub files seeded for all 12 curated collections

Replay viewer improvements shipped alongside:
- WinProbPoint refactored from {p0,p1} to {probs: number[]} for N players
- renderWinProbSparkline draws one line per player with matching colors
- replay.ts updated to build probs[] from replay.win_prob arrays
- Dynamic legend generated from replay.players instead of hardcoded P0/P1

New annotation overlay component (§16.8):
- AnnotationOverlay: timeline track, per-turn list, canvas markers
- createAnnotationForm: type selector, author, body, localStorage + API
- ANNOTATION_OVERLAY_STYLES: self-contained CSS for the overlay

Evolver: add mutations_per_hour metric to Totals (live.json §14)
Types: consolidate evolution types into types.ts, re-export from api-types.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:15:31 -04:00
jedarden
fd9ffbc048 feat(watch/replays): show featured playlists as curated sections per §10
Replace the flat horizontal playlist row with a curated layout:
- Top 3 featured playlists (Best of Week, Biggest Upsets, Closest Finishes)
  displayed as distinct visual sections in a 2:1:1 grid
- "Best of Week" highlighted with a primary accent style
- Remaining playlists shown in a scrollable "More Collections" row
- "Browse all →" header link routes to /watch/playlists

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:11:16 -04:00
jedarden
b7fea448bd feat(mobile): implement mobile-first responsive design per §16.5
- Fix nav/home breakpoints from 768px → 639px to match design system
- Add leaderboard mobile card view with tap-to-expand stats and full-stats link
- Add canvas wrapper aspect-ratio:1 on phone (fills full width, square viewport)
- Add commentary text scroll on mobile, win-prob header stacking
- Replay viewer: mobile controls, pinch-to-zoom, tap-to-play, swipe scrub,
  floating view-mode toggle, debug telemetry slide-up sheet (already in place)
- Sandbox: desktop-required message with link already implemented

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 17:04:02 -04:00
jedarden
38269d1285 feat(home): redesign homepage per §16.3 — dynamic data, territory replay, compact layout
- Remove duplicate SWR cache (use shared fetchers from api-types.ts)
- Add territory view mode to featured replay embed
- Use demo replay fallback when no live matches available
- Compact layout with tighter spacing for 1080p above-the-fold
- Add missing placeholder data files: evolution/meta.json, seasons/index.json
- Fix unused import in cmd/acb-index-builder/s3_test.go

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 17:01:24 -04:00
jedarden
80af92b022 feat(replay): add debug telemetry panel and fix test build
Add debug telemetry UI to replay viewer with player toggles,
priority-based target markers, and stacked reasoning boxes.
Fix undefined generateTestImage in main_test.go.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:57:15 -04:00
jedarden
80040fa501 test(index-builder): add tests for fast playlist lookup helpers
Covers buildFirstMatchPerBot, isNewBotDebutFast, buildPairFrequency,
isRivalryMatchFast, and integration test for playlist generation with
the optimized lookups.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:48:20 -04:00
jedarden
be3843d9ac fix(index-builder): correct series/season exempt queries, optimize playlist curation
- Fix deploy.go to query actual table names (series_games not series_matches,
  join through series_games for seasons instead of non-existent season_matches)
- Add playlist_matches table to exempt match IDs from R2 pruning
- Pre-build lookup maps for O(1) playlist match filtering instead of O(n²)
- Enhance home page featured replay to prefer AI-enriched matches
- Add enrichment test coverage (shouldEnrich criteria validation)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:47:13 -04:00
jedarden
aa1c78c9d7 docs: document series/season scheduler verification in PROGRESS.md
Verified all §11 deliverables are fully implemented:
series scheduler, seasonal ELO reset, bracket display, season leaderboard.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:39:43 -04:00
jedarden
33e443c199 docs: document series scheduler and seasonal ELO reset in PROGRESS.md
The series scheduler (series_season.go) and season management were already
fully implemented but not tracked in PROGRESS.md. Updates the file listing
to include series_season.go, series_season_test.go, Dockerfile in the
matchmaker, and series.ts, seasons.ts, season-detail.ts in pages.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:29:50 -04:00
jedarden
46ff42ef84 feat(playlists): add static playlist placeholder files for dev mode
Populate web/public/data/playlists/ with all 12 playlist slug JSON files
and update index.json so the frontend fetch calls work during local
development without requiring the index builder to have run.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:22:30 -04:00
jedarden
513ca42d7a chore: minor import cleanup in predictions page
Remove unused API_BASE constant and reorder imports in predictions.ts.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:16:24 -04:00
jedarden
9d7a2e2e3c fix(web): remove unused imports in predictions.ts to fix TypeScript build
PredictionHistoryEntry was imported but never used, and API_BASE was
declared but never read. These caused tsc to fail with TS6196/TS6133.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:15:33 -04:00
jedarden
b1121ed6f8 feat(playlists): add playlist curation and rebuild logic per §10, with series/seasons/enrichment
Implement auto-curated playlists in the index builder: 12 playlist types
(closest finishes, upsets, comebacks, marathons, rivalry classics, etc.)
with weekly highlight curation. Add DB persistence, R2 pruning exemptions,
frontend pages, and AI commentary enrichment pipeline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 16:11:27 -04:00
jedarden
70b7337867 feat(blog): add rivalry context to spotlight prompt and fix narrative tests
The buildSpotlightPrompt function accepted a rivalries parameter but never
used it. This adds top rivalry data to the LLM prompt so the generated
Counter-Strategy Spotlight can reference active rivalries. Test updated to
verify rivalry data appears in prompt output.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 15:45:33 -04:00
jedarden
1796f2a27e feat(matchmaker): add series game result propagation to scheduler
The series scheduler was scheduling games and creating series_games rows,
but never updated winner_id or incremented a_wins/b_wins when individual
matches completed. This left series in perpetual "active" state since
finalizeCompletedSeries checks win counts that were never incremented.

Add updateSeriesGameResults step that:
- Finds series_games with completed matches but NULL winner_id
- Updates winner_id from match_participants
- Increments a_wins or b_wins on the series table

Called as step 0 in tickSeriesScheduler, before finalization checks.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 15:31:33 -04:00
jedarden
51edf35d22 feat(sandbox): integrate Go WASM engine with multi-player support per §13.1
Enhance the WASM game sandbox with production-accurate Go engine:

- Add multi-player support (2-4 players) to Go WASM engine via JS callbacks
- New acbEngine.addPlayer/clearPlayers/runMatchMulti API for N-player matches
- Sandbox auto-loads Go WASM engine in background, falls back to TS engine
- Engine selector: Auto (Go WASM → TS fallback), Go WASM only, or TS only
- Engine status indicator shows which engine is active
- Performance panel reports which engine was used

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 15:28:35 -04:00
jedarden
347ae4f1df feat(predictions): resolve predictions on match completion, add API endpoints and frontend
- Worker resolves open predictions after writing match results (resolvePredictions + upsertPredictorStats)
- API endpoints: POST /api/predict, GET /api/predictions/open, GET /api/predictions/history
- Frontend /watch/predictions page with polling, prediction submission, and history display
- predictor_stats table tracks streaks and accuracy per predictor
- Series format selection: fix threshold from >200 to >=200 for bo3 eligibility

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-21 14:08:15 -04:00