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
4 changes: 3 additions & 1 deletion METHODOLOGY.md
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,9 @@ Q_i = mean of q_{i,h} over the three forwards

A provider's weight also reflects whether it shows up. Each scheduled observation marks every provider: 1 if it was read successfully and produced a price (a price held out by the outlier check of section 6.4 still counts as present when the provider's own vote priced the index, since the fence keeps a print out of the index, not out of the attendance record; when the fence-reject carry below substituted the vote instead, the provider counts absent — its receipt carries a `carried_vote_from` marker), 0 if it was read successfully and produced none, and unchanged if our own collection or parsing failed, since a provider is never penalized for our failure.

The attendance factor `A_i` is the exponentially weighted average of this series over the 90-day regression window, with its own attendance half-life, normalized so a provider present throughout has `A_i` = 1. A newly seated provider's scheduled observations before it joined count as 0, so its first print starts near zero; at the 6-hour half-life, sustained printing reaches full attendance in about two days.
On population-scaled marketplace lanes, a trusted thin-book print contributes its disclosed `population_scale` instead of 1. The scale is `min(machines/min_machines, hosts/min_hosts, 1)`, strictly positive and at most 1; `population_machines` and `population_hosts` describe that print's book. An absent scale means exactly 1. Carried re-casts never borrow the booked print's scale or create a new attendance credit.

The attendance factor `A_i` is the exponentially weighted average of this series over the 90-day regression window, with its own attendance half-life, normalized so a provider present at full credit throughout has `A_i` = 1. A newly seated provider's scheduled observations before it joined count as 0, so its first print starts near zero; at the 6-hour half-life, sustained printing reaches full attendance in about two days.

The missing print itself is handled by cause:

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ Before public launch, it selects the launch version. Each result reports the
version and `methodology_id`; observations before that version's effective time
are labeled `back-calculated`.

The raw inputs are disclosed prices and dispersions, recorded currency and FX,
The raw inputs include a trusted print's disclosed `population_scale` attendance
credit (exactly 1 when absent), alongside prices and dispersions, recorded currency and FX,
upstream status, carry basis, filter verdicts, timing, top-level flags, and
`calc_params`. On vote-pre-smoothing generations
(`calc_params.pre_smoothing_half_life_hours`, effective 2026-09-14) each voting
Expand Down
4 changes: 2 additions & 2 deletions scripts/verify_published_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ def _run_full(
else ""
)
print(
f" FIRST DIVERGENCE: {check.observed_at}{source} "
f"{divergence.quantity} derived {divergence.derived!r} "
f" FIRST DIVERGENCE: {check.observed_at} "
f"{divergence.quantity}{source} derived {divergence.derived!r} "
f"published {divergence.published!r}"
)
# Same summary shape as the receipts path below: the full re-derivation
Expand Down
24 changes: 18 additions & 6 deletions src/gpu_index/index/weights.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,23 @@ def new_weight_state() -> Dict[str, Any]:
}


def series_print(usd: Any, observation: Tuple[float, str]) -> Dict[str, Any]:
def series_print(
usd: Any, observation: Tuple[float, str], *, credit: Optional[float] = None
) -> Dict[str, Any]:
"""The ONE constructor for a weight-series price entry: a slot's
resolved USD print plus the trusted filter_observation value/currency
(native terms, the recorded-currency posture). resolve_slot_prints builds every
entry through here and the artifact pins the result verbatim
(weight_calc.slot_prints), so the series shape is structurally — not
just test-enforced — identical between the live path and replay."""
just test-enforced — identical between the live path and replay.

A thin book's disclosed population scale is fractional attendance credit.
Absent credit means exactly 1.0 and leaves legacy entries unchanged."""
native_price, native_currency = observation
return {"usd": usd, "native": native_price, "currency": native_currency}
entry = {"usd": usd, "native": native_price, "currency": native_currency}
if credit is not None:
entry["credit"] = float(credit)
return entry


def _ordinal(day: str) -> int:
Expand Down Expand Up @@ -1356,7 +1364,8 @@ def compute_attendance_view(

A_i = sum_{s not skip} w(s)*present_i(s) / sum_{s not skip} w(s)

where present_i(s) = 1 exactly when s sits in the source's
where present_i(s) is the print's credit (exactly 1 when absent)
when s sits in the source's
weight-state PRICES series (the trusted-print presence record --
accepted, sigma-fenced, and mismatch-pending prints alike), state-3
stamps (events code "sk") drop from numerator AND denominator (the
Expand Down Expand Up @@ -1459,7 +1468,7 @@ def compute_attendance_view(
continue
denominator += w
if s in series:
numerator += w
numerator += w * float(series[s].get("credit", 1.0))
factor = 1.0 if denominator == 0.0 else numerator / denominator
# The backward walk (docstring): skips consume nothing; the
# verdict LATCHES where the law resolves it, and the walk then
Expand Down Expand Up @@ -2071,11 +2080,14 @@ def advance_panel_weight_state(
prices = weight_state.setdefault("prices", {})
for sid in sorted(prints or {}):
entry = prints[sid]
prices.setdefault(sid, {})[obs_stamp] = {
stored = {
"usd": entry["usd"],
"native": entry["native"],
"currency": entry["currency"],
}
if "credit" in entry:
stored["credit"] = float(entry["credit"])
prices.setdefault(sid, {})[obs_stamp] = stored
vectors = weight_state.setdefault("vectors", {})
if vector:
vectors[obs_stamp] = dict(vector)
Expand Down
22 changes: 15 additions & 7 deletions src/gpu_index/published/full.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
compute_attendance_view,
compute_panel_weights,
new_weight_state,
series_print,
)
from gpu_index.published.artifacts import PublishedRecordError
from gpu_index.published.verify import (
Expand Down Expand Up @@ -309,11 +310,15 @@ def public_weight_print(receipt: dict, *, observed_at: str) -> dict:
f"{observed_at} {source_id}: the public FX rate is not a "
"positive finite number",
)
return {
"usd": float(price),
"native": native,
"currency": currency,
}
credit = receipt.get("population_scale")
if "population_scale" in receipt and (
not _is_number(credit) or not 0 < credit <= 1
):
raise FullReproductionRefusal(
"invalid_population_scale",
f"{observed_at} {source_id}: population_scale must be finite in (0, 1]",
)
return series_print(float(price), (native, currency), credit=credit)


def _first_divergence(
Expand Down Expand Up @@ -478,7 +483,7 @@ def reproduce_full_history(
) -> FullReproduction:
"""Derive target-day weights, votes, IQM, and index from raw public rows.

Optional comparison rows supply published outputs only; every derivation
Optional comparison rows supply published final outputs only; every derivation
input and state transition still comes from the version history.
"""
history = sorted(list(observations), key=_stamp)
Expand Down Expand Up @@ -692,7 +697,10 @@ def reproduce_full_history(
published_value = comparison.get("value_usd_gpu_hr")
published_band = comparison.get("stability_band_usd_gpu_hr")
divergence = _first_divergence(
comparison["receipts"],
# Versioned receipts describe this replay's intermediate
# outputs. As-published receipt copies can be absent or stale;
# only their immutable final values remain the target.
receipts,
block,
derived_weights,
derived_value=derived_value,
Expand Down
Loading
Loading