尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
An advanced-analytics site for one NFL team, built to answer the questions a fan
actually argues about — is my team good, is my quarterback good, how do we compare
to the league, how's the secondary — in a form you can read at a glance rather than
a spreadsheet you have to interpret.
Independent fan project, not affiliated with the NFL or any team. Stats from
nflverse (CC-BY 4.0), FTN charting data,
and public endpoints.查看完整 README ↗An advanced-analytics site for one NFL team, built to answer the questions a fan actually argues about — is my team good, is my quarterback good, how do we compare to the league, how's the secondary — in a form you can read at a glance rather than a spreadsheet you have to interpret.
Live: foxboro-files.vercel.app
Independent fan project, not affiliated with the NFL or any team. Stats from nflverse (CC-BY 4.0), FTN charting data, and public endpoints.
Eight pages covering team strength, per-game recaps, the upcoming matchup, schedule, roster and position grades, a quarterback deep dive, league-wide standings and every team's unit grades, and news. Units are graded out of 100 against the other 31 teams and ranks read "26th of 32", because "−0.15 EPA/play" means nothing to most people and "26th in the league" means everything. Tap a stat and it lists the plays behind it. After each game, What Stood Out lists up to three genuinely rare things — "the 3rd-best defensive game by any team this season", "the first win over PIT since 2023" — each a fixed check in code with its comparison shown, and nothing at all after an ordinary game.
Three things drive most of the value:
Opponent adjustment. A unit isn't judged on raw production — it's compared against what its opponents do in their other games. Shutting down a normally-explosive offense counts for more than shutting down a team that's bad against everybody. This is the same leave-one-out idea behind DVOA.
Prior-season blending, phased out. Through two games, pure current-season data is too noisy to make forward-looking claims from, so predictive numbers blend real 2025 performance, tapering to zero by game four. Descriptive numbers never blend. Which is which is documented per-page and labelled in the UI.
Honesty about what the data can't do. Free data still can't grade individual linemen or defensive backs — that needs every rep charted, which is PFF's business model. (nflverse's participation data shows who was on the field, not who won the rep, and isn't published until after a season.) So the team-unit cards are named for what they measure (Pass Defense, Pass Rush, Run Defense, Pass Protection) rather than for position groups they don't isolate.
data/generated/. Pages read static files; every stat window is precomputed
at build time. Nothing to provision, nothing to migrate, and the full history of every
number is in git.npm run build:data # fetch → build everything → verify
npm run build:data:skip-ai # same, without the AI narrative step
npm run verify:data # check committed data without rebuilding
npm test # unit tests
npm run calibrate:shrink 2025 # re-measure statistical constants off a finished season
scripts/build-all.ts orchestrates every build step off a single raw snapshot, so no
two outputs can be computed from different fetches. It hard-fails on the data steps and
fails soft on the AI step. Refreshes run on GitHub Actions: news every three hours, and
stats four times across the Sunday–Monday cycle plus daily, timed around when nflverse
finalizes play-by-play. A Sunday afternoon game is reflected on the site in about an
hour, including its generated recap.
Early on, three counting stats were wrong in a way no internal check could catch: the
site's numbers agreed with each other perfectly and didn't match football. A fumble on a
reception was attributed to nobody; fumbles lost were counted instead of fumbles; and
every QB scramble in the league was silently dropped, because nflverse leaves
rusher_id empty on those rows and only populates rusher_player_id.
scripts/verify-data.ts now diffs the site's rushing, receiving, passing, defensive and
kicking numbers against nflverse's own independent aggregation of the same games (QB
lines also against Next Gen Stats), alongside cross-file assertions (team EPA must match
the league rankings file to 1e-9; no fabricated position card may exist) and a check that
every "see the plays" list matches the number it opens from. CI gates on it. It caught a
fourth discrepancy within a minute of being written, and later a fifth: every QB's box
score counted sacks as pass attempts. Because nflverse's totals and Next Gen Stats land a
day after the play-by-play, a source that hasn't caught up is skipped with a notice rather
than failing the post-game refresh.
The same comparison also runs for every team in the league on each refresh
(scripts/league-audit.ts), as an early warning that never blocks. Only New England's
player lines are on the site, so a new kind of unusual play used to surface the first time
it happened in a Patriots game — a lateral in Week 5 froze the site for a day. Run
league-wide, it immediately found two more (an aborted snap credited to the center who
fumbled it, a lateral touchdown credited to the first receiver) that had already happened
to other teams. A player traded mid-season is compared on his combined line across both teams,
since that's what nflverse's season total is. The daily health check emails any mismatch.
The AI writes three things — a recap's short Take, the game preview, and the news digest —
from facts handed to it. Every draft passes narrow checks in code
(scripts/lib/aiChecks.ts), each added because that exact error shipped (a road game
placed in Foxborough, an invented first name, a wrong month). A draft that fails twice
isn't published, every attempt is logged to data/generated/ai-diagnostics*.json, and
each AI block has a "Flag it" link. The daily health check reads that log, so an expired API key — which otherwise just leaves recaps without a Take — emails the owner like any other failure. Everything else, including recap bullets and the
injury report, is computed in code.
scripts/lib/reliability.ts exists because shrinkage wasn't enough.
Regressing every team toward the league mean stops one small-sample team from outranking a well-measured one. It does not stop a ranking that is entirely noise — when the whole league is small-sample, every team is pulled by roughly the same weight, the ordering survives, and the table still looks authoritative.
Two games into the season, the receiver "hands" metric ranked New England 3rd in the league. Testing it properly: the spread observed between teams was smaller than random chance alone produces at those sample sizes — a reliability of 0.00. Flipping a single drop moved them from 3rd to 16th. So the site withholds the rank and shows raw counts until the metric earns one, with hysteresis on the threshold because replaying the completed 2025 season showed a single cutoff made the rank blink on and off week to week.
The same tooling measures the shrinkage constants against a finished season instead of leaving them as numbers picked by feel, and reports that RB and TE efficiency don't stabilize even across a full year — which is why those two cards carry a visible caveat rather than a confident grade.
npm install
npm run dev
The generated data in data/generated/ is committed, so the site runs immediately
without fetching anything. To refresh from source, run npm run build:data.
The AI writing (recap Takes, the game preview, the news digest, the Around the League
headline picker) uses one secret: ANTHROPIC_API_KEY, stored only in GitHub. Vercel
doesn't need it — the AI runs in the GitHub refresh jobs, and Vercel serves the finished
files. If the key expires or is deleted, nothing turns red and the site keeps its last good
text, but the daily health check opens an issue saying "API key rejected (HTTP 401)…
Replace ANTHROPIC_API_KEY" (first used for real on Oct 16, 2026).
ANTHROPIC_API_KEY → Update.