fix(narrative): add season championship context and §13.2 critical moments to spotlight prompt

Add formatSeasonChampionshipContext helper to inject season progress,
championship bracket positioning, and seed lines into LLM prompts.
Add §13.2 critical moment / turning point summary to the match-of-the-week
section of buildSpotlightPrompt. These complete the §15.1/§15.5 alignment
for structured contextual match data in sports-journalism-style prompts.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-04-22 20:08:49 -04:00
parent 922ef5cd5a
commit be66af1ad5

View file

@ -792,9 +792,12 @@ func buildSpotlightPrompt(data *IndexData, movers []eloMover, strats []strategyC
sb.WriteString("Reference specific bot names, ELO deltas (before/after), rivalry dynamics, and critical moments. ")
sb.WriteString("Be dramatic but factual. Write in present tense with a punchy, journalistic tone. Do not use emojis.\n\n")
// Season standings context
sb.WriteString(fmt.Sprintf("Season: %s\n", getCurrentSeasonName(data)))
sb.WriteString(fmt.Sprintf("Active bots: %d, Matches this week: %d\n\n", len(data.Bots), countWeeklyMatches(data)))
// Season standings context with championship positioning
seasonName := getCurrentSeasonName(data)
sb.WriteString(fmt.Sprintf("Season: %s\n", seasonName))
sb.WriteString(fmt.Sprintf("Active bots: %d, Matches this week: %d\n", len(data.Bots), countWeeklyMatches(data)))
sb.WriteString(formatSeasonChampionshipContext(data))
sb.WriteString("\n")
// Season standings (top 5 with rank, rating delta, archetype)
sb.WriteString("Season standings (top 5):\n")
@ -864,13 +867,27 @@ func buildSpotlightPrompt(data *IndexData, movers []eloMover, strats []strategyC
if bestMatch != nil {
sb.WriteString(fmt.Sprintf("\nMatch of the week: %s — score %s in %d turns [match %s]\n",
bestMatch.Description, bestMatch.Score, bestMatch.TurnCount, bestMatch.MatchID))
// Include pre-match ELO for participants if available
// Include pre-match ELO and §13.2 critical moment summary for participants
for _, m := range data.Matches {
if m.ID == bestMatch.MatchID && len(m.Participants) >= 2 {
for _, p := range m.Participants {
sb.WriteString(fmt.Sprintf(" %s: pre-match ELO %.0f\n",
getBotName(p.BotID, data), p.PreMatchRating))
}
// §13.2 critical moment / turning point summary
var winner, loser *ParticipantData
for i := range m.Participants {
if m.Participants[i].Won {
winner = &m.Participants[i]
} else {
loser = &m.Participants[i]
}
}
if winner != nil && loser != nil {
if cm := summarizeCriticalMoment(m, winner, loser); cm != "" {
sb.WriteString(fmt.Sprintf(" Turning point: %s\n", cm))
}
}
break
}
}
@ -2199,6 +2216,53 @@ func buildBotSpotlight(data *IndexData) *botSpotlight {
// ─── Formatting helpers (meta report specific) ────────────────────────────────
// formatSeasonChampionshipContext returns a human-readable summary of season progress
// and championship bracket positioning for LLM prompts.
func formatSeasonChampionshipContext(data *IndexData) string {
var active *SeasonData
for i := range data.Seasons {
if data.Seasons[i].Status == "active" {
active = &data.Seasons[i]
break
}
}
if active == nil {
return ""
}
daysElapsed := data.GeneratedAt.Sub(active.StartsAt).Hours() / 24
weekNum := int(daysElapsed/7) + 1
if weekNum > 4 {
weekNum = 4
}
var sb strings.Builder
theme := ""
if active.Theme != "" {
theme = fmt.Sprintf(" (%s)", active.Theme)
}
sb.WriteString(fmt.Sprintf("Season progress: Week %d of 4%s", weekNum, theme))
if weekNum >= 3 {
sb.WriteString(". Championship bracket approaching — top 8 qualify")
} else {
sb.WriteString(". Early season — seeding phase")
}
// Championship seed line
topBots := getTopBots(data, 3)
if len(topBots) > 0 {
sb.WriteString(". Current championship seeds: ")
names := make([]string, 0, len(topBots))
for i, bot := range topBots {
names = append(names, fmt.Sprintf("#%d %s (ELO %d)", i+1, bot.Name, int(bot.Rating)))
}
sb.WriteString(strings.Join(names, ", "))
}
return sb.String()
}
func formatMapOfTheWeek(m *mapOfTheWeek) string {
if m == nil {
return "Not enough map data this week."