Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions DATA_PIPELINE_LINEAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,19 @@ Each copied observation receives an immutable provenance reference to the protec
source database and source row. The target database can be discarded and rebuilt
without altering the source.

For point-in-time safety, a copied row's `observed_at` is the latest valid UTC
timestamp among its source `received_at`, `result_available_at`, and `as_of`
fields—not the first non-empty field. The content digest commits to all three raw
timestamps, the derived knowledge time, and the derivation rule. A completed
result therefore cannot enter a projection before the source says that result was
available.

Rows with malformed or offset-free timestamps, source timestamps later than the
import receipt, missing final scores, or a final result-availability time before
the logical game start are rejected. Import receipts report per-reason quarantine
counts and a canonical digest of the rejected source-row set without modifying the
protected database.

## Explicit exclusions

The implementation does not copy or activate:
Expand All @@ -51,9 +64,26 @@ range fall back to bounded daily requests.
Provider availability is not guaranteed, and provider terms govern use. A fetch
failure stays visible as an ingest error and never becomes synthetic current data.

## Point-in-time DumbMoney export

Normalized game observations are append-only, content-addressed revisions.
The existing `games` table remains a compatibility view of the latest revision;
it is not the historical source of truth. Point-in-time projections select the
latest unambiguous revision received on or before the requested cutoff. A later
score, schedule change, or correction is retained but cannot leak into an older
forecast.

`SportsForecastEnvelopeV1` commits to the selected revision set and exports only
candidate research. Its three fixed authority fields prevent the envelope from
granting order or capital permissions. Source terms still govern use; the
envelope records references and limitations but does not grant redistribution
or model-training rights.

## Verification

Automated tests create temporary source and destination databases, verify that the
source bytes remain unchanged, exercise normalization and aliases, and inspect the
HTTP/API projection contracts. Operationally, recheck `git status` in Dummy after
an import and confirm it is clean.
HTTP/API projection contracts. They also prove deterministic envelope identity,
future-leakage rejection, contradiction and staleness handling, and append-only
revision retention. Operationally, recheck `git status` in Dummy after an import
and confirm it is clean.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,20 @@ selected teams, point-in-time history, model version, and seed.
| `GET` | `/api/v1/leagues/{league}/teams` | Current team picker |
| `GET` | `/api/v1/week` | Rolling current-week projection board |
| `POST` | `/api/v1/simulations/hypothetical` | Reproducible matchup simulation |
| `POST` | `/api/v1/exports/dumbmoney/sports-forecast` | Candidate-only point-in-time forecast envelope |
| `POST` | `/api/v1/data/refresh` | Bounded public schedule refresh |

OpenAPI is available at `/docs`.

The DumbMoney export is schema
`dumbmoney.sports-forecast-envelope.v1`. Its canonical SHA-256 identity commits
to the exact append-only observation revisions, cutoff, model/champion version,
seed, draw count, distributions, evidence, provenance, data-rights warnings,
expiry, and authority invariants. It always emits `candidate_only=true`,
`order_authority=false`, and `capital_authority=false`. It refuses future,
stale, ambiguous, in-progress, or completed target observations and contains no
wagering, brokerage, order, or capital interface.

## Determinism and governance

```mermaid
Expand Down
6 changes: 6 additions & 0 deletions src/universal_sports_engine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
simulate_many_analytical,
simulate_profile_analytical,
)
from universal_sports_engine.dumbmoney import (
DumbMoneyForecastExporter,
SportsForecastEnvelopeV1,
)
from universal_sports_engine.simulation import (
counterfactual_game,
simulate_game,
Expand All @@ -19,6 +23,8 @@
__all__ = [
"AdaptiveAnalyticalResult",
"AnalyticalResult",
"DumbMoneyForecastExporter",
"SportsForecastEnvelopeV1",
"counterfactual_game",
"simulate_analytical",
"simulate_ensemble_analytical",
Expand Down
8 changes: 8 additions & 0 deletions src/universal_sports_engine/data/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ class GameRecord:
payload_hash: str


@dataclass(frozen=True, slots=True)
class GameObservationRevision:
"""One immutable, content-addressed revision of a game observation."""

revision_id: str
game: GameRecord


@dataclass(frozen=True, slots=True)
class TeamRecord:
league: str
Expand Down
Loading