Skip to content

feat: portfolio_dispatch dedup — refuse a same-title open task (force=true overrides) (v0.14.6)#30

Merged
mabry1985 merged 1 commit into
mainfrom
feat/dispatch-dedup
Jul 3, 2026
Merged

feat: portfolio_dispatch dedup — refuse a same-title open task (force=true overrides) (v0.14.6)#30
mabry1985 merged 1 commit into
mainfrom
feat/dispatch-dedup

Conversation

@mabry1985

Copy link
Copy Markdown
Contributor

Closes #25. From Roxy's operational experience: she dispatched several Assess repo tasks that stacked up, because portfolio_dispatch had no guard against re-dispatching work already on the board.

Behavior

Before dispatching, portfolio_dispatch reads 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:

Skipped — a feature titled 'Assess repo' is already open on 'team-web' (bd-3, in_progress). … or pass force=true to dispatch a second copy anyway.

  • force=true dispatches a second copy anyway.
  • An unreadable board never blocks a dispatch (better a possible dup than a PM that can't dispatch).
  • Exact-after-normalize only — no fuzzy match; a false positive would silently drop a real task, worse than an occasional missed near-dup.

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

…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>
@protoquinn

protoquinn Bot commented Jul 3, 2026

Copy link
Copy Markdown

👀 Quinn is reviewing — verdict (PASS / WARN / FAIL) + findings to follow.

@mabry1985 mabry1985 merged commit 2968975 into main Jul 3, 2026
@mabry1985 mabry1985 deleted the feat/dispatch-dedup branch July 3, 2026 03:21

@protoquinn protoquinn Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 to portfolio_dispatch (+force param). Normalization is clean (trim/lower/collapse), terminal-lane skip is correct, fallthrough on _BoardUnavailable is 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.toml and protoagent.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 feats via or []), exception scope is appropriately narrow, and design decisions (exact match only, never-block-on-unreadable-board) are well-reasoned per #25.

— Quinn, QA Engineer

@protoquinn

protoquinn Bot commented Jul 3, 2026

Copy link
Copy Markdown

Submitted COMMENT review on #30.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant