fix(tracker): converge hidden hand cards after target slots fill#22
Conversation
markRandomHandTransferCandidates now mirrors its per-seat quota into expectedSlotsByLocation ({fromSeat/hand: N-K, targetSeat/hand: K}). Hidden transfer entities get promoted to hand location candidates (with subZoneCandidates), which the seat-layer elimination deliberately skips; with no location-layer constraint the group could never prune their seat once the target's slots filled, so they kept an impossible candidate seat (130/131 stayed {2,3} after seat 3 was full).
removeCardsFromConstraintGroups already decrements expectedSlotsByLocation as members resolve and leave, so the mirrored quota drops to 0 and the location layer prunes the stale seat, converging them to seats=[2]. Counts were already correct; this only fixes the seats projection.
Flip the randomTransferLifecycle E2E star-assertion and end-state snapshot from the old [2,3] to the fixed [2]. 170 tracker tests, typecheck:tracker, lint, build:prod green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 50 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough修正随机手牌转移候选的 hand 位置槽位约束,使隐藏卡牌的候选席位从 Changes随机手牌转移候选修复
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request implements a targeted fix for the random hand transfer constraint resolution. Specifically, it updates markRandomHandTransferCandidates in src/tracker/roomMovement/candidates.ts to populate expectedSlotsByLocation alongside expectedSlotsBySeat. This ensures that when a seat's hand slots are fully occupied, location-level elimination correctly removes impossible seat candidates for hidden cards (e.g., converging to seats=[2] instead of incorrectly retaining [2, 3]). The implementation report and end-to-end lifecycle tests have been updated to reflect this fix and verify the correct convergence behavior. There are no review comments, so I have no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/agents/lifecycle.md`:
- Line 55: 更新 lifecycle 文档中关于 EXIT 阶段的描述,使其匹配 src/index.js 的实际顺序:先将
window.console.log 覆盖为 console.info,再向 SGSMODULE 元素广播 'EXIT',最后删除
SGSMODULE;将“清空还原”改为准确描述覆盖行为。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 21fc66a0-89a0-4599-bd2f-e0a7ca4fc040
📒 Files selected for processing (9)
CLAUDE.mddocs/agents/card_tracker.mddocs/agents/conventions.mddocs/agents/lifecycle.mddocs/agents/overview.mddocs/agents/serena.mdplans/anonymous-card-entity-optimization-plan.mdplans/random-hand-transfer-and-anonymous-entity-implementation-report.mdsrc/tracker/ConstraintGroup.ts
💤 Files with no reviewable changes (3)
- docs/agents/conventions.md
- plans/anonymous-card-entity-optimization-plan.md
- plans/random-hand-transfer-and-anonymous-entity-implementation-report.md
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
概述
⑤ 的长链路 E2E 暴露了一个收敛缺口:随机暗牌转移后,当目标座位手牌槽被明牌占满,来源两张暗牌仍保留不可能的目标座位候选(
seats=[2,3])。本 PR 定向修复该缺口,使其收敛为seats=[2]。base 为dev。根因(诊断确认)
转移约束组只声明了
expectedSlotsBySeat、缺expectedSlotsByLocation:subZoneCandidates)后,ConstraintGroup.resolve()的座位层消除(expectedSlotsBySeat分支)刻意跳过带subZoneCandidates的牌,交由位置层处理;明牌能收敛是走了 Room 的 known-only 排他分支;暗牌走不到那条分支,只能靠位置层——而位置层缺失。
修复
markRandomHandTransferCandidates(roomMovement/candidates.ts)建组时同步镜像一份 hand 位置约束:removeCardsFromConstraintGroups本就随成员解析离组同步扣减expectedSlotsByLocation,故明牌 42/46/47 解析到 seat3 离组后,seat3/hand名额降到 0,位置层消除即剔除 130/131 的 seat3 候选 →seats=[2]。计数层(unknownCardCount)一直正确,本次只修seats投影。测试
tests/tracker/randomTransferLifecycle.test.ts:★断言与终态 inline snapshot 由旧的[2,3]改锁[2];130/131 仍known:false(暗牌身份不泄露)。pnpm test:tracker— 23 文件 / 170 项通过(无回归)pnpm typecheck:tracker/pnpm lint/pnpm build:prod/git diff --check— 全通过范围说明
原设想的完整候选范围模型(
handSlotRange.ts、candidateMin/Max)经诊断确认与本验收目标正交(它管匿名实体物化计数,不管本处seats消除),未纳入本次改动;如需匿名计数精度可作单独后续。🤖 Generated with Claude Code
Summary by CodeRabbit