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
| Stage | Status | Tries | Time | What the health gate measured |
|---|---|---|---|---|
| teams-and-games | ok | 1 | 10.0s | 36 teams, 7548 games, 180 upcoming games with a kickoff time |
| stadiums | ok | 1 | 1.0s | 32 stadiums with real coordinates and roof types |
| player-stats | ok | 1 | 84.4s | 33867 stat rows, newest season 2026 with 1646 players |
| player-weeks | ok | 1 | 6.2s | 147020 player-week rows over 9 seasons |
| injuries | ok | 1 | 0.8s | 93203 injury rows |
| depth-charts | ok | 1 | 0.1s | 877 listed starters across 32 clubs, snapshot Sun Oct 18 2026 |
| play-by-play | ok | 1 | 136.7s | 1231 penalties across 92 game(s), all attributed to a known player |
| penalty-flags | degraded | 1 | 14.2s | 8 completed season(s) on file; 77 of 92 completed 2026 game(s) collected -- the rest are not published on nflpenalties.com yet |
| odds-snapshots | ok | 1 | 0.8s | 2961 line snapshot(s) on record; 15 of 15 game(s) in the next seven days have a recorded line |
| game-forecasts | degraded | 1 | 0.9s | 8 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 |
| officials | ok | 1 | 1.6s | 3041 games with a crew on file, 3041 with a named referee |
| referee-tendencies | ok | 1 | 0.2s | 152 referee-seasons measured |
| advanced-stats | ok | 1 | 4.1s | 332075 snap rows, 7974 defensive and 2974 rushing advanced rows |
| grades | ok | 1 | 2.8s | 1662 player grades across 9 position groups and 96 unit grades for 2026 |
| weekly-grades | ok | 1 | 35.1s | 2026 through week 6: 2065 players in 9 position groups, 32 clubs graded, 7 positions calibrated |
| position-rank-drivers | ok | 1 | 2.7s | 2026 week 6: 320 driver rows across 10 units (10 graded) |
| schedule-strength | ok | 1 | 0.6s | 2026 week 6: 26 team(s) with a recorded opponent, 13 completed game(s), 0 missing an opponent grade |
| team-writeups | ok | 1 | 5.2s | 32 write-ups for 2026 week 6 |
| coach-records | ok | 1 | 1.3s | 177 head coaches, all 32 2026 clubs covered |
| data-quality | degraded | 1 | 0.7s | 25 checks, 0 failed, 1 warned, 0 waiting on a source; 6 franchise aliases derived |
| player-evaluation | ok | 1 | 15.1s | 11 NGS passing seasons, 188 2026 passing weeks, 2282 2026 PFR defensive player-games |
| yahoo-standings | ok | 1 | 0.1s | 1 captured pool standing(s) |
| yahoo-pool | ok | 1 | 0.3s | 107 pool games across 7 week(s), 93 with a posted Yahoo spread |
| features | ok | 1 | 3.1s | 15096 team-game rows, 32 registered features |
| predictions | ok | 1 | 0.3s | 14/14 games predicted for 2026 week 6 by 2 model(s), average confidence 60% |
| ats-picks | ok | 1 | 0.6s | 92/1 games picked against the pool's own line |
| score-predictions | ok | 1 | 0.5s | 14/14 games projected for 2026 week 6 |
| score-grade | ok | 1 | 0.2s | 2026 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-history | degraded | 1 | 0.5s | 92 picks on record, but only 91 of 92 finished games have one |
| tiebreakers | ok | 1 | 0.1s | 24 tiebreaker(s), each consistent with the pick for its game |
| pick-consistency | ok | 1 | 0.1s | pools cross-checked: no Survivor pick contradicts our own forecast |
| pick-review | ok | 1 | 0.3s | 87/148 graded correct; 92 genuine disagreements with the market (54 right) |
| pool-report | ok | 1 | 0.4s | 2026 weeks 1-5: 5 report cards, 79 graded picks, 47-31-1 against the Yahoo line |
| metric-audit-scores | ok | 1 | 0.2s | 26 metrics scored individually; 1 clear the 50% null by more than noise |
| edge-search | ok | 1 | 1.2s | 14 segments tested, 0 beyond noise |
| revise-picks | degraded | 1 | 0.2s | 119/152 picks carry the inputs they were made against; 51887 re-check(s) logged, 0 revision(s) -- some picks cannot be re-checked |
| crowd-analysis | ok | 1 | 0.1s | 107 game(s) with a pool crowd split analysed |
| live-stats | ok | 1 | 2.1s | 3956 player line(s) from 60 game(s), 25 still in progress |
| playoff-projection | ok | 1 | 0.1s | 32 clubs projected; probabilities sum to 14 as they must |
| betting-markets | ok | 1 | 0.7s | 60/1 upcoming games priced across 2 venue(s) |
| export-picks | ok | 1 | 0.1s | 1 pick(s) and 24 tiebreaker(s) exported for submission |
| pre-kick-snapshots | ok | 1 | 1.3s | 2026 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-audit | ok | 1 | 0.2s | 30 metrics x 32 clubs = 960 values; 194 missing and reported |
| editorial | ok | 1 | 0.2s | 39 storyline(s); 993/993 of today's messages consumed |
| schedule-plan | ok | 1 | 0.1s | 118 kickoff slot(s) planned |
| qa-watchdog | degraded | 1 | 0.4s | 4 warning defect(s), 0 repaired automatically |
| ci-history | degraded | 1 | 0.1s | no CI history -- the GitHub token was unavailable, so /ops shows an empty table honestly rather than a made-up pass rate |
| consistency | ok | 1 | 0.0s | referential and score checks passed |
| record-completion | ok | 1 | 0.2s | not 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.
| Severity | What | Detail | Seen |
|---|---|---|---|
| warn | connectioncompose-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 |
| warn | stale-pendingpipeline_components | 1 pipeline component still not built: Media Production (Director of Media Production). | 291 |
| warn | stale-pendingagent_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 |
| warn | stale-pendingimprovement_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
| Check | Kind | Result | Measured | Threshold | What it means |
|---|---|---|---|---|---|
depth_chart_ids_plausible | identity · warning | warn | 1 | 0 | 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. |
defensive_stats_present | completeness · warning | pass | 1110 | 271 | 1110 players have real defensive production (92 of 272 games played, so the bar is 271) |
drafted_players_listed | completeness · warning | pass | 0 | 0 | all 256 players drafted in 2026 are listed in the grades |
injury_report_coverage | completeness · warning | pass | 28 | 24 | 28/32 clubs have a real injury designation for week 6 |
kicking_stats_present | completeness · warning | pass | 33 | 10 | 33 kickers have attempted a field goal (92 of 272 games played, so the bar is 10) |
kickoff_times_present | completeness · warning | pass | 180 | 180 | 180/180 unplayed regular-season games carry a kickoff time (the scoreboard shows TBD without one) |
market_lines_present | completeness · info | pass | 107 | 272 | 107/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_coordinates | completeness · warning | pass | 32 | 32 | 32/32 clubs have real venue coordinates (a club without them shows no weather) |
betting_sources_agree | consistency · warning | pass | 0 | 0 | 14 board row(s); no game has Vegas, Kalshi and Polymarket more than 20 points apart |
data_recently_refreshed | freshness · warning | pass | 0.1 | 24 | schedule data was last fetched 0.1h ago (the deploy workflow re-ingests every 2 hours) |
injury_reports_current | freshness · warning | pass | 2465 | - | 2026 injury reports are live (1789 from nflverse, 676 from espn) |
stats_season_current | freshness · warning | pass | 2026 | 2025 | newest 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_count | identity · blocking | pass | 32 | 32 | 32 clubs on the 2026 schedule (the league has 32) |
every_team_code_resolves | identity · blocking | pass | 0 | 0 | all 36 team codes are either a current club or resolve to one |
external_vocabulary_matched | identity · warning | pass | 32 | 32 | matched 32/32 ESPN clubs to ours by name |
franchise_aliases_derived | identity · info | pass | 6 | - | 3 relocation(s), 1 duplicate abbreviation(s), 2 external abbreviation(s) -- all derived from real data, none hard-coded |
injury_names_resolve_to_players | identity · warning | pass | 1.9 | 10 | 6820/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_names | identity · blocking | pass | 0 | 0 | every remaining club name maps to exactly one code |
market_prices_coherent | plausibility · blocking | pass | 0 | 0 | every stored market price is a probability, and both sides of each game sum to roughly 1 |
scores_are_paired | plausibility · blocking | pass | 0 | 0 | every played game has both scores |
scores_in_range | plausibility · blocking | pass | 0 | 0 | no score outside 0-80 (the NFL record for a team is 72) |
stat_lines_internally_consistent | plausibility · blocking | pass | 0 | 0 | no 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_teams | referential · blocking | pass | 0 | 0 | no game(s) referencing a team code that does not exist |
injuries_reference_real_teams | referential · blocking | pass | 0 | 0 | no injury row(s) on a team code that does not exist |
stats_reference_real_teams | referential · blocking | pass | 0 | 0 | no 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.
| Code | Resolves to | Kind | Evidence |
|---|---|---|---|
espn:LAR | LA | external abbreviation | ESPN's public teams endpoint calls "Los Angeles Rams" LAR; we call it LA |
espn:WSH | WAS | external abbreviation | ESPN's public teams endpoint calls "Washington Commanders" WSH; we call it WAS |
nflverse:LAR | LA | duplicate abbreviation | same club name as LA ("Los Angeles Rams") and zero games under this code |
nflverse:OAK | LV | relocation | last played 2019 (344 games); LV debuts 2020 in the same division, no overlapping season |
nflverse:SD | LAC | relocation | last played 2016 (298 games); LAC debuts 2017 in the same division, no overlapping season |
nflverse:STL | LA | relocation | last 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.
| Feature | Coverage | What it is | Why any of it is missing |
|---|---|---|---|
coach_exp_diff | 100% | 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_games | 100% | 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_diff | 100% | elo_pre minus the opponent's, with the home side credited the standard 55-point field advantage. | Nothing missing. |
elo_pre | 100% | This team's Elo rating entering the game, replayed chronologically from real results only. | Nothing missing. |
is_division_game | 100% | Both clubs are in the same division. | Nothing missing. |
is_home | 100% | Whether this team is the home side. | Nothing missing. |
off_bye | 100% | Playing on 10 days' rest or more. | NULL wherever rest_days is NULL. |
rest_days | 100% | 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_week | 100% | Playing on 5 days' rest or fewer (Thursday games, mostly). | NULL wherever rest_days is NULL. |
indoor | 100% | 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_5 | 99% | Average points scored minus allowed over the previous 5 completed games. | NULL before a team has played 5 games on record. |
form_win_pct_5 | 99% | Win rate over this team's previous 5 completed games. | NULL before a team has played 5 games on record. |
spread_line | 98% | 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_line | 98% | Posted over/under for the game. | Same posting delay as spread_line. |
won | 98% | 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_km | 94% | 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_avg | 94% | Points allowed per game so far this season, entering this game. | NULL for a season opener. |
points_for_avg | 94% | Points scored per game so far this season, entering this game. | NULL for a season opener. |
season_win_pct | 94% | 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_pct | 82% | 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_prob | 72% | 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. |
moneyline | 72% | This team's American moneyline price. | Same posting delay as spread_line. |
coach_win_pct_diff | 70% | 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_out | 63% | Cornerbacks and safeties unavailable. | Same coverage as injuries_out. |
inj_dl_out | 63% | Defensive linemen unavailable. | Same coverage as injuries_out. |
inj_lb_out | 63% | Linebackers unavailable. | Same coverage as injuries_out. |
inj_ol_out | 63% | Offensive linemen unavailable. | Same coverage as injuries_out. |
inj_qb_out | 63% | 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_out | 63% | Running backs, receivers and tight ends unavailable. | Same coverage as injuries_out. |
inj_value_out | 63% | 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_out | 63% | 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_questionable | 63% | 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 → To | Kind | What it said | What was done about it |
|---|---|---|---|
editorial → anyone | announcement | storylines published 39 storyline(s) written from measured data and other components' findings. | editorial: announcement -- states a fact, asks nothing of anyone |
predictions → anyone | finding | picks 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 → anyone | finding | metric 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 → anyone | finding | pool 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 → anyone | announcement | Yahoo 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 → anyone | finding | injury source in use 1789 rows from nflverse, 676 rows from espn | editorial: noted; no storyline warranted from this finding |
data-quality → anyone | announcement | franchise identity resolved 6 alias(es) derived; 32 clubs on the 2026 schedule. | data-quality: announcement -- states a fact, asks nothing of anyone |
data-quality → anyone | finding | depth_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 → anyone | announcement | storylines published 39 storyline(s) written from measured data and other components' findings. | editorial: announcement -- states a fact, asks nothing of anyone |
predictions → anyone | finding | picks 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 → anyone | finding | metric 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 → anyone | finding | pool 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 → anyone | announcement | Yahoo 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 → anyone | finding | injury source in use 1789 rows from nflverse, 676 rows from espn | editorial: noted; no storyline warranted from this finding |
data-quality → anyone | announcement | franchise identity resolved 6 alias(es) derived; 32 clubs on the 2026 schedule. | data-quality: announcement -- states a fact, asks nothing of anyone |
data-quality → anyone | finding | depth_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 → anyone | announcement | storylines published 39 storyline(s) written from measured data and other components' findings. | editorial: announcement -- states a fact, asks nothing of anyone |
predictions → anyone | finding | picks 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 → anyone | finding | metric 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 → anyone | finding | pool 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 → anyone | announcement | Yahoo 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 → anyone | finding | injury source in use 1789 rows from nflverse, 676 rows from espn | editorial: noted; no storyline warranted from this finding |
data-quality → anyone | announcement | franchise identity resolved 6 alias(es) derived; 32 clubs on the 2026 schedule. | data-quality: announcement -- states a fact, asks nothing of anyone |
data-quality → anyone | finding | depth_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 → anyone | announcement | storylines published 39 storyline(s) written from measured data and other components' findings. | editorial: announcement -- states a fact, asks nothing of anyone |
predictions → anyone | finding | picks 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 → anyone | finding | metric 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 → anyone | finding | pool 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 → anyone | announcement | Yahoo 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 → anyone | finding | injury source in use 1789 rows from nflverse, 676 rows from espn | editorial: noted; no storyline warranted from this finding |
data-quality → anyone | announcement | franchise identity resolved 6 alias(es) derived; 32 clubs on the 2026 schedule. | data-quality: announcement -- states a fact, asks nothing of anyone |
data-quality → anyone | finding | depth_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 → anyone | announcement | storylines published 39 storyline(s) written from measured data and other components' findings. | editorial: announcement -- states a fact, asks nothing of anyone |
predictions → anyone | finding | picks 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 → anyone | finding | metric 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 → anyone | finding | pool 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 → anyone | announcement | Yahoo 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 → anyone | finding | injury source in use 1789 rows from nflverse, 676 rows from espn | editorial: noted; no storyline warranted from this finding |
data-quality → anyone | announcement | franchise identity resolved 6 alias(es) derived; 32 clubs on the 2026 schedule. | data-quality: announcement -- states a fact, asks nothing of anyone |
data-quality → anyone | finding | depth_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)
| Run | Result | When |
|---|
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).