feat: portfolio_dispatch dedup — refuse a same-title open task (force=true overrides) (v0.14.6)#30
Merged
Merged
Conversation
…ce=true overrides (v0.14.6) Roxy dispatched several 'Assess repo' tasks that stacked up — the PM had no guard against re-dispatching work already queued. portfolio_dispatch now reads the team board first and refuses when a feature with the same (normalized) title is already OPEN — backlog/ready/in_progress/in_review/ blocked (a DONE task of the same title is legit re-work, so terminal lanes don't count). Naming the existing feature (id + lane) lets the PM re-read instead of duplicating. force=true dispatches a second copy anyway. An unreadable board never blocks a dispatch (better a possible dup than a stuck PM). Exact-after-normalize match only — no fuzzy (a false positive would silently drop a real task). Closes #25. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
👀 Quinn is reviewing — verdict (PASS / WARN / FAIL) + findings to follow. |
There was a problem hiding this comment.
QA Audit — PR #30 | feat: portfolio_dispatch dedup — refuse a same-title open task (force=true overrides) (v0.14.6)
VERDICT: WARN (CI still in progress; see Observations)
CI Status
- test: in_progress
Diff Review
__init__.py: Adds_norm_title,_open_duplicate, and a pre-flight dedup check toportfolio_dispatch(+forceparam). Normalization is clean (trim/lower/collapse), terminal-lane skip is correct, fallthrough on_BoardUnavailableis a sound "never block" safeguard.tests/test_portfolio.py: 3 new tests (normalization + open-lane match, dispatch refusal, force override). Existing dispatch test patched to return empty board. Tests are targeted and well-structured.- Version bump: 0.14.5 → 0.14.6 across
pyproject.tomlandprotoagent.plugin.yaml.
Observations
- GAP: clawpatch structural review unavailable — repo not in project registry. Diff-based review only.
- GAP: CI (
test) still in progress — formal PASS/FAIL deferred to re-review once checks terminal. - No unresolved CodeRabbit threads.
- Code quality is high: edge cases handled (empty/None features, whitespace-only titles, None
featsviaor []), exception scope is appropriately narrow, and design decisions (exact match only, never-block-on-unreadable-board) are well-reasoned per #25.
— Quinn, QA Engineer
|
Submitted COMMENT review on #30. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #25. From Roxy's operational experience: she dispatched several
Assess repotasks that stacked up, becauseportfolio_dispatchhad no guard against re-dispatching work already on the board.Behavior
Before dispatching,
portfolio_dispatchreads the team board and refuses when a feature with the same normalized title (trimmed / lowercased / whitespace-collapsed) is already open — backlog/ready/in_progress/in_review/blocked. A DONE task of the same title is legit re-work, so terminal lanes (done/cancelled/closed/merged) don't count. The message names the existing feature (id + lane) so the PM re-reads instead of duplicating:force=truedispatches a second copy anyway.Tests
_open_duplicate(open-lane-only, normalization, no-match) + dispatch refuses / force overrides / proceeds-on-unreadable-board. 116 tests pass; ruff clean. v0.14.5 → v0.14.6.🤖 Generated with Claude Code