diff --git a/CHANGELOG.md b/CHANGELOG.md index 80fe055..30cabbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ This format follows Keep a Changelog principles and aims for Semantic Versioning - Link PRs/issues inline when helpful, e.g., (#123) or [#123]. Reference-style links at the bottom are encouraged for readability. ## [Unreleased] +_No unreleased changes._ + +## [2.3.0] - 2025-09-26 ### Added - Tests: added `test_random_reroll_throttle.py` to enforce reroll throttle behavior and `test_random_metrics_and_seed_history.py` to validate opt-in telemetry counters plus seed history exposure. - Random Mode curated theme pool now documents manual exclusions (`config/random_theme_exclusions.yml`) and ships a reporting script `code/scripts/report_random_theme_pool.py` (`--write-exclusions` emits Markdown/JSON) alongside `docs/random_theme_exclusions.md`. Diagnostics now show manual categories and tag index telemetry. diff --git a/RELEASE_NOTES_TEMPLATE.md b/RELEASE_NOTES_TEMPLATE.md index 194bf82..d283dc7 100644 --- a/RELEASE_NOTES_TEMPLATE.md +++ b/RELEASE_NOTES_TEMPLATE.md @@ -1,52 +1,85 @@ # MTG Python Deckbuilder ${VERSION} -## Unreleased (Draft) +## Summary +- Delivered multi-theme random builds with deterministic cascade, strict match support, and polished HTMX/UI flows. +- Added opt-in telemetry counters, reroll throttling safeguards, and structured diagnostics exports. +- Expanded tooling, documentation, and QA coverage for theme governance, performance profiling, and seed history management. +## Highlights +### Multi-theme random builds +- Primary/Secondary/Tertiary inputs with deterministic fallback cascade (P+S+T → P+S → P+T → P → synergy overlap → full pool). +- Strict match toggle persists across UI, API, permalink, and export flows with restored reroll parity and diagnostics integration. +- Auto-fill helpers for secondary/tertiary slots, a quick “Clear themes” control, and consistent multi-theme metadata across sessions, permalinks, exports, and metrics. + +### Telemetry & throttling +- Opt-in `RANDOM_TELEMETRY` counters capturing usage, fallback reasons, and seed history with NDJSON export endpoint. +- Reroll throttle enforcement with banner/countdown messaging plus override hooks for attempts and timeout controls. +- Expanded fast tests validating telemetry counters, throttle behavior, and reroll permutations. + +### Tooling & docs +- Random theme exclusion catalog with reporting script and documentation, alongside a multi-theme performance profiler and regression guard. +- Taxonomy snapshot tooling, splash penalty analytics, and governance documentation updated for strict alias and example enforcement. +- README, CHANGELOG, and release notes refreshed to cover the random modes feature set. + +### Observability & QA +- Diagnostics badge polish, recent/favorite seeds panel, seed history API, and structured logging for random builds. +- Sidecar exports include multi-theme metadata and locked commander indicators with consistent artifact sets. +- Manual QA checklist updates and broader pytest coverage for multi-theme flows, reroll behavior, performance, and telemetry. + +## Detailed changes ### Added - - Tests: added `test_random_reroll_throttle.py` to guard reroll throttle behavior and `test_random_metrics_and_seed_history.py` to verify opt-in telemetry counters and seed history API output. - - Analytics: splash penalty counters recognize both static and adaptive reasons; compare deltas with the flag toggled. -- Random Mode curated pool now loads manual exclusions (`config/random_theme_exclusions.yml`), includes reporting helpers (`code/scripts/report_random_theme_pool.py --write-exclusions`), and ships documentation (`docs/random_theme_exclusions.md`). Diagnostics cards show manual categories and tag index telemetry. -- Added `code/scripts/check_random_theme_perf.py` guard that compares the multi-theme profiler (`code/scripts/profile_multi_theme_filter.py`) against `config/random_theme_perf_baseline.json` with optional `--update-baseline`. -- Random Mode UI adds a “Clear themes” control that resets Primary/Secondary/Tertiary inputs plus local persistence in a single click. - - Diagnostics: Added `/status/random_theme_stats` and a diagnostics dashboard card surfacing commander/theme token coverage and top tokens for multi-theme debugging. - - Cache bust hooks tied to catalog refresh & tagging completion clear filter/preview caches (metrics now include last bust timestamps). - - Governance metrics: `example_enforcement_active`, `example_enforce_threshold_pct` (threshold default 90%) signal when curated coverage enforcement is active. - - Server authoritative mana & color identity fields (`mana_cost`, `color_identity_list`, `pip_colors`) included in preview/export; legacy client parsers removed. +- **Validation & telemetry tests** + - `test_random_reroll_throttle.py` guarding reroll throttle rules. + - `test_random_metrics_and_seed_history.py` verifying opt-in telemetry counters and seed history API output. + - `test_random_multi_theme_webflows.py` covering reroll-same-commander caching and permalink round-trips for multi-theme runs. + - `test_random_multi_theme_filtering.py` ensuring deterministic cascade across success tiers and sidecar metadata. + - `test_random_surprise_reroll_behavior.py` protecting Surprise Me input preservation and locked-commander cache reuse. +- **Random mode tooling & docs** + - Curated theme pool exclusions at `config/random_theme_exclusions.yml`, reporting helper `code/scripts/report_random_theme_pool.py --write-exclusions`, and companion docs in `docs/random_theme_exclusions.md`. + - Performance guard `code/scripts/check_random_theme_perf.py` comparing profiler output (`code/scripts/profile_multi_theme_filter.py`) with `config/random_theme_perf_baseline.json` (`--update-baseline` refreshes the file). + - Sidecar metadata now records primary/secondary/tertiary themes, resolved combos, fallback reason, and locked commander flag across summary payloads, permalinks, and exports. +- **UI & diagnostics enhancements** + - Auto-fill helpers for secondary and tertiary slots plus a single-click “Clear themes” control. + - Diagnostics endpoint `/status/random_theme_stats` surfacing commander/theme token coverage, attempts, timeout flags, and retries exhausted indicators. + - Diagnostics badges polished with icons/labels alongside a recent/favorite seeds panel and strict match toggle persistence. +- **Telemetry & throttling** + - Opt-in `RANDOM_TELEMETRY` usage counters, reroll fallback reasons, NDJSON export endpoint, and reroll throttle banner/countdown enforcement. +- **Governance & taxonomy tooling** + - Random theme exclusion catalog sidecars, taxonomy snapshot CLI (`code/scripts/snapshot_taxonomy.py`), splash penalty analytics, and governance docs covering strict alias enforcement and example minimums. + - Theme whitelist governance at `config/themes/theme_whitelist.yml`, curated+inferred synergy expansion, and tests such as `test_theme_whitelist_and_synergy_cap.py`. + - Editorial scripts for normalization, example padding, governance lint, and catalog merge pipeline (`code/scripts/build_theme_catalog.py`). +- **Dependencies & infrastructure** + - PyYAML optional dependency for governance parsing. ### Changed -### Added -- Tests: added `test_random_multi_theme_webflows.py` validating reroll-same-commander caching and permalink roundtrips for multi-theme runs across HTMX and API layers. -- Multi-theme filtering now reuses a cached lowercase tag column and builds a reusable token index so combination checks and synergy fallback avoid repeated pandas `.apply` passes; new script `code/scripts/profile_multi_theme_filter.py` reports mean ~9.3 ms / p95 ~21 ms cascade timings on the current catalog (seed 42, 300 iterations). -- Splash analytics updated to count both static and adaptive penalty reasons via a shared prefix, keeping historical dashboards intact. -- Random full builds internally auto-set `RANDOM_BUILD_SUPPRESS_INITIAL_EXPORT=1` (unless explicitly provided) to eliminate duplicate suffixed decklists. -- Preview assembly now pins curated `example_cards` then `synergy_example_cards` before heuristic sampling with diversity quotas (~40% payoff, 40% enabler/support, 20% wildcard) and synthetic placeholders only when underfilled. -- List & API filtering route migrated to optimized path avoiding repeated concatenation / casefolding work each request. -- Hover system consolidated to one global panel; removed fragment-specific duplicate & legacy large-image hover. Thumbnails enlarged & unified (110px → 165px → 230px). Hover activation limited to thumbnails; stability improved (no dismissal over flip control); DFC markup simplified to single with opacity transition. +- Multi-theme filtering now pre-computes lowercase token indices and reuses cached columns, reducing pandas `.apply` overhead (profiling mean ~9.3 ms / p95 ~21 ms at seed 42). +- Strict theme match toggle and auto-fill state persist across HTMX rerolls, API responses, full builds, sessions, permalinks, and exports. +- Random full builds enforce `RANDOM_BUILD_SUPPRESS_INITIAL_EXPORT=1` by default, eliminating duplicate suffixed decklists. +- Preview assembly pins curated `example_cards` and `synergy_example_cards` before heuristic sampling with diversity quotas; hover UI consolidated to one panel with resized thumbnails (110→165→230px) and keyboard-accessible DFC flip. +- List/API filtering path migrated to optimized fast filter (`filter_slugs_fast`) avoiding repeated concatenation and case folding per request. +- Splash analytics count both static and adaptive penalty reasons and share prefixes for continuity with existing dashboards. +- Cache bust hooks now clear filter/preview caches on catalog refresh or tagging completion; metrics expose `preview_last_bust_at` and warm cache stats. +- Theme normalization standardizes terms (ETB → Enter the Battlefield, Pillow Fort → Pillowfort, etc.), with synergy output capped at five entries (curated > enforced > inferred ordering). +- README, CHANGELOG, and governance docs updated to reflect new workflows, taxonomy snapshots, and telemetry controls. ### Deprecated -- Price / legality snippet integration deferred to Budget Mode. Any interim badges will be tracked under `logs/roadmaps/roadmap_9_budget_mode.md`. - - Legacy client-side mana/color identity parsers are considered deprecated; server-authoritative fields are now included in preview/export payloads. +- Price/legality snippet integration remains deferred to the future Budget Mode rollout (`logs/roadmaps/roadmap_9_budget_mode.md`). +- Legacy client-side mana and color identity parsers are deprecated in favor of server-authoritative fields included in preview/export payloads. ### Fixed -- Resolved duplicate template environment instantiation causing inconsistent navigation globals in picker fragments. -- Ensured preview cache key includes catalog ETag preventing stale samples after catalog reload. -- Random build duplicate decklist exports removed; suppression of the initial builder auto-export prevents creation of `*_1.csv` / `*_1.txt` artifacts. +- Resolved duplicate template environment instantiation that caused inconsistent navigation globals in picker fragments. +- Ensured preview cache keys include catalog ETag to avoid stale samples after catalog reloads. +- Suppressed legacy double-export path to prevent creation of `*_1.csv` / `*_1.txt` artifacts. +- Removed ultra-rare themes (frequency ≤1) unless protected via whitelist, keeping results focused on supported experiences. +- Corrected commander eligibility rules to restrict non-creature legendary permanents and honor “can be your commander” text. ---- +## Upgrade notes +- Enable multi-theme random builds via existing Random Mode flags; strict matching persists automatically across UI, API, permalink, and export contexts. +- Opt into telemetry by setting `RANDOM_TELEMETRY=1`; reroll throttle defaults are active but can be tuned through environment overrides. +- Refresh performance baselines with `code/scripts/check_random_theme_perf.py --update-baseline` when catalog changes materially affect timings. -### Added -- Theme whitelist governance (`config/themes/theme_whitelist.yml`) with normalization, enforced synergies, and synergy cap (5). -- Expanded curated synergy matrix plus PMI-based inferred synergies (data-driven) blended with curated anchors. -- Random UI polish: fallback notices gain accessible icons, focus outlines, and aria copy; diagnostics badges now include icons/labels; the theme help tooltip is an accessible popover with keyboard controls; secondary/tertiary theme inputs persist via localStorage so repeat builds start with previous choices. -- Test: `test_theme_whitelist_and_synergy_cap.py` validates enforced synergy presence and cap compliance. -- PyYAML dependency for governance parsing. - -### Changed -- Theme normalization (ETB -> Enter the Battlefield, Self Mill -> Mill, Pillow Fort -> Pillowfort, Reanimator -> Reanimate) applied prior to synergy derivation. -- Synergy output capped to 5 entries per theme (curated > enforced > inferred ordering). - -### Fixed -- Removed ultra-rare themes (frequency <=1) except those protected/always included via whitelist. -- Corrected commander eligibility: restricts non-creature legendary permanents. Now only Legendary Creatures (incl. Artifact/Enchantment Creatures), qualifying Legendary Artifact Vehicles/Spacecraft with printed P/T, or any card explicitly stating "can be your commander" are considered. Plain Legendary Enchantments (non-creature), Planeswalkers without the text, and other Legendary Artifacts are excluded. - ---- \ No newline at end of file +## Testing +```pwsh +pytest -q code/tests/test_random_reroll_throttle.py code/tests/test_random_metrics_and_seed_history.py +pytest -q code/tests/test_random_determinism.py code/tests/test_random_build_api.py code/tests/test_seeded_builder_minimal.py code/tests/test_builder_rng_seeded_stream.py +``` \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f78467a..5702970 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta" [project] name = "mtg-deckbuilder" -version = "2.2.10" +version = "2.3.0" description = "A command-line tool for building and analyzing Magic: The Gathering decks" readme = "README.md" license = {file = "LICENSE"}