Skip to content

fix(config): disambiguate PR comment markers across konflate instances - #511

Open
Stasky745 wants to merge 2 commits into
home-operations:mainfrom
Stasky745:feat/comment-marker-instance-tag
Open

fix(config): disambiguate PR comment markers across konflate instances#511
Stasky745 wants to merge 2 commits into
home-operations:mainfrom
Stasky745:feat/comment-marker-instance-tag

Conversation

@Stasky745

Copy link
Copy Markdown
Contributor

Overview

The hidden comment marker (<!-- konflate:pr-N -->) was keyed only by PR number. In a multi-cluster monorepo scenario two instances behind the same GitHub App rendering the same PR can't tell each other's comments apart, so the second one to post finds and overwrites the first's.

Add config.commentTag (KONFLATE_COMMENT_TAG), embedded in the marker. Falls back to StatusCheckName (already commonly set to a distinct per-instance name for branch protection), then to no tag. A single-instance setup with neither set is unaffected. Sanitized before embedding since it lands inside an HTML comment.

Additional information

This might create a new extra comment on a PR that already existed before the update, since the newly-tagged marker doesn't match the old untagged comment already on the PR. This is one-time and only for comments generated before the update.

Requirements

  • I have read and agree with the contributing guidelines
  • AI usage disclosure: YES, came up with the solution together with AI and Claude generated the code. I oversaw the code changes and we both ran tests.

The hidden comment marker (<!-- konflate:pr-N -->) was keyed only by PR
number. Multiple konflate deployments sharing one bot identity — a
folder-per-cluster monorepo's normal shape, e.g. dev/app and production/app
both authenticating as the same GitHub App — that render the same PR are
indistinguishable to UpsertComment: whichever posts second finds the first's
comment (same author, same marker) and overwrites it instead of creating its
own.

Add config.commentTag (KONFLATE_COMMENT_TAG), embedded in the marker.
Falls back to StatusCheckName (already commonly set to a distinct
per-instance name for branch protection), then to no tag — a
single-instance setup with neither set is unaffected. Sanitized before
embedding since it lands inside an HTML comment (see home-operations#314).
@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; the previously reported marker collision, default compatibility, and stale-template-marker concerns are addressed.

Summary

  • Adds commentTag configuration and Helm chart wiring, with custom status-check names as a fallback.
  • Hashes configured tags to avoid collisions and HTML-comment injection.
  • Replaces stale markers embedded by custom templates.
  • Adds regression coverage for defaults, collision resistance, deterministic markers, and mixed-version templates.

Comment thread internal/server/markdown.go Outdated
Comment thread internal/config/config.go Outdated
marker := konflateMarker(number)
func ensureMarker(number int, tag, body string) string {
marker := konflateMarker(number, tag)
if strings.Contains(body, marker) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Legacy marker remains embedded

For a tagged instance, a custom template that already emits the previously documented <!-- konflate:pr-{{ .PR.Number }} --> marker receives the new tagged marker in addition to the legacy one. During a mixed-version rollout, an older untagged instance can then match and overwrite this tagged comment, depending on comment ordering. Please remove or replace the legacy marker when injecting a tagged marker and cover this compatibility case in TestEnsureMarker.

Fix in Claude Code

…mplate markers

Three issues from review on home-operations#511:

- CommentMarkerTag() falling back to StatusCheckName unconditionally broke
  every single-instance install: Load fills a blank StatusCheckName in with
  DefaultStatusCheckName before any caller sees it, so the fallback always
  fired and changed every install's marker on upgrade. Now excludes the
  default constant from the fallback.

- konflateMarker's character-collapsing sanitizer let distinct tags collide
  ("dev/app", "dev app", "dev-app" all sanitized to "dev-app"),
  reintroducing the exact cross-instance overwrite this exists to prevent.
  Replaced with a sha256 hash of the raw tag: deterministic, collision-safe,
  and structurally can't break out of the HTML comment (hex-only output).

- ensureMarker didn't strip a marker a custom template already embeds
  verbatim (the contract says a template needn't include one, not that it
  mustn't). A stale untagged marker surviving alongside the new tagged one
  would let an older or differently-tagged instance still Contains-match and
  overwrite the comment during a mixed rollout.
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