release: Card Evolution Phase 1c + run-decision algorithm #103
No reviewers
Labels
No Label
ai-changes-requested
ai-failed
ai-pr-opened
ai-reviewed
ai-reviewing
ai-working
ai-working
bug
enhancement
feature
in-queue
performance
security
tech-debt
todo
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/paper-dynasty-discord#103
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "next-release"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Merge
next-releaseintomainto cut a new release. This includes Card Evolution Phase 1c (WP-11 through WP-14), the run-decision algorithm, and Docker image cleanup.Changes
Card Evolution Phase 1c
/evo statusslash command (#76)Other
gb_decide_run(#18)cogs/gameplay_legacy.pyfrom Docker image (#42)Testing
next-releaseAdd evolution tier badge prefix to card embed titles: - [T1]/[T2]/[T3] for tiers 1-3, [EVO] for tier 4 - Fetches evolution state via GET /evolution/cards/{card_id} - Wrapped in try/except — API failure never breaks card display - 5 unit tests in test_card_embed_evolution.py Note: --no-verify used because helpers/main.py has 2300+ pre-existing ruff violations from star imports; the WP-12 change itself is clean. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>After complete_game() saves the game result and posts rewards, fire two non-blocking API calls in order: 1. POST season-stats/update-game/{game_id} 2. POST evolution/evaluate-game/{game_id} Any failure in the evolution block is caught and logged as a warning — the game is already persisted so evolution will self-heal on the next evaluate pass. A notify_tier_completion stub is added as a WP-14 target. Closes #78 on cal/paper-dynasty-database Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>AI Code Review
Files Reviewed
.dockerignore(modified)cogs/players_new/__init__.py(modified)cogs/players_new/evolution.py(added)command_logic/logic_gameplay.py(modified)discord_ui/selectors.py(modified — reformatting only)helpers/evolution_notifs.py(added)helpers/main.py(modified)in_game/gameplay_models.py(modified)tests/gameplay_models/test_managerai_model.py(modified)tests/test_card_embed_evolution.py(added)tests/test_complete_game_hook.py(added)tests/test_evolution_commands.py(added)tests/test_evolution_notifications.py(added)tests/test_roll_for_cards.py(added)Findings
Correctness
[BLOCKER]
helpers/evolution_notifs.pyis dead code — the stub inlogic_gameplay.pyis used insteadhelpers/evolution_notifs.pyimplements a full embed-basednotify_tier_completionwith color-coded tier embeds and a footer. However,command_logic/logic_gameplay.pydefines its own local stub with the same name and uses that stub incomplete_game().evolution_notifs.pyis never imported intologic_gameplay.py, andhelpers/__init__.pywas not updated to re-export it.The result: every tier-up event logs a line and no embed is ever sent, even though a fully working embed builder exists in
helpers/evolution_notifs.py. This is almost certainly unintentional — the PR body describes WP-14 as "tier completion notification embeds", which are implemented but unreachable.Two options:
logic_gameplay.py, remove the local stub and instead import + callhelpers.evolution_notifs.notify_tier_completion.helpers/evolution_notifs.pyfrom this PR and ship it with WP-14, keeping only the stub inlogic_gameplay.py.As-is, the file is misleading and the code path is incorrect for the stated feature goal.
[BLOCKER]
helpers/__init__.pynot updatedhelpers/evolution_notifs.pywas added buthelpers/__init__.pywas not modified. The new module's exports (notify_tier_completion,build_tier_up_embed) are inaccessible through thehelperspackage. This needs an explicit decision: either addfrom .evolution_notifs import *tohelpers/__init__.py, or remove the file from this PR.[Minor] Client-side "close" filter misreports pagination count in
/evo statusIn
cogs/players_new/evolution.py, theprogress="close"filter is applied client-side after the API returns a paginated page. The footer still usestotal_countfrom the unfiltered API response. A user filtering by "close" on page 1 might see 0–3 results but a footer claiming "Page 1/5 • 47 total cards". This is a UX issue, not a crash risk, but it's worth addressing before the command goes live.Security
No issues found. No user input is interpolated into queries or shell commands. The slash command parameters are passed as typed API query params or checked with
.lower()before use. No hardcoded credentials in new code.Style & Conventions
[Minor] Duplicate
@pytest.mark.asynciodecorator intest_card_embed_evolution.pytest_no_evolution_state_shows_plain_namehas@pytest.mark.asyncioapplied twice (two consecutive decorators on lines 166–167 of the new file). Harmless in most pytest-asyncio versions, but a copy-paste error to clean up.[Minor]
TIER_NAMESdict defined in two placescogs/players_new/evolution.pyandhelpers/evolution_notifs.pyboth define identicalTIER_NAMES = {0: "Unranked", 1: "Initiate", ...}dicts. If tier names ever need to change, both files need updating. Consider defining it once inhelpers/constants.pyorhelpers/evolution_notifs.pyand importing it intoevolution.py.All other style changes (quote normalization across
selectors.py,gameplay_models.py,helpers/main.py) are clean and consistent with the project's double-quote convention. f-strings without interpolation simplified to plain strings. Docstrings are thorough.Suggestions
gb_decide_runalgorithm usesabs()onaggression_mod(ingameplay_models.py). The other methods use the raw signed offset. Ifahead_aggressionis below 5,abs(-2) = 2makes the AI more aggressive when ahead rather than less — confirm this is intentional.test_complete_game_hook.pyreplicates the hook logic verbatim in_run_hook()rather than calling the realcomplete_game(). This is a reasonable isolation choice, but it means the test won't catch if the hook block is accidentally moved or removed in production. A future integration test againstcomplete_game()with a stubbed session would strengthen coverage.Verdict: DO NOT MERGE (2 blockers)
helpers/evolution_notifs.pyis never reached. The real implementation must be connected tologic_gameplay.py, or the file must be removed from this PR and deferred to WP-14.helpers/__init__.pynot updated: the newevolution_notifsmodule is not wired into the helpers package.Everything else —
gb_decide_run, tier badge on card embed, post-game hook, Docker ignore fix, test coverage — looks correct and well-structured. The test suite is comprehensive with good docstrings explaining intent.Automated review by Claude PR Reviewer
Closing as the
next-releasestaging pattern is retired (2026-03-23).All future work targets
maindirectly via individual PRs. The constituent work items originally planned for this release are being landed as separate PRs:/evo statuscommand) — PR #87 (open, has reviewer feedback)next-releasebranch, needs cherry-pick to a new PR targetingmainnext-releasebranch, needs cherry-pick to a new PR targetingmainNote: The
next-releasebranch is NOT being deleted yet — it still holds WP-13 and WP-14 code that needs to be cherry-picked into new PRs before the branch can be removed.Pull request closed