Ops / Pipeline Status

Real components mapped to the spec's software-agent org chart roles -- see docs/22-agent-org-chart.md for exactly what this is and isn't. There is now an autonomous orchestrator (scripts/orchestrator/run.mjs): it runs unattended in CI on every push and on schedule, executes the pipeline in dependency order, gates each stage on a health check of the data that stage actually wrote, retries what it can, and records the outcome below. It is deliberately rules-based rather than an LLM -- the same standard the playoff engine is held to. Everything on this page is read from that pipeline's own database at build time; nothing here is written by hand.

Autonomous Orchestrator

Latest run

DEGRADED · 49/49 stages usable · trigger: local-schedule · 7 stage(s) degraded

Started 2026-10-19 06:12:02.675183+00, finished 2026-10-19 06:17:40.918886+00

StageStatusTriesTimeWhat the health gate measured
teams-and-gamesok110.0s36 teams, 7548 games, 180 upcoming games with a kickoff time
stadiumsok11.0s32 stadiums with real coordinates and roof types
player-statsok184.4s33867 stat rows, newest season 2026 with 1646 players
player-weeksok16.2s147020 player-week rows over 9 seasons
injuriesok10.8s93203 injury rows
depth-chartsok10.1s877 listed starters across 32 clubs, snapshot Sun Oct 18 2026
play-by-playok1136.7s1231 penalties across 92 game(s), all attributed to a known player
penalty-flagsdegraded114.2s8 completed season(s) on file; 77 of 92 completed 2026 game(s) collected -- the rest are not published on nflpenalties.com yet
odds-snapshotsok10.8s2961 line snapshot(s) on record; 15 of 15 game(s) in the next seven days have a recorded line
game-forecastsdegraded10.9s8 of 14 home-stadium game(s) in the next seven days have a recorded forecast -- the rest are beyond the Weather Service's range yet, or it did not answer
officialsok11.6s3041 games with a crew on file, 3041 with a named referee
referee-tendenciesok10.2s152 referee-seasons measured
advanced-statsok14.1s332075 snap rows, 7974 defensive and 2974 rushing advanced rows
gradesok12.8s1662 player grades across 9 position groups and 96 unit grades for 2026
weekly-gradesok135.1s2026 through week 6: 2065 players in 9 position groups, 32 clubs graded, 7 positions calibrated
position-rank-driversok12.7s2026 week 6: 320 driver rows across 10 units (10 graded)
schedule-strengthok10.6s2026 week 6: 26 team(s) with a recorded opponent, 13 completed game(s), 0 missing an opponent grade
team-writeupsok15.2s32 write-ups for 2026 week 6
coach-recordsok11.3s177 head coaches, all 32 2026 clubs covered
data-qualitydegraded10.7s25 checks, 0 failed, 1 warned, 0 waiting on a source; 6 franchise aliases derived
player-evaluationok115.1s11 NGS passing seasons, 188 2026 passing weeks, 2282 2026 PFR defensive player-games
yahoo-standingsok10.1s1 captured pool standing(s)
yahoo-poolok10.3s107 pool games across 7 week(s), 93 with a posted Yahoo spread
featuresok13.1s15096 team-game rows, 32 registered features
predictionsok10.3s14/14 games predicted for 2026 week 6 by 2 model(s), average confidence 60%
ats-picksok10.6s92/1 games picked against the pool's own line
score-predictionsok10.5s14/14 games projected for 2026 week 6
score-gradeok10.2s2026 week 5: 15 of 15 final games graded from a pre-kick snapshot; margin MAE 10.67 vs closing line 10.40; spread disagreement 8/14; under 30 disagreements, not a 52.4% test
pick-historydegraded10.5s92 picks on record, but only 91 of 92 finished games have one
tiebreakersok10.1s24 tiebreaker(s), each consistent with the pick for its game
pick-consistencyok10.1spools cross-checked: no Survivor pick contradicts our own forecast
pick-reviewok10.3s87/148 graded correct; 92 genuine disagreements with the market (54 right)
pool-reportok10.4s2026 weeks 1-5: 5 report cards, 79 graded picks, 47-31-1 against the Yahoo line
metric-audit-scoresok10.2s26 metrics scored individually; 1 clear the 50% null by more than noise
edge-searchok11.2s14 segments tested, 0 beyond noise
revise-picksdegraded10.2s119/152 picks carry the inputs they were made against; 51887 re-check(s) logged, 0 revision(s) -- some picks cannot be re-checked
crowd-analysisok10.1s107 game(s) with a pool crowd split analysed
live-statsok12.1s3956 player line(s) from 60 game(s), 25 still in progress
playoff-projectionok10.1s32 clubs projected; probabilities sum to 14 as they must
betting-marketsok10.7s60/1 upcoming games priced across 2 venue(s)
export-picksok10.1s1 pick(s) and 24 tiebreaker(s) exported for submission
pre-kick-snapshotsok11.3s2026 week 6: 1/1 unplayed game(s) have a snapshot (depth 448, exchange 3093, injury 139, sportsbook 27, weather 17, yahoo-pool 1); 20 feature vector(s) stored
metric-auditok10.2s30 metrics x 32 clubs = 960 values; 194 missing and reported
editorialok10.2s39 storyline(s); 993/993 of today's messages consumed
schedule-planok10.1s118 kickoff slot(s) planned
qa-watchdogdegraded10.4s4 warning defect(s), 0 repaired automatically
ci-historydegraded10.1sno CI history -- the GitHub token was unavailable, so /ops shows an empty table honestly rather than a made-up pass rate
consistencyok10.0sreferential and score checks passed
record-completionok10.2snot a pre-kickoff run -- no slot to record

Recent runs: degraded (local-schedule) · degraded (local-schedule) · degraded (local-schedule) · degraded (local-schedule) · degraded (local-schedule)

Score model grade

2026 week 5 Week 5 of 2026, score-ridge/v1: 15 of 15 games have a projection from before kickoff. Projected margin MAE is 10.67 points and RMSE is 14.27; the closing spread on the same games has MAE 10.40 and RMSE 13.04. Projected total MAE is 11.91 points and RMSE is 12.77; the closing total on the same games has MAE 10.17 and RMSE 10.87. The projection and the closing spread disagreed on 14 games, and 8 landed. 14 is below the 30-game floor used before a rate is read against 52.4%, so this is not that test. The projection and the closing total disagreed on 15 games, and 5 landed. 15 is below the 30-game floor used before a rate is read against 52.4%, so this is not that test. On 1 game the spread stored with the projection differs from the closing spread by at least 0.25 points. The grade uses the closing spread. The walk-forward measurement on 2199 games, 2018-2026, remains the bar: margin disagreement 50.07%, total disagreement 49.67%, projected margin MAE 10.23 against the closing line's 9.79. Both disagreement rates sit below the 52.4% break-even at -110. This grade does not replace that measurement.

2026 through week 5 Through week 5 of 2026, score-ridge/v1: 46 of 79 games have a projection from before kickoff. Projected margin MAE is 8.11 points and RMSE is 11.13; the closing spread on the same games has MAE 8.20 and RMSE 10.99. Projected total MAE is 12.00 points and RMSE is 13.34; the closing total on the same games has MAE 10.35 and RMSE 11.60. The projection and the closing spread disagreed on 41 games, and 28 landed (68.29%). 52.4% is the -110 break-even. This live count does not replace the walk-forward result. The projection and the closing total disagreed on 45 games, and 18 landed (40.00%). 52.4% is the -110 break-even. This live count does not replace the walk-forward result. On 4 games the spread stored with the projection differs from the closing spread by at least 0.25 points. The grade uses the closing spread. 1 game had only a post-kickoff snapshot, left out. 32 games had no snapshot, left out. Weeks 1 and 2 are final with no pre-kick snapshot, so those weeks are not in these averages. The walk-forward measurement on 2199 games, 2018-2026, remains the bar: margin disagreement 50.07%, total disagreement 49.67%, projected margin MAE 10.23 against the closing line's 9.79. Both disagreement rates sit below the 52.4% break-even at -110. This grade does not replace that measurement.

Watchdog

The qa-watchdog stage counts these and points here. Each row is one open problem in qa_defects: a missed pre-kickoff run, a cron that will not fire, a session that has expired. It stays until a later pass no longer sees it.

SeverityWhatDetailSeen
warnconnection
compose-vs-database-url
docker-compose.yml publishes port 5435 but DATABASE_URL uses 5432. `docker compose up` would start a different database from the one the pipeline reads, and a wrong-host failure here looks like a wrong password.291
warnstale-pending
pipeline_components
1 pipeline component still not built: Media Production (Director of Media Production).291
warnstale-pending
agent_messages
1 message addressed to a component and never answered, the oldest since 10/2/2026, 4:56:09 PM ET: data-quality -> depth-charts: Week-4 UI gap: IR QB Jaxson Da.291
warnstale-pending
improvement_candidates
8 model-improvement candidate left undecideds, the oldest since 9/26/2026, 6:48:24 PM ET: proposed: Give the model room to disagree with the market; proposed: Per-game deadlines, not one weekly deadline; proposed: Report the disagreement rate on every pick set; proposed: Snapshot line movement instead of only the closing; proposed: Use the player and unit grades as model inputs; proposed: Weather at kickoff, not just the venue; testing: Grades plus injuries against the spread; testing: Revise picks against late-breaking information.291

Data Quality & Identity

Cross-cutting checks run after ingestion, over the whole database. Each one stores the number it actually measuredalongside the threshold it was compared against, so this is evidence rather than a green tick. A blocking failure stops the deploy; a warning ships and is shown. Last run 2026-10-19 06:17:12.096+00.

24/25 passing · 1 warning

CheckKindResultMeasuredThresholdWhat it means
depth_chart_ids_plausibleidentity · warningwarn101 2026 depth-chart id(s) point at players whose careers began before 2001 -- the source's own name-join. Left out of the grades, never re-matched by name.
defensive_stats_presentcompleteness · warningpass11102711110 players have real defensive production (92 of 272 games played, so the bar is 271)
drafted_players_listedcompleteness · warningpass00all 256 players drafted in 2026 are listed in the grades
injury_report_coveragecompleteness · warningpass282428/32 clubs have a real injury designation for week 6
kicking_stats_presentcompleteness · warningpass331033 kickers have attempted a field goal (92 of 272 games played, so the bar is 10)
kickoff_times_presentcompleteness · warningpass180180180/180 unplayed regular-season games carry a kickoff time (the scoreboard shows TBD without one)
market_lines_presentcompleteness · infopass107272107/272 2026 regular-season games have a posted spread. Lines are published a week or so out, so a low number early in the season is the source being honest, not a gap.
stadium_coordinatescompleteness · warningpass323232/32 clubs have real venue coordinates (a club without them shows no weather)
betting_sources_agreeconsistency · warningpass0014 board row(s); no game has Vegas, Kalshi and Polymarket more than 20 points apart
data_recently_refreshedfreshness · warningpass0.124schedule data was last fetched 0.1h ago (the deploy workflow re-ingests every 2 hours)
injury_reports_currentfreshness · warningpass2465-2026 injury reports are live (1789 from nflverse, 676 from espn)
stats_season_currentfreshness · warningpass20262025newest player-stats season is 2026; the schedule already runs to 2026. This is the exact failure that hid Jaxson Dart: stats a season behind while ingestion reported success.
current_club_countidentity · blockingpass323232 clubs on the 2026 schedule (the league has 32)
every_team_code_resolvesidentity · blockingpass00all 36 team codes are either a current club or resolve to one
external_vocabulary_matchedidentity · warningpass3232matched 32/32 ESPN clubs to ours by name
franchise_aliases_derivedidentity · infopass6-3 relocation(s), 1 duplicate abbreviation(s), 2 external abbreviation(s) -- all derived from real data, none hard-coded
injury_names_resolve_to_playersidentity · warningpass1.9106820/6954 injury-report names resolve to a player row; normalisation recovers 117 that an exact string match misses. The 134 that remain are real players with no recorded stats -- practice-squad and rookie linemen -- not bad data.
no_duplicate_club_namesidentity · blockingpass00every remaining club name maps to exactly one code
market_prices_coherentplausibility · blockingpass00every stored market price is a probability, and both sides of each game sum to roughly 1
scores_are_pairedplausibility · blockingpass00every played game has both scores
scores_in_rangeplausibility · blockingpass00no score outside 0-80 (the NFL record for a team is 72)
stat_lines_internally_consistentplausibility · blockingpass00no player has more completions than attempts, more catches than targets, more field goals made than attempted, or more punts inside the 20 than punts
games_reference_real_teamsreferential · blockingpass00no game(s) referencing a team code that does not exist
injuries_reference_real_teamsreferential · blockingpass00no injury row(s) on a team code that does not exist
stats_reference_real_teamsreferential · blockingpass00no player stat row(s) on a team code that does not exist

Franchise Identity (6 resolved)

The teams table holds 36 codes for 32 clubs, and different providers spell some of them differently. Every row below was derived from real data, not typed in: relocations from the schedule's own season spans, duplicate codes from clubs sharing a name with no games played, and external spellings by asking ESPN's public teams endpoint what it calls each club. The live scoreboard reads this table instead of the hand-written map it used to carry.

CodeResolves toKindEvidence
espn:LARLAexternal abbreviationESPN's public teams endpoint calls "Los Angeles Rams" LAR; we call it LA
espn:WSHWASexternal abbreviationESPN's public teams endpoint calls "Washington Commanders" WSH; we call it WAS
nflverse:LARLAduplicate abbreviationsame club name as LA ("Los Angeles Rams") and zero games under this code
nflverse:OAKLVrelocationlast played 2019 (344 games); LV debuts 2020 in the same division, no overlapping season
nflverse:SDLACrelocationlast played 2016 (298 games); LAC debuts 2017 in the same division, no overlapping season
nflverse:STLLArelocationlast played 2015 (282 games); LA debuts 2016 in the same division, no overlapping season

Feature Registry (32 features)

15,096 rows — one per team per game across 1999–2026 (7,548 games) — built by scripts/features/build-features.mjs. Nothing is imputed: a value that can't be computed from real data is left null, and the reason is stated below. Coverage is measured at build time, not asserted. Form, Elo and season-to-date splits are computed strictly from games played before each row's own game, so a backtest can't score itself with results it wouldn't have had.

FeatureCoverageWhat it isWhy any of it is missing
coach_exp_diff100%This coach's career games minus the opposing coach's. Positive means the more experienced sideline.The matchup version of experience -- what the owner asked for: proven against unproven.
coach_games100%Games this head coach had coached BEFORE this one, across his whole career. Experience, counted rather than assumed.A first-year coach and a twenty-year coach are not the same input, and the log knows which is which.
elo_diff100%elo_pre minus the opponent's, with the home side credited the standard 55-point field advantage.Nothing missing.
elo_pre100%This team's Elo rating entering the game, replayed chronologically from real results only.Nothing missing.
is_division_game100%Both clubs are in the same division.Nothing missing.
is_home100%Whether this team is the home side.Nothing missing.
off_bye100%Playing on 10 days' rest or more.NULL wherever rest_days is NULL.
rest_days100%Days since this team's previous game of any type.NULL for a team's first game on record, which has no previous game to measure from.
short_week100%Playing on 5 days' rest or fewer (Thursday games, mostly).NULL wherever rest_days is NULL.
indoor100%The game is played under a roof.NULL for a retractable-roof venue whose game-day state is not published yet -- open or closed is genuinely not known in advance.
form_point_diff_599%Average points scored minus allowed over the previous 5 completed games.NULL before a team has played 5 games on record.
form_win_pct_599%Win rate over this team's previous 5 completed games.NULL before a team has played 5 games on record.
spread_line98%Closing spread from THIS team's perspective; negative means favoured.NULL until a line is posted, which is roughly a week before kickoff, and absent entirely for older seasons the source does not carry.
total_line98%Posted over/under for the game.Same posting delay as spread_line.
won98%The real outcome. Not a model input -- the label a backtest scores against.NULL for any game that has not been played, which is the point.
travel_km94%Great-circle distance from this team's own stadium to the venue; 0 for the home side.NULL when either club has no venue coordinates on file.
points_against_avg94%Points allowed per game so far this season, entering this game.NULL for a season opener.
points_for_avg94%Points scored per game so far this season, entering this game.NULL for a season opener.
season_win_pct94%Win rate so far this season, entering this game.NULL for a team's season opener, which has no prior games that season.
coach_win_pct82%This head coach's career win percentage going INTO this game. Null until he has coached a full season, because a 2-1 start is not a record.Computed strictly from earlier games, so a coach's later success cannot inform an earlier prediction.
market_win_prob72%Moneyline win probability with the bookmaker's margin removed by normalising both sides.NULL wherever either moneyline is missing. This is the single strongest predictor measured on this dataset -- kept as a benchmark any model has to beat, not as a crutch.
moneyline72%This team's American moneyline price.Same posting delay as spread_line.
coach_win_pct_diff70%This coach's career win percentage minus the opposing coach's.Null when either coach has under a season of games, rather than comparing against a number that does not exist yet.
inj_db_out63%Cornerbacks and safeties unavailable.Same coverage as injuries_out.
inj_dl_out63%Defensive linemen unavailable.Same coverage as injuries_out.
inj_lb_out63%Linebackers unavailable.Same coverage as injuries_out.
inj_ol_out63%Offensive linemen unavailable.Same coverage as injuries_out.
inj_qb_out63%Quarterbacks unavailable (Out, Doubtful or IR).Same coverage as injuries_out. Split out because a bare headcount treats a starting quarterback and a third-string guard as the same event -- measured, that count carried a fitted weight of -0.004, i.e. nothing.
inj_skill_out63%Running backs, receivers and tight ends unavailable.Same coverage as injuries_out.
inj_value_out63%Combined PRIOR-season fantasy production of the players who are unavailable -- how much the missing players actually did, not how many there are.Prior season, never the current one, since current-season totals include the games being predicted. Scores offensive skill positions only, because that is what the free stats feed measures -- a missing All-Pro cornerback appears in inj_db_out and contributes nothing here.
injuries_out63%Players listed Out or on Injured Reserve on that week's report.NULL for weeks with no published injury report -- the source starts in 2009, and reports do not exist outside game weeks.
injuries_questionable63%Players listed Questionable or Doubtful on that week's report.Same coverage as injuries_out.

This table is deliberately not a claim that these features predict anything. Measured on the completed games in it, the de-vigged market probability alone picks winners at 66.3% and the Elo baseline at 62.4% — a model built on the rest of these columns still has to beat the market number before it's worth trusting, and so far none has.

What the Components Told Each Other

These are real messages passed between pipeline components during actual runs — not a simulated conversation. The rule they are held to: a message only counts if something behaves differently because of it. So each one records whether it was acted on and what was actually done. A message nobody acted on shows as exactly that, because a bus where nothing is consumed is decoration. 40 of the last 40 were acted on.

From → ToKindWhat it saidWhat was done about it
editorial → anyoneannouncementstorylines published
39 storyline(s) written from measured data and other components' findings.
editorial: announcement -- states a fact, asks nothing of anyone
predictions → anyonefindingpicks re-checked against current inputs
2 pick(s) re-checked, 0 with moved inputs, 0 revised.
editorial: noted; no storyline warranted from this finding
predictions → anyonefindingmetric audit updated
26 metrics scored across 2319 completed games; 1 clear the null. Best: secondary_grade_diff at 52.4%.
editorial: noted; no storyline warranted from this finding
yahoo-ops → anyonefindingpool crowd split captured
PHI @ TEN: 13% on the home side; LAC @ BUF: 85% on the home side; SEA @ WAS: 15% on the home side
editorial: published the pool crowd lean on the front page
yahoo-ops → anyoneannouncementYahoo spreads available
93 game(s) carry the pool's own posted line -- ATS picks can be made against it.
yahoo-ops: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindinginjury source in use
1789 rows from nflverse, 676 rows from espn
editorial: noted; no storyline warranted from this finding
data-quality → anyoneannouncementfranchise identity resolved
6 alias(es) derived; 32 clubs on the 2026 schedule.
data-quality: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindingdepth_chart_ids_plausible
1 2026 depth-chart id(s) point at players whose careers began before 2001 -- the source's own name-join. Left out of the grades, never re-matched by name.
editorial: noted; no storyline warranted from this finding
editorial → anyoneannouncementstorylines published
39 storyline(s) written from measured data and other components' findings.
editorial: announcement -- states a fact, asks nothing of anyone
predictions → anyonefindingpicks re-checked against current inputs
2 pick(s) re-checked, 0 with moved inputs, 0 revised.
editorial: noted; no storyline warranted from this finding
predictions → anyonefindingmetric audit updated
26 metrics scored across 2319 completed games; 1 clear the null. Best: secondary_grade_diff at 52.4%.
editorial: noted; no storyline warranted from this finding
yahoo-ops → anyonefindingpool crowd split captured
PHI @ TEN: 13% on the home side; LAC @ BUF: 85% on the home side; SEA @ WAS: 15% on the home side
editorial: published the pool crowd lean on the front page
yahoo-ops → anyoneannouncementYahoo spreads available
93 game(s) carry the pool's own posted line -- ATS picks can be made against it.
yahoo-ops: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindinginjury source in use
1789 rows from nflverse, 676 rows from espn
editorial: noted; no storyline warranted from this finding
data-quality → anyoneannouncementfranchise identity resolved
6 alias(es) derived; 32 clubs on the 2026 schedule.
data-quality: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindingdepth_chart_ids_plausible
1 2026 depth-chart id(s) point at players whose careers began before 2001 -- the source's own name-join. Left out of the grades, never re-matched by name.
editorial: noted; no storyline warranted from this finding
editorial → anyoneannouncementstorylines published
39 storyline(s) written from measured data and other components' findings.
editorial: announcement -- states a fact, asks nothing of anyone
predictions → anyonefindingpicks re-checked against current inputs
2 pick(s) re-checked, 0 with moved inputs, 0 revised.
editorial: noted; no storyline warranted from this finding
predictions → anyonefindingmetric audit updated
26 metrics scored across 2319 completed games; 1 clear the null. Best: secondary_grade_diff at 52.4%.
editorial: noted; no storyline warranted from this finding
yahoo-ops → anyonefindingpool crowd split captured
PHI @ TEN: 13% on the home side; LAC @ BUF: 85% on the home side; SEA @ WAS: 15% on the home side
editorial: published the pool crowd lean on the front page
yahoo-ops → anyoneannouncementYahoo spreads available
93 game(s) carry the pool's own posted line -- ATS picks can be made against it.
yahoo-ops: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindinginjury source in use
1789 rows from nflverse, 676 rows from espn
editorial: noted; no storyline warranted from this finding
data-quality → anyoneannouncementfranchise identity resolved
6 alias(es) derived; 32 clubs on the 2026 schedule.
data-quality: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindingdepth_chart_ids_plausible
1 2026 depth-chart id(s) point at players whose careers began before 2001 -- the source's own name-join. Left out of the grades, never re-matched by name.
editorial: noted; no storyline warranted from this finding
editorial → anyoneannouncementstorylines published
39 storyline(s) written from measured data and other components' findings.
editorial: announcement -- states a fact, asks nothing of anyone
predictions → anyonefindingpicks re-checked against current inputs
2 pick(s) re-checked, 0 with moved inputs, 0 revised.
editorial: noted; no storyline warranted from this finding
predictions → anyonefindingmetric audit updated
26 metrics scored across 2319 completed games; 1 clear the null. Best: secondary_grade_diff at 52.4%.
editorial: noted; no storyline warranted from this finding
yahoo-ops → anyonefindingpool crowd split captured
PHI @ TEN: 13% on the home side; LAC @ BUF: 85% on the home side; SEA @ WAS: 15% on the home side
editorial: published the pool crowd lean on the front page
yahoo-ops → anyoneannouncementYahoo spreads available
93 game(s) carry the pool's own posted line -- ATS picks can be made against it.
yahoo-ops: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindinginjury source in use
1789 rows from nflverse, 676 rows from espn
editorial: noted; no storyline warranted from this finding
data-quality → anyoneannouncementfranchise identity resolved
6 alias(es) derived; 32 clubs on the 2026 schedule.
data-quality: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindingdepth_chart_ids_plausible
1 2026 depth-chart id(s) point at players whose careers began before 2001 -- the source's own name-join. Left out of the grades, never re-matched by name.
editorial: noted; no storyline warranted from this finding
editorial → anyoneannouncementstorylines published
39 storyline(s) written from measured data and other components' findings.
editorial: announcement -- states a fact, asks nothing of anyone
predictions → anyonefindingpicks re-checked against current inputs
2 pick(s) re-checked, 0 with moved inputs, 0 revised.
editorial: noted; no storyline warranted from this finding
predictions → anyonefindingmetric audit updated
26 metrics scored across 2319 completed games; 1 clear the null. Best: secondary_grade_diff at 52.4%.
editorial: noted; no storyline warranted from this finding
yahoo-ops → anyonefindingpool crowd split captured
PHI @ TEN: 13% on the home side; LAC @ BUF: 85% on the home side; SEA @ WAS: 15% on the home side
editorial: published the pool crowd lean on the front page
yahoo-ops → anyoneannouncementYahoo spreads available
93 game(s) carry the pool's own posted line -- ATS picks can be made against it.
yahoo-ops: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindinginjury source in use
1789 rows from nflverse, 676 rows from espn
editorial: noted; no storyline warranted from this finding
data-quality → anyoneannouncementfranchise identity resolved
6 alias(es) derived; 32 clubs on the 2026 schedule.
data-quality: announcement -- states a fact, asks nothing of anyone
data-quality → anyonefindingdepth_chart_ids_plausible
1 2026 depth-chart id(s) point at players whose careers began before 2001 -- the source's own name-join. Left out of the grades, never re-matched by name.
editorial: noted; no storyline warranted from this finding

Active (24)

Director of Betting Markets

Real Betting Markets -- scripts/ingestion/ingest-betting-markets.mjs

Director of Data Acquisition

Real Data Ingestion -- scripts/ingestion/ingest-teams-games.mjs

Director of Data Quality and Identity

Team Identity & Data Quality -- scripts/quality/data-quality.mjs -- derives the franchise alias table from real schedule spans and runs cross-cutting quality checks that record the number they measured.

Director of Availability

Depth Charts and Availability -- scripts/ingestion/ingest-depth-charts.mjs

Director of Editorial

Storyline Desk -- scripts/agents/editorial.mjs -- consumes what other components measured and turns it into storylines on the site. Deterministic sentences from real numbers, each carrying its own evidence; no language model, because the site builds in CI where none exists.

Director of Feature Engineering

Feature Registry -- scripts/features/build-features.mjs -- one row per team per game of real model inputs, with measured per-feature coverage in feature_registry.

Director of Football Research

Playoff Seeding Engine -- src/lib/playoffSeeding.ts

Director of Forecasting and Model Risk

Elo Baseline Model -- src/lib/elo.ts

Director of Player Evaluation

Player & Unit Grades -- scripts/ingestion/ingest-advanced-stats.mjs + scripts/model/grade-players.mjs -- snap counts and Pro Football Reference advanced stats turned into 1-100 percentile grades per player and per unit.

Director of Information Security

Security Audit & CSP -- docs/25-security.md, robots.txt, sitemap, CSP meta tag

Director of Live Statistics

In-Season Player Stats -- scripts/ingestion/ingest-live-stats.mjs

Media Director

Shared Design System -- src/layouts/Layout.astro (navy/red/gold, Oswald+Inter, card-based layout)

Director of Media Content

Player Stats & Standings -- scripts/ingestion/ingest-player-stats.mjs, src/pages/stats.astro, src/pages/standings.astro

Director of Decision Evidence

Pick Metric Audit -- scripts/model/snapshot-metrics.mjs

Director of Forecasting and Model Risk

Weekly Model Review & Edge Search -- scripts/model/review-picks.mjs grades every completed pick and separates model misses from market misses; scripts/model/find-edge.mjs tests candidate segments against the market every week and records what it finds, including the failures.

Director of Pipeline Orchestration

Pipeline Orchestrator -- scripts/orchestrator/run.mjs -- dependency-ordered stages with per-stage health gates, retries and recorded outcomes; runs unattended in CI on every push and on schedule.

Director of Platform and Reliability

Local Infra Health -- src/lib/db.ts (pooled connections used by every page and script) + the orchestrator's per-stage health gates, which are what actually verify infrastructure each run

Director of Player Evaluation

Player Evaluation Stats -- scripts/ingestion/ingest-player-evaluation.mjs -- Next Gen Stats, PFR weekly advanced stats, FTN charting, target-depth bands, kickoffs, and an on-field offensive-line pressure proxy. Stored for display and later tests. Not wired into score-ridge/v1, ats-grades+injuries/v1, or the grade SPECs.

Director of Position Grades

Position Rank Drivers -- scripts/model/build-position-rank-drivers.mjs -- explains each stored team_grade_weeks unit from players, week-bounded stats, and that week's injury report. Not an input to score-ridge/v1 or ats-grades+injuries/v1.

Director of Feature Engineering

Pre-kick Snapshots -- scripts/ingestion/snapshot-pre-kick.mjs

Director of Forecasting and Model Risk

Weekly Prediction Model -- scripts/model/predict-week.mjs -- trains on completed games and predicts the upcoming week; scripts/model/backtest.mjs walk-forward scores it against the market before anything ships.

Director of Testing and Quality Assurance

CI Pipeline -- .github/workflows/ci.yml

Director of Web Innovation

Sortable Data Tables -- public/js/sort-table.js

Director of Yahoo League Operations

Yahoo Pool Reader -- football-pool-auto-picker/scripts/capture-yahoo-week.mjs + scripts/ingestion/ingest-yahoo-pool.mjs -- reads the pool's own spread and pick distribution using the keyring session, read-only by construction. Writes stay gated on explicit owner approval.

Not Yet Built (1)

Per the spec's own framing: "hiring" means activating a real template. These roles have no real implementation behind them yet, so they're honestly listed as not hired rather than shown with invented activity -- and each one now states what is actually missing, so the list is something you can act on rather than a shrug.

Director of Media Production

Media Production -- src/layouts/Layout.astro -- Giants blue #0B2265 / red #A71930 on white, Oswald+Inter, sticky nav with measurement-driven overflow, card-based layout

Real CI History (Last 0 Runs)

RunResultWhen

Snapshotted via scripts/ops/snapshot-ci-status.mjs -- run manually, not live on every page load (the app doesn't hold a standing GitHub token).

Loading live game data…

View the live game on ESPN →

Live data from ESPN's public scoreboard API, fetched when you opened this — gridiron-local doesn't store or re-publish it.