Problem
Phase D's reviewed_prs dedup table is scoped per-agent:
```sql
unique(agent_id, owner, repo, pr_number)
```
This is the right scope when a user has one Code Review Engineer watching a repo. But once Phase C (#9) lands and users can hire multiple agents + subscribe each to a watched_repos row, nothing prevents two agents from watching the same (owner, repo). Both watchers would dedup independently → both review the same PR → user pays 2× tokens and gets duplicate/conflicting reviews on the PR.
Options
| Approach |
Behavior |
Trade-off |
A. Enforce uniqueness in watched_repos |
unique(user_id, owner, repo) — one agent per repo per user. 409 at subscribe time. |
Cleanest; surfaces the conflict early; matches user expectation. |
| B. Dedup at PR level not agent level |
Change reviewed_prs to unique(user_id, owner, repo, pr_number) — first watcher wins, others silently skip. |
Allows N watchers but is a silent footgun; user can't tell why a given agent never reviewed anything. |
| C. Let it happen |
Different agents → different memory → different reviews. |
Feels like a feature, but users will hate the bill and the duplicate reviews on the PR. |
Recommendation
Option A. Enforce at the watched_repos insert with a unique constraint on (user_id, owner, repo); return 409 when the conflict happens, with an error body naming the existing agent. We can revisit if users actually ask for multi-agent overlap.
Done when
watched_repos migration includes unique(user_id, owner, repo).
POST /agents/{id}/watched-repos returns 409 with a meaningful error when the conflict triggers.
- A test exercises both the success and conflict path.
Depends on
- #9 — folds into the Phase C migration; do this in the same change rather than a follow-up.
Problem
Phase D's
reviewed_prsdedup table is scoped per-agent:```sql
unique(agent_id, owner, repo, pr_number)
```
This is the right scope when a user has one Code Review Engineer watching a repo. But once Phase C (#9) lands and users can hire multiple agents + subscribe each to a
watched_reposrow, nothing prevents two agents from watching the same(owner, repo). Both watchers would dedup independently → both review the same PR → user pays 2× tokens and gets duplicate/conflicting reviews on the PR.Options
watched_reposunique(user_id, owner, repo)— one agent per repo per user. 409 at subscribe time.reviewed_prstounique(user_id, owner, repo, pr_number)— first watcher wins, others silently skip.Recommendation
Option A. Enforce at the
watched_reposinsert with a unique constraint on(user_id, owner, repo); return 409 when the conflict happens, with an error body naming the existing agent. We can revisit if users actually ask for multi-agent overlap.Done when
watched_reposmigration includesunique(user_id, owner, repo).POST /agents/{id}/watched-reposreturns 409 with a meaningful error when the conflict triggers.Depends on