Session 47: Name normalization + grade intel + ticker polish (2149 tests)

- Name normalization completed: NICKNAMES table (Matt↔Matthew, Mike↔Michael...)
  resolved in nameKey, parenthetical team-tag strip "(STL)", verified accent-fold
  (Iván/Ivan, José/Jose). Slate strip now DISPLAYS the normalized de-dotted name
  ("AJ Ewing" not "A.J. Ewing") via buildPlayerStripsFromProps.
- Complete MLB VYNDR INTELLIGENCE: mlbGameLogFeatures derives rest_days (days off
  between latest games; 0=B2B) + ab_per_game (usage). buildIntelFields renders
  usage as "X AB/G", rest as B2B/Xd, matchup from bvp_advantage fallback.
- Ticker SCAN dedup: pushTickerItems keeps one SCAN per sport (sport field or
  text-prefix parse for legacy); MOVE/GRADE preserved; cap 50.
- BOMBER threshold prorated for mid-season (hr>=15 strong / >=10 mod) so June
  sluggers classify BOMBER not FLEX/DRIVER.

Backend 2122 -> 2149 tests (+27), 179 suites. Web build clean (exit 0).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-06-19 01:45:36 -04:00
parent c8fc9f577e
commit 78db55d499
13 changed files with 346 additions and 32 deletions
+4 -2
View File
@@ -343,8 +343,10 @@ function scoreMLB(s) {
ops = num(s.ops), runs = num(s.runs), kRate = num(s.k_rate), doubles = num(s.doubles);
return {
// BOMBER is the single power archetype — fires for any high-HR bat (incl.
// high-strikeout sluggers like Judge), so power hitters classify as BOMBER.
BOMBER: hr >= 20 ? 0.6 + hr / 60 : hr >= 15 ? 0.3 : 0,
// high-strikeout sluggers like Judge). Session 47: thresholds prorated for
// mid-season HR totals (a 15-HR June pace is full-season slugger territory),
// so power leads over DRIVER for a slugger who also drives in runs.
BOMBER: hr >= 15 ? 0.6 + hr / 60 : hr >= 10 ? 0.35 : 0,
BRUSH: avg >= 0.28 && kRate < 16 ? 0.6 + (avg - 0.25) * 2 : avg >= 0.29 ? 0.4 : 0,
DRIVER: rbi >= 50 && hr >= 12 ? 0.5 + rbi / 200 : 0,
GHOST: sb >= 15 ? 0.6 + sb / 60 : sb >= 10 ? 0.35 : 0,