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>
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>
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>
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>
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>
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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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.
- 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>
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>
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>
- 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>
- 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>
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>
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>
- 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>
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>
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>
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>
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>
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>
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>
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>
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>
- 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>