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
10 changes: 10 additions & 0 deletions compute/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,16 @@ def _fetch_one_form4(ticker: str) -> tuple[dict, float, bool]:
next_update_utc=_iso(now + timedelta(days=_next_business_day_offset(now))),
universe=config.UNIVERSE,
universe_size=len(summaries),
# Phase 4.6 (0.10.7-phase4.6) — survivorship-bias provenance per
# Research Report v1.0 §7.4. Forward cron's as-of is today, and
# the universe we just scored IS today's current S&P 500 — so
# the lookup is honest by definition. survivorship_bias_corrected
# = True signals "this output's universe assumption is honest for
# its as_of_date" (vs False = historical query that fell back to
# current). Backtest / validation callers populate these from
# ``compute.ingest.historical_universe.members_at()`` directly.
universe_membership_as_of=now.date().isoformat(),
survivorship_bias_corrected=True,
compute_run_id=os.environ.get("GITHUB_RUN_ID", "local"),
git_commit=(os.environ.get("GITHUB_SHA") or "unknown")[:40],
mos_trailing_ic_smoke=mos_ic,
Expand Down
41 changes: 41 additions & 0 deletions tests/test_output/test_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,47 @@ def test_write_metadata_json_tier2_disabled_round_trip(tmp_path):
assert payload["tier2_enabled"] is False


def test_write_metadata_json_universe_provenance_round_trip(tmp_path):
"""Phase 4.6 — `universe_membership_as_of` + `survivorship_bias_corrected`
survive the Pydantic → JSON round trip and stay accessible to the
verify-helper + downstream backtest consumers."""
meta = Metadata(
version="0.10.7-phase4.6",
last_update_utc="2026-05-27T22:00:00Z",
next_update_utc="2026-05-28T22:00:00Z",
universe="SP500",
universe_size=502,
compute_run_id="run-789",
git_commit="abc789",
universe_membership_as_of="2026-05-27",
survivorship_bias_corrected=True,
)
out = write_metadata_json(meta, tmp_path)
payload = json.loads(out.read_text())
assert payload["universe_membership_as_of"] == "2026-05-27"
assert payload["survivorship_bias_corrected"] is True


def test_write_metadata_json_universe_provenance_legacy_snapshot(tmp_path):
"""Pre-0.10.7 metadata.json shapes (no universe-provenance fields)
still serialize cleanly — the two new fields default to None and the
payload contains them as null."""
meta = Metadata(
version="0.10.6-phase4.5e",
last_update_utc="2026-05-26T22:00:00Z",
next_update_utc="2026-05-27T22:00:00Z",
universe="SP500",
universe_size=502,
compute_run_id="run-legacy",
git_commit="legacy0",
# universe_membership_as_of / survivorship_bias_corrected omitted
)
out = write_metadata_json(meta, tmp_path)
payload = json.loads(out.read_text())
assert payload["universe_membership_as_of"] is None
assert payload["survivorship_bias_corrected"] is None


def test_write_stock_detail_round_trip(tmp_path):
detail = StockDetail(
ticker="AAPL",
Expand Down