Skip to content

Duplicate-comment dedupe never runs while the comment-id cache is warm #480

Description

@zachdunn

Follow-up to #470 / PR #471, observed during live smoke testing on 2026-07-23.

Behavior

PR #471's self-healing dedupe (patch the oldest marker comment, delete extras) lives in findMarkerComment's consumer — it only executes when the marker hunt runs. upsertBotComment's fast path PATCHes the KV-cached comment id directly with no listing, so while the cache is warm a duplicate marker comment sits untouched.

Verified live: with a duplicate planted on PR #468 and a warm cache, uploads comment --pr 468 updated the cached comment and left the duplicate. It only collapsed after forcing a cache miss (deleting the cached comment → 404 → cache drop → hunt → dedupe). See the throwaway test on issue #474.

Consequence

A race-created duplicate (the #470 scenario) can persist for up to the cache lifetime — COMMENT_ID_TTL is 30 days, refreshed on each hunt — before the healing pass ever sees it. Eventual healing holds; "heals on the next sync" does not when the cache is warm.

Proposed

Run the dedupe hunt opportunistically in the cases where cost is acceptable and intent is explicit:

  • uploads comment (the explicit CLI resync, and its server endpoint when invoked that way): always hunt instead of trusting the cached id. The command is rare and is precisely "make the comment state correct" — one extra listing per invocation is fine.
  • Optionally: a low-probability hunt on ordinary syncs (e.g. 1-in-N), or a hunt piggybacked on the issue_comment webhook self-heal (feat: github repo link lifecycle — unlink, reassign, admin visibility #325) which already fires on comment activity.

Keep the fast path for the high-frequency attach/promote syncs — the point is an explicit or cheap trigger that bounds duplicate lifetime to "next uploads comment" rather than "next cache miss".

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions