Context
src/github/comments.ts's createOrUpdateIssueCommentWithMarker (the single chokepoint every LoopOver PR
panel/agent-command comment goes through — createOrUpdatePrIntelligenceComment and
createOrUpdateAgentCommandComment both call it) searches an issue/PR's existing comments for LoopOver's own
marker comment (PR_PANEL_COMMENT_MARKER or one of its legacy aliases) so it can PATCH the existing comment
instead of creating a duplicate:
const COMMENT_SEARCH_PAGE_LIMIT = 3;
...
for (let page = 1; page <= COMMENT_SEARCH_PAGE_LIMIT; page += 1) {
const response = await octokit.request("GET /repos/{owner}/{repo}/issues/{issue_number}/comments", {
...
per_page: 100,
page,
});
...
if (batch.length < 100) break;
}
const canonical = canonicalMarkerComment(existing);
if (canonical) {
// PATCH the existing comment
} else if (options.createIfMissing !== false) {
// POST a brand-new comment
}
COMMENT_SEARCH_PAGE_LIMIT = 3 caps the search at the first 300 issue comments. If a PR/issue
accumulates more than 300 comments before LoopOver's own marker comment appears in the list (heavy
back-and-forth, other bots, CI notification comments, etc.), canonical comes back undefined even though
the marker comment exists further back, and createOrUpdateIssueCommentWithMarker creates a second
marker comment instead of updating the first — the exact "silent list-endpoint truncation" bug class this
codebase has repeatedly hardened against elsewhere:
src/github/pr-actions.ts's REVIEW_PAGE_LIMIT = 10 (1000 reviews) and
ISSUE_EVENTS_RECENT_PAGE_LIMIT = 10 (1000 events) are both explicitly commented as walking "every page ...
a single per_page:100 fetch would only see the bot's earliest reviews on a PR with a long review history."
src/github/backfill.ts (line ~2356) has a standing comment: "GitHub caps list endpoints at 100 items/page,
so a single per_page=100 fetch silently truncates a ..." and follows Link: rel="next" with much larger
bounds (PR_DETAIL_MAX_PAGES) or no fixed page cap at all, deferring only to hasNextPage(result.link).
src/github/app.ts's MAX_WORKFLOW_RUN_LIST_PAGES = 10 carries the same "mirrors
src/github/backfill.ts's githubPaginatedList/PR_DETAIL_MAX_PAGES bound" reasoning.
COMMENT_SEARCH_PAGE_LIMIT = 3 has no comment justifying why 300 is enough, and is far smaller than every
sibling bound in this exact file family. Since LoopOver's own marker comment is typically the FIRST comment
ever posted on a PR (created on the PR's first review pass), it will almost always still get pushed past page
3 by 300+ later human/bot comments on a genuinely long-running or heavily-discussed PR — not a hypothetical
edge case for this repo's own most-active PRs.
Requirements
- Raise
COMMENT_SEARCH_PAGE_LIMIT (or replace the fixed-page-count loop entirely) so the marker-comment
search follows GitHub's Link: rel="next" header until exhausted, bounded the same way
MAX_WORKFLOW_RUN_LIST_PAGES / REVIEW_PAGE_LIMIT are — a generous page cap (e.g. 10, matching the
sibling bounds in pr-actions.ts and app.ts) rather than the current 3.
- Preserve the existing early-exit behavior (
if (batch.length < 100) break;) so a short comment list still
makes only one request.
- Do not change
createOrUpdateIssueCommentWithMarker's public behavior for the common case (PR/issue with
fewer than 300 comments) — this is purely raising the search depth for pathological cases.
- Keep the existing per-page
per_page: 100 and the existing bot/marker filtering logic
(isLoopOverBotComment, markerAliases) unchanged.
Deliverables
Test Coverage Requirements
src/github/comments.ts is under src/**, so codecov/patch (99% target, branch-counted, 0% threshold)
gates this change directly. The new/changed lines in the pagination loop and any bound-adjustment must be
covered by the regression test above; test/unit/github-comments.test.ts already exercises this function
today, so extend it rather than adding a new test file.
Expected Outcome
A PR/issue with more than 300 (previously 300, raised per this issue) comments before LoopOver's own marker
comment can no longer end up with two competing LoopOver PR-panel comments — the search reliably finds the
existing marker comment regardless of how deep it sits in the comment history, matching the depth this repo
already guarantees for reviews (pr-actions.ts) and workflow runs (app.ts).
Links & Resources
src/github/comments.ts (COMMENT_SEARCH_PAGE_LIMIT, createOrUpdateIssueCommentWithMarker)
- Precedent:
src/github/pr-actions.ts (REVIEW_PAGE_LIMIT, ISSUE_EVENTS_RECENT_PAGE_LIMIT),
src/github/app.ts (MAX_WORKFLOW_RUN_LIST_PAGES), src/github/backfill.ts (Link-header pagination
helpers)
test/unit/github-comments.test.ts
Context
src/github/comments.ts'screateOrUpdateIssueCommentWithMarker(the single chokepoint every LoopOver PRpanel/agent-command comment goes through —
createOrUpdatePrIntelligenceCommentandcreateOrUpdateAgentCommandCommentboth call it) searches an issue/PR's existing comments for LoopOver's ownmarker comment (
PR_PANEL_COMMENT_MARKERor one of its legacy aliases) so it canPATCHthe existing commentinstead of creating a duplicate:
COMMENT_SEARCH_PAGE_LIMIT = 3caps the search at the first 300 issue comments. If a PR/issueaccumulates more than 300 comments before LoopOver's own marker comment appears in the list (heavy
back-and-forth, other bots, CI notification comments, etc.),
canonicalcomes backundefinedeven thoughthe marker comment exists further back, and
createOrUpdateIssueCommentWithMarkercreates a secondmarker comment instead of updating the first — the exact "silent list-endpoint truncation" bug class this
codebase has repeatedly hardened against elsewhere:
src/github/pr-actions.ts'sREVIEW_PAGE_LIMIT = 10(1000 reviews) andISSUE_EVENTS_RECENT_PAGE_LIMIT = 10(1000 events) are both explicitly commented as walking "every page ...a single per_page:100 fetch would only see the bot's earliest reviews on a PR with a long review history."
src/github/backfill.ts(line ~2356) has a standing comment: "GitHub caps list endpoints at 100 items/page,so a single
per_page=100fetch silently truncates a ..." and followsLink: rel="next"with much largerbounds (
PR_DETAIL_MAX_PAGES) or no fixed page cap at all, deferring only tohasNextPage(result.link).src/github/app.ts'sMAX_WORKFLOW_RUN_LIST_PAGES = 10carries the same "mirrorssrc/github/backfill.ts's githubPaginatedList/PR_DETAIL_MAX_PAGES bound" reasoning.
COMMENT_SEARCH_PAGE_LIMIT = 3has no comment justifying why 300 is enough, and is far smaller than everysibling bound in this exact file family. Since LoopOver's own marker comment is typically the FIRST comment
ever posted on a PR (created on the PR's first review pass), it will almost always still get pushed past page
3 by 300+ later human/bot comments on a genuinely long-running or heavily-discussed PR — not a hypothetical
edge case for this repo's own most-active PRs.
Requirements
COMMENT_SEARCH_PAGE_LIMIT(or replace the fixed-page-count loop entirely) so the marker-commentsearch follows GitHub's
Link: rel="next"header until exhausted, bounded the same wayMAX_WORKFLOW_RUN_LIST_PAGES/REVIEW_PAGE_LIMITare — a generous page cap (e.g. 10, matching thesibling bounds in
pr-actions.tsandapp.ts) rather than the current 3.if (batch.length < 100) break;) so a short comment list stillmakes only one request.
createOrUpdateIssueCommentWithMarker's public behavior for the common case (PR/issue withfewer than 300 comments) — this is purely raising the search depth for pathological cases.
per_page: 100and the existing bot/marker filtering logic(
isLoopOverBotComment,markerAliases) unchanged.Deliverables
COMMENT_SEARCH_PAGE_LIMITraised to match the sibling bound used elsewhere insrc/github/**(or theloop changed to follow
Link: rel="next"instead of a fixed count), with a comment explaining thechosen bound the same way
REVIEW_PAGE_LIMIT/MAX_WORKFLOW_RUN_LIST_PAGESare documented.test/unit/github-comments.test.tsthat stubs more than 300 (pre-existing bound)comments with the marker comment beyond page 3, and asserts
createOrUpdateIssueCommentWithMarkerfinds and updates it (PATCH) instead of creating a duplicate.
Test Coverage Requirements
src/github/comments.tsis undersrc/**, socodecov/patch(99% target, branch-counted, 0% threshold)gates this change directly. The new/changed lines in the pagination loop and any bound-adjustment must be
covered by the regression test above;
test/unit/github-comments.test.tsalready exercises this functiontoday, so extend it rather than adding a new test file.
Expected Outcome
A PR/issue with more than 300 (previously 300, raised per this issue) comments before LoopOver's own marker
comment can no longer end up with two competing LoopOver PR-panel comments — the search reliably finds the
existing marker comment regardless of how deep it sits in the comment history, matching the depth this repo
already guarantees for reviews (
pr-actions.ts) and workflow runs (app.ts).Links & Resources
src/github/comments.ts(COMMENT_SEARCH_PAGE_LIMIT,createOrUpdateIssueCommentWithMarker)src/github/pr-actions.ts(REVIEW_PAGE_LIMIT,ISSUE_EVENTS_RECENT_PAGE_LIMIT),src/github/app.ts(MAX_WORKFLOW_RUN_LIST_PAGES),src/github/backfill.ts(Link-header paginationhelpers)
test/unit/github-comments.test.ts