docs: address PR #51 review — rarity naming, OPS threshold, truncation invariant

- Add rarity name cross-reference table in Background section mapping PRD
  display names (Replacement/Reserve/Starter/All-Star/MVP/Hall of Fame) to
  codebase names (Common/Bronze/Silver/Gold/Diamond/HoF) with IDs
- Fix T4-2: correct Gold OPS threshold from 0.700 to 0.900 (confirmed in
  rarity_thresholds.py); add note that 0.700 is the Bronze floor
- Fix T4-1: restate truncation invariant as a single precise assertion —
  sum(columns) == 108 - truncated_amount — instead of two independent checks
  that can both pass while the sum is wrong for unrelated reasons

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Cal Corum 2026-03-24 16:07:18 -05:00
parent f2c09d09e6
commit 6f67cfec9a

View File

@ -26,6 +26,21 @@ probability system: 2d6 x 3 columns x 6 rows). Each Refractor tier (T1 through T
accumulated budget across all four tiers is 4.0 chances, equal to approximately 3.7% of the
108-chance total (4 / 108 ≈ 0.037).
**Rarity naming cross-reference:** The PRD chapters (`prd-evolution/`) use the player-facing
display names. The codebase and this spec use the internal names from `rarity_thresholds.py`.
They map as follows:
| PRD / Display Name | Codebase Name | ID |
|---|---|---|
| Replacement | Common | 5 |
| Reserve | Bronze | 4 |
| Starter | Silver | 3 |
| All-Star | Gold | 2 |
| MVP | Diamond | 1 |
| Hall of Fame | HoF | 99 |
All rarity references in this spec use the codebase names.
Rarity IDs in the codebase (from `rarity_thresholds.py`):
| Rarity Name | ID |
@ -74,8 +89,12 @@ Verify:
**Expected Outcome:**
Sum remains 108 after every boost under non-truncation conditions. Under truncation conditions
(a column hits 0), the sum is reduced by the truncated amount — the implementation discards the
excess rather than redistributing it. No column value falls below 0.
(a column hits 0), the final column sum must equal exactly `108 - truncated_amount` — where
`truncated_amount` is the portion of the 1.0-chance budget that was dropped due to the 0-floor
cap. This is a single combined assertion: `sum(columns) == 108 - truncated_amount`. Checking
"sum <= 108" and "truncated amount was discarded" as two independent conditions is insufficient
— a test can pass both checks while the sum is wrong for an unrelated reason (e.g., a positive
column also lost value due to a bug). No column value falls below 0.
**Risk If Failed:**
@ -121,7 +140,9 @@ Worked example for validation reference:
The cumulative 4.0-chance shift produces a ~3.7% total movement from negative to positive
outcomes. No single outcome column increases by more than 2.5 chances across the full T4
journey under any profile. The card remains recognizably Bronze — it does not cross the Gold
OPS threshold (0.700 for 2024/2025 thresholds) unless it was already near the boundary.
OPS threshold (0.900 for 2024/2025 thresholds; confirmed in `rarity_thresholds.py`
`BATTER_THRESHOLDS_2024.gold` and `BATTER_THRESHOLDS_2025.gold`) unless it was already near
the boundary. Note: 0.700 is the Bronze floor (`bronze` field), not the Gold threshold.
**Risk If Failed:**