fix(llmo): dedupe brand-presence citation counts by execution_id#2881
Merged
Sihalnic-Alin merged 5 commits intoJul 22, 2026
Conversation
aggregateDetailSources counted one citation per brand_presence_sources row instead of per distinct execution, so a URL cited multiple times within a single execution's answer inflated citationCount past the number of executions that actually cite it (e.g. 62 owned citations against 1 execution). Carry execution_id through flattenSourceRow and dedupe on it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
This PR will trigger a patch release when merged. |
Sihalnic-Alin
temporarily deployed
to
dev-branches
July 22, 2026 07:15 — with
GitHub Actions
Inactive
MysticatBot
approved these changes
Jul 22, 2026
There was a problem hiding this comment.
Hey @Sihalnic-Alin,
Verdict: Approve - well-scoped bug fix with correct dedup logic and good test coverage.
Complexity: LOW - small, single-service bug fix.
Changes: Deduplicates brand-presence citation counts by execution_id to fix inflated numbers on prompt/topic detail endpoints (2 files).
Non-blocking (2): minor issues and suggestions
- suggestion: Assert
promptsin the distinct-execution test case - since prompt counting is now gated inside the dedup branch, assertingexpect(entry.prompts).to.deep.equal([{ prompt: 'q1', count: 2 }])in the second test locks in that behavior explicitly -test/controllers/llmo/llmo-brand-presence.test.js:6620 - suggestion: Add a test case for rows without
execution_id(null/undefined) to verify they each count independently - this exercises the documented "rows without an execution_id always count" path directly -test/controllers/llmo/llmo-brand-presence.test.js:6572
Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 1m 0s | Cost: $3.14 | Commit: b3b4dad9624844b15a585fc4f56d016c582519b8
If this code review was useful, please react with 👍. Otherwise, react with 👎.
…tation dedup tests Addresses PR review feedback: lock in the prompts-count assertion for the distinct-execution-id case, and add explicit coverage for the "no execution_id" fallback path (each row counts independently). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sihalnic-Alin
temporarily deployed
to
dev-branches
July 22, 2026 08:05 — with
GitHub Actions
Inactive
Extends the existing fetchSourcesForExecutions handler test (mocked DB, no real Postgres needed) with a second brand_presence_sources row for the same execution_id + URL, proving the dedup fix holds through the full request/response path, not just the isolated aggregateDetailSources unit. Confirmed this fails against the pre-fix code (citationCount: 2) and passes with the fix (citationCount: 1). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sihalnic-Alin
temporarily deployed
to
dev-branches
July 22, 2026 08:37 — with
GitHub Actions
Inactive
aniham
approved these changes
Jul 22, 2026
Sihalnic-Alin
temporarily deployed
to
dev-branches
July 22, 2026 09:54 — with
GitHub Actions
Inactive
solaris007
pushed a commit
that referenced
this pull request
Jul 22, 2026
## [1.677.1](v1.677.0...v1.677.1) (2026-07-22) ### Bug Fixes * **llmo:** dedupe brand-presence citation counts by execution_id ([#2881](#2881)) ([49a727f](49a727f))
Member
|
🎉 This PR is included in version 1.677.1 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fix for inflated brand-presence citation counts on the Postgres-backed prompt/topic detail endpoints, surfaced via project-elmo-ui's URL Inspector showing implausible numbers like 62 "owned citations" against a prompt with only 1 execution.
Root cause (A):
aggregateDetailSources(src/controllers/llmo/llmo-brand-presence.js) counted one citation perbrand_presence_sourcesrow, not per distinct execution — a single execution can produce multiple rows for the same URL (e.g. one row per inline citation marker in that execution's answer), inflatingcitationCountpast the number of executions that actually cite it.Fix (B): carry
execution_idthroughflattenSourceRow(it was being dropped before reachingaggregateDetailSources), then dedupe bothcitationCountand per-prompt counts inaggregateDetailSourcesby distinctexecution_id— a URL cited multiple times within one execution's answer now counts once. Rows without anexecution_idstill always count, preserving prior behavior for that (not expected in practice) edge case.Tests
Added two cases to the
aggregateDetailSourcessuite: no double-counting across multiple rows sharing the sameexecution_id, and correct counting across distinctexecution_ids. Fullllmo-brand-presence.test.jssuite (515 tests) green locally; eslint clean.Related
Related to LLMO-1933
Surfaced while investigating project-elmo-ui's URL Inspector "show only cited executions" work (LLMO-1933) — this bug is separate and backend-only; no frontend change needed once this lands. No GitHub issue filed; described directly here.