# Sacboyz NFL Framework Plan

## 1. Summary

This document defines the V1 technical and product plan for a new standalone Sacboyz Signals repo:

`sacboyz/nfl-picks`

The NFL arm should reuse the proven operating discipline from `sacboyz/mlb-picks` while adapting hard for football. The goal is not a raw pick feed. The goal is an education-first decision engine that explains why a play qualifies, why it does not qualify, and when the correct answer is `ABSTAIN / NO_PLAY`.

The core decision flow is:

1. Start with team context.
2. Build or load a conservative projection.
3. Compare projection to sportsbook line to determine projected side.
4. Check whether books agree.
5. Remove baby lines.
6. Evaluate matchup, role, injury, opportunity, and game script.
7. Line-shop at publish time.
8. Grade, review, fade, or abstain.

No code should be implemented until this plan has been reviewed and approved.

## 2. MLB Framework Findings To Reuse

The existing MLB framework has a mature architecture that should be reused where sport-agnostic:

- V3-style contracts: `SlateContext`, `MarketBlend`, `ModelProjection`, `EngineSignal`, and `EngineCandidate`.
- Unified `CandidateBet`-style object.
- Six visible checks: Baby Line, Model/Projection Edge, Books Agree, Matchup, Role/Injury, Game Script.
- Market lifecycle: `trusted`, `watch`, `research`, `paused`.
- Ranked output tiers, check bars, risk flags, audit page, tracker, market health.
- Python runner pattern.
- GitHub Actions CI and scheduled run pattern.
- Cloudflare Pages-compatible `docs/` publishing.
- American odds to implied probability math.
- Sportsbook consensus and best-line logic.
- Report cards, tables, sweep/audit views, and market-trust sections.

The NFL repo should feel like the football version of the Sacboyz operating system, not a disconnected rebuild.

## 3. MLB Patterns Not To Copy

Do not copy these MLB assumptions into NFL:

- Daily slate cadence.
- Per-plate-appearance or baseball sample logic.
- MLB weather weighting.
- Baseball-calibrated pace or run-environment math.
- MLB thresholds without NFL recalibration.
- Fast in-season threshold convergence.
- Trusted market status inherited from MLB.

NFL has weekly samples, short seasons, discrete game windows, injury volatility, and large role changes from inactives. Thresholds should be frozen harder and recalibrated less often than MLB.

## 4. V1 Projection Source Decision

V1 uses a conservative baseline projection layer built from:

- nflverse/nflreadpy-accessible historical data.
- Prior-season priors.
- Current usage when available.
- Vegas team totals and implied team points.
- Game script.
- Player role.
- Market anchors.
- Depth chart assumptions.
- Injury and inactive state.

Optional third-party projections can be imported later, but they are not required for V1.

Market-relative-only signals may exist as supporting context, but they cannot generate A/B graded plays without an independent projection.

## 5. Anti-Circular Grading Rules

The graded sportsbook line cannot be the sole source of edge.

This rule applies to both props and team totals:

- Market and team totals may help anchor a projection.
- The same line being graded cannot be the only reason the model creates an edge.
- Team-total edge must derive from independent inputs such as pace, opponent points allowed, projected efficiency, injuries, and game-script context.
- The framework must separate projection inputs from sportsbook confirmation.

Sportsbook markets confirm, challenge, or weaken the signal. They do not create the signal alone.

## 6. V1 Markets

V1 includes:

- Passing Yards
- Passing Attempts
- Passing Completions
- Passing TDs
- Passing Interceptions
- Rushing Yards
- Rush Attempts
- Receiving Yards
- Receptions
- Rush + Receiving Yards
- Anytime TD
- Moneyline
- Spread
- Game Total
- Team Total

Kickers and defense/special teams are explicitly deferred out of V1. They are V1.5/V2 only.

## 7. Team Bets In V1

Team bets should exist in V1, but cautiously.

V1 team bets include:

- Moneyline
- Spread
- Game Total
- Team Total

They primarily serve as game-script context at first. They may receive:

- `Lean`
- `Review`
- `No Play`

Do not promote team bets to `Top Pick` status until backtesting validates the framework.

Team totals are especially important as both:

- A team-bet lean tool.
- A game-script input for player props.

Team total logic should compare:

- Sportsbook team total line.
- Model projected team points.
- Difference.
- Projected side.
- Sportsbook favored side.
- Best available line.

## 8. Education-First Workflow

The NFL framework should not simply ask, "What does the model like?"

It should ask:

1. Is there a real projection edge?
2. Is the line big enough to avoid a baby-line bet?
3. Do books agree with the projected side?
4. Does the defensive matchup support it?
5. Do injuries, role, and opportunity support it?
6. Does game script support it?
7. Is the best available line still playable?
8. If any answer is weak, should this become Review-Only, Fade, or Abstain?

The best NFL plays are not just the highest projected differences. They are the plays where projection, market, matchup, role, game script, and price tell the same story.

## 9. Core Workflow

### 9.1 Start With Team Context

Before evaluating player props, inspect:

- Moneyline
- Spread
- Game total
- Team totals
- Implied team points
- Favorite/underdog status
- Expected game script
- Defensive matchup
- Injury context
- Weather
- Rest
- Venue
- Travel
- Short week / bye / off-bye

Team tools should paint the game script first. If a team is projected to win, expect more late rushing volume. If a team is projected to trail, expect more passing volume.

### 9.2 Use Projection vs Line To Determine Side

Projected side is determined by comparing model projection to sportsbook line:

- Projection above line = Over lean.
- Projection below line = Under lean.
- Difference = projection minus line.
- Difference percent = edge strength relative to line.

The projection creates the initial signal. The market then confirms, challenges, or weakens it.

### 9.3 Check Whether Books Agree

Convert American odds into implied probability:

- If Over has higher implied chance, books lean Over.
- If Under has higher implied chance, books lean Under.
- If both sides are priced evenly, books have no clear lean.

Strong plays occur when projected side and sportsbook implied side agree.

### 9.4 Remove Baby Lines

Avoid props where the bet is mostly about basic opportunity rather than production. The framework should prefer betting on what players do with opportunity, not whether they get any opportunity at all.

### 9.5 Scan Props In Repeatable Order

Suggested V1 scan order:

1. Receiving Yards
2. Rushing Yards
3. Passing Yards
4. Receptions
5. Rush Attempts
6. Pass Attempts
7. Pass Completions
8. Rush + Receiving Yards
9. Passing TD / Interceptions
10. Anytime TD

If no market has enough edge, return `ABSTAIN / NO_PLAY`.

### 9.6 Line-Shop

Line shopping is mandatory:

- For Overs, prefer lowest available line and best odds.
- For Unders, prefer highest available line and best odds.
- Display best book, best line, and best odds.
- Flag stale and outlier lines.
- Do not chase moved lines if the edge is gone.

## 10. Proposed Architecture

The NFL architecture should mirror the MLB operating spine:

`SlateContext -> Engines -> EngineCandidate/CandidateBet -> Six Checks -> Hidden Gates -> Market Status -> Ranked Report -> Tracker/Market Health`

### 10.1 Core Modules

1. `GameTeamEngine`
   - Moneyline, spread, game total, team total.
   - Team implied points.
   - Rest, travel, short week, bye/off-bye.
   - Pace, PROE, efficiency, injury-adjusted team strength.

2. `PlayerPropEngine`
   - Passing, rushing, receiving, and combined yardage/volume markets.

3. `AnytimeTDModule`
   - Separate high-variance module for Anytime TD.
   - Uses TD probability, price, red-zone/goal-line role, team total, and matchup.

4. `MarketLineEngine`
   - Odds math.
   - Book lean.
   - Multi-book consensus.
   - Best line.
   - Stale/outlier line detection.
   - Publish-time edge gate.

5. `ContextEngine`
   - DvP/matchup.
   - Role and usage.
   - Injuries and opportunity.
   - Defensive injury overrides.
   - Weather and venue.

6. `GameScriptModule`
   - Favorite/underdog script.
   - Pass/run expectation.
   - Team total support.
   - Correlation groups.

7. `GradingEngine`
   - Six visible checks.
   - Hidden sub-gates.
   - BetScore.
   - Grade/state.
   - Market lifecycle.

8. `Reporter`
   - Ranked plays.
   - Full sweep/audit.
   - Team context.
   - Player prop cards.
   - Injury/opportunity badges.
   - Line-shopping display.

## 11. Contract And Data Model Plan

### 11.1 NFL SlateContext

NFL `SlateContext` should include:

- games
- game windows
- kickoff times
- sportsbooks and odds markets
- player props
- team markets
- team totals
- implied team points
- weather
- venue
- rest/travel/bye context
- injuries
- official inactives
- depth charts
- player usage
- defensive matchup data
- defensive injuries
- projections
- market health
- prior-season priors
- current-season usage

### 11.2 NFL CandidateBet

Candidate fields should include:

- game_id
- season
- week
- game_window
- kickoff_time
- home_team
- away_team
- player_id
- player_name
- team
- opponent
- position
- market
- side
- line
- odds
- sportsbook
- best_book
- best_line
- best_odds
- line_at_grade
- line_at_publish
- projection
- projection_source
- projection_source_current
- projection_includes_injury_news
- projected_side
- raw_diff
- diff_pct
- edge_at_publish
- implied_over
- implied_under
- book_lean
- books_agree
- books_n
- books_lean_pct
- market_blend
- inactive_state
- injury_news_timestamp
- data_completeness
- confidence_tier
- correlation_group_id
- sos_adjusted
- defensive_rank
- matchup_color
- defensive_injury_matchup_delta
- role_opportunity_tag
- injury_opportunity_tag
- game_script_tag
- check_results
- hidden_gate_results
- risk_flags
- bet_score
- grade
- state
- market_status
- reasoning

### 11.3 Additional Injury/Opportunity Fields

Add:

- player_injury_status
- player_injury_designation
- player_expected_workload
- returning_from_injury
- teammate_absence_boost
- next_man_up_role
- depth_chart_role
- snap_share_before_injury
- projected_snap_share_after_injury
- target_share_boost
- rush_share_boost
- red_zone_role_boost
- goal_line_role_boost
- opponent_defensive_injuries
- opponent_secondary_injury_count
- opponent_front_seven_injury_count
- opponent_key_defender_out

## 12. Required Active Gates

These are mechanisms, not just fields.

### 12.1 Inactive State Machine

Define:

- `PRE_INACTIVES`
- `POST_INACTIVES_CONFIRMED`
- `POST_INACTIVES_INVALIDATED`

Official inactives drop around 90 minutes before kickoff. This must gate publication:

- No A grade may publish while `PRE_INACTIVES`.
- `POST_INACTIVES_CONFIRMED` means projection and role were validated against actual inactives.
- `POST_INACTIVES_INVALIDATED` means player inactive, role changed, or projection stale; force re-grade or `ABSTAIN`.
- Tie `injury_news_timestamp` and `projection_includes_injury_news` to this state machine.
- Projection predating official inactives is an automatic Review gate.

### 12.2 Publish-Time Line Gate

Re-evaluate best available line versus projection before publishing.

Store:

- `line_at_grade`
- `line_at_publish`
- `edge_at_publish`

If edge compresses below the stat-specific threshold, auto-demote to `Review` or `Abstain`.

Line shopping must be enforced, not display-only.

### 12.3 Correlation Guard

Assign `correlation_group_id` to related same-game candidates.

Rules:

- Correlated plays can support a game-script read.
- UI must warn users not to treat correlated plays as independent edges.
- Backtester must de-weight correlated outcomes so tracker win rate is not inflated.
- Logically contradictory same-game pairs are a hard-fade gate unless an explicit override exists.

Example contradiction:

- QB passing under plus that QB's WR receiving over.

### 12.4 Hidden Sub-Gates

Keep six visible checks for MLB continuity, but these hidden gates can independently force `Review`, `Fade`, or `Abstain`:

- Sample size.
- Line shopping.
- Inactive state.
- Projection latency.
- Correlation.
- Data completeness.
- Publish-time edge.

## 13. Six Visible Checks

1. Baby Line
2. Projection Edge
3. Books Agree
4. Defensive Matchup
5. Role / Injury / Opportunity
6. Game Script

The visible checks preserve the MLB/Sacboyz language. The hidden gates enforce NFL-specific discipline.

## 14. Grades, States, BetScore, And Confidence

Grade is authoritative. BetScore explains strength.

### 14.1 Grades And States

- `A`: 85-100, no hard-fade gates, no review gates, all core checks satisfied.
- `B`: 70-84, at most one caution flag.
- `Review-Only`: 45-69, or any review gate.
- `Fade`: 0-44, or any hard-fade gate.
- `ABSTAIN / NO_PLAY`: insufficient signal, no projection, efficient market, unsupported market, missing core data, failed `data_completeness`, or edge gone after line shopping.

Do not overload `Review-Only`.

- Review means "worth human review."
- Abstain means "no betting opinion."

### 14.2 Confidence Ladder

- `High`: projection source is current, post-inactives confirmed, sample/role stable, best line still playable, and no major injury/correlation/data warnings.
- `Medium`: usable projection and market data, but one uncertainty exists such as cold-start, pre-inactives, moderate sample, minor role uncertainty, or mixed matchup.
- `Low`: thin sample, stale/provisional projection, unclear role, missing non-core context, unresolved injury/news, or unstable line.

Low confidence cannot produce A/B.

### 14.3 Data Completeness

Minimum V1 completeness requires:

- usable game metadata
- player/team identity
- market line and odds
- projection source
- injury/inactive state
- team context
- enough role/sample data to evaluate the market

Missing any core field forces `ABSTAIN / NO_PLAY`.

Missing non-core context becomes `Low` confidence or `Review`.

## 15. Market Lifecycle

Every NFL market starts in `research` or `watch`.

No NFL market inherits `trusted` status from MLB.

Promotion to `trusted` requires minimum backtested sample and settled evidence.

V1 posture:

- Most player props: `watch`
- Anytime TD: `research`
- Team bets: `research/watch context`
- Kickers/DST: out of V1

## 16. Thresholds

All baby-line minimums and edge thresholds must live in config constants.

### 16.1 Baby-Line Defaults

- Receiving yards: line > 40
- Rushing yards: line > 40
- Passing yards: line > 200
- Receptions: line > 3
- Rush attempts: line > 7
- Pass attempts: line > 25
- Pass completions: line > 18
- Rush + receiving yards: own threshold
- Anytime TD: special high-variance logic, not normal baby-line logic

### 16.2 Edge Threshold Defaults

- General floor: 10%
- Receiving yards: 20%
- Passing yards: 15%
- Rushing yards: 25%
- Receptions: 22.5%
- Rush attempts: 15%
- Pass attempts: 15%
- Pass completions: 15%
- Rush + receiving yards: 20%
- Team markets: propose NFL-specific thresholds, but keep V1 team bets at Lean / Review / No Play until validated

The 22.5% receptions threshold is intentionally between the earlier 20-25% range and should be recalibrated after sufficient NFL tracking.

## 17. Cold Start Weeks 1-4

Weeks 1-4 should use:

- Prior-season priors.
- Regression to team/position baselines.
- Market/team-total anchors.
- Depth chart assumptions.
- Early usage where available.

Cap confidence at Medium unless role, snaps, usage, and health are stable.

Do not widen thresholds just to create action.

## 18. Role / Injury / Opportunity

This is one visible check backed by a full NFL module. NFL injuries create both risk and opportunity.

### 18.1 Offensive Injury Opportunity

Detect when injuries create added opportunity:

- Starting RB out -> backup RB may gain carries, routes, targets, goal-line work.
- WR1 out -> WR2, slot WR, or TE may gain target share.
- TE out -> slot WR or backup TE may gain routes/red-zone role.
- QB out -> downgrade passing props and possibly change rushing/short-area volume.
- Offensive line injuries -> downgrade rushing efficiency, passing efficiency, and QB pocket time.
- Multiple skill players out -> boost remaining usage but caution if offense quality drops too far.

Classify as:

- `Opportunity Boost`
- `Role Upgrade, Review`
- `Usage Unclear`
- `Offense Downgrade`

### 18.2 Defensive Injury Advantage

Detect opponent injuries that improve matchup:

- Elite CB out -> boost WR/receiving matchup.
- Multiple secondary starters out -> boost passing yards, receiving yards, receptions.
- Star safety out -> boost explosive passing/TD context.
- Defensive tackle/linebacker injuries -> boost rushing efficiency/RB props.
- Edge rushers out -> improve QB passing environment.
- Multiple front-seven injuries -> upgrade rushing/game-script support.
- Defensive injuries near goal line -> support RB/TE/ATD touchdown equity.

Classify as:

- `Opponent Injury Boost`
- `Opponent Injury Caution`
- `Mismatch Confirmed`
- `Mismatch Overstated`

### 18.3 Hard And Review Gates

Hard-gate or review-gate:

- Player returning from injury.
- Questionable/doubtful status.
- Unclear workload.
- Teammate returning who may reduce role.
- Backup elevated without role certainty.
- Projection source does not reflect injury news.
- Projection predates official inactives.
- Line moved before projection/role updated.

Boost/contextualize:

- Clear lead-back promotion.
- Injured teammate increasing target/rush share.
- Stable usage after role change.
- Projection already reflecting updated role.
- Defensive injury creates stat-specific matchup advantage.

## 19. Defensive Matchup

Normalize defensive rank so:

- Rank 1 = most favorable matchup / most production allowed.
- Rank 32 = least favorable matchup / least production allowed.

For Overs:

- Green = good.
- Orange = caution.
- Red = fade.

For Unders:

- Green = fade.
- Orange = caution.
- Red = good.

Matchup must be stat-specific:

- Receiving yards vs receiving yards allowed / pass defense.
- Rushing yards vs rushing yards allowed / run defense.
- Passing yards vs pass defense.
- Receptions vs catches allowed by position.
- Anytime TD vs red-zone/goal-line defense.

Use season-long and recent-form context, especially last 3 games, while avoiding overreaction to tiny samples.

Add:

- minimum-sample floor for recent matchup windows
- handling for byes
- handling for blowouts and garbage time
- defensive injury override that can move matchup one band up or down
- `sos_adjusted` flag where available

SOS-adjusted matchup is a V1.5 refinement if not available in V1.

## 20. Game Script

Reject or caution plays that contradict likely game script unless explicitly overridden.

Examples:

- Favorite RB rushing over can fit if the team should lead.
- Underdog QB passing volume can fit if the team should trail.
- Passing overs weaken in low-total, bad-weather, or elite pass-defense games.
- Rushing unders are dangerous against weak run defenses or favored scripts.
- Contradictory same-game cards are hard-fade unless explicit override exists.

## 21. Correlation Handling

In V1, correlation is both a warning and a context signal.

It can support a game-script read, but users must not treat correlated plays as independent edges.

Examples:

- QB passing over and WR1 receiving over can support a pass-heavy script.
- QB passing under and WR receiving over is contradictory unless a specific explanation exists.
- Game total over and multiple receiving overs share a correlated script.

Correlation should appear in:

- UI warnings.
- Audit JSON.
- Tracker rows.
- Backtest weighting.

## 22. Anytime TD

Treat Anytime TD separately from yardage props.

Clarify model probability vs book-implied probability:

- Model TD probability/projection is the signal axis.
- Book-implied probability/price is the value axis.

Rules:

- Prefer plus-money or fair payout where model probability exceeds book-implied probability.
- Avoid heavy juice unless every other signal is elite.
- Require red-zone/goal-line role.
- Require team-total support.
- Require strong projection and matchup context.
- Most ATD plays should be Review-Only unless stricter thresholds clear.

## 23. Weekly Cadence And Game Windows

NFL is window-based, not daily.

Plan for:

- Thursday
- Sunday early
- Sunday late
- Sunday Night Football
- Monday Night Football
- international games
- holiday games

Each window should have:

- stale-line rules
- inactive-state handling
- pre-inactives confidence caps
- post-inactives re-grade
- publish-time line check

## 24. Data Source Map

V1 should plan around:

- nflverse/nflreadpy for historical data, schedules, team/player stats, and available play-by-play/usage fields.
- nflfastR/nflverse data for play-by-play, EPA/WPA-style fields, participation where available, pace, and PROE.
- Sportsbook odds API for h2h, spreads, totals, team totals, and player props.
- Weather API for wind speed, wind direction, precipitation, temperature, and venue context.
- Official NFL injury/inactive data where available.
- Depth chart and injury feeds as secondary support where official data is incomplete.
- PFF/FTN-style premium fields as optional V1.5 enrichments, not V1 blockers.

## 25. UI / Report Plan

Report sections should include:

- Team context board.
- Team totals / game-script board.
- Player props board.
- Anytime TD section.
- Ranked candidates.
- Review-only signals.
- Abstain / No Play summary.
- Full candidate sweep.
- Audit page.
- Market trust tiers.
- Injury/opportunity diagnostics.
- Line-shopping table.
- Correlation warnings.
- Data readiness section.

Labels should include:

- Edge
- Signal
- Candidate
- Review
- No Play
- Risk Flag
- Best Line
- Market Confirmation
- Role Boost
- Next Man Up
- Opportunity
- Opponent Injury Boost
- Projection May Be Stale

Avoid:

- lock language
- guaranteed-win language
- parlay-first framing

The product is singles-first. Parlays are entertainment only.

## 26. Tracking And Backtesting Plan

Track outcomes by:

- sport
- season
- week
- game window
- stat type
- difference range
- book agreement
- matchup color
- game script type
- injury/opportunity tag
- grade
- confidence tier
- market status
- closing line movement
- result
- correlation group

Backtesting must de-weight correlated outcomes so tracker win rate is not inflated by same-script plays.

Use tracking to refine:

- thresholds
- baby-line rules
- market lifecycle
- top-pick eligibility
- injury/opportunity tags
- matchup colors
- game-script rules

## 27. Testing Plan

V1 planning should include tests for:

- American odds to implied probability.
- Projection vs line side selection.
- Books agree logic.
- Baby-line thresholds.
- Edge threshold config.
- Receptions threshold at 22.5%.
- Inactive state machine.
- No A grade before post-inactives confirmation.
- Publish-time line gate demotion.
- `ABSTAIN / NO_PLAY` state.
- Data completeness.
- Confidence tier eligibility.
- Role / Injury / Opportunity classifications.
- Defensive injury matchup override.
- Correlation group tagging.
- Contradictory same-game hard-fade.
- Team bet Lean / Review / No Play behavior.
- Anytime TD model probability vs book-implied probability.
- Weekly game-window handling.
- Tracker fields and correlation de-weighting.

## 28. Open Questions For Ryan / Sacboyz

These should be resolved before implementation:

1. Which sportsbook API(s) will be V1 source of truth for NFL props and team totals?
2. Which injury/inactive source should be authoritative for the 90-minute gate?
3. Should V1 publish pre-inactives reports with no A grades, or only publish after inactives for each game window?
4. What minimum backtest sample should promote a market from watch/research to trusted?
5. Should team bets ever become Top Pick eligible after validation, or remain context-only long term?
6. Which premium data sources, if any, are acceptable for V1.5 route participation, defensive injuries, and pressure data?
7. What exact bankroll/sizing language should the product use, if any?

## 29. Suggested Next Implementation Prompt

After this plan is reviewed and approved:

```text
Implement Phase 1 for sacboyz/nfl-picks.

Create the standalone repo scaffold and docs-only architecture foundation:
- Python project skeleton
- config constants for V1 markets, thresholds, confidence tiers, states, and market lifecycle
- engine contract dataclasses
- CandidateBet-style dataclass
- no live API calls yet
- mock/static data fixtures
- unit tests for odds math, grading states, inactive state, data completeness, and line-shopping gates

Do not implement production projections, live odds fetching, or report publishing yet.
```

## 30. Pre-Build Review Checklist

Before code begins, review:

- Projection source and anti-circular grading.
- Inactive state machine.
- Publish-time line gate.
- Correlation guard and backtest de-weighting.
- Confidence ladder.
- Data completeness.
- V1 market scope.
- Deferred kickers/DST.
- Team bet V1 posture.
- Role / Injury / Opportunity module.
- Threshold defaults.
- Weekly cadence.
- UI language.

Build should not begin until this checklist is approved.
