Brainstorm: no repeat-comment, prefer novelty — Design¶
Date: 2026-06-19 Repo: tatara-operator (operator-only) Status: approved design, pre-plan
Problem¶
The hourly project-wide brainstorm agent surveys open issues and, per the 2026-06-15 brainstorm-dedup design, may call comment_on_issue when its idea "connects to" an existing issue instead of opening a duplicate. In practice the highest-leverage idea keeps mapping to the SAME open issue cycle after cycle, so the agent re-comments the same issue repeatedly instead of generating new improvements. Nothing tells the agent which issues the bot already engaged, and nothing stops a repeat comment.
Desired behavior: never comment twice on the same issue. If the best idea connects to an already-engaged issue, the agent moves on -- a different high-leverage improvement (novel standalone proposal in the same repo, another repo, or project-wide), a comment on a still-untouched issue, or a no-op.
Approved decisions¶
- Enforcement: prompt + operator hard-gate (inject bot-comment awareness AND refuse a duplicate bot comment at the egress endpoint). Matches the bot-authorship-at-egress design.
- Re-comment cap: 1 (zero re-comments). The bot comments any issue at most once, ever; after that the issue is off-limits for further comments.
- Detection: live SCM comment scan (
ListIssueComments, checkAuthor == BotLogin). Authoritative, no new persisted state.
All scoped to tatara-operator: the comment_on_issue cli MCP tool and wrapper pin already shipped (2026-06-15), so no cli / wrapper / agent.image change. The prompt only narrows WHEN the agent calls the existing tool.
Design¶
Part A -- context awareness (internal/controller/projectscan.go brainstorm())¶
brainstorm() already calls ListOpenIssues across all project repos to build the dedup context block. Extend that pass: for each open issue included in the context (subject to the existing cap, e.g. first 60), call ListIssueComments(ctx, owner, repo, number) and check whether any IssueComment.Author == proj.Spec.Scm.BotLogin.
- If yes, mark that issue's context entry
[bot-engaged](alongside its existingrepo#N [labels] Title+ snippet). - The scan honors the same truncation cap as the issue context: issues beyond the cap are not scanned and carry no flag;
log()when truncated. The Part B hard-gate still protects unscanned issues. BotLoginempty (no bot configured) -> skip the scan entirely, no flags. Same as today's behavior.- Cost: at most one
ListIssueCommentscall per in-context open issue per cycle (N <= cap, hourly). Trivial against GitHub's 5000/hr authenticated budget and GitLab equivalents.
Part A -- prompt (brainstormGoalProject)¶
Revise the action menu so a [bot-engaged] issue is removed from the comment-eligible set:
- Duplicate of an existing issue -> do NOT propose; one-line note naming the duplicate (unchanged).
- Connects to / is a sub-aspect of an issue that is NOT
[bot-engaged]->comment_on_issueon that issue (unchanged). - Connects to a
[bot-engaged]issue -> do NOT re-comment. Instead pick a different high-leverage improvement: a genuinely novel standalone idea (propose_issue, same repo / another repo / project-wide), OR a comment on a different still-untouched issue, OR finish with a no-op note if nothing else stands out. - Genuinely novel standalone ->
propose_issue(unchanged). - Explicit framing: "Prefer NEW improvements over re-engaging existing discussion. Never comment twice on the same issue."
Exactly one of {propose_issue, comment_on_issue, no-op-with-note} per run, as today. Writeback is unaffected (a no-proposal run is BrainstormComplete, not a failure).
Part B -- egress hard-gate (internal/restapi/handlers.go commentOnIssue)¶
The commentOnIssue handler already resolves the Project, maps repo to an owner/repo, fetches the project SCM token, and posts via an SCM writer. Before the write, add a gate:
- Obtain an SCM reader bound to the same project token. The handler today gets only a writer via the server's SCM factory; the concrete
*GitHub/*GitLabclients already satisfySCMReadertoo. Extend the factory so the handler can obtain a reader (either widen the existing factory's return type to a combined read+write interface, or add a siblingSCMReaderFor), reusing the same provider + token resolution. Match existing conventions. ListIssueComments(ctx, owner, repo, number); if anyAuthor == proj.Spec.Scm.BotLogin-> return 409 Conflict, bodybot already commented on this issue; pick another action. Do NOT post.- On block:
log.InfoContext(action=scm_issue_comment_blocked, reason=already_commented, project, repo, number)and increment a counterbrainstorm_recomment_blocked_total(hard rule 13). BotLoginempty -> skip the gate, post as today.
This is the authoritative backstop: even if the agent ignores the prompt, the operator refuses the second bot comment. It also makes comment_on_issue idempotent against the bot's own prior comment. TOCTOU between the read and the post is ignored -- hourly cadence + cap-1 make a concurrent double-post practically impossible.
Deploy order¶
Operator-only, single component: 1. tatara-operator: merge Part A + B -> operator image (CI builds + pushes). 2. tatara-helmfile: MR bumping the operator chart version AND the pinned image.tag (per the operator-deploy memory: both, never chart-only); diff -> merge -> pipeline applies.
No cli, wrapper, or Project agent.image change -- the prompt only constrains an already-deployed tool.
Testing (TDD)¶
- projectscan: with a bot comment present on an issue, the built context flags it
[bot-engaged]; absent -> no flag;BotLoginempty -> no scan calls. Goal text frombrainstormGoalProjectcontains the no-re-comment instruction (string asserts) and still namespropose_issue/comment_on_issue. - handler:
commentOnIssuereturns 409 when a bot comment already exists on the target issue (writer.Comment NOT called); 200 + writer.Comment called when none exists; reader built from the project token;BotLoginempty -> gate skipped. - Full envtest controller suite green (KUBEBUILDER_ASSETS via setup-envtest 1.33.0).
Out of scope¶
- Semantic "same topic" dedup: we key strictly on the bot's literal prior comment on that issue, not on content similarity.
- Recently-closed issues (the scan covers open issues only, as today).
- Per-issue cap > 1 / configurable back-and-forth: fixed at 1.
- No persisted comment-history state (live scan only).