claude-home/paper-dynasty/2026-03-30.md
2026-04-02 20:48:06 -05:00

5.4 KiB

title description type domain tags
Refractor Phase 2: Integration — boost wiring, tests, and review Implemented apply_tier_boost orchestration, dry_run evaluator, evaluate-game wiring with kill switch, and 51 new tests across paper-dynasty-database. PRs #176 and #177 merged. context paper-dynasty
paper-dynasty-database
refractor
phase-2
testing

Refractor Phase 2: Integration — boost wiring, tests, and review

Date: 2026-03-30 Branch: feature/refractor-phase2-integration (merged to main) Repo: paper-dynasty-database

What Was Done

Full implementation of Refractor Phase 2 Integration — wiring the Phase 2 Foundation boost functions (PR #176) into the live evaluate-game endpoint so that tier-ups actually create boosted variant cards with modified ratings.

  1. PR #176 merged (Foundation) — Review findings fixed (renamed evolution_tier to refractor_tier, removed redundant parens), then merged via pd-ops
  2. evaluate_card(dry_run=True) — Added dry_run parameter to separate tier detection from tier write. apply_tier_boost() becomes the sole writer of current_tier, ensuring atomicity with variant creation. Added computed_tier and computed_fully_evolved to return dict.
  3. apply_tier_boost() orchestration — Full flow: source card lookup, boost application per vs_hand split, variant card + ratings creation with idempotency guards, audit record with idempotency guard, atomic state mutations via db.atomic(). Display stat helpers compute fresh avg/obp/slg.
  4. evaluate_game() wiring — Calls evaluate_card with dry_run=True, loops through intermediate tiers on tier-up, handles partial multi-tier failures (reports last successful tier), REFRACTOR_BOOST_ENABLED env var kill switch, suppresses false notifications when boost is disabled or card_type is missing.
  5. 79-sum documentation fix — Clarified all references to "79-sum" across code, tests, and docs to note the 108-total card invariant (79 variable + 29 x-check for pitchers).
  6. 51 new tests — Display stat unit tests (12), integration tests for orchestration (27), HTTP endpoint tests (7), dry_run evaluator tests (6). Total suite: 223 passed.
  7. Five rounds of swarm reviews — Each change reviewed individually by swarm-reviewer agents. All findings addressed: false notification on null card_type, wrong tier in log message, partial multi-tier failure reporting, atomicity test accuracy, audit idempotency gap, import os placement.
  8. PR #177 merged — Review found two issues (import os inside function, audit idempotency gap on PostgreSQL UNIQUE constraint). Both fixed, pushed, approved by Claude, merged via pd-ops.

Decisions

Display stats computed fresh, not set to None

The original PO review note suggested setting avg/obp/slg to None on variant cards and deferring recalculation. Cal decided to compute them fresh using the exact Pydantic validator formulas instead — strictly better than stale or missing values. Design doc updated to reflect this.

Card/ratings creation outside db.atomic()

The design doc specified all writes inside db.atomic(). Implementation splits card/ratings creation outside (idempotent, retry-safe via get_or_none guards) with only state mutations (audit, tier write, Card.variant propagation) inside the atomic block. This is pragmatically correct — on retry, existing card/ratings are reused. Design doc updated.

Kill switch suppresses notifications entirely

When REFRACTOR_BOOST_ENABLED=false, the router skips both the boost AND the tier_up notification (via continue). This prevents false notifications to the Discord bot during maintenance windows. Initially the code fell through and emitted a notification without a variant — caught during coverage gap analysis and fixed.

Audit idempotency guard added

PR review identified that RefractorBoostAudit has a UNIQUE(card_state_id, tier) constraint in PostgreSQL (from the migration) that the SQLite test DB doesn't enforce. Added get_or_none before create to prevent IntegrityError on retry.

Follow-Up

  • Phase 3: Documentation updates in card-creation repo (docs only, no code)
  • Phase 4a: Validation test cases in database repo
  • Phase 4b: Discord bot tier-up notification fix (must ship alongside or after Phase 2 deploy)
  • Deploy Phase 2 to dev: run migration 2026-03-28_refractor_phase2_boost.sql on dev DB
  • Stale branches to clean up in database repo: feat/evolution-refractor-schema-migration, test/refractor-tier3

Files Changed

paper-dynasty-database:

  • app/services/refractor_boost.py — apply_tier_boost orchestration, display stat helpers, card_type validation, audit idempotency guard
  • app/services/refractor_evaluator.py — dry_run parameter, computed_tier/computed_fully_evolved in return dict
  • app/routers_v2/refractor.py — evaluate_game wiring, kill switch, partial multi-tier failure, isoformat crash fix
  • tests/test_refractor_boost.py — 12 new display stat tests, 79-sum comment fixes
  • tests/test_refractor_boost_integration.py — 27 new integration tests (new file)
  • tests/test_postgame_refractor.py — 7 new HTTP endpoint tests
  • tests/test_refractor_evaluator.py — 6 new dry_run unit tests

paper-dynasty (parent repo):

  • docs/refractor-phase2/01-phase1-foundation.md — 79-sum clarifications
  • docs/refractor-phase2/02-phase2-integration.md — atomicity boundary, display stats updates