Skip to content

fix(linear): enforce list-issues pagination backstops - #16128

Open
brennanb2025 wants to merge 5 commits into
mainfrom
brennanb2025/audit-15824
Open

brennanb2025 wants to merge 5 commits into
mainfrom
brennanb2025/audit-15824

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 5 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​198 $\color{#cf222e}{\Huge{\mathbf{−}}}$​4 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​194
Prod 9 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​144 $\color{#cf222e}{\Huge{\mathbf{−}}}$​29 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​115

Audit finding

The merged pagination safeguards were incomplete: a provider that repeated a cursor could trigger all 200 allowed requests, a stalled provider request could outlive the advertised 20-second budget, and an empty truncated human result hid the truncation marker. These are defensive correctness defects; no production incident from repeated or stalled Linear responses is known.

What changed

  • abort each in-flight Linear page request at the shared read deadline and return a truthful partial result
  • stop non-progressing and empty pages, deduplicating issues by stable id across pages
  • preserve truncated: showing 0 for empty partial human output
  • validate required mixed-version SSH metadata while preserving the older-host fallback that omits meta.returned
  • document that omitting --limit removes the caller cap but does not remove safety backstops, and that older hosts may omit priorityLabel

Compatibility

No request or result wire shape changes. Cancellation stays on the execution host, truncated and priorityLabel remain optional for mixed-version peers, and SSH formatting still falls back to meta.hasMore and rendered row counts.

Non-vacuity

Temporarily neutering the production hunks produced five expected failures: the repeat and empty-page cases made 200 requests, the deadline promise remained unsettled, empty human output omitted truncated: showing 0, and malformed SSH metadata formatted as valid. Omitting the signal from the request-scoped Linear client also failed its constructor contract test. Restoring the fixes returned every affected suite to green.

Testing

  • pnpm vitest run --config config/vitest.config.ts src/main/linear src/cli/linear-format.test.ts src/cli/index.test.ts src/main/ssh/ssh-remote-cli-format.test.ts src/main/ssh/ssh-remote-linear-truncation-output.test.ts src/main/ssh/ssh-remote-linear-cli.test.ts (22 files, 195 tests)
  • pnpm typecheck
  • node config/scripts/check-changed-code-quality.mjs
  • node config/scripts/check-react-doctor-changed.mjs
  • node config/scripts/generate-bundled-skill-guides.mjs --check
  • git diff --check

Visual proof: N/A — CLI JSON/text behavior only.

Merge note

PR #16119 concurrently touches the Linear guides and nearby formatter/SSH guard code. Whichever PR lands second should rebase and retain the combined contract wording.

Follow-up to #15824.

Stop non-progressing issue pages before the page ceiling, abort in-flight reads at the shared deadline, and keep partial empty results visibly truncated. Tighten the SSH result guard without requiring legacy row-count metadata, and document mixed-version fallbacks.
@coderabbitai

coderabbitai Bot commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5c4e7889-2254-4c9e-a0ae-5c2cff4dd977

📥 Commits

Reviewing files that changed from the base of the PR and between 94e7586 and 5df47ac.

📒 Files selected for processing (14)
  • skill-guides/linear-tickets.md
  • skill-guides/orca-linear.md
  • src/cli/bundled-skill-guides.ts
  • src/cli/linear-format.test.ts
  • src/cli/linear-format.ts
  • src/cli/specs/linear-mcp.ts
  • src/main/linear/client.test.ts
  • src/main/linear/client.ts
  • src/main/linear/mcp-issue-list-pagination.test.ts
  • src/main/linear/mcp-issue-list.test.ts
  • src/main/linear/mcp-issue-list.ts
  • src/main/ssh/ssh-remote-cli-format.test.ts
  • src/main/ssh/ssh-remote-linear-result-guards.ts
  • src/shared/linear/mcp-issue-list.ts
🚧 Files skipped from review as they are similar to previous changes (13)
  • src/main/linear/client.test.ts
  • src/main/linear/mcp-issue-list.ts
  • src/cli/linear-format.ts
  • src/cli/linear-format.test.ts
  • skill-guides/linear-tickets.md
  • src/main/ssh/ssh-remote-cli-format.test.ts
  • skill-guides/orca-linear.md
  • src/main/linear/mcp-issue-list-pagination.test.ts
  • src/main/linear/mcp-issue-list.test.ts
  • src/cli/specs/linear-mcp.ts
  • src/shared/linear/mcp-issue-list.ts
  • src/main/ssh/ssh-remote-linear-result-guards.ts
  • src/main/linear/client.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 2 remain after this review.


📝 Walkthrough

Walkthrough

Linear issue listing now creates request-scoped clients with abort signals and shared read deadlines. Pagination stops on repeated cursors, empty pages, or expired requests, and deduplicates issues. Truncation metadata remains available after bounded reads. Remote result guards validate issue-list metadata and workspace errors. CLI formatting reports truncation for empty results. Documentation describes uncapped reads, pagination, truncation metadata, and host-specific priorityLabel behavior.

Merge Risk: ⚪ Minimal · up to 5df47

The change adds bounded pagination and timeout safeguards while preserving existing output and mixed-version compatibility; no actionable merge-blocking risk remains after normal checks and review.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the audit finding, implementation, compatibility, testing, and visual-proof status. However, it omits several required template sections, including ELI5, Why, Linked Issue wit… Add the missing required template sections. Include the linked issue number after "Fixes #", complete the checklist, document AI disclosure and upstream-boundary status, and report the three known CI failures with their resolution or curren…
Docstring Coverage ⚠️ Warning Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 16 functions across 11 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: enforcing pagination backstops for Linear issue listing.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the audit finding, implementation, compatibility, testing, and visual-proof status. However, it omits several required template sections, including ELI5, Why, Linked Issue with an issue number, AI Disclosure, Review, Agent skill upstream boundary, Notes, and the Checklist. It also does not report the known CI failures described in the objectives.

Resolution

Add the missing required template sections. Include the linked issue number after "Fixes #", complete the checklist, document AI disclosure and upstream-boundary status, and report the three known CI failures with their resolution or current status.

Full details: Docstring Coverage

Explanation

Docstring coverage is 6.25% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 16 functions across 11 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2e2f8c6d-f6c7-4f0a-aaad-b98213a47f23

📥 Commits

Reviewing files that changed from the base of the PR and between d1127b9 and ea5bd02.

📒 Files selected for processing (14)
  • skill-guides/linear-tickets.md
  • skill-guides/orca-linear.md
  • src/cli/bundled-skill-guides.ts
  • src/cli/linear-format.test.ts
  • src/cli/linear-format.ts
  • src/cli/specs/linear-mcp.ts
  • src/main/linear/client.test.ts
  • src/main/linear/client.ts
  • src/main/linear/mcp-issue-list-pagination.test.ts
  • src/main/linear/mcp-issue-list.test.ts
  • src/main/linear/mcp-issue-list.ts
  • src/main/ssh/ssh-remote-cli-format.test.ts
  • src/main/ssh/ssh-remote-linear-result-guards.ts
  • src/shared/linear/mcp-issue-list.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 0 remain after this review.

@brennanb2025

brennanb2025 commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor Author

Exact-head review update (53eea01): malformed Linear MCP issue rows are fully validated (including required fields and optional nested metadata), with safe JSON fallback for SSH formatting; the fix is covered by the focused suite (22 files, 197 tests). Local typecheck, changed-code quality, React Doctor, bundled skill-guide check, oxfmt, and diff checks pass; re-review finds no additional in-scope issues, and the sole CodeRabbit thread is resolved and current (1 resolved, 0 unresolved, 0 outdated). Final GitHub CI reports 50 success, 3 failure (Node 24/26 shard 10 runtime export-parity mismatch plus dependent verify), and 4 skipped; merge is blocked by failed checks, and this CLI/SSH-only change has no Electron/mobile validation surface.

@brennanb2025

brennanb2025 commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor Author

Exact-head QA evidence (53eea01): pnpm vitest run --config config/vitest.config.ts src/main/linear src/cli/linear-format.test.ts src/cli/index.test.ts src/main/ssh/ssh-remote-cli-format.test.ts src/main/ssh/ssh-remote-linear-truncation-output.test.ts src/main/ssh/ssh-remote-linear-cli.test.ts passed (22 files, 197 tests), plus pnpm typecheck, changed-code quality, React Doctor, bundled skill-guide check, oxfmt, and git diff --check. No UI/mobile flow applies, so Electron Playwright CDP, visual proof, and emulator QA are not applicable; no owned dev processes were started. Final exact-head CI is 50 success, 3 failure (Node 24/26 shard 10 runtime export-parity expectation and dependent verify), 4 skipped; merge remains blocked pending base-branch parity resolution and rerun.

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@greptile-apps

greptile-apps Bot commented Aug 28, 2026 •

Copy link
Copy Markdown

Greptile Summary

The PR adds pagination progress backstops, issue deduplication, request cancellation, truthful empty-result truncation formatting, and stricter SSH result validation for Linear list-issues.

  • Stops repeated-cursor and empty-page walks while preserving continuation metadata.
  • Binds Linear page requests to a shared read deadline.
  • Preserves mixed-version formatting fallbacks and updates bundled CLI guidance.

Confidence Score: 4/5

The deadline must cover concurrency-slot acquisition before merging, otherwise list-issues can still exceed its advertised read budget.

The in-flight request is cancellable, but the operation can wait without a bound before reaching that cancellation logic because shared limiter acquisition has no timeout or abort path.

Files Needing Attention: src/main/linear/mcp-issue-list.ts

Important Files Changed

Filename Overview
src/main/linear/mcp-issue-list.ts Adds pagination and deadline safeguards, but the deadline does not cover waiting for the shared request semaphore.
src/main/linear/client.ts Adds a request-scoped Linear client that forwards the supplied AbortSignal.
src/main/ssh/ssh-remote-linear-result-guards.ts Strengthens issue-row and metadata validation while preserving optional mixed-version fields.
src/cli/linear-format.ts Correctly retains the truncation marker when a partial list contains zero issues.
src/shared/linear/mcp-issue-list.ts Clarifies that a null limit removes only the caller cap and does not imply a complete read.

Sequence Diagram

sequenceDiagram
  participant CLI as list-issues
  participant Pool as Shared Linear limiter
  participant Page as Page read
  participant SDK as Linear SDK
  CLI->>Pool: acquire()
  Note over CLI,Pool: Queue wait is currently unbounded
  Pool-->>Page: slot granted
  Page->>Page: check remaining 20s budget
  alt budget remains
    Page->>SDK: rawRequest(signal)
    SDK-->>Page: page or abort
  else deadline already passed
    Page-->>CLI: truncated partial result
  end
Loading

Comments Outside Diff (1)

  1. src/main/linear/mcp-issue-list.ts, line 2019-2023 (link)

    P1 Deadline excludes semaphore wait

    If all four shared Linear request slots are occupied by slow or stalled operations, withLinearRead waits on the unbounded acquire() before this callback checks the remaining deadline. The list-issues request therefore remains pending beyond its 20-second budget—and indefinitely when no slot is released—instead of returning a truncated partial result.

Reviews (1): Last reviewed commit: "Merge branch 'main' into brennanb2025/au..." | Re-trigger Greptile

This branch has not been deployed

No deployments
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