bug: T4 rarity upgrade collision with live-series card updates #57

Closed
opened 2026-04-08 00:16:09 +00:00 by cal · 1 comment
Owner

Problem

post_player_updates() in batters/creation.py (line ~456) unconditionally overwrites rarity_id when the OPS-derived rarity differs from the current rarity. There is no check for refractor T4 rarity upgrades.

If a card reaches T4 and gets a rarity bump (e.g., Bronze → Silver), the next live-series pipeline run will overwrite it back to Bronze based on raw OPS. The player's earned progression silently disappears.

The Phase 2 Validation Spec (T4-3) documents this risk with three proposed resolution strategies, but none has been selected or implemented.

Impact

High — this is a trust violation. Players earn a reward through gameplay that is then silently reverted by an automated pipeline. Must be guarded before refractor ships to prod.

Scope

Touches both repos:

  • card-creation: post_player_updates() needs a guard to skip rarity overwrites for cards with active T4 refractor state
  • database: May need an API endpoint or flag to query whether a card has an active T4 rarity upgrade (or the guard could query the existing /api/v2/refractor/cards/{id} endpoint)

Proposed Solutions (from Phase 2 Validation Spec T4-3)

  1. Card-creation checks refractor state before overwriting rarity
  2. Database API rejects rarity downgrades on T4 cards
  3. Rarity upgrade stored as a separate field, composed at read time

Design decision needed on which approach.

References

  • card-creation/batters/creation.pypost_player_updates()
  • card-creation/docs/REFRACTOR_PHASE2_VALIDATION_SPEC.md — T4-3
  • database/app/services/refractor_boost.py — boost logic (writes current_tier, variant, fully_evolved but not rarity)
## Problem `post_player_updates()` in `batters/creation.py` (line ~456) unconditionally overwrites `rarity_id` when the OPS-derived rarity differs from the current rarity. There is no check for refractor T4 rarity upgrades. If a card reaches T4 and gets a rarity bump (e.g., Bronze → Silver), the next live-series pipeline run will overwrite it back to Bronze based on raw OPS. The player's earned progression silently disappears. The Phase 2 Validation Spec (T4-3) documents this risk with three proposed resolution strategies, but none has been selected or implemented. ## Impact **High** — this is a trust violation. Players earn a reward through gameplay that is then silently reverted by an automated pipeline. Must be guarded before refractor ships to prod. ## Scope Touches both repos: - **card-creation**: `post_player_updates()` needs a guard to skip rarity overwrites for cards with active T4 refractor state - **database**: May need an API endpoint or flag to query whether a card has an active T4 rarity upgrade (or the guard could query the existing `/api/v2/refractor/cards/{id}` endpoint) ## Proposed Solutions (from Phase 2 Validation Spec T4-3) 1. Card-creation checks refractor state before overwriting rarity 2. Database API rejects rarity downgrades on T4 cards 3. Rarity upgrade stored as a separate field, composed at read time Design decision needed on which approach. ## References - `card-creation/batters/creation.py` — `post_player_updates()` - `card-creation/docs/REFRACTOR_PHASE2_VALIDATION_SPEC.md` — T4-3 - `database/app/services/refractor_boost.py` — boost logic (writes `current_tier`, `variant`, `fully_evolved` but not rarity)
Claude added the
ai-working
label 2026-04-08 11:01:27 +00:00
Collaborator

PR #63 implements the T4 rarity guard using Strategy 1 from the validation spec.

Approach: Before each post_player_updates() call, the pipeline identifies players whose OPS-derived rarity would be a downgrade, batch-queries a new GET /api/v2/refractor/fully-evolved endpoint, and skips the rarity write for any T4-evolved players. All other rarity changes (upgrades and same-rarity) proceed normally.

Safe fallback: get_fully_evolved_players() returns an empty set on any API error, so the guard is a no-op until the database endpoint is added. No pipeline disruption.

Database work still needed: GET /api/v2/refractor/fully-evolved?player_ids=1,2,3{"player_ids": [...]} must be added to paper-dynasty-database. The guard activates automatically once it's wired up.

Bonus: RARITY_LADDER added to rarity_thresholds.py also covers the prerequisite for #59.

PR #63 implements the T4 rarity guard using Strategy 1 from the validation spec. **Approach:** Before each `post_player_updates()` call, the pipeline identifies players whose OPS-derived rarity would be a downgrade, batch-queries a new `GET /api/v2/refractor/fully-evolved` endpoint, and skips the rarity write for any T4-evolved players. All other rarity changes (upgrades and same-rarity) proceed normally. **Safe fallback:** `get_fully_evolved_players()` returns an empty set on any API error, so the guard is a no-op until the database endpoint is added. No pipeline disruption. **Database work still needed:** `GET /api/v2/refractor/fully-evolved?player_ids=1,2,3` → `{"player_ids": [...]}` must be added to `paper-dynasty-database`. The guard activates automatically once it's wired up. **Bonus:** `RARITY_LADDER` added to `rarity_thresholds.py` also covers the prerequisite for #59.
Claude added
ai-pr-opened
and removed
ai-working
labels 2026-04-08 11:09:40 +00:00
cal closed this issue 2026-04-08 12:26:00 +00:00
Sign in to join this conversation.
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: cal/paper-dynasty-card-creation#57
No description provided.