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-30 13:37:02.598538+00, finished 2026-10-30 13:42:43.25863+00

StageStatusTriesTimeWhat the health gate measured
teams-and-gamesok110.8s36 teams, 7548 games, 164 upcoming games with a kickoff time
stadiumsok15.2s32 stadiums with real coordinates and roof types
player-statsok193.4s33915 stat rows, newest season 2026 with 1694 players
player-weeksok16.8s148122 player-week rows over 9 seasons
injuriesok12.5s94305 injury rows
depth-chartsok10.2s877 listed starters across 32 clubs, snapshot Thu Oct 29 2026
play-by-playok1132.5s1416 penalties across 108 game(s), all attributed to a known player
penalty-flagsdegraded12.8s8 completed season(s) on file; 104 of 108 completed 2026 game(s) collected -- the rest are not published on nflpenalties.com yet
odds-snapshotsok10.9s3859 line snapshot(s) on record; 14 of 14 game(s) in the next seven days have a recorded line
game-forecastsdegraded10.9s13 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.3s334685 snap rows, 7974 defensive and 2974 rushing advanced rows
gradesok12.8s1759 player grades across 9 position groups and 96 unit grades for 2026
weekly-gradesok137.4s2026 through week 8: 2068 players in 9 position groups, 32 clubs graded, 7 positions calibrated
position-rank-driversok12.5s2026 week 8: 319 driver rows across 10 units (10 graded)
schedule-strengthok10.5s2026 week 8: 2 team(s) with a recorded opponent, 1 completed game(s), 0 missing an opponent grade
team-writeupsok14.7s32 write-ups for 2026 week 8
coach-recordsok11.2s177 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-evaluationok114.7s11 NGS passing seasons, 219 2026 passing weeks, 3063 2026 PFR defensive player-games
yahoo-standingsok10.1s1 captured pool standing(s)
yahoo-poolok10.4s121 pool games across 8 week(s), 121 with a posted Yahoo spread
featuresok13.3s15096 team-game rows, 32 registered features
predictionsok10.3s14/14 games predicted for 2026 week 8 by 2 model(s), average confidence 60%
ats-picksok10.8s120/13 games picked against the pool's own line
score-predictionsok10.6s14/14 games projected for 2026 week 8
score-gradeok10.2s2026 week 7: 14 of 14 final games graded from a pre-kick snapshot; margin MAE 10.67 vs closing line 10.07; spread disagreement 5/14; under 30 disagreements, not a 52.4% test
pick-historydegraded10.5s120 picks on record, but only 107 of 108 finished games have one
tiebreakersok10.1s32 tiebreaker(s), each consistent with the pick for its game
pick-consistencyok10.1spools cross-checked: no Survivor pick contradicts our own forecast
pick-reviewok10.3s109/179 graded correct; 107 genuine disagreements with the market (64 right)
pool-reportok10.5s2026 weeks 1-7: 7 report cards, 107 graded picks, 61-44-2 against the Yahoo line
metric-audit-scoresok10.2s26 metrics scored individually; 2 clear the 50% null by more than noise
edge-searchok11.2s14 segments tested, 0 beyond noise
revise-picksdegraded10.4s175/208 picks carry the inputs they were made against; 87744 re-check(s) logged, 0 revision(s) -- some picks cannot be re-checked
crowd-analysisok10.1s121 game(s) with a pool crowd split analysed
live-statsok10.4s5004 player line(s) from 76 game(s), 37 still in progress
playoff-projectionok10.1s32 clubs projected; probabilities sum to 14 as they must
betting-marketsok11.3s88/13 upcoming games priced across 2 venue(s)
export-picksok10.1s13 pick(s) and 32 tiebreaker(s) exported for submission
pre-kick-snapshotsok11.7s2026 week 8: 13/13 unplayed game(s) have a snapshot (depth 5700, exchange 22678, injury 845, sportsbook 334, weather 116, yahoo-pool 169); 154 feature vector(s) stored
metric-auditok10.2s30 metrics x 32 clubs = 960 values; 192 missing and reported
editorialok10.3s39 storyline(s); 1120/1120 of today's messages consumed
schedule-planok10.2s118 kickoff slot(s) planned
qa-watchdogdegraded10.4s5 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.3snot 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 7 Week 7 of 2026, score-ridge/v1.1: 14 of 14 games have a projection from before kickoff. Projected margin MAE is 10.67 points and RMSE is 13.67; the closing spread on the same games has MAE 10.07 and RMSE 13.24. Projected total MAE is 10.57 points and RMSE is 12.48; the closing total on the same games has MAE 10.43 and RMSE 12.43. The projection and the closing spread disagreed on 14 games, and 5 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 2 games, and none landed. 2 is below the 30-game floor used before a rate is read against 52.4%, so this is not that test. The most-likely total in this version is the posted total stored with the snapshot. It is the ridge totals head only on a row that had no posted total, and that row is marked ridge. On 2 games 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 7 Through week 7 of 2026, score-ridge/v1.1: 28 of 60 games have a projection from before kickoff. Projected margin MAE is 8.93 points and RMSE is 11.14; the closing spread on the same games has MAE 8.36 and RMSE 10.83. Projected total MAE is 10.50 points and RMSE is 12.44; the closing total on the same games has MAE 10.43 and RMSE 12.42. The projection and the closing spread disagreed on 28 games, and 12 landed. 28 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 2 games, and none landed. 2 is below the 30-game floor used before a rate is read against 52.4%, so this is not that test. The most-likely total in this version is the posted total stored with the snapshot. It is the ridge totals head only on a row that had no posted total, and that row is marked ridge. On 3 games the spread stored with the projection differs from the closing spread by at least 0.25 points. The grade uses the closing spread. 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.1881
warnstale-pending
pipeline_components
1 pipeline component still not built: Media Production (Director of Media Production).1881
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.1881
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.1881
warnstale-pending
qa_defects
2 defect open for a month with no resolutions, the oldest since 9/26/2026, 8:45:15 PM ET: warn connection: compose-vs-database-url; warn stale-pending: pipeline_components.505

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-30 13:42:14.347+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 · warningpass11503181150 players have real defensive production (108 of 272 games played, so the bar is 318)
drafted_players_listedcompleteness · warningpass00all 256 players drafted in 2026 are listed in the grades
injury_report_coveragecompleteness · warningpass322432/32 clubs have a real injury designation for week 8
kicking_stats_presentcompleteness · warningpass331233 kickers have attempted a field goal (108 of 272 games played, so the bar is 12)
kickoff_times_presentcompleteness · warningpass164164164/164 unplayed regular-season games carry a kickoff time (the scoreboard shows TBD without one)
market_lines_presentcompleteness · infopass134272134/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 · warningpass3567-2026 injury reports are live (2417 from nflverse, 1150 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.9106865/7000 injury-report names resolve to a player row; normalisation recovers 125 that an exact string match misses. The 135 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
26 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 2335 completed games; 2 clear the null. Best: coach_record_diff at 52.5%.
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
121 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
2417 rows from nflverse, 1150 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
26 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 2335 completed games; 2 clear the null. Best: coach_record_diff at 52.5%.
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
121 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
2417 rows from nflverse, 1150 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
26 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 2335 completed games; 2 clear the null. Best: coach_record_diff at 52.5%.
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
121 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
2417 rows from nflverse, 1150 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
26 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 2335 completed games; 2 clear the null. Best: coach_record_diff at 52.5%.
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
121 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
2417 rows from nflverse, 1150 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
26 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 2335 completed games; 2 clear the null. Best: coach_record_diff at 52.5%.
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
121 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
2417 rows from nflverse, 1149 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.