- Add s3.go with AWS SDK v2 S3Client wrapper for R2/B2 operations
- Implement listObjects, deleteObject, objectExists, uploadFile, copyObject, downloadObject
- Add s3_test.go with MockS3Client and comprehensive tests
- Wire promoteRecentReplaysForCycle() into build cycle in main.go
- Add fetchRecentMatchIDs() to query recent matches from PostgreSQL
- Add fetchExemptMatchIDs() to protect series/season/playlist matches from pruning
- Implement pruneR2CacheWithDB() for 10GB cap enforcement with exemptions
- Update go.mod with AWS SDK v2 dependencies
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add LLMBaseURL and LLMAPIKey config options for narrative generation
- Wire up LLM client to generateBlog() when LLM is configured
- Fix ParticipantData type usage in test files
- Simplify rivalry arc detection (remove alternation check)
- Fix type conversion in upset detection gap calculation
- Mark narrative engine as complete in PROGRESS.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Created narrative.go with story arc detection per plan §15.5
- Arc types: Rise, Fall, Rivalry, upset, evolution, comeback
- LLMClient for OpenAI-compatible API narrative generation
- generateLLMChronicles() using narrative engine
- Updated blog.go with LLM integration
- Template-based fallback when LLM unavailable
- Added tests in narrative_test.go
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add blog generation to Go index builder (cmd/acb-index-builder/blog.go):
- Weekly meta report generation with competitive analysis
- Story arc chronicles: rise stories, upsets, rivalries
- Blog index and individual post JSON generation
- Add blog page to web SPA (web/src/pages/blog.ts):
- Blog listing with type filters (all/meta-report/chronicle)
- Individual post view with markdown rendering
- Tag cloud and post metadata display
- Added /blog and /blog/:slug routes
- Add Blog link to navigation menu
- Add placeholder blog data files for initial content
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Canvas-rendered PNG card generation in cmd/acb-index-builder/cards.go
- 1200x630 images for social sharing (OG/Twitter)
- Rating tiers with color coding (gold/silver/bronze/green/gray)
- Win rate color coding (green/blue/yellow/red)
- Rank badges for top 100 bots
- Evolved bot badges with island indicator
- Add card upload to R2 warm cache and B2 cold archive
- Add Open Graph meta tags in web/app.html
- Add dynamic OG tag management in web/src/og-tags.ts
- Update bot profile page to set OG tags on load
- Add BuildTimeout config field (fixes test failures)
- Add comprehensive tests for card generation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Per plan §11.1, the index builder reads PostgreSQL and generates all JSON
index files for Cloudflare Pages deployment:
- main.go: Build cycle orchestration with configurable timeout, self-restart
- config.go: Environment-based configuration with sensible defaults
- db.go: PostgreSQL data fetching for bots, matches, series, seasons, predictions
- generator.go: JSON index generation (leaderboard, bots, matches, playlists)
- deploy.go: Cloudflare Pages deployment via wrangler, R2 warm cache pruning
- Dockerfile: Multi-stage build with Go + Node.js + wrangler CLI
- main_test.go: Tests for config, index generation, playlists
Index builder runs on 15-minute cycles, deploys to Pages every ~90 minutes,
and prunes R2 warm cache weekly to stay within 10GB free tier.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>