feat: implement issue #598 — [Phase 1] Idempotency guard: never create a duplicate epic for the same idea - #620
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
More reviews will be available in 9 minutes and 40 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR implements an idempotency guard for the initiative-planner that prevents duplicate epic creation. When ChangesInitiative Planner Idempotency Guard
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
There was a problem hiding this comment.
Code Review
This pull request adds an idempotency guard to the initiative planner to prevent duplicate epic and DAG creation for the same idea discussion, along with corresponding unit tests. The feedback suggests wrapping the search query in literal double quotes in find_existing_epic to perform an exact phrase search, preventing unrelated issues from filling up the default 30-issue limit of gh issue list.
Dev-Lead — fix-reviews (applied)Changes committed and pushed. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
Dev-Lead — fix-bot-comment (no-changes)Agent reasoning |
|
Dev-Lead — review-changes (no-changes)No changes were needed for this PR. |
main shipped the prevent-duplicates idempotency guard (#620: find_existing_epic + the in-epic skip). The merge left two parallel guards. Collapse to one: - Drop the duplicate find_existing_initiative_epic and the separate top-of-file gate; keep main's find_existing_epic as the single detector. - Graft the net-new behavior onto main's guard: FORCE_REPLAN=1 records the existing epic for supersede and continues; the default skip now also posts an "already planned" discussion comment with a force_replan hint. - list_sub_issue_numbers uses main's DRY_RUN stub convention (DRY_RUN_EXISTING_SUBISSUES) instead of a bespoke override. - Tests repointed to DRY_RUN_EXISTING_EPIC / DRY_RUN_EXISTING_SUBISSUES; the first reframed to assert the skip-path discussion comment (main's test already covers no-creation). shellcheck clean; 28/28 bats pass. https://claude.ai/code/session_014djuNDBa3GASVDLQPXXg9L
* initiative-planner: idempotent re-plans with opt-in supersede Re-approving / re-dispatching / re-toggling the label on an already-planned discussion previously relied on the BMAD agent choosing not to re-create the epic — a fragile guard the agent even mis-described as built-in when it was not. The result was silent no-ops (discussion #653) with no audit trail and a latent risk of duplicate epics. Make apply-plan.sh own this decision deterministically via the back-reference it already stamps on every epic ("Planned from idea discussion #<src>"): - Default: if an OPEN `initiative` epic already exists for the discussion, create nothing and point the discussion back at it. - FORCE_REPLAN=1 (new `force_replan` workflow input): supersede instead — build the fresh epic/DAG, then CLOSE (never delete) the old epic and its sub-issues with a "superseded by #NEW" note so history and inbound references stay resolvable. The planner prompt now always runs apply-plan.sh and defers the create/skip/supersede decision to the script. Read-path helpers honor DRY_RUN/test overrides so the offline suite stays network-free. Adds bats coverage for the guard no-op, the supersede path, and force_replan with nothing to supersede. https://claude.ai/code/session_014djuNDBa3GASVDLQPXXg9L * initiative-planner: address review — bound issue list, harden supersede loop - find_existing_initiative_epic: add `--limit 1000` to `gh issue list`. The default cap of 30 would miss an existing epic once the repo has >30 open `initiative` issues (it already has 80+), silently defeating the guard and risking duplicate epics. - supersede loop: capture sub-issue numbers via command substitution instead of process substitution so a failed lookup trips `set -e` and aborts, rather than silently skipping the sub-issue closes. https://claude.ai/code/session_014djuNDBa3GASVDLQPXXg9L * initiative-planner: reconcile with main's #620 guard — supersede only main shipped the prevent-duplicates idempotency guard (#620: find_existing_epic + the in-epic skip). The merge left two parallel guards. Collapse to one: - Drop the duplicate find_existing_initiative_epic and the separate top-of-file gate; keep main's find_existing_epic as the single detector. - Graft the net-new behavior onto main's guard: FORCE_REPLAN=1 records the existing epic for supersede and continues; the default skip now also posts an "already planned" discussion comment with a force_replan hint. - list_sub_issue_numbers uses main's DRY_RUN stub convention (DRY_RUN_EXISTING_SUBISSUES) instead of a bespoke override. - Tests repointed to DRY_RUN_EXISTING_EPIC / DRY_RUN_EXISTING_SUBISSUES; the first reframed to assert the skip-path discussion comment (main's test already covers no-creation). shellcheck clean; 28/28 bats pass. https://claude.ai/code/session_014djuNDBa3GASVDLQPXXg9L --------- Co-authored-by: Claude <noreply@anthropic.com>



Closes #598
Implemented by dev-lead agent. Please review.
Summary by CodeRabbit
New Features
Tests